UNPKG

medusa-invoice

Version:
295 lines 27.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const medusa_1 = require("@medusajs/medusa"); const medusa_2 = require("@medusajs/medusa"); const utils_1 = require("@medusajs/utils"); const invoice_1 = require("../models/invoice"); const document_settings_1 = require("../models/document-settings"); const template_kind_1 = require("./types/template-kind"); const invoice_generator_1 = require("./generators/invoice-generator"); const constants_1 = require("./types/constants"); class InvoiceService extends medusa_1.TransactionBaseService { constructor(container) { super(container); this.orderService = container.orderService; this.documentInvoiceSettingsService = container.documentInvoiceSettingsService; } calculateTemplateKind(documentSettings, documentInvoiceSettings) { if (documentInvoiceSettings && documentInvoiceSettings.invoice_template) { return documentInvoiceSettings.invoice_template; } // Legacy if (documentSettings && documentSettings.invoice_template) { return documentSettings.invoice_template; } return template_kind_1.InvoiceTemplateKind.BASIC; } calculateFormatNumber(documentSettings, documentInvoiceSettings) { if (documentInvoiceSettings && documentInvoiceSettings.invoice_number_format) { return documentInvoiceSettings.invoice_number_format; } // Legacy if (documentSettings && documentSettings.invoice_number_format) { return documentSettings.invoice_number_format; } return undefined; } async getNextInvoiceNumber(resetForcedNumber) { const forcedNumber = await this.documentInvoiceSettingsService.getInvoiceForcedNumber(); if (forcedNumber !== undefined) { if (resetForcedNumber) { await this.documentInvoiceSettingsService.resetForcedNumberByCreatingNewSettings(); } return forcedNumber; } const lastInvoice = await this.activeManager_ .getRepository(invoice_1.Invoice) .createQueryBuilder("invoice") .orderBy("created_at", "DESC") .getOne(); if (lastInvoice !== null) { return (parseInt(lastInvoice.number) + 1).toString(); } return "1"; } copySettingsIfPossible(newSettings, lastSettings) { if (lastSettings) { newSettings.invoice_number_format = lastSettings.invoice_number_format; newSettings.invoice_template = lastSettings.invoice_template; newSettings.store_address = lastSettings.store_address; newSettings.store_logo_source = lastSettings.store_logo_source; } } async getTestDisplayNumber(formatNumber, forcedNumber) { const nextNumber = forcedNumber !== undefined ? forcedNumber : await this.getNextInvoiceNumber(); if (nextNumber) { return formatNumber ? formatNumber.replace(constants_1.INVOICE_NUMBER_PLACEHOLDER, nextNumber) : nextNumber; } throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Neither forced number is set or any order present"); } async getInvoiceTemplate() { const documentSettingsRepository = this.activeManager_.getRepository(document_settings_1.DocumentSettings); const lastDocumentSettings = await documentSettingsRepository .createQueryBuilder("documentSettings") .orderBy("created_at", "DESC") .getOne(); if (lastDocumentSettings) { return lastDocumentSettings.invoice_template; } return undefined; } async getStoreLogo() { const documentSettingsRepository = this.activeManager_.getRepository(document_settings_1.DocumentSettings); const lastDocumentSettings = await documentSettingsRepository .createQueryBuilder("documentSettings") .orderBy("created_at", "DESC") .getOne(); if (lastDocumentSettings) { return lastDocumentSettings.store_logo_source; } return undefined; } async updateStoreLogo(newLogoSource) { const documentSettingsRepository = this.activeManager_.getRepository(document_settings_1.DocumentSettings); const lastDocumentSettings = await documentSettingsRepository .createQueryBuilder("documentSettings") .leftJoinAndSelect("documentSettings.store_address", "store_address") .orderBy("documentSettings.created_at", "DESC") .getOne(); const newDocumentSettings = this.activeManager_.create(document_settings_1.DocumentSettings); this.copySettingsIfPossible(newDocumentSettings, lastDocumentSettings === null ? undefined : lastDocumentSettings); newDocumentSettings.store_logo_source = newLogoSource; const result = await documentSettingsRepository.save(newDocumentSettings); return result; } async updateStoreDocumentAddress(newAddress) { const newEntry = this.activeManager_.create(medusa_1.Address); newEntry.company = newAddress.company; newEntry.city = newAddress.city; newEntry.address_1 = newAddress.address_1; newEntry.postal_code = newAddress.postal_code; newEntry.phone = newAddress.phone; const resultAddress = await this.activeManager_ .getRepository(medusa_1.Address) .save(newEntry); const documentSettingsRepository = this.activeManager_.getRepository(document_settings_1.DocumentSettings); const lastDocumentSettings = await documentSettingsRepository .createQueryBuilder("documentSettings") .leftJoinAndSelect("documentSettings.store_address", "store_address") .orderBy("documentSettings.created_at", "DESC") .getOne(); const newDocumentSettings = this.activeManager_.create(document_settings_1.DocumentSettings); this.copySettingsIfPossible(newDocumentSettings, lastDocumentSettings === null ? undefined : lastDocumentSettings); newDocumentSettings.store_address = resultAddress; const result = await documentSettingsRepository.save(newDocumentSettings); return result; } async getLastDocumentSettings() { const documentSettingsRepository = this.activeManager_.getRepository(document_settings_1.DocumentSettings); const lastDocumentSettings = await documentSettingsRepository .createQueryBuilder("documentSettings") .leftJoinAndSelect("documentSettings.store_address", "store_address") .orderBy("documentSettings.created_at", "DESC") .getOne(); if (lastDocumentSettings === null) { return undefined; } return lastDocumentSettings; } async getInvoice(invoiceId, includeBuffer = false) { if (includeBuffer) { const invoice = await this.activeManager_ .getRepository(invoice_1.Invoice) .createQueryBuilder("invoice") .leftJoinAndSelect("invoice.document_settings", "document_settings") .leftJoinAndSelect("document_settings.store_address", "store_address") .leftJoinAndSelect("invoice.document_invoice_settings", "document_invoice_settings") .leftJoinAndSelect("invoice.order", "order") .where("invoice.id = :invoiceId", { invoiceId: invoiceId }) .getOne(); if (invoice && invoice !== null && invoice.document_settings) { const order = await this.orderService.retrieveWithTotals(invoice.order.id, { relations: [ "billing_address", "shipping_address", "shipping_methods.shipping_option", ], }); const calculatedTemplateKind = this.calculateTemplateKind(invoice.document_settings, invoice.document_invoice_settings); const buffer = await (0, invoice_generator_1.generateInvoice)(calculatedTemplateKind, invoice.document_settings, invoice, order); return { invoice: invoice, buffer: buffer, }; } } const invoice = await this.activeManager_ .getRepository(invoice_1.Invoice) .createQueryBuilder("invoice") .where("invoice.id = :invoiceId", { invoiceId: invoiceId }) .getOne(); if (invoice && invoice !== null) { return { invoice: invoice, }; } return { invoice: undefined, buffer: undefined, }; } async generateInvoiceForOrder(orderId) { const order = await this.orderService.retrieveWithTotals(orderId, { relations: [ "billing_address", "shipping_address", "shipping_methods.shipping_option", ], }); if (order) { const settings = await this.getLastDocumentSettings(); if (settings) { const invoiceSettings = await this.documentInvoiceSettingsService.getLastDocumentInvoiceSettings(); if (invoiceSettings) { const calculatedTemplateKind = this.calculateTemplateKind(settings, invoiceSettings); const [validationPassed, info] = (0, invoice_generator_1.validateInputForProvidedKind)(calculatedTemplateKind, settings); if (validationPassed) { const RESET_FORCED_NUMBER = true; const nextNumber = await this.getNextInvoiceNumber(RESET_FORCED_NUMBER); const newEntry = this.activeManager_.create(invoice_1.Invoice); newEntry.number = nextNumber; const invoiceFormatNumber = this.calculateFormatNumber(settings, invoiceSettings); newEntry.display_number = invoiceFormatNumber ? invoiceFormatNumber.replace(constants_1.INVOICE_NUMBER_PLACEHOLDER, newEntry.number) : newEntry.number; newEntry.order = order; newEntry.document_settings = settings; newEntry.document_invoice_settings = invoiceSettings; const resultInvoice = await this.activeManager_ .getRepository(invoice_1.Invoice) .save(newEntry); const metaDataUpdate = (0, medusa_1.setMetadata)(order, { invoice_id: resultInvoice.id, }); order.metadata = metaDataUpdate; await this.activeManager_.getRepository(medusa_2.Order).save(order); const buffer = await (0, invoice_generator_1.generateInvoice)(calculatedTemplateKind, settings, resultInvoice, order); return { invoice: newEntry, buffer: buffer, }; } else { throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, info); } } else { throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Retrieve invoice settings failed. Please check if they are set."); } } else { throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Retrieve document settings failed. Please check if they are set."); } } else { throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Cant retrieve order"); } } async generateTestInvoice(templateKind) { const lastOrder = await this.activeManager_.getRepository(medusa_2.Order).find({ skip: 0, take: 1, order: { created_at: "DESC" }, }); if (lastOrder && lastOrder.length > 0) { const lastOrderWithTotals = await this.orderService.retrieveWithTotals(lastOrder[0].id, { relations: [ "billing_address", "shipping_address", "shipping_methods.shipping_option", ], }); const settings = await this.getLastDocumentSettings(); if (settings) { const invoiceSettings = await this.documentInvoiceSettingsService.getLastDocumentInvoiceSettings(); if (invoiceSettings) { const testInvoice = this.activeManager_.create(invoice_1.Invoice); const nextNumber = await this.getNextInvoiceNumber(); testInvoice.number = nextNumber; testInvoice.display_number = invoiceSettings.invoice_number_format ? invoiceSettings.invoice_number_format.replace(constants_1.INVOICE_NUMBER_PLACEHOLDER, testInvoice.number) : testInvoice.number; testInvoice.created_at = new Date(Date.now()); const [validationPassed, info] = (0, invoice_generator_1.validateInputForProvidedKind)(templateKind, settings); if (validationPassed) { const buffer = await (0, invoice_generator_1.generateInvoice)(templateKind, settings, testInvoice, lastOrderWithTotals); return { invoice: testInvoice, buffer: buffer, }; } else { throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, info); } } else { throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Invoice settings are not defined"); } } else { throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Document settings are not defined"); } } else { throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "You need to have at least one order to see preview"); } } } exports.default = InvoiceService; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52b2ljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9pbnZvaWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkNBQWdGO0FBQ2hGLDZDQUF1RDtBQUN2RCwyQ0FBOEM7QUFDOUMsK0NBQTRDO0FBQzVDLG1FQUErRDtBQUcvRCx5REFBNEQ7QUFDNUQsc0VBR3dDO0FBQ3hDLGlEQUErRDtBQUcvRCxNQUFxQixjQUFlLFNBQVEsK0JBQXNCO0lBSWhFLFlBQVksU0FBUztRQUNuQixLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLFlBQVksR0FBRyxTQUFTLENBQUMsWUFBWSxDQUFDO1FBQzNDLElBQUksQ0FBQyw4QkFBOEI7WUFDakMsU0FBUyxDQUFDLDhCQUE4QixDQUFDO0lBQzdDLENBQUM7SUFFTyxxQkFBcUIsQ0FDM0IsZ0JBQWtDLEVBQ2xDLHVCQUFnRDtRQUVoRCxJQUFJLHVCQUF1QixJQUFJLHVCQUF1QixDQUFDLGdCQUFnQixFQUFFO1lBQ3ZFLE9BQU8sdUJBQXVCLENBQUMsZ0JBQXVDLENBQUM7U0FDeEU7UUFDRCxTQUFTO1FBQ1QsSUFBSSxnQkFBZ0IsSUFBSSxnQkFBZ0IsQ0FBQyxnQkFBZ0IsRUFBRTtZQUN6RCxPQUFPLGdCQUFnQixDQUFDLGdCQUF1QyxDQUFDO1NBQ2pFO1FBQ0QsT0FBTyxtQ0FBbUIsQ0FBQyxLQUFLLENBQUM7SUFDbkMsQ0FBQztJQUVPLHFCQUFxQixDQUMzQixnQkFBa0MsRUFDbEMsdUJBQWdEO1FBRWhELElBQ0UsdUJBQXVCO1lBQ3ZCLHVCQUF1QixDQUFDLHFCQUFxQixFQUM3QztZQUNBLE9BQU8sdUJBQXVCLENBQUMscUJBQXFCLENBQUM7U0FDdEQ7UUFDRCxTQUFTO1FBQ1QsSUFBSSxnQkFBZ0IsSUFBSSxnQkFBZ0IsQ0FBQyxxQkFBcUIsRUFBRTtZQUM5RCxPQUFPLGdCQUFnQixDQUFDLHFCQUFxQixDQUFDO1NBQy9DO1FBRUQs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