rerobe-js-orm 4.4.9 → 4.5.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/lib/factories/Product/ProductFromFormState.js +48 -47
- package/lib/form-states/Product/ProductFormState.d.ts +37 -0
- package/lib/form-states/Product/ProductFormState.js +299 -0
- package/lib/models/Product.d.ts +19 -0
- package/lib/models/Product.js +145 -0
- package/lib/types/rerobe-product-types.d.ts +15 -1
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ const ProductFactory_1 = require("./ProductFactory");
|
|
|
4
4
|
const Product_1 = require("../../models/Product");
|
|
5
5
|
class ProductFromFormState extends ProductFactory_1.default {
|
|
6
6
|
createProduct(props) {
|
|
7
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31;
|
|
7
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32;
|
|
8
8
|
const productAttributes = {
|
|
9
9
|
availableForSale: props.fields.availableForSale.selectedValue,
|
|
10
10
|
description: props.fields.description.inputValue,
|
|
@@ -28,19 +28,20 @@ class ProductFromFormState extends ProductFactory_1.default {
|
|
|
28
28
|
variantId: ((_j = props.props) === null || _j === void 0 ? void 0 : _j.variantId) || '',
|
|
29
29
|
reservedBy: ((_k = props.props) === null || _k === void 0 ? void 0 : _k.reservedBy) || [],
|
|
30
30
|
options: props.fields.options.selectedValue,
|
|
31
|
+
variantInventory: ((_l = props.fields.variantInventory) === null || _l === void 0 ? void 0 : _l.selectedValues) || [],
|
|
31
32
|
costPerItem: props.fields.costPerItem.inputValue,
|
|
32
33
|
compareAtPrice: props.fields.compareAtPrice.inputValue,
|
|
33
34
|
quantity: props.fields.quantity.inputValue,
|
|
34
|
-
merchants: ((
|
|
35
|
-
merchantId: ((
|
|
35
|
+
merchants: ((_m = props.props) === null || _m === void 0 ? void 0 : _m.merchants) || [],
|
|
36
|
+
merchantId: ((_o = props.props) === null || _o === void 0 ? void 0 : _o.merchantId) || '',
|
|
36
37
|
editorAuthorizations: props.fields.editorAuthorizations.selectedValue,
|
|
37
38
|
rfidTag: props.fields.rfidTag.inputValue || '',
|
|
38
39
|
sku: props.fields.sku.inputValue || '',
|
|
39
|
-
metaDataDescription: ((
|
|
40
|
-
metaDataTitle: ((
|
|
40
|
+
metaDataDescription: ((_p = props.fields.metaDataDescription) === null || _p === void 0 ? void 0 : _p.inputValue) || '',
|
|
41
|
+
metaDataTitle: ((_q = props.fields.metaDataTitle) === null || _q === void 0 ? void 0 : _q.inputValue) || '',
|
|
41
42
|
};
|
|
42
43
|
const productFilterAttributes = {
|
|
43
|
-
documentId: (
|
|
44
|
+
documentId: (_r = props.props) === null || _r === void 0 ? void 0 : _r.documentId,
|
|
44
45
|
brand: props.fields.brand.selectedValue,
|
|
45
46
|
measurementCategory: props.fields.measurementCategory.selectedValue,
|
|
46
47
|
size: props.fields.size.selectedValue,
|
|
@@ -61,10 +62,10 @@ class ProductFromFormState extends ProductFactory_1.default {
|
|
|
61
62
|
featuredCollections: props.fields.featuredCollections.selectedValues || [],
|
|
62
63
|
primaryAgeCategory: props.fields.primaryAgeCategory.selectedValue || '',
|
|
63
64
|
tags: props.fields.tags.selectedValues || [],
|
|
64
|
-
systemTags: ((
|
|
65
|
+
systemTags: ((_s = props.props) === null || _s === void 0 ? void 0 : _s.systemTags) || [],
|
|
65
66
|
};
|
|
66
67
|
const consignmentAttributes = {
|
|
67
|
-
sellRequestId: ((
|
|
68
|
+
sellRequestId: ((_t = props.props) === null || _t === void 0 ? void 0 : _t.sellRequestId) || '',
|
|
68
69
|
publishType: props.fields.publishType.selectedValue,
|
|
69
70
|
conditionRemarks: props.fields.conditionRemarks.inputValue,
|
|
70
71
|
productRemarks: props.fields.productRemarks.inputValue,
|
|
@@ -77,14 +78,14 @@ class ProductFromFormState extends ProductFactory_1.default {
|
|
|
77
78
|
nextAvailableSeason: props.fields.nextAvailableSeason.selectedValue,
|
|
78
79
|
notesForProductionTeam: props.fields.notesForProductionTeam.inputValue,
|
|
79
80
|
reviewedBy: props.fields.reviewedBy.selectedValue,
|
|
80
|
-
sellRequestImageUrls: ((
|
|
81
|
+
sellRequestImageUrls: ((_u = props.props) === null || _u === void 0 ? void 0 : _u.sellRequestImageUrls) || [],
|
|
81
82
|
salesChannel: props.fields.salesChannel.selectedValues || [],
|
|
82
83
|
sizeComment: props.fields.sizeComment.selectedValue,
|
|
83
|
-
salePrice: ((
|
|
84
|
+
salePrice: ((_v = props.props) === null || _v === void 0 ? void 0 : _v.salePrice) || '',
|
|
84
85
|
isOnSale: props.fields.isOnSale.selectedValue || '',
|
|
85
86
|
discountType: props.fields.discountType.selectedValue || '',
|
|
86
87
|
discountValue: props.fields.discountValue.inputValue || '',
|
|
87
|
-
selectedForClearance: ((
|
|
88
|
+
selectedForClearance: ((_w = props.props) === null || _w === void 0 ? void 0 : _w.selectedForClearance) || '',
|
|
88
89
|
locationIds: props.fields.locationIds.selectedValues || [],
|
|
89
90
|
inventoryLocations: props.fields.inventoryLocations.selectedValues || [],
|
|
90
91
|
majorDefects: props.fields.majorDefects.selectedValues || [], // ToDo: Deprecate
|
|
@@ -92,44 +93,44 @@ class ProductFromFormState extends ProductFactory_1.default {
|
|
|
92
93
|
careInstructions: props.fields.careInstructions.inputValue || '',
|
|
93
94
|
};
|
|
94
95
|
const timestampAttributes = {
|
|
95
|
-
createdAtTimestamp: (
|
|
96
|
-
updatedAtTimestamp: (
|
|
97
|
-
sellRequestReviewTimestamp: (
|
|
98
|
-
sellRequestReviewDraftTimestamp: (
|
|
99
|
-
rejectedTimestamp: (
|
|
100
|
-
holdTimestamp: (
|
|
101
|
-
acceptedTimestamp: (
|
|
102
|
-
sellerToDropOffTimestamp: (
|
|
103
|
-
sellerToShipTimestamp: (
|
|
104
|
-
sellerToGetPickUpTimestamp: (
|
|
105
|
-
qualityControlTimestamp: (
|
|
106
|
-
pendingPublicationTimestamp: (
|
|
107
|
-
listedTimestamp: (
|
|
108
|
-
clearanceTimestamp: (
|
|
109
|
-
reservedTimestamp: (
|
|
110
|
-
soldTimestamp: (
|
|
111
|
-
returnedTimestamp: (
|
|
112
|
-
soldSellerSelfPayTimestamp: (
|
|
113
|
-
soldSellerPayoutProcessingTimestamp: (
|
|
114
|
-
soldSellerPayoutFailedTimestamp: (
|
|
115
|
-
soldSellerToBePaidTimestamp: (
|
|
116
|
-
soldSellerPaidTimestamp: (
|
|
117
|
-
sellerSelfRejectTimestamp: (
|
|
118
|
-
liquidationRequestedTimestamp: (
|
|
119
|
-
sellerLiquidatedTimestamp: (
|
|
120
|
-
archivedTimestamp: (
|
|
121
|
-
liquidationReadyTimestamp: (
|
|
122
|
-
sellerDonatedTimestamp: (
|
|
123
|
-
merchantDonatedTimestamp: (
|
|
124
|
-
draftTimestamp: (
|
|
125
|
-
hiddenTimestamp: (
|
|
126
|
-
bookedTimestamp: (
|
|
127
|
-
openTimestamp: (
|
|
96
|
+
createdAtTimestamp: (_x = props.props) === null || _x === void 0 ? void 0 : _x.createdAtTimestamp,
|
|
97
|
+
updatedAtTimestamp: (_y = props.props) === null || _y === void 0 ? void 0 : _y.updatedAtTimestamp,
|
|
98
|
+
sellRequestReviewTimestamp: (_z = props.props) === null || _z === void 0 ? void 0 : _z.sellRequestReviewTimestamp,
|
|
99
|
+
sellRequestReviewDraftTimestamp: (_0 = props.props) === null || _0 === void 0 ? void 0 : _0.sellRequestReviewDraftTimestamp,
|
|
100
|
+
rejectedTimestamp: (_1 = props.props) === null || _1 === void 0 ? void 0 : _1.rejectedTimestamp,
|
|
101
|
+
holdTimestamp: (_2 = props.props) === null || _2 === void 0 ? void 0 : _2.holdTimestamp,
|
|
102
|
+
acceptedTimestamp: (_3 = props.props) === null || _3 === void 0 ? void 0 : _3.acceptedTimestamp,
|
|
103
|
+
sellerToDropOffTimestamp: (_4 = props.props) === null || _4 === void 0 ? void 0 : _4.sellerToDropOffTimestamp,
|
|
104
|
+
sellerToShipTimestamp: (_5 = props.props) === null || _5 === void 0 ? void 0 : _5.sellerToShipTimestamp,
|
|
105
|
+
sellerToGetPickUpTimestamp: (_6 = props.props) === null || _6 === void 0 ? void 0 : _6.sellerToGetPickUpTimestamp,
|
|
106
|
+
qualityControlTimestamp: (_7 = props.props) === null || _7 === void 0 ? void 0 : _7.qualityControlTimestamp,
|
|
107
|
+
pendingPublicationTimestamp: (_8 = props.props) === null || _8 === void 0 ? void 0 : _8.pendingPublicationTimestamp,
|
|
108
|
+
listedTimestamp: (_9 = props.props) === null || _9 === void 0 ? void 0 : _9.listedTimestamp,
|
|
109
|
+
clearanceTimestamp: (_10 = props.props) === null || _10 === void 0 ? void 0 : _10.clearanceTimestamp,
|
|
110
|
+
reservedTimestamp: (_11 = props.props) === null || _11 === void 0 ? void 0 : _11.reservedTimestamp,
|
|
111
|
+
soldTimestamp: (_12 = props.props) === null || _12 === void 0 ? void 0 : _12.soldTimestamp,
|
|
112
|
+
returnedTimestamp: (_13 = props.props) === null || _13 === void 0 ? void 0 : _13.returnedTimestamp,
|
|
113
|
+
soldSellerSelfPayTimestamp: (_14 = props.props) === null || _14 === void 0 ? void 0 : _14.soldSellerSelfPayTimestamp,
|
|
114
|
+
soldSellerPayoutProcessingTimestamp: (_15 = props.props) === null || _15 === void 0 ? void 0 : _15.soldSellerPayoutProcessingTimestamp,
|
|
115
|
+
soldSellerPayoutFailedTimestamp: (_16 = props.props) === null || _16 === void 0 ? void 0 : _16.soldSellerPayoutFailedTimestamp,
|
|
116
|
+
soldSellerToBePaidTimestamp: (_17 = props.props) === null || _17 === void 0 ? void 0 : _17.soldSellerToBePaidTimestamp,
|
|
117
|
+
soldSellerPaidTimestamp: (_18 = props.props) === null || _18 === void 0 ? void 0 : _18.soldSellerPaidTimestamp,
|
|
118
|
+
sellerSelfRejectTimestamp: (_19 = props.props) === null || _19 === void 0 ? void 0 : _19.sellerSelfRejectTimestamp,
|
|
119
|
+
liquidationRequestedTimestamp: (_20 = props.props) === null || _20 === void 0 ? void 0 : _20.liquidationRequestedTimestamp,
|
|
120
|
+
sellerLiquidatedTimestamp: (_21 = props.props) === null || _21 === void 0 ? void 0 : _21.sellerLiquidatedTimestamp,
|
|
121
|
+
archivedTimestamp: (_22 = props.props) === null || _22 === void 0 ? void 0 : _22.archivedTimestamp,
|
|
122
|
+
liquidationReadyTimestamp: (_23 = props.props) === null || _23 === void 0 ? void 0 : _23.liquidationReadyTimestamp,
|
|
123
|
+
sellerDonatedTimestamp: (_24 = props.props) === null || _24 === void 0 ? void 0 : _24.sellerDonatedTimestamp,
|
|
124
|
+
merchantDonatedTimestamp: (_25 = props.props) === null || _25 === void 0 ? void 0 : _25.merchantDonatedTimestamp,
|
|
125
|
+
draftTimestamp: (_26 = props.props) === null || _26 === void 0 ? void 0 : _26.draftTimestamp,
|
|
126
|
+
hiddenTimestamp: (_27 = props.props) === null || _27 === void 0 ? void 0 : _27.hiddenTimestamp,
|
|
127
|
+
bookedTimestamp: (_28 = props.props) === null || _28 === void 0 ? void 0 : _28.bookedTimestamp,
|
|
128
|
+
openTimestamp: (_29 = props.props) === null || _29 === void 0 ? void 0 : _29.openTimestamp,
|
|
128
129
|
};
|
|
129
130
|
const payoutAttributes = {
|
|
130
|
-
payoutMethod: (
|
|
131
|
-
payoutSystem: (
|
|
132
|
-
payoutReference: (
|
|
131
|
+
payoutMethod: (_30 = props.props) === null || _30 === void 0 ? void 0 : _30.payoutMethod,
|
|
132
|
+
payoutSystem: (_31 = props.props) === null || _31 === void 0 ? void 0 : _31.payoutSystem,
|
|
133
|
+
payoutReference: (_32 = props.props) === null || _32 === void 0 ? void 0 : _32.payoutReference,
|
|
133
134
|
};
|
|
134
135
|
return new Product_1.default(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, productAttributes), productFilterAttributes), consignmentAttributes), timestampAttributes), payoutAttributes));
|
|
135
136
|
}
|
|
@@ -3,6 +3,7 @@ import Product from '../../models/Product';
|
|
|
3
3
|
export default class ProductFormState extends FormState {
|
|
4
4
|
fields: ProductFormFields;
|
|
5
5
|
props: CompleteProduct;
|
|
6
|
+
private variantAxes?;
|
|
6
7
|
opts: {
|
|
7
8
|
featuredCollectionOpts: {
|
|
8
9
|
label: string;
|
|
@@ -59,5 +60,41 @@ export default class ProductFormState extends FormState {
|
|
|
59
60
|
private discountValueChangeHandler;
|
|
60
61
|
private calculateSalePrice;
|
|
61
62
|
private inventoryLocationsChangeHandler;
|
|
63
|
+
private isSameOptions;
|
|
64
|
+
private getExistingVariantByOptions;
|
|
65
|
+
private variantInventoryChangeHandler;
|
|
66
|
+
setVariantAxes(axes?: {
|
|
67
|
+
[axis: string]: string[];
|
|
68
|
+
}): void;
|
|
69
|
+
generateVariantsFromAxes(defaults?: Partial<VariantInventory>): void;
|
|
70
|
+
addAxis(axis: string): void;
|
|
71
|
+
removeAxis(axis: string): void;
|
|
72
|
+
addAxisValue(axis: string, value: string): void;
|
|
73
|
+
removeAxisValue(axis: string, value: string): void;
|
|
74
|
+
reorderAxes(order: string[]): void;
|
|
75
|
+
upsertVariantByOptions(options: {
|
|
76
|
+
[k: string]: string;
|
|
77
|
+
}, patch: Partial<VariantInventory>): void;
|
|
78
|
+
removeVariantByOptions(options: {
|
|
79
|
+
[k: string]: string;
|
|
80
|
+
}): void;
|
|
81
|
+
findVariantByOptions(options: {
|
|
82
|
+
[k: string]: string;
|
|
83
|
+
}): VariantInventory | undefined;
|
|
84
|
+
validateAxes(axes: {
|
|
85
|
+
[axis: string]: string[];
|
|
86
|
+
}): {
|
|
87
|
+
ok: boolean;
|
|
88
|
+
errors: string[];
|
|
89
|
+
};
|
|
90
|
+
diffVariantsFromAxes(nextAxes: {
|
|
91
|
+
[axis: string]: string[];
|
|
92
|
+
}): {
|
|
93
|
+
toAdd: {
|
|
94
|
+
[k: string]: string;
|
|
95
|
+
}[];
|
|
96
|
+
toRemove: string[];
|
|
97
|
+
};
|
|
98
|
+
private aggregateInventoryLocationsFromVariants;
|
|
62
99
|
private fieldFactory;
|
|
63
100
|
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
2
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
14
|
const FormState_1 = require("../FormState");
|
|
4
15
|
const options_1 = require("./options");
|
|
@@ -87,6 +98,8 @@ class ProductFormState extends FormState_1.default {
|
|
|
87
98
|
this.fields.handle = this.fieldFactory('textInput', 'handle');
|
|
88
99
|
// Product Classification (UNIQUE, MULTIVARIANT, TEMPLATE)
|
|
89
100
|
this.fields.productClass = this.fieldFactory('singleSelect', 'productClass', options_1.productClassOptions);
|
|
101
|
+
// Variant inventory per option-combination (max 3 axes)
|
|
102
|
+
this.fields.variantInventory = this.fieldFactory('multiSelect', 'variantInventory');
|
|
90
103
|
}
|
|
91
104
|
autoCreateTitle() {
|
|
92
105
|
return this.createProduct().autoCreateTitle();
|
|
@@ -569,6 +582,289 @@ class ProductFormState extends FormState_1.default {
|
|
|
569
582
|
this.multiSelectChangeHandler('inventoryLocations', val);
|
|
570
583
|
}
|
|
571
584
|
}
|
|
585
|
+
isSameOptions(a = {}, b = {}) {
|
|
586
|
+
const aKeys = Object.keys(a || {});
|
|
587
|
+
const bKeys = Object.keys(b || {});
|
|
588
|
+
if (aKeys.length !== bKeys.length)
|
|
589
|
+
return false;
|
|
590
|
+
return aKeys.every((k) => String(a[k]) === String(b[k]));
|
|
591
|
+
}
|
|
592
|
+
getExistingVariantByOptions(options = {}) {
|
|
593
|
+
var _a;
|
|
594
|
+
return ((_a = this.fields.variantInventory) === null || _a === void 0 ? void 0 : _a.selectedValues).find((v) => this.isSameOptions(v.options, options));
|
|
595
|
+
}
|
|
596
|
+
variantInventoryChangeHandler(val) {
|
|
597
|
+
var _a;
|
|
598
|
+
const numAxes = (val === null || val === void 0 ? void 0 : val.options) ? Object.keys(val.options).length : 0;
|
|
599
|
+
if (numAxes > 3) {
|
|
600
|
+
return; // silently ignore invalid (>3 axes)
|
|
601
|
+
}
|
|
602
|
+
const id = (val === null || val === void 0 ? void 0 : val.id) ||
|
|
603
|
+
((val === null || val === void 0 ? void 0 : val.options) ? (_a = this.getExistingVariantByOptions(val.options)) === null || _a === void 0 ? void 0 : _a.id : undefined) ||
|
|
604
|
+
this.utilities.makeRandId(28);
|
|
605
|
+
const existingInd = this.fields.variantInventory.selectedValues.findIndex((i) => i.id === id);
|
|
606
|
+
const existing = existingInd !== -1 ? this.fields.variantInventory.selectedValues[existingInd] : {};
|
|
607
|
+
const next = {
|
|
608
|
+
id,
|
|
609
|
+
options: val.options || existing.options || {},
|
|
610
|
+
locations: (val === null || val === void 0 ? void 0 : val.locations) !== undefined ? val.locations : existing.locations,
|
|
611
|
+
price: (val === null || val === void 0 ? void 0 : val.price) !== undefined ? val.price : existing.price,
|
|
612
|
+
compareAtPrice: (val === null || val === void 0 ? void 0 : val.compareAtPrice) !== undefined ? val.compareAtPrice : existing.compareAtPrice,
|
|
613
|
+
salePrice: (val === null || val === void 0 ? void 0 : val.salePrice) !== undefined ? val.salePrice : existing.salePrice,
|
|
614
|
+
isOnSale: (val === null || val === void 0 ? void 0 : val.isOnSale) !== undefined ? val.isOnSale : existing.isOnSale,
|
|
615
|
+
sku: (val === null || val === void 0 ? void 0 : val.sku) !== undefined ? val.sku : existing.sku,
|
|
616
|
+
taxable: (val === null || val === void 0 ? void 0 : val.taxable) !== undefined ? val.taxable : existing.taxable,
|
|
617
|
+
};
|
|
618
|
+
const foundInd = this.fields.variantInventory.selectedValues.findIndex((i) => i.id === id);
|
|
619
|
+
if (foundInd !== -1) {
|
|
620
|
+
const foundI = this.fields.variantInventory.selectedValues[foundInd];
|
|
621
|
+
let shouldToggleRemove = false;
|
|
622
|
+
if ((val === null || val === void 0 ? void 0 : val.locations) !== undefined) {
|
|
623
|
+
const norm = (arr = []) => [...arr]
|
|
624
|
+
.filter((l) => l && l.id)
|
|
625
|
+
.sort((a, b) => (a.id > b.id ? 1 : a.id < b.id ? -1 : 0))
|
|
626
|
+
.map((l) => `${l.id}:${Number(l.availableAmount) || 0}:${Number(l.incomingAmount) || 0}`)
|
|
627
|
+
.join('|');
|
|
628
|
+
shouldToggleRemove = norm(foundI.locations) === norm(next.locations);
|
|
629
|
+
}
|
|
630
|
+
if (shouldToggleRemove) {
|
|
631
|
+
this.fields.variantInventory.selectedValues.splice(foundInd, 1);
|
|
632
|
+
}
|
|
633
|
+
else {
|
|
634
|
+
this.fields.variantInventory.selectedValues.splice(foundInd, 1, next);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
638
|
+
this.multiSelectChangeHandler('variantInventory', next);
|
|
639
|
+
}
|
|
640
|
+
// aggregate updates
|
|
641
|
+
const totalQty = this.fields.variantInventory.selectedValues.reduce((acc, cur) => {
|
|
642
|
+
const locs = cur.locations;
|
|
643
|
+
const sum = Array.isArray(locs) ? locs.reduce((a, l) => a + (Number(l === null || l === void 0 ? void 0 : l.availableAmount) || 0), 0) : 0;
|
|
644
|
+
return acc + sum;
|
|
645
|
+
}, 0);
|
|
646
|
+
this.fields.quantity.inputValue = totalQty;
|
|
647
|
+
this.fields.availableForSale.selectedValue = totalQty > 0;
|
|
648
|
+
// aggregate main inventoryLocations from variant locations (sum by location id)
|
|
649
|
+
this.aggregateInventoryLocationsFromVariants();
|
|
650
|
+
}
|
|
651
|
+
// Public: define axes (≤3) for generating combinations
|
|
652
|
+
setVariantAxes(axes = {}) {
|
|
653
|
+
const axisKeys = Object.keys(axes || {});
|
|
654
|
+
if (axisKeys.length > 3) {
|
|
655
|
+
// trim to first 3 axes to enforce limit
|
|
656
|
+
this.variantAxes = axisKeys.slice(0, 3).reduce((acc, k) => {
|
|
657
|
+
acc[k] = Array.from(new Set((axes[k] || []).map((v) => String(v).trim()).filter(Boolean)));
|
|
658
|
+
return acc;
|
|
659
|
+
}, {});
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
this.variantAxes = axisKeys.reduce((acc, k) => {
|
|
663
|
+
acc[k] = Array.from(new Set((axes[k] || []).map((v) => String(v).trim()).filter(Boolean)));
|
|
664
|
+
return acc;
|
|
665
|
+
}, {});
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
// Public: regenerate variants from axes, preserving existing per-variant fields where options match
|
|
669
|
+
generateVariantsFromAxes(defaults = {}) {
|
|
670
|
+
const axes = this.variantAxes || {};
|
|
671
|
+
const axisKeys = Object.keys(axes);
|
|
672
|
+
if (axisKeys.length === 0) {
|
|
673
|
+
this.fields.variantInventory.selectedValues = [];
|
|
674
|
+
this.fields.variantInventory.valid = false;
|
|
675
|
+
this.aggregateInventoryLocationsFromVariants();
|
|
676
|
+
this.fields.quantity.inputValue = 0;
|
|
677
|
+
this.fields.availableForSale.selectedValue = false;
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
const cartesian = (keys, idx, cur, out) => {
|
|
681
|
+
if (idx >= keys.length) {
|
|
682
|
+
out.push(Object.assign({}, cur));
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
const key = keys[idx];
|
|
686
|
+
const values = axes[key] || [];
|
|
687
|
+
values.forEach((v) => {
|
|
688
|
+
cartesian(keys, idx + 1, Object.assign(Object.assign({}, cur), { [key]: v }), out);
|
|
689
|
+
});
|
|
690
|
+
};
|
|
691
|
+
const combos = [];
|
|
692
|
+
cartesian(axisKeys, 0, {}, combos);
|
|
693
|
+
const regenerated = combos.map((opts) => {
|
|
694
|
+
var _a, _b, _c, _d, _e, _f;
|
|
695
|
+
const prev = this.getExistingVariantByOptions(opts);
|
|
696
|
+
const id = (prev === null || prev === void 0 ? void 0 : prev.id) || this.utilities.makeRandId(28);
|
|
697
|
+
const merged = {
|
|
698
|
+
id,
|
|
699
|
+
options: opts,
|
|
700
|
+
locations: (prev === null || prev === void 0 ? void 0 : prev.locations) || defaults.locations,
|
|
701
|
+
price: (_a = prev === null || prev === void 0 ? void 0 : prev.price) !== null && _a !== void 0 ? _a : defaults.price,
|
|
702
|
+
compareAtPrice: (_b = prev === null || prev === void 0 ? void 0 : prev.compareAtPrice) !== null && _b !== void 0 ? _b : defaults.compareAtPrice,
|
|
703
|
+
salePrice: (_c = prev === null || prev === void 0 ? void 0 : prev.salePrice) !== null && _c !== void 0 ? _c : defaults.salePrice,
|
|
704
|
+
isOnSale: (_d = prev === null || prev === void 0 ? void 0 : prev.isOnSale) !== null && _d !== void 0 ? _d : defaults.isOnSale,
|
|
705
|
+
sku: (_e = prev === null || prev === void 0 ? void 0 : prev.sku) !== null && _e !== void 0 ? _e : defaults.sku,
|
|
706
|
+
taxable: (_f = prev === null || prev === void 0 ? void 0 : prev.taxable) !== null && _f !== void 0 ? _f : defaults.taxable,
|
|
707
|
+
};
|
|
708
|
+
return merged;
|
|
709
|
+
});
|
|
710
|
+
this.fields.variantInventory.selectedValues = regenerated;
|
|
711
|
+
this.fields.variantInventory.valid = regenerated.length > 0;
|
|
712
|
+
// Aggregate quantity and master locations
|
|
713
|
+
const totalQty = regenerated.reduce((acc, cur) => {
|
|
714
|
+
const locs = cur.locations;
|
|
715
|
+
const sum = Array.isArray(locs) ? locs.reduce((a, l) => a + (Number(l === null || l === void 0 ? void 0 : l.availableAmount) || 0), 0) : 0;
|
|
716
|
+
return acc + sum;
|
|
717
|
+
}, 0);
|
|
718
|
+
this.fields.quantity.inputValue = totalQty;
|
|
719
|
+
this.fields.availableForSale.selectedValue = totalQty > 0;
|
|
720
|
+
this.aggregateInventoryLocationsFromVariants();
|
|
721
|
+
}
|
|
722
|
+
// Convenience helpers for UI
|
|
723
|
+
addAxis(axis) {
|
|
724
|
+
const k = String(axis).trim();
|
|
725
|
+
if (!k)
|
|
726
|
+
return;
|
|
727
|
+
const current = this.variantAxes || {};
|
|
728
|
+
if (Object.keys(current).includes(k))
|
|
729
|
+
return;
|
|
730
|
+
const nextKeys = Object.keys(current).concat(k).slice(0, 3);
|
|
731
|
+
const next = {};
|
|
732
|
+
nextKeys.forEach((key) => (next[key] = current[key] || []));
|
|
733
|
+
if (!next[k])
|
|
734
|
+
next[k] = [];
|
|
735
|
+
this.variantAxes = next;
|
|
736
|
+
}
|
|
737
|
+
removeAxis(axis) {
|
|
738
|
+
const current = this.variantAxes || {};
|
|
739
|
+
if (!current[axis])
|
|
740
|
+
return;
|
|
741
|
+
const _a = current, _b = axis, _ = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
|
|
742
|
+
this.variantAxes = rest;
|
|
743
|
+
// remove affected variants by regenerating from remaining axes
|
|
744
|
+
this.generateVariantsFromAxes();
|
|
745
|
+
}
|
|
746
|
+
addAxisValue(axis, value) {
|
|
747
|
+
const current = this.variantAxes || {};
|
|
748
|
+
if (!current[axis])
|
|
749
|
+
current[axis] = [];
|
|
750
|
+
const val = String(value).trim();
|
|
751
|
+
if (!val)
|
|
752
|
+
return;
|
|
753
|
+
if (!current[axis].includes(val))
|
|
754
|
+
current[axis].push(val);
|
|
755
|
+
this.variantAxes = current;
|
|
756
|
+
this.generateVariantsFromAxes();
|
|
757
|
+
}
|
|
758
|
+
removeAxisValue(axis, value) {
|
|
759
|
+
const current = this.variantAxes || {};
|
|
760
|
+
if (!current[axis])
|
|
761
|
+
return;
|
|
762
|
+
const val = String(value).trim();
|
|
763
|
+
current[axis] = current[axis].filter((v) => v !== val);
|
|
764
|
+
this.variantAxes = current;
|
|
765
|
+
this.generateVariantsFromAxes();
|
|
766
|
+
}
|
|
767
|
+
reorderAxes(order) {
|
|
768
|
+
const current = this.variantAxes || {};
|
|
769
|
+
const keys = order.filter((k) => current[k]).slice(0, 3);
|
|
770
|
+
const rest = Object.keys(current)
|
|
771
|
+
.filter((k) => !keys.includes(k))
|
|
772
|
+
.slice(0, Math.max(0, 3 - keys.length));
|
|
773
|
+
const nextOrder = keys.concat(rest);
|
|
774
|
+
const next = {};
|
|
775
|
+
nextOrder.forEach((k) => (next[k] = current[k]));
|
|
776
|
+
this.variantAxes = next;
|
|
777
|
+
// No regen required; only presentation order
|
|
778
|
+
}
|
|
779
|
+
upsertVariantByOptions(options, patch) {
|
|
780
|
+
const prev = this.getExistingVariantByOptions(options);
|
|
781
|
+
const id = (prev === null || prev === void 0 ? void 0 : prev.id) || this.utilities.makeRandId(28);
|
|
782
|
+
this.variantInventoryChangeHandler(Object.assign({ id,
|
|
783
|
+
options }, patch));
|
|
784
|
+
}
|
|
785
|
+
removeVariantByOptions(options) {
|
|
786
|
+
const prev = this.getExistingVariantByOptions(options);
|
|
787
|
+
if (!prev)
|
|
788
|
+
return;
|
|
789
|
+
const ind = this.fields.variantInventory.selectedValues.findIndex((v) => v.id === prev.id);
|
|
790
|
+
if (ind !== -1) {
|
|
791
|
+
this.fields.variantInventory.selectedValues.splice(ind, 1);
|
|
792
|
+
// re-aggregate
|
|
793
|
+
const totalQty = this.fields.variantInventory.selectedValues.reduce((acc, cur) => {
|
|
794
|
+
const locs = cur.locations;
|
|
795
|
+
const sum = Array.isArray(locs) ? locs.reduce((a, l) => a + (Number(l === null || l === void 0 ? void 0 : l.availableAmount) || 0), 0) : 0;
|
|
796
|
+
return acc + sum;
|
|
797
|
+
}, 0);
|
|
798
|
+
this.fields.quantity.inputValue = totalQty;
|
|
799
|
+
this.fields.availableForSale.selectedValue = totalQty > 0;
|
|
800
|
+
this.aggregateInventoryLocationsFromVariants();
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
findVariantByOptions(options) {
|
|
804
|
+
return this.getExistingVariantByOptions(options);
|
|
805
|
+
}
|
|
806
|
+
validateAxes(axes) {
|
|
807
|
+
const errors = [];
|
|
808
|
+
const keys = Object.keys(axes || {});
|
|
809
|
+
if (keys.length > 3)
|
|
810
|
+
errors.push('Too many axes (max 3).');
|
|
811
|
+
keys.forEach((k) => {
|
|
812
|
+
const vals = axes[k] || [];
|
|
813
|
+
const clean = vals.map((v) => String(v).trim()).filter(Boolean);
|
|
814
|
+
if (clean.length !== vals.length)
|
|
815
|
+
errors.push(`Axis "${k}" has empty/invalid values.`);
|
|
816
|
+
});
|
|
817
|
+
return { ok: errors.length === 0, errors };
|
|
818
|
+
}
|
|
819
|
+
diffVariantsFromAxes(nextAxes) {
|
|
820
|
+
const curRows = this.fields.variantInventory.selectedValues || [];
|
|
821
|
+
const curKeySet = new Set(curRows.map((r) => JSON.stringify(r.options || {})));
|
|
822
|
+
// build combos for nextAxes
|
|
823
|
+
const keys = Object.keys(nextAxes || {});
|
|
824
|
+
const out = [];
|
|
825
|
+
const cart = (i, acc) => {
|
|
826
|
+
if (i >= keys.length) {
|
|
827
|
+
out.push(Object.assign({}, acc));
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
const k = keys[i];
|
|
831
|
+
const vals = nextAxes[k] || [];
|
|
832
|
+
vals.forEach((v) => cart(i + 1, Object.assign(Object.assign({}, acc), { [k]: v })));
|
|
833
|
+
};
|
|
834
|
+
cart(0, {});
|
|
835
|
+
const nextKeySet = new Set(out.map((o) => JSON.stringify(o)));
|
|
836
|
+
const toAdd = out.filter((o) => !curKeySet.has(JSON.stringify(o)));
|
|
837
|
+
const toRemove = curRows.filter((r) => !nextKeySet.has(JSON.stringify(r.options || {}))).map((r) => r.id);
|
|
838
|
+
return { toAdd, toRemove };
|
|
839
|
+
}
|
|
840
|
+
aggregateInventoryLocationsFromVariants() {
|
|
841
|
+
var _a;
|
|
842
|
+
const variants = ((_a = this.fields.variantInventory) === null || _a === void 0 ? void 0 : _a.selectedValues) || [];
|
|
843
|
+
const aggregateMap = {};
|
|
844
|
+
variants
|
|
845
|
+
.filter((v) => Array.isArray(v === null || v === void 0 ? void 0 : v.locations))
|
|
846
|
+
.forEach((v) => {
|
|
847
|
+
(v.locations || []).forEach((loc) => {
|
|
848
|
+
if (!loc || !loc.id || !loc.name)
|
|
849
|
+
return;
|
|
850
|
+
if (!aggregateMap[loc.id]) {
|
|
851
|
+
aggregateMap[loc.id] = {
|
|
852
|
+
id: loc.id,
|
|
853
|
+
name: loc.name,
|
|
854
|
+
availableAmount: Number(loc.availableAmount) || 0,
|
|
855
|
+
incomingAmount: Number(loc.incomingAmount) || 0,
|
|
856
|
+
};
|
|
857
|
+
}
|
|
858
|
+
else {
|
|
859
|
+
aggregateMap[loc.id].availableAmount += Number(loc.availableAmount) || 0;
|
|
860
|
+
aggregateMap[loc.id].incomingAmount += Number(loc.incomingAmount) || 0;
|
|
861
|
+
}
|
|
862
|
+
});
|
|
863
|
+
});
|
|
864
|
+
const aggregated = Object.values(aggregateMap);
|
|
865
|
+
this.fields.inventoryLocations.selectedValues = aggregated;
|
|
866
|
+
this.fields.inventoryLocations.valid = aggregated.length > 0;
|
|
867
|
+
}
|
|
572
868
|
fieldFactory(fieldType, fieldKey, fieldOptions) {
|
|
573
869
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
|
|
574
870
|
let options = fieldOptions || [];
|
|
@@ -859,6 +1155,9 @@ class ProductFormState extends FormState_1.default {
|
|
|
859
1155
|
if (fieldKey === 'inventoryLocations') {
|
|
860
1156
|
onChangeHandler = (val) => this.inventoryLocationsChangeHandler(val);
|
|
861
1157
|
}
|
|
1158
|
+
if (fieldKey === 'variantInventory') {
|
|
1159
|
+
onChangeHandler = (val) => this.variantInventoryChangeHandler(val);
|
|
1160
|
+
}
|
|
862
1161
|
return {
|
|
863
1162
|
options,
|
|
864
1163
|
hidden,
|
package/lib/models/Product.d.ts
CHANGED
|
@@ -11,6 +11,25 @@ export default class Product extends Base {
|
|
|
11
11
|
toObj(): CompleteProduct;
|
|
12
12
|
toProductInputObjForShopify(location?: string): any;
|
|
13
13
|
toProductInputObjForShopifyV2(locationId: string, weightUnit?: string): any[];
|
|
14
|
+
toProductInputObjForShopifyV3(locationId: string, weightUnit?: string): {
|
|
15
|
+
title: string;
|
|
16
|
+
status: string;
|
|
17
|
+
productOptions: {
|
|
18
|
+
name: string;
|
|
19
|
+
values: {
|
|
20
|
+
name: string;
|
|
21
|
+
}[];
|
|
22
|
+
}[];
|
|
23
|
+
descriptionHtml: string;
|
|
24
|
+
productType: string;
|
|
25
|
+
vendor: string;
|
|
26
|
+
tags: (string | null)[];
|
|
27
|
+
files: {
|
|
28
|
+
originalSource: string;
|
|
29
|
+
contentType: string;
|
|
30
|
+
}[];
|
|
31
|
+
variants: any[];
|
|
32
|
+
};
|
|
14
33
|
toObjForTextTranslation(): TranslatableAttributes;
|
|
15
34
|
toObjForTypesense(isCanonicalMerchant?: boolean): TypesenseProductObj;
|
|
16
35
|
buildUpdatedFieldsForSalesChannel(): {
|
package/lib/models/Product.js
CHANGED
|
@@ -29,6 +29,7 @@ class Product extends Base_1.default {
|
|
|
29
29
|
variantId: (props === null || props === void 0 ? void 0 : props.variantId) || '',
|
|
30
30
|
reservedBy: (props === null || props === void 0 ? void 0 : props.reservedBy) || [],
|
|
31
31
|
options: (props === null || props === void 0 ? void 0 : props.options) || {},
|
|
32
|
+
variantInventory: (props === null || props === void 0 ? void 0 : props.variantInventory) || [],
|
|
32
33
|
costPerItem: (props === null || props === void 0 ? void 0 : props.costPerItem) || '',
|
|
33
34
|
compareAtPrice: (props === null || props === void 0 ? void 0 : props.compareAtPrice) || '',
|
|
34
35
|
quantity: (props === null || props === void 0 ? void 0 : props.quantity) || 0,
|
|
@@ -289,6 +290,150 @@ class Product extends Base_1.default {
|
|
|
289
290
|
}
|
|
290
291
|
return [productInputObj];
|
|
291
292
|
}
|
|
293
|
+
toProductInputObjForShopifyV3(locationId, weightUnit) {
|
|
294
|
+
var _a;
|
|
295
|
+
const title = this.attributes.title || `Ribbn Product ${this.attributes.handle || this.filterAttributes.documentId}`;
|
|
296
|
+
const inInventoryStatuses = [
|
|
297
|
+
product_constants_1.PRODUCT_STATES.draft,
|
|
298
|
+
product_constants_1.PRODUCT_STATES.qualityControl,
|
|
299
|
+
product_constants_1.PRODUCT_STATES.pendingPublication,
|
|
300
|
+
product_constants_1.PRODUCT_STATES.listed,
|
|
301
|
+
product_constants_1.PRODUCT_STATES.availableInStore,
|
|
302
|
+
product_constants_1.PRODUCT_STATES.hold,
|
|
303
|
+
product_constants_1.PRODUCT_STATES.archived,
|
|
304
|
+
];
|
|
305
|
+
const baseVariantFields = () => ({
|
|
306
|
+
inventoryPolicy: 'DENY',
|
|
307
|
+
inventoryItem: {
|
|
308
|
+
cost: this.utilities.sanitizeNumber(this.attributes.costPerItem, 0),
|
|
309
|
+
tracked: true,
|
|
310
|
+
measurement: {
|
|
311
|
+
weight: {
|
|
312
|
+
weight: parseFloat(this.attributes.weight) || parseFloat('999'),
|
|
313
|
+
weightUnit: weightUnit || 'GRAMS',
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
sku: this.attributes.sku,
|
|
318
|
+
price: this.attributes.price || '0',
|
|
319
|
+
compareAtPrice: this.attributes.price || '0',
|
|
320
|
+
taxable: this.attributes.isTaxable === 'yes' ? true : false,
|
|
321
|
+
});
|
|
322
|
+
const passedTags = ((_a = this.filterAttributes.tags) === null || _a === void 0 ? void 0 : _a.length) ? this.filterAttributes.tags : [];
|
|
323
|
+
const tags = [
|
|
324
|
+
this.filterAttributes.documentId ? `ribbnId:${this.filterAttributes.documentId}` : null,
|
|
325
|
+
...passedTags,
|
|
326
|
+
].filter(Boolean);
|
|
327
|
+
const files = this.attributes.imageUrls
|
|
328
|
+
? this.attributes.imageUrls.map((image) => ({
|
|
329
|
+
originalSource: image.trim(),
|
|
330
|
+
contentType: 'IMAGE',
|
|
331
|
+
}))
|
|
332
|
+
: [];
|
|
333
|
+
const variantsFromInventory = Array.isArray(this.attributes.variantInventory)
|
|
334
|
+
? this.attributes.variantInventory
|
|
335
|
+
: [];
|
|
336
|
+
if (variantsFromInventory.length === 0) {
|
|
337
|
+
// Fallback: single-variant product (legacy behavior)
|
|
338
|
+
const variant = Object.assign(Object.assign({}, baseVariantFields()), { inventoryQuantities: [
|
|
339
|
+
{
|
|
340
|
+
locationId: `gid://shopify/Location/${locationId}`,
|
|
341
|
+
name: 'available',
|
|
342
|
+
quantity: 0,
|
|
343
|
+
},
|
|
344
|
+
], optionValues: [{ optionName: 'Variant', name: title }] });
|
|
345
|
+
if (inInventoryStatuses.indexOf(this.consignmentAttributes.status) !== -1) {
|
|
346
|
+
variant.inventoryQuantities[0].quantity = 1;
|
|
347
|
+
}
|
|
348
|
+
if (this.consignmentAttributes.salePrice &&
|
|
349
|
+
Boolean(this.timestampAttributes.clearanceTimestamp) &&
|
|
350
|
+
this.consignmentAttributes.isOnSale === 'yes') {
|
|
351
|
+
variant.price = this.consignmentAttributes.salePrice;
|
|
352
|
+
variant.compareAtPrice = this.attributes.price || variant.compareAtPrice;
|
|
353
|
+
}
|
|
354
|
+
return {
|
|
355
|
+
title,
|
|
356
|
+
status: 'DRAFT',
|
|
357
|
+
productOptions: [{ name: 'Variant', values: [{ name: title }] }],
|
|
358
|
+
descriptionHtml: this.attributes.description,
|
|
359
|
+
productType: this.filterAttributes.productType,
|
|
360
|
+
vendor: this.attributes.vendorId,
|
|
361
|
+
tags,
|
|
362
|
+
files,
|
|
363
|
+
variants: [variant],
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
// Multi-variant: derive axes and values from variantInventory
|
|
367
|
+
const axisOrder = [];
|
|
368
|
+
const axisValuesMap = {};
|
|
369
|
+
variantsFromInventory.forEach((v) => {
|
|
370
|
+
Object.keys(v.options || {}).forEach((axis) => {
|
|
371
|
+
if (!axisOrder.includes(axis))
|
|
372
|
+
axisOrder.push(axis);
|
|
373
|
+
if (!axisValuesMap[axis])
|
|
374
|
+
axisValuesMap[axis] = new Set();
|
|
375
|
+
const value = String(v.options[axis]);
|
|
376
|
+
if (value)
|
|
377
|
+
axisValuesMap[axis].add(value);
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
const limitedAxes = axisOrder.slice(0, 3);
|
|
381
|
+
const productOptions = limitedAxes.map((axis) => ({
|
|
382
|
+
name: axis,
|
|
383
|
+
values: Array.from(axisValuesMap[axis] || new Set()).map((name) => ({ name })),
|
|
384
|
+
}));
|
|
385
|
+
const variants = variantsFromInventory.map((v) => {
|
|
386
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
387
|
+
const optionValues = limitedAxes.map((axis) => ({
|
|
388
|
+
optionName: axis,
|
|
389
|
+
name: String(v.options[axis] || ''),
|
|
390
|
+
}));
|
|
391
|
+
const inventoryQuantities = Array.isArray(v.locations) && v.locations.length > 0
|
|
392
|
+
? [
|
|
393
|
+
{
|
|
394
|
+
locationId: `gid://shopify/Location/${locationId}`,
|
|
395
|
+
name: 'available',
|
|
396
|
+
quantity: (v.locations || []).reduce((acc, l) => acc + (Number(l === null || l === void 0 ? void 0 : l.availableAmount) || 0), 0),
|
|
397
|
+
},
|
|
398
|
+
]
|
|
399
|
+
: [
|
|
400
|
+
{
|
|
401
|
+
locationId: `gid://shopify/Location/${locationId}`,
|
|
402
|
+
name: 'available',
|
|
403
|
+
quantity: inInventoryStatuses.indexOf(this.consignmentAttributes.status) !== -1 ? 1 : 0,
|
|
404
|
+
},
|
|
405
|
+
];
|
|
406
|
+
const basePrice = ((_b = (_a = v.price) !== null && _a !== void 0 ? _a : this.attributes.price) !== null && _b !== void 0 ? _b : '0');
|
|
407
|
+
const variant = Object.assign(Object.assign({}, baseVariantFields()), { optionValues,
|
|
408
|
+
inventoryQuantities });
|
|
409
|
+
if (v.sku) {
|
|
410
|
+
variant.sku = v.sku;
|
|
411
|
+
}
|
|
412
|
+
if (v.taxable !== undefined) {
|
|
413
|
+
variant.taxable = v.taxable === 'yes';
|
|
414
|
+
}
|
|
415
|
+
variant.price = basePrice;
|
|
416
|
+
variant.compareAtPrice = ((_c = v.compareAtPrice) !== null && _c !== void 0 ? _c : basePrice);
|
|
417
|
+
const onSale = ((_d = v.isOnSale) !== null && _d !== void 0 ? _d : this.consignmentAttributes.isOnSale);
|
|
418
|
+
const salePrice = ((_e = v.salePrice) !== null && _e !== void 0 ? _e : this.consignmentAttributes.salePrice);
|
|
419
|
+
if (salePrice && Boolean(this.timestampAttributes.clearanceTimestamp) && onSale === 'yes') {
|
|
420
|
+
variant.price = salePrice;
|
|
421
|
+
variant.compareAtPrice = ((_g = (_f = v.compareAtPrice) !== null && _f !== void 0 ? _f : this.attributes.price) !== null && _g !== void 0 ? _g : basePrice);
|
|
422
|
+
}
|
|
423
|
+
return variant;
|
|
424
|
+
});
|
|
425
|
+
return {
|
|
426
|
+
title,
|
|
427
|
+
status: 'DRAFT',
|
|
428
|
+
productOptions,
|
|
429
|
+
descriptionHtml: this.attributes.description,
|
|
430
|
+
productType: this.filterAttributes.productType,
|
|
431
|
+
vendor: this.attributes.vendorId,
|
|
432
|
+
tags,
|
|
433
|
+
files,
|
|
434
|
+
variants,
|
|
435
|
+
};
|
|
436
|
+
}
|
|
292
437
|
toObjForTextTranslation() {
|
|
293
438
|
return {
|
|
294
439
|
description: this.attributes.description || this.FIELD_NOT_TRANSLATABLE_KEY,
|
|
@@ -30,7 +30,8 @@ type ProductAttributes = {
|
|
|
30
30
|
metaDataTitle?: string;
|
|
31
31
|
metaDataDescription?: string;
|
|
32
32
|
isTaxable?: string;
|
|
33
|
-
productClass?: 'UNIQUE' | 'MULTIVARIANT' | 'TEMPLATE' | string;
|
|
33
|
+
productClass?: 'UNIQUE' | 'MULTIVARIANT' | 'TEMPLATE' | 'SUPPLY' | 'DIGITAL' | string;
|
|
34
|
+
variantInventory?: VariantInventory[];
|
|
34
35
|
};
|
|
35
36
|
type ProductFilterAttributes = {
|
|
36
37
|
documentId: string;
|
|
@@ -151,6 +152,18 @@ type MaterialComposition = {
|
|
|
151
152
|
type EditorAuthorization = {
|
|
152
153
|
[key: string]: string[];
|
|
153
154
|
};
|
|
155
|
+
type VariantOptions = Record<string, string>;
|
|
156
|
+
type VariantInventory = {
|
|
157
|
+
id: string;
|
|
158
|
+
options: VariantOptions;
|
|
159
|
+
locations?: InventoryLocation[];
|
|
160
|
+
price?: string;
|
|
161
|
+
compareAtPrice?: string;
|
|
162
|
+
salePrice?: string;
|
|
163
|
+
isOnSale?: 'yes' | 'no';
|
|
164
|
+
sku?: string;
|
|
165
|
+
taxable?: 'yes' | 'no';
|
|
166
|
+
};
|
|
154
167
|
type ProductSellStatusKeys = 'SELL_REQUEST_REVIEW' | 'REJECTED' | 'HOLD' | 'ACCEPTED' | 'DROP_OFF_AT_REROBE' | 'SHIP_TO_REROBE' | 'AT_HOME_PICK_UP' | 'QUALITY_CONTROL' | 'LISTED' | 'SOLD' | 'RETURNED' | 'SOLD_SELLER_TO_BE_PAID' | 'SOLD_SELLER_PAID' | 'HIDDEN' | 'BOOKED' | 'OPEN';
|
|
155
168
|
type ProductPublishKeys = 'USER_PUBLISHED' | 'MERCHANT_PUBLISHED';
|
|
156
169
|
type ShopifyProduct = ProductAttributes & ProductFilterAttributes;
|
|
@@ -186,6 +199,7 @@ type ProductAttributesFormFields = {
|
|
|
186
199
|
handle: TextInputFormField<string>;
|
|
187
200
|
isTaxable: SingleSelectFormField<string>;
|
|
188
201
|
productClass: SingleSelectFormField<string>;
|
|
202
|
+
variantInventory: MultiSelectFormField<VariantInventory>;
|
|
189
203
|
};
|
|
190
204
|
type ProductFilterAttributesFormFields = {
|
|
191
205
|
brand: SingleSelectFormField<string>;
|