From 2594e37dc7eea57a08c9b378e68060e9772f1f41 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Mon, 25 Nov 2024 16:22:40 +0200 Subject: [PATCH] feat: wip mail receipt preview --- .../views/modules/estimate-regular.pug | 242 ---------------- .../views/modules/invoice-standard.pug | 272 ------------------ .../modules/payment-receive-standard.pug | 192 ------------- .../views/modules/receipt-regular.pug | 231 --------------- ...timateMailTemplateAttributesTransformer.ts | 30 +- .../GetSaleEstimateMailStateTransformer.ts | 4 +- ...entReceivedMailTemplateAttrsTransformer.ts | 59 +++- .../EstimateSendMailPreview.tsx | 16 +- .../SendMailViewReceiptPreview.tsx | 2 +- .../InvoiceCustomize/InvoiceMailReceipt.tsx | 2 +- .../InvoiceMailReceiptPreviewConnected.tsx | 12 +- .../InvoiceSendMailPreview.tsx | 2 +- 12 files changed, 109 insertions(+), 955 deletions(-) delete mode 100644 packages/server/resources/views/modules/estimate-regular.pug delete mode 100644 packages/server/resources/views/modules/invoice-standard.pug delete mode 100644 packages/server/resources/views/modules/payment-receive-standard.pug delete mode 100644 packages/server/resources/views/modules/receipt-regular.pug diff --git a/packages/server/resources/views/modules/estimate-regular.pug b/packages/server/resources/views/modules/estimate-regular.pug deleted file mode 100644 index 975436d0f..000000000 --- a/packages/server/resources/views/modules/estimate-regular.pug +++ /dev/null @@ -1,242 +0,0 @@ -extends ../PaperTemplateLayout.pug - -block head - - var prefix = 'bc' - style. - .#{prefix}-root { - color: #111; - padding: 24px 30px; - font-size: 12px; - position: relative; - box-shadow: inset 0 4px 0px 0 var(--invoice-primary-color); - } - .#{prefix}-header { - box-sizing: border-box; - display: flex; - flex-flow: wrap; - flex: 0 0 auto; - -webkit-box-align: start; - align-items: start; - -webkit-box-pack: start; - justify-content: flex-start; - gap: 10px; - } - .#{prefix}-header-details { - flex: 1; - display: flex; - flex-direction: column; - align-items: stretch; - gap: 20px; - flex: 1 1 0%; - } - .#{prefix}-big-title { - font-size: 30px; - margin: 0; - line-height: 1; - font-weight: 500; - color: #333; - } - .#{prefix}-logo-wrap img { - width: 100%; - height: 100%; - max-width: 260px; - max-height: 100px; - } - .#{prefix}-terms { - display: flex; - flex-direction: column; - gap: 4px; - margin-bottom: 24px; - } - .#{prefix}-terms-item { - display: flex; - flex-direction: row; - gap: 12px; - } - .#{prefix}-terms-item__label { - min-width: 120px; - color: #333; - } - .#{prefix}-terms-item__value { - } - .#{prefix}-addresses{ - box-sizing: border-box; - display: flex; - flex-flow: wrap; - align-items: flex-start; - justify-content: flex-start; - gap: 10px; - margin-bottom: 24px; - } - .#{prefix}-addresses > * { - flex: 1 1; - } - .#{prefix}-address { - } - .#{prefix}-address__item { - } - .#{prefix}-table { - width: 100%; - border-collapse: collapse; - text-align: left; - font-size: inherit; - } - .#{prefix}-table__header { - font-weight: 400; - border-bottom: 1px solid #000; - padding: 2px 10px; - color: #333; - } - .#{prefix}-table__header:first-of-type{ - padding-left: 0; - } - .#{prefix}-table__header:last-of-type{ - padding-right: 0; - } - .#{prefix}-table__header--right { - text-align: right; - } - .#{prefix}-table__header--item{ - width: 50%; - } - .#{prefix}-table__cell { - border-bottom: 1px solid #F6F6F6; - padding: 12px 10px; - } - .#{prefix}-table__cell--right{ - text-align: right; - } - .#{prefix}-table__cell:first-of-type{ - padding-left: 0; - } - .#{prefix}-table__cell:last-of-type { - padding-right: 0; - } - .#{prefix}-table__cell--item .item { - display: flex; - flex-direction: column; - gap: 2px; - } - .#{prefix}-table__cell--item .item .item__description{ - color: #5f6b7c; - } - .#{prefix}-totals { - display: flex; - flex-direction: column; - margin-left: auto; - width: 300px; - margin-bottom: 24px; - } - .#{prefix}-totals__item { - display: flex; - padding: 4px 0; - } - .#{prefix}-totals__item--border-gray { - border-bottom: 1px solid #DADADA; - } - .#{prefix}-totals__item--border-dark { - border-bottom: 1px solid #000; - } - .#{prefix}-totals__item--font-weight-bold { - font-weight: bold; - } - .#{prefix}-totals__item-label { - min-width: 160px; - } - .#{prefix}-totals__item-amount { - flex: 1 1 auto; - text-align: right; - } - .#{prefix}-statement { - margin-bottom: 20px; - } - .#{prefix}-statement__label { - color: #666; - } - .#{prefix}-statement__value { - white-space: pre-line; - } - -block content - div(class=`${prefix}-root`, style=`--invoice-primary-color: ${primaryColor}; --invoice-secondary-color: ${secondaryColor};`) - - //- Header (invluces big title, details and logo) - div(class=`${prefix}-header`) - - //- Header details (includes big title and details ) - div(class=`${prefix}-header-details`) - h1(class=`${prefix}-big-title`) Estimate - - //- Terms List - div(class=`${prefix}-terms`) - if showEstimateNumber - div(class=`${prefix}-terms-item`) - div(class=`${prefix}-terms-item__label`) #{estimateNumberLabel} - div(class=`${prefix}-terms-item__value`) #{estimateNumebr} - - if showEstimateDate - div(class=`${prefix}-terms-item`) - div(class=`${prefix}-terms-item__label`) #{estimateDateLabel} - div(class=`${prefix}-terms-item__value`) #{estimateDate} - - if showExpirationDate - div(class=`${prefix}-terms-item`) - div(class=`${prefix}-terms-item__label`) #{expirationDateLabel} - div(class=`${prefix}-terms-item__value`) #{expirationDate} - - //- Company logo - if showCompanyLogo && companyLogoUri - div(class=`${prefix}-logo-wrap`) - img(alt="Company logo", src=companyLogoUri) - - //- Addresses (Group section) - div(class=`${prefix}-addresses`) - if showCompanyAddress - div(class=`${prefix}-address-from`) - div !{companyAddress} - - if showCustomerAddress - div(class=`${prefix}-address-to`) - strong #{billedToLabel} - div !{customerAddress} - - //- Table section (Line items) - table(class=`${prefix}-table`) - thead - tr - th(class=`${prefix}-table__header ${prefix}-table__header--item`) Item - th(class=`${prefix}-table__header ${prefix}-table__header--quantity ${prefix}-table__header--right`) Qty - th(class=`${prefix}-table__header ${prefix}-table__header--rate ${prefix}-table__header--right`) Rate - th(class=`${prefix}-table__header ${prefix}-table__header--total ${prefix}-table__header--right`) Total - tbody - each line in lines - tr - td(class=`${prefix}-table__cell ${prefix}-table__cell--item`) - div.item - div.item__label #{line.item} - div.item__description #{line.description} - td(class=`${prefix}-table__cell ${prefix}-table__cell--quantity ${prefix}-table__cell--right`) #{line.quantity} - td(class=`${prefix}-table__cell ${prefix}-table__cell--rate ${prefix}-table__cell--right`) #{line.rate} - td(class=`${prefix}-table__cell ${prefix}-table__cell--total ${prefix}-table__cell--right`) #{line.total} - - //- Totals section - div(class=`${prefix}-totals`) - if showSubtotal - div(class=`${prefix}-totals__item ${prefix}-totals__item--border-gray`) - div(class=`${prefix}-totals__item-label`) #{subtotalLabel} - div(class=`${prefix}-totals__item-amount`) #{subtotal} - if showTotal - div(class=`${prefix}-totals__item ${prefix}-totals__item--border-dark ${prefix}-totals__item--font-weight-bold`) - div(class=`${prefix}-totals__item-label`) #{totalLabel} - div(class=`${prefix}-totals__item-amount`) #{total} - - //- Statements section - if showTermsConditions && termsConditions - div(class=`${prefix}-statement`) - div(class=`${prefix}-statement__label`) #{termsConditionsLabel} - div(class=`${prefix}-statement__value`) #{termsConditions} - - if showCustomerNote && customerNote - div(class=`${prefix}-statement`) - div(class=`${prefix}-statement__label`) #{customerNoteLabel} - div(class=`${prefix}-statement__value`) #{customerNote} diff --git a/packages/server/resources/views/modules/invoice-standard.pug b/packages/server/resources/views/modules/invoice-standard.pug deleted file mode 100644 index 0435d901a..000000000 --- a/packages/server/resources/views/modules/invoice-standard.pug +++ /dev/null @@ -1,272 +0,0 @@ -extends ../PaperTemplateLayout.pug - -block head - - var prefix = 'bc' - style. - .#{prefix}-root { - color: #111; - padding: 24px 30px; - font-size: 12px; - position: relative; - box-shadow: inset 0 4px 0px 0 var(--invoice-primary-color); - } - .#{prefix}-header{ - box-sizing: border-box; - display: flex; - flex-flow: wrap; - flex: 0 0 auto; - -webkit-box-align: start; - align-items: start; - -webkit-box-pack: start; - justify-content: flex-start; - gap: 10px; - } - .#{prefix}-header-details{ - flex: 1; - display: flex; - flex-direction: column; - align-items: stretch; - gap: 20px; - flex: 1 1 0%; - } - .#{prefix}-big-title { - font-size: 30px; - margin: 0; - line-height: 1; - font-weight: 500; - color: #333; - } - .#{prefix}-logo-wrap img { - width: 100%; - height: 100%; - max-width: 260px; - max-height: 100px; - } - .#{prefix}-details { - display: flex; - flex-direction: column; - gap: 4px; - margin-bottom: 24px; - } - .#{prefix}-detail { - display: flex; - flex-direction: row; - gap: 12px; - } - .#{prefix}-detail__label { - min-width: 120px; - color: #333; - } - .#{prefix}-detail__value { - /* Styles for detail values */ - } - .#{prefix}-address-root { - box-sizing: border-box; - display: flex; - flex-flow: wrap; - align-items: flex-start; - justify-content: flex-start; - gap: 10px; - margin-bottom: 24px; - } - .#{prefix}-address-from { - flex: 1; - } - .#{prefix}-address-from__item { - /* Styles for items in the billed-from address */ - } - .#{prefix}-address-to { - flex: 1; - } - .#{prefix}-address-to__item { - /* Styles for items in the billed-to address */ - } - .#{prefix}-table { - width: 100%; - border-collapse: collapse; - text-align: left; - font-size: inherit; - } - .#{prefix}-table__header { - font-weight: 400; - border-bottom: 1px solid #000; - padding: 2px 10px; - color: #333; - } - .#{prefix}-table__header:first-of-type{ - padding-left: 0; - } - .#{prefix}-table__header:last-of-type{ - padding-right: 0; - } - .#{prefix}-table__header--right { - text-align: right; - } - .#{prefix}-table__header--item { - width: 50%; - } - .#{prefix}-table__cell { - border-bottom: 1px solid #F6F6F6; - padding: 12px 10px; - } - .#{prefix}-table__cell:first-of-type{ - padding-left: 0; - } - .#{prefix}-table__cell:last-of-type { - padding-right: 0; - } - .#{prefix}-table__cell--right { - text-align: right; - } - .#{prefix}-table__cell--item .item { - display: flex; - flex-direction: column; - gap: 2px; - } - .#{prefix}-table__cell--item .item__description { - color: #5f6b7c; - } - .#{prefix}-totals { - display: flex; - flex-direction: column; - margin-left: auto; - width: 300px; - margin-bottom: 24px; - } - .#{prefix}-totals__item { - display: flex; - padding: 4px 0; - } - .#{prefix}-totals__item--border-gray { - border-bottom: 1px solid #DADADA; - } - .#{prefix}-totals__item--border-dark { - border-bottom: 1px solid #000; - } - .#{prefix}-totals__item--font-weight-bold { - font-weight: bold; - } - .#{prefix}-totals__item-label { - min-width: 160px; - } - .#{prefix}-totals__item-amount { - flex: 1 1 auto; - text-align: right; - } - .#{prefix}-paragraph { - margin-bottom: 20px; - } - .#{prefix}-paragraph__label { - color: #666; - } - .#{prefix}-paragraph__value { - white-space: pre-line; - } -block content - //- block head - div(class=`${prefix}-root`, style=`--invoice-primary-color: ${primaryColor}; --invoice-secondary-color: ${secondaryColor};`) - - //- Header (includes big title, details and logo ) - div(class=`${prefix}-header`) - //- Header details (includes big title and details ) - div(class=`${prefix}-header-details`) - //- Title and company logo - h1(class=`${prefix}-big-title`) Invoice - - //- Invoice details - div(class=`${prefix}-details`) - if showInvoiceNumber - div(class=`${prefix}-detail`) - div(class=`${prefix}-detail__label`) #{invoiceNumberLabel} - div(class=`${prefix}-detail__value`) #{invoiceNumber} - - if showDateIssue - div(class=`${prefix}-detail`) - div(class=`${prefix}-detail__label`) #{dateIssueLabel} - div(class=`${prefix}-detail__value`) #{dateIssue} - - if showDueDate - div(class=`${prefix}-detail`) - div(class=`${prefix}-detail__label`) #{dueDateLabel} - div(class=`${prefix}-detail__value`) #{dueDate} - - //- Company logo - if showCompanyLogo && companyLogoUri - div(class=`${prefix}-logo-wrap`) - img(alt="Company logo", src=companyLogoUri) - - //- Address section - div(class=`${prefix}-address-root`) - if showCompanyAddress - div(class=`${prefix}-address-from`) - div !{companyAddress} - - if showCustomerAddress - div(class=`${prefix}-address-to`) - strong #{billedToLabel} - div !{customerAddress} - - //- Invoice table - table(class=`${prefix}-table`) - thead - tr - th(class=`${prefix}-table__header ${prefix}-table__header--item`) #{lineItemLabel} - th(class=`${prefix}-table__header ${prefix}-table__header--quantity ${prefix}-table__header--right`) #{lineQuantityLabel} - th(class=`${prefix}-table__header ${prefix}-table__header--rate ${prefix}-table__header--right`) #{lineRateLabel} - th(class=`${prefix}-table__header ${prefix}-table__header--total ${prefix}-table__header--right`) #{lineTotalLabel} - tbody - each line in lines - tr - td(class=`${prefix}-table__cell ${prefix}-table__cell--item`) - div.item - div.item__label #{line.item} - div.item__description #{line.description} - td(class=`${prefix}-table__cell ${prefix}-table__cell--right`) #{line.quantity} - td(class=`${prefix}-table__cell ${prefix}-table__cell--right`) #{line.rate} - td(class=`${prefix}-table__cell ${prefix}-table__cell--right`) #{line.total} - - //- Totals section - div(class=`${prefix}-totals`) - if showSubtotal - div(class=`${prefix}-totals__item ${prefix}-totals__item--border-gray`) - div(class=`${prefix}-totals__item-label`) #{subtotalLabel} - div(class=`${prefix}-totals__item-amount`) #{subtotal} - - if showDiscount - div(class=`${prefix}-totals__item`) - div(class=`${prefix}-totals__item-label`) #{discountLabel} - div(class=`${prefix}-totals__item-amount`) #{discount} - - if showTaxes - each tax in taxes - div(class=`${prefix}-totals__item`) - div(class=`${prefix}-totals__item-label`) #{tax.label} - div(class=`${prefix}-totals__item-amount`) #{tax.amount} - - if showTotal - div(class=`${prefix}-totals__item ${prefix}-totals__item--border-dark ${prefix}-totals__item--font-weight-bold`) - div(class=`${prefix}-totals__item-label`) #{totalLabel} - div(class=`${prefix}-totals__item-amount`) #{total} - - if showPaymentMade - div(class=`${prefix}-totals__item`) - div(class=`${prefix}-totals__item-label`) #{paymentMadeLabel} - div(class=`${prefix}-totals__item-amount`) #{paymentMade} - - if showBalanceDue - div(class=`${prefix}-totals__item ${prefix}-totals__item--border-dark ${prefix}-totals__item--font-weight-bold`) - div(class=`${prefix}-totals__item-label`) #{balanceDueLabel} - div(class=`${prefix}-totals__item-amount`) #{balanceDue} - - //- Footer section - if showTermsConditions && termsConditions - div(class=`${prefix}-paragraph`) - if termsConditionsLabel - div(class=`${prefix}-paragraph__label`) #{termsConditionsLabel} - div(class=`${prefix}-paragraph__value`) #{termsConditions} - - if showStatement && statement - div(class=`${prefix}-paragraph`) - if statementLabel - div(class=`${prefix}-paragraph__label`) #{statementLabel} - div(class=`${prefix}-paragraph__value`) #{statement} diff --git a/packages/server/resources/views/modules/payment-receive-standard.pug b/packages/server/resources/views/modules/payment-receive-standard.pug deleted file mode 100644 index cf981ec4d..000000000 --- a/packages/server/resources/views/modules/payment-receive-standard.pug +++ /dev/null @@ -1,192 +0,0 @@ -extends ../PaperTemplateLayout.pug - -block head - - var prefix = 'bp3'; - - style. - .#{prefix}-root{ - color: #111; - padding: 24px 30px; - font-size: 12px; - position: relative; - box-shadow: inset 0 4px 0px 0 var(--invoice-primary-color); - } - .#{prefix}-header{ - box-sizing: border-box; - display: flex; - flex-flow: wrap; - flex: 0 0 auto; - -webkit-box-align: start; - align-items: start; - -webkit-box-pack: start; - justify-content: flex-start; - gap: 10px; - } - .#{prefix}-header-details{ - flex: 1; - display: flex; - flex-direction: column; - align-items: stretch; - gap: 20px; - flex: 1 1 0%; - } - .#{prefix}-big-title{ - font-size: 30px; - margin: 0; - line-height: 1; - font-weight: 500; - color: #333; - } - .#{prefix}-logo-wrap img { - width: 100%; - height: 100%; - max-width: 260px; - max-height: 100px; - } - .#{prefix}-terms-list{ - display: flex; - flex-direction: column; - gap: 4px; - margin-bottom: 24px; - } - .#{prefix}-terms-item{ - display: flex; - flex-direction: row; - gap: 12px; - } - .#{prefix}-terms-item__label{ - min-width: 120px; - color: #333; - } - .#{prefix}-addresses{ - box-sizing: border-box; - display: flex; - flex-flow: wrap; - align-items: flex-start; - justify-content: flex-start; - gap: 10px; - margin-bottom: 24px; - } - .#{prefix}-addresses > * { - flex: 1 1; - } - .#{prefix}-address__label{ - - } - .#{prefix}-table { - width: 100%; - border-collapse: collapse; - text-align: left; - font-size: inherit; - } - .#{prefix}-table__header { - font-weight: 400; - border-bottom: 1px solid #000; - padding: 2px 10px; - color: #333; - } - .#{prefix}-table__header:first-of-type{ - padding-left: 0; - } - .#{prefix}-table__header:last-of-type{ - padding-right: 0; - } - .#{prefix}-table__header--right { - text-align: right; - } - .#{prefix}-table__cell { - border-bottom: 1px solid #F6F6F6; - padding: 12px 10px; - } - .#{prefix}-table__cell:first-of-type{ - padding-left: 0; - } - .#{prefix}-table__cell:last-of-type { - padding-right: 0; - } - .#{prefix}-table__cell--right { - text-align: right; - } - .#{prefix}-totals { - display: flex; - flex-direction: column; - margin-left: auto; - width: 300px; - margin-bottom: 24px; - } - .#{prefix}-totals__item { - display: flex; - padding: 4px 0; - } - .#{prefix}-totals__item--gray-border { - border-bottom: 1px solid #DADADA; - } - .#{prefix}-totals__item--dark-border { - border-bottom: 1px solid #000; - } - .#{prefix}-totals__item--bold { - font-weight: bold; - } - .#{prefix}-totals__item-label { - min-width: 160px; - } - .#{prefix}-totals__item-amount { - flex: 1 1 auto; - text-align: right; - } -block content - div(class=`${prefix}-root`) - //- Header (includes big title, details and logo ) - div(class=`${prefix}-header`) - //- Header details (includes big title and details ) - div(class=`${prefix}-header-details`) - div(class=`${prefix}-big-title`) Payment - div(class=`${prefix}-terms-list`) - if showPaymentReceivedNumber - div(class=`${prefix}-terms-item`) - div(class=`${prefix}-terms-item__label`) #{paymentReceivedNumberLabel} - div(class=`${prefix}-terms-item__value`) #{paymentReceivedNumebr} - - if showPaymentReceivedDate - div(class=`${prefix}-terms-item`) - div(class=`${prefix}-terms-item__label`) #{paymentReceivedDateLabel} - div(class=`${prefix}-terms-item__value`) #{paymentReceivedDate} - - if showCompanyLogo && companyLogoUri - div(class=`${prefix}-logo-wrap`) - img(src=companyLogoUri alt="Company Logo") - - div(class=`${prefix}-addresses`) - if showCompanyAddress - div(class=`${prefix}-address-from`) - div !{companyAddress} - - if showCustomerAddress - div(class=`${prefix}-address-to`) - strong #{billedToLabel} - div !{customerAddress} - - table(class=`${prefix}-table`) - thead - tr - th(class=`${prefix}-table__header`) Invoice # - th(class=`${prefix}-table__header ${prefix}-table__header--right`) Invoice Amount - th(class=`${prefix}-table__header ${prefix}-table__header--right`) Paid Amount - - tbody - each line in lines - tr - td(class=`${prefix}-table__cell`) #{line.invoiceNumber} - td(class=`${prefix}-table__cell ${prefix}-table__cell--right`) #{line.invoiceAmount} - td(class=`${prefix}-table__cell ${prefix}-table__cell--right`) #{line.paidAmount} - - div(class=`${prefix}-totals`) - if showSubtotal - div(class=`${prefix}-totals__item ${prefix}-totals__item--gray-border`) - div(class=`${prefix}-totals__item-label`) #{subtotalLabel} - div(class=`${prefix}-totals__item-amount`) #{subtotal} - - if showTotal - div(class=`${prefix}-totals__item ${prefix}-totals__item--dark-border`) - div(class=`${prefix}-totals__item-label`) #{totalLabel} - div(class=`${prefix}-totals__item-amount`) #{total} diff --git a/packages/server/resources/views/modules/receipt-regular.pug b/packages/server/resources/views/modules/receipt-regular.pug deleted file mode 100644 index dfce3b5b5..000000000 --- a/packages/server/resources/views/modules/receipt-regular.pug +++ /dev/null @@ -1,231 +0,0 @@ -extends ../PaperTemplateLayout.pug - -block head - - var prefix = 'bc' - style. - .#{prefix}-root { - color: #000; - padding: 24px 30px; - font-size: 12px; - position: relative; - box-shadow: inset 0 4px 0px 0 var(--invoice-primary-color); - } - .#{prefix}-header{ - box-sizing: border-box; - display: flex; - flex-flow: wrap; - flex: 0 0 auto; - align-items: start; - justify-content: flex-start; - gap: 10px; - } - .#{prefix}-header-details{ - flex: 1; - display: flex; - flex-direction: column; - align-items: stretch; - gap: 20px; - flex: 1 1 0%; - } - .#{prefix}-logo-wrap img { - width: 100%; - height: 100%; - max-width: 260px; - max-height: 100px; - } - .#{prefix}-big-title { - font-size: 30px; - margin: 0; - line-height: 1; - font-weight: 500; - color: #333; - } - .#{prefix}-terms-list { - display: flex; - flex-direction: column; - gap: 4px; - margin-bottom: 24px; - } - .#{prefix}-terms-item { - display: flex; - flex-direction: row; - gap: 12px; - } - .#{prefix}-terms-item__label { - min-width: 120px; - color: #333; - } - .#{prefix}-terms-item__value {} - .#{prefix}-address-section { - box-sizing: border-box; - display: flex; - flex-flow: wrap; - -webkit-box-align: flex-start; - align-items: flex-start; - -webkit-box-pack: start; - justify-content: flex-start; - gap: 10px; - margin-bottom: 24px; - } - .#{prefix}-address-section > * { - flex: 1 1 auto; - } - .#{prefix}-address {} - .#{prefix}-table { - width: 100%; - border-collapse: collapse; - text-align: left; - font-size: inherit; - } - .#{prefix}-table__header { - font-weight: 400; - border-bottom: 1px solid #000; - padding: 2px 10px; - color: #333; - } - .#{prefix}-table__header:first-of-type{ - padding-left: 0; - } - .#{prefix}-table__header:last-of-type{ - padding-right: 0; - } - .#{prefix}-table__header--right { - text-align: right; - } - .#{prefix}-table__header--item{ - width: 50%; - } - .#{prefix}-table__cell { - border-bottom: 1px solid #F6F6F6; - padding: 12px 10px; - } - .#{prefix}-table__cell:first-of-type{ - padding-left: 0; - } - .#{prefix}-table__cell:last-of-type { - padding-right: 0; - } - .#{prefix}-table__cell--right { - text-align: right; - } - .#{prefix}-table__cell--item .item { - display: flex; - flex-direction: column; - gap: 2px; - } - .#{prefix}-table__cell--item .item .item__description{ - color: #5f6b7c; - } - .#{prefix}-totals { - display: flex; - flex-direction: column; - margin-left: auto; - width: 300px; - margin-bottom: 24px; - } - .#{prefix}-totals__line { - display: flex; - padding: 4px 0; - } - .#{prefix}-totals__line--gray-border { - border-bottom: 1px solid #DADADA; - } - .#{prefix}-totals__line--dark-border { - border-bottom: 1px solid #000; - } - .#{prefix}-totals__line__label { - min-width: 160px; - } - .#{prefix}-totals__line__amount { - flex: 1 1 auto; - text-align: right; - } - .#{prefix}-statement { - margin-bottom: 20px; - } - .#{prefix}-statement__label {} - .#{prefix}-statement__value { - white-space: pre-line; - } - -block content - //- block head - div(class=`${prefix}-root`, style=`--invoice-primary-color: ${primaryColor}; --invoice-secondary-color: ${secondaryColor};`) - - //- Header (includes big title, details and logo ) - div(class=`${prefix}-header`) - //- Header details (includes big title and details ) - div(class=`${prefix}-header-details`) - //- Title and company logo - h1(class=`${prefix}-big-title`) Receipt - - //- Terms List - div(class=`${prefix}-terms-list`) - if showReceiptNumber - div(class=`${prefix}-terms-item`) - span(class=`${prefix}-terms-item__label`)= receiptNumberLabel - span(class=`${prefix}-terms-item__value`)= receiptNumber - - if showReceiptDate - div(class=`${prefix}-terms-item`) - span(class=`${prefix}-terms-item__label`)= receiptDateLabel - span(class=`${prefix}-terms-item__value`)= receiptDate - - //- Company logo - if showCompanyLogo && companyLogoUri - div(class=`${prefix}-logo-wrap`) - img(src=companyLogoUri alt=`Company Logo`) - - //- Address Section - div(class=`${prefix}-address-section`) - if showCompanyAddress - div(class=`${prefix}-address-from`) - div !{companyAddress} - - if showCustomerAddress - div(class=`${prefix}-address-to`) - strong #{billedToLabel} - div !{customerAddress} - - //- Table Section - table(class=`${prefix}-table`) - thead(class=`${prefix}-table__header`) - tr - th(class=`${prefix}-table__header ${prefix}-table__header--item`) Item - th(class=`${prefix}-table__header ${prefix}-table__header--quantity ${prefix}-table__header--right`) Qty - th(class=`${prefix}-table__header ${prefix}-table__header--rate ${prefix}-table__header--right`) Rate - th(class=`${prefix}-table__header ${prefix}-table__header--total ${prefix}-table__header--right`) Total - tbody - each line in lines - tr(class=`${prefix}-table__row`) - td(class=`${prefix}-table__cell ${prefix}-table__cell--item`) - div.item - div.item__label #{line.item} - div.item__description #{line.description} - td(class=`${prefix}-table__cell ${prefix}-table__cell--right`) #{line.quantity} - td(class=`${prefix}-table__cell ${prefix}-table__cell--right`) #{line.rate} - td(class=`${prefix}-table__cell ${prefix}-table__cell--right`) #{line.total} - - //- Totals Section - div(class=`${prefix}-totals`) - if showSubtotal - div(class=`${prefix}-totals__line ${prefix}-totals__line--gray-border`) - span(class=`${prefix}-totals__line__label`)= subtotalLabel - span(class=`${prefix}-totals__line__amount`)= subtotal - - if showTotal - div(class=`${prefix}-totals__line ${prefix}-totals__line--dark-border`) - span(class=`${prefix}-totals__line__label`)= totalLabel - span(class=`${prefix}-totals__line__amount`)= total - - //- Customer Note Section - if showCustomerNote && customerNote - div(class=`${prefix}-statement`) - div(class=`${prefix}-statement__label`)= customerNoteLabel - div(class=`${prefix}-statement__value`)= customerNote - - //- Terms & Conditions Section - if showTermsConditions && termsConditions - div(class=`${prefix}-statement`) - div(class=`${prefix}-statement__label`)= termsConditionsLabel - div(class=`${prefix}-statement__value`)= termsConditions diff --git a/packages/server/src/services/Sales/Estimates/GetEstimateMailTemplateAttributesTransformer.ts b/packages/server/src/services/Sales/Estimates/GetEstimateMailTemplateAttributesTransformer.ts index a643ee58d..4d8cbfc0f 100644 --- a/packages/server/src/services/Sales/Estimates/GetEstimateMailTemplateAttributesTransformer.ts +++ b/packages/server/src/services/Sales/Estimates/GetEstimateMailTemplateAttributesTransformer.ts @@ -22,6 +22,9 @@ export class GetEstimateMailTemplateAttributesTransformer extends Transformer { 'total', 'totalLabel', + 'subtotal', + 'subtotalLabel', + 'dueAmount', 'dueAmountLabel', @@ -57,7 +60,7 @@ export class GetEstimateMailTemplateAttributesTransformer extends Transformer { } /** - * Primary color + * Primary color. * @returns {string} */ public primaryColor(): string { @@ -69,7 +72,7 @@ export class GetEstimateMailTemplateAttributesTransformer extends Transformer { * @returns {string} */ public estimateNumber(): string { - return this.options.estimate.number; + return this.options.estimate.estimateNumber; } /** @@ -77,7 +80,7 @@ export class GetEstimateMailTemplateAttributesTransformer extends Transformer { * @returns {string} */ public estimateNumberLabel(): string { - return 'Estimate Number'; + return 'Estimate No: {estimateNumber}'; } /** @@ -85,7 +88,7 @@ export class GetEstimateMailTemplateAttributesTransformer extends Transformer { * @returns {string} */ public expirationDate(): string { - return this.options.estimate.expirationDate; + return this.options.estimate.formattedExpirationDate; } /** @@ -93,14 +96,14 @@ export class GetEstimateMailTemplateAttributesTransformer extends Transformer { * @returns {string} */ public expirationDateLabel(): string { - return 'Expiration Date'; + return 'Expiration Date: {expirationDate}'; } /** * Estimate total. */ public total(): string { - return this.options.estimate.totalFormatted; + return this.options.estimate.formattedAmount; } /** @@ -111,6 +114,21 @@ export class GetEstimateMailTemplateAttributesTransformer extends Transformer { return 'Total'; } + /** + * Estimate subtotal. + */ + public subtotal(): string { + return this.options.estimate.formattedAmount; + } + + /** + * Estimate subtotal label. + * @returns {string} + */ + public subtotalLabel(): string { + return 'Subtotal'; + } + /** * Estimate mail items attributes. */ diff --git a/packages/server/src/services/Sales/Estimates/GetSaleEstimateMailStateTransformer.ts b/packages/server/src/services/Sales/Estimates/GetSaleEstimateMailStateTransformer.ts index fbfaf134b..c33783bc5 100644 --- a/packages/server/src/services/Sales/Estimates/GetSaleEstimateMailStateTransformer.ts +++ b/packages/server/src/services/Sales/Estimates/GetSaleEstimateMailStateTransformer.ts @@ -52,7 +52,7 @@ export class GetSaleEstimateMailStateTransformer extends SaleEstimateTransfromer * @returns {string | null} */ protected companyLogoUri = (invoice) => { - return invoice.pdfTemplate?.companyLogoUri; + return invoice.pdfTemplate?.companyLogoUri || null; }; /** @@ -60,7 +60,7 @@ export class GetSaleEstimateMailStateTransformer extends SaleEstimateTransfromer * @returns {string} */ protected primaryColor = (invoice) => { - return invoice.pdfTemplate?.attributes?.primaryColor; + return invoice.pdfTemplate?.attributes?.primaryColor || null; }; /** diff --git a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailTemplateAttrsTransformer.ts b/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailTemplateAttrsTransformer.ts index 94002cbbd..1dfcf8656 100644 --- a/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailTemplateAttrsTransformer.ts +++ b/packages/server/src/services/Sales/PaymentReceived/GetPaymentReceivedMailTemplateAttrsTransformer.ts @@ -1,4 +1,5 @@ import { Transformer } from '@/lib/Transformer/Transformer'; +import { PaymentReceivedEntryTransfromer } from './PaymentReceivedEntryTransformer'; export class GetPaymentReceivedMailTemplateAttrsTransformer extends Transformer { /** @@ -14,6 +15,7 @@ export class GetPaymentReceivedMailTemplateAttrsTransformer extends Transformer 'totalLabel', 'paymentNumberLabel', 'paymentNumber', + 'items', ]; }; @@ -65,9 +67,17 @@ export class GetPaymentReceivedMailTemplateAttrsTransformer extends Transformer return 'Total'; } + /** + * Subtotal. + * @returns {string} + */ + public subtotal(): string { + return this.options.paymentReceived.formattedAmount; + } + /** * Payment number label. - * @returns + * @returns {string} */ public paymentNumberLabel(): string { return 'Payment # {paymentNumber}'; @@ -80,4 +90,51 @@ export class GetPaymentReceivedMailTemplateAttrsTransformer extends Transformer public paymentNumber(): string { return this.options.paymentReceived.paymentReceiveNumber; } + + /** + * Items. + * @returns + */ + public items() { + return this.item( + this.options.paymentReceived.entries, + new GetPaymentReceivedMailTemplateItemAttrsTransformer() + ); + } +} + +class GetPaymentReceivedMailTemplateItemAttrsTransformer extends Transformer { + /** + * Included attributes. + * @returns {Array} + */ + public includeAttributes = () => { + return ['label', 'total']; + }; + + /** + * Excluded attributes. + * @returns {string[]} + */ + public excludeAttributes = () => { + return ['*']; + }; + + /** + * + * @param entry + * @returns + */ + public label(entry) { + return entry.invoice.invoiceNo; + } + + /** + * + * @param entry + * @returns + */ + public total(entry) { + return entry.paymentAmountFormatted; + } } diff --git a/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailPreview.tsx b/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailPreview.tsx index 8f687f9e8..917c8b551 100644 --- a/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailPreview.tsx +++ b/packages/webapp/src/containers/Sales/Estimates/EstimateSendMailDrawer/EstimateSendMailPreview.tsx @@ -1,8 +1,18 @@ +import { lazy } from 'react'; import { Suspense } from 'react'; -import { SendMailViewPreviewTabs } from '../SendMailViewDrawer/SendMailViewPreviewTabs'; import { Tab } from '@blueprintjs/core'; -import { EstimateSendPdfPreviewConnected } from './EstimateSendPdfPreviewConnected'; -import { EstimateSendMailReceiptPreview } from './EstimateSendMailReceiptPreview'; +import { SendMailViewPreviewTabs } from '../SendMailViewDrawer/SendMailViewPreviewTabs'; + +const EstimateSendPdfPreviewConnected = lazy(() => + import('./EstimateSendPdfPreviewConnected').then((module) => ({ + default: module.EstimateSendPdfPreviewConnected, + })), +); +const EstimateSendMailReceiptPreview = lazy(() => + import('./EstimateSendMailReceiptPreview').then((module) => ({ + default: module.EstimateSendMailReceiptPreview, + })), +); export function EstimateSendMailPreviewTabs() { return ( diff --git a/packages/webapp/src/containers/Sales/Estimates/SendMailViewDrawer/SendMailViewReceiptPreview.tsx b/packages/webapp/src/containers/Sales/Estimates/SendMailViewDrawer/SendMailViewReceiptPreview.tsx index 1bc73278d..24c3b9aae 100644 --- a/packages/webapp/src/containers/Sales/Estimates/SendMailViewDrawer/SendMailViewReceiptPreview.tsx +++ b/packages/webapp/src/containers/Sales/Estimates/SendMailViewDrawer/SendMailViewReceiptPreview.tsx @@ -13,7 +13,7 @@ export function SendMailReceipt({ diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailPreview.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailPreview.tsx index 97de7df22..64fba32c6 100644 --- a/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailPreview.tsx +++ b/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailPreview.tsx @@ -1,5 +1,5 @@ import { lazy, Suspense } from 'react'; -import { Tab, } from '@blueprintjs/core'; +import { Tab } from '@blueprintjs/core'; import { SendMailViewPreviewTabs } from '../../Estimates/SendMailViewDrawer/SendMailViewPreviewTabs'; const InvoiceMailReceiptPreviewConnected = lazy(() =>