From 863c7ad99fe4850c7a1d97cd9b670cf649cf8c2a Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Sun, 29 Sep 2024 22:59:14 +0200 Subject: [PATCH] feat: Hook up customer/company address to pdf templates --- .../views/modules/credit-note-standard.pug | 15 ++-- .../views/modules/estimate-regular.pug | 15 ++-- .../views/modules/invoice-standard.pug | 1 + .../modules/payment-receive-standard.pug | 17 ++--- .../views/modules/receipt-regular.pug | 17 ++--- packages/server/src/interfaces/CreditNote.ts | 16 +++- .../server/src/interfaces/PaymentReceive.ts | 11 ++- packages/server/src/interfaces/SaleInvoice.ts | 12 +-- packages/server/src/interfaces/SaleReceipt.ts | 12 +-- .../CreditNotes/CreditNoteBrandingTemplate.ts | 34 +++++++-- .../services/CreditNotes/GetCreditNotePdf.ts | 2 - .../src/services/CreditNotes/constants.ts | 25 ++----- .../server/src/services/CreditNotes/utils.ts | 2 + .../src/services/Sales/Estimates/constants.ts | 14 ++-- .../src/services/Sales/Estimates/utils.ts | 2 + .../Sales/Invoices/SaleEstimatePdfTemplate.ts | 2 +- .../src/services/Sales/Invoices/utils.ts | 3 + .../PaymentReceivedBrandingTemplate.ts | 15 +++- .../Sales/PaymentReceived/constants.ts | 25 ++----- .../services/Sales/PaymentReceived/utils.ts | 2 + .../Receipts/SaleReceiptBrandingTemplate.ts | 16 +++- .../src/services/Sales/Receipts/constants.ts | 26 ++----- .../src/services/Sales/Receipts/utils.ts | 3 +- .../src/system/models/TenantMetadata.ts | 4 +- .../server/src/utils/address-text-format.ts | 74 ++++++++++++++++--- packages/webapp/src/constants/PdfTemplates.ts | 3 +- .../EstimatePaperTemplate.tsx | 14 +++- .../Estimates/EstimateCustomize/constants.ts | 5 +- .../Receipts/ReceiptCustomize/constants.ts | 7 +- 29 files changed, 242 insertions(+), 152 deletions(-) diff --git a/packages/server/resources/views/modules/credit-note-standard.pug b/packages/server/resources/views/modules/credit-note-standard.pug index ae201b305..057e1069b 100644 --- a/packages/server/resources/views/modules/credit-note-standard.pug +++ b/packages/server/resources/views/modules/credit-note-standard.pug @@ -150,17 +150,14 @@ block content div(class=`${prefix}-terms-item__value`) #{creditNoteDate} div(class=`${prefix}-address-section`) - if showBilledFromAddress - div(class=`${prefix}-address`) - strong #{companyName} - each address in billedFromAddress - div #{address} + if showCompanyAddress + div(class=`${prefix}-address-from`) + div !{companyAddress} - if showBilledToAddress - div(class=`${prefix}-address`) + if showCustomerAddress + div(class=`${prefix}-address-to`) strong #{billedToLabel} - each address in billedToAddress - div #{address} + div !{customerAddress} table(class=`${prefix}-table`) thead diff --git a/packages/server/resources/views/modules/estimate-regular.pug b/packages/server/resources/views/modules/estimate-regular.pug index d245990ee..f29c065f3 100644 --- a/packages/server/resources/views/modules/estimate-regular.pug +++ b/packages/server/resources/views/modules/estimate-regular.pug @@ -156,17 +156,14 @@ block content //- Addresses (Group section) div(class=`${prefix}-addresses`) - if showBilledFromAddress - div(class=`${prefix}-address`) - strong #{companyName} - each item in billedFromAddress - div(class=`${prefix}-address__item`) #{item} + if showCompanyAddress + div(class=`${prefix}-address-from`) + div !{companyAddress} - if showBilledToAddress - div(class=`${prefix}-address`) + if showCustomerAddress + div(class=`${prefix}-address-to`) strong #{billedToLabel} - each item in billedToAddress - div(class=`${prefix}-address__item`) #{item} + div !{customerAddress} //- Table section (Line items) table(class=`${prefix}-table`) diff --git a/packages/server/resources/views/modules/invoice-standard.pug b/packages/server/resources/views/modules/invoice-standard.pug index 8915ec55e..098c67bbe 100644 --- a/packages/server/resources/views/modules/invoice-standard.pug +++ b/packages/server/resources/views/modules/invoice-standard.pug @@ -173,6 +173,7 @@ block content if showCustomerAddress div(class=`${prefix}-address-to`) + strong #{billedToLabel} div !{customerAddress} //- Invoice table diff --git a/packages/server/resources/views/modules/payment-receive-standard.pug b/packages/server/resources/views/modules/payment-receive-standard.pug index ec6dae598..c9c16bc72 100644 --- a/packages/server/resources/views/modules/payment-receive-standard.pug +++ b/packages/server/resources/views/modules/payment-receive-standard.pug @@ -140,17 +140,14 @@ block content div(class=`${prefix}-terms-item__value`) #{paymentReceivedDate} div(class=`${prefix}-addresses`) - if showBilledFromAddress - div(class=`${prefix}-address`) - strong(class=`${prefix}-address__item`) #{companyName} - each addressLine in billedFromAddress - div(class=`${prefix}-address__item`) #{addressLine} + if showCompanyAddress + div(class=`${prefix}-address-from`) + div !{companyAddress} - if showBillingToAddress - div(class=`${prefix}-address`) - strong(class=`${prefix}-address__item`) #{billedToLabel} - each addressLine in billedToAddress - div(class=`${prefix}-address__item`) #{addressLine} + if showCustomerAddress + div(class=`${prefix}-address-to`) + strong #{billedToLabel} + div !{customerAddress} table(class=`${prefix}-table`) thead diff --git a/packages/server/resources/views/modules/receipt-regular.pug b/packages/server/resources/views/modules/receipt-regular.pug index 39185c1d7..7d8fd015b 100644 --- a/packages/server/resources/views/modules/receipt-regular.pug +++ b/packages/server/resources/views/modules/receipt-regular.pug @@ -146,17 +146,14 @@ block content //- Address Section div(class=`${prefix}-address-section`) - if showBilledFromAddress - div(class=`${prefix}-address`) - strong= companyName - each addressLine in billedFromAddress - div= addressLine + if showCompanyAddress + div(class=`${prefix}-address-from`) + div !{companyAddress} - if showBilledToAddress - div(class=`${prefix}-address`) - strong= billedToLabel - each addressLine in billedToAddress - div= addressLine + if showCustomerAddress + div(class=`${prefix}-address-to`) + strong #{billedToLabel} + div !{customerAddress} //- Table Section table(class=`${prefix}-table`) diff --git a/packages/server/src/interfaces/CreditNote.ts b/packages/server/src/interfaces/CreditNote.ts index ffb4c26ba..aff44b125 100644 --- a/packages/server/src/interfaces/CreditNote.ts +++ b/packages/server/src/interfaces/CreditNote.ts @@ -262,16 +262,24 @@ export type ICreditNoteGLCommonEntry = Pick< >; export interface CreditNotePdfTemplateAttributes { + // # Primary color primaryColor: string; secondaryColor: string; + + // # Company logo showCompanyLogo: boolean; companyLogo: string; + + // # Company name companyName: string; - billedToAddress: string[]; - billedFromAddress: string[]; - showBilledToAddress: boolean; - showBilledFromAddress: boolean; + // # Customer Address + showCustomerAddress: boolean; + customerAddress: string; + + // # Company address + showCompanyAddress: boolean; + companyAddress: string; billedToLabel: string; total: string; diff --git a/packages/server/src/interfaces/PaymentReceive.ts b/packages/server/src/interfaces/PaymentReceive.ts index 8dd880872..f09323a55 100644 --- a/packages/server/src/interfaces/PaymentReceive.ts +++ b/packages/server/src/interfaces/PaymentReceive.ts @@ -207,10 +207,13 @@ export interface PaymentReceivedPdfTemplateAttributes { companyLogo: string; companyName: string; - billedToAddress: string[]; - billedFromAddress: string[]; - showBilledFromAddress: boolean; - showBillingToAddress: boolean; + // Customer Address + showCustomerAddress: boolean; + customerAddress: string; + + // Company address + showCompanyAddress: boolean; + companyAddress: string; billedToLabel: string; total: string; diff --git a/packages/server/src/interfaces/SaleInvoice.ts b/packages/server/src/interfaces/SaleInvoice.ts index 5eef382f3..6e3f94088 100644 --- a/packages/server/src/interfaces/SaleInvoice.ts +++ b/packages/server/src/interfaces/SaleInvoice.ts @@ -294,8 +294,13 @@ export interface InvoicePdfTemplateAttributes { invoiceNumber: string; showInvoiceNumber: boolean; - showBillingToAddress: boolean; - showBilledFromAddress: boolean; + // Customer Address + showCustomerAddress: boolean; + customerAddress: string; + + // Company address + showCompanyAddress: boolean; + companyAddress: string; billedToLabel: string; lineItemLabel: string; @@ -333,7 +338,4 @@ export interface InvoicePdfTemplateAttributes { statementLabel: string; showStatement: boolean; statement: string; - - billedToAddress: string[]; - billedFromAddres: string[]; } diff --git a/packages/server/src/interfaces/SaleReceipt.ts b/packages/server/src/interfaces/SaleReceipt.ts index d3e458313..6966722ff 100644 --- a/packages/server/src/interfaces/SaleReceipt.ts +++ b/packages/server/src/interfaces/SaleReceipt.ts @@ -163,11 +163,13 @@ export interface ISaleReceiptBrandingTemplateAttributes { companyLogo: string; companyName: string; - // Address - billedToAddress: string[]; - billedFromAddress: string[]; - showBilledFromAddress: boolean; - showBilledToAddress: boolean; + // Customer Address + showCustomerAddress: boolean; + customerAddress: string; + + // Company address + showCompanyAddress: boolean; + companyAddress: string; billedToLabel: string; // Total diff --git a/packages/server/src/services/CreditNotes/CreditNoteBrandingTemplate.ts b/packages/server/src/services/CreditNotes/CreditNoteBrandingTemplate.ts index 1b35dc29b..872f16ef4 100644 --- a/packages/server/src/services/CreditNotes/CreditNoteBrandingTemplate.ts +++ b/packages/server/src/services/CreditNotes/CreditNoteBrandingTemplate.ts @@ -1,26 +1,44 @@ -import { Inject } from "typedi"; -import { GetPdfTemplate } from "../PdfTemplate/GetPdfTemplate"; -import { defaultCreditNoteBrandingAttributes } from "./constants"; -import { mergePdfTemplateWithDefaultAttributes } from "../Sales/Invoices/utils"; +import { Inject } from 'typedi'; +import { GetPdfTemplate } from '../PdfTemplate/GetPdfTemplate'; +import { defaultCreditNoteBrandingAttributes } from './constants'; +import { mergePdfTemplateWithDefaultAttributes } from '../Sales/Invoices/utils'; +import { GetOrganizationBrandingAttributes } from '../PdfTemplate/GetOrganizationBrandingAttributes'; export class CreditNoteBrandingTemplate { @Inject() private getPdfTemplateService: GetPdfTemplate; + @Inject() + private getOrgBrandingAttributes: GetOrganizationBrandingAttributes; + /** * Retrieves the credit note branding template. - * @param {number} tenantId - * @param {number} templateId + * @param {number} tenantId + * @param {number} templateId * @returns {} */ - public async getCreditNoteBrandingTemplate(tenantId: number, templateId: number) { + public async getCreditNoteBrandingTemplate( + tenantId: number, + templateId: number + ) { const template = await this.getPdfTemplateService.getPdfTemplate( tenantId, templateId ); + // Retrieves the organization branding attributes. + const commonOrgBrandingAttrs = + await this.getOrgBrandingAttributes.getOrganizationBrandingAttributes( + tenantId + ); + // Merges the default branding attributes with common organization branding attrs. + const organizationBrandingAttrs = { + ...defaultCreditNoteBrandingAttributes, + ...commonOrgBrandingAttrs, + }; + const attributes = mergePdfTemplateWithDefaultAttributes( template.attributes, - defaultCreditNoteBrandingAttributes + organizationBrandingAttrs ); return { ...template, diff --git a/packages/server/src/services/CreditNotes/GetCreditNotePdf.ts b/packages/server/src/services/CreditNotes/GetCreditNotePdf.ts index 5a1ea0faf..4205fbfaa 100644 --- a/packages/server/src/services/CreditNotes/GetCreditNotePdf.ts +++ b/packages/server/src/services/CreditNotes/GetCreditNotePdf.ts @@ -34,8 +34,6 @@ export default class GetCreditNotePdf { tenantId, creditNoteId ); - console.log(brandingAttributes, 'brandingAttributes'); - const htmlContent = await this.templateInjectable.render( tenantId, 'modules/credit-note-standard', diff --git a/packages/server/src/services/CreditNotes/constants.ts b/packages/server/src/services/CreditNotes/constants.ts index db44e5968..4f1d51d30 100644 --- a/packages/server/src/services/CreditNotes/constants.ts +++ b/packages/server/src/services/CreditNotes/constants.ts @@ -80,24 +80,13 @@ export const defaultCreditNoteBrandingAttributes = { // # Company name companyName: 'Bigcapital Technology, Inc.', - // Address - billedToAddress: [ - 'Bigcapital Technology, Inc.', - '131 Continental Dr Suite 305 Newark,', - 'Delaware 19713', - 'United States', - '+1 762-339-5634', - 'ahmed@bigcapital.app', - ], - billedFromAddress: [ - '131 Continental Dr Suite 305 Newark,', - 'Delaware 19713', - 'United States', - '+1 762-339-5634', - 'ahmed@bigcapital.app', - ], - showBilledToAddress: true, - showBilledFromAddress: true, + // # Customer address + showCustomerAddress: true, + customerAddress: '', + + // # Company address + showCompanyAddress: true, + companyAddress: '', billedToLabel: 'Billed To', // Total diff --git a/packages/server/src/services/CreditNotes/utils.ts b/packages/server/src/services/CreditNotes/utils.ts index 6b94d955e..8936f922c 100644 --- a/packages/server/src/services/CreditNotes/utils.ts +++ b/packages/server/src/services/CreditNotes/utils.ts @@ -1,4 +1,5 @@ import { CreditNotePdfTemplateAttributes, ICreditNote } from '@/interfaces'; +import { contactAddressTextFormat } from '@/utils/address-text-format'; export const transformCreditNoteToPdfTemplate = ( creditNote: ICreditNote @@ -19,5 +20,6 @@ export const transformCreditNoteToPdfTemplate = ( })), customerNote: creditNote.note, termsConditions: creditNote.termsConditions, + customerAddress: contactAddressTextFormat(creditNote.customer), }; }; diff --git a/packages/server/src/services/Sales/Estimates/constants.ts b/packages/server/src/services/Sales/Estimates/constants.ts index 57ab68632..b42d66763 100644 --- a/packages/server/src/services/Sales/Estimates/constants.ts +++ b/packages/server/src/services/Sales/Estimates/constants.ts @@ -231,7 +231,6 @@ export const defaultEstimatePdfBrandingAttributes = { expirationDate: 'September 3, 2024', }; - interface EstimatePdfBrandingLineItem { item: string; description: string; @@ -247,10 +246,13 @@ export interface EstimatePdfBrandingAttributes { companyLogo: string; companyName: string; - billedToAddress: string[]; - billedFromAddress: string[]; - showBilledFromAddress: boolean; - showBilledToAddress: boolean; + // Customer Address + showCustomerAddress: boolean; + customerAddress: string; + + // Company Address + showCompanyAddress: boolean; + companyAddress: string; billedToLabel: string; total: string; @@ -282,4 +284,4 @@ export interface EstimatePdfBrandingAttributes { expirationDateLabel: string; showExpirationDate: boolean; expirationDate: string; -} \ No newline at end of file +} diff --git a/packages/server/src/services/Sales/Estimates/utils.ts b/packages/server/src/services/Sales/Estimates/utils.ts index 879667893..f15a25546 100644 --- a/packages/server/src/services/Sales/Estimates/utils.ts +++ b/packages/server/src/services/Sales/Estimates/utils.ts @@ -1,3 +1,4 @@ +import { contactAddressTextFormat } from '@/utils/address-text-format'; import { EstimatePdfBrandingAttributes } from './constants'; export const transformEstimateToPdfTemplate = ( @@ -18,5 +19,6 @@ export const transformEstimateToPdfTemplate = ( subtotal: estimate.formattedSubtotal, customerNote: estimate.customerNote, termsConditions: estimate.termsConditions, + customerAddress: contactAddressTextFormat(estimate.customer), }; }; diff --git a/packages/server/src/services/Sales/Invoices/SaleEstimatePdfTemplate.ts b/packages/server/src/services/Sales/Invoices/SaleEstimatePdfTemplate.ts index e0b955591..54048619a 100644 --- a/packages/server/src/services/Sales/Invoices/SaleEstimatePdfTemplate.ts +++ b/packages/server/src/services/Sales/Invoices/SaleEstimatePdfTemplate.ts @@ -28,7 +28,7 @@ export class SaleEstimatePdfTemplate { await this.getOrgBrandingAttrs.getOrganizationBrandingAttributes( tenantId ); - + // Merge the default branding attributes with organization attrs. const orgainizationBrandingAttrs = { ...defaultEstimatePdfBrandingAttributes, ...commonOrgBrandingAttrs, diff --git a/packages/server/src/services/Sales/Invoices/utils.ts b/packages/server/src/services/Sales/Invoices/utils.ts index 8131ea2bd..833822459 100644 --- a/packages/server/src/services/Sales/Invoices/utils.ts +++ b/packages/server/src/services/Sales/Invoices/utils.ts @@ -1,5 +1,6 @@ import { pickBy } from 'lodash'; import { InvoicePdfTemplateAttributes, ISaleInvoice } from '@/interfaces'; +import { contactAddressTextFormat } from '@/utils/address-text-format'; export const mergePdfTemplateWithDefaultAttributes = ( brandingTemplate?: Record, @@ -42,5 +43,7 @@ export const transformInvoiceToPdfTemplate = ( label: tax.name, amount: tax.taxRateAmountFormatted, })), + + customerAddress: contactAddressTextFormat(invoice.customer), }; }; diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedBrandingTemplate.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedBrandingTemplate.ts index 625b24d95..aa8d580df 100644 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedBrandingTemplate.ts +++ b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedBrandingTemplate.ts @@ -3,12 +3,18 @@ import { Inject, Service } from 'typedi'; import { mergePdfTemplateWithDefaultAttributes } from '../Invoices/utils'; import { defaultPaymentReceivedPdfTemplateAttributes } from './constants'; import { PdfTemplate } from '@/models/PdfTemplate'; +import { GetOrganizationBrandingAttributes } from '@/services/PdfTemplate/GetOrganizationBrandingAttributes'; @Service() export class PaymentReceivedBrandingTemplate { @Inject() private getPdfTemplateService: GetPdfTemplate; + + @Inject() + private getOrgBrandingAttributes: GetOrganizationBrandingAttributes; + + /** * Retrieves the payment received pdf template. * @param {number} tenantId @@ -23,9 +29,16 @@ export class PaymentReceivedBrandingTemplate { tenantId, paymentTemplateId ); + // Retrieves the organization branding attributes. + const commonOrgBrandingAttrs = this.getOrgBrandingAttributes.getOrganizationBrandingAttributes(tenantId); + + const organizationBrandingAttrs = { + ...defaultPaymentReceivedPdfTemplateAttributes, + ...commonOrgBrandingAttrs, + }; const attributes = mergePdfTemplateWithDefaultAttributes( template.attributes, - defaultPaymentReceivedPdfTemplateAttributes + organizationBrandingAttrs ); return { ...template, diff --git a/packages/server/src/services/Sales/PaymentReceived/constants.ts b/packages/server/src/services/Sales/PaymentReceived/constants.ts index c9fef7c5f..739cea048 100644 --- a/packages/server/src/services/Sales/PaymentReceived/constants.ts +++ b/packages/server/src/services/Sales/PaymentReceived/constants.ts @@ -58,24 +58,13 @@ export const defaultPaymentReceivedPdfTemplateAttributes = { // # Company name companyName: 'Bigcapital Technology, Inc.', - // Address - billedToAddress: [ - 'Bigcapital Technology, Inc.', - '131 Continental Dr Suite 305 Newark,', - 'Delaware 19713', - 'United States', - '+1 762-339-5634', - 'ahmed@bigcapital.app', - ], - billedFromAddress: [ - '131 Continental Dr Suite 305 Newark,', - 'Delaware 19713', - 'United States', - '+1 762-339-5634', - 'ahmed@bigcapital.app', - ], - showBilledFromAddress: true, - showBillingToAddress: true, + // # Customer address + showCustomerAddress: true, + customerAddress: '', + + // # Company address + showCompanyAddress: true, + companyAddress: '', billedToLabel: 'Billed To', // Total diff --git a/packages/server/src/services/Sales/PaymentReceived/utils.ts b/packages/server/src/services/Sales/PaymentReceived/utils.ts index 540aab9ed..bfd1ad8ea 100644 --- a/packages/server/src/services/Sales/PaymentReceived/utils.ts +++ b/packages/server/src/services/Sales/PaymentReceived/utils.ts @@ -2,6 +2,7 @@ import { IPaymentReceived, PaymentReceivedPdfTemplateAttributes, } from '@/interfaces'; +import { contactAddressTextFormat } from '@/utils/address-text-format'; export const transformPaymentReceivedToPdfTemplate = ( payment: IPaymentReceived @@ -17,5 +18,6 @@ export const transformPaymentReceivedToPdfTemplate = ( invoiceAmount: entry.invoice.totalFormatted, paidAmount: entry.paymentAmountFormatted, })), + customerAddress: contactAddressTextFormat(payment.customer), }; }; diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptBrandingTemplate.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptBrandingTemplate.ts index 5d7794421..1cef714b9 100644 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptBrandingTemplate.ts +++ b/packages/server/src/services/Sales/Receipts/SaleReceiptBrandingTemplate.ts @@ -2,12 +2,15 @@ import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate'; import { Inject, Service } from 'typedi'; import { defaultSaleReceiptBrandingAttributes } from './constants'; import { mergePdfTemplateWithDefaultAttributes } from '../Invoices/utils'; +import { GetOrganizationBrandingAttributes } from '@/services/PdfTemplate/GetOrganizationBrandingAttributes'; @Service() export class SaleReceiptBrandingTemplate { @Inject() private getPdfTemplateService: GetPdfTemplate; + @Inject() + private getOrgBrandingAttributes: GetOrganizationBrandingAttributes; /** * Retrieves the sale receipt branding template. @@ -23,9 +26,20 @@ export class SaleReceiptBrandingTemplate { tenantId, templateId ); + // Retrieves the organization branding attributes. + const commonOrgBrandingAttrs = + await this.getOrgBrandingAttributes.getOrganizationBrandingAttributes( + tenantId + ); + + // Merges the default branding attributes with organization common branding attrs. + const organizationBrandingAttrs = { + ...defaultSaleReceiptBrandingAttributes, + ...commonOrgBrandingAttrs, + }; const attributes = mergePdfTemplateWithDefaultAttributes( template.attributes, - defaultSaleReceiptBrandingAttributes + organizationBrandingAttrs ); return { ...template, diff --git a/packages/server/src/services/Sales/Receipts/constants.ts b/packages/server/src/services/Sales/Receipts/constants.ts index 0b2f38bc1..547d91a56 100644 --- a/packages/server/src/services/Sales/Receipts/constants.ts +++ b/packages/server/src/services/Sales/Receipts/constants.ts @@ -76,26 +76,16 @@ export const defaultSaleReceiptBrandingAttributes = { companyLogoUri: '', companyLogoKey: '', - // # Address - billedToAddress: [ - 'Bigcapital Technology, Inc.', - '131 Continental Dr Suite 305 Newark,', - 'Delaware 19713', - 'United States', - '+1 762-339-5634', - 'ahmed@bigcapital.app', - ], - billedFromAddress: [ - '131 Continental Dr Suite 305 Newark,', - 'Delaware 19713', - 'United States', - '+1 762-339-5634', - 'ahmed@bigcapital.app', - ], - showBilledFromAddress: true, - showBilledToAddress: true, + // # Customer address + showCustomerAddress: true, + customerAddress: '', + + // # Company address + showCompanyAddress: true, + companyAddress: '', billedToLabel: 'Billed To', + // # Total total: '$1000.00', totalLabel: 'Total', showTotal: true, diff --git a/packages/server/src/services/Sales/Receipts/utils.ts b/packages/server/src/services/Sales/Receipts/utils.ts index e1d9ac9d9..933de982a 100644 --- a/packages/server/src/services/Sales/Receipts/utils.ts +++ b/packages/server/src/services/Sales/Receipts/utils.ts @@ -1,4 +1,5 @@ import { ISaleReceipt, ISaleReceiptBrandingTemplateAttributes } from "@/interfaces"; +import { contactAddressTextFormat } from "@/utils/address-text-format"; @@ -13,8 +14,8 @@ export const transformReceiptToBrandingTemplateAttributes = (saleReceipt: ISaleR quantity: entry.quantityFormatted, total: entry.totalFormatted, })), - receiptNumber: saleReceipt.receiptNumber, receiptDate: saleReceipt.formattedReceiptDate, + customerAddress: contactAddressTextFormat(saleReceipt.customer), }; } \ No newline at end of file diff --git a/packages/server/src/system/models/TenantMetadata.ts b/packages/server/src/system/models/TenantMetadata.ts index 4b8f6573e..efc0d2840 100644 --- a/packages/server/src/system/models/TenantMetadata.ts +++ b/packages/server/src/system/models/TenantMetadata.ts @@ -1,4 +1,4 @@ -import { addressTextFormat } from '@/utils/address-text-format'; +import { organizationAddressTextFormat } from '@/utils/address-text-format'; import BaseModel from 'models/Model'; import { getUploadedObjectUri } from '../../services/Attachments/utils'; @@ -74,7 +74,7 @@ export default class TenantMetadata extends BaseModel { {POSTAL_CODE}, {COUNTRY} `; - return addressTextFormat(defaultMessage, { + return organizationAddressTextFormat(defaultMessage, { organizationName: this.name, address1: this.address?.address1, address2: this.address?.address2, diff --git a/packages/server/src/utils/address-text-format.ts b/packages/server/src/utils/address-text-format.ts index 73467aa9c..1b19d6301 100644 --- a/packages/server/src/utils/address-text-format.ts +++ b/packages/server/src/utils/address-text-format.ts @@ -1,3 +1,5 @@ +import { IContact } from '@/interfaces'; + interface OrganizationAddressFormatArgs { organizationName?: string; address1?: string; @@ -17,7 +19,19 @@ const defaultMessage = ` {COUNTRY} `; -export const addressTextFormat = ( +const formatText = (message: string, replacements: Record) => { + let formattedMessage = Object.entries(replacements).reduce( + (msg, [key, value]) => { + return msg.split(`{${key}}`).join(value || ''); + }, + message + ); + formattedMessage = formattedMessage.replace(/\n/g, '
'); + + return formattedMessage.trim(); +}; + +export const organizationAddressTextFormat = ( message: string, args: OrganizationAddressFormatArgs ) => { @@ -30,13 +44,53 @@ export const addressTextFormat = ( POSTAL_CODE: args.postalCode || '', COUNTRY: args.country || '', }; - let formattedMessage = Object.entries(replacements).reduce( - (msg, [key, value]) => { - return value ? msg.split(`{${key}}`).join(value) : msg; - }, - message - ); - formattedMessage = formattedMessage.replace(/\n/g, '
'); - - return formattedMessage.trim(); + return formatText(message, replacements); +}; + +interface ContactAddressTextFormatArgs { + displayName?: string; + state?: string; + postalCode?: string; + email?: string; + country?: string; + city?: string; + address2?: string; + address1?: string; +} + +const contactFormatMessage = `{CONTACT_NAME} +{ADDRESS_1} +{ADDRESS_2} +{CITY} {STATE} +{POSTAL_CODE} +{COUNTRY} +{EMAIL} +`; + +export const contactAddressTextFormat = ( + contact: IContact, + message: string = contactFormatMessage +) => { + const args = { + displayName: contact.displayName, + address1: contact.billingAddress1, + address2: contact.billingAddress2, + state: contact.billingAddressState, + country: contact.billingAddressCountry, + postalCode: contact?.billingAddressPostcode, + city: contact?.billingAddressCity, + email: contact?.email, + } as ContactAddressTextFormatArgs; + + const replacements: Record = { + CONTACT_NAME: args.displayName || '', + ADDRESS_1: args.address1 || '', + ADDRESS_2: args.address2 || '', + CITY: args.city || '', + STATE: args.state || '', + POSTAL_CODE: args.postalCode || '', + COUNTRY: args.country || '', + EMAIL: args?.email || '', + }; + return formatText(message, replacements); }; diff --git a/packages/webapp/src/constants/PdfTemplates.ts b/packages/webapp/src/constants/PdfTemplates.ts index 26c52b7f9..d1be6ba4f 100644 --- a/packages/webapp/src/constants/PdfTemplates.ts +++ b/packages/webapp/src/constants/PdfTemplates.ts @@ -17,10 +17,9 @@ United States,
ahmed@bigcapital.app `; - export const DefaultPdfTemplateAddressBilledFrom = `131 Continental Dr Suite 305 Newark,
Delaware 19713,
United States,
+1 762-339-5634,
ahmed@bigcapital.app -`; \ No newline at end of file +`; diff --git a/packages/webapp/src/containers/Sales/Estimates/EstimateCustomize/EstimatePaperTemplate.tsx b/packages/webapp/src/containers/Sales/Estimates/EstimateCustomize/EstimatePaperTemplate.tsx index 5dddf78a4..af1bb9d11 100644 --- a/packages/webapp/src/containers/Sales/Estimates/EstimateCustomize/EstimatePaperTemplate.tsx +++ b/packages/webapp/src/containers/Sales/Estimates/EstimateCustomize/EstimatePaperTemplate.tsx @@ -71,23 +71,27 @@ export function EstimatePaperTemplate({ primaryColor, secondaryColor, + // # Company logo showCompanyLogo = true, companyLogoUri = '', companyName, - // # Address - customerAddress = DefaultPdfTemplateAddressBilledTo, + // # Company address companyAddress = DefaultPdfTemplateAddressBilledFrom, showCompanyAddress = true, + + // # Customer address + customerAddress = DefaultPdfTemplateAddressBilledTo, showCustomerAddress = true, billedToLabel = 'Billed To', - // #Total + // # Total total = '$1000.00', totalLabel = 'Total', showTotal = true, + // # Subtotal subtotal = '1000/00', subtotalLabel = 'Subtotal', showSubtotal = true, @@ -111,14 +115,18 @@ export function EstimatePaperTemplate({ total: '$1000.00', }, ], + + // Estimate number showEstimateNumber = true, estimateNumberLabel = 'Estimate Number', estimateNumebr = '346D3D40-0001', + // Estimate date estimateDate = 'September 3, 2024', showEstimateDate = true, estimateDateLabel = 'Estimate Date', + // Expiration date expirationDateLabel = 'Expiration Date', showExpirationDate = true, expirationDate = 'September 3, 2024', diff --git a/packages/webapp/src/containers/Sales/Estimates/EstimateCustomize/constants.ts b/packages/webapp/src/containers/Sales/Estimates/EstimateCustomize/constants.ts index 4bcb5b7a9..7a471036e 100644 --- a/packages/webapp/src/containers/Sales/Estimates/EstimateCustomize/constants.ts +++ b/packages/webapp/src/containers/Sales/Estimates/EstimateCustomize/constants.ts @@ -23,10 +23,11 @@ export const initialValues = { // Company name companyName: 'Bigcapital Technology, Inc.', - // Addresses + // Customer address showCustomerAddress: true, + + // Company address showCompanyAddress: true, - customerAddress: '', companyAddress: '', billedToLabel: 'Billed To', diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptCustomize/constants.ts b/packages/webapp/src/containers/Sales/Receipts/ReceiptCustomize/constants.ts index 8f571d260..07ae60a23 100644 --- a/packages/webapp/src/containers/Sales/Receipts/ReceiptCustomize/constants.ts +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptCustomize/constants.ts @@ -21,11 +21,12 @@ export const initialValues = { // Company name companyName: 'Bigcapital Technology, Inc.', - // Addresses - showCompanyAddress: true, + // Customer address showCustomerAddress: true, + + // Company address companyAddress: '', - customerAddress: '', + showCompanyAddress: true, billedToLabel: 'Billed To', // Entries