mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-23 00:00:31 +00:00
Merge pull request #678 from bigcapitalhq/pdf-templates-company-customer-address
feat: Pdf templates customer/company addresses
This commit is contained in:
@@ -48,8 +48,8 @@ block head
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: wrap;
|
flex-flow: wrap;
|
||||||
-webkit-box-align: center;
|
-webkit-box-align: flex-start;
|
||||||
align-items: center;
|
align-items: flex-start;
|
||||||
-webkit-box-pack: start;
|
-webkit-box-pack: start;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
@@ -150,17 +150,14 @@ block content
|
|||||||
div(class=`${prefix}-terms-item__value`) #{creditNoteDate}
|
div(class=`${prefix}-terms-item__value`) #{creditNoteDate}
|
||||||
|
|
||||||
div(class=`${prefix}-address-section`)
|
div(class=`${prefix}-address-section`)
|
||||||
if showBilledFromAddress
|
if showCompanyAddress
|
||||||
div(class=`${prefix}-address`)
|
div(class=`${prefix}-address-from`)
|
||||||
strong #{companyName}
|
div !{companyAddress}
|
||||||
each address in billedFromAddress
|
|
||||||
div #{address}
|
|
||||||
|
|
||||||
if showBilledToAddress
|
if showCustomerAddress
|
||||||
div(class=`${prefix}-address`)
|
div(class=`${prefix}-address-to`)
|
||||||
strong #{billedToLabel}
|
strong #{billedToLabel}
|
||||||
each address in billedToAddress
|
div !{customerAddress}
|
||||||
div #{address}
|
|
||||||
|
|
||||||
table(class=`${prefix}-table`)
|
table(class=`${prefix}-table`)
|
||||||
thead
|
thead
|
||||||
|
|||||||
@@ -47,9 +47,7 @@ block head
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: wrap;
|
flex-flow: wrap;
|
||||||
-webkit-box-align: center;
|
align-items: flex-start;
|
||||||
align-items: center;
|
|
||||||
-webkit-box-pack: start;
|
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
@@ -156,17 +154,14 @@ block content
|
|||||||
|
|
||||||
//- Addresses (Group section)
|
//- Addresses (Group section)
|
||||||
div(class=`${prefix}-addresses`)
|
div(class=`${prefix}-addresses`)
|
||||||
if showBilledFromAddress
|
if showCompanyAddress
|
||||||
div(class=`${prefix}-address`)
|
div(class=`${prefix}-address-from`)
|
||||||
strong #{companyName}
|
div !{companyAddress}
|
||||||
each item in billedFromAddress
|
|
||||||
div(class=`${prefix}-address__item`) #{item}
|
|
||||||
|
|
||||||
if showBilledToAddress
|
if showCustomerAddress
|
||||||
div(class=`${prefix}-address`)
|
div(class=`${prefix}-address-to`)
|
||||||
strong #{billedToLabel}
|
strong #{billedToLabel}
|
||||||
each item in billedToAddress
|
div !{customerAddress}
|
||||||
div(class=`${prefix}-address__item`) #{item}
|
|
||||||
|
|
||||||
//- Table section (Line items)
|
//- Table section (Line items)
|
||||||
table(class=`${prefix}-table`)
|
table(class=`${prefix}-table`)
|
||||||
|
|||||||
@@ -48,9 +48,7 @@ block head
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: wrap;
|
flex-flow: wrap;
|
||||||
-webkit-box-align: center;
|
align-items: flex-start;
|
||||||
align-items: center;
|
|
||||||
-webkit-box-pack: start;
|
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
@@ -167,17 +165,14 @@ block content
|
|||||||
|
|
||||||
//- Address section
|
//- Address section
|
||||||
div(class=`${prefix}-address-root`)
|
div(class=`${prefix}-address-root`)
|
||||||
if showBilledFromAddress
|
if showCompanyAddress
|
||||||
div(class=`${prefix}-address-from`)
|
div(class=`${prefix}-address-from`)
|
||||||
strong #{companyName}
|
div !{companyAddress}
|
||||||
each item in billedFromAddres
|
|
||||||
div(class=`${prefix}-address-from__item`) #{item}
|
|
||||||
|
|
||||||
if showBillingToAddress
|
if showCustomerAddress
|
||||||
div(class=`${prefix}-address-to`)
|
div(class=`${prefix}-address-to`)
|
||||||
strong #{billedToLabel}
|
strong #{billedToLabel}
|
||||||
each item in billedToAddress
|
div !{customerAddress}
|
||||||
div(class=`${prefix}-address-to__item`) #{item}
|
|
||||||
|
|
||||||
//- Invoice table
|
//- Invoice table
|
||||||
table(class=`${prefix}-table`)
|
table(class=`${prefix}-table`)
|
||||||
|
|||||||
@@ -46,9 +46,7 @@ block head
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: wrap;
|
flex-flow: wrap;
|
||||||
-webkit-box-align: center;
|
align-items: flex-start;
|
||||||
align-items: center;
|
|
||||||
-webkit-box-pack: start;
|
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
@@ -140,17 +138,14 @@ block content
|
|||||||
div(class=`${prefix}-terms-item__value`) #{paymentReceivedDate}
|
div(class=`${prefix}-terms-item__value`) #{paymentReceivedDate}
|
||||||
|
|
||||||
div(class=`${prefix}-addresses`)
|
div(class=`${prefix}-addresses`)
|
||||||
if showBilledFromAddress
|
if showCompanyAddress
|
||||||
div(class=`${prefix}-address`)
|
div(class=`${prefix}-address-from`)
|
||||||
strong(class=`${prefix}-address__item`) #{companyName}
|
div !{companyAddress}
|
||||||
each addressLine in billedFromAddress
|
|
||||||
div(class=`${prefix}-address__item`) #{addressLine}
|
|
||||||
|
|
||||||
if showBillingToAddress
|
if showCustomerAddress
|
||||||
div(class=`${prefix}-address`)
|
div(class=`${prefix}-address-to`)
|
||||||
strong(class=`${prefix}-address__item`) #{billedToLabel}
|
strong #{billedToLabel}
|
||||||
each addressLine in billedToAddress
|
div !{customerAddress}
|
||||||
div(class=`${prefix}-address__item`) #{addressLine}
|
|
||||||
|
|
||||||
table(class=`${prefix}-table`)
|
table(class=`${prefix}-table`)
|
||||||
thead
|
thead
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ block head
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: wrap;
|
flex-flow: wrap;
|
||||||
-webkit-box-align: center;
|
-webkit-box-align: flex-start;
|
||||||
align-items: center;
|
align-items: flex-start;
|
||||||
-webkit-box-pack: start;
|
-webkit-box-pack: start;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
@@ -146,17 +146,14 @@ block content
|
|||||||
|
|
||||||
//- Address Section
|
//- Address Section
|
||||||
div(class=`${prefix}-address-section`)
|
div(class=`${prefix}-address-section`)
|
||||||
if showBilledFromAddress
|
if showCompanyAddress
|
||||||
div(class=`${prefix}-address`)
|
div(class=`${prefix}-address-from`)
|
||||||
strong= companyName
|
div !{companyAddress}
|
||||||
each addressLine in billedFromAddress
|
|
||||||
div= addressLine
|
|
||||||
|
|
||||||
if showBilledToAddress
|
if showCustomerAddress
|
||||||
div(class=`${prefix}-address`)
|
div(class=`${prefix}-address-to`)
|
||||||
strong= billedToLabel
|
strong #{billedToLabel}
|
||||||
each addressLine in billedToAddress
|
div !{customerAddress}
|
||||||
div= addressLine
|
|
||||||
|
|
||||||
//- Table Section
|
//- Table Section
|
||||||
table(class=`${prefix}-table`)
|
table(class=`${prefix}-table`)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ export class PdfTemplatesController extends BaseController {
|
|||||||
this.validationResult,
|
this.validationResult,
|
||||||
this.editPdfTemplate.bind(this)
|
this.editPdfTemplate.bind(this)
|
||||||
);
|
);
|
||||||
|
router.get('/state', this.getOrganizationBrandingState.bind(this));
|
||||||
router.get(
|
router.get(
|
||||||
'/',
|
'/',
|
||||||
[query('resource').optional()],
|
[query('resource').optional()],
|
||||||
@@ -175,4 +176,20 @@ export class PdfTemplatesController extends BaseController {
|
|||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async getOrganizationBrandingState(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
|
const { tenantId } = req;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data =
|
||||||
|
await this.pdfTemplateApplication.getPdfTemplateBrandingState(tenantId);
|
||||||
|
|
||||||
|
return res.status(200).send({ data });
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,16 +262,24 @@ export type ICreditNoteGLCommonEntry = Pick<
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
export interface CreditNotePdfTemplateAttributes {
|
export interface CreditNotePdfTemplateAttributes {
|
||||||
|
// # Primary color
|
||||||
primaryColor: string;
|
primaryColor: string;
|
||||||
secondaryColor: string;
|
secondaryColor: string;
|
||||||
|
|
||||||
|
// # Company logo
|
||||||
showCompanyLogo: boolean;
|
showCompanyLogo: boolean;
|
||||||
companyLogo: string;
|
companyLogo: string;
|
||||||
|
|
||||||
|
// # Company name
|
||||||
companyName: string;
|
companyName: string;
|
||||||
|
|
||||||
billedToAddress: string[];
|
// # Customer Address
|
||||||
billedFromAddress: string[];
|
showCustomerAddress: boolean;
|
||||||
showBilledToAddress: boolean;
|
customerAddress: string;
|
||||||
showBilledFromAddress: boolean;
|
|
||||||
|
// # Company address
|
||||||
|
showCompanyAddress: boolean;
|
||||||
|
companyAddress: string;
|
||||||
billedToLabel: string;
|
billedToLabel: string;
|
||||||
|
|
||||||
total: string;
|
total: string;
|
||||||
|
|||||||
@@ -207,10 +207,13 @@ export interface PaymentReceivedPdfTemplateAttributes {
|
|||||||
companyLogo: string;
|
companyLogo: string;
|
||||||
companyName: string;
|
companyName: string;
|
||||||
|
|
||||||
billedToAddress: string[];
|
// Customer Address
|
||||||
billedFromAddress: string[];
|
showCustomerAddress: boolean;
|
||||||
showBilledFromAddress: boolean;
|
customerAddress: string;
|
||||||
showBillingToAddress: boolean;
|
|
||||||
|
// Company address
|
||||||
|
showCompanyAddress: boolean;
|
||||||
|
companyAddress: string;
|
||||||
billedToLabel: string;
|
billedToLabel: string;
|
||||||
|
|
||||||
total: string;
|
total: string;
|
||||||
|
|||||||
@@ -294,8 +294,13 @@ export interface InvoicePdfTemplateAttributes {
|
|||||||
invoiceNumber: string;
|
invoiceNumber: string;
|
||||||
showInvoiceNumber: boolean;
|
showInvoiceNumber: boolean;
|
||||||
|
|
||||||
showBillingToAddress: boolean;
|
// Customer Address
|
||||||
showBilledFromAddress: boolean;
|
showCustomerAddress: boolean;
|
||||||
|
customerAddress: string;
|
||||||
|
|
||||||
|
// Company address
|
||||||
|
showCompanyAddress: boolean;
|
||||||
|
companyAddress: string;
|
||||||
billedToLabel: string;
|
billedToLabel: string;
|
||||||
|
|
||||||
lineItemLabel: string;
|
lineItemLabel: string;
|
||||||
@@ -333,7 +338,4 @@ export interface InvoicePdfTemplateAttributes {
|
|||||||
statementLabel: string;
|
statementLabel: string;
|
||||||
showStatement: boolean;
|
showStatement: boolean;
|
||||||
statement: string;
|
statement: string;
|
||||||
|
|
||||||
billedToAddress: string[];
|
|
||||||
billedFromAddres: string[];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,11 +163,13 @@ export interface ISaleReceiptBrandingTemplateAttributes {
|
|||||||
companyLogo: string;
|
companyLogo: string;
|
||||||
companyName: string;
|
companyName: string;
|
||||||
|
|
||||||
// Address
|
// Customer Address
|
||||||
billedToAddress: string[];
|
showCustomerAddress: boolean;
|
||||||
billedFromAddress: string[];
|
customerAddress: string;
|
||||||
showBilledFromAddress: boolean;
|
|
||||||
showBilledToAddress: boolean;
|
// Company address
|
||||||
|
showCompanyAddress: boolean;
|
||||||
|
companyAddress: string;
|
||||||
billedToLabel: string;
|
billedToLabel: string;
|
||||||
|
|
||||||
// Total
|
// Total
|
||||||
|
|||||||
7
packages/server/src/services/Attachments/utils.ts
Normal file
7
packages/server/src/services/Attachments/utils.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import config from '@/config';
|
||||||
|
|
||||||
|
|
||||||
|
export const getUploadedObjectUri = (objectKey: string) => {
|
||||||
|
return path.join(config.s3.endpoint, config.s3.bucket, objectKey);
|
||||||
|
}
|
||||||
@@ -1,26 +1,44 @@
|
|||||||
import { Inject } from "typedi";
|
import { Inject } from 'typedi';
|
||||||
import { GetPdfTemplate } from "../PdfTemplate/GetPdfTemplate";
|
import { GetPdfTemplate } from '../PdfTemplate/GetPdfTemplate';
|
||||||
import { defaultCreditNoteBrandingAttributes } from "./constants";
|
import { defaultCreditNoteBrandingAttributes } from './constants';
|
||||||
import { mergePdfTemplateWithDefaultAttributes } from "../Sales/Invoices/utils";
|
import { mergePdfTemplateWithDefaultAttributes } from '../Sales/Invoices/utils';
|
||||||
|
import { GetOrganizationBrandingAttributes } from '../PdfTemplate/GetOrganizationBrandingAttributes';
|
||||||
|
|
||||||
export class CreditNoteBrandingTemplate {
|
export class CreditNoteBrandingTemplate {
|
||||||
@Inject()
|
@Inject()
|
||||||
private getPdfTemplateService: GetPdfTemplate;
|
private getPdfTemplateService: GetPdfTemplate;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getOrgBrandingAttributes: GetOrganizationBrandingAttributes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the credit note branding template.
|
* Retrieves the credit note branding template.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
* @param {number} templateId
|
* @param {number} templateId
|
||||||
* @returns {}
|
* @returns {}
|
||||||
*/
|
*/
|
||||||
public async getCreditNoteBrandingTemplate(tenantId: number, templateId: number) {
|
public async getCreditNoteBrandingTemplate(
|
||||||
|
tenantId: number,
|
||||||
|
templateId: number
|
||||||
|
) {
|
||||||
const template = await this.getPdfTemplateService.getPdfTemplate(
|
const template = await this.getPdfTemplateService.getPdfTemplate(
|
||||||
tenantId,
|
tenantId,
|
||||||
templateId
|
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(
|
const attributes = mergePdfTemplateWithDefaultAttributes(
|
||||||
template.attributes,
|
template.attributes,
|
||||||
defaultCreditNoteBrandingAttributes
|
organizationBrandingAttrs
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
...template,
|
...template,
|
||||||
|
|||||||
@@ -34,8 +34,6 @@ export default class GetCreditNotePdf {
|
|||||||
tenantId,
|
tenantId,
|
||||||
creditNoteId
|
creditNoteId
|
||||||
);
|
);
|
||||||
console.log(brandingAttributes, 'brandingAttributes');
|
|
||||||
|
|
||||||
const htmlContent = await this.templateInjectable.render(
|
const htmlContent = await this.templateInjectable.render(
|
||||||
tenantId,
|
tenantId,
|
||||||
'modules/credit-note-standard',
|
'modules/credit-note-standard',
|
||||||
|
|||||||
@@ -80,24 +80,13 @@ export const defaultCreditNoteBrandingAttributes = {
|
|||||||
// # Company name
|
// # Company name
|
||||||
companyName: 'Bigcapital Technology, Inc.',
|
companyName: 'Bigcapital Technology, Inc.',
|
||||||
|
|
||||||
// Address
|
// # Customer address
|
||||||
billedToAddress: [
|
showCustomerAddress: true,
|
||||||
'Bigcapital Technology, Inc.',
|
customerAddress: '',
|
||||||
'131 Continental Dr Suite 305 Newark,',
|
|
||||||
'Delaware 19713',
|
// # Company address
|
||||||
'United States',
|
showCompanyAddress: true,
|
||||||
'+1 762-339-5634',
|
companyAddress: '',
|
||||||
'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,
|
|
||||||
billedToLabel: 'Billed To',
|
billedToLabel: 'Billed To',
|
||||||
|
|
||||||
// Total
|
// Total
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { CreditNotePdfTemplateAttributes, ICreditNote } from '@/interfaces';
|
import { CreditNotePdfTemplateAttributes, ICreditNote } from '@/interfaces';
|
||||||
|
import { contactAddressTextFormat } from '@/utils/address-text-format';
|
||||||
|
|
||||||
export const transformCreditNoteToPdfTemplate = (
|
export const transformCreditNoteToPdfTemplate = (
|
||||||
creditNote: ICreditNote
|
creditNote: ICreditNote
|
||||||
@@ -19,5 +20,6 @@ export const transformCreditNoteToPdfTemplate = (
|
|||||||
})),
|
})),
|
||||||
customerNote: creditNote.note,
|
customerNote: creditNote.note,
|
||||||
termsConditions: creditNote.termsConditions,
|
termsConditions: creditNote.termsConditions,
|
||||||
|
customerAddress: contactAddressTextFormat(creditNote.customer),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { Service } from 'typedi';
|
||||||
|
import { TenantMetadata } from '@/system/models';
|
||||||
|
import { CommonOrganizationBrandingAttributes } from './types';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class GetOrganizationBrandingAttributes {
|
||||||
|
/**
|
||||||
|
* Retrieves the given organization branding attributes initial state.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @returns {Promise<CommonOrganizationBrandingAttributes>}
|
||||||
|
*/
|
||||||
|
async getOrganizationBrandingAttributes(
|
||||||
|
tenantId: number
|
||||||
|
): Promise<CommonOrganizationBrandingAttributes> {
|
||||||
|
const tenantMetadata = await TenantMetadata.query().findOne({ tenantId });
|
||||||
|
|
||||||
|
const companyName = tenantMetadata?.name;
|
||||||
|
const primaryColor = tenantMetadata?.primaryColor;
|
||||||
|
const companyLogoKey = tenantMetadata?.logoKey;
|
||||||
|
const companyLogoUri = tenantMetadata?.logoUri;
|
||||||
|
const companyAddress = tenantMetadata?.addressTextFormatted;
|
||||||
|
|
||||||
|
return {
|
||||||
|
companyName,
|
||||||
|
companyAddress,
|
||||||
|
companyLogoUri,
|
||||||
|
companyLogoKey,
|
||||||
|
primaryColor,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { GetOrganizationBrandingAttributes } from './GetOrganizationBrandingAttributes';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class GetPdfTemplateBrandingState {
|
||||||
|
@Inject()
|
||||||
|
private getOrgBrandingAttributes: GetOrganizationBrandingAttributes;
|
||||||
|
|
||||||
|
getBrandingState(tenantId: number) {
|
||||||
|
const brandingAttributes =
|
||||||
|
this.getOrgBrandingAttributes.getOrganizationBrandingAttributes(tenantId);
|
||||||
|
|
||||||
|
return brandingAttributes;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Transformer } from '@/lib/Transformer/Transformer';
|
import { Transformer } from '@/lib/Transformer/Transformer';
|
||||||
import { getTransactionTypeLabel } from '@/utils/transactions-types';
|
import { getTransactionTypeLabel } from '@/utils/transactions-types';
|
||||||
|
import { getUploadedObjectUri } from '../Attachments/utils';
|
||||||
|
|
||||||
export class GetPdfTemplateTransformer extends Transformer {
|
export class GetPdfTemplateTransformer extends Transformer {
|
||||||
/**
|
/**
|
||||||
@@ -56,7 +57,7 @@ class GetPdfTemplateAttributesTransformer extends Transformer {
|
|||||||
*/
|
*/
|
||||||
protected companyLogoUri(template) {
|
protected companyLogoUri(template) {
|
||||||
return template.companyLogoKey
|
return template.companyLogoKey
|
||||||
? `https://bigcapital.sfo3.digitaloceanspaces.com/${template.companyLogoKey}`
|
? getUploadedObjectUri(template.companyLogoKey)
|
||||||
: '';
|
: '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { GetPdfTemplate } from './GetPdfTemplate';
|
|||||||
import { GetPdfTemplates } from './GetPdfTemplates';
|
import { GetPdfTemplates } from './GetPdfTemplates';
|
||||||
import { EditPdfTemplate } from './EditPdfTemplate';
|
import { EditPdfTemplate } from './EditPdfTemplate';
|
||||||
import { AssignPdfTemplateDefault } from './AssignPdfTemplateDefault';
|
import { AssignPdfTemplateDefault } from './AssignPdfTemplateDefault';
|
||||||
|
import { GetPdfTemplateBrandingState } from './GetPdfTemplateBrandingState';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class PdfTemplateApplication {
|
export class PdfTemplateApplication {
|
||||||
@@ -27,6 +28,9 @@ export class PdfTemplateApplication {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private assignPdfTemplateDefaultService: AssignPdfTemplateDefault;
|
private assignPdfTemplateDefaultService: AssignPdfTemplateDefault;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getPdfTemplateBrandingStateService: GetPdfTemplateBrandingState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new PDF template.
|
* Creates a new PDF template.
|
||||||
* @param {number} tenantId -
|
* @param {number} tenantId -
|
||||||
@@ -120,4 +124,12 @@ export class PdfTemplateApplication {
|
|||||||
templateId
|
templateId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {number} tenantId
|
||||||
|
*/
|
||||||
|
public async getPdfTemplateBrandingState(tenantId: number) {
|
||||||
|
return this.getPdfTemplateBrandingStateService.getBrandingState(tenantId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,3 +65,12 @@ export interface ICreateInvoicePdfTemplateDTO {
|
|||||||
statementLabel?: string;
|
statementLabel?: string;
|
||||||
showStatement?: boolean;
|
showStatement?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface CommonOrganizationBrandingAttributes {
|
||||||
|
companyName?: string;
|
||||||
|
primaryColor?: string;
|
||||||
|
companyLogoKey?: string;
|
||||||
|
companyLogoUri?: string;
|
||||||
|
companyAddress?: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -185,23 +185,10 @@ export const defaultEstimatePdfBrandingAttributes = {
|
|||||||
|
|
||||||
companyName: '',
|
companyName: '',
|
||||||
|
|
||||||
billedToAddress: [
|
customerAddress: '',
|
||||||
'Bigcapital Technology, Inc.',
|
companyAddress: '',
|
||||||
'131 Continental Dr Suite 305 Newark,',
|
showCustomerAddress: true,
|
||||||
'Delaware 19713',
|
showCompanyAddress: true,
|
||||||
'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,
|
|
||||||
billedToLabel: 'Billed To',
|
billedToLabel: 'Billed To',
|
||||||
|
|
||||||
total: '$1000.00',
|
total: '$1000.00',
|
||||||
@@ -244,7 +231,6 @@ export const defaultEstimatePdfBrandingAttributes = {
|
|||||||
expirationDate: 'September 3, 2024',
|
expirationDate: 'September 3, 2024',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
interface EstimatePdfBrandingLineItem {
|
interface EstimatePdfBrandingLineItem {
|
||||||
item: string;
|
item: string;
|
||||||
description: string;
|
description: string;
|
||||||
@@ -260,10 +246,13 @@ export interface EstimatePdfBrandingAttributes {
|
|||||||
companyLogo: string;
|
companyLogo: string;
|
||||||
companyName: string;
|
companyName: string;
|
||||||
|
|
||||||
billedToAddress: string[];
|
// Customer Address
|
||||||
billedFromAddress: string[];
|
showCustomerAddress: boolean;
|
||||||
showBilledFromAddress: boolean;
|
customerAddress: string;
|
||||||
showBilledToAddress: boolean;
|
|
||||||
|
// Company Address
|
||||||
|
showCompanyAddress: boolean;
|
||||||
|
companyAddress: string;
|
||||||
billedToLabel: string;
|
billedToLabel: string;
|
||||||
|
|
||||||
total: string;
|
total: string;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { contactAddressTextFormat } from '@/utils/address-text-format';
|
||||||
import { EstimatePdfBrandingAttributes } from './constants';
|
import { EstimatePdfBrandingAttributes } from './constants';
|
||||||
|
|
||||||
export const transformEstimateToPdfTemplate = (
|
export const transformEstimateToPdfTemplate = (
|
||||||
@@ -18,5 +19,6 @@ export const transformEstimateToPdfTemplate = (
|
|||||||
subtotal: estimate.formattedSubtotal,
|
subtotal: estimate.formattedSubtotal,
|
||||||
customerNote: estimate.customerNote,
|
customerNote: estimate.customerNote,
|
||||||
termsConditions: estimate.termsConditions,
|
termsConditions: estimate.termsConditions,
|
||||||
|
customerAddress: contactAddressTextFormat(estimate.customer),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,12 +2,16 @@ import { Inject, Service } from 'typedi';
|
|||||||
import { mergePdfTemplateWithDefaultAttributes } from './utils';
|
import { mergePdfTemplateWithDefaultAttributes } from './utils';
|
||||||
import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate';
|
import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate';
|
||||||
import { defaultEstimatePdfBrandingAttributes } from '../Estimates/constants';
|
import { defaultEstimatePdfBrandingAttributes } from '../Estimates/constants';
|
||||||
|
import { GetOrganizationBrandingAttributes } from '@/services/PdfTemplate/GetOrganizationBrandingAttributes';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class SaleEstimatePdfTemplate {
|
export class SaleEstimatePdfTemplate {
|
||||||
@Inject()
|
@Inject()
|
||||||
private getPdfTemplateService: GetPdfTemplate;
|
private getPdfTemplateService: GetPdfTemplate;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getOrgBrandingAttrs: GetOrganizationBrandingAttributes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the estimate pdf template.
|
* Retrieves the estimate pdf template.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -19,9 +23,19 @@ export class SaleEstimatePdfTemplate {
|
|||||||
tenantId,
|
tenantId,
|
||||||
estimateTemplateId
|
estimateTemplateId
|
||||||
);
|
);
|
||||||
|
// Retreives the organization branding attributes.
|
||||||
|
const commonOrgBrandingAttrs =
|
||||||
|
await this.getOrgBrandingAttrs.getOrganizationBrandingAttributes(
|
||||||
|
tenantId
|
||||||
|
);
|
||||||
|
// Merge the default branding attributes with organization attrs.
|
||||||
|
const orgainizationBrandingAttrs = {
|
||||||
|
...defaultEstimatePdfBrandingAttributes,
|
||||||
|
...commonOrgBrandingAttrs,
|
||||||
|
};
|
||||||
const attributes = mergePdfTemplateWithDefaultAttributes(
|
const attributes = mergePdfTemplateWithDefaultAttributes(
|
||||||
template.attributes,
|
template.attributes,
|
||||||
defaultEstimatePdfBrandingAttributes
|
orgainizationBrandingAttrs
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
...template,
|
...template,
|
||||||
|
|||||||
@@ -2,26 +2,39 @@ import { Inject, Service } from 'typedi';
|
|||||||
import { mergePdfTemplateWithDefaultAttributes } from './utils';
|
import { mergePdfTemplateWithDefaultAttributes } from './utils';
|
||||||
import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate';
|
import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate';
|
||||||
import { defaultInvoicePdfTemplateAttributes } from './constants';
|
import { defaultInvoicePdfTemplateAttributes } from './constants';
|
||||||
|
import { GetOrganizationBrandingAttributes } from '@/services/PdfTemplate/GetOrganizationBrandingAttributes';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class SaleInvoicePdfTemplate {
|
export class SaleInvoicePdfTemplate {
|
||||||
@Inject()
|
@Inject()
|
||||||
private getPdfTemplateService: GetPdfTemplate;
|
private getPdfTemplateService: GetPdfTemplate;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getOrgBrandingAttributes: GetOrganizationBrandingAttributes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the invoice pdf template.
|
* Retrieves the invoice pdf template.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
* @param {number} invoiceTemplateId
|
* @param {number} invoiceTemplateId
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async getInvoicePdfTemplate(tenantId: number, invoiceTemplateId: number){
|
async getInvoicePdfTemplate(tenantId: number, invoiceTemplateId: number) {
|
||||||
const template = await this.getPdfTemplateService.getPdfTemplate(
|
const template = await this.getPdfTemplateService.getPdfTemplate(
|
||||||
tenantId,
|
tenantId,
|
||||||
invoiceTemplateId
|
invoiceTemplateId
|
||||||
);
|
);
|
||||||
|
// Retrieves the organization branding attributes.
|
||||||
|
const commonOrgBrandingAttrs =
|
||||||
|
await this.getOrgBrandingAttributes.getOrganizationBrandingAttributes(
|
||||||
|
tenantId
|
||||||
|
);
|
||||||
|
const organizationBrandingAttrs = {
|
||||||
|
...defaultInvoicePdfTemplateAttributes,
|
||||||
|
...commonOrgBrandingAttrs,
|
||||||
|
};
|
||||||
const attributes = mergePdfTemplateWithDefaultAttributes(
|
const attributes = mergePdfTemplateWithDefaultAttributes(
|
||||||
template.attributes,
|
template.attributes,
|
||||||
defaultInvoicePdfTemplateAttributes
|
organizationBrandingAttrs
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
...template,
|
...template,
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ export const SaleInvoicesSampleData = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const defaultInvoicePdfTemplateAttributes = {
|
export const defaultInvoicePdfTemplateAttributes = {
|
||||||
primaryColor: 'red',
|
primaryColor: 'red',
|
||||||
secondaryColor: 'red',
|
secondaryColor: 'red',
|
||||||
|
|
||||||
@@ -179,13 +179,17 @@ export const defaultInvoicePdfTemplateAttributes = {
|
|||||||
dateIssueLabel: 'Date of issue',
|
dateIssueLabel: 'Date of issue',
|
||||||
showDateIssue: true,
|
showDateIssue: true,
|
||||||
|
|
||||||
// dateIssue,
|
// # Invoice number,
|
||||||
invoiceNumberLabel: 'Invoice number',
|
invoiceNumberLabel: 'Invoice number',
|
||||||
showInvoiceNumber: true,
|
showInvoiceNumber: true,
|
||||||
|
|
||||||
// Address
|
// # Customer address
|
||||||
showBillingToAddress: true,
|
showCustomerAddress: true,
|
||||||
showBilledFromAddress: true,
|
customerAddress: '',
|
||||||
|
|
||||||
|
// # Company address
|
||||||
|
showCompanyAddress: true,
|
||||||
|
companyAddress: '',
|
||||||
billedToLabel: 'Billed To',
|
billedToLabel: 'Billed To',
|
||||||
|
|
||||||
// Entries
|
// Entries
|
||||||
@@ -229,22 +233,7 @@ export const defaultInvoicePdfTemplateAttributes = {
|
|||||||
{ label: 'Sample Tax2 (7.00%)', amount: '21.74' },
|
{ label: 'Sample Tax2 (7.00%)', amount: '21.74' },
|
||||||
],
|
],
|
||||||
|
|
||||||
|
// # Statement
|
||||||
statementLabel: 'Statement',
|
statementLabel: 'Statement',
|
||||||
showStatement: true,
|
showStatement: true,
|
||||||
billedToAddress: [
|
};
|
||||||
'Bigcapital Technology, Inc.',
|
|
||||||
'131 Continental Dr Suite 305 Newark,',
|
|
||||||
'Delaware 19713',
|
|
||||||
'United States',
|
|
||||||
'+1 762-339-5634',
|
|
||||||
'ahmed@bigcapital.app',
|
|
||||||
],
|
|
||||||
billedFromAddres: [
|
|
||||||
'131 Continental Dr Suite 305 Newark,',
|
|
||||||
'Delaware 19713',
|
|
||||||
'United States',
|
|
||||||
'+1 762-339-5634',
|
|
||||||
'ahmed@bigcapital.app',
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { pickBy } from 'lodash';
|
import { pickBy } from 'lodash';
|
||||||
import { InvoicePdfTemplateAttributes, ISaleInvoice } from '@/interfaces';
|
import { InvoicePdfTemplateAttributes, ISaleInvoice } from '@/interfaces';
|
||||||
|
import { contactAddressTextFormat } from '@/utils/address-text-format';
|
||||||
|
|
||||||
export const mergePdfTemplateWithDefaultAttributes = (
|
export const mergePdfTemplateWithDefaultAttributes = (
|
||||||
brandingTemplate?: Record<string, any>,
|
brandingTemplate?: Record<string, any>,
|
||||||
@@ -42,5 +43,7 @@ export const transformInvoiceToPdfTemplate = (
|
|||||||
label: tax.name,
|
label: tax.name,
|
||||||
amount: tax.taxRateAmountFormatted,
|
amount: tax.taxRateAmountFormatted,
|
||||||
})),
|
})),
|
||||||
|
|
||||||
|
customerAddress: contactAddressTextFormat(invoice.customer),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,12 +3,16 @@ import { Inject, Service } from 'typedi';
|
|||||||
import { mergePdfTemplateWithDefaultAttributes } from '../Invoices/utils';
|
import { mergePdfTemplateWithDefaultAttributes } from '../Invoices/utils';
|
||||||
import { defaultPaymentReceivedPdfTemplateAttributes } from './constants';
|
import { defaultPaymentReceivedPdfTemplateAttributes } from './constants';
|
||||||
import { PdfTemplate } from '@/models/PdfTemplate';
|
import { PdfTemplate } from '@/models/PdfTemplate';
|
||||||
|
import { GetOrganizationBrandingAttributes } from '@/services/PdfTemplate/GetOrganizationBrandingAttributes';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class PaymentReceivedBrandingTemplate {
|
export class PaymentReceivedBrandingTemplate {
|
||||||
@Inject()
|
@Inject()
|
||||||
private getPdfTemplateService: GetPdfTemplate;
|
private getPdfTemplateService: GetPdfTemplate;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getOrgBrandingAttributes: GetOrganizationBrandingAttributes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the payment received pdf template.
|
* Retrieves the payment received pdf template.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -18,14 +22,24 @@ export class PaymentReceivedBrandingTemplate {
|
|||||||
public async getPaymentReceivedPdfTemplate(
|
public async getPaymentReceivedPdfTemplate(
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
paymentTemplateId: number
|
paymentTemplateId: number
|
||||||
) {
|
) {
|
||||||
const template = await this.getPdfTemplateService.getPdfTemplate(
|
const template = await this.getPdfTemplateService.getPdfTemplate(
|
||||||
tenantId,
|
tenantId,
|
||||||
paymentTemplateId
|
paymentTemplateId
|
||||||
);
|
);
|
||||||
|
// Retrieves the organization branding attributes.
|
||||||
|
const commonOrgBrandingAttrs =
|
||||||
|
await this.getOrgBrandingAttributes.getOrganizationBrandingAttributes(
|
||||||
|
tenantId
|
||||||
|
);
|
||||||
|
// Merges the default branding attributes with common organization branding attrs.
|
||||||
|
const organizationBrandingAttrs = {
|
||||||
|
...defaultPaymentReceivedPdfTemplateAttributes,
|
||||||
|
...commonOrgBrandingAttrs,
|
||||||
|
};
|
||||||
const attributes = mergePdfTemplateWithDefaultAttributes(
|
const attributes = mergePdfTemplateWithDefaultAttributes(
|
||||||
template.attributes,
|
template.attributes,
|
||||||
defaultPaymentReceivedPdfTemplateAttributes
|
organizationBrandingAttrs
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
...template,
|
...template,
|
||||||
|
|||||||
@@ -58,24 +58,13 @@ export const defaultPaymentReceivedPdfTemplateAttributes = {
|
|||||||
// # Company name
|
// # Company name
|
||||||
companyName: 'Bigcapital Technology, Inc.',
|
companyName: 'Bigcapital Technology, Inc.',
|
||||||
|
|
||||||
// Address
|
// # Customer address
|
||||||
billedToAddress: [
|
showCustomerAddress: true,
|
||||||
'Bigcapital Technology, Inc.',
|
customerAddress: '',
|
||||||
'131 Continental Dr Suite 305 Newark,',
|
|
||||||
'Delaware 19713',
|
// # Company address
|
||||||
'United States',
|
showCompanyAddress: true,
|
||||||
'+1 762-339-5634',
|
companyAddress: '',
|
||||||
'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,
|
|
||||||
billedToLabel: 'Billed To',
|
billedToLabel: 'Billed To',
|
||||||
|
|
||||||
// Total
|
// Total
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
IPaymentReceived,
|
IPaymentReceived,
|
||||||
PaymentReceivedPdfTemplateAttributes,
|
PaymentReceivedPdfTemplateAttributes,
|
||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
|
import { contactAddressTextFormat } from '@/utils/address-text-format';
|
||||||
|
|
||||||
export const transformPaymentReceivedToPdfTemplate = (
|
export const transformPaymentReceivedToPdfTemplate = (
|
||||||
payment: IPaymentReceived
|
payment: IPaymentReceived
|
||||||
@@ -17,5 +18,6 @@ export const transformPaymentReceivedToPdfTemplate = (
|
|||||||
invoiceAmount: entry.invoice.totalFormatted,
|
invoiceAmount: entry.invoice.totalFormatted,
|
||||||
paidAmount: entry.paymentAmountFormatted,
|
paidAmount: entry.paymentAmountFormatted,
|
||||||
})),
|
})),
|
||||||
|
customerAddress: contactAddressTextFormat(payment.customer),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,12 +2,15 @@ import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate';
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import { defaultSaleReceiptBrandingAttributes } from './constants';
|
import { defaultSaleReceiptBrandingAttributes } from './constants';
|
||||||
import { mergePdfTemplateWithDefaultAttributes } from '../Invoices/utils';
|
import { mergePdfTemplateWithDefaultAttributes } from '../Invoices/utils';
|
||||||
|
import { GetOrganizationBrandingAttributes } from '@/services/PdfTemplate/GetOrganizationBrandingAttributes';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class SaleReceiptBrandingTemplate {
|
export class SaleReceiptBrandingTemplate {
|
||||||
@Inject()
|
@Inject()
|
||||||
private getPdfTemplateService: GetPdfTemplate;
|
private getPdfTemplateService: GetPdfTemplate;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getOrgBrandingAttributes: GetOrganizationBrandingAttributes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the sale receipt branding template.
|
* Retrieves the sale receipt branding template.
|
||||||
@@ -23,9 +26,20 @@ export class SaleReceiptBrandingTemplate {
|
|||||||
tenantId,
|
tenantId,
|
||||||
templateId
|
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(
|
const attributes = mergePdfTemplateWithDefaultAttributes(
|
||||||
template.attributes,
|
template.attributes,
|
||||||
defaultSaleReceiptBrandingAttributes
|
organizationBrandingAttrs
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
...template,
|
...template,
|
||||||
|
|||||||
@@ -76,26 +76,16 @@ export const defaultSaleReceiptBrandingAttributes = {
|
|||||||
companyLogoUri: '',
|
companyLogoUri: '',
|
||||||
companyLogoKey: '',
|
companyLogoKey: '',
|
||||||
|
|
||||||
// # Address
|
// # Customer address
|
||||||
billedToAddress: [
|
showCustomerAddress: true,
|
||||||
'Bigcapital Technology, Inc.',
|
customerAddress: '',
|
||||||
'131 Continental Dr Suite 305 Newark,',
|
|
||||||
'Delaware 19713',
|
// # Company address
|
||||||
'United States',
|
showCompanyAddress: true,
|
||||||
'+1 762-339-5634',
|
companyAddress: '',
|
||||||
'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,
|
|
||||||
billedToLabel: 'Billed To',
|
billedToLabel: 'Billed To',
|
||||||
|
|
||||||
|
// # Total
|
||||||
total: '$1000.00',
|
total: '$1000.00',
|
||||||
totalLabel: 'Total',
|
totalLabel: 'Total',
|
||||||
showTotal: true,
|
showTotal: true,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { ISaleReceipt, ISaleReceiptBrandingTemplateAttributes } from "@/interfaces";
|
import { ISaleReceipt, ISaleReceiptBrandingTemplateAttributes } from "@/interfaces";
|
||||||
|
import { contactAddressTextFormat } from "@/utils/address-text-format";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -13,8 +14,8 @@ export const transformReceiptToBrandingTemplateAttributes = (saleReceipt: ISaleR
|
|||||||
quantity: entry.quantityFormatted,
|
quantity: entry.quantityFormatted,
|
||||||
total: entry.totalFormatted,
|
total: entry.totalFormatted,
|
||||||
})),
|
})),
|
||||||
|
|
||||||
receiptNumber: saleReceipt.receiptNumber,
|
receiptNumber: saleReceipt.receiptNumber,
|
||||||
receiptDate: saleReceipt.formattedReceiptDate,
|
receiptDate: saleReceipt.formattedReceiptDate,
|
||||||
|
customerAddress: contactAddressTextFormat(saleReceipt.customer),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { addressTextFormat } from '@/utils/address-text-format';
|
import { organizationAddressTextFormat } from '@/utils/address-text-format';
|
||||||
import BaseModel from 'models/Model';
|
import BaseModel from 'models/Model';
|
||||||
|
import { getUploadedObjectUri } from '../../services/Attachments/utils';
|
||||||
|
|
||||||
export default class TenantMetadata extends BaseModel {
|
export default class TenantMetadata extends BaseModel {
|
||||||
baseCurrency!: string;
|
baseCurrency!: string;
|
||||||
@@ -58,9 +59,7 @@ export default class TenantMetadata extends BaseModel {
|
|||||||
* @returns {string | null}
|
* @returns {string | null}
|
||||||
*/
|
*/
|
||||||
public get logoUri() {
|
public get logoUri() {
|
||||||
return this.logoKey
|
return this.logoKey ? getUploadedObjectUri(this.logoKey) : null;
|
||||||
? `https://bigcapital.sfo3.digitaloceanspaces.com/${this.logoKey}`
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,7 +74,7 @@ export default class TenantMetadata extends BaseModel {
|
|||||||
{POSTAL_CODE},
|
{POSTAL_CODE},
|
||||||
{COUNTRY}
|
{COUNTRY}
|
||||||
`;
|
`;
|
||||||
return addressTextFormat(defaultMessage, {
|
return organizationAddressTextFormat(defaultMessage, {
|
||||||
organizationName: this.name,
|
organizationName: this.name,
|
||||||
address1: this.address?.address1,
|
address1: this.address?.address1,
|
||||||
address2: this.address?.address2,
|
address2: this.address?.address2,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { IContact } from '@/interfaces';
|
||||||
|
|
||||||
interface OrganizationAddressFormatArgs {
|
interface OrganizationAddressFormatArgs {
|
||||||
organizationName?: string;
|
organizationName?: string;
|
||||||
address1?: string;
|
address1?: string;
|
||||||
@@ -17,7 +19,19 @@ const defaultMessage = `
|
|||||||
{COUNTRY}
|
{COUNTRY}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const addressTextFormat = (
|
const formatText = (message: string, replacements: Record<string, string>) => {
|
||||||
|
let formattedMessage = Object.entries(replacements).reduce(
|
||||||
|
(msg, [key, value]) => {
|
||||||
|
return msg.split(`{${key}}`).join(value || '');
|
||||||
|
},
|
||||||
|
message
|
||||||
|
);
|
||||||
|
formattedMessage = formattedMessage.replace(/\n/g, '<br />');
|
||||||
|
|
||||||
|
return formattedMessage.trim();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const organizationAddressTextFormat = (
|
||||||
message: string,
|
message: string,
|
||||||
args: OrganizationAddressFormatArgs
|
args: OrganizationAddressFormatArgs
|
||||||
) => {
|
) => {
|
||||||
@@ -30,13 +44,53 @@ export const addressTextFormat = (
|
|||||||
POSTAL_CODE: args.postalCode || '',
|
POSTAL_CODE: args.postalCode || '',
|
||||||
COUNTRY: args.country || '',
|
COUNTRY: args.country || '',
|
||||||
};
|
};
|
||||||
let formattedMessage = Object.entries(replacements).reduce(
|
return formatText(message, replacements);
|
||||||
(msg, [key, value]) => {
|
};
|
||||||
return value ? msg.split(`{${key}}`).join(value) : msg;
|
|
||||||
},
|
interface ContactAddressTextFormatArgs {
|
||||||
message
|
displayName?: string;
|
||||||
);
|
state?: string;
|
||||||
formattedMessage = formattedMessage.replace(/\n/g, '<br />');
|
postalCode?: string;
|
||||||
|
email?: string;
|
||||||
return formattedMessage.trim();
|
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<string, string> = {
|
||||||
|
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);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ United States, <br />
|
|||||||
ahmed@bigcapital.app
|
ahmed@bigcapital.app
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
||||||
export const DefaultPdfTemplateAddressBilledFrom = `131 Continental Dr Suite 305 Newark, <br />
|
export const DefaultPdfTemplateAddressBilledFrom = `131 Continental Dr Suite 305 Newark, <br />
|
||||||
Delaware 19713,<br />
|
Delaware 19713,<br />
|
||||||
United States, <br />
|
United States, <br />
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import React, { createContext, useContext } from 'react';
|
import React, { createContext, useContext } from 'react';
|
||||||
import {
|
import {
|
||||||
|
GetPdfTemplateBrandingStateResponse,
|
||||||
GetPdfTemplateResponse,
|
GetPdfTemplateResponse,
|
||||||
useGetPdfTemplate,
|
useGetPdfTemplate,
|
||||||
|
useGetPdfTemplateBrandingState,
|
||||||
} from '@/hooks/query/pdf-templates';
|
} from '@/hooks/query/pdf-templates';
|
||||||
import { Spinner } from '@blueprintjs/core';
|
import { Spinner } from '@blueprintjs/core';
|
||||||
|
|
||||||
@@ -9,6 +11,10 @@ interface PdfTemplateContextValue {
|
|||||||
templateId: number | string;
|
templateId: number | string;
|
||||||
pdfTemplate: GetPdfTemplateResponse | undefined;
|
pdfTemplate: GetPdfTemplateResponse | undefined;
|
||||||
isPdfTemplateLoading: boolean;
|
isPdfTemplateLoading: boolean;
|
||||||
|
|
||||||
|
// Branding state.
|
||||||
|
brandingTemplateState: GetPdfTemplateBrandingStateResponse | undefined;
|
||||||
|
isBrandingTemplateLoading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BrandingTemplateProps {
|
interface BrandingTemplateProps {
|
||||||
@@ -28,15 +34,23 @@ export const BrandingTemplateBoot = ({
|
|||||||
useGetPdfTemplate(templateId, {
|
useGetPdfTemplate(templateId, {
|
||||||
enabled: !!templateId,
|
enabled: !!templateId,
|
||||||
});
|
});
|
||||||
|
// Retreives the branding template state.
|
||||||
|
const { data: brandingTemplateState, isLoading: isBrandingTemplateLoading } =
|
||||||
|
useGetPdfTemplateBrandingState();
|
||||||
|
|
||||||
const value = {
|
const value = {
|
||||||
templateId,
|
templateId,
|
||||||
pdfTemplate,
|
pdfTemplate,
|
||||||
isPdfTemplateLoading,
|
isPdfTemplateLoading,
|
||||||
|
|
||||||
|
brandingTemplateState,
|
||||||
|
isBrandingTemplateLoading,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isPdfTemplateLoading) {
|
const isLoading = isPdfTemplateLoading || isBrandingTemplateLoading;
|
||||||
return <Spinner size={20} />
|
|
||||||
|
if (isLoading) {
|
||||||
|
return <Spinner size={20} />;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<PdfTemplateContext.Provider value={value}>
|
<PdfTemplateContext.Provider value={value}>
|
||||||
|
|||||||
@@ -44,15 +44,16 @@ export const useBrandingTemplateFormInitialValues = <
|
|||||||
>(
|
>(
|
||||||
initialValues = {},
|
initialValues = {},
|
||||||
) => {
|
) => {
|
||||||
const { pdfTemplate } = useBrandingTemplateBoot();
|
const { pdfTemplate, brandingTemplateState } = useBrandingTemplateBoot();
|
||||||
|
|
||||||
const defaultPdfTemplate = {
|
const brandingAttributes = {
|
||||||
templateName: pdfTemplate?.templateName,
|
templateName: pdfTemplate?.templateName,
|
||||||
|
...brandingTemplateState,
|
||||||
...pdfTemplate?.attributes,
|
...pdfTemplate?.attributes,
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
...initialValues,
|
...initialValues,
|
||||||
...(transformToForm(defaultPdfTemplate, initialValues) as T),
|
...(transformToForm(brandingAttributes, initialValues) as T),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,10 +14,12 @@ import {
|
|||||||
|
|
||||||
export interface CreditNotePaperTemplateProps extends PaperTemplateProps {
|
export interface CreditNotePaperTemplateProps extends PaperTemplateProps {
|
||||||
// Address
|
// Address
|
||||||
billedToAddress?: string;
|
showCustomerAddress?: boolean;
|
||||||
billedFromAddress?: string;
|
customerAddress?: string;
|
||||||
showBilledToAddress?: boolean;
|
|
||||||
showBilledFromAddress?: boolean;
|
showCompanyAddress?: boolean;
|
||||||
|
companyAddress?: string;
|
||||||
|
|
||||||
billedToLabel?: string;
|
billedToLabel?: string;
|
||||||
|
|
||||||
// Total
|
// Total
|
||||||
@@ -72,11 +74,12 @@ export function CreditNotePaperTemplate({
|
|||||||
companyName = 'Bigcapital Technology, Inc.',
|
companyName = 'Bigcapital Technology, Inc.',
|
||||||
|
|
||||||
// Address
|
// Address
|
||||||
billedToAddress = DefaultPdfTemplateAddressBilledTo,
|
showCustomerAddress = true,
|
||||||
billedFromAddress = DefaultPdfTemplateAddressBilledFrom,
|
customerAddress = DefaultPdfTemplateAddressBilledTo,
|
||||||
|
|
||||||
|
showCompanyAddress = true,
|
||||||
|
companyAddress = DefaultPdfTemplateAddressBilledFrom,
|
||||||
|
|
||||||
showBilledFromAddress = true,
|
|
||||||
showBilledToAddress = true,
|
|
||||||
billedToLabel = 'Billed To',
|
billedToLabel = 'Billed To',
|
||||||
|
|
||||||
// Total
|
// Total
|
||||||
@@ -141,16 +144,16 @@ export function CreditNotePaperTemplate({
|
|||||||
</PaperTemplate.TermsList>
|
</PaperTemplate.TermsList>
|
||||||
|
|
||||||
<PaperTemplate.AddressesGroup>
|
<PaperTemplate.AddressesGroup>
|
||||||
{showBilledFromAddress && (
|
{showCompanyAddress && (
|
||||||
<PaperTemplate.Address>
|
<PaperTemplate.Address>
|
||||||
<strong>{companyName}</strong>
|
<Box dangerouslySetInnerHTML={{ __html: companyAddress }} />
|
||||||
<Box dangerouslySetInnerHTML={{ __html: billedFromAddress }} />
|
|
||||||
</PaperTemplate.Address>
|
</PaperTemplate.Address>
|
||||||
)}
|
)}
|
||||||
{showBilledToAddress && (
|
|
||||||
|
{showCustomerAddress && (
|
||||||
<PaperTemplate.Address>
|
<PaperTemplate.Address>
|
||||||
<strong>{billedToLabel}</strong>
|
<strong>{billedToLabel}</strong>
|
||||||
<Box dangerouslySetInnerHTML={{ __html: billedToAddress }} />
|
<Box dangerouslySetInnerHTML={{ __html: customerAddress }} />
|
||||||
</PaperTemplate.Address>
|
</PaperTemplate.Address>
|
||||||
)}
|
)}
|
||||||
</PaperTemplate.AddressesGroup>
|
</PaperTemplate.AddressesGroup>
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ export const initialValues = {
|
|||||||
companyLogoUri: '',
|
companyLogoUri: '',
|
||||||
|
|
||||||
// Address
|
// Address
|
||||||
showBilledToAddress: true,
|
showCustomerAddress: true,
|
||||||
showBilledFromAddress: true,
|
showCompanyAddress: true,
|
||||||
billedToLabel: 'Bill To',
|
companyAddress: '',
|
||||||
|
billedToLabel: 'Billed To',
|
||||||
|
|
||||||
// Entries
|
// Entries
|
||||||
itemNameLabel: 'Item',
|
itemNameLabel: 'Item',
|
||||||
|
|||||||
@@ -32,11 +32,11 @@ export interface EstimatePaperTemplateProps extends PaperTemplateProps {
|
|||||||
companyName?: string;
|
companyName?: string;
|
||||||
|
|
||||||
// Address
|
// Address
|
||||||
showBilledToAddress?: boolean;
|
showCustomerAddress?: boolean;
|
||||||
billedToAddress?: string;
|
customerAddress?: string;
|
||||||
|
|
||||||
showBilledFromAddress?: boolean;
|
showCompanyAddress?: boolean;
|
||||||
billedFromAddress?: string;
|
companyAddress?: string;
|
||||||
billedToLabel?: string;
|
billedToLabel?: string;
|
||||||
|
|
||||||
// Totals
|
// Totals
|
||||||
@@ -71,23 +71,27 @@ export function EstimatePaperTemplate({
|
|||||||
primaryColor,
|
primaryColor,
|
||||||
secondaryColor,
|
secondaryColor,
|
||||||
|
|
||||||
|
// # Company logo
|
||||||
showCompanyLogo = true,
|
showCompanyLogo = true,
|
||||||
companyLogoUri = '',
|
companyLogoUri = '',
|
||||||
|
|
||||||
companyName,
|
companyName,
|
||||||
|
|
||||||
// # Address
|
// # Company address
|
||||||
billedToAddress = DefaultPdfTemplateAddressBilledTo,
|
companyAddress = DefaultPdfTemplateAddressBilledFrom,
|
||||||
billedFromAddress = DefaultPdfTemplateAddressBilledFrom,
|
showCompanyAddress = true,
|
||||||
showBilledFromAddress = true,
|
|
||||||
showBilledToAddress = true,
|
// # Customer address
|
||||||
|
customerAddress = DefaultPdfTemplateAddressBilledTo,
|
||||||
|
showCustomerAddress = true,
|
||||||
billedToLabel = 'Billed To',
|
billedToLabel = 'Billed To',
|
||||||
|
|
||||||
// #Total
|
// # Total
|
||||||
total = '$1000.00',
|
total = '$1000.00',
|
||||||
totalLabel = 'Total',
|
totalLabel = 'Total',
|
||||||
showTotal = true,
|
showTotal = true,
|
||||||
|
|
||||||
|
// # Subtotal
|
||||||
subtotal = '1000/00',
|
subtotal = '1000/00',
|
||||||
subtotalLabel = 'Subtotal',
|
subtotalLabel = 'Subtotal',
|
||||||
showSubtotal = true,
|
showSubtotal = true,
|
||||||
@@ -111,14 +115,18 @@ export function EstimatePaperTemplate({
|
|||||||
total: '$1000.00',
|
total: '$1000.00',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
|
// Estimate number
|
||||||
showEstimateNumber = true,
|
showEstimateNumber = true,
|
||||||
estimateNumberLabel = 'Estimate Number',
|
estimateNumberLabel = 'Estimate Number',
|
||||||
estimateNumebr = '346D3D40-0001',
|
estimateNumebr = '346D3D40-0001',
|
||||||
|
|
||||||
|
// Estimate date
|
||||||
estimateDate = 'September 3, 2024',
|
estimateDate = 'September 3, 2024',
|
||||||
showEstimateDate = true,
|
showEstimateDate = true,
|
||||||
estimateDateLabel = 'Estimate Date',
|
estimateDateLabel = 'Estimate Date',
|
||||||
|
|
||||||
|
// Expiration date
|
||||||
expirationDateLabel = 'Expiration Date',
|
expirationDateLabel = 'Expiration Date',
|
||||||
showExpirationDate = true,
|
showExpirationDate = true,
|
||||||
expirationDate = 'September 3, 2024',
|
expirationDate = 'September 3, 2024',
|
||||||
@@ -151,16 +159,15 @@ export function EstimatePaperTemplate({
|
|||||||
</PaperTemplate.TermsList>
|
</PaperTemplate.TermsList>
|
||||||
|
|
||||||
<PaperTemplate.AddressesGroup>
|
<PaperTemplate.AddressesGroup>
|
||||||
{showBilledFromAddress && (
|
{showCompanyAddress && (
|
||||||
<PaperTemplate.Address>
|
<PaperTemplate.Address>
|
||||||
<strong>{companyName}</strong>
|
<Box dangerouslySetInnerHTML={{ __html: companyAddress }} />
|
||||||
<Box dangerouslySetInnerHTML={{ __html: billedFromAddress }} />
|
|
||||||
</PaperTemplate.Address>
|
</PaperTemplate.Address>
|
||||||
)}
|
)}
|
||||||
{showBilledToAddress && (
|
{showCustomerAddress && (
|
||||||
<PaperTemplate.Address>
|
<PaperTemplate.Address>
|
||||||
<strong>{billedToLabel}</strong>
|
<strong>{billedToLabel}</strong>
|
||||||
<Box dangerouslySetInnerHTML={{ __html: billedToAddress }} />
|
<Box dangerouslySetInnerHTML={{ __html: customerAddress }} />
|
||||||
</PaperTemplate.Address>
|
</PaperTemplate.Address>
|
||||||
)}
|
)}
|
||||||
</PaperTemplate.AddressesGroup>
|
</PaperTemplate.AddressesGroup>
|
||||||
|
|||||||
@@ -23,9 +23,12 @@ export const initialValues = {
|
|||||||
// Company name
|
// Company name
|
||||||
companyName: 'Bigcapital Technology, Inc.',
|
companyName: 'Bigcapital Technology, Inc.',
|
||||||
|
|
||||||
// Addresses
|
// Customer address
|
||||||
showBilledFromAddress: true,
|
showCustomerAddress: true,
|
||||||
showBilledToAddress: true,
|
|
||||||
|
// Company address
|
||||||
|
showCompanyAddress: true,
|
||||||
|
companyAddress: '',
|
||||||
billedToLabel: 'Billed To',
|
billedToLabel: 'Billed To',
|
||||||
|
|
||||||
// Entries
|
// Entries
|
||||||
@@ -45,6 +48,7 @@ export const initialValues = {
|
|||||||
showCustomerNote: true,
|
showCustomerNote: true,
|
||||||
customerNoteLabel: 'Customer Note',
|
customerNoteLabel: 'Customer Note',
|
||||||
|
|
||||||
|
// Terms & Conditions
|
||||||
showTermsConditions: true,
|
showTermsConditions: true,
|
||||||
termsConditionsLabel: 'Terms & Conditions',
|
termsConditionsLabel: 'Terms & Conditions',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,8 +45,12 @@ export interface InvoicePaperTemplateProps {
|
|||||||
bigtitle?: string;
|
bigtitle?: string;
|
||||||
|
|
||||||
// Address
|
// Address
|
||||||
showBillingToAddress?: boolean;
|
showCustomerAddress?: boolean;
|
||||||
showBilledFromAddress?: boolean;
|
customerAddress?: string;
|
||||||
|
|
||||||
|
showCompanyAddress?: boolean;
|
||||||
|
companyAddress?: string;
|
||||||
|
|
||||||
billedToLabel?: string;
|
billedToLabel?: string;
|
||||||
|
|
||||||
// Entries
|
// Entries
|
||||||
@@ -90,9 +94,6 @@ export interface InvoicePaperTemplateProps {
|
|||||||
|
|
||||||
lines?: Array<PapaerLine>;
|
lines?: Array<PapaerLine>;
|
||||||
taxes?: Array<PaperTax>;
|
taxes?: Array<PaperTax>;
|
||||||
|
|
||||||
billedFromAddres?: string;
|
|
||||||
billedToAddress?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function InvoicePaperTemplate({
|
export function InvoicePaperTemplate({
|
||||||
@@ -118,8 +119,12 @@ export function InvoicePaperTemplate({
|
|||||||
showInvoiceNumber = true,
|
showInvoiceNumber = true,
|
||||||
|
|
||||||
// Address
|
// Address
|
||||||
showBillingToAddress = true,
|
showCustomerAddress = true,
|
||||||
showBilledFromAddress = true,
|
customerAddress = DefaultPdfTemplateAddressBilledTo,
|
||||||
|
|
||||||
|
showCompanyAddress = true,
|
||||||
|
companyAddress = DefaultPdfTemplateAddressBilledFrom,
|
||||||
|
|
||||||
billedToLabel = 'Billed To',
|
billedToLabel = 'Billed To',
|
||||||
|
|
||||||
// Entries
|
// Entries
|
||||||
@@ -171,8 +176,6 @@ export function InvoicePaperTemplate({
|
|||||||
statementLabel = 'Statement',
|
statementLabel = 'Statement',
|
||||||
showStatement = true,
|
showStatement = true,
|
||||||
statement = DefaultPdfTemplateStatement,
|
statement = DefaultPdfTemplateStatement,
|
||||||
billedToAddress = DefaultPdfTemplateAddressBilledTo,
|
|
||||||
billedFromAddres = DefaultPdfTemplateAddressBilledFrom,
|
|
||||||
}: InvoicePaperTemplateProps) {
|
}: InvoicePaperTemplateProps) {
|
||||||
return (
|
return (
|
||||||
<PaperTemplate
|
<PaperTemplate
|
||||||
@@ -202,16 +205,16 @@ export function InvoicePaperTemplate({
|
|||||||
</PaperTemplate.TermsList>
|
</PaperTemplate.TermsList>
|
||||||
|
|
||||||
<PaperTemplate.AddressesGroup>
|
<PaperTemplate.AddressesGroup>
|
||||||
{showBilledFromAddress && (
|
{showCompanyAddress && (
|
||||||
<PaperTemplate.Address>
|
<PaperTemplate.Address>
|
||||||
<strong>{companyName}</strong>
|
<Box dangerouslySetInnerHTML={{ __html: companyAddress }} />
|
||||||
<Box dangerouslySetInnerHTML={{ __html: billedFromAddres }} />
|
|
||||||
</PaperTemplate.Address>
|
</PaperTemplate.Address>
|
||||||
)}
|
)}
|
||||||
{showBillingToAddress && (
|
|
||||||
|
{showCustomerAddress && (
|
||||||
<PaperTemplate.Address>
|
<PaperTemplate.Address>
|
||||||
<strong>{billedToLabel}</strong>
|
<strong>{billedToLabel}</strong>
|
||||||
<Box dangerouslySetInnerHTML={{ __html: billedToAddress }} />
|
<Box dangerouslySetInnerHTML={{ __html: customerAddress }} />
|
||||||
</PaperTemplate.Address>
|
</PaperTemplate.Address>
|
||||||
)}
|
)}
|
||||||
</PaperTemplate.AddressesGroup>
|
</PaperTemplate.AddressesGroup>
|
||||||
|
|||||||
@@ -120,19 +120,18 @@ PaperTemplate.MutedText = () => {};
|
|||||||
PaperTemplate.Text = () => {};
|
PaperTemplate.Text = () => {};
|
||||||
|
|
||||||
PaperTemplate.AddressesGroup = (props: GroupProps) => {
|
PaperTemplate.AddressesGroup = (props: GroupProps) => {
|
||||||
return <Group spacing={10} {...props} className={styles.addressRoot} />;
|
|
||||||
};
|
|
||||||
PaperTemplate.Address = ({
|
|
||||||
children,
|
|
||||||
}: {
|
|
||||||
children: React.ReactNode;
|
|
||||||
}) => {
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Group
|
||||||
{children}
|
spacing={10}
|
||||||
</Box>
|
align={'flex-start'}
|
||||||
|
{...props}
|
||||||
|
className={styles.addressRoot}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
PaperTemplate.Address = ({ children }: { children: React.ReactNode }) => {
|
||||||
|
return <Box>{children}</Box>;
|
||||||
|
};
|
||||||
|
|
||||||
PaperTemplate.Statement = ({
|
PaperTemplate.Statement = ({
|
||||||
label,
|
label,
|
||||||
|
|||||||
@@ -26,8 +26,9 @@ export const initialValues = {
|
|||||||
companyName: 'Bigcapital Technology, Inc.',
|
companyName: 'Bigcapital Technology, Inc.',
|
||||||
|
|
||||||
// Addresses
|
// Addresses
|
||||||
showBilledFromAddress: true,
|
showCustomerAddress: true,
|
||||||
showBillingToAddress: true,
|
showCompanyAddress: true,
|
||||||
|
companyAddress: '',
|
||||||
billedToLabel: 'Billed To',
|
billedToLabel: 'Billed To',
|
||||||
|
|
||||||
// Entries
|
// Entries
|
||||||
|
|||||||
@@ -10,11 +10,14 @@ import {
|
|||||||
} from '@/constants/PdfTemplates';
|
} from '@/constants/PdfTemplates';
|
||||||
|
|
||||||
export interface PaymentReceivedPaperTemplateProps extends PaperTemplateProps {
|
export interface PaymentReceivedPaperTemplateProps extends PaperTemplateProps {
|
||||||
billedToAddress?: string;
|
// Customer address
|
||||||
showBilledToAddress?: boolean;
|
showCustomerAddress?: boolean;
|
||||||
|
customerAddress?: string;
|
||||||
|
|
||||||
|
// Company address
|
||||||
|
showCompanyAddress?: boolean;
|
||||||
|
companyAddress?: string;
|
||||||
|
|
||||||
billedFromAddress?: string;
|
|
||||||
showBilledFromAddress?: boolean;
|
|
||||||
billedToLabel?: string;
|
billedToLabel?: string;
|
||||||
|
|
||||||
// Total.
|
// Total.
|
||||||
@@ -56,10 +59,14 @@ export function PaymentReceivedPaperTemplate({
|
|||||||
// # Company name
|
// # Company name
|
||||||
companyName = 'Bigcapital Technology, Inc.',
|
companyName = 'Bigcapital Technology, Inc.',
|
||||||
|
|
||||||
billedToAddress = DefaultPdfTemplateAddressBilledTo,
|
// # Customer address
|
||||||
billedFromAddress = DefaultPdfTemplateAddressBilledFrom,
|
showCustomerAddress = true,
|
||||||
showBilledFromAddress,
|
customerAddress = DefaultPdfTemplateAddressBilledTo,
|
||||||
showBilledToAddress,
|
|
||||||
|
// # Company address
|
||||||
|
showCompanyAddress = true,
|
||||||
|
companyAddress = DefaultPdfTemplateAddressBilledFrom,
|
||||||
|
|
||||||
billedToLabel = 'Billed To',
|
billedToLabel = 'Billed To',
|
||||||
|
|
||||||
total = '$1000.00',
|
total = '$1000.00',
|
||||||
@@ -109,16 +116,16 @@ export function PaymentReceivedPaperTemplate({
|
|||||||
</PaperTemplate.TermsList>
|
</PaperTemplate.TermsList>
|
||||||
|
|
||||||
<PaperTemplate.AddressesGroup>
|
<PaperTemplate.AddressesGroup>
|
||||||
{showBilledFromAddress && (
|
{showCompanyAddress && (
|
||||||
<PaperTemplate.Address>
|
<PaperTemplate.Address>
|
||||||
<strong>{companyName}</strong>
|
<Box dangerouslySetInnerHTML={{ __html: companyAddress }} />
|
||||||
<Box dangerouslySetInnerHTML={{ __html: billedFromAddress }} />
|
|
||||||
</PaperTemplate.Address>
|
</PaperTemplate.Address>
|
||||||
)}
|
)}
|
||||||
{showBilledToAddress && (
|
|
||||||
|
{showCustomerAddress && (
|
||||||
<PaperTemplate.Address>
|
<PaperTemplate.Address>
|
||||||
<strong>{billedToLabel}</strong>
|
<strong>{billedToLabel}</strong>
|
||||||
<Box dangerouslySetInnerHTML={{ __html: billedToAddress }} />
|
<Box dangerouslySetInnerHTML={{ __html: customerAddress }} />
|
||||||
</PaperTemplate.Address>
|
</PaperTemplate.Address>
|
||||||
)}
|
)}
|
||||||
</PaperTemplate.AddressesGroup>
|
</PaperTemplate.AddressesGroup>
|
||||||
|
|||||||
@@ -14,15 +14,19 @@ export const initialValues = {
|
|||||||
showPaymentReceivedNumber: true,
|
showPaymentReceivedNumber: true,
|
||||||
paymentReceivedNumberLabel: 'Payment number',
|
paymentReceivedNumberLabel: 'Payment number',
|
||||||
|
|
||||||
|
// Payment number
|
||||||
showPaymentReceivedDate: true,
|
showPaymentReceivedDate: true,
|
||||||
paymentReceivedDateLabel: 'Date of Issue',
|
paymentReceivedDateLabel: 'Date of Issue',
|
||||||
|
|
||||||
// Company name
|
// Company name
|
||||||
companyName: 'Bigcapital Technology, Inc.',
|
companyName: 'Bigcapital Technology, Inc.',
|
||||||
|
|
||||||
// Addresses
|
// Customer address
|
||||||
showBilledFromAddress: true,
|
showCompanyAddress: true,
|
||||||
showBillingToAddress: true,
|
companyAddress: '',
|
||||||
|
|
||||||
|
// Company address
|
||||||
|
showCustomerAddress: true,
|
||||||
billedToLabel: 'Billed To',
|
billedToLabel: 'Billed To',
|
||||||
|
|
||||||
// Entries
|
// Entries
|
||||||
@@ -31,10 +35,11 @@ export const initialValues = {
|
|||||||
itemRateLabel: 'Rate',
|
itemRateLabel: 'Rate',
|
||||||
itemTotalLabel: 'Total',
|
itemTotalLabel: 'Total',
|
||||||
|
|
||||||
// Totals
|
// Subtotal
|
||||||
showSubtotal: true,
|
showSubtotal: true,
|
||||||
subtotalLabel: 'Subtotal',
|
subtotalLabel: 'Subtotal',
|
||||||
|
|
||||||
|
// Total
|
||||||
showTotal: true,
|
showTotal: true,
|
||||||
totalLabel: 'Total',
|
totalLabel: 'Total',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,18 +12,23 @@ export interface PaymentReceivedCustomizeValues extends BrandingTemplateValues {
|
|||||||
showInvoiceNumber?: boolean;
|
showInvoiceNumber?: boolean;
|
||||||
invoiceNumberLabel?: string;
|
invoiceNumberLabel?: string;
|
||||||
|
|
||||||
|
// # Issue date
|
||||||
showDateIssue?: boolean;
|
showDateIssue?: boolean;
|
||||||
dateIssueLabel?: string;
|
dateIssueLabel?: string;
|
||||||
|
|
||||||
|
// # Due date
|
||||||
showDueDate?: boolean;
|
showDueDate?: boolean;
|
||||||
dueDateLabel?: string;
|
dueDateLabel?: string;
|
||||||
|
|
||||||
// Company name
|
// # Company name
|
||||||
companyName?: string;
|
companyName?: string;
|
||||||
|
|
||||||
// Addresses
|
// # Customer address
|
||||||
showBilledFromAddress?: boolean;
|
showCustomerAddress?: boolean;
|
||||||
showBillingToAddress?: boolean;
|
|
||||||
|
// # Company address
|
||||||
|
showCompanyAddress?: boolean;
|
||||||
|
companyAddress?: string;
|
||||||
billedToLabel?: string;
|
billedToLabel?: string;
|
||||||
|
|
||||||
// Entries
|
// Entries
|
||||||
@@ -54,6 +59,7 @@ export interface PaymentReceivedCustomizeValues extends BrandingTemplateValues {
|
|||||||
termsConditionsLabel?: string;
|
termsConditionsLabel?: string;
|
||||||
showTermsConditions?: boolean;
|
showTermsConditions?: boolean;
|
||||||
|
|
||||||
|
// # Statement
|
||||||
statementLabel?: string;
|
statementLabel?: string;
|
||||||
showStatement?: boolean;
|
showStatement?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,12 @@ import {
|
|||||||
|
|
||||||
export interface ReceiptPaperTemplateProps extends PaperTemplateProps {
|
export interface ReceiptPaperTemplateProps extends PaperTemplateProps {
|
||||||
// Addresses
|
// Addresses
|
||||||
billedToAddress?: string;
|
showCustomerAddress?: boolean;
|
||||||
billedFromAddress?: string;
|
customerAddress?: string;
|
||||||
showBilledFromAddress?: boolean;
|
|
||||||
showBilledToAddress?: boolean;
|
showCompanyAddress?: boolean;
|
||||||
|
companyAddress?: string;
|
||||||
|
|
||||||
billedToLabel?: string;
|
billedToLabel?: string;
|
||||||
|
|
||||||
// Total
|
// Total
|
||||||
@@ -73,10 +75,12 @@ export function ReceiptPaperTemplate({
|
|||||||
companyName = 'Bigcapital Technology, Inc.',
|
companyName = 'Bigcapital Technology, Inc.',
|
||||||
|
|
||||||
// # Address
|
// # Address
|
||||||
billedToAddress = DefaultPdfTemplateAddressBilledTo,
|
showCustomerAddress = true,
|
||||||
billedFromAddress = DefaultPdfTemplateAddressBilledFrom,
|
customerAddress = DefaultPdfTemplateAddressBilledTo,
|
||||||
showBilledFromAddress = true,
|
|
||||||
showBilledToAddress = true,
|
showCompanyAddress = true,
|
||||||
|
companyAddress = DefaultPdfTemplateAddressBilledFrom,
|
||||||
|
|
||||||
billedToLabel = 'Billed To',
|
billedToLabel = 'Billed To',
|
||||||
|
|
||||||
total = '$1000.00',
|
total = '$1000.00',
|
||||||
@@ -135,16 +139,16 @@ export function ReceiptPaperTemplate({
|
|||||||
</PaperTemplate.TermsList>
|
</PaperTemplate.TermsList>
|
||||||
|
|
||||||
<PaperTemplate.AddressesGroup>
|
<PaperTemplate.AddressesGroup>
|
||||||
{showBilledFromAddress && (
|
{showCompanyAddress && (
|
||||||
<PaperTemplate.Address>
|
<PaperTemplate.Address>
|
||||||
<strong>{companyName}</strong>
|
<Box dangerouslySetInnerHTML={{ __html: companyAddress }} />
|
||||||
<Box dangerouslySetInnerHTML={{ __html: billedFromAddress }} />
|
|
||||||
</PaperTemplate.Address>
|
</PaperTemplate.Address>
|
||||||
)}
|
)}
|
||||||
{showBilledToAddress && (
|
|
||||||
|
{showCustomerAddress && (
|
||||||
<PaperTemplate.Address>
|
<PaperTemplate.Address>
|
||||||
<strong>{billedToLabel}</strong>
|
<strong>{billedToLabel}</strong>
|
||||||
<Box dangerouslySetInnerHTML={{ __html: billedToAddress }} />
|
<Box dangerouslySetInnerHTML={{ __html: customerAddress }} />
|
||||||
</PaperTemplate.Address>
|
</PaperTemplate.Address>
|
||||||
)}
|
)}
|
||||||
</PaperTemplate.AddressesGroup>
|
</PaperTemplate.AddressesGroup>
|
||||||
|
|||||||
@@ -21,9 +21,12 @@ export const initialValues = {
|
|||||||
// Company name
|
// Company name
|
||||||
companyName: 'Bigcapital Technology, Inc.',
|
companyName: 'Bigcapital Technology, Inc.',
|
||||||
|
|
||||||
// Addresses
|
// Customer address
|
||||||
showBilledFromAddress: true,
|
showCustomerAddress: true,
|
||||||
showBilledToAddress: true,
|
|
||||||
|
// Company address
|
||||||
|
companyAddress: '',
|
||||||
|
showCompanyAddress: true,
|
||||||
billedToLabel: 'Billed To',
|
billedToLabel: 'Billed To',
|
||||||
|
|
||||||
// Entries
|
// Entries
|
||||||
|
|||||||
@@ -203,3 +203,28 @@ export const useAssignPdfTemplateAsDefault = (
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Retrieve organization branding state.
|
||||||
|
// --------------------------------------------------
|
||||||
|
export interface GetPdfTemplateBrandingStateResponse {
|
||||||
|
companyName: string;
|
||||||
|
companyAddress: string;
|
||||||
|
companyLogoUri: string;
|
||||||
|
companyLogoKey: string;
|
||||||
|
primaryColor: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useGetPdfTemplateBrandingState = (
|
||||||
|
options?: UseQueryOptions<GetPdfTemplateBrandingStateResponse, Error>,
|
||||||
|
): UseQueryResult<GetPdfTemplateBrandingStateResponse, Error> => {
|
||||||
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
|
return useQuery<GetPdfTemplateBrandingStateResponse, Error>(
|
||||||
|
[PdfTemplatesQueryKey, 'state'],
|
||||||
|
() =>
|
||||||
|
apiRequest
|
||||||
|
.get('/pdf-templates/state')
|
||||||
|
.then((res) => transformToCamelCase(res.data?.data)),
|
||||||
|
options,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user