rerobe-js-orm 4.5.2 → 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.
@@ -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';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rerobe-js-orm",
3
- "version": "4.5.2",
3
+ "version": "4.5.3",
4
4
  "description": "ReRobe's Javascript ORM Framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",