Files
bigcapital/shared/email-components/src/lib/ReceiptPaymentEmail.tsx
Ahmed Bouhuolia dd1392cdc8 feat: add discount functionality to sales and purchase transactions
- Introduced discount_type and discount fields in Bills and SalesReceipts controllers.
- Updated database migrations to include discount and discount_type in estimates and credit notes tables.
- Enhanced SaleReceipt and SaleEstimate models to support discount attributes.
- Implemented formatting for discount amounts in transformers and PDF templates.
- Updated email templates to display discount information.

This commit enhances the handling of discounts across various transaction types, improving the overall functionality and user experience.
2024-11-30 14:46:56 +02:00

235 lines
5.1 KiB
TypeScript

import {
Button,
Column,
Heading,
render,
Row,
Section,
Text,
} from '@react-email/components';
import { CSSProperties } from 'react';
import { EmailTemplateLayout } from './EmailTemplateLayout';
import { EmailTemplate } from './EmailTemplate';
export interface ReceiptEmailTemplateProps {
preview: string;
companyName?: string;
companyLogoUri: string;
// # Colors
primaryColor?: string;
// # Receipt #
receiptNumber?: string;
receiptNumberLabel?: string;
// # Items
items: Array<{ label: string; quantity: string; rate: string }>;
// # Invoice total
total: string;
totalLabel?: string;
// # Discount
discount?: string;
discountLabel?: string;
// # Subtotal
subtotal?: string;
subtotalLabel?: string;
// # Message
message?: string;
}
export const ReceiptEmailTemplate: React.FC<
Readonly<ReceiptEmailTemplateProps>
> = ({
preview,
// # Company
companyName = 'Bigcapital, Inc.',
companyLogoUri,
// # Colors
primaryColor = 'rgb(0, 82, 204)',
// # Invoice total
total = '$1,000.00',
totalLabel = 'Total',
// # Subtotal
subtotal = '$1,000.00',
subtotalLabel = 'Subtotal',
// # Receipt #
receiptNumberLabel = 'Receipt # {receiptNumber}',
receiptNumber = 'REC-00001',
// # Message
message = '',
// # Items
items = [{ label: 'Swaniawski Muller', quantity: '1', rate: '$1,000.00' }],
}) => {
return (
<EmailTemplateLayout preview={preview}>
<EmailTemplate>
{companyLogoUri && <EmailTemplate.CompanyLogo src={companyLogoUri} />}
<Section style={headerInfoStyle}>
<Row>
<Heading style={invoiceCompanyNameStyle}>{companyName}</Heading>
</Row>
<Row>
<Text style={amountStyle}>{total}</Text>
</Row>
<Row>
<Text style={receiptNumberStyle}>
{receiptNumberLabel?.replace('{receiptNumber}', receiptNumber)}
</Text>
</Row>
</Section>
<Text style={messageStyle}>{message}</Text>
<Section style={totalsSectionStyle}>
{items.map((item, index) => (
<Row key={index} style={itemLineRowStyle}>
<Column width={'50%'}>
<Text style={listItemLabelStyle}>{item.label}</Text>
</Column>
<Column width={'50%'}>
<Text style={listItemAmountStyle}>
{item.quantity} x {item.rate}
</Text>
</Column>
</Row>
))}
<Row style={totalLineRowStyle}>
<Column width={'50%'}>
<Text style={dueAmountLineItemLabelStyle}>{subtotalLabel}</Text>
</Column>
<Column width={'50%'}>
<Text style={dueAmountLineItemAmountStyle}>{subtotal}</Text>
</Column>
</Row>
<Row style={totalLineRowStyle}>
<Column width={'50%'}>
<Text style={totalLineItemLabelStyle}>{totalLabel}</Text>
</Column>
<Column width={'50%'}>
<Text style={totalLineItemAmountStyle}>{total}</Text>
</Column>
</Row>
</Section>
</EmailTemplate>
</EmailTemplateLayout>
);
};
/**
* Renders the sale receipt mail template to string
* @param {ReceiptEmailTemplateProps} props
* @returns {Promise<string>}
*/
export const renderReceiptEmailTemplate = (
props: ReceiptEmailTemplateProps
) => {
return render(<ReceiptEmailTemplate {...props} />);
};
const headerInfoStyle: CSSProperties = {
textAlign: 'center',
marginBottom: 20,
};
const amountStyle: CSSProperties = {
margin: 0,
color: '#383E47',
fontWeight: 500,
};
const receiptNumberStyle: CSSProperties = {
margin: 0,
fontSize: '13px',
color: '#404854',
};
const invoiceCompanyNameStyle: CSSProperties = {
margin: 0,
fontSize: '18px',
fontWeight: 500,
color: '#404854',
};
const viewInvoiceButtonStyle: CSSProperties = {
display: 'block',
cursor: 'pointer',
textAlign: 'center',
fontSize: 16,
padding: '10px 15px',
lineHeight: '1',
backgroundColor: 'rgb(0, 82, 204)',
color: '#fff',
borderRadius: '5px',
};
const listItemLabelStyle: CSSProperties = {
margin: 0,
};
const listItemAmountStyle: CSSProperties = {
margin: 0,
textAlign: 'right',
};
const messageStyle: CSSProperties = {
whiteSpace: 'pre-line',
margin: '0 0 20px 0',
lineHeight: '20px',
};
const totalLineRowStyle: CSSProperties = {
borderBottom: '1px solid #000',
height: 40,
};
const totalLineItemLabelStyle: CSSProperties = {
...listItemLabelStyle,
fontWeight: 500,
};
const totalLineItemAmountStyle: CSSProperties = {
...listItemAmountStyle,
fontWeight: 600,
};
const dueAmountLineItemLabelStyle: CSSProperties = {
...listItemLabelStyle,
fontWeight: 500,
};
const dueAmountLineItemAmountStyle: CSSProperties = {
...listItemAmountStyle,
fontWeight: 600,
};
const itemLineRowStyle: CSSProperties = {
borderBottom: '1px solid #D9D9D9',
height: 40,
};
const totalsSectionStyle = {
marginTop: '20px',
borderTop: '1px solid #D9D9D9',
};