@tallyui/pos 3.1.1 → 3.2.0

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/index.d.ts CHANGED
@@ -1849,6 +1849,11 @@ declare function useSale(settings: Pick<StoreSettings, 'currency'>, opts: {
1849
1849
  capabilities?: ServerCapabilities;
1850
1850
  /** Where `park()` keeps parked carts; create it with `orderDraftSchema` */
1851
1851
  drafts?: RxCollection;
1852
+ /**
1853
+ * The current unit price (integer minor units) of a variant in the till's catalogue, or undefined when unknown.
1854
+ * When set, `resume()` re-prices the restored lines from it unless asked to keep the parked prices.
1855
+ */
1856
+ currentPrice?: (variantId: string) => number | undefined;
1852
1857
  /**
1853
1858
  * When set, `complete()` stamps the finalized order with this session before `onSaleCompleted`.
1854
1859
  * `complete()` runs after the money is taken, so a refused stamp (the session closed or went
@@ -1947,7 +1952,9 @@ declare function useSale(settings: Pick<StoreSettings, 'currency'>, opts: {
1947
1952
  /** Parks the cart in `drafts`; resolves to a refusal message, or null once parked. */
1948
1953
  park(): Promise<string | null>;
1949
1954
  /** Resumes a draft into an empty cart; resolves to a refusal message, or null once resumed. */
1950
- resume(draftId: string): Promise<string | null>;
1955
+ resume(draftId: string, options?: {
1956
+ keepParkedPrices?: boolean;
1957
+ }): Promise<string | null>;
1951
1958
  /**
1952
1959
  * Continue after a failed save whose order is confirmed stored (`canContinue`): exactly `newSale()`.
1953
1960
  * The order stays pending in the outbox, which will send it; it isn't handed to `onSaleCompleted` again, and
package/dist/index.js CHANGED
@@ -3928,7 +3928,7 @@ function useSale(settings, opts) {
3928
3928
  return null;
3929
3929
  },
3930
3930
  /** Resumes a draft into an empty cart; resolves to a refusal message, or null once resumed. */
3931
- async resume(draftId) {
3931
+ async resume(draftId, options) {
3932
3932
  if (locked()) return SALE_SAVING;
3933
3933
  if (!opts.drafts) throw new Error("useSale: resume() needs the drafts option");
3934
3934
  const live = builderNow.current;
@@ -3939,12 +3939,24 @@ function useSale(settings, opts) {
3939
3939
  const saved = JSON.parse(doc.toJSON().data);
3940
3940
  if (saved.currency.toUpperCase() !== settings.currency.toUpperCase()) return "That parked sale is in another currency";
3941
3941
  const builder = restoreOrderDraft(saved, { currency: settings.currency, taxContext });
3942
+ let n = 0;
3943
+ if (opts.currentPrice && !options?.keepParkedPrices) {
3944
+ for (const line of builder.getSnapshot().lineItems) {
3945
+ if (!line.variantId) continue;
3946
+ const price = opts.currentPrice(line.variantId);
3947
+ if (price !== void 0 && Number.isInteger(price) && price >= 0 && price !== line.unitPriceMinor) {
3948
+ builder.setUnitPrice(line.id, price);
3949
+ n++;
3950
+ }
3951
+ }
3952
+ }
3942
3953
  await doc.remove();
3943
3954
  if (builderNow.current !== live || live.getSnapshot() !== liveSnapshot) {
3944
3955
  await writeOrderDraft(opts.drafts, saved);
3945
3956
  return "The sale changed while it was being resumed; resume it again";
3946
3957
  }
3947
3958
  resetSale(null, builder);
3959
+ if (n > 0) setError(`Prices changed since this sale was parked: ${n} ${n === 1 ? "line" : "lines"} updated to today's price.`);
3948
3960
  return null;
3949
3961
  },
3950
3962
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tallyui/pos",
3
- "version": "3.1.1",
3
+ "version": "3.2.0",
4
4
  "type": "module",
5
5
  "description": "Shared POS business logic for Tally UI — tax, orders, payments, discounts, receipts",
6
6
  "main": "./dist/index.js",
@@ -27,20 +27,20 @@
27
27
  "directory": "packages/pos"
28
28
  },
29
29
  "peerDependencies": {
30
- "@tallyui/core": "^3.1.1",
30
+ "@tallyui/core": "^3.2.0",
31
31
  "react": ">=18",
32
32
  "rxdb": "~17.5.0",
33
33
  "rxjs": ">=7"
34
34
  },
35
35
  "devDependencies": {
36
- "@tallyui/core": "3.1.1",
36
+ "@tallyui/core": "3.2.0",
37
37
  "@types/react": ">=18",
38
38
  "react": "^19.2.4",
39
39
  "rxdb": "17.5.0",
40
40
  "rxjs": "7.8.2",
41
- "@tallyui/connector-medusa": "3.1.1",
42
- "@tallyui/connector-woocommerce": "3.1.1",
43
- "@tallyui/database": "3.1.1"
41
+ "@tallyui/connector-medusa": "3.2.0",
42
+ "@tallyui/connector-woocommerce": "3.2.0",
43
+ "@tallyui/database": "3.2.0"
44
44
  },
45
45
  "scripts": {
46
46
  "build": "tsup",
@@ -33,6 +33,11 @@ export function useSale(settings: Pick<StoreSettings, 'currency'>, opts: {
33
33
  registerId: string; cashierRef: string; capabilities?: ServerCapabilities;
34
34
  /** Where `park()` keeps parked carts; create it with `orderDraftSchema` */
35
35
  drafts?: RxCollection;
36
+ /**
37
+ * The current unit price (integer minor units) of a variant in the till's catalogue, or undefined when unknown.
38
+ * When set, `resume()` re-prices the restored lines from it unless asked to keep the parked prices.
39
+ */
40
+ currentPrice?: (variantId: string) => number | undefined;
36
41
  /**
37
42
  * When set, `complete()` stamps the finalized order with this session before `onSaleCompleted`.
38
43
  * `complete()` runs after the money is taken, so a refused stamp (the session closed or went
@@ -437,7 +442,7 @@ export function useSale(settings: Pick<StoreSettings, 'currency'>, opts: {
437
442
  return null;
438
443
  },
439
444
  /** Resumes a draft into an empty cart; resolves to a refusal message, or null once resumed. */
440
- async resume(draftId: string): Promise<string | null> {
445
+ async resume(draftId: string, options?: { keepParkedPrices?: boolean }): Promise<string | null> {
441
446
  if (locked()) return SALE_SAVING;
442
447
  if (!opts.drafts) throw new Error('useSale: resume() needs the drafts option');
443
448
  const live = builderNow.current;
@@ -448,12 +453,24 @@ export function useSale(settings: Pick<StoreSettings, 'currency'>, opts: {
448
453
  const saved: Order = JSON.parse(doc.toJSON().data);
449
454
  if (saved.currency.toUpperCase() !== settings.currency.toUpperCase()) return 'That parked sale is in another currency';
450
455
  const builder = restoreOrderDraft(saved, { currency: settings.currency, taxContext });
456
+ let n = 0;
457
+ if (opts.currentPrice && !options?.keepParkedPrices) {
458
+ for (const line of builder.getSnapshot().lineItems) {
459
+ if (!line.variantId) continue;
460
+ const price = opts.currentPrice(line.variantId);
461
+ if (price !== undefined && Number.isInteger(price) && price >= 0 && price !== line.unitPriceMinor) {
462
+ builder.setUnitPrice(line.id, price);
463
+ n++;
464
+ }
465
+ }
466
+ }
451
467
  await doc.remove();
452
468
  if (builderNow.current !== live || live.getSnapshot() !== liveSnapshot) {
453
469
  await writeOrderDraft(opts.drafts, saved);
454
470
  return 'The sale changed while it was being resumed; resume it again';
455
471
  }
456
472
  resetSale(null, builder);
473
+ if (n > 0) setError(`Prices changed since this sale was parked: ${n} ${n === 1 ? 'line' : 'lines'} updated to today's price.`);
457
474
  return null;
458
475
  },
459
476
  /**