@rytass/wms-module-core 0.1.0

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 (199) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +80 -0
  3. package/index.cjs.js +6479 -0
  4. package/index.d.ts +5 -0
  5. package/index.js +74 -0
  6. package/lib/constants/index.d.ts +1 -0
  7. package/lib/constants/stock-status.d.ts +30 -0
  8. package/lib/constants/stock-status.js +51 -0
  9. package/lib/core.module.d.ts +7 -0
  10. package/lib/core.module.js +102 -0
  11. package/lib/models/extensions/allocate-inventory-order/allocate-inventory-order-change.entity.d.ts +10 -0
  12. package/lib/models/extensions/allocate-inventory-order/allocate-inventory-order-change.entity.js +40 -0
  13. package/lib/models/extensions/allocate-inventory-order/allocate-inventory-order-item.entity.d.ts +20 -0
  14. package/lib/models/extensions/allocate-inventory-order/allocate-inventory-order-item.entity.js +103 -0
  15. package/lib/models/extensions/allocate-inventory-order/allocate-inventory-order.entity.d.ts +8 -0
  16. package/lib/models/extensions/allocate-inventory-order/allocate-inventory-order.entity.js +33 -0
  17. package/lib/models/extensions/hold-inventory-order/hold-inventory-order-change.entity.d.ts +10 -0
  18. package/lib/models/extensions/hold-inventory-order/hold-inventory-order-change.entity.js +40 -0
  19. package/lib/models/extensions/hold-inventory-order/hold-inventory-order-item.entity.d.ts +19 -0
  20. package/lib/models/extensions/hold-inventory-order/hold-inventory-order-item.entity.js +97 -0
  21. package/lib/models/extensions/hold-inventory-order/hold-inventory-order.entity.d.ts +10 -0
  22. package/lib/models/extensions/hold-inventory-order/hold-inventory-order.entity.js +43 -0
  23. package/lib/models/extensions/index.d.ts +37 -0
  24. package/lib/models/extensions/merge-batch-order/merge-batch-order-change.entity.d.ts +10 -0
  25. package/lib/models/extensions/merge-batch-order/merge-batch-order-change.entity.js +40 -0
  26. package/lib/models/extensions/merge-batch-order/merge-batch-order-item.entity.d.ts +15 -0
  27. package/lib/models/extensions/merge-batch-order/merge-batch-order-item.entity.js +74 -0
  28. package/lib/models/extensions/merge-batch-order/merge-batch-order.entity.d.ts +8 -0
  29. package/lib/models/extensions/merge-batch-order/merge-batch-order.entity.js +33 -0
  30. package/lib/models/extensions/quality-inspection-order/quality-inspection-order-change.entity.d.ts +11 -0
  31. package/lib/models/extensions/quality-inspection-order/quality-inspection-order-change.entity.js +45 -0
  32. package/lib/models/extensions/quality-inspection-order/quality-inspection-order-item.entity.d.ts +18 -0
  33. package/lib/models/extensions/quality-inspection-order/quality-inspection-order-item.entity.js +93 -0
  34. package/lib/models/extensions/quality-inspection-order/quality-inspection-order.entity.d.ts +9 -0
  35. package/lib/models/extensions/quality-inspection-order/quality-inspection-order.entity.js +38 -0
  36. package/lib/models/extensions/receive-inventory-order/receive-inventory-order-change.entity.d.ts +12 -0
  37. package/lib/models/extensions/receive-inventory-order/receive-inventory-order-change.entity.js +46 -0
  38. package/lib/models/extensions/receive-inventory-order/receive-inventory-order-item.entity.d.ts +19 -0
  39. package/lib/models/extensions/receive-inventory-order/receive-inventory-order-item.entity.js +89 -0
  40. package/lib/models/extensions/receive-inventory-order/receive-inventory-order.entity.d.ts +13 -0
  41. package/lib/models/extensions/receive-inventory-order/receive-inventory-order.entity.js +57 -0
  42. package/lib/models/extensions/reclassify-inventory-order/reclassify-inventory-order-change.entity.d.ts +10 -0
  43. package/lib/models/extensions/reclassify-inventory-order/reclassify-inventory-order-change.entity.js +40 -0
  44. package/lib/models/extensions/reclassify-inventory-order/reclassify-inventory-order-item.entity.d.ts +15 -0
  45. package/lib/models/extensions/reclassify-inventory-order/reclassify-inventory-order-item.entity.js +74 -0
  46. package/lib/models/extensions/reclassify-inventory-order/reclassify-inventory-order.entity.d.ts +8 -0
  47. package/lib/models/extensions/reclassify-inventory-order/reclassify-inventory-order.entity.js +33 -0
  48. package/lib/models/extensions/scrape-order/scrape-order-change.entity.d.ts +10 -0
  49. package/lib/models/extensions/scrape-order/scrape-order-change.entity.js +40 -0
  50. package/lib/models/extensions/scrape-order/scrape-order-item.entity.d.ts +18 -0
  51. package/lib/models/extensions/scrape-order/scrape-order-item.entity.js +93 -0
  52. package/lib/models/extensions/scrape-order/scrape-order.entity.d.ts +8 -0
  53. package/lib/models/extensions/scrape-order/scrape-order.entity.js +33 -0
  54. package/lib/models/extensions/ship-inventory-order/ship-inventory-order-change.entity.d.ts +12 -0
  55. package/lib/models/extensions/ship-inventory-order/ship-inventory-order-change.entity.js +46 -0
  56. package/lib/models/extensions/ship-inventory-order/ship-inventory-order-item.entity.d.ts +19 -0
  57. package/lib/models/extensions/ship-inventory-order/ship-inventory-order-item.entity.js +90 -0
  58. package/lib/models/extensions/ship-inventory-order/ship-inventory-order-reference.entity.d.ts +13 -0
  59. package/lib/models/extensions/ship-inventory-order/ship-inventory-order-reference.entity.js +65 -0
  60. package/lib/models/extensions/ship-inventory-order/ship-inventory-order.entity.d.ts +13 -0
  61. package/lib/models/extensions/ship-inventory-order/ship-inventory-order.entity.js +56 -0
  62. package/lib/models/extensions/split-batch-order/split-batch-order-change.entity.d.ts +10 -0
  63. package/lib/models/extensions/split-batch-order/split-batch-order-change.entity.js +40 -0
  64. package/lib/models/extensions/split-batch-order/split-batch-order-item.entity.d.ts +15 -0
  65. package/lib/models/extensions/split-batch-order/split-batch-order-item.entity.js +74 -0
  66. package/lib/models/extensions/split-batch-order/split-batch-order.entity.d.ts +8 -0
  67. package/lib/models/extensions/split-batch-order/split-batch-order.entity.js +33 -0
  68. package/lib/models/extensions/transfer-customer-order/transfer-customer-order-change.entity.d.ts +10 -0
  69. package/lib/models/extensions/transfer-customer-order/transfer-customer-order-change.entity.js +40 -0
  70. package/lib/models/extensions/transfer-customer-order/transfer-customer-order-item.entity.d.ts +19 -0
  71. package/lib/models/extensions/transfer-customer-order/transfer-customer-order-item.entity.js +98 -0
  72. package/lib/models/extensions/transfer-customer-order/transfer-customer-order.entity.d.ts +8 -0
  73. package/lib/models/extensions/transfer-customer-order/transfer-customer-order.entity.js +33 -0
  74. package/lib/models/extensions/transfer-order/transfer-order-change.entity.d.ts +10 -0
  75. package/lib/models/extensions/transfer-order/transfer-order-change.entity.js +40 -0
  76. package/lib/models/extensions/transfer-order/transfer-order-item.entity.d.ts +21 -0
  77. package/lib/models/extensions/transfer-order/transfer-order-item.entity.js +108 -0
  78. package/lib/models/extensions/transfer-order/transfer-order.entity.d.ts +12 -0
  79. package/lib/models/extensions/transfer-order/transfer-order.entity.js +53 -0
  80. package/lib/models/extensions/transfer-vendor-order/transfer-vendor-order-change.entity.d.ts +10 -0
  81. package/lib/models/extensions/transfer-vendor-order/transfer-vendor-order-change.entity.js +40 -0
  82. package/lib/models/extensions/transfer-vendor-order/transfer-vendor-order-item.entity.d.ts +19 -0
  83. package/lib/models/extensions/transfer-vendor-order/transfer-vendor-order-item.entity.js +98 -0
  84. package/lib/models/extensions/transfer-vendor-order/transfer-vendor-order.entity.d.ts +8 -0
  85. package/lib/models/extensions/transfer-vendor-order/transfer-vendor-order.entity.js +33 -0
  86. package/lib/models/index.d.ts +2 -0
  87. package/lib/models/metadata/batch-group.entity.d.ts +8 -0
  88. package/lib/models/metadata/batch-group.entity.js +31 -0
  89. package/lib/models/metadata/batch.entity.d.ts +15 -0
  90. package/lib/models/metadata/batch.entity.js +73 -0
  91. package/lib/models/metadata/index.d.ts +11 -0
  92. package/lib/models/metadata/loader-type.entity.d.ts +9 -0
  93. package/lib/models/metadata/loader-type.entity.js +43 -0
  94. package/lib/models/metadata/loader-unit.entity.d.ts +5 -0
  95. package/lib/models/metadata/loader-unit.entity.js +21 -0
  96. package/lib/models/metadata/loader.entity.d.ts +21 -0
  97. package/lib/models/metadata/loader.entity.js +98 -0
  98. package/lib/models/metadata/location.entity.d.ts +8 -0
  99. package/lib/models/metadata/location.entity.js +28 -0
  100. package/lib/models/metadata/material-unit.entity.d.ts +11 -0
  101. package/lib/models/metadata/material-unit.entity.js +51 -0
  102. package/lib/models/metadata/material.entity.d.ts +7 -0
  103. package/lib/models/metadata/material.entity.js +28 -0
  104. package/lib/models/metadata/sale-order.entity.d.ts +5 -0
  105. package/lib/models/metadata/sale-order.entity.js +21 -0
  106. package/lib/models/metadata/stock.entity.d.ts +8 -0
  107. package/lib/models/metadata/stock.entity.js +29 -0
  108. package/lib/models/metadata/unit.entity.d.ts +5 -0
  109. package/lib/models/metadata/unit.entity.js +21 -0
  110. package/lib/models/models.module.d.ts +6 -0
  111. package/lib/models/models.module.js +122 -0
  112. package/lib/services/allocate-inventory-order.service.d.ts +29 -0
  113. package/lib/services/allocate-inventory-order.service.js +299 -0
  114. package/lib/services/base-order.service.d.ts +41 -0
  115. package/lib/services/batch.service.d.ts +30 -0
  116. package/lib/services/batch.service.js +218 -0
  117. package/lib/services/helper.service.d.ts +6 -0
  118. package/lib/services/helper.service.js +28 -0
  119. package/lib/services/hold-inventory-order.service.d.ts +29 -0
  120. package/lib/services/hold-inventory-order.service.js +285 -0
  121. package/lib/services/index.d.ts +22 -0
  122. package/lib/services/loader.service.d.ts +43 -0
  123. package/lib/services/loader.service.js +282 -0
  124. package/lib/services/location.service.d.ts +13 -0
  125. package/lib/services/location.service.js +130 -0
  126. package/lib/services/material.service.d.ts +27 -0
  127. package/lib/services/material.service.js +172 -0
  128. package/lib/services/merge-batch-order.service.d.ts +19 -0
  129. package/lib/services/merge-batch-order.service.js +195 -0
  130. package/lib/services/quality-inspection-order.service.d.ts +19 -0
  131. package/lib/services/quality-inspection-order.service.js +135 -0
  132. package/lib/services/receive-inventory-order.service.d.ts +41 -0
  133. package/lib/services/receive-inventory-order.service.js +407 -0
  134. package/lib/services/reclassify-inventory-order.service.d.ts +19 -0
  135. package/lib/services/reclassify-inventory-order.service.js +181 -0
  136. package/lib/services/sale-order.service.d.ts +7 -0
  137. package/lib/services/sale-order.service.js +20 -0
  138. package/lib/services/scrape.service.d.ts +18 -0
  139. package/lib/services/scrape.service.js +139 -0
  140. package/lib/services/ship-inventory-order.service.d.ts +60 -0
  141. package/lib/services/ship-inventory-order.service.js +599 -0
  142. package/lib/services/split-batch-order.service.d.ts +19 -0
  143. package/lib/services/split-batch-order.service.js +161 -0
  144. package/lib/services/stock.service.d.ts +38 -0
  145. package/lib/services/stock.service.js +477 -0
  146. package/lib/services/transfer-customer-order.service.d.ts +35 -0
  147. package/lib/services/transfer-customer-order.service.js +279 -0
  148. package/lib/services/transfer-order.service.d.ts +44 -0
  149. package/lib/services/transfer-order.service.js +632 -0
  150. package/lib/services/transfer-vendor-order.service.d.ts +35 -0
  151. package/lib/services/transfer-vendor-order.service.js +279 -0
  152. package/lib/services/unit.service.d.ts +7 -0
  153. package/lib/services/unit.service.js +67 -0
  154. package/lib/services/warehouse-map.service.d.ts +10 -0
  155. package/lib/services/warehouse-map.service.js +38 -0
  156. package/lib/typings/aggregated-stock.d.ts +22 -0
  157. package/lib/typings/cancel-ship-inventory-order.input.d.ts +4 -0
  158. package/lib/typings/cancel-transfer-order.input.d.ts +4 -0
  159. package/lib/typings/core-module-options.d.ts +8 -0
  160. package/lib/typings/core-module-options.js +3 -0
  161. package/lib/typings/create-allocate-inventory-order.input.d.ts +25 -0
  162. package/lib/typings/create-hold-inventory-order.input.d.ts +21 -0
  163. package/lib/typings/create-inspection-order.input.d.ts +14 -0
  164. package/lib/typings/create-loader-type.input.d.ts +9 -0
  165. package/lib/typings/create-loader.input.d.ts +15 -0
  166. package/lib/typings/create-location.input.d.ts +12 -0
  167. package/lib/typings/create-material-unit.input.d.ts +5 -0
  168. package/lib/typings/create-material.input.d.ts +11 -0
  169. package/lib/typings/create-receive-inventory-order.input.d.ts +26 -0
  170. package/lib/typings/create-ship-inventory-order.input.d.ts +46 -0
  171. package/lib/typings/create-transfer-customer-order.input.d.ts +25 -0
  172. package/lib/typings/create-transfer-order.input.d.ts +25 -0
  173. package/lib/typings/create-transfer-vendor-order.input.d.ts +25 -0
  174. package/lib/typings/deallocate-inventory-order.d.ts +8 -0
  175. package/lib/typings/find-allocate-inventory-order.input.d.ts +13 -0
  176. package/lib/typings/find-batch.input.d.ts +8 -0
  177. package/lib/typings/find-hold-inventory-order.input.d.ts +13 -0
  178. package/lib/typings/find-loader.input.d.ts +33 -0
  179. package/lib/typings/find-location.input.d.ts +10 -0
  180. package/lib/typings/find-material.input.d.ts +10 -0
  181. package/lib/typings/find-receive-inventory-order.input.d.ts +26 -0
  182. package/lib/typings/find-receive-inventory-order.input.js +9 -0
  183. package/lib/typings/find-ship-inventory-order.input.d.ts +26 -0
  184. package/lib/typings/find-ship-inventory-order.input.js +9 -0
  185. package/lib/typings/find-stock.input.d.ts +21 -0
  186. package/lib/typings/find-transfer-order.input.d.ts +21 -0
  187. package/lib/typings/get-batch.input.d.ts +14 -0
  188. package/lib/typings/index.d.ts +18 -0
  189. package/lib/typings/merge-batch.input.d.ts +11 -0
  190. package/lib/typings/paginations.d.ts +4 -0
  191. package/lib/typings/receive-inventory-order.input.d.ts +8 -0
  192. package/lib/typings/reclassify-inventory-order.input.d.ts +11 -0
  193. package/lib/typings/release-inventory-order.input.d.ts +8 -0
  194. package/lib/typings/scrape.input.d.ts +8 -0
  195. package/lib/typings/ship-inventory-order.input.d.ts +4 -0
  196. package/lib/typings/split-batch.input.d.ts +10 -0
  197. package/lib/typings/transfer-order.input.d.ts +4 -0
  198. package/package.json +52 -0
  199. package/src/lib/models/extensions/README.md +219 -0
@@ -0,0 +1,477 @@
1
+ import { __decorate, __param, __metadata } from 'tslib';
2
+ import { Injectable, Inject } from '@nestjs/common';
3
+ import { StockEntity } from '../models/metadata/stock.entity.js';
4
+ import { DataSource } from 'typeorm';
5
+ import { MaterialEntity, MaterialEntityClass } from '../models/metadata/material.entity.js';
6
+ import { StockStatus, ChangeType } from '../constants/stock-status.js';
7
+ import { BatchEntity } from '@rytass/wms-base-nestjs-module';
8
+ import '../models/metadata/batch.entity.js';
9
+ import '../models/metadata/batch-group.entity.js';
10
+ import { LoadersEntityClass } from '../models/metadata/loader.entity.js';
11
+ import { LoaderTypeEntityClass } from '../models/metadata/loader-type.entity.js';
12
+ import '../models/metadata/loader-unit.entity.js';
13
+ import { LocationEntityClass } from '../models/metadata/location.entity.js';
14
+ import '../models/metadata/material-unit.entity.js';
15
+ import '../models/metadata/sale-order.entity.js';
16
+ import '../models/metadata/unit.entity.js';
17
+ import '../models/extensions/receive-inventory-order/receive-inventory-order-item.entity.js';
18
+ import '../models/extensions/receive-inventory-order/receive-inventory-order.entity.js';
19
+ import '../models/extensions/receive-inventory-order/receive-inventory-order-change.entity.js';
20
+ import '../models/extensions/ship-inventory-order/ship-inventory-order-item.entity.js';
21
+ import '../models/extensions/ship-inventory-order/ship-inventory-order.entity.js';
22
+ import '../models/extensions/ship-inventory-order/ship-inventory-order-reference.entity.js';
23
+ import '../models/extensions/ship-inventory-order/ship-inventory-order-change.entity.js';
24
+ import '../models/extensions/transfer-order/transfer-order.entity.js';
25
+ import '../models/extensions/transfer-order/transfer-order-item.entity.js';
26
+ import '../models/extensions/transfer-order/transfer-order-change.entity.js';
27
+ import '../models/extensions/hold-inventory-order/hold-inventory-order.entity.js';
28
+ import '../models/extensions/hold-inventory-order/hold-inventory-order-item.entity.js';
29
+ import '../models/extensions/hold-inventory-order/hold-inventory-order-change.entity.js';
30
+ import '../models/extensions/allocate-inventory-order/allocate-inventory-order.entity.js';
31
+ import '../models/extensions/allocate-inventory-order/allocate-inventory-order-item.entity.js';
32
+ import '../models/extensions/allocate-inventory-order/allocate-inventory-order-change.entity.js';
33
+ import '../models/extensions/split-batch-order/split-batch-order.entity.js';
34
+ import '../models/extensions/split-batch-order/split-batch-order-item.entity.js';
35
+ import '../models/extensions/split-batch-order/split-batch-order-change.entity.js';
36
+ import '../models/extensions/merge-batch-order/merge-batch-order.entity.js';
37
+ import '../models/extensions/merge-batch-order/merge-batch-order-item.entity.js';
38
+ import '../models/extensions/merge-batch-order/merge-batch-order-change.entity.js';
39
+ import '../models/extensions/reclassify-inventory-order/reclassify-inventory-order.entity.js';
40
+ import '../models/extensions/reclassify-inventory-order/reclassify-inventory-order-item.entity.js';
41
+ import '../models/extensions/reclassify-inventory-order/reclassify-inventory-order-change.entity.js';
42
+ import '../models/extensions/transfer-vendor-order/transfer-vendor-order.entity.js';
43
+ import '../models/extensions/transfer-vendor-order/transfer-vendor-order-item.entity.js';
44
+ import '../models/extensions/transfer-vendor-order/transfer-vendor-order-change.entity.js';
45
+ import '../models/extensions/quality-inspection-order/quality-inspection-order.entity.js';
46
+ import '../models/extensions/quality-inspection-order/quality-inspection-order-item.entity.js';
47
+ import '../models/extensions/quality-inspection-order/quality-inspection-order-change.entity.js';
48
+ import '../models/extensions/transfer-customer-order/transfer-customer-order.entity.js';
49
+ import '../models/extensions/transfer-customer-order/transfer-customer-order-item.entity.js';
50
+ import '../models/extensions/transfer-customer-order/transfer-customer-order-change.entity.js';
51
+ import '../models/extensions/scrape-order/scrape-order.entity.js';
52
+ import '../models/extensions/scrape-order/scrape-order-item.entity.js';
53
+ import '../models/extensions/scrape-order/scrape-order-change.entity.js';
54
+ import { WMS_CORE_MODULE_OPTIONS } from '../typings/core-module-options.js';
55
+
56
+ let StockService = class StockService {
57
+ dataSource;
58
+ stockEntity;
59
+ materialEntity;
60
+ coreOptions;
61
+ defaultLoaderId;
62
+ defaultLocationId;
63
+ stockRepository;
64
+ selectQueryBuilder;
65
+ aggregateKeys = ['materialId', 'batchId', 'locationId', 'loaderId', 'status'];
66
+ generatedAggregateKey = (aggregated) => {
67
+ return this.aggregateKeys.map((key) => aggregated[key]).join('|');
68
+ };
69
+ destructAggregateKey = (key) => {
70
+ const [materialId, batchId, locationId, loaderId, status] = key.split('|');
71
+ return {
72
+ materialId,
73
+ batchId,
74
+ locationId,
75
+ loaderId,
76
+ status: status,
77
+ };
78
+ };
79
+ constructor(dataSource, stockEntity, materialEntity, coreOptions) {
80
+ this.dataSource = dataSource;
81
+ this.stockEntity = stockEntity;
82
+ this.materialEntity = materialEntity;
83
+ this.coreOptions = coreOptions;
84
+ this.stockRepository = this.dataSource.getRepository(this.stockEntity);
85
+ // select builder for status and quantity calculation, calculated field will override fields in stock entity.
86
+ // every query should use this selectQueryBuilder to ensure status and quantity are correct
87
+ // status is resolved from batch flags: inShipment → IN_SHIPMENT, held → HELD, inTransfer → IN_TRANSFER, else → FREE
88
+ this.selectQueryBuilder = (alias, qb = this.dataSource
89
+ .getRepository(this.stockEntity)
90
+ .createQueryBuilder(alias)) => qb
91
+ .leftJoin((subQuery) => subQuery
92
+ .select(`CASE
93
+ WHEN b."inShipment" = true THEN '${StockStatus.IN_SHIPMENT}'
94
+ WHEN b."held" = true THEN '${StockStatus.HELD}'
95
+ WHEN b."transferId" IS NOT NULL THEN '${StockStatus.IN_TRANSFER}'
96
+ ELSE '${StockStatus.FREE}'
97
+ END`, 'status')
98
+ .addSelect('s.id', 'stockId')
99
+ .addSelect('b."transferId"', 'transferId')
100
+ .addSelect('b."held"', 'held')
101
+ .addSelect('b."inShipment"', 'inShipment')
102
+ .addSelect('b."inspectionResult"', 'inspectionResult')
103
+ .addSelect('b."saleId"', 'saleId')
104
+ .addSelect('b."vendorId"', 'vendorId')
105
+ .addSelect('b."customerId"', 'customerId')
106
+ .from('stocks', 's')
107
+ .innerJoin('batches', 'b', 's."batchId" = b.id'), 'stock_status', `stock_status."stockId" = ${alias}.id`)
108
+ .addSelect('stock_status.status', 'status')
109
+ .addSelect('stock_status."transferId"', 'transferId')
110
+ .addSelect('stock_status.held', 'held')
111
+ .addSelect('stock_status."inShipment"', 'inShipment')
112
+ .addSelect('stock_status."inspectionResult"', 'inspectionResult')
113
+ .addSelect('stock_status."saleId"', 'saleId')
114
+ .addSelect('stock_status."vendorId"', 'vendorId')
115
+ .addSelect('stock_status."customerId"', 'customerId')
116
+ .addSelect(`${alias}.*`);
117
+ }
118
+ async onModuleInit() {
119
+ const loaderTypeRepo = this.dataSource.getRepository(LoaderTypeEntityClass);
120
+ const locationRepo = this.dataSource.getRepository(LocationEntityClass);
121
+ const loaderRepo = this.dataSource.getRepository(LoadersEntityClass);
122
+ // Ensure default loader type exists
123
+ let loaderType = await loaderTypeRepo.findOneBy({
124
+ key: this.coreOptions.defaultLoaderTypeKey,
125
+ });
126
+ if (!loaderType) {
127
+ loaderType = await loaderTypeRepo.save(loaderTypeRepo.create({
128
+ key: this.coreOptions.defaultLoaderTypeKey,
129
+ description: this.coreOptions.defaultLoaderTypeKey,
130
+ }));
131
+ }
132
+ // Ensure default location exists
133
+ let location = await locationRepo.findOneBy({
134
+ key: this.coreOptions.defaultLocationKey,
135
+ });
136
+ if (!location) {
137
+ location = await locationRepo.save(locationRepo.create({
138
+ key: this.coreOptions.defaultLocationKey,
139
+ description: this.coreOptions.defaultLocationKey,
140
+ }));
141
+ }
142
+ this.defaultLocationId = location.id;
143
+ // Ensure default loader exists
144
+ let loader = await loaderRepo.findOneBy({
145
+ serialId: this.coreOptions.defaultLoaderSerialId,
146
+ });
147
+ if (!loader) {
148
+ loader = await loaderRepo.save(loaderRepo.create({
149
+ serialId: this.coreOptions.defaultLoaderSerialId,
150
+ typeId: loaderType.id,
151
+ locationId: location.id,
152
+ }));
153
+ }
154
+ this.defaultLoaderId = loader.id;
155
+ }
156
+ resolveLoaderId(loaderId) {
157
+ return loaderId || this.defaultLoaderId;
158
+ }
159
+ resolveLocationId(locationId) {
160
+ return locationId || this.defaultLocationId;
161
+ }
162
+ pipeSelectOptionsToQueryBuilder(options, queryBuilder, aggregated = false) {
163
+ if (options.materialId)
164
+ queryBuilder.andWhere('stock."materialId" = :materialId', {
165
+ materialId: options.materialId,
166
+ });
167
+ if (options.batchId)
168
+ queryBuilder.andWhere('stock."batchId" = :batchId', {
169
+ batchId: options.batchId,
170
+ });
171
+ if (options.locationId)
172
+ queryBuilder.andWhere('stock."locationId" = :locationId', {
173
+ locationId: options.locationId,
174
+ });
175
+ if (options.loaderId)
176
+ queryBuilder.andWhere('stock."loaderId" = :loaderId', {
177
+ loaderId: options.loaderId,
178
+ });
179
+ if (options.description)
180
+ queryBuilder.andWhere('stock."description" ILIKE :description', {
181
+ description: `%${options.description}%`,
182
+ });
183
+ if (options.wildcard) {
184
+ const { key, value } = options.wildcard;
185
+ queryBuilder.andWhere(`location."${String(key)}" ILIKE :value`, {
186
+ value: `%${value}%`,
187
+ });
188
+ }
189
+ if (options.status) {
190
+ switch (options.status) {
191
+ case StockStatus.PENDING_INSPECTION:
192
+ queryBuilder.andWhere('stock_status."inspectionResult" IS NULL');
193
+ break;
194
+ case StockStatus.INSPECTION_FAILED:
195
+ queryBuilder.andWhere('stock_status."inspectionResult" = false');
196
+ break;
197
+ case StockStatus.ALLOCATED:
198
+ queryBuilder.andWhere('stock_status."saleId" IS NOT NULL');
199
+ break;
200
+ case StockStatus.VENDOR_INVENTORY:
201
+ queryBuilder.andWhere('stock_status."vendorId" IS NOT NULL');
202
+ break;
203
+ case StockStatus.CUSTOMER_INVENTORY:
204
+ queryBuilder.andWhere('stock_status."customerId" IS NOT NULL');
205
+ break;
206
+ default:
207
+ queryBuilder.andWhere('stock_status.status = :status', {
208
+ status: options.status,
209
+ });
210
+ break;
211
+ }
212
+ }
213
+ if (options.negateStatus) {
214
+ switch (options.negateStatus) {
215
+ case StockStatus.PENDING_INSPECTION:
216
+ queryBuilder.andWhere('stock_status."inspectionResult" IS NOT NULL');
217
+ break;
218
+ case StockStatus.INSPECTION_FAILED:
219
+ queryBuilder.andWhere('(stock_status."inspectionResult" IS NULL OR stock_status."inspectionResult" != false)');
220
+ break;
221
+ case StockStatus.ALLOCATED:
222
+ queryBuilder.andWhere('stock_status."saleId" IS NULL');
223
+ break;
224
+ case StockStatus.VENDOR_INVENTORY:
225
+ queryBuilder.andWhere('stock_status."vendorId" IS NULL');
226
+ break;
227
+ case StockStatus.CUSTOMER_INVENTORY:
228
+ queryBuilder.andWhere('stock_status."customerId" IS NULL');
229
+ break;
230
+ default:
231
+ queryBuilder.andWhere('stock_status.status != :negateStatus', {
232
+ negateStatus: options.negateStatus,
233
+ });
234
+ break;
235
+ }
236
+ }
237
+ if (options.materialKey)
238
+ queryBuilder.innerJoin(MaterialEntityClass, 'mk', 'mk.id = stock."materialId" AND mk.key ILIKE :materialKey', {
239
+ materialKey: `%${options.materialKey}%`,
240
+ });
241
+ if (options.batchKey)
242
+ queryBuilder.innerJoin(BatchEntity, 'bk', 'bk.id = stock."batchId" AND bk.key ILIKE :batchKey', {
243
+ batchKey: `%${options.batchKey}%`,
244
+ });
245
+ if (options.locationKey)
246
+ queryBuilder.innerJoin(LocationEntityClass, 'lk', 'lk.id = stock."locationId" AND lk.key ILIKE :locationKey', {
247
+ locationKey: `%${options.locationKey}%`,
248
+ });
249
+ if (options.loaderKey)
250
+ queryBuilder.innerJoin(LoadersEntityClass, 'lk', 'lk.id = stock."loaderId" AND lk."serialId" ILIKE :loaderKey', {
251
+ loaderKey: `%${options.loaderKey}%`,
252
+ });
253
+ if (options.offset !== undefined && options.offset >= 0)
254
+ queryBuilder.skip(options.offset);
255
+ if (options.limit !== undefined && options.limit > 0)
256
+ queryBuilder.take(options.limit);
257
+ if (aggregated) {
258
+ queryBuilder.innerJoin('batches', 'b', 'stock."batchId" = b.id');
259
+ queryBuilder.select('stock."materialId"', 'materialId');
260
+ queryBuilder.addSelect('stock."batchId"', 'batchId');
261
+ queryBuilder.addSelect('stock."locationId"', 'locationId');
262
+ queryBuilder.addSelect('stock."loaderId"', 'loaderId');
263
+ queryBuilder.addSelect('stock_status.status', 'status');
264
+ queryBuilder.addSelect('stock_status."transferId"', 'transferId');
265
+ queryBuilder.addSelect('stock_status."held"', 'held');
266
+ queryBuilder.addSelect('stock_status."inShipment"', 'inShipment');
267
+ queryBuilder.addSelect('b."saleId"', 'saleId');
268
+ queryBuilder.addSelect('b."saleSerialId"', 'saleSerialId');
269
+ queryBuilder.addSelect('b."customerId"', 'customerId');
270
+ queryBuilder.addSelect('b."vendorId"', 'vendorId');
271
+ queryBuilder.addSelect('b."inspectionResult"', 'inspectionResult');
272
+ queryBuilder.addSelect('SUM(stock.quantity)', 'quantity');
273
+ queryBuilder.groupBy('stock."materialId"');
274
+ queryBuilder.addGroupBy('stock."batchId"');
275
+ queryBuilder.addGroupBy('stock."locationId"');
276
+ queryBuilder.addGroupBy('stock."loaderId"');
277
+ queryBuilder.addGroupBy('stock_status.status');
278
+ queryBuilder.addGroupBy('stock_status."transferId"');
279
+ queryBuilder.addGroupBy('stock_status."held"');
280
+ queryBuilder.addGroupBy('stock_status."inShipment"');
281
+ queryBuilder.addGroupBy('b."saleId"');
282
+ queryBuilder.addGroupBy('b."saleSerialId"');
283
+ queryBuilder.addGroupBy('b."customerId"');
284
+ queryBuilder.addGroupBy('b."vendorId"');
285
+ queryBuilder.addGroupBy('b."inspectionResult"');
286
+ queryBuilder.having('SUM(stock.quantity) <> 0');
287
+ if (options.aggregatedKeys?.length)
288
+ queryBuilder.andHaving([
289
+ 'stock."materialId"',
290
+ 'stock."batchId"',
291
+ 'stock."locationId"',
292
+ 'stock."loaderId"',
293
+ 'stock_status.status',
294
+ ].join(" || '|' || ") + ' IN (:...aggregatedKeys)', {
295
+ aggregatedKeys: options.aggregatedKeys,
296
+ });
297
+ }
298
+ return queryBuilder;
299
+ }
300
+ findMany(options) {
301
+ const queryBuilder = this.pipeSelectOptionsToQueryBuilder(options, this.selectQueryBuilder('stock'));
302
+ return queryBuilder.getManyAndCount();
303
+ }
304
+ async findManyGroupedByMaterialId(options) {
305
+ // Build aggregated subquery to get distinct materialIds where SUM(quantity) != 0
306
+ const aggregateSubquery = this.pipeSelectOptionsToQueryBuilder({ ...options, offset: undefined, limit: undefined }, this.selectQueryBuilder('stock'), true);
307
+ const rawMaterialIds = await this.dataSource
308
+ .createQueryBuilder()
309
+ .select('DISTINCT agg."materialId"', 'materialId')
310
+ .from(`(${aggregateSubquery.getQuery()})`, 'agg')
311
+ .setParameters(aggregateSubquery.getParameters())
312
+ .getRawMany();
313
+ const ids = rawMaterialIds.map((r) => r.materialId);
314
+ if (ids.length === 0)
315
+ return [[], 0];
316
+ const queryBuilder = this.dataSource
317
+ .getRepository(this.materialEntity)
318
+ .createQueryBuilder('material')
319
+ .where('material.id IN (:...materialIds)', { materialIds: ids });
320
+ if (options.offset !== undefined && options.offset >= 0)
321
+ queryBuilder.skip(options.offset);
322
+ if (options.limit !== undefined && options.limit > 0)
323
+ queryBuilder.take(options.limit);
324
+ return queryBuilder.getManyAndCount();
325
+ }
326
+ async findAggregatedStock(options, manager = this.dataSource.manager) {
327
+ const queryBuilder = this.pipeSelectOptionsToQueryBuilder(options, this.selectQueryBuilder('stock', manager.getRepository(this.stockEntity).createQueryBuilder('stock')), true);
328
+ return queryBuilder.getRawOne();
329
+ }
330
+ async validateStockAvailability(params, manager = this.dataSource.manager) {
331
+ const { materialId, batchId, locationId, loaderId, quantity } = params;
332
+ const aggregateQuery = this.pipeSelectOptionsToQueryBuilder({ materialId, batchId, locationId, loaderId }, this.selectQueryBuilder('stock', manager.getRepository(this.stockEntity).createQueryBuilder('stock')), true);
333
+ const result = await manager
334
+ .createQueryBuilder()
335
+ .select('COALESCE(SUM(agg.quantity), 0)', 'total')
336
+ .from(`(${aggregateQuery.getQuery()})`, 'agg')
337
+ .setParameters(aggregateQuery.getParameters())
338
+ .getRawOne();
339
+ const available = parseFloat(result?.total ?? '0');
340
+ if (available < quantity) {
341
+ throw new Error(`Insufficient stock: available ${available}, requested ${quantity} (materialId=${materialId}, batchId=${batchId}, loaderId=${loaderId})`);
342
+ }
343
+ }
344
+ async findAggregatedStocks(options) {
345
+ // Create the aggregated subquery without pagination
346
+ const aggregateSubquery = this.pipeSelectOptionsToQueryBuilder({ ...options, offset: undefined, limit: undefined }, this.selectQueryBuilder('stock'), options.aggregated ? true : false);
347
+ // Wrap the aggregated subquery and apply pagination on top
348
+ const paginatedQueryBuilder = this.dataSource
349
+ .createQueryBuilder()
350
+ .addSelect('agg.quantity', 'quantity')
351
+ .from(`(${aggregateSubquery.getQuery()})`, 'agg')
352
+ .setParameters(aggregateSubquery.getParameters());
353
+ this.aggregateKeys.forEach((key) => paginatedQueryBuilder.addSelect(`agg."${key}"`, key));
354
+ // Add batch-related fields
355
+ paginatedQueryBuilder.addSelect('agg."transferId"', 'transferId');
356
+ paginatedQueryBuilder.addSelect('agg."held"', 'held');
357
+ paginatedQueryBuilder.addSelect('agg."inShipment"', 'inShipment');
358
+ paginatedQueryBuilder.addSelect('agg."saleId"', 'saleId');
359
+ paginatedQueryBuilder.addSelect('agg."saleSerialId"', 'saleSerialId');
360
+ paginatedQueryBuilder.addSelect('agg."customerId"', 'customerId');
361
+ paginatedQueryBuilder.addSelect('agg."vendorId"', 'vendorId');
362
+ paginatedQueryBuilder.addSelect('agg."inspectionResult"', 'inspectionResult');
363
+ // Apply pagination to the outer query
364
+ if (options.offset !== undefined && options.offset >= 0) {
365
+ paginatedQueryBuilder.skip(options.offset);
366
+ }
367
+ if (options.limit !== undefined && options.limit > 0) {
368
+ paginatedQueryBuilder.take(options.limit);
369
+ }
370
+ // Get total count from the aggregated subquery
371
+ const countBuilder = this.pipeSelectOptionsToQueryBuilder({ ...options, offset: undefined, limit: undefined }, this.selectQueryBuilder('stock'), options.aggregated ? true : false);
372
+ const countResult = await this.dataSource
373
+ .createQueryBuilder()
374
+ .select('COUNT(*)', 'count')
375
+ .from(`(${countBuilder.getQuery()})`, 'grouped')
376
+ .setParameters(countBuilder.getParameters())
377
+ .getRawOne();
378
+ const count = parseInt(countResult?.count ?? '0', 10);
379
+ const items = await paginatedQueryBuilder.getRawMany();
380
+ return [items, count];
381
+ }
382
+ async findChangeLogs(options) {
383
+ // Build base query with all change entity joins
384
+ const changesQueryBuilder = this.pipeSelectOptionsToQueryBuilder({ ...options, offset: undefined, limit: undefined }, this.selectQueryBuilder('stock'), false)
385
+ .leftJoin('receive_inventory_order_changes', 'receive_change', 'stock."orderId" = receive_change.id')
386
+ .leftJoin('ship_inventory_order_changes', 'ship_change', 'stock."orderId" = ship_change.id')
387
+ .leftJoin('transfer_order_changes', 'transfer_change', 'stock."orderId" = transfer_change.id')
388
+ .leftJoin('transfer_vendor_order_changes', 'vendor_change', 'stock."orderId" = vendor_change.id')
389
+ .leftJoin('transfer_customer_order_changes', 'customer_change', 'stock."orderId" = customer_change.id')
390
+ .leftJoin('hold_inventory_order_changes', 'hold_change', 'stock."orderId" = hold_change.id')
391
+ .leftJoin('split_batch_order_changes', 'split_change', 'stock."orderId" = split_change.id')
392
+ .leftJoin('merge_batch_order_changes', 'merge_change', 'stock."orderId" = merge_change.id')
393
+ .leftJoin('allocate_inventory_order_changes', 'allocate_change', 'stock."orderId" = allocate_change.id')
394
+ .leftJoin('reclassify_inventory_order_changes', 'reclassify_change', 'stock."orderId" = reclassify_change.id')
395
+ .leftJoin('scrape_order_changes', 'scrape_change', 'stock."orderId" = scrape_change.id')
396
+ .andWhere(`(
397
+ (receive_change.id IS NOT NULL AND receive_change."quantityChanged" * stock.quantity > 0)
398
+ OR (ship_change.id IS NOT NULL AND ship_change."quantityChanged" * stock.quantity > 0)
399
+ OR (transfer_change.id IS NOT NULL AND transfer_change."quantityChanged" * stock.quantity > 0)
400
+ OR (vendor_change.id IS NOT NULL AND vendor_change."quantityChanged" * stock.quantity > 0)
401
+ OR (customer_change.id IS NOT NULL AND customer_change."quantityChanged" * stock.quantity > 0)
402
+ OR (hold_change.id IS NOT NULL AND hold_change."quantityChanged" * stock.quantity > 0)
403
+ OR (split_change.id IS NOT NULL AND split_change."quantityChanged" * stock.quantity > 0)
404
+ OR (merge_change.id IS NOT NULL AND merge_change."quantityChanged" * stock.quantity > 0)
405
+ OR (allocate_change.id IS NOT NULL AND allocate_change."quantityChanged" * stock.quantity > 0)
406
+ OR (reclassify_change.id IS NOT NULL AND reclassify_change."quantityChanged" * stock.quantity > 0)
407
+ OR (scrape_change.id IS NOT NULL AND scrape_change."quantityChanged" * stock.quantity > 0)
408
+ )`);
409
+ // Get count from the filtered base query (before adding expensive CASE)
410
+ const countQuerySimple = changesQueryBuilder
411
+ .clone()
412
+ .select('COUNT(DISTINCT stock.id)', 'count');
413
+ const countResult = await this.dataSource
414
+ .createQueryBuilder()
415
+ .select('SUM(counted.count)', 'total')
416
+ .from(`(${countQuerySimple.getQuery()})`, 'counted')
417
+ .setParameters(countQuerySimple.getParameters())
418
+ .getRawOne();
419
+ const count = parseInt(countResult?.total ?? '0', 10);
420
+ // Add changeType CASE only after we have the filtered result set, apply pagination
421
+ const resultQueryBuilder = changesQueryBuilder.clone();
422
+ if (options.offset !== undefined && options.offset >= 0) {
423
+ resultQueryBuilder.skip(options.offset);
424
+ }
425
+ if (options.limit !== undefined && options.limit > 0) {
426
+ resultQueryBuilder.take(options.limit);
427
+ }
428
+ // Explicitly select only the fields needed for ChangeLog
429
+ resultQueryBuilder
430
+ .select('stock.id', 'id')
431
+ .addSelect('stock.quantity', 'quantity')
432
+ .addSelect('stock_status.status', 'status')
433
+ .addSelect('stock."materialId"', 'materialId')
434
+ .addSelect('stock."batchId"', 'batchId')
435
+ .addSelect('stock."locationId"', 'locationId')
436
+ .addSelect('stock."loaderId"', 'loaderId')
437
+ .addSelect(`CASE
438
+ WHEN receive_change.id IS NOT NULL THEN '${ChangeType.RECEIVED}'
439
+ WHEN ship_change.id IS NOT NULL THEN
440
+ CASE WHEN ship_change."quantityChanged" > 0 THEN '${ChangeType.IN_SHIPMENT}'
441
+ ELSE '${ChangeType.SHIPPED}' END
442
+ WHEN transfer_change.id IS NOT NULL THEN
443
+ CASE WHEN transfer_change."quantityChanged" > 0 THEN '${ChangeType.IN_TRANSFER}'
444
+ ELSE '${ChangeType.TRANSFERRED}' END
445
+ WHEN vendor_change.id IS NOT NULL THEN
446
+ CASE WHEN vendor_change."quantityChanged" > 0 THEN '${ChangeType.VENDOR_TRANSFERRED}'
447
+ ELSE '${ChangeType.VENDOR_RETURNED}' END
448
+ WHEN customer_change.id IS NOT NULL THEN
449
+ CASE WHEN customer_change."quantityChanged" > 0 THEN '${ChangeType.CUSTOMER_HELD}'
450
+ ELSE '${ChangeType.CUSTOMER_RETURNED}' END
451
+ WHEN hold_change.id IS NOT NULL THEN
452
+ CASE WHEN hold_change."quantityChanged" > 0 THEN '${ChangeType.HELD}'
453
+ ELSE '${ChangeType.RELEASED}' END
454
+ WHEN split_change.id IS NOT NULL THEN '${ChangeType.SPLITTED}'
455
+ WHEN merge_change.id IS NOT NULL THEN '${ChangeType.MERGED}'
456
+ WHEN allocate_change.id IS NOT NULL THEN
457
+ CASE WHEN allocate_change."quantityChanged" > 0 THEN '${ChangeType.ALLOCATED}'
458
+ ELSE '${ChangeType.DEALLOCATED}' END
459
+ WHEN reclassify_change.id IS NOT NULL THEN '${ChangeType.RECLASSIFIED}'
460
+ WHEN scrape_change.id IS NOT NULL THEN '${ChangeType.SCRAPED}'
461
+ ELSE NULL
462
+ END`, 'changeType');
463
+ const items = await resultQueryBuilder
464
+ .addOrderBy('stock."createdAt"', 'DESC')
465
+ .getRawMany();
466
+ return [items, count];
467
+ }
468
+ };
469
+ StockService = __decorate([
470
+ Injectable(),
471
+ __param(1, Inject(StockEntity)),
472
+ __param(2, Inject(MaterialEntity)),
473
+ __param(3, Inject(WMS_CORE_MODULE_OPTIONS)),
474
+ __metadata("design:paramtypes", [DataSource, Object, Object, Object])
475
+ ], StockService);
476
+
477
+ export { StockService };
@@ -0,0 +1,35 @@
1
+ import { TransferCustomerOrderEntityClass, TransferCustomerOrderItemEntityClass, StockEntityClass } from '../models';
2
+ import { DataSource, EntityManager, EntityTarget } from 'typeorm';
3
+ import { CreateTransferCustomerOrderInput, UpdateTransferCustomerOrderInput } from '../typings/create-transfer-customer-order.input';
4
+ import { HelperService } from './helper.service';
5
+ import { MaterialService } from './material.service';
6
+ import { BatchService } from './batch.service';
7
+ import { StockService } from './stock.service';
8
+ export type TransferCustomerOrderItemInput = {
9
+ materialId: string;
10
+ batchId: string;
11
+ locationId?: string;
12
+ loaderId?: string;
13
+ quantity: number;
14
+ locationKey: string;
15
+ loaderKey?: string;
16
+ };
17
+ export declare class TransferCustomerOrderService<T extends TransferCustomerOrderEntityClass = TransferCustomerOrderEntityClass, K extends TransferCustomerOrderItemEntityClass = TransferCustomerOrderItemEntityClass> {
18
+ private readonly dataSource;
19
+ private readonly helperService;
20
+ private readonly materialService;
21
+ private readonly batchService;
22
+ private readonly stockService;
23
+ readonly transferCustomerOrderEntity: EntityTarget<T>;
24
+ readonly transferCustomerOrderItemEntity: EntityTarget<K>;
25
+ readonly stockEntity: EntityTarget<StockEntityClass>;
26
+ private readonly seqPrefix;
27
+ constructor(dataSource: DataSource, helperService: HelperService, materialService: MaterialService, batchService: BatchService, stockService: StockService, transferCustomerOrderEntity: EntityTarget<T>, transferCustomerOrderItemEntity: EntityTarget<K>, stockEntity: EntityTarget<StockEntityClass>);
28
+ private getRepositories;
29
+ private processTransferCustomerOrderItems;
30
+ createTransferCustomerOrder(options: CreateTransferCustomerOrderInput, manager?: EntityManager): Promise<T>;
31
+ updateTransferCustomerOrder({ id, manager, ...options }: UpdateTransferCustomerOrderInput & {
32
+ manager?: EntityManager;
33
+ }): Promise<T>;
34
+ returnTransferCustomerOrder(options: TransferCustomerOrderItemInput | TransferCustomerOrderItemInput[], manager?: EntityManager): Promise<T>;
35
+ }