mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-21 15:20:34 +00:00
fix: printing sale receipts
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import { Response } from 'express';
|
||||||
import {
|
import {
|
||||||
ApiTags,
|
ApiTags,
|
||||||
ApiOperation,
|
ApiOperation,
|
||||||
@@ -11,10 +12,12 @@ import {
|
|||||||
Controller,
|
Controller,
|
||||||
Delete,
|
Delete,
|
||||||
Get,
|
Get,
|
||||||
|
Headers,
|
||||||
Param,
|
Param,
|
||||||
Post,
|
Post,
|
||||||
Put,
|
Put,
|
||||||
Query,
|
Query,
|
||||||
|
Res,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { CreditNoteApplication } from './CreditNoteApplication.service';
|
import { CreditNoteApplication } from './CreditNoteApplication.service';
|
||||||
import { ICreditNotesQueryDTO } from './types/CreditNotes.types';
|
import { ICreditNotesQueryDTO } from './types/CreditNotes.types';
|
||||||
@@ -26,6 +29,7 @@ import {
|
|||||||
BulkDeleteDto,
|
BulkDeleteDto,
|
||||||
ValidateBulkDeleteResponseDto,
|
ValidateBulkDeleteResponseDto,
|
||||||
} from '@/common/dtos/BulkDelete.dto';
|
} from '@/common/dtos/BulkDelete.dto';
|
||||||
|
import { AcceptType } from '@/constants/accept-type';
|
||||||
|
|
||||||
@Controller('credit-notes')
|
@Controller('credit-notes')
|
||||||
@ApiTags('Credit Notes')
|
@ApiTags('Credit Notes')
|
||||||
@@ -65,8 +69,26 @@ export class CreditNotesController {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ApiResponse({ status: 404, description: 'Credit note not found' })
|
@ApiResponse({ status: 404, description: 'Credit note not found' })
|
||||||
getCreditNote(@Param('id') creditNoteId: number) {
|
async getCreditNote(
|
||||||
return this.creditNoteApplication.getCreditNote(creditNoteId);
|
@Param('id') creditNoteId: number,
|
||||||
|
@Headers('accept') acceptHeader: string,
|
||||||
|
@Res({ passthrough: true }) res: Response,
|
||||||
|
) {
|
||||||
|
if (acceptHeader.includes(AcceptType.ApplicationPdf)) {
|
||||||
|
const [pdfContent, filename] =
|
||||||
|
await this.creditNoteApplication.getCreditNotePdf(creditNoteId);
|
||||||
|
|
||||||
|
res.set({
|
||||||
|
'Content-Type': 'application/pdf',
|
||||||
|
'Content-Length': pdfContent.length,
|
||||||
|
'Content-Disposition': `attachment; filename="${filename}"`,
|
||||||
|
});
|
||||||
|
res.status(200).send(pdfContent);
|
||||||
|
} else {
|
||||||
|
const creditNote =
|
||||||
|
await this.creditNoteApplication.getCreditNote(creditNoteId);
|
||||||
|
return creditNote;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@@ -144,13 +166,10 @@ export class CreditNotesController {
|
|||||||
status: 200,
|
status: 200,
|
||||||
description: 'Credit notes deleted successfully',
|
description: 'Credit notes deleted successfully',
|
||||||
})
|
})
|
||||||
bulkDeleteCreditNotes(
|
bulkDeleteCreditNotes(@Body() bulkDeleteDto: BulkDeleteDto): Promise<void> {
|
||||||
@Body() bulkDeleteDto: BulkDeleteDto,
|
return this.creditNoteApplication.bulkDeleteCreditNotes(bulkDeleteDto.ids, {
|
||||||
): Promise<void> {
|
skipUndeletable: bulkDeleteDto.skipUndeletable ?? false,
|
||||||
return this.creditNoteApplication.bulkDeleteCreditNotes(
|
});
|
||||||
bulkDeleteDto.ids,
|
|
||||||
{ skipUndeletable: bulkDeleteDto.skipUndeletable ?? false },
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { Response } from 'express';
|
||||||
import {
|
import {
|
||||||
ApiExtraModels,
|
ApiExtraModels,
|
||||||
ApiOperation,
|
ApiOperation,
|
||||||
@@ -17,6 +18,7 @@ import {
|
|||||||
Post,
|
Post,
|
||||||
Put,
|
Put,
|
||||||
Query,
|
Query,
|
||||||
|
Res,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { PaymentReceivesApplication } from './PaymentReceived.application';
|
import { PaymentReceivesApplication } from './PaymentReceived.application';
|
||||||
import {
|
import {
|
||||||
@@ -225,11 +227,18 @@ export class PaymentReceivesController {
|
|||||||
public async getPaymentReceive(
|
public async getPaymentReceive(
|
||||||
@Param('id', ParseIntPipe) paymentReceiveId: number,
|
@Param('id', ParseIntPipe) paymentReceiveId: number,
|
||||||
@Headers('accept') acceptHeader: string,
|
@Headers('accept') acceptHeader: string,
|
||||||
|
@Res({ passthrough: true }) res: Response,
|
||||||
) {
|
) {
|
||||||
if (acceptHeader.includes(AcceptType.ApplicationPdf)) {
|
if (acceptHeader.includes(AcceptType.ApplicationPdf)) {
|
||||||
return this.paymentReceivesApplication.getPaymentReceivePdf(
|
const [pdfContent, filename] = await this.paymentReceivesApplication.getPaymentReceivePdf(
|
||||||
paymentReceiveId,
|
paymentReceiveId,
|
||||||
);
|
);
|
||||||
|
res.set({
|
||||||
|
'Content-Type': 'application/pdf',
|
||||||
|
'Content-Length': pdfContent.length,
|
||||||
|
'Content-Disposition': `attachment; filename="${filename}"`,
|
||||||
|
});
|
||||||
|
res.send(pdfContent);
|
||||||
} else if (acceptHeader.includes(AcceptType.ApplicationTextHtml)) {
|
} else if (acceptHeader.includes(AcceptType.ApplicationTextHtml)) {
|
||||||
const htmlContent =
|
const htmlContent =
|
||||||
await this.paymentReceivesApplication.getPaymentReceivedHtml(
|
await this.paymentReceivesApplication.getPaymentReceivedHtml(
|
||||||
|
|||||||
@@ -318,7 +318,7 @@ export class SaleEstimatesController {
|
|||||||
@Res({ passthrough: true }) res: Response,
|
@Res({ passthrough: true }) res: Response,
|
||||||
) {
|
) {
|
||||||
if (acceptHeader.includes(AcceptType.ApplicationPdf)) {
|
if (acceptHeader.includes(AcceptType.ApplicationPdf)) {
|
||||||
const pdfContent =
|
const [pdfContent] =
|
||||||
await this.saleEstimatesApplication.getSaleEstimatePdf(estimateId);
|
await this.saleEstimatesApplication.getSaleEstimatePdf(estimateId);
|
||||||
|
|
||||||
res.set({
|
res.set({
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export class GetSaleEstimatePdf {
|
|||||||
|
|
||||||
@Inject(SaleEstimate.name)
|
@Inject(SaleEstimate.name)
|
||||||
private readonly saleEstimateModel: TenantModelProxy<typeof SaleEstimate>,
|
private readonly saleEstimateModel: TenantModelProxy<typeof SaleEstimate>,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve sale estimate html content.
|
* Retrieve sale estimate html content.
|
||||||
@@ -50,9 +50,9 @@ export class GetSaleEstimatePdf {
|
|||||||
|
|
||||||
// Retrieves the sale estimate html.
|
// Retrieves the sale estimate html.
|
||||||
const htmlContent = await this.saleEstimateHtml(saleEstimateId);
|
const htmlContent = await this.saleEstimateHtml(saleEstimateId);
|
||||||
|
const buffer =
|
||||||
const content =
|
|
||||||
await this.chromiumlyTenancy.convertHtmlContent(htmlContent);
|
await this.chromiumlyTenancy.convertHtmlContent(htmlContent);
|
||||||
|
|
||||||
const eventPayload = { saleEstimateId };
|
const eventPayload = { saleEstimateId };
|
||||||
|
|
||||||
// Triggers the `onSaleEstimatePdfViewed` event.
|
// Triggers the `onSaleEstimatePdfViewed` event.
|
||||||
@@ -60,7 +60,7 @@ export class GetSaleEstimatePdf {
|
|||||||
events.saleEstimate.onPdfViewed,
|
events.saleEstimate.onPdfViewed,
|
||||||
eventPayload,
|
eventPayload,
|
||||||
);
|
);
|
||||||
return [content, filename];
|
return [buffer, filename];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -82,9 +82,7 @@ export class SaleInvoicesController {
|
|||||||
status: 200,
|
status: 200,
|
||||||
description: 'Sale invoices deleted successfully',
|
description: 'Sale invoices deleted successfully',
|
||||||
})
|
})
|
||||||
bulkDeleteSaleInvoices(
|
bulkDeleteSaleInvoices(@Body() bulkDeleteDto: BulkDeleteDto): Promise<void> {
|
||||||
@Body() bulkDeleteDto: BulkDeleteDto,
|
|
||||||
): Promise<void> {
|
|
||||||
return this.saleInvoiceApplication.bulkDeleteSaleInvoices(
|
return this.saleInvoiceApplication.bulkDeleteSaleInvoices(
|
||||||
bulkDeleteDto.ids,
|
bulkDeleteDto.ids,
|
||||||
{ skipUndeletable: bulkDeleteDto.skipUndeletable ?? false },
|
{ skipUndeletable: bulkDeleteDto.skipUndeletable ?? false },
|
||||||
@@ -212,7 +210,8 @@ export class SaleInvoicesController {
|
|||||||
@Res({ passthrough: true }) res: Response,
|
@Res({ passthrough: true }) res: Response,
|
||||||
) {
|
) {
|
||||||
if (acceptHeader.includes(AcceptType.ApplicationPdf)) {
|
if (acceptHeader.includes(AcceptType.ApplicationPdf)) {
|
||||||
const pdfContent = await this.saleInvoiceApplication.saleInvoicePdf(id);
|
const [pdfContent, filename] =
|
||||||
|
await this.saleInvoiceApplication.saleInvoicePdf(id);
|
||||||
|
|
||||||
res.set({
|
res.set({
|
||||||
'Content-Type': 'application/pdf',
|
'Content-Type': 'application/pdf',
|
||||||
|
|||||||
@@ -74,9 +74,7 @@ export class SaleReceiptsController {
|
|||||||
status: 200,
|
status: 200,
|
||||||
description: 'Sale receipts deleted successfully',
|
description: 'Sale receipts deleted successfully',
|
||||||
})
|
})
|
||||||
bulkDeleteSaleReceipts(
|
bulkDeleteSaleReceipts(@Body() bulkDeleteDto: BulkDeleteDto): Promise<void> {
|
||||||
@Body() bulkDeleteDto: BulkDeleteDto,
|
|
||||||
): Promise<void> {
|
|
||||||
return this.saleReceiptApplication.bulkDeleteSaleReceipts(
|
return this.saleReceiptApplication.bulkDeleteSaleReceipts(
|
||||||
bulkDeleteDto.ids,
|
bulkDeleteDto.ids,
|
||||||
{ skipUndeletable: bulkDeleteDto.skipUndeletable ?? false },
|
{ skipUndeletable: bulkDeleteDto.skipUndeletable ?? false },
|
||||||
@@ -165,7 +163,7 @@ export class SaleReceiptsController {
|
|||||||
@Res({ passthrough: true }) res: Response,
|
@Res({ passthrough: true }) res: Response,
|
||||||
) {
|
) {
|
||||||
if (acceptHeader.includes(AcceptType.ApplicationPdf)) {
|
if (acceptHeader.includes(AcceptType.ApplicationPdf)) {
|
||||||
const pdfContent =
|
const [pdfContent] =
|
||||||
await this.saleReceiptApplication.getSaleReceiptPdf(id);
|
await this.saleReceiptApplication.getSaleReceiptPdf(id);
|
||||||
|
|
||||||
res.set({
|
res.set({
|
||||||
|
|||||||
Reference in New Issue
Block a user