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