@things-factory/integration-sellercraft 5.0.0-alpha.3 → 5.0.0-alpha.32

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 (41) 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 +10 -0
  4. package/dist-server/constants/order-status-mapping.js.map +1 -0
  5. package/dist-server/controllers/index.js +2 -0
  6. package/dist-server/controllers/index.js.map +1 -1
  7. package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-categories.js +18 -20
  8. package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-categories.js.map +1 -1
  9. package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-order.js +17 -14
  10. package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-order.js.map +1 -1
  11. package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-product.js +23 -43
  12. package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-product.js.map +1 -1
  13. package/dist-server/controllers/sellercraft-channel-integration/sellercraft-channel-integration.js +1 -1
  14. package/dist-server/routers/sellercraft-router.js +29 -13
  15. package/dist-server/routers/sellercraft-router.js.map +1 -1
  16. package/dist-server/service/index.js +5 -1
  17. package/dist-server/service/index.js.map +1 -1
  18. package/dist-server/service/marketplace-channel/index.js +9 -0
  19. package/dist-server/service/marketplace-channel/index.js.map +1 -0
  20. package/dist-server/service/marketplace-channel/marketplace-channel-order-mutation.js +150 -0
  21. package/dist-server/service/marketplace-channel/marketplace-channel-order-mutation.js.map +1 -0
  22. package/dist-server/service/marketplace-channel/marketplace-channel-product-mutation.js +149 -0
  23. package/dist-server/service/marketplace-channel/marketplace-channel-product-mutation.js.map +1 -0
  24. package/dist-server/service/marketplace-channel/marketplace-channel.js +83 -0
  25. package/dist-server/service/marketplace-channel/marketplace-channel.js.map +1 -0
  26. package/dist-server/service/sellercraft/sellercraft.js +1 -1
  27. package/package.json +15 -15
  28. package/server/constants/index.ts +2 -1
  29. package/server/constants/order-status-mapping.ts +6 -0
  30. package/server/controllers/index.ts +2 -0
  31. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-categories.ts +18 -20
  32. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-order.ts +18 -14
  33. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-product.ts +27 -47
  34. package/server/controllers/sellercraft-channel-integration/sellercraft-channel-integration.ts +1 -1
  35. package/server/routers/sellercraft-router.ts +32 -14
  36. package/server/service/index.ts +6 -1
  37. package/server/service/marketplace-channel/index.ts +6 -0
  38. package/server/service/marketplace-channel/marketplace-channel-order-mutation.ts +182 -0
  39. package/server/service/marketplace-channel/marketplace-channel-product-mutation.ts +161 -0
  40. package/server/service/marketplace-channel/marketplace-channel.ts +64 -0
  41. package/server/service/sellercraft/sellercraft.ts +1 -1
@@ -11,35 +11,25 @@ export function ingestChannelProduct() {
11
11
  let productVariations: any[] = product.variations.map(variant => {
12
12
  return {
13
13
  seller_sku: variant.variationSku,
14
- native_variant_id: variant.variationId,
14
+ native_variant_id: variant.variationId.toString(),
15
15
  label: variant.name,
16
- is_enabled: variant.isEnabled,
17
- is_sellable: variant.isSellable,
18
- variant_attributes: variant?.attributes
19
- ? variant.attributes.map(attribute => {
20
- return {
21
- attribute_key: attribute.id,
22
- values: []
23
- }
24
- })
25
- : [],
16
+ is_enabled: variant.isEnabled || true,
17
+ is_sellable: variant.isSellable || true,
18
+ is_deleted: false, // default
19
+ variant_attributes: variant?.attributes.map(attribute => {
20
+ return {
21
+ ...attribute,
22
+ native_attribute_id: attribute.native_attribute_id.toString()
23
+ }
24
+ }) || [],
26
25
  stock_locked: variant?.stockLocked ? variant.stockLocked : 0,
27
26
  native_stock_reported: variant?.stockReported ? variant.stockReported : 0,
28
- price_full: variant.fullPrice,
29
- price_discounted: variant.priceDiscounted,
30
- price_discounts: variant?.product_discounts
31
- ? variant.product_discounts.map(discount => {
32
- return {
33
- price_discounted: discount.priceDiscounted,
34
- native_discount_id: discount.id,
35
- name: discount.name
36
- }
37
- })
38
- : [],
27
+ price_full: variant.fullPrice || 0,
28
+ price_discounted: variant.priceDiscounted || variant.fullPrice || 0,
39
29
  inventory_products: variant?.inventoryProducts
40
30
  ? variant.inventoryProducts.map(inventoryProduct => {
41
31
  return {
42
- quantity: inventoryProduct.qty,
32
+ quantity: inventoryProduct.qty || 1,
43
33
  name: inventoryProduct.name,
44
34
  inventory_sku: inventoryProduct.sku,
45
35
  product_versions: inventoryProduct?.productVersions
@@ -53,7 +43,7 @@ export function ingestChannelProduct() {
53
43
  package_weight_gram: productVersion?.packageWeightGram
54
44
  ? productVersion.packageWeightGram
55
45
  : 0,
56
- stock_available: productVersion.qty
46
+ stock_available: productVersion.qty || 0
57
47
  }
58
48
  })
59
49
  : []
@@ -68,43 +58,33 @@ export function ingestChannelProduct() {
68
58
  channel_shop_id: product.channelShopId,
69
59
  channel_code: product.channelCode,
70
60
  channel_country: product.channelCountry,
71
- native_category_id: product.categoryId,
72
- native_product_id: product.productId,
61
+ native_category_id: product.categoryId.toString(),
62
+ native_product_id: product.productId.toString(),
73
63
  label: product.name,
74
- brand: product.brand,
75
- is_verified: product.isVerified,
76
- images: product.images.map(image => {
64
+ brand: product.brand || '',
65
+ is_verified: product.isVerified || true,
66
+ flexible_attributes: product.channelCode == 'WCM' ? true : false, // add channels that do not support category_attributes ingestion
67
+ images: product?.images.map(image => {
77
68
  return {
78
69
  file_url: image.url
79
70
  }
80
71
  }),
81
- product_attributes: product.attributes.map(attribute => {
72
+ product_attributes: product?.attributes.map(attribute => {
82
73
  return {
83
- native_attribute_id: attribute.id,
84
- values: []
74
+ ...attribute,
75
+ native_attribute_id: attribute.native_attribute_id.toString()
85
76
  }
86
- })
77
+ }),
78
+ variants: productVariations
87
79
  }
88
80
  })
89
81
 
90
82
  return {
91
- payload: {}
83
+ payload: [...newProducts]
92
84
  }
93
85
  },
94
86
  normalize(res) {
95
- const {
96
- handover_type: handOverType,
97
- pickup_time: pickupTime,
98
- pickup_address: pickupAddress,
99
- dropoff_address: dropoffAddress
100
- } = res.data
101
-
102
- return {
103
- handOverType,
104
- pickupTime,
105
- pickupAddress,
106
- dropoffAddress
107
- }
87
+ return res
108
88
  }
109
89
  }
110
90
  }
@@ -38,7 +38,7 @@ export class SellercraftChannelIntegration {
38
38
  headers: {
39
39
  'Content-Type': 'application/json',
40
40
  request_id: requestId,
41
- 'x-api-key': apiKey
41
+ 'X-Api-Key': apiKey
42
42
  },
43
43
  body: jsondata
44
44
  })
@@ -10,7 +10,7 @@ export const sellercraftRouter = new Router()
10
10
 
11
11
  sellercraftRouter.post('/sellercraft/store/update-product-price', async (context, next) => {
12
12
  const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
13
- const { apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
13
+ const { tokenCraftApiKey: apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
14
14
 
15
15
  const xApiKey = context.headers['x-api-key']
16
16
 
@@ -23,7 +23,7 @@ sellercraftRouter.post('/sellercraft/store/update-product-price', async (context
23
23
  var result
24
24
 
25
25
  // 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
26
+ var fullPath = `${tokenCraftUrl}?channel_id=${requestBody[i].channel_id}&shop_id=${requestBody[i].shop_id}`
27
27
  const response: any = await fetch(fullPath, {
28
28
  method: 'get',
29
29
  headers: {
@@ -67,7 +67,7 @@ sellercraftRouter.post('/sellercraft/store/update-product-price', async (context
67
67
 
68
68
  sellercraftRouter.post('/sellercraft/store/update-product-stock', async (context, next) => {
69
69
  const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
70
- const { apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
70
+ const { tokenCraftApiKey: apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
71
71
 
72
72
  const xApiKey = context.headers['x-api-key']
73
73
 
@@ -79,7 +79,7 @@ sellercraftRouter.post('/sellercraft/store/update-product-stock', async (context
79
79
  var result
80
80
 
81
81
  // 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
82
+ var fullPath = `${tokenCraftUrl}?channel_id=${requestBody[i].channel_id}&shop_id=${requestBody[i].shop_id}`
83
83
  const response: any = await fetch(fullPath, {
84
84
  method: 'get',
85
85
  headers: {
@@ -120,7 +120,7 @@ sellercraftRouter.post('/sellercraft/store/update-product-stock', async (context
120
120
 
121
121
  sellercraftRouter.post('/sellercraft/store/update-order-status', async (context, next) => {
122
122
  const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
123
- const { apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
123
+ const { tokenCraftApiKey: apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
124
124
 
125
125
  const xApiKey = context.headers['x-api-key']
126
126
 
@@ -131,7 +131,7 @@ sellercraftRouter.post('/sellercraft/store/update-order-status', async (context,
131
131
  var store: any = {}
132
132
 
133
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
134
+ var fullPath = `${tokenCraftUrl}?channel_id=${requestBody.channel_id}&shop_id=${requestBody.shop_id}`
135
135
  const response: any = await fetch(fullPath, {
136
136
  method: 'get',
137
137
  headers: {
@@ -160,7 +160,7 @@ sellercraftRouter.post('/sellercraft/store/update-order-status', async (context,
160
160
 
161
161
  sellercraftRouter.post('/sellercraft/store/update-product-attribute', async (context, next) => {
162
162
  const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
163
- const { apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
163
+ const { tokenCraftApiKey: apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
164
164
 
165
165
  const xApiKey = context.headers['x-api-key']
166
166
 
@@ -168,10 +168,9 @@ sellercraftRouter.post('/sellercraft/store/update-product-attribute', async (con
168
168
 
169
169
  const requestBody = context.request.body
170
170
  var store: any = {}
171
- const attributes: any[] = requestBody.attributes
172
171
 
173
172
  // 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
173
+ var fullPath = `${tokenCraftUrl}?channel_id=${requestBody.channel_id}&shop_id=${requestBody.shop_id}`
175
174
  const response: any = await fetch(fullPath, {
176
175
  method: 'get',
177
176
  headers: {
@@ -189,14 +188,33 @@ sellercraftRouter.post('/sellercraft/store/update-product-attribute', async (con
189
188
  storeURL: store.shop.credential.store_url,
190
189
  platform: PLATFORM[`${store.shop.org_prefix}`]
191
190
  }
191
+
192
+ let { product_sku: productSku, native_product_id: itemId, variants } = requestBody
192
193
 
193
- await Promise.all(
194
- attributes.map(async attribute => {
195
- const attributeReqBody = { attributeId: attribute.native_attribute_id, name: attribute.attribute_key }
194
+ variants.map(variant => {
195
+ let { variant_sku: variantSku, native_variant_id: variantId, attributes } = variant
196
196
 
197
- await StoreAPI.updateProductAttribute(mappedStore, attributeReqBody)
197
+ attributes.map(attribute => {
198
+ let { native_attribute_id: id, attribute_key: name, attribute_value: value } = attribute
199
+
200
+ return {
201
+ id,
202
+ name,
203
+ value
204
+ }
198
205
  })
199
- )
206
+
207
+ return {
208
+ variantSku,
209
+ variantId,
210
+ attributes
211
+ }
212
+ })
213
+
214
+ for (var i = 0; i < variants.length; i++) {
215
+ let variant = variants[i]
216
+ await StoreAPI.updateProductAttribute(mappedStore, { productSku, itemId, variant })
217
+ }
200
218
 
201
219
  context.status = 200
202
220
  })
@@ -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]
@@ -0,0 +1,182 @@
1
+ import { Arg, Ctx, Mutation, Resolver } from 'type-graphql'
2
+ import { getRepository } from 'typeorm'
3
+
4
+ import { MarketplaceChannel } from './marketplace-channel'
5
+
6
+ import { config } from '@things-factory/env'
7
+ import { StoreAPI } from '@things-factory/integration-marketplace'
8
+ import { SellercraftChannelIntegrationAPI } from '../../controllers/sellercraft-channel-integration-api'
9
+
10
+ @Resolver()
11
+ export class MarketplaceChannelOrderMutation {
12
+ @Mutation(returns => Boolean)
13
+ async syncAllMarketplaceChannelOrders(
14
+ @Arg('fromDate') fromDate: string,
15
+ @Arg('toDate') toDate: string,
16
+ @Ctx() context: any
17
+ ): Promise<boolean> {
18
+ const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
19
+ const { tokenCraftApiKey: apiKey, getShopsTokenCraftUrl } = sellercraftChannelIntegrationConfig
20
+
21
+ const channels: MarketplaceChannel[] = await getRepository(MarketplaceChannel).find()
22
+
23
+ for (var i = 0; i < channels.length; i++) {
24
+ var channelsFullPath = getShopsTokenCraftUrl + '?channel_id=' + channels[i].channelId
25
+ const channelResponse: any = await fetch(channelsFullPath, {
26
+ method: 'get',
27
+ headers: {
28
+ 'Content-Type': 'application/json',
29
+ 'x-api-key': apiKey
30
+ }
31
+ })
32
+
33
+ if (!channelResponse.ok) {
34
+ throw new Error(channelResponse)
35
+ }
36
+ var shopsResponse = await channelResponse.json()
37
+ var shops = shopsResponse.shops
38
+
39
+ for (var j = 0; j < shops.length; j++) {
40
+ var store = {
41
+ accessKey: shops[j].credential.consumer_key,
42
+ accessSecret: shops[j].credential.consumer_secret,
43
+ storeURL: shops[j].credential.store_url,
44
+ platform: channels[i].name,
45
+ accessToken: shops[j].credential.access_token // Magento+
46
+ }
47
+
48
+ // let countryCode = shops[j].country_code
49
+ // let channelCode = shops[j].org_prefix
50
+ let organisationId = shops[j].account_id
51
+ let channelShopId = shops[j].channel_shop_id
52
+
53
+ const orderReq = {
54
+ fromDate: fromDate,
55
+ toDate: toDate
56
+ }
57
+ const orderResult = await StoreAPI.getStoreOrders(store, orderReq)
58
+
59
+ var sellercraftStore = { ...store, platform: 'sellercraftChannelIntegration' }
60
+
61
+ let mappedOrderResult = orderResult.results.map(order => {
62
+ let {
63
+ firstName: custFirstName,
64
+ lastName: custLastName,
65
+ orderCreatedAt: createdAt,
66
+ orderUpdatedAt: updatedAt,
67
+ orderNo: id,
68
+ status
69
+ } = order
70
+
71
+ let {
72
+ first_name: billFirstName,
73
+ last_name: billLastName,
74
+ address_1: billAddress1,
75
+ address_2: billAddress2,
76
+ address_3: billAddress3,
77
+ address_4: billAddress4,
78
+ address_5: billAddress5,
79
+ city: billCity,
80
+ postcode: billPostalCode,
81
+ country: billCountry,
82
+ phone: billPhone1,
83
+ phone_2: billPhone2
84
+ } = order?.billing
85
+
86
+ let {
87
+ first_name: shipFirstName,
88
+ last_name: shipLastName,
89
+ address_1: shipAddress1,
90
+ address_2: shipAddress2,
91
+ address_3: shipAddress3,
92
+ address_4: shipAddress4,
93
+ address_5: shipAddress5,
94
+ city: shipCity,
95
+ postcode: shipPostalCode,
96
+ country: shipCountry,
97
+ phone: shipPhone1,
98
+ phone_2: shipPhone2
99
+ } = order.shipping
100
+
101
+ let orderItems = order.orderItems.map(item => {
102
+ let { name: id, variationId: variationId, slaExpiresAt, total, totalTax, subtotal, subtotalTax, qty } = item
103
+
104
+ return {
105
+ id,
106
+ variationId,
107
+ currency: order.orderShipping.collectionCurrency,
108
+ createdAt: order.orderCreatedAt,
109
+ updatedAt: order.orderUpdatedAt,
110
+ charges: [
111
+ {
112
+ name: 'PRICE_NORMAL_SELLING',
113
+ grossAmount: total,
114
+ nettAmount: subtotal
115
+ },
116
+ {
117
+ name: 'TAXES',
118
+ grossAmount: totalTax,
119
+ nettAmount: subtotalTax
120
+ }
121
+ ],
122
+ slaExpiresAt,
123
+ qty
124
+ }
125
+ })
126
+
127
+ let mappedOrderItems = []
128
+ orderItems.map(oi => {
129
+ for (let i = 0; i < oi.qty; i++) {
130
+ mappedOrderItems.push({
131
+ ...oi,
132
+ id: `${oi.id}-${i+1}`
133
+ })
134
+ }
135
+ })
136
+
137
+ return {
138
+ custFirstName,
139
+ custLastName,
140
+ createdAt,
141
+ updatedAt,
142
+ id,
143
+ billFirstName,
144
+ billLastName,
145
+ billAddress1: billAddress1.toString() || shipAddress1.toString(),
146
+ billAddress2: billAddress2 || shipAddress2,
147
+ billAddress3: billAddress3 || shipAddress3,
148
+ billAddress4: billAddress4 || shipAddress4,
149
+ billAddress5: billAddress5 || shipAddress5,
150
+ billCity: billCity || shipCity,
151
+ billPostalCode: billPostalCode || shipPostalCode,
152
+ billCountry: billCountry || shipCountry,
153
+ billPhone1: billPhone1 || shipPhone1,
154
+ billPhone2: billPhone2 || shipPhone2,
155
+ shipFirstName,
156
+ shipLastName,
157
+ shipAddress1: shipAddress1.toString(),
158
+ shipAddress2,
159
+ shipAddress3,
160
+ shipAddress4,
161
+ shipAddress5,
162
+ shipCity,
163
+ shipPostalCode,
164
+ shipCountry,
165
+ shipPhone1,
166
+ shipPhone2,
167
+ mappedOrderItems,
168
+ channelShopId,
169
+ organisationId,
170
+ status
171
+ }
172
+ })
173
+
174
+ if (mappedOrderResult.length > 0) {
175
+ await SellercraftChannelIntegrationAPI.ingestChannelOrder(sellercraftStore, { orders: mappedOrderResult })
176
+ }
177
+ }
178
+
179
+ return true
180
+ }
181
+ }
182
+ }
@@ -0,0 +1,161 @@
1
+ import { Ctx, Mutation, Resolver } from 'type-graphql'
2
+ import { getRepository } from 'typeorm'
3
+
4
+ import { MarketplaceChannel } from './marketplace-channel'
5
+
6
+ import { config } from '@things-factory/env'
7
+ import { StoreAPI } from '@things-factory/integration-marketplace'
8
+ import { SellercraftChannelIntegrationAPI } from '../../controllers/sellercraft-channel-integration-api'
9
+
10
+ @Resolver()
11
+ export class MarketplaceChannelProductMutation {
12
+ @Mutation(returns => Boolean)
13
+ async syncAllMarketplaceChannelProducts(@Ctx() context: any): Promise<boolean> {
14
+ const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
15
+ const { tokenCraftApiKey: apiKey, getShopsTokenCraftUrl } = sellercraftChannelIntegrationConfig
16
+
17
+ const channels: MarketplaceChannel[] = await getRepository(MarketplaceChannel).find()
18
+
19
+ for (var i = 0; i < channels.length; i++) {
20
+ var channelsFullPath = getShopsTokenCraftUrl + '?channel_id=' + channels[i].channelId
21
+ const channelResponse: any = await fetch(channelsFullPath, {
22
+ method: 'get',
23
+ headers: {
24
+ 'Content-Type': 'application/json',
25
+ 'x-api-key': apiKey
26
+ }
27
+ })
28
+
29
+ if (!channelResponse.ok) {
30
+ throw new Error(channelResponse)
31
+ }
32
+ var shopsResponse = await channelResponse.json()
33
+ var shops = shopsResponse.shops
34
+
35
+ for (var j = 0; j < shops.length; j++) {
36
+ var store = {
37
+ accessKey: shops[j].credential.consumer_key,
38
+ accessSecret: shops[j].credential.consumer_secret,
39
+ storeURL: shops[j].credential.store_url,
40
+ platform: channels[i].name,
41
+ accessToken: shops[j].credential.access_token // Magento+
42
+ }
43
+
44
+ let countryCode = shops[j].country_code
45
+ let channelCode = shops[j].org_prefix
46
+ let organisationId = shops[j].account_id
47
+ let channelShopId = shops[j].channel_shop_id
48
+
49
+ var sellercraftStore = { ...store, platform: 'sellercraftChannelIntegration' }
50
+
51
+ const productResult = await StoreAPI.getStoreProducts(store, {})
52
+
53
+ const categoryResult = await StoreAPI.getStoreProductCategories(store, {})
54
+
55
+ let mappedProducts = productResult.results.map(item => {
56
+ let { categoryId, itemId: productId, name, brand, isVerified, images, attributes, variations } = item
57
+
58
+ variations = variations.map(variation => {
59
+ let {
60
+ variationSku,
61
+ variationId,
62
+ name,
63
+ isEnabled: isEnabled,
64
+ isEnabled: isSellable,
65
+ attributes,
66
+ stockLocked,
67
+ qty: stockReported,
68
+ costPrice: fullPrice,
69
+ sellPrice: priceDiscounted,
70
+ length,
71
+ width,
72
+ height,
73
+ weight
74
+ } = variation
75
+
76
+ return {
77
+ variationSku,
78
+ variationId,
79
+ name,
80
+ isEnabled,
81
+ isSellable,
82
+ attributes,
83
+ stockLocked,
84
+ stockReported,
85
+ fullPrice,
86
+ priceDiscounted,
87
+ inventoryProducts: [
88
+ {
89
+ qty: stockReported,
90
+ name: `${name} - ${variationSku}`,
91
+ sku: variationSku,
92
+ productVersions: [
93
+ {
94
+ label: 'Default',
95
+ packageLengthMM: length,
96
+ packageWidthMM: width,
97
+ packageHeightMM: height,
98
+ packageWeightGram: weight,
99
+ qty: 1
100
+ }
101
+ ]
102
+ }
103
+ ]
104
+ }
105
+ })
106
+
107
+ images = images?.map(image => {
108
+ return {
109
+ url: image
110
+ }
111
+ })
112
+
113
+ return {
114
+ organisationId,
115
+ channelShopId: channelShopId,
116
+ channelCode: channels[i].channelCode,
117
+ channelCountry: shops[j].country_code,
118
+ categoryId,
119
+ productId,
120
+ name,
121
+ brand,
122
+ isVerified,
123
+ images,
124
+ attributes,
125
+ variations
126
+ }
127
+ })
128
+
129
+ let mappedCategories = categoryResult.results.map(category => {
130
+ let { id: categoryId, name: categoryName, parent, isActive } = category
131
+
132
+ return {
133
+ categoryId,
134
+ categoryName,
135
+ parent,
136
+ isLeaf: parent == 0 ? false : true,
137
+ isActive: isActive || true,
138
+ channelCode,
139
+ countryCode,
140
+ childrenCategories: []
141
+ }
142
+ })
143
+
144
+ mappedCategories = mappedCategories.map(category => {
145
+ if (mappedCategories.filter(e => e.parent == category.categoryId).length > 0) {
146
+ category.childrenCategories = mappedCategories.filter(e => e.parent == category.categoryId)
147
+ }
148
+ return category
149
+ })
150
+
151
+ await SellercraftChannelIntegrationAPI.ingestChannelCategories(sellercraftStore, {
152
+ categories: mappedCategories
153
+ })
154
+
155
+ await SellercraftChannelIntegrationAPI.ingestChannelProduct(sellercraftStore, { products: mappedProducts })
156
+ }
157
+
158
+ return true
159
+ }
160
+ }
161
+ }
@@ -0,0 +1,64 @@
1
+ import { Field, ID, ObjectType } from 'type-graphql'
2
+ import {
3
+ Column,
4
+ CreateDateColumn,
5
+ Entity,
6
+ Index,
7
+ ManyToOne,
8
+ PrimaryGeneratedColumn,
9
+ RelationId,
10
+ UpdateDateColumn
11
+ } from 'typeorm'
12
+
13
+ import { User } from '@things-factory/auth-base'
14
+ import { Domain } from '@things-factory/shell'
15
+
16
+ @Entity()
17
+ @Index('ix_marketplace_channel_0 ', (marketplaceChannel: MarketplaceChannel) => [marketplaceChannel.domain, marketplaceChannel.name], { unique: true })
18
+ @ObjectType({ description: 'Entity for Marketplace Channel' })
19
+ export class MarketplaceChannel {
20
+ @PrimaryGeneratedColumn('uuid')
21
+ @Field(type => ID)
22
+ readonly id: string
23
+
24
+ @ManyToOne(type => Domain)
25
+ @Field({ nullable: true })
26
+ domain?: Domain
27
+
28
+ @RelationId((marketplaceChannel: MarketplaceChannel) => marketplaceChannel.domain)
29
+ domainId?: string
30
+
31
+ @Column()
32
+ @Field()
33
+ name: string
34
+
35
+ @Column()
36
+ @Field()
37
+ channelCode: string
38
+
39
+ @Column()
40
+ @Field()
41
+ channelId: string
42
+
43
+ @CreateDateColumn()
44
+ @Field({ nullable: true })
45
+ createdAt?: Date
46
+
47
+ @UpdateDateColumn()
48
+ @Field({ nullable: true })
49
+ updatedAt?: Date
50
+
51
+ @ManyToOne(type => User, { nullable: true })
52
+ @Field({ nullable: true })
53
+ creator?: User
54
+
55
+ @RelationId((marketplaceChannel: MarketplaceChannel) => marketplaceChannel.creator)
56
+ creatorId?: string
57
+
58
+ @ManyToOne(type => User, { nullable: true })
59
+ @Field({ nullable: true })
60
+ updater?: User
61
+
62
+ @RelationId((marketplaceChannel: MarketplaceChannel) => marketplaceChannel.updater)
63
+ updaterId?: string
64
+ }
@@ -87,6 +87,6 @@ export class Sellercraft {
87
87
  @Field({ nullable: true })
88
88
  updater?: User
89
89
 
90
- @RelationId((sellercraft: Sellercraft) => sellercraft.creator)
90
+ @RelationId((sellercraft: Sellercraft) => sellercraft.updater)
91
91
  updaterId?: string
92
92
  }