@things-factory/integration-sellercraft 8.0.0-beta.8 → 8.0.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.
Files changed (51) hide show
  1. package/dist-server/tsconfig.tsbuildinfo +1 -1
  2. package/package.json +14 -14
  3. package/server/constants/index.ts +2 -0
  4. package/server/constants/order-status-mapping.ts +28 -0
  5. package/server/constants/platform.ts +6 -0
  6. package/server/controllers/index.ts +5 -0
  7. package/server/controllers/sellercraft/apis/add-inbound-order.ts +50 -0
  8. package/server/controllers/sellercraft/apis/echo.ts +14 -0
  9. package/server/controllers/sellercraft/apis/fetch-order-document.ts +18 -0
  10. package/server/controllers/sellercraft/apis/index.ts +8 -0
  11. package/server/controllers/sellercraft/apis/initiate-order-document.ts +17 -0
  12. package/server/controllers/sellercraft/apis/initiate-order-shipment.ts +29 -0
  13. package/server/controllers/sellercraft/apis/pack-marketplace-order.ts +35 -0
  14. package/server/controllers/sellercraft/apis/update-marketplace-order.ts +14 -0
  15. package/server/controllers/sellercraft/apis/update-product.ts +21 -0
  16. package/server/controllers/sellercraft/index.ts +7 -0
  17. package/server/controllers/sellercraft/platform-action.ts +39 -0
  18. package/server/controllers/sellercraft/sellercraft.ts +109 -0
  19. package/server/controllers/sellercraft-api/decorators.ts +52 -0
  20. package/server/controllers/sellercraft-api/index.ts +51 -0
  21. package/server/controllers/sellercraft-api/types.ts +0 -0
  22. package/server/controllers/sellercraft-channel-integration/apis/echo.ts +14 -0
  23. package/server/controllers/sellercraft-channel-integration/apis/index.ts +6 -0
  24. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-categories.ts +37 -0
  25. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-category-attributes.ts +65 -0
  26. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-order-package.ts +62 -0
  27. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-order.ts +92 -0
  28. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-product.ts +97 -0
  29. package/server/controllers/sellercraft-channel-integration/index.ts +7 -0
  30. package/server/controllers/sellercraft-channel-integration/platform-action.ts +39 -0
  31. package/server/controllers/sellercraft-channel-integration/sellercraft-channel-integration.ts +115 -0
  32. package/server/controllers/sellercraft-channel-integration-api/decorators.ts +45 -0
  33. package/server/controllers/sellercraft-channel-integration-api/index.ts +45 -0
  34. package/server/controllers/sellercraft-channel-integration-api/types.ts +0 -0
  35. package/server/index.ts +7 -0
  36. package/server/middlewares/index.ts +3 -0
  37. package/server/migrations/index.ts +9 -0
  38. package/server/routers/sellercraft-router.ts +326 -0
  39. package/server/routes.ts +32 -0
  40. package/server/service/index.ts +23 -0
  41. package/server/service/marketplace-channel/index.ts +6 -0
  42. package/server/service/marketplace-channel/marketplace-channel-order-mutation.ts +456 -0
  43. package/server/service/marketplace-channel/marketplace-channel-product-mutation.ts +282 -0
  44. package/server/service/marketplace-channel/marketplace-channel.ts +76 -0
  45. package/server/service/sellercraft/index.ts +6 -0
  46. package/server/service/sellercraft/sellercraft-mutation.ts +126 -0
  47. package/server/service/sellercraft/sellercraft-query.ts +43 -0
  48. package/server/service/sellercraft/sellercraft-type.ts +54 -0
  49. package/server/service/sellercraft/sellercraft.ts +96 -0
  50. package/server/utils/tokencraft-util.ts +60 -0
  51. package/tsconfig.json +9 -0
@@ -0,0 +1,456 @@
1
+ import { Arg, Ctx, Mutation, Resolver } from 'type-graphql'
2
+
3
+ import { StoreAPI } from '@things-factory/integration-marketplace'
4
+ import { getRepository } from '@things-factory/shell'
5
+
6
+ import { SHIPPING_TYPE } from '../../constants'
7
+ import { SellercraftChannelIntegrationAPI } from '../../controllers/sellercraft-channel-integration-api'
8
+ import { getShops } from '../../utils/tokencraft-util'
9
+ import { MarketplaceChannel } from './marketplace-channel'
10
+
11
+ @Resolver()
12
+ export class MarketplaceChannelOrderMutation {
13
+ @Mutation(returns => Boolean)
14
+ async syncAllMarketplaceChannelOrders(
15
+ @Ctx() context: ResolverContext,
16
+ @Arg('fromCreatedDate', { nullable: true }) fromCreatedDate?: string,
17
+ @Arg('toCreatedDate', { nullable: true }) toCreatedDate?: string,
18
+ @Arg('fromUpdatedDate', { nullable: true }) fromUpdatedDate?: string,
19
+ @Arg('toUpdatedDate', { nullable: true }) toUpdatedDate?: string,
20
+ @Arg('channelId', { nullable: true }) channelId?: string,
21
+ @Arg('shopId', { nullable: true }) shopId?: string,
22
+ @Arg('airflow', { nullable: true }) airflow?: boolean
23
+ ): Promise<boolean> {
24
+ let channels: MarketplaceChannel[] = await getRepository(MarketplaceChannel).find({ where: { isActive: true } })
25
+ let errors: any = []
26
+
27
+ if (channelId) {
28
+ channels = channels.filter(channel => channel.channelId == channelId)
29
+ }
30
+
31
+ for (var i = 0; i < channels.length; i++) {
32
+ try {
33
+ const channel: MarketplaceChannel = channels[i]
34
+ let shops: any = await getShops(channel.channelId)
35
+
36
+ if (shopId) {
37
+ shops = shops.filter(shop => shop.channel_shop_id == shopId)
38
+ }
39
+
40
+ for (var j = 0; j < shops.length; j++) {
41
+ try {
42
+ var store = {
43
+ accessKey: shops[j]?.credential?.consumer_key || '',
44
+ accessSecret: shops[j]?.credential?.consumer_secret || '',
45
+ storeURL: shops[j]?.credential?.store_url || '',
46
+ platform: channel.name,
47
+ accessToken: shops[j]?.credential?.access_token, // Magento+, Tiktok
48
+ channelShopId: shops[j]?.channel_shop_id,
49
+ storeId: shops[j]?.credential?.store_url || ''
50
+ }
51
+
52
+ // let countryCode = shops[j].country_code
53
+ // let channelCode = shops[j].org_prefix
54
+ let organisationId = shops[j].account_id
55
+ let channelShopId = shops[j].channel_shop_id
56
+
57
+ let orderResult = []
58
+ let page: number = store.platform == 'magento' ? 1 : 0
59
+ let hasMorePage: boolean = true
60
+ let lastOrderId: string
61
+ let cursor: string
62
+ var limit: number = 20
63
+
64
+ while (hasMorePage) {
65
+ const {
66
+ results: marketplaceOrders,
67
+ more,
68
+ nextCursor
69
+ } = await StoreAPI.getStoreOrders(store, {
70
+ fromCreatedDate,
71
+ toCreatedDate,
72
+ fromUpdatedDate,
73
+ toUpdatedDate,
74
+ pagination: { page, limit },
75
+ lastOrderId,
76
+ nextCursor: cursor
77
+ })
78
+
79
+ var sellercraftStore = { ...store, platform: 'sellercraftChannelIntegration' }
80
+
81
+ let mappedOrderResult = marketplaceOrders.map(order => {
82
+ let id = store.platform == 'magento' || store.platform == 'shopify' ? order.name : order.orderNo
83
+ let {
84
+ firstName: custFirstName,
85
+ lastName: custLastName,
86
+ orderCreatedAt: createdAt,
87
+ orderUpdatedAt: updatedAt,
88
+ status,
89
+ sellercraftStatus,
90
+ isSOF,
91
+ orderLineList,
92
+ sellercraftDisplayOrderNo
93
+ } = order
94
+
95
+ let {
96
+ first_name: billFirstName,
97
+ last_name: billLastName,
98
+ address_1: billAddress1,
99
+ address_2: billAddress2,
100
+ address_3: billAddress3,
101
+ address_4: billAddress4,
102
+ address_5: billAddress5,
103
+ city: billCity,
104
+ postcode: billPostalCode,
105
+ country: billCountry,
106
+ phone: billPhone1,
107
+ phone_2: billPhone2
108
+ } = order?.billing
109
+
110
+ let {
111
+ first_name: shipFirstName,
112
+ last_name: shipLastName,
113
+ address_1: shipAddress1,
114
+ address_2: shipAddress2,
115
+ address_3: shipAddress3,
116
+ address_4: shipAddress4,
117
+ address_5: shipAddress5,
118
+ city: shipCity,
119
+ postcode: shipPostalCode,
120
+ country: shipCountry,
121
+ phone: shipPhone1,
122
+ phone_2: shipPhone2
123
+ } = order.shipping
124
+
125
+ let orderPackage = order?.orderPackage || {}
126
+
127
+ let orderItems = order.orderItems.map(item => {
128
+ let {
129
+ name: id,
130
+ variationId: variationId,
131
+ slaExpiresAt,
132
+ total,
133
+ totalTax,
134
+ subtotal,
135
+ subtotalTax,
136
+ qty
137
+ } = item
138
+
139
+ return {
140
+ id,
141
+ variationId,
142
+ currency: order.orderShipping.collectionCurrency,
143
+ createdAt: order.orderCreatedAt,
144
+ updatedAt: order.orderUpdatedAt,
145
+ charges: [
146
+ {
147
+ name: 'CHARGES_MARKETING',
148
+ grossAmount: 0,
149
+ nettAmount: 0
150
+ },
151
+ {
152
+ name: 'CLAIMS_DAMAGE',
153
+ grossAmount: 0,
154
+ nettAmount: 0
155
+ },
156
+ {
157
+ name: 'CLAIMS_LOST',
158
+ grossAmount: 0,
159
+ nettAmount: 0
160
+ },
161
+ {
162
+ name: 'COMMISSION_PLATFORM',
163
+ grossAmount: 0,
164
+ nettAmount: 0
165
+ },
166
+ {
167
+ name: 'DEPOSIT_PRESALE',
168
+ grossAmount: 0,
169
+ nettAmount: 0
170
+ },
171
+ {
172
+ name: 'FEE_MISCELLANEOUS',
173
+ grossAmount: 0,
174
+ nettAmount: 0
175
+ },
176
+ {
177
+ name: 'FEE_TRANSACTION',
178
+ grossAmount: 0,
179
+ nettAmount: 0
180
+ },
181
+ {
182
+ name: 'PRICE_NORMAL_SELLING',
183
+ grossAmount: total,
184
+ nettAmount: subtotal
185
+ },
186
+ {
187
+ name: 'PRICE_RECOMMENDED_RETAIL',
188
+ grossAmount: 0,
189
+ nettAmount: 0
190
+ },
191
+ {
192
+ name: 'PROMOTIONS_CUSTOMER_RECEIVED',
193
+ grossAmount: 0,
194
+ nettAmount: 0
195
+ },
196
+ {
197
+ name: 'PROMOTIONS_REBATE_PLATFORM',
198
+ grossAmount: 0,
199
+ nettAmount: 0
200
+ },
201
+ {
202
+ name: 'PROMOTIONS_REBATE_SELLER',
203
+ grossAmount: 0,
204
+ nettAmount: 0
205
+ },
206
+ {
207
+ name: 'REVERSAL_CHARGES_MARKETING',
208
+ grossAmount: 0,
209
+ nettAmount: 0
210
+ },
211
+ {
212
+ name: 'REVERSAL_COMMISSION',
213
+ grossAmount: 0,
214
+ nettAmount: 0
215
+ },
216
+ {
217
+ name: 'REVERSAL_FEE_MISCELLANEOUS',
218
+ grossAmount: 0,
219
+ nettAmount: 0
220
+ },
221
+ {
222
+ name: 'REVERSAL_PROMOTIONS_CUSTOMER_RECEIVED',
223
+ grossAmount: 0,
224
+ nettAmount: 0
225
+ },
226
+ {
227
+ name: 'REVERSAL_SELLER_RETURN_REFUND_AMOUNT',
228
+ grossAmount: 0,
229
+ nettAmount: 0
230
+ },
231
+ {
232
+ name: 'REVERSAL_SHIPPING_CUSTOMER_PAID',
233
+ grossAmount: 0,
234
+ nettAmount: 0
235
+ },
236
+ {
237
+ name: 'REVERSAL_SHIPPING_REBATE_PLATFORM',
238
+ grossAmount: 0,
239
+ nettAmount: 0
240
+ },
241
+ {
242
+ name: 'REVERSAL_SHIPPING_SELLER_PAID',
243
+ grossAmount: 0,
244
+ nettAmount: 0
245
+ },
246
+ {
247
+ name: 'SHIPPING_COST_TOTAL',
248
+ grossAmount: 0,
249
+ nettAmount: 0
250
+ },
251
+ {
252
+ name: 'SHIPPING_CUSTOMER_PAID',
253
+ grossAmount: 0,
254
+ nettAmount: 0
255
+ },
256
+ {
257
+ name: 'SHIPPING_REBATE_PLATFORM',
258
+ grossAmount: 0,
259
+ nettAmount: 0
260
+ },
261
+ {
262
+ name: 'SHIPPING_SELLER_PAID',
263
+ grossAmount: 0,
264
+ nettAmount: 0
265
+ },
266
+ {
267
+ name: 'TAXES',
268
+ grossAmount: totalTax,
269
+ nettAmount: subtotalTax
270
+ },
271
+ {
272
+ name: 'VOUCHERS_CUSTOMER_RECEIVED',
273
+ grossAmount: 0,
274
+ nettAmount: 0
275
+ },
276
+ {
277
+ name: 'VOUCHERS_REBATE_PLATFORM',
278
+ grossAmount: 0,
279
+ nettAmount: 0
280
+ },
281
+ {
282
+ name: 'VOUCHERS_REBATE_SELLER',
283
+ grossAmount: 0,
284
+ nettAmount: 0
285
+ }
286
+ ],
287
+ slaExpiresAt,
288
+ qty
289
+ }
290
+ })
291
+
292
+ let mappedOrderItems = []
293
+ orderItems.map(oi => {
294
+ for (let i = 0; i < oi.qty; i++) {
295
+ let orderLine
296
+ if (orderLineList) {
297
+ orderLine = orderLineList?.find(ol => ol.sku_id == oi.variationId) || null
298
+ orderLineList = orderLineList.filter(ol => ol.order_line_id != orderLine.order_line_id)
299
+ }
300
+ mappedOrderItems.push({
301
+ ...oi,
302
+ id: orderLine ? orderLine.order_line_id : `${oi.id}-${i + 1}`
303
+ })
304
+ }
305
+ })
306
+
307
+ return {
308
+ custFirstName,
309
+ custLastName,
310
+ createdAt,
311
+ updatedAt,
312
+ id,
313
+ sellercraftDisplayOrderNo,
314
+ billFirstName,
315
+ billLastName,
316
+ billAddress1: billAddress1?.toString() || shipAddress1?.toString(),
317
+ billAddress2: billAddress2 || shipAddress2,
318
+ billAddress3: billAddress3 || shipAddress3,
319
+ billAddress4: billAddress4 || shipAddress4,
320
+ billAddress5: billAddress5 || shipAddress5,
321
+ billCity: billCity || shipCity,
322
+ billPostalCode: billPostalCode || shipPostalCode,
323
+ billCountry: billCountry || shipCountry,
324
+ billPhone1: billPhone1 || shipPhone1,
325
+ billPhone2: billPhone2 || shipPhone2,
326
+ shipFirstName,
327
+ shipLastName,
328
+ shipAddress1: shipAddress1?.toString(),
329
+ shipAddress2,
330
+ shipAddress3,
331
+ shipAddress4,
332
+ shipAddress5,
333
+ shipCity,
334
+ shipPostalCode,
335
+ shipCountry,
336
+ shipPhone1,
337
+ shipPhone2,
338
+ mappedOrderItems,
339
+ channelShopId,
340
+ organisationId,
341
+ status: sellercraftStatus || status,
342
+ isSOF: isSOF ? isSOF : false,
343
+ orderPackage,
344
+ charges: getOrderCharges(mappedOrderItems)
345
+ }
346
+ })
347
+
348
+ if (mappedOrderResult.length > 0) {
349
+ while (mappedOrderResult.length > 0) {
350
+ let spliceResult = mappedOrderResult.splice(
351
+ 0,
352
+ mappedOrderResult.length >= 20 ? 20 : mappedOrderResult.length
353
+ )
354
+
355
+ try {
356
+ await SellercraftChannelIntegrationAPI.ingestChannelOrder(sellercraftStore, {
357
+ orders: spliceResult
358
+ })
359
+ } catch (e) {
360
+ errors.push({
361
+ name: 'Order Ingestion Error',
362
+ msg: JSON.stringify(e) || {}
363
+ })
364
+ }
365
+
366
+ await Promise.all(
367
+ spliceResult.map(async result => {
368
+ if (!result?.isSOF && result?.orderPackage?.packageId) {
369
+ let orderPackage: any = result.orderPackage
370
+ let newOrderPackage: any = {
371
+ channelShopId,
372
+ nativeOrderId: result.id,
373
+ nativePackageId: orderPackage.packageId,
374
+ shippingTrackingCode: orderPackage.trackingNumber,
375
+ shippingTypeValue: orderPackage?.shippingType
376
+ ? orderPackage.shippingType
377
+ : SHIPPING_TYPE.DROP_SHIPPING,
378
+ warehouseCode: SHIPPING_TYPE.DROP_SHIPPING,
379
+ shipper: {
380
+ name: orderPackage.shippingProvider,
381
+ isCodSupported: orderPackage?.isCodSupport ? orderPackage.isCodSupport : false
382
+ },
383
+ documents: orderPackage?.orderDocument || [],
384
+ shipperLastMile: {
385
+ name: orderPackage.shippingProvider,
386
+ isCodSupported: orderPackage?.isCodSupport ? orderPackage.isCodSupport : false
387
+ },
388
+ orderItemIds: orderPackage?.orderListIdList
389
+ ? orderPackage.orderListIdList
390
+ : result.mappedOrderItems.map(orderItem => orderItem.id)
391
+ }
392
+ try {
393
+ await SellercraftChannelIntegrationAPI.ingestChannelOrderPackage(
394
+ sellercraftStore,
395
+ newOrderPackage
396
+ )
397
+ } catch (e) {
398
+ errors.push({
399
+ name: 'Order Package Ingestion Error',
400
+ msg: JSON.stringify(e) || {}
401
+ })
402
+ }
403
+ }
404
+ })
405
+ )
406
+ }
407
+ }
408
+
409
+ if (more) page++
410
+ hasMorePage = more
411
+ cursor = nextCursor
412
+ }
413
+ } catch (e) {
414
+ errors.push({
415
+ name: 'Order Processing / Mapping Error',
416
+ msg: JSON.stringify(e) || {}
417
+ })
418
+ }
419
+ }
420
+ } catch (e) {
421
+ errors.push({
422
+ name: 'Store Error',
423
+ msg: JSON.stringify(e) || {}
424
+ })
425
+ }
426
+ }
427
+ if (errors.length > 1 && airflow) {
428
+ throw errors
429
+ }
430
+ return true
431
+ }
432
+ }
433
+
434
+ function getOrderCharges(mappedOrderItems) {
435
+ let chargesList = []
436
+
437
+ for (let i = 0; i < mappedOrderItems.length; i++) {
438
+ for (let j = 0; j < mappedOrderItems[i].charges.length; j++) {
439
+ let charge = mappedOrderItems[i].charges[j]
440
+ let foundCharge = chargesList.find(cl => cl.name == charge.name)
441
+ if (foundCharge) {
442
+ foundCharge.grossAmount = parseFloat(foundCharge.grossAmount) + parseFloat(charge.grossAmount)
443
+ foundCharge.nettAmount = parseFloat(foundCharge.nettAmount) + parseFloat(charge.nettAmount)
444
+ chargesList = chargesList.filter(cl => cl.name != charge.name)
445
+ } else {
446
+ foundCharge = {
447
+ name: charge.name,
448
+ grossAmount: charge.grossAmount,
449
+ nettAmount: charge.nettAmount
450
+ }
451
+ }
452
+ chargesList.push(foundCharge)
453
+ }
454
+ }
455
+ return chargesList
456
+ }