declastruct-stripe-sdk
Version:
declarative control of stripe constructs, via declastruct
66 lines • 3.33 kB
JavaScript
"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