@things-factory/product-base 4.3.122 → 4.3.138
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/service/index.js +7 -2
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/product/product-mutation.js +17 -4
- package/dist-server/service/product/product-mutation.js.map +1 -1
- package/dist-server/service/product/product.js +6 -0
- package/dist-server/service/product/product.js.map +1 -1
- package/dist-server/service/product-barcode/index.js +9 -0
- package/dist-server/service/product-barcode/index.js.map +1 -0
- package/dist-server/service/product-barcode/product-barcode-mutation.js +120 -0
- package/dist-server/service/product-barcode/product-barcode-mutation.js.map +1 -0
- package/dist-server/service/product-barcode/product-barcode-query.js +87 -0
- package/dist-server/service/product-barcode/product-barcode-query.js.map +1 -0
- package/dist-server/service/product-barcode/product-barcode-type.js +63 -0
- package/dist-server/service/product-barcode/product-barcode-type.js.map +1 -0
- package/dist-server/service/product-barcode/product-barcode.js +99 -0
- package/dist-server/service/product-barcode/product-barcode.js.map +1 -0
- package/dist-server/service/product-bundle-setting/product-bundle-setting-query.js +3 -1
- package/dist-server/service/product-bundle-setting/product-bundle-setting-query.js.map +1 -1
- package/dist-server/service/product-detail/product-detail-mutation.js +70 -13
- package/dist-server/service/product-detail/product-detail-mutation.js.map +1 -1
- package/dist-server/service/product-detail/product-detail-query.js +12 -7
- package/dist-server/service/product-detail/product-detail-query.js.map +1 -1
- package/dist-server/service/product-detail/product-detail-types.js +4 -3
- package/dist-server/service/product-detail/product-detail-types.js.map +1 -1
- package/dist-server/service/product-detail/product-detail.js +8 -2
- package/dist-server/service/product-detail/product-detail.js.map +1 -1
- package/dist-server/service/product-detail-bizplace-setting/product-detail-bizplace-setting-mutation.js +8 -4
- package/dist-server/service/product-detail-bizplace-setting/product-detail-bizplace-setting-mutation.js.map +1 -1
- package/package.json +4 -5
- package/server/service/index.ts +7 -2
- package/server/service/product/product-mutation.ts +21 -4
- package/server/service/product/product.ts +5 -0
- package/server/service/product-barcode/index.ts +6 -0
- package/server/service/product-barcode/product-barcode-mutation.ts +112 -0
- package/server/service/product-barcode/product-barcode-query.ts +43 -0
- package/server/service/product-barcode/product-barcode-type.ts +35 -0
- package/server/service/product-barcode/product-barcode.ts +78 -0
- package/server/service/product-bundle-setting/product-bundle-setting-query.ts +6 -4
- package/server/service/product-detail/product-detail-mutation.ts +79 -11
- package/server/service/product-detail/product-detail-query.ts +14 -8
- package/server/service/product-detail/product-detail-types.ts +6 -2
- package/server/service/product-detail/product-detail.ts +7 -2
- package/server/service/product-detail-bizplace-setting/product-detail-bizplace-setting-mutation.ts +8 -4
- package/LICENSE.md +0 -21
package/package.json
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/product-base",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.138",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"browser": "client/index.js",
|
|
6
6
|
"things-factory": true,
|
|
7
|
-
"license": "MIT",
|
|
8
7
|
"author": "",
|
|
9
8
|
"description": "Server module that handles product",
|
|
10
9
|
"publishConfig": {
|
|
@@ -24,8 +23,8 @@
|
|
|
24
23
|
"migration:create": "node ../../node_modules/typeorm/cli.js migration:create -d ./server/migrations"
|
|
25
24
|
},
|
|
26
25
|
"dependencies": {
|
|
27
|
-
"@things-factory/biz-base": "^4.3.
|
|
28
|
-
"@things-factory/routing-base": "^4.3.
|
|
26
|
+
"@things-factory/biz-base": "^4.3.138",
|
|
27
|
+
"@things-factory/routing-base": "^4.3.138"
|
|
29
28
|
},
|
|
30
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "1d4e0a3ff6b8792c843b9735a28a3f5fb946b144"
|
|
31
30
|
}
|
package/server/service/index.ts
CHANGED
|
@@ -15,8 +15,10 @@ import {
|
|
|
15
15
|
entities as ProductCombinationSettingEntities,
|
|
16
16
|
resolvers as ProductCombinationSettingResolvers
|
|
17
17
|
} from './product-combination-setting'
|
|
18
|
+
import { entities as ProductBarcodeEntities, resolvers as ProductBarcodeResolvers } from './product-barcode'
|
|
18
19
|
|
|
19
20
|
/* EXPORT ENTITY TYPES */
|
|
21
|
+
export * from './product-barcode/product-barcode'
|
|
20
22
|
export * from './product-combination-setting/product-combination-setting'
|
|
21
23
|
export * from './product-combination/product-combination'
|
|
22
24
|
export * from './product/product'
|
|
@@ -27,6 +29,7 @@ export * from './product-detail-bizplace-setting/product-detail-bizplace-setting
|
|
|
27
29
|
export * from './product-set/product-set'
|
|
28
30
|
|
|
29
31
|
/* EXPORT TYPES */
|
|
32
|
+
export * from './product-barcode/product-barcode-type'
|
|
30
33
|
export * from './product-combination/product-combination-type'
|
|
31
34
|
export * from './product-combination-setting/product-combination-setting-type'
|
|
32
35
|
export * from './product/product-types'
|
|
@@ -44,7 +47,8 @@ export const entities = [
|
|
|
44
47
|
...ProductDetailBizplaceSettingEntities,
|
|
45
48
|
...ProductSetEntities,
|
|
46
49
|
...ProductCombinationEntities,
|
|
47
|
-
...ProductCombinationSettingEntities
|
|
50
|
+
...ProductCombinationSettingEntities,
|
|
51
|
+
...ProductBarcodeEntities
|
|
48
52
|
]
|
|
49
53
|
|
|
50
54
|
export const schema = {
|
|
@@ -56,6 +60,7 @@ export const schema = {
|
|
|
56
60
|
...ProductDetailBizplaceSettingResolver,
|
|
57
61
|
...ProductSetResolvers,
|
|
58
62
|
...ProductCombinationResolvers,
|
|
59
|
-
...ProductCombinationSettingResolvers
|
|
63
|
+
...ProductCombinationSettingResolvers,
|
|
64
|
+
...ProductBarcodeResolvers
|
|
60
65
|
]
|
|
61
66
|
}
|
|
@@ -10,6 +10,7 @@ import { Domain } from '@things-factory/shell'
|
|
|
10
10
|
|
|
11
11
|
import { PRODUCT_STATUS } from '../../constants'
|
|
12
12
|
import { ProductDetail } from '../product-detail/product-detail'
|
|
13
|
+
import { ProductBarcode } from '../product-barcode/product-barcode'
|
|
13
14
|
import {
|
|
14
15
|
createProductDetail,
|
|
15
16
|
updateMultipleProductDetail,
|
|
@@ -269,11 +270,27 @@ export async function createProduct(product: any, context: any) {
|
|
|
269
270
|
updater: user
|
|
270
271
|
})
|
|
271
272
|
|
|
272
|
-
let productDetails
|
|
273
|
-
if (
|
|
273
|
+
let productDetails
|
|
274
|
+
if (product.productDetails) {
|
|
275
|
+
productDetails = product.productDetails.reduce((acc, currentObj) => {
|
|
276
|
+
let existingProductDetail = acc.find(
|
|
277
|
+
itm => itm.packingType == currentObj.packingType && itm.uom == currentObj.uom
|
|
278
|
+
)
|
|
279
|
+
if (existingProductDetail) {
|
|
280
|
+
existingProductDetail.productBarcodes = [...existingProductDetail.productBarcodes, { gtin: currentObj.gtin }]
|
|
281
|
+
return acc
|
|
282
|
+
} else {
|
|
283
|
+
let newProductDetail = {
|
|
284
|
+
...currentObj,
|
|
285
|
+
productBarcodes: [{ gtin: currentObj.gtin }]
|
|
286
|
+
}
|
|
287
|
+
return [...acc, newProductDetail]
|
|
288
|
+
}
|
|
289
|
+
}, [])
|
|
290
|
+
} else {
|
|
274
291
|
productDetails = [new ProductDetail({ ...product, product: result, isDefault: true })]
|
|
275
|
-
if (productDetails[0].
|
|
276
|
-
productDetails[0].
|
|
292
|
+
if (!productDetails[0].productBarcodes || productDetails[0].productBarcodes.length < 1) {
|
|
293
|
+
productDetails[0].productBarcodes = [{ gtin: product.sku }]
|
|
277
294
|
}
|
|
278
295
|
}
|
|
279
296
|
|
|
@@ -18,6 +18,7 @@ import { Routing } from '@things-factory/routing-base'
|
|
|
18
18
|
import { Domain } from '@things-factory/shell'
|
|
19
19
|
|
|
20
20
|
import { ProductDetail } from '../product-detail/product-detail'
|
|
21
|
+
import { ProductBarcode } from '../product-barcode/product-barcode'
|
|
21
22
|
import { ProductSet } from '../product-set/product-set'
|
|
22
23
|
|
|
23
24
|
const ORMCONFIG = config.get('ormconfig', {})
|
|
@@ -115,6 +116,10 @@ export class Product {
|
|
|
115
116
|
@Field(type => [ProductDetail], { nullable: true })
|
|
116
117
|
productDetails: ProductDetail[]
|
|
117
118
|
|
|
119
|
+
@OneToMany(type => ProductBarcode, productBarcodes => productBarcodes.product, { nullable: true })
|
|
120
|
+
@Field(type => [ProductBarcode], { nullable: true })
|
|
121
|
+
productBarcodes: ProductBarcode[]
|
|
122
|
+
|
|
118
123
|
@ManyToOne(type => Product, { nullable: true })
|
|
119
124
|
@Field({ nullable: true })
|
|
120
125
|
productRef: Product
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ProductBarcode } from './product-barcode'
|
|
2
|
+
import { ProductBarcodeQuery } from './product-barcode-query'
|
|
3
|
+
import { ProductBarcodeMutation } from './product-barcode-mutation'
|
|
4
|
+
|
|
5
|
+
export const entities = [ProductBarcode]
|
|
6
|
+
export const resolvers = [ProductBarcodeQuery, ProductBarcodeMutation]
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'
|
|
2
|
+
import { getRepository, In } from 'typeorm'
|
|
3
|
+
import { ProductBarcode } from './product-barcode'
|
|
4
|
+
import { NewProductBarcode, ProductBarcodePatch } from './product-barcode-type'
|
|
5
|
+
|
|
6
|
+
@Resolver(ProductBarcode)
|
|
7
|
+
export class ProductBarcodeMutation {
|
|
8
|
+
@Directive('@transaction')
|
|
9
|
+
@Mutation(returns => ProductBarcode, { description: 'To create new ProductBarcode' })
|
|
10
|
+
async createProductBarcode(
|
|
11
|
+
@Arg('productBarcode') productBarcode: NewProductBarcode,
|
|
12
|
+
@Ctx() context: any
|
|
13
|
+
): Promise<ProductBarcode> {
|
|
14
|
+
const { domain, user, tx } = context.state
|
|
15
|
+
|
|
16
|
+
return await tx.getRepository(ProductBarcode).save({
|
|
17
|
+
...productBarcode,
|
|
18
|
+
domain,
|
|
19
|
+
creator: user,
|
|
20
|
+
updater: user
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@Directive('@transaction')
|
|
25
|
+
@Mutation(returns => ProductBarcode, { description: 'To modify ProductBarcode information' })
|
|
26
|
+
async updateProductBarcode(
|
|
27
|
+
@Arg('id') id: string,
|
|
28
|
+
@Arg('patch') patch: ProductBarcodePatch,
|
|
29
|
+
@Ctx() context: any
|
|
30
|
+
): Promise<ProductBarcode> {
|
|
31
|
+
const { domain, user, tx } = context.state
|
|
32
|
+
|
|
33
|
+
const repository = tx.getRepository(ProductBarcode)
|
|
34
|
+
const productBarcode = await repository.findOne({
|
|
35
|
+
where: { domain, id }
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
return await repository.save({
|
|
39
|
+
...productBarcode,
|
|
40
|
+
...patch,
|
|
41
|
+
updater: user
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@Directive('@transaction')
|
|
46
|
+
@Mutation(returns => [ProductBarcode], { description: "To modify multiple ProductBarcodes' information" })
|
|
47
|
+
async updateMultipleProductBarcode(
|
|
48
|
+
@Arg('patches', type => [ProductBarcodePatch]) patches: ProductBarcodePatch[],
|
|
49
|
+
@Ctx() context: any
|
|
50
|
+
): Promise<ProductBarcode[]> {
|
|
51
|
+
const { domain, user, tx } = context.state
|
|
52
|
+
|
|
53
|
+
let results = []
|
|
54
|
+
const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
|
|
55
|
+
const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
|
|
56
|
+
const productBarcodeRepo = tx.getRepository(ProductBarcode)
|
|
57
|
+
|
|
58
|
+
if (_createRecords.length > 0) {
|
|
59
|
+
for (let i = 0; i < _createRecords.length; i++) {
|
|
60
|
+
const newRecord = _createRecords[i]
|
|
61
|
+
|
|
62
|
+
const result = await productBarcodeRepo.save({
|
|
63
|
+
...newRecord,
|
|
64
|
+
domain,
|
|
65
|
+
creator: user,
|
|
66
|
+
updater: user
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
results.push({ ...result, cuFlag: '+' })
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (_updateRecords.length > 0) {
|
|
74
|
+
for (let i = 0; i < _updateRecords.length; i++) {
|
|
75
|
+
const newRecord = _updateRecords[i]
|
|
76
|
+
const productBarcode = await productBarcodeRepo.findOne(newRecord.id)
|
|
77
|
+
|
|
78
|
+
const result = await productBarcodeRepo.save({
|
|
79
|
+
...productBarcode,
|
|
80
|
+
...newRecord,
|
|
81
|
+
updater: user
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
results.push({ ...result, cuFlag: 'M' })
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return results
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@Directive('@transaction')
|
|
92
|
+
@Mutation(returns => Boolean, { description: 'To delete ProductBarcode' })
|
|
93
|
+
async deleteProductBarcode(@Arg('id') id: string, @Ctx() context: any): Promise<boolean> {
|
|
94
|
+
const { domain, tx } = context.state
|
|
95
|
+
|
|
96
|
+
await tx.getRepository(ProductBarcode).delete({ domain, id })
|
|
97
|
+
return true
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@Directive('@transaction')
|
|
101
|
+
@Mutation(returns => Boolean, { description: 'To delete multiple productBarcodes' })
|
|
102
|
+
async deleteProductBarcodes(@Arg('ids', type => [String]) ids: string[], @Ctx() context: any): Promise<boolean> {
|
|
103
|
+
const { domain, tx } = context.state
|
|
104
|
+
|
|
105
|
+
await tx.getRepository(ProductBarcode).delete({
|
|
106
|
+
domain,
|
|
107
|
+
id: In(ids)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
return true
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'
|
|
2
|
+
import { getRepository } from 'typeorm'
|
|
3
|
+
import { Domain, ListParam, convertListParams } from '@things-factory/shell'
|
|
4
|
+
import { User } from '@things-factory/auth-base'
|
|
5
|
+
import { ProductBarcode } from './product-barcode'
|
|
6
|
+
import { ProductBarcodeList } from './product-barcode-type'
|
|
7
|
+
|
|
8
|
+
@Resolver(ProductBarcode)
|
|
9
|
+
export class ProductBarcodeQuery {
|
|
10
|
+
@Query(returns => ProductBarcode, { description: 'To fetch a ProductBarcode' })
|
|
11
|
+
async productBarcode(@Arg('id') id: string, @Ctx() context: any): Promise<ProductBarcode> {
|
|
12
|
+
const { domain } = context.state
|
|
13
|
+
|
|
14
|
+
return await getRepository(ProductBarcode).findOne({
|
|
15
|
+
where: { domain, id }
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@Query(returns => ProductBarcodeList, { description: 'To fetch multiple ProductBarcodes' })
|
|
20
|
+
async productBarcodes(@Args() params: ListParam, @Ctx() context: any): Promise<ProductBarcodeList> {
|
|
21
|
+
const { domain } = context.state
|
|
22
|
+
|
|
23
|
+
const convertedParams = convertListParams(params, domain.id)
|
|
24
|
+
const [items, total] = await getRepository(ProductBarcode).findAndCount(convertedParams)
|
|
25
|
+
|
|
26
|
+
return { items, total }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@FieldResolver(type => Domain)
|
|
30
|
+
async domain(@Root() productBarcode: ProductBarcode): Promise<Domain> {
|
|
31
|
+
return await getRepository(Domain).findOne(productBarcode.domainId)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@FieldResolver(type => User)
|
|
35
|
+
async updater(@Root() productBarcode: ProductBarcode): Promise<User> {
|
|
36
|
+
return await getRepository(User).findOne(productBarcode.updaterId)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@FieldResolver(type => User)
|
|
40
|
+
async creator(@Root() productBarcode: ProductBarcode): Promise<User> {
|
|
41
|
+
return await getRepository(User).findOne(productBarcode.creatorId)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ObjectType, Field, InputType, Int, ID, registerEnumType } from 'type-graphql'
|
|
2
|
+
|
|
3
|
+
import { ObjectRef } from '@things-factory/shell'
|
|
4
|
+
|
|
5
|
+
import { ProductBarcode } from './product-barcode'
|
|
6
|
+
|
|
7
|
+
@InputType()
|
|
8
|
+
export class NewProductBarcode {
|
|
9
|
+
@Field()
|
|
10
|
+
name: string
|
|
11
|
+
|
|
12
|
+
@Field()
|
|
13
|
+
productDetail: ObjectRef
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@InputType()
|
|
17
|
+
export class ProductBarcodePatch {
|
|
18
|
+
@Field(type => ID, { nullable: true })
|
|
19
|
+
id?: string
|
|
20
|
+
|
|
21
|
+
@Field({ nullable: true })
|
|
22
|
+
gtin?: string
|
|
23
|
+
|
|
24
|
+
@Field({ nullable: true })
|
|
25
|
+
cuFlag: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@ObjectType()
|
|
29
|
+
export class ProductBarcodeList {
|
|
30
|
+
@Field(type => [ProductBarcode])
|
|
31
|
+
items: ProductBarcode[]
|
|
32
|
+
|
|
33
|
+
@Field(type => Int)
|
|
34
|
+
total: number
|
|
35
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CreateDateColumn,
|
|
3
|
+
UpdateDateColumn,
|
|
4
|
+
Entity,
|
|
5
|
+
Index,
|
|
6
|
+
Column,
|
|
7
|
+
RelationId,
|
|
8
|
+
ManyToOne,
|
|
9
|
+
PrimaryGeneratedColumn
|
|
10
|
+
} from 'typeorm'
|
|
11
|
+
import { ObjectType, Field, ID } from 'type-graphql'
|
|
12
|
+
|
|
13
|
+
import { ProductDetail } from '../product-detail/product-detail'
|
|
14
|
+
import { Product } from '../product/product'
|
|
15
|
+
import { Domain } from '@things-factory/shell'
|
|
16
|
+
import { User } from '@things-factory/auth-base'
|
|
17
|
+
|
|
18
|
+
@Entity()
|
|
19
|
+
@Index('ix_product_barcode_0', (productBarcode: ProductBarcode) => [productBarcode.domain, productBarcode.id], {
|
|
20
|
+
unique: true
|
|
21
|
+
})
|
|
22
|
+
@ObjectType({ description: 'Entity for ProductBarcode' })
|
|
23
|
+
export class ProductBarcode {
|
|
24
|
+
@PrimaryGeneratedColumn('uuid')
|
|
25
|
+
@Field(type => ID)
|
|
26
|
+
readonly id: string
|
|
27
|
+
|
|
28
|
+
@ManyToOne(type => Domain)
|
|
29
|
+
@Field({ nullable: true })
|
|
30
|
+
domain?: Domain
|
|
31
|
+
|
|
32
|
+
@RelationId((productBarcode: ProductBarcode) => productBarcode.domain)
|
|
33
|
+
domainId?: string
|
|
34
|
+
|
|
35
|
+
@Column()
|
|
36
|
+
@Field()
|
|
37
|
+
gtin: string
|
|
38
|
+
|
|
39
|
+
@ManyToOne(type => Product)
|
|
40
|
+
@Field(type => Product)
|
|
41
|
+
product?: Product
|
|
42
|
+
|
|
43
|
+
@RelationId((productBarcode: ProductBarcode) => productBarcode.product)
|
|
44
|
+
productId?: string
|
|
45
|
+
|
|
46
|
+
@ManyToOne(type => ProductDetail)
|
|
47
|
+
@Field(type => ProductDetail)
|
|
48
|
+
productDetail?: ProductDetail
|
|
49
|
+
|
|
50
|
+
@RelationId((productBarcode: ProductBarcode) => productBarcode.productDetail)
|
|
51
|
+
productDetailId?: string
|
|
52
|
+
|
|
53
|
+
@CreateDateColumn()
|
|
54
|
+
@Field({ nullable: true })
|
|
55
|
+
createdAt?: Date
|
|
56
|
+
|
|
57
|
+
@UpdateDateColumn()
|
|
58
|
+
@Field({ nullable: true })
|
|
59
|
+
updatedAt?: Date
|
|
60
|
+
|
|
61
|
+
@ManyToOne(type => User, {
|
|
62
|
+
nullable: true
|
|
63
|
+
})
|
|
64
|
+
@Field({ nullable: true })
|
|
65
|
+
creator?: User
|
|
66
|
+
|
|
67
|
+
@RelationId((productBarcode: ProductBarcode) => productBarcode.creator)
|
|
68
|
+
creatorId?: string
|
|
69
|
+
|
|
70
|
+
@ManyToOne(type => User, {
|
|
71
|
+
nullable: true
|
|
72
|
+
})
|
|
73
|
+
@Field({ nullable: true })
|
|
74
|
+
updater?: User
|
|
75
|
+
|
|
76
|
+
@RelationId((productBarcode: ProductBarcode) => productBarcode.updater)
|
|
77
|
+
updaterId?: string
|
|
78
|
+
}
|
|
@@ -86,10 +86,14 @@ export class ProductBundleSettingQuery {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
let productBundleSets = await qb
|
|
89
|
-
.offset((page - 1) * limit)
|
|
90
|
-
.limit(limit)
|
|
91
89
|
.getRawMany()
|
|
92
90
|
|
|
91
|
+
const total = productBundleSets.length
|
|
92
|
+
productBundleSets = await qb
|
|
93
|
+
.offset((page - 1) * limit)
|
|
94
|
+
.limit(limit)
|
|
95
|
+
.getRawMany()
|
|
96
|
+
|
|
93
97
|
const items = productBundleSets.map(item => {
|
|
94
98
|
return {
|
|
95
99
|
// id: item.pbs_id,
|
|
@@ -126,8 +130,6 @@ export class ProductBundleSettingQuery {
|
|
|
126
130
|
}
|
|
127
131
|
})
|
|
128
132
|
|
|
129
|
-
const total = await qb.getCount()
|
|
130
|
-
|
|
131
133
|
return { items, total }
|
|
132
134
|
}
|
|
133
135
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
2
|
import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
|
|
3
3
|
import { getRepository, In, Raw } from 'typeorm'
|
|
4
|
+
import { ProductBarcode } from '../product-barcode/product-barcode'
|
|
4
5
|
|
|
5
6
|
import { Product } from '../product/product'
|
|
6
7
|
import { ProductDetail } from './product-detail'
|
|
@@ -89,14 +90,39 @@ export async function updateMultipleProductDetail(productId, patches, context: a
|
|
|
89
90
|
const { domain, user, tx } = context.state
|
|
90
91
|
|
|
91
92
|
let results = []
|
|
92
|
-
const _createRecords = patches.filter((patch: any) => !patch.id)
|
|
93
|
-
const _updateRecords = patches.filter((patch: any) => patch.id)
|
|
94
93
|
// const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
|
|
95
94
|
|
|
95
|
+
patches.map(itm => {
|
|
96
|
+
let name = itm.name ? itm.name : itm.packingType + '-' + itm.packingSize + '-' + itm.uom
|
|
97
|
+
|
|
98
|
+
let maxCounter = 1
|
|
99
|
+
patches.find(itm => {
|
|
100
|
+
if (itm.name && itm.name.includes(name)) {
|
|
101
|
+
let itmCounter = parseInt(itm.name[itm.name.indexOf('(') + 1])
|
|
102
|
+
|
|
103
|
+
if (itmCounter && itmCounter == maxCounter) {
|
|
104
|
+
maxCounter = itmCounter + 1
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
name += '(' + maxCounter + ')'
|
|
110
|
+
|
|
111
|
+
if (!itm.name || itm.name == '') {
|
|
112
|
+
itm.name = name
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
const _createRecords = patches.filter((patch: any) => !patch.id)
|
|
117
|
+
const _updateRecords = patches.filter((patch: any) => patch.id)
|
|
96
118
|
const productRepo = tx.getRepository(Product)
|
|
97
119
|
const productDetailRepo = tx.getRepository(ProductDetail)
|
|
120
|
+
const productBarcodeRepo = tx.getRepository(ProductBarcode)
|
|
98
121
|
|
|
99
|
-
const product: Product = await productRepo.findOne({
|
|
122
|
+
const product: Product = await productRepo.findOne({
|
|
123
|
+
where: { id: productId },
|
|
124
|
+
relations: ['productDetails']
|
|
125
|
+
})
|
|
100
126
|
|
|
101
127
|
const defaultProductDetail: ProductDetail = patches.find(x => x.isDefault)
|
|
102
128
|
|
|
@@ -104,8 +130,9 @@ export async function updateMultipleProductDetail(productId, patches, context: a
|
|
|
104
130
|
for (let i = 0; i < _createRecords.length; i++) {
|
|
105
131
|
const newRecord = {
|
|
106
132
|
..._createRecords[i],
|
|
107
|
-
|
|
133
|
+
gtin: _createRecords[i]?.productBarcodes[0].gtin,
|
|
108
134
|
product,
|
|
135
|
+
packingSize: _createRecords[i].packingSize <= 0 ? 1 : _createRecords[i].packingSize,
|
|
109
136
|
childProductDetail: null,
|
|
110
137
|
childQty: 0,
|
|
111
138
|
domain: domain,
|
|
@@ -113,11 +140,23 @@ export async function updateMultipleProductDetail(productId, patches, context: a
|
|
|
113
140
|
updater: user
|
|
114
141
|
}
|
|
115
142
|
|
|
116
|
-
if (newRecord.
|
|
143
|
+
if (!newRecord.productBarcodes || newRecord.productBarcodes.length < 1) {
|
|
117
144
|
throw new Error('GTIN cannot be empty.')
|
|
118
145
|
}
|
|
119
146
|
|
|
120
147
|
const result = await productDetailRepo.save(newRecord)
|
|
148
|
+
for (let i = 0; i < newRecord.productBarcodes.length; i++) {
|
|
149
|
+
const newProductBarcode = {
|
|
150
|
+
gtin: newRecord.productBarcodes[i].gtin,
|
|
151
|
+
product,
|
|
152
|
+
productDetail: newRecord.id,
|
|
153
|
+
domain: domain,
|
|
154
|
+
creator: user,
|
|
155
|
+
updater: user
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
await productBarcodeRepo.save(newProductBarcode)
|
|
159
|
+
}
|
|
121
160
|
|
|
122
161
|
results.push({ ...result, cuFlag: '+' })
|
|
123
162
|
}
|
|
@@ -128,42 +167,71 @@ export async function updateMultipleProductDetail(productId, patches, context: a
|
|
|
128
167
|
let updateRecords = _updateRecords.find(ur => ur.id == product.productDetails[x].id)
|
|
129
168
|
|
|
130
169
|
if (updateRecords) {
|
|
131
|
-
const productDetail: ProductDetail = await productDetailRepo.findOne({
|
|
170
|
+
const productDetail: ProductDetail = await productDetailRepo.findOne({
|
|
171
|
+
where: { id: updateRecords.id },
|
|
172
|
+
relations: ['productBarcodes']
|
|
173
|
+
})
|
|
132
174
|
|
|
133
175
|
const updateRecord = {
|
|
134
176
|
...productDetail,
|
|
135
177
|
...updateRecords,
|
|
136
|
-
name: updateRecords.
|
|
178
|
+
name: updateRecords.name,
|
|
137
179
|
product,
|
|
138
180
|
childProductDetail: null,
|
|
139
181
|
childQty: 0,
|
|
140
182
|
updater: user
|
|
141
183
|
}
|
|
142
184
|
|
|
143
|
-
if (updateRecord.
|
|
185
|
+
if (!updateRecord.productBarcodes || updateRecord.productBarcodes.length < 1) {
|
|
144
186
|
throw new Error('GTIN cannot be empty.')
|
|
145
187
|
}
|
|
146
188
|
|
|
147
189
|
const result = await productDetailRepo.save({
|
|
148
190
|
...productDetail,
|
|
149
191
|
...updateRecord,
|
|
150
|
-
name: updateRecord.
|
|
192
|
+
name: updateRecord.name,
|
|
151
193
|
product,
|
|
152
194
|
childProductDetail: null,
|
|
153
195
|
childQty: 0,
|
|
154
196
|
updater: user
|
|
155
197
|
})
|
|
156
198
|
|
|
199
|
+
for (let i = 0; i < updateRecord.productBarcodes.length; i++) {
|
|
200
|
+
let foundProductBarcode = productDetail.productBarcodes.find(
|
|
201
|
+
itm => itm.gtin == updateRecord.productBarcodes[i].gtin
|
|
202
|
+
)
|
|
203
|
+
if (!foundProductBarcode) {
|
|
204
|
+
const newProductBarcode = {
|
|
205
|
+
gtin: updateRecord.productBarcodes[i].gtin,
|
|
206
|
+
product,
|
|
207
|
+
productDetail: updateRecord.id,
|
|
208
|
+
domain: domain,
|
|
209
|
+
creator: user,
|
|
210
|
+
updater: user
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
await productBarcodeRepo.save(newProductBarcode)
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
let deleteProductBarcodeIds = productDetail.productBarcodes.map(itm => {
|
|
217
|
+
if (!updateRecord.productBarcodes.find(pb => pb.gtin == itm.gtin)) {
|
|
218
|
+
return itm.id
|
|
219
|
+
}
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
await productBarcodeRepo.delete({ id: In(deleteProductBarcodeIds) })
|
|
223
|
+
|
|
157
224
|
results.push({ ...result, cuFlag: 'M' })
|
|
158
225
|
} else {
|
|
159
226
|
deleteIds.push(product.productDetails[x].id)
|
|
160
227
|
}
|
|
161
228
|
}
|
|
162
229
|
|
|
230
|
+
await productBarcodeRepo.delete({ productDetail: In(deleteIds) })
|
|
163
231
|
await productDetailRepo.delete({ id: In(deleteIds) })
|
|
164
232
|
|
|
165
233
|
for await (let patch of patches.filter(x => x.childProductDetail)) {
|
|
166
|
-
let matchedChildProductDetail = results.find(itm => itm.
|
|
234
|
+
let matchedChildProductDetail = results.find(itm => itm.name == patch.childProductDetail)
|
|
167
235
|
|
|
168
236
|
if (matchedChildProductDetail) {
|
|
169
237
|
const childProductDetail: ProductDetail = await productDetailRepo.findOne({
|
|
@@ -171,7 +239,7 @@ export async function updateMultipleProductDetail(productId, patches, context: a
|
|
|
171
239
|
relations: ['product']
|
|
172
240
|
})
|
|
173
241
|
const productDetail: ProductDetail = await productDetailRepo.findOne({
|
|
174
|
-
where: {
|
|
242
|
+
where: { name: patch.name, product: childProductDetail.product }
|
|
175
243
|
})
|
|
176
244
|
|
|
177
245
|
await productDetailRepo.save({
|
|
@@ -7,6 +7,7 @@ import { buildCondition, buildQuery, Domain, Filter, Pagination, Sorting } from
|
|
|
7
7
|
|
|
8
8
|
import { ProductDetail } from './product-detail'
|
|
9
9
|
import { ProductDetailList } from './product-detail-types'
|
|
10
|
+
import { ProductBarcode } from '../product-barcode/product-barcode'
|
|
10
11
|
|
|
11
12
|
@Resolver(ProductDetail)
|
|
12
13
|
export class ProductDetailQuery {
|
|
@@ -76,6 +77,9 @@ export class ProductDetailQuery {
|
|
|
76
77
|
const qb: SelectQueryBuilder<ProductDetail> = getRepository(ProductDetail).createQueryBuilder('ProductDetail')
|
|
77
78
|
qb.innerJoinAndSelect('ProductDetail.product', 'Product', '"Product"."deleted_at" IS NULL')
|
|
78
79
|
qb.innerJoinAndSelect('Product.bizplace', 'Bizplace')
|
|
80
|
+
qb.innerJoin('ProductDetail.productBarcodes', 'ProductBarcode')
|
|
81
|
+
qb.addSelect('ProductBarcode.id')
|
|
82
|
+
qb.addSelect('ProductBarcode.gtin')
|
|
79
83
|
qb.leftJoinAndSelect('ProductDetail.childProductDetail', 'ChildProductDetail')
|
|
80
84
|
qb.leftJoinAndSelect('Product.creator', 'Creator')
|
|
81
85
|
qb.leftJoinAndSelect('Product.updater', 'Updater')
|
|
@@ -154,10 +158,11 @@ export class ProductDetailQuery {
|
|
|
154
158
|
return {
|
|
155
159
|
...item,
|
|
156
160
|
productId: item.product.id,
|
|
157
|
-
name: item.
|
|
161
|
+
name: item.name,
|
|
158
162
|
description: item.product.description,
|
|
159
163
|
type: item.product.type,
|
|
160
164
|
sku: item.product.sku,
|
|
165
|
+
brand: item.product.brand,
|
|
161
166
|
isRequireSerialNumberScanningInbound: item.product.isRequireSerialNumberScanningInbound,
|
|
162
167
|
isRequireSerialNumberScanningOutbound: item.product.isRequireSerialNumberScanningOutbound
|
|
163
168
|
}
|
|
@@ -173,20 +178,21 @@ export class ProductDetailQuery {
|
|
|
173
178
|
@Ctx() context: any
|
|
174
179
|
): Promise<ProductDetailList> {
|
|
175
180
|
try {
|
|
176
|
-
const { tx } = context.state
|
|
177
|
-
|
|
178
181
|
const customerDomainId: Domain = await getRepository(Domain).findOne(customerCompanyDomainId)
|
|
179
182
|
if (!customerDomainId) throw new Error('Unable to find company domain')
|
|
180
|
-
var foundProductDetails
|
|
181
183
|
|
|
182
|
-
|
|
184
|
+
const res: ProductBarcode[] = await getRepository(ProductBarcode).find({
|
|
183
185
|
where: { domain: customerDomainId, gtin },
|
|
184
|
-
relations: ['product']
|
|
186
|
+
relations: ['productDetail', 'productDetail.product']
|
|
185
187
|
})
|
|
186
188
|
|
|
187
|
-
|
|
189
|
+
// validate there is a match for the gtin
|
|
190
|
+
if (res.length <= 0) throw new Error('No product candidate found')
|
|
191
|
+
|
|
192
|
+
// get productDetails from response
|
|
193
|
+
const productDetails: ProductDetail[] = res.map(x => x.productDetail)
|
|
188
194
|
|
|
189
|
-
return { items, total }
|
|
195
|
+
return { items: productDetails, total: productDetails.length }
|
|
190
196
|
} catch (e) {
|
|
191
197
|
throw new Error(e)
|
|
192
198
|
}
|
|
@@ -3,6 +3,7 @@ import { Field, Float, InputType, Int, ObjectType } from 'type-graphql'
|
|
|
3
3
|
import { ObjectRef } from '@things-factory/shell'
|
|
4
4
|
|
|
5
5
|
import { ProductDetail } from './product-detail'
|
|
6
|
+
import { ProductBarcodePatch } from '../product-barcode/product-barcode-type'
|
|
6
7
|
|
|
7
8
|
@InputType()
|
|
8
9
|
export class NewProductDetail {
|
|
@@ -149,8 +150,11 @@ export class ProductDetailPatch {
|
|
|
149
150
|
@Field({ nullable: true })
|
|
150
151
|
name?: string
|
|
151
152
|
|
|
152
|
-
@Field({ nullable: true })
|
|
153
|
-
gtin?: string
|
|
153
|
+
// @Field({ nullable: true })
|
|
154
|
+
// gtin?: string
|
|
155
|
+
|
|
156
|
+
@Field(type => [ProductBarcodePatch], { nullable: true })
|
|
157
|
+
productBarcodes: ProductBarcodePatch[]
|
|
154
158
|
|
|
155
159
|
@Field({ nullable: true })
|
|
156
160
|
refCode?: string
|