@things-factory/warehouse-base 7.0.0-alpha.9 → 7.0.0-y.0
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/index.js +3 -1
- package/dist-server/index.js.map +1 -1
- package/dist-server/service/inventory/inventory-mutation.js +140 -136
- package/dist-server/service/inventory/inventory-mutation.js.map +1 -1
- package/dist-server/service/inventory/inventory-query.js +5 -10
- package/dist-server/service/inventory/inventory-query.js.map +1 -1
- package/dist-server/service/inventory/inventory-types.js +8 -0
- package/dist-server/service/inventory/inventory-types.js.map +1 -1
- package/dist-server/service/pallet/pallet-query.js +1 -1
- package/dist-server/service/pallet/pallet-query.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/server/index.ts +2 -7
- package/server/service/inventory/inventory-mutation.ts +222 -218
- package/server/service/inventory/inventory-query.ts +15 -66
- package/server/service/inventory/inventory-types.ts +6 -0
- package/server/service/pallet/pallet-query.ts +2 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/warehouse-base",
|
|
3
|
-
"version": "7.0.0-
|
|
3
|
+
"version": "7.0.0-y.0",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"browser": "client/index.js",
|
|
6
6
|
"things-factory": true,
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
"migration:create": "node ../../node_modules/typeorm/cli.js migration:create -d ./server/migrations"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@things-factory/biz-base": "^7.0.0-alpha.
|
|
28
|
-
"@things-factory/id-rule-base": "^7.0.0-alpha.
|
|
29
|
-
"@things-factory/integration-sellercraft": "^7.0.0-
|
|
30
|
-
"@things-factory/marketplace-base": "^7.0.0-
|
|
31
|
-
"@things-factory/product-base": "^7.0.0-alpha.
|
|
32
|
-
"@things-factory/setting-base": "^7.0.0-alpha.
|
|
27
|
+
"@things-factory/biz-base": "^7.0.0-alpha.22",
|
|
28
|
+
"@things-factory/id-rule-base": "^7.0.0-alpha.22",
|
|
29
|
+
"@things-factory/integration-sellercraft": "^7.0.0-y.0",
|
|
30
|
+
"@things-factory/marketplace-base": "^7.0.0-y.0",
|
|
31
|
+
"@things-factory/product-base": "^7.0.0-alpha.22",
|
|
32
|
+
"@things-factory/setting-base": "^7.0.0-alpha.22"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "4fce83c3ef32c7f5c06309d05eb5917a095983b6"
|
|
35
35
|
}
|
package/server/index.ts
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
export * from './constants'
|
|
2
2
|
export { createLocation, deleteLocation, deleteLocations, updateLocation } from './service/location/location-mutation'
|
|
3
|
-
export {
|
|
4
|
-
createWarehouse,
|
|
5
|
-
deleteWarehouse,
|
|
6
|
-
deleteWarehouses,
|
|
7
|
-
updateWarehouse
|
|
8
|
-
} from './service/warehouse/warehouse-mutation'
|
|
3
|
+
export { createWarehouse, deleteWarehouse, deleteWarehouses, updateWarehouse } from './service/warehouse/warehouse-mutation'
|
|
9
4
|
export * from './migrations'
|
|
10
5
|
export * from './utils'
|
|
11
6
|
export * from './service'
|
|
12
7
|
export * from './service/inventory/inventory-query'
|
|
13
|
-
|
|
8
|
+
export { updateMultipleInventory } from './service/inventory/inventory-mutation'
|
|
14
9
|
export { approveInventoryChanges } from './service/inventory-change/inventory-change-mutation'
|
|
@@ -88,224 +88,7 @@ export class InventoryMutation {
|
|
|
88
88
|
@Directive('@transaction')
|
|
89
89
|
@Mutation(returns => [Inventory])
|
|
90
90
|
async updateMultipleInventory(@Arg('patches', type => [InventoryPatch]) patches: InventoryPatch[], @Ctx() context: ResolverContext): Promise<Inventory[]> {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
let results = []
|
|
94
|
-
const _createRecords = patches.filter((patch: any) => !patch.id)
|
|
95
|
-
const _updateRecords = patches.filter((patch: any) => patch.id)
|
|
96
|
-
|
|
97
|
-
const inventoryRepo = tx.getRepository(Inventory)
|
|
98
|
-
if (_createRecords.length > 0) {
|
|
99
|
-
let today = new Date()
|
|
100
|
-
let year = today.getFullYear()
|
|
101
|
-
let month = today.getMonth()
|
|
102
|
-
let date = today.getDate()
|
|
103
|
-
|
|
104
|
-
for (let i = 0; i < _createRecords.length; i++) {
|
|
105
|
-
const total = await tx.getRepository(Inventory).countBy({
|
|
106
|
-
createdAt: MoreThan(new Date(year, month, date))
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
const newRecord = _createRecords[i]
|
|
110
|
-
|
|
111
|
-
if (newRecord.location && newRecord.location.id) {
|
|
112
|
-
var location = await tx.getRepository(Location).findOne({
|
|
113
|
-
where: { id: newRecord.location.id },
|
|
114
|
-
relations: ['warehouse']
|
|
115
|
-
})
|
|
116
|
-
newRecord.location = location
|
|
117
|
-
newRecord.zone = location.zone
|
|
118
|
-
newRecord.warehouse = location.warehouse
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (newRecord.bizplace && newRecord.bizplace.id) {
|
|
122
|
-
newRecord.bizplace = (await tx.getRepository(Bizplace).findOneBy({ id: newRecord.bizplace.id })) as any
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (newRecord.product && newRecord.product.id) {
|
|
126
|
-
var product = (await tx.getRepository(Product).findOneBy({ id: newRecord.product.id })) as any
|
|
127
|
-
newRecord.product = product
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
let palletId =
|
|
131
|
-
'P' +
|
|
132
|
-
year.toString().substr(year.toString().length - 2) +
|
|
133
|
-
('0' + (month + 1).toString()).substr(('0' + (month + 1).toString()).toString().length - 2) +
|
|
134
|
-
('0' + date.toString()).substr(('0' + date.toString()).length - 2) +
|
|
135
|
-
('0000' + (total + 1).toString()).substr(('0000' + (total + 1).toString()).length - 4)
|
|
136
|
-
|
|
137
|
-
newRecord.name = palletId
|
|
138
|
-
newRecord.status = newRecord.qty < 1 ? 'TERMINATED' : 'STORED'
|
|
139
|
-
newRecord.palletId = palletId
|
|
140
|
-
|
|
141
|
-
const result = await inventoryRepo.save({
|
|
142
|
-
domain: domain,
|
|
143
|
-
creator: user,
|
|
144
|
-
updater: user,
|
|
145
|
-
lastSeq: 0,
|
|
146
|
-
...newRecord
|
|
147
|
-
} as any)
|
|
148
|
-
|
|
149
|
-
await tx.getRepository(InventoryHistory).save({
|
|
150
|
-
...newRecord,
|
|
151
|
-
domain: domain,
|
|
152
|
-
creator: user,
|
|
153
|
-
updater: user,
|
|
154
|
-
name: InventoryNoGenerator.inventoryHistoryName(),
|
|
155
|
-
seq: 0,
|
|
156
|
-
transactionType: 'NEW',
|
|
157
|
-
productId: newRecord.product.id,
|
|
158
|
-
warehouseId: newRecord.warehouse.id,
|
|
159
|
-
locationId: newRecord.location.id
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
results.push({ ...result, cuFlag: '+' })
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (_updateRecords.length > 0) {
|
|
167
|
-
for (let i = 0; i < _updateRecords.length; i++) {
|
|
168
|
-
const newRecord = _updateRecords[i]
|
|
169
|
-
const newHistoryRecord = JSON.parse(JSON.stringify(_updateRecords[i]))
|
|
170
|
-
let transactionType = ''
|
|
171
|
-
|
|
172
|
-
let inventory = await inventoryRepo.findOne({
|
|
173
|
-
where: { id: newRecord.id },
|
|
174
|
-
relations: ['warehouse', 'location', 'product', 'bizplace']
|
|
175
|
-
})
|
|
176
|
-
newHistoryRecord.openingQty = inventory.qty
|
|
177
|
-
newHistoryRecord.openingUomValue = inventory.uomValue
|
|
178
|
-
|
|
179
|
-
// Get last sequence from InventoryHistory
|
|
180
|
-
let latestEntry = await tx.getRepository(InventoryHistory).find({
|
|
181
|
-
where: { palletId: inventory.palletId },
|
|
182
|
-
order: { seq: 'DESC' },
|
|
183
|
-
take: 1
|
|
184
|
-
})
|
|
185
|
-
let lastSeq = latestEntry[0].seq
|
|
186
|
-
|
|
187
|
-
// Condition 1: Change location (RELOCATE)
|
|
188
|
-
if (newRecord.location && newRecord.location.id) {
|
|
189
|
-
var location = await tx.getRepository(Location).findOne({
|
|
190
|
-
where: { id: newRecord.location.id },
|
|
191
|
-
relations: ['warehouse']
|
|
192
|
-
})
|
|
193
|
-
newRecord.location = location
|
|
194
|
-
newRecord.zone = location.zone
|
|
195
|
-
newRecord.warehouse = location.warehouse
|
|
196
|
-
|
|
197
|
-
newHistoryRecord.location = location
|
|
198
|
-
newHistoryRecord.zone = location.zone
|
|
199
|
-
newHistoryRecord.warehouse = location.warehouse
|
|
200
|
-
|
|
201
|
-
transactionType = 'RELOCATE'
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// Condition 2: Change of qty or uomValue.
|
|
205
|
-
// Set qty movement for inventory history
|
|
206
|
-
if (typeof newRecord.qty != 'undefined') {
|
|
207
|
-
transactionType = 'ADJUSTMENT'
|
|
208
|
-
newHistoryRecord.qty = newRecord.qty - inventory.qty
|
|
209
|
-
if (newRecord.qty < 1) {
|
|
210
|
-
newRecord.status = 'TERMINATED'
|
|
211
|
-
newRecord.qty = 0
|
|
212
|
-
newRecord.uomValue = 0
|
|
213
|
-
}
|
|
214
|
-
} else {
|
|
215
|
-
newHistoryRecord.qty = 0
|
|
216
|
-
}
|
|
217
|
-
// Set uomValue movement for inventory history
|
|
218
|
-
if (typeof newRecord.uomValue != 'undefined') {
|
|
219
|
-
transactionType = 'ADJUSTMENT'
|
|
220
|
-
newHistoryRecord.uomValue = newRecord.uomValue - inventory.uomValue
|
|
221
|
-
if (newRecord.uomValue < 1) {
|
|
222
|
-
newRecord.uomValue = 0
|
|
223
|
-
}
|
|
224
|
-
} else {
|
|
225
|
-
newHistoryRecord.uomValue = 0
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// Condition 3: Change of bizplace or product or batch id or packing type
|
|
229
|
-
if (newRecord.bizplace && newRecord.bizplace.id) {
|
|
230
|
-
newRecord.bizplace = (await tx.getRepository(Bizplace).findOneBy({ id: newRecord.bizplace.id })) as any
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
if (newRecord.product && newRecord.product.id) {
|
|
234
|
-
newRecord.product = (await tx.getRepository(Product).findOneBy({ id: newRecord.product.id })) as any
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if ((newRecord.product && newRecord.product.id) || (newRecord.bizplace && newRecord.bizplace.id) || newRecord.batchId || newRecord.packingType) {
|
|
238
|
-
if (
|
|
239
|
-
inventory.bizplace.id !== (newRecord.bizplace ? newRecord.bizplace.id : '') ||
|
|
240
|
-
inventory.product.id !== (newRecord.product ? newRecord.product.id : '') ||
|
|
241
|
-
inventory.batchId !== newRecord.batchId ||
|
|
242
|
-
inventory.packingType !== newRecord.packingType
|
|
243
|
-
) {
|
|
244
|
-
transactionType = 'ADJUSTMENT'
|
|
245
|
-
lastSeq = lastSeq + 1
|
|
246
|
-
let inventoryHistory = {
|
|
247
|
-
...inventory,
|
|
248
|
-
domain: domain,
|
|
249
|
-
bizplace: inventory.bizplace.id,
|
|
250
|
-
openingQty: inventory.qty,
|
|
251
|
-
openingUomValue: inventory.uomValue,
|
|
252
|
-
qty: -inventory.qty || 0,
|
|
253
|
-
uomValue: -inventory.uomValue || 0,
|
|
254
|
-
name: InventoryNoGenerator.inventoryHistoryName(),
|
|
255
|
-
seq: lastSeq,
|
|
256
|
-
inventory,
|
|
257
|
-
transactionType: transactionType,
|
|
258
|
-
status: INVENTORY_STATUS.TERMINATED,
|
|
259
|
-
productId: inventory.product.id,
|
|
260
|
-
warehouseId: inventory.warehouse.id,
|
|
261
|
-
locationId: inventory.location.id,
|
|
262
|
-
creator: user,
|
|
263
|
-
updater: user
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
delete inventoryHistory.id
|
|
267
|
-
await tx.getRepository(InventoryHistory).save(inventoryHistory as any)
|
|
268
|
-
|
|
269
|
-
newHistoryRecord.qty = newRecord.qty || inventory.qty
|
|
270
|
-
newHistoryRecord.uomValue = newRecord.uomValue || inventory.uomValue || 0
|
|
271
|
-
newHistoryRecord.openingQty = 0
|
|
272
|
-
newHistoryRecord.openingUomValue = 0
|
|
273
|
-
newHistoryRecord.batchId = newRecord.batchId || inventory.batchId || '-'
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
//Transaction type will be RELOCATE if there is only location change. Any other changes will be considered Adjustment.
|
|
278
|
-
lastSeq = lastSeq + 1
|
|
279
|
-
let inventoryHistory = {
|
|
280
|
-
...inventory,
|
|
281
|
-
...newHistoryRecord,
|
|
282
|
-
domain: domain,
|
|
283
|
-
creator: user,
|
|
284
|
-
updater: user,
|
|
285
|
-
name: InventoryNoGenerator.inventoryHistoryName(),
|
|
286
|
-
seq: lastSeq,
|
|
287
|
-
inventory,
|
|
288
|
-
transactionType: transactionType == '' ? 'ADJUSTMENT' : transactionType,
|
|
289
|
-
productId: newHistoryRecord.product ? newHistoryRecord.product.id : inventory.product.id,
|
|
290
|
-
warehouseId: newHistoryRecord.warehouse ? newHistoryRecord.warehouse.id : inventory.warehouse.id,
|
|
291
|
-
locationId: newHistoryRecord.location ? newHistoryRecord.location.id : inventory.location.id
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
delete inventoryHistory.id
|
|
295
|
-
await tx.getRepository(InventoryHistory).save(inventoryHistory)
|
|
296
|
-
|
|
297
|
-
const result = await inventoryRepo.save({
|
|
298
|
-
...inventory,
|
|
299
|
-
...newRecord,
|
|
300
|
-
updater: user,
|
|
301
|
-
lastSeq: lastSeq
|
|
302
|
-
})
|
|
303
|
-
|
|
304
|
-
results.push({ ...result, cuFlag: 'M' })
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
return results
|
|
91
|
+
return await updateMultipleInventory(patches, context)
|
|
309
92
|
}
|
|
310
93
|
|
|
311
94
|
@Directive('@privilege(category: "inventory", privilege: "mutation")')
|
|
@@ -480,3 +263,224 @@ export class InventoryMutation {
|
|
|
480
263
|
return true
|
|
481
264
|
}
|
|
482
265
|
}
|
|
266
|
+
|
|
267
|
+
export async function updateMultipleInventory(patches: InventoryPatch[], context: ResolverContext): Promise<Inventory[]> {
|
|
268
|
+
const { domain, user, tx } = context.state
|
|
269
|
+
|
|
270
|
+
let results = []
|
|
271
|
+
const _createRecords = patches.filter((patch: any) => !patch.id)
|
|
272
|
+
const _updateRecords = patches.filter((patch: any) => patch.id)
|
|
273
|
+
|
|
274
|
+
const inventoryRepo = tx.getRepository(Inventory)
|
|
275
|
+
if (_createRecords.length > 0) {
|
|
276
|
+
let today = new Date()
|
|
277
|
+
let year = today.getFullYear()
|
|
278
|
+
let month = today.getMonth()
|
|
279
|
+
let date = today.getDate()
|
|
280
|
+
|
|
281
|
+
for (let i = 0; i < _createRecords.length; i++) {
|
|
282
|
+
const total = await tx.getRepository(Inventory).countBy({
|
|
283
|
+
createdAt: MoreThan(new Date(year, month, date))
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
const newRecord = _createRecords[i]
|
|
287
|
+
|
|
288
|
+
if (newRecord.location && newRecord.location.id) {
|
|
289
|
+
var location = await tx.getRepository(Location).findOne({
|
|
290
|
+
where: { id: newRecord.location.id },
|
|
291
|
+
relations: ['warehouse']
|
|
292
|
+
})
|
|
293
|
+
newRecord.location = location
|
|
294
|
+
newRecord.zone = location.zone
|
|
295
|
+
newRecord.warehouse = location.warehouse
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (newRecord.bizplace && newRecord.bizplace.id) {
|
|
299
|
+
newRecord.bizplace = (await tx.getRepository(Bizplace).findOneBy({ id: newRecord.bizplace.id })) as any
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (newRecord.product && newRecord.product.id) {
|
|
303
|
+
var product = (await tx.getRepository(Product).findOneBy({ id: newRecord.product.id })) as any
|
|
304
|
+
newRecord.product = product
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
let palletId =
|
|
308
|
+
'P' +
|
|
309
|
+
year.toString().substr(year.toString().length - 2) +
|
|
310
|
+
('0' + (month + 1).toString()).substr(('0' + (month + 1).toString()).toString().length - 2) +
|
|
311
|
+
('0' + date.toString()).substr(('0' + date.toString()).length - 2) +
|
|
312
|
+
('0000' + (total + 1).toString()).substr(('0000' + (total + 1).toString()).length - 4)
|
|
313
|
+
|
|
314
|
+
newRecord.name = palletId
|
|
315
|
+
newRecord.status = newRecord.qty < 1 ? 'TERMINATED' : 'STORED'
|
|
316
|
+
newRecord.palletId = palletId
|
|
317
|
+
|
|
318
|
+
const result = await inventoryRepo.save({
|
|
319
|
+
domain: domain,
|
|
320
|
+
creator: user,
|
|
321
|
+
updater: user,
|
|
322
|
+
lastSeq: 0,
|
|
323
|
+
...newRecord
|
|
324
|
+
} as any)
|
|
325
|
+
|
|
326
|
+
await tx.getRepository(InventoryHistory).save({
|
|
327
|
+
...newRecord,
|
|
328
|
+
domain: domain,
|
|
329
|
+
creator: user,
|
|
330
|
+
updater: user,
|
|
331
|
+
name: InventoryNoGenerator.inventoryHistoryName(),
|
|
332
|
+
seq: 0,
|
|
333
|
+
transactionType: 'NEW',
|
|
334
|
+
productId: newRecord.product.id,
|
|
335
|
+
warehouseId: newRecord.warehouse.id,
|
|
336
|
+
locationId: newRecord.location.id
|
|
337
|
+
})
|
|
338
|
+
|
|
339
|
+
results.push({ ...result, cuFlag: '+' })
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (_updateRecords.length > 0) {
|
|
344
|
+
for (let i = 0; i < _updateRecords.length; i++) {
|
|
345
|
+
const newRecord = _updateRecords[i]
|
|
346
|
+
const newHistoryRecord = JSON.parse(JSON.stringify(_updateRecords[i]))
|
|
347
|
+
let transactionType = ''
|
|
348
|
+
|
|
349
|
+
let inventory = await inventoryRepo.findOne({
|
|
350
|
+
where: { id: newRecord.id },
|
|
351
|
+
relations: ['warehouse', 'location', 'product', 'bizplace']
|
|
352
|
+
})
|
|
353
|
+
newHistoryRecord.openingQty = inventory.qty
|
|
354
|
+
newHistoryRecord.openingUomValue = inventory.uomValue
|
|
355
|
+
|
|
356
|
+
// Get last sequence from InventoryHistory
|
|
357
|
+
let latestEntry = await tx.getRepository(InventoryHistory).find({
|
|
358
|
+
where: { palletId: inventory.palletId },
|
|
359
|
+
order: { seq: 'DESC' },
|
|
360
|
+
take: 1
|
|
361
|
+
})
|
|
362
|
+
let lastSeq = latestEntry[0].seq
|
|
363
|
+
|
|
364
|
+
// Condition 1: Change location (RELOCATE)
|
|
365
|
+
if (newRecord.location && newRecord.location.id) {
|
|
366
|
+
var location = await tx.getRepository(Location).findOne({
|
|
367
|
+
where: { id: newRecord.location.id },
|
|
368
|
+
relations: ['warehouse']
|
|
369
|
+
})
|
|
370
|
+
newRecord.location = location
|
|
371
|
+
newRecord.zone = location.zone
|
|
372
|
+
newRecord.warehouse = location.warehouse
|
|
373
|
+
|
|
374
|
+
newHistoryRecord.location = location
|
|
375
|
+
newHistoryRecord.zone = location.zone
|
|
376
|
+
newHistoryRecord.warehouse = location.warehouse
|
|
377
|
+
|
|
378
|
+
transactionType = 'RELOCATE'
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Condition 2: Change of qty or uomValue.
|
|
382
|
+
// Set qty movement for inventory history
|
|
383
|
+
if (typeof newRecord.qty != 'undefined') {
|
|
384
|
+
transactionType = 'ADJUSTMENT'
|
|
385
|
+
newHistoryRecord.qty = newRecord.qty - inventory.qty
|
|
386
|
+
if (newRecord.qty < 1) {
|
|
387
|
+
newRecord.status = 'TERMINATED'
|
|
388
|
+
newRecord.qty = 0
|
|
389
|
+
newRecord.uomValue = 0
|
|
390
|
+
}
|
|
391
|
+
} else {
|
|
392
|
+
newHistoryRecord.qty = 0
|
|
393
|
+
}
|
|
394
|
+
// Set uomValue movement for inventory history
|
|
395
|
+
if (typeof newRecord.uomValue != 'undefined') {
|
|
396
|
+
transactionType = 'ADJUSTMENT'
|
|
397
|
+
newHistoryRecord.uomValue = newRecord.uomValue - inventory.uomValue
|
|
398
|
+
if (newRecord.uomValue < 1) {
|
|
399
|
+
newRecord.uomValue = 0
|
|
400
|
+
}
|
|
401
|
+
} else {
|
|
402
|
+
newHistoryRecord.uomValue = 0
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Condition 3: Change of bizplace or product or batch id or packing type
|
|
406
|
+
if (newRecord.bizplace && newRecord.bizplace.id) {
|
|
407
|
+
newRecord.bizplace = (await tx.getRepository(Bizplace).findOneBy({ id: newRecord.bizplace.id })) as any
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (newRecord.product && newRecord.product.id) {
|
|
411
|
+
newRecord.product = (await tx.getRepository(Product).findOneBy({ id: newRecord.product.id })) as any
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
if ((newRecord.product && newRecord.product.id) || (newRecord.bizplace && newRecord.bizplace.id) || newRecord.batchId || newRecord.packingType) {
|
|
415
|
+
if (
|
|
416
|
+
inventory.bizplace.id !== (newRecord.bizplace ? newRecord.bizplace.id : '') ||
|
|
417
|
+
inventory.product.id !== (newRecord.product ? newRecord.product.id : '') ||
|
|
418
|
+
inventory.batchId !== newRecord.batchId ||
|
|
419
|
+
inventory.packingType !== newRecord.packingType
|
|
420
|
+
) {
|
|
421
|
+
transactionType = 'ADJUSTMENT'
|
|
422
|
+
lastSeq = lastSeq + 1
|
|
423
|
+
let inventoryHistory: any = {
|
|
424
|
+
...inventory,
|
|
425
|
+
domain: domain,
|
|
426
|
+
bizplace: inventory.bizplace.id,
|
|
427
|
+
openingQty: inventory.qty,
|
|
428
|
+
openingUomValue: inventory.uomValue,
|
|
429
|
+
qty: -inventory.qty || 0,
|
|
430
|
+
uomValue: -inventory.uomValue || 0,
|
|
431
|
+
name: InventoryNoGenerator.inventoryHistoryName(),
|
|
432
|
+
seq: lastSeq,
|
|
433
|
+
inventory,
|
|
434
|
+
transactionType: transactionType,
|
|
435
|
+
status: INVENTORY_STATUS.TERMINATED,
|
|
436
|
+
productId: inventory.product.id,
|
|
437
|
+
warehouseId: inventory.warehouse.id,
|
|
438
|
+
locationId: inventory.location.id,
|
|
439
|
+
creator: user,
|
|
440
|
+
updater: user
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
delete inventoryHistory.id
|
|
444
|
+
await tx.getRepository(InventoryHistory).save(inventoryHistory as any)
|
|
445
|
+
|
|
446
|
+
newHistoryRecord.qty = newRecord.qty || inventory.qty
|
|
447
|
+
newHistoryRecord.uomValue = newRecord.uomValue || inventory.uomValue || 0
|
|
448
|
+
newHistoryRecord.openingQty = 0
|
|
449
|
+
newHistoryRecord.openingUomValue = 0
|
|
450
|
+
newHistoryRecord.batchId = newRecord.batchId || inventory.batchId || '-'
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
//Transaction type will be RELOCATE if there is only location change. Any other changes will be considered Adjustment.
|
|
455
|
+
lastSeq = lastSeq + 1
|
|
456
|
+
let inventoryHistory = {
|
|
457
|
+
...inventory,
|
|
458
|
+
...newHistoryRecord,
|
|
459
|
+
domain: domain,
|
|
460
|
+
creator: user,
|
|
461
|
+
updater: user,
|
|
462
|
+
name: InventoryNoGenerator.inventoryHistoryName(),
|
|
463
|
+
seq: lastSeq,
|
|
464
|
+
inventory,
|
|
465
|
+
transactionType: transactionType == '' ? 'ADJUSTMENT' : transactionType,
|
|
466
|
+
productId: newHistoryRecord.product ? newHistoryRecord.product.id : inventory.product.id,
|
|
467
|
+
warehouseId: newHistoryRecord.warehouse ? newHistoryRecord.warehouse.id : inventory.warehouse.id,
|
|
468
|
+
locationId: newHistoryRecord.location ? newHistoryRecord.location.id : inventory.location.id
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
delete inventoryHistory.id
|
|
472
|
+
await tx.getRepository(InventoryHistory).save(inventoryHistory)
|
|
473
|
+
|
|
474
|
+
const result = await inventoryRepo.save({
|
|
475
|
+
...inventory,
|
|
476
|
+
...newRecord,
|
|
477
|
+
updater: user,
|
|
478
|
+
lastSeq: lastSeq
|
|
479
|
+
})
|
|
480
|
+
|
|
481
|
+
results.push({ ...result, cuFlag: 'M' })
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
return results
|
|
486
|
+
}
|
|
@@ -6,16 +6,7 @@ import { Bizplace, getPartnersCompanyBizplaces, getPermittedBizplaceIds } from '
|
|
|
6
6
|
import { logger } from '@things-factory/env'
|
|
7
7
|
import { Product, ProductBundleSetting } from '@things-factory/product-base'
|
|
8
8
|
import { Setting } from '@things-factory/setting-base'
|
|
9
|
-
import {
|
|
10
|
-
buildQuery,
|
|
11
|
-
Domain,
|
|
12
|
-
Filter,
|
|
13
|
-
ListParam,
|
|
14
|
-
Pagination,
|
|
15
|
-
Sorting,
|
|
16
|
-
getQueryBuilderFromListParams,
|
|
17
|
-
getRepository
|
|
18
|
-
} from '@things-factory/shell'
|
|
9
|
+
import { buildQuery, Domain, Filter, getQueryBuilderFromListParams, getRepository, ListParam, Pagination, Sorting } from '@things-factory/shell'
|
|
19
10
|
|
|
20
11
|
import { INVENTORY_STATUS, LOCATION_TYPE } from '../../constants'
|
|
21
12
|
import { InventoryChange } from '../inventory-change/inventory-change'
|
|
@@ -137,9 +128,7 @@ export class InventoryQuery {
|
|
|
137
128
|
const sort: OrderByCondition = (sortings || []).reduce(
|
|
138
129
|
(acc, sort) => ({
|
|
139
130
|
...acc,
|
|
140
|
-
[arrChildSortData.indexOf(sort.name) >= 0 ? sort.name + '.name' : 'inventory.' + sort.name]: sort.desc
|
|
141
|
-
? 'DESC'
|
|
142
|
-
: 'ASC'
|
|
131
|
+
[arrChildSortData.indexOf(sort.name) >= 0 ? sort.name + '.name' : 'inventory.' + sort.name]: sort.desc ? 'DESC' : 'ASC'
|
|
143
132
|
}),
|
|
144
133
|
{}
|
|
145
134
|
)
|
|
@@ -210,10 +199,7 @@ export class InventoryQuery {
|
|
|
210
199
|
|
|
211
200
|
@Directive('@privilege(category: "inventory", privilege: "query", domainOwnerGranted: true)')
|
|
212
201
|
@Query(returns => InventoryList)
|
|
213
|
-
async renewInventoriesGroupByProduct(
|
|
214
|
-
@Args() params: ListParam,
|
|
215
|
-
@Ctx() context: ResolverContext
|
|
216
|
-
): Promise<InventoryList> {
|
|
202
|
+
async renewInventoriesGroupByProduct(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<InventoryList> {
|
|
217
203
|
const { domain } = context.state
|
|
218
204
|
|
|
219
205
|
const queryBuilder = getQueryBuilderFromListParams({
|
|
@@ -242,6 +228,7 @@ export class InventoryQuery {
|
|
|
242
228
|
.addSelect('product.primaryValue', 'primaryValue')
|
|
243
229
|
.addSelect('product.primaryUnit', 'primaryUnit')
|
|
244
230
|
.addSelect('product.auxUnit1', 'auxUnit1')
|
|
231
|
+
.addSelect('product.minQty', 'minQty')
|
|
245
232
|
.addSelect('i.product_color', 'productColor')
|
|
246
233
|
.addSelect('i.product_quality', 'productQuality')
|
|
247
234
|
.addSelect('i.work_category', 'workCategory')
|
|
@@ -250,7 +237,7 @@ export class InventoryQuery {
|
|
|
250
237
|
.addSelect('COALESCE(SUM(i.locked_qty), 0)', 'lockedQty')
|
|
251
238
|
.addSelect('COALESCE(SUM(i.uom_value), 0)', 'uomValue')
|
|
252
239
|
.addSelect('COALESCE(SUM(i.locked_uom_value), 0)', 'lockedUomValue')
|
|
253
|
-
.innerJoin('i.product', 'product', '
|
|
240
|
+
.innerJoin('i.product', 'product', 'product.deleted_at IS NULL')
|
|
254
241
|
.andWhere('i.status = :status', { status: INVENTORY_STATUS.STORED })
|
|
255
242
|
.andWhere('i.expiration_date >= now()')
|
|
256
243
|
.andWhere('product.domain_id = :domain', { domain: domain.id })
|
|
@@ -591,11 +578,7 @@ export class InventoryQuery {
|
|
|
591
578
|
|
|
592
579
|
@Directive('@transaction')
|
|
593
580
|
@Query(returns => Boolean)
|
|
594
|
-
async checkProductIdenticality(
|
|
595
|
-
@Arg('palletA') palletA: string,
|
|
596
|
-
@Arg('palletB') palletB: string,
|
|
597
|
-
@Ctx() context: ResolverContext
|
|
598
|
-
): Promise<Boolean> {
|
|
581
|
+
async checkProductIdenticality(@Arg('palletA') palletA: string, @Arg('palletB') palletB: string, @Ctx() context: ResolverContext): Promise<Boolean> {
|
|
599
582
|
const { tx } = context.state
|
|
600
583
|
const invRepo: Repository<Inventory> = tx.getRepository(Inventory)
|
|
601
584
|
const invA: Inventory = await invRepo.findOne({
|
|
@@ -608,20 +591,11 @@ export class InventoryQuery {
|
|
|
608
591
|
relations: ['product']
|
|
609
592
|
})
|
|
610
593
|
|
|
611
|
-
return
|
|
612
|
-
invA?.batchId === invB?.batchId &&
|
|
613
|
-
invA?.product?.id === invB?.product?.id &&
|
|
614
|
-
invA?.packingType === invB?.packingType
|
|
615
|
-
)
|
|
594
|
+
return invA?.batchId === invB?.batchId && invA?.product?.id === invB?.product?.id && invA?.packingType === invB?.packingType
|
|
616
595
|
}
|
|
617
596
|
|
|
618
597
|
@Query(returns => Boolean)
|
|
619
|
-
async checkCartonIdenticality(
|
|
620
|
-
@Arg('cartonA') cartonA: string,
|
|
621
|
-
@Arg('palletA') palletA: string,
|
|
622
|
-
@Arg('cartonB') cartonB: string,
|
|
623
|
-
@Ctx() context: ResolverContext
|
|
624
|
-
) {
|
|
598
|
+
async checkCartonIdenticality(@Arg('cartonA') cartonA: string, @Arg('palletA') palletA: string, @Arg('cartonB') cartonB: string, @Ctx() context: ResolverContext) {
|
|
625
599
|
const invRepo: Repository<Inventory> = getRepository(Inventory)
|
|
626
600
|
const invA: Inventory = await invRepo.findOne({
|
|
627
601
|
where: {
|
|
@@ -654,11 +628,7 @@ export class InventoryQuery {
|
|
|
654
628
|
}
|
|
655
629
|
|
|
656
630
|
@Query(returns => Boolean)
|
|
657
|
-
async checkInventoryOwner(
|
|
658
|
-
@Arg('palletId') palletId: string,
|
|
659
|
-
@Arg('bizplaceName') bizplaceName: string,
|
|
660
|
-
@Ctx() context: ResolverContext
|
|
661
|
-
): Promise<Boolean> {
|
|
631
|
+
async checkInventoryOwner(@Arg('palletId') palletId: string, @Arg('bizplaceName') bizplaceName: string, @Ctx() context: ResolverContext): Promise<Boolean> {
|
|
662
632
|
const invRepo: Repository<Inventory> = getRepository(Inventory)
|
|
663
633
|
const bizRepo: Repository<Bizplace> = getRepository(Bizplace)
|
|
664
634
|
|
|
@@ -709,28 +679,20 @@ export class InventoryQuery {
|
|
|
709
679
|
})
|
|
710
680
|
}
|
|
711
681
|
|
|
712
|
-
const remainOnlyParam = params?.filters?.find(
|
|
713
|
-
(f: { name: string; operator: string; value: any }) => f.name === 'remainOnly'
|
|
714
|
-
)
|
|
682
|
+
const remainOnlyParam = params?.filters?.find((f: { name: string; operator: string; value: any }) => f.name === 'remainOnly')
|
|
715
683
|
|
|
716
684
|
let remainOnly: boolean = false
|
|
717
685
|
if (typeof remainOnlyParam?.value !== 'undefined') {
|
|
718
686
|
remainOnly = remainOnlyParam.value
|
|
719
|
-
params.filters = params.filters.filter(
|
|
720
|
-
(f: { name: string; operator: string; value: any }) => f.name !== 'remainOnly'
|
|
721
|
-
)
|
|
687
|
+
params.filters = params.filters.filter((f: { name: string; operator: string; value: any }) => f.name !== 'remainOnly')
|
|
722
688
|
}
|
|
723
689
|
|
|
724
|
-
const unlockOnlyParam = params?.filters?.find(
|
|
725
|
-
(f: { name: string; operator: string; value: any }) => f.name === 'unlockOnly'
|
|
726
|
-
)
|
|
690
|
+
const unlockOnlyParam = params?.filters?.find((f: { name: string; operator: string; value: any }) => f.name === 'unlockOnly')
|
|
727
691
|
|
|
728
692
|
let unlockOnly: boolean = false
|
|
729
693
|
if (typeof unlockOnlyParam?.value !== 'undefined') {
|
|
730
694
|
unlockOnly = unlockOnlyParam.value
|
|
731
|
-
params.filters = params.filters.filter(
|
|
732
|
-
(f: { name: string; operator: string; value: any }) => f.name !== 'unlockOnly'
|
|
733
|
-
)
|
|
695
|
+
params.filters = params.filters.filter((f: { name: string; operator: string; value: any }) => f.name !== 'unlockOnly')
|
|
734
696
|
}
|
|
735
697
|
|
|
736
698
|
const productBundleSettings: ProductBundleSetting[] = await getRepository(ProductBundleSetting).find({
|
|
@@ -1106,18 +1068,7 @@ export class InventoryQuery {
|
|
|
1106
1068
|
}
|
|
1107
1069
|
|
|
1108
1070
|
export async function inventoriesByStrategy(
|
|
1109
|
-
{
|
|
1110
|
-
worksheetId,
|
|
1111
|
-
batchId,
|
|
1112
|
-
bizplaceId,
|
|
1113
|
-
productName,
|
|
1114
|
-
productSku,
|
|
1115
|
-
packingType,
|
|
1116
|
-
packingSize,
|
|
1117
|
-
uom,
|
|
1118
|
-
pickingStrategy,
|
|
1119
|
-
locationSortingRules
|
|
1120
|
-
},
|
|
1071
|
+
{ worksheetId, batchId, bizplaceId, productName, productSku, packingType, packingSize, uom, pickingStrategy, locationSortingRules },
|
|
1121
1072
|
trxMgr: EntityManager
|
|
1122
1073
|
) {
|
|
1123
1074
|
const qb = await trxMgr.getRepository(Inventory).createQueryBuilder('INV')
|
|
@@ -1206,9 +1157,7 @@ export async function inventoriesByStrategy(
|
|
|
1206
1157
|
case 'LOCATION':
|
|
1207
1158
|
if (locationSortingRules?.length > 0) {
|
|
1208
1159
|
locationSortingRules.forEach((rule: { name: string; desc: boolean }, idx: number) => {
|
|
1209
|
-
idx === 0
|
|
1210
|
-
? qb.orderBy(`LOC.${rule.name}`, rule.desc ? 'DESC' : 'ASC')
|
|
1211
|
-
: qb.addOrderBy(`LOC.${rule.name}`, rule.desc ? 'DESC' : 'ASC')
|
|
1160
|
+
idx === 0 ? qb.orderBy(`LOC.${rule.name}`, rule.desc ? 'DESC' : 'ASC') : qb.addOrderBy(`LOC.${rule.name}`, rule.desc ? 'DESC' : 'ASC')
|
|
1212
1161
|
})
|
|
1213
1162
|
} else qb.orderBy('"LOC"."name"', 'DESC')
|
|
1214
1163
|
break
|
|
@@ -104,6 +104,12 @@ export class InventoryPatch {
|
|
|
104
104
|
@Field(type => Float, { nullable: true })
|
|
105
105
|
qty?: number
|
|
106
106
|
|
|
107
|
+
@Field(type => Float, { nullable: true })
|
|
108
|
+
lockedQty?: number
|
|
109
|
+
|
|
110
|
+
@Field(type => Float, { nullable: true })
|
|
111
|
+
lockedUomValue?: number
|
|
112
|
+
|
|
107
113
|
@Field({ nullable: true })
|
|
108
114
|
status?: string
|
|
109
115
|
|