@rsc-labs/medusa-documents
Version:
Generate documents from Medusa
277 lines (276 loc) • 14.5 kB
JavaScript
"use strict";
/*
* Copyright 2024 RSC-Labs, https://rsoftcon.com/
*
* MIT License
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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.first_name = newAddress.first_name;
newEntry.last_name = newAddress.last_name;
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']
});
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']
});
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']
});
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;