rerobe-js-orm 4.5.1 → 4.5.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/lib/factories/Order/OrderFromShopifyWebhook.d.ts +1 -0
- package/lib/factories/Order/OrderFromShopifyWebhook.js +107 -0
- package/lib/form-states/Product/ProductFormState.d.ts +22 -0
- package/lib/form-states/Product/ProductFormState.js +122 -0
- package/lib/types/rerobe-product-types.d.ts +3 -0
- package/package.json +1 -1
|
@@ -277,5 +277,112 @@ class OrderFromShopifyWebhook extends OrderFactory_1.default {
|
|
|
277
277
|
shippingLine, state: Order_1.default.ORDER_STATES.completed, shippingType: orderHelpers.getShippingTypeFromShopifyObj(shipping_lines), paymentType: orderHelpers.getPaymentTypeUsingTags(tags), salesChannel: orderHelpers.getSalesChannelUsingTags(tags), tags: tags ? tags.split(', ') : [] }));
|
|
278
278
|
return rerobeOrder.toObj();
|
|
279
279
|
}
|
|
280
|
+
// Aligned with Shopify REST order payload that includes current_* fields
|
|
281
|
+
createOrderV2(order) {
|
|
282
|
+
const { id, name, financial_status, fulfillment_status, cancel_reason, created_at, processed_at, updated_at, currency, contact_email, email, shipping_address, line_items = [], discount_applications = [], shipping_lines = [], tax_lines = [], tags = '', cancelled_at, closed_at, order_number, current_subtotal_price_set, current_total_price_set, current_total_tax_set, current_total_discounts_set, current_shipping_price_set, } = order || {};
|
|
283
|
+
const moneyFromSet = (setObj) => {
|
|
284
|
+
const shop = setObj === null || setObj === void 0 ? void 0 : setObj.shop_money;
|
|
285
|
+
return shop
|
|
286
|
+
? { amount: shop.amount, currencyCode: shop.currency_code }
|
|
287
|
+
: { amount: 0, currencyCode: currency || '' };
|
|
288
|
+
};
|
|
289
|
+
const subtotalPrice = moneyFromSet(current_subtotal_price_set);
|
|
290
|
+
const totalPrice = moneyFromSet(current_total_price_set);
|
|
291
|
+
const totalTax = moneyFromSet(current_total_tax_set);
|
|
292
|
+
const totalShippingPrice = moneyFromSet(current_shipping_price_set);
|
|
293
|
+
const totalDiscount = current_total_discounts_set
|
|
294
|
+
? moneyFromSet(current_total_discounts_set)
|
|
295
|
+
: { amount: 0, currencyCode: currency || '' };
|
|
296
|
+
const shippingAddress = shipping_address
|
|
297
|
+
? {
|
|
298
|
+
address1: shipping_address.address1,
|
|
299
|
+
address2: shipping_address.address2,
|
|
300
|
+
city: shipping_address.city,
|
|
301
|
+
country: shipping_address.country,
|
|
302
|
+
countryCode: shipping_address.country_code,
|
|
303
|
+
province: shipping_address.province,
|
|
304
|
+
zip: shipping_address.zip,
|
|
305
|
+
}
|
|
306
|
+
: null;
|
|
307
|
+
const lineItems = line_items.map((item) => ({
|
|
308
|
+
title: item.title,
|
|
309
|
+
quantity: item.quantity,
|
|
310
|
+
variant: {
|
|
311
|
+
id: item.variant_id ? `gid://shopify/ProductVariant/${item.variant_id}` : '',
|
|
312
|
+
title: item.variant_title || '',
|
|
313
|
+
image: { id: '', originalSrc: '' },
|
|
314
|
+
},
|
|
315
|
+
shopifyProductId: item.product_id ? `gid://shopify/Product/${item.product_id}` : null,
|
|
316
|
+
originalTotalPrice: moneyFromSet(item.price_set),
|
|
317
|
+
discountedTotalPrice: moneyFromSet(item.total_discount_set),
|
|
318
|
+
}));
|
|
319
|
+
const discountApplications = discount_applications.map((item) => ({
|
|
320
|
+
allocationMethod: item.allocation_method ? String(item.allocation_method).toUpperCase() : '',
|
|
321
|
+
targetSelection: item.target_selection ? String(item.target_selection).toUpperCase() : '',
|
|
322
|
+
targetType: item.target_type ? String(item.target_type).toUpperCase() : '',
|
|
323
|
+
value: { amount: item.value },
|
|
324
|
+
}));
|
|
325
|
+
const taxLinesV2 = tax_lines.map((item) => ({
|
|
326
|
+
rate: item.rate,
|
|
327
|
+
title: item.title,
|
|
328
|
+
priceSet: { amount: item.price, currencyCode: currency || '' },
|
|
329
|
+
}));
|
|
330
|
+
const shippingLine = shipping_lines && shipping_lines.length
|
|
331
|
+
? {
|
|
332
|
+
id: '',
|
|
333
|
+
title: shipping_lines[0].title,
|
|
334
|
+
source: shipping_lines[0].source,
|
|
335
|
+
discountedPrice: moneyFromSet(shipping_lines[0].discounted_price_set),
|
|
336
|
+
originalPrice: moneyFromSet(shipping_lines[0].price_set),
|
|
337
|
+
taxLines: (shipping_lines[0].tax_lines || []).map((t) => ({
|
|
338
|
+
rate: t.rate,
|
|
339
|
+
title: t.title,
|
|
340
|
+
priceSet: { amount: t.price, currencyCode: currency || '' },
|
|
341
|
+
})),
|
|
342
|
+
}
|
|
343
|
+
: {
|
|
344
|
+
id: '',
|
|
345
|
+
title: '',
|
|
346
|
+
taxLines: [],
|
|
347
|
+
discountAllocations: [],
|
|
348
|
+
discountedPrice: { amount: 0 },
|
|
349
|
+
originalPrice: { amount: 0 },
|
|
350
|
+
source: '',
|
|
351
|
+
};
|
|
352
|
+
// @ts-ignore
|
|
353
|
+
const fulfillmentStatus = !fulfillment_status ? '' : fulfillmentStatusRestMapping[fulfillment_status];
|
|
354
|
+
const rerobeOrder = new Order_1.default({
|
|
355
|
+
id: orderHelpers.getOrderIdFromShopifyObj(order),
|
|
356
|
+
shopifyId: `gid://shopify/Order/${id}`,
|
|
357
|
+
shopifyOrderNumber: name ? Number(String(name).replace('#', '')) : order_number || 0,
|
|
358
|
+
name: name || '',
|
|
359
|
+
currencyCode: currency || '',
|
|
360
|
+
email: contact_email || email || '',
|
|
361
|
+
financialStatus: financial_status ? String(financial_status).toUpperCase() : '',
|
|
362
|
+
fulfillmentStatus,
|
|
363
|
+
cancelReason: cancel_reason ? String(cancel_reason).toUpperCase() : '',
|
|
364
|
+
createdAt: created_at,
|
|
365
|
+
processedAt: processed_at,
|
|
366
|
+
updatedAt: updated_at,
|
|
367
|
+
canceledAt: cancelled_at,
|
|
368
|
+
closedAt: closed_at,
|
|
369
|
+
orderNumber: order_number || 0,
|
|
370
|
+
shippingAddress,
|
|
371
|
+
lineItems,
|
|
372
|
+
subtotalPrice,
|
|
373
|
+
totalPrice,
|
|
374
|
+
totalTax,
|
|
375
|
+
totalShippingPrice,
|
|
376
|
+
totalDiscount,
|
|
377
|
+
discountApplications,
|
|
378
|
+
shippingLine,
|
|
379
|
+
tags: tags ? String(tags).split(', ').filter(Boolean) : [],
|
|
380
|
+
state: Order_1.default.ORDER_STATES.completed,
|
|
381
|
+
shippingType: orderHelpers.getShippingTypeFromShopifyObj(shipping_lines),
|
|
382
|
+
paymentType: orderHelpers.getPaymentTypeUsingTags(tags),
|
|
383
|
+
salesChannel: orderHelpers.getSalesChannelUsingTags(tags),
|
|
384
|
+
});
|
|
385
|
+
return rerobeOrder.toObj();
|
|
386
|
+
}
|
|
280
387
|
}
|
|
281
388
|
exports.default = OrderFromShopifyWebhook;
|
|
@@ -95,6 +95,28 @@ export default class ProductFormState extends FormState {
|
|
|
95
95
|
}[];
|
|
96
96
|
toRemove: string[];
|
|
97
97
|
};
|
|
98
|
+
getVariantIds(): string[];
|
|
99
|
+
getVariantRows(): VariantInventory[];
|
|
100
|
+
bulkEditVariantFields(patch: Partial<VariantInventory>, selector?: {
|
|
101
|
+
ids?: string[];
|
|
102
|
+
predicate?: (v: VariantInventory) => boolean;
|
|
103
|
+
}): void;
|
|
104
|
+
bulkEditVariantLocationAmount(location: {
|
|
105
|
+
id: string;
|
|
106
|
+
name: string;
|
|
107
|
+
}, amount: number, options?: {
|
|
108
|
+
ids?: string[];
|
|
109
|
+
predicate?: (v: VariantInventory) => boolean;
|
|
110
|
+
mode?: 'set' | 'increment';
|
|
111
|
+
field?: 'availableAmount' | 'incomingAmount';
|
|
112
|
+
}): void;
|
|
113
|
+
bulkEditVariantSkus(updates: {
|
|
114
|
+
id?: string;
|
|
115
|
+
options?: {
|
|
116
|
+
[k: string]: string;
|
|
117
|
+
};
|
|
118
|
+
sku: string;
|
|
119
|
+
}[]): void;
|
|
98
120
|
private aggregateInventoryLocationsFromVariants;
|
|
99
121
|
private fieldFactory;
|
|
100
122
|
}
|
|
@@ -837,6 +837,128 @@ class ProductFormState extends FormState_1.default {
|
|
|
837
837
|
const toRemove = curRows.filter((r) => !nextKeySet.has(JSON.stringify(r.options || {}))).map((r) => r.id);
|
|
838
838
|
return { toAdd, toRemove };
|
|
839
839
|
}
|
|
840
|
+
// UI: expose variant ids and rows
|
|
841
|
+
getVariantIds() {
|
|
842
|
+
return this.fields.variantInventory.selectedValues.map((v) => v.id);
|
|
843
|
+
}
|
|
844
|
+
getVariantRows() {
|
|
845
|
+
return this.fields.variantInventory.selectedValues.slice();
|
|
846
|
+
}
|
|
847
|
+
// Bulk edit user-mutable variant fields (excludes inventory locations and options/id)
|
|
848
|
+
bulkEditVariantFields(patch, selector) {
|
|
849
|
+
const allowedKeys = [
|
|
850
|
+
'price',
|
|
851
|
+
'compareAtPrice',
|
|
852
|
+
'salePrice',
|
|
853
|
+
'isOnSale',
|
|
854
|
+
'sku',
|
|
855
|
+
'taxable',
|
|
856
|
+
'costPerItem',
|
|
857
|
+
'continueSellingWhenOutOfStock',
|
|
858
|
+
];
|
|
859
|
+
const rows = this.fields.variantInventory.selectedValues;
|
|
860
|
+
const shouldEdit = (v) => {
|
|
861
|
+
if ((selector === null || selector === void 0 ? void 0 : selector.ids) && selector.ids.length)
|
|
862
|
+
return selector.ids.includes(v.id);
|
|
863
|
+
if (selector === null || selector === void 0 ? void 0 : selector.predicate)
|
|
864
|
+
return !!selector.predicate(v);
|
|
865
|
+
return true; // default: all
|
|
866
|
+
};
|
|
867
|
+
rows.forEach((v, idx) => {
|
|
868
|
+
if (!shouldEdit(v))
|
|
869
|
+
return;
|
|
870
|
+
const next = Object.assign({}, v);
|
|
871
|
+
allowedKeys.forEach((k) => {
|
|
872
|
+
if (patch[k] !== undefined)
|
|
873
|
+
next[k] = patch[k];
|
|
874
|
+
});
|
|
875
|
+
this.fields.variantInventory.selectedValues[idx] = next;
|
|
876
|
+
});
|
|
877
|
+
// Recompute aggregates (locations unchanged, so totals stay the same but we keep logic consistent)
|
|
878
|
+
const totalQty = this.fields.variantInventory.selectedValues.reduce((acc, cur) => {
|
|
879
|
+
const locs = cur.locations;
|
|
880
|
+
const sum = Array.isArray(locs) ? locs.reduce((a, l) => a + (Number(l === null || l === void 0 ? void 0 : l.availableAmount) || 0), 0) : 0;
|
|
881
|
+
return acc + sum;
|
|
882
|
+
}, 0);
|
|
883
|
+
this.fields.quantity.inputValue = totalQty;
|
|
884
|
+
this.fields.availableForSale.selectedValue = totalQty > 0;
|
|
885
|
+
this.aggregateInventoryLocationsFromVariants();
|
|
886
|
+
}
|
|
887
|
+
// Bulk edit inventory amount for a specific location across selected variants
|
|
888
|
+
// mode: 'set' (default) to overwrite, 'increment' to add delta
|
|
889
|
+
bulkEditVariantLocationAmount(location, amount, options) {
|
|
890
|
+
const rows = this.fields.variantInventory.selectedValues;
|
|
891
|
+
const shouldEdit = (v) => {
|
|
892
|
+
if ((options === null || options === void 0 ? void 0 : options.ids) && options.ids.length)
|
|
893
|
+
return options.ids.includes(v.id);
|
|
894
|
+
if (options === null || options === void 0 ? void 0 : options.predicate)
|
|
895
|
+
return !!options.predicate(v);
|
|
896
|
+
return true; // default all
|
|
897
|
+
};
|
|
898
|
+
const mode = (options === null || options === void 0 ? void 0 : options.mode) || 'set';
|
|
899
|
+
const targetField = (options === null || options === void 0 ? void 0 : options.field) || 'availableAmount';
|
|
900
|
+
rows.forEach((v, idx) => {
|
|
901
|
+
if (!shouldEdit(v))
|
|
902
|
+
return;
|
|
903
|
+
const locs = (v.locations || []);
|
|
904
|
+
const existingIdx = locs.findIndex((l) => l && l.id === location.id);
|
|
905
|
+
if (existingIdx !== -1) {
|
|
906
|
+
const current = locs[existingIdx];
|
|
907
|
+
const nextVal = mode === 'increment' ? Number(current[targetField] || 0) + Number(amount) : Number(amount);
|
|
908
|
+
const updated = Object.assign(Object.assign({}, current), { [targetField]: nextVal });
|
|
909
|
+
locs.splice(existingIdx, 1, updated);
|
|
910
|
+
}
|
|
911
|
+
else {
|
|
912
|
+
const base = {
|
|
913
|
+
id: location.id,
|
|
914
|
+
name: location.name,
|
|
915
|
+
availableAmount: 0,
|
|
916
|
+
incomingAmount: 0,
|
|
917
|
+
};
|
|
918
|
+
base[targetField] = mode === 'increment' ? Number(amount) : Number(amount);
|
|
919
|
+
locs.push(base);
|
|
920
|
+
}
|
|
921
|
+
this.fields.variantInventory.selectedValues[idx] = Object.assign(Object.assign({}, v), { locations: locs });
|
|
922
|
+
});
|
|
923
|
+
// Recompute aggregates
|
|
924
|
+
const totalQty = this.fields.variantInventory.selectedValues.reduce((acc, cur) => {
|
|
925
|
+
const locs = cur.locations;
|
|
926
|
+
const sum = Array.isArray(locs) ? locs.reduce((a, l) => a + (Number(l === null || l === void 0 ? void 0 : l.availableAmount) || 0), 0) : 0;
|
|
927
|
+
return acc + sum;
|
|
928
|
+
}, 0);
|
|
929
|
+
this.fields.quantity.inputValue = totalQty;
|
|
930
|
+
this.fields.availableForSale.selectedValue = totalQty > 0;
|
|
931
|
+
this.aggregateInventoryLocationsFromVariants();
|
|
932
|
+
}
|
|
933
|
+
// Bulk edit SKUs per selected variant individually
|
|
934
|
+
bulkEditVariantSkus(updates) {
|
|
935
|
+
if (!Array.isArray(updates) || !updates.length)
|
|
936
|
+
return;
|
|
937
|
+
const rows = this.fields.variantInventory.selectedValues;
|
|
938
|
+
const indexById = {};
|
|
939
|
+
rows.forEach((v, i) => (indexById[v.id] = i));
|
|
940
|
+
updates.forEach((u) => {
|
|
941
|
+
let idx = -1;
|
|
942
|
+
if (u.id && indexById[u.id] !== undefined) {
|
|
943
|
+
idx = indexById[u.id];
|
|
944
|
+
}
|
|
945
|
+
else if (u.options) {
|
|
946
|
+
idx = rows.findIndex((v) => this.isSameOptions(v.options, u.options));
|
|
947
|
+
}
|
|
948
|
+
if (idx !== -1) {
|
|
949
|
+
const cur = rows[idx] || {};
|
|
950
|
+
this.fields.variantInventory.selectedValues[idx] = Object.assign(Object.assign({}, cur), { sku: u.sku });
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
// Aggregates unchanged but keep consistent calc
|
|
954
|
+
const totalQty = this.fields.variantInventory.selectedValues.reduce((acc, cur) => {
|
|
955
|
+
const locs = cur.locations;
|
|
956
|
+
const sum = Array.isArray(locs) ? locs.reduce((a, l) => a + (Number(l === null || l === void 0 ? void 0 : l.availableAmount) || 0), 0) : 0;
|
|
957
|
+
return acc + sum;
|
|
958
|
+
}, 0);
|
|
959
|
+
this.fields.quantity.inputValue = totalQty;
|
|
960
|
+
this.fields.availableForSale.selectedValue = totalQty > 0;
|
|
961
|
+
}
|
|
840
962
|
aggregateInventoryLocationsFromVariants() {
|
|
841
963
|
var _a;
|
|
842
964
|
const variants = ((_a = this.fields.variantInventory) === null || _a === void 0 ? void 0 : _a.selectedValues) || [];
|
|
@@ -163,6 +163,9 @@ type VariantInventory = {
|
|
|
163
163
|
isOnSale?: 'yes' | 'no';
|
|
164
164
|
sku?: string;
|
|
165
165
|
taxable?: 'yes' | 'no';
|
|
166
|
+
shopifyId?: string;
|
|
167
|
+
costPerItem?: string;
|
|
168
|
+
continueSellingWhenOutOfStock?: boolean;
|
|
166
169
|
};
|
|
167
170
|
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';
|
|
168
171
|
type ProductPublishKeys = 'USER_PUBLISHED' | 'MERCHANT_PUBLISHED';
|