mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-21 07:10:33 +00:00
feat: Map the invoice preview data
This commit is contained in:
@@ -416,6 +416,7 @@ export default class SaleInvoice extends mixin(TenantModel, [
|
|||||||
const {
|
const {
|
||||||
TransactionPaymentServiceEntry,
|
TransactionPaymentServiceEntry,
|
||||||
} = require('models/TransactionPaymentServiceEntry');
|
} = require('models/TransactionPaymentServiceEntry');
|
||||||
|
const { PdfTemplate } = require('models/PdfTemplate');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
@@ -593,6 +594,18 @@ export default class SaleInvoice extends mixin(TenantModel, [
|
|||||||
query.where('reference_type', 'SaleInvoice');
|
query.where('reference_type', 'SaleInvoice');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sale invoice may belongs to pdf branding template.
|
||||||
|
*/
|
||||||
|
pdfTemplate: {
|
||||||
|
relation: Model.BelongsToOneRelation,
|
||||||
|
modelClass: PdfTemplate,
|
||||||
|
join: {
|
||||||
|
from: 'sales_invoices.pdfTemplateId',
|
||||||
|
to: 'pdf_templates.id',
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import { Inject, Service } from 'typedi';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
||||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||||
import { PaymentLink } from '@/system/models';
|
import { PaymentLink } from '@/system/models';
|
||||||
import { Inject, Service } from 'typedi';
|
|
||||||
import { GeneratePaymentLinkTransformer } from './GeneratePaymentLinkTransformer';
|
|
||||||
import { GetInvoicePaymentLinkMetaTransformer } from './GetInvoicePaymentLinkTransformer';
|
import { GetInvoicePaymentLinkMetaTransformer } from './GetInvoicePaymentLinkTransformer';
|
||||||
import { initalizeTenantServices } from '@/api/middleware/TenantDependencyInjection';
|
import { initalizeTenantServices } from '@/api/middleware/TenantDependencyInjection';
|
||||||
|
|
||||||
@@ -46,7 +45,7 @@ export class GetInvoicePaymentLinkMetadata {
|
|||||||
|
|
||||||
const invoice = await SaleInvoice.query()
|
const invoice = await SaleInvoice.query()
|
||||||
.findById(paymentLink.resourceId)
|
.findById(paymentLink.resourceId)
|
||||||
.withGraphFetched('entries')
|
.withGraphFetched('entries.item')
|
||||||
.withGraphFetched('customer')
|
.withGraphFetched('customer')
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { ItemEntryTransformer } from './ItemEntryTransformer';
|
||||||
import { SaleInvoiceTransformer } from './SaleInvoiceTransformer';
|
import { SaleInvoiceTransformer } from './SaleInvoiceTransformer';
|
||||||
|
|
||||||
export class GetInvoicePaymentLinkMetaTransformer extends SaleInvoiceTransformer {
|
export class GetInvoicePaymentLinkMetaTransformer extends SaleInvoiceTransformer {
|
||||||
@@ -33,6 +34,9 @@ export class GetInvoicePaymentLinkMetaTransformer extends SaleInvoiceTransformer
|
|||||||
'dueDate',
|
'dueDate',
|
||||||
'dueDateFormatted',
|
'dueDateFormatted',
|
||||||
'invoiceNo',
|
'invoiceNo',
|
||||||
|
'invoiceMessage',
|
||||||
|
'termsConditions',
|
||||||
|
'entries',
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -43,4 +47,50 @@ export class GetInvoicePaymentLinkMetaTransformer extends SaleInvoiceTransformer
|
|||||||
public companyName() {
|
public companyName() {
|
||||||
return 'Bigcapital Technology, Inc.';
|
return 'Bigcapital Technology, Inc.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the entries of the sale invoice.
|
||||||
|
* @param {ISaleInvoice} invoice
|
||||||
|
* @returns {}
|
||||||
|
*/
|
||||||
|
protected entries = (invoice) => {
|
||||||
|
return this.item(
|
||||||
|
invoice.entries,
|
||||||
|
new GetInvoicePaymentLinkEntryMetaTransformer(),
|
||||||
|
{
|
||||||
|
currencyCode: invoice.currencyCode,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class GetInvoicePaymentLinkEntryMetaTransformer extends ItemEntryTransformer {
|
||||||
|
/**
|
||||||
|
* Include these attributes to item entry object.
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
public includeAttributes = (): string[] => {
|
||||||
|
return [
|
||||||
|
'quantity',
|
||||||
|
'quantityFormatted',
|
||||||
|
'rate',
|
||||||
|
'rateFormatted',
|
||||||
|
'total',
|
||||||
|
'totalFormatted',
|
||||||
|
'itemName',
|
||||||
|
'description',
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
itemName(entry) {
|
||||||
|
return entry.item.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclude these attributes from payment link object.
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
public excludeAttributes = (): string[] => {
|
||||||
|
return ['*'];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,14 +10,11 @@ export default function PaymentPortalPage() {
|
|||||||
const { linkId } = useParams<{ linkId: string }>();
|
const { linkId } = useParams<{ linkId: string }>();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<BodyClassName className={styles.rootBodyPage}>
|
<BodyClassName className={styles.rootBodyPage}>
|
||||||
<PaymentPortalBoot linkId={linkId}>
|
<PaymentPortalBoot linkId={linkId}>
|
||||||
<PaymentPortal />
|
<PaymentPortal />
|
||||||
|
<PaymentInvoicePreviewDrawer name={DRAWERS.PAYMENT_INVOICE_PREVIEW} />
|
||||||
</PaymentPortalBoot>
|
</PaymentPortalBoot>
|
||||||
</BodyClassName>
|
</BodyClassName>
|
||||||
|
|
||||||
<PaymentInvoicePreviewDrawer name={DRAWERS.PAYMENT_INVOICE_PREVIEW} />
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,36 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import { Box, DrawerBody, DrawerHeaderContent } from '@/components';
|
import { Box, DrawerBody, DrawerHeaderContent } from '@/components';
|
||||||
import { InvoicePaperTemplate } from '@/containers/Sales/Invoices/InvoiceCustomize/InvoicePaperTemplate';
|
import { InvoicePaperTemplate } from '@/containers/Sales/Invoices/InvoiceCustomize/InvoicePaperTemplate';
|
||||||
|
import { usePaymentPortalBoot } from '../../PaymentPortalBoot';
|
||||||
|
|
||||||
export function PaymentInvoicePreviewContent() {
|
export function PaymentInvoicePreviewContent() {
|
||||||
|
const { sharableLinkMeta } = usePaymentPortalBoot();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DrawerHeaderContent title={'Invoice'} />
|
<DrawerHeaderContent title={'Invoice'} />
|
||||||
|
|
||||||
<DrawerBody>
|
<DrawerBody>
|
||||||
<Box style={{ paddingTop: 20, paddingBottom: 20 }}>
|
<Box style={{ paddingTop: 20, paddingBottom: 20 }}>
|
||||||
<InvoicePaperTemplate />
|
<InvoicePaperTemplate
|
||||||
|
invoiceNumber={sharableLinkMeta?.invoiceNo}
|
||||||
|
dueDate={sharableLinkMeta?.dueDateFormatted}
|
||||||
|
dateIssue={sharableLinkMeta?.invoiceDateFormatted}
|
||||||
|
total={sharableLinkMeta?.totalFormatted}
|
||||||
|
subtotal={sharableLinkMeta?.subtotalFormatted}
|
||||||
|
balanceDue={sharableLinkMeta?.dueAmountFormatted}
|
||||||
|
paymentMade={sharableLinkMeta?.paymentAmountFormatted}
|
||||||
|
termsConditions={sharableLinkMeta?.termsConditions}
|
||||||
|
statement={sharableLinkMeta?.invoiceMessage}
|
||||||
|
companyName={sharableLinkMeta?.companyName}
|
||||||
|
lines={sharableLinkMeta?.entries?.map((entry) => ({
|
||||||
|
item: entry.itemName,
|
||||||
|
description: entry.description,
|
||||||
|
quantity: entry.quantityFormatted,
|
||||||
|
rate: entry.rateFormatted,
|
||||||
|
total: entry.totalFormatted,
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</DrawerBody>
|
</DrawerBody>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
|
import { Position } from '@blueprintjs/core';
|
||||||
import { Drawer, DrawerSuspense } from '@/components';
|
import { Drawer, DrawerSuspense } from '@/components';
|
||||||
import withDrawers from '@/containers/Drawer/withDrawers';
|
import withDrawers from '@/containers/Drawer/withDrawers';
|
||||||
import { PaymentInvoicePreviewContent } from './PaymentInvoicePreviewContent';
|
import { PaymentInvoicePreviewContent } from './PaymentInvoicePreviewContent';
|
||||||
import { Position } from '@blueprintjs/core';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -99,16 +99,16 @@ export function InvoicePaperTemplate({
|
|||||||
|
|
||||||
dueDate = 'September 3, 2024',
|
dueDate = 'September 3, 2024',
|
||||||
dueDateLabel = 'Date due',
|
dueDateLabel = 'Date due',
|
||||||
showDueDate,
|
showDueDate = true,
|
||||||
|
|
||||||
dateIssue = 'September 3, 2024',
|
dateIssue = 'September 3, 2024',
|
||||||
dateIssueLabel = 'Date of issue',
|
dateIssueLabel = 'Date of issue',
|
||||||
showDateIssue,
|
showDateIssue = true,
|
||||||
|
|
||||||
// dateIssue,
|
// dateIssue,
|
||||||
invoiceNumberLabel = 'Invoice number',
|
invoiceNumberLabel = 'Invoice number',
|
||||||
invoiceNumber = '346D3D40-0001',
|
invoiceNumber = '346D3D40-0001',
|
||||||
showInvoiceNumber,
|
showInvoiceNumber = true,
|
||||||
|
|
||||||
// Address
|
// Address
|
||||||
showBillingToAddress = true,
|
showBillingToAddress = true,
|
||||||
@@ -281,12 +281,12 @@ export function InvoicePaperTemplate({
|
|||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Stack spacing={0}>
|
<Stack spacing={0}>
|
||||||
{showTermsConditions && (
|
{showTermsConditions && termsConditions && (
|
||||||
<PaperTemplate.Statement label={termsConditionsLabel}>
|
<PaperTemplate.Statement label={termsConditionsLabel}>
|
||||||
{termsConditions}
|
{termsConditions}
|
||||||
</PaperTemplate.Statement>
|
</PaperTemplate.Statement>
|
||||||
)}
|
)}
|
||||||
{showStatement && (
|
{showStatement && statement && (
|
||||||
<PaperTemplate.Statement label={statementLabel}>
|
<PaperTemplate.Statement label={statementLabel}>
|
||||||
{statement}
|
{statement}
|
||||||
</PaperTemplate.Statement>
|
</PaperTemplate.Statement>
|
||||||
|
|||||||
@@ -67,6 +67,18 @@ export interface GetSharableLinkMetaResponse {
|
|||||||
totalLocalFormatted: string;
|
totalLocalFormatted: string;
|
||||||
customerName: string;
|
customerName: string;
|
||||||
companyName: string;
|
companyName: string;
|
||||||
|
invoiceMessage: string;
|
||||||
|
termsConditions: string;
|
||||||
|
entries: Array<{
|
||||||
|
description: string;
|
||||||
|
itemName: string;
|
||||||
|
quantity: number;
|
||||||
|
quantityFormatted: string;
|
||||||
|
rate: number;
|
||||||
|
rateFormatted: string;
|
||||||
|
total: number;
|
||||||
|
totalFormatted: string;
|
||||||
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user