mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 12:20:31 +00:00
feat: add adjustment total in estimates, invoices, and receipts pdf templates
This commit is contained in:
@@ -1,14 +1,12 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { ChromiumlyTenancy } from '@/services/ChromiumlyTenancy/ChromiumlyTenancy';
|
||||
import { TemplateInjectable } from '@/services/TemplateInjectable/TemplateInjectable';
|
||||
import { GetSaleEstimate } from './GetSaleEstimate';
|
||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
import { SaleEstimatePdfTemplate } from '../Invoices/SaleEstimatePdfTemplate';
|
||||
import { transformEstimateToPdfTemplate } from './utils';
|
||||
import { EstimatePdfBrandingAttributes } from './constants';
|
||||
import events from '@/subscribers/events';
|
||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||
import { renderEstimatePaperTemplateHtml } from '@bigcapital/pdf-templates';
|
||||
import { renderEstimatePaperTemplateHtml, EstimatePaperTemplateProps } from '@bigcapital/pdf-templates';
|
||||
|
||||
@Service()
|
||||
export class SaleEstimatesPdf {
|
||||
@@ -97,7 +95,7 @@ export class SaleEstimatesPdf {
|
||||
async getEstimateBrandingAttributes(
|
||||
tenantId: number,
|
||||
estimateId: number
|
||||
): Promise<EstimatePdfBrandingAttributes> {
|
||||
): Promise<EstimatePaperTemplateProps> {
|
||||
const { PdfTemplate } = this.tenancy.models(tenantId);
|
||||
const saleEstimate = await this.getSaleEstimate.getEstimate(
|
||||
tenantId,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { EstimatePaperTemplateProps } from '@bigcapital/pdf-templates';
|
||||
import { contactAddressTextFormat } from '@/utils/address-text-format';
|
||||
import { EstimatePdfBrandingAttributes } from './constants';
|
||||
|
||||
export const transformEstimateToPdfTemplate = (
|
||||
estimate
|
||||
): Partial<EstimatePdfBrandingAttributes> => {
|
||||
): Partial<EstimatePaperTemplateProps> => {
|
||||
return {
|
||||
expirationDate: estimate.formattedExpirationDate,
|
||||
estimateNumebr: estimate.estimateNumber,
|
||||
@@ -17,6 +17,7 @@ export const transformEstimateToPdfTemplate = (
|
||||
})),
|
||||
total: estimate.formattedSubtotal,
|
||||
subtotal: estimate.formattedSubtotal,
|
||||
adjustment: estimate.adjustmentFormatted,
|
||||
customerNote: estimate.note,
|
||||
termsConditions: estimate.termsConditions,
|
||||
customerAddress: contactAddressTextFormat(estimate.customer),
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { renderInvoicePaperTemplateHtml } from '@bigcapital/pdf-templates';
|
||||
import {
|
||||
renderInvoicePaperTemplateHtml,
|
||||
InvoicePaperTemplateProps,
|
||||
} from '@bigcapital/pdf-templates';
|
||||
import { ChromiumlyTenancy } from '@/services/ChromiumlyTenancy/ChromiumlyTenancy';
|
||||
import { GetSaleInvoice } from './GetSaleInvoice';
|
||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
import { transformInvoiceToPdfTemplate } from './utils';
|
||||
import { InvoicePdfTemplateAttributes } from '@/interfaces';
|
||||
import { SaleInvoicePdfTemplate } from './SaleInvoicePdfTemplate';
|
||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||
import events from '@/subscribers/events';
|
||||
@@ -100,7 +102,7 @@ export class SaleInvoicePdf {
|
||||
async getInvoiceBrandingAttributes(
|
||||
tenantId: number,
|
||||
invoiceId: number
|
||||
): Promise<InvoicePdfTemplateAttributes> {
|
||||
): Promise<InvoicePaperTemplateProps> {
|
||||
const { PdfTemplate } = this.tenancy.models(tenantId);
|
||||
|
||||
const invoice = await this.getInvoiceService.getSaleInvoice(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { pickBy } from 'lodash';
|
||||
import { InvoicePdfTemplateAttributes, ISaleInvoice } from '@/interfaces';
|
||||
import { ISaleInvoice } from '@/interfaces';
|
||||
import { contactAddressTextFormat } from '@/utils/address-text-format';
|
||||
import { InvoicePaperTemplateProps } from '@bigcapital/pdf-templates';
|
||||
|
||||
export const mergePdfTemplateWithDefaultAttributes = (
|
||||
brandingTemplate?: Record<string, any>,
|
||||
@@ -18,7 +19,7 @@ export const mergePdfTemplateWithDefaultAttributes = (
|
||||
|
||||
export const transformInvoiceToPdfTemplate = (
|
||||
invoice: ISaleInvoice
|
||||
): Partial<InvoicePdfTemplateAttributes> => {
|
||||
): Partial<InvoicePaperTemplateProps> => {
|
||||
return {
|
||||
dueDate: invoice.dueDateFormatted,
|
||||
dateIssue: invoice.invoiceDateFormatted,
|
||||
@@ -29,6 +30,7 @@ export const transformInvoiceToPdfTemplate = (
|
||||
paymentMade: invoice.paymentAmountFormatted,
|
||||
dueAmount: invoice.dueAmountFormatted,
|
||||
discount: invoice.discountAmountFormatted,
|
||||
adjustment: invoice.adjustmentFormatted,
|
||||
discountLabel: invoice.discountPercentageFormatted
|
||||
? `Discount [${invoice.discountPercentageFormatted}]`
|
||||
: 'Discount',
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { ChromiumlyTenancy } from '@/services/ChromiumlyTenancy/ChromiumlyTenancy';
|
||||
import {
|
||||
renderReceiptPaperTemplateHtml,
|
||||
ReceiptPaperTemplateProps,
|
||||
} from '@bigcapital/pdf-templates';
|
||||
import { GetSaleReceipt } from './GetSaleReceipt';
|
||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
import { SaleReceiptBrandingTemplate } from './SaleReceiptBrandingTemplate';
|
||||
import { transformReceiptToBrandingTemplateAttributes } from './utils';
|
||||
import { ISaleReceiptBrandingTemplateAttributes } from '@/interfaces';
|
||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||
import events from '@/subscribers/events';
|
||||
import { renderReceiptPaperTemplateHtml } from '@bigcapital/pdf-templates';
|
||||
|
||||
@Service()
|
||||
export class SaleReceiptsPdf {
|
||||
@@ -90,12 +92,12 @@ export class SaleReceiptsPdf {
|
||||
* Retrieves receipt branding attributes.
|
||||
* @param {number} tenantId
|
||||
* @param {number} receiptId
|
||||
* @returns {Promise<ISaleReceiptBrandingTemplateAttributes>}
|
||||
* @returns {Promise<ReceiptPaperTemplateProps>}
|
||||
*/
|
||||
public async getReceiptBrandingAttributes(
|
||||
tenantId: number,
|
||||
receiptId: number
|
||||
): Promise<ISaleReceiptBrandingTemplateAttributes> {
|
||||
): Promise<ReceiptPaperTemplateProps> {
|
||||
const { PdfTemplate } = this.tenancy.models(tenantId);
|
||||
|
||||
const saleReceipt = await this.getSaleReceiptService.getSaleReceipt(
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import {
|
||||
ISaleReceipt,
|
||||
ISaleReceiptBrandingTemplateAttributes,
|
||||
} from '@/interfaces';
|
||||
import { ISaleReceipt } from '@/interfaces';
|
||||
import { contactAddressTextFormat } from '@/utils/address-text-format';
|
||||
import { ReceiptPaperTemplateProps } from '@bigcapital/pdf-templates';
|
||||
|
||||
export const transformReceiptToBrandingTemplateAttributes = (
|
||||
saleReceipt: ISaleReceipt
|
||||
): Partial<ISaleReceiptBrandingTemplateAttributes> => {
|
||||
): Partial<ReceiptPaperTemplateProps> => {
|
||||
return {
|
||||
total: saleReceipt.totalFormatted,
|
||||
subtotal: saleReceipt.subtotalFormatted,
|
||||
@@ -23,6 +21,7 @@ export const transformReceiptToBrandingTemplateAttributes = (
|
||||
discountLabel: saleReceipt.discountPercentageFormatted
|
||||
? `Discount [${saleReceipt.discountPercentageFormatted}]`
|
||||
: 'Discount',
|
||||
adjustment: saleReceipt.adjustmentFormatted,
|
||||
customerAddress: contactAddressTextFormat(saleReceipt.customer),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -239,6 +239,7 @@ export const useJournalTotals = () => {
|
||||
const totalDebit = safeSumBy(entries, 'debit');
|
||||
|
||||
const total = Math.max(totalCredit, totalDebit);
|
||||
|
||||
// Retrieves the formatted total money.
|
||||
const formattedTotal = React.useMemo(
|
||||
() => formattedAmount(total, currencyCode),
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"main": "./dist/components.umd.js",
|
||||
"module": "./dist/components.es.js",
|
||||
"types": "./dist/src/index.d.ts",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/src/index.d.ts",
|
||||
|
||||
@@ -43,7 +43,7 @@ export interface EstimatePaperTemplateProps extends PaperTemplateProps {
|
||||
companyAddress?: string;
|
||||
billedToLabel?: string;
|
||||
|
||||
// Totals
|
||||
// Total
|
||||
total?: string;
|
||||
showTotal?: boolean;
|
||||
totalLabel?: string;
|
||||
@@ -53,6 +53,11 @@ export interface EstimatePaperTemplateProps extends PaperTemplateProps {
|
||||
showDiscount?: boolean;
|
||||
discountLabel?: string;
|
||||
|
||||
// # Adjustment
|
||||
adjustment?: string;
|
||||
showAdjustment?: boolean;
|
||||
adjustmentLabel?: string;
|
||||
|
||||
// # Subtotal
|
||||
subtotal?: string;
|
||||
showSubtotal?: boolean;
|
||||
@@ -117,6 +122,11 @@ export function EstimatePaperTemplate({
|
||||
subtotalLabel = 'Subtotal',
|
||||
showSubtotal = true,
|
||||
|
||||
// # Adjustment
|
||||
adjustment = '',
|
||||
showAdjustment = true,
|
||||
adjustmentLabel = 'Adjustment',
|
||||
|
||||
// # Customer Note
|
||||
showCustomerNote = true,
|
||||
customerNote = DefaultPdfTemplateStatement,
|
||||
@@ -240,6 +250,12 @@ export function EstimatePaperTemplate({
|
||||
amount={discount}
|
||||
/>
|
||||
)}
|
||||
{showAdjustment && adjustment && (
|
||||
<PaperTemplate.TotalLine
|
||||
label={adjustmentLabel}
|
||||
amount={adjustment}
|
||||
/>
|
||||
)}
|
||||
{showTotal && (
|
||||
<PaperTemplate.TotalLine label={totalLabel} amount={total} />
|
||||
)}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { isEmpty } from 'lodash';
|
||||
import {
|
||||
PaperTemplate,
|
||||
PaperTemplateProps,
|
||||
@@ -33,17 +34,21 @@ export interface InvoicePaperTemplateProps extends PaperTemplateProps {
|
||||
primaryColor?: string;
|
||||
secondaryColor?: string;
|
||||
|
||||
// Company
|
||||
showCompanyLogo?: boolean;
|
||||
companyLogoUri?: string;
|
||||
|
||||
// Invoice number
|
||||
showInvoiceNumber?: boolean;
|
||||
invoiceNumber?: string;
|
||||
invoiceNumberLabel?: string;
|
||||
|
||||
// Date of issue
|
||||
showDateIssue?: boolean;
|
||||
dateIssue?: string;
|
||||
dateIssueLabel?: string;
|
||||
|
||||
// Due date
|
||||
showDueDate?: boolean;
|
||||
dueDate?: string;
|
||||
dueDateLabel?: string;
|
||||
@@ -66,7 +71,7 @@ export interface InvoicePaperTemplateProps extends PaperTemplateProps {
|
||||
lineRateLabel?: string;
|
||||
lineTotalLabel?: string;
|
||||
|
||||
// Totals
|
||||
// Total
|
||||
showTotal?: boolean;
|
||||
totalLabel?: string;
|
||||
total?: string;
|
||||
@@ -76,11 +81,17 @@ export interface InvoicePaperTemplateProps extends PaperTemplateProps {
|
||||
discountLabel?: string;
|
||||
discount?: string;
|
||||
|
||||
// Adjustment
|
||||
showAdjustment?: boolean;
|
||||
adjustmentLabel?: string;
|
||||
adjustment?: string;
|
||||
|
||||
// Subtotal
|
||||
showSubtotal?: boolean;
|
||||
subtotalLabel?: string;
|
||||
subtotal?: string;
|
||||
|
||||
// Payment made
|
||||
showPaymentMade?: boolean;
|
||||
paymentMadeLabel?: string;
|
||||
paymentMade?: string;
|
||||
@@ -97,6 +108,7 @@ export interface InvoicePaperTemplateProps extends PaperTemplateProps {
|
||||
showTermsConditions?: boolean;
|
||||
termsConditions?: string;
|
||||
|
||||
// Statement
|
||||
statementLabel?: string;
|
||||
showStatement?: boolean;
|
||||
statement?: string;
|
||||
@@ -145,20 +157,24 @@ export function InvoicePaperTemplate({
|
||||
totalLabel = 'Total',
|
||||
subtotalLabel = 'Subtotal',
|
||||
discountLabel = 'Discount',
|
||||
adjustmentLabel = 'Adjustment',
|
||||
paymentMadeLabel = 'Payment Made',
|
||||
dueAmountLabel = 'Balance Due',
|
||||
|
||||
// Totals
|
||||
showTotal = true,
|
||||
total = '$662.75',
|
||||
|
||||
showSubtotal = true,
|
||||
showDiscount = true,
|
||||
showTaxes = true,
|
||||
showPaymentMade = true,
|
||||
showDueAmount = true,
|
||||
showAdjustment = true,
|
||||
|
||||
total = '$662.75',
|
||||
subtotal = '630.00',
|
||||
discount = '0.00',
|
||||
adjustment = '',
|
||||
paymentMade = '100.00',
|
||||
dueAmount = '$562.75',
|
||||
|
||||
@@ -243,17 +259,18 @@ export function InvoicePaperTemplate({
|
||||
accessor: (data) => (
|
||||
<Stack spacing={2}>
|
||||
<Text>{data.item}</Text>
|
||||
<Text
|
||||
color={'#5f6b7c'}
|
||||
fontSize={12}
|
||||
>
|
||||
<Text color={'#5f6b7c'} fontSize={12}>
|
||||
{data.description}
|
||||
</Text>
|
||||
</Stack>
|
||||
),
|
||||
thStyle: { width: '60%' },
|
||||
},
|
||||
{ label: lineQuantityLabel, accessor: 'quantity', align: 'right' },
|
||||
{
|
||||
label: lineQuantityLabel,
|
||||
accessor: 'quantity',
|
||||
align: 'right',
|
||||
},
|
||||
{ label: lineRateLabel, accessor: 'rate', align: 'right' },
|
||||
{ label: lineTotalLabel, accessor: 'total', align: 'right' },
|
||||
]}
|
||||
@@ -267,12 +284,18 @@ export function InvoicePaperTemplate({
|
||||
border={PaperTemplateTotalBorder.Gray}
|
||||
/>
|
||||
)}
|
||||
{showDiscount && (
|
||||
{showDiscount && !isEmpty(discount) && (
|
||||
<PaperTemplate.TotalLine
|
||||
label={discountLabel}
|
||||
amount={discount}
|
||||
/>
|
||||
)}
|
||||
{showAdjustment && !isEmpty(adjustment) && (
|
||||
<PaperTemplate.TotalLine
|
||||
label={adjustmentLabel}
|
||||
amount={adjustment}
|
||||
/>
|
||||
)}
|
||||
{showTaxes && (
|
||||
<>
|
||||
{taxes.map((tax, index) => (
|
||||
|
||||
@@ -39,6 +39,11 @@ export interface ReceiptPaperTemplateProps extends PaperTemplateProps {
|
||||
showDiscount?: boolean;
|
||||
discountLabel?: string;
|
||||
|
||||
// # Adjustment
|
||||
adjustment?: string;
|
||||
showAdjustment?: boolean;
|
||||
adjustmentLabel?: string;
|
||||
|
||||
// Total
|
||||
total?: string;
|
||||
showTotal?: boolean;
|
||||
@@ -111,6 +116,11 @@ export function ReceiptPaperTemplate({
|
||||
discountLabel = 'Discount',
|
||||
showDiscount = true,
|
||||
|
||||
// # Adjustment
|
||||
adjustment = '',
|
||||
adjustmentLabel = 'Adjustment',
|
||||
showAdjustment = true,
|
||||
|
||||
// # Subtotal
|
||||
subtotal = '1000/00',
|
||||
subtotalLabel = 'Subtotal',
|
||||
@@ -228,6 +238,12 @@ export function ReceiptPaperTemplate({
|
||||
amount={discount}
|
||||
/>
|
||||
)}
|
||||
{showAdjustment && adjustment && (
|
||||
<PaperTemplate.TotalLine
|
||||
label={adjustmentLabel}
|
||||
amount={adjustment}
|
||||
/>
|
||||
)}
|
||||
{showTotal && (
|
||||
<PaperTemplate.TotalLine label={totalLabel} amount={total} />
|
||||
)}
|
||||
|
||||
@@ -8,8 +8,6 @@ export const renderInvoicePaperTemplateHtml = (
|
||||
props: InvoicePaperTemplateProps
|
||||
) => {
|
||||
return renderSSR(
|
||||
<InvoicePaperTemplate
|
||||
{...props}
|
||||
/>
|
||||
<InvoicePaperTemplate {...props} />
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user