@ordergroove/offers 2.47.2-alpha-PR-1356-3.33 → 2.47.2
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/CHANGELOG.md +11 -0
- package/dist/bundle-report.html +23 -23
- package/dist/offers.js +73 -73
- package/dist/offers.js.map +3 -3
- package/package.json +2 -2
- package/src/components/IncentiveText.js +3 -0
- package/src/components/PrepaidStatus.js +1 -2
- package/src/components/__tests__/IncentiveText.spec.js +36 -0
- package/src/core/__tests__/reducer.spec.js +43 -0
- package/src/core/actions.js +3 -9
- package/src/core/constants.js +0 -4
- package/src/core/descriptors.js +1 -2
- package/src/core/reducer.ts +7 -1
- package/src/core/selectors.ts +0 -6
- package/src/core/types/reducer.ts +4 -5
- package/src/shopify/__tests__/reducers/optedin.spec.js +0 -347
- package/src/shopify/reducers/config.ts +5 -12
- package/src/shopify/shopifyReducer.ts +44 -99
- package/src/shopify/utils.ts +0 -5
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
sellingPlansToFrequencies,
|
|
14
14
|
getPrepaidShipments
|
|
15
15
|
} from '../utils';
|
|
16
|
-
import {
|
|
16
|
+
import { ShopifySellingPlanGroupsEntity, ShopifyVariantsEntity } from '../types/shopify';
|
|
17
17
|
|
|
18
18
|
const config = (
|
|
19
19
|
state: ConfigState = {
|
|
@@ -48,11 +48,11 @@ const config = (
|
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
// prepaid selling plans
|
|
51
|
-
const
|
|
52
|
-
if (
|
|
51
|
+
const prepaidSellingPlanGroups = product?.selling_plan_groups.filter(group => /^Prepaid-.*/.test(group.name));
|
|
52
|
+
if (prepaidSellingPlanGroups.length) {
|
|
53
53
|
configToAdd = {
|
|
54
54
|
...configToAdd,
|
|
55
|
-
prepaidSellingPlans: { ...state.prepaidSellingPlans, ...
|
|
55
|
+
prepaidSellingPlans: { ...state.prepaidSellingPlans, ...getPrepaidSellingPlans(prepaidSellingPlanGroups) }
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
return {
|
|
@@ -177,14 +177,7 @@ function getUpdatedDefaultFrequency(
|
|
|
177
177
|
);
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
|
|
181
|
-
product: ShopifyProductEntity
|
|
182
|
-
): Record<string, { numberShipments: number; sellingPlan: string }[]> {
|
|
183
|
-
const prepaidSellingPlanGroups = product?.selling_plan_groups.filter(group => /^Prepaid-.*/.test(group.name));
|
|
184
|
-
if (!prepaidSellingPlanGroups.length) {
|
|
185
|
-
return {};
|
|
186
|
-
}
|
|
187
|
-
|
|
180
|
+
function getPrepaidSellingPlans(prepaidSellingPlanGroups) {
|
|
188
181
|
return prepaidSellingPlanGroups.reduce((acc, cur) => {
|
|
189
182
|
const variant = cur.name.split('-')[1];
|
|
190
183
|
|
|
@@ -42,18 +42,16 @@ import type {
|
|
|
42
42
|
} from '../core/types/reducer';
|
|
43
43
|
|
|
44
44
|
import { sellingPlanAllocationsReducer, getSellingPlans } from './reducers/productPlans';
|
|
45
|
-
import config
|
|
45
|
+
import config from './reducers/config';
|
|
46
46
|
import { experimentsReducer } from '../core/experiments';
|
|
47
47
|
import {
|
|
48
48
|
getPayAsYouGoSellingPlanGroup,
|
|
49
49
|
getPayAsYouGoSellingPlanGroups,
|
|
50
50
|
sellingPlansToEveryPeriod,
|
|
51
51
|
sellingPlansToFrequencies,
|
|
52
|
-
getPrepaidShipments
|
|
53
|
-
getDefaultPrepaidOption
|
|
52
|
+
getPrepaidShipments
|
|
54
53
|
} from './utils';
|
|
55
54
|
import { EmptyObject } from '../core/types/utility';
|
|
56
|
-
import { ELIGIBILITY_GROUPS } from '../core/constants';
|
|
57
55
|
|
|
58
56
|
const overrideLineKey = (state, productId, newValue) => {
|
|
59
57
|
const keys = Object.keys(state).filter(it => it.startsWith(productId.toString()));
|
|
@@ -118,76 +116,39 @@ export const mapExistingOptinsFromOfferResponse = (
|
|
|
118
116
|
});
|
|
119
117
|
|
|
120
118
|
export const reduceNewOptinsFromOfferResponse = (
|
|
121
|
-
{
|
|
122
|
-
autoship = {},
|
|
123
|
-
autoship_by_default = {},
|
|
124
|
-
default_frequencies = {},
|
|
125
|
-
in_stock = {},
|
|
126
|
-
eligibility_groups
|
|
127
|
-
}: ReceiveOfferPayload,
|
|
119
|
+
{ autoship = {}, autoship_by_default = {}, default_frequencies = {}, in_stock = {} }: ReceiveOfferPayload,
|
|
128
120
|
existingOptins: OptedInState,
|
|
129
121
|
offerEl: OfferElement | EmptyObject,
|
|
130
|
-
frequencyConfig: ReceiveOfferPayload['frequencyConfig']
|
|
131
|
-
prepaidSellingPlans: ReceiveOfferPayload['prepaidSellingPlans']
|
|
122
|
+
frequencyConfig: ReceiveOfferPayload['frequencyConfig']
|
|
132
123
|
) =>
|
|
133
124
|
Object.keys(autoship).reduce((acc, id) => {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
} else if (
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
id,
|
|
151
|
-
// we might not have a prepaid plan yet if the Shopify product request hasn't completed (SETUP_PRODUCT)
|
|
152
|
-
frequency: prepaidPlan?.sellingPlan || PREPAID_PLACEHOLDER,
|
|
153
|
-
prepaidShipments: prepaidPlan?.numberShipments || null
|
|
154
|
-
});
|
|
125
|
+
if (!existingOptins.some(it => it.id === id)) {
|
|
126
|
+
if (!(autoship[id] && autoship_by_default[id] && in_stock[id])) return acc;
|
|
127
|
+
const { frequencies: sellingPlans, frequenciesEveryPeriod } = frequencyConfig;
|
|
128
|
+
const { defaultFrequency } = offerEl || {};
|
|
129
|
+
const psdf = default_frequencies[id];
|
|
130
|
+
let frequency;
|
|
131
|
+
|
|
132
|
+
if (default_frequencies[id] && hasShopifySellingPlans(sellingPlans, frequenciesEveryPeriod)) {
|
|
133
|
+
frequency =
|
|
134
|
+
mapFrequencyToSellingPlan(sellingPlans, frequenciesEveryPeriod, `${psdf.every}_${psdf.every_period}`) ||
|
|
135
|
+
getDefaultSellingPlan(sellingPlans, frequenciesEveryPeriod, defaultFrequency) ||
|
|
136
|
+
getFirstSellingPlan(sellingPlans);
|
|
137
|
+
} else if (default_frequencies[id]) {
|
|
138
|
+
frequency = `${psdf.every}_${psdf.every_period}`;
|
|
139
|
+
} else {
|
|
140
|
+
frequency = getDefaultSellingPlan(sellingPlans, frequenciesEveryPeriod, defaultFrequency) || '_'; // Placeholder to be backfilled in SETUP_PRODUCT reducer
|
|
155
141
|
}
|
|
142
|
+
|
|
143
|
+
return acc.concat({
|
|
144
|
+
id,
|
|
145
|
+
frequency
|
|
146
|
+
});
|
|
156
147
|
}
|
|
157
148
|
|
|
158
149
|
return acc;
|
|
159
150
|
}, []);
|
|
160
151
|
|
|
161
|
-
const getOptInDefaultFrequency = ({
|
|
162
|
-
frequencyConfig,
|
|
163
|
-
offerEl,
|
|
164
|
-
default_frequencies,
|
|
165
|
-
id
|
|
166
|
-
}: {
|
|
167
|
-
frequencyConfig: ReceiveOfferPayload['frequencyConfig'];
|
|
168
|
-
offerEl: OfferElement | EmptyObject;
|
|
169
|
-
default_frequencies: ReceiveOfferPayload['default_frequencies'];
|
|
170
|
-
id: string;
|
|
171
|
-
}) => {
|
|
172
|
-
const { frequencies: sellingPlans, frequenciesEveryPeriod } = frequencyConfig;
|
|
173
|
-
const { defaultFrequency } = offerEl || {};
|
|
174
|
-
const psdf = default_frequencies[id];
|
|
175
|
-
let frequency;
|
|
176
|
-
|
|
177
|
-
if (default_frequencies[id] && hasShopifySellingPlans(sellingPlans, frequenciesEveryPeriod)) {
|
|
178
|
-
frequency =
|
|
179
|
-
mapFrequencyToSellingPlan(sellingPlans, frequenciesEveryPeriod, `${psdf.every}_${psdf.every_period}`) ||
|
|
180
|
-
getDefaultSellingPlan(sellingPlans, frequenciesEveryPeriod, defaultFrequency) ||
|
|
181
|
-
getFirstSellingPlan(sellingPlans);
|
|
182
|
-
} else if (default_frequencies[id]) {
|
|
183
|
-
frequency = `${psdf.every}_${psdf.every_period}`;
|
|
184
|
-
} else {
|
|
185
|
-
frequency = getDefaultSellingPlan(sellingPlans, frequenciesEveryPeriod, defaultFrequency) || '_'; // Placeholder to be backfilled in SETUP_PRODUCT reducer
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return frequency;
|
|
189
|
-
};
|
|
190
|
-
|
|
191
152
|
const productOrVariantInStockReducer = (acc, cur) => ({
|
|
192
153
|
...overrideLineKey(acc, cur.id, cur.available),
|
|
193
154
|
[cur.id]: cur.available
|
|
@@ -273,7 +234,6 @@ function getOptedInItem(cartItem) {
|
|
|
273
234
|
return item;
|
|
274
235
|
}
|
|
275
236
|
|
|
276
|
-
const PREPAID_PLACEHOLDER = 'prepaid-replace-me';
|
|
277
237
|
export const optedin = (state: OptedInState = [], action): OptedInState => {
|
|
278
238
|
if (constants.SETUP_CART === action.type) {
|
|
279
239
|
const cart = action.payload;
|
|
@@ -284,15 +244,9 @@ export const optedin = (state: OptedInState = [], action): OptedInState => {
|
|
|
284
244
|
|
|
285
245
|
if (constants.RECEIVE_OFFER === action.type) {
|
|
286
246
|
const payload = action.payload as ReceiveOfferPayload;
|
|
287
|
-
const { offer: offerEl = {}, frequencyConfig
|
|
247
|
+
const { offer: offerEl = {}, frequencyConfig } = payload;
|
|
288
248
|
const existingOptins = mapExistingOptinsFromOfferResponse(state, offerEl, frequencyConfig);
|
|
289
|
-
const newOptins = reduceNewOptinsFromOfferResponse(
|
|
290
|
-
payload,
|
|
291
|
-
existingOptins,
|
|
292
|
-
offerEl,
|
|
293
|
-
frequencyConfig,
|
|
294
|
-
prepaidSellingPlans
|
|
295
|
-
);
|
|
249
|
+
const newOptins = reduceNewOptinsFromOfferResponse(payload, existingOptins, offerEl, frequencyConfig);
|
|
296
250
|
|
|
297
251
|
return [...existingOptins, ...newOptins];
|
|
298
252
|
}
|
|
@@ -300,33 +254,24 @@ export const optedin = (state: OptedInState = [], action): OptedInState => {
|
|
|
300
254
|
if (constants.SETUP_PRODUCT === action.type) {
|
|
301
255
|
const { product } = action.payload;
|
|
302
256
|
const sellingPlanGroup = getPayAsYouGoSellingPlanGroup(product?.selling_plan_groups);
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
257
|
+
if (!sellingPlanGroup) {
|
|
258
|
+
return state;
|
|
259
|
+
}
|
|
260
|
+
const frequencies = sellingPlansToFrequencies(sellingPlanGroup);
|
|
261
|
+
const frequenciesEveryPeriod = sellingPlansToEveryPeriod(sellingPlanGroup);
|
|
262
|
+
|
|
263
|
+
return state.map(curr => {
|
|
264
|
+
if (isOgFrequency(curr.frequency)) {
|
|
265
|
+
return {
|
|
266
|
+
...curr,
|
|
267
|
+
frequency:
|
|
268
|
+
mapFrequencyToSellingPlan(frequencies, frequenciesEveryPeriod, curr.frequency) ||
|
|
269
|
+
getFirstSellingPlan(frequencies)
|
|
270
|
+
};
|
|
271
|
+
}
|
|
306
272
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
const prepaidSellingPlansForVariant = prepaidSellingPlans[curr.id];
|
|
310
|
-
if (sellingPlanGroup && isOgFrequency(curr.frequency)) {
|
|
311
|
-
return {
|
|
312
|
-
...curr,
|
|
313
|
-
frequency:
|
|
314
|
-
mapFrequencyToSellingPlan(frequencies, frequenciesEveryPeriod, curr.frequency) ||
|
|
315
|
-
getFirstSellingPlan(frequencies)
|
|
316
|
-
};
|
|
317
|
-
} else if (curr.frequency === PREPAID_PLACEHOLDER && prepaidSellingPlansForVariant?.length > 0) {
|
|
318
|
-
// if we opted the user into a prepaid plan on RECEIVE_OFFER and now have the actual selling plan information, update it
|
|
319
|
-
const { sellingPlan, numberShipments } = getDefaultPrepaidOption(prepaidSellingPlansForVariant);
|
|
320
|
-
return {
|
|
321
|
-
...curr,
|
|
322
|
-
frequency: sellingPlan,
|
|
323
|
-
prepaidShipments: numberShipments
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
return curr;
|
|
328
|
-
})
|
|
329
|
-
.filter(i => i.frequency !== PREPAID_PLACEHOLDER); // remove any leftover placeholders
|
|
273
|
+
return curr;
|
|
274
|
+
});
|
|
330
275
|
}
|
|
331
276
|
|
|
332
277
|
if (constants.PRODUCT_CHANGE_PREPAID_SHIPMENTS === action.type) {
|
package/src/shopify/utils.ts
CHANGED
|
@@ -77,8 +77,3 @@ export function getPrepaidShipments(sellingPlan) {
|
|
|
77
77
|
const shipments = sellingPlan?.options.find(({ name }) => name === 'Shipment amount')?.value.split(' ')[0];
|
|
78
78
|
return shipments ? Number(shipments) : undefined;
|
|
79
79
|
}
|
|
80
|
-
|
|
81
|
-
export function getDefaultPrepaidOption<T>(options: T[]): T {
|
|
82
|
-
// prefer the second plan by default, which has more prepaid shipments
|
|
83
|
-
return options[1] || options[0];
|
|
84
|
-
}
|