@things-factory/operato-wms 3.7.2 → 3.7.7
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/client/pages/components/select-product-popup.js +5 -1
- package/client/pages/constants/order.js +10 -0
- package/client/pages/inbound/putaway-product.js +162 -139
- package/client/pages/inventory-check/inspecting-product.js +146 -80
- package/client/pages/manifest/create-loading-manifest.js +314 -0
- package/client/pages/manifest/dispatcher-verification-popup.js +86 -0
- package/client/pages/manifest/loading-manifest-detail.js +345 -0
- package/client/pages/manifest/loading-manifest-list.js +305 -0
- package/client/pages/order/arrival-notice/create-arrival-notice.js +8 -1
- package/client/pages/order/goods-received-note/received-note-list.js +138 -6
- package/client/pages/order/release-order/b2b/b2b-order-list.js +45 -5
- package/client/pages/order/release-order/b2b/b2b-order-requests.js +45 -5
- package/client/pages/order/release-order/b2c/b2c-order-requests.js +181 -21
- package/client/pages/order/release-order/bulk-print-packing-list.js +23 -0
- package/client/pages/order/release-order/create-release-order.js +25 -4
- package/client/pages/order/release-order/receive-release-order-request.js +27 -24
- package/client/pages/order/release-order/release-extra-product-popup.js +189 -56
- package/client/pages/order/release-order/release-order-detail.js +292 -71
- package/client/pages/order/reverse-kitting-order/reverse-kitting-order-detail.js +115 -50
- package/client/pages/order/reverse-kitting-order/reverse-kitting-order-list.js +1 -6
- package/client/pages/order/reverse-kitting-order/reverse-kitting-pallet-label-popup.js +239 -0
- package/client/pages/order/transport-order/delivery-order-list.js +99 -59
- package/client/pages/outbound/loading-product.js +4 -1
- package/client/pages/outbound/merged-outbound-worksheet.js +39 -1
- package/client/pages/outbound/packing-product.js +4 -1
- package/client/pages/outbound/packing-worksheet-list.js +39 -1
- package/client/pages/outbound/picking-product.js +622 -290
- package/client/pages/outbound/serial-number-popup.js +280 -0
- package/client/pages/outbound/worksheet-picking.js +28 -2
- package/client/pages/report/product-label-report.js +401 -0
- package/client/pages/support/inventory-comparison.js +296 -0
- package/client/pages/vas/print-product-label.js +298 -132
- package/client/pages/vas/reverse-kitting/execute-reverse-kitting.js +30 -12
- package/client/pages/vas/reverse-kitting/popup-combination-sets.js +75 -5
- package/client/pages/vas/reverse-kitting/popup-reverse-kitting-template.js +113 -18
- package/client/route.js +23 -0
- package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.js +64 -54
- package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.js.map +1 -1
- package/dist-server/graphql/resolvers/extra/add-release-good-products.js +34 -9
- package/dist-server/graphql/resolvers/extra/add-release-good-products.js.map +1 -1
- package/dist-server/graphql/resolvers/index.js +3 -1
- package/dist-server/graphql/resolvers/index.js.map +1 -1
- package/dist-server/graphql/resolvers/inventory-comparison/index.js +6 -0
- package/dist-server/graphql/resolvers/inventory-comparison/index.js.map +1 -0
- package/dist-server/graphql/resolvers/inventory-comparison/inventory-comparison-list.js +78 -0
- package/dist-server/graphql/resolvers/inventory-comparison/inventory-comparison-list.js.map +1 -0
- package/dist-server/graphql/resolvers/reports/index.js +2 -1
- package/dist-server/graphql/resolvers/reports/index.js.map +1 -1
- package/dist-server/graphql/resolvers/reports/product-label-report.js +56 -0
- package/dist-server/graphql/resolvers/reports/product-label-report.js.map +1 -0
- package/dist-server/graphql/types/index.js +5 -2
- package/dist-server/graphql/types/index.js.map +1 -1
- package/dist-server/graphql/types/inventory-comparison/index.js +13 -0
- package/dist-server/graphql/types/inventory-comparison/index.js.map +1 -0
- package/dist-server/graphql/types/inventory-comparison/inventory-comparison-list.js +14 -0
- package/dist-server/graphql/types/inventory-comparison/inventory-comparison-list.js.map +1 -0
- package/dist-server/graphql/types/inventory-comparison/inventory-comparison.js +18 -0
- package/dist-server/graphql/types/inventory-comparison/inventory-comparison.js.map +1 -0
- package/dist-server/graphql/types/reports/index.js +6 -1
- package/dist-server/graphql/types/reports/index.js.map +1 -1
- package/dist-server/graphql/types/reports/product-label-report-list.js +14 -0
- package/dist-server/graphql/types/reports/product-label-report-list.js.map +1 -0
- package/dist-server/graphql/types/reports/product-label-report.js +16 -0
- package/dist-server/graphql/types/reports/product-label-report.js.map +1 -0
- package/package.json +65 -65
- package/server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.ts +75 -65
- package/server/graphql/resolvers/extra/add-release-good-products.ts +57 -15
- package/server/graphql/resolvers/index.ts +3 -1
- package/server/graphql/resolvers/inventory-comparison/index.ts +5 -0
- package/server/graphql/resolvers/inventory-comparison/inventory-comparison-list.ts +99 -0
- package/server/graphql/resolvers/reports/index.ts +3 -1
- package/server/graphql/resolvers/reports/product-label-report.ts +56 -0
- package/server/graphql/types/index.ts +5 -2
- package/server/graphql/types/inventory-comparison/index.ts +11 -0
- package/server/graphql/types/inventory-comparison/inventory-comparison-list.ts +8 -0
- package/server/graphql/types/inventory-comparison/inventory-comparison.ts +12 -0
- package/server/graphql/types/reports/index.ts +6 -1
- package/server/graphql/types/reports/product-label-report-list.ts +8 -0
- package/server/graphql/types/reports/product-label-report.ts +10 -0
- package/things-factory.config.js +24 -0
- package/translations/en.json +64 -12
- package/translations/ko.json +50 -1
- package/translations/ms.json +51 -1
- package/translations/zh.json +50 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/operato-wms",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.7",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"browser": "client/index.js",
|
|
6
6
|
"things-factory": true,
|
|
@@ -42,71 +42,71 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@operato/ghost-print": "0.1.14",
|
|
45
|
-
"@things-factory/apptool-ui": "^3.7.
|
|
46
|
-
"@things-factory/attachment-ui": "^3.7.
|
|
47
|
-
"@things-factory/auth-ui": "^3.7.
|
|
48
|
-
"@things-factory/barcode-ui": "^3.7.
|
|
49
|
-
"@things-factory/biz-ui": "^3.7.
|
|
50
|
-
"@things-factory/board-service": "^3.7.
|
|
51
|
-
"@things-factory/board-ui": "^3.7.
|
|
52
|
-
"@things-factory/code-ui": "^3.7.
|
|
53
|
-
"@things-factory/context-ui": "^3.7.
|
|
54
|
-
"@things-factory/export-ui": "^3.7.
|
|
55
|
-
"@things-factory/export-ui-csv": "^3.7.
|
|
56
|
-
"@things-factory/export-ui-excel": "^3.7.
|
|
57
|
-
"@things-factory/fav-base": "^3.7.
|
|
58
|
-
"@things-factory/form-ui": "^3.7.
|
|
59
|
-
"@things-factory/grist-ui": "^3.7.
|
|
60
|
-
"@things-factory/help": "^3.7.
|
|
61
|
-
"@things-factory/i18n-ui": "^3.7.
|
|
62
|
-
"@things-factory/id-rule-base": "^3.7.
|
|
63
|
-
"@things-factory/import-ui": "^3.7.
|
|
64
|
-
"@things-factory/import-ui-excel": "^3.7.
|
|
65
|
-
"@things-factory/menu-ui": "^3.7.
|
|
66
|
-
"@things-factory/more-ui": "^3.7.
|
|
67
|
-
"@things-factory/notification": "^3.7.
|
|
68
|
-
"@things-factory/pdf": "^3.7.
|
|
69
|
-
"@things-factory/print-proxy-service": "^3.7.
|
|
70
|
-
"@things-factory/print-service": "^3.7.
|
|
71
|
-
"@things-factory/print-ui": "^3.7.
|
|
72
|
-
"@things-factory/product-base": "^3.7.
|
|
73
|
-
"@things-factory/resource-ui": "^3.7.
|
|
74
|
-
"@things-factory/sales-ui": "^3.7.
|
|
75
|
-
"@things-factory/scene-chartjs": "^3.7.
|
|
76
|
-
"@things-factory/scene-clock": "^3.7.
|
|
77
|
-
"@things-factory/scene-clone": "^3.7.
|
|
78
|
-
"@things-factory/scene-compass": "^3.7.
|
|
79
|
-
"@things-factory/scene-data-transform": "^3.7.
|
|
80
|
-
"@things-factory/scene-excel": "^3.7.
|
|
81
|
-
"@things-factory/scene-firebase": "^3.7.
|
|
82
|
-
"@things-factory/scene-form": "^3.7.
|
|
83
|
-
"@things-factory/scene-gauge": "^3.7.
|
|
84
|
-
"@things-factory/scene-google-map": "^3.7.
|
|
85
|
-
"@things-factory/scene-graphql": "^3.7.
|
|
86
|
-
"@things-factory/scene-half-roundrect": "^3.7.
|
|
87
|
-
"@things-factory/scene-indoor-map": "^3.7.
|
|
88
|
-
"@things-factory/scene-label": "^3.7.
|
|
89
|
-
"@things-factory/scene-legend": "^3.7.
|
|
90
|
-
"@things-factory/scene-marker": "^3.7.
|
|
91
|
-
"@things-factory/scene-mqtt": "^3.7.
|
|
92
|
-
"@things-factory/scene-news-ticker": "^3.7.
|
|
93
|
-
"@things-factory/scene-progressbar": "^3.7.
|
|
94
|
-
"@things-factory/scene-random": "^3.7.
|
|
95
|
-
"@things-factory/scene-restful": "^3.7.
|
|
96
|
-
"@things-factory/scene-switch": "^3.7.
|
|
97
|
-
"@things-factory/scene-tab": "^3.7.
|
|
98
|
-
"@things-factory/scene-table": "^3.7.
|
|
99
|
-
"@things-factory/scene-visualizer": "^3.7.
|
|
100
|
-
"@things-factory/scene-wheel-sorter": "^3.7.
|
|
101
|
-
"@things-factory/setting-ui": "^3.7.
|
|
102
|
-
"@things-factory/system-ui": "^3.7.
|
|
103
|
-
"@things-factory/transport-base": "^3.7.
|
|
104
|
-
"@things-factory/tutorial-ui": "^3.7.
|
|
105
|
-
"@things-factory/warehouse-base": "^3.7.
|
|
106
|
-
"@things-factory/worksheet-base": "^3.7.
|
|
45
|
+
"@things-factory/apptool-ui": "^3.7.5",
|
|
46
|
+
"@things-factory/attachment-ui": "^3.7.5",
|
|
47
|
+
"@things-factory/auth-ui": "^3.7.7",
|
|
48
|
+
"@things-factory/barcode-ui": "^3.7.7",
|
|
49
|
+
"@things-factory/biz-ui": "^3.7.5",
|
|
50
|
+
"@things-factory/board-service": "^3.7.5",
|
|
51
|
+
"@things-factory/board-ui": "^3.7.5",
|
|
52
|
+
"@things-factory/code-ui": "^3.7.5",
|
|
53
|
+
"@things-factory/context-ui": "^3.7.5",
|
|
54
|
+
"@things-factory/export-ui": "^3.7.5",
|
|
55
|
+
"@things-factory/export-ui-csv": "^3.7.5",
|
|
56
|
+
"@things-factory/export-ui-excel": "^3.7.5",
|
|
57
|
+
"@things-factory/fav-base": "^3.7.5",
|
|
58
|
+
"@things-factory/form-ui": "^3.7.5",
|
|
59
|
+
"@things-factory/grist-ui": "^3.7.5",
|
|
60
|
+
"@things-factory/help": "^3.7.5",
|
|
61
|
+
"@things-factory/i18n-ui": "^3.7.5",
|
|
62
|
+
"@things-factory/id-rule-base": "^3.7.6",
|
|
63
|
+
"@things-factory/import-ui": "^3.7.5",
|
|
64
|
+
"@things-factory/import-ui-excel": "^3.7.5",
|
|
65
|
+
"@things-factory/menu-ui": "^3.7.5",
|
|
66
|
+
"@things-factory/more-ui": "^3.7.5",
|
|
67
|
+
"@things-factory/notification": "^3.7.5",
|
|
68
|
+
"@things-factory/pdf": "^3.7.5",
|
|
69
|
+
"@things-factory/print-proxy-service": "^3.7.5",
|
|
70
|
+
"@things-factory/print-service": "^3.7.5",
|
|
71
|
+
"@things-factory/print-ui": "^3.7.5",
|
|
72
|
+
"@things-factory/product-base": "^3.7.7",
|
|
73
|
+
"@things-factory/resource-ui": "^3.7.7",
|
|
74
|
+
"@things-factory/sales-ui": "^3.7.7",
|
|
75
|
+
"@things-factory/scene-chartjs": "^3.7.5",
|
|
76
|
+
"@things-factory/scene-clock": "^3.7.5",
|
|
77
|
+
"@things-factory/scene-clone": "^3.7.5",
|
|
78
|
+
"@things-factory/scene-compass": "^3.7.5",
|
|
79
|
+
"@things-factory/scene-data-transform": "^3.7.5",
|
|
80
|
+
"@things-factory/scene-excel": "^3.7.5",
|
|
81
|
+
"@things-factory/scene-firebase": "^3.7.5",
|
|
82
|
+
"@things-factory/scene-form": "^3.7.5",
|
|
83
|
+
"@things-factory/scene-gauge": "^3.7.5",
|
|
84
|
+
"@things-factory/scene-google-map": "^3.7.5",
|
|
85
|
+
"@things-factory/scene-graphql": "^3.7.5",
|
|
86
|
+
"@things-factory/scene-half-roundrect": "^3.7.5",
|
|
87
|
+
"@things-factory/scene-indoor-map": "^3.7.5",
|
|
88
|
+
"@things-factory/scene-label": "^3.7.7",
|
|
89
|
+
"@things-factory/scene-legend": "^3.7.5",
|
|
90
|
+
"@things-factory/scene-marker": "^3.7.5",
|
|
91
|
+
"@things-factory/scene-mqtt": "^3.7.5",
|
|
92
|
+
"@things-factory/scene-news-ticker": "^3.7.5",
|
|
93
|
+
"@things-factory/scene-progressbar": "^3.7.5",
|
|
94
|
+
"@things-factory/scene-random": "^3.7.5",
|
|
95
|
+
"@things-factory/scene-restful": "^3.7.5",
|
|
96
|
+
"@things-factory/scene-switch": "^3.7.5",
|
|
97
|
+
"@things-factory/scene-tab": "^3.7.5",
|
|
98
|
+
"@things-factory/scene-table": "^3.7.5",
|
|
99
|
+
"@things-factory/scene-visualizer": "^3.7.5",
|
|
100
|
+
"@things-factory/scene-wheel-sorter": "^3.7.5",
|
|
101
|
+
"@things-factory/setting-ui": "^3.7.5",
|
|
102
|
+
"@things-factory/system-ui": "^3.7.5",
|
|
103
|
+
"@things-factory/transport-base": "^3.7.5",
|
|
104
|
+
"@things-factory/tutorial-ui": "^3.7.5",
|
|
105
|
+
"@things-factory/warehouse-base": "^3.7.7",
|
|
106
|
+
"@things-factory/worksheet-base": "^3.7.7"
|
|
107
107
|
},
|
|
108
108
|
"devDependencies": {
|
|
109
|
-
"@things-factory/builder": "^3.7.
|
|
109
|
+
"@things-factory/builder": "^3.7.5"
|
|
110
110
|
},
|
|
111
|
-
"gitHead": "
|
|
111
|
+
"gitHead": "7e1cfc771ca9e8970d90493d3049d4d589e96f08"
|
|
112
112
|
}
|
|
@@ -8,75 +8,13 @@ export const elcclInventoryHistorySummaryReport = {
|
|
|
8
8
|
try {
|
|
9
9
|
const { tx }: { tx: EntityManager } = context.state
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
await inventoryHistorySummaryReportQuery(_, params, context)
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
let fromDate = params.filters.find(data => data.name === 'fromDate')
|
|
16
|
-
let toDate = params.filters.find(data => data.name === 'toDate')
|
|
17
|
-
|
|
18
|
-
if (!bizplaceFilter || !fromDate || !toDate) throw 'Invalid input'
|
|
19
|
-
|
|
20
|
-
const bizplace: Bizplace = await getRepository(Bizplace).findOne({
|
|
21
|
-
id: bizplaceFilter.value
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
let balanceOnlyQuery = ''
|
|
25
|
-
if (balanceOnlyFilter && balanceOnlyFilter.value) {
|
|
26
|
-
balanceOnlyQuery = 'and (opening_qty + adjustment_qty + total_in_qty + total_out_qty + total_return_qty) > 0 '
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
await tx.query(
|
|
30
|
-
`
|
|
31
|
-
create temp table temp_inv_history on commit drop as (
|
|
32
|
-
select i2.pallet_id, ih.product_id::uuid, ih.packing_type, ih.batch_id,
|
|
33
|
-
ih.id as inventory_history_id, ih.seq, ih.status, ih.transaction_type, ih.qty, ih.opening_qty, ih.weight, ih.opening_weight, ih.created_at,
|
|
34
|
-
ih.ref_order_id::uuid as ref_order_id
|
|
35
|
-
from inventories i2
|
|
36
|
-
inner join reduced_inventory_histories ih on ih.pallet_id = i2.pallet_id and ih.domain_id = i2.domain_id
|
|
37
|
-
where
|
|
38
|
-
i2.domain_id = $1
|
|
39
|
-
and i2.bizplace_id = $2
|
|
40
|
-
and ih.created_at <= $3
|
|
41
|
-
)
|
|
42
|
-
`,
|
|
43
|
-
[context.state.domain.id, bizplace.id, toDate.value]
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
await tx.query(
|
|
47
|
-
`
|
|
48
|
-
create temp table temp_elccl_inventory_summary on commit drop as (
|
|
49
|
-
select src.*,
|
|
50
|
-
opening_qty + adjustment_qty + total_in_qty + total_out_qty + total_return_qty as closing_qty,
|
|
51
|
-
prd.name as product_name, prd.sku as product_sku, prd.description as product_description
|
|
52
|
-
from (
|
|
53
|
-
select ih.batch_id, ih.packing_type,
|
|
54
|
-
min(ih.created_at) as initial_date,
|
|
55
|
-
sum(case when (ih.transaction_type = 'UNLOADING' or ih.transaction_type = 'NEW') and rtn.id is null then qty else 0 end) as initial_qty,
|
|
56
|
-
sum(case when ih.created_at > $1 and ih.transaction_type = 'ADJUSTMENT' then ih.qty else 0 end) as adjustment_qty,
|
|
57
|
-
sum(case when ih.created_at < $1 then ih.qty else 0 end) as opening_qty,
|
|
58
|
-
sum(case when ih.created_at > $1 then case when ih.qty > 0 and ih.transaction_type <> 'ADJUSTMENT' and ih.transaction_type <> 'RETURN' and rtn.id is null then ih.qty else 0 end else 0 end) as total_in_qty,
|
|
59
|
-
sum(case when ih.created_at > $1 then case when (ih.qty < 0 and ih.transaction_type <> 'ADJUSTMENT') or ih.transaction_type = 'RETURN' then ih.qty else 0 end else 0 end) as total_out_qty,
|
|
60
|
-
ih.product_id,
|
|
61
|
-
sum(case when rtn.id is not null and ih.transaction_type <> 'ADJUSTMENT' and ih.created_at > $1 then qty else 0 end) as total_return_qty
|
|
62
|
-
from temp_inv_history ih
|
|
63
|
-
left join return_orders rtn on rtn.id = ih.ref_order_id
|
|
64
|
-
group by ih.batch_id, ih.product_id, ih.packing_type
|
|
65
|
-
order by batch_id
|
|
66
|
-
) src
|
|
67
|
-
inner join products prd on prd.id = src.product_id
|
|
68
|
-
where (opening_qty > 0 or total_in_qty > 0 or adjustment_qty > 0)
|
|
69
|
-
${balanceOnlyQuery}
|
|
70
|
-
)
|
|
71
|
-
`,
|
|
72
|
-
[fromDate.value]
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
const total: any = await tx.query(`select count(*) from temp_elccl_inventory_summary`)
|
|
13
|
+
const total: any = await tx.query(`select count(*) from temp_inventory_summary`)
|
|
76
14
|
|
|
77
15
|
const result: any = await tx.query(
|
|
78
16
|
`
|
|
79
|
-
select * from
|
|
17
|
+
select * from temp_inventory_summary ORDER BY initial_date OFFSET $1 LIMIT $2
|
|
80
18
|
`,
|
|
81
19
|
[(params.pagination.page - 1) * params.pagination.limit, params.pagination.limit]
|
|
82
20
|
)
|
|
@@ -109,3 +47,75 @@ export const elcclInventoryHistorySummaryReport = {
|
|
|
109
47
|
}
|
|
110
48
|
}
|
|
111
49
|
}
|
|
50
|
+
|
|
51
|
+
export async function inventoryHistorySummaryReportQuery(_: any, params: ListParam, context: any): Promise<void> {
|
|
52
|
+
try {
|
|
53
|
+
const { tx }: { tx: EntityManager } = context.state
|
|
54
|
+
|
|
55
|
+
let balanceOnlyFilter = params.filters.find(data => data.name === 'balanceOnly')
|
|
56
|
+
|
|
57
|
+
let bizplaceFilter = params.filters.find(data => data.name === 'bizplace')
|
|
58
|
+
|
|
59
|
+
let fromDate = params.filters.find(data => data.name === 'fromDate')
|
|
60
|
+
let toDate = params.filters.find(data => data.name === 'toDate')
|
|
61
|
+
|
|
62
|
+
if (!bizplaceFilter || !fromDate || !toDate) throw 'Invalid input'
|
|
63
|
+
|
|
64
|
+
const bizplace: Bizplace = await getRepository(Bizplace).findOne({
|
|
65
|
+
id: bizplaceFilter.value
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
let balanceOnlyQuery = ''
|
|
69
|
+
if (balanceOnlyFilter && balanceOnlyFilter.value) {
|
|
70
|
+
balanceOnlyQuery = 'and (opening_qty + adjustment_qty + total_in_qty + total_out_qty + total_return_qty) > 0 '
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
await tx.query(
|
|
74
|
+
`
|
|
75
|
+
create temp table temp_inv_history on commit drop as (
|
|
76
|
+
select i2.pallet_id, ih.product_id::uuid, ih.packing_type, ih.batch_id,
|
|
77
|
+
ih.id as inventory_history_id, ih.seq, ih.status, ih.transaction_type, ih.qty, ih.opening_qty, ih.weight, ih.opening_weight, ih.created_at,
|
|
78
|
+
ih.ref_order_id::uuid as ref_order_id
|
|
79
|
+
from inventories i2
|
|
80
|
+
inner join reduced_inventory_histories ih on ih.pallet_id = i2.pallet_id and ih.domain_id = i2.domain_id
|
|
81
|
+
where
|
|
82
|
+
i2.domain_id = $1
|
|
83
|
+
and i2.bizplace_id = $2
|
|
84
|
+
and ih.created_at <= $3
|
|
85
|
+
)
|
|
86
|
+
`,
|
|
87
|
+
[context.state.domain.id, bizplace.id, toDate.value]
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
await tx.query(
|
|
91
|
+
`
|
|
92
|
+
create temp table temp_inventory_summary on commit drop as (
|
|
93
|
+
select src.*,
|
|
94
|
+
opening_qty + adjustment_qty + total_in_qty + total_out_qty + total_return_qty as closing_qty,
|
|
95
|
+
prd.name as product_name, prd.sku as product_sku, prd.description as product_description
|
|
96
|
+
from (
|
|
97
|
+
select ih.batch_id, ih.packing_type,
|
|
98
|
+
min(ih.created_at) as initial_date,
|
|
99
|
+
sum(case when (ih.transaction_type = 'UNLOADING' or ih.transaction_type = 'NEW') and rtn.id is null then qty else 0 end) as initial_qty,
|
|
100
|
+
sum(case when ih.created_at > $1 and ih.transaction_type = 'ADJUSTMENT' then ih.qty else 0 end) as adjustment_qty,
|
|
101
|
+
sum(case when ih.created_at < $1 then ih.qty else 0 end) as opening_qty,
|
|
102
|
+
sum(case when ih.created_at > $1 then case when ih.qty > 0 and ih.transaction_type <> 'ADJUSTMENT' and ih.transaction_type <> 'RETURN' and rtn.id is null then ih.qty else 0 end else 0 end) as total_in_qty,
|
|
103
|
+
sum(case when ih.created_at > $1 then case when (ih.qty < 0 and ih.transaction_type <> 'ADJUSTMENT') or ih.transaction_type = 'RETURN' then ih.qty else 0 end else 0 end) as total_out_qty,
|
|
104
|
+
ih.product_id,
|
|
105
|
+
sum(case when rtn.id is not null and ih.transaction_type <> 'ADJUSTMENT' and ih.created_at > $1 then qty else 0 end) as total_return_qty
|
|
106
|
+
from temp_inv_history ih
|
|
107
|
+
left join return_orders rtn on rtn.id = ih.ref_order_id
|
|
108
|
+
group by ih.batch_id, ih.product_id, ih.packing_type
|
|
109
|
+
order by batch_id
|
|
110
|
+
) src
|
|
111
|
+
inner join products prd on prd.id = src.product_id
|
|
112
|
+
where (opening_qty > 0 or total_in_qty > 0 or adjustment_qty > 0)
|
|
113
|
+
${balanceOnlyQuery}
|
|
114
|
+
)
|
|
115
|
+
`,
|
|
116
|
+
[fromDate.value]
|
|
117
|
+
)
|
|
118
|
+
} catch (error) {
|
|
119
|
+
throw error
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
+
import { EntityManager } from 'typeorm'
|
|
2
|
+
|
|
1
3
|
import { User } from '@things-factory/auth-base'
|
|
2
4
|
import { Bizplace } from '@things-factory/biz-base'
|
|
3
5
|
import { Product } from '@things-factory/product-base'
|
|
4
|
-
import { OrderInventory, OrderNoGenerator,
|
|
6
|
+
import { ORDER_INVENTORY_STATUS, OrderInventory, OrderNoGenerator, ReleaseGood } from '@things-factory/sales-base'
|
|
5
7
|
import { Domain } from '@things-factory/shell'
|
|
6
|
-
import { Inventory,
|
|
8
|
+
import { Inventory, INVENTORY_TRANSACTION_TYPE, InventoryHistory } from '@things-factory/warehouse-base'
|
|
7
9
|
import {
|
|
8
10
|
generatePickingWorksheetDetail,
|
|
9
11
|
Worksheet,
|
|
10
|
-
WorksheetDetail,
|
|
11
12
|
WORKSHEET_STATUS,
|
|
12
|
-
WORKSHEET_TYPE
|
|
13
|
+
WORKSHEET_TYPE,
|
|
14
|
+
WorksheetDetail
|
|
13
15
|
} from '@things-factory/worksheet-base'
|
|
14
|
-
import { EntityManager } from 'typeorm'
|
|
15
16
|
|
|
16
17
|
export const addReleaseGoodProducts = {
|
|
17
18
|
async addReleaseGoodProducts(_: any, { name, orderInventories, existingOrderInventories }, context: any) {
|
|
@@ -56,13 +57,6 @@ export const addReleaseGoodProducts = {
|
|
|
56
57
|
}
|
|
57
58
|
})
|
|
58
59
|
|
|
59
|
-
if (foundPickingHistory) {
|
|
60
|
-
let pickedQty = Number(foundPickingHistory.qty.toString().replace('-', ''))
|
|
61
|
-
|
|
62
|
-
if (curOrderInv.releaseQty < pickedQty)
|
|
63
|
-
throw new Error(`${foundPickingHistory.palletId} has picked ${pickedQty}`)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
60
|
existingOrderInv = await tx.getRepository(OrderInventory).findOne({
|
|
67
61
|
where: {
|
|
68
62
|
releaseGood,
|
|
@@ -73,6 +67,17 @@ export const addReleaseGoodProducts = {
|
|
|
73
67
|
}
|
|
74
68
|
})
|
|
75
69
|
|
|
70
|
+
if (foundInv && foundInv.lockedQty == 0) {
|
|
71
|
+
foundInv.qty += Number(existingOrderInv.releaseQty)
|
|
72
|
+
foundInv.uomValue += Number(existingOrderInv.releaseUomValue)
|
|
73
|
+
foundInv.lockedQty = Number(existingOrderInv.releaseQty)
|
|
74
|
+
foundInv.lockedUomValue = Number(existingOrderInv.releaseUomValue)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (curOrderInv.releaseQty < existingOrderInv.pickedQty) {
|
|
78
|
+
throw new Error(`${curOrderInv.inventory.palletId} has already picked ${existingOrderInv.pickedQty}`)
|
|
79
|
+
}
|
|
80
|
+
|
|
76
81
|
if (curOrderInv.releaseQty === 0) {
|
|
77
82
|
foundInv.lockedQty = Number(foundInv.lockedQty) - Number(existingOrderInv.releaseQty)
|
|
78
83
|
foundInv.lockedUomValue = Number(foundInv.lockedUomValue) - Number(existingOrderInv.releaseUomValue)
|
|
@@ -84,6 +89,7 @@ export const addReleaseGoodProducts = {
|
|
|
84
89
|
curOrderInv = {
|
|
85
90
|
...existingOrderInv,
|
|
86
91
|
releaseQty: curOrderInv.releaseQty,
|
|
92
|
+
releaseUomValue: curOrderInv.releaseUomValue,
|
|
87
93
|
lockedUomValue: curOrderInv.lockedUomValue,
|
|
88
94
|
status: ORDER_INVENTORY_STATUS.CANCELLED
|
|
89
95
|
}
|
|
@@ -103,19 +109,46 @@ export const addReleaseGoodProducts = {
|
|
|
103
109
|
await tx.getRepository(WorksheetDetail).save(existingWorksheetDetail)
|
|
104
110
|
await tx.getRepository(OrderInventory).save(curOrderInv)
|
|
105
111
|
}
|
|
112
|
+
} else if (curOrderInv.releaseQty == existingOrderInv.pickedQty) {
|
|
113
|
+
curOrderInv = {
|
|
114
|
+
...existingOrderInv,
|
|
115
|
+
releaseQty: curOrderInv.releaseQty,
|
|
116
|
+
releaseUomValue: curOrderInv.releaseUomValue,
|
|
117
|
+
lockedUomValue: curOrderInv.lockedUomValue,
|
|
118
|
+
status: ORDER_INVENTORY_STATUS.PICKED
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let existingWorksheetDetail: WorksheetDetail = await tx.getRepository(WorksheetDetail).findOne({
|
|
122
|
+
where: {
|
|
123
|
+
targetInventory: curOrderInv
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
existingWorksheetDetail = {
|
|
128
|
+
...existingWorksheetDetail,
|
|
129
|
+
status: WORKSHEET_STATUS.PICKED
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
await tx.getRepository(WorksheetDetail).save(existingWorksheetDetail)
|
|
133
|
+
await tx.getRepository(OrderInventory).save(curOrderInv)
|
|
106
134
|
} else {
|
|
107
|
-
foundInv.lockedQty = Number(curOrderInv.releaseQty)
|
|
108
|
-
foundInv.lockedUomValue = Number(curOrderInv.releaseUomValue)
|
|
109
135
|
foundInv.updater = user
|
|
136
|
+
foundInv.lockedQty =
|
|
137
|
+
foundInv.lockedQty - Number(existingOrderInv.releaseQty) + Number(curOrderInv.releaseQty)
|
|
138
|
+
foundInv.lockedUomValue =
|
|
139
|
+
foundInv.lockedUomValue - Number(existingOrderInv.releaseUomValue) + Number(curOrderInv.releaseUomValue)
|
|
110
140
|
|
|
111
141
|
await tx.getRepository(Inventory).save(foundInv)
|
|
112
142
|
|
|
113
143
|
if (existingOrderInv) {
|
|
144
|
+
const orderInvStatus = ORDER_INVENTORY_STATUS.PICKING
|
|
145
|
+
|
|
114
146
|
// if found existing OrderInventory and worksheetDetail then qty, uomValue, and status are updated
|
|
115
147
|
curOrderInv = {
|
|
116
148
|
...existingOrderInv,
|
|
117
149
|
releaseQty: curOrderInv.releaseQty,
|
|
118
|
-
releaseUomValue: curOrderInv.releaseUomValue
|
|
150
|
+
releaseUomValue: curOrderInv.releaseUomValue,
|
|
151
|
+
status: orderInvStatus
|
|
119
152
|
}
|
|
120
153
|
|
|
121
154
|
let existingWorksheetDetail: WorksheetDetail = await tx.getRepository(WorksheetDetail).findOne({
|
|
@@ -268,6 +301,15 @@ export const addReleaseGoodProducts = {
|
|
|
268
301
|
savedOrderInv.domain = domain
|
|
269
302
|
savedOrderInv.creator = user
|
|
270
303
|
savedOrderInv.updater = user
|
|
304
|
+
|
|
305
|
+
if (newOrderInv?.id) {
|
|
306
|
+
// newOrderInv will have id if it was updated from existingOrderInv
|
|
307
|
+
// this solution will remove ix_order-inventory_0 unique error
|
|
308
|
+
// ** please revise this resolver in future. looks like there's few
|
|
309
|
+
// things that can refactor
|
|
310
|
+
savedOrderInv.id = newOrderInv.id
|
|
311
|
+
}
|
|
312
|
+
|
|
271
313
|
savedOrderInv = await tx.getRepository(OrderInventory).save(savedOrderInv)
|
|
272
314
|
|
|
273
315
|
if (!existingOrderInv && pickingWorksheet) {
|
|
@@ -5,6 +5,7 @@ import * as Dashboard from './dashboard'
|
|
|
5
5
|
import * as Extra from './extra'
|
|
6
6
|
import * as OpaMenu from './opa-menu'
|
|
7
7
|
import * as Reports from './reports'
|
|
8
|
+
import * as InventoryComparison from './inventory-comparison'
|
|
8
9
|
|
|
9
10
|
export const queries = [
|
|
10
11
|
BoardSetting.Query,
|
|
@@ -12,7 +13,8 @@ export const queries = [
|
|
|
12
13
|
CustomKimeda.Query,
|
|
13
14
|
Dashboard.Query,
|
|
14
15
|
OpaMenu.Query,
|
|
15
|
-
Reports.Query
|
|
16
|
+
Reports.Query,
|
|
17
|
+
InventoryComparison.Query
|
|
16
18
|
]
|
|
17
19
|
|
|
18
20
|
export const mutations = [Extra.Mutation]
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { onhandInventories } from '@things-factory/warehouse-base'
|
|
2
|
+
import { ListParam } from '@things-factory/shell'
|
|
3
|
+
import { EntityManager } from 'typeorm'
|
|
4
|
+
import { inventoryHistorySummaryReportQuery } from '../custom/elccl/elccl-inventory-history-summary-report'
|
|
5
|
+
|
|
6
|
+
export const inventoryComparisonList = {
|
|
7
|
+
async inventoryComparisonList(_: any, params: ListParam, context: any) {
|
|
8
|
+
try {
|
|
9
|
+
const { tx }: { tx: EntityManager } = context.state
|
|
10
|
+
|
|
11
|
+
let bizplaceFilter = params.filters.find(data => data.name === 'bizplace')
|
|
12
|
+
|
|
13
|
+
if (!bizplaceFilter) {
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let toDateFilter = params.filters.find(data => data.name === 'toDate')
|
|
18
|
+
let toDateDate = new Date(toDateFilter.value)
|
|
19
|
+
let fromDate = toDateDate.setDate(toDateDate.getDate() - 1)
|
|
20
|
+
let fromDateISO = new Date(fromDate).toISOString()
|
|
21
|
+
let nonTallyFilter = params.filters.find(data => data.name === 'nonTally').value
|
|
22
|
+
let productFilter = params.filters.find(data => data.name === 'product')
|
|
23
|
+
|
|
24
|
+
params.filters.push({
|
|
25
|
+
name: 'fromDate',
|
|
26
|
+
operator: 'eq',
|
|
27
|
+
value: fromDateISO
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
params.filters.push(
|
|
31
|
+
{ name: 'status', operator: 'notin', value: ['INTRANSIT', 'TERMINATED', 'DELETED'] },
|
|
32
|
+
{ name: 'remainOnly', operator: 'eq', value: true },
|
|
33
|
+
{ name: 'unlockOnly', operator: 'eq', value: true },
|
|
34
|
+
{ name: 'created_at', operator: 'eq', value: toDateFilter.value },
|
|
35
|
+
{ name: 'timezoneOffset', operator: 'eq', value: new Date().getTimezoneOffset() },
|
|
36
|
+
{ name: 'expiration', operator: 'eq', value: false }
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
let productQueryFilter = ``
|
|
40
|
+
|
|
41
|
+
if (productFilter) {
|
|
42
|
+
let products = productFilter.value
|
|
43
|
+
.toLowerCase()
|
|
44
|
+
.split(',')
|
|
45
|
+
.map(prod => {
|
|
46
|
+
return "'%" + prod.trim().replace(/'/g, "''") + "%'"
|
|
47
|
+
})
|
|
48
|
+
.join(',')
|
|
49
|
+
|
|
50
|
+
productQueryFilter =
|
|
51
|
+
productQueryFilter +
|
|
52
|
+
`
|
|
53
|
+
${nonTallyFilter ? 'and' : 'where'} (lower(summ.product_name) like any(array[${products}])
|
|
54
|
+
or lower(summ.product_sku) like any(array[${products}]))`
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
await Promise.all([
|
|
58
|
+
inventoryHistorySummaryReportQuery(_, params, context),
|
|
59
|
+
onhandInventories(params.filters, params.pagination, params.sortings, [], context, false)
|
|
60
|
+
])
|
|
61
|
+
|
|
62
|
+
await tx.query(`
|
|
63
|
+
create temp table tmp_inv_comp on commit drop as (
|
|
64
|
+
select summ."batch_id", summ.product_id, summ.product_name, summ.product_sku, summ.packing_type, summ.closing_qty, coalesce(oh.qty, 0) as "onhand_qty" from temp_inventory_summary summ
|
|
65
|
+
left join (
|
|
66
|
+
select "batch_id" as "batch_id", product_id, sum("qty") as qty from tmp_data group by "batch_id", product_id
|
|
67
|
+
) oh on oh.batch_id = summ.batch_id and oh.product_id = summ.product_id
|
|
68
|
+
${nonTallyFilter ? 'where coalesce(oh.qty, 0) <> summ.closing_qty' : ''}
|
|
69
|
+
${productQueryFilter}
|
|
70
|
+
);
|
|
71
|
+
`)
|
|
72
|
+
|
|
73
|
+
let sumData = await tx.query(`
|
|
74
|
+
select * from tmp_inv_comp
|
|
75
|
+
offset $1 limit $2
|
|
76
|
+
`, [(params.pagination.page - 1) * params.pagination.limit, params.pagination.limit])
|
|
77
|
+
|
|
78
|
+
const totalQuery: number = await tx.query(`select count(*) from tmp_inv_comp `)
|
|
79
|
+
|
|
80
|
+
const total = parseInt(totalQuery[0].count)
|
|
81
|
+
|
|
82
|
+
const items: any[] = sumData.map(item => {
|
|
83
|
+
return {
|
|
84
|
+
productName: item.product_name,
|
|
85
|
+
productSku: item.product_sku,
|
|
86
|
+
packingType: item.packing_type,
|
|
87
|
+
closingQty: item.closing_qty,
|
|
88
|
+
remainQty: item.onhand_qty,
|
|
89
|
+
batchId: item.batch_id
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
return { items, total }
|
|
94
|
+
|
|
95
|
+
} catch (error) {
|
|
96
|
+
throw error
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { inboundOrderDetailsReport } from './inbound-order-details-report'
|
|
2
2
|
import { outboundOrderDetailsReport } from './outbound-order-details-report'
|
|
3
|
+
import { productLabelReport } from './product-label-report'
|
|
3
4
|
|
|
4
5
|
export const Query = {
|
|
5
6
|
...inboundOrderDetailsReport,
|
|
6
|
-
...outboundOrderDetailsReport
|
|
7
|
+
...outboundOrderDetailsReport,
|
|
8
|
+
...productLabelReport
|
|
7
9
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { getRepository } from 'typeorm'
|
|
2
|
+
|
|
3
|
+
import { Sequence, SEQUENCE_TYPE } from '@things-factory/id-rule-base'
|
|
4
|
+
import { Domain, ListParam } from '@things-factory/shell'
|
|
5
|
+
|
|
6
|
+
export const productLabelReport = {
|
|
7
|
+
async productLabelReport(_: any, params: ListParam, context: any) {
|
|
8
|
+
try {
|
|
9
|
+
const { domain }: { domain: Domain } = context.state
|
|
10
|
+
// const { domain }: { domain: Domain } = context.state
|
|
11
|
+
const bizplaceId = params.filters.find(data => data.name === 'bizplace').value
|
|
12
|
+
const type = params.filters.find(data => data.name === 'type')?.value
|
|
13
|
+
const fromDate = params.filters.find(data => data.name === 'fromDate').value
|
|
14
|
+
const toDate = params.filters.find(data => data.name === 'toDate').value
|
|
15
|
+
|
|
16
|
+
if (!bizplaceId || !fromDate || !toDate) throw new Error('Invalid input')
|
|
17
|
+
|
|
18
|
+
const items = await getRepository(Sequence).query(`
|
|
19
|
+
SELECT "date", "type", "count", "bizplace_id" FROM (
|
|
20
|
+
SELECT
|
|
21
|
+
"sq"."pattern"::JSONB ->> 'type' AS "type",
|
|
22
|
+
"sq"."pattern"::JSONB ->> 'date' AS "date",
|
|
23
|
+
"sq"."pattern"::JSONB ->> 'bizplaceId' AS "bizplace_id",
|
|
24
|
+
"sq"."seq" AS "count"
|
|
25
|
+
FROM "sequences" "sq" WHERE "sq"."type" = '${SEQUENCE_TYPE.PRODUCT_LABEL_COUNTER}'
|
|
26
|
+
AND "sq"."domain_id" = '${domain.id}'
|
|
27
|
+
) AS foo
|
|
28
|
+
WHERE "bizplace_id" = '${bizplaceId}'
|
|
29
|
+
${type ? `AND "type" ilike '%${type}%'` : ''}
|
|
30
|
+
AND "date"::date BETWEEN '${fromDate}' AND '${toDate}'
|
|
31
|
+
`)
|
|
32
|
+
|
|
33
|
+
// @farishelmi any usage for this function? If no please remove.
|
|
34
|
+
/*
|
|
35
|
+
need to transform into queryBuilder form
|
|
36
|
+
const qb: SelectQueryBuilder<Sequence> = tx
|
|
37
|
+
.getRepository(Sequence)
|
|
38
|
+
.createQueryBuilder('sq')
|
|
39
|
+
.select(`"sq"."pattern"::JSONB ->> 'type'`, 'type')
|
|
40
|
+
.addSelect(`"sq"."pattern"::JSONB ->> 'date'`, 'date')
|
|
41
|
+
.addSelect(`"sq"."pattern"::JSONB ->> 'bizplaceId'`, 'bizplace_id')
|
|
42
|
+
.addSelect(`"sq"."seq"`, 'count')
|
|
43
|
+
.where('"sq"."type" = :sequenceType', { sequenceType: SEQUENCE_TYPE.PRODUCT_LABEL_COUNTER })
|
|
44
|
+
.andWhere(`"sq"."pattern"::JSONB ->> 'bizplaceId' = :bizplaceId`, { bizplaceId })
|
|
45
|
+
.andWhere(`"sq"."domain_id" = :domainId`, { domainId: domain.id })
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
items,
|
|
50
|
+
total: 0
|
|
51
|
+
}
|
|
52
|
+
} catch (error) {
|
|
53
|
+
throw error
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -5,6 +5,7 @@ import * as Dashboard from './dashboard'
|
|
|
5
5
|
import * as Extra from './extra'
|
|
6
6
|
import * as OpaMenu from './opa-menu'
|
|
7
7
|
import * as Reports from './reports'
|
|
8
|
+
import * as InventoryComparison from './inventory-comparison'
|
|
8
9
|
|
|
9
10
|
export const queries = [
|
|
10
11
|
BoardSetting.Query,
|
|
@@ -12,7 +13,8 @@ export const queries = [
|
|
|
12
13
|
CustomKimeda.Query,
|
|
13
14
|
Dashboard.Query,
|
|
14
15
|
OpaMenu.Query,
|
|
15
|
-
Reports.Query
|
|
16
|
+
Reports.Query,
|
|
17
|
+
InventoryComparison.Query
|
|
16
18
|
]
|
|
17
19
|
|
|
18
20
|
export const mutations = [Extra.Mutation]
|
|
@@ -22,5 +24,6 @@ export const types = [
|
|
|
22
24
|
...CustomElccl.Types,
|
|
23
25
|
...Dashboard.Types,
|
|
24
26
|
...OpaMenu.Types,
|
|
25
|
-
...Reports.Types
|
|
27
|
+
...Reports.Types,
|
|
28
|
+
...InventoryComparison.Types
|
|
26
29
|
]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { InventoryComparison } from "./inventory-comparison";
|
|
2
|
+
import { InventoryComparisonList } from "./inventory-comparison-list";
|
|
3
|
+
|
|
4
|
+
export const Query = `
|
|
5
|
+
inventoryComparisonList(filters: [Filter], pagination: Pagination, sortings: [Sorting]): InventoryComparisonList @privilege(category: "inventory_comparison", privilege: "query") @transaction
|
|
6
|
+
`
|
|
7
|
+
|
|
8
|
+
export const Types = [
|
|
9
|
+
InventoryComparison,
|
|
10
|
+
InventoryComparisonList
|
|
11
|
+
]
|