@things-factory/warehouse-base 5.0.14 → 6.0.0-alpha.3

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 (142) hide show
  1. package/dist-server/controllers/ecommerce/ecommerce-controller.js +1 -1
  2. package/dist-server/controllers/ecommerce/ecommerce-controller.js.map +1 -1
  3. package/dist-server/controllers/ecommerce/sellercraft-controller.js +64 -60
  4. package/dist-server/controllers/ecommerce/sellercraft-controller.js.map +1 -1
  5. package/dist-server/controllers/warehouse-controller.js +7 -5
  6. package/dist-server/controllers/warehouse-controller.js.map +1 -1
  7. package/dist-server/service/inventory/inventory-mutation.js +6 -6
  8. package/dist-server/service/inventory/inventory-mutation.js.map +1 -1
  9. package/dist-server/service/inventory/inventory-query.js +217 -195
  10. package/dist-server/service/inventory/inventory-query.js.map +1 -1
  11. package/dist-server/service/inventory/inventory-types.js +14 -15
  12. package/dist-server/service/inventory/inventory-types.js.map +1 -1
  13. package/dist-server/service/inventory/inventory.js +62 -42
  14. package/dist-server/service/inventory/inventory.js.map +1 -1
  15. package/dist-server/service/inventory-change/inventory-change-mutation.js +252 -216
  16. package/dist-server/service/inventory-change/inventory-change-mutation.js.map +1 -1
  17. package/dist-server/service/inventory-change/inventory-change-query.js +6 -7
  18. package/dist-server/service/inventory-change/inventory-change-query.js.map +1 -1
  19. package/dist-server/service/inventory-change/inventory-change.js +7 -7
  20. package/dist-server/service/inventory-change/inventory-change.js.map +1 -1
  21. package/dist-server/service/inventory-history/inventory-history-mutation.js +1 -1
  22. package/dist-server/service/inventory-history/inventory-history-mutation.js.map +1 -1
  23. package/dist-server/service/inventory-history/inventory-history-query.js +89 -99
  24. package/dist-server/service/inventory-history/inventory-history-query.js.map +1 -1
  25. package/dist-server/service/inventory-history/inventory-history-types.js +3 -3
  26. package/dist-server/service/inventory-history/inventory-history-types.js.map +1 -1
  27. package/dist-server/service/inventory-history/inventory-history.js +7 -7
  28. package/dist-server/service/inventory-history/inventory-history.js.map +1 -1
  29. package/dist-server/service/inventory-item/inventory-item-mutation.js +10 -10
  30. package/dist-server/service/inventory-item/inventory-item-mutation.js.map +1 -1
  31. package/dist-server/service/inventory-item/inventory-item-query.js +18 -17
  32. package/dist-server/service/inventory-item/inventory-item-query.js.map +1 -1
  33. package/dist-server/service/inventory-item/inventory-item-type.js +4 -5
  34. package/dist-server/service/inventory-item/inventory-item-type.js.map +1 -1
  35. package/dist-server/service/inventory-item/inventory-item.js +5 -5
  36. package/dist-server/service/inventory-item/inventory-item.js.map +1 -1
  37. package/dist-server/service/inventory-item-change/inventory-item-change-mutation.js +4 -4
  38. package/dist-server/service/inventory-item-change/inventory-item-change-mutation.js.map +1 -1
  39. package/dist-server/service/inventory-item-change/inventory-item-change-query.js +7 -9
  40. package/dist-server/service/inventory-item-change/inventory-item-change-query.js.map +1 -1
  41. package/dist-server/service/inventory-item-change/inventory-item-change-type.js +6 -7
  42. package/dist-server/service/inventory-item-change/inventory-item-change-type.js.map +1 -1
  43. package/dist-server/service/inventory-item-change/inventory-item-change.js +3 -4
  44. package/dist-server/service/inventory-item-change/inventory-item-change.js.map +1 -1
  45. package/dist-server/service/inventory-product/inventory-product-mutation.js +4 -4
  46. package/dist-server/service/inventory-product/inventory-product-mutation.js.map +1 -1
  47. package/dist-server/service/inventory-product/inventory-product-query.js +7 -9
  48. package/dist-server/service/inventory-product/inventory-product-query.js.map +1 -1
  49. package/dist-server/service/inventory-product/inventory-product-type.js +1 -2
  50. package/dist-server/service/inventory-product/inventory-product-type.js.map +1 -1
  51. package/dist-server/service/inventory-product/inventory-product.js +5 -5
  52. package/dist-server/service/inventory-product/inventory-product.js.map +1 -1
  53. package/dist-server/service/location/location-mutation.js +5 -5
  54. package/dist-server/service/location/location-mutation.js.map +1 -1
  55. package/dist-server/service/location/location-query.js +17 -19
  56. package/dist-server/service/location/location-query.js.map +1 -1
  57. package/dist-server/service/location/location-types.js +3 -3
  58. package/dist-server/service/location/location-types.js.map +1 -1
  59. package/dist-server/service/location/location.js +14 -14
  60. package/dist-server/service/location/location.js.map +1 -1
  61. package/dist-server/service/movement/movement-mutation.js +6 -5
  62. package/dist-server/service/movement/movement-mutation.js.map +1 -1
  63. package/dist-server/service/movement/movement-query.js +15 -15
  64. package/dist-server/service/movement/movement-query.js.map +1 -1
  65. package/dist-server/service/movement/movement-types.js +4 -5
  66. package/dist-server/service/movement/movement-types.js.map +1 -1
  67. package/dist-server/service/movement/movement.js +5 -5
  68. package/dist-server/service/movement/movement.js.map +1 -1
  69. package/dist-server/service/pallet/pallet-mutation.js +5 -5
  70. package/dist-server/service/pallet/pallet-mutation.js.map +1 -1
  71. package/dist-server/service/pallet/pallet-query.js +9 -11
  72. package/dist-server/service/pallet/pallet-query.js.map +1 -1
  73. package/dist-server/service/pallet/pallet-types.js +5 -6
  74. package/dist-server/service/pallet/pallet-types.js.map +1 -1
  75. package/dist-server/service/pallet/pallet.js +6 -6
  76. package/dist-server/service/pallet/pallet.js.map +1 -1
  77. package/dist-server/service/pallet-count/pallet-count-mutation.js +1 -1
  78. package/dist-server/service/pallet-count/pallet-count-mutation.js.map +1 -1
  79. package/dist-server/service/pallet-count/pallet-count-query.js +6 -8
  80. package/dist-server/service/pallet-count/pallet-count-query.js.map +1 -1
  81. package/dist-server/service/pallet-count/pallet-count.js +3 -4
  82. package/dist-server/service/pallet-count/pallet-count.js.map +1 -1
  83. package/dist-server/service/pallet-history/pallet-history-mutation.js +1 -1
  84. package/dist-server/service/pallet-history/pallet-history-mutation.js.map +1 -1
  85. package/dist-server/service/pallet-history/pallet-history-query.js +6 -8
  86. package/dist-server/service/pallet-history/pallet-history-query.js.map +1 -1
  87. package/dist-server/service/pallet-history/pallet-history.js +6 -6
  88. package/dist-server/service/pallet-history/pallet-history.js.map +1 -1
  89. package/dist-server/service/reduced-inventory-history/reduced-inventory-history.js +1 -1
  90. package/dist-server/service/reduced-inventory-history/reduced-inventory-history.js.map +1 -1
  91. package/dist-server/service/tote/tote-mutation.js +4 -4
  92. package/dist-server/service/tote/tote-mutation.js.map +1 -1
  93. package/dist-server/service/tote/tote-query.js +12 -13
  94. package/dist-server/service/tote/tote-query.js.map +1 -1
  95. package/dist-server/service/tote/tote-types.js +2 -3
  96. package/dist-server/service/tote/tote-types.js.map +1 -1
  97. package/dist-server/service/tote/tote.js +5 -5
  98. package/dist-server/service/tote/tote.js.map +1 -1
  99. package/dist-server/service/warehouse/warehouse-mutation.js +1 -1
  100. package/dist-server/service/warehouse/warehouse-mutation.js.map +1 -1
  101. package/dist-server/service/warehouse/warehouse-query.js +9 -10
  102. package/dist-server/service/warehouse/warehouse-query.js.map +1 -1
  103. package/dist-server/service/warehouse/warehouse.js +12 -12
  104. package/dist-server/service/warehouse/warehouse.js.map +1 -1
  105. package/dist-server/tsconfig.tsbuildinfo +1 -1
  106. package/dist-server/utils/inventory-util.js +16 -16
  107. package/dist-server/utils/inventory-util.js.map +1 -1
  108. package/package.json +8 -8
  109. package/server/controllers/ecommerce/ecommerce-controller.ts +1 -1
  110. package/server/controllers/ecommerce/sellercraft-controller.ts +75 -65
  111. package/server/controllers/warehouse-controller.ts +9 -4
  112. package/server/service/inventory/inventory-mutation.ts +28 -24
  113. package/server/service/inventory/inventory-query.ts +269 -304
  114. package/server/service/inventory/inventory.ts +50 -35
  115. package/server/service/inventory-change/inventory-change-mutation.ts +305 -256
  116. package/server/service/inventory-change/inventory-change-query.ts +9 -9
  117. package/server/service/inventory-history/inventory-history-mutation.ts +12 -15
  118. package/server/service/inventory-history/inventory-history-query.ts +158 -133
  119. package/server/service/inventory-item/inventory-item-mutation.ts +20 -17
  120. package/server/service/inventory-item/inventory-item-query.ts +28 -18
  121. package/server/service/inventory-item-change/inventory-item-change-mutation.ts +12 -9
  122. package/server/service/inventory-item-change/inventory-item-change-query.ts +10 -8
  123. package/server/service/inventory-product/inventory-product-mutation.ts +16 -12
  124. package/server/service/inventory-product/inventory-product-query.ts +7 -8
  125. package/server/service/location/location-mutation.ts +24 -24
  126. package/server/service/location/location-query.ts +27 -23
  127. package/server/service/location/location.ts +11 -10
  128. package/server/service/movement/movement-mutation.ts +7 -8
  129. package/server/service/movement/movement-query.ts +18 -16
  130. package/server/service/pallet/pallet-mutation.ts +18 -20
  131. package/server/service/pallet/pallet-query.ts +13 -14
  132. package/server/service/pallet-count/pallet-count-mutation.ts +20 -17
  133. package/server/service/pallet-count/pallet-count-query.ts +6 -7
  134. package/server/service/pallet-history/pallet-history-mutation.ts +15 -15
  135. package/server/service/pallet-history/pallet-history-query.ts +7 -8
  136. package/server/service/reduced-inventory-history/reduced-inventory-history.ts +1 -1
  137. package/server/service/tote/tote-mutation.ts +23 -22
  138. package/server/service/tote/tote-query.ts +18 -14
  139. package/server/service/warehouse/warehouse-mutation.ts +21 -18
  140. package/server/service/warehouse/warehouse-query.ts +11 -11
  141. package/server/service/warehouse/warehouse.ts +7 -7
  142. package/server/utils/inventory-util.ts +10 -10
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getInventoriesByStrategy = exports.getProductBundleInventory = exports.checkPalletIdenticallity = exports.checkPalletDuplication = exports.switchLocationStatus = exports.generateInventoryHistory = exports.InventoryUtil = void 0;
4
- const typeorm_1 = require("typeorm");
5
4
  const product_base_1 = require("@things-factory/product-base");
5
+ const shell_1 = require("@things-factory/shell");
6
6
  const constants_1 = require("../constants");
7
7
  const service_1 = require("../service");
8
8
  const utils_1 = require("../utils");
@@ -94,8 +94,8 @@ exports.InventoryUtil = InventoryUtil;
94
94
  * seq will be calculated based on number of records for one specific pallet id (provided by inventory object)
95
95
  */
96
96
  async function generateInventoryHistory(inventory, refOrder, transactionType, qty, uomValue, user, trxMgr) {
97
- const invHistoryRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(service_1.InventoryHistory)) || (0, typeorm_1.getRepository)(service_1.InventoryHistory);
98
- const invRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(service_1.Inventory)) || (0, typeorm_1.getRepository)(service_1.Inventory);
97
+ const invHistoryRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(service_1.InventoryHistory)) || (0, shell_1.getRepository)(service_1.InventoryHistory);
98
+ const invRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(service_1.Inventory)) || (0, shell_1.getRepository)(service_1.Inventory);
99
99
  if (!(inventory === null || inventory === void 0 ? void 0 : inventory.id))
100
100
  throw new Error(`Can't find out ID of inventory.`);
101
101
  inventory = await invRepo.findOne({
@@ -152,12 +152,12 @@ exports.generateInventoryHistory = generateInventoryHistory;
152
152
  * @param trxMgr
153
153
  */
154
154
  async function switchLocationStatus(domain, location, updater, trxMgr) {
155
- const invRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(service_1.Inventory)) || (0, typeorm_1.getRepository)(service_1.Inventory);
156
- const locationRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(service_1.Location)) || (0, typeorm_1.getRepository)(service_1.Location);
157
- const allocatedItemsCnt = await invRepo.count({
158
- domain,
155
+ const invRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(service_1.Inventory)) || (0, shell_1.getRepository)(service_1.Inventory);
156
+ const locationRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(service_1.Location)) || (0, shell_1.getRepository)(service_1.Location);
157
+ const allocatedItemsCnt = await invRepo.countBy({
158
+ domain: { id: domain.id },
159
159
  status: constants_1.INVENTORY_STATUS.STORED,
160
- location
160
+ location: { id: location.id }
161
161
  });
162
162
  if (!allocatedItemsCnt && location.status !== constants_1.LOCATION_STATUS.EMPTY) {
163
163
  location = await locationRepo.save(Object.assign(Object.assign({}, location), { status: constants_1.LOCATION_STATUS.EMPTY, updater }));
@@ -169,10 +169,10 @@ async function switchLocationStatus(domain, location, updater, trxMgr) {
169
169
  }
170
170
  exports.switchLocationStatus = switchLocationStatus;
171
171
  async function checkPalletDuplication(domain, bizplace, palletId, trxMgr) {
172
- const invRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(service_1.Inventory)) || (0, typeorm_1.getRepository)(service_1.Inventory);
173
- const duplicatedPalletCnt = await invRepo.count({
174
- domain,
175
- bizplace,
172
+ const invRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(service_1.Inventory)) || (0, shell_1.getRepository)(service_1.Inventory);
173
+ const duplicatedPalletCnt = await invRepo.countBy({
174
+ domain: { id: domain.id },
175
+ bizplace: { id: bizplace.id },
176
176
  palletId
177
177
  });
178
178
  return Boolean(duplicatedPalletCnt);
@@ -190,16 +190,16 @@ exports.checkPalletDuplication = checkPalletDuplication;
190
190
  */
191
191
  async function checkPalletIdenticallity(domain, bizplace, palletId, batchId, product, packingType, trxMgr) {
192
192
  var _a;
193
- const productRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(product_base_1.Product)) || (0, typeorm_1.getRepository)(product_base_1.Product);
194
- const invRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(service_1.Inventory)) || (0, typeorm_1.getRepository)(service_1.Inventory);
193
+ const productRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(product_base_1.Product)) || (0, shell_1.getRepository)(product_base_1.Product);
194
+ const invRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(service_1.Inventory)) || (0, shell_1.getRepository)(service_1.Inventory);
195
195
  if (typeof product === 'string') {
196
- const foundProduct = await productRepo.findOne(product);
196
+ const foundProduct = await productRepo.findOneBy({ id: product }); /* TODO check migration typeorm 0.3 */
197
197
  if (!foundProduct)
198
198
  throw new Error(`Failed to find product with ${product}`);
199
199
  product = foundProduct;
200
200
  }
201
201
  const inv = await invRepo.findOne({
202
- where: { domain, bizplace, palletId },
202
+ where: { domain: { id: domain.id }, bizplace, palletId },
203
203
  relations: ['product']
204
204
  });
205
205
  if (batchId !== inv.batchId)
@@ -1 +1 @@
1
- {"version":3,"file":"inventory-util.js","sourceRoot":"","sources":["../../server/utils/inventory-util.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, getRepository, Repository } from 'typeorm'\n\nimport { User } from '@things-factory/auth-base'\nimport { Bizplace } from '@things-factory/biz-base'\nimport { Product } from '@things-factory/product-base'\nimport { Domain } from '@things-factory/shell'\n\nimport { INVENTORY_STATUS, INVENTORY_TRANSACTION_TYPE, LOCATION_STATUS, LOCATION_TYPE } from '../constants'\nimport { Inventory, InventoryHistory, Location } from '../service'\nimport { InventoryNoGenerator } from '../utils'\n\nexport class InventoryUtil {\n protected trxMgr: EntityManager\n protected domain: Domain\n protected user: User\n\n constructor(trxMgr: EntityManager, domain: Domain, user: User) {\n this.trxMgr = trxMgr\n this.domain = domain\n this.user = user\n }\n\n public readonly ERROR_MSG = {\n FIND: {\n NO_RESULT: (condition: any) => `There's no results matched with condition ${condition}`,\n NO_CHILD_RESULT: (condition: any) => `There's no child result matched with condition ${condition}`,\n NOT_MATCH: (source: any, target: any) => `Unable to find matching ${target} using ${source}`\n },\n ORDER_ITEM: {\n NO_MATCHING_RESULT: (condition: any, condition2: any) =>\n `Current item with ${condition} (${condition2}) not belong to this order`,\n EXCESS_QTY: (condition: any, condition2: any, condition3: any) =>\n `Excess qty is scanned for item ${condition}, ${condition2} (${condition3})`\n },\n PRODUCT: {\n NO_MATCHING_RESULT: (condition: any, condition2: any) =>\n `Order packing type and packing size not match with product master, ${condition} (${condition2})`,\n BARCODE_NOT_EXIST: (condition: any, condition2: any, condition3: any) =>\n `Product barcode - ${condition} with ${condition2} ${condition3}, not exist in master data.`\n },\n CREATE: {\n ID_EXISTS: 'Target has ID already',\n EMPTY_CREATOR: 'Cannot create without creator',\n EMPTY_UPDATER: 'Cannot create without updater'\n },\n UPDATE: {\n ID_NOT_EXISTS: `Target doesn't have ID`,\n EMPTY_UPDATER: 'Cannot update without updater'\n },\n VALIDITY: {\n UNEXPECTED_FIELD_VALUE: (field: string, expectedValue: any, actualValue: any) =>\n `Expected ${field} value is ${expectedValue} but got ${actualValue}`,\n DUPLICATED: (field: string, value: any) => `There is duplicated ${field} value (${value})`,\n CANT_PROCEED_STEP_BY: (step: string, reason: string) => `Can't proceed to ${step} because ${reason}`\n }\n }\n\n async createInventory(inventory: Partial<Inventory>): Promise<Inventory> {\n inventory = this.setStamp(inventory)\n return await this.trxMgr.getRepository(Inventory).save(inventory)\n }\n\n /**\n * @summary Update inventory record\n * @description It will update inventory after set a stamp (domain, updater)\n * The special point of this function is that this changes won't generate inventory history\n * If you want to generate inventory history automatically you would better to use transactionInventory function\n */\n async updateInventory(inventory: Partial<Inventory>): Promise<Inventory> {\n if (!inventory.id) throw new Error(this.ERROR_MSG.UPDATE.ID_NOT_EXISTS)\n inventory = this.setStamp(inventory)\n return await this.trxMgr.getRepository(Inventory).save(inventory)\n }\n\n /**\n * @summary Do transaction on inventory record\n * @description It will update inventory after set a temp (domain, updater)\n * and then generate inventory history based on current changes\n */\n async transactionInventory(\n inventory: Inventory,\n refOrder: any,\n changedQty: number,\n changedUom: number,\n transactionType: string\n ): Promise<Inventory> {\n if (inventory.id) {\n inventory = await this.updateInventory(inventory)\n } else {\n inventory = await this.createInventory(inventory)\n }\n\n await generateInventoryHistory(inventory, refOrder, transactionType, changedQty, changedUom, this.user, this.trxMgr)\n\n return inventory\n }\n\n /**\n * @summary set common stamp like domain, creator, updater\n * @description Set common stamp to passed record\n * If it doesn't have id it will handle it as creating one\n * If it has id it will handle it as updating one\n */\n setStamp(record: Record<string, any>): Record<string, any> {\n if (!record.domain) record.domain = this.domain\n if (!record.id && !record.creator) record.creator = this.user\n if (!record.updater) record.updater = this.user\n\n return record\n }\n}\n\n/**\n * @description It will insert new record into inventory histories table.\n * seq will be calculated based on number of records for one specific pallet id (provided by inventory object)\n */\nexport async function generateInventoryHistory(\n inventory: Inventory,\n refOrder: any,\n transactionType: string,\n qty: number,\n uomValue: number,\n user: User,\n trxMgr?: EntityManager\n): Promise<InventoryHistory> {\n const invHistoryRepo: Repository<InventoryHistory> =\n trxMgr?.getRepository(InventoryHistory) || getRepository(InventoryHistory)\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n\n if (!inventory?.id) throw new Error(`Can't find out ID of inventory.`)\n\n inventory = await invRepo.findOne({\n where: { id: inventory.id },\n relations: ['domain', 'bizplace', 'product', 'warehouse', 'location']\n })\n\n const domain: Domain = inventory.domain\n const location: Location = inventory.location\n\n const lastInvHistory: InventoryHistory = await invHistoryRepo.findOne({\n where: {\n domain: inventory.domain,\n palletId: inventory.palletId\n },\n order: {\n seq: 'DESC'\n }\n })\n\n let seq: number = 0\n let openingQty: number = 0\n let openingUomValue: number = 0\n\n if (lastInvHistory) {\n openingQty = lastInvHistory.openingQty + lastInvHistory.qty\n openingUomValue = lastInvHistory.openingUomValue + lastInvHistory.uomValue\n seq = lastInvHistory.seq + 1\n }\n\n let remainQty = (openingQty || 0) + (qty || 0)\n\n let inventoryHistory: any = new InventoryHistory()\n\n inventoryHistory = {\n ...inventory,\n name: InventoryNoGenerator.inventoryHistoryName(),\n inventory,\n seq: seq,\n status: remainQty == 0 ? INVENTORY_STATUS.TERMINATED : inventory.status,\n transactionType,\n refOrderId: refOrder?.id || null,\n orderNo: refOrder?.name || null,\n orderRefNo: refOrder?.refNo || null,\n qty,\n openingQty,\n uomValue,\n openingUomValue: openingUomValue,\n creator: user,\n updater: user\n }\n\n delete inventoryHistory.updatedAt\n delete inventoryHistory.createdAt\n delete inventoryHistory.id\n\n let newInventoryHistory = await invHistoryRepo.save(inventoryHistory)\n\n if (remainQty == 0) {\n seq = seq + 1\n let terminatedHistory = {\n ...newInventoryHistory,\n name: InventoryNoGenerator.inventoryHistoryName(),\n seq: seq,\n status: INVENTORY_STATUS.TERMINATED,\n transactionType: INVENTORY_TRANSACTION_TYPE.TERMINATED,\n uom: inventory.uom,\n qty: 0,\n openingQty: 0,\n uomValue: 0,\n openingUomValue: 0\n }\n\n delete terminatedHistory.id\n\n newInventoryHistory = await invHistoryRepo.save(terminatedHistory)\n inventory.status = INVENTORY_STATUS.TERMINATED\n }\n\n if (inventory.lastSeq !== seq) {\n await invRepo.update(inventory.id, { lastSeq: newInventoryHistory.seq, updater: user })\n }\n\n await switchLocationStatus(domain, location, user, trxMgr)\n return newInventoryHistory\n}\n\n/**\n * @description: Check location emptiness and update status of location\n * @param domain\n * @param location\n * @param updater\n * @param trxMgr\n */\nexport async function switchLocationStatus(\n domain: Domain,\n location: Location,\n updater: User,\n trxMgr?: EntityManager\n): Promise<Location> {\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n const locationRepo: Repository<Location> = trxMgr?.getRepository(Location) || getRepository(Location)\n const allocatedItemsCnt: number = await invRepo.count({\n domain,\n status: INVENTORY_STATUS.STORED,\n location\n })\n\n if (!allocatedItemsCnt && location.status !== LOCATION_STATUS.EMPTY) {\n location = await locationRepo.save({\n ...location,\n status: LOCATION_STATUS.EMPTY,\n updater\n })\n } else if (allocatedItemsCnt && location.status === LOCATION_STATUS.EMPTY) {\n location = await locationRepo.save({\n ...location,\n status: LOCATION_STATUS.OCCUPIED,\n updater\n })\n }\n\n return location\n}\n\nexport async function checkPalletDuplication(\n domain: Domain,\n bizplace: Bizplace,\n palletId: string,\n trxMgr?: EntityManager\n): Promise<boolean> {\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n const duplicatedPalletCnt: number = await invRepo.count({\n domain,\n bizplace,\n palletId\n })\n\n return Boolean(duplicatedPalletCnt)\n}\n\n/**\n * @description Check whether inventory is same with passed conditions\n * @param {Domain} domain\n * @param {Bizplace} bizplace\n * @param {String} palletId\n * @param {String} batchId\n * @param {String | Product} product\n * @param {String} packingType\n * @param {EntityManager} trxMgr\n */\nexport async function checkPalletIdenticallity(\n domain: Domain,\n bizplace: Bizplace,\n palletId: string,\n batchId: string,\n product: string | Product,\n packingType: string,\n trxMgr?: EntityManager\n): Promise<{ identicallity: boolean; errorMessage?: string }> {\n const productRepo: Repository<Product> = trxMgr?.getRepository(Product) || getRepository(Product)\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n\n if (typeof product === 'string') {\n const foundProduct: Product = await productRepo.findOne(product)\n if (!foundProduct) throw new Error(`Failed to find product with ${product}`)\n product = foundProduct\n }\n\n const inv: Inventory = await invRepo.findOne({\n where: { domain, bizplace, palletId },\n relations: ['product']\n })\n\n if (batchId !== inv.batchId) return { identicallity: false, errorMessage: `Batch ID is not matched with ${batchId}` }\n\n if (product?.id !== inv?.product?.id)\n return { identicallity: false, errorMessage: `Product is not matched with ${product.name}` }\n\n if (packingType !== inv.packingType)\n return { identicallity: false, errorMessage: `Packing Type is not matched with ${packingType}` }\n\n return { identicallity: true }\n}\n\n/**\n * @description Check whether inventory is same with passed conditions\n * @param {Domain} domain\n * @param {Domain} productOwnerDomain\n * @param {OrderProduct} bizplace *\n * @param {EntityManager} trxMgr\n */\nexport async function getProductBundleInventory(\n domain: Domain,\n productOwnerDomain: Domain,\n orderProducts: any[],\n trxMgr: EntityManager\n): Promise<any> {\n let orderProductsJson = JSON.stringify(\n orderProducts.map(itm => {\n return {\n ...itm,\n product_id: itm.product.id,\n packing_type: itm.packingType,\n packing_size: itm.packingSize,\n uom: itm.uom\n }\n }) || []\n )\n\n const result: any[] = await trxMgr.query(\n `\n select product_bundle_id, sku, name, min(available_qty) as qty from (\n select\n pb.sku, pb.name, pbs.product_bundle_id, pbs.bundle_qty, pd.product_id, pd.packing_type, pd.packing_size, pd.uom,\n floor(coalesce(sum(inv.qty - coalesce(inv.locked_qty,0)),0)/pbs.bundle_qty) as available_qty, \n floor(coalesce(sum(inv.uom_value - coalesce(inv.locked_uom_value,0)),0)/pbs.bundle_qty) as available_uom_value \n from (\n select pb.id, pb.sku, pb.name\n from json_populate_recordset(NULL::order_products,'${orderProductsJson}') src \n inner join product_details pd ON src.product_id = pd.product_id and src.packing_type = pd.packing_type and src.packing_size = pd.packing_size and src.uom = pd.uom\n inner join product_bundle_settings pbs on pbs.product_detail_id = pd.id\n inner join product_bundles pb on pb.id = pbs.product_bundle_id and pb.status = 'ACTIVATED'\n where pb.domain_id = $1\n group by pb.id, pb.sku, pb.name\n ) pb\n inner join product_bundle_settings pbs on pbs.product_bundle_id = pb.id\n inner join product_details pd on pd.id = pbs.product_detail_id \n left join inventories inv on ((inv.status <> 'TERMINATED' and (inv.qty - coalesce(inv.locked_qty,0)) > 0) or (inv.status = 'TERMINATED' and (inv.qty - coalesce(inv.locked_qty,0)) = 0)) and inv.product_id = pd.product_id and inv.packing_type = pd.packing_type and inv.packing_size = pd.packing_size and inv.uom = pd.uom\n where inv.domain_id = $2\n group by pb.sku, pb.name, pbs.product_bundle_id, pbs.bundle_qty, pd.product_id, pd.packing_type, pd.packing_size, pd.uom\n ) foo group by product_bundle_id, sku, name\n `,\n [productOwnerDomain.id, domain.id]\n )\n\n return result\n}\n\n/**\n * @description This function will return multiple products\n * and it is different with @inventoriesByStrategy that returns\n * inventories for one product only\n * @param {string} bizplaceId\n * @param {string} worksheetId\n * @param {any[]} orderProducts\n * @param {string} pickingStrategy\n * @param {[Object]} locationSortingRules\n * @param {EntityManager} trxMgr\n * @returns inventories for multiple products\n */\nexport async function getInventoriesByStrategy(\n domainId: string,\n bizplaceId: string,\n worksheetId: string,\n orderProducts: any[],\n locationSortingRules: any[],\n trxMgr: EntityManager\n): Promise<Inventory[]> {\n let orderProductsJSON: string = JSON.stringify(orderProducts)\n let locationSorting: string = (locationSortingRules || [])\n .map((rule: { name: string; descOrder: boolean }) => {\n return `l.${rule.name}${rule.descOrder ? 'DESC' : ''}`\n })\n .join(', ')\n\n if (locationSorting === '') locationSorting = 'l.name'\n\n await trxMgr.query(\n `\n CREATE TEMP TABLE temp_op2(\n \"productId\" VARCHAR(50),\n \"batchId\" VARCHAR(50),\n \"packingType\" VARCHAR(50),\n \"packingSize\" INT,\n \"uom\" VARCHAR(10),\n \"releaseQty\" INT,\n \"pickingStrategy\" VARCHAR(25),\n \"orderProductId\" VARCHAR(50)\n );\n `\n )\n\n await trxMgr.query(\n `\n INSERT INTO temp_op2\n SELECT \"productId\", \"batchId\", \"packingType\", \"packingSize\", \"uom\", \"releaseQty\", \"pickingStrategy\", \"orderProductId\"\n FROM JSON_POPULATE_RECORDSET(NULL::temp_op2, $1) js\n `,\n [orderProductsJSON]\n )\n\n await trxMgr.query(\n `\n CREATE TEMP TABLE acc_oi2 AS (\n SELECT oi.inventory_id, SUM(oi.release_qty) AS total_release_qty, SUM(oi.release_uom_value) AS total_release_uom_value\n FROM order_inventories oi\n WHERE oi.status IN ('PENDING','PENDING_RECEIVE','PENDING_WORKSHEET','PENDING_SPLIT')\n AND oi.bizplace_id = $1\n AND oi.inventory_id NOTNULL\n AND oi.ref_worksheet_id != $2\n GROUP BY oi.inventory_id\n )\n `,\n [bizplaceId, worksheetId]\n )\n\n // get inventories\n let inventories = await trxMgr.query(\n `\n SELECT\n i.id,\n op.\"productId\",\n op.\"batchId\",\n i.qty - COALESCE(i.locked_qty,0) - COALESCE(foo.total_release_qty,0) AS \"remainQty\",\n i.uom_value - COALESCE(i.locked_uom_value,0) - COALESCE(foo.total_release_uom_value,0) AS \"remainUomValue\",\n op.\"packingType\",\n op.\"packingSize\",\n op.\"uom\",\n op.\"orderProductId\",\n ROW_NUMBER() OVER (\n PARTITION BY op.\"productId\", op.\"batchId\", op.\"packingType\", op.\"packingSize\", op.\"uom\"\n ORDER BY \n CASE WHEN op.\"pickingStrategy\" = 'FIFO' THEN i.created_at END,\n CASE WHEN op.\"pickingStrategy\" = 'FEFO' THEN i.expiration_date END,\n CASE WHEN op.\"pickingStrategy\" = 'LIFO' THEN i.created_at END DESC,\n CASE WHEN op.\"pickingStrategy\" = 'FMFO' THEN i.manufacture_date END,\n ${locationSorting}\n ) AS rn\n FROM inventories i\n INNER JOIN locations l ON i.location_id = l.id\n AND l.TYPE NOT IN ($1, $2)\n INNER JOIN temp_op2 op ON i.product_id = op.\"productId\"::uuid\n AND i.batch_id = op.\"batchId\"\n AND i.packing_type = op.\"packingType\"\n AND i.packing_size = op.\"packingSize\"\n LEFT JOIN acc_oi2 foo ON i.id = foo.inventory_id\n WHERE i.domain_id = $3\n AND i.bizplace_id = $4\n AND i.status = $5\n ORDER BY op.\"productId\", rn\n `,\n [LOCATION_TYPE.QUARANTINE, LOCATION_TYPE.RESERVE, domainId, bizplaceId, INVENTORY_STATUS.STORED]\n )\n\n await trxMgr.query('DROP TABLE temp_op2, acc_oi2')\n\n return inventories\n}\n"]}
1
+ {"version":3,"file":"inventory-util.js","sourceRoot":"","sources":["../../server/utils/inventory-util.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, Repository } from 'typeorm'\n\nimport { User } from '@things-factory/auth-base'\nimport { Bizplace } from '@things-factory/biz-base'\nimport { Product } from '@things-factory/product-base'\nimport { Domain, getRepository } from '@things-factory/shell'\n\nimport { INVENTORY_STATUS, INVENTORY_TRANSACTION_TYPE, LOCATION_STATUS, LOCATION_TYPE } from '../constants'\nimport { Inventory, InventoryHistory, Location } from '../service'\nimport { InventoryNoGenerator } from '../utils'\n\nexport class InventoryUtil {\n protected trxMgr: EntityManager\n protected domain: Domain\n protected user: User\n\n constructor(trxMgr: EntityManager, domain: Domain, user: User) {\n this.trxMgr = trxMgr\n this.domain = domain\n this.user = user\n }\n\n public readonly ERROR_MSG = {\n FIND: {\n NO_RESULT: (condition: any) => `There's no results matched with condition ${condition}`,\n NO_CHILD_RESULT: (condition: any) => `There's no child result matched with condition ${condition}`,\n NOT_MATCH: (source: any, target: any) => `Unable to find matching ${target} using ${source}`\n },\n ORDER_ITEM: {\n NO_MATCHING_RESULT: (condition: any, condition2: any) =>\n `Current item with ${condition} (${condition2}) not belong to this order`,\n EXCESS_QTY: (condition: any, condition2: any, condition3: any) =>\n `Excess qty is scanned for item ${condition}, ${condition2} (${condition3})`\n },\n PRODUCT: {\n NO_MATCHING_RESULT: (condition: any, condition2: any) =>\n `Order packing type and packing size not match with product master, ${condition} (${condition2})`,\n BARCODE_NOT_EXIST: (condition: any, condition2: any, condition3: any) =>\n `Product barcode - ${condition} with ${condition2} ${condition3}, not exist in master data.`\n },\n CREATE: {\n ID_EXISTS: 'Target has ID already',\n EMPTY_CREATOR: 'Cannot create without creator',\n EMPTY_UPDATER: 'Cannot create without updater'\n },\n UPDATE: {\n ID_NOT_EXISTS: `Target doesn't have ID`,\n EMPTY_UPDATER: 'Cannot update without updater'\n },\n VALIDITY: {\n UNEXPECTED_FIELD_VALUE: (field: string, expectedValue: any, actualValue: any) =>\n `Expected ${field} value is ${expectedValue} but got ${actualValue}`,\n DUPLICATED: (field: string, value: any) => `There is duplicated ${field} value (${value})`,\n CANT_PROCEED_STEP_BY: (step: string, reason: string) => `Can't proceed to ${step} because ${reason}`\n }\n }\n\n async createInventory(inventory: Partial<Inventory>): Promise<Inventory> {\n inventory = this.setStamp(inventory)\n return await this.trxMgr.getRepository(Inventory).save(inventory)\n }\n\n /**\n * @summary Update inventory record\n * @description It will update inventory after set a stamp (domain, updater)\n * The special point of this function is that this changes won't generate inventory history\n * If you want to generate inventory history automatically you would better to use transactionInventory function\n */\n async updateInventory(inventory: Partial<Inventory>): Promise<Inventory> {\n if (!inventory.id) throw new Error(this.ERROR_MSG.UPDATE.ID_NOT_EXISTS)\n inventory = this.setStamp(inventory)\n return await this.trxMgr.getRepository(Inventory).save(inventory)\n }\n\n /**\n * @summary Do transaction on inventory record\n * @description It will update inventory after set a temp (domain, updater)\n * and then generate inventory history based on current changes\n */\n async transactionInventory(\n inventory: Inventory,\n refOrder: any,\n changedQty: number,\n changedUom: number,\n transactionType: string\n ): Promise<Inventory> {\n if (inventory.id) {\n inventory = await this.updateInventory(inventory)\n } else {\n inventory = await this.createInventory(inventory)\n }\n\n await generateInventoryHistory(inventory, refOrder, transactionType, changedQty, changedUom, this.user, this.trxMgr)\n\n return inventory\n }\n\n /**\n * @summary set common stamp like domain, creator, updater\n * @description Set common stamp to passed record\n * If it doesn't have id it will handle it as creating one\n * If it has id it will handle it as updating one\n */\n setStamp(record: Record<string, any>): Record<string, any> {\n if (!record.domain) record.domain = this.domain\n if (!record.id && !record.creator) record.creator = this.user\n if (!record.updater) record.updater = this.user\n\n return record\n }\n}\n\n/**\n * @description It will insert new record into inventory histories table.\n * seq will be calculated based on number of records for one specific pallet id (provided by inventory object)\n */\nexport async function generateInventoryHistory(\n inventory: Inventory,\n refOrder: any,\n transactionType: string,\n qty: number,\n uomValue: number,\n user: User,\n trxMgr?: EntityManager\n): Promise<InventoryHistory> {\n const invHistoryRepo: Repository<InventoryHistory> =\n trxMgr?.getRepository(InventoryHistory) || getRepository(InventoryHistory)\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n\n if (!inventory?.id) throw new Error(`Can't find out ID of inventory.`)\n\n inventory = await invRepo.findOne({\n where: { id: inventory.id },\n relations: ['domain', 'bizplace', 'product', 'warehouse', 'location']\n })\n\n const domain: Domain = inventory.domain\n const location: Location = inventory.location\n\n const lastInvHistory: InventoryHistory = await invHistoryRepo.findOne({\n where: {\n domain: inventory.domain,\n palletId: inventory.palletId\n },\n order: {\n seq: 'DESC'\n }\n })\n\n let seq: number = 0\n let openingQty: number = 0\n let openingUomValue: number = 0\n\n if (lastInvHistory) {\n openingQty = lastInvHistory.openingQty + lastInvHistory.qty\n openingUomValue = lastInvHistory.openingUomValue + lastInvHistory.uomValue\n seq = lastInvHistory.seq + 1\n }\n\n let remainQty = (openingQty || 0) + (qty || 0)\n\n let inventoryHistory: any = new InventoryHistory()\n\n inventoryHistory = {\n ...inventory,\n name: InventoryNoGenerator.inventoryHistoryName(),\n inventory,\n seq: seq,\n status: remainQty == 0 ? INVENTORY_STATUS.TERMINATED : inventory.status,\n transactionType,\n refOrderId: refOrder?.id || null,\n orderNo: refOrder?.name || null,\n orderRefNo: refOrder?.refNo || null,\n qty,\n openingQty,\n uomValue,\n openingUomValue: openingUomValue,\n creator: user,\n updater: user\n }\n\n delete inventoryHistory.updatedAt\n delete inventoryHistory.createdAt\n delete inventoryHistory.id\n\n let newInventoryHistory = await invHistoryRepo.save(inventoryHistory)\n\n if (remainQty == 0) {\n seq = seq + 1\n let terminatedHistory = {\n ...newInventoryHistory,\n name: InventoryNoGenerator.inventoryHistoryName(),\n seq: seq,\n status: INVENTORY_STATUS.TERMINATED,\n transactionType: INVENTORY_TRANSACTION_TYPE.TERMINATED,\n uom: inventory.uom,\n qty: 0,\n openingQty: 0,\n uomValue: 0,\n openingUomValue: 0\n }\n\n delete terminatedHistory.id\n\n newInventoryHistory = await invHistoryRepo.save(terminatedHistory)\n inventory.status = INVENTORY_STATUS.TERMINATED\n }\n\n if (inventory.lastSeq !== seq) {\n await invRepo.update(inventory.id, { lastSeq: newInventoryHistory.seq, updater: user })\n }\n\n await switchLocationStatus(domain, location, user, trxMgr)\n return newInventoryHistory\n}\n\n/**\n * @description: Check location emptiness and update status of location\n * @param domain\n * @param location\n * @param updater\n * @param trxMgr\n */\nexport async function switchLocationStatus(\n domain: Domain,\n location: Location,\n updater: User,\n trxMgr?: EntityManager\n): Promise<Location> {\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n const locationRepo: Repository<Location> = trxMgr?.getRepository(Location) || getRepository(Location)\n const allocatedItemsCnt: number = await invRepo.countBy({\n domain: { id: domain.id },\n status: INVENTORY_STATUS.STORED,\n location: { id: location.id }\n })\n\n if (!allocatedItemsCnt && location.status !== LOCATION_STATUS.EMPTY) {\n location = await locationRepo.save({\n ...location,\n status: LOCATION_STATUS.EMPTY,\n updater\n })\n } else if (allocatedItemsCnt && location.status === LOCATION_STATUS.EMPTY) {\n location = await locationRepo.save({\n ...location,\n status: LOCATION_STATUS.OCCUPIED,\n updater\n })\n }\n\n return location\n}\n\nexport async function checkPalletDuplication(\n domain: Domain,\n bizplace: Bizplace,\n palletId: string,\n trxMgr?: EntityManager\n): Promise<boolean> {\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n const duplicatedPalletCnt: number = await invRepo.countBy({\n domain: { id: domain.id },\n bizplace: { id: bizplace.id },\n palletId\n })\n\n return Boolean(duplicatedPalletCnt)\n}\n\n/**\n * @description Check whether inventory is same with passed conditions\n * @param {Domain} domain\n * @param {Bizplace} bizplace\n * @param {String} palletId\n * @param {String} batchId\n * @param {String | Product} product\n * @param {String} packingType\n * @param {EntityManager} trxMgr\n */\nexport async function checkPalletIdenticallity(\n domain: Domain,\n bizplace: Bizplace,\n palletId: string,\n batchId: string,\n product: string | Product,\n packingType: string,\n trxMgr?: EntityManager\n): Promise<{ identicallity: boolean; errorMessage?: string }> {\n const productRepo: Repository<Product> = trxMgr?.getRepository(Product) || getRepository(Product)\n const invRepo: Repository<Inventory> = trxMgr?.getRepository(Inventory) || getRepository(Inventory)\n\n if (typeof product === 'string') {\n const foundProduct: Product = await productRepo.findOneBy({ id: product }) /* TODO check migration typeorm 0.3 */\n if (!foundProduct) throw new Error(`Failed to find product with ${product}`)\n product = foundProduct\n }\n\n const inv: Inventory = await invRepo.findOne({\n where: { domain: { id: domain.id }, bizplace, palletId },\n relations: ['product']\n })\n\n if (batchId !== inv.batchId) return { identicallity: false, errorMessage: `Batch ID is not matched with ${batchId}` }\n\n if (product?.id !== inv?.product?.id)\n return { identicallity: false, errorMessage: `Product is not matched with ${product.name}` }\n\n if (packingType !== inv.packingType)\n return { identicallity: false, errorMessage: `Packing Type is not matched with ${packingType}` }\n\n return { identicallity: true }\n}\n\n/**\n * @description Check whether inventory is same with passed conditions\n * @param {Domain} domain\n * @param {Domain} productOwnerDomain\n * @param {OrderProduct} bizplace *\n * @param {EntityManager} trxMgr\n */\nexport async function getProductBundleInventory(\n domain: Domain,\n productOwnerDomain: Domain,\n orderProducts: any[],\n trxMgr: EntityManager\n): Promise<any> {\n let orderProductsJson = JSON.stringify(\n orderProducts.map(itm => {\n return {\n ...itm,\n product_id: itm.product.id,\n packing_type: itm.packingType,\n packing_size: itm.packingSize,\n uom: itm.uom\n }\n }) || []\n )\n\n const result: any[] = await trxMgr.query(\n `\n select product_bundle_id, sku, name, min(available_qty) as qty from (\n select\n pb.sku, pb.name, pbs.product_bundle_id, pbs.bundle_qty, pd.product_id, pd.packing_type, pd.packing_size, pd.uom,\n floor(coalesce(sum(inv.qty - coalesce(inv.locked_qty,0)),0)/pbs.bundle_qty) as available_qty, \n floor(coalesce(sum(inv.uom_value - coalesce(inv.locked_uom_value,0)),0)/pbs.bundle_qty) as available_uom_value \n from (\n select pb.id, pb.sku, pb.name\n from json_populate_recordset(NULL::order_products,'${orderProductsJson}') src \n inner join product_details pd ON src.product_id = pd.product_id and src.packing_type = pd.packing_type and src.packing_size = pd.packing_size and src.uom = pd.uom\n inner join product_bundle_settings pbs on pbs.product_detail_id = pd.id\n inner join product_bundles pb on pb.id = pbs.product_bundle_id and pb.status = 'ACTIVATED'\n where pb.domain_id = $1\n group by pb.id, pb.sku, pb.name\n ) pb\n inner join product_bundle_settings pbs on pbs.product_bundle_id = pb.id\n inner join product_details pd on pd.id = pbs.product_detail_id \n left join inventories inv on ((inv.status <> 'TERMINATED' and (inv.qty - coalesce(inv.locked_qty,0)) > 0) or (inv.status = 'TERMINATED' and (inv.qty - coalesce(inv.locked_qty,0)) = 0)) and inv.product_id = pd.product_id and inv.packing_type = pd.packing_type and inv.packing_size = pd.packing_size and inv.uom = pd.uom\n where inv.domain_id = $2\n group by pb.sku, pb.name, pbs.product_bundle_id, pbs.bundle_qty, pd.product_id, pd.packing_type, pd.packing_size, pd.uom\n ) foo group by product_bundle_id, sku, name\n `,\n [productOwnerDomain.id, domain.id]\n )\n\n return result\n}\n\n/**\n * @description This function will return multiple products\n * and it is different with @inventoriesByStrategy that returns\n * inventories for one product only\n * @param {string} bizplaceId\n * @param {string} worksheetId\n * @param {any[]} orderProducts\n * @param {string} pickingStrategy\n * @param {[Object]} locationSortingRules\n * @param {EntityManager} trxMgr\n * @returns inventories for multiple products\n */\nexport async function getInventoriesByStrategy(\n domainId: string,\n bizplaceId: string,\n worksheetId: string,\n orderProducts: any[],\n locationSortingRules: any[],\n trxMgr: EntityManager\n): Promise<Inventory[]> {\n let orderProductsJSON: string = JSON.stringify(orderProducts)\n let locationSorting: string = (locationSortingRules || [])\n .map((rule: { name: string; descOrder: boolean }) => {\n return `l.${rule.name}${rule.descOrder ? 'DESC' : ''}`\n })\n .join(', ')\n\n if (locationSorting === '') locationSorting = 'l.name'\n\n await trxMgr.query(\n `\n CREATE TEMP TABLE temp_op2(\n \"productId\" VARCHAR(50),\n \"batchId\" VARCHAR(50),\n \"packingType\" VARCHAR(50),\n \"packingSize\" INT,\n \"uom\" VARCHAR(10),\n \"releaseQty\" INT,\n \"pickingStrategy\" VARCHAR(25),\n \"orderProductId\" VARCHAR(50)\n );\n `\n )\n\n await trxMgr.query(\n `\n INSERT INTO temp_op2\n SELECT \"productId\", \"batchId\", \"packingType\", \"packingSize\", \"uom\", \"releaseQty\", \"pickingStrategy\", \"orderProductId\"\n FROM JSON_POPULATE_RECORDSET(NULL::temp_op2, $1) js\n `,\n [orderProductsJSON]\n )\n\n await trxMgr.query(\n `\n CREATE TEMP TABLE acc_oi2 AS (\n SELECT oi.inventory_id, SUM(oi.release_qty) AS total_release_qty, SUM(oi.release_uom_value) AS total_release_uom_value\n FROM order_inventories oi\n WHERE oi.status IN ('PENDING','PENDING_RECEIVE','PENDING_WORKSHEET','PENDING_SPLIT')\n AND oi.bizplace_id = $1\n AND oi.inventory_id NOTNULL\n AND oi.ref_worksheet_id != $2\n GROUP BY oi.inventory_id\n )\n `,\n [bizplaceId, worksheetId]\n )\n\n // get inventories\n let inventories = await trxMgr.query(\n `\n SELECT\n i.id,\n op.\"productId\",\n op.\"batchId\",\n i.qty - COALESCE(i.locked_qty,0) - COALESCE(foo.total_release_qty,0) AS \"remainQty\",\n i.uom_value - COALESCE(i.locked_uom_value,0) - COALESCE(foo.total_release_uom_value,0) AS \"remainUomValue\",\n op.\"packingType\",\n op.\"packingSize\",\n op.\"uom\",\n op.\"orderProductId\",\n ROW_NUMBER() OVER (\n PARTITION BY op.\"productId\", op.\"batchId\", op.\"packingType\", op.\"packingSize\", op.\"uom\"\n ORDER BY \n CASE WHEN op.\"pickingStrategy\" = 'FIFO' THEN i.created_at END,\n CASE WHEN op.\"pickingStrategy\" = 'FEFO' THEN i.expiration_date END,\n CASE WHEN op.\"pickingStrategy\" = 'LIFO' THEN i.created_at END DESC,\n CASE WHEN op.\"pickingStrategy\" = 'FMFO' THEN i.manufacture_date END,\n ${locationSorting}\n ) AS rn\n FROM inventories i\n INNER JOIN locations l ON i.location_id = l.id\n AND l.TYPE NOT IN ($1, $2)\n INNER JOIN temp_op2 op ON i.product_id = op.\"productId\"::uuid\n AND i.batch_id = op.\"batchId\"\n AND i.packing_type = op.\"packingType\"\n AND i.packing_size = op.\"packingSize\"\n LEFT JOIN acc_oi2 foo ON i.id = foo.inventory_id\n WHERE i.domain_id = $3\n AND i.bizplace_id = $4\n AND i.status = $5\n ORDER BY op.\"productId\", rn\n `,\n [LOCATION_TYPE.QUARANTINE, LOCATION_TYPE.RESERVE, domainId, bizplaceId, INVENTORY_STATUS.STORED]\n )\n\n await trxMgr.query('DROP TABLE temp_op2, acc_oi2')\n\n return inventories\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/warehouse-base",
3
- "version": "5.0.14",
3
+ "version": "6.0.0-alpha.3",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -24,12 +24,12 @@
24
24
  "migration:create": "node ../../node_modules/typeorm/cli.js migration:create -d ./server/migrations"
25
25
  },
26
26
  "dependencies": {
27
- "@things-factory/biz-base": "^5.0.14",
28
- "@things-factory/id-rule-base": "^5.0.14",
29
- "@things-factory/integration-sellercraft": "^5.0.14",
30
- "@things-factory/marketplace-base": "^5.0.14",
31
- "@things-factory/product-base": "^5.0.14",
32
- "@things-factory/setting-base": "^5.0.14"
27
+ "@things-factory/biz-base": "^6.0.0-alpha.3",
28
+ "@things-factory/id-rule-base": "^6.0.0-alpha.3",
29
+ "@things-factory/integration-sellercraft": "^6.0.0-alpha.3",
30
+ "@things-factory/marketplace-base": "^6.0.0-alpha.3",
31
+ "@things-factory/product-base": "^6.0.0-alpha.3",
32
+ "@things-factory/setting-base": "^6.0.0-alpha.3"
33
33
  },
34
- "gitHead": "9ceaa39746fcf42953e429fab2001353cd821ded"
34
+ "gitHead": "1e273b6485662da938cae8fdca035d994ef4a95d"
35
35
  }
@@ -15,7 +15,7 @@ export class EcommerceController extends WarehouseController {
15
15
  productId: string,
16
16
  companyDomain: Domain
17
17
  ): Promise<void> {
18
- const product: Product = await this.trxMgr.getRepository(Product).findOne(productId)
18
+ const product: Product = await this.trxMgr.getRepository(Product).findOneBy({ id: productId })
19
19
  let inventories: Inventory[] = await this.trxMgr.getRepository(Inventory).find({
20
20
  where: { domain: this.domain, product, status: Not(Equal(INVENTORY_STATUS.TERMINATED)) },
21
21
  relations: ['location']
@@ -8,83 +8,93 @@ import { WarehouseController } from '../warehouse-controller'
8
8
 
9
9
  export class SellercraftController extends WarehouseController {
10
10
  async updateSellercraftStock(sellercraft: Sellercraft, inventory: Inventory): Promise<void> {
11
- const bizplace: Bizplace = await this.trxMgr.getRepository(Bizplace).findOne({ domain: sellercraft.domain })
11
+ let sellercraftSetting: any = sellercraft.sellercraftSetting
12
+ let disableUpdateStock: boolean =
13
+ sellercraftSetting?.disableUpdateStock && sellercraftSetting?.disableUpdateStock == 1 ? true : false
12
14
 
13
- let product: Product = inventory.product
14
- const productDetails: ProductDetail[] = product.productDetails
15
+ if (!disableUpdateStock) {
16
+ const bizplace: Bizplace = await this.trxMgr.getRepository(Bizplace).findOneBy({ domain: sellercraft.domain })
15
17
 
16
- let qb = await this.trxMgr.getRepository(Inventory).createQueryBuilder('inv')
17
- qb.leftJoinAndSelect('inv.location', 'loc')
18
- .andWhere('"inv"."domain_id" = :domainId')
19
- .andWhere('"inv"."bizplace_id" = :bizplaceId')
20
- .andWhere('"inv"."product_id" = :productId')
21
- .andWhere('"inv"."status" != :status')
22
- .andWhere('"loc"."type" NOT IN (:...locationTypes)')
23
- .setParameters({
24
- domainId: this.domain.id,
25
- bizplaceId: bizplace.id,
26
- productId: product.id,
27
- status: INVENTORY_STATUS.TERMINATED,
28
- locationTypes: [LOCATION_TYPE.QUARANTINE, LOCATION_TYPE.RESERVE]
29
- })
18
+ let product: Product = inventory.product
19
+ const productDetails: ProductDetail[] = product.productDetails
30
20
 
31
- let inventories: Inventory[] = await qb.getMany()
21
+ let qb = await this.trxMgr.getRepository(Inventory).createQueryBuilder('inv')
22
+ qb.leftJoinAndSelect('inv.location', 'loc')
23
+ .andWhere('"inv"."domain_id" = :domainId')
24
+ .andWhere('"inv"."bizplace_id" = :bizplaceId')
25
+ .andWhere('"inv"."product_id" = :productId')
26
+ .andWhere('"inv"."status" = :status')
27
+ .andWhere('"loc"."type" NOT IN (:...locationTypes)')
28
+ .setParameters({
29
+ domainId: this.domain.id,
30
+ bizplaceId: bizplace.id,
31
+ productId: product.id,
32
+ status: INVENTORY_STATUS.STORED,
33
+ locationTypes: [LOCATION_TYPE.QUARANTINE, LOCATION_TYPE.RESERVE]
34
+ })
32
35
 
33
- let defaultProductDetail: ProductDetail = product.productDetails.find(productDetail => productDetail.isDefault)
34
- let inventoryTotalQty: number = 0
35
- let inventoryTotalLockedQty: number = 0
36
+ let inventories: Inventory[] = await qb.getMany()
36
37
 
37
- if (inventories?.length > 0) {
38
- const sellercraftInvs: any[] = await Promise.all(
39
- inventories.map(async (inventory: Inventory) => {
40
- const inventoryPackingType: string = inventory.packingType
38
+ let defaultProductDetail: ProductDetail = product.productDetails.find(productDetail => productDetail.isDefault)
39
+ let inventoryTotalQty: number = 0
40
+ let inventoryTotalLockedQty: number = 0
41
41
 
42
- let packingSize: number = 1
43
- if (inventoryPackingType !== defaultProductDetail.packingType) {
44
- const unmatchingProductDetail: ProductDetail = product.productDetails.find(
45
- productDetail => productDetail.packingType === inventoryPackingType
46
- )
42
+ if (inventories?.length > 0) {
43
+ const sellercraftInvs: any[] = await Promise.all(
44
+ inventories.map(async (inventory: Inventory) => {
45
+ const inventoryPackingType: string = inventory.packingType
47
46
 
48
- packingSize = await this.getChildPackingSize(productDetails, defaultProductDetail, unmatchingProductDetail)
49
- }
47
+ let packingSize: number = 1
48
+ if (inventoryPackingType !== defaultProductDetail.packingType) {
49
+ const unmatchingProductDetail: ProductDetail = product.productDetails.find(
50
+ productDetail => productDetail.packingType === inventoryPackingType
51
+ )
50
52
 
51
- return { totalQty: inventory.qty * packingSize, totalLockedQty: inventory.lockedQty * packingSize }
52
- })
53
- )
53
+ packingSize = await this.getChildPackingSize(
54
+ productDetails,
55
+ defaultProductDetail,
56
+ unmatchingProductDetail
57
+ )
58
+ }
54
59
 
55
- inventoryTotalQty = sellercraftInvs.reduce((total, currentValue) => {
56
- total += currentValue.totalQty
57
- return total
58
- }, 0)
60
+ return { totalQty: inventory.qty * packingSize, totalLockedQty: inventory.lockedQty * packingSize }
61
+ })
62
+ )
59
63
 
60
- inventoryTotalLockedQty = sellercraftInvs.reduce((total, currentValue) => {
61
- total += currentValue.totalLockedQty
62
- return total
63
- }, 0)
64
- }
64
+ inventoryTotalQty = sellercraftInvs.reduce((total, currentValue) => {
65
+ total += currentValue.totalQty
66
+ return total
67
+ }, 0)
65
68
 
66
- const sellercraftInv: any[] = [
67
- {
68
- sku: product.sku,
69
- gtin: defaultProductDetail.gtin,
70
- stock: {
71
- quantity_total: inventoryTotalQty,
72
- quantity_reserved: inventoryTotalLockedQty,
73
- unit_of_measure: 'EA'
74
- },
75
- package_weight_gm: defaultProductDetail.nettWeight < 1 ? 1 : defaultProductDetail.nettWeight,
76
- package_dimensions: {
77
- length_mm: defaultProductDetail.depth < 1 ? 1 : defaultProductDetail.depth,
78
- width_mm: defaultProductDetail.width < 1 ? 1 : defaultProductDetail.width,
79
- height_mm: defaultProductDetail.height < 1 ? 1 : defaultProductDetail.height
80
- }
69
+ inventoryTotalLockedQty = sellercraftInvs.reduce((total, currentValue) => {
70
+ total += currentValue.totalLockedQty
71
+ return total
72
+ }, 0)
81
73
  }
82
- ]
83
74
 
84
- await SellercraftAPI.updateProduct(sellercraft, {
85
- context: { state: { domain: this?.domain, user: this?.user } },
86
- accountId: sellercraft.accountId,
87
- sellercraftInv
88
- })
75
+ const sellercraftInv: any[] = [
76
+ {
77
+ sku: product.sku,
78
+ gtin: defaultProductDetail.gtin,
79
+ stock: {
80
+ quantity_total: inventoryTotalQty,
81
+ quantity_reserved: inventoryTotalLockedQty,
82
+ unit_of_measure: 'EA'
83
+ },
84
+ package_weight_gm: defaultProductDetail.nettWeight < 1 ? 1 : defaultProductDetail.nettWeight,
85
+ package_dimensions: {
86
+ length_mm: defaultProductDetail.depth < 1 ? 1 : defaultProductDetail.depth,
87
+ width_mm: defaultProductDetail.width < 1 ? 1 : defaultProductDetail.width,
88
+ height_mm: defaultProductDetail.height < 1 ? 1 : defaultProductDetail.height
89
+ }
90
+ }
91
+ ]
92
+
93
+ await SellercraftAPI.updateProduct(sellercraft, {
94
+ context: { state: { domain: this?.domain, user: this?.user } },
95
+ accountId: sellercraft.accountId,
96
+ sellercraftInv
97
+ })
98
+ }
89
99
  }
90
100
  }
@@ -62,10 +62,15 @@ export class WarehouseController {
62
62
  */
63
63
  async notifyToUsers(users: User[], message: NotificationMsgInterface): Promise<void> {
64
64
  const receivers: any[] = users.map(user => user.id)
65
- await sendNotification({
66
- receivers,
67
- message
68
- })
65
+
66
+ /**
67
+ * @notes Temporary off sendNotification due to suspect of causing wms down
68
+ */
69
+
70
+ // await sendNotification({
71
+ // receivers,
72
+ // message
73
+ // })
69
74
  }
70
75
 
71
76
  /**
@@ -1,12 +1,10 @@
1
1
  import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
- import { EntityManager, In, MoreThan, SelectQueryBuilder } from 'typeorm'
2
+ import { In, MoreThan, SelectQueryBuilder } from 'typeorm'
3
3
 
4
- import { User } from '@things-factory/auth-base'
5
4
  import { Bizplace } from '@things-factory/biz-base'
6
5
  import { generateId } from '@things-factory/id-rule-base'
7
6
  import { Sellercraft, SellercraftStatus } from '@things-factory/integration-sellercraft'
8
7
  import { Product } from '@things-factory/product-base'
9
- import { Domain } from '@things-factory/shell'
10
8
 
11
9
  import { INVENTORY_STATUS, INVENTORY_TRANSACTION_TYPE, LOCATION_STATUS, RULE_TYPE } from '../../constants'
12
10
  import { SellercraftController } from '../../controllers'
@@ -21,8 +19,11 @@ export class InventoryMutation {
21
19
  @Directive('@privilege(category: "inventory", privilege: "mutation")')
22
20
  @Directive('@transaction')
23
21
  @Mutation(returns => Inventory)
24
- async createInventory(@Arg('inventory') inventory: NewInventory, @Ctx() context: any): Promise<Inventory> {
25
- const { tx }: { tx: EntityManager } = context.state
22
+ async createInventory(
23
+ @Arg('inventory') inventory: NewInventory,
24
+ @Ctx() context: ResolverContext
25
+ ): Promise<Inventory> {
26
+ const { tx } = context.state
26
27
 
27
28
  return await tx.getRepository(Inventory).save({
28
29
  domain: context.state.domain,
@@ -35,8 +36,8 @@ export class InventoryMutation {
35
36
  @Directive('@privilege(category: "inventory", privilege: "mutation")')
36
37
  @Directive('@transaction')
37
38
  @Mutation(returns => Inventory)
38
- async updateInventory(@Arg('patch') patch: InventoryPatch, @Ctx() context: any): Promise<Inventory> {
39
- const { domain, user, tx }: { domain: Domain; user: User; tx: EntityManager } = context.state
39
+ async updateInventory(@Arg('patch') patch: InventoryPatch, @Ctx() context: ResolverContext): Promise<Inventory> {
40
+ const { domain, user, tx } = context.state
40
41
 
41
42
  const invQb: SelectQueryBuilder<Inventory> = await tx
42
43
  .getRepository(Inventory)
@@ -66,9 +67,9 @@ export class InventoryMutation {
66
67
  async updateInventoryRemark(
67
68
  @Arg('id') id: string,
68
69
  @Arg('remark') remark: string,
69
- @Ctx() context: any
70
+ @Ctx() context: ResolverContext
70
71
  ): Promise<Inventory> {
71
- const { domain, user, tx }: { domain: Domain; user: User; tx: EntityManager } = context.state
72
+ const { domain, user, tx } = context.state
72
73
 
73
74
  const repository = tx.getRepository(Inventory)
74
75
  const inventory = await repository.findOne({ where: { domain: domain, id } })
@@ -83,10 +84,10 @@ export class InventoryMutation {
83
84
  @Directive('@privilege(category: "inventory", privilege: "mutation")')
84
85
  @Directive('@transaction')
85
86
  @Mutation(returns => Boolean)
86
- async deleteInventory(@Arg('name') name: string, @Ctx() context: any): Promise<Boolean> {
87
- const { tx }: { tx: EntityManager } = context.state
87
+ async deleteInventory(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<Boolean> {
88
+ const { tx } = context.state
88
89
 
89
- await tx.getRepository(Inventory).delete({ domain: context.state.domain, name })
90
+ await tx.getRepository(Inventory).delete({ domain: { id: context.state.domain.id }, name })
90
91
  return true
91
92
  }
92
93
 
@@ -95,9 +96,9 @@ export class InventoryMutation {
95
96
  @Mutation(returns => [Inventory])
96
97
  async updateMultipleInventory(
97
98
  @Arg('patches', type => [InventoryPatch]) patches: InventoryPatch[],
98
- @Ctx() context: any
99
+ @Ctx() context: ResolverContext
99
100
  ): Promise<Inventory[]> {
100
- const { domain, user, tx }: { domain: Domain; user: User; tx: EntityManager } = context.state
101
+ const { domain, user, tx } = context.state
101
102
 
102
103
  let results = []
103
104
  const _createRecords = patches.filter((patch: any) => !patch.id)
@@ -111,7 +112,7 @@ export class InventoryMutation {
111
112
  let date = today.getDate()
112
113
 
113
114
  for (let i = 0; i < _createRecords.length; i++) {
114
- const total = await tx.getRepository(Inventory).count({
115
+ const total = await tx.getRepository(Inventory).countBy({
115
116
  createdAt: MoreThan(new Date(year, month, date))
116
117
  })
117
118
 
@@ -128,11 +129,11 @@ export class InventoryMutation {
128
129
  }
129
130
 
130
131
  if (newRecord.bizplace && newRecord.bizplace.id) {
131
- newRecord.bizplace = await tx.getRepository(Bizplace).findOne(newRecord.bizplace.id)
132
+ newRecord.bizplace = (await tx.getRepository(Bizplace).findOneBy({ id: newRecord.bizplace.id })) as any
132
133
  }
133
134
 
134
135
  if (newRecord.product && newRecord.product.id) {
135
- var product = await tx.getRepository(Product).findOne(newRecord.product.id)
136
+ var product = (await tx.getRepository(Product).findOneBy({ id: newRecord.product.id })) as any
136
137
  newRecord.product = product
137
138
  }
138
139
 
@@ -236,11 +237,11 @@ export class InventoryMutation {
236
237
 
237
238
  // Condition 3: Change of bizplace or product or batch id or packing type
238
239
  if (newRecord.bizplace && newRecord.bizplace.id) {
239
- newRecord.bizplace = await tx.getRepository(Bizplace).findOne(newRecord.bizplace.id)
240
+ newRecord.bizplace = (await tx.getRepository(Bizplace).findOneBy({ id: newRecord.bizplace.id })) as any
240
241
  }
241
242
 
242
243
  if (newRecord.product && newRecord.product.id) {
243
- newRecord.product = await tx.getRepository(Product).findOne(newRecord.product.id)
244
+ newRecord.product = (await tx.getRepository(Product).findOneBy({ id: newRecord.product.id })) as any
244
245
  }
245
246
 
246
247
  if (
@@ -323,8 +324,11 @@ export class InventoryMutation {
323
324
  @Directive('@privilege(category: "inventory", privilege: "mutation")')
324
325
  @Directive('@transaction')
325
326
  @Mutation(returns => Boolean)
326
- async deleteInventories(@Arg('ids', type => [String]) ids: string[], @Ctx() context: any): Promise<Boolean> {
327
- const { tx }: { tx: EntityManager } = context.state
327
+ async deleteInventories(
328
+ @Arg('ids', type => [String]) ids: string[],
329
+ @Ctx() context: ResolverContext
330
+ ): Promise<Boolean> {
331
+ const { tx } = context.state
328
332
 
329
333
  await tx.getRepository(Inventory).delete({
330
334
  id: In(ids)
@@ -343,9 +347,9 @@ export class InventoryMutation {
343
347
  @Arg('fromLocationName') fromLocationName: string,
344
348
  @Arg('toLocationName') toLocationName: string,
345
349
  @Arg('qty') qty: number,
346
- @Ctx() context: any
350
+ @Ctx() context: ResolverContext
347
351
  ): Promise<Boolean> {
348
- const { domain, user, tx }: { domain: Domain; user: User; tx: EntityManager } = context.state
352
+ const { domain, user, tx } = context.state
349
353
 
350
354
  const fromLocation: Location = await tx.getRepository(Location).findOne({
351
355
  where: { domain: domain, name: fromLocationName },
@@ -391,7 +395,7 @@ export class InventoryMutation {
391
395
  })
392
396
 
393
397
  const partialTransferFunc = async function (inventory, qty, fromLocation, toLocation, cartonId, palletId, context) {
394
- const { user, tx }: { domain: Domain; user: User; tx: EntityManager } = context.state
398
+ const { user, tx } = context.state
395
399
 
396
400
  if (qty < inventory.qty - (inventory?.lockedQty > 0 ? inventory.lockedQty : 0)) {
397
401
  if (!palletId || palletId.trim() == '') throw new Error('Require new lot id for partial transfer')