From ace75f2dfa7264b86daa6cbf85b14b68ce198259 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Tue, 1 Oct 2024 09:47:58 +0200 Subject: [PATCH] feat: Hook up customer/company address to invoice preview of payment page --- .../GetInvoicePaymentLinkTransformer.ts | 10 ++++++ .../src/system/models/TenantMetadata.ts | 9 ++--- .../server/src/utils/address-text-format.ts | 33 ++++++++++++++----- packages/webapp/src/constants/PdfTemplates.ts | 10 +++--- .../PaymentPortal/PaymentPortal.tsx | 23 ++++++++----- .../PaymentInvoicePreviewContent.tsx | 4 +++ .../webapp/src/hooks/query/payment-link.ts | 1 + 7 files changed, 63 insertions(+), 27 deletions(-) diff --git a/packages/server/src/services/Sales/Invoices/GetInvoicePaymentLinkTransformer.ts b/packages/server/src/services/Sales/Invoices/GetInvoicePaymentLinkTransformer.ts index b85696497..87c4823c0 100644 --- a/packages/server/src/services/Sales/Invoices/GetInvoicePaymentLinkTransformer.ts +++ b/packages/server/src/services/Sales/Invoices/GetInvoicePaymentLinkTransformer.ts @@ -3,6 +3,7 @@ import { ItemEntryTransformer } from './ItemEntryTransformer'; import { SaleInvoiceTaxEntryTransformer } from './SaleInvoiceTaxEntryTransformer'; import { SaleInvoiceTransformer } from './SaleInvoiceTransformer'; import { Transformer } from '@/lib/Transformer/Transformer'; +import { contactAddressTextFormat } from '@/utils/address-text-format'; export class GetInvoicePaymentLinkMetaTransformer extends SaleInvoiceTransformer { /** @@ -43,6 +44,7 @@ export class GetInvoicePaymentLinkMetaTransformer extends SaleInvoiceTransformer 'organization', 'isReceivable', 'hasStripePaymentMethod', + 'formattedCustomerAddress', ]; }; @@ -101,6 +103,14 @@ export class GetInvoicePaymentLinkMetaTransformer extends SaleInvoiceTransformer (paymentMethod) => paymentMethod.paymentIntegration.service === 'Stripe' ); } + + protected formattedCustomerAddress(invoice) { + return contactAddressTextFormat(invoice.customer, `{ADDRESS_1} +{ADDRESS_2} +{CITY}, {STATE} {POSTAL_CODE} +{COUNTRY} +{PHONE}`); + } } class GetPaymentLinkOrganizationMetaTransformer extends Transformer { diff --git a/packages/server/src/system/models/TenantMetadata.ts b/packages/server/src/system/models/TenantMetadata.ts index efc0d2840..0b7ae3ce3 100644 --- a/packages/server/src/system/models/TenantMetadata.ts +++ b/packages/server/src/system/models/TenantMetadata.ts @@ -68,11 +68,11 @@ export default class TenantMetadata extends BaseModel { */ public get addressTextFormatted() { const defaultMessage = `{ORGANIZATION_NAME} - {ADDRESS_1}, - {ADDRESS_2}, - {CITY} {STATE}, - {POSTAL_CODE}, + {ADDRESS_1} + {ADDRESS_2} + {CITY}, {STATE} {POSTAL_CODE} {COUNTRY} + {PHONE} `; return organizationAddressTextFormat(defaultMessage, { organizationName: this.name, @@ -81,6 +81,7 @@ export default class TenantMetadata extends BaseModel { state: this.address?.stateProvince, city: this.address?.city, postalCode: this.address?.postalCode, + phone: this.address?.phone, country: 'United State', }); } diff --git a/packages/server/src/utils/address-text-format.ts b/packages/server/src/utils/address-text-format.ts index 1b19d6301..d5f85c721 100644 --- a/packages/server/src/utils/address-text-format.ts +++ b/packages/server/src/utils/address-text-format.ts @@ -8,17 +8,27 @@ interface OrganizationAddressFormatArgs { city?: string; country?: string; postalCode?: string; + phone?: string; } const defaultMessage = ` {ORGANIZATION_NAME} - {ADDRESS_1}, - {ADDRESS_2}, - {CITY} {STATE}, - {POSTAL_CODE}, + {ADDRESS_1} + {ADDRESS_2} + {CITY}, {STATE} {POSTAL_CODE} {COUNTRY} + {PHONE} `; - +/** + * Formats the address text based on the provided message and arguments. + * This function replaces placeholders in the message with actual values + * from the OrganizationAddressFormatArgs. It ensures that the final + * formatted message is clean and free of excessive newlines. + * + * @param {string} message - The message template containing placeholders. + * @param {Record} args - The arguments containing the values to replace in the message. + * @returns {string} - The formatted address text. + */ const formatText = (message: string, replacements: Record) => { let formattedMessage = Object.entries(replacements).reduce( (msg, [key, value]) => { @@ -26,9 +36,11 @@ const formatText = (message: string, replacements: Record) => { }, message ); + formattedMessage = formattedMessage.replace(/\n{2,}/g, '\n').trim(); formattedMessage = formattedMessage.replace(/\n/g, '
'); + formattedMessage = formattedMessage.trim(); - return formattedMessage.trim(); + return formattedMessage; }; export const organizationAddressTextFormat = ( @@ -43,6 +55,7 @@ export const organizationAddressTextFormat = ( STATE: args.state || '', POSTAL_CODE: args.postalCode || '', COUNTRY: args.country || '', + PHONE: args.phone || '', }; return formatText(message, replacements); }; @@ -56,15 +69,15 @@ interface ContactAddressTextFormatArgs { city?: string; address2?: string; address1?: string; + phone?: string; } const contactFormatMessage = `{CONTACT_NAME} {ADDRESS_1} {ADDRESS_2} -{CITY} {STATE} -{POSTAL_CODE} +{CITY}, {STATE} {POSTAL_CODE} {COUNTRY} -{EMAIL} +{PHONE} `; export const contactAddressTextFormat = ( @@ -80,6 +93,7 @@ export const contactAddressTextFormat = ( postalCode: contact?.billingAddressPostcode, city: contact?.billingAddressCity, email: contact?.email, + phone: contact?.billingAddressPhone, } as ContactAddressTextFormatArgs; const replacements: Record = { @@ -91,6 +105,7 @@ export const contactAddressTextFormat = ( POSTAL_CODE: args.postalCode || '', COUNTRY: args.country || '', EMAIL: args?.email || '', + PHONE: args?.phone || '', }; return formatText(message, replacements); }; diff --git a/packages/webapp/src/constants/PdfTemplates.ts b/packages/webapp/src/constants/PdfTemplates.ts index d1be6ba4f..c08cce9c5 100644 --- a/packages/webapp/src/constants/PdfTemplates.ts +++ b/packages/webapp/src/constants/PdfTemplates.ts @@ -10,11 +10,11 @@ export const DefaultPdfTemplateItemDescription = 'Website development with content and SEO optimization'; export const DefaultPdfTemplateAddressBilledTo = `Bigcapital Technology, Inc.
-131 Continental Dr Suite 305 Newark,
-Delaware 19713,
-United States,
-+1 762-339-5634,
-ahmed@bigcapital.app +131 Continental Dr,
+Suite 305,
+Newark, Delaware 19713,
+United States,
++1 762-339-5634 `; export const DefaultPdfTemplateAddressBilledFrom = `131 Continental Dr Suite 305 Newark,
diff --git a/packages/webapp/src/containers/PaymentPortal/PaymentPortal.tsx b/packages/webapp/src/containers/PaymentPortal/PaymentPortal.tsx index 6bb2114ca..6e1080910 100644 --- a/packages/webapp/src/containers/PaymentPortal/PaymentPortal.tsx +++ b/packages/webapp/src/containers/PaymentPortal/PaymentPortal.tsx @@ -1,4 +1,4 @@ -import { Text, Classes, Button, Intent } from '@blueprintjs/core'; +import { Text, Classes, Button, Intent, Tag } from '@blueprintjs/core'; import clsx from 'classnames'; import { AppToaster, Box, Group, Stack } from '@/components'; import { usePaymentPortalBoot } from './PaymentPortalBoot'; @@ -54,20 +54,25 @@ export function PaymentPortal() { {sharableLinkMeta?.organization?.name} Sent an Invoice for{' '} {sharableLinkMeta?.totalFormatted} - - Invoice due {sharableLinkMeta?.dueDateFormatted} - + + + Invoice due {sharableLinkMeta?.dueDateFormatted}{' '} + + {sharableLinkMeta?.customerName} - Bigcapital Technology, Inc. - 131 Continental Dr Suite 305 Newark, - Delaware 19713 - United States - ahmed@bigcapital.app + + {sharableLinkMeta?.formattedCustomerAddress && ( + + )}

diff --git a/packages/webapp/src/containers/PaymentPortal/drawers/PaymentInvoicePreviewDrawer/PaymentInvoicePreviewContent.tsx b/packages/webapp/src/containers/PaymentPortal/drawers/PaymentInvoicePreviewDrawer/PaymentInvoicePreviewContent.tsx index d55bb9598..037c11b08 100644 --- a/packages/webapp/src/containers/PaymentPortal/drawers/PaymentInvoicePreviewDrawer/PaymentInvoicePreviewContent.tsx +++ b/packages/webapp/src/containers/PaymentPortal/drawers/PaymentInvoicePreviewDrawer/PaymentInvoicePreviewContent.tsx @@ -34,6 +34,10 @@ export function PaymentInvoicePreviewContent() { label: tax.name, amount: tax.taxRateAmountFormatted, }))} + companyAddress={ + sharableLinkMeta?.organization?.addressTextFormatted + } + customerAddress={sharableLinkMeta?.formattedCustomerAddress} /> diff --git a/packages/webapp/src/hooks/query/payment-link.ts b/packages/webapp/src/hooks/query/payment-link.ts index 1eadbed73..96cce6c0f 100644 --- a/packages/webapp/src/hooks/query/payment-link.ts +++ b/packages/webapp/src/hooks/query/payment-link.ts @@ -108,6 +108,7 @@ export interface GetInvoicePaymentLinkResponse { organization: GetInvoicePaymentLinkOrganizationRes; hasStripePaymentMethod: boolean; isReceivable: boolean; + formattedCustomerAddress: string; } /**