diff --git a/packages/server/src/interfaces/SaleEstimate.ts b/packages/server/src/interfaces/SaleEstimate.ts index 90eddc8ff..88ffcf51c 100644 --- a/packages/server/src/interfaces/SaleEstimate.ts +++ b/packages/server/src/interfaces/SaleEstimate.ts @@ -26,6 +26,9 @@ export interface ISaleEstimate { branchId?: number; warehouseId?: number; + total?: number; + totalLocal?: number; + discountAmount?: number; discountPercentage?: number | null; diff --git a/packages/server/src/services/Sales/Estimates/GetEstimateMailTemplateAttributesTransformer.ts b/packages/server/src/services/Sales/Estimates/GetEstimateMailTemplateAttributesTransformer.ts index 4d8cbfc0f..81d6d9a6c 100644 --- a/packages/server/src/services/Sales/Estimates/GetEstimateMailTemplateAttributesTransformer.ts +++ b/packages/server/src/services/Sales/Estimates/GetEstimateMailTemplateAttributesTransformer.ts @@ -25,6 +25,12 @@ export class GetEstimateMailTemplateAttributesTransformer extends Transformer { 'subtotal', 'subtotalLabel', + 'discount', + 'discountLabel', + + 'adjustment', + 'adjustmentLabel', + 'dueAmount', 'dueAmountLabel', @@ -103,7 +109,7 @@ export class GetEstimateMailTemplateAttributesTransformer extends Transformer { * Estimate total. */ public total(): string { - return this.options.estimate.formattedAmount; + return this.options.estimate.totalFormatted; } /** @@ -114,11 +120,43 @@ export class GetEstimateMailTemplateAttributesTransformer extends Transformer { return 'Total'; } + /** + * Estimate discount. + * @returns {string} + */ + public discount(): string { + return this.options.estimate?.discountAmountFormatted; + } + + /** + * Estimate discount label. + * @returns {string} + */ + public discountLabel(): string { + return 'Discount'; + } + + /** + * Estimate adjustment. + * @returns {string} + */ + public adjustment(): string { + return this.options.estimate?.adjustmentFormatted; + } + + /** + * Estimate adjustment label. + * @returns {string} + */ + public adjustmentLabel(): string { + return 'Adjustment'; + } + /** * Estimate subtotal. */ public subtotal(): string { - return this.options.estimate.formattedAmount; + return this.options.estimate.formattedSubtotal; } /** diff --git a/packages/server/src/services/Sales/Estimates/SaleEstimateTransformer.ts b/packages/server/src/services/Sales/Estimates/SaleEstimateTransformer.ts index 3ce5143d2..8876d0a14 100644 --- a/packages/server/src/services/Sales/Estimates/SaleEstimateTransformer.ts +++ b/packages/server/src/services/Sales/Estimates/SaleEstimateTransformer.ts @@ -21,6 +21,8 @@ export class SaleEstimateTransfromer extends Transformer { 'discountAmountFormatted', 'discountPercentageFormatted', 'adjustmentFormatted', + 'totalFormatted', + 'totalLocalFormatted', 'formattedCreatedAt', 'entries', 'attachments', @@ -134,6 +136,27 @@ export class SaleEstimateTransfromer extends Transformer { }); }; + /** + * Retrieves the formatted estimate total. + * @returns {string} + */ + protected totalFormatted = (estimate: ISaleEstimate): string => { + return formatNumber(estimate.total, { + currencyCode: estimate.currencyCode, + }); + }; + + /** + * Retrieves the formatted estimate total in local currency. + * @param estimate + * @returns {string} + */ + protected totalLocalFormatted = (estimate: ISaleEstimate): string => { + return formatNumber(estimate.totalLocal, { + currencyCode: estimate.currencyCode, + }); + }; + /** * Retrieves the entries of the sale estimate. * @param {ISaleEstimate} estimate diff --git a/packages/server/src/services/Sales/Estimates/SaleEstimatesPdf.ts b/packages/server/src/services/Sales/Estimates/SaleEstimatesPdf.ts index 906da6de6..65b965388 100644 --- a/packages/server/src/services/Sales/Estimates/SaleEstimatesPdf.ts +++ b/packages/server/src/services/Sales/Estimates/SaleEstimatesPdf.ts @@ -18,9 +18,6 @@ export class SaleEstimatesPdf { @Inject() private chromiumlyTenancy: ChromiumlyTenancy; - @Inject() - private templateInjectable: TemplateInjectable; - @Inject() private getSaleEstimate: GetSaleEstimate; @@ -62,6 +59,7 @@ export class SaleEstimatesPdf { // Retireves the sale estimate html. const htmlContent = await this.saleEstimateHtml(tenantId, saleEstimateId); + // Converts the html content to pdf. const content = await this.chromiumlyTenancy.convertHtmlContent( tenantId, htmlContent diff --git a/packages/server/src/services/Sales/Invoices/GetInvoicePaymentMailAttributesTransformer.ts b/packages/server/src/services/Sales/Invoices/GetInvoicePaymentMailAttributesTransformer.ts index 1ac116064..749295371 100644 --- a/packages/server/src/services/Sales/Invoices/GetInvoicePaymentMailAttributesTransformer.ts +++ b/packages/server/src/services/Sales/Invoices/GetInvoicePaymentMailAttributesTransformer.ts @@ -23,6 +23,15 @@ export class GetInvoiceMailTemplateAttributesTransformer extends Transformer { 'invoiceNumber', 'invoiceNumberLabel', + 'subtotal', + 'subtotalLabel', + + 'discount', + 'discountLabel', + + 'adjustment', + 'adjustmentLabel', + 'total', 'totalLabel', @@ -76,6 +85,30 @@ export class GetInvoiceMailTemplateAttributesTransformer extends Transformer { return 'Invoice # {invoiceNumber}'; } + public subtotal(): string { + return this.options.invoice?.subtotalFormatted; + } + + public subtotalLabel(): string { + return 'Subtotal'; + } + + public discount(): string { + return this.options.invoice?.discountAmountFormatted; + } + + public discountLabel(): string { + return 'Discount'; + } + + public adjustment(): string { + return this.options.invoice?.adjustmentFormatted; + } + + public adjustmentLabel(): string { + return 'Adjustment'; + } + public total(): string { return this.options.invoice?.totalFormatted; } diff --git a/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailTemplateAttributesTransformer.ts b/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailTemplateAttributesTransformer.ts index 838a94aba..43a212425 100644 --- a/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailTemplateAttributesTransformer.ts +++ b/packages/server/src/services/Sales/Receipts/GetSaleReceiptMailTemplateAttributesTransformer.ts @@ -20,6 +20,12 @@ export class GetSaleReceiptMailTemplateAttributesTransformer extends Transformer 'total', 'totalLabel', + 'discount', + 'discountLabel', + + 'adjustment', + 'adjustmentLabel', + 'subtotal', 'subtotalLabel', @@ -98,7 +104,7 @@ export class GetSaleReceiptMailTemplateAttributesTransformer extends Transformer * Receipt total. */ public total(): string { - return this.options.receipt.formattedAmount; + return this.options.receipt.totalFormatted; } /** @@ -109,12 +115,44 @@ export class GetSaleReceiptMailTemplateAttributesTransformer extends Transformer return 'Total'; } + /** + * Receipt discount. + * @returns {string} + */ + public discount(): string { + return this.options.receipt?.discountAmountFormatted; + } + + /** + * Receipt discount label. + * @returns {string} + */ + public discountLabel(): string { + return 'Discount'; + } + + /** + * Receipt adjustment. + * @returns {string} + */ + public adjustment(): string { + return this.options.receipt?.adjustmentFormatted; + } + + /** + * Receipt adjustment label. + * @returns {string} + */ + public adjustmentLabel(): string { + return 'Adjustment'; + } + /** * Receipt subtotal. * @returns {string} */ public subtotal(): string { - return this.options.receipt.formattedSubtotal; + return this.options.receipt.subtotalFormatted; } /** diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bca408cb5..81fb022c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -882,6 +882,12 @@ importers: '@react-email/components': specifier: 0.0.25 version: 0.0.25(react-dom@18.3.1)(react@18.3.1) + '@types/lodash.isempty': + specifier: ^4.4.9 + version: 4.4.9 + lodash.isempty: + specifier: ^4.4.0 + version: 4.4.0 react: specifier: 18.3.1 version: 18.3.1 @@ -2504,7 +2510,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.24.5 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.26.0) dev: true @@ -11420,6 +11426,12 @@ packages: - tedious dev: false + /@types/lodash.isempty@4.4.9: + resolution: {integrity: sha512-DPSFfnT2JmZiAWNWOU8IRZws/Ha6zyGF5m06TydfsY+0dVoQqby2J61Na2QU4YtwiZ+moC6cJS6zWYBJq4wBVw==} + dependencies: + '@types/lodash': 4.17.13 + dev: false + /@types/lodash@4.17.13: resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==} dev: false @@ -15958,7 +15970,7 @@ packages: postcss-modules-values: 4.0.0(postcss@8.4.47) postcss-value-parser: 4.2.0 semver: 7.6.2 - webpack: 5.91.0(esbuild@0.23.1) + webpack: 5.91.0(esbuild@0.18.20)(webpack-cli@5.1.4) /css-minimizer-webpack-plugin@3.4.1(esbuild@0.23.1)(webpack@5.91.0): resolution: {integrity: sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==} @@ -31178,7 +31190,7 @@ packages: peerDependencies: webpack: ^5.0.0 dependencies: - webpack: 5.91.0(esbuild@0.23.1) + webpack: 5.91.0(esbuild@0.18.20)(webpack-cli@5.1.4) /styled-components@5.3.11(@babel/core@7.26.0)(react-dom@18.3.1)(react-is@18.3.1)(react@18.3.1): resolution: {integrity: sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==} @@ -33492,6 +33504,7 @@ packages: - '@swc/core' - esbuild - uglify-js + dev: false /webpack@5.91.0(esbuild@0.23.1)(webpack-cli@4.10.0): resolution: {integrity: sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==} diff --git a/shared/email-components/package.json b/shared/email-components/package.json index d206dd876..3511d3299 100644 --- a/shared/email-components/package.json +++ b/shared/email-components/package.json @@ -22,11 +22,13 @@ }, "dependencies": { "@react-email/components": "0.0.25", + "@types/lodash.isempty": "^4.4.9", + "lodash.isempty": "^4.4.0", + "react": "18.3.1", + "react-dom": "18.3.1", "tailwindcss": "^3.4.14", "vite-plugin-dts": "^4.3.0", - "vitest": "^2.1.3", - "react-dom": "18.3.1", - "react": "18.3.1" + "vitest": "^2.1.3" }, "devDependencies": { "@eslint/js": "^9.13.0", diff --git a/shared/email-components/src/lib/CreditNoteEmailTemplate.stories.tsx b/shared/email-components/src/lib/CreditNoteEmailTemplate.stories.tsx index 04e55d40e..a4dc4a80e 100644 --- a/shared/email-components/src/lib/CreditNoteEmailTemplate.stories.tsx +++ b/shared/email-components/src/lib/CreditNoteEmailTemplate.stories.tsx @@ -30,4 +30,7 @@ If you have any questions, please let us know. Thanks, Bigcapital`, + subtotal: '$1,000.00', + discount: '$1,000.00', + adjustment: '$1,000.00' }; diff --git a/shared/email-components/src/lib/CreditNoteEmailTemplate.tsx b/shared/email-components/src/lib/CreditNoteEmailTemplate.tsx index bc2341f45..bee45a17d 100644 --- a/shared/email-components/src/lib/CreditNoteEmailTemplate.tsx +++ b/shared/email-components/src/lib/CreditNoteEmailTemplate.tsx @@ -7,6 +7,7 @@ import { Section, Text, } from '@react-email/components'; +import isEmpty from 'lodash.isempty'; import { EmailTemplateLayout } from './EmailTemplateLayout'; import { CSSProperties } from 'react'; import { EmailTemplate } from './EmailTemplate'; @@ -25,6 +26,18 @@ export interface CreditNoteEmailProps { total: string; totalLabel?: string; + // # Subtotal + subtotal: string; + subtotalLabel?: string; + + // # Adjustment + adjustment?: string; + adjustmentLabel?: string; + + // # Discount + discount?: string; + discountLabel?: string; + // # Items items: Array<{ label: string; quantity: string; rate: string }>; @@ -56,6 +69,18 @@ export const CreditNoteEmailTemplate: React.FC< total, totalLabel = 'Total', + // # Subtotal + subtotal, + subtotalLabel = 'Subtotal', + + // # Discount + discount, + discountLabel = 'Discount', + + // # Adjustment + adjustment, + adjustmentLabel = 'Adjustment', + // # Credit Note # creditNoteNumberLabel = 'Credit Note # {creditNoteNumber}', creditNoteNumber = 'CN-00001', @@ -70,70 +95,104 @@ export const CreditNoteEmailTemplate: React.FC< // # Items items = [], }) => { - return ( - - -
- {companyLogoUri && } + return ( + + +
+ {companyLogoUri && } -
- - {companyName} - - - {total} - - - - {creditNoteNumberLabel?.replace( - '{creditNoteNumber}', - creditNoteNumber - )} - - -
- - {message} - - -
- {items.map((item, index) => ( - - - {item.label} - - - - - {item.quantity} x {item.rate} - - - - ))} - - - - {totalLabel} - - - - {total} - - -
+
+ + {companyName} + + + {total} + + + + {creditNoteNumberLabel?.replace( + '{creditNoteNumber}', + creditNoteNumber + )} + +
- - - ); - }; + + {message} + + +
+ {items.map((item, index) => ( + + + {item.label} + + + + + {item.quantity} x {item.rate} + + + + ))} + + + + {subtotalLabel} + + + + {subtotal} + + + + {!isEmpty(discount) && ( + + + {discountLabel} + + + + {discount} + + + )} + + {!isEmpty(adjustment) && ( + + + {adjustmentLabel} + + + + {adjustment} + + + )} + + + + {totalLabel} + + + + {total} + + +
+
+
+
+ ); +}; /** * Renders the estimate mail template to string diff --git a/shared/email-components/src/lib/EstimatePaymentEmail.stories.tsx b/shared/email-components/src/lib/EstimatePaymentEmail.stories.tsx index 634783ae8..07c03f5fe 100644 --- a/shared/email-components/src/lib/EstimatePaymentEmail.stories.tsx +++ b/shared/email-components/src/lib/EstimatePaymentEmail.stories.tsx @@ -30,4 +30,7 @@ If you have any questions, please let us know. Thanks, Bigcapital`, + adjustment: '$100.00', + discount: '$100.00', + subtotal: '$100.00', }; diff --git a/shared/email-components/src/lib/EstimatePaymentEmail.tsx b/shared/email-components/src/lib/EstimatePaymentEmail.tsx index 61b69686a..562019bc3 100644 --- a/shared/email-components/src/lib/EstimatePaymentEmail.tsx +++ b/shared/email-components/src/lib/EstimatePaymentEmail.tsx @@ -1,8 +1,8 @@ import { CSSProperties } from 'react'; +import isEmpty from 'lodash.isempty'; import { Button, Column, - Container, Heading, render, Row, @@ -30,7 +30,15 @@ export interface EstimatePaymentEmailProps { subtotal: string; subtotalLabel?: string; - // # Estimate No# + // # Adjustment + adjustment?: string; + adjustmentLabel?: string; + + // # Discount + discount?: string; + discountLabel?: string; + + // # Estimate No. estimateNumber?: string; estimateNumberLabel?: string; @@ -65,6 +73,14 @@ export const EstimatePaymentEmail: React.FC< total, totalLabel = 'Total', + // # Adjustment + adjustment, + adjustmentLabel = 'Adjustment', + + // # Discount + discount, + discountLabel = 'Discount', + // # Subtotal subtotal, subtotalLabel = 'Subtotal', @@ -87,84 +103,108 @@ export const EstimatePaymentEmail: React.FC< // # Items items = [], }) => { - return ( - - - {companyLogoUri && } + return ( + + + {companyLogoUri && } -
- - {companyName} +
+ + {companyName} + + + {total} + + + + {estimateNumberLabel?.replace('{estimateNumber}', estimateNumber)} + + + + + {expirationDateLabel.replace('{expirationDate}', expirationDate)} + + +
+ + {message} + + +
+ {items.map((item, index) => ( + + + {item.label} + + + + + {item.quantity} x {item.rate} + + - - {total} - - - - {estimateNumberLabel?.replace('{estimateNumber}', estimateNumber)} - - - - - {expirationDateLabel.replace('{expirationDate}', expirationDate)} - - -
+ ))} - {message} - + + + {subtotalLabel} + -
- {items.map((item, index) => ( - - - {item.label} - - - - - {item.quantity} x {item.rate} - - - - ))} + + {subtotal} + + + {!isEmpty(discount) && ( - {subtotalLabel} + {discountLabel} - {subtotal} + {discount} + )} + {!isEmpty(adjustment) && ( - {totalLabel} + {adjustmentLabel} - {total} + {adjustment} -
- - - ); - }; + )} + + + + {totalLabel} + + + + {total} + + +
+
+
+ ); +}; /** * Renders the estimate mail template to string - * @param {EstimatePaymentEmailProps} props + * @param {EstimatePaymentEmailProps} props * @returns {Promise} */ export const renderEstimateEmailTemplate = ( diff --git a/shared/email-components/src/lib/InvoicePaymentEmail.stories.tsx b/shared/email-components/src/lib/InvoicePaymentEmail.stories.tsx index 280e3b452..7edd51120 100644 --- a/shared/email-components/src/lib/InvoicePaymentEmail.stories.tsx +++ b/shared/email-components/src/lib/InvoicePaymentEmail.stories.tsx @@ -33,6 +33,9 @@ Thanks, Bigcapital`, dueDate: ' 10 Oct 2024', total: '$1,000.00', + subtotal: '$1,000.00', dueAmount: '$1,000.00', items: [{ label: 'Swaniawski Muller', quantity: '1', rate: '$1,000.00' }], + adjustment: '$100.00', + discount: '$100.00', }; diff --git a/shared/email-components/src/lib/InvoicePaymentEmail.tsx b/shared/email-components/src/lib/InvoicePaymentEmail.tsx index 3c263ef9a..34fcd309b 100644 --- a/shared/email-components/src/lib/InvoicePaymentEmail.tsx +++ b/shared/email-components/src/lib/InvoicePaymentEmail.tsx @@ -1,6 +1,6 @@ +import { CSSProperties } from 'react'; import { Button, - Container, Section, Heading, Text, @@ -8,7 +8,7 @@ import { Column, render, } from '@react-email/components'; -import { CSSProperties } from 'react'; +import isEmpty from 'lodash.isempty'; import { EmailTemplateLayout } from './EmailTemplateLayout'; import { EmailTemplate } from './EmailTemplate'; @@ -36,6 +36,18 @@ export interface InvoicePaymentEmailProps { dueAmount: string; dueAmountLabel?: string; + // # Adjustment + adjustment?: string; + adjustmentLabel?: string; + + // # Discount + discount?: string; + discountLabel?: string; + + // # Subtotal + subtotal: string; + subtotalLabel?: string; + // # Due date dueDate: string; dueDateLabel?: string; @@ -82,6 +94,18 @@ export const InvoicePaymentEmail: React.FC< total, totalLabel = 'Total', + // # Subtotal + subtotal, + subtotalLabel = 'Subtotal', + + // # Discount + discount, + discountLabel = 'Discount', + + // # Adjustment + adjustment, + adjustmentLabel = 'Adjustment', + // # Invoice due amount dueAmountLabel = 'Due Amount', dueAmount, @@ -92,84 +116,118 @@ export const InvoicePaymentEmail: React.FC< items, }) => { - return ( - - -
- {companyLogoUri && } + return ( + + +
+ {companyLogoUri && } -
- - {companyName} - - - {invoiceAmount} - - - - {invoiceNumberLabel?.replace('{invoiceNumber}', invoiceNumber)} - - - - - {dueDateLabel.replace('{dueDate}', dueDate)} - - -
+
+ + {companyName} + + + {invoiceAmount} + + + + {invoiceNumberLabel?.replace('{invoiceNumber}', invoiceNumber)} + + + + + {dueDateLabel.replace('{dueDate}', dueDate)} + + +
- {invoiceMessage} - + {invoiceMessage} + -
- {items.map((item, index) => ( - - - {item.label} - - - - - {item.quantity} x {item.rate} - - - - ))} - - +
+ {items.map((item, index) => ( + - - {dueAmountLabel} + {item.label} + + + + + {item.quantity} x {item.rate} + + ))} + + + + {subtotalLabel} + + + + {subtotal} + + + + {!isEmpty(discount) && ( + + + {discountLabel} + - {dueAmount} + {discount} + )} - + {!isEmpty(adjustment) && ( + - {totalLabel} + {adjustmentLabel} - {total} + {adjustment} -
+ )} + + + + {totalLabel} + + + + {total} + + + + + + + {dueAmountLabel} + + + + + {dueAmount} + +
- - - ); - }; +
+
+
+ ); +}; export const renderInvoicePaymentEmail = (props: InvoicePaymentEmailProps) => { return render(); @@ -237,6 +295,11 @@ const dueAmounLineRowStyle: CSSProperties = { height: 40, }; +const lineRowStyle: CSSProperties = { + borderBottom: '1px solid #D9D9D9', + height: 40, +}; + const totalLineRowStyle: CSSProperties = { borderBottom: '1px solid #000', height: 40, diff --git a/shared/email-components/src/lib/ReceiptPaymentEmail.stories.tsx b/shared/email-components/src/lib/ReceiptPaymentEmail.stories.tsx index b68d4ab3b..6753b6f0f 100644 --- a/shared/email-components/src/lib/ReceiptPaymentEmail.stories.tsx +++ b/shared/email-components/src/lib/ReceiptPaymentEmail.stories.tsx @@ -28,4 +28,6 @@ If you have any questions, please let us know. Thanks, Bigcapital`, + adjustment: '$100.00', + discount: '$100.00', }; diff --git a/shared/email-components/src/lib/ReceiptPaymentEmail.tsx b/shared/email-components/src/lib/ReceiptPaymentEmail.tsx index bb92d1d0b..f1771f8f5 100644 --- a/shared/email-components/src/lib/ReceiptPaymentEmail.tsx +++ b/shared/email-components/src/lib/ReceiptPaymentEmail.tsx @@ -1,5 +1,5 @@ +import { CSSProperties } from 'react'; import { - Button, Column, Heading, render, @@ -7,14 +7,12 @@ import { Section, Text, } from '@react-email/components'; -import { CSSProperties } from 'react'; +import isEmpty from 'lodash.isempty'; import { EmailTemplateLayout } from './EmailTemplateLayout'; import { EmailTemplate } from './EmailTemplate'; - export interface ReceiptEmailTemplateProps { preview: string; - companyName?: string; companyLogoUri: string; @@ -36,6 +34,10 @@ export interface ReceiptEmailTemplateProps { discount?: string; discountLabel?: string; + // # Adjustment + adjustment?: string; + adjustmentLabel?: string; + // # Subtotal subtotal?: string; subtotalLabel?: string; @@ -60,6 +62,14 @@ export const ReceiptEmailTemplate: React.FC< total = '$1,000.00', totalLabel = 'Total', + // # Diso + discountLabel = 'Discount', + discount, + + // # ADjustment + adjustmentLabel = 'Adjustment', + adjustment, + // # Subtotal subtotal = '$1,000.00', subtotalLabel = 'Subtotal', @@ -74,68 +84,92 @@ export const ReceiptEmailTemplate: React.FC< // # Items items = [{ label: 'Swaniawski Muller', quantity: '1', rate: '$1,000.00' }], }) => { - return ( - - - {companyLogoUri && } + return ( + + + {companyLogoUri && } -
- - {companyName} - +
+ + {companyName} + - - {total} - + + {total} + - - - {receiptNumberLabel?.replace('{receiptNumber}', receiptNumber)} - - -
+ + + {receiptNumberLabel?.replace('{receiptNumber}', receiptNumber)} + + +
- {message} + {message} -
- {items.map((item, index) => ( - - - {item.label} - - - - - {item.quantity} x {item.rate} - - - - ))} - - +
+ {items.map((item, index) => ( + - {subtotalLabel} + {item.label} - {subtotal} + + {item.quantity} x {item.rate} + - - + ))} + + + + {subtotalLabel} + + + + {subtotal} + + + + {!isEmpty(discount) && ( + - {totalLabel} + {discountLabel} - {total} + {discount} -
- - - ); - }; + )} + + {!isEmpty(adjustment) && ( + + + {adjustmentLabel} + + + + {adjustment} + + + )} + + + + {totalLabel} + + + + {total} + + +
+
+
+ ); +}; /** * Renders the sale receipt mail template to string