@things-factory/warehouse-base 4.3.671 → 4.3.673

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 (191) hide show
  1. package/dist-server/constants/adjustment-code.js +13 -0
  2. package/dist-server/constants/adjustment-code.js.map +1 -0
  3. package/dist-server/constants/index.js +23 -0
  4. package/dist-server/constants/index.js.map +1 -0
  5. package/dist-server/constants/inventory.js +74 -0
  6. package/dist-server/constants/inventory.js.map +1 -0
  7. package/dist-server/constants/location.js +19 -0
  8. package/dist-server/constants/location.js.map +1 -0
  9. package/dist-server/constants/pallet.js +13 -0
  10. package/dist-server/constants/pallet.js.map +1 -0
  11. package/dist-server/constants/rule-type.js +8 -0
  12. package/dist-server/constants/rule-type.js.map +1 -0
  13. package/dist-server/constants/tote.js +9 -0
  14. package/dist-server/constants/tote.js.map +1 -0
  15. package/dist-server/controllers/ecommerce/ecommerce-controller.js +125 -0
  16. package/dist-server/controllers/ecommerce/ecommerce-controller.js.map +1 -0
  17. package/dist-server/controllers/ecommerce/index.js +22 -0
  18. package/dist-server/controllers/ecommerce/index.js.map +1 -0
  19. package/dist-server/controllers/ecommerce/pos-controller.js +65 -0
  20. package/dist-server/controllers/ecommerce/pos-controller.js.map +1 -0
  21. package/dist-server/controllers/ecommerce/powrup-controller.js +87 -0
  22. package/dist-server/controllers/ecommerce/powrup-controller.js.map +1 -0
  23. package/dist-server/controllers/ecommerce/sellercraft-controller.js +85 -0
  24. package/dist-server/controllers/ecommerce/sellercraft-controller.js.map +1 -0
  25. package/dist-server/controllers/ecommerce/webspert-controller.js +131 -0
  26. package/dist-server/controllers/ecommerce/webspert-controller.js.map +1 -0
  27. package/dist-server/controllers/index.js +19 -0
  28. package/dist-server/controllers/index.js.map +1 -0
  29. package/dist-server/controllers/warehouse-controller.js +143 -0
  30. package/dist-server/controllers/warehouse-controller.js.map +1 -0
  31. package/dist-server/index.js +35 -0
  32. package/dist-server/index.js.map +1 -0
  33. package/dist-server/middlewares/index.js +1 -0
  34. package/dist-server/middlewares/index.js.map +1 -0
  35. package/dist-server/migrations/index.js +12 -0
  36. package/dist-server/migrations/index.js.map +1 -0
  37. package/dist-server/service/index.js +96 -0
  38. package/dist-server/service/index.js.map +1 -0
  39. package/dist-server/service/inventory/index.js +9 -0
  40. package/dist-server/service/inventory/index.js.map +1 -0
  41. package/dist-server/service/inventory/inventory-mutation.js +414 -0
  42. package/dist-server/service/inventory/inventory-mutation.js.map +1 -0
  43. package/dist-server/service/inventory/inventory-query.js +1211 -0
  44. package/dist-server/service/inventory/inventory-query.js.map +1 -0
  45. package/dist-server/service/inventory/inventory-types.js +478 -0
  46. package/dist-server/service/inventory/inventory-types.js.map +1 -0
  47. package/dist-server/service/inventory/inventory.js +569 -0
  48. package/dist-server/service/inventory/inventory.js.map +1 -0
  49. package/dist-server/service/inventory-change/index.js +9 -0
  50. package/dist-server/service/inventory-change/index.js.map +1 -0
  51. package/dist-server/service/inventory-change/inventory-change-mutation.js +1188 -0
  52. package/dist-server/service/inventory-change/inventory-change-mutation.js.map +1 -0
  53. package/dist-server/service/inventory-change/inventory-change-query.js +150 -0
  54. package/dist-server/service/inventory-change/inventory-change-query.js.map +1 -0
  55. package/dist-server/service/inventory-change/inventory-change-types.js +73 -0
  56. package/dist-server/service/inventory-change/inventory-change-types.js.map +1 -0
  57. package/dist-server/service/inventory-change/inventory-change.js +225 -0
  58. package/dist-server/service/inventory-change/inventory-change.js.map +1 -0
  59. package/dist-server/service/inventory-history/index.js +9 -0
  60. package/dist-server/service/inventory-history/index.js.map +1 -0
  61. package/dist-server/service/inventory-history/inventory-history-mutation.js +121 -0
  62. package/dist-server/service/inventory-history/inventory-history-mutation.js.map +1 -0
  63. package/dist-server/service/inventory-history/inventory-history-query.js +1694 -0
  64. package/dist-server/service/inventory-history/inventory-history-query.js.map +1 -0
  65. package/dist-server/service/inventory-history/inventory-history-types.js +626 -0
  66. package/dist-server/service/inventory-history/inventory-history-types.js.map +1 -0
  67. package/dist-server/service/inventory-history/inventory-history.js +238 -0
  68. package/dist-server/service/inventory-history/inventory-history.js.map +1 -0
  69. package/dist-server/service/inventory-item/index.js +9 -0
  70. package/dist-server/service/inventory-item/index.js.map +1 -0
  71. package/dist-server/service/inventory-item/inventory-item-mutation.js +274 -0
  72. package/dist-server/service/inventory-item/inventory-item-mutation.js.map +1 -0
  73. package/dist-server/service/inventory-item/inventory-item-query.js +265 -0
  74. package/dist-server/service/inventory-item/inventory-item-query.js.map +1 -0
  75. package/dist-server/service/inventory-item/inventory-item-type.js +127 -0
  76. package/dist-server/service/inventory-item/inventory-item-type.js.map +1 -0
  77. package/dist-server/service/inventory-item/inventory-item.js +146 -0
  78. package/dist-server/service/inventory-item/inventory-item.js.map +1 -0
  79. package/dist-server/service/inventory-item-change/index.js +9 -0
  80. package/dist-server/service/inventory-item-change/index.js.map +1 -0
  81. package/dist-server/service/inventory-item-change/inventory-item-change-mutation.js +121 -0
  82. package/dist-server/service/inventory-item-change/inventory-item-change-mutation.js.map +1 -0
  83. package/dist-server/service/inventory-item-change/inventory-item-change-query.js +87 -0
  84. package/dist-server/service/inventory-item-change/inventory-item-change-query.js.map +1 -0
  85. package/dist-server/service/inventory-item-change/inventory-item-change-type.js +107 -0
  86. package/dist-server/service/inventory-item-change/inventory-item-change-type.js.map +1 -0
  87. package/dist-server/service/inventory-item-change/inventory-item-change.js +110 -0
  88. package/dist-server/service/inventory-item-change/inventory-item-change.js.map +1 -0
  89. package/dist-server/service/inventory-product/index.js +9 -0
  90. package/dist-server/service/inventory-product/index.js.map +1 -0
  91. package/dist-server/service/inventory-product/inventory-product-mutation.js +120 -0
  92. package/dist-server/service/inventory-product/inventory-product-mutation.js.map +1 -0
  93. package/dist-server/service/inventory-product/inventory-product-query.js +87 -0
  94. package/dist-server/service/inventory-product/inventory-product-query.js.map +1 -0
  95. package/dist-server/service/inventory-product/inventory-product-type.js +95 -0
  96. package/dist-server/service/inventory-product/inventory-product-type.js.map +1 -0
  97. package/dist-server/service/inventory-product/inventory-product.js +112 -0
  98. package/dist-server/service/inventory-product/inventory-product.js.map +1 -0
  99. package/dist-server/service/location/index.js +9 -0
  100. package/dist-server/service/location/index.js.map +1 -0
  101. package/dist-server/service/location/location-mutation.js +279 -0
  102. package/dist-server/service/location/location-mutation.js.map +1 -0
  103. package/dist-server/service/location/location-query.js +321 -0
  104. package/dist-server/service/location/location-query.js.map +1 -0
  105. package/dist-server/service/location/location-types.js +296 -0
  106. package/dist-server/service/location/location-types.js.map +1 -0
  107. package/dist-server/service/location/location.js +146 -0
  108. package/dist-server/service/location/location.js.map +1 -0
  109. package/dist-server/service/movement/index.js +9 -0
  110. package/dist-server/service/movement/index.js.map +1 -0
  111. package/dist-server/service/movement/movement-mutation.js +80 -0
  112. package/dist-server/service/movement/movement-mutation.js.map +1 -0
  113. package/dist-server/service/movement/movement-query.js +286 -0
  114. package/dist-server/service/movement/movement-query.js.map +1 -0
  115. package/dist-server/service/movement/movement-types.js +117 -0
  116. package/dist-server/service/movement/movement-types.js.map +1 -0
  117. package/dist-server/service/movement/movement.js +101 -0
  118. package/dist-server/service/movement/movement.js.map +1 -0
  119. package/dist-server/service/pallet/index.js +9 -0
  120. package/dist-server/service/pallet/index.js.map +1 -0
  121. package/dist-server/service/pallet/pallet-mutation.js +194 -0
  122. package/dist-server/service/pallet/pallet-mutation.js.map +1 -0
  123. package/dist-server/service/pallet/pallet-query.js +164 -0
  124. package/dist-server/service/pallet/pallet-query.js.map +1 -0
  125. package/dist-server/service/pallet/pallet-types.js +109 -0
  126. package/dist-server/service/pallet/pallet-types.js.map +1 -0
  127. package/dist-server/service/pallet/pallet.js +112 -0
  128. package/dist-server/service/pallet/pallet.js.map +1 -0
  129. package/dist-server/service/pallet-count/index.js +9 -0
  130. package/dist-server/service/pallet-count/index.js.map +1 -0
  131. package/dist-server/service/pallet-count/pallet-count-mutation.js +153 -0
  132. package/dist-server/service/pallet-count/pallet-count-mutation.js.map +1 -0
  133. package/dist-server/service/pallet-count/pallet-count-query.js +86 -0
  134. package/dist-server/service/pallet-count/pallet-count-query.js.map +1 -0
  135. package/dist-server/service/pallet-count/pallet-count-types.js +65 -0
  136. package/dist-server/service/pallet-count/pallet-count-types.js.map +1 -0
  137. package/dist-server/service/pallet-count/pallet-count.js +89 -0
  138. package/dist-server/service/pallet-count/pallet-count.js.map +1 -0
  139. package/dist-server/service/pallet-history/index.js +9 -0
  140. package/dist-server/service/pallet-history/index.js.map +1 -0
  141. package/dist-server/service/pallet-history/pallet-history-mutation.js +120 -0
  142. package/dist-server/service/pallet-history/pallet-history-mutation.js.map +1 -0
  143. package/dist-server/service/pallet-history/pallet-history-query.js +87 -0
  144. package/dist-server/service/pallet-history/pallet-history-query.js.map +1 -0
  145. package/dist-server/service/pallet-history/pallet-history-types.js +65 -0
  146. package/dist-server/service/pallet-history/pallet-history-types.js.map +1 -0
  147. package/dist-server/service/pallet-history/pallet-history.js +107 -0
  148. package/dist-server/service/pallet-history/pallet-history.js.map +1 -0
  149. package/dist-server/service/product-detail-stock/index.js +9 -0
  150. package/dist-server/service/product-detail-stock/index.js.map +1 -0
  151. package/dist-server/service/product-detail-stock/product-detail-stock-mutation.js +120 -0
  152. package/dist-server/service/product-detail-stock/product-detail-stock-mutation.js.map +1 -0
  153. package/dist-server/service/product-detail-stock/product-detail-stock-query.js +66 -0
  154. package/dist-server/service/product-detail-stock/product-detail-stock-query.js.map +1 -0
  155. package/dist-server/service/product-detail-stock/product-detail-stock-types.js +57 -0
  156. package/dist-server/service/product-detail-stock/product-detail-stock-types.js.map +1 -0
  157. package/dist-server/service/product-detail-stock/product-detail-stock.js +90 -0
  158. package/dist-server/service/product-detail-stock/product-detail-stock.js.map +1 -0
  159. package/dist-server/service/reduced-inventory-history/index.js +6 -0
  160. package/dist-server/service/reduced-inventory-history/index.js.map +1 -0
  161. package/dist-server/service/reduced-inventory-history/reduced-inventory-history.js +133 -0
  162. package/dist-server/service/reduced-inventory-history/reduced-inventory-history.js.map +1 -0
  163. package/dist-server/service/tote/index.js +9 -0
  164. package/dist-server/service/tote/index.js.map +1 -0
  165. package/dist-server/service/tote/tote-mutation.js +192 -0
  166. package/dist-server/service/tote/tote-mutation.js.map +1 -0
  167. package/dist-server/service/tote/tote-query.js +162 -0
  168. package/dist-server/service/tote/tote-query.js.map +1 -0
  169. package/dist-server/service/tote/tote-types.js +75 -0
  170. package/dist-server/service/tote/tote-types.js.map +1 -0
  171. package/dist-server/service/tote/tote.js +98 -0
  172. package/dist-server/service/tote/tote.js.map +1 -0
  173. package/dist-server/service/warehouse/index.js +9 -0
  174. package/dist-server/service/warehouse/index.js.map +1 -0
  175. package/dist-server/service/warehouse/warehouse-mutation.js +148 -0
  176. package/dist-server/service/warehouse/warehouse-mutation.js.map +1 -0
  177. package/dist-server/service/warehouse/warehouse-query.js +91 -0
  178. package/dist-server/service/warehouse/warehouse-query.js.map +1 -0
  179. package/dist-server/service/warehouse/warehouse-types.js +82 -0
  180. package/dist-server/service/warehouse/warehouse-types.js.map +1 -0
  181. package/dist-server/service/warehouse/warehouse.js +114 -0
  182. package/dist-server/service/warehouse/warehouse.js.map +1 -0
  183. package/dist-server/utils/datetime-util.js +61 -0
  184. package/dist-server/utils/datetime-util.js.map +1 -0
  185. package/dist-server/utils/index.js +20 -0
  186. package/dist-server/utils/index.js.map +1 -0
  187. package/dist-server/utils/inventory-no-generator.js +17 -0
  188. package/dist-server/utils/inventory-no-generator.js.map +1 -0
  189. package/dist-server/utils/inventory-util.js +413 -0
  190. package/dist-server/utils/inventory-util.js.map +1 -0
  191. package/package.json +10 -10
@@ -0,0 +1,1694 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.InventoryHistoryQuery = void 0;
17
+ const type_graphql_1 = require("type-graphql");
18
+ const typeorm_1 = require("typeorm");
19
+ const auth_base_1 = require("@things-factory/auth-base");
20
+ const biz_base_1 = require("@things-factory/biz-base");
21
+ const product_base_1 = require("@things-factory/product-base");
22
+ const shell_1 = require("@things-factory/shell");
23
+ const __1 = require("../");
24
+ const inventory_types_1 = require("../inventory/inventory-types");
25
+ const location_1 = require("../location/location");
26
+ const warehouse_1 = require("../warehouse/warehouse");
27
+ const inventory_history_1 = require("./inventory-history");
28
+ const inventory_history_types_1 = require("./inventory-history-types");
29
+ let InventoryHistoryQuery = class InventoryHistoryQuery {
30
+ async inventoryHistories(params, context) {
31
+ const { domain, user } = context.state;
32
+ params.filters.push({ name: 'domain', operator: 'eq', value: domain.id });
33
+ if (!params.filters.find((filter) => filter.name === 'bizplace')) {
34
+ params.filters.push({
35
+ name: 'bizplace',
36
+ operator: 'in',
37
+ value: await (0, biz_base_1.getPermittedBizplaceIds)(domain, user)
38
+ });
39
+ }
40
+ const convertedParams = (0, shell_1.convertListParams)(params);
41
+ let [items, total] = await (0, typeorm_1.getRepository)(inventory_history_1.InventoryHistory).findAndCount(Object.assign(Object.assign({}, convertedParams), { relations: ['domain', 'bizplace', 'product', 'location', 'warehouse', 'creator', 'updater'], order: {
42
+ palletId: 'DESC',
43
+ createdAt: 'ASC'
44
+ } }));
45
+ items = (await Promise.all(items.map(async (item) => {
46
+ switch (item.transactionType) {
47
+ case 'UNLOADING':
48
+ item.description = 'Inbound';
49
+ break;
50
+ case 'UNDO_UNLOADING':
51
+ item.description = 'Undo Unloading';
52
+ item.orderRefNo = '';
53
+ break;
54
+ case 'LOADING':
55
+ item.description = 'Loading';
56
+ break;
57
+ case 'UNDO_LOADING':
58
+ item.description = 'Undo Loading';
59
+ break;
60
+ default:
61
+ item.description = String(item.transactionType);
62
+ break;
63
+ }
64
+ item.description = item.description.toUpperCase();
65
+ return Object.assign(Object.assign({}, item), { orderRefNo: item.orderRefNo, orderNo: item.orderNo, qty: item.qty, openingQty: item.openingQty });
66
+ })));
67
+ return { items, total };
68
+ }
69
+ async inventoryHistory(name, context) {
70
+ const { domain } = context.state;
71
+ return await (0, typeorm_1.getRepository)(inventory_history_1.InventoryHistory).findOne({
72
+ where: { domain: domain, name, relations: ['domain', 'creator', 'updater'] }
73
+ });
74
+ }
75
+ async bizplaceInventoryHistories(context, inventoryHistory, filters, pagination, sortings) {
76
+ const { domain, user, tx } = context.state;
77
+ const ownerBizplace = await (0, biz_base_1.getMyBizplace)(domain, user);
78
+ const customerBizplace = await tx.getRepository(biz_base_1.Bizplace).findOne(inventoryHistory.bizplace.id);
79
+ const productFilters = filters.find(x => x.name == 'product_info');
80
+ filters = filters.filter(x => x.name != 'product_info');
81
+ const fromDate = new Date(inventoryHistory.fromDate);
82
+ const toDate = new Date(inventoryHistory.toDate);
83
+ const convertedParams = (0, shell_1.convertListParams)({ filters, pagination, sortings });
84
+ let where = { domain: domain };
85
+ if (productFilters) {
86
+ let productFilterValue = `%${productFilters.value.toLowerCase()}%`;
87
+ const productQb = (0, typeorm_1.getRepository)(product_base_1.Product).createQueryBuilder('prd');
88
+ productQb.where(new typeorm_1.Brackets(qb => {
89
+ qb.where('Lower(prd.sku) LIKE :productInfo', { productInfo: productFilterValue })
90
+ .orWhere('Lower(prd.name) LIKE :productInfo', { productInfo: productFilterValue })
91
+ .orWhere('Lower(prd.description) LIKE :productInfo', { productInfo: productFilterValue })
92
+ .orWhere('Lower(prd.brand) LIKE :productInfo', { productInfo: productFilterValue });
93
+ }));
94
+ const _products = await productQb.getMany();
95
+ where['product'] = (0, typeorm_1.In)(_products.map((product) => product.id));
96
+ }
97
+ if (inventoryHistory && inventoryHistory.warehouseName) {
98
+ const _warehouses = await tx.getRepository(warehouse_1.Warehouse).find({
99
+ domain: domain,
100
+ name: (0, typeorm_1.Raw)(alias => `LOWER(${alias}) LIKE '${inventoryHistory.warehouseName.toLowerCase()}'`)
101
+ });
102
+ where['warehouse'] = (0, typeorm_1.In)(_warehouses.map((warehouse) => warehouse.id));
103
+ }
104
+ if (inventoryHistory && inventoryHistory.locationName) {
105
+ const _locations = await tx.getRepository(location_1.Location).find({
106
+ where: {
107
+ domain: domain,
108
+ name: (0, typeorm_1.Raw)(alias => `LOWER(${alias}) LIKE '${inventoryHistory.locationName.toLowerCase()}'`)
109
+ }
110
+ });
111
+ where['location'] = (0, typeorm_1.In)(_locations.map((location) => location.id));
112
+ }
113
+ where['createdAt'] = (0, typeorm_1.Between)(fromDate, toDate);
114
+ convertedParams.where = Object.assign(Object.assign(Object.assign({}, convertedParams.where), where), { bizplace: customerBizplace });
115
+ const [items, total] = await tx.getRepository(inventory_history_1.InventoryHistory).findAndCount(Object.assign(Object.assign({}, convertedParams), { relations: ['domain', 'product', 'warehouse', 'location', 'bizplace', 'updater'], order: {
116
+ palletId: 'ASC',
117
+ seq: 'ASC'
118
+ } }));
119
+ return { items, total };
120
+ }
121
+ async inventoryHistoryReport(params, context) {
122
+ try {
123
+ const { domain, tx } = context.state;
124
+ let bizplaceFilter = { name: '', operator: '', value: '' };
125
+ let userFilter = params.filters.find(data => data.name === 'user');
126
+ let fromDate = params.filters.find(data => data.name === 'fromDate');
127
+ let toDate = params.filters.find(data => data.name === 'toDate');
128
+ let batchNo = params.filters.find(data => data.name === 'batchNo');
129
+ let product = params.filters.find(data => data.name === 'product');
130
+ let byPallet = params.filters.find(data => data.name === 'byPallet');
131
+ let productDesc = params.filters.find(data => data.name === 'productDescription');
132
+ let hasTransactionOrBalanceFilter = params.filters.find(data => data.name === 'hasTransactionOrBalance');
133
+ let tzoffset = params.filters.find(data => data.name === 'tzoffset').value + ' seconds';
134
+ if (userFilter) {
135
+ const user = await tx.getRepository(auth_base_1.User).findOne({
136
+ where: { id: userFilter.value },
137
+ relations: ['bizplaces']
138
+ });
139
+ const bizplace = user.bizplaces[0];
140
+ if (!bizplace)
141
+ throw 'Invalid input';
142
+ bizplaceFilter = { name: 'bizplace', operator: 'eq', value: bizplace.id };
143
+ }
144
+ else {
145
+ bizplaceFilter = params.filters.find(data => data.name === 'bizplace');
146
+ }
147
+ if (!bizplaceFilter || !fromDate || !toDate)
148
+ throw 'Invalid input';
149
+ const bizplace = await tx.getRepository(biz_base_1.Bizplace).findOne({
150
+ id: bizplaceFilter.value
151
+ });
152
+ let batchNoQuery = '';
153
+ if (batchNo) {
154
+ batchNoQuery =
155
+ 'AND Lower(invh.batch_id) LIKE ANY(ARRAY[' +
156
+ batchNo.value
157
+ .toLowerCase()
158
+ .split(',')
159
+ .map(prod => {
160
+ return "'%" + prod.trim().replace(/'/g, "''") + "%'";
161
+ })
162
+ .join(',') +
163
+ '])';
164
+ }
165
+ let productQuery = '';
166
+ if (product) {
167
+ let productValue = product.value
168
+ .toLowerCase()
169
+ .split(',')
170
+ .map(prod => {
171
+ return "'%" + prod.trim().replace(/'/g, "''") + "%'";
172
+ })
173
+ .join(',');
174
+ productQuery = `AND (
175
+ Lower(prd.name) LIKE ANY(ARRAY[${productValue}])
176
+ OR Lower(prd.sku) LIKE ANY(ARRAY[${productValue}])
177
+ OR Lower(prd.description) LIKE ANY(ARRAY[${productValue}])
178
+ OR Lower(prd.brand) LIKE ANY(ARRAY[${productValue}])
179
+ OR Lower(prd.brand_sku) LIKE ANY(ARRAY[${productValue}])
180
+ )`;
181
+ }
182
+ let productDescQuery = '';
183
+ if (productDesc) {
184
+ productDescQuery = "AND Lower(description) LIKE '%" + productDesc.value.toLowerCase() + "%'";
185
+ }
186
+ let hasTransactionOrBalanceQuery = '';
187
+ if (hasTransactionOrBalanceFilter && hasTransactionOrBalanceFilter.value) {
188
+ hasTransactionOrBalanceQuery = 'and (src.totalRow > 1 or src.totalQty <> 0)';
189
+ }
190
+ await tx.query(`
191
+ create temp table temp_products AS
192
+ (
193
+ select prd.*, prd.id::varchar as product_id from products prd
194
+ inner join bizplaces b on b.id = prd.bizplace_id
195
+ inner join companies c on c.domain_id = b.domain_id
196
+ inner join bizplaces b2 on b2.company_id = c.id
197
+ where b2.id = $1
198
+ ${productQuery}
199
+ )`, [bizplace.id]);
200
+ await tx.query(`
201
+ create temp table temp_data_src AS
202
+ (
203
+ SELECT prd.sku as sku, prd.name AS product_name, prd.description AS product_description, prd.type as product_type, prd.aux_value_1 AS product_aux_value_1, trim(invh.batch_id) as batch_id, invh.product_id,
204
+ invh.packing_type, invh.bizplace_id, invh.domain_id,
205
+ invh.ref_order_id, invh.order_no, invh.order_ref_no, invh.transaction_type, invh.status, invh.created_at,
206
+ TRUNC(CAST(invh.qty AS NUMERIC), 3) as qty, TRUNC(CAST(invh.opening_qty AS NUMERIC), 3) as opening_qty,
207
+ invh.uom, TRUNC(CAST(COALESCE(invh.uom_value, 0) AS NUMERIC), 3) as uom_value, TRUNC(CAST(COALESCE(invh.opening_uom_value, 0) AS NUMERIC), 3) as opening_uom_value
208
+ FROM reduced_inventory_histories invh
209
+ INNER JOIN temp_products prd ON prd.id = invh.product_id::uuid
210
+ WHERE
211
+ invh.domain_id = $1
212
+ AND invh.bizplace_id = $2
213
+ AND invh.created_at <= $3::timestamp
214
+ ${batchNoQuery}
215
+ )
216
+ `, [domain.id, bizplace.id, toDate.value]);
217
+ await tx.query(`
218
+ create temp table temp_inv_history as (
219
+ SELECT src.sku, src.product_name, src.product_description, src.product_type, src.product_aux_value_1, src.batch_id, src.product_id, src.packing_type, src.uom,
220
+ src.bizplace_id, src.domain_id,
221
+ TRUNC(CAST(SUM(COALESCE(src.qty,0)) AS NUMERIC), 3) AS qty,
222
+ TRUNC(CAST(SUM(COALESCE(src.opening_qty,0)) AS NUMERIC), 3) AS opening_qty,
223
+ TRUNC(CAST(SUM(COALESCE(src.uom_value,0)) AS NUMERIC), 3) AS uom_value,
224
+ TRUNC(CAST(SUM(COALESCE(src.opening_uom_value,0)) AS NUMERIC), 3) AS opening_uom_value,
225
+ 'Opening Balance' AS order_name,
226
+ '-' AS ref_no,
227
+ '-' as transaction_type,
228
+ 0 AS rn,
229
+ $1::timestamp AS created_at,
230
+ $1::date AS created_date
231
+ FROM temp_data_src src
232
+ WHERE src.created_at < $1::timestamp
233
+ GROUP BY src.sku, src.product_name, src.product_description, src.product_type, src.product_aux_value_1, src.batch_id, src.product_id, src.packing_type, src.uom,
234
+ src.bizplace_id, src.domain_id
235
+ UNION ALL
236
+ SELECT sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
237
+ domain_id, TRUNC(CAST(sum(qty) AS NUMERIC), 3) as qty, TRUNC(CAST(sum(opening_qty) AS NUMERIC), 3) as opening_qty, TRUNC(CAST(sum(uom_value) AS NUMERIC), 3) as uom_value, TRUNC(CAST(sum(opening_uom_value) AS NUMERIC), 3) as opening_uom_value,
238
+ order_name, ref_no, '-' as transaction_type ,1 AS rn, MIN(created_at) - $2::interval as created_at, (MIN(created_at) - $2::interval)::DATE as created_date
239
+ FROM (
240
+ SELECT invh.sku, invh.product_name, invh.product_description, invh.product_type, invh.product_aux_value_1, invh.batch_id, invh.product_id, invh.packing_type, invh.bizplace_id,
241
+ invh.domain_id,
242
+ invh.qty, invh.opening_qty, invh.uom_value, invh.uom, invh.opening_uom_value,
243
+ COALESCE(order_no, '-') AS order_name,
244
+ COALESCE(order_ref_no, '-') AS ref_no,
245
+ COALESCE(invh.transaction_type, '-') AS transaction_type,
246
+ invh.created_at,
247
+ invh.created_at::date as created_date
248
+ FROM temp_data_src invh
249
+ WHERE (invh.qty <> 0 OR invh.uom_value <> 0) AND
250
+ invh.transaction_type <> 'ADJUSTMENT' AND
251
+ invh.transaction_type <> 'PICKING' AND
252
+ invh.transaction_type <> 'CANCEL_ORDER' AND
253
+ invh.transaction_type <>'NEW'
254
+ AND invh.created_at >= $1::timestamp
255
+ ) AS inv_movement
256
+ GROUP BY sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
257
+ domain_id, order_name, ref_no, rn
258
+ UNION ALL
259
+ SELECT sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
260
+ domain_id, TRUNC(CAST(sum(qty) AS NUMERIC), 3) as qty, TRUNC(CAST(sum(opening_qty) AS NUMERIC), 3) as opening_qty, TRUNC(CAST(sum(uom_value) AS NUMERIC), 3) as uom_value, TRUNC(CAST(sum(opening_uom_value) AS NUMERIC), 3) as opening_uom_value,
261
+ CASE
262
+ WHEN transaction_type IN ('PICKING', 'CANCEL_ORDER') THEN order_no
263
+ ELSE order_name
264
+ END AS order_name,
265
+ CASE
266
+ WHEN transaction_type IN ('PICKING', 'CANCEL_ORDER') THEN ref_no
267
+ ELSE order_name
268
+ END AS ref_no,
269
+ transaction_type,
270
+ 1 AS rn,
271
+ created_at - $2::interval as created_at,
272
+ created_at::date as created_date
273
+ FROM (
274
+ SELECT
275
+ invh.sku, invh.product_name, invh.product_description, invh.product_type, invh.product_aux_value_1, invh.batch_id, invh.product_id,
276
+ invh.packing_type, invh.uom, invh.bizplace_id, invh.domain_id,
277
+ invh.qty, invh.opening_qty, invh.uom_value, invh.opening_uom_value,
278
+ invh.transaction_type,
279
+ invh.transaction_type AS order_name,
280
+ order_no,
281
+ order_ref_no AS ref_no,
282
+ invh.created_at,
283
+ invh.created_at::date as created_date
284
+ FROM temp_data_src invh
285
+ WHERE (invh.qty <> 0 OR invh.uom_value <> 0) AND
286
+ (invh.transaction_type = 'ADJUSTMENT'
287
+ OR invh.transaction_type = 'PICKING'
288
+ OR invh.transaction_type = 'CANCEL_ORDER'
289
+ OR invh.transaction_type = 'NEW')
290
+ AND invh.created_at >= $1::timestamp
291
+ ) AS inv_movement
292
+ GROUP BY
293
+ sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
294
+ domain_id, inv_movement.transaction_type,inv_movement.order_no,order_name, ref_no, rn, created_at
295
+ UNION ALL
296
+ SELECT sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
297
+ domain_id, TRUNC(CAST(sum(-opening_qty) AS NUMERIC), 3) as qty, TRUNC(CAST(sum(opening_qty) AS NUMERIC), 3) as opening_qty, TRUNC(CAST(sum(-opening_uom_value) AS NUMERIC), 3) as uom_value, TRUNC(CAST(sum(opening_uom_value) AS NUMERIC), 3) as opening_uom_value,
298
+ order_name, ref_no, transaction_type,1 AS rn, created_at - $2::interval as created_at, created_at::date as created_date
299
+ FROM (
300
+ SELECT invh.sku, invh.product_name, invh.product_description, invh.product_type, invh.product_aux_value_1, invh.batch_id, invh.product_id, invh.packing_type, invh.uom, invh.bizplace_id,
301
+ invh.domain_id,
302
+ invh.qty, invh.opening_qty, invh.uom_value, invh.opening_uom_value,
303
+ invh.transaction_type as transaction_type,
304
+ invh.transaction_type AS order_name,
305
+ invh.transaction_type AS ref_no,
306
+ invh.created_at,
307
+ invh.created_at:: date as created_date
308
+ FROM temp_data_src invh
309
+ WHERE
310
+ invh.transaction_type = 'ADJUSTMENT'
311
+ AND invh.status = 'MISSING'
312
+ AND invh.created_at >= $1::timestamp
313
+ ) AS inv_movement
314
+ GROUP BY sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
315
+ domain_id, order_name, ref_no, inv_movement.transaction_type,rn, created_at
316
+ )`, [fromDate.value, tzoffset]);
317
+ let result;
318
+ if ((byPallet === null || byPallet === void 0 ? void 0 : byPallet.value) === true) {
319
+ result = await tx.query(`
320
+ select sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
321
+ domain_id, qty, opening_qty, round(uom_value::decimal,2) as uom_value, opening_uom_value, order_name, ref_no, transaction_type,created_at::date
322
+ from temp_inv_history invh where
323
+ exists (
324
+ select 1 from (
325
+ select sku, batch_id, product_name, packing_type, sum(qty) as totalQty, count(*) as totalRow from temp_inv_history ih2
326
+ group by sku, batch_id, product_name, packing_type
327
+ ) src
328
+ where src.sku = invh.sku and src.batch_id = invh.batch_id and src.product_name = invh.product_name and src.packing_type = invh.packing_type
329
+ ${hasTransactionOrBalanceQuery}
330
+ )
331
+ ORDER BY invh.sku asc, invh.product_name asc, invh.product_description asc, invh.packing_type asc, invh.batch_id asc, invh.uom asc, invh.rn asc, invh.created_at asc
332
+ `);
333
+ }
334
+ else {
335
+ result = await tx.query(`
336
+ select sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
337
+ domain_id, sum(qty) as qty, sum(opening_qty) as opening_qty, sum(uom_value) as uom_value, sum(opening_uom_value) as opening_uom_value, order_name, ref_no, transaction_type, created_at::date
338
+ from(
339
+ select sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
340
+ domain_id, qty, opening_qty, TRUNC(CAST(uom_value AS NUMERIC), 3) as uom_value, opening_uom_value, order_name, ref_no, transaction_type,created_at::date
341
+ from temp_inv_history invh where
342
+ exists (
343
+ select 1 from (
344
+ select sku, batch_id, product_name, packing_type, TRUNC(CAST(sum(qty) AS NUMERIC), 3) as totalQty, count(*) as totalRow from temp_inv_history ih2
345
+ group by sku, batch_id, product_name, packing_type
346
+ ) src
347
+ where src.sku = invh.sku and src.batch_id = invh.batch_id and src.product_name = invh.product_name and src.packing_type = invh.packing_type
348
+ ${hasTransactionOrBalanceQuery}
349
+ )
350
+ ) foo
351
+ GROUP BY sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
352
+ domain_id, order_name, ref_no, transaction_type, created_at
353
+ ORDER BY sku asc, product_name asc, product_description asc, packing_type asc, batch_id asc, uom asc, created_at asc,
354
+ CASE
355
+ WHEN transaction_type = 'CANCEL_ORDER' THEN 2
356
+ ELSE 1
357
+ END
358
+ `);
359
+ }
360
+ tx.query(`
361
+ drop table temp_products, temp_data_src, temp_inv_history
362
+ `);
363
+ let items = result;
364
+ items = items.map(item => {
365
+ return {
366
+ batchId: item.batch_id,
367
+ bizplace: bizplace,
368
+ packingType: item.packing_type,
369
+ product: {
370
+ id: item.product_id,
371
+ sku: item.sku,
372
+ name: item.product_name,
373
+ type: item.product_type,
374
+ description: item.product_description,
375
+ auxValue1: item.product_aux_value_1 === null ? '' : '[' + item.product_aux_value_1 + ']'
376
+ },
377
+ qty: item.qty,
378
+ uom: item.uom,
379
+ uomValue: item.uom_value,
380
+ openingQty: item.opening_qty,
381
+ openingUomValue: item.opening_uom_value,
382
+ orderNo: item.order_name,
383
+ orderRefNo: item.ref_no,
384
+ transactionType: item.transaction_type,
385
+ createdAt: item.created_at,
386
+ palletId: ''
387
+ };
388
+ });
389
+ return items;
390
+ }
391
+ catch (error) {
392
+ throw error;
393
+ }
394
+ }
395
+ async inventoryHistoryPalletReport(params, context) {
396
+ try {
397
+ const { domain, tx } = context.state;
398
+ let userFilter = params.filters.find(data => data.name === 'user');
399
+ let bizplaceFilter = { name: '', operator: '', value: '' };
400
+ if (userFilter) {
401
+ const user = await tx.getRepository(auth_base_1.User).findOne({
402
+ where: { id: userFilter.value },
403
+ relations: ['bizplaces']
404
+ });
405
+ const bizplace = user.bizplaces[0];
406
+ if (!bizplace)
407
+ throw 'Invalid input';
408
+ bizplaceFilter = { name: 'bizplace', operator: 'eq', value: bizplace.id };
409
+ }
410
+ else {
411
+ bizplaceFilter = params.filters.find(data => data.name === 'bizplace');
412
+ }
413
+ let fromDate = params.filters.find(data => data.name === 'fromDate');
414
+ let toDate = params.filters.find(data => data.name === 'toDate');
415
+ let product = params.filters.find(data => data.name === 'product');
416
+ if (!fromDate || !toDate)
417
+ throw 'Invalid input';
418
+ let bizplaceQuery = '';
419
+ if (bizplaceFilter) {
420
+ const bizplace = await tx.getRepository(biz_base_1.Bizplace).findOne({
421
+ id: bizplaceFilter.value
422
+ });
423
+ if (bizplace) {
424
+ bizplaceQuery = "AND i2.bizplace_id = '" + bizplace.id + "'";
425
+ }
426
+ else {
427
+ throw 'Invalid input';
428
+ }
429
+ }
430
+ let productQuery = '';
431
+ if (product) {
432
+ productQuery =
433
+ 'AND prd.name ILIKE ANY(ARRAY[' +
434
+ product.value
435
+ .split(',')
436
+ .map(prod => {
437
+ return "'%" + prod.trim().replace(/'/g, "''") + "%'";
438
+ })
439
+ .join(',') +
440
+ '])';
441
+ }
442
+ const result = await tx.getRepository(inventory_history_1.InventoryHistory).query(`
443
+ with invHistory as (
444
+ select case when ar.name is null then 'NEW' else ar.name end as arrival_notice_name,
445
+ case when js.container_size is null then '' else js.container_size end as container_size,
446
+ i2.batch_id,
447
+ bzp.name as bizplace_name,
448
+ i2.pallet_id, ih.seq, ih.status, ih.transaction_type, i2.product_id, prd.name as product_name,
449
+ prd.description as product_description, ih.id as inventory_history_id, ih.packing_type, ih.qty, ih.opening_qty,
450
+ ih.created_at::date
451
+ from inventories i2
452
+ inner join reduced_inventory_histories ih on ih.pallet_id = i2.pallet_id and ih.domain_id = i2.domain_id
453
+ inner join products prd on prd.id = i2.product_id
454
+ inner join bizplaces bzp on bzp.id = ih.bizplace_id
455
+ left join order_inventories oi on oi.inventory_id = i2.id and oi.arrival_notice_id is not null
456
+ left join arrival_notices ar on ar.id = oi.arrival_notice_id
457
+ left join job_sheets js on js.id = ar.job_sheet_id
458
+ where
459
+ i2.domain_id = '${domain.id}'
460
+ and (
461
+ (ih.status = 'STORED' and ih.transaction_type = 'NEW')
462
+ or (ih.status = 'STORED' and ih.transaction_type = 'CANCEL_ORDER')
463
+ or (ih.status = 'STORED' and ih.transaction_type = 'RETURN')
464
+ or (ih.status = 'STORED' and ih.transaction_type = 'PUTAWAY')
465
+ or (ih.status = 'TERMINATED' and ih.transaction_type = 'TERMINATED')
466
+ )
467
+ ${bizplaceQuery}
468
+ ${productQuery}
469
+ order by ih.pallet_id, ih.seq
470
+ ), inventoryHistoryMovement as (
471
+ select bizplace_name, container_size, pallet_id, seq, status, transaction_type, product_id, product_name, product_description, batch_id,
472
+ inventory_history_id, packing_type, qty, opening_qty, created_at, arrival_notice_name from (
473
+ select row_number() over(partition by pallet_id order by created_at asc) as rn, * from invHistory where status = 'STORED'
474
+ )as invIn where rn = 1
475
+ union all
476
+ select bizplace_name, container_size, pallet_id, seq, status, transaction_type, product_id, product_name, product_description, batch_id,
477
+ inventory_history_id, packing_type, qty, opening_qty, created_at, arrival_notice_name from (
478
+ select row_number() over(partition by pallet_id order by created_at desc) as rn, * from invHistory
479
+ )as invOut where rn = 1 and status = 'TERMINATED'
480
+ ), inventoryHistoriesByPallet as (
481
+ select invHistory.bizplace_name, invHistory.container_size, invHistory.product_name, invHistory.product_description, invHistory.arrival_notice_name, invHistory.batch_id,
482
+ SUM(case when invHistory.created_at <= '${new Date(fromDate.value).toLocaleDateString()} 00:00:00' then
483
+ case when invHistory.status = 'STORED' then 1 else -1 end
484
+ else 0 end) as opening_balance,
485
+ SUM(case when invHistory.created_at >= '${new Date(fromDate.value).toLocaleDateString()} 00:00:00'
486
+ and invHistory.created_at <= '${new Date(toDate.value).toLocaleDateString()} 23:59:59' then
487
+ case when invHistory.status = 'STORED' then 1 else 0 end
488
+ else 0 end) as in_balance,
489
+ SUM(case when invHistory.created_at >= '${new Date(fromDate.value).toLocaleDateString()} 00:00:00'
490
+ and invHistory.created_at <= '${new Date(toDate.value).toLocaleDateString()} 23:59:59' then
491
+ case when invHistory.status = 'TERMINATED' then 1 else 0 end
492
+ else 0 end) as out_balance
493
+ from(
494
+ select * from inventoryHistoryMovement
495
+ ) as invHistory group by bizplace_name, container_size, product_name, product_description, arrival_notice_name, batch_id
496
+ )
497
+ select invh.*, invh.opening_balance + invh.in_balance - invh.out_balance as closing_balance
498
+ , (
499
+ select json_agg(json_build_object('created_at', created_at, 'in_balance', in_balance, 'out_balance', out_balance)) as jsonData from
500
+ (
501
+ select bizplace_name, product_name, batch_id, arrival_notice_name, created_at,
502
+ SUM(case when status = 'STORED' then 1 else 0 end) as in_balance,
503
+ SUM(case when status = 'TERMINATED' then 1 else 0 end) as out_balance
504
+ from inventoryHistoryMovement
505
+ where created_at >= '${new Date(fromDate.value).toLocaleDateString()} 00:00:00' and
506
+ created_at <= '${new Date(toDate.value).toLocaleDateString()} 23:59:59' and
507
+ bizplace_name = invh.bizplace_name and product_name = invh.product_name and
508
+ batch_id = invh.batch_id and arrival_notice_name = invh.arrival_notice_name
509
+ group by bizplace_name, product_name, batch_id, arrival_notice_name, created_at
510
+ order by created_at
511
+ )
512
+ as t
513
+ )::varchar as json_date_movement
514
+ from inventoryHistoriesByPallet invh
515
+ where invh.opening_balance >= 0
516
+ and invh.in_balance >= 0
517
+ and invh.out_balance >= 0
518
+ and (invh.opening_balance > 0 or invh.in_balance > 0)
519
+ order by invh.bizplace_name, invh.product_name, invh.batch_id;
520
+ `);
521
+ let items = result;
522
+ items = items.map(item => {
523
+ return {
524
+ bizplace: { name: item.bizplace_name },
525
+ product: {
526
+ name: item.product_name.trim() + ' ( ' + (item.product_description || '-').trim() + ' )'
527
+ },
528
+ arrivalNoticeName: item.arrival_notice_name,
529
+ batchId: item.batch_id,
530
+ openingBalance: item.opening_balance,
531
+ inBalance: item.in_balance,
532
+ outBalance: item.out_balance,
533
+ closingBalance: item.closing_balance,
534
+ jsonDateMovement: item.json_date_movement,
535
+ containerSize: item.container_size
536
+ };
537
+ });
538
+ return items;
539
+ }
540
+ catch (error) {
541
+ throw error;
542
+ }
543
+ }
544
+ async inventoryHistoryPalletDetailReport(params, context) {
545
+ try {
546
+ const { domain, tx } = context.state;
547
+ let userFilter = params.filters.find(data => data.name === 'user');
548
+ let bizplaceFilter = { name: '', operator: '', value: '' };
549
+ if (userFilter) {
550
+ const user = await tx.getRepository(auth_base_1.User).findOne({
551
+ where: { id: userFilter.value },
552
+ relations: ['bizplaces']
553
+ });
554
+ const bizplace = user.bizplaces[0];
555
+ if (!bizplace)
556
+ throw 'Invalid input';
557
+ bizplaceFilter = { name: 'bizplace', operator: 'eq', value: bizplace.id };
558
+ }
559
+ else {
560
+ bizplaceFilter = params.filters.find(data => data.name === 'bizplace');
561
+ }
562
+ let fromDate = params.filters.find(data => data.name === 'fromDate');
563
+ let toDate = params.filters.find(data => data.name === 'toDate');
564
+ let product = params.filters.find(data => data.name === 'product');
565
+ if (!fromDate || !toDate)
566
+ throw 'Invalid input';
567
+ let bizplaceQuery = '';
568
+ if (bizplaceFilter) {
569
+ const bizplace = await tx.getRepository(biz_base_1.Bizplace).findOne({
570
+ id: bizplaceFilter.value
571
+ });
572
+ if (bizplace) {
573
+ bizplaceQuery = "AND i2.bizplace_id = '" + bizplace.id + "'";
574
+ }
575
+ else {
576
+ throw 'Invalid input';
577
+ }
578
+ }
579
+ let productQuery = '';
580
+ if (product) {
581
+ productQuery =
582
+ 'AND prd.name ILIKE ANY(ARRAY[' +
583
+ product.value
584
+ .split(',')
585
+ .map(prod => {
586
+ return "'%" + prod.trim().replace(/'/g, "''") + "%'";
587
+ })
588
+ .join(',') +
589
+ '])';
590
+ }
591
+ const result = await tx.getRepository(inventory_history_1.InventoryHistory).query(`
592
+ with invHistory as (
593
+ select case when ar.name is null then 'NEW' else ar.name end as arrival_notice_name,
594
+ case when js.container_size is null then '' else js.container_size end as container_size,
595
+ i2.batch_id,
596
+ bzp.name as bizplace_name,
597
+ i2.pallet_id, ih.seq, ih.status, ih.transaction_type, i2.product_id, prd.name as product_name,
598
+ prd.description as product_description, ih.id as inventory_history_id, ih.packing_type, ih.qty, ih.opening_qty,
599
+ ih.created_at::date
600
+ from inventories i2
601
+ inner join reduced_inventory_histories ih on ih.pallet_id = i2.pallet_id and ih.domain_id = i2.domain_id
602
+ inner join products prd on prd.id = i2.product_id
603
+ inner join bizplaces bzp on bzp.id = ih.bizplace_id
604
+ left join order_inventories oi on oi.inventory_id = i2.id and oi.arrival_notice_id is not null
605
+ left join arrival_notices ar on ar.id = oi.arrival_notice_id
606
+ left join job_sheets js on js.id = ar.job_sheet_id
607
+ where
608
+ i2.domain_id = '${domain.id}'
609
+ and (
610
+ (ih.status = 'STORED' and ih.transaction_type = 'NEW')
611
+ or (ih.status = 'STORED' and ih.transaction_type = 'CANCEL_ORDER')
612
+ or (ih.status = 'STORED' and ih.transaction_type = 'RETURN')
613
+ or (ih.status = 'STORED' and ih.transaction_type = 'PUTAWAY')
614
+ or (ih.status = 'TERMINATED' and ih.transaction_type = 'TERMINATED')
615
+ )
616
+ ${bizplaceQuery}
617
+ ${productQuery}
618
+ order by ih.pallet_id, ih.seq
619
+ ), inventoryHistoryMovement as (
620
+ select bizplace_name, container_size, pallet_id, seq, status, transaction_type, product_id, product_name, product_description, batch_id,
621
+ inventory_history_id, packing_type, qty, opening_qty, created_at, arrival_notice_name from (
622
+ select row_number() over(partition by pallet_id order by created_at asc) as rn, * from invHistory where status = 'STORED'
623
+ )as invIn where rn = 1
624
+ union all
625
+ select bizplace_name, container_size, pallet_id, seq, status, transaction_type, product_id, product_name, product_description, batch_id,
626
+ inventory_history_id, packing_type, qty, opening_qty, created_at, arrival_notice_name from (
627
+ select row_number() over(partition by pallet_id order by created_at desc) as rn, * from invHistory
628
+ )as invOut where rn = 1 and status = 'TERMINATED'
629
+ ), inventoryHistoriesByPallet as (
630
+ select invHistory.bizplace_name, invHistory.container_size, invHistory.product_name, invHistory.product_description, invHistory.arrival_notice_name, invHistory.batch_id,
631
+ SUM(case when invHistory.created_at <= '${new Date(fromDate.value).toLocaleDateString()} 00:00:00' then
632
+ case when invHistory.status = 'STORED' then 1 else -1 end
633
+ else 0 end) as opening_balance,
634
+ SUM(case when invHistory.created_at >= '${new Date(fromDate.value).toLocaleDateString()} 00:00:00'
635
+ and invHistory.created_at <= '${new Date(toDate.value).toLocaleDateString()} 23:59:59' then
636
+ case when invHistory.status = 'STORED' then 1 else 0 end
637
+ else 0 end) as in_balance,
638
+ SUM(case when invHistory.created_at >= '${new Date(fromDate.value).toLocaleDateString()} 00:00:00'
639
+ and invHistory.created_at <= '${new Date(toDate.value).toLocaleDateString()} 23:59:59' then
640
+ case when invHistory.status = 'TERMINATED' then 1 else 0 end
641
+ else 0 end) as out_balance
642
+ from(
643
+ select * from inventoryHistoryMovement
644
+ ) as invHistory group by bizplace_name, container_size, product_name, product_description, arrival_notice_name, batch_id
645
+ )
646
+ select invh.*, invh.opening_balance + invh.in_balance - invh.out_balance as closing_balance
647
+ , (
648
+ select json_agg(json_build_object('created_at', created_at, 'in_balance', in_balance, 'out_balance', out_balance)) as jsonData from
649
+ (
650
+ select bizplace_name, product_name, batch_id, arrival_notice_name, created_at,
651
+ SUM(case when status = 'STORED' then 1 else 0 end) as in_balance,
652
+ SUM(case when status = 'TERMINATED' then 1 else 0 end) as out_balance
653
+ from inventoryHistoryMovement
654
+ where created_at >= '${new Date(fromDate.value).toLocaleDateString()} 00:00:00' and
655
+ created_at <= '${new Date(toDate.value).toLocaleDateString()} 23:59:59' and
656
+ bizplace_name = invh.bizplace_name and product_name = invh.product_name and
657
+ batch_id = invh.batch_id and arrival_notice_name = invh.arrival_notice_name
658
+ group by bizplace_name, product_name, batch_id, arrival_notice_name, created_at
659
+ order by created_at
660
+ )
661
+ as t
662
+ )::varchar as json_date_movement
663
+ from inventoryHistoriesByPallet invh
664
+ where invh.opening_balance >= 0
665
+ and invh.in_balance >= 0
666
+ and invh.out_balance >= 0
667
+ and (invh.opening_balance > 0 or invh.in_balance > 0)
668
+ order by invh.bizplace_name, invh.product_name, invh.batch_id;
669
+ `);
670
+ let items = result;
671
+ items = items.map(item => {
672
+ return {
673
+ bizplace: { name: item.bizplace_name },
674
+ product: {
675
+ name: item.product_name.trim() + ' ( ' + (item.product_description || '-').trim() + ' )'
676
+ },
677
+ arrivalNoticeName: item.arrival_notice_name,
678
+ batchId: item.batch_id,
679
+ openingBalance: item.opening_balance,
680
+ inBalance: item.in_balance,
681
+ outBalance: item.out_balance,
682
+ closingBalance: item.closing_balance,
683
+ jsonDateMovement: item.json_date_movement,
684
+ containerSize: item.container_size
685
+ };
686
+ });
687
+ return items;
688
+ }
689
+ catch (error) {
690
+ throw error;
691
+ }
692
+ }
693
+ async inventoryHistoryPalletStorageReport(params, context) {
694
+ try {
695
+ const { domain, tx } = context.state;
696
+ let userFilter = params.filters.find(data => data.name === 'user');
697
+ let bizplaceFilter = { name: '', operator: '', value: '' };
698
+ if (userFilter) {
699
+ const user = await tx.getRepository(auth_base_1.User).findOne({
700
+ where: { id: userFilter.value },
701
+ relations: ['bizplaces']
702
+ });
703
+ const bizplace = user.bizplaces[0];
704
+ if (!bizplace)
705
+ throw 'Invalid input';
706
+ bizplaceFilter = { name: 'bizplace', operator: 'eq', value: bizplace.id };
707
+ }
708
+ else {
709
+ bizplaceFilter = params.filters.find(data => data.name === 'bizplace');
710
+ }
711
+ let fromDate = params.filters.find(data => data.name === 'fromDate');
712
+ let toDate = params.filters.find(data => data.name === 'toDate');
713
+ if (!bizplaceFilter || !fromDate || !toDate)
714
+ throw 'Invalid input';
715
+ const bizplace = await tx.getRepository(biz_base_1.Bizplace).findOne({
716
+ id: bizplaceFilter.value
717
+ });
718
+ let queryFilter = ``;
719
+ let queryParams = [fromDate.value, toDate.value];
720
+ let locationType = params.filters.find(data => data.name === 'locationType');
721
+ if (locationType) {
722
+ queryFilter = queryFilter + `AND location_type = $` + (queryParams.length + 1);
723
+ queryParams.push(locationType.value);
724
+ }
725
+ let zone = params.filters.find(data => data.name === 'zone');
726
+ if (zone) {
727
+ queryFilter = queryFilter + `AND LOWER(location_zone) like $` + (queryParams.length + 1);
728
+ queryParams.push(zone.value.toLowerCase());
729
+ }
730
+ await tx.query(`
731
+ create temp table temp_history as (
732
+ select distinct on (ih.pallet_id) ih.seq,
733
+ ih.pallet_id, inv.created_at as in_at, loc.name as location_name, loc."type" as location_type, loc."zone" as location_zone,
734
+ bz.name as bizplace_name, p.sku as product_sku
735
+ from reduced_inventory_histories ih
736
+ inner join inventories inv on inv.pallet_id = ih.pallet_id and inv.domain_id = ih.domain_id
737
+ inner join locations loc on loc.id = ih.location_id
738
+ inner join bizplaces bz on bz.id = ih.bizplace_id
739
+ inner join products p ON p.id = ih.product_id
740
+ where ih.domain_id = $1
741
+ and inv.bizplace_id = $2
742
+ and not exists(
743
+ select * from (
744
+ SELECT distinct on (ih2.pallet_id) ih2.pallet_id, ih2.seq, ih2.status
745
+ FROM reduced_inventory_histories ih2
746
+ where ih2.domain_id = $1
747
+ and ih2.created_at < $3
748
+ order by ih2.pallet_id , ih2.seq desc
749
+ ) ih2
750
+ where ih2.status = 'TERMINATED'
751
+ and ih2.pallet_id = ih.pallet_id
752
+ )
753
+ and ih.created_at <= $4
754
+ order by ih.pallet_id , ih.seq desc
755
+ )
756
+ `, [domain.id, bizplace.id, fromDate.value, toDate.value]);
757
+ await tx.query(`
758
+ create temp table temp_pallet_storage_history as (
759
+ select * from (
760
+ select bizplace_name, location_type, location_zone, location_name,
761
+ COUNT(pallet_id) filter (where in_at between $1 and $2) as inbound_qty,
762
+ COUNT(*) as total_qty,
763
+ string_agg(case when in_at between $1 and $2 then pallet_id end, ', ') as inbound_pallet_id,
764
+ string_agg(case when in_at not between $1 and $2 then pallet_id || ' (' || product_sku || ')' end, ', ') as pallet_id
765
+ from temp_history where location_type IN ('SHELF', 'BUFFER', 'DAMAGE', 'QUARANTINE', 'RESERVE', 'STORAGE', 'BIN')
766
+ group by bizplace_name, location_name, location_type, location_zone
767
+ union
768
+ select bizplace_name, location_type, location_zone, location_name,
769
+ case when in_at between $1 and $2 then 1 else 0 end as inbound_qty,
770
+ 1 as total_qty,
771
+ case when in_at between $1 and $2 then pallet_id end as inbound_pallet_id,
772
+ case when in_at not between $1 and $2 then pallet_id || ' (' || product_sku || ')' end pallet_id
773
+ from temp_history where location_type = 'FLOOR'
774
+ ) as src where 1 = 1
775
+ ${queryFilter}
776
+ )
777
+ `, queryParams);
778
+ const total = await tx.query(`select count(*) from temp_pallet_storage_history`);
779
+ const totalWithOpeningBalance = await tx.query(`select count(*) from temp_pallet_storage_history where pallet_id notnull`);
780
+ const result = await tx.query(`
781
+ select * from temp_pallet_storage_history order by location_type, location_name, pallet_id, inbound_pallet_id OFFSET $1 LIMIT $2
782
+ `, [(params.pagination.page - 1) * params.pagination.limit, params.pagination.limit]);
783
+ tx.query(`
784
+ drop table temp_history, temp_pallet_storage_history
785
+ `);
786
+ let items = result.map(itm => {
787
+ return Object.assign(Object.assign({}, itm), { bizplace: {
788
+ name: itm.bizplace_name
789
+ }, location: {
790
+ name: itm.location_name,
791
+ type: itm.location_type,
792
+ zone: itm.location_zone
793
+ }, palletId: itm.pallet_id, inboundPalletId: itm.inbound_pallet_id, inboundQty: itm.inbound_qty, totalQty: itm.total_qty });
794
+ });
795
+ return { items, total: total[0].count, totalWithOpeningBalance: totalWithOpeningBalance[0].count };
796
+ }
797
+ catch (ex) {
798
+ throw ex;
799
+ }
800
+ }
801
+ async inventoryHistorySummaryReport(params, context) {
802
+ try {
803
+ const { tx } = context.state;
804
+ let bizplaceFilter = { name: '', operator: '', value: '' };
805
+ let userFilter = params.filters.find(data => data.name === 'user');
806
+ let fromDate = params.filters.find(data => data.name === 'fromDate');
807
+ let toDate = params.filters.find(data => data.name === 'toDate');
808
+ let byPallet = params.filters.find(data => data.name === 'byPallet');
809
+ if (userFilter) {
810
+ const user = await tx.getRepository(auth_base_1.User).findOne({
811
+ where: { id: userFilter.value },
812
+ relations: ['bizplaces']
813
+ });
814
+ const bizplace = user.bizplaces[0];
815
+ if (!bizplace)
816
+ throw 'Invalid input';
817
+ bizplaceFilter = { name: 'bizplace', operator: 'eq', value: bizplace.id };
818
+ }
819
+ else {
820
+ bizplaceFilter = params.filters.find(data => data.name === 'bizplace');
821
+ }
822
+ if (!bizplaceFilter || !fromDate || !toDate)
823
+ throw 'Invalid input';
824
+ const bizplace = await tx.getRepository(biz_base_1.Bizplace).findOne({
825
+ id: bizplaceFilter.value
826
+ });
827
+ let [result, total] = byPallet.value
828
+ ? await massageInventoryPalletSummary(tx, params, bizplace, context)
829
+ : await massageInventorySummary(tx, params, bizplace, context);
830
+ let items = result.map(itm => {
831
+ return Object.assign(Object.assign({}, itm), { batchId: itm.batch_id, packingType: itm.packing_type, packingSize: itm.packing_size, openingQty: itm.opening_qty, missingQty: itm.missing_qty, adjustmentQty: itm.adjustment_qty, closingQty: itm.closing_qty, totalInQty: itm.total_in_qty, totalOutQty: itm.total_out_qty, product: {
832
+ id: itm.product_id,
833
+ sku: itm.product_sku,
834
+ name: itm.product_name,
835
+ description: itm.product_description,
836
+ type: itm.product_type
837
+ } });
838
+ });
839
+ return {
840
+ items,
841
+ total: total[0].count,
842
+ totalInboundQty: total[0].totalinqty || 0,
843
+ totalOpeningBal: total[0].totalopeningbal || 0
844
+ };
845
+ }
846
+ catch (error) {
847
+ throw error;
848
+ }
849
+ }
850
+ async onhandInventories(context, filters, pagination, sortings, locationSortingRules, setPagination) {
851
+ const { domain, user, tx } = context.state;
852
+ // define all inputs
853
+ let userFilter = filters.find(data => data.name === 'user');
854
+ let product = filters.find(data => data.name === 'product');
855
+ let createdAt = filters.find(data => data.name === 'created_at');
856
+ let location = filters.find(data => data.name === 'location');
857
+ let batchId = filters.find(data => data.name === 'batchId');
858
+ let palletId = filters.find(data => data.name === 'palletId');
859
+ let cartonId = filters.find(data => data.name === 'cartonId');
860
+ let packingType = filters.find(data => data.name === 'packingType');
861
+ let timezoneOffset = filters.find(data => data.name === 'timezoneOffset').value + ' minutes';
862
+ // expiration date filter
863
+ let expiration = filters.find(data => data.name === 'expiration').value;
864
+ let expFromDate = filters.find(data => data.name === 'expFromDate');
865
+ let expToDate = filters.find(data => data.name === 'expToDate');
866
+ let bizplaceFilter = { name: '', operator: '', value: [] };
867
+ // prepare query filters
868
+ if (userFilter) {
869
+ const user = await tx.getRepository(auth_base_1.User).findOne({
870
+ where: { id: userFilter.value },
871
+ relations: ['bizplaces']
872
+ });
873
+ const bizplace = user.bizplaces[0];
874
+ if (!bizplace)
875
+ throw 'Invalid input';
876
+ bizplaceFilter = { name: 'bizplace', operator: 'eq', value: [bizplace.id] };
877
+ }
878
+ else {
879
+ bizplaceFilter = !filters.find((filter) => filter.name === 'bizplace')
880
+ ? {
881
+ name: 'bizplace',
882
+ operator: 'in',
883
+ value: await (0, biz_base_1.getPermittedBizplaceIds)(domain, user),
884
+ relation: true
885
+ }
886
+ : Object.assign(Object.assign({}, filters.find(data => data.name === 'bizplace')), { value: [filters.find(data => data.name === 'bizplace').value] });
887
+ }
888
+ let queryFilter = ``;
889
+ let bizplaces = bizplaceFilter.value.map(id => `('${id}')`).join(',');
890
+ if (product) {
891
+ let products = product.value
892
+ .toLowerCase()
893
+ .split(',')
894
+ .map(prod => {
895
+ return "'%" + prod.trim().replace(/'/g, "''") + "%'";
896
+ })
897
+ .join(',');
898
+ queryFilter =
899
+ queryFilter +
900
+ ` and exists (
901
+ select prd.id as product_id from products prd
902
+ inner join bizplaces b on b.id = prd.bizplace_id
903
+ inner join companies c on c.domain_id = b.domain_id
904
+ inner join bizplaces b2 on b2.company_id = c.id
905
+ where exists (
906
+ SELECT * FROM tmp_bizfilter bizFilter
907
+ WHERE bizFilter.bizplace_id = "b2"."id"
908
+ )
909
+ and (lower(prd.name) like any(array[${products}])
910
+ or lower(prd.description) like any(array[${products}])
911
+ or lower(prd.sku) like any(array[${products}])
912
+ or lower(prd.brand_sku) like any(array[${products}]))
913
+ and prd.id = rih.product_id
914
+ group by prd.id
915
+ )`;
916
+ }
917
+ if (location) {
918
+ let locations = location.value
919
+ .map(loc => {
920
+ return "'" + loc + "'";
921
+ })
922
+ .join(',');
923
+ queryFilter =
924
+ queryFilter +
925
+ `and exists (
926
+ select loc.id from locations loc where
927
+ loc.id = any(array[${locations}]::uuid[])
928
+ and loc.id = rih.location_id
929
+ )`;
930
+ }
931
+ // default sorting
932
+ let queryOrder = 'order by created_at desc';
933
+ if (sortings && sortings.length > 0) {
934
+ const arrObjectMap = [
935
+ { name: 'palletId', value: 'rih.pallet_id' },
936
+ { name: 'cartonId', value: 'rih.carton_id' },
937
+ { name: 'batchId', value: 'rih.batch_id' },
938
+ { name: 'initialInboundAt', value: 'rih.initial_inbound_at' },
939
+ { name: 'bizplace|name', value: 'bz.name' },
940
+ { name: 'product|name', value: 'prd.sku' },
941
+ { name: 'remainQty', value: 'rih.qty' },
942
+ { name: 'location|name', value: 'loc.name' }
943
+ ];
944
+ sortings.forEach((sorting, idx) => {
945
+ let itmIndex = arrObjectMap.findIndex(x => x.name === sorting.name);
946
+ queryOrder = `${idx === 0 ? 'order by' : queryOrder + ','} ${itmIndex >= 0 ? arrObjectMap[itmIndex].value : sorting.name} ${sorting.desc ? 'DESC' : 'ASC'}`;
947
+ });
948
+ }
949
+ if (batchId)
950
+ queryFilter = `${queryFilter} and lower(rih.batch_id) like '${batchId.value.toLowerCase()}' `;
951
+ if (palletId)
952
+ queryFilter = `${queryFilter} and rih.pallet_id like '${palletId.value}' `;
953
+ if (cartonId)
954
+ queryFilter = `${queryFilter} and rih.carton_id like '${cartonId.value}' `;
955
+ if (packingType)
956
+ queryFilter = `${queryFilter} and rih.packing_type like '${packingType.value}' `;
957
+ let expirationQueryFilter = ``;
958
+ if (expiration)
959
+ expirationQueryFilter = ` and iv.expiration_date >= '${expFromDate.value}'::timestamp + '${timezoneOffset}'::INTERVAL and
960
+ iv.expiration_date <= '${expToDate.value}'::timestamp + '${timezoneOffset}'::INTERVAL + '1 day'::INTERVAL`;
961
+ // query the results
962
+ await tx.query(`
963
+ CREATE TEMP TABLE tmp_bizfilter on commit drop AS (
964
+ SELECT bizplace_id::uuid FROM (VALUES ${bizplaces}) AS bizFilter(bizplace_id)
965
+ );
966
+ `);
967
+ await tx.query(`
968
+ create temp table tmp_src on commit drop as (
969
+ select domain_id, pallet_id, carton_id, seq,
970
+ TRUNC(qty::numeric,3) as qty,
971
+ TRUNC(uom_value::numeric,3) as uom_value,
972
+ packing_type, batch_id, batch_id_ref, created_at, status, unit_cost,
973
+ product_id::uuid as product_id, bizplace_id::uuid as bizplace_id, location_id::uuid as location_id
974
+ from reduced_inventory_histories rih
975
+ where domain_id = $1 and created_at < $2::timestamp + $3::INTERVAL + '1 day'::INTERVAL
976
+ );
977
+ `, [domain.id, createdAt.value, timezoneOffset]);
978
+ await tx.query(`
979
+ CREATE TEMP TABLE tmp_src_group on commit drop AS (
980
+ select ih.domain_id, ih.pallet_id,
981
+ TRUNC(sum(ih.qty)::numeric,3) as qty,
982
+ TRUNC(sum(ih.uom_value)::numeric,3) as uom_value,
983
+ max(ih.seq) as last_seq, max(ih.created_at) as created_at,
984
+ min(ih.created_at) as initial_inbound_at
985
+ from tmp_src ih
986
+ group by ih.domain_id, ih.pallet_id
987
+ );
988
+ `);
989
+ await tx.query(`
990
+ create temp table tmp_data on commit drop as (
991
+ 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,
992
+ iv.expiration_date, iv.manufacture_date, iv.reusable_pallet_id, iv.remark
993
+ from
994
+ (
995
+ SELECT ih.*, ih2.status FROM tmp_src_group ih
996
+ INNER JOIN inventory_histories ih2
997
+ ON ih.domain_id = ih2.domain_id
998
+ AND ih.pallet_id = ih2.pallet_id
999
+ AND ih.last_seq = ih2.seq
1000
+ ) dt
1001
+ 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 and rih.status <> 'TERMINATED'
1002
+ inner join inventories iv on iv.domain_id = dt.domain_id and iv.pallet_id = dt.pallet_id and iv.status <> 'MISSING'
1003
+ where exists (
1004
+ SELECT * FROM tmp_bizfilter bizFilter
1005
+ WHERE bizFilter.bizplace_id = "rih"."bizplace_id"
1006
+ )
1007
+ ${queryFilter}
1008
+ ${expirationQueryFilter}
1009
+ );
1010
+ `);
1011
+ const total = await tx.query(`select count(*) from tmp_data`);
1012
+ const result = await tx.query(`
1013
+ select
1014
+ rih.domain_id, rih.pallet_id as "palletId", rih.carton_id as "cartonId",
1015
+ TRUNC(rih.qty::numeric,3) as "remainQty",
1016
+ TRUNC(rih.uom_value::numeric,3) as "uomValue", rih.uom, rih.last_seq, rih.created_at,
1017
+ rih.initial_inbound_at as "initialInboundAt", rih.unit_cost as "unitCost",
1018
+ case when rih.reusable_pallet_id is not null then concat(rih.batch_id, ' (', plt.name, ')') else rih.batch_id end as "batchId",
1019
+ rih.batch_id_ref as "batchIdRef", rih.product_id, rih.packing_type as "packingType", rih.bizplace_id, rih.location_id,
1020
+ 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, prd.outbound_alert as product_outbound_alert, prd.min_outbound_shelf_life as product_min_outbound_shelf_life,
1021
+ bz.id as bizplace_id, bz.name as bizplace_name,
1022
+ loc.id as location_id, loc.name as location_name, loc."zone" as location_zone, loc."type" as location_type, loc."row" as location_row, loc."column" as location_column, loc.shelf as location_shelf,
1023
+ wh.name as warehouse_name, plt.name as reusable_pallet_name,
1024
+ rih.remark,
1025
+ rih.manufacture_date as "manufactureDate",
1026
+ rih.expiration_date as "expirationDate",
1027
+ prd.outbound_alert as "outboundAlert",
1028
+ prd.min_outbound_shelf_life as "minOutboundShelfLife",
1029
+ case
1030
+ when rih.expiration_date < now() then 'Expired'
1031
+ when (rih.expiration_date - (prd.min_outbound_shelf_life || ' days')::INTERVAL) < now() then 'Expiring'
1032
+ when (rih.expiration_date - (prd.outbound_alert || ' days')::INTERVAL) < now() then 'Risky'
1033
+ else 'Normal' end as expiry,
1034
+ i.adjustment_note as "adjustmentNote",
1035
+ TRUNC(coalesce((
1036
+ select sum(oi1.release_qty) as nonLoadedQty from order_inventories oi1
1037
+ inner join release_goods rg1 on rg1.id = oi1.release_good_id
1038
+ where rg1.status in ('PICKING', 'LOADING')
1039
+ and oi1.inventory_id = rih.inventory_id
1040
+ and oi1.status in ('PICKED', 'LOADING')
1041
+ and rg1.domain_id = '${domain.id}'
1042
+ group by oi1.inventory_id
1043
+ ),0)::numeric,3) as "nonLoadedQty",
1044
+ TRUNC(coalesce((
1045
+ select sum(oi1.release_uom_value) as nonLoadedUomValue from order_inventories oi1
1046
+ inner join release_goods rg1 on rg1.id = oi1.release_good_id
1047
+ where rg1.status in ('PICKING', 'LOADING')
1048
+ and oi1.inventory_id = rih.inventory_id
1049
+ and oi1.status in ('PICKED', 'LOADING')
1050
+ and rg1.domain_id = '${domain.id}'
1051
+ group by oi1.inventory_id
1052
+ ),0)::numeric,3) as "nonLoadedUomValue",
1053
+ TRUNC(i.transfer_qty::numeric,3) as "transferQty",
1054
+ TRUNC(i.transfer_uom_value::numeric,3) as "transferUomValue"
1055
+ from tmp_data rih
1056
+ left join pallets plt on plt.id = rih.reusable_pallet_id
1057
+ inner join products prd on prd.id = rih.product_id
1058
+ inner join bizplaces bz on bz.id = rih.bizplace_id
1059
+ inner join locations loc on loc.id = rih.location_id
1060
+ inner join warehouses wh on wh.id = loc.warehouse_id
1061
+ inner join inventories i on i.id = rih.inventory_id
1062
+ WHERE 1 = 1
1063
+ ${queryOrder}
1064
+ ${setPagination ? 'OFFSET ' + (pagination.page - 1) * pagination.limit + ' LIMIT ' + pagination.limit : ''}
1065
+ `);
1066
+ const convertGmt = timestamp => {
1067
+ const offsetInt = parseInt(timezoneOffset); // the offset value from client-side
1068
+ const offsetHours = offsetInt < 0 ? Math.abs(offsetInt / 60) : offsetInt / 60;
1069
+ const localTimestamp = new Date(timestamp.getTime() + offsetHours * 60 * 60 * 1000);
1070
+ const day = localTimestamp.getDate();
1071
+ const month = localTimestamp.getMonth() + 1;
1072
+ const year = localTimestamp.getFullYear();
1073
+ const hours = localTimestamp.getHours().toString().padStart(2, '0');
1074
+ const minutes = localTimestamp.getMinutes().toString().padStart(2, '0');
1075
+ const seconds = localTimestamp.getSeconds().toString().padStart(2, '0');
1076
+ const datePart = `${day}/${month}/${year}`;
1077
+ const timePart = `${hours}:${minutes}:${seconds}`;
1078
+ const dateTime = `${datePart}, ${timePart}`;
1079
+ return dateTime;
1080
+ };
1081
+ const getCondition = locationType => {
1082
+ return ({
1083
+ BIN: 'New',
1084
+ BUFFER: 'New',
1085
+ FLOOR: 'New',
1086
+ SHELF: 'New',
1087
+ STORAGE: 'New',
1088
+ RESERVE: 'Reserve',
1089
+ DAMAGE: 'Damage',
1090
+ QUARANTINE: 'Quarantine'
1091
+ }[locationType] || 'Unknown');
1092
+ };
1093
+ let items = result.map(itm => {
1094
+ const processedInbound = itm.initialInboundAt ? convertGmt(itm.initialInboundAt) : '';
1095
+ return Object.assign(Object.assign({}, itm), { initialInboundAt: processedInbound, bizplace: {
1096
+ id: itm.bizplace_id,
1097
+ name: itm.bizplace_name
1098
+ }, location: {
1099
+ id: itm.location_id,
1100
+ name: itm.location_name,
1101
+ type: itm.location_type,
1102
+ zone: itm.location_zone
1103
+ }, product: {
1104
+ id: itm.product_id,
1105
+ name: itm.product_name,
1106
+ description: itm.product_description,
1107
+ sku: itm.product_sku,
1108
+ brand: itm.product_brand,
1109
+ volume: itm.product_volume,
1110
+ outboundAlert: itm.product_outbound_alert,
1111
+ minOutboundShelfLife: itm.product_min_outbound_shelf_life
1112
+ }, condition: itm.location_type ? getCondition(itm.location_type) : 'Unknown' });
1113
+ });
1114
+ return { items, total: total[0].count };
1115
+ }
1116
+ async bizplaceInventoryHistoriesForExport(context, inventoryHistory, filters) {
1117
+ const { domain, tx } = context.state;
1118
+ const customerBizplace = await tx.getRepository(biz_base_1.Bizplace).findOne(inventoryHistory.bizplace.id);
1119
+ const productFilters = filters.find(x => x.name == 'product_info');
1120
+ filters = filters.filter(x => x.name != 'product_info');
1121
+ const fromDate = new Date(inventoryHistory.fromDate);
1122
+ const toDate = new Date(inventoryHistory.toDate);
1123
+ if (productFilters) {
1124
+ let productFilterValue = `%${productFilters.value.toLowerCase()}%`;
1125
+ const productQb = (0, typeorm_1.getRepository)(product_base_1.Product).createQueryBuilder('prd');
1126
+ productQb.where(new typeorm_1.Brackets(qb => {
1127
+ qb.where('Lower(prd.sku) LIKE :productInfo', { productInfo: productFilterValue })
1128
+ .orWhere('Lower(prd.name) LIKE :productInfo', { productInfo: productFilterValue })
1129
+ .orWhere('Lower(prd.description) LIKE :productInfo', { productInfo: productFilterValue })
1130
+ .orWhere('Lower(prd.brand) LIKE :productInfo', { productInfo: productFilterValue });
1131
+ }));
1132
+ const _products = await productQb.getMany();
1133
+ filters.push({
1134
+ name: 'product_id',
1135
+ operator: 'in',
1136
+ value: _products.map((product) => product.id)
1137
+ });
1138
+ }
1139
+ if (inventoryHistory && inventoryHistory.warehouseName) {
1140
+ const _warehouses = await tx.getRepository(warehouse_1.Warehouse).find({
1141
+ domain: domain,
1142
+ name: (0, typeorm_1.Raw)(alias => `LOWER(${alias}) LIKE '${inventoryHistory.warehouseName.toLowerCase()}'`)
1143
+ });
1144
+ filters.push({
1145
+ name: 'warehouse_id',
1146
+ operator: 'in',
1147
+ value: _warehouses.map((warehouse) => warehouse.id)
1148
+ });
1149
+ }
1150
+ if (inventoryHistory && inventoryHistory.locationName) {
1151
+ const _locations = await tx.getRepository(location_1.Location).find({
1152
+ where: {
1153
+ domain: domain,
1154
+ name: (0, typeorm_1.Raw)(alias => `LOWER(${alias}) LIKE '${inventoryHistory.locationName.toLowerCase()}'`)
1155
+ }
1156
+ });
1157
+ filters.push({
1158
+ name: 'location_id',
1159
+ operator: 'in',
1160
+ value: _locations.map((location) => location.id)
1161
+ });
1162
+ }
1163
+ filters.push({
1164
+ name: 'createdAt',
1165
+ operator: 'between',
1166
+ value: [fromDate, toDate]
1167
+ }, {
1168
+ name: 'bizplace_id',
1169
+ operator: 'eq',
1170
+ value: customerBizplace.id
1171
+ });
1172
+ const qb = (0, typeorm_1.getRepository)(inventory_history_1.InventoryHistory).createQueryBuilder('ih');
1173
+ (0, shell_1.buildQuery)(qb, { filters }, context);
1174
+ qb.select('prd.sku', 'sku')
1175
+ .addSelect('prd.name', 'productName')
1176
+ .addSelect('prd.description', 'productDescription')
1177
+ .addSelect('prd.brand', 'brand')
1178
+ .addSelect('ih.seq', 'seq')
1179
+ .addSelect('ih.pallet_id', 'palletId')
1180
+ .addSelect('ih.carton_id', 'cartonId')
1181
+ .addSelect('ih.batch_id', 'batchId')
1182
+ .addSelect('ih.batch_id_ref', 'batchIdRef')
1183
+ .addSelect('ih.opening_qty', 'openingQty')
1184
+ .addSelect('ih.qty', 'qty')
1185
+ .addSelect('ih.opening_uom_value', 'openingUomValue')
1186
+ .addSelect('ih.uom_value', 'uomValue')
1187
+ .addSelect('ih.uom', 'uom')
1188
+ .addSelect('ih.zone', 'zone')
1189
+ .addSelect('ih.order_no', 'orderNo')
1190
+ .addSelect('ih.order_ref_no', 'refNo')
1191
+ .addSelect('ih.status', 'status')
1192
+ .addSelect('ih.transaction_type', 'transactionType')
1193
+ .addSelect('bzp.name', 'bizplace')
1194
+ .addSelect('wh.name', 'warehouse')
1195
+ .addSelect('lc.name', 'location')
1196
+ .addSelect('ih.created_at', 'createdAt')
1197
+ .addSelect('ih.updated_at', 'updatedAt')
1198
+ .addSelect('up.name', 'updater')
1199
+ .leftJoin('ih.product', 'prd')
1200
+ .leftJoin('ih.warehouse', 'wh')
1201
+ .leftJoin('ih.location', 'lc')
1202
+ .leftJoin('ih.bizplace', 'bzp')
1203
+ .leftJoin('ih.updater', 'up')
1204
+ .orderBy('ih.pallet_id')
1205
+ .addOrderBy('ih.seq');
1206
+ const [items, total] = await Promise.all([qb.getRawMany(), qb.getCount()]);
1207
+ return { items, total };
1208
+ }
1209
+ async inventoryHistoryVolumeSummaryReport(params, context) {
1210
+ try {
1211
+ const { domain, user, tx } = context.state;
1212
+ let bizplaceFilter = { name: '', operator: '', value: '' };
1213
+ let userFilter = params.filters.find(data => data.name === 'user');
1214
+ let fromDate = params.filters.find(data => data.name === 'fromDate');
1215
+ let toDate = params.filters.find(data => data.name === 'toDate');
1216
+ if (userFilter) {
1217
+ const user = await tx.getRepository(auth_base_1.User).findOne({
1218
+ where: { id: userFilter.value },
1219
+ relations: ['bizplaces']
1220
+ });
1221
+ const bizplace = user.bizplaces[0];
1222
+ if (!bizplace)
1223
+ throw 'Invalid input';
1224
+ bizplaceFilter = { name: 'bizplace', operator: 'eq', value: bizplace.id };
1225
+ }
1226
+ else {
1227
+ bizplaceFilter = params.filters.find(data => data.name === 'bizplace');
1228
+ }
1229
+ if (!bizplaceFilter || !fromDate || !toDate)
1230
+ throw 'Invalid input';
1231
+ const bizplace = await tx.getRepository(biz_base_1.Bizplace).findOne({
1232
+ id: bizplaceFilter.value
1233
+ });
1234
+ //check if all product details got volume
1235
+ let foundPermittedBizplace;
1236
+ if (bizplace) {
1237
+ foundPermittedBizplace = await tx.getRepository(biz_base_1.Bizplace).findOne(bizplace.id, {
1238
+ relations: ['company', 'company.domain']
1239
+ });
1240
+ const companyDomain = foundPermittedBizplace.company.domain;
1241
+ let foundProductDetail = await tx
1242
+ .getRepository(product_base_1.ProductDetail)
1243
+ .createQueryBuilder('pd')
1244
+ .where('pd.domain = :domainId ', { domainId: companyDomain.id })
1245
+ .andWhere(new typeorm_1.Brackets(qb => {
1246
+ qb.where('pd.volume = 0').orWhere('pd.volume is null');
1247
+ }))
1248
+ .getOne();
1249
+ if (foundProductDetail) {
1250
+ throw new Error('there is product master with empty volume');
1251
+ }
1252
+ }
1253
+ await tx.query(`
1254
+ create temp table temp_reduced_inventory_histories ON COMMIT drop as (
1255
+ select
1256
+ row_number() over (order by cast(rih.created_at + (interval '8 hour') as DATE) ASC) as row,
1257
+ SUM(case when rih.transaction_type in ('UNLOADING', 'RETURN') then rih.qty end) as "inboundQty",
1258
+ round(cast(SUM(case when rih.transaction_type in ('UNLOADING', 'RETURN') then rih.qty * pd.volume end) as numeric), 2) as "inboundVolume",
1259
+ SUM(case when rih.transaction_type in ('ADJUSTMENT', 'NEW', 'CC_ADJUSTMENT') then rih.qty end) as "adjustedQty",
1260
+ 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",
1261
+ SUM(case when rih.transaction_type = 'ADJUSTMENT' and status = 'MISSING' then rih.opening_qty end) as "missingQty",
1262
+ round(cast(SUM(case when rih.transaction_type = 'ADJUSTMENT' and status = 'MISSING' then rih.opening_qty * pd.volume end) as numeric), 2) as "missingVolume",
1263
+ SUM(case when rih.transaction_type = 'PICKING' then -(rih.qty) end) as "outboundQty",
1264
+ round(cast(SUM(case when rih.transaction_type = 'PICKING' then -(rih.qty) * pd.volume end) as numeric), 2) as "outboundVolume",
1265
+ 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",
1266
+ 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",
1267
+ rih.bizplace_id as bizplace_id,
1268
+ cast(rih.created_at + (interval '8 hour') as DATE) as "tempDate"
1269
+ from reduced_inventory_histories rih
1270
+ left join product_details pd on pd.id = rih.product_detail_id
1271
+ where rih.status not like 'TERMINATED' and rih.bizplace_id = $1
1272
+ group by CAST(rih.created_at + (interval '8 hour') as DATE), rih.bizplace_id
1273
+ )
1274
+ `, [bizplace.id]);
1275
+ await tx.query(`
1276
+ create temp table temp_reduced_inventory_histories_with_date_range ON COMMIT drop as (
1277
+ select
1278
+ coalesce(tmp."tempDate", dr.range_date) as date,
1279
+ row_number() over (order by coalesce(tmp."tempDate", dr.range_date) ASC) as row,
1280
+ coalesce(tmp."inboundQty", 0) as "inboundQty",
1281
+ coalesce(tmp."inboundVolume", 0) as "inboundVolume",
1282
+ coalesce(tmp."adjustedQty", 0) as "adjustedQty",
1283
+ coalesce(tmp."adjustedVolume", 0) as "adjustedVolume",
1284
+ coalesce(tmp."missingQty", 0) as "missingQty",
1285
+ coalesce(tmp."missingVolume", 0) as "missingVolume",
1286
+ coalesce(tmp."outboundQty", 0) as "outboundQty",
1287
+ coalesce(tmp."outboundVolume", 0) as "outboundVolume",
1288
+ '${bizplace.id}' as bizplace_id,
1289
+ (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"
1290
+ from temp_reduced_inventory_histories tmp
1291
+ full join (
1292
+ select date_trunc('day', dd):: date as range_date
1293
+ from generate_series
1294
+ ( $1::timestamp
1295
+ , $2::timestamp
1296
+ , '1 day'::interval) dd
1297
+ ) dr on dr.range_date = tmp."tempDate" order by date
1298
+ )
1299
+ `, [fromDate.value, toDate.value]);
1300
+ await tx.query(`
1301
+ create temp table temp_result ON COMMIT drop as(
1302
+ select lag(sub."closingQty", 1, 0::double precision) over (partition by sub.bizplace_id order by sub.date) as "openingQty",
1303
+ lag(sub."closingVolume", 1, 0::numeric) over (partition by sub.bizplace_id order by sub.date) as "openingVolume", sub.* from(
1304
+ select (select sum(tmp2.total) from temp_reduced_inventory_histories_with_date_range tmp2 where tmp2.row <= tmp.row) as "closingQty",
1305
+ (select sum(tmp2."totalVolume") from temp_reduced_inventory_histories_with_date_range tmp2 where tmp2.row <= tmp.row) as "closingVolume", tmp.* from
1306
+ temp_reduced_inventory_histories_with_date_range tmp) sub
1307
+ )
1308
+ `);
1309
+ await tx.query(`
1310
+ create temp table temp_final ON COMMIT drop as(
1311
+ select * from temp_result tr where tr.date between $1 and $2 OFFSET $3 LIMIT $4
1312
+ )
1313
+ `, [fromDate.value, toDate.value, (params.pagination.page - 1) * params.pagination.limit, params.pagination.limit]);
1314
+ const result = await tx.query(`
1315
+ select * from temp_final
1316
+ `);
1317
+ const total = await tx.query(`
1318
+ select count(*), sum(tmp."inboundQty") as "totalInboundQty", sum(tmp."inboundVolume") as "totalInboundVolume",
1319
+ sum(tmp."adjustedQty") as "totalAdjustedQty", sum(tmp."adjustedVolume") as "totalAdjustedVolume",
1320
+ sum(tmp."missingQty") as "totalMissingQty", sum(tmp."missingVolume") as "totalMissingVolume",
1321
+ sum(tmp."outboundQty") as "totalOutboundQty", sum(tmp."outboundVolume") as "totalOutboundVolume" from temp_final tmp
1322
+ `);
1323
+ return {
1324
+ items: result,
1325
+ total: total[0].count,
1326
+ totalOpeningQty: (result === null || result === void 0 ? void 0 : result.length) > 0 ? result[0].openingQty : 0,
1327
+ totalOpeningVolume: (result === null || result === void 0 ? void 0 : result.length) > 0 ? result[0].openingVolume : 0,
1328
+ totalInboundQty: (result === null || result === void 0 ? void 0 : result.length) > 0 ? total[0].totalInboundQty : 0,
1329
+ totalInboundVolume: (result === null || result === void 0 ? void 0 : result.length) > 0 ? total[0].totalInboundVolume : 0,
1330
+ totalAdjustedQty: (result === null || result === void 0 ? void 0 : result.length) > 0 ? total[0].totalAdjustedQty : 0,
1331
+ totalAdjustedVolume: (result === null || result === void 0 ? void 0 : result.length) > 0 ? total[0].totalAdjustedVolume : 0,
1332
+ totalMissingQty: (result === null || result === void 0 ? void 0 : result.length) > 0 ? total[0].totalMissingQty : 0,
1333
+ totalMissingVolume: (result === null || result === void 0 ? void 0 : result.length) > 0 ? total[0].totalMissingVolume : 0,
1334
+ totalOutboundQty: (result === null || result === void 0 ? void 0 : result.length) > 0 ? total[0].totalOutboundQty : 0,
1335
+ totalOutboundVolume: (result === null || result === void 0 ? void 0 : result.length) > 0 ? total[0].totalOutboundVolume : 0,
1336
+ totalClosingQty: (result === null || result === void 0 ? void 0 : result.length) > 0 ? result[result.length - 1].closingQty : 0,
1337
+ totalClosingVolume: (result === null || result === void 0 ? void 0 : result.length) > 0 ? result[result.length - 1].closingVolume : 0
1338
+ };
1339
+ }
1340
+ catch (error) {
1341
+ throw error;
1342
+ }
1343
+ }
1344
+ async domain(inventoryHistory) {
1345
+ return await (0, typeorm_1.getRepository)(shell_1.Domain).findOne(inventoryHistory.domainId);
1346
+ }
1347
+ async updater(inventoryHistory) {
1348
+ return await (0, typeorm_1.getRepository)(auth_base_1.User).findOne(inventoryHistory.updaterId);
1349
+ }
1350
+ async creator(inventoryHistory) {
1351
+ return await (0, typeorm_1.getRepository)(auth_base_1.User).findOne(inventoryHistory.creatorId);
1352
+ }
1353
+ };
1354
+ __decorate([
1355
+ (0, type_graphql_1.Query)(returns => inventory_history_types_1.InventoryHistoryList),
1356
+ __param(0, (0, type_graphql_1.Args)()),
1357
+ __param(1, (0, type_graphql_1.Ctx)()),
1358
+ __metadata("design:type", Function),
1359
+ __metadata("design:paramtypes", [typeof (_a = typeof shell_1.ListParam !== "undefined" && shell_1.ListParam) === "function" ? _a : Object, Object]),
1360
+ __metadata("design:returntype", Promise)
1361
+ ], InventoryHistoryQuery.prototype, "inventoryHistories", null);
1362
+ __decorate([
1363
+ (0, type_graphql_1.Query)(returns => inventory_history_1.InventoryHistory),
1364
+ __param(0, (0, type_graphql_1.Arg)('name')),
1365
+ __param(1, (0, type_graphql_1.Ctx)()),
1366
+ __metadata("design:type", Function),
1367
+ __metadata("design:paramtypes", [String, Object]),
1368
+ __metadata("design:returntype", Promise)
1369
+ ], InventoryHistoryQuery.prototype, "inventoryHistory", null);
1370
+ __decorate([
1371
+ (0, type_graphql_1.Directive)('@transaction'),
1372
+ (0, type_graphql_1.Query)(returns => inventory_history_types_1.InventoryHistoryList),
1373
+ __param(0, (0, type_graphql_1.Ctx)()),
1374
+ __param(1, (0, type_graphql_1.Arg)('inventoryHistory', type => inventory_history_types_1.InventoryHistoryPatch, { nullable: true })),
1375
+ __param(2, (0, type_graphql_1.Arg)('filters', type => [shell_1.Filter], { nullable: true })),
1376
+ __param(3, (0, type_graphql_1.Arg)('pagination', type => shell_1.Pagination, { nullable: true })),
1377
+ __param(4, (0, type_graphql_1.Arg)('sortings', type => [shell_1.Sorting], { nullable: true })),
1378
+ __metadata("design:type", Function),
1379
+ __metadata("design:paramtypes", [Object, inventory_history_types_1.InventoryHistoryPatch, Array, typeof (_b = typeof shell_1.Pagination !== "undefined" && shell_1.Pagination) === "function" ? _b : Object, Array]),
1380
+ __metadata("design:returntype", Promise)
1381
+ ], InventoryHistoryQuery.prototype, "bizplaceInventoryHistories", null);
1382
+ __decorate([
1383
+ (0, type_graphql_1.Directive)('@transaction'),
1384
+ (0, type_graphql_1.Query)(returns => [inventory_history_1.InventoryHistory]),
1385
+ __param(0, (0, type_graphql_1.Args)()),
1386
+ __param(1, (0, type_graphql_1.Ctx)()),
1387
+ __metadata("design:type", Function),
1388
+ __metadata("design:paramtypes", [typeof (_c = typeof shell_1.ListParam !== "undefined" && shell_1.ListParam) === "function" ? _c : Object, Object]),
1389
+ __metadata("design:returntype", Promise)
1390
+ ], InventoryHistoryQuery.prototype, "inventoryHistoryReport", null);
1391
+ __decorate([
1392
+ (0, type_graphql_1.Directive)('@transaction'),
1393
+ (0, type_graphql_1.Query)(returns => [inventory_history_1.InventoryHistory]),
1394
+ __param(0, (0, type_graphql_1.Args)()),
1395
+ __param(1, (0, type_graphql_1.Ctx)()),
1396
+ __metadata("design:type", Function),
1397
+ __metadata("design:paramtypes", [typeof (_d = typeof shell_1.ListParam !== "undefined" && shell_1.ListParam) === "function" ? _d : Object, Object]),
1398
+ __metadata("design:returntype", Promise)
1399
+ ], InventoryHistoryQuery.prototype, "inventoryHistoryPalletReport", null);
1400
+ __decorate([
1401
+ (0, type_graphql_1.Directive)('@transaction'),
1402
+ (0, type_graphql_1.Query)(returns => [inventory_history_1.InventoryHistory]),
1403
+ __param(0, (0, type_graphql_1.Args)()),
1404
+ __param(1, (0, type_graphql_1.Ctx)()),
1405
+ __metadata("design:type", Function),
1406
+ __metadata("design:paramtypes", [typeof (_e = typeof shell_1.ListParam !== "undefined" && shell_1.ListParam) === "function" ? _e : Object, Object]),
1407
+ __metadata("design:returntype", Promise)
1408
+ ], InventoryHistoryQuery.prototype, "inventoryHistoryPalletDetailReport", null);
1409
+ __decorate([
1410
+ (0, type_graphql_1.Directive)('@transaction'),
1411
+ (0, type_graphql_1.Query)(returns => inventory_history_types_1.InventoryHistoryPalletReportList),
1412
+ __param(0, (0, type_graphql_1.Args)()),
1413
+ __param(1, (0, type_graphql_1.Ctx)()),
1414
+ __metadata("design:type", Function),
1415
+ __metadata("design:paramtypes", [typeof (_f = typeof shell_1.ListParam !== "undefined" && shell_1.ListParam) === "function" ? _f : Object, Object]),
1416
+ __metadata("design:returntype", Promise)
1417
+ ], InventoryHistoryQuery.prototype, "inventoryHistoryPalletStorageReport", null);
1418
+ __decorate([
1419
+ (0, type_graphql_1.Directive)('@transaction'),
1420
+ (0, type_graphql_1.Query)(returns => inventory_history_types_1.InventoryHistorySummaryList),
1421
+ __param(0, (0, type_graphql_1.Args)()),
1422
+ __param(1, (0, type_graphql_1.Ctx)()),
1423
+ __metadata("design:type", Function),
1424
+ __metadata("design:paramtypes", [typeof (_g = typeof shell_1.ListParam !== "undefined" && shell_1.ListParam) === "function" ? _g : Object, Object]),
1425
+ __metadata("design:returntype", Promise)
1426
+ ], InventoryHistoryQuery.prototype, "inventoryHistorySummaryReport", null);
1427
+ __decorate([
1428
+ (0, type_graphql_1.Directive)('@transaction'),
1429
+ (0, type_graphql_1.Query)(returns => inventory_types_1.InventoryList),
1430
+ __param(0, (0, type_graphql_1.Ctx)()),
1431
+ __param(1, (0, type_graphql_1.Arg)('filters', type => [shell_1.Filter], { nullable: true })),
1432
+ __param(2, (0, type_graphql_1.Arg)('pagination', type => shell_1.Pagination, { nullable: true })),
1433
+ __param(3, (0, type_graphql_1.Arg)('sortings', type => [shell_1.Sorting], { nullable: true })),
1434
+ __param(4, (0, type_graphql_1.Arg)('locationSortingRules', type => [shell_1.Sorting], { nullable: true })),
1435
+ __param(5, (0, type_graphql_1.Arg)('setPagination', type => Boolean, { defaultValue: true })),
1436
+ __metadata("design:type", Function),
1437
+ __metadata("design:paramtypes", [Object, Array, typeof (_h = typeof shell_1.Pagination !== "undefined" && shell_1.Pagination) === "function" ? _h : Object, Array, Array, Boolean]),
1438
+ __metadata("design:returntype", Promise)
1439
+ ], InventoryHistoryQuery.prototype, "onhandInventories", null);
1440
+ __decorate([
1441
+ (0, type_graphql_1.Directive)('@transaction'),
1442
+ (0, type_graphql_1.Query)(returns => __1.RawInventoryHistoryList),
1443
+ __param(0, (0, type_graphql_1.Ctx)()),
1444
+ __param(1, (0, type_graphql_1.Arg)('inventoryHistory', type => inventory_history_types_1.InventoryHistoryPatch, { nullable: true })),
1445
+ __param(2, (0, type_graphql_1.Arg)('filters', type => [shell_1.Filter], { nullable: true })),
1446
+ __metadata("design:type", Function),
1447
+ __metadata("design:paramtypes", [Object, inventory_history_types_1.InventoryHistoryPatch, Array]),
1448
+ __metadata("design:returntype", Promise)
1449
+ ], InventoryHistoryQuery.prototype, "bizplaceInventoryHistoriesForExport", null);
1450
+ __decorate([
1451
+ (0, type_graphql_1.Directive)('@transaction'),
1452
+ (0, type_graphql_1.Query)(returns => inventory_history_types_1.InventoryHistoryVolumeSummaryReportList),
1453
+ __param(0, (0, type_graphql_1.Args)()),
1454
+ __param(1, (0, type_graphql_1.Ctx)()),
1455
+ __metadata("design:type", Function),
1456
+ __metadata("design:paramtypes", [typeof (_j = typeof shell_1.ListParam !== "undefined" && shell_1.ListParam) === "function" ? _j : Object, Object]),
1457
+ __metadata("design:returntype", Promise)
1458
+ ], InventoryHistoryQuery.prototype, "inventoryHistoryVolumeSummaryReport", null);
1459
+ __decorate([
1460
+ (0, type_graphql_1.FieldResolver)(type => shell_1.Domain),
1461
+ __param(0, (0, type_graphql_1.Root)()),
1462
+ __metadata("design:type", Function),
1463
+ __metadata("design:paramtypes", [inventory_history_1.InventoryHistory]),
1464
+ __metadata("design:returntype", Promise)
1465
+ ], InventoryHistoryQuery.prototype, "domain", null);
1466
+ __decorate([
1467
+ (0, type_graphql_1.FieldResolver)(type => auth_base_1.User),
1468
+ __param(0, (0, type_graphql_1.Root)()),
1469
+ __metadata("design:type", Function),
1470
+ __metadata("design:paramtypes", [inventory_history_1.InventoryHistory]),
1471
+ __metadata("design:returntype", Promise)
1472
+ ], InventoryHistoryQuery.prototype, "updater", null);
1473
+ __decorate([
1474
+ (0, type_graphql_1.FieldResolver)(type => auth_base_1.User),
1475
+ __param(0, (0, type_graphql_1.Root)()),
1476
+ __metadata("design:type", Function),
1477
+ __metadata("design:paramtypes", [inventory_history_1.InventoryHistory]),
1478
+ __metadata("design:returntype", Promise)
1479
+ ], InventoryHistoryQuery.prototype, "creator", null);
1480
+ InventoryHistoryQuery = __decorate([
1481
+ (0, type_graphql_1.Resolver)(inventory_history_1.InventoryHistory)
1482
+ ], InventoryHistoryQuery);
1483
+ exports.InventoryHistoryQuery = InventoryHistoryQuery;
1484
+ async function massageInventorySummary(tx, params, bizplace, context) {
1485
+ await productsQuery(tx, params, bizplace);
1486
+ await filterInventoryQuery(tx, params, bizplace, context);
1487
+ let fromDate = params.filters.find(data => data.name === 'fromDate');
1488
+ let hasTransactionOrBalanceFilter = params.filters.find(data => data.name === 'hasTransactionOrBalance');
1489
+ let hasTransactionOrBalanceQuery = '';
1490
+ if (hasTransactionOrBalanceFilter && hasTransactionOrBalanceFilter.value) {
1491
+ hasTransactionOrBalanceQuery = 'and (opening_qty > 0 or total_in_qty > 0 or adjustment_qty > 0)';
1492
+ }
1493
+ await tx.query(`
1494
+ create temp table temp_inventory_summary ON COMMIT DROP as (
1495
+ select src.*,
1496
+ TRUNC(CAST(opening_qty + adjustment_qty + total_in_qty + total_out_qty + missing_qty AS NUMERIC), 3) as closing_qty
1497
+ from (
1498
+ 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,
1499
+ TRUNC(CAST(sum(case when ih.created_at >= $1 and ih.transaction_type = 'ADJUSTMENT' then ih.qty else 0 end) AS NUMERIC), 3) as adjustment_qty,
1500
+ TRUNC(CAST(sum(case when ih.created_at < $1 then qty else 0 end) AS NUMERIC), 3) as opening_qty,
1501
+ TRUNC(CAST(sum(case when ih.status = 'MISSING' then -ih.opening_qty else 0 end) AS NUMERIC), 3) as missing_qty,
1502
+ TRUNC(CAST(sum(case when ih.created_at >= $1 then case when ih.qty > 0 and ih.transaction_type <> 'ADJUSTMENT' and ih.transaction_type <> 'RELOCATE' then ih.qty else 0 end else 0 end) AS NUMERIC), 3) as total_in_qty,
1503
+ TRUNC(CAST(sum(case when ih.created_at >= $1 then case when ih.qty < 0 and ih.transaction_type <> 'ADJUSTMENT' and ih.transaction_type <> 'RELOCATE' then ih.qty else 0 end else 0 end) AS NUMERIC), 3) as total_out_qty,
1504
+ ih.product_id
1505
+ from temp_inv_history ih
1506
+ inner join temp_products prd on prd.id = ih.product_id
1507
+ group by prd.sku, prd.name, prd.description, prd.type, ih.product_id, ih.packing_type, ih.packing_size
1508
+ ) src
1509
+ where 1=1
1510
+ ${hasTransactionOrBalanceQuery}
1511
+ )
1512
+ `, [fromDate.value]);
1513
+ const total = await tx.query(`select count(*) from temp_inventory_summary`);
1514
+ const result = await tx.query(`
1515
+ select * from temp_inventory_summary ORDER BY product_name, product_description, product_type, packing_type, packing_size OFFSET $1 LIMIT $2
1516
+ `, [(params.pagination.page - 1) * params.pagination.limit, params.pagination.limit]);
1517
+ return [result, total];
1518
+ }
1519
+ async function massageInventoryPalletSummary(tx, params, bizplace, context) {
1520
+ await productsQuery(tx, params, bizplace);
1521
+ await filterInventoryQuery(tx, params, bizplace, context);
1522
+ let fromDate = params.filters.find(data => data.name === 'fromDate');
1523
+ let toDate = params.filters.find(data => data.name === 'toDate');
1524
+ let hasTransactionOrBalanceFilter = params.filters.find(data => data.name === 'hasTransactionOrBalance');
1525
+ let hasTransactionOrBalanceQuery = '';
1526
+ if (hasTransactionOrBalanceFilter && hasTransactionOrBalanceFilter.value) {
1527
+ hasTransactionOrBalanceQuery = 'and (opening_qty > 0 or total_in_qty > 0 or adjustment_qty > 0)';
1528
+ }
1529
+ await tx.query(`
1530
+ create temp table temp_inventory_pallet_summary ON COMMIT DROP as (
1531
+ select invh.*,
1532
+ invh.opening_qty + invh.total_in_qty + invh.total_out_qty + invh.adjustment_qty as closing_qty from (
1533
+ select product_sku, product_id, product_name, product_description, product_type,
1534
+ SUM(case when invHistory.created_at < $1 then
1535
+ case when invHistory.status = 'STORED' then 1
1536
+ when invhistory.status = 'TERMINATED' then -1
1537
+ else 0 end
1538
+ else 0 end) as opening_qty,
1539
+ SUM(case when invHistory.created_at >= $1 and invHistory.created_at <= $2 then
1540
+ case when (invHistory.transaction_type = 'UNLOADING' or invHistory.transaction_type = 'NEW' or invHistory.transaction_type = 'CANCEL_ORDER') then 1 else 0 end
1541
+ else 0 end) as total_in_qty,
1542
+ SUM(case when invHistory.created_at >= $1 and invHistory.created_at <= $2 then
1543
+ case when invHistory.status = 'TERMINATED' AND invHistory.transaction_type <> 'ADJUSTMENT' then -1 else 0 end
1544
+ else 0 end) as total_out_qty,
1545
+ SUM(case when invHistory.created_at >= $1 and invHistory.created_at <= $2 then
1546
+ case when invHistory.status = 'TERMINATED' AND invHistory.transaction_type = 'ADJUSTMENT' then -1
1547
+ when invHistory.status = 'STORED' AND invHistory.transaction_type = 'ADJUSTMENT' then 1 else 0 end
1548
+ else 0 end) as adjustment_qty
1549
+ from(
1550
+ select pallet_id, seq, status, transaction_type, product_sku, product_id, product_name, product_description, product_type,
1551
+ inventory_history_id, packing_type, packing_size, qty, opening_qty, created_at from (
1552
+ select row_number() over(partition by invh.pallet_id order by invh.created_at asc) as rn, invh.* ,
1553
+ prd.sku as product_sku, prd.name as product_name, prd.description as product_description, prd.type AS product_type
1554
+ from temp_inv_history invh
1555
+ inner join temp_products prd on prd.id = invh.product_id
1556
+ where (transaction_type = 'UNLOADING' or invh.transaction_type = 'NEW' or invh.transaction_type = 'CANCEL_ORDER')
1557
+ and invh.created_at >= $1
1558
+ ) as invIn where rn = 1
1559
+ union all
1560
+ select pallet_id, seq, status, transaction_type, product_sku, product_id, product_name, product_description, product_type,
1561
+ inventory_history_id, packing_type, packing_size, qty, opening_qty, created_at from (
1562
+ SELECT row_number() over(partition by pallet_id, invh.product_id order by seq asc) as rn,
1563
+ invh.pallet_id, invh.product_id, invh.packing_type, invh.packing_size,
1564
+ invh.batch_id, invh.inventory_history_id,
1565
+ invh.seq, 'STORED' AS status, invh.transaction_type, invh.qty, invh.opening_qty,
1566
+ invh.created_at,
1567
+ prd.sku as product_sku, prd.name as product_name, prd.description as product_description, prd.type AS product_type
1568
+ from temp_inv_history invh
1569
+ inner join temp_products prd on prd.id = invh.product_id
1570
+ where invh.created_at < $1
1571
+ and (invh.status = 'STORED' or invh.status = 'UNLOADED')
1572
+ ) as invStored where rn = 1
1573
+ union all
1574
+ select pallet_id, seq, status, transaction_type, product_sku, product_id, product_name, product_description, product_type,
1575
+ inventory_history_id, packing_type, packing_size, qty, opening_qty, started_at as created_at from (
1576
+ select row_number() over(partition by invh.pallet_id, invh.product_id order by invh.seq desc) as rn, invh.*,
1577
+ prd.sku as product_sku, prd.name as product_name, prd.description as product_description, prd.type AS product_type, repeatedGroup.started_at
1578
+ from temp_inv_history invh
1579
+ inner join (
1580
+ select pallet_id, min(created_at) as started_at, max(created_at) as ended_at, min(seq) as min_seq, max(seq) as max_seq, status from (
1581
+ select startData.*, sum(startflag) over (partition by pallet_id order by seq) as grp from (
1582
+ select s.*,
1583
+ (case when lag(status) over (partition by pallet_id order by seq) = status then 0 else 1 end) as startflag
1584
+ from temp_inv_history s
1585
+ ) startData
1586
+ ) endData
1587
+ group by pallet_id, grp, status
1588
+ ) repeatedGroup on repeatedGroup.pallet_id = invh.pallet_id and repeatedGroup.min_seq <= invh.seq and repeatedGroup.max_seq >= invh.seq
1589
+ inner join temp_products prd on prd.id = invh.product_id
1590
+ where invh.status = 'TERMINATED' and invh.transaction_type IN ('TERMINATED', 'ADJUSTMENT')
1591
+ ) as invOut where rn=1
1592
+ union all
1593
+ SELECT invh.pallet_id, invh.seq, invh.status, invh.transaction_type,
1594
+ prd.sku AS product_sku, invh.product_id, prd.name AS product_name, prd.description AS product_description, prd.type AS product_type,
1595
+ invh.inventory_history_id, invh.packing_type, invh.packing_size, invh.qty, invh.opening_qty, invh.created_at
1596
+ FROM temp_inv_history invh
1597
+ INNER JOIN (
1598
+ SELECT invh.pallet_id, invh.seq AS stored_seq, invh2.seq AS terminated_seq FROM temp_inv_history invh
1599
+ INNER JOIN temp_inv_history invh2 ON invh2.pallet_id = invh.pallet_id AND invh2.status='STORED' AND invh2.seq = invh.seq + 1 AND invh2.product_id <> invh.product_id
1600
+ WHERE invh.transaction_type = 'ADJUSTMENT'
1601
+ ) dt ON dt.pallet_id = invh.pallet_id AND (dt.stored_seq = invh.seq OR dt.terminated_seq = invh.seq)
1602
+ inner join temp_products prd on prd.id = invh.product_id
1603
+ where invh.created_at >= $1
1604
+ ORDER BY product_name, pallet_id, seq
1605
+ ) as invHistory
1606
+ group by product_sku, product_id, product_name, product_description, product_type
1607
+ ) invh
1608
+ where 1=1
1609
+ ${hasTransactionOrBalanceQuery}
1610
+ )
1611
+ `, [fromDate.value, toDate.value]);
1612
+ const total = await tx.query(`select count(*) as count, sum(total_in_qty) as totalInQty, sum(opening_qty) as totalOpeningBal from temp_inventory_pallet_summary`);
1613
+ const result = await tx.query(`
1614
+ select *, 'PALLET' as packing_type from temp_inventory_pallet_summary ORDER BY product_name, product_description OFFSET $1 LIMIT $2
1615
+ `, [(params.pagination.page - 1) * params.pagination.limit, params.pagination.limit]);
1616
+ return [result, total];
1617
+ }
1618
+ async function productsQuery(tx, params, bizplace) {
1619
+ let product = params.filters.find(data => data.name === 'product');
1620
+ let productDesc = params.filters.find(data => data.name === 'productDescription');
1621
+ let productType = params.filters.find(data => data.name === 'productType');
1622
+ let productQuery = '';
1623
+ if (product) {
1624
+ let productValue = product.value
1625
+ .toLowerCase()
1626
+ .split(',')
1627
+ .map(prod => {
1628
+ return "'%" + prod.trim().replace(/'/g, "''") + "%'";
1629
+ })
1630
+ .join(',');
1631
+ productQuery = `AND (
1632
+ Lower(prd.name) LIKE ANY(ARRAY[${productValue}])
1633
+ OR Lower(prd.sku) LIKE ANY(ARRAY[${productValue}])
1634
+ OR Lower(prd.description) LIKE ANY(ARRAY[${productValue}])
1635
+ )`;
1636
+ }
1637
+ let productDescQuery = '';
1638
+ if (productDesc) {
1639
+ productDescQuery = "AND Lower(prd.description) LIKE '%" + productDesc.value.toLowerCase() + "%'";
1640
+ }
1641
+ let productTypeQuery = '';
1642
+ if (productType) {
1643
+ productTypeQuery = "AND prd.type = '" + productType.value + "'";
1644
+ }
1645
+ await tx.query(`
1646
+ create temp table temp_products ON COMMIT DROP AS
1647
+ (
1648
+ select prd.id, prd.name, prd.sku, prd.description, prd.id::varchar as product_id, prd.type from products prd
1649
+ inner join bizplaces b on b.id = prd.bizplace_id
1650
+ inner join companies c on c.domain_id = b.domain_id
1651
+ inner join bizplaces b2 on b2.company_id = c.id
1652
+ where b2.id = $1
1653
+ ${productQuery}
1654
+ ${productDescQuery}
1655
+ ${productTypeQuery}
1656
+ GROUP BY prd.id, prd.sku, prd.name, prd.description
1657
+ )`, [bizplace.id]);
1658
+ }
1659
+ async function filterInventoryQuery(tx, params, bizplace, context) {
1660
+ let toDate = params.filters.find(data => data.name === 'toDate');
1661
+ let batchNo = params.filters.find(data => data.name === 'batchNo');
1662
+ let batchNoQuery = '';
1663
+ if (batchNo) {
1664
+ batchNoQuery =
1665
+ 'AND Lower(ih.batch_id) LIKE ANY(ARRAY[' +
1666
+ batchNo.value
1667
+ .toLowerCase()
1668
+ .split(',')
1669
+ .map(prod => {
1670
+ return "'%" + prod.trim().replace(/'/g, "''") + "%'";
1671
+ })
1672
+ .join(',') +
1673
+ '])';
1674
+ }
1675
+ await tx.query(`
1676
+ create temp table temp_inv_history ON COMMIT DROP as (
1677
+ WITH filtered_histories AS (
1678
+ SELECT *
1679
+ FROM reduced_inventory_histories
1680
+ WHERE domain_id = $1
1681
+ AND bizplace_id = $2
1682
+ AND created_at <= $3
1683
+ )
1684
+ SELECT i2.pallet_id, ih.product_id::uuid, ih.packing_type, i2.packing_size, ih.batch_id,
1685
+ ih.id AS inventory_history_id, ih.seq, ih.status, ih.transaction_type, ih.qty, ih.opening_qty, ih.created_at
1686
+ FROM inventories i2
1687
+ INNER JOIN filtered_histories ih
1688
+ ON ih.pallet_id = i2.pallet_id
1689
+ AND ih.domain_id = i2.domain_id
1690
+ ${batchNoQuery}
1691
+ )
1692
+ `, [context.state.domain.id, bizplace.id, toDate.value]);
1693
+ }
1694
+ //# sourceMappingURL=inventory-history-query.js.map