@ordergroove/offers 2.37.0 → 2.37.1-alpha-PR-839-2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ordergroove/offers",
3
- "version": "2.37.0",
3
+ "version": "2.37.1-alpha-PR-839-2.3+c8979267",
4
4
  "description": "offer state component",
5
5
  "author": "Eugenio Lattanzio <eugenio63@gmail.com>",
6
6
  "homepage": "https://github.com/ordergroove/plush-toys#readme",
@@ -48,5 +48,5 @@
48
48
  "@ordergroove/offers-templates": "^0.9.6",
49
49
  "@types/lodash.memoize": "^4.1.9"
50
50
  },
51
- "gitHead": "e702e182ecc53ced69c632d6269bb8f98c778b42"
51
+ "gitHead": "c89792671c191119f07054b3ad14f902866a9f26"
52
52
  }
@@ -47,23 +47,44 @@ describe('autoshipEligible', () => {
47
47
  expect(actual).toEqual({ 'yum key 1': null, 'yum key 2': null });
48
48
  });
49
49
 
50
+ const sellingPlans = {
51
+ default: 1,
52
+ prepaid1: 2,
53
+ prepaid2: 3,
54
+ psfl: 4
55
+ };
56
+ function getSetupProductPayload({ productSellingPlans, variants = {}, additionalSellingPlanGroups = {} } = {}) {
57
+ const sellingPlanGroups = {
58
+ 'Subscribe and Save': [sellingPlans.default],
59
+ ...additionalSellingPlanGroups
60
+ };
61
+ return {
62
+ product: {
63
+ id: 'yum product id',
64
+ selling_plan_allocations: productSellingPlans?.map(id => ({ selling_plan_id: id })),
65
+ variants: Object.entries(variants).map(([productId, sellingPlanIds]) => ({
66
+ id: productId,
67
+ selling_plan_allocations: sellingPlanIds.map(id => ({ selling_plan_id: id }))
68
+ })),
69
+ selling_plan_groups: Object.entries(sellingPlanGroups).map(([sellingPlanName, sellingPlanIds]) => ({
70
+ name: sellingPlanName,
71
+ selling_plans: sellingPlanIds.map(id => ({ id }))
72
+ }))
73
+ }
74
+ };
75
+ }
76
+
50
77
  it('should return true for each product and variant given action SETUP_PRODUCT and products have selling plan allocations', () => {
51
78
  const actual = autoshipEligible(
52
79
  {},
53
80
  {
54
81
  type: constants.SETUP_PRODUCT,
55
- payload: {
56
- product: {
57
- id: 'yum product id',
58
- selling_plan_allocations: [{ 'yum key': 'yum value' }],
59
- variants: [
60
- {
61
- id: 'yum variant id',
62
- selling_plan_allocations: [{ 'yum key': 'yum value' }]
63
- }
64
- ]
82
+ payload: getSetupProductPayload({
83
+ productSellingPlans: [sellingPlans.default],
84
+ variants: {
85
+ 'yum variant id': [sellingPlans.default]
65
86
  }
66
- }
87
+ })
67
88
  }
68
89
  );
69
90
 
@@ -75,18 +96,11 @@ describe('autoshipEligible', () => {
75
96
  {},
76
97
  {
77
98
  type: constants.SETUP_PRODUCT,
78
- payload: {
79
- product: {
80
- id: 'yum product id',
81
- selling_plan_allocations: [],
82
- variants: [
83
- {
84
- id: 'yum variant id',
85
- selling_plan_allocations: []
86
- }
87
- ]
99
+ payload: getSetupProductPayload({
100
+ variants: {
101
+ 'yum variant id': []
88
102
  }
89
- }
103
+ })
90
104
  }
91
105
  );
92
106
 
@@ -110,51 +124,17 @@ describe('autoshipEligible', () => {
110
124
  {},
111
125
  {
112
126
  type: constants.SETUP_PRODUCT,
113
- payload: {
114
- product: {
115
- id: 'yum product id',
116
- selling_plan_allocations: [],
117
- variants: [
118
- {
119
- id: 'single-non-prepaid',
120
- selling_plan_allocations: [{ selling_plan_id: 1 }]
121
- },
122
- {
123
- id: 'prepaid-and-non-prepaid',
124
- selling_plan_allocations: [{ selling_plan_id: 1 }, { selling_plan_id: 2 }]
125
- },
126
- {
127
- id: 'single-prepaid',
128
- selling_plan_allocations: [{ selling_plan_id: 2 }]
129
- },
130
- {
131
- id: 'multiple-prepaid',
132
- selling_plan_allocations: [{ selling_plan_id: 2 }, { selling_plan_id: 3 }]
133
- }
134
- ],
135
- selling_plan_groups: [
136
- {
137
- name: 'Subscribe and Save',
138
- selling_plans: [
139
- {
140
- id: 1
141
- }
142
- ]
143
- },
144
- {
145
- name: 'Prepaid-yum variant id',
146
- selling_plans: [
147
- {
148
- id: 2
149
- },
150
- {
151
- id: 3
152
- }
153
- ]
154
- }
155
- ]
127
+ payload: getSetupProductPayload({
128
+ variants: {
129
+ 'single-non-prepaid': [sellingPlans.default],
130
+ 'prepaid-and-non-prepaid': [sellingPlans.default, sellingPlans.prepaid1],
131
+ 'single-prepaid': [sellingPlans.prepaid1],
132
+ 'multiple-prepaid': [sellingPlans.prepaid1, sellingPlans.prepaid2]
133
+ },
134
+ additionalSellingPlanGroups: {
135
+ 'Prepaid-yum variant id': [sellingPlans.prepaid1, sellingPlans.prepaid2]
156
136
  }
157
- }
137
+ })
158
138
  }
159
139
  );
160
140
 
@@ -166,6 +146,32 @@ describe('autoshipEligible', () => {
166
146
  'multiple-prepaid': false
167
147
  });
168
148
  });
149
+
150
+ it('should return false if there are only PSFL selling plans', () => {
151
+ const actual = autoshipEligible(
152
+ {},
153
+ {
154
+ type: constants.SETUP_PRODUCT,
155
+ payload: getSetupProductPayload({
156
+ variants: {
157
+ 'single-non-psfl': [sellingPlans.default],
158
+ 'sub-eligible-psfl': [sellingPlans.default, sellingPlans.psfl],
159
+ 'not-sub-eligible-psfl': [sellingPlans.psfl]
160
+ },
161
+ additionalSellingPlanGroups: {
162
+ og_psfl_2m: [sellingPlans.psfl]
163
+ }
164
+ })
165
+ }
166
+ );
167
+
168
+ expect(actual).toEqual({
169
+ 'yum product id': false,
170
+ 'single-non-psfl': true,
171
+ 'sub-eligible-psfl': true,
172
+ 'not-sub-eligible-psfl': false
173
+ });
174
+ });
169
175
  });
170
176
 
171
177
  describe('config', () => {
@@ -23,6 +23,7 @@ import baseReducer, {
23
23
  templates,
24
24
  prepaidShipmentsSelected
25
25
  } from '../core/reducer';
26
+
26
27
  import {
27
28
  getFirstSellingPlan,
28
29
  hasShopifySellingPlans,
@@ -131,10 +132,11 @@ const getOGSellingPlanGroup = product => {
131
132
  isProductSpecificFrequencySellingPlanGroup
132
133
  );
133
134
 
134
- return (
135
- productSpecificFrequencySellingPlanGroup ||
136
- product?.selling_plan_groups.find(group => group.name === DEFAULT_PAY_AS_YOU_GO_GROUP_NAME)
137
- );
135
+ return productSpecificFrequencySellingPlanGroup || getDefaultSubscriptionSellingPlanGroup(product);
136
+ };
137
+
138
+ const getDefaultSubscriptionSellingPlanGroup = product => {
139
+ return product?.selling_plan_groups.find(group => group.name === DEFAULT_PAY_AS_YOU_GO_GROUP_NAME);
138
140
  };
139
141
 
140
142
  const isProductSpecificFrequencySellingPlanGroup = group => group.name.startsWith('og_psfl');
@@ -151,28 +153,6 @@ const reduceProductCartLine = (acc, cur) => {
151
153
  return { ...acc, [cur.key]: acc[productId] || null };
152
154
  };
153
155
 
154
- const isPrepaidSellingPlanGroup = sellingPlanGroup => sellingPlanGroup.name.toUpperCase().includes('PREPAID');
155
-
156
- const filterNonPrepaidSellingPlans = (sellingPlanAllocations, sellingPlanGroups) => {
157
- if (!sellingPlanAllocations || sellingPlanAllocations.length === 0) {
158
- return [];
159
- }
160
- if (!sellingPlanGroups || sellingPlanGroups.length === 0) {
161
- return sellingPlanAllocations;
162
- }
163
-
164
- const nonPrepaidSellingPlansIds = sellingPlanGroups.reduce((allIds, group) => {
165
- if (!isPrepaidSellingPlanGroup(group)) {
166
- allIds.push(...group.selling_plans.map(sellingPlan => sellingPlan.id));
167
- }
168
- return allIds;
169
- }, []);
170
-
171
- return sellingPlanAllocations.filter(sellingPlanAllocation =>
172
- nonPrepaidSellingPlansIds.includes(sellingPlanAllocation.selling_plan_id)
173
- );
174
- };
175
-
176
156
  export const autoshipEligible = (state = {}, action) => {
177
157
  if (constants.RECEIVE_PRODUCT_PLANS === action.type) {
178
158
  return Object.entries(action.payload).reduce(productTrue, state);
@@ -185,15 +165,23 @@ export const autoshipEligible = (state = {}, action) => {
185
165
  const {
186
166
  payload: { product }
187
167
  } = action;
168
+ const defaultSellingPlanGroup = getDefaultSubscriptionSellingPlanGroup(product);
169
+ const sellingPlanIdsInDefaultGroup = new Set(
170
+ defaultSellingPlanGroup?.selling_plans.map(sellingPlan => sellingPlan.id) ?? []
171
+ );
188
172
  return [product, ...(product?.variants || [])]?.reduce((acc, cur) => {
189
- const selling_plans_without_prepaid = filterNonPrepaidSellingPlans(
190
- cur?.selling_plan_allocations,
191
- product?.selling_plan_groups
192
- );
173
+ const productSellingPlansFromDefaultGroup =
174
+ cur?.selling_plan_allocations?.filter(sellingPlan =>
175
+ sellingPlanIdsInDefaultGroup.has(sellingPlan.selling_plan_id)
176
+ ) ?? [];
177
+
178
+ // a product is autoship eligible if it has plans from the default "Subscribe and Save" selling plan group
179
+ // the presence of other selling plans (prepaid, product-specific frequencies) does not mean it is autoship eligible
180
+ const isAutoshipEligible = productSellingPlansFromDefaultGroup.length > 0;
193
181
 
194
182
  return {
195
- ...overrideLineKey(acc, cur.id, selling_plans_without_prepaid?.length > 0),
196
- [cur.id]: selling_plans_without_prepaid?.length > 0
183
+ ...overrideLineKey(acc, cur.id, isAutoshipEligible),
184
+ [cur.id]: isAutoshipEligible
197
185
  };
198
186
  }, state);
199
187
  }