@cogenta/commerce 0.2.0 → 0.4.3
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/dist/admin/permissions.d.ts +8 -0
- package/dist/admin/permissions.d.ts.map +1 -1
- package/dist/admin/permissions.js +1 -0
- package/dist/admin/permissions.js.map +1 -1
- package/dist/admin/router.d.ts +47 -5
- package/dist/admin/router.d.ts.map +1 -1
- package/dist/admin/router.js +942 -24
- package/dist/admin/router.js.map +1 -1
- package/dist/cart/store.d.ts +23 -0
- package/dist/cart/store.d.ts.map +1 -1
- package/dist/cart/store.js +49 -2
- package/dist/cart/store.js.map +1 -1
- package/dist/catalog/csv.d.ts +29 -0
- package/dist/catalog/csv.d.ts.map +1 -0
- package/dist/catalog/csv.js +396 -0
- package/dist/catalog/csv.js.map +1 -0
- package/dist/catalog/store.d.ts +24 -4
- package/dist/catalog/store.d.ts.map +1 -1
- package/dist/catalog/store.js +238 -11
- package/dist/catalog/store.js.map +1 -1
- package/dist/catalog/types.d.ts +92 -0
- package/dist/catalog/types.d.ts.map +1 -1
- package/dist/catalog/types.js +20 -0
- package/dist/catalog/types.js.map +1 -1
- package/dist/coupon/store.d.ts +63 -5
- package/dist/coupon/store.d.ts.map +1 -1
- package/dist/coupon/store.js +140 -7
- package/dist/coupon/store.js.map +1 -1
- package/dist/customer/store.d.ts +17 -0
- package/dist/customer/store.d.ts.map +1 -1
- package/dist/customer/store.js +26 -0
- package/dist/customer/store.js.map +1 -1
- package/dist/index.d.ts +18 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/dist/invoice/credit-note.d.ts +45 -0
- package/dist/invoice/credit-note.d.ts.map +1 -0
- package/dist/invoice/credit-note.js +109 -0
- package/dist/invoice/credit-note.js.map +1 -0
- package/dist/invoice/sequence.d.ts +21 -0
- package/dist/invoice/sequence.d.ts.map +1 -0
- package/dist/invoice/sequence.js +64 -0
- package/dist/invoice/sequence.js.map +1 -0
- package/dist/invoice/store.d.ts +23 -1
- package/dist/invoice/store.d.ts.map +1 -1
- package/dist/invoice/store.js +23 -56
- package/dist/invoice/store.js.map +1 -1
- package/dist/order/csv.d.ts +24 -0
- package/dist/order/csv.d.ts.map +1 -0
- package/dist/order/csv.js +42 -0
- package/dist/order/csv.js.map +1 -0
- package/dist/order/notify.d.ts +65 -0
- package/dist/order/notify.d.ts.map +1 -0
- package/dist/order/notify.js +180 -0
- package/dist/order/notify.js.map +1 -0
- package/dist/order/store.d.ts +58 -1
- package/dist/order/store.d.ts.map +1 -1
- package/dist/order/store.js +145 -10
- package/dist/order/store.js.map +1 -1
- package/dist/order/types.d.ts +35 -1
- package/dist/order/types.d.ts.map +1 -1
- package/dist/order/types.js +2 -0
- package/dist/order/types.js.map +1 -1
- package/dist/payment/paypal.d.ts +9 -0
- package/dist/payment/paypal.d.ts.map +1 -0
- package/dist/payment/paypal.js +583 -0
- package/dist/payment/paypal.js.map +1 -0
- package/dist/payment/registry.d.ts +15 -6
- package/dist/payment/registry.d.ts.map +1 -1
- package/dist/payment/registry.js +17 -6
- package/dist/payment/registry.js.map +1 -1
- package/dist/payment/types.d.ts +6 -0
- package/dist/payment/types.d.ts.map +1 -1
- package/dist/shipping/store.d.ts +29 -3
- package/dist/shipping/store.d.ts.map +1 -1
- package/dist/shipping/store.js +68 -4
- package/dist/shipping/store.js.map +1 -1
- package/dist/subscription/renewal-notifier.d.ts +17 -0
- package/dist/subscription/renewal-notifier.d.ts.map +1 -0
- package/dist/subscription/renewal-notifier.js +33 -0
- package/dist/subscription/renewal-notifier.js.map +1 -0
- package/dist/subscription/store.d.ts +126 -3
- package/dist/subscription/store.d.ts.map +1 -1
- package/dist/subscription/store.js +348 -8
- package/dist/subscription/store.js.map +1 -1
- package/dist/tables.d.ts +17 -0
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +273 -0
- package/dist/tables.js.map +1 -1
- package/dist/tax/store.d.ts +20 -0
- package/dist/tax/store.d.ts.map +1 -1
- package/dist/tax/store.js +51 -7
- package/dist/tax/store.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import { isCogentaError } from '@cogenta/core';
|
|
2
|
+
import { minorUnitExponent, normaliseCurrency } from '../money.js';
|
|
3
|
+
/**
|
|
4
|
+
* CSV import/export for the catalogue (fiche 51 task 6), following the exact
|
|
5
|
+
* shape `@cogenta/api`'s redirect router already established for its own CSV
|
|
6
|
+
* feature: a hand-written, zero-dependency reader/writer (R9 — the whole
|
|
7
|
+
* feature is quoted fields, embedded commas/newlines and doubled-quote
|
|
8
|
+
* escaping), a header row matched **by name**, case-insensitively and in any
|
|
9
|
+
* order (the "correspondance de colonnes" the fiche asks for — a real export
|
|
10
|
+
* from another shop or from a spreadsheet a person reordered still imports),
|
|
11
|
+
* and a strict two-call preview/apply split: nothing is written until a
|
|
12
|
+
* caller that has already seen `outcome` for every row asks a second time
|
|
13
|
+
* with `apply: true`.
|
|
14
|
+
*
|
|
15
|
+
* One row is one variant. A product is looked up (or created) by `handle`;
|
|
16
|
+
* several rows sharing a handle add several variants to the same product —
|
|
17
|
+
* only the first row that creates the product uses its `title`/`status`
|
|
18
|
+
* columns, later rows for the same still-new handle reuse what the first
|
|
19
|
+
* row already decided.
|
|
20
|
+
*/
|
|
21
|
+
const HEADER = [
|
|
22
|
+
'handle',
|
|
23
|
+
'title',
|
|
24
|
+
'status',
|
|
25
|
+
'sku',
|
|
26
|
+
'variant',
|
|
27
|
+
'price',
|
|
28
|
+
'currency',
|
|
29
|
+
'onhand',
|
|
30
|
+
'allowbackorder',
|
|
31
|
+
'weightgrams',
|
|
32
|
+
'taxcategory',
|
|
33
|
+
'lowstockthreshold',
|
|
34
|
+
'compareprice',
|
|
35
|
+
'salestartsat',
|
|
36
|
+
'saleendsat',
|
|
37
|
+
'widthmm',
|
|
38
|
+
'heightmm',
|
|
39
|
+
'depthmm',
|
|
40
|
+
];
|
|
41
|
+
/** Parses CSV text into rows of fields — copied from `@cogenta/api`'s `csv.ts`
|
|
42
|
+
* rather than depended on: the two packages are siblings (`@cogenta/commerce`
|
|
43
|
+
* has no dependency on `@cogenta/api` today, and a CSV reader is not a reason
|
|
44
|
+
* to start one), and RFC 4180 does not change. */
|
|
45
|
+
function parseCsv(text) {
|
|
46
|
+
const rows = [];
|
|
47
|
+
let row = [];
|
|
48
|
+
let field = '';
|
|
49
|
+
let inQuotes = false;
|
|
50
|
+
let i = 0;
|
|
51
|
+
const length = text.length;
|
|
52
|
+
while (i < length) {
|
|
53
|
+
const ch = text[i];
|
|
54
|
+
if (inQuotes) {
|
|
55
|
+
if (ch === '"') {
|
|
56
|
+
if (text[i + 1] === '"') {
|
|
57
|
+
field += '"';
|
|
58
|
+
i += 2;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
inQuotes = false;
|
|
62
|
+
i += 1;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
field += ch;
|
|
66
|
+
i += 1;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (ch === '"') {
|
|
70
|
+
inQuotes = true;
|
|
71
|
+
i += 1;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (ch === ',') {
|
|
75
|
+
row.push(field);
|
|
76
|
+
field = '';
|
|
77
|
+
i += 1;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (ch === '\r') {
|
|
81
|
+
i += 1;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (ch === '\n') {
|
|
85
|
+
row.push(field);
|
|
86
|
+
rows.push(row);
|
|
87
|
+
row = [];
|
|
88
|
+
field = '';
|
|
89
|
+
i += 1;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
field += ch;
|
|
93
|
+
i += 1;
|
|
94
|
+
}
|
|
95
|
+
if (field.length > 0 || row.length > 0) {
|
|
96
|
+
row.push(field);
|
|
97
|
+
rows.push(row);
|
|
98
|
+
}
|
|
99
|
+
return rows;
|
|
100
|
+
}
|
|
101
|
+
function escapeField(value) {
|
|
102
|
+
return /[",\r\n]/u.test(value) ? `"${value.replace(/"/gu, '""')}"` : value;
|
|
103
|
+
}
|
|
104
|
+
function stringifyCsv(rows) {
|
|
105
|
+
return (rows.map((row) => row.map(escapeField).join(',')).join('\r\n') + (rows.length > 0 ? '\r\n' : ''));
|
|
106
|
+
}
|
|
107
|
+
function formatMajor(amountMinor, currency) {
|
|
108
|
+
const exponent = minorUnitExponent(currency);
|
|
109
|
+
return (amountMinor / 10 ** exponent).toFixed(exponent);
|
|
110
|
+
}
|
|
111
|
+
/** Rounds to the nearest minor unit rather than truncating. `null` for anything not a plain, non-negative number. */
|
|
112
|
+
function parseMajor(text, currency) {
|
|
113
|
+
const trimmed = text.trim();
|
|
114
|
+
if (trimmed === '' || Number.isNaN(Number(trimmed)))
|
|
115
|
+
return null;
|
|
116
|
+
const major = Number(trimmed);
|
|
117
|
+
if (!Number.isFinite(major) || major < 0)
|
|
118
|
+
return null;
|
|
119
|
+
return Math.round(major * 10 ** minorUnitExponent(currency));
|
|
120
|
+
}
|
|
121
|
+
function parseNullableInt(text) {
|
|
122
|
+
const trimmed = text.trim();
|
|
123
|
+
if (trimmed === '')
|
|
124
|
+
return null;
|
|
125
|
+
const value = Number(trimmed);
|
|
126
|
+
return Number.isInteger(value) && value >= 0 ? value : undefined;
|
|
127
|
+
}
|
|
128
|
+
function parseNullableDate(text) {
|
|
129
|
+
const trimmed = text.trim();
|
|
130
|
+
if (trimmed === '')
|
|
131
|
+
return null;
|
|
132
|
+
return Number.isNaN(new Date(trimmed).getTime()) ? undefined : trimmed;
|
|
133
|
+
}
|
|
134
|
+
export function exportProductsCsv(products, variantsByProduct) {
|
|
135
|
+
const rows = [[...HEADER]];
|
|
136
|
+
for (const product of products) {
|
|
137
|
+
const variants = variantsByProduct.get(product.id) ?? [];
|
|
138
|
+
for (const variant of variants) {
|
|
139
|
+
rows.push([
|
|
140
|
+
product.handle,
|
|
141
|
+
product.title,
|
|
142
|
+
product.status,
|
|
143
|
+
variant.sku,
|
|
144
|
+
variant.title,
|
|
145
|
+
formatMajor(variant.priceMinor, variant.currency),
|
|
146
|
+
variant.currency,
|
|
147
|
+
String(variant.onHand),
|
|
148
|
+
String(variant.allowBackorder),
|
|
149
|
+
String(variant.weightGrams),
|
|
150
|
+
variant.taxCategory,
|
|
151
|
+
variant.lowStockThreshold === null ? '' : String(variant.lowStockThreshold),
|
|
152
|
+
variant.compareAtPriceMinor === null
|
|
153
|
+
? ''
|
|
154
|
+
: formatMajor(variant.compareAtPriceMinor, variant.currency),
|
|
155
|
+
variant.saleStartsAt ?? '',
|
|
156
|
+
variant.saleEndsAt ?? '',
|
|
157
|
+
variant.widthMm === null ? '' : String(variant.widthMm),
|
|
158
|
+
variant.heightMm === null ? '' : String(variant.heightMm),
|
|
159
|
+
variant.depthMm === null ? '' : String(variant.depthMm),
|
|
160
|
+
]);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return stringifyCsv(rows);
|
|
164
|
+
}
|
|
165
|
+
function parseImportCsv(csv, maxRows) {
|
|
166
|
+
const table = parseCsv(csv);
|
|
167
|
+
if (table.length === 0) {
|
|
168
|
+
return { rows: [], issues: [{ line: 0, detail: 'The file is empty.' }] };
|
|
169
|
+
}
|
|
170
|
+
const header = (table[0] ?? []).map((cell) => cell.trim().toLowerCase());
|
|
171
|
+
const index = (name) => header.indexOf(name);
|
|
172
|
+
const required = ['handle', 'title', 'sku', 'variant', 'price', 'currency'];
|
|
173
|
+
const missing = required.filter((name) => index(name) === -1);
|
|
174
|
+
if (missing.length > 0) {
|
|
175
|
+
return {
|
|
176
|
+
rows: [],
|
|
177
|
+
issues: [{ line: 1, detail: `The header row is missing: ${missing.join(', ')}.` }],
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
const cell = (cells, name) => (cells[index(name)] ?? '').trim();
|
|
181
|
+
const rows = [];
|
|
182
|
+
const issues = [];
|
|
183
|
+
const dataRows = table.slice(1, 1 + maxRows);
|
|
184
|
+
for (const [offset, cells] of dataRows.entries()) {
|
|
185
|
+
const line = offset + 2;
|
|
186
|
+
if (cells.length === 1 && (cells[0] ?? '').trim() === '')
|
|
187
|
+
continue;
|
|
188
|
+
const handle = cell(cells, 'handle').toLowerCase();
|
|
189
|
+
const title = cell(cells, 'title');
|
|
190
|
+
const sku = cell(cells, 'sku');
|
|
191
|
+
const variantTitle = cell(cells, 'variant');
|
|
192
|
+
const rawStatus = index('status') === -1 ? '' : cell(cells, 'status');
|
|
193
|
+
const currency = normaliseCurrency(cell(cells, 'currency') || 'EUR');
|
|
194
|
+
if (handle === '' || title === '' || sku === '' || variantTitle === '') {
|
|
195
|
+
issues.push({ line, detail: 'Missing "handle", "title", "sku" or "variant".' });
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (rawStatus !== '' && rawStatus !== 'active' && rawStatus !== 'archived') {
|
|
199
|
+
issues.push({ line, detail: `"${rawStatus}" is not "active" or "archived".` });
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
const priceMinor = parseMajor(cell(cells, 'price'), currency);
|
|
203
|
+
if (priceMinor === null) {
|
|
204
|
+
issues.push({ line, detail: `"${cell(cells, 'price')}" is not a usable price.` });
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const onHandRaw = cell(cells, 'onhand');
|
|
208
|
+
const onHand = onHandRaw === '' ? 0 : Number(onHandRaw);
|
|
209
|
+
if (!Number.isInteger(onHand) || onHand < 0) {
|
|
210
|
+
issues.push({ line, detail: `"${onHandRaw}" is not a usable stock count.` });
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
const lowStockThreshold = parseNullableInt(cell(cells, 'lowstockthreshold'));
|
|
214
|
+
const widthMm = parseNullableInt(cell(cells, 'widthmm'));
|
|
215
|
+
const heightMm = parseNullableInt(cell(cells, 'heightmm'));
|
|
216
|
+
const depthMm = parseNullableInt(cell(cells, 'depthmm'));
|
|
217
|
+
if (lowStockThreshold === undefined ||
|
|
218
|
+
widthMm === undefined ||
|
|
219
|
+
heightMm === undefined ||
|
|
220
|
+
depthMm === undefined) {
|
|
221
|
+
issues.push({ line, detail: 'A threshold or dimension column is not a whole number.' });
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const comparePriceText = cell(cells, 'compareprice');
|
|
225
|
+
const compareAtPriceMinor = comparePriceText === '' ? null : parseMajor(comparePriceText, currency);
|
|
226
|
+
if (comparePriceText !== '' && compareAtPriceMinor === null) {
|
|
227
|
+
issues.push({ line, detail: `"${comparePriceText}" is not a usable compare-at price.` });
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
const saleStartsAt = parseNullableDate(cell(cells, 'salestartsat'));
|
|
231
|
+
const saleEndsAt = parseNullableDate(cell(cells, 'saleendsat'));
|
|
232
|
+
if (saleStartsAt === undefined || saleEndsAt === undefined) {
|
|
233
|
+
issues.push({ line, detail: 'A sale date column is not a usable date.' });
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
rows.push({
|
|
237
|
+
line,
|
|
238
|
+
handle,
|
|
239
|
+
title,
|
|
240
|
+
status: rawStatus === 'archived' ? 'archived' : 'active',
|
|
241
|
+
sku,
|
|
242
|
+
variantTitle,
|
|
243
|
+
priceMinor,
|
|
244
|
+
currency,
|
|
245
|
+
onHand,
|
|
246
|
+
allowBackorder: cell(cells, 'allowbackorder').toLowerCase() === 'true',
|
|
247
|
+
weightGrams: Number(cell(cells, 'weightgrams')) || 0,
|
|
248
|
+
taxCategory: cell(cells, 'taxcategory') || 'standard',
|
|
249
|
+
lowStockThreshold,
|
|
250
|
+
compareAtPriceMinor,
|
|
251
|
+
saleStartsAt,
|
|
252
|
+
saleEndsAt,
|
|
253
|
+
widthMm,
|
|
254
|
+
heightMm,
|
|
255
|
+
depthMm,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
if (table.length - 1 > maxRows) {
|
|
259
|
+
issues.push({
|
|
260
|
+
line: maxRows + 2,
|
|
261
|
+
detail: `Only the first ${maxRows} data rows were read; the rest of the file was not.`,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
return { rows, issues };
|
|
265
|
+
}
|
|
266
|
+
export async function previewProductsImport(csv, catalog, maxRows = 5000) {
|
|
267
|
+
const { rows, issues } = parseImportCsv(csv, maxRows);
|
|
268
|
+
const lastLineIndexBySku = new Map();
|
|
269
|
+
for (const [index, row] of rows.entries())
|
|
270
|
+
lastLineIndexBySku.set(row.sku, index);
|
|
271
|
+
const variantCache = new Map();
|
|
272
|
+
const outcomes = [];
|
|
273
|
+
for (const [index, row] of rows.entries()) {
|
|
274
|
+
if (lastLineIndexBySku.get(row.sku) !== index) {
|
|
275
|
+
outcomes.push({
|
|
276
|
+
line: row.line,
|
|
277
|
+
handle: row.handle,
|
|
278
|
+
sku: row.sku,
|
|
279
|
+
outcome: 'duplicate',
|
|
280
|
+
detail: 'A later row in this file uses the same SKU; only that one will be applied.',
|
|
281
|
+
});
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
if (!variantCache.has(row.sku)) {
|
|
285
|
+
variantCache.set(row.sku, await catalog.readVariantBySku(row.sku));
|
|
286
|
+
}
|
|
287
|
+
const existing = variantCache.get(row.sku) ?? null;
|
|
288
|
+
outcomes.push({
|
|
289
|
+
line: row.line,
|
|
290
|
+
handle: row.handle,
|
|
291
|
+
sku: row.sku,
|
|
292
|
+
outcome: existing === null ? 'create' : 'update',
|
|
293
|
+
...(existing === null
|
|
294
|
+
? {}
|
|
295
|
+
: { detail: `Currently priced at ${existing.priceMinor} ${existing.currency}.` }),
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
const summary = {
|
|
299
|
+
create: 0,
|
|
300
|
+
update: 0,
|
|
301
|
+
duplicate: 0,
|
|
302
|
+
invalid: issues.length,
|
|
303
|
+
};
|
|
304
|
+
for (const outcome of outcomes)
|
|
305
|
+
summary[outcome.outcome] = (summary[outcome.outcome] ?? 0) + 1;
|
|
306
|
+
return { rows: outcomes, issues, summary };
|
|
307
|
+
}
|
|
308
|
+
export async function applyProductsImport(csv, catalog, maxRows = 5000) {
|
|
309
|
+
const { rows, issues } = parseImportCsv(csv, maxRows);
|
|
310
|
+
const lastLineIndexBySku = new Map();
|
|
311
|
+
for (const [index, row] of rows.entries())
|
|
312
|
+
lastLineIndexBySku.set(row.sku, index);
|
|
313
|
+
const applicable = rows.filter((row, index) => lastLineIndexBySku.get(row.sku) === index);
|
|
314
|
+
let created = 0;
|
|
315
|
+
let updated = 0;
|
|
316
|
+
const failed = [...issues];
|
|
317
|
+
const productIdByHandle = new Map();
|
|
318
|
+
// Sequential, not `Promise.all`: each write is its own set of queries
|
|
319
|
+
// against one SQLite writer lock, and racing them would only serialise
|
|
320
|
+
// behind it anyway while making the per-row failure report meaningless.
|
|
321
|
+
for (const row of applicable) {
|
|
322
|
+
try {
|
|
323
|
+
let productId = productIdByHandle.get(row.handle);
|
|
324
|
+
if (productId === undefined) {
|
|
325
|
+
const existingProduct = await catalog.readProductByHandle(row.handle);
|
|
326
|
+
const product = existingProduct ??
|
|
327
|
+
(await catalog.createProduct({
|
|
328
|
+
handle: row.handle,
|
|
329
|
+
title: row.title,
|
|
330
|
+
status: row.status,
|
|
331
|
+
}));
|
|
332
|
+
productId = product.id;
|
|
333
|
+
productIdByHandle.set(row.handle, productId);
|
|
334
|
+
}
|
|
335
|
+
const existingVariant = await catalog.readVariantBySku(row.sku);
|
|
336
|
+
if (existingVariant === null) {
|
|
337
|
+
await catalog.createVariant({
|
|
338
|
+
productId,
|
|
339
|
+
sku: row.sku,
|
|
340
|
+
title: row.variantTitle,
|
|
341
|
+
priceMinor: row.priceMinor,
|
|
342
|
+
currency: row.currency,
|
|
343
|
+
onHand: row.onHand,
|
|
344
|
+
allowBackorder: row.allowBackorder,
|
|
345
|
+
weightGrams: row.weightGrams,
|
|
346
|
+
taxCategory: row.taxCategory,
|
|
347
|
+
lowStockThreshold: row.lowStockThreshold,
|
|
348
|
+
compareAtPriceMinor: row.compareAtPriceMinor,
|
|
349
|
+
saleStartsAt: row.saleStartsAt,
|
|
350
|
+
saleEndsAt: row.saleEndsAt,
|
|
351
|
+
widthMm: row.widthMm,
|
|
352
|
+
heightMm: row.heightMm,
|
|
353
|
+
depthMm: row.depthMm,
|
|
354
|
+
});
|
|
355
|
+
created += 1;
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
await catalog.updateVariant(existingVariant.id, {
|
|
359
|
+
title: row.variantTitle,
|
|
360
|
+
priceMinor: row.priceMinor,
|
|
361
|
+
currency: row.currency,
|
|
362
|
+
allowBackorder: row.allowBackorder,
|
|
363
|
+
weightGrams: row.weightGrams,
|
|
364
|
+
taxCategory: row.taxCategory,
|
|
365
|
+
lowStockThreshold: row.lowStockThreshold,
|
|
366
|
+
compareAtPriceMinor: row.compareAtPriceMinor,
|
|
367
|
+
saleStartsAt: row.saleStartsAt,
|
|
368
|
+
saleEndsAt: row.saleEndsAt,
|
|
369
|
+
widthMm: row.widthMm,
|
|
370
|
+
heightMm: row.heightMm,
|
|
371
|
+
depthMm: row.depthMm,
|
|
372
|
+
});
|
|
373
|
+
// The stock count on an import row is a snapshot, not a delta — a
|
|
374
|
+
// real stock take, going through the same audited path every other
|
|
375
|
+
// absolute stock write does (fiche 51 task 4).
|
|
376
|
+
if (existingVariant.onHand !== row.onHand) {
|
|
377
|
+
await catalog.setStock(existingVariant.id, row.onHand, { note: 'CSV import' });
|
|
378
|
+
}
|
|
379
|
+
updated += 1;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
catch (error) {
|
|
383
|
+
failed.push({
|
|
384
|
+
line: row.line,
|
|
385
|
+
detail: isCogentaError(error) ? error.message : String(error),
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return {
|
|
390
|
+
created,
|
|
391
|
+
updated,
|
|
392
|
+
skipped: rows.length - applicable.length,
|
|
393
|
+
failed,
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
//# sourceMappingURL=csv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv.js","sourceRoot":"","sources":["../../src/catalog/csv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAIlE;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,GAAG;IACb,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,KAAK;IACL,SAAS;IACT,OAAO;IACP,UAAU;IACV,QAAQ;IACR,gBAAgB;IAChB,aAAa;IACb,aAAa;IACb,mBAAmB;IACnB,cAAc;IACd,cAAc;IACd,YAAY;IACZ,SAAS;IACT,UAAU;IACV,SAAS;CACD,CAAA;AAEV;;;kDAGkD;AAClD,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,IAAI,GAAe,EAAE,CAAA;IAC3B,IAAI,GAAG,GAAa,EAAE,CAAA;IACtB,IAAI,KAAK,GAAG,EAAE,CAAA;IACd,IAAI,QAAQ,GAAG,KAAK,CAAA;IACpB,IAAI,CAAC,GAAG,CAAC,CAAA;IACT,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;IAE1B,OAAO,CAAC,GAAG,MAAM,EAAE,CAAC;QAClB,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QAElB,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBACf,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;oBACxB,KAAK,IAAI,GAAG,CAAA;oBACZ,CAAC,IAAI,CAAC,CAAA;oBACN,SAAQ;gBACV,CAAC;gBACD,QAAQ,GAAG,KAAK,CAAA;gBAChB,CAAC,IAAI,CAAC,CAAA;gBACN,SAAQ;YACV,CAAC;YACD,KAAK,IAAI,EAAE,CAAA;YACX,CAAC,IAAI,CAAC,CAAA;YACN,SAAQ;QACV,CAAC;QAED,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACf,QAAQ,GAAG,IAAI,CAAA;YACf,CAAC,IAAI,CAAC,CAAA;YACN,SAAQ;QACV,CAAC;QACD,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACf,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACf,KAAK,GAAG,EAAE,CAAA;YACV,CAAC,IAAI,CAAC,CAAA;YACN,SAAQ;QACV,CAAC;QACD,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YAChB,CAAC,IAAI,CAAC,CAAA;YACN,SAAQ;QACV,CAAC;QACD,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YAChB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACf,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACd,GAAG,GAAG,EAAE,CAAA;YACR,KAAK,GAAG,EAAE,CAAA;YACV,CAAC,IAAI,CAAC,CAAA;YACN,SAAQ;QACV,CAAC;QACD,KAAK,IAAI,EAAE,CAAA;QACX,CAAC,IAAI,CAAC,CAAA;IACR,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACf,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAChB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAA;AAC5E,CAAC;AAED,SAAS,YAAY,CAAC,IAAoC;IACxD,OAAO,CACL,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CACjG,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,WAAmB,EAAE,QAAgB;IACxD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAA;IAC5C,OAAO,CAAC,WAAW,GAAG,EAAE,IAAI,QAAQ,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;AACzD,CAAC;AAED,qHAAqH;AACrH,SAAS,UAAU,CAAC,IAAY,EAAE,QAAgB;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAC3B,IAAI,OAAO,KAAK,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IAChE,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA;IAC7B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IACrD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,IAAI,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAA;AAC9D,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAC3B,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,IAAI,CAAA;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA;IAC7B,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AAClE,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAC3B,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,IAAI,CAAA;IAC/B,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAA;AACxE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,QAA4B,EAC5B,iBAA0D;IAE1D,MAAM,IAAI,GAAe,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAA;IACtC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAA;QACxD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC;gBACR,OAAO,CAAC,MAAM;gBACd,OAAO,CAAC,KAAK;gBACb,OAAO,CAAC,MAAM;gBACd,OAAO,CAAC,GAAG;gBACX,OAAO,CAAC,KAAK;gBACb,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC;gBACjD,OAAO,CAAC,QAAQ;gBAChB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;gBACtB,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC;gBAC9B,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;gBAC3B,OAAO,CAAC,WAAW;gBACnB,OAAO,CAAC,iBAAiB,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC;gBAC3E,OAAO,CAAC,mBAAmB,KAAK,IAAI;oBAClC,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC,QAAQ,CAAC;gBAC9D,OAAO,CAAC,YAAY,IAAI,EAAE;gBAC1B,OAAO,CAAC,UAAU,IAAI,EAAE;gBACxB,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;gBACvD,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACzD,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;aACxD,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IACD,OAAO,YAAY,CAAC,IAAI,CAAC,CAAA;AAC3B,CAAC;AAoDD,SAAS,cAAc,CACrB,GAAW,EACX,OAAe;IAEf,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAA;IAC3B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC,EAAE,CAAA;IAC1E,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAA;IACxE,MAAM,KAAK,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5D,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC,CAAA;IAC3E,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC7D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,IAAI,EAAE,EAAE;YACR,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,8BAA8B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;SACnF,CAAA;IACH,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,KAAwB,EAAE,IAAY,EAAU,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAElG,MAAM,IAAI,GAAgB,EAAE,CAAA;IAC5B,MAAM,MAAM,GAAyB,EAAE,CAAA;IACvC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAA;IAE5C,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QACjD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,CAAA;QACvB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,SAAQ;QAElE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAA;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;QAC3C,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;QACrE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,KAAK,CAAC,CAAA;QAEpE,IAAI,MAAM,KAAK,EAAE,IAAI,KAAK,KAAK,EAAE,IAAI,GAAG,KAAK,EAAE,IAAI,YAAY,KAAK,EAAE,EAAE,CAAC;YACvE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,gDAAgD,EAAE,CAAC,CAAA;YAC/E,SAAQ;QACV,CAAC;QACD,IAAI,SAAS,KAAK,EAAE,IAAI,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;YAC3E,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,SAAS,kCAAkC,EAAE,CAAC,CAAA;YAC9E,SAAQ;QACV,CAAC;QACD,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAA;QAC7D,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,0BAA0B,EAAE,CAAC,CAAA;YACjF,SAAQ;QACV,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;QACvC,MAAM,MAAM,GAAG,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACvD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,SAAS,gCAAgC,EAAE,CAAC,CAAA;YAC5E,SAAQ;QACV,CAAC;QAED,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAA;QAC5E,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAA;QACxD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAA;QAC1D,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAA;QACxD,IACE,iBAAiB,KAAK,SAAS;YAC/B,OAAO,KAAK,SAAS;YACrB,QAAQ,KAAK,SAAS;YACtB,OAAO,KAAK,SAAS,EACrB,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,wDAAwD,EAAE,CAAC,CAAA;YACvF,SAAQ;QACV,CAAC;QACD,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,EAAE,cAAc,CAAC,CAAA;QACpD,MAAM,mBAAmB,GACvB,gBAAgB,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAA;QACzE,IAAI,gBAAgB,KAAK,EAAE,IAAI,mBAAmB,KAAK,IAAI,EAAE,CAAC;YAC5D,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,gBAAgB,qCAAqC,EAAE,CAAC,CAAA;YACxF,SAAQ;QACV,CAAC;QACD,MAAM,YAAY,GAAG,iBAAiB,CAAC,IAAI,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,CAAA;QACnE,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAA;QAC/D,IAAI,YAAY,KAAK,SAAS,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC3D,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,0CAA0C,EAAE,CAAC,CAAA;YACzE,SAAQ;QACV,CAAC;QAED,IAAI,CAAC,IAAI,CAAC;YACR,IAAI;YACJ,MAAM;YACN,KAAK;YACL,MAAM,EAAE,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ;YACxD,GAAG;YACH,YAAY;YACZ,UAAU;YACV,QAAQ;YACR,MAAM;YACN,cAAc,EAAE,IAAI,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM;YACtE,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC;YACpD,WAAW,EAAE,IAAI,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,UAAU;YACrD,iBAAiB;YACjB,mBAAmB;YACnB,YAAY;YACZ,UAAU;YACV,OAAO;YACP,QAAQ;YACR,OAAO;SACR,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,OAAO,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,OAAO,GAAG,CAAC;YACjB,MAAM,EAAE,kBAAkB,OAAO,qDAAqD;SACvF,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,GAAW,EACX,OAAqB,EACrB,OAAO,GAAG,IAAI;IAEd,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAErD,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAkB,CAAA;IACpD,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE;QAAE,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAEjF,MAAM,YAAY,GAAG,IAAI,GAAG,EAA0B,CAAA;IACtD,MAAM,QAAQ,GAA8B,EAAE,CAAA;IAC9C,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1C,IAAI,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC;YAC9C,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,GAAG,EAAE,GAAG,CAAC,GAAG;gBACZ,OAAO,EAAE,WAAW;gBACpB,MAAM,EAAE,4EAA4E;aACrF,CAAC,CAAA;YACF,SAAQ;QACV,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;QACpE,CAAC;QACD,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAA;QAClD,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,OAAO,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;YAChD,GAAG,CAAC,QAAQ,KAAK,IAAI;gBACnB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,MAAM,EAAE,uBAAuB,QAAQ,CAAC,UAAU,IAAI,QAAQ,CAAC,QAAQ,GAAG,EAAE,CAAC;SACpF,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,OAAO,GAA2B;QACtC,MAAM,EAAE,CAAC;QACT,MAAM,EAAE,CAAC;QACT,SAAS,EAAE,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC,MAAM;KACvB,CAAA;IACD,KAAK,MAAM,OAAO,IAAI,QAAQ;QAAE,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;IAE9F,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAW,EACX,OAAqB,EACrB,OAAO,GAAG,IAAI;IAEd,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAErD,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAkB,CAAA;IACpD,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE;QAAE,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACjF,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAA;IAEzF,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,MAAM,MAAM,GAAyB,CAAC,GAAG,MAAM,CAAC,CAAA;IAChD,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAA;IAEnD,sEAAsE;IACtE,uEAAuE;IACvE,wEAAwE;IACxE,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,IAAI,SAAS,GAAG,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YACjD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;gBACrE,MAAM,OAAO,GACX,eAAe;oBACf,CAAC,MAAM,OAAO,CAAC,aAAa,CAAC;wBAC3B,MAAM,EAAE,GAAG,CAAC,MAAM;wBAClB,KAAK,EAAE,GAAG,CAAC,KAAK;wBAChB,MAAM,EAAE,GAAG,CAAC,MAAM;qBACnB,CAAC,CAAC,CAAA;gBACL,SAAS,GAAG,OAAO,CAAC,EAAE,CAAA;gBACtB,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;YAC9C,CAAC;YAED,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC/D,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;gBAC7B,MAAM,OAAO,CAAC,aAAa,CAAC;oBAC1B,SAAS;oBACT,GAAG,EAAE,GAAG,CAAC,GAAG;oBACZ,KAAK,EAAE,GAAG,CAAC,YAAY;oBACvB,UAAU,EAAE,GAAG,CAAC,UAAU;oBAC1B,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,cAAc,EAAE,GAAG,CAAC,cAAc;oBAClC,WAAW,EAAE,GAAG,CAAC,WAAW;oBAC5B,WAAW,EAAE,GAAG,CAAC,WAAW;oBAC5B,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;oBACxC,mBAAmB,EAAE,GAAG,CAAC,mBAAmB;oBAC5C,YAAY,EAAE,GAAG,CAAC,YAAY;oBAC9B,UAAU,EAAE,GAAG,CAAC,UAAU;oBAC1B,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,OAAO,EAAE,GAAG,CAAC,OAAO;iBACrB,CAAC,CAAA;gBACF,OAAO,IAAI,CAAC,CAAA;YACd,CAAC;iBAAM,CAAC;gBACN,MAAM,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,EAAE,EAAE;oBAC9C,KAAK,EAAE,GAAG,CAAC,YAAY;oBACvB,UAAU,EAAE,GAAG,CAAC,UAAU;oBAC1B,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,cAAc,EAAE,GAAG,CAAC,cAAc;oBAClC,WAAW,EAAE,GAAG,CAAC,WAAW;oBAC5B,WAAW,EAAE,GAAG,CAAC,WAAW;oBAC5B,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;oBACxC,mBAAmB,EAAE,GAAG,CAAC,mBAAmB;oBAC5C,YAAY,EAAE,GAAG,CAAC,YAAY;oBAC9B,UAAU,EAAE,GAAG,CAAC,UAAU;oBAC1B,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,OAAO,EAAE,GAAG,CAAC,OAAO;iBACrB,CAAC,CAAA;gBACF,kEAAkE;gBAClE,mEAAmE;gBACnE,+CAA+C;gBAC/C,IAAI,eAAe,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC;oBAC1C,MAAM,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAA;gBAChF,CAAC;gBACD,OAAO,IAAI,CAAC,CAAA;YACd,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,MAAM,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO;QACP,OAAO;QACP,OAAO,EAAE,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM;QACxC,MAAM;KACP,CAAA;AACH,CAAC"}
|
package/dist/catalog/store.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { type DatabaseHandle, type SqlExecutor } from '@cogenta/core';
|
|
2
|
-
import type { CreateProductInput, CreateVariantInput, Product, ProductStatus, StockRequest, StockShortfall, UpdateProductInput, UpdateVariantInput, Variant } from './types.js';
|
|
2
|
+
import type { CreateProductInput, CreateVariantInput, Product, ProductStatus, ProductTerm, StockMovement, StockMovementOptions, StockRequest, StockShortfall, UpdateProductInput, UpdateVariantInput, Variant } from './types.js';
|
|
3
3
|
export interface ProductListOptions {
|
|
4
4
|
readonly status?: ProductStatus;
|
|
5
5
|
/** Case-insensitive substring of handle or title. */
|
|
6
6
|
readonly search?: string;
|
|
7
7
|
readonly limit?: number;
|
|
8
8
|
readonly offset?: number;
|
|
9
|
+
/** `createdAt` (the historical default) unless stated otherwise (fiche 51 task 2). */
|
|
10
|
+
readonly sort?: 'createdAt' | 'title' | 'handle';
|
|
11
|
+
readonly direction?: 'asc' | 'desc';
|
|
9
12
|
}
|
|
10
13
|
/**
|
|
11
14
|
* The outcome of taking stock. Never a boolean and never a throw for the
|
|
@@ -34,10 +37,14 @@ export interface CatalogStore {
|
|
|
34
37
|
updateVariant(id: string, input: UpdateVariantInput): Promise<Variant>;
|
|
35
38
|
deleteVariant(id: string): Promise<void>;
|
|
36
39
|
listVariants(productId: string): Promise<readonly Variant[]>;
|
|
40
|
+
/** Every variant with a threshold set whose `onHand` has reached or crossed
|
|
41
|
+
* it, lowest stock first (fiche 51 task 4). A variant with no threshold is
|
|
42
|
+
* never in this list, however low its stock. */
|
|
43
|
+
listLowStock(): Promise<readonly Variant[]>;
|
|
37
44
|
/** Sets absolute stock. For a stock take, never for a sale. */
|
|
38
|
-
setStock(variantId: string, onHand: number): Promise<Variant>;
|
|
45
|
+
setStock(variantId: string, onHand: number, options?: StockMovementOptions): Promise<Variant>;
|
|
39
46
|
/** Adds to stock. For a delivery, and for putting a cancelled order back. */
|
|
40
|
-
restock(requests: readonly StockRequest[], tx?: SqlExecutor): Promise<void>;
|
|
47
|
+
restock(requests: readonly StockRequest[], tx?: SqlExecutor, options?: StockMovementOptions): Promise<void>;
|
|
41
48
|
/**
|
|
42
49
|
* Takes stock for a sale, atomically, all lines or none.
|
|
43
50
|
*
|
|
@@ -47,7 +54,20 @@ export interface CatalogStore {
|
|
|
47
54
|
* racing for the last unit both pass the read, and exactly one passes the
|
|
48
55
|
* UPDATE — which is the difference between a shop and an oversold shop.
|
|
49
56
|
*/
|
|
50
|
-
takeStock(requests: readonly StockRequest[], tx?: SqlExecutor): Promise<StockOutcome>;
|
|
57
|
+
takeStock(requests: readonly StockRequest[], tx?: SqlExecutor, options?: StockMovementOptions): Promise<StockOutcome>;
|
|
58
|
+
/** A variant's append-only stock history, most recent first (fiche 51 task 4). */
|
|
59
|
+
listStockMovements(variantId: string): Promise<readonly StockMovement[]>;
|
|
60
|
+
/** A product's classification against zero or more taxonomies (fiche 51 task 3). */
|
|
61
|
+
listProductTerms(productId: string): Promise<readonly ProductTerm[]>;
|
|
62
|
+
/**
|
|
63
|
+
* Replaces everything this product carries in `taxonomy` with `termIds` —
|
|
64
|
+
* the same "whole field, replaced on save" semantics `f.taxonomy` already
|
|
65
|
+
* uses on a collection entry. Terms of a *different* taxonomy on the same
|
|
66
|
+
* product are untouched.
|
|
67
|
+
*/
|
|
68
|
+
setProductTerms(productId: string, taxonomy: string, termIds: readonly string[]): Promise<readonly ProductTerm[]>;
|
|
69
|
+
/** The product linked to this content entry, if any — the reverse of `contentRef` (fiche 51 task 1). */
|
|
70
|
+
readProductByContentRef(collection: string, entryId: string): Promise<Product | null>;
|
|
51
71
|
}
|
|
52
72
|
export declare function createCatalogStore(db: DatabaseHandle, now?: () => number): CatalogStore;
|
|
53
73
|
//# sourceMappingURL=store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/catalog/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EAInB,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/catalog/store.ts"],"names":[],"mappings":"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"}
|