@teleporthq/teleport-plugin-next-workflows 0.44.4 → 0.44.6

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.
Files changed (29) hide show
  1. package/__tests__/account-delete-owned-rows.test.ts +488 -0
  2. package/__tests__/invoice-paid-status.test.ts +382 -0
  3. package/__tests__/invoice-tender.test.ts +5 -3
  4. package/dist/cjs/account-delete-route-generator.d.ts +9 -6
  5. package/dist/cjs/account-delete-route-generator.d.ts.map +1 -1
  6. package/dist/cjs/account-delete-route-generator.js +131 -1
  7. package/dist/cjs/account-delete-route-generator.js.map +1 -1
  8. package/dist/cjs/invoice/invoice-assembly-code.d.ts.map +1 -1
  9. package/dist/cjs/invoice/invoice-assembly-code.js +19 -2
  10. package/dist/cjs/invoice/invoice-assembly-code.js.map +1 -1
  11. package/dist/cjs/invoice/invoice-html-code.d.ts.map +1 -1
  12. package/dist/cjs/invoice/invoice-html-code.js +100 -71
  13. package/dist/cjs/invoice/invoice-html-code.js.map +1 -1
  14. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  15. package/dist/esm/account-delete-route-generator.d.ts +9 -6
  16. package/dist/esm/account-delete-route-generator.d.ts.map +1 -1
  17. package/dist/esm/account-delete-route-generator.js +131 -1
  18. package/dist/esm/account-delete-route-generator.js.map +1 -1
  19. package/dist/esm/invoice/invoice-assembly-code.d.ts.map +1 -1
  20. package/dist/esm/invoice/invoice-assembly-code.js +19 -2
  21. package/dist/esm/invoice/invoice-assembly-code.js.map +1 -1
  22. package/dist/esm/invoice/invoice-html-code.d.ts.map +1 -1
  23. package/dist/esm/invoice/invoice-html-code.js +100 -71
  24. package/dist/esm/invoice/invoice-html-code.js.map +1 -1
  25. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  26. package/package.json +3 -3
  27. package/src/account-delete-route-generator.ts +140 -7
  28. package/src/invoice/invoice-assembly-code.ts +19 -2
  29. package/src/invoice/invoice-html-code.ts +100 -71
@@ -94,6 +94,16 @@ var CURRENCY_SYMBOLS = {
94
94
  'CLP': 'CLP$', 'PEN': 'S/.', 'VND': '\\u20AB', 'UAH': '\\u20B4',
95
95
  };
96
96
 
97
+ // \`teleport_orders.payment_status\` values that mean the order's money was
98
+ // collected — the editor's PAID_PAYMENT_STATUS_VALUES (teleport-gui
99
+ // e-commerce/constants/order-statuses.ts), provider spellings included.
100
+ var PAID_ORDER_PAYMENT_STATUSES = ['paid', 'partially_refunded', 'succeeded', 'success', 'completed', 'captured'];
101
+
102
+ function isPaidOrder(order) {
103
+ var paymentStatus = String((order && order.payment_status) || '').trim().toLowerCase();
104
+ return PAID_ORDER_PAYMENT_STATUSES.indexOf(paymentStatus) !== -1;
105
+ }
106
+
97
107
  function isLoopbackHost(host) {
98
108
  var name = String(host || '').replace(/:[0-9]+$/, '').toLowerCase();
99
109
  return name === 'localhost' || name === '127.0.0.1' || name === '[::1]';
@@ -474,15 +484,22 @@ function assembleInvoiceData(body, hydratedOrder, hydratedItems) {
474
484
  var fallbackPaymentIntentId = orderRow.payment_intent_id || '';
475
485
  var fallbackNotes = orderRow.notes || '';
476
486
 
487
+ // Paid or not, when the caller does not say: the order's money state. The
488
+ // payment webhook marks an order paid and then asks for its invoice with just
489
+ // the order id; a cash-on-delivery order is invoiced unpaid when it is placed.
490
+ // The orders table keeps no payment time of its own — the mark-paid write
491
+ // stamps \`updated_at\`, just before the webhook asks.
492
+ var paidByOrder = !body.status && isPaidOrder(orderRow);
493
+
477
494
  var invoiceData = {
478
495
  id: body.id || require('crypto').randomUUID(),
479
496
  // Numbered by the route: an invoice issued at payment takes the next
480
497
  // number, a regenerated one keeps its own.
481
498
  invoiceNumber: '',
482
- status: body.status || 'issued',
499
+ status: body.status || (paidByOrder ? 'paid' : 'issued'),
483
500
  issueDate: issueDate,
484
501
  dueDate: dueDate,
485
- paidAt: body.paidAt || null,
502
+ paidAt: body.paidAt || (paidByOrder ? orderRow.updated_at || new Date().toISOString() : null),
486
503
  customerName: body.customerName || fallbackCustomerName || '',
487
504
  customerEmail: body.customerEmail || fallbackCustomerEmail || '',
488
505
  customerAddress: body.customerAddress || fallbackCustomerAddress || '',
@@ -1 +1 @@
1
- {"version":3,"file":"invoice-assembly-code.js","sourceRoot":"","sources":["../../../src/invoice/invoice-assembly-code.ts"],"names":[],"mappings":";;;AACA,iEAA4D;AAC5D,2EAAuE;AAEvE;;;;;;;;GAQG;AACI,MAAM,2BAA2B,GAAG,CAAC,QAA6B,EAAU,EAAE;;IACnF,MAAM,cAAc,GAAG,QAAQ,CAAC,cAAc,IAAI,CAAC,CAAA;IACnD,MAAM,kBAAkB,GAAG,QAAQ,CAAC,kBAAkB,KAAK,IAAI,CAAA;IAC/D,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;;;;;;;;yBAQgB,cAAc;;8BAET,kBAAkB;0BACtB,oBAAoB;EAC5C,qDAAyB;EACzB,gCAAc,CAAC,gCAAgC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2gBlD,CAAA;AACD,CAAC,CAAA;AAhiBY,QAAA,2BAA2B,+BAgiBvC"}
1
+ {"version":3,"file":"invoice-assembly-code.js","sourceRoot":"","sources":["../../../src/invoice/invoice-assembly-code.ts"],"names":[],"mappings":";;;AACA,iEAA4D;AAC5D,2EAAuE;AAEvE;;;;;;;;GAQG;AACI,MAAM,2BAA2B,GAAG,CAAC,QAA6B,EAAU,EAAE;;IACnF,MAAM,cAAc,GAAG,QAAQ,CAAC,cAAc,IAAI,CAAC,CAAA;IACnD,MAAM,kBAAkB,GAAG,QAAQ,CAAC,kBAAkB,KAAK,IAAI,CAAA;IAC/D,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;;;;;;;;yBAQgB,cAAc;;8BAET,kBAAkB;0BACtB,oBAAoB;EAC5C,qDAAyB;EACzB,gCAAc,CAAC,gCAAgC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4hBlD,CAAA;AACD,CAAC,CAAA;AAjjBY,QAAA,2BAA2B,+BAijBvC"}
@@ -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,MA8gCF,CAAA"}
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,MA2iCF,CAAA"}
@@ -13,12 +13,12 @@ exports.generateInvoiceHtmlCode = void 0;
13
13
  //
14
14
  // The UIDL tree has several features that need runtime handling:
15
15
  //
16
- // 1. `<context>` elements carry default invoice data on their attributes
17
- // (Company, Invoice, Customer, Products, Payment). Children reference
18
- // that data through expressions like `invoiceData?.Company?.name`. We
19
- // build a per-render scope from the attrs merged with real DB data
20
- // (real wins unless empty) so every expression resolves against the
21
- // buyer's actual order.
16
+ // 1. `<context>` elements carry the design canvas's sample invoice on
17
+ // their attributes (Company, Invoice, Customer, Products, Payment).
18
+ // Children reference that data through expressions like
19
+ // `invoiceData?.Company?.name`. Every render builds the scope from the
20
+ // real invoice alone, so every expression resolves against the buyer's
21
+ // actual order and an empty field prints nothing — never the sample.
22
22
  //
23
23
  // 2. `cms-list-repeater` iterates `invoiceData.Products` with a
24
24
  // per-iteration variable (the `renderPropIdentifier`). Each line item
@@ -136,11 +136,12 @@ var COMPONENT_DEFINITIONS = ${componentDefinitionsJson};
136
136
  var MAX_COMPONENT_DEPTH = 12;
137
137
 
138
138
  // ---------------------------------------------------------------------------
139
- // Scope construction — merges real DB data with defaults the user set on
140
- // the <context> element in the editor. Per-field fallback: if the real
141
- // field is empty/null, the UIDL default wins. Covers the common dev case
142
- // where COMPANY_DETAILS from invoiceSettings isn't filled in but the user
143
- // dropped "Acme Corporation" into the template preview.
139
+ // Scope construction — the real invoice, the store's company details and the
140
+ // buyer, never the sample on the template's <context>: an empty notes field,
141
+ // VAT number or paid date printed the design canvas's "Payment is due within
142
+ // 30 days", "US123456789" or "Jan 20, 2025" on a real invoice. The one value
143
+ // read from the context is the company logo URL, which the editor writes there
144
+ // from the store's own logo (the sample's is empty).
144
145
  // ---------------------------------------------------------------------------
145
146
 
146
147
  function extractStaticAttrsFromContext(uidl) {
@@ -177,23 +178,9 @@ function findFirstContextNode(node) {
177
178
  return null;
178
179
  }
179
180
 
180
- function nonEmpty(v) {
181
- if (v == null) return false;
182
- if (typeof v === 'string') return v.length > 0;
183
- if (typeof v === 'number') return !isNaN(v);
184
- return true;
185
- }
186
-
187
- function mergeWithDefaults(primary, defaults) {
188
- var out = Object.assign({}, defaults || {});
189
- if (primary) {
190
- Object.keys(primary).forEach(function (k) {
191
- if (nonEmpty(primary[k])) out[k] = primary[k];
192
- });
193
- }
194
- return out;
195
- }
196
-
181
+ // Money on the invoice, in the PDF and the email alike. A symbol that ends in
182
+ // a letter is a word ("lei", "CHF", "kr") and stands apart from the number
183
+ // ("lei 119.00"); a sign sits against it ("$119.00", "\u20AC119.00").
197
184
  function formatCurrencyValue(amount, sym, decimals) {
198
185
  var num = Number(amount);
199
186
  if (!isFinite(num)) num = 0;
@@ -201,7 +188,17 @@ function formatCurrencyValue(amount, sym, decimals) {
201
188
  var fixed = num.toFixed(dec);
202
189
  var parts = fixed.split('.');
203
190
  parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');
204
- return (sym || '') + parts.join('.');
191
+ var symbol = String(sym == null ? '' : sym).trim();
192
+ var separator = /\\p{L}$/u.test(symbol) ? ' ' : '';
193
+ return symbol + separator + parts.join('.');
194
+ }
195
+
196
+ // Invoice statuses of money that was collected: a refund later moves a paid
197
+ // invoice to one of the last two, and it was paid all the same.
198
+ var SETTLED_INVOICE_STATUSES = ['paid', 'partially_refunded', 'refunded'];
199
+
200
+ function isSettledInvoice(status) {
201
+ return SETTLED_INVOICE_STATUSES.indexOf(String(status || '').toLowerCase()) !== -1;
205
202
  }
206
203
 
207
204
  // Per-line VAT formulas. These MIRROR the GUI helpers in
@@ -252,7 +249,7 @@ function formatDateValue(raw) {
252
249
  }
253
250
 
254
251
  function buildInvoiceDataScope(invoiceData) {
255
- var defaults = extractStaticAttrsFromContext(TEMPLATE_COMPONENT_UIDL);
252
+ var contextCompany = extractStaticAttrsFromContext(TEMPLATE_COMPONENT_UIDL).Company || {};
256
253
  var sym = invoiceData.currencySymbol || '$';
257
254
 
258
255
  var realCompany = {
@@ -266,7 +263,7 @@ function buildInvoiceDataScope(invoiceData) {
266
263
  registrationNumber: COMPANY_DETAILS.companyRegNumber,
267
264
  email: COMPANY_DETAILS.companyEmail,
268
265
  phone: COMPANY_DETAILS.companyPhone,
269
- logoUrl: invoiceData.companyLogoUrl || '',
266
+ logoUrl: invoiceData.companyLogoUrl || contextCompany.logoUrl || '',
270
267
  website: COMPANY_DETAILS.companyWebsite,
271
268
  };
272
269
 
@@ -302,12 +299,20 @@ function buildInvoiceDataScope(invoiceData) {
302
299
  amountDueNumber = Math.max(0, totalNumber - giftCardAmountNumber);
303
300
  }
304
301
 
302
+ // A paid invoice asks for nothing: where the due date would print, it says
303
+ // when it was paid. The order keeps no payment method finer than its
304
+ // provider, so the line names none.
305
+ var paid = isSettledInvoice(invoiceData.status);
306
+ var paidDate = formatDateValue(invoiceData.paidAt || (paid ? invoiceData.issueDate : ''));
307
+ var paidLine = paid ? 'Paid' + (paidDate ? ' on ' + paidDate : '') : '';
308
+
305
309
  var realInvoice = {
306
310
  invoiceNumber: invoiceData.invoiceNumber ? '#' + invoiceData.invoiceNumber : '',
307
311
  status: invoiceData.status || '',
308
312
  issueDate: formatDateValue(invoiceData.issueDate),
309
- dueDate: formatDateValue(invoiceData.dueDate),
310
- paidDate: formatDateValue(invoiceData.paidAt),
313
+ dueDate: paidLine || formatDateValue(invoiceData.dueDate),
314
+ paidDate: paidDate,
315
+ paidLine: paidLine,
311
316
  subtotal: formatCurrencyValue(invoiceData.subtotal, sym),
312
317
  taxRate: invoiceData.taxRate != null ? String(invoiceData.taxRate) : '',
313
318
  taxAmount: formatCurrencyValue(invoiceData.taxAmount, sym),
@@ -334,13 +339,6 @@ function buildInvoiceDataScope(invoiceData) {
334
339
  notes: invoiceData.notes || '',
335
340
  pdfUrl: invoiceData.pdfUrl || '',
336
341
  };
337
- // The merge below lets an EMPTY real value fall back to the template's
338
- // sample — right for a company address, wrong for a code or a card tail: an
339
- // order without a voucher must not print the designer's "SAVE20".
340
- var realInvoiceNeverSampled = { voucherCode: voucherCode, giftCardLast4: giftCardLast4 };
341
- // The buyer and their payment are never sampled either: an order with no
342
- // city (a booking, a pickup, a download) must not print the designer's
343
- // sample customer's, nor a card it was not paid with.
344
342
 
345
343
  var realCustomer = {
346
344
  name: invoiceData.customerName || '',
@@ -453,11 +451,11 @@ function buildInvoiceDataScope(invoiceData) {
453
451
 
454
452
  return {
455
453
  invoiceData: {
456
- Company: mergeWithDefaults(realCompany, defaults.Company),
457
- Invoice: Object.assign(mergeWithDefaults(realInvoice, defaults.Invoice), realInvoiceNeverSampled),
454
+ Company: realCompany,
455
+ Invoice: realInvoice,
458
456
  Customer: realCustomer,
459
457
  Payment: realPayment,
460
- Products: realProducts.length > 0 ? realProducts : (defaults.Products || []),
458
+ Products: realProducts,
461
459
  },
462
460
  };
463
461
  }
@@ -958,7 +956,12 @@ function buildFallbackInvoiceHtml(scope) {
958
956
  var parts = [];
959
957
  parts.push('<div style="padding:32px;font-family:Helvetica,Arial,sans-serif;color:#333;font-size:10pt;">');
960
958
  parts.push('<h1 style="text-align:right;font-size:24pt;margin:0 0 4px;">INVOICE</h1>');
961
- parts.push('<p style="text-align:right;color:#666;margin:0 0 24px;">' + escapeHtml(inv.invoiceNumber || '') + '</p>');
959
+ if (inv.paidLine) {
960
+ parts.push('<p style="text-align:right;color:#666;margin:0 0 4px;">' + escapeHtml(inv.invoiceNumber || '') + '</p>');
961
+ parts.push('<p style="text-align:right;color:#666;margin:0 0 24px;">' + escapeHtml(inv.paidLine) + '</p>');
962
+ } else {
963
+ parts.push('<p style="text-align:right;color:#666;margin:0 0 24px;">' + escapeHtml(inv.invoiceNumber || '') + '</p>');
964
+ }
962
965
  parts.push('<div style="display:flex;gap:40px;margin-bottom:24px;">');
963
966
  parts.push('<div style="flex:1;"><strong>' + escapeHtml(comp.name || '') + '</strong><br/>' +
964
967
  escapeHtml(comp.address || '') + '<br/>' +
@@ -1057,25 +1060,47 @@ function resolveTextSpans(spans, scope) {
1057
1060
  }).join('');
1058
1061
  }
1059
1062
 
1060
- // Amount tokens whose line means nothing at zero: "Delivery $0.00" on a
1061
- // pickup order, "Discount −$0.00" without a voucher. The table row (or list
1062
- // item / paragraph) that carries such a token is dropped before the tokens are
1063
- // filled, so the merchant's summary only lists the figures that applied.
1064
- // Matched innermost — a row inside a row keeps its parent.
1065
- var OPTIONAL_AMOUNT_TOKENS = ['shippingAmount', 'discountAmount', 'giftCardAmount'];
1066
-
1067
- function stripZeroAmountLines(template, inv) {
1068
- var out = template;
1069
- for (var i = 0; i < OPTIONAL_AMOUNT_TOKENS.length; i++) {
1070
- var key = OPTIONAL_AMOUNT_TOKENS[i];
1071
- if (Number(inv[key] || 0) > 0) continue;
1072
- var line = new RegExp(
1073
- '<(tr|li|p)\\\\b(?:(?!<\\\\/?\\\\1\\\\b)[\\\\s\\\\S])*?\\\\{\\\\{' + key + '\\\\}\\\\}(?:(?!<\\\\/?\\\\1\\\\b)[\\\\s\\\\S])*?<\\\\/\\\\1\\\\s*>',
1074
- 'g'
1075
- );
1076
- out = out.replace(line, '');
1077
- }
1078
- return out;
1063
+ // The summary lines the email leaves out. An amount whose line means nothing at
1064
+ // zero: "Delivery $0.00" on a pickup order, "Discount −$0.00" without a
1065
+ // voucher, "Tax $0.00" in an untaxed store. And what a paid invoice no longer
1066
+ // asks for: its due date and the amount due. As on the PDF, the amount due is
1067
+ // printed only beside a gift card; without one it is the total again.
1068
+ var OPTIONAL_AMOUNT_TOKENS = ['shippingAmount', 'discountAmount', 'taxAmount', 'giftCardAmount'];
1069
+
1070
+ function omittedLineTokens(inv) {
1071
+ var tokens = OPTIONAL_AMOUNT_TOKENS.filter(function (key) {
1072
+ return !(Number(inv[key] || 0) > 0);
1073
+ });
1074
+ var paid = isSettledInvoice(inv.status);
1075
+ if (paid) tokens.push('dueDate');
1076
+ if (paid || !(Number(inv.giftCardAmount || 0) > 0)) tokens.push('amountDue');
1077
+ return tokens;
1078
+ }
1079
+
1080
+ // A line is the table row, list item or paragraph carrying the token, matched
1081
+ // innermost — a row inside a row keeps its parent. The editor's designs publish
1082
+ // each line as a <div> of <span>s instead, so a token outside those drops the
1083
+ // innermost <div> holding it, and only when that <div> is the line alone: one
1084
+ // that also holds a block or another token is the merchant's own, and stays.
1085
+ var NO_BLOCK_OR_TOKEN = '(?!<\\\\/?(?:div|p|tr|li|table|ul|ol|h[1-6])\\\\b|\\\\{\\\\{)';
1086
+
1087
+ function stripLinesHolding(template, key) {
1088
+ var token = '\\\\{\\\\{' + key + '\\\\}\\\\}';
1089
+ var row = new RegExp(
1090
+ '<(tr|li|p)\\\\b(?:(?!<\\\\/?\\\\1\\\\b)[\\\\s\\\\S])*?' + token + '(?:(?!<\\\\/?\\\\1\\\\b)[\\\\s\\\\S])*?<\\\\/\\\\1\\\\s*>',
1091
+ 'g'
1092
+ );
1093
+ var lineDiv = new RegExp(
1094
+ '<div\\\\b(?:' + NO_BLOCK_OR_TOKEN + '[\\\\s\\\\S])*?' + token + '(?:' + NO_BLOCK_OR_TOKEN + '[\\\\s\\\\S])*?<\\\\/div\\\\s*>',
1095
+ 'g'
1096
+ );
1097
+ return template.replace(row, '').replace(lineDiv, '');
1098
+ }
1099
+
1100
+ function stripOmittedLines(template, inv) {
1101
+ return omittedLineTokens(inv).reduce(function (out, key) {
1102
+ return stripLinesHolding(out, key);
1103
+ }, template);
1079
1104
  }
1080
1105
 
1081
1106
  function replacePlaceholders(template, data) {
@@ -1083,7 +1108,8 @@ function replacePlaceholders(template, data) {
1083
1108
  var inv = data.invoice || {};
1084
1109
  var cust = data.customer || {};
1085
1110
  var comp = data.company || {};
1086
- return stripZeroAmountLines(template, inv).replace(/\\{\\{(\\w+)\\}\\}/g, function (match, key) {
1111
+ var sym = inv.currencySymbol;
1112
+ return stripOmittedLines(template, inv).replace(/\\{\\{(\\w+)\\}\\}/g, function (match, key) {
1087
1113
  var map = {
1088
1114
  invoiceNumber: inv.number || '',
1089
1115
  customerName: cust.name || '',
@@ -1094,14 +1120,14 @@ function replacePlaceholders(template, data) {
1094
1120
  // so the mail and its attachment agree.
1095
1121
  invoiceDate: formatDateValue(inv.issueDate),
1096
1122
  dueDate: formatDateValue(inv.dueDate),
1097
- totalAmount: (inv.currencySymbol || '') + Number(inv.total || 0).toFixed(2),
1098
- subtotal: (inv.currencySymbol || '') + Number(inv.subtotal || 0).toFixed(2),
1099
- taxAmount: (inv.currencySymbol || '') + Number(inv.taxAmount || 0).toFixed(2),
1100
- shippingAmount: (inv.currencySymbol || '') + Number(inv.shippingAmount || 0).toFixed(2),
1101
- discountAmount: (inv.currencySymbol || '') + Number(inv.discountAmount || 0).toFixed(2),
1102
- giftCardAmount: (inv.currencySymbol || '') + Number(inv.giftCardAmount || 0).toFixed(2),
1123
+ totalAmount: formatCurrencyValue(inv.total, sym),
1124
+ subtotal: formatCurrencyValue(inv.subtotal, sym),
1125
+ taxAmount: formatCurrencyValue(inv.taxAmount, sym),
1126
+ shippingAmount: formatCurrencyValue(inv.shippingAmount, sym),
1127
+ discountAmount: formatCurrencyValue(inv.discountAmount, sym),
1128
+ giftCardAmount: formatCurrencyValue(inv.giftCardAmount, sym),
1103
1129
  // What is left after a gift card; the whole total when none was used.
1104
- amountDue: (inv.currencySymbol || '') + Number(inv.amountDue != null ? inv.amountDue : (inv.total || 0)).toFixed(2),
1130
+ amountDue: formatCurrencyValue(inv.amountDue != null ? inv.amountDue : inv.total, sym),
1105
1131
  companyName: comp.name || '',
1106
1132
  companyEmail: comp.email || '',
1107
1133
  invoiceUrl: inv.pdfUrl || '',
@@ -1119,6 +1145,9 @@ function buildDataContext(invoiceData) {
1119
1145
  return {
1120
1146
  invoice: {
1121
1147
  number: invoiceData.invoiceNumber || '',
1148
+ // Paid or not decides which lines the email keeps (see omittedLineTokens).
1149
+ status: invoiceData.status || '',
1150
+ paidAt: invoiceData.paidAt || null,
1122
1151
  issueDate: invoiceData.issueDate || '',
1123
1152
  dueDate: invoiceData.dueDate || '',
1124
1153
  subtotal: invoiceData.subtotal || 0,
@@ -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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"}