@ordergroove/offers 2.47.2-alpha-PR-1356-3.33 → 2.48.0

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.47.2-alpha-PR-1356-3.33+ee810ebfe",
3
+ "version": "2.48.0",
4
4
  "description": "offer state component",
5
5
  "author": "Eugenio Lattanzio <eugenio63@gmail.com>",
6
6
  "homepage": "https://github.com/ordergroove/plush-toys#readme",
@@ -49,5 +49,5 @@
49
49
  "@ordergroove/offers-templates": "^0.10.0",
50
50
  "@types/lodash.memoize": "^4.1.9"
51
51
  },
52
- "gitHead": "ee810ebfe69c9a4aae3d7dbf2624cf4ef49324e6"
52
+ "gitHead": "8ec942439e46e09a4970c14c0faa93bba6975f31"
53
53
  }
@@ -109,6 +109,9 @@ export class IncentiveText extends withProduct(LitElement) {
109
109
  // we only have criteria if the incentive is standardized
110
110
  incentive.criteria &&
111
111
  incentive.criteria.node_type === 'PREMISE' &&
112
+ // prefer to show non-threshold discounts
113
+ // we don't currently evaluate thresholds, so we don't know if they apply or not (especially if it's order-level)
114
+ !incentive.threshold_field &&
112
115
  preferredIncentiveStandards.includes(incentive.criteria.standard)
113
116
  );
114
117
 
@@ -208,6 +208,42 @@ describe('IncentiveText', () => {
208
208
  expect(el.innerText.trim()).toEqual('33%');
209
209
  });
210
210
 
211
+ it('prefers non-threshold incentives', async () => {
212
+ const el = new IncentiveText();
213
+ el.from = 'DiscountPercent';
214
+ el.incentives = {
215
+ initial: [],
216
+ ongoing: [
217
+ {
218
+ field: 'total_price',
219
+ object: 'item',
220
+ type: 'Discount Percent',
221
+ value: 25,
222
+ threshold_field: 'order',
223
+ threshold_value: '10.00',
224
+ criteria: {
225
+ node_type: 'PREMISE',
226
+ standard: 'PROGRAM_WIDE'
227
+ }
228
+ },
229
+ {
230
+ field: 'total_price',
231
+ object: 'item',
232
+ type: 'Discount Percent',
233
+ value: 10,
234
+ threshold_field: null,
235
+ threshold_value: null,
236
+ criteria: {
237
+ node_type: 'PREMISE',
238
+ standard: 'PROGRAM_WIDE'
239
+ }
240
+ }
241
+ ]
242
+ };
243
+ await appendToBody(el);
244
+ expect(el.innerText.trim()).toEqual('10%');
245
+ });
246
+
211
247
  it('returns other matching incentives if no preferred incentives available', async () => {
212
248
  const el = new IncentiveText();
213
249
  el.from = 'DiscountPercent';
@@ -1072,6 +1072,21 @@ describe('reducers', () => {
1072
1072
  it('should consider incentives_display_enhanced if present', () => {
1073
1073
  const enhancedOfferResponse = {
1074
1074
  ...offerResponse,
1075
+ incentives: {
1076
+ 44198332104980: {
1077
+ ongoing: ['8285f16f826e4cf29b49f073e45e32ab', 'threshold-id', '10205e185a5c4ccf83de75459241623a'],
1078
+ initial: ['0f98a321d29e47d2a17fe3a8a7522d26']
1079
+ }
1080
+ },
1081
+ incentives_display: {
1082
+ ...offerResponse.incentives_display,
1083
+ 'threshold-id': {
1084
+ object: 'order',
1085
+ field: 'sub_total',
1086
+ type: 'Discount Percent',
1087
+ value: 20.0
1088
+ }
1089
+ },
1075
1090
  incentives_display_enhanced: {
1076
1091
  '8285f16f826e4cf29b49f073e45e32ab': {
1077
1092
  incentive_target: 'order',
@@ -1081,6 +1096,14 @@ describe('reducers', () => {
1081
1096
  threshold_field: null,
1082
1097
  threshold_value: null
1083
1098
  },
1099
+ 'threshold-id': {
1100
+ incentive_target: 'order',
1101
+ incentive_type: 'discount_percent',
1102
+ incentive_value: '20.00',
1103
+ // no criteria, since this is program-wide
1104
+ threshold_field: 'order',
1105
+ threshold_value: '10.00'
1106
+ },
1084
1107
  '10205e185a5c4ccf83de75459241623a': {
1085
1108
  incentive_target: 'item',
1086
1109
  incentive_type: 'discount_percent',
@@ -1117,6 +1140,22 @@ describe('reducers', () => {
1117
1140
  type: 'Discount Percent',
1118
1141
  value: 10.0,
1119
1142
  id: '8285f16f826e4cf29b49f073e45e32ab',
1143
+ threshold_field: null,
1144
+ threshold_value: null,
1145
+ criteria: {
1146
+ node_type: 'PREMISE',
1147
+ standard: 'PROGRAM_WIDE',
1148
+ premise_value: null
1149
+ }
1150
+ },
1151
+ {
1152
+ object: 'order',
1153
+ field: 'sub_total',
1154
+ type: 'Discount Percent',
1155
+ value: 20.0,
1156
+ id: 'threshold-id',
1157
+ threshold_field: 'order',
1158
+ threshold_value: '10.00',
1120
1159
  criteria: {
1121
1160
  node_type: 'PREMISE',
1122
1161
  standard: 'PROGRAM_WIDE',
@@ -1129,6 +1168,8 @@ describe('reducers', () => {
1129
1168
  type: 'Discount Amount',
1130
1169
  value: 5.0,
1131
1170
  id: '10205e185a5c4ccf83de75459241623a',
1171
+ threshold_field: null,
1172
+ threshold_value: null,
1132
1173
  criteria: {
1133
1174
  node_type: 'PREMISE',
1134
1175
  standard: 'PREPAID_ORDERS_PER_BILLING',
@@ -1143,6 +1184,8 @@ describe('reducers', () => {
1143
1184
  type: 'Discount Percent',
1144
1185
  value: 11.0,
1145
1186
  id: '0f98a321d29e47d2a17fe3a8a7522d26',
1187
+ threshold_field: null,
1188
+ threshold_value: null,
1146
1189
  criteria: {
1147
1190
  node_type: 'PREMISE',
1148
1191
  standard: 'PSI',
@@ -180,7 +180,13 @@ const mapIncentive = (
180
180
  ? enhanced.criteria
181
181
  : // when there is no criteria in the enhanced incentive, it means it's a program wide incentive
182
182
  // for ease-of-use, we set use a "PROGRAM_WIDE" pseudo-standard here
183
- { node_type: 'PREMISE', standard: constants.INCENTIVE_STANDARD_TYPES.PROGRAM_WIDE, premise_value: null }
183
+ {
184
+ node_type: 'PREMISE',
185
+ standard: constants.INCENTIVE_STANDARD_TYPES.PROGRAM_WIDE,
186
+ premise_value: null
187
+ },
188
+ threshold_field: enhanced.threshold_field,
189
+ threshold_value: enhanced.threshold_value
184
190
  }
185
191
  : {}),
186
192
  id: [i][0]
@@ -20,8 +20,10 @@ export type IncentivesState = Record<string, IncentiveObject>;
20
20
  export type Incentive = ApiIncentive & {
21
21
  id: string;
22
22
  /**
23
- * undefined when the offer profile is not standardized
23
+ * all these fields are undefined when the offer profile is not standardized
24
24
  */
25
+ threshold_field?: string | null;
26
+ threshold_value?: string | null;
25
27
  criteria?: {
26
28
  node_type: string;
27
29
  premise_value: unknown;
@@ -123,7 +123,7 @@ export const reduceNewOptinsFromOfferResponse = (
123
123
  autoship_by_default = {},
124
124
  default_frequencies = {},
125
125
  in_stock = {},
126
- eligibility_groups
126
+ eligibility_groups = {}
127
127
  }: ReceiveOfferPayload,
128
128
  existingOptins: OptedInState,
129
129
  offerEl: OfferElement | EmptyObject,
@@ -143,7 +143,7 @@ export const reduceNewOptinsFromOfferResponse = (
143
143
  id
144
144
  })
145
145
  });
146
- } else if (eligibility_groups[id].includes(ELIGIBILITY_GROUPS.PREPAID)) {
146
+ } else if (eligibility_groups[id]?.includes(ELIGIBILITY_GROUPS.PREPAID)) {
147
147
  // if the product is prepaid eligible but not subscription eligible, opt them into a prepaid subscription
148
148
  const prepaidPlan = prepaidSellingPlans ? getDefaultPrepaidOption(prepaidSellingPlans) : null;
149
149
  return acc.concat({