@things-factory/warehouse-base 4.3.21 → 4.3.24
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/inventory/inventory-query.js +35 -33
- package/dist-server/service/inventory/inventory-query.js.map +1 -1
- package/dist-server/service/inventory/inventory.js +8 -0
- package/dist-server/service/inventory/inventory.js.map +1 -1
- package/dist-server/service/inventory-change/inventory-change-mutation.js +2 -0
- package/dist-server/service/inventory-change/inventory-change-mutation.js.map +1 -1
- package/dist-server/service/inventory-history/inventory-history-query.js +186 -8
- package/dist-server/service/inventory-history/inventory-history-query.js.map +1 -1
- package/dist-server/service/inventory-history/inventory-history-types.js +125 -1
- package/dist-server/service/inventory-history/inventory-history-types.js.map +1 -1
- package/dist-server/service/pallet-count/pallet-count-mutation.js +2 -5
- package/dist-server/service/pallet-count/pallet-count-mutation.js.map +1 -1
- package/dist-server/utils/inventory-no-generator.js +4 -7
- package/dist-server/utils/inventory-no-generator.js.map +1 -1
- package/package.json +8 -8
- package/server/service/inventory/inventory-query.ts +44 -44
- package/server/service/inventory/inventory.ts +6 -0
- package/server/service/inventory-change/inventory-change-mutation.ts +3 -0
- package/server/service/inventory-history/inventory-history-query.ts +232 -22
- package/server/service/inventory-history/inventory-history-types.ts +89 -0
- package/server/service/pallet-count/pallet-count-mutation.ts +2 -2
- package/server/utils/inventory-no-generator.ts +4 -4
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
|
|
2
|
-
import { Between, Brackets, EntityManager, getRepository, In, Raw, SelectQueryBuilder } from 'typeorm'
|
|
2
|
+
import { Between, Brackets, EntityManager, getRepository, In, Raw, SelectQueryBuilder, IsNull } from 'typeorm'
|
|
3
3
|
|
|
4
4
|
import { User } from '@things-factory/auth-base'
|
|
5
|
-
import { Bizplace, getMyBizplace, getPermittedBizplaceIds } from '@things-factory/biz-base'
|
|
6
|
-
import { Product } from '@things-factory/product-base'
|
|
5
|
+
import { Bizplace, getMyBizplace, getPermittedBizplaceIds, getPermittedBizplace } from '@things-factory/biz-base'
|
|
6
|
+
import { Product, ProductDetail } from '@things-factory/product-base'
|
|
7
7
|
import { buildQuery, convertListParams, Domain, Filter, ListParam, Pagination, Sorting } from '@things-factory/shell'
|
|
8
8
|
|
|
9
9
|
import { RawInventoryHistoryList } from '../'
|
|
@@ -15,7 +15,8 @@ import {
|
|
|
15
15
|
InventoryHistoryList,
|
|
16
16
|
InventoryHistoryPalletReportList,
|
|
17
17
|
InventoryHistoryPatch,
|
|
18
|
-
InventoryHistorySummaryList
|
|
18
|
+
InventoryHistorySummaryList,
|
|
19
|
+
InventoryHistoryVolumeSummaryReportList
|
|
19
20
|
} from './inventory-history-types'
|
|
20
21
|
|
|
21
22
|
@Resolver(InventoryHistory)
|
|
@@ -933,6 +934,7 @@ export class InventoryHistoryQuery {
|
|
|
933
934
|
packingType: itm.packing_type,
|
|
934
935
|
packingSize: itm.packing_size,
|
|
935
936
|
openingQty: itm.opening_qty,
|
|
937
|
+
missingQty: itm.missing_qty,
|
|
936
938
|
adjustmentQty: itm.adjustment_qty,
|
|
937
939
|
closingQty: itm.closing_qty,
|
|
938
940
|
totalInQty: itm.total_in_qty,
|
|
@@ -1003,15 +1005,15 @@ export class InventoryHistoryQuery {
|
|
|
1003
1005
|
} else {
|
|
1004
1006
|
bizplaceFilter = !filters.find((filter: any) => filter.name === 'bizplace')
|
|
1005
1007
|
? {
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1008
|
+
name: 'bizplace',
|
|
1009
|
+
operator: 'in',
|
|
1010
|
+
value: await getPermittedBizplaceIds(domain, user),
|
|
1011
|
+
relation: true
|
|
1012
|
+
}
|
|
1011
1013
|
: {
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1014
|
+
...filters.find(data => data.name === 'bizplace'),
|
|
1015
|
+
value: [filters.find(data => data.name === 'bizplace').value]
|
|
1016
|
+
}
|
|
1015
1017
|
}
|
|
1016
1018
|
|
|
1017
1019
|
let queryFilter = ``
|
|
@@ -1078,9 +1080,8 @@ export class InventoryHistoryQuery {
|
|
|
1078
1080
|
sortings.forEach((sorting, idx) => {
|
|
1079
1081
|
let itmIndex = arrObjectMap.findIndex(x => x.name === sorting.name)
|
|
1080
1082
|
|
|
1081
|
-
queryOrder = `${idx === 0 ? 'order by' : queryOrder + ','} ${
|
|
1082
|
-
|
|
1083
|
-
} ${sorting.desc ? 'DESC' : 'ASC'}`
|
|
1083
|
+
queryOrder = `${idx === 0 ? 'order by' : queryOrder + ','} ${itmIndex >= 0 ? arrObjectMap[itmIndex].value : sorting.name
|
|
1084
|
+
} ${sorting.desc ? 'DESC' : 'ASC'}`
|
|
1084
1085
|
})
|
|
1085
1086
|
}
|
|
1086
1087
|
|
|
@@ -1115,12 +1116,14 @@ export class InventoryHistoryQuery {
|
|
|
1115
1116
|
`,
|
|
1116
1117
|
[domain.id, createdAt.value, timezoneOffset]
|
|
1117
1118
|
)
|
|
1118
|
-
|
|
1119
|
+
|
|
1120
|
+
//comment start
|
|
1121
|
+
//detailed review needed 19 May 2022 by @ChrisLim-git
|
|
1119
1122
|
await tx.query(
|
|
1120
1123
|
`
|
|
1121
1124
|
create temp table tmp_data on commit drop as (
|
|
1122
|
-
select dt.*, rih.carton_id, rih.batch_id, rih.batch_id_ref, rih.product_id, rih.packing_type, rih.bizplace_id, rih.location_id, rih.unit_cost, iv.uom,
|
|
1123
|
-
iv.expiration_date, iv.reusable_pallet_id, iv.remark
|
|
1125
|
+
select dt.*, rih.carton_id, rih.batch_id, rih.batch_id_ref, rih.product_id, rih.packing_type, rih.bizplace_id, rih.location_id, rih.unit_cost,iv.id as inventory_id, iv.uom,
|
|
1126
|
+
iv.expiration_date, iv.manufacture_date, iv.reusable_pallet_id, iv.remark,iv.status
|
|
1124
1127
|
from
|
|
1125
1128
|
(
|
|
1126
1129
|
select ih.domain_id, ih.pallet_id, sum(ih.qty) as qty, sum(ih.uom_value) as uom_value, max(ih.seq) as last_seq, max(ih.created_at) as created_at,
|
|
@@ -1128,7 +1131,7 @@ export class InventoryHistoryQuery {
|
|
|
1128
1131
|
from tmp_src ih
|
|
1129
1132
|
group by ih.domain_id, ih.pallet_id
|
|
1130
1133
|
) dt
|
|
1131
|
-
inner join tmp_src rih on dt.domain_id = rih.domain_id and dt.pallet_id = rih.pallet_id and dt.last_seq = rih.seq
|
|
1134
|
+
inner join tmp_src rih on dt.domain_id = rih.domain_id and dt.pallet_id = rih.pallet_id and dt.last_seq = rih.seq
|
|
1132
1135
|
inner join inventories iv on iv.domain_id = dt.domain_id and iv.pallet_id = dt.pallet_id and iv.status <> 'MISSING'
|
|
1133
1136
|
where exists (
|
|
1134
1137
|
SELECT * FROM tmp_bizfilter bizFilter
|
|
@@ -1140,7 +1143,39 @@ export class InventoryHistoryQuery {
|
|
|
1140
1143
|
`
|
|
1141
1144
|
)
|
|
1142
1145
|
|
|
1143
|
-
|
|
1146
|
+
await tx.query(
|
|
1147
|
+
`
|
|
1148
|
+
create temp table tmp_result on commit drop as (
|
|
1149
|
+
select
|
|
1150
|
+
rih.domain_id, rih.pallet_id as "palletId", rih.carton_id as "cartonId", rih.qty as "remainQty", rih.uom_value as "uomValue", rih.uom, rih.last_seq, rih.created_at,
|
|
1151
|
+
rih.initial_inbound_at as "initialInboundAt", rih.unit_cost as "unitCost",
|
|
1152
|
+
case when rih.reusable_pallet_id is not null then concat(rih.batch_id, ' (', plt.name, ')') else rih.batch_id end as "batchId",
|
|
1153
|
+
rih.batch_id_ref as "batchIdRef", rih.product_id as "productId", rih.packing_type as "packingType",
|
|
1154
|
+
prd.id as product_id, prd.name as product_name, prd.sku as product_sku, prd.brand as product_brand, prd.description as product_description, prd.volume as product_volume,
|
|
1155
|
+
bz.id as bizplace_id, bz.name as bizplace_name,
|
|
1156
|
+
loc.id as location_id, loc.name as location_name, loc."zone" as location_zone, loc."row" as location_row, loc."column" as location_column, loc.shelf as location_shelf,
|
|
1157
|
+
wh.name as warehouse_name, plt.name as reusable_pallet_name,
|
|
1158
|
+
rih.remark,
|
|
1159
|
+
rih.manufacture_date as "manufactureDate",
|
|
1160
|
+
rih.expiration_date as "expirationDate"
|
|
1161
|
+
,sum(case when oi.status = 'LOADING' or (oi.status = 'SORTING' and oi.type = 'RELEASE_OF_GOODS') then oi.release_qty else 0 end) as "nonLoadedQty"
|
|
1162
|
+
,sum(case when oi.status = 'LOADING' or (oi.status = 'SORTING' and oi.type = 'RELEASE_OF_GOODS') then (oi.release_uom_value / oi.release_qty* oi.release_qty) else 0 end) as "nonLoadedUomValue"
|
|
1163
|
+
from tmp_data rih
|
|
1164
|
+
left join pallets plt on plt.id = rih.reusable_pallet_id
|
|
1165
|
+
inner join products prd on prd.id = rih.product_id
|
|
1166
|
+
inner join bizplaces bz on bz.id = rih.bizplace_id
|
|
1167
|
+
inner join locations loc on loc.id = rih.location_id
|
|
1168
|
+
inner join warehouses wh on wh.id = loc.warehouse_id
|
|
1169
|
+
inner join order_inventories oi on oi.inventory_id = rih.inventory_id
|
|
1170
|
+
group by rih.inventory_id,rih.domain_id,rih.pallet_id,rih.carton_id,rih.qty,rih.uom_value,rih.uom,rih.last_seq,rih.created_at, rih.initial_inbound_at,rih.unit_cost,rih.reusable_pallet_id,
|
|
1171
|
+
rih.batch_id,plt.name,rih.batch_id_ref,rih.product_id,rih.packing_type,rih.bizplace_id,rih.location_id,prd.id,bz.id,loc.id,wh.name,rih.remark,rih.expiration_date,rih.manufacture_date,rih.status
|
|
1172
|
+
having 1=1 and (case when rih.status = 'TERMINATED' and SUM(CASE WHEN oi.status = 'LOADING' or (oi.status = 'SORTING' AND oi.type = 'RELEASE_OF_GOODS') THEN oi.release_qty ELSE 0 END) > 0 then rih.status = 'TERMINATED' else rih.status <> 'TERMINATED' end)
|
|
1173
|
+
order by created_at desc
|
|
1174
|
+
);
|
|
1175
|
+
`
|
|
1176
|
+
)
|
|
1177
|
+
|
|
1178
|
+
const total: any = await tx.query(`select count(*) from tmp_result`)
|
|
1144
1179
|
|
|
1145
1180
|
const result: any = await tx.query(
|
|
1146
1181
|
`
|
|
@@ -1154,18 +1189,25 @@ export class InventoryHistoryQuery {
|
|
|
1154
1189
|
loc.id as location_id, loc.name as location_name, loc."zone" as location_zone, loc."row" as location_row, loc."column" as location_column, loc.shelf as location_shelf,
|
|
1155
1190
|
wh.name as warehouse_name, plt.name as reusable_pallet_name,
|
|
1156
1191
|
rih.remark,
|
|
1192
|
+
rih.manufacture_date as "manufactureDate",
|
|
1157
1193
|
rih.expiration_date as "expirationDate"
|
|
1194
|
+
,sum(case when oi.status = 'LOADING' or (oi.status = 'SORTING' and oi.type = 'RELEASE_OF_GOODS') then oi.release_qty else 0 end) as "nonLoadedQty"
|
|
1195
|
+
,sum(case when oi.status = 'LOADING' or (oi.status = 'SORTING' and oi.type = 'RELEASE_OF_GOODS') then (oi.release_uom_value / oi.release_qty* oi.release_qty) else 0 end) as "nonLoadedUomValue"
|
|
1158
1196
|
from tmp_data rih
|
|
1159
1197
|
left join pallets plt on plt.id = rih.reusable_pallet_id
|
|
1160
1198
|
inner join products prd on prd.id = rih.product_id
|
|
1161
1199
|
inner join bizplaces bz on bz.id = rih.bizplace_id
|
|
1162
1200
|
inner join locations loc on loc.id = rih.location_id
|
|
1163
1201
|
inner join warehouses wh on wh.id = loc.warehouse_id
|
|
1164
|
-
|
|
1202
|
+
inner join order_inventories oi on oi.inventory_id = rih.inventory_id
|
|
1203
|
+
group by rih.inventory_id,rih.domain_id,rih.pallet_id,rih.carton_id,rih.qty,rih.uom_value,rih.uom,rih.last_seq,rih.created_at, rih.initial_inbound_at,rih.unit_cost,rih.reusable_pallet_id,
|
|
1204
|
+
rih.batch_id,plt.name,rih.batch_id_ref,rih.product_id,rih.packing_type,rih.bizplace_id,rih.location_id,prd.id,bz.id,loc.id,wh.name,rih.remark,rih.expiration_date,rih.manufacture_date,rih.status
|
|
1205
|
+
having 1=1 and (case when rih.status = 'TERMINATED' and SUM(CASE WHEN oi.status = 'LOADING' or (oi.status = 'SORTING' AND oi.type = 'RELEASE_OF_GOODS') THEN oi.release_qty ELSE 0 END) > 0 then rih.status = 'TERMINATED' else rih.status <> 'TERMINATED' end)
|
|
1165
1206
|
${queryOrder}
|
|
1166
1207
|
${setPagination ? 'OFFSET ' + (pagination.page - 1) * pagination.limit + ' LIMIT ' + pagination.limit : ''}
|
|
1167
1208
|
`
|
|
1168
1209
|
)
|
|
1210
|
+
//comment end
|
|
1169
1211
|
|
|
1170
1212
|
// map all results
|
|
1171
1213
|
let items = result.map(itm => {
|
|
@@ -1317,6 +1359,173 @@ export class InventoryHistoryQuery {
|
|
|
1317
1359
|
return { items, total }
|
|
1318
1360
|
}
|
|
1319
1361
|
|
|
1362
|
+
@Directive('@transaction')
|
|
1363
|
+
@Query(returns => InventoryHistoryVolumeSummaryReportList)
|
|
1364
|
+
async inventoryHistoryVolumeSummaryReport(
|
|
1365
|
+
@Args() params: ListParam,
|
|
1366
|
+
@Ctx() context: any
|
|
1367
|
+
): Promise<InventoryHistoryVolumeSummaryReportList> {
|
|
1368
|
+
try {
|
|
1369
|
+
const { domain, user, tx }: { domain: Domain; user: User; tx: EntityManager } = context.state
|
|
1370
|
+
|
|
1371
|
+
let bizplaceFilter = { name: '', operator: '', value: '' }
|
|
1372
|
+
|
|
1373
|
+
let userFilter = params.filters.find(data => data.name === 'user')
|
|
1374
|
+
let fromDate = params.filters.find(data => data.name === 'fromDate')
|
|
1375
|
+
let toDate = params.filters.find(data => data.name === 'toDate')
|
|
1376
|
+
|
|
1377
|
+
if (userFilter) {
|
|
1378
|
+
const user: User = await tx.getRepository(User).findOne({
|
|
1379
|
+
where: { id: userFilter.value },
|
|
1380
|
+
relations: ['bizplaces']
|
|
1381
|
+
})
|
|
1382
|
+
|
|
1383
|
+
const bizplace: Bizplace = user.bizplaces[0]
|
|
1384
|
+
|
|
1385
|
+
if (!bizplace) throw 'Invalid input'
|
|
1386
|
+
|
|
1387
|
+
bizplaceFilter = { name: 'bizplace', operator: 'eq', value: bizplace.id }
|
|
1388
|
+
} else {
|
|
1389
|
+
bizplaceFilter = params.filters.find(data => data.name === 'bizplace')
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
if (!bizplaceFilter || !fromDate || !toDate) throw 'Invalid input'
|
|
1393
|
+
|
|
1394
|
+
const bizplace: Bizplace = await tx.getRepository(Bizplace).findOne({
|
|
1395
|
+
id: bizplaceFilter.value
|
|
1396
|
+
})
|
|
1397
|
+
|
|
1398
|
+
//check if all product details got volume
|
|
1399
|
+
let foundPermittedBizplace: Bizplace
|
|
1400
|
+
|
|
1401
|
+
if (bizplace) {
|
|
1402
|
+
foundPermittedBizplace = await tx.getRepository(Bizplace).findOne(bizplace.id, {
|
|
1403
|
+
relations: ['company', 'company.domain']
|
|
1404
|
+
})
|
|
1405
|
+
|
|
1406
|
+
const companyDomain: Domain = foundPermittedBizplace.company.domain
|
|
1407
|
+
|
|
1408
|
+
let foundProductDetail = await tx
|
|
1409
|
+
.getRepository(ProductDetail)
|
|
1410
|
+
.findOne({ where: { domain: companyDomain, volume: IsNull() || 0 } })
|
|
1411
|
+
|
|
1412
|
+
if (foundProductDetail) {
|
|
1413
|
+
throw new Error('there is product master with empty volume')
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
await tx.query(
|
|
1418
|
+
`
|
|
1419
|
+
create temp table temp_reduced_inventory_histories ON COMMIT drop as (
|
|
1420
|
+
select
|
|
1421
|
+
row_number() over (order by cast(rih.created_at + (interval '8 hour') as DATE) ASC) as row,
|
|
1422
|
+
SUM(case when rih.transaction_type in ('UNLOADING', 'RETURN') then rih.qty end) as "inboundQty",
|
|
1423
|
+
round(cast(SUM(case when rih.transaction_type in ('UNLOADING', 'RETURN') then rih.qty * pd.volume end) as numeric), 2) as "inboundVolume",
|
|
1424
|
+
SUM(case when rih.transaction_type in ('ADJUSTMENT', 'NEW', 'CC_ADJUSTMENT') then rih.qty end) as "adjustedQty",
|
|
1425
|
+
round(cast(SUM(case when rih.transaction_type in ('ADJUSTMENT', 'NEW', 'CC_ADJUSTMENT') and rih.status <> 'MISSING' then rih.qty * pd.volume end) as numeric), 2) as "adjustedVolume",
|
|
1426
|
+
SUM(case when rih.transaction_type = 'ADJUSTMENT' and status = 'MISSING' then rih.opening_qty end) as "missingQty",
|
|
1427
|
+
round(cast(SUM(case when rih.transaction_type = 'ADJUSTMENT' and status = 'MISSING' then rih.opening_qty * pd.volume end) as numeric), 2) as "missingVolume",
|
|
1428
|
+
SUM(case when rih.transaction_type = 'PICKING' then -(rih.qty) end) as "outboundQty",
|
|
1429
|
+
round(cast(SUM(case when rih.transaction_type = 'PICKING' then -(rih.qty) * pd.volume end) as numeric), 2) as "outboundVolume",
|
|
1430
|
+
SUM(case when rih.transaction_type in ('UNLOADING', 'ADJUSTMENT', 'PICKING', 'NEW', 'RETURN', 'CC_ADJUSTMENT') then rih.qty end) - SUM(case when rih.transaction_type = 'ADJUSTMENT' and status = 'MISSING' then rih.opening_qty else 0 end) as "tempTotal",
|
|
1431
|
+
round(cast(SUM(case when rih.transaction_type in ('UNLOADING', 'ADJUSTMENT', 'PICKING', 'NEW', 'RETURN', 'CC_ADJUSTMENT') then rih.qty * pd.volume end) - round(cast(SUM(case when rih.transaction_type = 'ADJUSTMENT' and status = 'MISSING' then rih.opening_qty * pd.volume else 0 end) as numeric), 2) as numeric), 2) as "tempTotalVolume",
|
|
1432
|
+
rih.bizplace_id as bizplace_id,
|
|
1433
|
+
cast(rih.created_at + (interval '8 hour') as DATE) as "tempDate"
|
|
1434
|
+
from reduced_inventory_histories rih
|
|
1435
|
+
left join product_details pd on pd.product_id = rih.product_id and pd.packing_type = rih.packing_type
|
|
1436
|
+
where rih.status not like 'TERMINATED' and rih.bizplace_id = $1
|
|
1437
|
+
group by CAST(rih.created_at + (interval '8 hour') as DATE), rih.bizplace_id
|
|
1438
|
+
)
|
|
1439
|
+
`,
|
|
1440
|
+
[bizplace.id]
|
|
1441
|
+
)
|
|
1442
|
+
|
|
1443
|
+
await tx.query(
|
|
1444
|
+
`
|
|
1445
|
+
create temp table temp_reduced_inventory_histories_with_date_range ON COMMIT drop as (
|
|
1446
|
+
select
|
|
1447
|
+
coalesce(tmp."tempDate", dr.range_date) as date,
|
|
1448
|
+
row_number() over (order by coalesce(tmp."tempDate", dr.range_date) ASC) as row,
|
|
1449
|
+
coalesce(tmp."inboundQty", 0) as "inboundQty",
|
|
1450
|
+
coalesce(tmp."inboundVolume", 0) as "inboundVolume",
|
|
1451
|
+
coalesce(tmp."adjustedQty", 0) as "adjustedQty",
|
|
1452
|
+
coalesce(tmp."adjustedVolume", 0) as "adjustedVolume",
|
|
1453
|
+
coalesce(tmp."missingQty", 0) as "missingQty",
|
|
1454
|
+
coalesce(tmp."missingVolume", 0) as "missingVolume",
|
|
1455
|
+
coalesce(tmp."outboundQty", 0) as "outboundQty",
|
|
1456
|
+
coalesce(tmp."outboundVolume", 0) as "outboundVolume",
|
|
1457
|
+
'${bizplace.id}' as bizplace_id,
|
|
1458
|
+
(case when tmp."tempTotal" isnull then 0 else tmp."tempTotal" end) as total, (case when tmp."tempTotalVolume" isnull then 0 else tmp."tempTotalVolume" end) as "totalVolume"
|
|
1459
|
+
from temp_reduced_inventory_histories tmp
|
|
1460
|
+
full join (
|
|
1461
|
+
select date_trunc('day', dd):: date as range_date
|
|
1462
|
+
from generate_series
|
|
1463
|
+
( $1::timestamp
|
|
1464
|
+
, $2::timestamp
|
|
1465
|
+
, '1 day'::interval) dd
|
|
1466
|
+
) dr on dr.range_date = tmp."tempDate" order by date
|
|
1467
|
+
)
|
|
1468
|
+
`,
|
|
1469
|
+
[fromDate.value, toDate.value]
|
|
1470
|
+
)
|
|
1471
|
+
|
|
1472
|
+
await tx.query(
|
|
1473
|
+
`
|
|
1474
|
+
create temp table temp_result ON COMMIT drop as(
|
|
1475
|
+
select lag(sub."closingQty", 1, 0) over (partition by sub.bizplace_id order by sub.date) as "openingQty",
|
|
1476
|
+
lag(sub."closingVolume", 1, 0) over (partition by sub.bizplace_id order by sub.date) as "openingVolume", sub.* from(
|
|
1477
|
+
select (select sum(tmp2.total) from temp_reduced_inventory_histories_with_date_range tmp2 where tmp2.row <= tmp.row) as "closingQty",
|
|
1478
|
+
(select sum(tmp2."totalVolume") from temp_reduced_inventory_histories_with_date_range tmp2 where tmp2.row <= tmp.row) as "closingVolume", tmp.* from
|
|
1479
|
+
temp_reduced_inventory_histories_with_date_range tmp) sub
|
|
1480
|
+
)
|
|
1481
|
+
`
|
|
1482
|
+
)
|
|
1483
|
+
|
|
1484
|
+
await tx.query(
|
|
1485
|
+
`
|
|
1486
|
+
create temp table temp_final ON COMMIT drop as(
|
|
1487
|
+
select * from temp_result tr where tr.date between $1 and $2 OFFSET $3 LIMIT $4
|
|
1488
|
+
)
|
|
1489
|
+
`,
|
|
1490
|
+
[fromDate.value, toDate.value, (params.pagination.page - 1) * params.pagination.limit, params.pagination.limit]
|
|
1491
|
+
)
|
|
1492
|
+
|
|
1493
|
+
const result: any = await tx.query(
|
|
1494
|
+
`
|
|
1495
|
+
select * from temp_final
|
|
1496
|
+
`
|
|
1497
|
+
)
|
|
1498
|
+
|
|
1499
|
+
const total: any = await tx.query(
|
|
1500
|
+
`
|
|
1501
|
+
select count(*), sum(tmp."inboundQty") as "totalInboundQty", sum(tmp."inboundVolume") as "totalInboundVolume",
|
|
1502
|
+
sum(tmp."adjustedQty") as "totalAdjustedQty", sum(tmp."adjustedVolume") as "totalAdjustedVolume",
|
|
1503
|
+
sum(tmp."missingQty") as "totalMissingQty", sum(tmp."missingVolume") as "totalMissingVolume",
|
|
1504
|
+
sum(tmp."outboundQty") as "totalOutboundQty", sum(tmp."outboundVolume") as "totalOutboundVolume" from temp_final tmp
|
|
1505
|
+
`
|
|
1506
|
+
)
|
|
1507
|
+
|
|
1508
|
+
return {
|
|
1509
|
+
items: result,
|
|
1510
|
+
total: total[0].count,
|
|
1511
|
+
totalOpeningQty: result?.length > 0 ? result[0].openingQty : 0,
|
|
1512
|
+
totalOpeningVolume: result?.length > 0 ? result[0].openingVolume : 0,
|
|
1513
|
+
totalInboundQty: result?.length > 0 ? total[0].totalInboundQty : 0,
|
|
1514
|
+
totalInboundVolume: result?.length > 0 ? total[0].totalInboundVolume : 0,
|
|
1515
|
+
totalAdjustedQty: result?.length > 0 ? total[0].totalAdjustedQty : 0,
|
|
1516
|
+
totalAdjustedVolume: result?.length > 0 ? total[0].totalAdjustedVolume : 0,
|
|
1517
|
+
totalMissingQty: result?.length > 0 ? total[0].totalMissingQty : 0,
|
|
1518
|
+
totalMissingVolume: result?.length > 0 ? total[0].totalMissingVolume : 0,
|
|
1519
|
+
totalOutboundQty: result?.length > 0 ? total[0].totalOutboundQty : 0,
|
|
1520
|
+
totalOutboundVolume: result?.length > 0 ? total[0].totalOutboundVolume : 0,
|
|
1521
|
+
totalClosingQty: result?.length > 0 ? result[result.length - 1].closingQty : 0,
|
|
1522
|
+
totalClosingVolume: result?.length > 0 ? result[result.length - 1].closingVolume : 0
|
|
1523
|
+
}
|
|
1524
|
+
} catch (error) {
|
|
1525
|
+
throw error
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1320
1529
|
@FieldResolver(type => Domain)
|
|
1321
1530
|
async domain(@Root() inventoryHistory: InventoryHistory) {
|
|
1322
1531
|
return await getRepository(Domain).findOne(inventoryHistory.domainId)
|
|
@@ -1348,11 +1557,12 @@ async function massageInventorySummary(tx: EntityManager, params: ListParam, biz
|
|
|
1348
1557
|
`
|
|
1349
1558
|
create temp table temp_inventory_summary ON COMMIT DROP as (
|
|
1350
1559
|
select src.*,
|
|
1351
|
-
opening_qty + adjustment_qty + total_in_qty + total_out_qty as closing_qty
|
|
1560
|
+
opening_qty + adjustment_qty + total_in_qty + total_out_qty + missing_qty as closing_qty
|
|
1352
1561
|
from (
|
|
1353
1562
|
select prd.sku AS product_sku, prd.name as product_name, prd.description as product_description, prd.type AS product_type, ih.packing_type, ih.packing_size,
|
|
1354
1563
|
sum(case when ih.created_at >= $1 and ih.transaction_type = 'ADJUSTMENT' then ih.qty else 0 end) as adjustment_qty,
|
|
1355
1564
|
sum(case when ih.created_at < $1 then qty else 0 end) as opening_qty,
|
|
1565
|
+
sum(case when ih.status = 'MISSING' then -ih.opening_qty else 0 end) as missing_qty,
|
|
1356
1566
|
sum(case when ih.created_at >= $1 then case when ih.qty > 0 and ih.transaction_type <> 'ADJUSTMENT' then ih.qty else 0 end else 0 end) as total_in_qty,
|
|
1357
1567
|
sum(case when ih.created_at >= $1 then case when ih.qty < 0 and ih.transaction_type <> 'ADJUSTMENT' then ih.qty else 0 end else 0 end) as total_out_qty,
|
|
1358
1568
|
ih.product_id
|
|
@@ -165,6 +165,9 @@ export class InventoryHistorySummary {
|
|
|
165
165
|
@Field(type => Float, { nullable: true })
|
|
166
166
|
openingQty?: number
|
|
167
167
|
|
|
168
|
+
@Field(type => Float, { nullable: true })
|
|
169
|
+
missingQty?: number
|
|
170
|
+
|
|
168
171
|
@Field(type => Float, { nullable: true })
|
|
169
172
|
adjustmentQty?: number
|
|
170
173
|
|
|
@@ -353,3 +356,89 @@ export class RawInventoryHistory {
|
|
|
353
356
|
@Field({ nullable: true })
|
|
354
357
|
updater?: string
|
|
355
358
|
}
|
|
359
|
+
@ObjectType()
|
|
360
|
+
export class InventoryHistoryVolumeSummaryReport {
|
|
361
|
+
@Field({ nullable: true })
|
|
362
|
+
date?: Date
|
|
363
|
+
|
|
364
|
+
@Field(type => Int, { nullable: true })
|
|
365
|
+
openingQty?: number
|
|
366
|
+
|
|
367
|
+
@Field(type => Float, { nullable: true })
|
|
368
|
+
openingVolume?: number
|
|
369
|
+
|
|
370
|
+
@Field(type => Int, { nullable: true })
|
|
371
|
+
inboundQty?: number
|
|
372
|
+
|
|
373
|
+
@Field(type => Float, { nullable: true })
|
|
374
|
+
inboundVolume?: number
|
|
375
|
+
|
|
376
|
+
@Field(type => Int, { nullable: true })
|
|
377
|
+
adjustedQty?: number
|
|
378
|
+
|
|
379
|
+
@Field(type => Float, { nullable: true })
|
|
380
|
+
adjustedVolume?: number
|
|
381
|
+
|
|
382
|
+
@Field(type => Int, { nullable: true })
|
|
383
|
+
missingQty?: number
|
|
384
|
+
|
|
385
|
+
@Field(type => Float, { nullable: true })
|
|
386
|
+
missingVolume?: number
|
|
387
|
+
|
|
388
|
+
@Field(type => Int, { nullable: true })
|
|
389
|
+
outboundQty?: number
|
|
390
|
+
|
|
391
|
+
@Field(type => Float, { nullable: true })
|
|
392
|
+
outboundVolume?: number
|
|
393
|
+
|
|
394
|
+
@Field(type => Int, { nullable: true })
|
|
395
|
+
closingQty?: number
|
|
396
|
+
|
|
397
|
+
@Field(type => Float, { nullable: true })
|
|
398
|
+
closingVolume?: number
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
@ObjectType()
|
|
402
|
+
export class InventoryHistoryVolumeSummaryReportList {
|
|
403
|
+
@Field(type => [InventoryHistoryVolumeSummaryReport], { nullable: true })
|
|
404
|
+
items?: InventoryHistoryVolumeSummaryReport[]
|
|
405
|
+
|
|
406
|
+
@Field(type => Int, { nullable: true })
|
|
407
|
+
total?: number
|
|
408
|
+
|
|
409
|
+
@Field(type => Int, { nullable: true })
|
|
410
|
+
totalOpeningQty?: number
|
|
411
|
+
|
|
412
|
+
@Field(type => Float, { nullable: true })
|
|
413
|
+
totalOpeningVolume?: number
|
|
414
|
+
|
|
415
|
+
@Field(type => Int, { nullable: true })
|
|
416
|
+
totalInboundQty?: number
|
|
417
|
+
|
|
418
|
+
@Field(type => Float, { nullable: true })
|
|
419
|
+
totalInboundVolume?: number
|
|
420
|
+
|
|
421
|
+
@Field(type => Int, { nullable: true })
|
|
422
|
+
totalAdjustedQty?: number
|
|
423
|
+
|
|
424
|
+
@Field(type => Float, { nullable: true })
|
|
425
|
+
totalAdjustedVolume?: number
|
|
426
|
+
|
|
427
|
+
@Field(type => Int, { nullable: true })
|
|
428
|
+
totalMissingQty?: number
|
|
429
|
+
|
|
430
|
+
@Field(type => Float, { nullable: true })
|
|
431
|
+
totalMissingVolume?: number
|
|
432
|
+
|
|
433
|
+
@Field(type => Int, { nullable: true })
|
|
434
|
+
totalOutboundQty?: number
|
|
435
|
+
|
|
436
|
+
@Field(type => Float, { nullable: true })
|
|
437
|
+
totalOutboundVolume?: number
|
|
438
|
+
|
|
439
|
+
@Field(type => Int, { nullable: true })
|
|
440
|
+
totalClosingQty?: number
|
|
441
|
+
|
|
442
|
+
@Field(type => Float, { nullable: true })
|
|
443
|
+
totalClosingVolume?: number
|
|
444
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
|
|
2
2
|
import { EntityManager, In, MoreThan } from 'typeorm'
|
|
3
|
-
import
|
|
3
|
+
import { v4 as uuidv4 } from 'uuid'
|
|
4
4
|
|
|
5
5
|
import { User } from '@things-factory/auth-base'
|
|
6
6
|
import { Domain } from '@things-factory/shell'
|
|
@@ -125,7 +125,7 @@ export class PalletCountMutation {
|
|
|
125
125
|
|
|
126
126
|
if (!palletCount) {
|
|
127
127
|
let newPallet = {
|
|
128
|
-
name:
|
|
128
|
+
name: uuidv4(),
|
|
129
129
|
seq: 0,
|
|
130
130
|
domain: domain,
|
|
131
131
|
creator: user,
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid'
|
|
2
2
|
|
|
3
3
|
export class InventoryNoGenerator {
|
|
4
4
|
static inventoryName() {
|
|
5
|
-
return
|
|
5
|
+
return uuidv4()
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
static inventoryHistoryName() {
|
|
9
|
-
return
|
|
9
|
+
return uuidv4()
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
static inventoryItemName() {
|
|
13
|
-
return
|
|
13
|
+
return uuidv4()
|
|
14
14
|
}
|
|
15
15
|
}
|