UNPKG

declastruct-stripe-sdk

Version:

declarative control of stripe constructs, via declastruct

66 lines 3.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.genInvoiceDraft = void 0; const date_fns_1 = require("date-fns"); const domain_objects_1 = require("domain-objects"); const hash_fns_1 = require("hash-fns"); const helpful_errors_1 = require("helpful-errors"); const type_fns_1 = require("type-fns"); const visualogic_1 = require("visualogic"); const castToDeclaredStripeInvoice_1 = require("../cast/castToDeclaredStripeInvoice"); const getCustomer_1 = require("../customer/getCustomer"); const getInvoice_1 = require("./getInvoice"); /** * .what = creates a new invoice draft with stripe * .what.requirements * - prevents creating duplicate invoice, per customer * - returns invoice in draft state * - throws error if invoice was already issued */ exports.genInvoiceDraft = (0, visualogic_1.withLogTrail)(async (input, context) => { // lookup the customer by ref const customerFound = await (0, getCustomer_1.getCustomer)({ by: { ref: input.invoice.customerRef } }, context); if (!customerFound) throw new helpful_errors_1.UnexpectedCodePathError('customer does not exist for by ref', { input, }); // check whether the invoice already exists for the customer const invoiceFound = await (0, getInvoice_1.getInvoice)({ by: { unique: { customerRef: input.invoice.customerRef, exid: input.invoice.exid, }, }, }, context); // if it does, then check that its still drafted; if so, return it if (invoiceFound) { // if its still drafted, then this can safely be treated as an idempotent retry if (invoiceFound.status === 'draft') return invoiceFound; // otherwise, the caller is unaware of the actual state of this invoice, and needs to be informed that this is not possible throw new helpful_errors_1.BadRequestError('can not draft an invoice that was already issued', { invoiceFound }); } // otherwise, create the new invoice const stripeInvoiceCreated = await context.stripe.invoices.create({ customer: customerFound.id, auto_advance: input.invoice.config.autoAdvance, collection_method: input.invoice.config.collectionMethod, description: input.invoice.description ?? undefined, due_date: input.invoice.dueDate ? Math.ceil((0, date_fns_1.parseISO)(input.invoice.dueDate).getTime() / 1000) // https://stackoverflow.com/a/55848218/3068233 : undefined, metadata: { exid: input.invoice.exid, ...(0, type_fns_1.omit)(input.invoice.metadata ?? {}, ['exid']), }, }, { idempotencyKey: (0, hash_fns_1.toHashSha256Sync)([ 'v1.0.1', (0, domain_objects_1.serialize)((0, type_fns_1.pick)(input.invoice, ['customerRef', 'exid'])), // make it idempotent on the unique keys of the invoice; // todo: use domain-objects.getUniqueKeys({ of: DeclaredStripeInvoice }) instead of hardcoding the keys ].join(';')), }); // resolve the created invoice return (0, castToDeclaredStripeInvoice_1.castToDeclaredStripeInvoice)(stripeInvoiceCreated); }, { name: (0, visualogic_1.getResourceNameFromFileName)(__filename) }); //# sourceMappingURL=genInvoiceDraft.js.map