@shopgate/tracking-core 7.30.0-alpha.7 → 7.30.0-alpha.9
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/core/AppHandler.js +121 -19
- package/core/Core.js +337 -82
- package/helpers/events.js +46 -7
- package/helpers/formatHelpers.js +324 -49
- package/helpers/helper.js +247 -36
- package/helpers/optOut.js +114 -13
- package/helpers/urlMapping.js +110 -14
- package/package.json +4 -10
- package/plugins/Base.js +94 -17
- package/plugins/trackers/FbPixel.js +186 -17
- package/plugins/trackers/GaBase.js +250 -31
- package/plugins/trackers/GaClassic.js +93 -13
- package/plugins/trackers/GaUniversal.js +162 -16
- package/plugins/trackers/Unified.js +67 -11
- package/typedef.js +51 -17
package/helpers/formatHelpers.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import "core-js/modules/es.string.replace.js";
|
|
2
|
+
import { hex2bin, SGLink } from "./helper";
|
|
3
|
+
import sgTrackingUrlMapper from "./urlMapping";
|
|
4
|
+
import { customEvents } from "./events";
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* Gets the value at path of object. If the resolved value is undefined,
|
|
3
8
|
* the defaultValue is used in its place.
|
|
4
9
|
*
|
|
@@ -6,160 +11,430 @@ function _extends(){_extends=Object.assign||function(target){for(var i=1;i<argum
|
|
|
6
11
|
* @param {string} path The path of the property to get
|
|
7
12
|
* @param {*} [defaultValue] The value returned for undefined resolved values
|
|
8
13
|
* @returns {*} Returns the resolved value
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
*/
|
|
15
|
+
function get(object, path, defaultValue) {
|
|
16
|
+
// Initialize the parameters
|
|
17
|
+
const data = object || {};
|
|
18
|
+
const dataPath = path || '';
|
|
19
|
+
const defaultReturnValue = defaultValue;
|
|
20
|
+
|
|
21
|
+
// Get the segments of the path
|
|
22
|
+
const pathSegments = dataPath.split('.');
|
|
23
|
+
if (!dataPath || !pathSegments.length) {
|
|
24
|
+
// No path or path segments where determinable - return the default value
|
|
25
|
+
return defaultReturnValue;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
13
29
|
* Recursive callable function to traverse through a complex object
|
|
14
30
|
*
|
|
15
31
|
* @param {Object} currentData The current data that shall be investigated
|
|
16
32
|
* @param {number} currentPathSegmentIndex The current index within the path segment list
|
|
17
33
|
* @returns {*} The value at the end of the path or the default one
|
|
18
|
-
*/
|
|
19
|
-
|
|
34
|
+
*/
|
|
35
|
+
function checkPathSegment(currentData, currentPathSegmentIndex) {
|
|
36
|
+
// Get the current segment within the path
|
|
37
|
+
const currentPathSegment = pathSegments[currentPathSegmentIndex];
|
|
38
|
+
const nextPathSegmentIndex = currentPathSegmentIndex + 1;
|
|
39
|
+
|
|
40
|
+
/**
|
|
20
41
|
* Prepare the default value as return value for the case that no matching property was
|
|
21
42
|
* found for the current path segment. In that case the path must be wrong.
|
|
22
|
-
*/
|
|
23
|
-
result=
|
|
24
|
-
|
|
25
|
-
|
|
43
|
+
*/
|
|
44
|
+
let result = defaultReturnValue;
|
|
45
|
+
if (currentData && currentData.hasOwnProperty(currentPathSegment)) {
|
|
46
|
+
if (typeof currentData[currentPathSegment] !== 'object' || pathSegments.length === nextPathSegmentIndex) {
|
|
47
|
+
// A final value was found
|
|
48
|
+
result = currentData[currentPathSegment];
|
|
49
|
+
} else {
|
|
50
|
+
// The value at the current step within the path is another object. Traverse through it
|
|
51
|
+
result = checkPathSegment(currentData[currentPathSegment], nextPathSegmentIndex);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Start traversing the path within the data object
|
|
58
|
+
return checkPathSegment(data, 0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
26
62
|
* Converts a numeric value into a suitable one for the unified tracking data
|
|
27
63
|
*
|
|
28
64
|
* @param {*} numericValue The value that shall be converted
|
|
29
65
|
* @returns {number|undefined} The converted value
|
|
30
66
|
* @private
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
//
|
|
34
|
-
|
|
67
|
+
*/
|
|
68
|
+
function getUnifiedNumber(numericValue) {
|
|
69
|
+
// Convert the value
|
|
70
|
+
const convertedValue = parseFloat(numericValue);
|
|
71
|
+
|
|
72
|
+
// Check if the converted value is numeric. If it's not, return "undefined" instead of it
|
|
73
|
+
// eslint-disable-next-line no-restricted-globals
|
|
74
|
+
return !isNaN(convertedValue) ? convertedValue : undefined;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
35
78
|
* Converts a value to a string. It returns an empty string for null or undefined.
|
|
36
79
|
* @param {*} value The value.
|
|
37
80
|
* @return {string}
|
|
38
|
-
*/
|
|
81
|
+
*/
|
|
82
|
+
function getStringValue(value) {
|
|
83
|
+
return value || value === 0 ? `${value}` : '';
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
39
87
|
* Returns the productNumber or uid from a product
|
|
40
88
|
*
|
|
41
89
|
* @param {Object} product Object with product data
|
|
42
90
|
* @returns {string} productNumber or uid of the product
|
|
43
91
|
* @private
|
|
44
|
-
*/
|
|
92
|
+
*/
|
|
93
|
+
function getProductIdentifier(product) {
|
|
94
|
+
return get(product, 'productNumber') || get(product, 'uid');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
45
98
|
* Removes shop names out of the page title
|
|
46
99
|
* @param {string} title The page title
|
|
47
100
|
* @param {string} shopName The shop name
|
|
48
101
|
* @returns {string} The sanitized page title
|
|
49
|
-
*/
|
|
50
|
-
|
|
102
|
+
*/
|
|
103
|
+
function sanitizeTitle(title, shopName) {
|
|
104
|
+
// Take care that the parameters don't contain leading or trailing spaces
|
|
105
|
+
let trimmedTitle = title.trim();
|
|
106
|
+
const trimmedShopName = shopName.trim();
|
|
107
|
+
if (!trimmedShopName) {
|
|
108
|
+
/**
|
|
51
109
|
* If no shop name is available, it doesn't make sense to replace it.
|
|
52
110
|
* So we return the the trimmed title directly.
|
|
53
|
-
*/
|
|
111
|
+
*/
|
|
112
|
+
return trimmedTitle;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
54
116
|
* Setup the RegExp. It matches leading and trailing occurrences
|
|
55
117
|
* of known patterns for generically added shop names within page title
|
|
56
|
-
*/
|
|
57
|
-
|
|
58
|
-
|
|
118
|
+
*/
|
|
119
|
+
const shopNameRegExp = new RegExp(`((^${trimmedShopName}:)|(- ${trimmedShopName}$))+`, 'ig');
|
|
120
|
+
if (trimmedTitle === trimmedShopName) {
|
|
121
|
+
// Clear the page title if it only contains the shop name
|
|
122
|
+
trimmedTitle = '';
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Remove the shop name from the page title
|
|
126
|
+
return trimmedTitle.replace(shopNameRegExp, '').trim();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
59
130
|
* Convert sgData product to unified item
|
|
60
131
|
*
|
|
61
132
|
* @param {Object} product Item from sgData
|
|
62
133
|
* @returns {Object} Data for the unified item
|
|
63
|
-
*/
|
|
134
|
+
*/
|
|
135
|
+
function formatSgDataProduct(product) {
|
|
136
|
+
return {
|
|
137
|
+
id: getStringValue(getProductIdentifier(product)),
|
|
138
|
+
type: 'product',
|
|
139
|
+
name: get(product, 'name'),
|
|
140
|
+
priceNet: getUnifiedNumber(get(product, 'amount.net')),
|
|
141
|
+
priceGross: getUnifiedNumber(get(product, 'amount.gross')),
|
|
142
|
+
quantity: getUnifiedNumber(get(product, 'quantity')),
|
|
143
|
+
currency: get(product, 'amount.currency'),
|
|
144
|
+
brand: get(product, 'manufacturer')
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
64
149
|
* Convert sgData products to unified items
|
|
65
150
|
*
|
|
66
151
|
* @param {Array} products Items from sgData
|
|
67
152
|
* @returns {UnifiedPurchaseItem[] | UnifiedAddToCartItem[]} Data for the unified items
|
|
68
|
-
*/
|
|
69
|
-
|
|
153
|
+
*/
|
|
154
|
+
function formatSgDataProducts(products) {
|
|
155
|
+
// TODO: Error handling for malformed data
|
|
156
|
+
|
|
157
|
+
if (!products || !Array.isArray(products)) {
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
return products.map(formatSgDataProduct);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
70
164
|
* Convert products from the favouriteListItemAdded event to unified items
|
|
71
165
|
*
|
|
72
166
|
* @param {Array} products Items from sgData
|
|
73
167
|
* @returns {UnifiedAddToWishlistItem[]} Data for the unified items
|
|
74
|
-
*/
|
|
168
|
+
*/
|
|
169
|
+
function formatFavouriteListItems(products) {
|
|
170
|
+
if (!products || !Array.isArray(products)) {
|
|
171
|
+
return [];
|
|
172
|
+
}
|
|
173
|
+
return products.map(product => ({
|
|
174
|
+
id: getStringValue(get(product, 'product_number_public') || get(product, 'product_number') || get(product, 'uid')),
|
|
175
|
+
type: 'product',
|
|
176
|
+
name: get(product, 'name'),
|
|
177
|
+
priceNet: getUnifiedNumber(get(product, 'unit_amount_net')) / 100,
|
|
178
|
+
priceGross: getUnifiedNumber(get(product, 'unit_amount_with_tax')) / 100,
|
|
179
|
+
currency: get(product, 'currency_id')
|
|
180
|
+
}));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
75
184
|
* Storage for helper functions that transforms raw data
|
|
76
185
|
* into the unified format for the tracking plugins
|
|
77
|
-
*/
|
|
186
|
+
*/
|
|
187
|
+
const dataFormatHelpers = {};
|
|
188
|
+
|
|
189
|
+
/**
|
|
78
190
|
* Converter for the custom events
|
|
79
191
|
*
|
|
80
192
|
* @param {Object} data Raw data from the core
|
|
81
193
|
* @returns {UnifiedCustomEvent} Data for the unified custom event
|
|
82
194
|
* @private
|
|
83
|
-
*/
|
|
84
|
-
|
|
195
|
+
*/
|
|
196
|
+
const formatEventData = data => ({
|
|
197
|
+
eventCategory: '',
|
|
198
|
+
eventAction: '',
|
|
199
|
+
eventLabel: null,
|
|
200
|
+
eventValue: null,
|
|
201
|
+
nonInteraction: false,
|
|
202
|
+
...data
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// Assign the format helper to all custom events
|
|
206
|
+
customEvents.forEach(event => {
|
|
207
|
+
dataFormatHelpers[event] = formatEventData;
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
/**
|
|
85
211
|
* Converter for the purchase event
|
|
86
212
|
*
|
|
87
213
|
* @param {Object} rawData Raw data from the core
|
|
88
214
|
* @returns {UnifiedPurchase} Data for the unified purchase event
|
|
89
|
-
*/
|
|
215
|
+
*/
|
|
216
|
+
dataFormatHelpers.purchase = rawData => ({
|
|
217
|
+
id: getStringValue(get(rawData, 'order.number')),
|
|
218
|
+
type: 'product',
|
|
219
|
+
affiliation: get(rawData, 'shop.name', ''),
|
|
220
|
+
revenueGross: getUnifiedNumber(get(rawData, 'order.amount.gross')),
|
|
221
|
+
revenueNet: getUnifiedNumber(get(rawData, 'order.amount.net')),
|
|
222
|
+
tax: getUnifiedNumber(get(rawData, 'order.amount.tax')),
|
|
223
|
+
shippingGross: getUnifiedNumber(get(rawData, 'order.shipping.amount.gross')),
|
|
224
|
+
shippingNet: getUnifiedNumber(get(rawData, 'order.shipping.amount.net')),
|
|
225
|
+
currency: get(rawData, 'order.amount.currency'),
|
|
226
|
+
items: formatSgDataProducts(get(rawData, 'order.products'))
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
/**
|
|
90
230
|
* Converter for the pageview event
|
|
91
231
|
*
|
|
92
232
|
* @param {Object} rawData Raw data from the core
|
|
93
233
|
* @returns {{page: {merchantUrl: string, shopgateUrl: string}}} Formatted data
|
|
94
|
-
*/
|
|
234
|
+
*/
|
|
235
|
+
dataFormatHelpers.pageview = rawData => {
|
|
236
|
+
const mappedUrls = sgTrackingUrlMapper(get(rawData, 'page.link'), rawData);
|
|
237
|
+
return {
|
|
238
|
+
page: {
|
|
239
|
+
merchantUrl: mappedUrls.public,
|
|
240
|
+
shopgateUrl: mappedUrls.private
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
/**
|
|
95
246
|
* Converter for the viewContent event
|
|
96
247
|
*
|
|
97
248
|
* @param {Object} rawData Raw data from the core
|
|
98
249
|
* @returns {UnifiedPageview} Data for the unified page view event
|
|
99
|
-
*/
|
|
250
|
+
*/
|
|
251
|
+
dataFormatHelpers.viewContent = rawData => {
|
|
252
|
+
let link = get(rawData, 'page.link');
|
|
253
|
+
if (link.indexOf('sg_app_resources') !== -1) {
|
|
254
|
+
/**
|
|
100
255
|
* Check if the link is formatted in the app style
|
|
101
256
|
* and reformat it do make it parsable with SGLink
|
|
102
257
|
* Note: this will be removed when CON-410 is done
|
|
103
|
-
*/
|
|
258
|
+
*/
|
|
259
|
+
link = `http://dummy.com${link.replace(/(.*sg_app_resources\/\d*)/i, '')}`;
|
|
260
|
+
}
|
|
261
|
+
link = new SGLink(link);
|
|
262
|
+
|
|
263
|
+
/**
|
|
104
264
|
* In splittedPath we have the action as the first array entry
|
|
105
265
|
* to get the id/action params we remove the action from the array
|
|
106
|
-
*/
|
|
266
|
+
*/
|
|
267
|
+
const splittedPath = [...link.splittedPath];
|
|
268
|
+
splittedPath.shift();
|
|
269
|
+
|
|
270
|
+
/**
|
|
107
271
|
* All pages have action as type and a parsed page title without shop name as name
|
|
108
272
|
* fb content ID = 'id / name'
|
|
109
|
-
*/
|
|
273
|
+
*/
|
|
274
|
+
let id = splittedPath.join('/');
|
|
275
|
+
let type = link.action || 'index';
|
|
276
|
+
let name = sanitizeTitle(get(rawData, 'page.title', ''), get(rawData, 'shop.name', '')) || get(rawData, 'page.name');
|
|
277
|
+
|
|
278
|
+
/**
|
|
110
279
|
* Category, product and product related pages should have productnumber/categorynumber as id
|
|
111
280
|
* they should have product name / category name as name
|
|
112
|
-
*/
|
|
281
|
+
*/
|
|
282
|
+
if (rawData.hasOwnProperty('product') && type === 'item') {
|
|
283
|
+
type = 'product';
|
|
284
|
+
id = getProductIdentifier(rawData.product);
|
|
285
|
+
} else if (rawData.hasOwnProperty('category') && type === 'category') {
|
|
286
|
+
id = get(rawData, 'category.uid');
|
|
287
|
+
if (splittedPath.indexOf('all') !== -1) {
|
|
288
|
+
id += '/all';
|
|
289
|
+
}
|
|
290
|
+
} else if (rawData.hasOwnProperty('search') && type === 'search') {
|
|
291
|
+
id = get(rawData, 'search.query');
|
|
292
|
+
name = name.substring(0, name.indexOf(':')).trim();
|
|
293
|
+
} else if (['product_info', 'reviews', 'add_review'].indexOf(type) !== -1) {
|
|
294
|
+
id = hex2bin(link.splittedPath[1]) || '';
|
|
295
|
+
} else if (type === 'payment_success') {
|
|
296
|
+
type = 'checkout_success';
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
id,
|
|
300
|
+
type,
|
|
301
|
+
name
|
|
302
|
+
};
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
/**
|
|
113
306
|
* Converter for the addToCart event
|
|
114
307
|
*
|
|
115
308
|
* @param {Object} rawData Raw data from the core
|
|
116
309
|
* @returns {UnifiedAddToCart} data for the addToCart event
|
|
117
|
-
*/
|
|
310
|
+
*/
|
|
311
|
+
dataFormatHelpers.addToCart = rawData => ({
|
|
312
|
+
type: 'product',
|
|
313
|
+
items: formatSgDataProducts(get(rawData, 'products'))
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
/**
|
|
118
317
|
* Converter for the variantSelected event
|
|
119
318
|
*
|
|
120
319
|
* @param {Object} rawData {variant:{}, baseProduct:{}} Raw data from the core
|
|
121
320
|
* @returns {Object} data for the addToCart event
|
|
122
|
-
*/
|
|
321
|
+
*/
|
|
322
|
+
dataFormatHelpers.variantSelected = rawData => ({
|
|
323
|
+
variant: formatSgDataProduct(rawData.variant),
|
|
324
|
+
baseProduct: formatSgDataProduct(rawData.baseProduct)
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
/**
|
|
123
328
|
* Converter for the addToWishlist event
|
|
124
329
|
*
|
|
125
330
|
* @param {Object} rawData Raw data from the core
|
|
126
331
|
* @returns {UnifiedAddToWishlist} data for the addToWishlist event
|
|
127
|
-
*/
|
|
332
|
+
*/
|
|
333
|
+
dataFormatHelpers.addToWishlist = rawData => ({
|
|
334
|
+
type: 'product',
|
|
335
|
+
items: formatFavouriteListItems(get(rawData, 'favouriteListProducts'))
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
/**
|
|
128
339
|
* Converter for the initiatedCheckout event
|
|
129
340
|
*
|
|
130
341
|
* @param {Object} rawData Raw data from the core
|
|
131
342
|
* @returns {UnifiedInitiatedCheckout} data for the addToCart event
|
|
132
|
-
*/
|
|
133
|
-
|
|
134
|
-
|
|
343
|
+
*/
|
|
344
|
+
dataFormatHelpers.initiatedCheckout = rawData => {
|
|
345
|
+
const checkoutType = get(rawData, 'checkoutType', 'default');
|
|
346
|
+
// Get amount, depending if pp express on cart or item page was clicked
|
|
347
|
+
const amount = get(rawData, 'product.amount') || get(rawData, 'cart.amount');
|
|
348
|
+
return {
|
|
349
|
+
type: checkoutType,
|
|
350
|
+
valueNet: getUnifiedNumber(get(amount, 'net')),
|
|
351
|
+
valueGross: getUnifiedNumber(get(amount, 'gross')),
|
|
352
|
+
// PP express on item page sends the quantity directly
|
|
353
|
+
numItems: getUnifiedNumber(get(rawData, 'quantity') || get(rawData, 'cart.productsCount')),
|
|
354
|
+
currency: get(amount, 'currency'),
|
|
355
|
+
paymentInfoAvailable: checkoutType !== 'default'
|
|
356
|
+
};
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
/**
|
|
135
360
|
* Converter for the completedRegistration event
|
|
136
361
|
* @param {Object} rawData rawData Raw data from the core
|
|
137
362
|
* @returns {UnifiedCompletedRegistration} Information about the registration type
|
|
138
|
-
*/
|
|
363
|
+
*/
|
|
364
|
+
dataFormatHelpers.completedRegistration = rawData => ({
|
|
365
|
+
registrationMethod: get(rawData, 'registrationType')
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
/**
|
|
139
369
|
* Converter for the search event
|
|
140
370
|
*
|
|
141
371
|
* @param {Object} rawData Raw data from the core
|
|
142
372
|
* @returns {UnifiedSearched} data for the search event
|
|
143
|
-
*/
|
|
373
|
+
*/
|
|
374
|
+
dataFormatHelpers.search = rawData => {
|
|
375
|
+
const hits = get(rawData, 'search.resultCount');
|
|
376
|
+
return {
|
|
377
|
+
type: 'product',
|
|
378
|
+
query: get(rawData, 'search.query'),
|
|
379
|
+
hits: getUnifiedNumber(hits),
|
|
380
|
+
success: !!hits
|
|
381
|
+
};
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
/**
|
|
144
385
|
* Return the url from the rawData
|
|
145
386
|
*
|
|
146
387
|
* @param {Object} rawData Raw data from the core
|
|
147
388
|
* @returns {Object} data for the setCampaignWithUrl event
|
|
148
|
-
*/
|
|
389
|
+
*/
|
|
390
|
+
dataFormatHelpers.setCampaignWithUrl = rawData => ({
|
|
391
|
+
url: rawData.url
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
/**
|
|
149
395
|
* Converter for the addedPaymentInfo event
|
|
150
396
|
*
|
|
151
397
|
* @param {Object} rawData Raw data from the core
|
|
152
398
|
* @returns {UnifiedPaymentInfo} Data for the AddedPaymentInfo event
|
|
153
|
-
*/
|
|
399
|
+
*/
|
|
400
|
+
dataFormatHelpers.addedPaymentInfo = rawData => ({
|
|
401
|
+
success: get(rawData, 'paymentMethodAdded.success'),
|
|
402
|
+
name: get(rawData, 'paymentMethodAdded.name')
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
/**
|
|
154
406
|
* Converter for the selectedPaymentInfo event. It's compatible to the addedPaymentInfo event, but
|
|
155
407
|
* other than this, it's also triggered when a payment method was selected which doesn't have
|
|
156
408
|
* configurable entities, like "credit card".
|
|
157
409
|
*
|
|
158
410
|
* @param {Object} rawData Raw data from the core
|
|
159
411
|
* @returns {UnifiedPaymentInfo} Data for the SelectedPaymentInfo event
|
|
160
|
-
*/
|
|
412
|
+
*/
|
|
413
|
+
dataFormatHelpers.selectedPaymentInfo = rawData => ({
|
|
414
|
+
success: get(rawData, 'paymentMethodSelected.success'),
|
|
415
|
+
name: get(rawData, 'paymentMethodSelected.name')
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
/**
|
|
161
419
|
* Converter for the logItemView event.
|
|
162
420
|
*
|
|
163
421
|
* @param {Object} rawData Raw data from the core
|
|
164
422
|
* @returns {UnifiedItemView} Data for the logItemView event
|
|
165
|
-
*/
|
|
423
|
+
*/
|
|
424
|
+
dataFormatHelpers.itemView = rawData => {
|
|
425
|
+
let product;
|
|
426
|
+
if (rawData.product) {
|
|
427
|
+
({
|
|
428
|
+
product
|
|
429
|
+
} = rawData);
|
|
430
|
+
} else if (rawData.variant) {
|
|
431
|
+
product = rawData.variant;
|
|
432
|
+
}
|
|
433
|
+
product = formatSgDataProduct(product);
|
|
434
|
+
delete product.quantity;
|
|
435
|
+
return {
|
|
436
|
+
...product,
|
|
437
|
+
type: ''
|
|
438
|
+
};
|
|
439
|
+
};
|
|
440
|
+
export default dataFormatHelpers;
|