@things-factory/worksheet-base 4.3.355 → 4.3.357

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 (121) hide show
  1. package/dist-server/constants/worksheet.js +2 -1
  2. package/dist-server/constants/worksheet.js.map +1 -1
  3. package/dist-server/controllers/inspect/cycle-count-worksheet-controller.js +691 -257
  4. package/dist-server/controllers/inspect/cycle-count-worksheet-controller.js.map +1 -1
  5. package/dist-server/controllers/outbound/picking-worksheet-controller.js +76 -0
  6. package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
  7. package/dist-server/controllers/worksheet-controller.js +9 -2
  8. package/dist-server/controllers/worksheet-controller.js.map +1 -1
  9. package/dist-server/entities/worksheet-detail.js +9 -4
  10. package/dist-server/entities/worksheet-detail.js.map +1 -1
  11. package/dist-server/entities/worksheet.js +4 -0
  12. package/dist-server/entities/worksheet.js.map +1 -1
  13. package/dist-server/graphql/resolvers/worksheet/check-stock-take-current-location.js +18 -11
  14. package/dist-server/graphql/resolvers/worksheet/check-stock-take-current-location.js.map +1 -1
  15. package/dist-server/graphql/resolvers/worksheet/cycle-count-adjustment.js +75 -48
  16. package/dist-server/graphql/resolvers/worksheet/cycle-count-adjustment.js.map +1 -1
  17. package/dist-server/graphql/resolvers/worksheet/cycle-count-worksheet-for-carton.js +82 -0
  18. package/dist-server/graphql/resolvers/worksheet/cycle-count-worksheet-for-carton.js.map +1 -0
  19. package/dist-server/graphql/resolvers/worksheet/cycle-count-worksheet-for-pallet.js +82 -0
  20. package/dist-server/graphql/resolvers/worksheet/cycle-count-worksheet-for-pallet.js.map +1 -0
  21. package/dist-server/graphql/resolvers/worksheet/generate-worksheet/generate-cycle-count-worksheet-carton.js +17 -0
  22. package/dist-server/graphql/resolvers/worksheet/generate-worksheet/generate-cycle-count-worksheet-carton.js.map +1 -0
  23. package/dist-server/graphql/resolvers/worksheet/generate-worksheet/generate-cycle-count-worksheet.js +4 -4
  24. package/dist-server/graphql/resolvers/worksheet/generate-worksheet/generate-cycle-count-worksheet.js.map +1 -1
  25. package/dist-server/graphql/resolvers/worksheet/generate-worksheet/index.js +2 -1
  26. package/dist-server/graphql/resolvers/worksheet/generate-worksheet/index.js.map +1 -1
  27. package/dist-server/graphql/resolvers/worksheet/index.js +3 -2
  28. package/dist-server/graphql/resolvers/worksheet/index.js.map +1 -1
  29. package/dist-server/graphql/resolvers/worksheet/inspecting/add-extra-inventory.js +16 -0
  30. package/dist-server/graphql/resolvers/worksheet/inspecting/add-extra-inventory.js.map +1 -0
  31. package/dist-server/graphql/resolvers/worksheet/inspecting/check-missing-inventory-carton.js +16 -0
  32. package/dist-server/graphql/resolvers/worksheet/inspecting/check-missing-inventory-carton.js.map +1 -0
  33. package/dist-server/graphql/resolvers/worksheet/inspecting/check-missing-inventory.js +16 -0
  34. package/dist-server/graphql/resolvers/worksheet/inspecting/check-missing-inventory.js.map +1 -0
  35. package/dist-server/graphql/resolvers/worksheet/inspecting/index.js +9 -5
  36. package/dist-server/graphql/resolvers/worksheet/inspecting/index.js.map +1 -1
  37. package/dist-server/graphql/resolvers/worksheet/inspecting/inspecting-carton.js +16 -0
  38. package/dist-server/graphql/resolvers/worksheet/inspecting/inspecting-carton.js.map +1 -0
  39. package/dist-server/graphql/resolvers/worksheet/inspecting/inspecting-pallet.js +16 -0
  40. package/dist-server/graphql/resolvers/worksheet/inspecting/inspecting-pallet.js.map +1 -0
  41. package/dist-server/graphql/resolvers/worksheet/inspecting/relocate-inventory-carton.js +16 -0
  42. package/dist-server/graphql/resolvers/worksheet/inspecting/relocate-inventory-carton.js.map +1 -0
  43. package/dist-server/graphql/resolvers/worksheet/inspecting/relocate-inventory.js +16 -0
  44. package/dist-server/graphql/resolvers/worksheet/inspecting/relocate-inventory.js.map +1 -0
  45. package/dist-server/graphql/resolvers/worksheet/inspecting/undo-inspection-carton.js +16 -0
  46. package/dist-server/graphql/resolvers/worksheet/inspecting/undo-inspection-carton.js.map +1 -0
  47. package/dist-server/graphql/resolvers/worksheet/not-tally-target-inventories.js +9 -5
  48. package/dist-server/graphql/resolvers/worksheet/not-tally-target-inventories.js.map +1 -1
  49. package/dist-server/graphql/resolvers/worksheet/worksheet-with-pagination.js +9 -7
  50. package/dist-server/graphql/resolvers/worksheet/worksheet-with-pagination.js.map +1 -1
  51. package/dist-server/graphql/resolvers/worksheet/worksheets.js +23 -9
  52. package/dist-server/graphql/resolvers/worksheet/worksheets.js.map +1 -1
  53. package/dist-server/graphql/resolvers/worksheet-detail/create-worksheet-detail.js +8 -1
  54. package/dist-server/graphql/resolvers/worksheet-detail/create-worksheet-detail.js.map +1 -1
  55. package/dist-server/graphql/resolvers/worksheet-detail/worksheet-detail.js +12 -1
  56. package/dist-server/graphql/resolvers/worksheet-detail/worksheet-detail.js.map +1 -1
  57. package/dist-server/graphql/types/worksheet/index.js +65 -9
  58. package/dist-server/graphql/types/worksheet/index.js.map +1 -1
  59. package/dist-server/graphql/types/worksheet/inventory-check-worksheet.js +2 -1
  60. package/dist-server/graphql/types/worksheet/inventory-check-worksheet.js.map +1 -1
  61. package/dist-server/graphql/types/worksheet/worksheet-detail-info.js +3 -0
  62. package/dist-server/graphql/types/worksheet/worksheet-detail-info.js.map +1 -1
  63. package/dist-server/graphql/types/worksheet/worksheet.js +2 -0
  64. package/dist-server/graphql/types/worksheet/worksheet.js.map +1 -1
  65. package/dist-server/graphql/types/worksheet-detail/new-worksheet-detail.js +1 -0
  66. package/dist-server/graphql/types/worksheet-detail/new-worksheet-detail.js.map +1 -1
  67. package/dist-server/graphql/types/worksheet-detail/worksheet-detail-patch.js +1 -0
  68. package/dist-server/graphql/types/worksheet-detail/worksheet-detail-patch.js.map +1 -1
  69. package/dist-server/graphql/types/worksheet-detail/worksheet-detail.js +1 -0
  70. package/dist-server/graphql/types/worksheet-detail/worksheet-detail.js.map +1 -1
  71. package/dist-server/utils/lmd-util.js +10 -10
  72. package/dist-server/utils/lmd-util.js.map +1 -1
  73. package/package.json +6 -6
  74. package/server/constants/worksheet.ts +2 -1
  75. package/server/controllers/inspect/cycle-count-worksheet-controller.ts +904 -296
  76. package/server/controllers/outbound/picking-worksheet-controller.ts +95 -1
  77. package/server/controllers/worksheet-controller.ts +10 -4
  78. package/server/entities/worksheet-detail.ts +7 -10
  79. package/server/entities/worksheet.ts +3 -0
  80. package/server/graphql/resolvers/worksheet/check-stock-take-current-location.ts +21 -14
  81. package/server/graphql/resolvers/worksheet/cycle-count-adjustment.ts +114 -51
  82. package/server/graphql/resolvers/worksheet/cycle-count-worksheet-for-carton.ts +90 -0
  83. package/server/graphql/resolvers/worksheet/cycle-count-worksheet-for-pallet.ts +91 -0
  84. package/server/graphql/resolvers/worksheet/generate-worksheet/generate-cycle-count-worksheet-carton.ts +57 -0
  85. package/server/graphql/resolvers/worksheet/generate-worksheet/generate-cycle-count-worksheet.ts +17 -11
  86. package/server/graphql/resolvers/worksheet/generate-worksheet/index.ts +2 -0
  87. package/server/graphql/resolvers/worksheet/index.ts +4 -2
  88. package/server/graphql/resolvers/worksheet/inspecting/{add-extra-pallet.ts → add-extra-inventory.ts} +27 -12
  89. package/server/graphql/resolvers/worksheet/inspecting/check-missing-inventory-carton.ts +24 -0
  90. package/server/graphql/resolvers/worksheet/inspecting/{check-missing-pallet.ts → check-missing-inventory.ts} +10 -5
  91. package/server/graphql/resolvers/worksheet/inspecting/index.ts +17 -9
  92. package/server/graphql/resolvers/worksheet/inspecting/inspecting-carton.ts +51 -0
  93. package/server/graphql/resolvers/worksheet/inspecting/{inspecting.ts → inspecting-pallet.ts} +5 -5
  94. package/server/graphql/resolvers/worksheet/inspecting/relocate-inventory-carton.ts +62 -0
  95. package/server/graphql/resolvers/worksheet/inspecting/{relocate-pallet.ts → relocate-inventory.ts} +15 -5
  96. package/server/graphql/resolvers/worksheet/inspecting/undo-inspection-carton.ts +24 -0
  97. package/server/graphql/resolvers/worksheet/not-tally-target-inventories.ts +11 -7
  98. package/server/graphql/resolvers/worksheet/worksheet-with-pagination.ts +9 -7
  99. package/server/graphql/resolvers/worksheet/worksheets.ts +57 -38
  100. package/server/graphql/resolvers/worksheet-detail/create-worksheet-detail.ts +10 -2
  101. package/server/graphql/resolvers/worksheet-detail/worksheet-detail.ts +12 -1
  102. package/server/graphql/types/worksheet/index.ts +65 -9
  103. package/server/graphql/types/worksheet/inventory-check-worksheet.ts +2 -1
  104. package/server/graphql/types/worksheet/worksheet-detail-info.ts +3 -0
  105. package/server/graphql/types/worksheet/worksheet.ts +2 -0
  106. package/server/graphql/types/worksheet-detail/new-worksheet-detail.ts +1 -0
  107. package/server/graphql/types/worksheet-detail/worksheet-detail-patch.ts +1 -0
  108. package/server/graphql/types/worksheet-detail/worksheet-detail.ts +1 -0
  109. package/server/utils/lmd-util.ts +30 -45
  110. package/tsconfig.json +1 -1
  111. package/dist-server/graphql/resolvers/worksheet/cycle-count-worksheet.js +0 -74
  112. package/dist-server/graphql/resolvers/worksheet/cycle-count-worksheet.js.map +0 -1
  113. package/dist-server/graphql/resolvers/worksheet/inspecting/add-extra-pallet.js +0 -16
  114. package/dist-server/graphql/resolvers/worksheet/inspecting/add-extra-pallet.js.map +0 -1
  115. package/dist-server/graphql/resolvers/worksheet/inspecting/check-missing-pallet.js +0 -16
  116. package/dist-server/graphql/resolvers/worksheet/inspecting/check-missing-pallet.js.map +0 -1
  117. package/dist-server/graphql/resolvers/worksheet/inspecting/inspecting.js +0 -16
  118. package/dist-server/graphql/resolvers/worksheet/inspecting/inspecting.js.map +0 -1
  119. package/dist-server/graphql/resolvers/worksheet/inspecting/relocate-pallet.js +0 -16
  120. package/dist-server/graphql/resolvers/worksheet/inspecting/relocate-pallet.js.map +0 -1
  121. package/server/graphql/resolvers/worksheet/cycle-count-worksheet.ts +0 -80
@@ -5,176 +5,315 @@ const typeorm_1 = require("typeorm");
5
5
  const biz_base_1 = require("@things-factory/biz-base");
6
6
  const sales_base_1 = require("@things-factory/sales-base");
7
7
  const warehouse_base_1 = require("@things-factory/warehouse-base");
8
+ const product_base_1 = require("@things-factory/product-base");
9
+ const setting_base_1 = require("@things-factory/setting-base");
10
+ const id_rule_base_1 = require("@things-factory/id-rule-base");
8
11
  const constants_1 = require("../../constants");
9
12
  const entities_1 = require("../../entities");
10
13
  const utils_1 = require("../../utils");
11
14
  const worksheet_controller_1 = require("../worksheet-controller");
12
15
  class CycleCountWorksheetController extends worksheet_controller_1.WorksheetController {
13
- async generateCycleCountWorksheet(executionDate, customerId, orderInventoryIds = [], orderInventory, limit) {
14
- // Find out warehouse and customer bizplace
16
+ async createCycleCountWorksheet(customerBizplace, customerId, executionDate, inventoryCheckItem, selectedLocation, limit) {
17
+ const cycleCount = await (0, sales_base_1.generateCycleCount)(this.trxMgr, this.domain, this.user, executionDate, customerId);
18
+ // Find out inventories which is target for cycle counting
19
+ const qb = this.trxMgr.getRepository(warehouse_base_1.Inventory).createQueryBuilder('INV');
20
+ qb.leftJoinAndSelect('INV.location', 'LOC')
21
+ .leftJoinAndSelect('INV.product', 'PROD')
22
+ .leftJoinAndSelect('INV.productDetail', 'PD')
23
+ .where('INV.domain_id = :domainId', { domainId: this.domain.id })
24
+ .andWhere('INV.bizplace_id = :bizplaceId', { bizplaceId: customerBizplace.id })
25
+ .andWhere('INV.status = :status', { status: warehouse_base_1.INVENTORY_STATUS.STORED });
26
+ if (inventoryCheckItem && inventoryCheckItem.length > 0) {
27
+ let keyval = {
28
+ batchId: 'batch_id',
29
+ batchIdRef: 'batch_id_ref',
30
+ productDetailId: 'product_detail_id'
31
+ };
32
+ qb.andWhere(new typeorm_1.Brackets(qb => {
33
+ inventoryCheckItem.forEach((itm, idx) => {
34
+ qb.orWhere(new typeorm_1.Brackets(qb2 => {
35
+ let first = true;
36
+ for (var prop in itm) {
37
+ if (first) {
38
+ first = false;
39
+ qb2.where(`INV.${keyval[prop]} ${itm[prop] == null ? 'is null' : " = '" + itm[prop] + "'"}`);
40
+ }
41
+ else {
42
+ qb2.andWhere(`INV.${keyval[prop]} ${itm[prop] == null ? 'is null' : " = '" + itm[prop] + "'"}`);
43
+ }
44
+ }
45
+ }));
46
+ });
47
+ }));
48
+ }
49
+ else if (selectedLocation && selectedLocation.length > 0) {
50
+ // If selectedLocation is provided
51
+ // Query inventory items located at the selected location
52
+ qb.andWhere('INV.location_id IN (:...locationIds)', { locationIds: selectedLocation });
53
+ }
54
+ else {
55
+ if (limit > 0) {
56
+ qb.orderBy('RANDOM()').limit(limit);
57
+ }
58
+ }
59
+ let inventories = await qb.getMany();
60
+ if (!inventories.length) {
61
+ throw new Error(`Failed to find inventories`);
62
+ }
63
+ let cycleCountWorksheet = new entities_1.Worksheet();
64
+ cycleCountWorksheet.domain = this.domain;
65
+ cycleCountWorksheet.bizplace = customerBizplace;
66
+ cycleCountWorksheet.name = utils_1.WorksheetNoGenerator.cycleCount();
67
+ cycleCountWorksheet.inventoryCheck = cycleCount;
68
+ cycleCountWorksheet.type = constants_1.WORKSHEET_TYPE.CYCLE_COUNT;
69
+ cycleCountWorksheet.status = constants_1.WORKSHEET_STATUS.DEACTIVATED;
70
+ cycleCountWorksheet.checkCount = 1;
71
+ cycleCountWorksheet.creator = this.user;
72
+ cycleCountWorksheet.updater = this.user;
73
+ cycleCountWorksheet = await this.trxMgr.getRepository(entities_1.Worksheet).save(cycleCountWorksheet);
74
+ // generate order inventory mapping with inventory ID
75
+ let targetInventoryCheckItems = [];
76
+ for (let i = 0; i < inventories.length; i++) {
77
+ const inventory = inventories[i];
78
+ let targetInventoryCheckItem = new sales_base_1.InventoryCheckItem();
79
+ targetInventoryCheckItem.domain = this.domain;
80
+ targetInventoryCheckItem.bizplace = customerBizplace;
81
+ targetInventoryCheckItem.status = sales_base_1.INVENTORY_CHECK_ITEM_STATUS.PENDING;
82
+ targetInventoryCheckItem.name = sales_base_1.OrderNoGenerator.inventoryCheckItem();
83
+ targetInventoryCheckItem.inventoryCheck = cycleCount;
84
+ targetInventoryCheckItem.originQty = inventory.qty;
85
+ targetInventoryCheckItem.originWeight = 0;
86
+ targetInventoryCheckItem.originUomValue = inventory.uomValue;
87
+ targetInventoryCheckItem.originBatchNo = inventory.batchId;
88
+ targetInventoryCheckItem.originLocation = inventory.location;
89
+ targetInventoryCheckItem.inventory = inventory;
90
+ targetInventoryCheckItem.product = inventory.product;
91
+ targetInventoryCheckItem.productDetail = inventory.productDetail;
92
+ targetInventoryCheckItem.countNo = 1;
93
+ targetInventoryCheckItem.creator = this.user;
94
+ targetInventoryCheckItem.updater = this.user;
95
+ targetInventoryCheckItems.push(targetInventoryCheckItem);
96
+ inventory.updater = this.user;
97
+ }
98
+ targetInventoryCheckItems = await this.trxMgr
99
+ .getRepository(sales_base_1.InventoryCheckItem)
100
+ .save(targetInventoryCheckItems, { chunk: 500 });
101
+ inventories = await this.trxMgr.getRepository(warehouse_base_1.Inventory).save(inventories, { chunk: 500 });
102
+ let cycleCountWorksheetDetails = [];
103
+ for (let i = 0; i < targetInventoryCheckItems.length; i++) {
104
+ let targetInventoryCheckItem = targetInventoryCheckItems[i];
105
+ let cycleCountWorksheetDetail = new entities_1.WorksheetDetail();
106
+ cycleCountWorksheetDetail.domain = this.domain;
107
+ cycleCountWorksheetDetail.bizplace = customerBizplace;
108
+ cycleCountWorksheetDetail.worksheet = cycleCountWorksheet;
109
+ cycleCountWorksheetDetail.name = utils_1.WorksheetNoGenerator.cycleCountDetail();
110
+ cycleCountWorksheetDetail.targetInventoryCheckItem = targetInventoryCheckItem;
111
+ cycleCountWorksheetDetail.type = constants_1.WORKSHEET_TYPE.CYCLE_COUNT;
112
+ cycleCountWorksheetDetail.status = constants_1.WORKSHEET_STATUS.DEACTIVATED;
113
+ cycleCountWorksheetDetail.creator = this.user;
114
+ cycleCountWorksheetDetail.updater = this.user;
115
+ cycleCountWorksheetDetails.push(cycleCountWorksheetDetail);
116
+ }
117
+ await this.trxMgr.getRepository(entities_1.WorksheetDetail).save(cycleCountWorksheetDetails, { chunk: 500 });
118
+ return cycleCountWorksheet;
119
+ }
120
+ async createNextRoundCycleCountWorksheet(customerId, existingInventoryCheck, nextExecutionDate, currentCycleCountWorksheet, inventoryCheckItemIds) {
121
+ try {
122
+ // Step 1: Create a new cycle count worksheet for the next round
123
+ let nextRoundWorksheet = new entities_1.Worksheet();
124
+ Object.assign(nextRoundWorksheet, currentCycleCountWorksheet);
125
+ nextRoundWorksheet.id = undefined;
126
+ nextRoundWorksheet.domain = this.domain;
127
+ nextRoundWorksheet.bizplace = customerId;
128
+ nextRoundWorksheet.name = utils_1.WorksheetNoGenerator.cycleCount();
129
+ nextRoundWorksheet.status = constants_1.WORKSHEET_STATUS.EXECUTING;
130
+ nextRoundWorksheet.endedAt = null;
131
+ nextRoundWorksheet.updater = this.user;
132
+ nextRoundWorksheet.worksheetDetails = null;
133
+ nextRoundWorksheet.checkCount = currentCycleCountWorksheet.checkCount + 1;
134
+ nextRoundWorksheet.inventoryCheck = existingInventoryCheck;
135
+ nextRoundWorksheet.type = constants_1.WORKSHEET_TYPE.CYCLE_COUNT;
136
+ // Step 2: Save the new Worksheet
137
+ await this.trxMgr.getRepository(entities_1.Worksheet).save(nextRoundWorksheet);
138
+ // Step 3: Fetch current InventoryCheckItems
139
+ const currentInventoryCheckItems = await this.trxMgr
140
+ .getRepository(sales_base_1.InventoryCheckItem)
141
+ .findByIds(inventoryCheckItemIds);
142
+ // Step 4: Create new InventoryCheckItems based on the current ones
143
+ const nextRoundInventoryCheckItems = currentInventoryCheckItems.map(currentItem => {
144
+ let nextRoundItem = new sales_base_1.InventoryCheckItem();
145
+ Object.assign(nextRoundItem, currentItem);
146
+ nextRoundItem.id = undefined;
147
+ nextRoundItem.domain = this.domain;
148
+ nextRoundItem.bizplace = customerId;
149
+ nextRoundItem.inventoryCheck = currentItem.inventoryCheckId;
150
+ nextRoundItem.status = sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTING;
151
+ nextRoundItem.name = sales_base_1.OrderNoGenerator.inventoryCheckItem();
152
+ nextRoundItem.originQty = currentItem.inspectedQty || currentItem.originQty;
153
+ nextRoundItem.originUomValue = currentItem.inspectedUomValue || currentItem.originUomValue;
154
+ nextRoundItem.originBatchNo = currentItem.inspectedBatchNo || currentItem.originBatchNo;
155
+ nextRoundItem.originLocation = currentItem.inspectedLocationId || currentItem.originLocationId;
156
+ nextRoundItem.inspectedQty = null;
157
+ nextRoundItem.inspectedUomValue = null;
158
+ nextRoundItem.inspectedBatchNo = null;
159
+ nextRoundItem.inspectedLocationId = null;
160
+ nextRoundItem.countNo = currentItem.countNo + 1;
161
+ nextRoundItem.inventory = currentItem.inventoryId;
162
+ nextRoundItem.product = currentItem.productId;
163
+ nextRoundItem.productDetail = currentItem.productDetailId;
164
+ nextRoundItem.creator = this.user;
165
+ nextRoundItem.updater = this.user;
166
+ return nextRoundItem;
167
+ });
168
+ // Step 5: Save the new InventoryCheckItems
169
+ await this.trxMgr.getRepository(sales_base_1.InventoryCheckItem).save(nextRoundInventoryCheckItems, { chunk: 500 });
170
+ // Step 6: Create a new cycle count worksheet details for the next round
171
+ let nextRoundWorksheetDetails = nextRoundInventoryCheckItems.map(newItem => {
172
+ let detail = new entities_1.WorksheetDetail();
173
+ detail.domain = this.domain;
174
+ detail.bizplace = customerId;
175
+ detail.worksheet = nextRoundWorksheet;
176
+ detail.name = utils_1.WorksheetNoGenerator.cycleCountDetail();
177
+ detail.targetInventoryCheckItem = newItem;
178
+ detail.type = constants_1.WORKSHEET_TYPE.CYCLE_COUNT;
179
+ detail.status = constants_1.WORKSHEET_STATUS.EXECUTING;
180
+ detail.creator = this.user;
181
+ detail.updater = this.user;
182
+ return detail;
183
+ });
184
+ // Step 7: Save the new Worksheet Details
185
+ await this.trxMgr.getRepository(entities_1.WorksheetDetail).save(nextRoundWorksheetDetails, { chunk: 500 });
186
+ // Step 8: Mark the selected inventory as TERMINATED
187
+ currentInventoryCheckItems.forEach(item => {
188
+ item.status = sales_base_1.INVENTORY_CHECK_ITEM_STATUS.TERMINATED;
189
+ item.updater = this.user;
190
+ });
191
+ await this.trxMgr.getRepository(sales_base_1.InventoryCheckItem).save(currentInventoryCheckItems);
192
+ // Step 9: Directly update the worksheet details
193
+ await this.trxMgr
194
+ .getRepository(entities_1.WorksheetDetail)
195
+ .createQueryBuilder()
196
+ .update(entities_1.WorksheetDetail)
197
+ .set({
198
+ status: constants_1.WORKSHEET_STATUS.DONE,
199
+ updater: this.user
200
+ })
201
+ .where('targetInventoryCheckItem IN (:...ids)', { ids: currentInventoryCheckItems.map(item => item.id) })
202
+ .execute();
203
+ // Check if any record is not DONE
204
+ const notDoneCount = await this.trxMgr.getRepository(entities_1.WorksheetDetail).count({
205
+ where: {
206
+ worksheet: currentCycleCountWorksheet,
207
+ status: (0, typeorm_1.Not)((0, typeorm_1.Equal)(constants_1.WORKSHEET_STATUS.DONE))
208
+ }
209
+ });
210
+ if (notDoneCount === 0) {
211
+ // Step 11: Update status of existing InventoryCheck
212
+ existingInventoryCheck.status = sales_base_1.ORDER_STATUS.INSPECTING;
213
+ existingInventoryCheck.updater = this.user;
214
+ await this.trxMgr.getRepository(sales_base_1.InventoryCheck).save(existingInventoryCheck);
215
+ // Step 12: Mark the current worksheet as DONE
216
+ currentCycleCountWorksheet.status = constants_1.WORKSHEET_STATUS.DONE;
217
+ currentCycleCountWorksheet.updater = this.user;
218
+ await this.trxMgr.getRepository(entities_1.Worksheet).save(currentCycleCountWorksheet);
219
+ }
220
+ existingInventoryCheck.executionDate = nextExecutionDate;
221
+ existingInventoryCheck.updater = this.user;
222
+ await this.trxMgr.getRepository(sales_base_1.InventoryCheck).save(existingInventoryCheck);
223
+ return nextRoundWorksheet;
224
+ }
225
+ catch (error) {
226
+ console.error('An error occurred while creating the next round cycle count worksheet:', error);
227
+ throw new Error('Failed to create next round cycle count worksheet');
228
+ }
229
+ }
230
+ async generateCycleCountWorksheet(executionDate, customerId, inventoryCheckItemIds = [], inventoryCheckItem = [], limit = 0, selectedLocation = [], cycleCountNo) {
15
231
  const customerBizplace = await this.trxMgr.getRepository(biz_base_1.Bizplace).findOne(customerId);
16
- let foundCycleCountWorksheet = await this.trxMgr.getRepository(entities_1.Worksheet).findOne({
232
+ const foundInventoryCheck = await this.trxMgr.getRepository(sales_base_1.InventoryCheck).findOne({
233
+ where: {
234
+ domain: this.domain,
235
+ bizplace: customerBizplace,
236
+ name: cycleCountNo
237
+ }
238
+ });
239
+ const worksheetRepository = this.trxMgr.getRepository(entities_1.Worksheet);
240
+ const foundCycleCountWorksheet = await worksheetRepository.findOne({
17
241
  where: {
18
242
  domain: this.domain,
19
243
  bizplace: customerBizplace,
20
244
  type: (0, typeorm_1.In)([constants_1.WORKSHEET_TYPE.CYCLE_COUNT, constants_1.WORKSHEET_TYPE.CYCLE_COUNT_RECHECK]),
21
245
  status: (0, typeorm_1.Not)(constants_1.WORKSHEET_STATUS.DONE)
22
246
  },
23
- relations: ['worksheetDetails', 'worksheetDetails.targetInventory', 'inventoryCheck']
247
+ order: {
248
+ checkCount: 'DESC'
249
+ },
250
+ relations: ['worksheetDetails', 'worksheetDetails.targetInventoryCheckItem', 'inventoryCheck']
24
251
  });
25
- // Create second round of cycle count with specified order inventories
26
- if (orderInventoryIds.length) {
27
- // Update status of target inventories (NOT_TALLY => INSPECTING)
28
- let targetInventories = await this.trxMgr
29
- .getRepository(sales_base_1.OrderInventory)
30
- .findByIds(orderInventoryIds);
31
- targetInventories.forEach((targetInventory) => {
32
- targetInventory.status = sales_base_1.ORDER_INVENTORY_STATUS.INSPECTING;
33
- targetInventory.updater = this.user;
34
- });
35
- await this.trxMgr.getRepository(sales_base_1.OrderInventory).save(targetInventories);
36
- // Update status of worksheet (NOT_TALLY => EXECUTING)
37
- foundCycleCountWorksheet.type = constants_1.WORKSHEET_TYPE.CYCLE_COUNT_RECHECK;
38
- foundCycleCountWorksheet.status = constants_1.WORKSHEET_STATUS.EXECUTING;
39
- foundCycleCountWorksheet.endedAt = null;
40
- foundCycleCountWorksheet.updater = this.user;
41
- await this.trxMgr.getRepository(entities_1.Worksheet).save(foundCycleCountWorksheet);
42
- // Update status of worksheet details (NOT_TALLY => EXECUTING)
43
- let worksheetDetails = foundCycleCountWorksheet.worksheetDetails.filter((wsd) => orderInventoryIds.indexOf(wsd.targetInventory.id) >= 0);
44
- worksheetDetails.forEach((wsd) => {
45
- wsd.status = constants_1.WORKSHEET_STATUS.EXECUTING;
46
- wsd.updater = this.user;
47
- });
48
- await this.trxMgr.getRepository(entities_1.WorksheetDetail).save(worksheetDetails);
49
- // Update status of cycle count
50
- const cycleCount = foundCycleCountWorksheet.inventoryCheck;
51
- cycleCount.status = sales_base_1.ORDER_STATUS.INSPECTING;
52
- cycleCount.updater = this.user;
53
- await this.trxMgr.getRepository(sales_base_1.InventoryCheck).save(cycleCount);
54
- return foundCycleCountWorksheet;
252
+ if (inventoryCheckItemIds.length) {
253
+ return await this.createNextRoundCycleCountWorksheet(customerId, foundInventoryCheck, executionDate, foundCycleCountWorksheet, inventoryCheckItemIds);
55
254
  }
56
255
  else {
57
- // Create first round of cycle count with whole pallets
58
256
  if (foundCycleCountWorksheet) {
59
- throw new Error(`Unfinished cycle count worksheet exists.`);
60
- }
61
- const cycleCount = await (0, sales_base_1.generateCycleCount)(this.trxMgr, this.domain, this.user, executionDate, customerId);
62
- // Find out inventories which is target for cycle counting
63
- const qb = this.trxMgr.getRepository(warehouse_base_1.Inventory).createQueryBuilder('INV');
64
- qb.leftJoinAndSelect('INV.location', 'LOC')
65
- .where('INV.domain_id = :domainId', { domainId: this.domain.id })
66
- .andWhere('INV.bizplace_id = :bizplaceId', { bizplaceId: customerBizplace.id })
67
- .andWhere('INV.status = :status', { status: warehouse_base_1.INVENTORY_STATUS.STORED })
68
- .andWhere(new typeorm_1.Brackets(qb => {
69
- qb.where('"INV"."locked_qty" ISNULL');
70
- qb.orWhere('"INV"."locked_qty" = 0');
71
- }));
72
- if (orderInventory && orderInventory.length > 0) {
73
- let keyval = {
74
- batchId: 'batch_id',
75
- batchIdRef: 'batch_id_ref',
76
- productDetailId: 'product_detail_id'
77
- };
78
- qb.andWhere(new typeorm_1.Brackets(qb => {
79
- orderInventory.forEach((itm, idx) => {
80
- // sample itm value
81
- // batchId: 'WO00019730', batchIdRef: null, productDetailId: '1d679587-c713-42d6-bd0a-74e587e39cc7'
82
- qb.orWhere(new typeorm_1.Brackets(qb2 => {
83
- let first = true;
84
- for (var prop in itm) {
85
- if (first) {
86
- first = false;
87
- qb2.where(`INV.${keyval[prop]} ${itm[prop] == null ? 'is null' : " = '" + itm[prop] + "'"}`);
88
- }
89
- else {
90
- qb2.andWhere(`INV.${keyval[prop]} ${itm[prop] == null ? 'is null' : " = '" + itm[prop] + "'"}`);
91
- }
92
- }
93
- }));
94
- });
95
- }));
96
- }
97
- else {
98
- if (limit > 0) {
99
- qb.orderBy('RANDOM()').limit(limit);
100
- }
101
- }
102
- let inventories = await qb.getMany();
103
- if (!inventories.length) {
104
- throw new Error(`Failed to find inventories`);
105
- }
106
- let cycleCountWorksheet = new entities_1.Worksheet();
107
- cycleCountWorksheet.domain = this.domain;
108
- cycleCountWorksheet.bizplace = customerBizplace;
109
- cycleCountWorksheet.name = utils_1.WorksheetNoGenerator.cycleCount();
110
- cycleCountWorksheet.inventoryCheck = cycleCount;
111
- cycleCountWorksheet.type = constants_1.WORKSHEET_TYPE.CYCLE_COUNT;
112
- cycleCountWorksheet.status = constants_1.WORKSHEET_STATUS.DEACTIVATED;
113
- cycleCountWorksheet.creator = this.user;
114
- cycleCountWorksheet.updater = this.user;
115
- cycleCountWorksheet = await this.trxMgr.getRepository(entities_1.Worksheet).save(cycleCountWorksheet);
116
- // generate order inventory mapping with inventory ID
117
- let targetInventories = [];
118
- for (let i = 0; i < inventories.length; i++) {
119
- const inventory = inventories[i];
120
- let targetInventory = new sales_base_1.OrderInventory();
121
- targetInventory.domain = this.domain;
122
- targetInventory.bizplace = customerBizplace;
123
- targetInventory.status = sales_base_1.ORDER_INVENTORY_STATUS.PENDING;
124
- targetInventory.name = sales_base_1.OrderNoGenerator.orderInventory();
125
- targetInventory.inventoryCheck = cycleCount;
126
- targetInventory.originQty = inventory.qty;
127
- targetInventory.originWeight = 0;
128
- targetInventory.originUomValue = inventory.uomValue;
129
- targetInventory.originBatchNo = inventory.batchId;
130
- targetInventory.originLocation = inventory.location;
131
- targetInventory.releaseQty = 0;
132
- targetInventory.releaseWeight = 0;
133
- targetInventory.releaseUomValue = 0;
134
- targetInventory.inventory = inventory;
135
- targetInventory.creator = this.user;
136
- targetInventory.updater = this.user;
137
- targetInventories.push(targetInventory);
138
- inventory.lockedQty = inventory.qty;
139
- inventory.lockedWeight = 0;
140
- inventory.lockedUomValue = inventory.uomValue;
141
- inventory.updater = this.user;
257
+ throw new Error('Unfinished cycle count worksheet exists.');
142
258
  }
143
- targetInventories = await this.trxMgr.getRepository(sales_base_1.OrderInventory).save(targetInventories, { chunk: 500 });
144
- inventories = await this.trxMgr.getRepository(warehouse_base_1.Inventory).save(inventories, { chunk: 500 });
145
- let cycleCountWorksheetDetails = [];
146
- for (let i = 0; i < targetInventories.length; i++) {
147
- let targetInventory = targetInventories[i];
148
- let cycleCountWorksheetDetail = new entities_1.WorksheetDetail();
149
- cycleCountWorksheetDetail.domain = this.domain;
150
- cycleCountWorksheetDetail.bizplace = customerBizplace;
151
- cycleCountWorksheetDetail.worksheet = cycleCountWorksheet;
152
- cycleCountWorksheetDetail.name = utils_1.WorksheetNoGenerator.cycleCountDetail();
153
- cycleCountWorksheetDetail.targetInventory = targetInventory;
154
- cycleCountWorksheetDetail.type = constants_1.WORKSHEET_TYPE.CYCLE_COUNT;
155
- cycleCountWorksheetDetail.status = constants_1.WORKSHEET_STATUS.DEACTIVATED;
156
- cycleCountWorksheetDetail.creator = this.user;
157
- cycleCountWorksheetDetail.updater = this.user;
158
- cycleCountWorksheetDetails.push(cycleCountWorksheetDetail);
259
+ return await this.createCycleCountWorksheet(customerBizplace, customerId, executionDate, inventoryCheckItem, selectedLocation, limit);
260
+ }
261
+ }
262
+ async generateCycleCountWorksheetCarton(executionDate, customerId, cycleCountNo, cartonIds = [], batchIds = [], productDetailIds = [], locationNames = []) {
263
+ const customerBizplace = await this.trxMgr.getRepository(biz_base_1.Bizplace).findOne(customerId);
264
+ const foundInventoryCheck = await this.trxMgr.getRepository(sales_base_1.InventoryCheck).findOne({
265
+ where: {
266
+ domain: this.domain,
267
+ bizplace: customerBizplace,
268
+ name: cycleCountNo
159
269
  }
160
- await this.trxMgr.getRepository(entities_1.WorksheetDetail).save(cycleCountWorksheetDetails, { chunk: 500 });
161
- return cycleCountWorksheet;
270
+ });
271
+ const worksheetRepository = this.trxMgr.getRepository(entities_1.Worksheet);
272
+ const foundCycleCountWorksheet = await worksheetRepository.findOne({
273
+ where: {
274
+ domain: this.domain,
275
+ bizplace: customerBizplace,
276
+ type: (0, typeorm_1.In)([constants_1.WORKSHEET_TYPE.CYCLE_COUNT, constants_1.WORKSHEET_TYPE.CYCLE_COUNT_RECHECK]),
277
+ status: (0, typeorm_1.Not)(constants_1.WORKSHEET_STATUS.DONE)
278
+ },
279
+ order: {
280
+ checkCount: 'DESC'
281
+ },
282
+ relations: ['worksheetDetails', 'worksheetDetails.targetInventoryCheckItem', 'inventoryCheck']
283
+ });
284
+ const qb = this.trxMgr.getRepository(sales_base_1.InventoryCheckItem).createQueryBuilder('inventoryCheckItem');
285
+ qb.innerJoinAndSelect('inventoryCheckItem.inventory', 'inventory')
286
+ .innerJoinAndSelect('inventoryCheckItem.productDetail', 'productDetail')
287
+ .innerJoinAndSelect('inventoryCheckItem.originLocation', 'location')
288
+ .where('inventory.cartonId IN (:...cartonIds)', { cartonIds })
289
+ .andWhere('inventory.batchId IN (:...batchIds)', { batchIds })
290
+ .andWhere('productDetail.id IN (:...productDetailIds)', { productDetailIds })
291
+ .andWhere('location.name IN (:...locationNames)', { locationNames })
292
+ .andWhere('inventoryCheckItem.domain_id = :domainId', { domainId: this.domain.id })
293
+ .andWhere('inventoryCheckItem.bizplace_id = :bizplaceId', { bizplaceId: customerBizplace.id })
294
+ .andWhere('inventoryCheckItem.inventory_check_id = :inventoryCheckId', {
295
+ inventoryCheckId: foundInventoryCheck.id
296
+ });
297
+ const inventoryCheckItems = await qb.getMany();
298
+ const inventoryCheckItemIds = inventoryCheckItems.map(item => item.id);
299
+ if (inventoryCheckItemIds.length) {
300
+ return await this.createNextRoundCycleCountWorksheet(customerId, foundInventoryCheck, executionDate, foundCycleCountWorksheet, inventoryCheckItemIds);
162
301
  }
163
302
  }
164
303
  async activateCycleCount(worksheetNo) {
165
304
  let worksheet = await this.findActivatableWorksheet(worksheetNo, constants_1.WORKSHEET_TYPE.CYCLE_COUNT, [
166
305
  'inventoryCheck',
167
306
  'worksheetDetails',
168
- 'worksheetDetails.targetInventory'
307
+ 'worksheetDetails.targetInventoryCheckItem'
169
308
  ]);
170
309
  let worksheetDetails = worksheet.worksheetDetails;
171
- let targetInventories = worksheetDetails.map((wsd) => wsd.targetInventory);
172
- for (let i = 0; i < targetInventories.length; i++) {
173
- let targetInventory = targetInventories[i];
174
- targetInventory.status = sales_base_1.ORDER_INVENTORY_STATUS.INSPECTING;
175
- targetInventory.updater = this.user;
310
+ let targetInventoryCheckItems = worksheetDetails.map((wsd) => wsd.targetInventoryCheckItem);
311
+ for (let i = 0; i < targetInventoryCheckItems.length; i++) {
312
+ let targetInventoryCheckItem = targetInventoryCheckItems[i];
313
+ targetInventoryCheckItem.status = sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTING;
314
+ targetInventoryCheckItem.updater = this.user;
176
315
  }
177
- await this.trxMgr.getRepository(sales_base_1.OrderInventory).save(targetInventories, { chunk: 500 });
316
+ await this.trxMgr.getRepository(sales_base_1.InventoryCheckItem).save(targetInventoryCheckItems, { chunk: 500 });
178
317
  for (let i = 0; i < worksheetDetails.length; i++) {
179
318
  let foundWSD = worksheetDetails[i];
180
319
  foundWSD.status = constants_1.WORKSHEET_STATUS.EXECUTING;
@@ -191,91 +330,213 @@ class CycleCountWorksheetController extends worksheet_controller_1.WorksheetCont
191
330
  await this.updateRefOrder(cycleCount);
192
331
  return worksheet;
193
332
  }
194
- async inspecting(worksheetDetailName, inspectedBatchNo, inspectedQty, inspectedUomValue) {
195
- let worksheetDetail = await this.findExecutableWorksheetDetailByName(worksheetDetailName, constants_1.WORKSHEET_TYPE.CYCLE_COUNT, ['targetInventory', 'targetInventory.inventory', 'targetInventory.inventory.location']);
196
- let targetInventory = worksheetDetail.targetInventory;
197
- const inventory = targetInventory.inventory;
198
- const { batchId, qty, uomValue } = inventory;
199
- const isChanged = batchId !== inspectedBatchNo || qty !== inspectedQty || uomValue !== inspectedUomValue;
333
+ async inspectingPallet(worksheetDetailName, inspectedBatchNo, inspectedQty, inspectedUomValue) {
334
+ let worksheetDetail = await this.findExecutableWorksheetDetailByName(worksheetDetailName, constants_1.WORKSHEET_TYPE.CYCLE_COUNT, ['targetInventoryCheckItem', 'targetInventoryCheckItem.inventory', 'targetInventoryCheckItem.inventory.location']);
335
+ let targetInventoryCheckItem = worksheetDetail.targetInventoryCheckItem;
336
+ const { originBatchNo, originQty, originUomValue } = targetInventoryCheckItem;
337
+ const isChanged = originBatchNo !== inspectedBatchNo || originQty !== inspectedQty || originUomValue !== inspectedUomValue;
200
338
  const worksheetDetailStatus = isChanged ? constants_1.WORKSHEET_STATUS.NOT_TALLY : constants_1.WORKSHEET_STATUS.DONE;
201
- const targetInventoryStatus = isChanged
202
- ? sales_base_1.ORDER_INVENTORY_STATUS.NOT_TALLY
203
- : sales_base_1.ORDER_INVENTORY_STATUS.INSPECTED;
339
+ const targetInventoryCheckItemStatus = isChanged
340
+ ? sales_base_1.INVENTORY_CHECK_ITEM_STATUS.NOT_TALLY
341
+ : sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTED;
204
342
  worksheetDetail.status = worksheetDetailStatus;
205
343
  worksheetDetail.updater = this.user;
206
344
  await this.trxMgr.getRepository(entities_1.WorksheetDetail).save(worksheetDetail);
207
- targetInventory.inspectedBatchNo = inspectedBatchNo;
208
- targetInventory.inspectedQty = inspectedQty;
209
- targetInventory.inspectedUomValue = inspectedUomValue;
210
- targetInventory.inspectedLocation = targetInventory.inventory.location;
211
- targetInventory.status = targetInventoryStatus;
212
- targetInventory.updater = this.user;
213
- await this.updateOrderTargets([targetInventory]);
214
- //If all tally, remove lockedQty, lockedWeight, lockedUomValue
215
- if (!isChanged) {
216
- inventory.lockedQty = 0;
217
- inventory.lockedWeight = 0;
218
- inventory.lockedUomValue = 0;
219
- inventory.updater = this.user;
220
- await this.trxMgr.getRepository(warehouse_base_1.Inventory).save(inventory, { chunk: 500 });
345
+ targetInventoryCheckItem.inspectedBatchNo = inspectedBatchNo;
346
+ targetInventoryCheckItem.inspectedQty = inspectedQty;
347
+ targetInventoryCheckItem.inspectedUomValue = inspectedUomValue;
348
+ targetInventoryCheckItem.inspectedLocation = targetInventoryCheckItem.inventory.location;
349
+ targetInventoryCheckItem.status = targetInventoryCheckItemStatus;
350
+ targetInventoryCheckItem.updater = this.user;
351
+ await this.updateOrderTargets([targetInventoryCheckItem]);
352
+ }
353
+ async inspectingCarton(productDetailId, cartonId, batchId, locationId, inspectedBatchNo, inspectedQty, inspectedUomValue) {
354
+ var _a, _b, _c, _d;
355
+ const productDetail = await this.trxMgr.getRepository(product_base_1.ProductDetail).findOne({
356
+ where: { id: productDetailId },
357
+ relations: ['product']
358
+ });
359
+ let qb = this.trxMgr
360
+ .getRepository(warehouse_base_1.Inventory)
361
+ .createQueryBuilder('inv')
362
+ .where('inv.product_detail_id = :productDetailId', { productDetailId })
363
+ .andWhere('inv.carton_id = :cartonId', { cartonId })
364
+ .andWhere('inv.batch_id = :batchId', { batchId })
365
+ .andWhere('inv.location_id = :locationId', { locationId });
366
+ let orderByField = 'created_at';
367
+ let orderByDirection = 'ASC';
368
+ switch (productDetail.product.pickingStrategy) {
369
+ case 'LIFO':
370
+ orderByDirection = 'DESC';
371
+ break;
372
+ case 'FEFO':
373
+ orderByField = 'expiration_date';
374
+ break;
375
+ case 'FMFO':
376
+ orderByField = 'manufacture_date';
377
+ break;
378
+ }
379
+ qb.addOrderBy(`"inv"."${orderByField}"`, orderByDirection);
380
+ if (['FEFO', 'FMFO'].includes(productDetail.product.pickingStrategy)) {
381
+ qb.addOrderBy('"inv"."created_at"', 'ASC');
382
+ }
383
+ const inventories = await qb.getMany();
384
+ const inventoryIds = inventories.map(inv => inv.id);
385
+ const inventoryCheckItems = await this.trxMgr
386
+ .getRepository(sales_base_1.InventoryCheckItem)
387
+ .createQueryBuilder('inventoryCheckItem')
388
+ .leftJoinAndSelect('inventoryCheckItem.inventory', 'inventory')
389
+ .where('inventory.id IN (:...ids)', { ids: inventoryIds })
390
+ .andWhere('inventoryCheckItem.status = :status', { status: 'INSPECTING' })
391
+ .getMany();
392
+ const totalOriginQty = inventoryCheckItems.reduce((total, item) => total + (item.originQty || 0), 0);
393
+ const totalOriginUomValue = inventoryCheckItems.reduce((total, item) => total + (item.originUomValue || 0), 0);
394
+ const hasQtyDiscrepancy = totalOriginQty !== inspectedQty;
395
+ const hasUomValueDiscrepancy = totalOriginUomValue !== inspectedUomValue;
396
+ const hasBatchNoDiscrepancy = inventoryCheckItems.some(checkItem => checkItem.originBatchNo !== inspectedBatchNo);
397
+ const hasDiscrepancies = hasQtyDiscrepancy || hasUomValueDiscrepancy || hasBatchNoDiscrepancy;
398
+ let inventoryCheckItemStatus;
399
+ let worksheetDetailStatus;
400
+ if (inventoryCheckItems.length > 1) {
401
+ inventoryCheckItemStatus = hasDiscrepancies
402
+ ? sales_base_1.INVENTORY_CHECK_ITEM_STATUS.GROUP_NOT_TALLY
403
+ : sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTED;
404
+ worksheetDetailStatus = hasDiscrepancies ? constants_1.WORKSHEET_STATUS.NOT_TALLY : constants_1.WORKSHEET_STATUS.DONE;
405
+ }
406
+ else {
407
+ inventoryCheckItemStatus = hasDiscrepancies
408
+ ? sales_base_1.INVENTORY_CHECK_ITEM_STATUS.NOT_TALLY
409
+ : sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTED;
410
+ worksheetDetailStatus = hasDiscrepancies ? constants_1.WORKSHEET_STATUS.NOT_TALLY : constants_1.WORKSHEET_STATUS.DONE;
411
+ }
412
+ let totalInspectedQty = inspectedQty;
413
+ let totalInspectedUomValue = inspectedUomValue;
414
+ for (const checkItem of inventoryCheckItems) {
415
+ const qtyToInspect = totalInspectedQty > 0 ? Math.min(totalInspectedQty, checkItem.originQty) : 0;
416
+ const uomValueToInspect = totalInspectedUomValue > 0 ? Math.min(totalInspectedUomValue, checkItem.originUomValue) : 0;
417
+ checkItem.inspectedQty = ((_a = checkItem.inspectedQty) !== null && _a !== void 0 ? _a : 0) + qtyToInspect;
418
+ totalInspectedQty -= qtyToInspect;
419
+ checkItem.inspectedUomValue = ((_b = checkItem.inspectedUomValue) !== null && _b !== void 0 ? _b : 0) + uomValueToInspect;
420
+ totalInspectedUomValue -= uomValueToInspect;
421
+ checkItem.inspectedBatchNo = inspectedBatchNo;
422
+ checkItem.inspectedLocation = checkItem.originLocationId;
423
+ checkItem.status = inventoryCheckItemStatus;
424
+ checkItem.updater = this.user;
425
+ await this.trxMgr.getRepository(sales_base_1.InventoryCheckItem).save(checkItem);
426
+ let worksheetDetail = await this.trxMgr.getRepository(entities_1.WorksheetDetail).findOne({
427
+ where: { targetInventoryCheckItem: checkItem.id, type: constants_1.WORKSHEET_TYPE.CYCLE_COUNT }
428
+ });
429
+ if (worksheetDetail) {
430
+ worksheetDetail.status = worksheetDetailStatus;
431
+ worksheetDetail.updater = this.user;
432
+ await this.trxMgr.getRepository(entities_1.WorksheetDetail).save(worksheetDetail);
433
+ }
434
+ }
435
+ if (totalInspectedQty > 0 && totalInspectedUomValue > 0 && inventoryCheckItems.length > 0) {
436
+ const lastItem = inventoryCheckItems[inventoryCheckItems.length - 1];
437
+ lastItem.inspectedQty = ((_c = lastItem.inspectedQty) !== null && _c !== void 0 ? _c : 0) + totalInspectedQty;
438
+ lastItem.inspectedUomValue = ((_d = lastItem.inspectedUomValue) !== null && _d !== void 0 ? _d : 0) + totalInspectedUomValue;
439
+ await this.trxMgr.getRepository(sales_base_1.InventoryCheckItem).save(lastItem);
221
440
  }
222
441
  }
223
442
  async undoInspection(worksheetDetailName) {
224
- let worksheetDetail = await this.findWorksheetDetail({ domain: this.domain, name: worksheetDetailName, status: (0, typeorm_1.Not)((0, typeorm_1.Equal)(constants_1.WORKSHEET_STATUS.EXECUTING)) }, ['targetInventory', 'targetInventory.inventory']);
225
- let targetInventory = worksheetDetail.targetInventory;
226
- targetInventory.inspectedBatchNo = null;
227
- targetInventory.inspectedQty = null;
228
- targetInventory.inspectedWeight = null;
229
- targetInventory.inspectedUomValue = null;
230
- targetInventory.inspectedLocation = null;
231
- targetInventory.status =
232
- targetInventory.status === sales_base_1.ORDER_INVENTORY_STATUS.RELOCATED
233
- ? sales_base_1.ORDER_INVENTORY_STATUS.MISSING
234
- : sales_base_1.ORDER_INVENTORY_STATUS.INSPECTING;
235
- targetInventory.updater = this.user;
236
- await this.updateOrderTargets([targetInventory]);
443
+ let worksheetDetail = await this.findWorksheetDetail({ domain: this.domain, name: worksheetDetailName, status: (0, typeorm_1.Not)((0, typeorm_1.Equal)(constants_1.WORKSHEET_STATUS.EXECUTING)) }, ['targetInventoryCheckItem', 'targetInventoryCheckItem.inventory']);
444
+ let targetInventoryCheckItem = worksheetDetail.targetInventoryCheckItem;
445
+ targetInventoryCheckItem.inspectedBatchNo = null;
446
+ targetInventoryCheckItem.inspectedQty = null;
447
+ targetInventoryCheckItem.inspectedWeight = null;
448
+ targetInventoryCheckItem.inspectedUomValue = null;
449
+ targetInventoryCheckItem.inspectedLocation = null;
450
+ targetInventoryCheckItem.status =
451
+ targetInventoryCheckItem.status === sales_base_1.INVENTORY_CHECK_ITEM_STATUS.RELOCATED
452
+ ? sales_base_1.INVENTORY_CHECK_ITEM_STATUS.MISSING
453
+ : sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTING;
454
+ targetInventoryCheckItem.updater = this.user;
455
+ await this.updateOrderTargets([targetInventoryCheckItem]);
237
456
  worksheetDetail.status =
238
- targetInventory.status === sales_base_1.ORDER_INVENTORY_STATUS.MISSING
457
+ targetInventoryCheckItem.status === sales_base_1.INVENTORY_CHECK_ITEM_STATUS.MISSING
239
458
  ? constants_1.WORKSHEET_STATUS.NOT_TALLY
240
459
  : constants_1.WORKSHEET_STATUS.EXECUTING;
241
460
  worksheetDetail.updater = this.user;
242
461
  await this.trxMgr.getRepository(entities_1.WorksheetDetail).save(worksheetDetail);
243
- const inventory = targetInventory.inventory;
244
- inventory.lockedQty = inventory.qty;
245
- inventory.lockedWeight = inventory.weight;
246
- inventory.lockedUomValue = inventory.uomValue;
247
- inventory.updater = this.user;
248
- await this.trxMgr.getRepository(warehouse_base_1.Inventory).save(inventory, { chunk: 500 });
249
462
  }
250
- async checkMissingPallet(worksheetDetailName) {
251
- let worksheetDetail = await this.findExecutableWorksheetDetailByName(worksheetDetailName, constants_1.WORKSHEET_TYPE.CYCLE_COUNT, ['targetInventory']);
252
- let targetInventory = worksheetDetail.targetInventory;
463
+ async undoInspectionCarton(productDetailId, cartonId, batchId, locationId) {
464
+ let qb = this.trxMgr.getRepository(warehouse_base_1.Inventory).createQueryBuilder('inv');
465
+ qb.where('inv.product_detail_id = :productDetailId', { productDetailId })
466
+ .andWhere('inv.carton_id = :cartonId', { cartonId })
467
+ .andWhere('inv.batch_id = :batchId', { batchId })
468
+ .andWhere('inv.location_id = :locationId', { locationId });
469
+ const inventories = await qb.getMany();
470
+ const inventoryCheckItems = await Promise.all(inventories.map(inventory => this.trxMgr.getRepository(sales_base_1.InventoryCheckItem).findOne({ where: { inventory: inventory.id } })));
471
+ for (const checkItem of inventoryCheckItems) {
472
+ checkItem.inspectedBatchNo = null;
473
+ checkItem.inspectedQty = null;
474
+ checkItem.inspectedWeight = null;
475
+ checkItem.inspectedUomValue = null;
476
+ checkItem.inspectedLocation = null;
477
+ checkItem.status = sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTING;
478
+ checkItem.updater = this.user;
479
+ let worksheetDetail = await this.trxMgr.getRepository(entities_1.WorksheetDetail).findOne({
480
+ where: { targetInventoryCheckItem: checkItem.id, type: constants_1.WORKSHEET_TYPE.CYCLE_COUNT },
481
+ relations: ['targetInventoryCheckItem']
482
+ });
483
+ if (worksheetDetail) {
484
+ worksheetDetail.status = constants_1.WORKSHEET_STATUS.EXECUTING;
485
+ worksheetDetail.updater = this.user;
486
+ await this.trxMgr.getRepository(entities_1.WorksheetDetail).save(worksheetDetail);
487
+ }
488
+ await this.trxMgr.getRepository(sales_base_1.InventoryCheckItem).save(checkItem);
489
+ }
490
+ }
491
+ async checkMissingInventory(worksheetDetailName) {
492
+ let worksheetDetail = await this.findExecutableWorksheetDetailByName(worksheetDetailName, constants_1.WORKSHEET_TYPE.CYCLE_COUNT, ['targetInventoryCheckItem']);
493
+ let targetInventoryCheckItem = worksheetDetail.targetInventoryCheckItem;
253
494
  worksheetDetail.status = constants_1.WORKSHEET_STATUS.NOT_TALLY;
254
495
  worksheetDetail.updater = this.user;
255
496
  await this.trxMgr.getRepository(entities_1.WorksheetDetail).save(worksheetDetail);
256
- targetInventory.status = sales_base_1.ORDER_INVENTORY_STATUS.MISSING;
257
- targetInventory.updater = this.user;
258
- await this.updateOrderTargets([targetInventory]);
497
+ targetInventoryCheckItem.status = sales_base_1.INVENTORY_CHECK_ITEM_STATUS.MISSING;
498
+ targetInventoryCheckItem.updater = this.user;
499
+ await this.updateOrderTargets([targetInventoryCheckItem]);
259
500
  }
260
- async addExtraPallet(cycleCountNo, palletId, inspectedBatchNo, inspectedQty, inspectedUomValue, locationName) {
501
+ async checkMissingInventoryCarton(productDetailId, cartonId, batchId, locationId) {
502
+ let qb = this.trxMgr.getRepository(warehouse_base_1.Inventory).createQueryBuilder('inv');
503
+ qb.where('inv.product_detail_id = :productDetailId', { productDetailId })
504
+ .andWhere('inv.carton_id = :cartonId', { cartonId })
505
+ .andWhere('inv.batch_id = :batchId', { batchId })
506
+ .andWhere('inv.location_id = :locationId', { locationId });
507
+ const inventories = await qb.getMany();
508
+ const inventoryCheckItems = await Promise.all(inventories.map(inventory => this.trxMgr.getRepository(sales_base_1.InventoryCheckItem).findOne({ where: { inventory: inventory.id } })));
509
+ for (const checkItem of inventoryCheckItems) {
510
+ checkItem.inspectedBatchNo = null;
511
+ checkItem.inspectedQty = null;
512
+ checkItem.inspectedWeight = null;
513
+ checkItem.inspectedUomValue = null;
514
+ checkItem.inspectedLocation = null;
515
+ checkItem.status = sales_base_1.INVENTORY_CHECK_ITEM_STATUS.MISSING;
516
+ checkItem.updater = this.user;
517
+ let worksheetDetail = await this.trxMgr.getRepository(entities_1.WorksheetDetail).findOne({
518
+ where: { targetInventoryCheckItem: checkItem.id, type: constants_1.WORKSHEET_TYPE.CYCLE_COUNT },
519
+ relations: ['targetInventoryCheckItem']
520
+ });
521
+ if (worksheetDetail) {
522
+ worksheetDetail.status = constants_1.WORKSHEET_STATUS.NOT_TALLY;
523
+ worksheetDetail.updater = this.user;
524
+ await this.trxMgr.getRepository(entities_1.WorksheetDetail).save(worksheetDetail);
525
+ }
526
+ await this.trxMgr.getRepository(sales_base_1.InventoryCheckItem).save(checkItem);
527
+ }
528
+ }
529
+ async addExtraInventory(cycleCountNo, inspectedLocation, productDetailId, productId, inspectedBatchNo, inspectedQty, inspectedUomValue, countNo) {
530
+ var _a;
531
+ let today = new Date(), year = today.getFullYear(), month = today.getMonth(), date = today.getDate();
261
532
  const inventoryCheck = await this.findRefOrder(sales_base_1.InventoryCheck, {
262
533
  name: cycleCountNo,
263
534
  status: sales_base_1.ORDER_STATUS.INSPECTING
264
- }, ['bizplace']);
265
- const bizplace = inventoryCheck.bizplace;
266
- const qb = this.trxMgr.getRepository(warehouse_base_1.Inventory).createQueryBuilder('INV');
267
- let inventory = await qb
268
- .where('INV.domain = :domainId', { domainId: this.domain.id })
269
- .andWhere('INV.bizplace = :bizplaceId', { bizplaceId: bizplace.id })
270
- .andWhere('INV.palletId = :palletId', { palletId })
271
- .andWhere('INV.status = :status', { status: warehouse_base_1.INVENTORY_STATUS.STORED })
272
- .andWhere(new typeorm_1.Brackets(qb => {
273
- qb.where('INV.lockedQty ISNULL');
274
- qb.orWhere('INV.lockedQty = 0');
275
- }))
276
- .getOne();
277
- if (!inventory)
278
- throw new Error('Failed to find inventory');
535
+ }, ['bizplace', 'bizplace.domain']);
536
+ const bizplace = await this.trxMgr.getRepository(biz_base_1.Bizplace).findOne({
537
+ where: { id: inventoryCheck.bizplace.id },
538
+ relations: ['domain']
539
+ });
279
540
  const worksheet = await this.trxMgr.getRepository(entities_1.Worksheet).findOne({
280
541
  where: {
281
542
  domain: this.domain,
@@ -285,45 +546,113 @@ class CycleCountWorksheetController extends worksheet_controller_1.WorksheetCont
285
546
  }
286
547
  });
287
548
  const location = await this.trxMgr.getRepository(warehouse_base_1.Location).findOne({
288
- where: { domain: this.domain, name: locationName }
549
+ where: { domain: this.domain, name: inspectedLocation },
550
+ relations: ['warehouse']
551
+ });
552
+ const productDetail = await this.trxMgr.getRepository(product_base_1.ProductDetail).findOne({
553
+ where: { id: productDetailId }
554
+ });
555
+ const product = await this.trxMgr.getRepository(product_base_1.Product).findOne({
556
+ where: { id: productId }
557
+ });
558
+ const total = await this.trxMgr.getRepository(warehouse_base_1.Inventory).count({
559
+ createdAt: (0, typeorm_1.MoreThan)(new Date(year, month, date))
560
+ });
561
+ const yy = String(year).substr(String(year).length - 2);
562
+ const mm = String(month + 1).padStart(2, '0');
563
+ const dd = String(date).padStart(2, '0');
564
+ const dateStr = yy + mm + dd;
565
+ let newInventory = new warehouse_base_1.Inventory();
566
+ newInventory.bizplace = bizplace;
567
+ newInventory.domain = this.domain;
568
+ newInventory.name = warehouse_base_1.InventoryNoGenerator.inventoryName();
569
+ newInventory.palletId = await (0, id_rule_base_1.generateId)({
570
+ domain: this.domain,
571
+ type: 'adjustment_pallet_id',
572
+ seed: {
573
+ batchId: inspectedBatchNo,
574
+ date: dateStr
575
+ }
576
+ });
577
+ const warehouseCartonSetting = await this.trxMgr.getRepository(setting_base_1.Setting).findOne({
578
+ where: { domain: this.domain, category: 'id-rule', name: 'enable-carton-label', value: true }
579
+ });
580
+ const partnerCartonSetting = await this.trxMgr.getRepository(setting_base_1.PartnerSetting).findOne({
581
+ where: {
582
+ setting: warehouseCartonSetting,
583
+ domain: this.domain,
584
+ partnerDomain: (_a = inventoryCheck.bizplace) === null || _a === void 0 ? void 0 : _a.domain,
585
+ value: true
586
+ }
289
587
  });
290
- let targetInventory = new sales_base_1.OrderInventory();
291
- targetInventory.domain = this.domain;
292
- targetInventory.bizplace = bizplace;
293
- targetInventory.status = sales_base_1.ORDER_INVENTORY_STATUS.ADDED;
294
- targetInventory.name = sales_base_1.OrderNoGenerator.orderInventory();
295
- targetInventory.inventoryCheck = inventoryCheck;
296
- targetInventory.inventory = inventory;
297
- targetInventory.inspectedBatchNo = inspectedBatchNo;
298
- targetInventory.inspectedQty = inspectedQty;
299
- targetInventory.inspectedWeight = 0;
300
- targetInventory.inspectedUomValue = inspectedUomValue;
301
- targetInventory.inspectedLocation = location;
302
- targetInventory.creator = this.user;
303
- targetInventory.updater = this.user;
304
- await this.trxMgr.getRepository(sales_base_1.OrderInventory).save(targetInventory);
588
+ if ((partnerCartonSetting === null || partnerCartonSetting === void 0 ? void 0 : partnerCartonSetting.value) || (warehouseCartonSetting === null || warehouseCartonSetting === void 0 ? void 0 : warehouseCartonSetting.value)) {
589
+ let cartonId = await (0, id_rule_base_1.generateId)({
590
+ domain: this.domain,
591
+ type: 'adjustment_carton_id',
592
+ seed: { date: dateStr }
593
+ });
594
+ if (!cartonId)
595
+ throw new Error('No adjustment carton id setting rule found');
596
+ newInventory.cartonId = cartonId;
597
+ }
598
+ newInventory.batchId = inspectedBatchNo;
599
+ newInventory.product = product;
600
+ newInventory.productDetail = productDetail;
601
+ newInventory.packingType = productDetail.packingType;
602
+ newInventory.packingSize = productDetail.packingSize;
603
+ newInventory.uom = productDetail.uom;
604
+ newInventory.qty = inspectedQty;
605
+ newInventory.uomValue = inspectedUomValue;
606
+ newInventory.location = location;
607
+ newInventory.warehouse = location.warehouse;
608
+ newInventory.zone = location.zone;
609
+ newInventory.status = warehouse_base_1.INVENTORY_STATUS.CC_ADDED;
610
+ newInventory.creator = this.user;
611
+ newInventory.updater = this.user;
612
+ await this.trxMgr.getRepository(warehouse_base_1.Inventory).save(newInventory);
613
+ let targetInventoryCheckItem = new sales_base_1.InventoryCheckItem();
614
+ targetInventoryCheckItem.domain = this.domain;
615
+ targetInventoryCheckItem.bizplace = bizplace;
616
+ targetInventoryCheckItem.status = sales_base_1.INVENTORY_CHECK_ITEM_STATUS.ADDED;
617
+ targetInventoryCheckItem.name = sales_base_1.OrderNoGenerator.inventoryCheckItem();
618
+ targetInventoryCheckItem.inventoryCheck = inventoryCheck;
619
+ targetInventoryCheckItem.inventory = newInventory;
620
+ targetInventoryCheckItem.inspectedBatchNo = inspectedBatchNo;
621
+ targetInventoryCheckItem.inspectedQty = inspectedQty;
622
+ targetInventoryCheckItem.inspectedUomValue = inspectedUomValue;
623
+ targetInventoryCheckItem.inspectedLocation = location;
624
+ targetInventoryCheckItem.productDetail = productDetail;
625
+ targetInventoryCheckItem.product = product;
626
+ targetInventoryCheckItem.countNo = countNo;
627
+ targetInventoryCheckItem.creator = this.user;
628
+ targetInventoryCheckItem.updater = this.user;
629
+ await this.trxMgr.getRepository(sales_base_1.InventoryCheckItem).save(targetInventoryCheckItem);
305
630
  let worksheetDetail = new entities_1.WorksheetDetail();
306
631
  worksheetDetail.domain = this.domain;
307
632
  worksheetDetail.bizplace = bizplace;
308
633
  worksheetDetail.worksheet = worksheet;
309
634
  worksheetDetail.name = utils_1.WorksheetNoGenerator.cycleCountDetail();
310
- worksheetDetail.targetInventory = targetInventory;
635
+ worksheetDetail.targetInventoryCheckItem = targetInventoryCheckItem;
311
636
  worksheetDetail.type = constants_1.WORKSHEET_TYPE.CYCLE_COUNT;
312
637
  worksheetDetail.status = constants_1.WORKSHEET_STATUS.NOT_TALLY;
313
638
  worksheetDetail.creator = this.user;
314
639
  worksheetDetail.updater = this.user;
315
640
  await this.trxMgr.getRepository(entities_1.WorksheetDetail).save(worksheetDetail);
316
641
  }
317
- async relocatePallet(worksheetDetailName, inspectedBatchNo, inspectedQty, inspectedUomValue, inspectedLocationName) {
642
+ async relocateInventory(worksheetDetailName, inspectedBatchNo, inspectedQty, inspectedUomValue, inspectedLocationName) {
318
643
  var _a;
319
644
  let worksheetDetail = await this.trxMgr.getRepository(entities_1.WorksheetDetail).findOne({
320
645
  where: { domain: this.domain, name: worksheetDetailName, type: constants_1.WORKSHEET_TYPE.CYCLE_COUNT },
321
- relations: ['targetInventory', 'targetInventory.inventory', 'targetInventory.inventory.location']
646
+ relations: [
647
+ 'targetInventoryCheckItem',
648
+ 'targetInventoryCheckItem.inventory',
649
+ 'targetInventoryCheckItem.inventory.location'
650
+ ]
322
651
  });
323
652
  if (!worksheetDetail)
324
653
  throw new Error('Failed to find worksheet detail');
325
- let targetInventory = worksheetDetail.targetInventory;
326
- const location = (_a = targetInventory === null || targetInventory === void 0 ? void 0 : targetInventory.inventory) === null || _a === void 0 ? void 0 : _a.location;
654
+ let targetInventoryCheckItem = worksheetDetail.targetInventoryCheckItem;
655
+ const location = (_a = targetInventoryCheckItem === null || targetInventoryCheckItem === void 0 ? void 0 : targetInventoryCheckItem.inventory) === null || _a === void 0 ? void 0 : _a.location;
327
656
  if (location.name === inspectedLocationName)
328
657
  throw new Error(`You can't relocate at same location`);
329
658
  const inspectedLocation = await this.trxMgr.getRepository(warehouse_base_1.Location).findOne({
@@ -332,14 +661,121 @@ class CycleCountWorksheetController extends worksheet_controller_1.WorksheetCont
332
661
  worksheetDetail.status = constants_1.WORKSHEET_STATUS.NOT_TALLY;
333
662
  worksheetDetail.updater = this.user;
334
663
  await this.trxMgr.getRepository(entities_1.WorksheetDetail).save(worksheetDetail);
335
- targetInventory.inspectedLocation = inspectedLocation;
336
- targetInventory.inspectedBatchNo = inspectedBatchNo;
337
- targetInventory.inspectedQty = inspectedQty;
338
- targetInventory.inspectedWeight = 0;
339
- targetInventory.inspectedUomValue = inspectedUomValue;
340
- targetInventory.status = sales_base_1.ORDER_INVENTORY_STATUS.RELOCATED;
341
- targetInventory.updater = this.user;
342
- await this.updateOrderTargets([targetInventory]);
664
+ targetInventoryCheckItem.inspectedLocation = inspectedLocation;
665
+ targetInventoryCheckItem.inspectedBatchNo = inspectedBatchNo;
666
+ targetInventoryCheckItem.inspectedQty = inspectedQty;
667
+ targetInventoryCheckItem.inspectedWeight = 0;
668
+ targetInventoryCheckItem.inspectedUomValue = inspectedUomValue;
669
+ targetInventoryCheckItem.status = sales_base_1.INVENTORY_CHECK_ITEM_STATUS.RELOCATED;
670
+ targetInventoryCheckItem.updater = this.user;
671
+ await this.updateOrderTargets([targetInventoryCheckItem]);
672
+ }
673
+ async relocateInventoryCarton(productDetailId, cartonId, batchId, locationId, inspectedBatchNo, inspectedQty, inspectedUomValue, inspectedLocationName) {
674
+ var _a, _b, _c, _d;
675
+ const productDetail = await this.trxMgr.getRepository(product_base_1.ProductDetail).findOne({
676
+ where: { id: productDetailId },
677
+ relations: ['product']
678
+ });
679
+ let qb = this.trxMgr
680
+ .getRepository(warehouse_base_1.Inventory)
681
+ .createQueryBuilder('inv')
682
+ .where('inv.product_detail_id = :productDetailId', { productDetailId })
683
+ .andWhere('inv.carton_id = :cartonId', { cartonId })
684
+ .andWhere('inv.batch_id = :batchId', { batchId })
685
+ .andWhere('inv.location_id = :locationId', { locationId });
686
+ let orderByField = 'created_at';
687
+ let orderByDirection = 'ASC';
688
+ switch (productDetail.product.pickingStrategy) {
689
+ case 'LIFO':
690
+ orderByDirection = 'DESC';
691
+ break;
692
+ case 'FEFO':
693
+ orderByField = 'expiration_date';
694
+ break;
695
+ case 'FMFO':
696
+ orderByField = 'manufacture_date';
697
+ break;
698
+ }
699
+ qb.addOrderBy(`"inv"."${orderByField}"`, orderByDirection);
700
+ if (['FEFO', 'FMFO'].includes(productDetail.product.pickingStrategy)) {
701
+ qb.addOrderBy('"inv"."created_at"', 'ASC');
702
+ }
703
+ const inventories = await qb.getMany();
704
+ if (inventories.length === 0) {
705
+ throw new Error('No inventories found.');
706
+ }
707
+ const location = await this.trxMgr.getRepository(warehouse_base_1.Location).findOne({
708
+ where: { id: locationId }
709
+ });
710
+ if (location.name === inspectedLocationName) {
711
+ throw new Error(`You can't relocate to the same location.`);
712
+ }
713
+ const inspectedLocation = await this.trxMgr.getRepository(warehouse_base_1.Location).findOne({
714
+ where: { name: inspectedLocationName, domain: this.domain }
715
+ });
716
+ if (!inspectedLocation) {
717
+ throw new Error(`Inspected location "${inspectedLocationName}" not found.`);
718
+ }
719
+ const inventoryIds = inventories.map(inv => inv.id);
720
+ const inventoryCheckItems = await this.trxMgr
721
+ .getRepository(sales_base_1.InventoryCheckItem)
722
+ .createQueryBuilder('inventoryCheckItem')
723
+ .leftJoinAndSelect('inventoryCheckItem.inventory', 'inventory')
724
+ .where('inventory.id IN (:...ids)', { ids: inventoryIds })
725
+ .andWhere('inventoryCheckItem.status = :status', { status: 'INSPECTING' })
726
+ .getMany();
727
+ if (inventoryCheckItems.length === 0) {
728
+ throw new Error('No inventory check items found.');
729
+ }
730
+ const totalOriginQty = inventoryCheckItems.reduce((total, item) => total + (item.originQty || 0), 0);
731
+ const totalOriginUomValue = inventoryCheckItems.reduce((total, item) => total + (item.originUomValue || 0), 0);
732
+ const hasQtyDiscrepancy = totalOriginQty !== inspectedQty;
733
+ const hasUomValueDiscrepancy = totalOriginUomValue !== inspectedUomValue;
734
+ const hasBatchNoDiscrepancy = inventoryCheckItems.some(checkItem => checkItem.originBatchNo !== inspectedBatchNo);
735
+ const hasLocationDiscrepancy = inventoryCheckItems.some(checkItem => checkItem.originLocationId !== inspectedLocation.id);
736
+ const hasDiscrepancies = hasQtyDiscrepancy || hasUomValueDiscrepancy || hasBatchNoDiscrepancy || hasLocationDiscrepancy;
737
+ let inventoryCheckItemStatus, worksheetDetailStatus;
738
+ if (inventoryCheckItems.length > 1) {
739
+ inventoryCheckItemStatus = hasDiscrepancies
740
+ ? sales_base_1.INVENTORY_CHECK_ITEM_STATUS.RELOCATED
741
+ : sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTED;
742
+ worksheetDetailStatus = hasDiscrepancies ? constants_1.WORKSHEET_STATUS.NOT_TALLY : constants_1.WORKSHEET_STATUS.DONE;
743
+ }
744
+ else {
745
+ inventoryCheckItemStatus = hasDiscrepancies
746
+ ? sales_base_1.INVENTORY_CHECK_ITEM_STATUS.RELOCATED
747
+ : sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTED;
748
+ worksheetDetailStatus = hasDiscrepancies ? constants_1.WORKSHEET_STATUS.NOT_TALLY : constants_1.WORKSHEET_STATUS.DONE;
749
+ }
750
+ let totalInspectedQty = inspectedQty;
751
+ let totalInspectedUomValue = inspectedUomValue;
752
+ for (const checkItem of inventoryCheckItems) {
753
+ const qtyToInspect = totalInspectedQty > 0 ? Math.min(totalInspectedQty, checkItem.originQty) : 0;
754
+ const uomValueToInspect = totalInspectedUomValue > 0 ? Math.min(totalInspectedUomValue, checkItem.originUomValue) : 0;
755
+ checkItem.inspectedQty = ((_a = checkItem.inspectedQty) !== null && _a !== void 0 ? _a : 0) + qtyToInspect;
756
+ totalInspectedQty -= qtyToInspect;
757
+ checkItem.inspectedUomValue = ((_b = checkItem.inspectedUomValue) !== null && _b !== void 0 ? _b : 0) + uomValueToInspect;
758
+ totalInspectedUomValue -= uomValueToInspect;
759
+ checkItem.inspectedBatchNo = inspectedBatchNo;
760
+ checkItem.inspectedLocation = inspectedLocation;
761
+ checkItem.status = inventoryCheckItemStatus;
762
+ checkItem.updater = this.user;
763
+ await this.trxMgr.getRepository(sales_base_1.InventoryCheckItem).save(checkItem);
764
+ let worksheetDetail = await this.trxMgr.getRepository(entities_1.WorksheetDetail).findOne({
765
+ where: { targetInventoryCheckItem: checkItem.id, type: constants_1.WORKSHEET_TYPE.CYCLE_COUNT }
766
+ });
767
+ if (worksheetDetail) {
768
+ worksheetDetail.status = worksheetDetailStatus;
769
+ worksheetDetail.updater = this.user;
770
+ await this.trxMgr.getRepository(entities_1.WorksheetDetail).save(worksheetDetail);
771
+ }
772
+ }
773
+ if (totalInspectedQty > 0 && totalInspectedUomValue > 0 && inventoryCheckItems.length > 0) {
774
+ const lastItem = inventoryCheckItems[inventoryCheckItems.length - 1];
775
+ lastItem.inspectedQty = ((_c = lastItem.inspectedQty) !== null && _c !== void 0 ? _c : 0) + totalInspectedQty;
776
+ lastItem.inspectedUomValue = ((_d = lastItem.inspectedUomValue) !== null && _d !== void 0 ? _d : 0) + totalInspectedUomValue;
777
+ await this.trxMgr.getRepository(sales_base_1.InventoryCheckItem).save(lastItem);
778
+ }
343
779
  }
344
780
  async completeCycleCount(inventoryCheckNo) {
345
781
  const inventoryCheck = await this.findRefOrder(sales_base_1.InventoryCheck, {
@@ -353,37 +789,35 @@ class CycleCountWorksheetController extends worksheet_controller_1.WorksheetCont
353
789
  type: (0, typeorm_1.In)([constants_1.WORKSHEET_TYPE.CYCLE_COUNT, constants_1.WORKSHEET_TYPE.CYCLE_COUNT_RECHECK]),
354
790
  inventoryCheck
355
791
  },
356
- relations: ['worksheetDetails', 'worksheetDetails.targetInventory', 'worksheetDetails.targetInventory.inventory']
792
+ relations: [
793
+ 'worksheetDetails',
794
+ 'worksheetDetails.targetInventoryCheckItem',
795
+ 'worksheetDetails.targetInventoryCheckItem.inventory'
796
+ ]
357
797
  });
358
798
  this.checkRecordValidity(worksheet, { status: constants_1.WORKSHEET_STATUS.EXECUTING });
359
799
  const worksheetDetails = worksheet.worksheetDetails;
360
- const targetInventories = worksheetDetails.map((wsd) => wsd.targetInventory);
361
- const { tallyTargetInventories, notTallyTargetInventories } = targetInventories.reduce((result, targetInventory) => {
362
- if (targetInventory.status !== sales_base_1.ORDER_INVENTORY_STATUS.INSPECTED) {
363
- result.notTallyTargetInventories.push(targetInventory);
800
+ const targetInventoryCheckItems = worksheetDetails.map((wsd) => wsd.targetInventoryCheckItem);
801
+ const { tallyTargetInventoryCheckItems, notTallyTargetInventoryCheckItems } = targetInventoryCheckItems.reduce((result, targetInventoryCheckItem) => {
802
+ if (targetInventoryCheckItem.status !== sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTED) {
803
+ result.notTallyTargetInventoryCheckItems.push(targetInventoryCheckItem);
364
804
  }
365
805
  else {
366
- result.tallyTargetInventories.push(targetInventory);
806
+ result.tallyTargetInventoryCheckItems.push(targetInventoryCheckItem);
367
807
  }
368
808
  return result;
369
809
  }, {
370
- tallyTargetInventories: [],
371
- notTallyTargetInventories: []
372
- });
373
- const tallyInventories = tallyTargetInventories.map(targetInventory => targetInventory.inventory);
374
- tallyTargetInventories.forEach((targetInventory) => {
375
- targetInventory.status = sales_base_1.ORDER_INVENTORY_STATUS.TERMINATED;
376
- targetInventory.updater = this.user;
810
+ tallyTargetInventoryCheckItems: [],
811
+ notTallyTargetInventoryCheckItems: []
377
812
  });
378
- await this.trxMgr.getRepository(sales_base_1.OrderInventory).save(tallyTargetInventories, { chunk: 500 });
379
- tallyInventories.forEach((inventory) => {
380
- inventory.lockedQty = 0;
381
- inventory.lockedWeight = 0;
382
- inventory.lockedUomValue = 0;
383
- inventory.updater = this.user;
813
+ const tallyInventories = tallyTargetInventoryCheckItems.map(targetInventoryCheckItem => targetInventoryCheckItem.inventory);
814
+ tallyTargetInventoryCheckItems.forEach((targetInventoryCheckItem) => {
815
+ targetInventoryCheckItem.status = sales_base_1.INVENTORY_CHECK_ITEM_STATUS.TERMINATED;
816
+ targetInventoryCheckItem.updater = this.user;
384
817
  });
818
+ await this.trxMgr.getRepository(sales_base_1.InventoryCheckItem).save(tallyTargetInventoryCheckItems, { chunk: 500 });
385
819
  await this.trxMgr.getRepository(warehouse_base_1.Inventory).save(tallyInventories, { chunk: 500 });
386
- if (notTallyTargetInventories.length) {
820
+ if (notTallyTargetInventoryCheckItems.length) {
387
821
  worksheet.status = constants_1.WORKSHEET_STATUS.NOT_TALLY;
388
822
  inventoryCheck.status = sales_base_1.ORDER_STATUS.PENDING_REVIEW;
389
823
  }