@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.
Files changed (44) hide show
  1. package/dist-server/service/index.js +7 -2
  2. package/dist-server/service/index.js.map +1 -1
  3. package/dist-server/service/product/product-mutation.js +17 -4
  4. package/dist-server/service/product/product-mutation.js.map +1 -1
  5. package/dist-server/service/product/product.js +6 -0
  6. package/dist-server/service/product/product.js.map +1 -1
  7. package/dist-server/service/product-barcode/index.js +9 -0
  8. package/dist-server/service/product-barcode/index.js.map +1 -0
  9. package/dist-server/service/product-barcode/product-barcode-mutation.js +120 -0
  10. package/dist-server/service/product-barcode/product-barcode-mutation.js.map +1 -0
  11. package/dist-server/service/product-barcode/product-barcode-query.js +87 -0
  12. package/dist-server/service/product-barcode/product-barcode-query.js.map +1 -0
  13. package/dist-server/service/product-barcode/product-barcode-type.js +63 -0
  14. package/dist-server/service/product-barcode/product-barcode-type.js.map +1 -0
  15. package/dist-server/service/product-barcode/product-barcode.js +99 -0
  16. package/dist-server/service/product-barcode/product-barcode.js.map +1 -0
  17. package/dist-server/service/product-bundle-setting/product-bundle-setting-query.js +3 -1
  18. package/dist-server/service/product-bundle-setting/product-bundle-setting-query.js.map +1 -1
  19. package/dist-server/service/product-detail/product-detail-mutation.js +70 -13
  20. package/dist-server/service/product-detail/product-detail-mutation.js.map +1 -1
  21. package/dist-server/service/product-detail/product-detail-query.js +12 -7
  22. package/dist-server/service/product-detail/product-detail-query.js.map +1 -1
  23. package/dist-server/service/product-detail/product-detail-types.js +4 -3
  24. package/dist-server/service/product-detail/product-detail-types.js.map +1 -1
  25. package/dist-server/service/product-detail/product-detail.js +8 -2
  26. package/dist-server/service/product-detail/product-detail.js.map +1 -1
  27. package/dist-server/service/product-detail-bizplace-setting/product-detail-bizplace-setting-mutation.js +8 -4
  28. package/dist-server/service/product-detail-bizplace-setting/product-detail-bizplace-setting-mutation.js.map +1 -1
  29. package/package.json +4 -5
  30. package/server/service/index.ts +7 -2
  31. package/server/service/product/product-mutation.ts +21 -4
  32. package/server/service/product/product.ts +5 -0
  33. package/server/service/product-barcode/index.ts +6 -0
  34. package/server/service/product-barcode/product-barcode-mutation.ts +112 -0
  35. package/server/service/product-barcode/product-barcode-query.ts +43 -0
  36. package/server/service/product-barcode/product-barcode-type.ts +35 -0
  37. package/server/service/product-barcode/product-barcode.ts +78 -0
  38. package/server/service/product-bundle-setting/product-bundle-setting-query.ts +6 -4
  39. package/server/service/product-detail/product-detail-mutation.ts +79 -11
  40. package/server/service/product-detail/product-detail-query.ts +14 -8
  41. package/server/service/product-detail/product-detail-types.ts +6 -2
  42. package/server/service/product-detail/product-detail.ts +7 -2
  43. package/server/service/product-detail-bizplace-setting/product-detail-bizplace-setting-mutation.ts +8 -4
  44. 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.122",
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.122",
28
- "@things-factory/routing-base": "^4.3.122"
26
+ "@things-factory/biz-base": "^4.3.138",
27
+ "@things-factory/routing-base": "^4.3.138"
29
28
  },
30
- "gitHead": "3edd80e6ca68480b22ee0e25eba34d13ab0e49f1"
29
+ "gitHead": "1d4e0a3ff6b8792c843b9735a28a3f5fb946b144"
31
30
  }
@@ -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 = product.productDetails
273
- if (!productDetails) {
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].gtin == null || productDetails[0] == undefined) {
276
- productDetails[0].gtin = product.sku
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({ where: { id: productId }, relations: ['productDetails'] })
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
- name: _createRecords[i].gtin,
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.gtin == null || newRecord.gtin == undefined) {
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({ id: updateRecords.id })
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.gtin,
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.gtin == '' || updateRecord.gtin == null || updateRecord.gtin == undefined) {
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.gtin,
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.gtin == patch.childProductDetail)
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: { gtin: patch.gtin, product: childProductDetail.product }
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.product.name,
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
- let [items, total] = await getRepository(ProductDetail).findAndCount({
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
- if (items?.length <= 0) throw new Error('No product candidate found')
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