@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.
Files changed (84) hide show
  1. package/client/pages/components/select-product-popup.js +5 -1
  2. package/client/pages/constants/order.js +10 -0
  3. package/client/pages/inbound/putaway-product.js +162 -139
  4. package/client/pages/inventory-check/inspecting-product.js +146 -80
  5. package/client/pages/manifest/create-loading-manifest.js +314 -0
  6. package/client/pages/manifest/dispatcher-verification-popup.js +86 -0
  7. package/client/pages/manifest/loading-manifest-detail.js +345 -0
  8. package/client/pages/manifest/loading-manifest-list.js +305 -0
  9. package/client/pages/order/arrival-notice/create-arrival-notice.js +8 -1
  10. package/client/pages/order/goods-received-note/received-note-list.js +138 -6
  11. package/client/pages/order/release-order/b2b/b2b-order-list.js +45 -5
  12. package/client/pages/order/release-order/b2b/b2b-order-requests.js +45 -5
  13. package/client/pages/order/release-order/b2c/b2c-order-requests.js +181 -21
  14. package/client/pages/order/release-order/bulk-print-packing-list.js +23 -0
  15. package/client/pages/order/release-order/create-release-order.js +25 -4
  16. package/client/pages/order/release-order/receive-release-order-request.js +27 -24
  17. package/client/pages/order/release-order/release-extra-product-popup.js +189 -56
  18. package/client/pages/order/release-order/release-order-detail.js +292 -71
  19. package/client/pages/order/reverse-kitting-order/reverse-kitting-order-detail.js +115 -50
  20. package/client/pages/order/reverse-kitting-order/reverse-kitting-order-list.js +1 -6
  21. package/client/pages/order/reverse-kitting-order/reverse-kitting-pallet-label-popup.js +239 -0
  22. package/client/pages/order/transport-order/delivery-order-list.js +99 -59
  23. package/client/pages/outbound/loading-product.js +4 -1
  24. package/client/pages/outbound/merged-outbound-worksheet.js +39 -1
  25. package/client/pages/outbound/packing-product.js +4 -1
  26. package/client/pages/outbound/packing-worksheet-list.js +39 -1
  27. package/client/pages/outbound/picking-product.js +622 -290
  28. package/client/pages/outbound/serial-number-popup.js +280 -0
  29. package/client/pages/outbound/worksheet-picking.js +28 -2
  30. package/client/pages/report/product-label-report.js +401 -0
  31. package/client/pages/support/inventory-comparison.js +296 -0
  32. package/client/pages/vas/print-product-label.js +298 -132
  33. package/client/pages/vas/reverse-kitting/execute-reverse-kitting.js +30 -12
  34. package/client/pages/vas/reverse-kitting/popup-combination-sets.js +75 -5
  35. package/client/pages/vas/reverse-kitting/popup-reverse-kitting-template.js +113 -18
  36. package/client/route.js +23 -0
  37. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.js +64 -54
  38. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.js.map +1 -1
  39. package/dist-server/graphql/resolvers/extra/add-release-good-products.js +34 -9
  40. package/dist-server/graphql/resolvers/extra/add-release-good-products.js.map +1 -1
  41. package/dist-server/graphql/resolvers/index.js +3 -1
  42. package/dist-server/graphql/resolvers/index.js.map +1 -1
  43. package/dist-server/graphql/resolvers/inventory-comparison/index.js +6 -0
  44. package/dist-server/graphql/resolvers/inventory-comparison/index.js.map +1 -0
  45. package/dist-server/graphql/resolvers/inventory-comparison/inventory-comparison-list.js +78 -0
  46. package/dist-server/graphql/resolvers/inventory-comparison/inventory-comparison-list.js.map +1 -0
  47. package/dist-server/graphql/resolvers/reports/index.js +2 -1
  48. package/dist-server/graphql/resolvers/reports/index.js.map +1 -1
  49. package/dist-server/graphql/resolvers/reports/product-label-report.js +56 -0
  50. package/dist-server/graphql/resolvers/reports/product-label-report.js.map +1 -0
  51. package/dist-server/graphql/types/index.js +5 -2
  52. package/dist-server/graphql/types/index.js.map +1 -1
  53. package/dist-server/graphql/types/inventory-comparison/index.js +13 -0
  54. package/dist-server/graphql/types/inventory-comparison/index.js.map +1 -0
  55. package/dist-server/graphql/types/inventory-comparison/inventory-comparison-list.js +14 -0
  56. package/dist-server/graphql/types/inventory-comparison/inventory-comparison-list.js.map +1 -0
  57. package/dist-server/graphql/types/inventory-comparison/inventory-comparison.js +18 -0
  58. package/dist-server/graphql/types/inventory-comparison/inventory-comparison.js.map +1 -0
  59. package/dist-server/graphql/types/reports/index.js +6 -1
  60. package/dist-server/graphql/types/reports/index.js.map +1 -1
  61. package/dist-server/graphql/types/reports/product-label-report-list.js +14 -0
  62. package/dist-server/graphql/types/reports/product-label-report-list.js.map +1 -0
  63. package/dist-server/graphql/types/reports/product-label-report.js +16 -0
  64. package/dist-server/graphql/types/reports/product-label-report.js.map +1 -0
  65. package/package.json +65 -65
  66. package/server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.ts +75 -65
  67. package/server/graphql/resolvers/extra/add-release-good-products.ts +57 -15
  68. package/server/graphql/resolvers/index.ts +3 -1
  69. package/server/graphql/resolvers/inventory-comparison/index.ts +5 -0
  70. package/server/graphql/resolvers/inventory-comparison/inventory-comparison-list.ts +99 -0
  71. package/server/graphql/resolvers/reports/index.ts +3 -1
  72. package/server/graphql/resolvers/reports/product-label-report.ts +56 -0
  73. package/server/graphql/types/index.ts +5 -2
  74. package/server/graphql/types/inventory-comparison/index.ts +11 -0
  75. package/server/graphql/types/inventory-comparison/inventory-comparison-list.ts +8 -0
  76. package/server/graphql/types/inventory-comparison/inventory-comparison.ts +12 -0
  77. package/server/graphql/types/reports/index.ts +6 -1
  78. package/server/graphql/types/reports/product-label-report-list.ts +8 -0
  79. package/server/graphql/types/reports/product-label-report.ts +10 -0
  80. package/things-factory.config.js +24 -0
  81. package/translations/en.json +64 -12
  82. package/translations/ko.json +50 -1
  83. package/translations/ms.json +51 -1
  84. 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.2",
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.0",
46
- "@things-factory/attachment-ui": "^3.7.0",
47
- "@things-factory/auth-ui": "^3.7.0",
48
- "@things-factory/barcode-ui": "^3.7.2",
49
- "@things-factory/biz-ui": "^3.7.0",
50
- "@things-factory/board-service": "^3.7.0",
51
- "@things-factory/board-ui": "^3.7.0",
52
- "@things-factory/code-ui": "^3.7.0",
53
- "@things-factory/context-ui": "^3.7.0",
54
- "@things-factory/export-ui": "^3.7.0",
55
- "@things-factory/export-ui-csv": "^3.7.0",
56
- "@things-factory/export-ui-excel": "^3.7.0",
57
- "@things-factory/fav-base": "^3.7.0",
58
- "@things-factory/form-ui": "^3.7.0",
59
- "@things-factory/grist-ui": "^3.7.0",
60
- "@things-factory/help": "^3.7.0",
61
- "@things-factory/i18n-ui": "^3.7.0",
62
- "@things-factory/id-rule-base": "^3.7.0",
63
- "@things-factory/import-ui": "^3.7.0",
64
- "@things-factory/import-ui-excel": "^3.7.0",
65
- "@things-factory/menu-ui": "^3.7.0",
66
- "@things-factory/more-ui": "^3.7.0",
67
- "@things-factory/notification": "^3.7.0",
68
- "@things-factory/pdf": "^3.7.0",
69
- "@things-factory/print-proxy-service": "^3.7.0",
70
- "@things-factory/print-service": "^3.7.0",
71
- "@things-factory/print-ui": "^3.7.0",
72
- "@things-factory/product-base": "^3.7.0",
73
- "@things-factory/resource-ui": "^3.7.0",
74
- "@things-factory/sales-ui": "^3.7.2",
75
- "@things-factory/scene-chartjs": "^3.7.0",
76
- "@things-factory/scene-clock": "^3.7.0",
77
- "@things-factory/scene-clone": "^3.7.0",
78
- "@things-factory/scene-compass": "^3.7.0",
79
- "@things-factory/scene-data-transform": "^3.7.0",
80
- "@things-factory/scene-excel": "^3.7.0",
81
- "@things-factory/scene-firebase": "^3.7.0",
82
- "@things-factory/scene-form": "^3.7.0",
83
- "@things-factory/scene-gauge": "^3.7.0",
84
- "@things-factory/scene-google-map": "^3.7.0",
85
- "@things-factory/scene-graphql": "^3.7.0",
86
- "@things-factory/scene-half-roundrect": "^3.7.0",
87
- "@things-factory/scene-indoor-map": "^3.7.0",
88
- "@things-factory/scene-label": "^3.7.2",
89
- "@things-factory/scene-legend": "^3.7.0",
90
- "@things-factory/scene-marker": "^3.7.0",
91
- "@things-factory/scene-mqtt": "^3.7.0",
92
- "@things-factory/scene-news-ticker": "^3.7.0",
93
- "@things-factory/scene-progressbar": "^3.7.0",
94
- "@things-factory/scene-random": "^3.7.0",
95
- "@things-factory/scene-restful": "^3.7.0",
96
- "@things-factory/scene-switch": "^3.7.0",
97
- "@things-factory/scene-tab": "^3.7.0",
98
- "@things-factory/scene-table": "^3.7.0",
99
- "@things-factory/scene-visualizer": "^3.7.0",
100
- "@things-factory/scene-wheel-sorter": "^3.7.0",
101
- "@things-factory/setting-ui": "^3.7.0",
102
- "@things-factory/system-ui": "^3.7.0",
103
- "@things-factory/transport-base": "^3.7.0",
104
- "@things-factory/tutorial-ui": "^3.7.0",
105
- "@things-factory/warehouse-base": "^3.7.2",
106
- "@things-factory/worksheet-base": "^3.7.2"
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.0"
109
+ "@things-factory/builder": "^3.7.5"
110
110
  },
111
- "gitHead": "b82cb916c52c767d69db36d8ee28ed3fdbf06f23"
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
- let balanceOnlyFilter = params.filters.find(data => data.name === 'balanceOnly')
11
+ await inventoryHistorySummaryReportQuery(_, params, context)
12
12
 
13
- let bizplaceFilter = params.filters.find(data => data.name === 'bizplace')
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 temp_elccl_inventory_summary ORDER BY initial_date OFFSET $1 LIMIT $2
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, ORDER_INVENTORY_STATUS, ReleaseGood } from '@things-factory/sales-base'
6
+ import { ORDER_INVENTORY_STATUS, OrderInventory, OrderNoGenerator, ReleaseGood } from '@things-factory/sales-base'
5
7
  import { Domain } from '@things-factory/shell'
6
- import { Inventory, InventoryHistory, INVENTORY_TRANSACTION_TYPE } from '@things-factory/warehouse-base'
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,5 @@
1
+ import { inventoryComparisonList } from './inventory-comparison-list'
2
+
3
+ export const Query = {
4
+ ...inventoryComparisonList
5
+ }
@@ -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
+ ]