UNPKG

vendure-plugin-payment-terms

Version:

This plugin allows certain customers to pay using Payment Terms. Payment Terms are when a customer is allowed to make a payment a certain number of days after an invoice is due.

172 lines (171 loc) 9.18 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.VendurePluginPaymentTerms = void 0; const core_1 = require("@vendure/core"); const payment_eligibilty_checker_1 = require("./api/payment-eligibilty-checker"); const payment_handler_1 = require("./api/payment-handler"); const schedule_1 = require("@nestjs/schedule"); const cron_1 = require("cron"); const rxjs_1 = require("rxjs"); require("./api/types"); const dayjs_1 = __importDefault(require("dayjs")); const payment_terms_event_1 = require("./api/payment-terms-event"); const constants_1 = require("./constants"); const payment_method_quote_field_resolver_1 = require("./api/payment-method-quote-field.resolver"); const schema_1 = require("./api/schema"); const payment_method_checker_config_arg_fix_resolver_1 = require("./api/payment-method-checker-config-arg-fix.resolver"); const CRON_JOB_PREFIX = `VendurePluginPaymentTerms`; let VendurePluginPaymentTerms = class VendurePluginPaymentTerms { constructor(eventBus, conn, orderService, schedulerRegistry) { this.eventBus = eventBus; this.conn = conn; this.orderService = orderService; this.schedulerRegistry = schedulerRegistry; } onApplicationBootstrap() { this.eventBus.ofType(core_1.CustomerEvent).pipe((0, rxjs_1.filter)((e) => e.type !== 'deleted' && !!e.entity.customFields.paymentTermsInDays && !!e.entity.emailAddress)).subscribe(({ entity, ctx }) => { const jobName = this.getCronJobNameForCustomer(entity); // const testCronTime=`40 * * * * *` try { const job = this.schedulerRegistry.getCronJob(jobName); const lastTimeExecuted = job.lastDate(); let everyThisDayFromNow = 0; let dueDate; if (lastTimeExecuted) { dueDate = (0, dayjs_1.default)(lastTimeExecuted).add(entity.customFields.paymentTermsInDays ?? 0, 'days'); everyThisDayFromNow = dueDate.diff(new Date(), 'days'); } else { everyThisDayFromNow = (entity.customFields.paymentTermsInDays ?? 0); dueDate = (0, dayjs_1.default)(new Date()).add(everyThisDayFromNow, 'days'); } everyThisDayFromNow = Math.round(everyThisDayFromNow); const realCronTimeFormat = `0 0 */${everyThisDayFromNow} * *`; job.setTime(new cron_1.CronTime(realCronTimeFormat)); core_1.Logger.info(`The next payment due remainder for ${entity.emailAddress} is reset to ${(0, dayjs_1.default)(job.nextDate().toJSDate()).locale('en').format('ddd, MMM D, YYYY h:mm A')}`, constants_1.loggerCtx); } catch (e) { //no existing cron Job, create new one const everyThisDayFromNow = Math.round((entity.customFields.paymentTermsInDays ?? 0)); const realCronTimeFormat = `0 0 */${everyThisDayFromNow} * *`; const job = new cron_1.CronJob(realCronTimeFormat, async () => { core_1.Logger.info(`Notifying ${entity.emailAddress} to update his Payment Terms`); //fire the event const orderRepo = this.conn.getRepository(ctx, core_1.Order); const notRemindedCustomerOrders = await orderRepo.createQueryBuilder('order') .leftJoinAndSelect('order.customer', 'customer') .leftJoinAndSelect('order.lines', 'line') .where('customer.id=:customerId', { customerId: entity.id }) .andWhere('order.customFields.notReminded') .getMany(); const orderUpdatePromises = []; for (let order of notRemindedCustomerOrders) { this.eventBus.publish(new payment_terms_event_1.PaymentTermsDueEvent(ctx, entity, order)); orderUpdatePromises.push(this.orderService.updateCustomFields(ctx, order.id, { ...order.customFields, notReminded: false })); } await Promise.all(orderUpdatePromises); }); this.schedulerRegistry.addCronJob(jobName, job); job.start(); core_1.Logger.info(`The next payment due remainder for ${entity.emailAddress} is set to ${(0, dayjs_1.default)(job.nextDate().toJSDate()).locale('en').format('ddd, MMM D, YYYY h:mm A')}`, constants_1.loggerCtx); } }); this.eventBus.ofType(core_1.CustomerEvent).pipe((0, rxjs_1.filter)((e) => e.type === 'deleted')).subscribe(({ entity }) => { try { const name = this.getCronJobNameForCustomer(entity); const job = this.schedulerRegistry.getCronJob(name); job.stop(); this.schedulerRegistry.deleteCronJob(name); core_1.Logger.info(`Stopped the payment due remainder for ${entity.emailAddress}`, constants_1.loggerCtx); } catch (e) { //no cron Job for customer, ignore } }); } getCronJobNameForCustomer(customer) { return `${CRON_JOB_PREFIX}-${customer.emailAddress}`; } }; VendurePluginPaymentTerms = __decorate([ (0, core_1.VendurePlugin)({ imports: [core_1.PluginCommonModule, schedule_1.ScheduleModule.forRoot()], shopApiExtensions: { resolvers: [payment_method_quote_field_resolver_1.PaymentMethodQuoteFieldResolver], schema: schema_1.shopApiExtensions }, adminApiExtensions: { resolvers: [payment_method_checker_config_arg_fix_resolver_1.OverridePaymentMethodResolver] }, configuration: (config) => { if (config.paymentOptions.paymentMethodEligibilityCheckers?.length) { config.paymentOptions.paymentMethodEligibilityCheckers.push(payment_eligibilty_checker_1.paymentTermsEligibilityChecker); } else { config.paymentOptions.paymentMethodEligibilityCheckers = [payment_eligibilty_checker_1.paymentTermsEligibilityChecker]; } config.paymentOptions.paymentMethodHandlers.push(payment_handler_1.paymentWithTermsHandler); config.customFields.Customer.push({ name: 'paymentTermsInDays', type: 'float', defaultValue: 0, public: false, ui: { component: 'number-form-input', suffix: 'days' }, label: [ { languageCode: core_1.LanguageCode.en, value: 'Payment Terms' } ] }, { name: 'paymentLimit', defaultValue: 0, type: 'int', public: false, ui: { component: 'currency-form-input' }, label: [ { languageCode: core_1.LanguageCode.en, value: 'Payment Limit' } ] }); config.customFields.Address.push({ name: 'vat', label: [ { languageCode: core_1.LanguageCode.en, value: 'VAT Number' } ], type: 'string' }, { name: 'purchaseOrder', label: [ { languageCode: core_1.LanguageCode.en, value: 'Purchase Order (PO) Number' } ], type: 'string' }); config.customFields.Order.push({ name: 'notReminded', type: 'boolean', public: false, readonly: true, defaultValue: true, label: [ { languageCode: core_1.LanguageCode.en, value: 'Not Reminded' } ], }); return config; } }), __metadata("design:paramtypes", [core_1.EventBus, core_1.TransactionalConnection, core_1.OrderService, schedule_1.SchedulerRegistry]) ], VendurePluginPaymentTerms); exports.VendurePluginPaymentTerms = VendurePluginPaymentTerms;