@things-factory/warehouse-base 4.0.9 → 4.0.13
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/constants/index.js +1 -0
- package/dist-server/constants/index.js.map +1 -1
- package/dist-server/constants/location.js +3 -2
- package/dist-server/constants/location.js.map +1 -1
- package/dist-server/constants/rule-type.js +8 -0
- package/dist-server/constants/rule-type.js.map +1 -0
- package/dist-server/service/inventory/inventory-mutation.js +68 -28
- package/dist-server/service/inventory/inventory-mutation.js.map +1 -1
- package/dist-server/service/inventory/inventory-query.js +119 -86
- package/dist-server/service/inventory/inventory-query.js.map +1 -1
- package/dist-server/service/inventory/inventory-types.js +16 -0
- package/dist-server/service/inventory/inventory-types.js.map +1 -1
- package/dist-server/service/inventory/inventory.js +13 -9
- package/dist-server/service/inventory/inventory.js.map +1 -1
- package/dist-server/service/inventory-change/inventory-change-mutation.js +7 -9
- package/dist-server/service/inventory-change/inventory-change-mutation.js.map +1 -1
- package/dist-server/service/inventory-change/inventory-change.js +5 -1
- package/dist-server/service/inventory-change/inventory-change.js.map +1 -1
- package/dist-server/service/inventory-history/inventory-history-query.js +28 -26
- package/dist-server/service/inventory-history/inventory-history-query.js.map +1 -1
- package/dist-server/service/inventory-history/inventory-history-types.js +4 -4
- package/dist-server/service/inventory-history/inventory-history-types.js.map +1 -1
- package/dist-server/service/inventory-history/inventory-history.js +1 -1
- package/dist-server/service/inventory-history/inventory-history.js.map +1 -1
- package/dist-server/service/location/location-query.js +1 -1
- package/dist-server/service/location/location-query.js.map +1 -1
- package/dist-server/service/location/location-types.js +24 -0
- package/dist-server/service/location/location-types.js.map +1 -1
- package/dist-server/service/location/location.js +2 -2
- package/dist-server/service/location/location.js.map +1 -1
- package/dist-server/utils/datetime-util.js +49 -0
- package/dist-server/utils/datetime-util.js.map +1 -0
- package/dist-server/utils/index.js +1 -0
- package/dist-server/utils/index.js.map +1 -1
- package/dist-server/utils/inventory-util.js +104 -37
- package/dist-server/utils/inventory-util.js.map +1 -1
- package/package.json +8 -8
- package/server/constants/index.ts +1 -0
- package/server/constants/location.ts +3 -2
- package/server/constants/rule-type.ts +4 -0
- package/server/service/inventory/inventory-mutation.ts +65 -20
- package/server/service/inventory/inventory-query.ts +151 -107
- package/server/service/inventory/inventory-types.ts +12 -0
- package/server/service/inventory/inventory.ts +13 -10
- package/server/service/inventory-change/inventory-change-mutation.ts +10 -11
- package/server/service/inventory-change/inventory-change.ts +6 -2
- package/server/service/inventory-history/inventory-history-query.ts +27 -28
- package/server/service/inventory-history/inventory-history-types.ts +2 -2
- package/server/service/inventory-history/inventory-history.ts +2 -2
- package/server/service/location/location-query.ts +1 -1
- package/server/service/location/location-types.ts +18 -0
- package/server/service/location/location.ts +2 -2
- package/server/utils/datetime-util.ts +54 -0
- package/server/utils/index.ts +1 -0
- package/server/utils/inventory-util.ts +162 -39
|
@@ -3,7 +3,7 @@ import { Brackets, EntityManager, Equal, getRepository, Not, Repository, SelectQ
|
|
|
3
3
|
|
|
4
4
|
import { User } from '@things-factory/auth-base'
|
|
5
5
|
import { Bizplace, getPartnersCompanyBizplaces, getPermittedBizplaceIds } from '@things-factory/biz-base'
|
|
6
|
-
import { Product, ProductBundleSetting } from '@things-factory/product-base'
|
|
6
|
+
import { Product, ProductBundleSetting, ProductDetail } from '@things-factory/product-base'
|
|
7
7
|
import { Setting } from '@things-factory/setting-base'
|
|
8
8
|
import { buildQuery, Domain, Filter, ListParam, Pagination, Sorting } from '@things-factory/shell'
|
|
9
9
|
|
|
@@ -25,125 +25,139 @@ export class InventoryQuery {
|
|
|
25
25
|
): Promise<InventoryList> {
|
|
26
26
|
const { domain, user }: { domain: Domain; user: User } = context.state
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
params.filters.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const remainOnlyParam: { name: string; operator: string; value: boolean } = params?.filters?.find(
|
|
42
|
-
(f: { name: string; operator: string; value: any }) => f.name === 'remainOnly'
|
|
43
|
-
)
|
|
28
|
+
try {
|
|
29
|
+
const productFilters = filters.find(x => x.name == 'product_info')
|
|
30
|
+
filters = filters.filter(x => x.name != 'product_info')
|
|
31
|
+
const params = { filters, pagination }
|
|
32
|
+
|
|
33
|
+
if (!params.filters.find((filter: any) => filter.name === 'bizplace')) {
|
|
34
|
+
params.filters.push({
|
|
35
|
+
name: 'bizplace',
|
|
36
|
+
operator: 'in',
|
|
37
|
+
value: await getPermittedBizplaceIds(domain, user),
|
|
38
|
+
relation: true
|
|
39
|
+
})
|
|
40
|
+
}
|
|
44
41
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
remainOnly = remainOnlyParam.value
|
|
48
|
-
params.filters = params.filters.filter(
|
|
49
|
-
(f: { name: string; operator: string; value: any }) => f.name !== 'remainOnly'
|
|
42
|
+
const remainOnlyParam: { name: string; operator: string; value: boolean } = params?.filters?.find(
|
|
43
|
+
(f: { name: string; operator: string; value: any }) => f.name === 'remainOnly'
|
|
50
44
|
)
|
|
51
|
-
}
|
|
52
45
|
|
|
53
|
-
|
|
54
|
-
(
|
|
55
|
-
|
|
46
|
+
let remainOnly: boolean = false
|
|
47
|
+
if (typeof remainOnlyParam?.value !== 'undefined') {
|
|
48
|
+
remainOnly = remainOnlyParam.value
|
|
49
|
+
params.filters = params.filters.filter(
|
|
50
|
+
(f: { name: string; operator: string; value: any }) => f.name !== 'remainOnly'
|
|
51
|
+
)
|
|
52
|
+
}
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
unlockOnly = unlockOnlyParam.value
|
|
60
|
-
params.filters = params.filters.filter(
|
|
61
|
-
(f: { name: string; operator: string; value: any }) => f.name !== 'unlockOnly'
|
|
54
|
+
const unlockOnlyParam: { name: string; operator: string; value: boolean } = params?.filters?.find(
|
|
55
|
+
(f: { name: string; operator: string; value: any }) => f.name === 'unlockOnly'
|
|
62
56
|
)
|
|
63
|
-
}
|
|
64
57
|
|
|
65
|
-
|
|
66
|
-
|
|
58
|
+
let unlockOnly: boolean = false
|
|
59
|
+
if (typeof unlockOnlyParam?.value !== 'undefined') {
|
|
60
|
+
unlockOnly = unlockOnlyParam.value
|
|
61
|
+
params.filters = params.filters.filter(
|
|
62
|
+
(f: { name: string; operator: string; value: any }) => f.name !== 'unlockOnly'
|
|
63
|
+
)
|
|
64
|
+
}
|
|
67
65
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
.leftJoinAndSelect('iv.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
66
|
+
const qb: SelectQueryBuilder<Inventory> = getRepository(Inventory).createQueryBuilder('iv')
|
|
67
|
+
buildQuery(qb, params, context)
|
|
68
|
+
|
|
69
|
+
qb.leftJoinAndSelect('iv.domain', 'domain')
|
|
70
|
+
.leftJoinAndSelect('iv.bizplace', 'bizplace')
|
|
71
|
+
.leftJoinAndSelect('iv.product', 'product')
|
|
72
|
+
.leftJoinAndSelect('iv.warehouse', 'warehouse')
|
|
73
|
+
.leftJoinAndSelect('iv.location', 'location')
|
|
74
|
+
.leftJoinAndSelect('iv.creator', 'creator')
|
|
75
|
+
.leftJoinAndSelect('iv.updater', 'updater')
|
|
76
|
+
// .addSelect('(SELECT COUNT(id) FROM inventory_changes ic where "iv"."id" = "ic"."inventory_id" )', 'changeCount')
|
|
77
|
+
|
|
78
|
+
if (remainOnly) {
|
|
79
|
+
qb.andWhere('iv.qty > 0')
|
|
80
|
+
.andWhere('CASE WHEN iv.lockedQty IS NULL THEN 0 ELSE iv.lockedQty END >= 0')
|
|
81
|
+
.andWhere('iv.qty - CASE WHEN iv.lockedQty IS NULL THEN 0 ELSE iv.lockedQty END > 0')
|
|
82
|
+
}
|
|
75
83
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
.andWhere('iv.qty - CASE WHEN iv.lockedQty IS NULL THEN 0 ELSE iv.lockedQty END > 0')
|
|
80
|
-
}
|
|
84
|
+
if (unlockOnly) {
|
|
85
|
+
qb.andWhere('CASE WHEN iv.lockedQty IS NULL THEN 0 ELSE iv.lockedQty END = 0')
|
|
86
|
+
}
|
|
81
87
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
if (productFilters) {
|
|
89
|
+
let productFilterValue = `%${productFilters.value.toLowerCase()}%`
|
|
90
|
+
qb.andWhere(qb => {
|
|
91
|
+
const subQuery = qb
|
|
92
|
+
.subQuery()
|
|
93
|
+
.select()
|
|
94
|
+
.from(Product, `products`)
|
|
95
|
+
.where(`products.id = iv.product_id`)
|
|
96
|
+
.andWhere(
|
|
97
|
+
new Brackets(qb => {
|
|
98
|
+
qb.where('Lower(products.sku) LIKE :productInfo', { productInfo: productFilterValue })
|
|
99
|
+
.orWhere('Lower(products.name) LIKE :productInfo', { productInfo: productFilterValue })
|
|
100
|
+
.orWhere('Lower(products.description) LIKE :productInfo', { productInfo: productFilterValue })
|
|
101
|
+
.orWhere('Lower(products.brand) LIKE :productInfo', { productInfo: productFilterValue })
|
|
102
|
+
})
|
|
103
|
+
)
|
|
104
|
+
.getQuery()
|
|
105
|
+
return `EXISTS ${subQuery}`
|
|
106
|
+
})
|
|
107
|
+
}
|
|
85
108
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
})
|
|
100
|
-
)
|
|
101
|
-
.getQuery()
|
|
102
|
-
return `EXISTS ${subQuery}`
|
|
103
|
-
})
|
|
104
|
-
}
|
|
109
|
+
if (sortings?.length !== 0) {
|
|
110
|
+
const arrChildSortData = ['bizplace', 'product', 'location', 'warehouse', 'zone']
|
|
111
|
+
const sort = (sortings || []).reduce(
|
|
112
|
+
(acc, sort) => ({
|
|
113
|
+
...acc,
|
|
114
|
+
[arrChildSortData.indexOf(sort.name) >= 0 ? sort.name + '.name' : 'iv.' + sort.name]: sort.desc
|
|
115
|
+
? 'DESC'
|
|
116
|
+
: 'ASC'
|
|
117
|
+
}),
|
|
118
|
+
{}
|
|
119
|
+
)
|
|
120
|
+
qb.orderBy(sort)
|
|
121
|
+
}
|
|
105
122
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
[arrChildSortData.indexOf(sort.name) >= 0 ? sort.name + '.name' : 'iv.' + sort.name]: sort.desc
|
|
112
|
-
? 'DESC'
|
|
113
|
-
: 'ASC'
|
|
114
|
-
}),
|
|
115
|
-
{}
|
|
116
|
-
)
|
|
117
|
-
qb.orderBy(sort)
|
|
118
|
-
}
|
|
123
|
+
if (locationSortingRules?.length > 0) {
|
|
124
|
+
locationSortingRules.forEach((rule: { name: string; desc: boolean }) => {
|
|
125
|
+
qb.addOrderBy(`location.${rule.name}`, rule.desc ? 'DESC' : 'ASC')
|
|
126
|
+
})
|
|
127
|
+
}
|
|
119
128
|
|
|
120
|
-
|
|
121
|
-
locationSortingRules.forEach((rule: { name: string; desc: boolean }) => {
|
|
122
|
-
qb.addOrderBy(`location.${rule.name}`, rule.desc ? 'DESC' : 'ASC')
|
|
123
|
-
})
|
|
124
|
-
}
|
|
129
|
+
let [items, total] = await qb.getManyAndCount()
|
|
125
130
|
|
|
126
|
-
|
|
131
|
+
items = await Promise.all(
|
|
132
|
+
items.map(async (item: Inventory) => {
|
|
133
|
+
let inventoryChangeCount = await getRepository(InventoryChange).count({
|
|
134
|
+
where: { inventory: item.id }
|
|
135
|
+
})
|
|
127
136
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
let inventoryChangeCount = await getRepository(InventoryChange).count({
|
|
131
|
-
where: { inventory: item.id }
|
|
132
|
-
})
|
|
137
|
+
const selectedQty = item.lockedQty ? item.lockedQty : 0
|
|
138
|
+
const selectedUomValue = item.lockedUomValue ? item.lockedUomValue : 0
|
|
133
139
|
|
|
134
|
-
|
|
135
|
-
|
|
140
|
+
item.product['productDetails'] = await getRepository(ProductDetail).find({
|
|
141
|
+
where: {
|
|
142
|
+
product: item.product.id,
|
|
143
|
+
packingType: item.packingType,
|
|
144
|
+
packingSize: item.packingSize
|
|
145
|
+
}
|
|
146
|
+
})
|
|
136
147
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
148
|
+
return {
|
|
149
|
+
...item,
|
|
150
|
+
changeCount: inventoryChangeCount,
|
|
151
|
+
remainQty: item.qty - selectedQty,
|
|
152
|
+
remainUomValue: item.uomValue - selectedUomValue
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
)
|
|
145
156
|
|
|
146
|
-
|
|
157
|
+
return { items, total }
|
|
158
|
+
} catch (error) {
|
|
159
|
+
throw error
|
|
160
|
+
}
|
|
147
161
|
}
|
|
148
162
|
|
|
149
163
|
@Directive('@privilege(category: "inventory", privilege: "query")')
|
|
@@ -226,6 +240,7 @@ export class InventoryQuery {
|
|
|
226
240
|
productQuery = `AND (
|
|
227
241
|
Lower("Product"."name") LIKE ANY(ARRAY[${productValue}])
|
|
228
242
|
OR Lower("Product"."sku") LIKE ANY(ARRAY[${productValue}])
|
|
243
|
+
OR Lower("Product"."brand") LIKE ANY(ARRAY[${productValue}])
|
|
229
244
|
OR Lower("Product"."description") LIKE ANY(ARRAY[${productValue}])
|
|
230
245
|
OR Lower("ProductRef"."name") LIKE ANY(ARRAY[${productValue}])
|
|
231
246
|
OR Lower("ProductRef"."sku") LIKE ANY(ARRAY[${productValue}])
|
|
@@ -267,7 +282,7 @@ export class InventoryQuery {
|
|
|
267
282
|
`
|
|
268
283
|
create temp table temp_inv_history AS
|
|
269
284
|
(
|
|
270
|
-
SELECT "Product"."id" AS "id", "Product"."sku" AS "sku", "Product"."name" AS "name", "Product"."type" AS "type", "Product"."description" AS "description",
|
|
285
|
+
SELECT "Product"."id" AS "id", "Product"."sku" AS "sku", "Product"."brand" AS "brand", "Product"."name" AS "name", "Product"."type" AS "type", "Product"."description" AS "description",
|
|
271
286
|
"Product"."weight" AS "weight", "ProductRef"."name" AS "productRefName",
|
|
272
287
|
"ProductRef"."description" AS "productRefDesciption", "Bizplace"."name" AS "bizplaceName", SUM("Inventory"."qty") AS "qty" ,
|
|
273
288
|
CASE WHEN SUM("Inventory"."qty") > 0 THEN SUM(COALESCE("Inventory"."unit_cost", 0) * "Inventory"."qty")/ SUM("Inventory"."qty") ELSE 0 END AS "averageUnitCost",
|
|
@@ -313,6 +328,7 @@ export class InventoryQuery {
|
|
|
313
328
|
id: item.id,
|
|
314
329
|
name: item.name,
|
|
315
330
|
sku: item.sku,
|
|
331
|
+
brand: item.brand,
|
|
316
332
|
description: item.description,
|
|
317
333
|
type: item.type,
|
|
318
334
|
weight: item.weight,
|
|
@@ -341,6 +357,8 @@ export class InventoryQuery {
|
|
|
341
357
|
@Arg('productName') productName: string,
|
|
342
358
|
@Arg('productSku') productSku: string,
|
|
343
359
|
@Arg('packingType') packingType: string,
|
|
360
|
+
@Arg('packingSize') packingSize: number,
|
|
361
|
+
@Arg('uom') uom: string,
|
|
344
362
|
@Arg('pickingStrategy') pickingStrategy: string,
|
|
345
363
|
@Arg('locationSortingRules', type => [Sorting], { nullable: true }) locationSortingRules?: Sorting[],
|
|
346
364
|
@Arg('bizplaceId', { nullable: true }) bizplaceId?: string
|
|
@@ -360,7 +378,18 @@ export class InventoryQuery {
|
|
|
360
378
|
}
|
|
361
379
|
|
|
362
380
|
return inventoriesByStrategy(
|
|
363
|
-
{
|
|
381
|
+
{
|
|
382
|
+
worksheetId,
|
|
383
|
+
batchId,
|
|
384
|
+
bizplaceId,
|
|
385
|
+
productName,
|
|
386
|
+
productSku,
|
|
387
|
+
packingType,
|
|
388
|
+
packingSize,
|
|
389
|
+
uom,
|
|
390
|
+
pickingStrategy,
|
|
391
|
+
locationSortingRules
|
|
392
|
+
},
|
|
364
393
|
tx
|
|
365
394
|
)
|
|
366
395
|
}
|
|
@@ -633,7 +662,18 @@ export class InventoryQuery {
|
|
|
633
662
|
}
|
|
634
663
|
|
|
635
664
|
export async function inventoriesByStrategy(
|
|
636
|
-
{
|
|
665
|
+
{
|
|
666
|
+
worksheetId,
|
|
667
|
+
batchId,
|
|
668
|
+
bizplaceId,
|
|
669
|
+
productName,
|
|
670
|
+
productSku,
|
|
671
|
+
packingType,
|
|
672
|
+
packingSize,
|
|
673
|
+
uom,
|
|
674
|
+
pickingStrategy,
|
|
675
|
+
locationSortingRules
|
|
676
|
+
},
|
|
637
677
|
trxMgr: EntityManager
|
|
638
678
|
) {
|
|
639
679
|
const qb = await trxMgr.getRepository(Inventory).createQueryBuilder('INV')
|
|
@@ -658,11 +698,15 @@ export async function inventoriesByStrategy(
|
|
|
658
698
|
.andWhere('"PROD"."name" = :productName')
|
|
659
699
|
.andWhere('"PROD"."sku" = :productSku')
|
|
660
700
|
.andWhere('"INV"."packing_type" = :packingType')
|
|
701
|
+
.andWhere('"INV"."packing_size" = :packingSize')
|
|
702
|
+
.andWhere('"INV"."uom" = :uom')
|
|
661
703
|
.andWhere('"INV"."status" = :status', { status: 'STORED' })
|
|
662
704
|
.setParameters({
|
|
663
705
|
productName,
|
|
664
706
|
productSku,
|
|
665
|
-
packingType
|
|
707
|
+
packingType,
|
|
708
|
+
packingSize,
|
|
709
|
+
uom
|
|
666
710
|
})
|
|
667
711
|
|
|
668
712
|
if (batchId !== '') {
|
|
@@ -50,9 +50,15 @@ export class InventoryPatch {
|
|
|
50
50
|
@Field({ nullable: true })
|
|
51
51
|
sku?: string
|
|
52
52
|
|
|
53
|
+
@Field({ nullable: true })
|
|
54
|
+
brand?: string
|
|
55
|
+
|
|
53
56
|
@Field({ nullable: true })
|
|
54
57
|
productName?: string
|
|
55
58
|
|
|
59
|
+
@Field({ nullable: true })
|
|
60
|
+
productDetailId?: string
|
|
61
|
+
|
|
56
62
|
@Field(type => ObjectRef, { nullable: true })
|
|
57
63
|
reusablePallet?: ObjectRef
|
|
58
64
|
|
|
@@ -80,6 +86,9 @@ export class InventoryPatch {
|
|
|
80
86
|
@Field({ nullable: true })
|
|
81
87
|
otherRef?: string
|
|
82
88
|
|
|
89
|
+
@Field({ nullable: true })
|
|
90
|
+
transactionType?: string
|
|
91
|
+
|
|
83
92
|
@Field({ nullable: true })
|
|
84
93
|
zone?: string
|
|
85
94
|
|
|
@@ -257,6 +266,9 @@ export class InventoryBundleGroup {
|
|
|
257
266
|
@Field({ nullable: true })
|
|
258
267
|
releaseUomValueWithUom?: string
|
|
259
268
|
|
|
269
|
+
@Field({ nullable: true })
|
|
270
|
+
uom?: string
|
|
271
|
+
|
|
260
272
|
@Field({ nullable: true })
|
|
261
273
|
packingType?: string
|
|
262
274
|
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
import { User } from '@things-factory/auth-base'
|
|
15
15
|
import { Bizplace } from '@things-factory/biz-base'
|
|
16
16
|
import { Product, ProductDetail } from '@things-factory/product-base'
|
|
17
|
-
import { Domain } from '@things-factory/shell'
|
|
17
|
+
import { Domain, ScalarDate } from '@things-factory/shell'
|
|
18
18
|
|
|
19
19
|
import { InventoryChange } from '../inventory-change/inventory-change'
|
|
20
20
|
import { Location } from '../location/location'
|
|
@@ -38,8 +38,8 @@ export class Inventory {
|
|
|
38
38
|
@RelationId((inventory: Inventory) => inventory.domain)
|
|
39
39
|
domainId: string
|
|
40
40
|
|
|
41
|
-
@ManyToOne(type => Bizplace)
|
|
42
|
-
@Field(type => Bizplace)
|
|
41
|
+
@ManyToOne(type => Bizplace, { nullable: true })
|
|
42
|
+
@Field(type => Bizplace, { nullable: true })
|
|
43
43
|
bizplace: Bizplace
|
|
44
44
|
|
|
45
45
|
@ManyToOne(type => Inventory)
|
|
@@ -50,8 +50,8 @@ export class Inventory {
|
|
|
50
50
|
@Field()
|
|
51
51
|
name: string
|
|
52
52
|
|
|
53
|
-
@Column()
|
|
54
|
-
@Field()
|
|
53
|
+
@Column({ nullable: true })
|
|
54
|
+
@Field({ nullable: true })
|
|
55
55
|
palletId: string
|
|
56
56
|
|
|
57
57
|
@Column({ nullable: true })
|
|
@@ -131,8 +131,8 @@ export class Inventory {
|
|
|
131
131
|
@Field({ nullable: true })
|
|
132
132
|
sellPrice: number
|
|
133
133
|
|
|
134
|
-
@Column()
|
|
135
|
-
@Field()
|
|
134
|
+
@Column({ nullable: true })
|
|
135
|
+
@Field({ nullable: true })
|
|
136
136
|
packingType: string
|
|
137
137
|
|
|
138
138
|
@Column('float', { nullable: true, default: 1 })
|
|
@@ -175,8 +175,8 @@ export class Inventory {
|
|
|
175
175
|
@Field({ nullable: true })
|
|
176
176
|
description: string
|
|
177
177
|
|
|
178
|
-
@Column()
|
|
179
|
-
@Field()
|
|
178
|
+
@Column({ nullable: true })
|
|
179
|
+
@Field({ nullable: true })
|
|
180
180
|
status: string
|
|
181
181
|
|
|
182
182
|
@Column({ nullable: true })
|
|
@@ -192,7 +192,7 @@ export class Inventory {
|
|
|
192
192
|
inventoryChanges: InventoryChange[]
|
|
193
193
|
|
|
194
194
|
@Column('date', { nullable: true })
|
|
195
|
-
@Field({ nullable: true })
|
|
195
|
+
@Field(type => ScalarDate, { nullable: true })
|
|
196
196
|
expirationDate: Date
|
|
197
197
|
|
|
198
198
|
@Field({ nullable: true })
|
|
@@ -204,6 +204,9 @@ export class Inventory {
|
|
|
204
204
|
@Field({ nullable: true })
|
|
205
205
|
productSKU: string
|
|
206
206
|
|
|
207
|
+
@Field({ nullable: true })
|
|
208
|
+
productBrand: string
|
|
209
|
+
|
|
207
210
|
@Field(type => Float, { nullable: true })
|
|
208
211
|
averageUnitCost: number
|
|
209
212
|
|
|
@@ -15,6 +15,7 @@ import { EcommerceController, SellercraftController } from '../../controllers'
|
|
|
15
15
|
import { InventoryNoGenerator } from '../../utils'
|
|
16
16
|
import { InventoryHistory } from '../inventory-history/inventory-history'
|
|
17
17
|
import { Inventory } from '../inventory/inventory'
|
|
18
|
+
import { InventoryPatch } from '../inventory/inventory-types'
|
|
18
19
|
import { Location } from '../location/location'
|
|
19
20
|
import { InventoryChange } from './inventory-change'
|
|
20
21
|
import { InventoryChangeList, InventoryChangePatch, NewInventoryChange } from './inventory-change-types'
|
|
@@ -129,7 +130,7 @@ export class InventoryChangeMutation {
|
|
|
129
130
|
@Directive('@transaction')
|
|
130
131
|
@Mutation(returns => Boolean)
|
|
131
132
|
async submitInventoryChanges(
|
|
132
|
-
@Arg('patches', type => [
|
|
133
|
+
@Arg('patches', type => [InventoryPatch]) patches: InventoryPatch[],
|
|
133
134
|
@Ctx() context: any
|
|
134
135
|
) {
|
|
135
136
|
const { domain, user, tx }: { domain: Domain; user: User; tx: EntityManager } = context.state
|
|
@@ -140,15 +141,15 @@ export class InventoryChangeMutation {
|
|
|
140
141
|
const inventoryChangeRepo = tx.getRepository(InventoryChange)
|
|
141
142
|
if (_createRecords.length > 0) {
|
|
142
143
|
for (let i = 0; i < _createRecords.length; i++) {
|
|
143
|
-
const newRecord
|
|
144
|
+
const newRecord = _createRecords[i]
|
|
144
145
|
|
|
145
146
|
var location = await tx.getRepository(Location).findOne({
|
|
146
|
-
where: { id: newRecord.id },
|
|
147
|
+
where: { id: newRecord.location.id },
|
|
147
148
|
relations: ['warehouse']
|
|
148
149
|
})
|
|
149
150
|
newRecord.location = location
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
newRecord.zone = location.zone
|
|
152
|
+
newRecord.warehouse = location.warehouse
|
|
152
153
|
|
|
153
154
|
newRecord.bizplace = await tx.getRepository(Bizplace).findOne(newRecord.bizplace.id)
|
|
154
155
|
|
|
@@ -176,7 +177,7 @@ export class InventoryChangeMutation {
|
|
|
176
177
|
|
|
177
178
|
if (_updateRecords.length > 0) {
|
|
178
179
|
for (let i = 0; i < _updateRecords.length; i++) {
|
|
179
|
-
const updateRecord
|
|
180
|
+
const updateRecord = _updateRecords[i]
|
|
180
181
|
|
|
181
182
|
let existingRecord = await tx.getRepository(Inventory).findOne({
|
|
182
183
|
where: { id: updateRecord.id },
|
|
@@ -189,8 +190,8 @@ export class InventoryChangeMutation {
|
|
|
189
190
|
relations: ['warehouse']
|
|
190
191
|
})
|
|
191
192
|
updateRecord.location = location
|
|
192
|
-
|
|
193
|
-
|
|
193
|
+
updateRecord.zone = location.zone
|
|
194
|
+
updateRecord.warehouse = location.warehouse
|
|
194
195
|
}
|
|
195
196
|
|
|
196
197
|
if (!!updateRecord?.bizplace?.id)
|
|
@@ -356,9 +357,7 @@ export class InventoryChangeMutation {
|
|
|
356
357
|
if (newRecord.uomValue != null && newRecord.uomValue != inventory.uomValue) {
|
|
357
358
|
newHistoryRecord.uomValue = newRecord.uomValue - inventory.uomValue
|
|
358
359
|
Math.round(newHistoryRecord.uomValue * 100) / 100
|
|
359
|
-
|
|
360
|
-
newRecord.uomValue = 0
|
|
361
|
-
}
|
|
360
|
+
|
|
362
361
|
transactionType = 'ADJUSTMENT'
|
|
363
362
|
} else {
|
|
364
363
|
newHistoryRecord.uomValue = 0
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { User } from '@things-factory/auth-base'
|
|
14
14
|
import { Bizplace } from '@things-factory/biz-base'
|
|
15
15
|
import { Product, ProductDetail } from '@things-factory/product-base'
|
|
16
|
-
import { Domain } from '@things-factory/shell'
|
|
16
|
+
import { Domain, ScalarDate } from '@things-factory/shell'
|
|
17
17
|
|
|
18
18
|
import { InventoryHistory } from '../inventory-history/inventory-history'
|
|
19
19
|
import { Inventory } from '../inventory/inventory'
|
|
@@ -23,6 +23,10 @@ import { Location } from '../location/location'
|
|
|
23
23
|
@Index('ix_inventory-change_0', (inventoryChange: InventoryChange) => [inventoryChange.domain, inventoryChange.id], {
|
|
24
24
|
unique: true
|
|
25
25
|
})
|
|
26
|
+
@Index('ix_inventory-change_1', (inventoryChange: InventoryChange) => [
|
|
27
|
+
inventoryChange.domain,
|
|
28
|
+
inventoryChange.inventory
|
|
29
|
+
])
|
|
26
30
|
@ObjectType()
|
|
27
31
|
export class InventoryChange {
|
|
28
32
|
@PrimaryGeneratedColumn('uuid')
|
|
@@ -116,7 +120,7 @@ export class InventoryChange {
|
|
|
116
120
|
lastInventoryHistory: InventoryHistory
|
|
117
121
|
|
|
118
122
|
@Column('date', { nullable: true })
|
|
119
|
-
@Field({ nullable: true })
|
|
123
|
+
@Field(type => ScalarDate, { nullable: true })
|
|
120
124
|
expirationDate: Date
|
|
121
125
|
|
|
122
126
|
@Column('int', { nullable: true })
|