@things-factory/operato-hub 4.3.775 → 4.3.776
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/dist-server/routers/api/restful-apis/v1/company/add-products.js +39 -4
- package/dist-server/routers/api/restful-apis/v1/company/add-products.js.map +1 -1
- package/dist-server/routers/api/restful-apis/v1/company/upsert-products.js +48 -3
- package/dist-server/routers/api/restful-apis/v1/company/upsert-products.js.map +1 -1
- package/dist-server/routers/api/restful-apis/v1/utils/params.js +125 -0
- package/dist-server/routers/api/restful-apis/v1/utils/params.js.map +1 -1
- package/openapi/v1/product.yaml +528 -0
- package/package.json +17 -16
- package/server/routers/api/restful-apis/v1/company/add-products.ts +41 -5
- package/server/routers/api/restful-apis/v1/company/upsert-products.ts +52 -1
- package/server/routers/api/restful-apis/v1/utils/params.ts +125 -0
|
@@ -3,6 +3,7 @@ import { EntityManager, getConnection, getRepository, In } from 'typeorm'
|
|
|
3
3
|
|
|
4
4
|
import { restfulApiRouter as router } from '@things-factory/api'
|
|
5
5
|
import { Bizplace } from '@things-factory/biz-base'
|
|
6
|
+
import { webhookHandler, WebhookEventsEnum } from '@things-factory/integration-base'
|
|
6
7
|
import { Product, ProductBarcode, ProductDetail } from '@things-factory/product-base'
|
|
7
8
|
|
|
8
9
|
import { businessMiddleware, loggingMiddleware, validationMiddleware } from '../middlewares'
|
|
@@ -15,15 +16,18 @@ router.post(
|
|
|
15
16
|
loggingMiddleware,
|
|
16
17
|
async (context, next) => {
|
|
17
18
|
try {
|
|
19
|
+
let response = []
|
|
20
|
+
let bizplace: Bizplace
|
|
21
|
+
const { user, domain } = context.state
|
|
22
|
+
|
|
18
23
|
await getConnection().transaction(async (tx: EntityManager) => {
|
|
19
24
|
if (!Array.isArray(context.request.body.data)) throw new ApiError('E01', 'data field is not an array')
|
|
20
25
|
|
|
21
26
|
const products = context.request.body.data
|
|
22
27
|
const skus = products.map(p => p.sku)
|
|
23
|
-
const { user, domain } = context.state
|
|
24
28
|
|
|
25
29
|
// find bizplace
|
|
26
|
-
|
|
30
|
+
bizplace = await getRepository(Bizplace).findOne({
|
|
27
31
|
where: {
|
|
28
32
|
domain
|
|
29
33
|
}
|
|
@@ -48,8 +52,6 @@ router.post(
|
|
|
48
52
|
throw new ApiError('E05', `existing products found: ${existedProducts.map(ep => ep.sku)}`)
|
|
49
53
|
}
|
|
50
54
|
|
|
51
|
-
let response = []
|
|
52
|
-
|
|
53
55
|
// save product
|
|
54
56
|
await Promise.all(
|
|
55
57
|
products.map(async p => {
|
|
@@ -117,7 +119,37 @@ router.post(
|
|
|
117
119
|
auxUnit2: pdResult.auxUnit2,
|
|
118
120
|
auxValue2: pdResult.auxValue2,
|
|
119
121
|
auxUnit3: pdResult.auxUnit3,
|
|
120
|
-
auxValue3: pdResult.auxValue3
|
|
122
|
+
auxValue3: pdResult.auxValue3,
|
|
123
|
+
auxUnit4: pdResult.auxUnit4,
|
|
124
|
+
auxValue4: pdResult.auxValue4,
|
|
125
|
+
auxUnit5: pdResult.auxUnit5,
|
|
126
|
+
auxValue5: pdResult.auxValue5,
|
|
127
|
+
auxUnit6: pdResult.auxUnit6,
|
|
128
|
+
auxValue6: pdResult.auxValue6,
|
|
129
|
+
auxUnit7: pdResult.auxUnit7,
|
|
130
|
+
auxValue7: pdResult.auxValue7,
|
|
131
|
+
auxUnit8: pdResult.auxUnit8,
|
|
132
|
+
auxValue8: pdResult.auxValue8,
|
|
133
|
+
auxUnit9: pdResult.auxUnit9,
|
|
134
|
+
auxValue9: pdResult.auxValue9,
|
|
135
|
+
auxUnit10: pdResult.auxUnit10,
|
|
136
|
+
auxValue10: pdResult.auxValue10,
|
|
137
|
+
auxUnit11: pdResult.auxUnit11,
|
|
138
|
+
auxValue11: pdResult.auxValue11,
|
|
139
|
+
auxUnit12: pdResult.auxUnit12,
|
|
140
|
+
auxValue12: pdResult.auxValue12,
|
|
141
|
+
auxUnit13: pdResult.auxUnit13,
|
|
142
|
+
auxValue13: pdResult.auxValue13,
|
|
143
|
+
auxUnit14: pdResult.auxUnit14,
|
|
144
|
+
auxValue14: pdResult.auxValue14,
|
|
145
|
+
auxUnit15: pdResult.auxUnit15,
|
|
146
|
+
auxValue15: pdResult.auxValue15,
|
|
147
|
+
auxUnit16: pdResult.auxUnit16,
|
|
148
|
+
auxValue16: pdResult.auxValue16,
|
|
149
|
+
auxUnit17: pdResult.auxUnit17,
|
|
150
|
+
auxValue17: pdResult.auxValue17,
|
|
151
|
+
auxUnit18: pdResult.auxUnit18,
|
|
152
|
+
auxValue18: pdResult.auxValue18
|
|
121
153
|
}
|
|
122
154
|
)
|
|
123
155
|
}
|
|
@@ -170,6 +202,10 @@ router.post(
|
|
|
170
202
|
data: response
|
|
171
203
|
}
|
|
172
204
|
})
|
|
205
|
+
|
|
206
|
+
response.forEach(product => {
|
|
207
|
+
webhookHandler({ id: product.id, domain }, bizplace, WebhookEventsEnum.ProductCreated)
|
|
208
|
+
})
|
|
173
209
|
} catch (e) {
|
|
174
210
|
if (e instanceof ApiError) ApiErrorHandler(context, e)
|
|
175
211
|
else throwInternalServerError(context, e)
|
|
@@ -4,6 +4,7 @@ import { v4 as uuidv4 } from 'uuid'
|
|
|
4
4
|
|
|
5
5
|
import { restfulApiRouter as router } from '@things-factory/api'
|
|
6
6
|
import { Bizplace } from '@things-factory/biz-base'
|
|
7
|
+
import { webhookHandler, WebhookEventsEnum } from '@things-factory/integration-base'
|
|
7
8
|
import { pickStrategy, Product, ProductBarcode, ProductDetail } from '@things-factory/product-base'
|
|
8
9
|
|
|
9
10
|
import { businessMiddleware, loggingMiddleware, validationMiddleware } from '../middlewares'
|
|
@@ -72,6 +73,9 @@ router.post(
|
|
|
72
73
|
...patch,
|
|
73
74
|
id: uuidv4(),
|
|
74
75
|
isRequiredCheckExpiry: patch?.isRequiredCheckExpiry ? patch.isRequiredCheckExpiry : false,
|
|
76
|
+
isRequiredCheckManufactureDate: patch?.isRequiredCheckManufactureDate !== undefined
|
|
77
|
+
? patch.isRequiredCheckManufactureDate
|
|
78
|
+
: false,
|
|
75
79
|
isRequireSerialNumberScanning: patch?.isRequireSerialNumberScanning
|
|
76
80
|
? patch.isRequireSerialNumberScanning
|
|
77
81
|
: false,
|
|
@@ -96,6 +100,8 @@ router.post(
|
|
|
96
100
|
return generateNewProductDetail(pd, product)
|
|
97
101
|
})
|
|
98
102
|
|
|
103
|
+
syncDefaultProductDetailToProduct(product, patch.productDetails)
|
|
104
|
+
|
|
99
105
|
results.push(product)
|
|
100
106
|
_createProducts.push(convertToSnakeCase(product))
|
|
101
107
|
|
|
@@ -186,6 +192,9 @@ router.post(
|
|
|
186
192
|
...matchingProduct,
|
|
187
193
|
...patch,
|
|
188
194
|
id: matchingProduct.id,
|
|
195
|
+
isRequiredCheckManufactureDate: patch?.isRequiredCheckManufactureDate !== undefined
|
|
196
|
+
? patch.isRequiredCheckManufactureDate
|
|
197
|
+
: (matchingProduct?.isRequiredCheckManufactureDate ?? false),
|
|
189
198
|
updaterId: user.id,
|
|
190
199
|
updatedAt: now
|
|
191
200
|
}
|
|
@@ -195,6 +204,8 @@ router.post(
|
|
|
195
204
|
product.productDetails = patch?.productDetails.map(pd => {
|
|
196
205
|
return updateProductDetail(pd, matchingProduct)
|
|
197
206
|
})
|
|
207
|
+
|
|
208
|
+
syncDefaultProductDetailToProduct(product, product.productDetails)
|
|
198
209
|
}
|
|
199
210
|
|
|
200
211
|
results.push(product)
|
|
@@ -351,6 +362,14 @@ router.post(
|
|
|
351
362
|
}
|
|
352
363
|
})
|
|
353
364
|
|
|
365
|
+
_createProducts.forEach(product => {
|
|
366
|
+
webhookHandler({ id: product.id, domain }, bizplace, WebhookEventsEnum.ProductCreated)
|
|
367
|
+
})
|
|
368
|
+
|
|
369
|
+
_updateProducts.forEach(product => {
|
|
370
|
+
webhookHandler({ id: product.id, domain }, bizplace, WebhookEventsEnum.ProductUpdated)
|
|
371
|
+
})
|
|
372
|
+
|
|
354
373
|
//pass response
|
|
355
374
|
context.body = {
|
|
356
375
|
data: massageResponseDate(results)
|
|
@@ -399,7 +418,7 @@ function checkProductDetails(params, data) {
|
|
|
399
418
|
|
|
400
419
|
const matchProductDetail = param.productDetails.find(
|
|
401
420
|
pd =>
|
|
402
|
-
pd.packingSize === foundIsDefaultProdDetail.packingSize &&
|
|
421
|
+
(pd.packingSize === foundIsDefaultProdDetail.packingSize || parseFloat(pd.packingSize) === foundIsDefaultProdDetail.packingSize) &&
|
|
403
422
|
pd.packingType === foundIsDefaultProdDetail.packingType &&
|
|
404
423
|
pd.uom === foundIsDefaultProdDetail.uom
|
|
405
424
|
)
|
|
@@ -411,6 +430,38 @@ function checkProductDetails(params, data) {
|
|
|
411
430
|
})
|
|
412
431
|
}
|
|
413
432
|
|
|
433
|
+
/**
|
|
434
|
+
* Syncs the default product detail's fields to the product.
|
|
435
|
+
* @param product - The product to sync fields to.
|
|
436
|
+
* @param productDetails - The product details array to find the default from.
|
|
437
|
+
*/
|
|
438
|
+
function syncDefaultProductDetailToProduct(product: any, productDetails: any[]) {
|
|
439
|
+
const defaultPd = productDetails.find(pd => pd.isDefault === true)
|
|
440
|
+
if (!defaultPd) return
|
|
441
|
+
|
|
442
|
+
product.packingType = defaultPd.packingType
|
|
443
|
+
product.weightUnit = defaultPd.weightUnit
|
|
444
|
+
product.grossWeight = defaultPd.grossWeight
|
|
445
|
+
product.lengthUnit = defaultPd.lengthUnit
|
|
446
|
+
product.costPrice = defaultPd.costPrice
|
|
447
|
+
product.primaryUnit = defaultPd.uom
|
|
448
|
+
product.primaryValue = defaultPd.uomValue
|
|
449
|
+
product.width = defaultPd.width
|
|
450
|
+
product.depth = defaultPd.depth
|
|
451
|
+
product.height = defaultPd.height
|
|
452
|
+
product.volume = defaultPd.volume
|
|
453
|
+
product.bufferQty = defaultPd.bufferQty
|
|
454
|
+
product.minQty = defaultPd.minQty
|
|
455
|
+
product.maxQty = defaultPd.maxQty
|
|
456
|
+
product.auxUnit1 = defaultPd.auxUnit1
|
|
457
|
+
product.auxValue1 = defaultPd.auxValue1
|
|
458
|
+
product.auxUnit2 = defaultPd.auxUnit2
|
|
459
|
+
product.auxValue2 = defaultPd.auxValue2
|
|
460
|
+
product.auxUnit3 = defaultPd.auxUnit3
|
|
461
|
+
product.auxValue3 = defaultPd.auxValue3
|
|
462
|
+
product.cogsAccountCode = defaultPd.cogsAccountCode
|
|
463
|
+
}
|
|
464
|
+
|
|
414
465
|
/**
|
|
415
466
|
* Converts the keys of an object to snake_case.
|
|
416
467
|
*
|
|
@@ -313,6 +313,42 @@ export const params = {
|
|
|
313
313
|
'pickingStrategy',
|
|
314
314
|
'minInboundShelfLife',
|
|
315
315
|
'minOutboundShelfLife',
|
|
316
|
+
'auxUnit1',
|
|
317
|
+
'auxValue1',
|
|
318
|
+
'auxUnit2',
|
|
319
|
+
'auxValue2',
|
|
320
|
+
'auxUnit3',
|
|
321
|
+
'auxValue3',
|
|
322
|
+
'auxUnit4',
|
|
323
|
+
'auxValue4',
|
|
324
|
+
'auxUnit5',
|
|
325
|
+
'auxValue5',
|
|
326
|
+
'auxUnit6',
|
|
327
|
+
'auxValue6',
|
|
328
|
+
'auxUnit7',
|
|
329
|
+
'auxValue7',
|
|
330
|
+
'auxUnit8',
|
|
331
|
+
'auxValue8',
|
|
332
|
+
'auxUnit9',
|
|
333
|
+
'auxValue9',
|
|
334
|
+
'auxUnit10',
|
|
335
|
+
'auxValue10',
|
|
336
|
+
'auxUnit11',
|
|
337
|
+
'auxValue11',
|
|
338
|
+
'auxUnit12',
|
|
339
|
+
'auxValue12',
|
|
340
|
+
'auxUnit13',
|
|
341
|
+
'auxValue13',
|
|
342
|
+
'auxUnit14',
|
|
343
|
+
'auxValue14',
|
|
344
|
+
'auxUnit15',
|
|
345
|
+
'auxValue15',
|
|
346
|
+
'auxUnit16',
|
|
347
|
+
'auxValue16',
|
|
348
|
+
'auxUnit17',
|
|
349
|
+
'auxValue17',
|
|
350
|
+
'auxUnit18',
|
|
351
|
+
'auxValue18',
|
|
316
352
|
'productDetails',
|
|
317
353
|
'productDetails.isDefault',
|
|
318
354
|
'productDetails.gtin',
|
|
@@ -344,6 +380,32 @@ export const params = {
|
|
|
344
380
|
'productDetails.auxValue4',
|
|
345
381
|
'productDetails.auxUnit5',
|
|
346
382
|
'productDetails.auxValue5',
|
|
383
|
+
'productDetails.auxUnit6',
|
|
384
|
+
'productDetails.auxValue6',
|
|
385
|
+
'productDetails.auxUnit7',
|
|
386
|
+
'productDetails.auxValue7',
|
|
387
|
+
'productDetails.auxUnit8',
|
|
388
|
+
'productDetails.auxValue8',
|
|
389
|
+
'productDetails.auxUnit9',
|
|
390
|
+
'productDetails.auxValue9',
|
|
391
|
+
'productDetails.auxUnit10',
|
|
392
|
+
'productDetails.auxValue10',
|
|
393
|
+
'productDetails.auxUnit11',
|
|
394
|
+
'productDetails.auxValue11',
|
|
395
|
+
'productDetails.auxUnit12',
|
|
396
|
+
'productDetails.auxValue12',
|
|
397
|
+
'productDetails.auxUnit13',
|
|
398
|
+
'productDetails.auxValue13',
|
|
399
|
+
'productDetails.auxUnit14',
|
|
400
|
+
'productDetails.auxValue14',
|
|
401
|
+
'productDetails.auxUnit15',
|
|
402
|
+
'productDetails.auxValue15',
|
|
403
|
+
'productDetails.auxUnit16',
|
|
404
|
+
'productDetails.auxValue16',
|
|
405
|
+
'productDetails.auxUnit17',
|
|
406
|
+
'productDetails.auxValue17',
|
|
407
|
+
'productDetails.auxUnit18',
|
|
408
|
+
'productDetails.auxValue18',
|
|
347
409
|
'productDetails.childProductDetail',
|
|
348
410
|
'productDetails.productBarcodes',
|
|
349
411
|
'productDetails.productBarcodes.gtin'
|
|
@@ -685,6 +747,42 @@ export const params = {
|
|
|
685
747
|
'pickingStrategy',
|
|
686
748
|
'minInboundShelfLife',
|
|
687
749
|
'minOutboundShelfLife',
|
|
750
|
+
'auxUnit1',
|
|
751
|
+
'auxValue1',
|
|
752
|
+
'auxUnit2',
|
|
753
|
+
'auxValue2',
|
|
754
|
+
'auxUnit3',
|
|
755
|
+
'auxValue3',
|
|
756
|
+
'auxUnit4',
|
|
757
|
+
'auxValue4',
|
|
758
|
+
'auxUnit5',
|
|
759
|
+
'auxValue5',
|
|
760
|
+
'auxUnit6',
|
|
761
|
+
'auxValue6',
|
|
762
|
+
'auxUnit7',
|
|
763
|
+
'auxValue7',
|
|
764
|
+
'auxUnit8',
|
|
765
|
+
'auxValue8',
|
|
766
|
+
'auxUnit9',
|
|
767
|
+
'auxValue9',
|
|
768
|
+
'auxUnit10',
|
|
769
|
+
'auxValue10',
|
|
770
|
+
'auxUnit11',
|
|
771
|
+
'auxValue11',
|
|
772
|
+
'auxUnit12',
|
|
773
|
+
'auxValue12',
|
|
774
|
+
'auxUnit13',
|
|
775
|
+
'auxValue13',
|
|
776
|
+
'auxUnit14',
|
|
777
|
+
'auxValue14',
|
|
778
|
+
'auxUnit15',
|
|
779
|
+
'auxValue15',
|
|
780
|
+
'auxUnit16',
|
|
781
|
+
'auxValue16',
|
|
782
|
+
'auxUnit17',
|
|
783
|
+
'auxValue17',
|
|
784
|
+
'auxUnit18',
|
|
785
|
+
'auxValue18',
|
|
688
786
|
'productDetails',
|
|
689
787
|
'productDetails.isDefault',
|
|
690
788
|
'productDetails.name',
|
|
@@ -716,8 +814,35 @@ export const params = {
|
|
|
716
814
|
'productDetails.auxValue4',
|
|
717
815
|
'productDetails.auxUnit5',
|
|
718
816
|
'productDetails.auxValue5',
|
|
817
|
+
'productDetails.auxUnit6',
|
|
818
|
+
'productDetails.auxValue6',
|
|
819
|
+
'productDetails.auxUnit7',
|
|
820
|
+
'productDetails.auxValue7',
|
|
821
|
+
'productDetails.auxUnit8',
|
|
822
|
+
'productDetails.auxValue8',
|
|
823
|
+
'productDetails.auxUnit9',
|
|
824
|
+
'productDetails.auxValue9',
|
|
825
|
+
'productDetails.auxUnit10',
|
|
826
|
+
'productDetails.auxValue10',
|
|
827
|
+
'productDetails.auxUnit11',
|
|
828
|
+
'productDetails.auxValue11',
|
|
829
|
+
'productDetails.auxUnit12',
|
|
830
|
+
'productDetails.auxValue12',
|
|
831
|
+
'productDetails.auxUnit13',
|
|
832
|
+
'productDetails.auxValue13',
|
|
833
|
+
'productDetails.auxUnit14',
|
|
834
|
+
'productDetails.auxValue14',
|
|
835
|
+
'productDetails.auxUnit15',
|
|
836
|
+
'productDetails.auxValue15',
|
|
837
|
+
'productDetails.auxUnit16',
|
|
838
|
+
'productDetails.auxValue16',
|
|
839
|
+
'productDetails.auxUnit17',
|
|
840
|
+
'productDetails.auxValue17',
|
|
841
|
+
'productDetails.auxUnit18',
|
|
842
|
+
'productDetails.auxValue18',
|
|
719
843
|
'productDetails.childProductDetail',
|
|
720
844
|
'productDetails.childQty',
|
|
845
|
+
'productDetails.cogsAccountCode',
|
|
721
846
|
'productDetails.productBarcodes.gtin'
|
|
722
847
|
],
|
|
723
848
|
'add-sales-invoice': [
|