mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-21 15:20:34 +00:00
Merge pull request #740 from bigcapitalhq/fix-invoice-preview
feat: getting invoice preview on send mail view
This commit is contained in:
@@ -449,6 +449,7 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
const acceptType = accept.types([
|
const acceptType = accept.types([
|
||||||
ACCEPT_TYPE.APPLICATION_JSON,
|
ACCEPT_TYPE.APPLICATION_JSON,
|
||||||
ACCEPT_TYPE.APPLICATION_PDF,
|
ACCEPT_TYPE.APPLICATION_PDF,
|
||||||
|
ACCEPT_TYPE.APPLICATION_TEXT_HTML,
|
||||||
]);
|
]);
|
||||||
// Retrieves invoice in PDF format.
|
// Retrieves invoice in PDF format.
|
||||||
if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) {
|
if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) {
|
||||||
@@ -463,7 +464,13 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
'Content-Disposition': `attachment; filename="${filename}"`,
|
'Content-Disposition': `attachment; filename="${filename}"`,
|
||||||
});
|
});
|
||||||
res.send(pdfContent);
|
res.send(pdfContent);
|
||||||
// Retrieves invoice in json format.
|
// Retrieves invoice in html json format.
|
||||||
|
} else if (ACCEPT_TYPE.APPLICATION_TEXT_HTML === acceptType) {
|
||||||
|
const htmlContent = await this.saleInvoiceApplication.saleInvoiceHtml(
|
||||||
|
tenantId,
|
||||||
|
saleInvoiceId
|
||||||
|
);
|
||||||
|
return res.status(200).send({ htmlContent });
|
||||||
} else {
|
} else {
|
||||||
const saleInvoice = await this.saleInvoiceApplication.getSaleInvoice(
|
const saleInvoice = await this.saleInvoiceApplication.getSaleInvoice(
|
||||||
tenantId,
|
tenantId,
|
||||||
|
|||||||
@@ -31,6 +31,25 @@ export class SaleInvoicePdf {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private eventPublisher: EventPublisher;
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve sale invoice html content.
|
||||||
|
* @param {number} tenantId - Tenant Id.
|
||||||
|
* @param {ISaleInvoice} saleInvoice -
|
||||||
|
* @returns {Promise<string>}
|
||||||
|
*/
|
||||||
|
public async saleInvoiceHtml(
|
||||||
|
tenantId: number,
|
||||||
|
invoiceId: number
|
||||||
|
): Promise<string> {
|
||||||
|
const brandingAttributes = await this.getInvoiceBrandingAttributes(
|
||||||
|
tenantId,
|
||||||
|
invoiceId
|
||||||
|
);
|
||||||
|
return renderInvoicePaperTemplateHtml({
|
||||||
|
...brandingAttributes,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve sale invoice pdf content.
|
* Retrieve sale invoice pdf content.
|
||||||
* @param {number} tenantId - Tenant Id.
|
* @param {number} tenantId - Tenant Id.
|
||||||
@@ -43,13 +62,8 @@ export class SaleInvoicePdf {
|
|||||||
): Promise<[Buffer, string]> {
|
): Promise<[Buffer, string]> {
|
||||||
const filename = await this.getInvoicePdfFilename(tenantId, invoiceId);
|
const filename = await this.getInvoicePdfFilename(tenantId, invoiceId);
|
||||||
|
|
||||||
const brandingAttributes = await this.getInvoiceBrandingAttributes(
|
const htmlContent = await this.saleInvoiceHtml(tenantId, invoiceId);
|
||||||
tenantId,
|
|
||||||
invoiceId
|
|
||||||
);
|
|
||||||
const htmlContent = renderInvoicePaperTemplateHtml({
|
|
||||||
...brandingAttributes,
|
|
||||||
});
|
|
||||||
// Converts the given html content to pdf document.
|
// Converts the given html content to pdf document.
|
||||||
const buffer = await this.chromiumlyTenancy.convertHtmlContent(
|
const buffer = await this.chromiumlyTenancy.convertHtmlContent(
|
||||||
tenantId,
|
tenantId,
|
||||||
|
|||||||
@@ -273,6 +273,19 @@ export class SaleInvoiceApplication {
|
|||||||
return this.pdfSaleInvoiceService.saleInvoicePdf(tenantId, saleInvoiceId);
|
return this.pdfSaleInvoiceService.saleInvoicePdf(tenantId, saleInvoiceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the html content of the given sale invoice.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} saleInvoiceId
|
||||||
|
* @returns {Promise<string>}
|
||||||
|
*/
|
||||||
|
public saleInvoiceHtml(
|
||||||
|
tenantId: number,
|
||||||
|
saleInvoiceId: number
|
||||||
|
): Promise<string> {
|
||||||
|
return this.pdfSaleInvoiceService.saleInvoiceHtml(tenantId, saleInvoiceId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
|
|||||||
@@ -1,18 +1,41 @@
|
|||||||
|
import { Spinner } from '@blueprintjs/core';
|
||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import { Box } from '@/components';
|
import { Stack } from '@/components';
|
||||||
import { InvoicePaperTemplate } from '../InvoiceCustomize/InvoicePaperTemplate';
|
|
||||||
import { InvoiceSendMailPreviewWithHeader } from './InvoiceSendMailHeaderPreview';
|
import { InvoiceSendMailPreviewWithHeader } from './InvoiceSendMailHeaderPreview';
|
||||||
|
import { useInvoiceHtml } from '@/hooks/query';
|
||||||
|
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||||
|
|
||||||
export function InvoiceSendPdfPreviewConnected() {
|
export function InvoiceSendPdfPreviewConnected() {
|
||||||
return (
|
return (
|
||||||
<InvoiceSendMailPreviewWithHeader>
|
<InvoiceSendMailPreviewWithHeader>
|
||||||
<Box px={4} py={6}>
|
<Stack px={4} py={6}>
|
||||||
<InvoicePaperTemplate
|
<InvoiceSendPdfPreviewIframe />
|
||||||
className={css`
|
</Stack>
|
||||||
margin: 0 auto;
|
|
||||||
`}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</InvoiceSendMailPreviewWithHeader>
|
</InvoiceSendMailPreviewWithHeader>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function InvoiceSendPdfPreviewIframe() {
|
||||||
|
const { payload } = useDrawerContext();
|
||||||
|
const { data, isLoading } = useInvoiceHtml(payload?.invoiceId);
|
||||||
|
|
||||||
|
if (isLoading && data) {
|
||||||
|
return <Spinner size={20} />;
|
||||||
|
}
|
||||||
|
const iframeSrcDoc = data?.htmlContent;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<iframe
|
||||||
|
title={'invoice-pdf-preview'}
|
||||||
|
srcDoc={iframeSrcDoc}
|
||||||
|
className={css`
|
||||||
|
height: 1123px;
|
||||||
|
width: 794px;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.05);
|
||||||
|
margin: 0 auto;
|
||||||
|
`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -201,6 +201,34 @@ export function usePdfInvoice(invoiceId) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface GetInvoiceHtmlResponse {
|
||||||
|
htmlContent: string;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Retrieves the invoice html content.
|
||||||
|
* @param {number} invoiceId
|
||||||
|
* @param {UseQueryOptions<GetInvoiceHtmlResponse>} options
|
||||||
|
* @returns {UseQueryResult<GetInvoiceHtmlResponse>}
|
||||||
|
*/
|
||||||
|
export const useInvoiceHtml = (
|
||||||
|
invoiceId: number,
|
||||||
|
options?: UseQueryOptions<GetInvoiceHtmlResponse>,
|
||||||
|
): UseQueryResult<GetInvoiceHtmlResponse> => {
|
||||||
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
|
return useQuery<GetInvoiceHtmlResponse>(
|
||||||
|
['SALE_INVOICE_HTML', invoiceId],
|
||||||
|
() =>
|
||||||
|
apiRequest
|
||||||
|
.get(`sales/invoices/${invoiceId}`, {
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json+html',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => transformToCamelCase(res.data)),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve due invoices of the given customer id.
|
* Retrieve due invoices of the given customer id.
|
||||||
* @param {number} customerId - Customer id.
|
* @param {number} customerId - Customer id.
|
||||||
|
|||||||
Reference in New Issue
Block a user