@things-factory/integration-sellercraft 4.3.24 → 4.3.25

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/integration-sellercraft",
3
- "version": "4.3.24",
3
+ "version": "4.3.25",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -31,7 +31,7 @@
31
31
  "@things-factory/context-ui": "^4.3.23",
32
32
  "@things-factory/grist-ui": "^4.3.23",
33
33
  "@things-factory/i18n-base": "^4.3.23",
34
- "@things-factory/integration-marketplace": "^4.3.24",
34
+ "@things-factory/integration-marketplace": "^4.3.25",
35
35
  "@things-factory/integration-ui": "^4.3.24",
36
36
  "@things-factory/more-ui": "^4.3.23",
37
37
  "@things-factory/resource-ui": "^4.3.24",
@@ -51,5 +51,5 @@
51
51
  "nock": "^13.0.2",
52
52
  "should": "^13.2.3"
53
53
  },
54
- "gitHead": "43ba20d3476c8604e94f6a6b0bd7e84b6ec1bfd8"
54
+ "gitHead": "bdcecd8454d7a76df3c5676a39440d57bc21d5cb"
55
55
  }
@@ -132,7 +132,7 @@ sellercraftRouter.post('/sellercraft/store/update-product-stock', async (context
132
132
  }
133
133
  if (req.locationId) {
134
134
  let location = JSON.parse(req.locationId)
135
- req.qty -= location[0].available
135
+ req.qty -= await StoreAPI.getStoreProductVariationStock(mappedStore, { variantId: req.variationId })
136
136
  req.locationId = location[0].location_id
137
137
  }
138
138
  result = await StoreAPI.updateStoreProductVariationStock(mappedStore, req)
@@ -142,15 +142,8 @@ sellercraftRouter.post('/sellercraft/store/update-product-stock', async (context
142
142
  itemId: requestBody[i].native_product_id,
143
143
  distributors: requestBody[i].distributors || [], // for Magento
144
144
  variationSku: requestBody[i].variant.sku,
145
- locationId: requestBody[i]?.variant?.extra_metadata?.locationId, // for Shopify
146
- inventoryItemId: requestBody[i]?.variant?.extra_metadata?.inventoryItemId, // for Shopify
147
145
  context: { state: { domain: null } }
148
146
  }
149
- if (req.locationId) {
150
- let location = JSON.parse(req.locationId)
151
- req.qty -= location[0].available
152
- req.locationId = location[0].location_id
153
- }
154
147
  result = await StoreAPI.updateStoreProductStock(mappedStore, req)
155
148
  }
156
149
 
@@ -1,4 +1,4 @@
1
- import { Ctx, Mutation, Resolver } from 'type-graphql'
1
+ import { Arg, Ctx, Mutation, Resolver } from 'type-graphql'
2
2
  import { getRepository } from 'typeorm'
3
3
 
4
4
  import { config } from '@things-factory/env'
@@ -10,215 +10,224 @@ import { MarketplaceChannel } from './marketplace-channel'
10
10
  @Resolver()
11
11
  export class MarketplaceChannelProductMutation {
12
12
  @Mutation(returns => Boolean)
13
- async syncAllMarketplaceChannelProducts(@Ctx() context: any): Promise<boolean> {
13
+ async syncAllMarketplaceChannelProducts(
14
+ @Ctx() context: any,
15
+ @Arg('fromUpdatedDate', { nullable: true }) fromUpdatedDate?: string,
16
+ @Arg('toUpdatedDate', { nullable: true }) toUpdatedDate?: string
17
+ ): Promise<boolean> {
14
18
  const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
15
19
  const { tokenCraftApiKey: apiKey, getShopsTokenCraftUrl } = sellercraftChannelIntegrationConfig
16
20
 
17
21
  const channels: MarketplaceChannel[] = await getRepository(MarketplaceChannel).find({ where: { isActive: true } })
18
22
 
19
23
  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+, Tiktok
42
- channelShopId: shops[j]?.channel_shop_id,
43
- storeId: shops[j]?.credential?.store_url || ''
44
- }
45
-
46
- let countryCode = shops[j].country_code
47
- let channelCode = shops[j].org_prefix
48
- let organisationId = shops[j].account_id
49
- let channelShopId = shops[j].channel_shop_id
50
-
51
- var sellercraftStore = { ...store, platform: 'sellercraftChannelIntegration' }
52
-
53
- const productResult = []
54
- let totalPages: number = 1
55
- let limit: number = 50
56
- let parentLinks = []
57
-
58
- for (let page = 0; page < totalPages; page++) {
59
- const { results, total, parentLinkList } = await StoreAPI.getStoreProducts(store, {
60
- pagination: { page, limit }
61
- })
62
- totalPages = Math.ceil(total / limit)
63
- productResult.push(...results)
64
- if (store.platform == 'magento') parentLinks.push(...parentLinkList)
65
- }
66
-
67
- const categoryResult = []
68
- let totalPagesCategory: number = 1
69
- let limitCategory: number = 100
70
-
71
- if (store.platform != 'shopify') {
72
- for (let page = 0; page < totalPagesCategory; page++) {
73
- const { results, total } = await StoreAPI.getStoreProductCategories(store, {
74
- pagination: { page, limitCategory }
75
- })
76
- totalPagesCategory = Math.ceil(total / limitCategory)
77
- categoryResult.push(...results)
24
+ try {
25
+ var channelsFullPath = getShopsTokenCraftUrl + '?channel_id=' + channels[i].channelId
26
+ const channelResponse: any = await fetch(channelsFullPath, {
27
+ method: 'get',
28
+ headers: {
29
+ 'Content-Type': 'application/json',
30
+ 'x-api-key': apiKey
78
31
  }
79
- } else {
80
- categoryResult.push({ id: 1, name: 'default', isActive: true })
81
- }
32
+ })
82
33
 
83
- let mappedProducts = productResult.map(item => {
84
- let { categoryId, itemId: productId, name, brand, isVerified, images, attributes, variations } = item
85
-
86
- variations = variations.map(variation => {
87
- let {
88
- variationSku,
89
- variationId,
90
- name,
91
- isEnabled: isEnabled,
92
- isSellable: isSellable,
93
- attributes,
94
- stockLocked,
95
- qty: stockReported,
96
- costPrice: fullPrice,
97
- sellPrice: priceDiscounted,
98
- length,
99
- width,
100
- height,
101
- weight,
102
- extraMetadata
103
- } = variation
104
-
105
- return {
106
- variationSku,
107
- variationId,
108
- name,
109
- isEnabled,
110
- isSellable,
111
- attributes: store.platform != 'shopify' ? attributes : null,
112
- stockLocked,
113
- stockReported,
114
- fullPrice: parseFloat(fullPrice) || 0,
115
- priceDiscounted: parseFloat(priceDiscounted) || 0,
116
- inventoryProducts: [
117
- {
118
- qty: 1,
119
- name: `${name} - ${variationSku}`,
120
- sku: variationSku,
121
- productVersions: [
122
- {
123
- label: 'Default',
124
- packageLengthMM: length,
125
- packageWidthMM: width,
126
- packageHeightMM: height,
127
- packageWeightGram: weight,
128
- qty: stockReported
129
- }
130
- ]
131
- }
132
- ],
133
- extraMetadata
34
+ if (!channelResponse.ok) {
35
+ throw new Error(channelResponse)
36
+ }
37
+ var shopsResponse = await channelResponse.json()
38
+ var shops = shopsResponse.shops
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: channels[i].name,
47
+ accessToken: shops[j]?.credential?.access_token, // Magento+, Tiktok
48
+ channelShopId: shops[j]?.channel_shop_id,
49
+ storeId: shops[j]?.credential?.store_url || ''
134
50
  }
135
- })
136
51
 
137
- images = images?.map(image => {
138
- return {
139
- url: image
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
+ var sellercraftStore = { ...store, platform: 'sellercraftChannelIntegration' }
58
+
59
+ const productResult = []
60
+ let totalPages: number = 1
61
+ let limit: number = 50
62
+ let parentLinks = []
63
+
64
+ for (let page = 0; page < totalPages; page++) {
65
+ const { results, total, parentLinkList } = await StoreAPI.getStoreProducts(store, {
66
+ pagination: { page, limit }
67
+ })
68
+ totalPages = Math.ceil(total / limit)
69
+ productResult.push(...results)
70
+ if (store.platform == 'magento') parentLinks.push(...parentLinkList)
140
71
  }
141
- })
142
-
143
- return {
144
- organisationId,
145
- channelShopId: channelShopId,
146
- channelCode: channels[i].channelCode,
147
- channelCountry: shops[j].country_code,
148
- categoryId: store.platform == 'shopify' ? 1 : categoryId,
149
- productId: parentLinks.find(e => e.children.includes(productId))?.id || productId,
150
- name,
151
- brand,
152
- isVerified,
153
- images,
154
- attributes,
155
- variations
156
- }
157
- })
158
72
 
159
- let mappedCategories = categoryResult.map(category => {
160
- let { id: categoryId, name: categoryName, parent, isActive } = category
161
-
162
- return {
163
- categoryId,
164
- categoryName,
165
- parent,
166
- isActive: isActive || true,
167
- channelCode,
168
- countryCode,
169
- childrenCategories: []
170
- }
171
- })
73
+ const categoryResult = []
74
+ let totalPagesCategory: number = 1
75
+ let limitCategory: number = 100
172
76
 
173
- if (store.platform == 'magento') {
174
- let newList = []
175
- for (let np of mappedProducts) {
176
- if (np.productId == np.variations[0].variationId) {
177
- let vars = mappedProducts
178
- .filter(e => e.productId == np.productId)
179
- .map(e => {
180
- return e.variations[0]
77
+ if (store.platform != 'shopify') {
78
+ for (let page = 0; page < totalPagesCategory; page++) {
79
+ const { results, total } = await StoreAPI.getStoreProductCategories(store, {
80
+ pagination: { page, limitCategory }
181
81
  })
182
- np.variations = vars
183
- if (np.variations.length > 1) {
184
- np.variations = np.variations.filter(v => v.variationId != np.productId)
82
+ totalPagesCategory = Math.ceil(total / limitCategory)
83
+ categoryResult.push(...results)
185
84
  }
186
- newList.push(np)
85
+ } else {
86
+ categoryResult.push({ id: 1, name: 'default', isActive: true })
187
87
  }
188
- }
189
- mappedProducts = newList
190
- }
191
88
 
192
- try {
193
- let filterList = []
194
- mappedCategories = mappedCategories.map(category => {
195
- if (mappedCategories.filter(e => e.parent == category.categoryId).length > 0) {
196
- category.childrenCategories = mappedCategories.filter(e => e.parent == category.categoryId)
197
- filterList.push(...mappedCategories.filter(e => e.parent == category.categoryId))
198
- }
199
- return category
200
- })
89
+ let mappedProducts = productResult.map(item => {
90
+ let { categoryId, itemId: productId, name, brand, isVerified, images, attributes, variations } = item
91
+
92
+ variations = variations.map(variation => {
93
+ let {
94
+ variationSku,
95
+ variationId,
96
+ name,
97
+ isEnabled: isEnabled,
98
+ isSellable: isSellable,
99
+ attributes,
100
+ stockLocked,
101
+ qty: stockReported,
102
+ costPrice: fullPrice,
103
+ sellPrice: priceDiscounted,
104
+ length,
105
+ width,
106
+ height,
107
+ weight,
108
+ extraMetadata
109
+ } = variation
110
+
111
+ return {
112
+ variationSku,
113
+ variationId,
114
+ name,
115
+ isEnabled,
116
+ isSellable,
117
+ attributes: store.platform != 'shopify' ? attributes : null,
118
+ stockLocked,
119
+ stockReported,
120
+ fullPrice: parseFloat(fullPrice) || 0,
121
+ priceDiscounted: parseFloat(priceDiscounted) || 0,
122
+ inventoryProducts: [
123
+ {
124
+ qty: 1,
125
+ name: `${name} - ${variationSku}`,
126
+ sku: variationSku,
127
+ productVersions: [
128
+ {
129
+ label: 'Default',
130
+ packageLengthMM: length,
131
+ packageWidthMM: width,
132
+ packageHeightMM: height,
133
+ packageWeightGram: weight,
134
+ qty: stockReported
135
+ }
136
+ ]
137
+ }
138
+ ],
139
+ extraMetadata
140
+ }
141
+ })
142
+
143
+ images = images?.map(image => {
144
+ return {
145
+ url: image
146
+ }
147
+ })
148
+
149
+ return {
150
+ organisationId,
151
+ channelShopId: channelShopId,
152
+ channelCode: channels[i].channelCode,
153
+ channelCountry: shops[j].country_code,
154
+ categoryId: store.platform == 'shopify' ? 1 : categoryId,
155
+ productId: parentLinks.find(e => e.children.includes(productId))?.id || productId,
156
+ name,
157
+ brand,
158
+ isVerified,
159
+ images,
160
+ attributes,
161
+ variations
162
+ }
163
+ })
164
+
165
+ let mappedCategories = categoryResult.map(category => {
166
+ let { id: categoryId, name: categoryName, parent, isActive } = category
167
+
168
+ return {
169
+ categoryId,
170
+ categoryName,
171
+ parent,
172
+ isActive: isActive || true,
173
+ channelCode,
174
+ countryCode,
175
+ childrenCategories: []
176
+ }
177
+ })
201
178
 
202
- mappedCategories = mappedCategories.map(mc => {
203
- if (filterList.indexOf(mc) == -1) {
204
- return mc
179
+ if (store.platform == 'magento') {
180
+ let newList = []
181
+ for (let np of mappedProducts) {
182
+ if (np.productId == np.variations[0].variationId) {
183
+ let vars = mappedProducts
184
+ .filter(e => e.productId == np.productId)
185
+ .map(e => {
186
+ return e.variations[0]
187
+ })
188
+ np.variations = vars
189
+ if (np.variations.length > 1) {
190
+ np.variations = np.variations.filter(v => v.variationId != np.productId)
191
+ }
192
+ newList.push(np)
193
+ }
194
+ }
195
+ mappedProducts = newList
205
196
  }
206
- }).filter(e => e)
207
197
 
208
- await SellercraftChannelIntegrationAPI.ingestChannelCategories(sellercraftStore, {
209
- categories: mappedCategories
210
- })
211
- } catch (e) {}
198
+ try {
199
+ let filterList = []
200
+ mappedCategories = mappedCategories.map(category => {
201
+ if (mappedCategories.filter(e => e.parent == category.categoryId).length > 0) {
202
+ category.childrenCategories = mappedCategories.filter(e => e.parent == category.categoryId)
203
+ filterList.push(...mappedCategories.filter(e => e.parent == category.categoryId))
204
+ }
205
+ return category
206
+ })
207
+
208
+ mappedCategories = mappedCategories
209
+ .map(mc => {
210
+ if (filterList.indexOf(mc) == -1) {
211
+ return mc
212
+ }
213
+ })
214
+ .filter(e => e)
212
215
 
213
- try {
214
- for (let k = 0, l = mappedProducts.length; k < l; k++) {
215
- await SellercraftChannelIntegrationAPI.ingestChannelProduct(sellercraftStore, {
216
- products: [mappedProducts[k]]
217
- })
218
- }
219
- } catch (e) {}
220
- }
216
+ await SellercraftChannelIntegrationAPI.ingestChannelCategories(sellercraftStore, {
217
+ categories: mappedCategories
218
+ })
219
+ } catch (e) {}
221
220
 
221
+ try {
222
+ for (let k = 0, l = mappedProducts.length; k < l; k++) {
223
+ await SellercraftChannelIntegrationAPI.ingestChannelProduct(sellercraftStore, {
224
+ products: [mappedProducts[k]]
225
+ })
226
+ }
227
+ } catch (e) {}
228
+ } catch (e) {}
229
+ }
230
+ } catch (e) {}
222
231
  }
223
232
  return true
224
233
  }