@things-factory/product-base 8.0.0-beta.9 → 8.0.2
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/product/product-mutation.js +1 -1
- package/dist-server/service/product/product-mutation.js.map +1 -1
- package/dist-server/service/product/product-query.d.ts +1 -1
- package/dist-server/service/product/product-query.js +5 -5
- package/dist-server/service/product/product-query.js.map +1 -1
- package/dist-server/service/product/product-types.d.ts +4 -2
- package/dist-server/service/product/product-types.js +10 -2
- package/dist-server/service/product/product-types.js.map +1 -1
- package/dist-server/service/product/product.d.ts +2 -1
- package/dist-server/service/product/product.js +6 -1
- package/dist-server/service/product/product.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/server/constants/index.ts +1 -0
- package/server/constants/product.ts +24 -0
- package/server/controllers/index.ts +0 -0
- package/server/index.ts +2 -0
- package/server/middlewares/index.ts +0 -0
- package/server/migrations/index.ts +9 -0
- package/server/service/index.ts +61 -0
- package/server/service/product/index.ts +6 -0
- package/server/service/product/product-mutation.ts +407 -0
- package/server/service/product/product-query.ts +336 -0
- package/server/service/product/product-types.ts +458 -0
- package/server/service/product/product.ts +548 -0
- package/server/service/product/validate-product.ts +42 -0
- package/server/service/product-bundle/index.ts +6 -0
- package/server/service/product-bundle/product-bundle-mutation.ts +140 -0
- package/server/service/product-bundle/product-bundle-query.ts +104 -0
- package/server/service/product-bundle/product-bundle-types.ts +51 -0
- package/server/service/product-bundle/product-bundle.ts +102 -0
- package/server/service/product-bundle-setting/index.ts +6 -0
- package/server/service/product-bundle-setting/product-bundle-setting-mutation.ts +168 -0
- package/server/service/product-bundle-setting/product-bundle-setting-query.ts +139 -0
- package/server/service/product-bundle-setting/product-bundle-setting-types.ts +41 -0
- package/server/service/product-bundle-setting/product-bundle-setting.ts +45 -0
- package/server/service/product-combination/index.ts +6 -0
- package/server/service/product-combination/product-combination-mutation.ts +148 -0
- package/server/service/product-combination/product-combination-query.ts +48 -0
- package/server/service/product-combination/product-combination-type.ts +50 -0
- package/server/service/product-combination/product-combination.ts +116 -0
- package/server/service/product-combination-setting/index.ts +6 -0
- package/server/service/product-combination-setting/product-combination-setting-mutation.ts +248 -0
- package/server/service/product-combination-setting/product-combination-setting-query.ts +176 -0
- package/server/service/product-combination-setting/product-combination-setting-type.ts +44 -0
- package/server/service/product-combination-setting/product-combination-setting.ts +77 -0
- package/server/service/product-detail/index.ts +6 -0
- package/server/service/product-detail/product-detail-mutation.ts +238 -0
- package/server/service/product-detail/product-detail-query.ts +213 -0
- package/server/service/product-detail/product-detail-types.ts +280 -0
- package/server/service/product-detail/product-detail.ts +388 -0
- package/server/service/product-detail-bizplace-setting/index.ts +6 -0
- package/server/service/product-detail-bizplace-setting/product-detail-bizplace-setting-mutation.ts +118 -0
- package/server/service/product-detail-bizplace-setting/product-detail-bizplace-setting-query.ts +90 -0
- package/server/service/product-detail-bizplace-setting/product-detail-bizplace-setting-types.ts +62 -0
- package/server/service/product-detail-bizplace-setting/product-detail-bizplace-setting.ts +104 -0
- package/server/service/product-set/index.ts +6 -0
- package/server/service/product-set/product-set-mutation.ts +149 -0
- package/server/service/product-set/product-set-query.ts +114 -0
- package/server/service/product-set/product-set-types.ts +45 -0
- package/server/service/product-set/product-set.ts +95 -0
- package/server/utils/index.ts +1 -0
- package/server/utils/product-util.ts +11 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import _ from 'lodash'
|
|
2
|
+
import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
|
|
3
|
+
import { In, Raw } from 'typeorm'
|
|
4
|
+
|
|
5
|
+
import { getRepository } from '@things-factory/shell'
|
|
6
|
+
|
|
7
|
+
import { Product } from '../product/product'
|
|
8
|
+
import { ProductDetail } from './product-detail'
|
|
9
|
+
import { ProductDetailPatch } from './product-detail-types'
|
|
10
|
+
|
|
11
|
+
@Resolver(ProductDetail)
|
|
12
|
+
export class ProductDetailMutation {
|
|
13
|
+
@Directive('@transaction')
|
|
14
|
+
@Mutation(returns => ProductDetail)
|
|
15
|
+
async updateProductDetail(
|
|
16
|
+
@Arg('id') id: string,
|
|
17
|
+
@Arg('patch') patch: ProductDetailPatch,
|
|
18
|
+
@Ctx() context: ResolverContext
|
|
19
|
+
): Promise<ProductDetail> {
|
|
20
|
+
return await updateProductDetail(id, patch, context)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@Directive('@transaction')
|
|
24
|
+
@Mutation(returns => [ProductDetail])
|
|
25
|
+
async updateMultipleProductDetail(
|
|
26
|
+
@Arg('productId') productId: string,
|
|
27
|
+
@Arg('patches', type => [ProductDetailPatch]) patches: ProductDetailPatch[],
|
|
28
|
+
@Ctx() context: ResolverContext
|
|
29
|
+
): Promise<ProductDetail[]> {
|
|
30
|
+
try {
|
|
31
|
+
return await updateMultipleProductDetail(productId, patches, context)
|
|
32
|
+
} catch (error) {
|
|
33
|
+
throw error
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@Directive('@transaction')
|
|
38
|
+
@Mutation(returns => Boolean)
|
|
39
|
+
async deleteProductDetail(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<Boolean> {
|
|
40
|
+
const { domain, user } = context.state
|
|
41
|
+
|
|
42
|
+
await getRepository(ProductDetail).delete({ domain: { id: domain.id }, name })
|
|
43
|
+
|
|
44
|
+
return true
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@Directive('@transaction')
|
|
48
|
+
@Mutation(returns => Boolean)
|
|
49
|
+
async deleteProductDetails(
|
|
50
|
+
@Arg('names', type => [String]) names: string[],
|
|
51
|
+
@Ctx() context: ResolverContext
|
|
52
|
+
): Promise<Boolean> {
|
|
53
|
+
const { domain, user } = context.state
|
|
54
|
+
|
|
55
|
+
await getRepository(ProductDetail).delete({
|
|
56
|
+
domain: { id: domain.id },
|
|
57
|
+
name: In(names)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
return true
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function createProductDetail(productDetail: any, context: ResolverContext) {
|
|
65
|
+
const { domain, user, tx } = context.state
|
|
66
|
+
|
|
67
|
+
return await tx.getRepository(ProductDetail).save({
|
|
68
|
+
...productDetail,
|
|
69
|
+
domain,
|
|
70
|
+
creator: user,
|
|
71
|
+
updater: user
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export async function updateProductDetail(id: string, patch: any, context: ResolverContext) {
|
|
76
|
+
const { domain, user, tx } = context.state
|
|
77
|
+
|
|
78
|
+
const repository = tx.getRepository(ProductDetail)
|
|
79
|
+
const productDetail: ProductDetail = await repository.findOne({ where: { id } })
|
|
80
|
+
|
|
81
|
+
if (patch.gtin == undefined) {
|
|
82
|
+
delete patch.gtin
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return await repository.save({
|
|
86
|
+
...productDetail,
|
|
87
|
+
...patch,
|
|
88
|
+
updater: user
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export async function updateMultipleProductDetail(productId, patches, context: ResolverContext) {
|
|
93
|
+
try {
|
|
94
|
+
const { domain, user, tx } = context.state
|
|
95
|
+
|
|
96
|
+
let results = []
|
|
97
|
+
const _createRecords = patches.filter((patch: any) => !patch.id)
|
|
98
|
+
const _updateRecords = patches.filter((patch: any) => patch.id)
|
|
99
|
+
// const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
|
|
100
|
+
|
|
101
|
+
const productRepo = tx.getRepository(Product)
|
|
102
|
+
const productDetailRepo = tx.getRepository(ProductDetail)
|
|
103
|
+
|
|
104
|
+
const product: Product = await productRepo.findOne({ where: { id: productId }, relations: ['productDetails'] })
|
|
105
|
+
|
|
106
|
+
const defaultProductDetail: ProductDetail = patches.find(x => x.isDefault)
|
|
107
|
+
|
|
108
|
+
if (_createRecords.length > 0) {
|
|
109
|
+
for (let i = 0; i < _createRecords.length; i++) {
|
|
110
|
+
const newRecord = {
|
|
111
|
+
..._createRecords[i],
|
|
112
|
+
name: _createRecords[i].gtin,
|
|
113
|
+
product,
|
|
114
|
+
childProductDetail: null,
|
|
115
|
+
childQty: 0,
|
|
116
|
+
domain: domain,
|
|
117
|
+
creator: user,
|
|
118
|
+
updater: user
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (newRecord.gtin == null || newRecord.gtin == undefined) {
|
|
122
|
+
throw new Error('GTIN cannot be empty.')
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const result = await productDetailRepo.save(newRecord)
|
|
126
|
+
|
|
127
|
+
results.push({ ...result, cuFlag: '+' })
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
let deleteIds = []
|
|
132
|
+
for (let x = 0; x < product.productDetails.length; x++) {
|
|
133
|
+
let updateRecords = _updateRecords.find(ur => ur.id == product.productDetails[x].id)
|
|
134
|
+
|
|
135
|
+
if (updateRecords) {
|
|
136
|
+
const productDetail: ProductDetail = await productDetailRepo.findOneBy({ id: updateRecords.id })
|
|
137
|
+
|
|
138
|
+
const updateRecord = {
|
|
139
|
+
...productDetail,
|
|
140
|
+
...updateRecords,
|
|
141
|
+
name: updateRecords.gtin,
|
|
142
|
+
product,
|
|
143
|
+
childProductDetail: null,
|
|
144
|
+
childQty: 0,
|
|
145
|
+
updater: user
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (updateRecord.gtin == '' || updateRecord.gtin == null || updateRecord.gtin == undefined) {
|
|
149
|
+
throw new Error('GTIN cannot be empty.')
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const result = await productDetailRepo.save({
|
|
153
|
+
...productDetail,
|
|
154
|
+
...updateRecord,
|
|
155
|
+
name: updateRecord.gtin,
|
|
156
|
+
product,
|
|
157
|
+
childProductDetail: null,
|
|
158
|
+
childQty: 0,
|
|
159
|
+
updater: user
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
results.push({ ...result, cuFlag: 'M' })
|
|
163
|
+
} else {
|
|
164
|
+
deleteIds.push(product.productDetails[x].id)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
await productDetailRepo.delete({ id: In(deleteIds) })
|
|
169
|
+
|
|
170
|
+
for await (let patch of patches.filter(x => x.childProductDetail)) {
|
|
171
|
+
let matchedChildProductDetail = results.find(itm => itm.gtin == patch.childProductDetail)
|
|
172
|
+
|
|
173
|
+
if (matchedChildProductDetail) {
|
|
174
|
+
const childProductDetail: ProductDetail = await productDetailRepo.findOne({
|
|
175
|
+
where: { id: matchedChildProductDetail.id },
|
|
176
|
+
relations: ['product']
|
|
177
|
+
})
|
|
178
|
+
const productDetail: ProductDetail = await productDetailRepo.findOne({
|
|
179
|
+
where: { gtin: patch.gtin, product: { id: childProductDetail.product.id } }
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
await productDetailRepo.save({
|
|
183
|
+
...productDetail,
|
|
184
|
+
childQty: patch.childQty,
|
|
185
|
+
childProductDetail: childProductDetail,
|
|
186
|
+
updater: user
|
|
187
|
+
})
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
let defaultProductUpdate: Product
|
|
192
|
+
|
|
193
|
+
//// Temporary solution, to fetch the first case packing type of SKU and update Case data in Product Table.
|
|
194
|
+
//// To be removed
|
|
195
|
+
let firstCase: ProductDetail = await productDetailRepo.findOne({
|
|
196
|
+
where: { product: { id: product.id }, packingType: Raw(alias => `lower(${alias}) = 'case'`) },
|
|
197
|
+
order: {
|
|
198
|
+
name: 'ASC'
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
if (firstCase) {
|
|
202
|
+
defaultProductUpdate = {
|
|
203
|
+
...defaultProductUpdate,
|
|
204
|
+
caseGtin: firstCase.gtin,
|
|
205
|
+
caseWidth: firstCase.width,
|
|
206
|
+
caseHeight: firstCase.height,
|
|
207
|
+
caseDepth: firstCase.depth,
|
|
208
|
+
caseGrossWeight: firstCase.grossWeight,
|
|
209
|
+
caseWeight: firstCase.nettWeight,
|
|
210
|
+
caseVolume: firstCase.volume
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/////////////////////////////////////////////////////
|
|
214
|
+
|
|
215
|
+
if (defaultProductDetail) {
|
|
216
|
+
defaultProductUpdate = {
|
|
217
|
+
...defaultProductUpdate,
|
|
218
|
+
packingType: defaultProductDetail.packingType,
|
|
219
|
+
primaryUnit: defaultProductDetail.uom,
|
|
220
|
+
primaryValue: defaultProductDetail.uomValue,
|
|
221
|
+
cogsAccountCode: defaultProductDetail.cogsAccountCode
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (!_.isEmpty(defaultProductUpdate)) {
|
|
226
|
+
await productRepo.update(
|
|
227
|
+
{
|
|
228
|
+
id: product.id
|
|
229
|
+
},
|
|
230
|
+
defaultProductUpdate
|
|
231
|
+
)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return results
|
|
235
|
+
} catch (error) {
|
|
236
|
+
throw error
|
|
237
|
+
}
|
|
238
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { Arg, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
|
|
2
|
+
import { Brackets, SelectQueryBuilder } from 'typeorm'
|
|
3
|
+
|
|
4
|
+
import { User } from '@things-factory/auth-base'
|
|
5
|
+
import { Bizplace, getCompaniesBizplaces, getPartnersCompanyBizplaces } from '@things-factory/biz-base'
|
|
6
|
+
import { buildCondition, buildQuery, Domain, Filter, getRepository, Pagination, Sorting } from '@things-factory/shell'
|
|
7
|
+
|
|
8
|
+
import { ProductDetail } from './product-detail'
|
|
9
|
+
import { ProductDetailList } from './product-detail-types'
|
|
10
|
+
|
|
11
|
+
@Resolver(ProductDetail)
|
|
12
|
+
export class ProductDetailQuery {
|
|
13
|
+
@Directive('@transaction')
|
|
14
|
+
@Query(returns => ProductDetail)
|
|
15
|
+
async productDetail(
|
|
16
|
+
@Arg('gtin') gtin: string,
|
|
17
|
+
@Arg('productId') productId: string,
|
|
18
|
+
@Arg('customerCompanyDomainId') customerCompanyDomainId: string,
|
|
19
|
+
@Ctx() context: ResolverContext
|
|
20
|
+
): Promise<ProductDetail> {
|
|
21
|
+
const { tx } = context.state
|
|
22
|
+
|
|
23
|
+
const customerDomain = await tx.getRepository(Domain).findOneBy({ id: customerCompanyDomainId })
|
|
24
|
+
if (!customerDomain) {
|
|
25
|
+
throw new Error('Unable to find company domain')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var foundProductDetail
|
|
29
|
+
if (productId) {
|
|
30
|
+
foundProductDetail = await tx.getRepository(ProductDetail).findOne({
|
|
31
|
+
where: { domain: { id: customerDomain.id }, product: { id: productId } },
|
|
32
|
+
relations: ['product']
|
|
33
|
+
})
|
|
34
|
+
} else {
|
|
35
|
+
foundProductDetail = await tx.getRepository(ProductDetail).findOne({
|
|
36
|
+
where: { domain: { id: customerDomain.id }, gtin },
|
|
37
|
+
relations: ['product']
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!foundProductDetail) throw new Error('No product candidate found')
|
|
42
|
+
|
|
43
|
+
return foundProductDetail
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@Query(returns => ProductDetailList)
|
|
47
|
+
async productDetails(
|
|
48
|
+
@Ctx() context: ResolverContext,
|
|
49
|
+
@Arg('filters', type => [Filter], { nullable: true }) filters?: Filter[],
|
|
50
|
+
@Arg('pagination', type => Pagination, { nullable: true }) pagination?: Pagination,
|
|
51
|
+
@Arg('sortings', type => [Sorting], { nullable: true }) sortings?: Sorting[]
|
|
52
|
+
): Promise<ProductDetailList> {
|
|
53
|
+
const { domain, user } = context.state
|
|
54
|
+
const { domains } = user
|
|
55
|
+
|
|
56
|
+
const params = { filters, pagination }
|
|
57
|
+
const productInfoFilters = params.filters.find(x => x.name == 'product_info' || x.name == 'sku' || x.name == 'name' || x.name == 'description' || x.name == 'type')
|
|
58
|
+
|
|
59
|
+
const bizplaceFilter = params.filters.find(x => x.name == 'bizplace_id')
|
|
60
|
+
const productFilter = params.filters.find(x => x.name == 'product')
|
|
61
|
+
const createArrivalNotice = params.filters.find(x => x.name == 'create_arrival_notice')
|
|
62
|
+
const productInfoFilterColumns = ['sku', 'name', 'description', 'type', 'brand']
|
|
63
|
+
params.filters = params.filters.filter(
|
|
64
|
+
x =>
|
|
65
|
+
x.name != 'product_info' &&
|
|
66
|
+
x.name != 'bizplace_id' &&
|
|
67
|
+
x.name != 'product' &&
|
|
68
|
+
x.name != 'sku' &&
|
|
69
|
+
x.name != 'brand' &&
|
|
70
|
+
x.name != 'name' &&
|
|
71
|
+
x.name != 'description' &&
|
|
72
|
+
x.name != 'type' &&
|
|
73
|
+
x.name != 'create_arrival_notice'
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
const qb: SelectQueryBuilder<ProductDetail> = getRepository(ProductDetail).createQueryBuilder('ProductDetail')
|
|
77
|
+
qb.innerJoinAndSelect('ProductDetail.product', 'Product', '"Product"."deleted_at" IS NULL')
|
|
78
|
+
qb.innerJoinAndSelect('Product.bizplace', 'Bizplace')
|
|
79
|
+
qb.leftJoinAndSelect('ProductDetail.childProductDetail', 'ChildProductDetail')
|
|
80
|
+
qb.leftJoinAndSelect('Product.creator', 'Creator')
|
|
81
|
+
qb.leftJoinAndSelect('Product.updater', 'Updater')
|
|
82
|
+
|
|
83
|
+
buildQuery(qb, params, context, {
|
|
84
|
+
domainRef: false,
|
|
85
|
+
searchables: ['name']
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
if (bizplaceFilter?.value) {
|
|
89
|
+
const bizplaceId: string = bizplaceFilter.value
|
|
90
|
+
|
|
91
|
+
const foundBizplace: Bizplace = await getRepository(Bizplace).findOne({
|
|
92
|
+
where: { id: bizplaceId } /* CONFIRMME regarding TYPEORM - did I migrate correctly ? */,
|
|
93
|
+
relations: ['company', 'company.domain']
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
if (foundBizplace) {
|
|
97
|
+
const companyDomain: Domain = foundBizplace.company?.domain
|
|
98
|
+
const companyBizplace: Bizplace = await getRepository(Bizplace).findOne({
|
|
99
|
+
where: { domain: { id: companyDomain.id } }
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
const bizplaceIds = [companyBizplace.id, foundBizplace.id]
|
|
103
|
+
qb.andWhere('Bizplace.id IN (:...bizplaceIds)', { bizplaceIds: [...new Set(bizplaceIds)] })
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
const warehouseDomain: Domain = domain
|
|
107
|
+
let bizplaceIds = []
|
|
108
|
+
if (warehouseDomain?.extType === 'company') {
|
|
109
|
+
const companyBizplace: Bizplace = await getRepository(Bizplace).findOne({
|
|
110
|
+
where: { domain: { id: warehouseDomain.id } }
|
|
111
|
+
})
|
|
112
|
+
bizplaceIds.push(companyBizplace.id)
|
|
113
|
+
} else if (warehouseDomain?.extType === 'factory') {
|
|
114
|
+
const myBizplace: Bizplace = await getRepository(Bizplace).findOne({
|
|
115
|
+
where: { domain: { id: warehouseDomain.id } },
|
|
116
|
+
relations: ['domain']
|
|
117
|
+
})
|
|
118
|
+
const companiesBizplaces: Bizplace[] = await getCompaniesBizplaces(domains, warehouseDomain)
|
|
119
|
+
const partnersCompanyBizplaces: Bizplace[] = await getPartnersCompanyBizplaces(domain, user)
|
|
120
|
+
bizplaceIds = [...bizplaceIds, myBizplace.id, ...companiesBizplaces.map(biz => biz.id), ...partnersCompanyBizplaces.map(biz => biz.id)]
|
|
121
|
+
} else {
|
|
122
|
+
const companiesBizplaces: Bizplace[] = await getCompaniesBizplaces(domains, warehouseDomain)
|
|
123
|
+
const partnersCompanyBizplaces: Bizplace[] = await getPartnersCompanyBizplaces(domain, user)
|
|
124
|
+
bizplaceIds = [...bizplaceIds, ...companiesBizplaces.map(biz => biz.id), ...partnersCompanyBizplaces.map(biz => biz.id)]
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
qb.andWhere('Product.bizplace_id IN (:...bizplaceIds)', { bizplaceIds: bizplaceIds })
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (productFilter?.value) {
|
|
131
|
+
if (productFilter.operator === 'eq') {
|
|
132
|
+
qb.andWhere('ProductDetail.product_id = :productId', { productId: productFilter.value })
|
|
133
|
+
} else if (productFilter.operator === 'in') {
|
|
134
|
+
qb.andWhere('ProductDetail.product_id in(:...productId)', { productId: productFilter.value })
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (productInfoFilters?.value) {
|
|
139
|
+
let productInfo = productInfoFilters
|
|
140
|
+
qb.andWhere(
|
|
141
|
+
new Brackets(qb2 => {
|
|
142
|
+
productInfoFilterColumns.forEach(filter => {
|
|
143
|
+
const condition = buildCondition('Product', filter, productInfo.operator, productInfo.value, productInfo.relation, Object.keys(qb.getParameters()).length)
|
|
144
|
+
|
|
145
|
+
qb2.orWhere(condition.clause, condition.parameters)
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (createArrivalNotice?.value) {
|
|
152
|
+
qb.andWhere('(Product.isRequireSerialNumberScanning = false OR (Product.isRequireSerialNumberScanning = true AND ProductDetail.isDefault = true))')
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
let [items, total] = await qb.getManyAndCount()
|
|
156
|
+
|
|
157
|
+
items = items.map(item => {
|
|
158
|
+
return {
|
|
159
|
+
...item,
|
|
160
|
+
productId: item.product.id,
|
|
161
|
+
name: item.product.name,
|
|
162
|
+
description: item.product.description,
|
|
163
|
+
type: item.product.type,
|
|
164
|
+
sku: item.product.sku,
|
|
165
|
+
isRequireSerialNumberScanningInbound: item.product.isRequireSerialNumberScanningInbound,
|
|
166
|
+
isRequireSerialNumberScanningOutbound: item.product.isRequireSerialNumberScanningOutbound
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
return { items, total }
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@Query(returns => ProductDetailList)
|
|
174
|
+
async checkGtin(
|
|
175
|
+
@Arg('gtin') gtin: string,
|
|
176
|
+
@Arg('customerCompanyDomainId') customerCompanyDomainId: string,
|
|
177
|
+
@Ctx() context: ResolverContext
|
|
178
|
+
): Promise<ProductDetailList> {
|
|
179
|
+
try {
|
|
180
|
+
const { tx } = context.state
|
|
181
|
+
|
|
182
|
+
const customerDomainId: Domain = await getRepository(Domain).findOneBy({ id: customerCompanyDomainId })
|
|
183
|
+
if (!customerDomainId) throw new Error('Unable to find company domain')
|
|
184
|
+
var foundProductDetails
|
|
185
|
+
|
|
186
|
+
let [items, total] = await getRepository(ProductDetail).findAndCount({
|
|
187
|
+
where: { domain: { id: customerDomainId.id }, gtin },
|
|
188
|
+
relations: ['product']
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
if (items?.length <= 0) throw new Error('No product candidate found')
|
|
192
|
+
|
|
193
|
+
return { items, total }
|
|
194
|
+
} catch (e) {
|
|
195
|
+
throw new Error(e)
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
@FieldResolver(type => Domain)
|
|
200
|
+
async domain(@Root() productDetail: ProductDetail): Promise<Domain> {
|
|
201
|
+
return await getRepository(Domain).findOneBy({ id: productDetail.domain.id })
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
@FieldResolver(type => User)
|
|
205
|
+
async updater(@Root() productDetail: ProductDetail): Promise<User> {
|
|
206
|
+
return await getRepository(User).findOneBy({ id: productDetail.updater.id })
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
@FieldResolver(type => User)
|
|
210
|
+
async creator(@Root() productDetail: ProductDetail): Promise<User> {
|
|
211
|
+
return await getRepository(User).findOneBy({ id: productDetail.creator.id })
|
|
212
|
+
}
|
|
213
|
+
}
|