@crmcom/self-service-sdk 2.1.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/orders.js ADDED
@@ -0,0 +1,732 @@
1
+ import { httpUtil } from './httpUtil'
2
+ import { ErrorCodes, createResult, createCommonResult } from './resultUtil'
3
+ import { account } from './account';
4
+ import { logger } from './logger';
5
+
6
+ export const orders = {
7
+ getMyOrders,
8
+ getOrder,
9
+ getOrderCatalogues,
10
+ getOrderCatalogueCategories,
11
+ getProductCategories,
12
+ getProducts,
13
+ getProductsWithFacets,
14
+ getProduct,
15
+ getProductVariants,
16
+ getProductComponents,
17
+ estimateOrderFulfillment,
18
+ estimateOrder,
19
+ makeOrder,
20
+ getOrdersRecommendation,
21
+ getServicesRecommendation,
22
+ getProductTypes,
23
+ getProductBrands,
24
+ getProductsRecommendation,
25
+ }
26
+
27
+ async function getMyOrders({
28
+ page = 1,
29
+ size = 20,
30
+ sort="CREATED_DATE",
31
+ order='DESC',
32
+ custom_fields,
33
+ include_custom_fields,
34
+ include_total = true,
35
+ completed_on_gte,
36
+ completed_on_lte,
37
+ state,
38
+ supply_method
39
+ } = {},) {
40
+ try {
41
+ let id = httpUtil.getSession().sub;
42
+ let response = await httpUtil.get({
43
+ resourcePath: '/v2/contacts/' + id + '/orders',
44
+ queryParams: {
45
+ page,
46
+ size,
47
+ sort,
48
+ order,
49
+ custom_fields,
50
+ include_custom_fields,
51
+ include_total,
52
+ state,
53
+ supply_method,
54
+ "completed_on[gte]": completed_on_gte,
55
+ "completed_on[lte]": completed_on_lte
56
+ },
57
+ withAccessToken: true
58
+ });
59
+ return createCommonResult(response);
60
+ } catch (e) {
61
+ logger.error('Exception getMyOrders:', e);
62
+ return createResult(ErrorCodes.UNKNOWN, e);
63
+ }
64
+ }
65
+
66
+ async function getOrder(id) {
67
+ try {
68
+ let response = await httpUtil.get({
69
+ resourcePath: '/v2/orders/' + id,
70
+ withAccessToken: true
71
+ });
72
+ if (response.code == "OK")
73
+ return createResult(ErrorCodes.OK, response.data);
74
+ else {
75
+ if (response.error && response.error.error == "COM.CRM.EXCEPTIONS.ORDERS.CANNOTFULFILLORDEREXCEPTION" || response.error && response.error.error == "COM.CRM.EXCEPTIONS.CANNOTFULFILLORDEREXCEPTION") {
76
+ return createResult(ErrorCodes.CAN_NOT_FULFILL_ORDER_EXCEPTION, response.error);
77
+ }
78
+ return createCommonResult(response);
79
+ }
80
+ } catch (e) {
81
+ logger.error('Exception getOrder:', e);
82
+ return createResult(ErrorCodes.UNKNOWN, e);
83
+ }
84
+ }
85
+
86
+ async function getOrderCatalogues({
87
+ search_value,
88
+ fulfilled_by,
89
+ supply_method,
90
+ ordering_time,
91
+ order_catalog_ids,
92
+ page = 1,
93
+ size = 100,
94
+ sort = 'name',//='UPDATED_DATE',
95
+ order = 'ASC', //='DESC'
96
+ } = {},) {
97
+ try {
98
+ if (!fulfilled_by) {
99
+ fulfilled_by = httpUtil.getSession().current_organisation_id;
100
+ }
101
+ let response = await httpUtil.get({
102
+ resourcePath: '/v2/order_catalogues',
103
+ withAccessToken: true,
104
+ queryParams: {
105
+ search_value,
106
+ fulfilled_by,
107
+ supply_method,
108
+ ordering_time,
109
+ page,
110
+ size,
111
+ sort,
112
+ order,
113
+ order_catalog_ids
114
+ }
115
+ });
116
+ return createCommonResult(response);
117
+ } catch (e) {
118
+ logger.error('Exception getOrderCatalogues:', e);
119
+ return createResult(ErrorCodes.UNKNOWN, e);
120
+ }
121
+ }
122
+
123
+ async function getOrderCatalogueCategories({
124
+ search_value,
125
+ parent_id,
126
+ return_all,
127
+ include_total,
128
+ page = 1,
129
+ size = 100,
130
+ sort = 'priority',//='UPDATED_DATE',
131
+ order = 'ASC', //='DESC'
132
+ } = {}, catalogId) {
133
+ try {
134
+ let response = await httpUtil.get({
135
+ resourcePath: '/v2/order_catalogues/' + catalogId + '/categories',
136
+ withAccessToken: true,
137
+ queryParams: {
138
+ search_value,
139
+ parent_id,
140
+ return_all,
141
+ page,
142
+ size,
143
+ sort,
144
+ order,
145
+ include_total
146
+ }
147
+ });
148
+ return createCommonResult(response);
149
+ } catch (e) {
150
+ logger.error('Exception getOrderCatalogueCategories:', e);
151
+ return createResult(ErrorCodes.UNKNOWN, e);
152
+ }
153
+ }
154
+
155
+ async function getProductCategories({
156
+ available_in_order_menus = true,
157
+ include_total,
158
+ organisation_id,
159
+ parent_id,
160
+ return_all,
161
+ page = 1,
162
+ size = 100,
163
+ sort = 'name',//='UPDATED_DATE',
164
+ order = 'ASC', //='DESC'
165
+ } = {},) {
166
+ try {
167
+ let response = await httpUtil.get({
168
+ resourcePath: '/v2/products/categories',
169
+ withAccessToken: true,
170
+ queryParams: {
171
+ available_in_order_menus,
172
+ include_total,
173
+ organisation_id,
174
+ parent_id,
175
+ return_all,
176
+ page,
177
+ size,
178
+ sort,
179
+ order
180
+ }
181
+ });
182
+ return createCommonResult(response);
183
+ } catch (e) {
184
+ logger.error('Exception getProductCategories:', e);
185
+ return createResult(ErrorCodes.UNKNOWN, e);
186
+ }
187
+ }
188
+
189
+ async function getProducts({
190
+ product_ids,
191
+ product_skus,
192
+ brand_id,
193
+ category_id,
194
+ classification,
195
+ composition,
196
+ country,
197
+ currency,
198
+ custom_fields,
199
+ family_id,
200
+ fulfilled_by,
201
+ include_custom_fields,
202
+ include_total,
203
+ is_modifier,
204
+ name,
205
+ order_catalog_id,
206
+ order_category_id,
207
+ owned_by,
208
+ search_value,
209
+ supply_method,
210
+ type_id,
211
+ page = 1,
212
+ size = 100,
213
+ sort = 'name',//='UPDATED_DATE',
214
+ order = 'ASC', //='DESC'
215
+ } = {},) {
216
+ try {
217
+ let validity_date = Math.floor(new Date().getTime() / 1000.0);
218
+ let query = {
219
+ product_ids,
220
+ product_skus,
221
+ brand_id,
222
+ category_id,
223
+ classification,
224
+ composition,
225
+ country,
226
+ currency,
227
+ custom_fields,
228
+ family_id,
229
+ fulfilled_by,
230
+ include_custom_fields,
231
+ include_total,
232
+ is_modifier,
233
+ name,
234
+ order_catalog_id,
235
+ order_category_id,
236
+ owned_by,
237
+ search_value,
238
+ supply_method,
239
+ type_id,
240
+ page,
241
+ size,
242
+ sort,
243
+ order,
244
+ }
245
+ query["validity_date"] = validity_date;
246
+ let response = await httpUtil.get({
247
+ resourcePath: '/v2/products',
248
+ withAccessToken: true,
249
+ queryParams: query
250
+ });
251
+ return createCommonResult(response);
252
+ } catch (e) {
253
+ logger.error('Exception getProducts:', e);
254
+ return createResult(ErrorCodes.UNKNOWN, e);
255
+ }
256
+ }
257
+
258
+ async function getProductsWithFacets({
259
+ product_ids,
260
+ brand_id,
261
+ category_id,
262
+ classification,
263
+ composition,
264
+ country,
265
+ currency,
266
+ custom_fields,
267
+ family_id,
268
+ fulfilled_by,
269
+ include_custom_fields,
270
+ include_total,
271
+ is_modifier,
272
+ name,
273
+ order_catalog_id,
274
+ order_category_id,
275
+ owned_by,
276
+ search_value,
277
+ supply_method,
278
+ type_id,
279
+ page = 1,
280
+ size = 100,
281
+ sort = 'name',//='UPDATED_DATE',
282
+ order = 'ASC', //='DESC'
283
+ } = {},) {
284
+ try {
285
+ let validity_date = Math.floor(new Date().getTime() / 1000.0);
286
+ let query = {
287
+ product_ids,
288
+ brand_id,
289
+ category_id,
290
+ classification,
291
+ composition,
292
+ country,
293
+ currency,
294
+ custom_fields,
295
+ family_id,
296
+ fulfilled_by,
297
+ include_custom_fields,
298
+ include_total,
299
+ is_modifier,
300
+ name,
301
+ order_catalog_id,
302
+ order_category_id,
303
+ owned_by,
304
+ search_value,
305
+ supply_method,
306
+ type_id,
307
+ page,
308
+ size,
309
+ sort,
310
+ order,
311
+ }
312
+ query["validity_date"] = validity_date;
313
+ let response = await httpUtil.get({
314
+ resourcePath: '/v2/products/analytics',
315
+ withAccessToken: true,
316
+ queryParams: query
317
+ });
318
+ return createCommonResult(response);
319
+ } catch (e) {
320
+ logger.error('Exception getProducts:', e);
321
+ return createResult(ErrorCodes.UNKNOWN, e);
322
+ }
323
+ }
324
+
325
+ async function getProductBrands({
326
+ brand_ids,
327
+ include_total,
328
+ search_value,
329
+ page = 1,
330
+ size = 100,
331
+ sort = 'name',
332
+ order = 'ASC',
333
+ } = {},) {
334
+ try {
335
+ let query = {
336
+ brand_ids,
337
+ include_total,
338
+ search_value,
339
+ page,
340
+ size,
341
+ sort,
342
+ order,
343
+ }
344
+ let response = await httpUtil.get({
345
+ resourcePath: '/v2/products/brands',
346
+ withAccessToken: true,
347
+ queryParams: query
348
+ });
349
+ return createCommonResult(response);
350
+ } catch (e) {
351
+ logger.error('Exception getProductTypes:', e);
352
+ return createResult(ErrorCodes.UNKNOWN, e);
353
+ }
354
+ }
355
+
356
+
357
+ async function getProduct(id, {
358
+ fulfilled_by,
359
+ supply_method
360
+ }) {
361
+ try {
362
+ let response = await httpUtil.get({
363
+ resourcePath: '/v2/products/' + id,
364
+ queryParams: {
365
+ fulfilled_by,
366
+ supply_method
367
+ },
368
+ withAccessToken: true
369
+ });
370
+ return createCommonResult(response);
371
+ } catch (e) {
372
+ logger.error('Exception getProduct:', e);
373
+ return createResult(ErrorCodes.UNKNOWN, e);
374
+ }
375
+ }
376
+
377
+ async function getProductVariants({
378
+ fulfilled_by,
379
+ supply_method,
380
+ include_characteristics = true,
381
+ } = {}, productId) {
382
+ try {
383
+ let response = await httpUtil.get({
384
+ resourcePath: '/v2/products/' + productId + '/variants',
385
+ queryParams: {
386
+ supply_method,
387
+ fulfilled_by,
388
+ include_characteristics
389
+ },
390
+ withAccessToken: true
391
+ });
392
+ return createCommonResult(response);
393
+ } catch (e) {
394
+ logger.error('Exception getProductVariants:', e);
395
+ return createResult(ErrorCodes.UNKNOWN, e);
396
+ }
397
+ }
398
+
399
+ async function getProductComponents(productID, {
400
+ fulfilled_by,
401
+ supply_method
402
+ }) {
403
+ try {
404
+ let response = await httpUtil.get({
405
+ resourcePath: '/v2/products/' + productID + '/components',
406
+ withAccessToken: true,
407
+ queryParams: {
408
+ fulfilled_by,
409
+ supply_method
410
+ }
411
+ });
412
+ return createCommonResult(response);
413
+ } catch (e) {
414
+ logger.error('Exception getProductComponents:', e);
415
+ return createResult(ErrorCodes.UNKNOWN, e);
416
+ }
417
+ }
418
+
419
+
420
+ async function estimateOrderFulfillment({
421
+ supply_method,
422
+ postal_code,
423
+ lat_lot,
424
+ address_id,
425
+ requested_delivery_at,
426
+ requested_organisation_id,
427
+ is_open=true,
428
+ country_code,
429
+ contact_id
430
+ }) {
431
+ try {
432
+ let response = await httpUtil.post({
433
+ resourcePath: '/v2/estimates/order_fulfillment',
434
+ body: {
435
+ supply_method,
436
+ postal_code,
437
+ lat_lot,
438
+ address_id,
439
+ requested_delivery_at,
440
+ requested_organisation_id,
441
+ is_open,
442
+ country_code,
443
+ contact_id
444
+ },
445
+ withAccessToken: true
446
+ });
447
+ //check return code here instead of put as there would be different intepretation for different API
448
+ if (response.code == 'OK') {
449
+ return createCommonResult(response);
450
+ } else {
451
+ if (response.error && response.error.error == "COM.CRM.EXCEPTIONS.ORDERS.CANNOTFULFILLORDEREXCEPTION"
452
+ || response.error && response.error.error == "COM.CRM.EXCEPTIONS.CANNOTFULFILLORDEREXCEPTION" || response.error && response.error.error == "CRM.EXCEPTIONS.CANNOTFULFILLORDEREXCEPTION") {
453
+ return createResult(ErrorCodes.CAN_NOT_FULFILL_ORDER_EXCEPTION, response.error);
454
+ }
455
+ return createCommonResult(response);
456
+ }
457
+ } catch (e) {
458
+ logger.error('Exception orderFulfillment:', e);
459
+ return createResult(ErrorCodes.UNKNOWN, e);
460
+ }
461
+ }
462
+
463
+ async function estimateOrder({
464
+ account_id,
465
+ supply_method,
466
+ fulfilled_by,
467
+ requested_delivery_at,
468
+ address_id,
469
+ notes,
470
+ queue_id,
471
+ use_wallet_funds,
472
+ wallet_funds_amount,
473
+ payment_method_type,
474
+ discount,
475
+ milestones,
476
+ line_items,
477
+ current_location,
478
+ estimation_id,
479
+ preferred_billing_day
480
+ } = {}) {
481
+ try {
482
+ if (!account_id) {
483
+ let primeAccRes = await account.getPrimaryAccount();
484
+ if (primeAccRes.code != ErrorCodes.OK)
485
+ return primeAccRes;
486
+ if (!primeAccRes.data.content && primeAccRes.data.content.size() == 0)
487
+ return createResult(ErrorCodes.ACCOUNT_NOT_FOUND, response.error);
488
+ account_id = primeAccRes.data.content[0].id;
489
+ }
490
+ let response = await httpUtil.post({
491
+ resourcePath: '/v2/estimates/orders',
492
+ body: {
493
+ account_id,
494
+ supply_method,
495
+ fulfilled_by,
496
+ requested_delivery_at,
497
+ address_id,
498
+ notes,
499
+ queue_id,
500
+ use_wallet_funds,
501
+ wallet_funds_amount,
502
+ payment_method_type,
503
+ discount,
504
+ milestones,
505
+ items: line_items,
506
+ current_location,
507
+ estimation_id,
508
+ preferred_billing_day
509
+ },
510
+ withAccessToken: true
511
+ });
512
+ //check return code here instead of put as there would be different intepretation for different API
513
+ //console.log('response=1=====',response)
514
+ if (response.code == 'OK') {
515
+ return createCommonResult(response);
516
+ } else {
517
+ if (response.error && response.error.error == "COM.CRM.EXCEPTIONS.ORDERS.CANNOTFULFILLORDEREXCEPTION"
518
+ || response.error && response.error.error == "COM.CRM.EXCEPTIONS.CANNOTFULFILLORDEREXCEPTION" || response.error && response.error.error == "CRM.EXCEPTIONS.CANNOTFULFILLORDEREXCEPTION") {
519
+ return createResult(ErrorCodes.CAN_NOT_FULFILL_ORDER_EXCEPTION, response.error);
520
+ } else if (response.error && response.error.error == "COM.CRM.EXCEPTIONS.ORDERS.MINIMUMORDERAMOUNTNOTREACHEDEXCEPTION" || response.error && response.error.error == "COM.CRM.EXCEPTIONS.MINIMUMORDERAMOUNTNOTREACHEDEXCEPTION") {
521
+ return createResult(ErrorCodes.MINIMUM_ORDER_AMOUNT_NOT_REACHED, response.error);
522
+ }
523
+ else if (response.error && response.error.error == "COM.CRM.EXCEPTIONS.SERVICEALREADYEXISTSONSUBSCRIPTIONEXCEPTION") {
524
+ return createResult(ErrorCodes.SERVICE_ALREADY_EXIST, response.error);
525
+ }
526
+ else if (response.error && response.error.error == "FINANCE.EXCEPTIONS.CANNOTEXECUTEACTIONCREDITLIMITEXCEPTION") {
527
+ return createResult(ErrorCodes.CANNOTEXECUTEACTIONCREDITLIMITEXCEPTION, response.error);
528
+ }
529
+ else if (response.error && response.error.error == "CRM.EXCEPTIONS.CANNOTSPENDAMOUNTWALLETBALANCENOTENOUGHEXCEPTION") {
530
+ return createResult(ErrorCodes.CANNOTSPENDAMOUNTWALLETBALANCENOTENOUGHEXCEPTION, response.error);
531
+ } else if (response.error && response.error.error == "COM.CRM.EXCEPTIONS.CANNOTEXECUTESUBSCRIPTIONACTIONEXCEPTION") {
532
+ return createResult(ErrorCodes.CANNOTEXECUTESUBSCRIPTIONACTIONEXCEPTION, response.error);
533
+ }
534
+ return createCommonResult(response);
535
+ }
536
+ } catch (e) {
537
+ logger.error('Exception estimateOrder:', e);
538
+ return createResult(ErrorCodes.UNKNOWN, e);
539
+ }
540
+ }
541
+
542
+ async function makeOrder({
543
+ estimation_id,
544
+ use_wallet_funds,
545
+ wallet_funds_amount,
546
+ notes,
547
+ intent_id,
548
+ use_account_funds,
549
+ account_funds_amount,
550
+ payments,
551
+ devices,
552
+ custom_fields,
553
+ pass
554
+ }) {
555
+ try {
556
+ let response = await httpUtil.post({
557
+ resourcePath: '/v2/orders',
558
+ body: {
559
+ estimation_id,
560
+ use_wallet_funds,
561
+ wallet_funds_amount,
562
+ notes,
563
+ intent_id,
564
+ use_account_funds,
565
+ account_funds_amount,
566
+ payments,
567
+ devices,
568
+ custom_fields,
569
+ pass
570
+ },
571
+ withAccessToken: true
572
+ });
573
+ if (response.code == 'OK') {
574
+ return createCommonResult(response);
575
+ } else {
576
+ if (response.error && response.error.error == "COM.CRM.EXCEPTIONS.ORDERS.CANNOTFULFILLORDEREXCEPTION"
577
+ || response.error && response.error.error == "COM.CRM.EXCEPTIONS.CANNOTFULFILLORDEREXCEPTION" || response.error && response.error.error == "CRM.EXCEPTIONS.CANNOTFULFILLORDEREXCEPTION") {
578
+ return createResult(ErrorCodes.CAN_NOT_FULFILL_ORDER_EXCEPTION, response.error);
579
+ } else if (response.error && response.error.error == "COM.CRM.EXCEPTIONS.ORDERS.MINIMUMORDERAMOUNTNOTREACHEDEXCEPTION" || response.error && response.error.error == "COM.CRM.EXCEPTIONS.MINIMUMORDERAMOUNTNOTREACHEDEXCEPTION") {
580
+ return createResult(ErrorCodes.MINIMUM_ORDER_AMOUNT_NOT_REACHED, response.error);
581
+ }
582
+ else if (response.error && response.error.error == "FINANCE.EXCEPTIONS.CANNOTEXECUTEACTIONCREDITLIMITEXCEPTION") {
583
+ return createResult(ErrorCodes.CANNOTEXECUTEACTIONCREDITLIMITEXCEPTION, response.error);
584
+ }
585
+ return createCommonResult(response);
586
+ }
587
+ } catch (e) {
588
+ logger.error('Exception addDevice:', e);
589
+ return createResult(ErrorCodes.UNKNOWN, e);
590
+ }
591
+ }
592
+
593
+ async function getOrdersRecommendation({
594
+ estimation_id,
595
+ include_creatives,
596
+ include_cross_sells,
597
+ include_upsells,
598
+ include_reward_offers,
599
+ include_promotions,
600
+ order_catalogue_ids,
601
+ } = {}) {
602
+ try {
603
+ let response = await httpUtil.get({
604
+ resourcePath: '/v2/orders/recommendation',
605
+ queryParams: {
606
+ estimation_id,
607
+ include_creatives,
608
+ include_cross_sells,
609
+ include_upsells,
610
+ include_reward_offers,
611
+ include_promotions,
612
+ order_catalogue_ids,
613
+ },
614
+ withAccessToken: true
615
+ });
616
+ return createCommonResult(response);
617
+ } catch (e) {
618
+ logger.error('Exception getOrdersRecommendation:', e);
619
+ return createResult(ErrorCodes.UNKNOWN, e);
620
+ }
621
+ }
622
+
623
+ async function getServicesRecommendation({
624
+ contact_id,
625
+ product_id,
626
+ include_components,
627
+ price_terms_id,
628
+ account_id,
629
+ billing_period_duration,
630
+ billing_period_uot,
631
+ include_creatives,
632
+ include_total,
633
+ order,
634
+ page = 1,
635
+ size = 10,
636
+ sort,
637
+ organisation_id,
638
+ search_value,
639
+ service_id,
640
+ subscription_id,
641
+ } = {}) {
642
+ try {
643
+ let id = await httpUtil.getSession().sub;
644
+ if(!contact_id) contact_id = id;
645
+ let response = await httpUtil.get({
646
+ resourcePath: '/v2/services/recommendation',
647
+ queryParams: {
648
+ contact_id,
649
+ account_id,
650
+ product_id,
651
+ include_components,
652
+ price_terms_id,
653
+ billing_period_duration,
654
+ billing_period_uot,
655
+ include_creatives,
656
+ include_total,
657
+ order,
658
+ page,
659
+ size,
660
+ organisation_id,
661
+ search_value,
662
+ service_id,
663
+ sort,
664
+ subscription_id,
665
+ },
666
+ withAccessToken: true
667
+ });
668
+ return createCommonResult(response);
669
+ } catch (e) {
670
+ logger.error('Exception getServicesRecommendation:', e);
671
+ return createResult(ErrorCodes.UNKNOWN, e);
672
+ }
673
+ }
674
+
675
+ async function getProductTypes({
676
+ classifications,
677
+ include_total,
678
+ name,
679
+ search_value,
680
+ page = 1,
681
+ size = 100,
682
+ sort = 'name',//='UPDATED_DATE',
683
+ order = 'ASC', //='DESC'
684
+ } = {},) {
685
+ try {
686
+ let query = {
687
+ classifications,
688
+ include_total,
689
+ name,
690
+ search_value,
691
+ page,
692
+ size,
693
+ sort,
694
+ order,
695
+ }
696
+ let response = await httpUtil.get({
697
+ resourcePath: '/v2/products/types',
698
+ withAccessToken: true,
699
+ queryParams: query
700
+ });
701
+ return createCommonResult(response);
702
+ } catch (e) {
703
+ logger.error('Exception getProductTypes:', e);
704
+ return createResult(ErrorCodes.UNKNOWN, e);
705
+ }
706
+ }
707
+
708
+ async function getProductsRecommendation({
709
+ contact_id,
710
+ size = 5,
711
+ category_type,
712
+ category_id,
713
+ } = {}) {
714
+ try {
715
+ let id = await httpUtil.getSession().sub;
716
+ if(!contact_id) contact_id = id;
717
+ let response = await httpUtil.get({
718
+ resourcePath: '/v2/products/recommendation',
719
+ queryParams: {
720
+ contact_id,
721
+ size,
722
+ category_type,
723
+ category_id,
724
+ },
725
+ withAccessToken: true
726
+ });
727
+ return createCommonResult(response);
728
+ } catch (e) {
729
+ logger.error('Exception getProductsRecommendation:', e);
730
+ return createResult(ErrorCodes.UNKNOWN, e);
731
+ }
732
+ }