Store PDF in database
MODIFY
src/integration/billing/stripe/StripeBillingIntegration.ts
src/integration/billing/stripe/StripeBillingIntegration.ts
@@ -13,6 +13,7 @@ import { StripeBillingSetting } from '../../../types/Setting';
import Transaction from '../../../types/Transaction';
import User from '../../../types/User';
import Utils from '../../../utils/Utils';
+import axios from 'axios';
import moment from 'moment';
import ICustomerListOptions = Stripe.customers.ICustomerListOptions;
@@ -384,11 +385,13 @@ export default class StripeBillingIntegration extends BillingIntegration<StripeB
public async sendInvoiceToUser(invoice: BillingInvoice): Promise<BillingInvoice> {
await this.checkConnection();
+ let pdfUrl = '';
+ // Send invoice to user
try {
const stripeInvoice = await this.stripe.invoices.sendInvoice(invoice.invoiceID);
invoice.status = stripeInvoice.status as BillingInvoiceStatus;
invoice.id = await BillingStorage.saveInvoice(this.tenantID, invoice);
- return invoice;
+ pdfUrl = stripeInvoice.invoice_pdf;
} catch (error) {
throw new BackendError({
source: Constants.CENTRAL_SERVER,
@@ -398,6 +401,25 @@ export default class StripeBillingIntegration extends BillingIntegration<StripeB
detailedMessages: { error: error.message, stack: error.stack }
});
}
+ // Save generated pdf
+ if (pdfUrl !== '') {
+ try {
+ const response = await axios.get(pdfUrl, { responseType: 'arraybuffer' });
+ const base64Image = Buffer.from(response.data).toString('base64');
+ const encodedImage = 'data:' + response.headers['content-type'] + ';base64,' + base64Image;
+ invoice.encodedPdf = encodedImage;
+ await BillingStorage.saveInvoicePdf(this.tenantID, invoice.id, invoice.encodedPdf);
+ } catch (error) {
+ throw new BackendError({
+ source: Constants.CENTRAL_SERVER,
+ action: ServerAction.BILLING_CREATE_INVOICE,
+ module: MODULE_NAME, method: 'createInvoice',
+ message: 'Failed to save invoice PDF in database',
+ detailedMessages: { error: error.message, stack: error.stack }
+ });
+ }
+ }
+ return invoice;
}
public async startTransaction(transaction: Transaction): Promise<BillingDataTransactionStart> {

MODIFY
src/storage/mongodb/BillingStorage.ts
src/storage/mongodb/BillingStorage.ts
-import { BillingInvoice, BillingInvoiceStatus } from '../../types/Billing';
+import { BillingInvoice, BillingInvoicePdf, BillingInvoiceStatus } from '../../types/Billing';
import Constants from '../../utils/Constants';
import { DataResult } from '../../types/DataResult';
@@ -177,6 +177,26 @@ export default class BillingStorage {
return invoiceMDB._id.toHexString();
}
+ public static async saveInvoicePdf(tenantId: string, invoiceId: string, encodedPdf: string): Promise<BillingInvoicePdf> {
+ // Debug
+ const uniqueTimerID = Logging.traceStart(MODULE_NAME, 'saveInvoicePdf');
+ // Build Request
+ // Properties to save
+ const invoiceFileMDB: any = {
+ _id: invoiceId ? Utils.convertToObjectID(invoiceId) : new ObjectID(),
+ encodedPdf: encodedPdf
+ };
+ // Modify and return the modified document
+ await global.database.getCollection<BillingInvoicePdf>(tenantId, 'invoicespdf').findOneAndReplace(
+ { _id: invoiceFileMDB._id },
+ invoiceFileMDB,
+ { upsert: true }
+ );
+ // Debug
+ Logging.traceEnd(MODULE_NAME, 'saveInvoicePdf', uniqueTimerID, { invoiceFileMDB });
+ return invoiceFileMDB._id.toHexString();
+ }
+
public static async deleteInvoice(tenantID: string, id: string): Promise<void> {
// Debug
const uniqueTimerID = Logging.traceStart(MODULE_NAME, 'deleteInvoice');

MODIFY
src/types/Billing.ts
src/types/Billing.ts
@@ -71,6 +71,7 @@ export interface BillingInvoice {
customerID?: string;
createdOn?: Date;
nbrOfItems?: number;
+ encodedPdf?: string;
}
export interface BillingInvoiceItem {
@@ -84,3 +85,8 @@ export enum BillingInvoiceStatus {
OPEN = 'open',
DRAFT = 'draft',
}
+
+export interface BillingInvoicePdf {
+ id: string;
+ encodedPdf: string; // Base64 format
+}

Store PDF in database