@tomei/finance
Version:
NestJS package for finance module
962 lines • 38.9 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const util = __importStar(require("util"));
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const puppeteer = __importStar(require("puppeteer"));
const media_1 = require("@tomei/media");
const enum_1 = require("../enum");
const document_item_1 = __importDefault(require("./document-item"));
const account_system_entity_1 = require("../account-system-entity/account-system-entity");
const document_repository_1 = require("./document.repository");
const document_item_entity_1 = __importDefault(require("../models/document-item.entity"));
const general_1 = require("@tomei/general");
const config_1 = require("@tomei/config");
const sequelize_1 = require("sequelize");
const login_user_1 = require("../helpers/login-user");
const activity_history_1 = require("@tomei/activity-history");
class Document extends account_system_entity_1.AccountSystemEntity {
get ObjectType() {
return this._ObjectType;
}
get IsNewRecord() {
return this._IsNewRecord;
}
set IsNewRecord(record) {
this._IsNewRecord = record;
}
get DocType() {
return this._DocType;
}
set DocType(docType) {
this._DocType = docType;
}
get DocDate() {
return this._DocDate;
}
set DocDate(date) {
this._DocDate = date;
}
get DocHTMLFileMediaId() {
return this._DocHTMLFileMediaId;
}
set DocHTMLFileMediaId(mediaId) {
this._DocHTMLFileMediaId = mediaId;
}
get DocPDFFileMediaId() {
return this._DocPDFFileMediaId;
}
set DocPDFFileMediaId(mediaId) {
this._DocPDFFileMediaId = mediaId;
}
get Amount() {
return this._Amount;
}
set Amount(amount) {
this._Amount = amount;
}
get Status() {
return this._Status;
}
set Status(status) {
this._Status = status;
}
get RepositoryBase() {
return Document._RepositoryBase;
}
get ObjectId() {
return this.DocNo;
}
get ObjectName() {
return this.DocNo;
}
get TableName() {
return 'finance_Document';
}
constructor(dbTransaction, documentData) {
super();
this.DocNo = 'New';
this._DocDate = new Date();
this.Currency = 'MYR';
this._Amount = 0;
this.Description = '';
this._Status = enum_1.DocumentStatus.UNPAID;
this.IssuedById = '';
this.IssuedToId = '';
this.IssuedToType = '';
this.RelatedObjectId = '';
this.RelatedObjectType = '';
this.CreatedById = '';
this.UpdatedById = '';
this.UseAccSystemDocYN = 'N';
this._ObjectType = 'Document';
this._DocHTMLFileMediaId = '';
this._DocPDFFileMediaId = '';
this._IsNewRecord = true;
this._DocumentItems = [];
if (dbTransaction) {
this._DbTransaction = dbTransaction;
}
if (documentData) {
this.DocNo = documentData.DocNo;
this.DocType = documentData.DocType;
this.DocDate = documentData.DocDate;
this.CompanyId = documentData.CompanyId;
this.Currency = documentData.Currency;
this.Amount = documentData.Amount;
this.Description = documentData.Description;
this.Status = documentData.Status;
this.IssuedById = documentData.IssuedById;
this.IssuedToId = documentData.IssuedToId;
this.IssuedToType = documentData.IssuedToType;
this.RelatedObjectId = documentData.RelatedObjectId;
this.RelatedObjectType = documentData.RelatedObjectType;
this.CreatedById = documentData.CreatedById;
this.CreatedAt = documentData.CreatedAt;
this.UpdatedById = documentData.UpdatedById;
this.UpdatedAt = documentData.UpdatedAt;
this.DocPDFFileMediaId = documentData.DocPDFFileMediaId;
this.DocHTMLFileMediaId = documentData.DocHTMLFileMediaId;
this.AccSystemRefId = documentData.AccSystemRefId;
this.PostedToAccSystemYN = documentData.PostedToAccSystemYN;
this.PostedById = documentData.PostedById;
this.PostedDateTime = documentData.PostedDateTime;
this.UseAccSystemDocYN = documentData.UseAccSystemDocYN;
this.IsNewRecord = false;
}
}
init(params) {
this.DocNo = params.DocNo;
this.DocType = params.DocType;
this.DocDate = params.DocDate;
this.CompanyId = params.CompanyId;
this.Currency = params.Currency;
this.Amount = params.Amount;
this.Description = params.Description;
this.Status = params.Status;
this.IssuedById = params.IssuedById;
this.IssuedToId = params.IssuedToId;
this.IssuedToType = params.IssuedToType;
this.RelatedObjectId = params.RelatedObjectId;
this.RelatedObjectType = params.RelatedObjectType;
this.CreatedById = params.CreatedById;
this.CreatedAt = params.CreatedAt;
this.UpdatedById = params.UpdatedById;
this.UpdatedAt = params.UpdatedAt;
this.DocPDFFileMediaId = params.DocPDFFileMediaId;
this.DocHTMLFileMediaId = params.DocHTMLFileMediaId;
this.AccSystemRefId = params.AccSystemRefId;
this.PostedToAccSystemYN = params.PostedToAccSystemYN;
this.PostedById = params.PostedById;
this.PostedDateTime = params.PostedDateTime;
this.UseAccSystemDocYN = params.UseAccSystemDocYN;
}
static async initDocument(dbTransaction, docNo) {
try {
const documentData = await this._RepositoryBase.findOne({
where: {
DocNo: docNo,
},
include: [
{
model: document_item_entity_1.default,
},
],
transaction: dbTransaction,
});
if (documentData) {
const document = new Document(dbTransaction, {
DocNo: documentData.DocNo,
DocType: documentData.DocType,
CompanyId: documentData.CompanyId,
DocDate: documentData.DocDate,
Currency: documentData.Currency,
Amount: documentData.Amount,
Description: documentData.Description,
Status: documentData.Status,
IssuedById: documentData.IssuedById,
IssuedToId: documentData.IssuedToId,
IssuedToType: documentData.IssuedToType,
RelatedObjectId: documentData.RelatedObjectId,
RelatedObjectType: documentData.RelatedObjectType,
CreatedById: documentData.CreatedById,
CreatedAt: documentData.CreatedAt,
UpdatedById: documentData.UpdatedById,
UpdatedAt: documentData.UpdatedAt,
DocPDFFileMediaId: documentData.DocPDFFileMediaId,
DocHTMLFileMediaId: documentData.DocHTMLFileMediaId,
AccSystemRefId: documentData.AccSystemRefId,
PostedToAccSystemYN: documentData.PostedToAccSystemYN,
PostedById: documentData.PostedById,
PostedDateTime: documentData.PostedDateTime,
UseAccSystemDocYN: documentData.UseAccSystemDocYN,
});
return document;
}
else {
const notFoundError = new general_1.ClassError('Document', 'InitDocumentErrMsg00', `No Document record found.`);
throw notFoundError;
}
}
catch (error) {
throw error;
}
}
async reCalculateAmount() {
const roundToTwoDecimals = (value) => Math.round(value * 100) / 100;
this.Amount = 0;
for (const documentItem of this._DocumentItems) {
this.Amount = roundToTwoDecimals(this.Amount + documentItem.Amount);
}
}
get DocumentItems() {
return new Promise((resolve, reject) => {
if (!this.IsNewRecord) {
document_item_1.default.initDocumentItems(this._DbTransaction, this)
.then((documentItems) => {
resolve(documentItems);
})
.catch((err) => {
reject(err);
});
}
else {
resolve(this._DocumentItems);
}
});
}
async getDocumentItems(dbTransaction) {
try {
if (!this.IsNewRecord) {
const documentItems = await document_item_1.default.initDocumentItems(dbTransaction, this);
this._DocumentItems = documentItems;
}
return this._DocumentItems;
}
catch (error) {
throw error;
}
}
static async settleByCreditNote(loginUser, dbTransaction, DocNo, AmountToReduce) {
const document = await this.initDocument(dbTransaction, DocNo);
if (document.DocType !== enum_1.DocType.INVOICE) {
throw new general_1.ClassError('Document', 'SettleByCreditNoteErrMsgXX', 'Only Invoice can be issued credit note.');
}
if (AmountToReduce > document.Amount) {
throw new general_1.ClassError('Document', 'SettleByCreditNoteErrMsgXX', 'Amount to reduce is more than the document amount.');
}
const EntityValueBefore = {
DocNo: document.DocNo,
DocType: document.DocType,
CompanyId: document.CompanyId,
DocDate: document.DocDate,
Currency: document.Currency,
Amount: document.Amount,
Description: document.Description,
Status: document.Status,
IssuedById: document.IssuedById,
IssuedToId: document.IssuedToId,
IssuedToType: document.IssuedToType,
RelatedObjectId: document.RelatedObjectId,
RelatedObjectType: document.RelatedObjectType,
CreatedById: document.CreatedById,
CreatedAt: document.CreatedAt,
UpdatedById: document.UpdatedById,
UpdatedAt: document.UpdatedAt,
DocPDFFileMediaId: document.DocPDFFileMediaId,
DocHTMLFileMediaId: document.DocHTMLFileMediaId,
AccSystemRefId: document.AccSystemRefId,
PostedToAccSystemYN: document.PostedToAccSystemYN,
PostedById: document.PostedById,
PostedDateTime: document.PostedDateTime,
UseAccSystemDocYN: document.UseAccSystemDocYN,
};
let updatedStatus;
if (AmountToReduce == document.Amount) {
updatedStatus = enum_1.DocumentStatus.SETTLED;
}
else {
updatedStatus = enum_1.DocumentStatus.PARTIALSETTLED;
}
await this._RepositoryBase.update({
Amount: AmountToReduce,
Status: updatedStatus,
UpdatedAt: document.UpdatedAt,
UpdatedById: document.UpdatedById,
}, {
where: {
DocNo: document.DocNo,
},
transaction: dbTransaction,
});
const UpdatedDocument = await this.initDocument(dbTransaction, DocNo);
const EntityValueAfter = {
DocNo: UpdatedDocument.DocNo,
DocType: UpdatedDocument.DocType,
CompanyId: UpdatedDocument.CompanyId,
DocDate: UpdatedDocument.DocDate,
Currency: UpdatedDocument.Currency,
Amount: UpdatedDocument.Amount,
Description: UpdatedDocument.Description,
Status: UpdatedDocument.Status,
IssuedById: UpdatedDocument.IssuedById,
IssuedToId: UpdatedDocument.IssuedToId,
IssuedToType: UpdatedDocument.IssuedToType,
RelatedObjectId: UpdatedDocument.RelatedObjectId,
RelatedObjectType: UpdatedDocument.RelatedObjectType,
CreatedById: UpdatedDocument.CreatedById,
CreatedAt: UpdatedDocument.CreatedAt,
UpdatedById: UpdatedDocument.UpdatedById,
UpdatedAt: UpdatedDocument.UpdatedAt,
DocPDFFileMediaId: UpdatedDocument.DocPDFFileMediaId,
DocHTMLFileMediaId: UpdatedDocument.DocHTMLFileMediaId,
AccSystemRefId: UpdatedDocument.AccSystemRefId,
PostedToAccSystemYN: UpdatedDocument.PostedToAccSystemYN,
PostedById: UpdatedDocument.PostedById,
PostedDateTime: UpdatedDocument.PostedDateTime,
UseAccSystemDocYN: UpdatedDocument.UseAccSystemDocYN,
};
const activity = new activity_history_1.Activity();
activity.ActivityId = activity.createId();
activity.Action = activity_history_1.ActionEnum.UPDATE;
activity.Description = `Settle Finance Document (${UpdatedDocument._DocType}) from Credit Note.`;
activity.EntityType = 'FinanceCustomer';
activity.EntityId = DocNo;
activity.EntityValueBefore = JSON.stringify(EntityValueBefore);
activity.EntityValueAfter = JSON.stringify(EntityValueAfter);
await activity.create(loginUser.ObjectId, dbTransaction);
return UpdatedDocument;
}
static async DEFAULT_INVOICE_TEMPLATE_HTML() {
const templateLocation = path.resolve('./invoice-template/index.html');
const readFileContent = util.promisify(fs.readFile);
const htmlBuffer = await readFileContent(templateLocation);
const htmlStream = {
buffer: htmlBuffer,
fieldname: 'FileStream',
originalname: 'index.html',
mimetype: 'text/html',
size: htmlBuffer.length,
encoding: '8bit',
filename: 'sample-invoice.html',
destination: path.dirname(templateLocation),
path: '',
stream: null,
};
return htmlStream;
}
async DEFAULT_INVOICE_TEMPLATE_PDF(customer, date = new Date()) {
const templateLocation = path.resolve('./invoice-template/index.html');
const cssLocation = path.resolve('./invoice-template/assets/css/style.css');
const readFileContent = util.promisify(fs.readFile);
const [htmlString] = await Promise.all([
readFileContent(templateLocation, 'utf8'),
]);
const browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox'],
});
const page = await browser.newPage();
const imagePath = path.resolve('./invoice-template/assets/img/ezcash-logo.svg');
const imageBuffer = await readFileContent(imagePath);
const imageDataUrl = `data:image/svg+xml;base64,${imageBuffer.toString('base64')}`;
const imgTag = `<img src="${imageDataUrl}" alt="Logo">`;
await page.setContent(htmlString);
await page.addStyleTag({ path: cssLocation });
const divHandle = await page.$('.tm_logo');
await divHandle.evaluate((div, imgTag) => {
div.innerHTML = imgTag;
}, imgTag);
const currentDate = date.toLocaleDateString('en-GB');
const invoiceNo = this.DocNo;
const invoiceTitleInfo = `
<div class="tm_invoice_seperator tm_gray_bg"></div>
<div class="tm_invoice_info_list">
<p class="tm_invoice_number tm_m0">
Invoice No: <b class="tm_primary_color">${invoiceNo}</b>
</p>
<p class="tm_invoice_date tm_m0">
Date: <b class="tm_primary_color">${currentDate}</b>
</p>
</div>
`;
const invoiceTitleInfoHandle = await page.$('.tm_invoice_info');
await invoiceTitleInfoHandle.evaluate((invoice, invoiceTitleInfo) => {
invoice.innerHTML = invoiceTitleInfo;
}, invoiceTitleInfo);
const invoiceCustomerContent = `
<p class="tm_mb2">
<b class="tm_primary_color">Invoice To:</b>
</p>
<p>
${customer.FullName} <br />
${customer.DefaultAddress.AddressLine1}, ${customer.DefaultAddress.City} <br />
${customer.DefaultAddress.Country} <br />
${customer.Email}
</p>
`;
const invoiceCustomerHandle = await page.$('.tm_customer_detail');
await invoiceCustomerHandle.evaluate((invoice, invoiceCustomerContent) => {
invoice.innerHTML = invoiceCustomerContent;
}, invoiceCustomerContent);
const invoicePayToContent = ``;
const invoicePayToHandle = await page.$('.tm_payto_detail');
await invoicePayToHandle.evaluate((invoice, invoicePayToContent) => {
invoice.innerHTML = invoicePayToContent;
}, invoicePayToContent);
const invoicePaymentInfoContent = ``;
const invoicePaymentInfoHandle = await page.$('.tm_payment_info');
await invoicePaymentInfoHandle.evaluate((invoice, invoicePaymentInfoContent) => {
invoice.innerHTML = invoicePaymentInfoContent;
}, invoicePaymentInfoContent);
const invoiceSubtotal = +this.Amount;
const invoiceTax = 0;
const invoiceRightFooterContent = `
<table>
<tbody>
<tr>
<td
class="tm_width_3 tm_primary_color tm_border_none tm_bold"
>
Subtotal
</td>
<td
class="tm_width_3 tm_primary_color tm_text_right tm_border_none tm_bold"
>
${this.Currency} ${invoiceSubtotal.toFixed(2)}
</td>
</tr>
<tr>
<td
class="tm_width_3 tm_primary_color tm_border_none tm_pt0"
>
Tax <span class="tm_ternary_color">(0%)</span>
</td>
<td
class="tm_width_3 tm_primary_color tm_text_right tm_border_none tm_pt0"
>
${this.Currency} ${invoiceTax.toFixed(2)}
</td>
</tr>
<tr class="tm_border_top tm_border_bottom">
<td
class="tm_width_3 tm_border_top_0 tm_bold tm_f16 tm_primary_color"
>
Grand Total
</td>
<td
class="tm_width_3 tm_border_top_0 tm_bold tm_f16 tm_primary_color tm_text_right"
>
${this.Currency} ${(invoiceSubtotal + invoiceTax).toFixed(2)}
</td>
</tr>
</tbody>
</table>
`;
const invoiceRightFooterHandle = await page.$('.tm_item_total_section');
await invoiceRightFooterHandle.evaluate((invoice, invoiceRightFooterContent) => {
invoice.innerHTML = invoiceRightFooterContent;
}, invoiceRightFooterContent);
const invoiceTNCContent = `
<li>
All payment must be made to:
<ul>
<li>Bank: <b>RHB BANK BHD</b></li>
<li>Account Name: <b>TXG Financial Solutions Sdn Bhd</b></li>
<li>Account No.: <b>2142 13000 17954</b></li>
</ul>
</li>
<li>
Once payment has been made, please email your transaction confirmation slip to <i>payment@ezcash.com.my</i>
</li>
`;
const invoiceTNCHandle = await page.$('.tm_tnc_content');
await invoiceTNCHandle.evaluate((invoice, invoiceTNCContent) => {
invoice.innerHTML = invoiceTNCContent;
}, invoiceTNCContent);
const invoiceDocumentItems = await this.DocumentItems;
let invoiceItemContent = ``;
invoiceDocumentItems.forEach((documentItem, i) => {
invoiceItemContent += `
<tr>
<td class="tm_width_3">${i + 1}. ${documentItem.Name}</td>
<td class="tm_width_4">
${documentItem.Description}
</td>
<td class="tm_width_2">${documentItem.Currency} ${documentItem.UnitPrice}</td>
<td class="tm_width_1">${documentItem.Quantity}</td>
<td class="tm_width_2 tm_text_right">${documentItem.Currency} ${(+documentItem.UnitPrice * +documentItem.Quantity).toFixed(2)}</td>
</tr>
`;
});
const invoiceDocumentItemHandle = await page.$('.tm_items_content');
await invoiceDocumentItemHandle.evaluate((invoice, invoiceItemContent) => {
invoice.innerHTML = invoiceItemContent;
}, invoiceItemContent);
const pdfBuffer = await page.pdf({
format: 'a4',
printBackground: true,
margin: {
left: '0px',
top: '0px',
right: '0px',
bottom: '0px',
},
});
const pdfBufferAsBuffer = Buffer.from(pdfBuffer);
const pdfStream = {
buffer: pdfBufferAsBuffer,
fieldname: 'FileStream',
originalname: 'sample-invoice.pdf',
mimetype: 'application/pdf',
size: pdfBuffer.length,
encoding: '8bit',
filename: 'sample-invoice.pdf',
destination: '',
path: '',
stream: null,
};
return pdfStream;
}
async DEFAULT_RECEIPT_TEMPLATE_PDF(customer, date = new Date()) {
const templateLocation = path.resolve('./invoice-template/index.html');
const cssLocation = path.resolve('./invoice-template/assets/css/style.css');
const readFileContent = util.promisify(fs.readFile);
const [htmlString] = await Promise.all([
readFileContent(templateLocation, 'utf8'),
]);
const browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox'],
});
const page = await browser.newPage();
const imagePath = path.resolve('./invoice-template/assets/img/ezcash-logo.svg');
const imageBuffer = await readFileContent(imagePath);
const imageDataUrl = `data:image/svg+xml;base64,${imageBuffer.toString('base64')}`;
const imgTag = `<img src="${imageDataUrl}" alt="Logo">`;
await page.setContent(htmlString);
await page.addStyleTag({ path: cssLocation });
const divHandle = await page.$('.tm_logo');
await divHandle.evaluate((div, imgTag) => {
div.innerHTML = imgTag;
}, imgTag);
const currentDate = date.toLocaleDateString('en-GB');
const receiptNo = this.DocNo;
const receiptTitle = `
<div class="tm_primary_color tm_f50 tm_text_uppercase">
Receipt
</div>
`;
const receiptTitleHandle = await page.$('.tm_invoice_title');
await receiptTitleHandle.evaluate((receipt, receiptTitle) => {
receipt.innerHTML = receiptTitle;
}, receiptTitle);
const receiptTitleInfo = `
<div class="tm_invoice_seperator tm_gray_bg"></div>
<div class="tm_invoice_info_list">
<p class="tm_invoice_number tm_m0">
Receipt No: <b class="tm_primary_color">${receiptNo}</b>
</p>
<p class="tm_invoice_date tm_m0">
Date: <b class="tm_primary_color">${currentDate}</b>
</p>
</div>
`;
const receiptTitleInfoHandle = await page.$('.tm_invoice_info');
await receiptTitleInfoHandle.evaluate((receipt, receiptTitleInfo) => {
receipt.innerHTML = receiptTitleInfo;
}, receiptTitleInfo);
const receiptCustomerContent = `
<p class="tm_mb2">
<b class="tm_primary_color">Issued To:</b>
</p>
<p>
${customer.FullName} <br />
${customer.DefaultAddress.AddressLine1}, ${customer.DefaultAddress.City} <br />
${customer.DefaultAddress.Country} <br />
${customer.Email}
</p>
`;
const receiptCustomerHandle = await page.$('.tm_customer_detail');
await receiptCustomerHandle.evaluate((receipt, receiptCustomerContent) => {
receipt.innerHTML = receiptCustomerContent;
}, receiptCustomerContent);
const receiptPayToContent = ``;
const receiptPayToHandle = await page.$('.tm_payto_detail');
await receiptPayToHandle.evaluate((receipt, receiptPayToContent) => {
receipt.innerHTML = receiptPayToContent;
}, receiptPayToContent);
const receiptPaymentInfoContent = ``;
const receiptPaymentInfoHandle = await page.$('.tm_payment_info');
await receiptPaymentInfoHandle.evaluate((receipt, receiptPaymentInfoContent) => {
receipt.innerHTML = receiptPaymentInfoContent;
}, receiptPaymentInfoContent);
const receiptSubtotal = +this.Amount;
const receiptTax = 0;
const receiptRightFooterContent = `
<table>
<tbody>
<tr>
<td
class="tm_width_3 tm_primary_color tm_border_none tm_bold"
>
Subtotal
</td>
<td
class="tm_width_3 tm_primary_color tm_text_right tm_border_none tm_bold"
>
${this.Currency} ${receiptSubtotal}
</td>
</tr>
<tr>
<td
class="tm_width_3 tm_primary_color tm_border_none tm_pt0"
>
Tax <span class="tm_ternary_color">(0%)</span>
</td>
<td
class="tm_width_3 tm_primary_color tm_text_right tm_border_none tm_pt0"
>
${this.Currency} ${receiptTax}
</td>
</tr>
<tr class="tm_border_top tm_border_bottom">
<td
class="tm_width_3 tm_border_top_0 tm_bold tm_f16 tm_primary_color"
>
Grand Total
</td>
<td
class="tm_width_3 tm_border_top_0 tm_bold tm_f16 tm_primary_color tm_text_right"
>
${this.Currency} ${receiptSubtotal + receiptTax}
</td>
</tr>
</tbody>
</table>
`;
const receiptRightFooterHandle = await page.$('.tm_item_total_section');
await receiptRightFooterHandle.evaluate((receipt, receiptRightFooterContent) => {
receipt.innerHTML = receiptRightFooterContent;
}, receiptRightFooterContent);
const receiptDocumentItems = await this.DocumentItems;
let receiptItemContent = ``;
receiptDocumentItems.forEach((documentItem, i) => {
receiptItemContent += `
<tr>
<td class="tm_width_3">${i + 1}. ${documentItem.Name}</td>
<td class="tm_width_4">
${documentItem.Description}
</td>
<td class="tm_width_2">${documentItem.Currency} ${documentItem.UnitPrice}</td>
<td class="tm_width_1">${documentItem.Quantity}</td>
<td class="tm_width_2 tm_text_right">${documentItem.Currency} ${+documentItem.UnitPrice * +documentItem.Quantity}</td>
</tr>
`;
});
const receiptDocumentItemHandle = await page.$('.tm_items_content');
await receiptDocumentItemHandle.evaluate((receipt, receiptItemContent) => {
receipt.innerHTML = receiptItemContent;
}, receiptItemContent);
const receiptFooterContent = `
<p class="tm_mb5 tm_text_center tm_f11">
<i>
Thank you for your payment. This is computer generated receipt
- no signature is required.
</i>
</p>
`;
const receiptFooterHandle = await page.$('.tm_footer_section');
await receiptFooterHandle.evaluate((receipt, receiptFooterContent) => {
receipt.innerHTML = receiptFooterContent;
}, receiptFooterContent);
const pdfBuffer = await page.pdf({
format: 'a4',
printBackground: true,
margin: {
left: '0px',
top: '0px',
right: '0px',
bottom: '0px',
},
});
const pdfBufferAsBuffer = Buffer.from(pdfBuffer);
const pdfStream = {
buffer: pdfBufferAsBuffer,
fieldname: 'FileStream',
originalname: 'sample-invoice.pdf',
mimetype: 'application/pdf',
size: pdfBuffer.length,
encoding: '8bit',
filename: 'sample-invoice.pdf',
destination: '',
path: '',
stream: null,
};
return pdfStream;
}
get DocumentFileInHTML() {
return (async () => {
const { HTMLMedia } = await this.generateInvoice();
return HTMLMedia;
})();
}
get DocumentFileInPDF() {
return (async () => {
const { PDFMedia } = await this.generateInvoice();
return PDFMedia;
})();
}
async generateInvoice(userId, customer, dbTransaction, date) {
const media = new media_1.Medias(this.mediaCommonService);
const htmlPayload = {
ObjectId: this.DocNo,
ObjectType: 'Document',
Type: media_1.MediaType.Document,
FileName: `${this.DocType}-${this.DocNo}`,
FileStream: await Document.DEFAULT_INVOICE_TEMPLATE_HTML(),
FileExtension: 'html',
Title: `${this.DocType}-${this.DocNo}.html`,
Description: `HTML ${this.DocType}`,
IsEncryptedYN: 'N',
};
const user = new login_user_1.LoginUser(userId ?? 'System', null, null);
const HTMLInvoiceMedia = await media.postInternal(await Document.DEFAULT_INVOICE_TEMPLATE_HTML(), htmlPayload, user, dbTransaction);
const pdfPayload = {
ObjectId: this.DocNo,
ObjectType: 'Document',
Type: media_1.MediaType.Document,
FileName: `${this.DocType}-${this.DocNo}`,
FileStream: await this.DEFAULT_INVOICE_TEMPLATE_PDF(customer, date),
FileExtension: 'pdf',
Title: `${this.DocType}-${this.DocNo}.pdf`,
Description: `PDF ${this.DocType}`,
IsEncryptedYN: 'N',
};
const PDFInvoiceMedia = await media.postInternal(await this.DEFAULT_INVOICE_TEMPLATE_PDF(customer, date), pdfPayload, user, dbTransaction);
return {
HTMLMedia: HTMLInvoiceMedia,
PDFMedia: PDFInvoiceMedia,
};
}
async generateReceipt(userId, customer, transaction, date) {
const media = new media_1.Medias(this.mediaCommonService);
const user = new login_user_1.LoginUser(userId ?? 'System', null, null);
const htmlPayload = {
ObjectId: this.DocNo,
ObjectType: 'Document',
Type: media_1.MediaType.Document,
FileName: `${this.DocType}-${this.DocNo}`,
FileStream: await Document.DEFAULT_INVOICE_TEMPLATE_HTML(),
FileExtension: 'html',
Title: `${this.DocType}-${this.DocNo}.html`,
Description: `HTML ${this.DocType}`,
IsEncryptedYN: 'N',
};
const HTMLInvoiceMedia = await media.postInternal(await Document.DEFAULT_INVOICE_TEMPLATE_HTML(), htmlPayload, user, transaction);
const pdfPayload = {
ObjectId: this.DocNo,
ObjectType: 'Document',
Type: media_1.MediaType.Document,
FileName: `${this.DocType}-${this.DocNo}`,
FileStream: await this.DEFAULT_RECEIPT_TEMPLATE_PDF(customer, date),
FileExtension: 'pdf',
Title: `${this.DocType}-${this.DocNo}.pdf`,
Description: `PDF ${this.DocType}`,
IsEncryptedYN: 'N',
};
const PDFInvoiceMedia = await media.postInternal(await this.DEFAULT_RECEIPT_TEMPLATE_PDF(customer, date), pdfPayload, user, transaction);
return {
HTMLMedia: HTMLInvoiceMedia,
PDFMedia: PDFInvoiceMedia,
};
}
async generateCreditNote(userId, customer) {
console.log(userId, customer, '<< generateCreditNote');
}
async newDocumentItem(documentItem) {
let di;
if (documentItem) {
di = documentItem;
}
else {
di = new document_item_1.default(this._DbTransaction, this);
}
di.DocNo = this.DocNo;
this._DocumentItems.push(di);
this.reCalculateAmount();
return documentItem;
}
async getPreviousDocument(docType) {
return await this.RepositoryBase.findOne({
where: {
DocType: docType,
},
order: [['CreatedAt', 'DESC']],
});
}
static async findAll(loginUser, dbTransaction, page, row, search, order, accountingSystem) {
try {
const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
const isPrivileged = await loginUser.checkPrivileges(systemCode, 'Invoice - View');
if (!isPrivileged) {
throw new general_1.ClassError('Document', 'DocumentFindAllErrMsg00', `You do not have 'Invoice - View' privilege.`);
}
let options = {
transaction: dbTransaction,
order: [['CreatedAt', 'DESC']],
};
const searchObj = {};
if (search?.DocNo) {
searchObj.DocNo = search.DocNo;
}
if (search?.DocType) {
searchObj.DocType = search.DocType;
}
if (search?.StartDate) {
searchObj.DocDate = {
...searchObj.DocDate,
[sequelize_1.Op.gte]: new Date(search.StartDate).toISOString(),
};
}
if (search?.EndDate) {
searchObj.DocDate = {
...searchObj.DocDate,
[sequelize_1.Op.lte]: new Date(search.EndDate).toISOString(),
};
}
if (search?.IssuedToId) {
searchObj.IssuedToId = search.IssuedToId;
}
if (search?.IssuedToType) {
searchObj.IssuedToType = search.IssuedToType;
}
if (search?.Status) {
searchObj.Status = search.Status;
}
if (search?.RelatedObjectId) {
searchObj.RelatedObjectId = search.RelatedObjectId;
}
if (search?.RelatedObjectType) {
searchObj.RelatedObjectType = search.RelatedObjectType;
}
if (search?.Description) {
searchObj.Description = search.Description;
}
if (page && row) {
options = {
...options,
limit: row,
offset: row * (page - 1),
};
}
if (order) {
options = {
...options,
order: order,
};
}
if (search.DocumentItems) {
let docItemWhere = {};
let docItemSearch = search.DocumentItems;
if (docItemSearch.ItemId) {
docItemWhere['ItemId'] = docItemSearch.ItemId;
}
if (docItemSearch.Name) {
docItemWhere['Name'] = { [sequelize_1.Op.like]: `%${docItemSearch.Name}%` };
}
if (docItemSearch.ItemType) {
docItemWhere['ItemType'] = docItemSearch.ItemType;
}
options = {
...options,
include: [
{
model: document_item_entity_1.default,
where: docItemWhere,
},
],
};
delete search.DocumentItems;
}
if (Object.keys(searchObj).length) {
options = {
...options,
where: searchObj,
};
}
let documents = await Document._RepositoryBase.findAllWithPagination(options);
let isChangesExit = false;
for (let i = 0; i < documents?.rows?.length; i++) {
const doc = await documents?.rows[i];
if (doc.UseAccSystemDocYN.toLowerCase() === 'y') {
console.log(doc.UseAccSystemDocYN.toLowerCase());
if (accountingSystem === null || accountingSystem === undefined) {
throw new general_1.ClassError('Document', 'DocumentFindAllErrMsg01', `Accounting System is not set`);
}
const invoiceStatus = await accountingSystem.getInvoiceStatus(doc.AccSystemRefId);
if (doc.Status !== invoiceStatus) {
doc.Status = invoiceStatus;
await this._RepositoryBase.update({
Status: invoiceStatus,
}, {
where: {
DocNo: doc.DocNo,
},
transaction: dbTransaction,
});
isChangesExit = true;
}
}
}
if (isChangesExit) {
documents =
await Document._RepositoryBase.findAllWithPagination(options);
}
return documents;
}
catch (error) {
throw error;
}
}
}
Document._RepositoryBase = new document_repository_1.DocumentRepository();
Document._MediaRepository = new media_1.MediasRepository();
exports.default = Document;
//# sourceMappingURL=document.js.map