@things-factory/warehouse-base 4.3.154 → 4.3.156
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/adjustment-code.js +13 -0
- package/dist-server/constants/adjustment-code.js.map +1 -0
- package/dist-server/constants/index.js +1 -0
- package/dist-server/constants/index.js.map +1 -1
- package/dist-server/constants/inventory.js +2 -1
- package/dist-server/constants/inventory.js.map +1 -1
- package/dist-server/service/inventory/inventory-query.js +2 -0
- 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 +18 -0
- package/dist-server/service/inventory/inventory.js.map +1 -1
- package/dist-server/service/inventory-change/inventory-change-mutation.js +35 -2
- package/dist-server/service/inventory-change/inventory-change-mutation.js.map +1 -1
- package/dist-server/service/inventory-change/inventory-change-query.js +28 -0
- package/dist-server/service/inventory-change/inventory-change-query.js.map +1 -1
- package/dist-server/service/inventory-change/inventory-change-types.js +8 -0
- package/dist-server/service/inventory-change/inventory-change-types.js.map +1 -1
- package/dist-server/service/inventory-change/inventory-change.js +15 -0
- package/dist-server/service/inventory-change/inventory-change.js.map +1 -1
- package/dist-server/service/tote/tote-query.js +5 -2
- package/dist-server/service/tote/tote-query.js.map +1 -1
- package/dist-server/utils/inventory-util.js +3 -0
- package/dist-server/utils/inventory-util.js.map +1 -1
- package/package.json +9 -9
- package/server/constants/adjustment-code.ts +9 -0
- package/server/constants/index.ts +1 -0
- package/server/constants/inventory.ts +2 -1
- package/server/service/inventory/inventory-query.ts +4 -0
- package/server/service/inventory/inventory-types.ts +12 -0
- package/server/service/inventory/inventory.ts +18 -15
- package/server/service/inventory-change/inventory-change-mutation.ts +89 -18
- package/server/service/inventory-change/inventory-change-query.ts +30 -0
- package/server/service/inventory-change/inventory-change-types.ts +6 -0
- package/server/service/inventory-change/inventory-change.ts +12 -0
- package/server/service/tote/tote-query.ts +9 -2
- package/server/utils/inventory-util.ts +3 -0
|
@@ -1,14 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
Arg,
|
|
3
|
+
Ctx,
|
|
4
|
+
Directive,
|
|
5
|
+
Mutation,
|
|
6
|
+
Resolver
|
|
7
|
+
} from 'type-graphql'
|
|
8
|
+
import {
|
|
9
|
+
EntityManager,
|
|
10
|
+
In,
|
|
11
|
+
MoreThan,
|
|
12
|
+
Not
|
|
13
|
+
} from 'typeorm'
|
|
3
14
|
|
|
4
15
|
import { User } from '@things-factory/auth-base'
|
|
5
16
|
import { Bizplace } from '@things-factory/biz-base'
|
|
6
17
|
import { generateId } from '@things-factory/id-rule-base'
|
|
7
18
|
import { Account } from '@things-factory/integration-accounting'
|
|
8
19
|
import { MarketplaceStore } from '@things-factory/integration-marketplace'
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
20
|
+
import {
|
|
21
|
+
Sellercraft,
|
|
22
|
+
SellercraftStatus
|
|
23
|
+
} from '@things-factory/integration-sellercraft'
|
|
24
|
+
import {
|
|
25
|
+
Product,
|
|
26
|
+
ProductDetail
|
|
27
|
+
} from '@things-factory/product-base'
|
|
28
|
+
import {
|
|
29
|
+
PartnerSetting,
|
|
30
|
+
Setting
|
|
31
|
+
} from '@things-factory/setting-base'
|
|
12
32
|
import { Domain } from '@things-factory/shell'
|
|
13
33
|
|
|
14
34
|
import {
|
|
@@ -18,7 +38,11 @@ import {
|
|
|
18
38
|
LOCATION_STATUS,
|
|
19
39
|
LOCATION_TYPE
|
|
20
40
|
} from '../../constants'
|
|
21
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
EcommerceController,
|
|
43
|
+
PosController,
|
|
44
|
+
SellercraftController
|
|
45
|
+
} from '../../controllers'
|
|
22
46
|
import { InventoryNoGenerator } from '../../utils'
|
|
23
47
|
import { InventoryHistory } from '../inventory-history/inventory-history'
|
|
24
48
|
import { InventoryItemChange } from '../inventory-item-change/inventory-item-change'
|
|
@@ -28,7 +52,11 @@ import { Inventory } from '../inventory/inventory'
|
|
|
28
52
|
import { InventoryPatch } from '../inventory/inventory-types'
|
|
29
53
|
import { Location } from '../location/location'
|
|
30
54
|
import { InventoryChange } from './inventory-change'
|
|
31
|
-
import {
|
|
55
|
+
import {
|
|
56
|
+
InventoryChangeList,
|
|
57
|
+
InventoryChangePatch,
|
|
58
|
+
NewInventoryChange
|
|
59
|
+
} from './inventory-change-types'
|
|
32
60
|
|
|
33
61
|
@Resolver(InventoryChange)
|
|
34
62
|
export class InventoryChangeMutation {
|
|
@@ -216,22 +244,26 @@ export class InventoryChangeMutation {
|
|
|
216
244
|
|
|
217
245
|
var product: Product = await tx.getRepository(Product).findOne(newRecord.product.id)
|
|
218
246
|
var productDetail: ProductDetail = await tx.getRepository(ProductDetail).findOne({
|
|
219
|
-
where: [
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
247
|
+
where: [
|
|
248
|
+
{
|
|
249
|
+
product: { id: newRecord.product.id },
|
|
250
|
+
packingType: newRecord.packingType,
|
|
251
|
+
packingSize: newRecord.packingSize,
|
|
252
|
+
uom: newRecord.uom
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
product: { id: newRecord.product.id },
|
|
256
|
+
isDefault: true
|
|
257
|
+
}
|
|
258
|
+
],
|
|
229
259
|
order: { isDefault: 'DESC' }
|
|
230
260
|
})
|
|
231
261
|
|
|
232
262
|
newRecord.product = product
|
|
233
263
|
newRecord.productDetail = productDetail
|
|
234
|
-
|
|
264
|
+
if (!newRecord.unitCost){
|
|
265
|
+
newRecord.unitCost = product.unitCost
|
|
266
|
+
}
|
|
235
267
|
newRecord.status = 'PENDING'
|
|
236
268
|
newRecord.transactionType = 'NEW'
|
|
237
269
|
|
|
@@ -324,6 +356,8 @@ export class InventoryChangeMutation {
|
|
|
324
356
|
|
|
325
357
|
const adjustQty: number = updateRecord?.qty | 0
|
|
326
358
|
let qtyDiff: number = 0
|
|
359
|
+
|
|
360
|
+
//if updateRecord.unitcost then ...
|
|
327
361
|
|
|
328
362
|
let existingRecord = await tx.getRepository(Inventory).findOne({
|
|
329
363
|
where: { domain, palletId: updateRecord?.palletId },
|
|
@@ -342,6 +376,15 @@ export class InventoryChangeMutation {
|
|
|
342
376
|
qtyDiff = existingQty == adjustQty ? existingQty - adjustQty : adjustQty - existingQty
|
|
343
377
|
}
|
|
344
378
|
|
|
379
|
+
if (!updateRecord.unitCost){
|
|
380
|
+
if(existingRecord.unitCost != null){
|
|
381
|
+
updateRecord.unitCost = existingRecord.unitCost
|
|
382
|
+
}
|
|
383
|
+
if (!existingRecord.unitCost){
|
|
384
|
+
updateRecord.unitCost = existingRecord.product.costPrice
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
345
388
|
if (!!updateRecord?.location?.id) {
|
|
346
389
|
var location = await tx.getRepository(Location).findOne({
|
|
347
390
|
where: { id: updateRecord.location.id },
|
|
@@ -389,6 +432,7 @@ export class InventoryChangeMutation {
|
|
|
389
432
|
domain: domain,
|
|
390
433
|
creator: user,
|
|
391
434
|
updater: user
|
|
435
|
+
//here?
|
|
392
436
|
})
|
|
393
437
|
|
|
394
438
|
const prevBizAccount: Account = await tx
|
|
@@ -870,6 +914,20 @@ export async function approveInventoryChanges(patches: any, context: any) {
|
|
|
870
914
|
statusFilter = (newRecord.qty != null ? newRecord.qty : inventory.qty) > 0 ? 'STORED' : 'TERMINATED'
|
|
871
915
|
}
|
|
872
916
|
|
|
917
|
+
let { expirationDate } = inventory
|
|
918
|
+
const { shelfLife } = inventory.product
|
|
919
|
+
|
|
920
|
+
if (shelfLife && expirationDate) {
|
|
921
|
+
let date: Date = new Date()
|
|
922
|
+
expirationDate = new Date(expirationDate)
|
|
923
|
+
|
|
924
|
+
const releaseBefore: Date = new Date(expirationDate.setDate(expirationDate.getDate() - shelfLife))
|
|
925
|
+
|
|
926
|
+
if (date > releaseBefore) {
|
|
927
|
+
inventory.obsolete = true
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
|
|
873
931
|
delete newRecord.createdAt
|
|
874
932
|
await tx.getRepository(Inventory).save({
|
|
875
933
|
...inventory,
|
|
@@ -1028,6 +1086,19 @@ export async function approveInventoryChanges(patches: any, context: any) {
|
|
|
1028
1086
|
? null
|
|
1029
1087
|
: newRecord.expirationDate
|
|
1030
1088
|
|
|
1089
|
+
const { shelfLife } = newRecord.product
|
|
1090
|
+
|
|
1091
|
+
if (shelfLife && expirationDate) {
|
|
1092
|
+
let date: Date = new Date()
|
|
1093
|
+
expirationDate = new Date(expirationDate)
|
|
1094
|
+
|
|
1095
|
+
const releaseBefore: Date = new Date(expirationDate.setDate(expirationDate.getDate() - shelfLife))
|
|
1096
|
+
|
|
1097
|
+
if (date > releaseBefore) {
|
|
1098
|
+
newRecord.obsolete = true
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1031
1102
|
let savedInventory = await tx.getRepository(Inventory).save({
|
|
1032
1103
|
...newRecord,
|
|
1033
1104
|
expirationDate,
|
|
@@ -32,6 +32,36 @@ export class InventoryChangeQuery {
|
|
|
32
32
|
params.filters = [...params.filters.filter(filter => filter.name != 'bizplace')]
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
const fromDateParamIdx = params.filters.findIndex(param => param.name === 'fromDate')
|
|
36
|
+
if (fromDateParamIdx >= 0) {
|
|
37
|
+
let fromDateVal = new Date(params.filters[fromDateParamIdx].value)
|
|
38
|
+
params.filters.splice(fromDateParamIdx, 1)
|
|
39
|
+
|
|
40
|
+
params.filters.push({
|
|
41
|
+
name: 'createdAt',
|
|
42
|
+
operator: 'gte',
|
|
43
|
+
value: fromDateVal.toISOString(),
|
|
44
|
+
relation: false
|
|
45
|
+
})
|
|
46
|
+
} else {
|
|
47
|
+
throw new Error(`Error: Date range not provided correctly.`)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const toDateParamIdx = params.filters.findIndex(param => param.name === 'toDate')
|
|
51
|
+
if (toDateParamIdx >= 0) {
|
|
52
|
+
let toDateVal = new Date(params.filters[toDateParamIdx].value)
|
|
53
|
+
params.filters.splice(toDateParamIdx, 1)
|
|
54
|
+
|
|
55
|
+
params.filters.push({
|
|
56
|
+
name: 'createdAt',
|
|
57
|
+
operator: 'lt',
|
|
58
|
+
value: new Date(toDateVal.setDate(toDateVal.getDate() + 1)).toISOString(),
|
|
59
|
+
relation: false
|
|
60
|
+
})
|
|
61
|
+
} else {
|
|
62
|
+
throw new Error(`Error: Date range not provided correctly.`)
|
|
63
|
+
}
|
|
64
|
+
|
|
35
65
|
const qb: SelectQueryBuilder<InventoryChange> = getRepository(InventoryChange).createQueryBuilder('ic')
|
|
36
66
|
buildQuery(qb, params, context)
|
|
37
67
|
|
|
@@ -104,6 +104,10 @@ export class InventoryChange {
|
|
|
104
104
|
@Field({ nullable: true })
|
|
105
105
|
uom: string
|
|
106
106
|
|
|
107
|
+
@Column({ nullable: true })
|
|
108
|
+
@Field({ nullable: true })
|
|
109
|
+
sku: string
|
|
110
|
+
|
|
107
111
|
@Column('float', { nullable: true })
|
|
108
112
|
@Field({ nullable: true })
|
|
109
113
|
weight: number
|
|
@@ -120,6 +124,14 @@ export class InventoryChange {
|
|
|
120
124
|
@Field({ nullable: true })
|
|
121
125
|
unitCost: number
|
|
122
126
|
|
|
127
|
+
@Column({ nullable: true })
|
|
128
|
+
@Field({ nullable: true })
|
|
129
|
+
adjustmentCode: string
|
|
130
|
+
|
|
131
|
+
@Column({ nullable: true })
|
|
132
|
+
@Field({ nullable: true })
|
|
133
|
+
adjustmentNote: string
|
|
134
|
+
|
|
123
135
|
@Column()
|
|
124
136
|
@Field()
|
|
125
137
|
status: string
|
|
@@ -23,7 +23,14 @@ export class ToteQuery {
|
|
|
23
23
|
const nameFilter: any = filters.find((filter: any) => filter.name === 'name')
|
|
24
24
|
const bizplaceFilter: any = filters.find((filter: any) => filter.name === 'bizplace')
|
|
25
25
|
const statusFilter: any = filters.find((filter: any) => filter.name === 'status')
|
|
26
|
-
const deletedFilter: any = filters.find((filter: any) => filter.name === '
|
|
26
|
+
const deletedFilter: any = filters.find((filter: any) => filter.name === 'deleted_at')
|
|
27
|
+
|
|
28
|
+
if (deletedFilter) {
|
|
29
|
+
filters.splice(
|
|
30
|
+
filters.findIndex(itm => itm.name == 'deleted_at'),
|
|
31
|
+
1
|
|
32
|
+
)
|
|
33
|
+
}
|
|
27
34
|
|
|
28
35
|
const queryBuilder = tx.getRepository(Tote).createQueryBuilder()
|
|
29
36
|
buildQuery(queryBuilder, { filters, pagination, sortings }, context)
|
|
@@ -47,7 +54,7 @@ export class ToteQuery {
|
|
|
47
54
|
queryBuilder.andWhere('Tote.bizplace_id = :id', { id: bizplaceFilter.value })
|
|
48
55
|
}
|
|
49
56
|
|
|
50
|
-
if (deletedFilter) {
|
|
57
|
+
if (deletedFilter.value) {
|
|
51
58
|
queryBuilder.andWhere('Tote.deletedAt IS NOT NULL')
|
|
52
59
|
} else {
|
|
53
60
|
queryBuilder.andWhere('Tote.deletedAt IS NULL')
|
|
@@ -523,6 +523,7 @@ export async function getInventoriesByStrategy(
|
|
|
523
523
|
) AS rn
|
|
524
524
|
FROM inventories i
|
|
525
525
|
INNER JOIN locations l ON i.location_id = l.id
|
|
526
|
+
INNER JOIN products p ON p.id = i.product_id
|
|
526
527
|
AND l.TYPE NOT IN ($1, $2)
|
|
527
528
|
INNER JOIN temp_op2 op ON i.product_id = op."productId"::uuid
|
|
528
529
|
AND i.batch_id = op."batchId"
|
|
@@ -532,6 +533,8 @@ export async function getInventoriesByStrategy(
|
|
|
532
533
|
WHERE i.domain_id = $3
|
|
533
534
|
AND i.bizplace_id = $4
|
|
534
535
|
AND i.status = $5
|
|
536
|
+
AND i.obsolete = false
|
|
537
|
+
AND case when i.expiration_date is not null and p.shell_life is not null then CURRENT_DATE < i.expiration_date - p.shell_life else true end
|
|
535
538
|
ORDER BY op."productId", rn
|
|
536
539
|
`,
|
|
537
540
|
[LOCATION_TYPE.QUARANTINE, LOCATION_TYPE.RESERVE, domainId, bizplaceId, INVENTORY_STATUS.STORED]
|