@things-factory/integration-sellercraft 5.0.0-alpha.4 → 5.0.0-alpha.42

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 (48) hide show
  1. package/dist-server/constants/index.js +1 -0
  2. package/dist-server/constants/index.js.map +1 -1
  3. package/dist-server/constants/order-status-mapping.js +28 -0
  4. package/dist-server/constants/order-status-mapping.js.map +1 -0
  5. package/dist-server/constants/platform.js +3 -1
  6. package/dist-server/constants/platform.js.map +1 -1
  7. package/dist-server/controllers/index.js +2 -0
  8. package/dist-server/controllers/index.js.map +1 -1
  9. package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-categories.js +19 -20
  10. package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-categories.js.map +1 -1
  11. package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-order-package.js +5 -2
  12. package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-order-package.js.map +1 -1
  13. package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-order.js +29 -19
  14. package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-order.js.map +1 -1
  15. package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-product.js +24 -40
  16. package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-product.js.map +1 -1
  17. package/dist-server/controllers/sellercraft-channel-integration/sellercraft-channel-integration.js +9 -5
  18. package/dist-server/controllers/sellercraft-channel-integration/sellercraft-channel-integration.js.map +1 -1
  19. package/dist-server/routers/sellercraft-router.js +220 -84
  20. package/dist-server/routers/sellercraft-router.js.map +1 -1
  21. package/dist-server/service/index.js +5 -1
  22. package/dist-server/service/index.js.map +1 -1
  23. package/dist-server/service/marketplace-channel/index.js +9 -0
  24. package/dist-server/service/marketplace-channel/index.js.map +1 -0
  25. package/dist-server/service/marketplace-channel/marketplace-channel-order-mutation.js +364 -0
  26. package/dist-server/service/marketplace-channel/marketplace-channel-order-mutation.js.map +1 -0
  27. package/dist-server/service/marketplace-channel/marketplace-channel-product-mutation.js +207 -0
  28. package/dist-server/service/marketplace-channel/marketplace-channel-product-mutation.js.map +1 -0
  29. package/dist-server/service/marketplace-channel/marketplace-channel.js +88 -0
  30. package/dist-server/service/marketplace-channel/marketplace-channel.js.map +1 -0
  31. package/dist-server/service/sellercraft/sellercraft.js +1 -1
  32. package/package.json +15 -15
  33. package/server/constants/index.ts +2 -1
  34. package/server/constants/order-status-mapping.ts +25 -0
  35. package/server/constants/platform.ts +3 -1
  36. package/server/controllers/index.ts +2 -0
  37. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-categories.ts +19 -20
  38. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-order-package.ts +6 -2
  39. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-order.ts +30 -19
  40. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-product.ts +32 -47
  41. package/server/controllers/sellercraft-channel-integration/sellercraft-channel-integration.ts +9 -5
  42. package/server/routers/sellercraft-router.ts +225 -87
  43. package/server/service/index.ts +6 -1
  44. package/server/service/marketplace-channel/index.ts +6 -0
  45. package/server/service/marketplace-channel/marketplace-channel-order-mutation.ts +412 -0
  46. package/server/service/marketplace-channel/marketplace-channel-product-mutation.ts +218 -0
  47. package/server/service/marketplace-channel/marketplace-channel.ts +68 -0
  48. package/server/service/sellercraft/sellercraft.ts +1 -1
@@ -1,8 +1,10 @@
1
1
  import Router from 'koa-router'
2
+ import uuid from 'uuid/v4'
2
3
 
3
4
  import { config } from '@things-factory/env'
4
5
  import { StoreAPI } from '@things-factory/integration-marketplace'
5
- import { PLATFORM } from '../constants'
6
+
7
+ import { PLATFORM, SHIPPING_TYPE } from '../constants'
6
8
 
7
9
  const debug = require('debug')('things-factory:integration-sellercraft:sellercraft-router')
8
10
 
@@ -10,7 +12,7 @@ export const sellercraftRouter = new Router()
10
12
 
11
13
  sellercraftRouter.post('/sellercraft/store/update-product-price', async (context, next) => {
12
14
  const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
13
- const { apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
15
+ const { tokenCraftApiKey: apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
14
16
 
15
17
  const xApiKey = context.headers['x-api-key']
16
18
 
@@ -23,7 +25,7 @@ sellercraftRouter.post('/sellercraft/store/update-product-price', async (context
23
25
  var result
24
26
 
25
27
  // https://staging-tokencraft.sellercraft.co/v1/get-shop?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=dd9cf3b7-114f-4d74-a7e2-7b524ae086f2
26
- var fullPath = tokenCraftUrl + '?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=' + requestBody[i].shop_id
28
+ var fullPath = `${tokenCraftUrl}?channel_id=${requestBody[i].channel_id}&shop_id=${requestBody[i].shop_id}`
27
29
  const response: any = await fetch(fullPath, {
28
30
  method: 'get',
29
31
  headers: {
@@ -36,38 +38,50 @@ sellercraftRouter.post('/sellercraft/store/update-product-price', async (context
36
38
  }
37
39
 
38
40
  let mappedStore: any = {
39
- accessKey: store.shop.credential.consumer_key,
40
- accessSecret: store.shop.credential.consumer_secret,
41
- storeURL: store.shop.credential.store_url,
42
- platform: PLATFORM[`${store.shop.org_prefix}`]
41
+ accessKey: store.shop?.credential?.consumer_key || '',
42
+ accessSecret: store.shop?.credential?.consumer_secret || '',
43
+ storeURL: store.shop?.credential?.store_url,
44
+ platform: PLATFORM[`${store.shop.org_prefix}`],
45
+ accessToken: store.shop?.credential?.access_token,
46
+ channelShopId: store.shop?.channel_shop_id
43
47
  }
44
48
 
45
- if (requestBody[i].native_variant_id) {
46
- const req = {
47
- costPrice: requestBody[i].full_price,
48
- sellPrice: requestBody[i].sale_price,
49
- productId: requestBody[i].native_product_id,
50
- variationId: requestBody[i].native_variant_id
51
- }
52
- result = await StoreAPI.updateStoreProductVariationPrice(mappedStore, req)
53
- } else {
54
- const req = {
55
- costPrice: requestBody[i].full_price,
56
- sellPrice: requestBody[i].sale_price,
57
- productId: requestBody[i].native_product_id
49
+ try {
50
+ if (requestBody[i].native_variant_id != requestBody[i].native_product_id) {
51
+ const req = {
52
+ costPrice: requestBody[i].full_price,
53
+ sellPrice: requestBody[i].sale_price,
54
+ productId: requestBody[i].native_product_id,
55
+ variationId: requestBody[i].native_variant_id,
56
+ variationSku: requestBody[i].sku
57
+ }
58
+ result = await StoreAPI.updateStoreProductVariationPrice(mappedStore, req)
59
+ } else {
60
+ const req = {
61
+ costPrice: requestBody[i].full_price,
62
+ sellPrice: requestBody[i].sale_price,
63
+ productId: requestBody[i].native_product_id,
64
+ variationSku: requestBody[i].sku
65
+ }
66
+ result = await StoreAPI.updateStoreProductPrice(mappedStore, req)
58
67
  }
59
- result = await StoreAPI.updateStoreProductPrice(mappedStore, req)
60
- }
61
68
 
62
- debug(result)
63
- }
69
+ debug(result)
64
70
 
65
- context.status = 200
71
+ context.type = 'application/json'
72
+ context.status = 200
73
+ context.body = 'Succeeded'
74
+ } catch (e) {
75
+ context.type = 'application/json'
76
+ context.status = 500
77
+ context.body = e.message
78
+ }
79
+ }
66
80
  })
67
81
 
68
82
  sellercraftRouter.post('/sellercraft/store/update-product-stock', async (context, next) => {
69
83
  const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
70
- const { apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
84
+ const { tokenCraftApiKey: apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
71
85
 
72
86
  const xApiKey = context.headers['x-api-key']
73
87
 
@@ -79,7 +93,7 @@ sellercraftRouter.post('/sellercraft/store/update-product-stock', async (context
79
93
  var result
80
94
 
81
95
  // https://staging-tokencraft.sellercraft.co/v1/get-shop?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=dd9cf3b7-114f-4d74-a7e2-7b524ae086f2
82
- var fullPath = tokenCraftUrl + '?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=' + requestBody[i].shop_id
96
+ var fullPath = `${tokenCraftUrl}?channel_id=${requestBody[i].channel_id}&shop_id=${requestBody[i].shop_id}`
83
97
  const response: any = await fetch(fullPath, {
84
98
  method: 'get',
85
99
  headers: {
@@ -92,75 +106,172 @@ sellercraftRouter.post('/sellercraft/store/update-product-stock', async (context
92
106
  }
93
107
 
94
108
  let mappedStore: any = {
95
- accessKey: store.shop.credential.consumer_key,
96
- accessSecret: store.shop.credential.consumer_secret,
97
- storeURL: store.shop.credential.store_url,
98
- platform: PLATFORM[`${store.shop.org_prefix}`]
109
+ accessKey: store.shop?.credential?.consumer_key || '',
110
+ accessSecret: store.shop?.credential?.consumer_secret || '',
111
+ storeURL: store.shop?.credential?.store_url,
112
+ platform: PLATFORM[`${store.shop.org_prefix}`],
113
+ accessToken: store.shop?.credential?.access_token,
114
+ channelShopId: store.shop?.channel_shop_id
99
115
  }
100
116
 
101
- if (requestBody[i].native_variant_id) {
102
- const req = {
103
- qty: requestBody[i].stock,
104
- itemId: requestBody[i].native_product_id,
105
- variationId: requestBody[i].native_variant_id
106
- }
107
- result = await StoreAPI.updateStoreProductVariationStock(mappedStore, req)
108
- } else {
109
- const req = {
110
- qty: requestBody[i].stock,
111
- itemId: requestBody[i].native_product_id
117
+ try {
118
+ if (requestBody[i].native_variant_id != requestBody[i].native_product_id) {
119
+ const req = {
120
+ qty: requestBody[i].stock,
121
+ itemId: requestBody[i].native_product_id,
122
+ variationId: requestBody[i].native_variant_id,
123
+ distributors: requestBody[i].distributors || [], // for Magento
124
+ variationSku: requestBody[i].sku
125
+ }
126
+ result = await StoreAPI.updateStoreProductVariationStock(mappedStore, req)
127
+ } else {
128
+ const req = {
129
+ qty: requestBody[i].stock,
130
+ itemId: requestBody[i].native_product_id,
131
+ distributors: requestBody[i].distributors || [], // for Magento
132
+ variationSku: requestBody[i].sku
133
+ }
134
+ result = await StoreAPI.updateStoreProductStock(mappedStore, req)
112
135
  }
113
- result = await StoreAPI.updateStoreProductStock(mappedStore, req)
114
- }
115
136
 
116
- debug(result)
137
+ debug(result)
138
+
139
+ context.type = 'application/json'
140
+ context.status = 200
141
+ context.body = 'Succeeded'
142
+ } catch (e) {
143
+ context.type = 'application/json'
144
+ context.status = 500
145
+ context.body = e.message
146
+ }
117
147
  }
118
- context.status = 200
119
148
  })
120
149
 
121
150
  sellercraftRouter.post('/sellercraft/store/update-order-status', async (context, next) => {
122
- const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
123
- const { apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
151
+ try {
152
+ const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
153
+ const { tokenCraftApiKey: apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
124
154
 
125
- const xApiKey = context.headers['x-api-key']
155
+ const xApiKey = context.headers['x-api-key']
126
156
 
127
- if (apiKey !== xApiKey) context.throw(400, 'api key validation failed')
157
+ if (apiKey !== xApiKey) context.throw(400, 'api key validation failed')
128
158
 
129
- const requestBody = context.request.body
130
- var result
131
- var store: any = {}
159
+ const requestBody = context.request.body
160
+ var result
161
+ var store: any = {}
132
162
 
133
- // https://staging-tokencraft.sellercraft.co/v1/get-shop?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=dd9cf3b7-114f-4d74-a7e2-7b524ae086f2
134
- var fullPath = tokenCraftUrl + '?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=' + requestBody.shop_id
135
- const response: any = await fetch(fullPath, {
136
- method: 'get',
137
- headers: {
138
- 'Content-Type': 'application/json',
139
- 'x-api-key': apiKey
163
+ // https://staging-tokencraft.sellercraft.co/v1/get-shop?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=dd9cf3b7-114f-4d74-a7e2-7b524ae086f2
164
+ var fullPath = `${tokenCraftUrl}?channel_id=${requestBody.channel_id}&shop_id=${requestBody.shop_id}`
165
+ const response: any = await fetch(fullPath, {
166
+ method: 'get',
167
+ headers: {
168
+ 'Content-Type': 'application/json',
169
+ 'x-api-key': apiKey
170
+ }
171
+ })
172
+ if (response.ok) {
173
+ store = await response.json()
140
174
  }
141
- })
142
- if (response.ok) {
143
- store = await response.json()
144
- }
145
175
 
146
- let mappedStore: any = {
147
- accessKey: store.shop.credential.consumer_key,
148
- accessSecret: store.shop.credential.consumer_secret,
149
- storeURL: store.shop.credential.store_url,
150
- platform: PLATFORM[`${store.shop.org_prefix}`]
151
- }
176
+ let mappedStore: any = {
177
+ accessKey: store.shop?.credential?.consumer_key || '',
178
+ accessSecret: store.shop?.credential?.consumer_secret || '',
179
+ storeURL: store.shop?.credential?.store_url,
180
+ platform: PLATFORM[`${store.shop.org_prefix}`],
181
+ accessToken: store.shop?.credential?.access_token,
182
+ channelShopId: store.shop?.channel_shop_id
183
+ }
152
184
 
153
- const reqBody = { orderId: requestBody.native_order_id, status: requestBody.order_status }
185
+ const reqBody = {
186
+ orderId: requestBody.native_order_id,
187
+ status: requestBody.order_status,
188
+ carrier: requestBody?.shipper_last_mile,
189
+ trackingNo: requestBody?.tracking_number,
190
+ orderItems: requestBody?.order_item_ids,
191
+ isSOF: requestBody?.seller_logistics
192
+ }
154
193
 
155
- result = await StoreAPI.updateOrderStatus(mappedStore, reqBody)
156
- debug(result)
194
+ let responseBody: any = { operation_id: uuid() }
195
+ try {
196
+ try {
197
+ result = await StoreAPI.updateOrderStatus(mappedStore, reqBody)
198
+ debug(result)
199
+ } catch (e) {}
200
+
201
+ if (result?.requiredDocument) {
202
+ // call document api and ingest channel order package
203
+ const order: any = await StoreAPI.getStoreOrder(mappedStore, { orderId: reqBody.orderId })
204
+ let orderPackage: any = order ? (order[0]?.orderPackage ? order[0].orderPackage : {}) : {}
205
+ if (orderPackage) {
206
+ const packageId: string = orderPackage.packageId
207
+
208
+ let orderDocument: any = orderPackage.orderDocument
209
+ if (orderDocument?.length == 0) {
210
+ let hasDocument: boolean = false
211
+ while (!hasDocument) {
212
+ orderDocument = await StoreAPI.getStoreOrderDocument(mappedStore, { packageId, documentType: 1 })
213
+ if (orderDocument?.length > 0) {
214
+ hasDocument = true
215
+ break
216
+ }
217
+ }
218
+ }
219
+
220
+ // Order Package Payload
221
+ let newOrderPackage: any =
222
+ {
223
+ channel_shop_id: mappedStore.channelShopId,
224
+ native_order_id: reqBody.orderId,
225
+ native_package_id: orderPackage.packageId.toString(),
226
+ shipping_tracking_code: orderPackage.trackingNumber,
227
+ shipping_type_value: orderPackage?.shippingType ? orderPackage.shippingType : SHIPPING_TYPE.DROP_SHIPPING,
228
+ warehouse_code: SHIPPING_TYPE.DROP_SHIPPING,
229
+ shipper: {
230
+ name: orderPackage.shippingProvider,
231
+ is_cod_supported: orderPackage?.isCodSupport ? orderPackage.isCodSupport : false
232
+ },
233
+ documents:
234
+ orderDocument.map(doc => {
235
+ return {
236
+ file: doc.file,
237
+ file_type_value: doc.fileTypeValue,
238
+ mime_type: doc.mimeType
239
+ }
240
+ }) || [],
241
+ shipper_last_mile: {
242
+ name: orderPackage.shippingProvider,
243
+ is_cod_supported: orderPackage?.isCodSupport ? orderPackage.isCodSupport : false
244
+ },
245
+ order_item_ids: orderPackage?.orderListIdList ? orderPackage.orderListIdList : reqBody.orderItems
246
+ } || {}
247
+
248
+ responseBody.package = newOrderPackage
249
+ }
250
+ responseBody.response_code = 'E0'
251
+ responseBody.message = 'Success'
252
+ }
253
+
254
+ responseBody.time = Math.floor(new Date(new Date().toUTCString()).getTime() / 1000)
255
+
256
+ context.type = 'application/json'
257
+ context.status = 200
258
+ context.body = responseBody
259
+
260
+ await next()
261
+ } catch (e) {
262
+ responseBody.response_code = 'E1'
263
+ responseBody.message = e.message
157
264
 
158
- context.status = 200
265
+ context.type = 'application/json'
266
+ context.status = 500
267
+ context.body = responseBody
268
+ }
269
+ } catch (e) {}
159
270
  })
160
271
 
161
272
  sellercraftRouter.post('/sellercraft/store/update-product-attribute', async (context, next) => {
162
273
  const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
163
- const { apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
274
+ const { tokenCraftApiKey: apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
164
275
 
165
276
  const xApiKey = context.headers['x-api-key']
166
277
 
@@ -168,10 +279,9 @@ sellercraftRouter.post('/sellercraft/store/update-product-attribute', async (con
168
279
 
169
280
  const requestBody = context.request.body
170
281
  var store: any = {}
171
- const attributes: any[] = requestBody.attributes
172
282
 
173
283
  // https://staging-tokencraft.sellercraft.co/v1/get-shop?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=dd9cf3b7-114f-4d74-a7e2-7b524ae086f2
174
- var fullPath = tokenCraftUrl + '?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=' + requestBody.shop_id
284
+ var fullPath = `${tokenCraftUrl}?channel_id=${requestBody.channel_id}&shop_id=${requestBody.shop_id}`
175
285
  const response: any = await fetch(fullPath, {
176
286
  method: 'get',
177
287
  headers: {
@@ -184,19 +294,47 @@ sellercraftRouter.post('/sellercraft/store/update-product-attribute', async (con
184
294
  }
185
295
 
186
296
  let mappedStore: any = {
187
- accessKey: store.shop.credential.consumer_key,
188
- accessSecret: store.shop.credential.consumer_secret,
189
- storeURL: store.shop.credential.store_url,
190
- platform: PLATFORM[`${store.shop.org_prefix}`]
297
+ accessKey: store.shop?.credential?.consumer_key || '',
298
+ accessSecret: store.shop?.credential?.consumer_secret || '',
299
+ storeURL: store.shop?.credential?.store_url,
300
+ platform: PLATFORM[`${store.shop.org_prefix}`],
301
+ accessToken: store.shop?.credential?.access_token,
302
+ channelShopId: store.shop?.channel_shop_id
191
303
  }
192
304
 
193
- await Promise.all(
194
- attributes.map(async attribute => {
195
- const attributeReqBody = { attributeId: attribute.native_attribute_id, name: attribute.attribute_key }
305
+ let { product_sku: productSku, native_product_id: itemId, variants } = requestBody
306
+
307
+ variants.map(variant => {
308
+ let { variant_sku: variantSku, native_variant_id: variantId, attributes } = variant
309
+
310
+ attributes.map(attribute => {
311
+ let { native_attribute_id: id, attribute_key: name, attribute_value: value } = attribute
196
312
 
197
- await StoreAPI.updateProductAttribute(mappedStore, attributeReqBody)
313
+ return {
314
+ id,
315
+ name,
316
+ value
317
+ }
198
318
  })
199
- )
200
319
 
201
- context.status = 200
320
+ return {
321
+ variantSku,
322
+ variantId,
323
+ attributes
324
+ }
325
+ })
326
+
327
+ for (var i = 0; i < variants.length; i++) {
328
+ try {
329
+ let variant = variants[i]
330
+ await StoreAPI.updateProductAttribute(mappedStore, { productSku, itemId, variant })
331
+ context.type = 'application/json'
332
+ context.status = 200
333
+ context.body = 'Succeeded'
334
+ } catch (e) {
335
+ context.type = 'application/json'
336
+ context.status = 500
337
+ context.body = e.message
338
+ }
339
+ }
202
340
  })
@@ -3,10 +3,12 @@ export * from './sellercraft/sellercraft'
3
3
 
4
4
  /* IMPORT ENTITIES AND RESOLVERS */
5
5
  import { entities as SellercraftEntities, resolvers as SellercraftResolvers } from './sellercraft'
6
+ import { entities as MarketplaceChannelEntities, resolvers as MarketplaceSellercraftResolvers } from './marketplace-channel'
6
7
 
7
8
  export const entities = [
8
9
  /* ENTITIES */
9
10
  ...SellercraftEntities,
11
+ ...MarketplaceChannelEntities
10
12
  ]
11
13
 
12
14
 
@@ -14,5 +16,8 @@ export const schema = {
14
16
  resolverClasses: [
15
17
  /* RESOLVER CLASSES */
16
18
  ...SellercraftResolvers,
17
- ]
19
+ ...MarketplaceSellercraftResolvers
20
+ ]
18
21
  }
22
+
23
+ export { MarketplaceSellercraftResolvers }
@@ -0,0 +1,6 @@
1
+ import { MarketplaceChannel } from './marketplace-channel'
2
+ import { MarketplaceChannelOrderMutation } from './marketplace-channel-order-mutation'
3
+ import { MarketplaceChannelProductMutation } from './marketplace-channel-product-mutation'
4
+
5
+ export const entities = [MarketplaceChannel]
6
+ export const resolvers = [MarketplaceChannelOrderMutation, MarketplaceChannelProductMutation]