@final-commerce/command-frame 0.5.0 → 0.6.0-staging.1
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/README.md +5 -5
- package/dist/CommonTypes.d.ts +6 -6
- package/dist/CommonTypes.js +2 -2
- package/dist/actions/add-cart-discount/mock.d.ts +1 -1
- package/dist/actions/add-cart-discount/mock.js +8 -8
- package/dist/actions/add-cart-fee/mock.d.ts +1 -1
- package/dist/actions/add-cart-fee/mock.js +8 -8
- package/dist/actions/add-product-to-cart/mock.d.ts +1 -1
- package/dist/actions/add-product-to-cart/mock.js +24 -10
- package/dist/actions/add-product-to-cart/types.d.ts +13 -1
- package/dist/actions/adjust-inventory/mock.d.ts +1 -1
- package/dist/actions/adjust-inventory/mock.js +6 -6
- package/dist/actions/apply-transition/mock.d.ts +1 -1
- package/dist/actions/apply-transition/mock.js +8 -8
- package/dist/actions/apply-transition/types.d.ts +1 -1
- package/dist/actions/authenticate-user/mock.d.ts +1 -1
- package/dist/actions/authenticate-user/mock.js +3 -3
- package/dist/actions/calculate-refund-total/action.d.ts +1 -1
- package/dist/actions/calculate-refund-total/action.js +2 -2
- package/dist/actions/can-transition/types.d.ts +1 -1
- package/dist/actions/cash-payment/mock.d.ts +1 -1
- package/dist/actions/cash-payment/mock.js +10 -10
- package/dist/actions/cash-payment/types.d.ts +1 -1
- package/dist/actions/extension-payment/mock.d.ts +1 -1
- package/dist/actions/extension-payment/mock.js +3 -3
- package/dist/actions/extension-payment/types.d.ts +1 -1
- package/dist/actions/get-available-transitions/mock.d.ts +1 -1
- package/dist/actions/get-available-transitions/mock.js +19 -19
- package/dist/actions/get-final-context/mock.d.ts +1 -1
- package/dist/actions/get-final-context/mock.js +2 -2
- package/dist/actions/get-products/mock.d.ts +1 -1
- package/dist/actions/get-products/mock.js +26 -9
- package/dist/actions/get-refunds/types.d.ts +1 -1
- package/dist/actions/get-remaining-refundable-quantities/action.d.ts +1 -1
- package/dist/actions/get-remaining-refundable-quantities/action.js +2 -2
- package/dist/actions/get-remaining-refundable-quantities/mock.d.ts +1 -1
- package/dist/actions/get-remaining-refundable-quantities/mock.js +2 -2
- package/dist/actions/integration-payment/types.d.ts +1 -1
- package/dist/actions/park-order/types.d.ts +1 -1
- package/dist/actions/partial-payment/mock.d.ts +1 -1
- package/dist/actions/partial-payment/mock.js +8 -8
- package/dist/actions/partial-payment/types.d.ts +1 -1
- package/dist/actions/print/mock.d.ts +1 -1
- package/dist/actions/print/mock.js +9 -9
- package/dist/actions/print/types.d.ts +6 -6
- package/dist/actions/redeem-payment/types.d.ts +1 -1
- package/dist/actions/remove-cart-fee/mock.d.ts +1 -1
- package/dist/actions/remove-cart-fee/mock.js +7 -7
- package/dist/actions/remove-product-from-cart/mock.d.ts +1 -1
- package/dist/actions/remove-product-from-cart/mock.js +11 -8
- package/dist/actions/resume-parked-order/types.d.ts +1 -1
- package/dist/actions/select-all-refund-items/action.d.ts +1 -1
- package/dist/actions/select-all-refund-items/action.js +2 -2
- package/dist/actions/set-active-product/mock.d.ts +1 -1
- package/dist/actions/set-active-product/mock.js +19 -14
- package/dist/actions/set-active-refund/types.d.ts +1 -1
- package/dist/actions/tap-to-pay-payment/mock.d.ts +1 -1
- package/dist/actions/tap-to-pay-payment/mock.js +6 -6
- package/dist/actions/tap-to-pay-payment/types.d.ts +1 -1
- package/dist/actions/terminal-payment/mock.d.ts +1 -1
- package/dist/actions/terminal-payment/mock.js +6 -6
- package/dist/actions/terminal-payment/types.d.ts +2 -2
- package/dist/actions/update-cart-item-quantity/mock.d.ts +1 -1
- package/dist/actions/update-cart-item-quantity/mock.js +23 -15
- package/dist/actions/update-cart-item-quantity/types.d.ts +8 -1
- package/dist/actions/upsert-custom-table-data/mock.d.ts +1 -1
- package/dist/actions/upsert-custom-table-data/mock.js +3 -3
- package/dist/demo/database.js +30 -4
- package/package.json +2 -2
|
@@ -1,60 +1,68 @@
|
|
|
1
|
-
import { MOCK_CART, mockPublishEvent } from
|
|
1
|
+
import { MOCK_CART, mockPublishEvent } from '../../demo/database';
|
|
2
|
+
import { extendPrice, isValidQuantity } from '@final-commerce/common';
|
|
2
3
|
export const mockUpdateCartItemQuantity = (params) => {
|
|
3
|
-
console.log(
|
|
4
|
+
console.log('[Mock] updateCartItemQuantity called', params);
|
|
4
5
|
if (!params?.internalId) {
|
|
5
|
-
throw new Error(
|
|
6
|
+
throw new Error('internalId is required');
|
|
6
7
|
}
|
|
7
8
|
if (params.quantity === undefined || params.quantity === null) {
|
|
8
|
-
throw new Error(
|
|
9
|
+
throw new Error('quantity is required');
|
|
9
10
|
}
|
|
10
11
|
const { internalId, quantity } = params;
|
|
11
12
|
// Find the product in the cart
|
|
12
|
-
const productIndex = MOCK_CART.products.findIndex(p => p.internalId === internalId);
|
|
13
|
+
const productIndex = MOCK_CART.products.findIndex((p) => p.internalId === internalId);
|
|
13
14
|
if (productIndex === -1) {
|
|
14
15
|
throw new Error(`Cart item with internalId ${internalId} not found`);
|
|
15
16
|
}
|
|
16
17
|
const product = MOCK_CART.products[productIndex];
|
|
17
18
|
const previousQuantity = product.quantity;
|
|
19
|
+
// The line resolved its unit when it was added; a piece-sold line has none and stays whole.
|
|
20
|
+
if (quantity !== 0 &&
|
|
21
|
+
!isValidQuantity(quantity, (product.unit ?? { unitId: 'piece', ratioToBase: 1, precision: 0 }))) {
|
|
22
|
+
throw new Error(product.unit
|
|
23
|
+
? `${quantity} is finer than ${product.unit.abbreviation} can express (${product.unit.precision} decimals)`
|
|
24
|
+
: `${product.name} is sold by the piece, so ${quantity} is not a quantity it can sell in`);
|
|
25
|
+
}
|
|
18
26
|
// If quantity is 0, remove the item
|
|
19
27
|
if (quantity === 0) {
|
|
20
28
|
MOCK_CART.products.splice(productIndex, 1);
|
|
21
29
|
// Recalculate totals
|
|
22
|
-
const lineTotal = product.price
|
|
30
|
+
const lineTotal = extendPrice(product.price, previousQuantity);
|
|
23
31
|
MOCK_CART.subtotal -= lineTotal;
|
|
24
32
|
MOCK_CART.total -= lineTotal;
|
|
25
33
|
MOCK_CART.amountToBeCharged = MOCK_CART.total;
|
|
26
34
|
MOCK_CART.remainingBalance = MOCK_CART.total;
|
|
27
35
|
// Publish product-deleted event
|
|
28
|
-
mockPublishEvent(
|
|
36
|
+
mockPublishEvent('cart', 'product-deleted', {
|
|
29
37
|
product: product,
|
|
30
|
-
internalId: internalId
|
|
38
|
+
internalId: internalId,
|
|
31
39
|
});
|
|
32
40
|
return Promise.resolve({
|
|
33
41
|
success: true,
|
|
34
42
|
internalId: internalId,
|
|
35
43
|
quantity: 0,
|
|
36
|
-
timestamp: new Date().toISOString()
|
|
44
|
+
timestamp: new Date().toISOString(),
|
|
37
45
|
});
|
|
38
46
|
}
|
|
39
47
|
// Update quantity
|
|
40
|
-
const quantityDelta = quantity - previousQuantity;
|
|
41
48
|
product.quantity = quantity;
|
|
42
|
-
//
|
|
43
|
-
|
|
49
|
+
// Difference of the two ROUNDED extensions — rounding the delta itself would let the
|
|
50
|
+
// line's running total drift from what extendPrice(price, quantity) says it is.
|
|
51
|
+
const lineTotalDelta = extendPrice(product.price, quantity) - extendPrice(product.price, previousQuantity);
|
|
44
52
|
MOCK_CART.subtotal += lineTotalDelta;
|
|
45
53
|
MOCK_CART.total += lineTotalDelta;
|
|
46
54
|
MOCK_CART.amountToBeCharged = MOCK_CART.total;
|
|
47
55
|
MOCK_CART.remainingBalance = MOCK_CART.total;
|
|
48
56
|
// Publish product-updated event
|
|
49
|
-
mockPublishEvent(
|
|
57
|
+
mockPublishEvent('cart', 'product-updated', {
|
|
50
58
|
product: product,
|
|
51
59
|
previousQuantity: previousQuantity,
|
|
52
|
-
newQuantity: quantity
|
|
60
|
+
newQuantity: quantity,
|
|
53
61
|
});
|
|
54
62
|
return Promise.resolve({
|
|
55
63
|
success: true,
|
|
56
64
|
internalId: internalId,
|
|
57
65
|
quantity: quantity,
|
|
58
|
-
timestamp: new Date().toISOString()
|
|
66
|
+
timestamp: new Date().toISOString(),
|
|
59
67
|
});
|
|
60
68
|
};
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
export interface UpdateCartItemQuantityParams {
|
|
2
2
|
/** The unique identifier for the specific cart item to update. */
|
|
3
3
|
internalId: string;
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* The new quantity. If set to 0, the item will be removed from the cart.
|
|
6
|
+
*
|
|
7
|
+
* **May be fractional** for a variant sold by measure; the number of decimals allowed comes
|
|
8
|
+
* from `variant.unit.precision`. The engine refuses anything finer and names the unit in the
|
|
9
|
+
* error. Do not round or clamp before sending — a silently altered quantity is charged and
|
|
10
|
+
* deducted differently than the one the cashier typed.
|
|
11
|
+
*/
|
|
5
12
|
quantity: number;
|
|
6
13
|
}
|
|
7
14
|
export interface UpdateCartItemQuantityResponse {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { UpsertCustomTableData } from
|
|
1
|
+
import { UpsertCustomTableData } from './types';
|
|
2
2
|
export declare const mockUpsertCustomTableData: UpsertCustomTableData;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const mockUpsertCustomTableData = async (params) => {
|
|
2
|
-
console.log(
|
|
2
|
+
console.log('[Mock] upsertCustomTableData called', params);
|
|
3
3
|
const data = params?.data;
|
|
4
4
|
const now = new Date().toISOString();
|
|
5
5
|
// Return the data with _id and timestamps added
|
|
@@ -7,11 +7,11 @@ export const mockUpsertCustomTableData = async (params) => {
|
|
|
7
7
|
...data,
|
|
8
8
|
_id: data?._id || `mock_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
9
9
|
createdAt: data?.createdAt || now,
|
|
10
|
-
updatedAt: now
|
|
10
|
+
updatedAt: now,
|
|
11
11
|
};
|
|
12
12
|
return {
|
|
13
13
|
success: true,
|
|
14
14
|
data: resultData,
|
|
15
|
-
timestamp: now
|
|
15
|
+
timestamp: now,
|
|
16
16
|
};
|
|
17
17
|
};
|
package/dist/demo/database.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Stores mock data that mimics the Render environment
|
|
4
4
|
*/
|
|
5
5
|
import { CFProductType, CFUserTypes, CurrencyCode, } from '../CommonTypes';
|
|
6
|
+
import { extendPrice, resolveUnit, toBase } from '@final-commerce/common';
|
|
6
7
|
export * from './mocks';
|
|
7
8
|
// Asset Imports - Using Remote URLs to avoid build complexity with asset copying
|
|
8
9
|
const ASSETS_BASE_URL = 'https://raw.githubusercontent.com/Final-Commerce/command-frame/refs/heads/main/src/demo/assets';
|
|
@@ -314,12 +315,25 @@ export const MOCK_PRODUCT_BLACK_GARLIC = createSimpleProduct('prod_black_garlic'
|
|
|
314
315
|
// Helper to create line item
|
|
315
316
|
const createLineItem = (product, variantIndex = 0, quantity = 1) => {
|
|
316
317
|
const variant = product.variants[variantIndex];
|
|
318
|
+
// Same contract as a real order line: the unit is FROZEN on the line (a re-rated unit must
|
|
319
|
+
// not restate old orders), and the money is extendPrice — price × quantity may carry a
|
|
320
|
+
// fractional quantity, and the raw multiply would put fractional cents on the order.
|
|
321
|
+
const unit = variant.unitId ? resolveUnit(variant.unitId) : undefined;
|
|
322
|
+
const total = extendPrice(variant.price, quantity);
|
|
317
323
|
return {
|
|
318
324
|
productId: product._id,
|
|
319
325
|
variantId: variant._id,
|
|
320
326
|
name: product.name,
|
|
321
327
|
quantity,
|
|
322
328
|
price: variant.price,
|
|
329
|
+
...(unit
|
|
330
|
+
? {
|
|
331
|
+
unitId: unit.unitId,
|
|
332
|
+
unitAbbreviation: unit.abbreviation,
|
|
333
|
+
unitRatioToBase: unit.ratioToBase,
|
|
334
|
+
stockQuantity: toBase(quantity, unit),
|
|
335
|
+
}
|
|
336
|
+
: {}),
|
|
323
337
|
taxes: [],
|
|
324
338
|
discount: {
|
|
325
339
|
itemDiscounts: [],
|
|
@@ -327,8 +341,8 @@ const createLineItem = (product, variantIndex = 0, quantity = 1) => {
|
|
|
327
341
|
},
|
|
328
342
|
fee: { itemFees: [] },
|
|
329
343
|
totalTax: 0,
|
|
330
|
-
total
|
|
331
|
-
lineNetWithFees:
|
|
344
|
+
total,
|
|
345
|
+
lineNetWithFees: total,
|
|
332
346
|
metadata: [],
|
|
333
347
|
image: product.images?.[0] || '',
|
|
334
348
|
sku: variant.sku,
|
|
@@ -784,12 +798,24 @@ export const createOrderFromCart = (paymentType, amount, processor = 'cash') =>
|
|
|
784
798
|
const receiptId = `receipt_${Date.now()}`;
|
|
785
799
|
// Map cart products to line items
|
|
786
800
|
const lineItems = MOCK_CART.products.map((p) => {
|
|
801
|
+
// The cart line resolved its unit when it was added; the ORDER line freezes it, exactly
|
|
802
|
+
// as production does. extendPrice for the same reason as everywhere: fractional
|
|
803
|
+
// quantities must not leave fractional cents on an order.
|
|
804
|
+
const lineTotal = extendPrice(p.price, p.quantity);
|
|
787
805
|
return {
|
|
788
806
|
productId: p.id,
|
|
789
807
|
variantId: p.variantId,
|
|
790
808
|
name: p.name,
|
|
791
809
|
quantity: p.quantity,
|
|
792
810
|
price: p.price,
|
|
811
|
+
...(p.unit
|
|
812
|
+
? {
|
|
813
|
+
unitId: p.unit.unitId,
|
|
814
|
+
unitAbbreviation: p.unit.abbreviation,
|
|
815
|
+
unitRatioToBase: p.unit.ratioToBase,
|
|
816
|
+
stockQuantity: toBase(p.quantity, p.unit),
|
|
817
|
+
}
|
|
818
|
+
: {}),
|
|
793
819
|
taxes: [],
|
|
794
820
|
discount: {
|
|
795
821
|
itemDiscounts: [],
|
|
@@ -797,8 +823,8 @@ export const createOrderFromCart = (paymentType, amount, processor = 'cash') =>
|
|
|
797
823
|
},
|
|
798
824
|
fee: { itemFees: [] },
|
|
799
825
|
totalTax: 0,
|
|
800
|
-
total:
|
|
801
|
-
lineNetWithFees:
|
|
826
|
+
total: lineTotal,
|
|
827
|
+
lineNetWithFees: lineTotal,
|
|
802
828
|
metadata: [],
|
|
803
829
|
image: p.images?.[0] || '',
|
|
804
830
|
sku: p.sku || '',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@final-commerce/command-frame",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0-staging.1",
|
|
4
4
|
"description": "Commands Frame library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"ignoreBranchesMissingTickets": true
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@final-commerce/common": "
|
|
60
|
+
"@final-commerce/common": "2.2.0-staging.2"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@commitlint/cli": "^19.0.0",
|