@teleporthq/teleport-plugin-next-workflows 0.43.65 → 0.43.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/cart-clear-db-mirror.test.ts +12 -0
- package/__tests__/cart-get-total-regional-pricing.test.ts +166 -0
- package/__tests__/continue-on-error.test.ts +119 -0
- package/__tests__/invoice-delivery-fee.test.ts +104 -0
- package/__tests__/invoice-regional-tax.test.ts +126 -0
- package/__tests__/payment-redirect-and-order-notification.test.ts +6 -0
- package/__tests__/paypal-webhook-order-notification.test.ts +41 -0
- package/__tests__/sent-email-log-module.test.ts +381 -0
- package/__tests__/sent-email-log-wiring.test.ts +267 -0
- package/dist/cjs/account-delete-route-generator.d.ts.map +1 -1
- package/dist/cjs/account-delete-route-generator.js +14 -5
- package/dist/cjs/account-delete-route-generator.js.map +1 -1
- package/dist/cjs/api-route-generator.d.ts.map +1 -1
- package/dist/cjs/api-route-generator.js +44 -9
- package/dist/cjs/api-route-generator.js.map +1 -1
- package/dist/cjs/auth-generator.d.ts.map +1 -1
- package/dist/cjs/auth-generator.js +15 -6
- package/dist/cjs/auth-generator.js.map +1 -1
- package/dist/cjs/executor-generator.d.ts.map +1 -1
- package/dist/cjs/executor-generator.js +17 -4
- package/dist/cjs/executor-generator.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/invoice/api-routes-code.d.ts.map +1 -1
- package/dist/cjs/invoice/api-routes-code.js +42 -4
- package/dist/cjs/invoice/api-routes-code.js.map +1 -1
- package/dist/cjs/invoice/email-sender-code.d.ts.map +1 -1
- package/dist/cjs/invoice/email-sender-code.js +58 -29
- package/dist/cjs/invoice/email-sender-code.js.map +1 -1
- package/dist/cjs/invoice/index.d.ts +1 -4
- package/dist/cjs/invoice/index.d.ts.map +1 -1
- package/dist/cjs/invoice/index.js +5 -19
- package/dist/cjs/invoice/index.js.map +1 -1
- package/dist/cjs/invoice/invoice-html-code.d.ts.map +1 -1
- package/dist/cjs/invoice/invoice-html-code.js +31 -8
- package/dist/cjs/invoice/invoice-html-code.js.map +1 -1
- package/dist/cjs/invoice/regional-invoice-tax-code.d.ts +25 -0
- package/dist/cjs/invoice/regional-invoice-tax-code.d.ts.map +1 -0
- package/dist/cjs/invoice/regional-invoice-tax-code.js +116 -0
- package/dist/cjs/invoice/regional-invoice-tax-code.js.map +1 -0
- package/dist/cjs/invoice/resolve-data-source.d.ts +6 -0
- package/dist/cjs/invoice/resolve-data-source.d.ts.map +1 -0
- package/dist/cjs/invoice/resolve-data-source.js +23 -0
- package/dist/cjs/invoice/resolve-data-source.js.map +1 -0
- package/dist/cjs/nodes/cart/cart-clear.d.ts.map +1 -1
- package/dist/cjs/nodes/cart/cart-clear.js +6 -0
- package/dist/cjs/nodes/cart/cart-clear.js.map +1 -1
- package/dist/cjs/nodes/cart/cart-get-total.d.ts.map +1 -1
- package/dist/cjs/nodes/cart/cart-get-total.js +81 -5
- package/dist/cjs/nodes/cart/cart-get-total.js.map +1 -1
- package/dist/cjs/nodes/data/data-create-item.d.ts.map +1 -1
- package/dist/cjs/nodes/data/data-create-item.js +8 -0
- package/dist/cjs/nodes/data/data-create-item.js.map +1 -1
- package/dist/cjs/sent-email-log/index.d.ts +16 -0
- package/dist/cjs/sent-email-log/index.d.ts.map +1 -0
- package/dist/cjs/sent-email-log/index.js +53 -0
- package/dist/cjs/sent-email-log/index.js.map +1 -0
- package/dist/cjs/sent-email-log/sent-email-log-code.d.ts +4 -0
- package/dist/cjs/sent-email-log/sent-email-log-code.d.ts.map +1 -0
- package/dist/cjs/sent-email-log/sent-email-log-code.js +415 -0
- package/dist/cjs/sent-email-log/sent-email-log-code.js.map +1 -0
- package/dist/cjs/sent-email-log/sent-email-log-scope.d.ts +21 -0
- package/dist/cjs/sent-email-log/sent-email-log-scope.d.ts.map +1 -0
- package/dist/cjs/sent-email-log/sent-email-log-scope.js +36 -0
- package/dist/cjs/sent-email-log/sent-email-log-scope.js.map +1 -0
- package/dist/cjs/transactional-email-code.d.ts +12 -1
- package/dist/cjs/transactional-email-code.d.ts.map +1 -1
- package/dist/cjs/transactional-email-code.js +43 -5
- package/dist/cjs/transactional-email-code.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/webhook-generator.d.ts.map +1 -1
- package/dist/cjs/webhook-generator.js +9 -2
- package/dist/cjs/webhook-generator.js.map +1 -1
- package/dist/cjs/workflow-project-plugin.d.ts.map +1 -1
- package/dist/cjs/workflow-project-plugin.js +14 -0
- package/dist/cjs/workflow-project-plugin.js.map +1 -1
- package/dist/esm/account-delete-route-generator.d.ts.map +1 -1
- package/dist/esm/account-delete-route-generator.js +15 -6
- package/dist/esm/account-delete-route-generator.js.map +1 -1
- package/dist/esm/api-route-generator.d.ts.map +1 -1
- package/dist/esm/api-route-generator.js +44 -9
- package/dist/esm/api-route-generator.js.map +1 -1
- package/dist/esm/auth-generator.d.ts.map +1 -1
- package/dist/esm/auth-generator.js +15 -6
- package/dist/esm/auth-generator.js.map +1 -1
- package/dist/esm/executor-generator.d.ts.map +1 -1
- package/dist/esm/executor-generator.js +17 -4
- package/dist/esm/executor-generator.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/invoice/api-routes-code.d.ts.map +1 -1
- package/dist/esm/invoice/api-routes-code.js +42 -4
- package/dist/esm/invoice/api-routes-code.js.map +1 -1
- package/dist/esm/invoice/email-sender-code.d.ts.map +1 -1
- package/dist/esm/invoice/email-sender-code.js +58 -29
- package/dist/esm/invoice/email-sender-code.js.map +1 -1
- package/dist/esm/invoice/index.d.ts +1 -4
- package/dist/esm/invoice/index.d.ts.map +1 -1
- package/dist/esm/invoice/index.js +4 -18
- package/dist/esm/invoice/index.js.map +1 -1
- package/dist/esm/invoice/invoice-html-code.d.ts.map +1 -1
- package/dist/esm/invoice/invoice-html-code.js +31 -8
- package/dist/esm/invoice/invoice-html-code.js.map +1 -1
- package/dist/esm/invoice/regional-invoice-tax-code.d.ts +25 -0
- package/dist/esm/invoice/regional-invoice-tax-code.d.ts.map +1 -0
- package/dist/esm/invoice/regional-invoice-tax-code.js +113 -0
- package/dist/esm/invoice/regional-invoice-tax-code.js.map +1 -0
- package/dist/esm/invoice/resolve-data-source.d.ts +6 -0
- package/dist/esm/invoice/resolve-data-source.d.ts.map +1 -0
- package/dist/esm/invoice/resolve-data-source.js +19 -0
- package/dist/esm/invoice/resolve-data-source.js.map +1 -0
- package/dist/esm/nodes/cart/cart-clear.d.ts.map +1 -1
- package/dist/esm/nodes/cart/cart-clear.js +6 -0
- package/dist/esm/nodes/cart/cart-clear.js.map +1 -1
- package/dist/esm/nodes/cart/cart-get-total.d.ts.map +1 -1
- package/dist/esm/nodes/cart/cart-get-total.js +81 -5
- package/dist/esm/nodes/cart/cart-get-total.js.map +1 -1
- package/dist/esm/nodes/data/data-create-item.d.ts.map +1 -1
- package/dist/esm/nodes/data/data-create-item.js +8 -0
- package/dist/esm/nodes/data/data-create-item.js.map +1 -1
- package/dist/esm/sent-email-log/index.d.ts +16 -0
- package/dist/esm/sent-email-log/index.d.ts.map +1 -0
- package/dist/esm/sent-email-log/index.js +45 -0
- package/dist/esm/sent-email-log/index.js.map +1 -0
- package/dist/esm/sent-email-log/sent-email-log-code.d.ts +4 -0
- package/dist/esm/sent-email-log/sent-email-log-code.d.ts.map +1 -0
- package/dist/esm/sent-email-log/sent-email-log-code.js +411 -0
- package/dist/esm/sent-email-log/sent-email-log-code.js.map +1 -0
- package/dist/esm/sent-email-log/sent-email-log-scope.d.ts +21 -0
- package/dist/esm/sent-email-log/sent-email-log-scope.d.ts.map +1 -0
- package/dist/esm/sent-email-log/sent-email-log-scope.js +31 -0
- package/dist/esm/sent-email-log/sent-email-log-scope.js.map +1 -0
- package/dist/esm/transactional-email-code.d.ts +12 -1
- package/dist/esm/transactional-email-code.d.ts.map +1 -1
- package/dist/esm/transactional-email-code.js +42 -4
- package/dist/esm/transactional-email-code.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/webhook-generator.d.ts.map +1 -1
- package/dist/esm/webhook-generator.js +9 -2
- package/dist/esm/webhook-generator.js.map +1 -1
- package/dist/esm/workflow-project-plugin.d.ts.map +1 -1
- package/dist/esm/workflow-project-plugin.js +14 -0
- package/dist/esm/workflow-project-plugin.js.map +1 -1
- package/package.json +4 -4
- package/src/account-delete-route-generator.ts +16 -5
- package/src/api-route-generator.ts +51 -9
- package/src/auth-generator.ts +17 -6
- package/src/executor-generator.ts +17 -4
- package/src/index.ts +1 -0
- package/src/invoice/api-routes-code.ts +48 -4
- package/src/invoice/email-sender-code.ts +58 -29
- package/src/invoice/index.ts +4 -23
- package/src/invoice/invoice-html-code.ts +31 -8
- package/src/invoice/regional-invoice-tax-code.ts +112 -0
- package/src/invoice/resolve-data-source.ts +25 -0
- package/src/nodes/cart/cart-clear.ts +6 -0
- package/src/nodes/cart/cart-get-total.ts +94 -5
- package/src/nodes/data/data-create-item.ts +8 -0
- package/src/sent-email-log/index.ts +57 -0
- package/src/sent-email-log/sent-email-log-code.ts +419 -0
- package/src/sent-email-log/sent-email-log-scope.ts +36 -0
- package/src/transactional-email-code.ts +61 -4
- package/src/webhook-generator.ts +11 -2
- package/src/workflow-project-plugin.ts +15 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateInvoicePdfRouteCode = exports.generateInvoiceGenerateRouteCode = void 0;
|
|
4
|
+
const regional_invoice_tax_code_1 = require("./regional-invoice-tax-code");
|
|
4
5
|
const generateInvoiceGenerateRouteCode = (settings) => {
|
|
5
6
|
var _a, _b;
|
|
6
7
|
const prefix = settings.invoicePrefix || 'INV-';
|
|
@@ -21,7 +22,10 @@ const generateInvoiceGenerateRouteCode = (settings) => {
|
|
|
21
22
|
|
|
22
23
|
var dataAccess = require('../../../utils/invoices/data-access');
|
|
23
24
|
var pdfGenerator = require('../../../utils/invoices/pdf-generator');
|
|
24
|
-
${emailEnabled
|
|
25
|
+
${emailEnabled
|
|
26
|
+
? `var emailSender = require('../../../utils/invoices/email-sender');
|
|
27
|
+
var sentEmailLog = require('../../../utils/email/sent-email-log');`
|
|
28
|
+
: ''}
|
|
25
29
|
|
|
26
30
|
var INVOICE_PREFIX = ${JSON.stringify(prefix)};
|
|
27
31
|
var DEFAULT_TAX_RATE = ${defaultTaxRate};
|
|
@@ -29,6 +33,7 @@ var DEFAULT_CURRENCY = "USD";
|
|
|
29
33
|
var SHOW_DISCOUNT = ${showDiscount};
|
|
30
34
|
var TAX_INCLUDED_IN_PRICE = ${taxIncludedInPrice};
|
|
31
35
|
var TEMPLATE_DOCUMENT = ${templateDocumentJson};
|
|
36
|
+
${regional_invoice_tax_code_1.REGIONAL_INVOICE_TAX_CODE}
|
|
32
37
|
|
|
33
38
|
// Runtime storage configuration. When all three are set, the generated PDF
|
|
34
39
|
// is also POSTed to the storage worker so consumers (e.g. the payment
|
|
@@ -286,6 +291,9 @@ module.exports = async function handler(req, res) {
|
|
|
286
291
|
: hydratedItems.map(function (row) {
|
|
287
292
|
return {
|
|
288
293
|
productId: row.product_id || row.productId || null,
|
|
294
|
+
// Paired with \`productId\` to find the rate a line was charged at
|
|
295
|
+
// on an order priced by region (see resolveRegionalInvoiceTax).
|
|
296
|
+
variantId: row.variant_id || row.variantId || null,
|
|
289
297
|
name: row.product_name || row.name || 'Item',
|
|
290
298
|
variantLabel: row.variant_label || row.variantLabel || null,
|
|
291
299
|
variantSwatches: row.variant_swatches || row.variantSwatches || null,
|
|
@@ -382,6 +390,28 @@ module.exports = async function handler(req, res) {
|
|
|
382
390
|
}
|
|
383
391
|
var total = goodsTotal + shippingAmount;
|
|
384
392
|
|
|
393
|
+
// An order priced by region records the rate each line was charged at, so
|
|
394
|
+
// its invoice is computed from that record instead of the store default.
|
|
395
|
+
// A caller that states its own \`taxRate\` keeps the single-rate path.
|
|
396
|
+
var taxIncludedInPrice = TAX_INCLUDED_IN_PRICE;
|
|
397
|
+
var regionalTaxBreakdown = body.taxRate == null
|
|
398
|
+
? parseOrderTaxBreakdown(orderShippingSource.tax_breakdown)
|
|
399
|
+
: null;
|
|
400
|
+
if (regionalTaxBreakdown) {
|
|
401
|
+
var regionalTax = resolveRegionalInvoiceTax(regionalTaxBreakdown, items, discountAmount, shippingAmount);
|
|
402
|
+
taxRate = regionalTax.taxRate;
|
|
403
|
+
taxIncludedInPrice = regionalTax.taxIncluded;
|
|
404
|
+
subtotal = regionalTax.subtotal;
|
|
405
|
+
taxAmount = regionalTax.taxAmount;
|
|
406
|
+
shippingAmount = regionalTax.shippingNet;
|
|
407
|
+
total = regionalTax.total;
|
|
408
|
+
for (var ti = 0; ti < items.length; ti++) {
|
|
409
|
+
items[ti].taxRate = regionalTax.itemTax[ti].rate;
|
|
410
|
+
items[ti].taxIncluded = regionalTax.itemTax[ti].included;
|
|
411
|
+
items[ti].taxAmount = regionalTax.itemTax[ti].amount;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
385
415
|
// Cross-check against the amount the order was actually placed for. The
|
|
386
416
|
// invoice is built from line items, the order carries the charged total,
|
|
387
417
|
// and the two must agree — when they don't, the invoice is being written
|
|
@@ -484,7 +514,7 @@ module.exports = async function handler(req, res) {
|
|
|
484
514
|
// this flag the builder can't tell whether the stored unitPrice is
|
|
485
515
|
// a net (added on top) or a gross (included in price) value, and
|
|
486
516
|
// the line-item table renders blank cells.
|
|
487
|
-
taxIncludedInPrice:
|
|
517
|
+
taxIncludedInPrice: taxIncludedInPrice,
|
|
488
518
|
discountAmount: Math.round(discountAmount * 100) / 100,
|
|
489
519
|
// Delivery fee, surfaced so the PDF/HTML renderer can print its own line
|
|
490
520
|
// and the merchant's template can bind \`invoice.shippingAmount\`.
|
|
@@ -603,7 +633,12 @@ ${emailEnabled
|
|
|
603
633
|
currency: currency,
|
|
604
634
|
});
|
|
605
635
|
|
|
606
|
-
|
|
636
|
+
${emailEnabled
|
|
637
|
+
? ` // The email's ledger row is written in the background — land it before
|
|
638
|
+
// replying, a serverless function may be frozen the instant it responds.
|
|
639
|
+
await sentEmailLog.settleSentEmailLog();
|
|
640
|
+
`
|
|
641
|
+
: ''} res.status(200).json({
|
|
607
642
|
success: true,
|
|
608
643
|
invoiceId: invoiceData.id,
|
|
609
644
|
invoiceNumber: invoiceNumber,
|
|
@@ -623,7 +658,10 @@ ${emailEnabled
|
|
|
623
658
|
});
|
|
624
659
|
} catch (error) {
|
|
625
660
|
console.error('[invoice] Generation threw:', error && error.stack ? error.stack : error);
|
|
626
|
-
|
|
661
|
+
${emailEnabled
|
|
662
|
+
? ` await sentEmailLog.settleSentEmailLog();
|
|
663
|
+
`
|
|
664
|
+
: ''} res.status(500).json({ success: false, error: error.message || 'Failed to generate invoice' });
|
|
627
665
|
}
|
|
628
666
|
};
|
|
629
667
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-routes-code.js","sourceRoot":"","sources":["../../../src/invoice/api-routes-code.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"api-routes-code.js","sourceRoot":"","sources":["../../../src/invoice/api-routes-code.ts"],"names":[],"mappings":";;;AACA,2EAAuE;AAEhE,MAAM,gCAAgC,GAAG,CAAC,QAA6B,EAAU,EAAE;;IACxF,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,IAAI,MAAM,CAAA;IAC/C,MAAM,cAAc,GAAG,QAAQ,CAAC,cAAc,IAAI,CAAC,CAAA;IACnD,MAAM,YAAY,GAAG,QAAQ,CAAC,YAAY,KAAK,IAAI,CAAA;IACnD,MAAM,kBAAkB,GAAG,QAAQ,CAAC,kBAAkB,KAAK,IAAI,CAAA;IAC/D,MAAM,YAAY,GAAG,QAAQ,CAAC,qBAAqB,KAAK,KAAK,CAAA;IAC7D,MAAM,YAAY,GAAG,CAAA,MAAA,QAAQ,CAAC,aAAa,0CAAE,OAAO,MAAK,IAAI,CAAA;IAC7D,MAAM,oBAAoB,GAAG,CAAA,MAAA,QAAQ,CAAC,QAAQ,0CAAE,QAAQ;QACtD,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC5C,CAAC,CAAC,MAAM,CAAA;IAEV,OAAO;;;;;;;;;EAUP,YAAY;QACV,CAAC,CAAC;mEAC6D;QAC/D,CAAC,CAAC,EACN;;uBAEuB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;yBACpB,cAAc;;sBAEjB,YAAY;8BACJ,kBAAkB;0BACtB,oBAAoB;EAC5C,qDAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2jBzB,YAAY;QACV,CAAC,CAAC;;;;;;;;;;;;;;;CAeL;QACG,CAAC,CAAC;;CAGN;;;;;;;;;;;EAYE,YAAY;QACV,CAAC,CAAC;;;CAGL;QACG,CAAC,CAAC,EACN;;;;;;;;;;;;;;;;;;;;EAqBE,YAAY;QACV,CAAC,CAAC;CACL;QACG,CAAC,CAAC,EACN;;;CAGC,CAAA;AACD,CAAC,CAAA;AA/pBY,QAAA,gCAAgC,oCA+pB5C;AAEM,MAAM,2BAA2B,GAAG,GAAW,EAAE;IACtD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoDR,CAAA;AACD,CAAC,CAAA;AAtDY,QAAA,2BAA2B,+BAsDvC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email-sender-code.d.ts","sourceRoot":"","sources":["../../../src/invoice/email-sender-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AAErE,eAAO,MAAM,uBAAuB,kBAAmB,wBAAwB,KAAG,
|
|
1
|
+
{"version":3,"file":"email-sender-code.d.ts","sourceRoot":"","sources":["../../../src/invoice/email-sender-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AAErE,eAAO,MAAM,uBAAuB,kBAAmB,wBAAwB,KAAG,MAyFjF,CAAA;AAqND,eAAO,MAAM,4BAA4B,aAAc,MAAM,GAAG,IAAI,KAAG,OAAO,MAAM,EAAE,MAAM,CAkB3F,CAAA"}
|
|
@@ -13,9 +13,15 @@ const generateEmailSenderCode = (emailDelivery) => {
|
|
|
13
13
|
return `/**
|
|
14
14
|
* Invoice Email Sender
|
|
15
15
|
* Provider: ${emailDelivery.provider}
|
|
16
|
+
*
|
|
17
|
+
* \`sendInvoiceEmail\` is the public entry: it builds the message once, hands
|
|
18
|
+
* it to the provider function and records the attempt in the sent-email
|
|
19
|
+
* ledger. The provider function never builds the message itself, so the row
|
|
20
|
+
* carries exactly the subject and body that went out.
|
|
16
21
|
*/
|
|
17
22
|
|
|
18
23
|
var pdfGenerator = require('./pdf-generator');
|
|
24
|
+
var sentEmailLog = require('../email/sent-email-log');
|
|
19
25
|
var replacePlaceholders = pdfGenerator.replacePlaceholders;
|
|
20
26
|
|
|
21
27
|
var SECRET_KEYS = ${secretKeysJson};
|
|
@@ -34,11 +40,52 @@ function buildEmailData(invoiceData) {
|
|
|
34
40
|
body: replacePlaceholders(${JSON.stringify(bodyTemplate)}, data),
|
|
35
41
|
to: invoiceData.customerEmail || '',
|
|
36
42
|
from: ${JSON.stringify(fromName ? `${fromName} <${fromEmail}>` : fromEmail)},
|
|
43
|
+
templateData: data,
|
|
37
44
|
};
|
|
38
45
|
}
|
|
39
46
|
|
|
47
|
+
function attachmentName(invoiceData) {
|
|
48
|
+
return (invoiceData.invoiceNumber || 'invoice') + '.pdf';
|
|
49
|
+
}
|
|
50
|
+
|
|
40
51
|
${generateProviderSendFunction(emailDelivery.provider)}
|
|
41
52
|
|
|
53
|
+
async function sendInvoiceEmail(invoiceData, pdfBuffer) {
|
|
54
|
+
var emailData = buildEmailData(invoiceData);
|
|
55
|
+
if (!emailData.to) return { success: false, error: 'No customer email provided' };
|
|
56
|
+
var result;
|
|
57
|
+
try {
|
|
58
|
+
result = await sendInvoiceEmailWithProvider(emailData, invoiceData, pdfBuffer);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
result = { success: false, error: err && err.message ? err.message : String(err) };
|
|
61
|
+
}
|
|
62
|
+
sentEmailLog.recordSentEmail({
|
|
63
|
+
emailType: 'invoice-email',
|
|
64
|
+
audience: 'customer',
|
|
65
|
+
to: emailData.to,
|
|
66
|
+
from: emailData.from,
|
|
67
|
+
subject: emailData.subject,
|
|
68
|
+
html: emailData.body,
|
|
69
|
+
payload: emailData.templateData,
|
|
70
|
+
attachments: [{
|
|
71
|
+
filename: attachmentName(invoiceData),
|
|
72
|
+
contentType: 'application/pdf',
|
|
73
|
+
sizeBytes: pdfBuffer && pdfBuffer.length ? pdfBuffer.length : null,
|
|
74
|
+
url: invoiceData.pdfUrl || null,
|
|
75
|
+
}],
|
|
76
|
+
provider: ${JSON.stringify(emailDelivery.provider)},
|
|
77
|
+
providerMessageId: result && result.messageId,
|
|
78
|
+
status: result && result.success ? 'sent' : 'failed',
|
|
79
|
+
error: result && !result.success ? result.error : null,
|
|
80
|
+
source: 'invoice',
|
|
81
|
+
sourceRef: 'api/invoices/generate',
|
|
82
|
+
orderId: invoiceData.orderId,
|
|
83
|
+
referenceType: 'invoice',
|
|
84
|
+
referenceId: invoiceData.id,
|
|
85
|
+
});
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
|
|
42
89
|
module.exports = { sendInvoiceEmail };
|
|
43
90
|
`;
|
|
44
91
|
};
|
|
@@ -47,22 +94,19 @@ function generateProviderSendFunction(provider) {
|
|
|
47
94
|
switch (provider) {
|
|
48
95
|
case 'resend':
|
|
49
96
|
return `
|
|
50
|
-
async function
|
|
97
|
+
async function sendInvoiceEmailWithProvider(emailData, invoiceData, pdfBuffer) {
|
|
51
98
|
try {
|
|
52
99
|
var Resend = require('resend').Resend;
|
|
53
100
|
var apiKey = resolveSecretKey('apiKey');
|
|
54
101
|
if (!apiKey) return { success: false, error: 'Resend API key not configured' };
|
|
55
102
|
var resend = new Resend(apiKey);
|
|
56
|
-
var emailData = buildEmailData(invoiceData);
|
|
57
|
-
if (!emailData.to) return { success: false, error: 'No customer email provided' };
|
|
58
|
-
|
|
59
103
|
var payload = {
|
|
60
104
|
from: emailData.from,
|
|
61
105
|
to: [emailData.to],
|
|
62
106
|
subject: emailData.subject,
|
|
63
107
|
html: emailData.body,
|
|
64
108
|
attachments: [{
|
|
65
|
-
filename: (invoiceData
|
|
109
|
+
filename: attachmentName(invoiceData),
|
|
66
110
|
content: pdfBuffer.toString('base64'),
|
|
67
111
|
}],
|
|
68
112
|
};
|
|
@@ -75,15 +119,12 @@ async function sendInvoiceEmail(invoiceData, pdfBuffer) {
|
|
|
75
119
|
}`;
|
|
76
120
|
case 'sendgrid':
|
|
77
121
|
return `
|
|
78
|
-
async function
|
|
122
|
+
async function sendInvoiceEmailWithProvider(emailData, invoiceData, pdfBuffer) {
|
|
79
123
|
try {
|
|
80
124
|
var sgMail = require('@sendgrid/mail');
|
|
81
125
|
var apiKey = resolveSecretKey('apiKey');
|
|
82
126
|
if (!apiKey) return { success: false, error: 'SendGrid API key not configured' };
|
|
83
127
|
sgMail.setApiKey(apiKey);
|
|
84
|
-
var emailData = buildEmailData(invoiceData);
|
|
85
|
-
if (!emailData.to) return { success: false, error: 'No customer email provided' };
|
|
86
|
-
|
|
87
128
|
var msg = {
|
|
88
129
|
to: emailData.to,
|
|
89
130
|
from: emailData.from,
|
|
@@ -91,7 +132,7 @@ async function sendInvoiceEmail(invoiceData, pdfBuffer) {
|
|
|
91
132
|
html: emailData.body,
|
|
92
133
|
attachments: [{
|
|
93
134
|
content: pdfBuffer.toString('base64'),
|
|
94
|
-
filename: (invoiceData
|
|
135
|
+
filename: attachmentName(invoiceData),
|
|
95
136
|
type: 'application/pdf',
|
|
96
137
|
disposition: 'attachment',
|
|
97
138
|
}],
|
|
@@ -104,7 +145,7 @@ async function sendInvoiceEmail(invoiceData, pdfBuffer) {
|
|
|
104
145
|
}`;
|
|
105
146
|
case 'mailgun':
|
|
106
147
|
return `
|
|
107
|
-
async function
|
|
148
|
+
async function sendInvoiceEmailWithProvider(emailData, invoiceData, pdfBuffer) {
|
|
108
149
|
try {
|
|
109
150
|
var Mailgun = require('mailgun.js');
|
|
110
151
|
var formData = require('form-data');
|
|
@@ -115,9 +156,6 @@ async function sendInvoiceEmail(invoiceData, pdfBuffer) {
|
|
|
115
156
|
|
|
116
157
|
var mailgun = new Mailgun(formData);
|
|
117
158
|
var mg = mailgun.client({ username: 'api', key: apiKey });
|
|
118
|
-
var emailData = buildEmailData(invoiceData);
|
|
119
|
-
if (!emailData.to) return { success: false, error: 'No customer email provided' };
|
|
120
|
-
|
|
121
159
|
var msg = {
|
|
122
160
|
from: emailData.from,
|
|
123
161
|
to: [emailData.to],
|
|
@@ -125,7 +163,7 @@ async function sendInvoiceEmail(invoiceData, pdfBuffer) {
|
|
|
125
163
|
html: emailData.body,
|
|
126
164
|
attachment: [{
|
|
127
165
|
data: pdfBuffer,
|
|
128
|
-
filename: (invoiceData
|
|
166
|
+
filename: attachmentName(invoiceData),
|
|
129
167
|
contentType: 'application/pdf',
|
|
130
168
|
}],
|
|
131
169
|
};
|
|
@@ -137,22 +175,19 @@ async function sendInvoiceEmail(invoiceData, pdfBuffer) {
|
|
|
137
175
|
}`;
|
|
138
176
|
case 'postmark':
|
|
139
177
|
return `
|
|
140
|
-
async function
|
|
178
|
+
async function sendInvoiceEmailWithProvider(emailData, invoiceData, pdfBuffer) {
|
|
141
179
|
try {
|
|
142
180
|
var postmark = require('postmark');
|
|
143
181
|
var serverToken = resolveSecretKey('serverToken');
|
|
144
182
|
if (!serverToken) return { success: false, error: 'Postmark server token not configured' };
|
|
145
183
|
var client = new postmark.ServerClient(serverToken);
|
|
146
|
-
var emailData = buildEmailData(invoiceData);
|
|
147
|
-
if (!emailData.to) return { success: false, error: 'No customer email provided' };
|
|
148
|
-
|
|
149
184
|
var msg = {
|
|
150
185
|
From: emailData.from,
|
|
151
186
|
To: emailData.to,
|
|
152
187
|
Subject: emailData.subject,
|
|
153
188
|
HtmlBody: emailData.body,
|
|
154
189
|
Attachments: [{
|
|
155
|
-
Name: (invoiceData
|
|
190
|
+
Name: attachmentName(invoiceData),
|
|
156
191
|
Content: pdfBuffer.toString('base64'),
|
|
157
192
|
ContentType: 'application/pdf',
|
|
158
193
|
}],
|
|
@@ -185,7 +220,7 @@ function parseFromString(from) {
|
|
|
185
220
|
return { name: '', email: str };
|
|
186
221
|
}
|
|
187
222
|
|
|
188
|
-
async function
|
|
223
|
+
async function sendInvoiceEmailWithProvider(emailData, invoiceData, pdfBuffer) {
|
|
189
224
|
var invoiceNumber = invoiceData && invoiceData.invoiceNumber ? invoiceData.invoiceNumber : '(no number)';
|
|
190
225
|
try {
|
|
191
226
|
console.info('[invoice-email][mailersend] begin — invoice=' + invoiceNumber +
|
|
@@ -196,12 +231,6 @@ async function sendInvoiceEmail(invoiceData, pdfBuffer) {
|
|
|
196
231
|
console.error('[invoice-email][mailersend] skip — API key not configured (set \`apiKey\` secret or INVOICE_MAILERSEND_APIKEY env)');
|
|
197
232
|
return { success: false, error: 'MailerSend API key not configured' };
|
|
198
233
|
}
|
|
199
|
-
var emailData = buildEmailData(invoiceData);
|
|
200
|
-
if (!emailData.to) {
|
|
201
|
-
console.error('[invoice-email][mailersend] skip — invoiceData.customerEmail is empty (order hydrating yielded no billing_email; set it on the order row or pass customerEmail in the generate payload)');
|
|
202
|
-
return { success: false, error: 'No customer email provided' };
|
|
203
|
-
}
|
|
204
|
-
|
|
205
234
|
var MailerSend = require('mailersend').MailerSend;
|
|
206
235
|
var EmailParams = require('mailersend').EmailParams;
|
|
207
236
|
var Sender = require('mailersend').Sender;
|
|
@@ -219,7 +248,7 @@ async function sendInvoiceEmail(invoiceData, pdfBuffer) {
|
|
|
219
248
|
|
|
220
249
|
var attachment = new Attachment(
|
|
221
250
|
pdfBuffer.toString('base64'),
|
|
222
|
-
(invoiceData
|
|
251
|
+
attachmentName(invoiceData),
|
|
223
252
|
'attachment'
|
|
224
253
|
);
|
|
225
254
|
|
|
@@ -261,7 +290,7 @@ async function sendInvoiceEmail(invoiceData, pdfBuffer) {
|
|
|
261
290
|
}`;
|
|
262
291
|
default:
|
|
263
292
|
return `
|
|
264
|
-
async function
|
|
293
|
+
async function sendInvoiceEmailWithProvider() {
|
|
265
294
|
return { success: false, error: 'Unsupported email provider: ${provider}' };
|
|
266
295
|
}`;
|
|
267
296
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email-sender-code.js","sourceRoot":"","sources":["../../../src/invoice/email-sender-code.ts"],"names":[],"mappings":";;;AAEO,MAAM,uBAAuB,GAAG,CAAC,aAAuC,EAAU,EAAE;IACzF,IAAI,CAAC,aAAa,IAAI,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE;QACvE,OAAO,iIAAiI,CAAA;KACzI;IAED,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,UAAU,IAAI,EAAE,CAAC,CAAA;IACrE,MAAM,SAAS,GAAG,aAAa,CAAC,SAAS,IAAI,EAAE,CAAA;IAC/C,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,IAAI,EAAE,CAAA;IAC7C,MAAM,eAAe,GAAG,aAAa,CAAC,OAAO,IAAI,2BAA2B,CAAA;IAC5E,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,IAAI,2CAA2C,CAAA;IAEtF,OAAO;;eAEM,aAAa,CAAC,QAAQ
|
|
1
|
+
{"version":3,"file":"email-sender-code.js","sourceRoot":"","sources":["../../../src/invoice/email-sender-code.ts"],"names":[],"mappings":";;;AAEO,MAAM,uBAAuB,GAAG,CAAC,aAAuC,EAAU,EAAE;IACzF,IAAI,CAAC,aAAa,IAAI,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE;QACvE,OAAO,iIAAiI,CAAA;KACzI;IAED,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,UAAU,IAAI,EAAE,CAAC,CAAA;IACrE,MAAM,SAAS,GAAG,aAAa,CAAC,SAAS,IAAI,EAAE,CAAA;IAC/C,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,IAAI,EAAE,CAAA;IAC7C,MAAM,eAAe,GAAG,aAAa,CAAC,OAAO,IAAI,2BAA2B,CAAA;IAC5E,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,IAAI,2CAA2C,CAAA;IAEtF,OAAO;;eAEM,aAAa,CAAC,QAAQ;;;;;;;;;;;;oBAYjB,cAAc;;;;;;;;;;;;mCAYC,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC;gCAClC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC;;YAEhD,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,KAAK,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;;;;;;;;;EAS7E,4BAA4B,CAAC,aAAa,CAAC,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;gBAyBtC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC;;;;;;;;;;;;;;CAcrD,CAAA;AACD,CAAC,CAAA;AAzFY,QAAA,uBAAuB,2BAyFnC;AAED,SAAS,4BAA4B,CAAC,QAAgB;IACpD,QAAQ,QAAQ,EAAE;QAChB,KAAK,QAAQ;YACX,OAAO;;;;;;;;;;;;;;;;;;;;;;;EAuBX,CAAA;QAEE,KAAK,UAAU;YACb,OAAO;;;;;;;;;;;;;;;;;;;;;;;;EAwBX,CAAA;QAEE,KAAK,SAAS;YACZ,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BX,CAAA;QAEE,KAAK,UAAU;YACb,OAAO;;;;;;;;;;;;;;;;;;;;;;;EAuBX,CAAA;QAEE,KAAK,YAAY;YACf,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwFX,CAAA;QAEE;YACE,OAAO;;iEAEoD,QAAQ;EACvE,CAAA;KACC;AACH,CAAC;AAEM,MAAM,4BAA4B,GAAG,CAAC,QAAuB,EAA0B,EAAE;IAC9F,IAAI,CAAC,QAAQ,EAAE;QACb,OAAO,EAAE,CAAA;KACV;IACD,QAAQ,QAAQ,EAAE;QAChB,KAAK,QAAQ;YACX,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAA;QAC7B,KAAK,UAAU;YACb,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,CAAA;QACvC,KAAK,SAAS;YACZ,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAA;QAC3D,KAAK,UAAU;YACb,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAA;QAC/B,KAAK,YAAY;YACf,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAA;QACjC;YACE,OAAO,EAAE,CAAA;KACZ;AACH,CAAC,CAAA;AAlBY,QAAA,4BAA4B,gCAkBxC"}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import { ProjectPluginStructure, UIDLInvoiceSettings, DataSourceType } from '@teleporthq/teleport-types';
|
|
2
2
|
export declare const generateInvoiceFiles: (invoiceSettings: UIDLInvoiceSettings, structure: ProjectPluginStructure, dataSourceType: DataSourceType | null, dataSourceConfig: Record<string, unknown> | null) => void;
|
|
3
|
-
export
|
|
4
|
-
dataSourceType: DataSourceType | null;
|
|
5
|
-
dataSourceConfig: Record<string, unknown> | null;
|
|
6
|
-
};
|
|
3
|
+
export { resolveInvoiceDataSource } from './resolve-data-source';
|
|
7
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/invoice/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EAEtB,mBAAmB,EACnB,cAAc,EACf,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/invoice/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EAEtB,mBAAmB,EACnB,cAAc,EACf,MAAM,4BAA4B,CAAA;AAQnC,eAAO,MAAM,oBAAoB,oBACd,mBAAmB,aACzB,sBAAsB,kBACjB,cAAc,GAAG,IAAI,oBACnB,OAAO,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,KAC/C,IA6IF,CAAA;AAED,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA"}
|
|
@@ -7,6 +7,7 @@ const email_sender_code_1 = require("./email-sender-code");
|
|
|
7
7
|
const data_access_code_1 = require("./data-access-code");
|
|
8
8
|
const api_routes_code_1 = require("./api-routes-code");
|
|
9
9
|
const auth_generator_1 = require("../auth-generator");
|
|
10
|
+
const sent_email_log_1 = require("../sent-email-log");
|
|
10
11
|
const generateInvoiceFiles = (invoiceSettings, structure, dataSourceType, dataSourceConfig) => {
|
|
11
12
|
var _a;
|
|
12
13
|
const { files, dependencies } = structure;
|
|
@@ -49,6 +50,8 @@ const generateInvoiceFiles = (invoiceSettings, structure, dataSourceType, dataSo
|
|
|
49
50
|
],
|
|
50
51
|
});
|
|
51
52
|
if ((_a = invoiceSettings.emailDelivery) === null || _a === void 0 ? void 0 : _a.enabled) {
|
|
53
|
+
// The sender records every attempt in the sent-email ledger.
|
|
54
|
+
(0, sent_email_log_1.ensureSentEmailLogModule)(structure);
|
|
52
55
|
const emailSenderCode = (0, email_sender_code_1.generateEmailSenderCode)(invoiceSettings.emailDelivery);
|
|
53
56
|
files.set('invoice-email-sender', {
|
|
54
57
|
path: ['utils', 'invoices'],
|
|
@@ -134,23 +137,6 @@ const generateInvoiceFiles = (invoiceSettings, structure, dataSourceType, dataSo
|
|
|
134
137
|
}
|
|
135
138
|
};
|
|
136
139
|
exports.generateInvoiceFiles = generateInvoiceFiles;
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const { uidl } = structure;
|
|
140
|
-
if (!uidl.dataSources) {
|
|
141
|
-
return { dataSourceType: null, dataSourceConfig: null };
|
|
142
|
-
}
|
|
143
|
-
if ((_a = uidl.authentication) === null || _a === void 0 ? void 0 : _a.dataSourceId) {
|
|
144
|
-
const ds = uidl.dataSources[uidl.authentication.dataSourceId];
|
|
145
|
-
if (ds) {
|
|
146
|
-
return { dataSourceType: ds.type, dataSourceConfig: ds.config };
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
const dsEntries = Object.values(uidl.dataSources);
|
|
150
|
-
if (dsEntries.length > 0) {
|
|
151
|
-
return { dataSourceType: dsEntries[0].type, dataSourceConfig: dsEntries[0].config };
|
|
152
|
-
}
|
|
153
|
-
return { dataSourceType: null, dataSourceConfig: null };
|
|
154
|
-
};
|
|
155
|
-
exports.resolveInvoiceDataSource = resolveInvoiceDataSource;
|
|
140
|
+
var resolve_data_source_1 = require("./resolve-data-source");
|
|
141
|
+
Object.defineProperty(exports, "resolveInvoiceDataSource", { enumerable: true, get: function () { return resolve_data_source_1.resolveInvoiceDataSource; } });
|
|
156
142
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/invoice/index.ts"],"names":[],"mappings":";;;AAAA,+DAKmC;AACnC,6DAA+D;AAC/D,2DAA2F;AAC3F,yDAAiF;AACjF,uDAAiG;AACjG,sDAAiE;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/invoice/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoice-html-code.d.ts","sourceRoot":"","sources":["../../../src/invoice/invoice-html-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AA4HhE,eAAO,MAAM,uBAAuB,aACxB,mBAAmB,uBACR,OAAO,iBACb,OAAO,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,KACxD,
|
|
1
|
+
{"version":3,"file":"invoice-html-code.d.ts","sourceRoot":"","sources":["../../../src/invoice/invoice-html-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AA4HhE,eAAO,MAAM,uBAAuB,aACxB,mBAAmB,uBACR,OAAO,iBACb,OAAO,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,KACxD,MA65BF,CAAA"}
|
|
@@ -285,6 +285,7 @@ function buildInvoiceDataScope(invoiceData) {
|
|
|
285
285
|
discountAmount: formatCurrencyValue(invoiceData.discountAmount, sym),
|
|
286
286
|
shippingAmount: formatCurrencyValue(shippingAmountNumber, sym),
|
|
287
287
|
hasShipping: shippingAmountNumber > 0 ? 'true' : 'false',
|
|
288
|
+
hasTax: Number(invoiceData.taxAmount) > 0 ? 'true' : 'false',
|
|
288
289
|
total: formatCurrencyValue(invoiceData.total, sym),
|
|
289
290
|
currency: invoiceData.currency || 'USD',
|
|
290
291
|
currencySymbol: sym,
|
|
@@ -331,13 +332,18 @@ function buildInvoiceDataScope(invoiceData) {
|
|
|
331
332
|
var lineStored = Number(it.totalPrice || it.total_price);
|
|
332
333
|
if (!isFinite(lineStored) || lineStored === 0) lineStored = qty * unitStored;
|
|
333
334
|
|
|
334
|
-
|
|
335
|
-
|
|
335
|
+
// A line on an order priced by region carries its own rate and inclusion
|
|
336
|
+
// mode (a food line at 7% beside a tools line at 19%); every other line is
|
|
337
|
+
// taxed at the invoice's single rate.
|
|
338
|
+
var lineRate = typeof it.taxIncluded === 'boolean' ? Number(it.taxRate) || 0 : taxRate;
|
|
339
|
+
var lineIncluded = typeof it.taxIncluded === 'boolean' ? it.taxIncluded : taxIncluded;
|
|
340
|
+
var unitNet = computeNetFromGrossValue(unitStored, lineRate, lineIncluded);
|
|
341
|
+
var lineNet = computeNetFromGrossValue(lineStored, lineRate, lineIncluded);
|
|
336
342
|
// Per-unit VAT mirrors the GUI helper: derived from the NET unit
|
|
337
343
|
// price at the configured rate (rather than dividing line VAT by qty,
|
|
338
344
|
// which yields odd values when qty is 0 or missing).
|
|
339
|
-
var unitVat = computeLineVatAmountValue(unitStored,
|
|
340
|
-
var lineVat = computeLineVatAmountValue(lineStored,
|
|
345
|
+
var unitVat = computeLineVatAmountValue(unitStored, lineRate, lineIncluded);
|
|
346
|
+
var lineVat = computeLineVatAmountValue(lineStored, lineRate, lineIncluded);
|
|
341
347
|
var unitGross = unitNet + unitVat;
|
|
342
348
|
var lineGross = lineNet + lineVat;
|
|
343
349
|
|
|
@@ -375,6 +381,9 @@ function buildInvoiceDataScope(invoiceData) {
|
|
|
375
381
|
lineTotalNet: formatCurrencyValue(lineNet, sym),
|
|
376
382
|
lineTotalGross: formatCurrencyValue(lineGross, sym),
|
|
377
383
|
lineVatAmount: formatCurrencyValue(lineVat, sym),
|
|
384
|
+
// The rate this line was taxed at ("20%"): its own on an order priced by
|
|
385
|
+
// region, the invoice's single rate otherwise. Bound by the VAT % column.
|
|
386
|
+
lineVatRate: (lineRate > 0 ? Math.round(lineRate * 100) / 100 : 0) + '%',
|
|
378
387
|
sku: it.sku || '',
|
|
379
388
|
itemTaxRate: it.taxRate != null ? String(it.taxRate) : (taxRate > 0 ? String(taxRate) : ''),
|
|
380
389
|
itemTaxAmount: it.taxAmount != null ? formatCurrencyValue(it.taxAmount, sym) : formatCurrencyValue(lineVat, sym),
|
|
@@ -545,13 +554,20 @@ function resolveReferenceValue(ref, scope) {
|
|
|
545
554
|
}
|
|
546
555
|
|
|
547
556
|
function matchConditionOperation(val, op, operand) {
|
|
557
|
+
// The editor stores every operand as a STRING ('true', '0'), while
|
|
558
|
+
// \`resolveReferenceValue\` hands back a typed value for \`expr\` references
|
|
559
|
+
// (it turns 'true' into boolean true). A strict \`===\` across those two
|
|
560
|
+
// shapes never matches — that is how the template's Delivery row, gated on
|
|
561
|
+
// \`Invoice.hasShipping = 'true'\`, stayed hidden on every invoice with a
|
|
562
|
+
// fee — so mixed-type equality compares the string forms instead.
|
|
563
|
+
var sameType = typeof val === typeof operand;
|
|
548
564
|
switch (op) {
|
|
549
565
|
case '=':
|
|
550
566
|
case '===':
|
|
551
|
-
return val === operand;
|
|
567
|
+
return sameType ? val === operand : String(val) === String(operand);
|
|
552
568
|
case '!=':
|
|
553
569
|
case '!==':
|
|
554
|
-
return val !== operand;
|
|
570
|
+
return sameType ? val !== operand : String(val) !== String(operand);
|
|
555
571
|
case '>': return Number(val) > Number(operand);
|
|
556
572
|
case '<': return Number(val) < Number(operand);
|
|
557
573
|
case '>=': return Number(val) >= Number(operand);
|
|
@@ -896,18 +912,25 @@ function buildFallbackInvoiceHtml(scope) {
|
|
|
896
912
|
'<th style="text-align:left;border-bottom:2px solid #333;padding:6px;">Item</th>' +
|
|
897
913
|
'<th style="text-align:right;border-bottom:2px solid #333;padding:6px;">Qty</th>' +
|
|
898
914
|
'<th style="text-align:right;border-bottom:2px solid #333;padding:6px;">Unit Price</th>' +
|
|
915
|
+
'<th style="text-align:right;border-bottom:2px solid #333;padding:6px;">VAT %</th>' +
|
|
916
|
+
'<th style="text-align:right;border-bottom:2px solid #333;padding:6px;">VAT</th>' +
|
|
899
917
|
'<th style="text-align:right;border-bottom:2px solid #333;padding:6px;">Total</th>' +
|
|
900
918
|
'</tr></thead><tbody>');
|
|
901
919
|
products.forEach(function (p) {
|
|
902
920
|
parts.push('<tr>' +
|
|
903
921
|
'<td style="border-bottom:1px solid #eee;padding:6px;">' + (p.variantSwatchesHtml || '') + escapeHtml(p.name) + '</td>' +
|
|
904
922
|
'<td style="border-bottom:1px solid #eee;padding:6px;text-align:right;">' + escapeHtml(p.quantity) + '</td>' +
|
|
905
|
-
'<td style="border-bottom:1px solid #eee;padding:6px;text-align:right;">' + escapeHtml(p.
|
|
906
|
-
'<td style="border-bottom:1px solid #eee;padding:6px;text-align:right;">' + escapeHtml(p.
|
|
923
|
+
'<td style="border-bottom:1px solid #eee;padding:6px;text-align:right;">' + escapeHtml(p.unitPriceNet) + '</td>' +
|
|
924
|
+
'<td style="border-bottom:1px solid #eee;padding:6px;text-align:right;">' + escapeHtml(p.lineVatRate) + '</td>' +
|
|
925
|
+
'<td style="border-bottom:1px solid #eee;padding:6px;text-align:right;">' + escapeHtml(p.lineVatAmount) + '</td>' +
|
|
926
|
+
'<td style="border-bottom:1px solid #eee;padding:6px;text-align:right;">' + escapeHtml(p.lineTotalGross) + '</td>' +
|
|
907
927
|
'</tr>');
|
|
908
928
|
});
|
|
909
929
|
parts.push('</tbody></table>');
|
|
910
930
|
var totalsRows = '<div style="display:flex;justify-content:space-between;margin-bottom:4px;"><span>Subtotal</span><span>' + escapeHtml(inv.subtotal) + '</span></div>';
|
|
931
|
+
if (inv.hasTax === 'true') {
|
|
932
|
+
totalsRows += '<div style="display:flex;justify-content:space-between;margin-bottom:4px;"><span>VAT</span><span>' + escapeHtml(inv.taxAmount) + '</span></div>';
|
|
933
|
+
}
|
|
911
934
|
if (inv.hasShipping === 'true') {
|
|
912
935
|
totalsRows += '<div style="display:flex;justify-content:space-between;margin-bottom:4px;"><span>Delivery</span><span>' + escapeHtml(inv.shippingAmount) + '</span></div>';
|
|
913
936
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoice-html-code.js","sourceRoot":"","sources":["../../../src/invoice/invoice-html-code.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"invoice-html-code.js","sourceRoot":"","sources":["../../../src/invoice/invoice-html-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Invoice VAT for an order placed on a store with shipping zones and tax
|
|
3
|
+
* jurisdictions, as source for the generated `/api/invoices/generate` route.
|
|
4
|
+
*
|
|
5
|
+
* Such an order does not have ONE rate: a German food line at 7% can sit beside
|
|
6
|
+
* a tools line at 19%, a French order's prices may include VAT while the store
|
|
7
|
+
* default adds it on top, and the delivery fee may be taxed. The store's
|
|
8
|
+
* baked `DEFAULT_TAX_RATE` / `TAX_INCLUDED_IN_PRICE` describe none of that, so
|
|
9
|
+
* the place-order workflow records what was actually charged in
|
|
10
|
+
* `teleport_orders.tax_breakdown`, and this prices the invoice from it.
|
|
11
|
+
*
|
|
12
|
+
* Totals reconcile with `teleport_orders.total_amount` by construction:
|
|
13
|
+
* `goods (gross) + shipping_amount (gross) - discount_amount`. The discount is
|
|
14
|
+
* taken off the goods first and only then off the shipping, exactly as the
|
|
15
|
+
* payment line items split it, and each part's tax shrinks in proportion.
|
|
16
|
+
*
|
|
17
|
+
* The printed rows add up too: `subtotal` (goods, net) + `taxAmount` (goods
|
|
18
|
+
* AND shipping tax) + `shippingNet` = `total`. Delivery is therefore shown net
|
|
19
|
+
* of its tax, or its tax would be counted twice.
|
|
20
|
+
*
|
|
21
|
+
* An order without a breakdown — every order placed before regions existed —
|
|
22
|
+
* returns null and keeps the single-rate arithmetic it was always invoiced with.
|
|
23
|
+
*/
|
|
24
|
+
export declare const REGIONAL_INVOICE_TAX_CODE = "\nfunction parseOrderTaxBreakdown(raw) {\n if (!raw) return null;\n var parsed = raw;\n if (typeof raw === 'string') {\n try {\n parsed = JSON.parse(raw);\n } catch (e) {\n return null;\n }\n }\n if (!parsed || typeof parsed !== 'object' || !Array.isArray(parsed.lines)) return null;\n return parsed;\n}\n\nfunction regionalInvoiceRound(value, decimals) {\n var factor = decimals === 0 ? 1 : 100;\n var n = Number(value);\n return Math.round((isFinite(n) ? n : 0) * factor) / factor;\n}\n\n// items: the invoice lines as the route normalised them (productId, variantId,\n// quantity, unitPrice, totalPrice \u2014 all stored, i.e. NET where tax is added on\n// top and GROSS where it is included).\nfunction resolveRegionalInvoiceTax(breakdown, items, discountAmount, shippingAmount) {\n var decimals = breakdown.taxDecimals === 0 ? 0 : 2;\n var standardRate = Number(breakdown.taxRate);\n if (!isFinite(standardRate) || standardRate < 0) standardRate = 0;\n var standardIncluded = breakdown.taxIncluded === true;\n var claimed = [];\n var itemTax = [];\n var goodsGross = 0;\n var goodsTax = 0;\n for (var i = 0; i < items.length; i++) {\n var item = items[i];\n var match = null;\n for (var l = 0; l < breakdown.lines.length; l++) {\n var line = breakdown.lines[l];\n if (!line || claimed.indexOf(l) !== -1) continue;\n if (\n String(line.productId || '') === String(item.productId || '') &&\n String(line.variantId || '') === String(item.variantId || '')\n ) {\n match = line;\n claimed.push(l);\n break;\n }\n }\n var matchedRate = match ? Number(match.taxRate) : NaN;\n var rate = isFinite(matchedRate) && matchedRate >= 0 ? matchedRate : standardRate;\n var included = match ? match.taxIncluded === true : standardIncluded;\n var quantity = Number(item.quantity) || 1;\n var stored = Number(item.totalPrice) || 0;\n var lineGross = !included && rate > 0\n ? regionalInvoiceRound(\n regionalInvoiceRound((Number(item.unitPrice) || 0) * (1 + rate / 100), decimals) * quantity,\n decimals\n )\n : stored;\n var lineTax = included\n ? (rate > 0 ? stored - stored / (1 + rate / 100) : 0)\n : lineGross - stored;\n goodsGross += lineGross;\n goodsTax += lineTax;\n itemTax.push({ rate: rate, included: included, amount: regionalInvoiceRound(lineTax, decimals) });\n }\n\n var discount = discountAmount > 0 ? discountAmount : 0;\n var shipping = shippingAmount > 0 ? shippingAmount : 0;\n var goodsAfter = Math.max(0, goodsGross - discount);\n var goodsShare = goodsGross > 0 ? goodsAfter / goodsGross : 0;\n var shippingAfter = Math.max(0, shipping - Math.max(0, discount - goodsGross));\n var shippingShare = shipping > 0 ? shippingAfter / shipping : 0;\n var shippingTax = Number(breakdown.shippingTax);\n if (!isFinite(shippingTax) || shippingTax < 0) shippingTax = 0;\n var allocatedGoodsTax = goodsTax * goodsShare;\n var allocatedShippingTax = shippingTax * shippingShare;\n\n return {\n taxRate: standardRate,\n taxIncluded: standardIncluded,\n subtotal: goodsAfter - allocatedGoodsTax,\n taxAmount: allocatedGoodsTax + allocatedShippingTax,\n shippingNet: shippingAfter - allocatedShippingTax,\n total: goodsAfter + shippingAfter,\n itemTax: itemTax,\n };\n}\n";
|
|
25
|
+
//# sourceMappingURL=regional-invoice-tax-code.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regional-invoice-tax-code.d.ts","sourceRoot":"","sources":["../../../src/invoice/regional-invoice-tax-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,yBAAyB,8zGAwFrC,CAAA"}
|