@things-factory/warehouse-base 6.0.134 → 6.0.141
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.
- package/dist-server/service/inventory/inventory-mutation.js +17 -9
- package/dist-server/service/inventory/inventory-mutation.js.map +1 -1
- package/dist-server/service/inventory/inventory-query.js +16 -0
- package/dist-server/service/inventory/inventory-query.js.map +1 -1
- package/dist-server/service/inventory-change/inventory-change-query.js +8 -3
- package/dist-server/service/inventory-change/inventory-change-query.js.map +1 -1
- package/dist-server/service/inventory-history/inventory-history-query.js +21 -0
- package/dist-server/service/inventory-history/inventory-history-query.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/dist-server/utils/inventory-util.js +5 -4
- package/dist-server/utils/inventory-util.js.map +1 -1
- package/package.json +4 -4
- package/server/service/inventory/inventory-mutation.ts +23 -4
- package/server/service/inventory/inventory-query.ts +11 -0
- package/server/service/inventory-change/inventory-change-query.ts +9 -4
- package/server/service/inventory-history/inventory-history-query.ts +29 -0
- package/server/utils/inventory-util.ts +15 -3
|
@@ -62,14 +62,14 @@ class InventoryUtil {
|
|
|
62
62
|
* @description It will update inventory after set a temp (domain, updater)
|
|
63
63
|
* and then generate inventory history based on current changes
|
|
64
64
|
*/
|
|
65
|
-
async transactionInventory(inventory, refOrder, changedQty, changedUom, transactionType) {
|
|
65
|
+
async transactionInventory(inventory, refOrder, changedQty, changedUom, transactionType, description) {
|
|
66
66
|
if (inventory.id) {
|
|
67
67
|
inventory = await this.updateInventory(inventory);
|
|
68
68
|
}
|
|
69
69
|
else {
|
|
70
70
|
inventory = await this.createInventory(inventory);
|
|
71
71
|
}
|
|
72
|
-
await generateInventoryHistory(inventory, refOrder, transactionType, changedQty, changedUom, this.user, this.trxMgr);
|
|
72
|
+
await generateInventoryHistory(inventory, refOrder, transactionType, changedQty, changedUom, this.user, this.trxMgr, description || null);
|
|
73
73
|
return inventory;
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
@@ -93,7 +93,7 @@ exports.InventoryUtil = InventoryUtil;
|
|
|
93
93
|
* @description It will insert new record into inventory histories table.
|
|
94
94
|
* seq will be calculated based on number of records for one specific pallet id (provided by inventory object)
|
|
95
95
|
*/
|
|
96
|
-
async function generateInventoryHistory(inventory, refOrder, transactionType, qty, uomValue, user, trxMgr) {
|
|
96
|
+
async function generateInventoryHistory(inventory, refOrder, transactionType, qty, uomValue, user, trxMgr, description) {
|
|
97
97
|
const invHistoryRepo = (trxMgr === null || trxMgr === void 0 ? void 0 : trxMgr.getRepository(service_1.InventoryHistory)) || (0, shell_1.getRepository)(service_1.InventoryHistory);
|
|
98
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))
|
|
@@ -123,7 +123,8 @@ async function generateInventoryHistory(inventory, refOrder, transactionType, qt
|
|
|
123
123
|
}
|
|
124
124
|
let remainQty = (openingQty || 0) + (qty || 0);
|
|
125
125
|
let inventoryHistory = new service_1.InventoryHistory();
|
|
126
|
-
inventoryHistory = Object.assign(Object.assign({}, inventory), { name: utils_1.InventoryNoGenerator.inventoryHistoryName(),
|
|
126
|
+
inventoryHistory = Object.assign(Object.assign({}, inventory), { name: utils_1.InventoryNoGenerator.inventoryHistoryName(), description,
|
|
127
|
+
inventory, seq: seq, status: remainQty == 0 ? constants_1.INVENTORY_STATUS.TERMINATED : inventory.status, transactionType, refOrderId: (refOrder === null || refOrder === void 0 ? void 0 : refOrder.id) || null, orderNo: (refOrder === null || refOrder === void 0 ? void 0 : refOrder.name) || null, orderRefNo: (refOrder === null || refOrder === void 0 ? void 0 : refOrder.refNo) || null, qty,
|
|
127
128
|
openingQty,
|
|
128
129
|
uomValue, openingUomValue: openingUomValue, creator: user, updater: user });
|
|
129
130
|
delete inventoryHistory.updatedAt;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inventory-util.js","sourceRoot":"","sources":["../../server/utils/inventory-util.ts"],"names":[],"mappings":";;;AAIA,+DAAsD;AACtD,iDAA6D;AAE7D,4CAA2G;AAC3G,wCAAkE;AAClE,oCAA+C;AAE/C,MAAa,aAAa;IAKxB,YAAY,MAAqB,EAAE,MAAc,EAAE,IAAU;QAM7C,cAAS,GAAG;YAC1B,IAAI,EAAE;gBACJ,SAAS,EAAE,CAAC,SAAc,EAAE,EAAE,CAAC,6CAA6C,SAAS,EAAE;gBACvF,eAAe,EAAE,CAAC,SAAc,EAAE,EAAE,CAAC,kDAAkD,SAAS,EAAE;gBAClG,SAAS,EAAE,CAAC,MAAW,EAAE,MAAW,EAAE,EAAE,CAAC,2BAA2B,MAAM,UAAU,MAAM,EAAE;aAC7F;YACD,UAAU,EAAE;gBACV,kBAAkB,EAAE,CAAC,SAAc,EAAE,UAAe,EAAE,EAAE,CACtD,qBAAqB,SAAS,KAAK,UAAU,4BAA4B;gBAC3E,UAAU,EAAE,CAAC,SAAc,EAAE,UAAe,EAAE,UAAe,EAAE,EAAE,CAC/D,kCAAkC,SAAS,KAAK,UAAU,KAAK,UAAU,GAAG;aAC/E;YACD,OAAO,EAAE;gBACP,kBAAkB,EAAE,CAAC,SAAc,EAAE,UAAe,EAAE,EAAE,CACtD,sEAAsE,SAAS,KAAK,UAAU,GAAG;gBACnG,iBAAiB,EAAE,CAAC,SAAc,EAAE,UAAe,EAAE,UAAe,EAAE,EAAE,CACtE,qBAAqB,SAAS,SAAS,UAAU,IAAI,UAAU,6BAA6B;aAC/F;YACD,MAAM,EAAE;gBACN,SAAS,EAAE,uBAAuB;gBAClC,aAAa,EAAE,+BAA+B;gBAC9C,aAAa,EAAE,+BAA+B;aAC/C;YACD,MAAM,EAAE;gBACN,aAAa,EAAE,wBAAwB;gBACvC,aAAa,EAAE,+BAA+B;aAC/C;YACD,QAAQ,EAAE;gBACR,sBAAsB,EAAE,CAAC,KAAa,EAAE,aAAkB,EAAE,WAAgB,EAAE,EAAE,CAC9E,YAAY,KAAK,aAAa,aAAa,YAAY,WAAW,EAAE;gBACtE,UAAU,EAAE,CAAC,KAAa,EAAE,KAAU,EAAE,EAAE,CAAC,uBAAuB,KAAK,WAAW,KAAK,GAAG;gBAC1F,oBAAoB,EAAE,CAAC,IAAY,EAAE,MAAc,EAAE,EAAE,CAAC,oBAAoB,IAAI,YAAY,MAAM,EAAE;aACrG;SACF,CAAA;QAtCC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAqCD,KAAK,CAAC,eAAe,CAAC,SAA6B;QACjD,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;QACpC,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,mBAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACnE,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,eAAe,CAAC,SAA6B;QACjD,IAAI,CAAC,SAAS,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;QACvE,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;QACpC,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,mBAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACnE,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,oBAAoB,CACxB,SAAoB,EACpB,QAAa,EACb,UAAkB,EAClB,UAAkB,EAClB,eAAuB;QAEvB,IAAI,SAAS,CAAC,EAAE,EAAE;YAChB,SAAS,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;SAClD;aAAM;YACL,SAAS,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;SAClD;QAED,MAAM,wBAAwB,CAAC,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAEpH,OAAO,SAAS,CAAA;IAClB,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,MAA2B;QAClC,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC/C,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAA;QAC7D,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAA;QAE/C,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAnGD,sCAmGC;AAED;;;GAGG;AACI,KAAK,UAAU,wBAAwB,CAC5C,SAAoB,EACpB,QAAa,EACb,eAAuB,EACvB,GAAW,EACX,QAAgB,EAChB,IAAU,EACV,MAAsB;IAEtB,MAAM,cAAc,GAClB,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,aAAa,CAAC,0BAAgB,CAAC,KAAI,IAAA,qBAAa,EAAC,0BAAgB,CAAC,CAAA;IAC5E,MAAM,OAAO,GAA0B,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,aAAa,CAAC,mBAAS,CAAC,KAAI,IAAA,qBAAa,EAAC,mBAAS,CAAC,CAAA;IAEnG,IAAI,CAAC,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,EAAE,CAAA;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IAEtE,SAAS,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC;QAChC,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,CAAC,EAAE,EAAE;QAC3B,SAAS,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,CAAC;KACtE,CAAC,CAAA;IAEF,MAAM,MAAM,GAAW,SAAS,CAAC,MAAM,CAAA;IACvC,MAAM,QAAQ,GAAa,SAAS,CAAC,QAAQ,CAAA;IAE7C,MAAM,cAAc,GAAqB,MAAM,cAAc,CAAC,OAAO,CAAC;QACpE,KAAK,EAAE;YACL,MAAM,EAAE,EAAE,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE;YACnC,QAAQ,EAAE,SAAS,CAAC,QAAQ;SAC7B;QACD,KAAK,EAAE;YACL,GAAG,EAAE,MAAM;SACZ;KACF,CAAC,CAAA;IAEF,IAAI,GAAG,GAAW,CAAC,CAAA;IACnB,IAAI,UAAU,GAAW,CAAC,CAAA;IAC1B,IAAI,eAAe,GAAW,CAAC,CAAA;IAE/B,IAAI,cAAc,EAAE;QAClB,UAAU,GAAG,cAAc,CAAC,UAAU,GAAG,cAAc,CAAC,GAAG,CAAA;QAC3D,eAAe,GAAG,cAAc,CAAC,eAAe,GAAG,cAAc,CAAC,QAAQ,CAAA;QAC1E,GAAG,GAAG,cAAc,CAAC,GAAG,GAAG,CAAC,CAAA;KAC7B;IAED,IAAI,SAAS,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAA;IAE9C,IAAI,gBAAgB,GAAQ,IAAI,0BAAgB,EAAE,CAAA;IAElD,gBAAgB,mCACX,SAAS,KACZ,IAAI,EAAE,4BAAoB,CAAC,oBAAoB,EAAE,EACjD,SAAS,EACT,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,4BAAgB,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,EACvE,eAAe,EACf,UAAU,EAAE,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,EAAE,KAAI,IAAI,EAChC,OAAO,EAAE,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,KAAI,IAAI,EAC/B,UAAU,EAAE,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,KAAK,KAAI,IAAI,EACnC,GAAG;QACH,UAAU;QACV,QAAQ,EACR,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,IAAI,EACb,OAAO,EAAE,IAAI,GACd,CAAA;IAED,OAAO,gBAAgB,CAAC,SAAS,CAAA;IACjC,OAAO,gBAAgB,CAAC,SAAS,CAAA;IACjC,OAAO,gBAAgB,CAAC,EAAE,CAAA;IAE1B,IAAI,mBAAmB,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;IAErE,IAAI,SAAS,IAAI,CAAC,EAAE;QAClB,GAAG,GAAG,GAAG,GAAG,CAAC,CAAA;QACb,IAAI,iBAAiB,mCAChB,mBAAmB,KACtB,IAAI,EAAE,4BAAoB,CAAC,oBAAoB,EAAE,EACjD,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,4BAAgB,CAAC,UAAU,EACnC,eAAe,EAAE,sCAA0B,CAAC,UAAU,EACtD,GAAG,EAAE,SAAS,CAAC,GAAG,EAClB,GAAG,EAAE,CAAC,EACN,UAAU,EAAE,CAAC,EACb,QAAQ,EAAE,CAAC,EACX,eAAe,EAAE,CAAC,GACnB,CAAA;QAED,OAAO,iBAAiB,CAAC,EAAE,CAAA;QAE3B,mBAAmB,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;QAClE,SAAS,CAAC,MAAM,GAAG,4BAAgB,CAAC,UAAU,CAAA;KAC/C;IAED,IAAI,SAAS,CAAC,OAAO,KAAK,GAAG,EAAE;QAC7B,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;KACxF;IAED,MAAM,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;IAC1D,OAAO,mBAAmB,CAAA;AAC5B,CAAC;AAlGD,4DAkGC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,oBAAoB,CACxC,MAAc,EACd,QAAkB,EAClB,OAAa,EACb,MAAsB;IAEtB,MAAM,OAAO,GAA0B,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,aAAa,CAAC,mBAAS,CAAC,KAAI,IAAA,qBAAa,EAAC,mBAAS,CAAC,CAAA;IACnG,MAAM,YAAY,GAAyB,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,aAAa,CAAC,kBAAQ,CAAC,KAAI,IAAA,qBAAa,EAAC,kBAAQ,CAAC,CAAA;IACrG,MAAM,iBAAiB,GAAW,MAAM,OAAO,CAAC,OAAO,CAAC;QACtD,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;QACzB,MAAM,EAAE,4BAAgB,CAAC,MAAM;QAC/B,QAAQ,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE;KAC9B,CAAC,CAAA;IAEF,IAAI,CAAC,iBAAiB,IAAI,QAAQ,CAAC,MAAM,KAAK,2BAAe,CAAC,KAAK,EAAE;QACnE,QAAQ,GAAG,MAAM,YAAY,CAAC,IAAI,iCAC7B,QAAQ,KACX,MAAM,EAAE,2BAAe,CAAC,KAAK,EAC7B,OAAO,IACP,CAAA;KACH;SAAM,IAAI,iBAAiB,IAAI,QAAQ,CAAC,MAAM,KAAK,2BAAe,CAAC,KAAK,EAAE;QACzE,QAAQ,GAAG,MAAM,YAAY,CAAC,IAAI,iCAC7B,QAAQ,KACX,MAAM,EAAE,2BAAe,CAAC,QAAQ,EAChC,OAAO,IACP,CAAA;KACH;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AA7BD,oDA6BC;AAEM,KAAK,UAAU,sBAAsB,CAC1C,MAAc,EACd,QAAkB,EAClB,QAAgB,EAChB,MAAsB;IAEtB,MAAM,OAAO,GAA0B,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,aAAa,CAAC,mBAAS,CAAC,KAAI,IAAA,qBAAa,EAAC,mBAAS,CAAC,CAAA;IACnG,MAAM,mBAAmB,GAAW,MAAM,OAAO,CAAC,OAAO,CAAC;QACxD,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;QACzB,QAAQ,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE;QAC7B,QAAQ;KACT,CAAC,CAAA;IAEF,OAAO,OAAO,CAAC,mBAAmB,CAAC,CAAA;AACrC,CAAC;AAdD,wDAcC;AAED;;;;;;;;;GASG;AACI,KAAK,UAAU,wBAAwB,CAC5C,MAAc,EACd,QAAkB,EAClB,QAAgB,EAChB,OAAe,EACf,OAAyB,EACzB,WAAmB,EACnB,MAAsB;;IAEtB,MAAM,WAAW,GAAwB,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,aAAa,CAAC,sBAAO,CAAC,KAAI,IAAA,qBAAa,EAAC,sBAAO,CAAC,CAAA;IACjG,MAAM,OAAO,GAA0B,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,aAAa,CAAC,mBAAS,CAAC,KAAI,IAAA,qBAAa,EAAC,mBAAS,CAAC,CAAA;IAEnG,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAC/B,MAAM,YAAY,GAAY,MAAM,WAAW,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA,CAAC,sCAAsC;QACjH,IAAI,CAAC,YAAY;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,OAAO,EAAE,CAAC,CAAA;QAC5E,OAAO,GAAG,YAAY,CAAA;KACvB;IAED,MAAM,GAAG,GAAc,MAAM,OAAO,CAAC,OAAO,CAAC;QAC3C,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE;QAC7E,SAAS,EAAE,CAAC,SAAS,CAAC;KACvB,CAAC,CAAA;IAEF,IAAI,OAAO,KAAK,GAAG,CAAC,OAAO;QAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,gCAAgC,OAAO,EAAE,EAAE,CAAA;IAErH,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,EAAE,OAAK,MAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,OAAO,0CAAE,EAAE,CAAA;QAClC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,+BAA+B,OAAO,CAAC,IAAI,EAAE,EAAE,CAAA;IAE9F,IAAI,WAAW,KAAK,GAAG,CAAC,WAAW;QACjC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,oCAAoC,WAAW,EAAE,EAAE,CAAA;IAElG,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,CAAA;AAChC,CAAC;AAhCD,4DAgCC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,yBAAyB,CAC7C,MAAc,EACd,kBAA0B,EAC1B,aAAoB,EACpB,MAAqB;IAErB,IAAI,iBAAiB,GAAG,IAAI,CAAC,SAAS,CACpC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QACtB,uCACK,GAAG,KACN,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,EAC1B,YAAY,EAAE,GAAG,CAAC,WAAW,EAC7B,YAAY,EAAE,GAAG,CAAC,WAAW,EAC7B,GAAG,EAAE,GAAG,CAAC,GAAG,IACb;IACH,CAAC,CAAC,IAAI,EAAE,CACT,CAAA;IAED,MAAM,MAAM,GAAU,MAAM,MAAM,CAAC,KAAK,CACtC;;;;;;;;+DAQ2D,iBAAiB;;;;;;;;;;;;;KAa3E,EACD,CAAC,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CACnC,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AA7CD,8DA6CC;AAED;;;;;;;;;;;GAWG;AACI,KAAK,UAAU,wBAAwB,CAC5C,QAAgB,EAChB,UAAkB,EAClB,WAAmB,EACnB,aAAoB,EACpB,oBAA2B,EAC3B,MAAqB;IAErB,IAAI,iBAAiB,GAAW,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAA;IAC7D,IAAI,eAAe,GAAW,CAAC,oBAAoB,IAAI,EAAE,CAAC;SACvD,GAAG,CAAC,CAAC,IAA0C,EAAE,EAAE;QAClD,OAAO,KAAK,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;IACxD,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,IAAI,eAAe,KAAK,EAAE;QAAE,eAAe,GAAG,QAAQ,CAAA;IAEtD,MAAM,MAAM,CAAC,KAAK,CAChB;;;;;;;;;;;GAWD,CACA,CAAA;IAED,MAAM,MAAM,CAAC,KAAK,CAChB;;;;GAID,EACC,CAAC,iBAAiB,CAAC,CACpB,CAAA;IAED,MAAM,MAAM,CAAC,KAAK,CAChB;;;;;;;;;;GAUD,EACC,CAAC,UAAU,EAAE,WAAW,CAAC,CAC1B,CAAA;IAED,kBAAkB;IAClB,IAAI,WAAW,GAAG,MAAM,MAAM,CAAC,KAAK,CAClC;;;;;;;;;;;;;;;;;;UAkBM,eAAe;;;;;;;;;;;;;;GActB,EACC,CAAC,yBAAa,CAAC,UAAU,EAAE,yBAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,4BAAgB,CAAC,MAAM,CAAC,CACjG,CAAA;IAED,MAAM,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAA;IAElD,OAAO,WAAW,CAAA;AACpB,CAAC;AAjGD,4DAiGC","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: { id: inventory.domain.id },\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: { id: bizplace.id }, 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 description?: 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(\n inventory,\n refOrder,\n transactionType,\n changedQty,\n changedUom,\n this.user,\n this.trxMgr,\n description || null\n )\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 description?: string\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: { id: inventory.domain.id },\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 description,\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: { id: bizplace.id }, 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": "6.0.
|
|
3
|
+
"version": "6.0.141",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"browser": "client/index.js",
|
|
6
6
|
"things-factory": true,
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@things-factory/biz-base": "^6.0.133",
|
|
28
28
|
"@things-factory/id-rule-base": "^6.0.133",
|
|
29
|
-
"@things-factory/integration-sellercraft": "^6.0.
|
|
30
|
-
"@things-factory/marketplace-base": "^6.0.
|
|
29
|
+
"@things-factory/integration-sellercraft": "^6.0.141",
|
|
30
|
+
"@things-factory/marketplace-base": "^6.0.141",
|
|
31
31
|
"@things-factory/product-base": "^6.0.133",
|
|
32
32
|
"@things-factory/setting-base": "^6.0.133"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "d9fe5f28cee1bf8f527688e06d190ae78d6e2b04"
|
|
35
35
|
}
|
|
@@ -268,6 +268,7 @@ export class InventoryMutation {
|
|
|
268
268
|
uomValue: -inventory.uomValue || 0,
|
|
269
269
|
name: InventoryNoGenerator.inventoryHistoryName(),
|
|
270
270
|
seq: lastSeq,
|
|
271
|
+
inventory,
|
|
271
272
|
transactionType: transactionType,
|
|
272
273
|
status: INVENTORY_STATUS.TERMINATED,
|
|
273
274
|
productId: inventory.product.id,
|
|
@@ -298,6 +299,7 @@ export class InventoryMutation {
|
|
|
298
299
|
updater: user,
|
|
299
300
|
name: InventoryNoGenerator.inventoryHistoryName(),
|
|
300
301
|
seq: lastSeq,
|
|
302
|
+
inventory,
|
|
301
303
|
transactionType: transactionType == '' ? 'ADJUSTMENT' : transactionType,
|
|
302
304
|
productId: newHistoryRecord.product ? newHistoryRecord.product.id : inventory.product.id,
|
|
303
305
|
warehouseId: newHistoryRecord.warehouse ? newHistoryRecord.warehouse.id : inventory.warehouse.id,
|
|
@@ -347,6 +349,7 @@ export class InventoryMutation {
|
|
|
347
349
|
@Arg('fromLocationName') fromLocationName: string,
|
|
348
350
|
@Arg('toLocationName') toLocationName: string,
|
|
349
351
|
@Arg('qty') qty: number,
|
|
352
|
+
@Arg('reason', { nullable: true }) reason: string,
|
|
350
353
|
@Ctx() context: ResolverContext
|
|
351
354
|
): Promise<Boolean> {
|
|
352
355
|
const { domain, user, tx } = context.state
|
|
@@ -360,7 +363,7 @@ export class InventoryMutation {
|
|
|
360
363
|
where: { domain: { id: domain.id }, name: toLocationName },
|
|
361
364
|
relations: ['domain', 'warehouse']
|
|
362
365
|
})
|
|
363
|
-
if (!toLocation) throw new Error(
|
|
366
|
+
if (!toLocation) throw new Error(context.t(`error.To_location_does_not_exists`))
|
|
364
367
|
|
|
365
368
|
if (qty < 0) throw new Error(`Invalid quantity`)
|
|
366
369
|
|
|
@@ -426,7 +429,8 @@ export class InventoryMutation {
|
|
|
426
429
|
null,
|
|
427
430
|
-transferQty,
|
|
428
431
|
-transferUomValue,
|
|
429
|
-
INVENTORY_TRANSACTION_TYPE.RELOCATE
|
|
432
|
+
INVENTORY_TRANSACTION_TYPE.RELOCATE,
|
|
433
|
+
reason || null
|
|
430
434
|
)
|
|
431
435
|
|
|
432
436
|
await transactionInventory.transactionInventory(
|
|
@@ -434,7 +438,8 @@ export class InventoryMutation {
|
|
|
434
438
|
null,
|
|
435
439
|
transferQty,
|
|
436
440
|
transferUomValue,
|
|
437
|
-
INVENTORY_TRANSACTION_TYPE.RELOCATE
|
|
441
|
+
INVENTORY_TRANSACTION_TYPE.RELOCATE,
|
|
442
|
+
reason || null
|
|
438
443
|
)
|
|
439
444
|
|
|
440
445
|
if (sellercraft) {
|
|
@@ -460,7 +465,14 @@ export class InventoryMutation {
|
|
|
460
465
|
})
|
|
461
466
|
}
|
|
462
467
|
|
|
463
|
-
await transactionInventory.transactionInventory(
|
|
468
|
+
await transactionInventory.transactionInventory(
|
|
469
|
+
inventory,
|
|
470
|
+
null,
|
|
471
|
+
0,
|
|
472
|
+
0,
|
|
473
|
+
INVENTORY_TRANSACTION_TYPE.RELOCATE,
|
|
474
|
+
reason || null
|
|
475
|
+
)
|
|
464
476
|
|
|
465
477
|
if (sellercraft) {
|
|
466
478
|
const sellercraftCtrl: SellercraftController = new SellercraftController(tx, domain, user)
|
|
@@ -482,6 +494,13 @@ export class InventoryMutation {
|
|
|
482
494
|
|
|
483
495
|
await partialTransferFunc(inventory, qty, fromLocation, toLocation, cartonId, palletId, context)
|
|
484
496
|
} else {
|
|
497
|
+
if (!palletId) {
|
|
498
|
+
palletId = await generateId({
|
|
499
|
+
domain: domain,
|
|
500
|
+
type: RULE_TYPE.LOT_NUMBER_ID,
|
|
501
|
+
seed: { date: DateGenerator.generateDate() }
|
|
502
|
+
})
|
|
503
|
+
}
|
|
485
504
|
await partialTransferFunc(inventory, qty, fromLocation, toLocation, null, palletId, context)
|
|
486
505
|
}
|
|
487
506
|
|
|
@@ -186,6 +186,17 @@ export class InventoryQuery {
|
|
|
186
186
|
})
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
+
@Directive('@privilege(category: "inventory", privilege: "query", domainOwnerGranted: true)')
|
|
190
|
+
@Query(returns => Inventory)
|
|
191
|
+
async inventoryById(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<Inventory> {
|
|
192
|
+
const { domain } = context.state
|
|
193
|
+
|
|
194
|
+
return await getRepository(Inventory).findOne({
|
|
195
|
+
where: { domain: { id: domain.id }, id },
|
|
196
|
+
relations: ['domain', 'bizplace', 'product', 'location', 'warehouse', 'creator', 'updater']
|
|
197
|
+
})
|
|
198
|
+
}
|
|
199
|
+
|
|
189
200
|
@Directive('@privilege(category: "inventory", privilege: "query", domainOwnerGranted: true)')
|
|
190
201
|
@Query(returns => Inventory)
|
|
191
202
|
async inventoryByPallet(@Arg('palletId') palletId: string, @Ctx() context: ResolverContext): Promise<Inventory> {
|
|
@@ -3,7 +3,7 @@ import { Brackets, SelectQueryBuilder } from 'typeorm'
|
|
|
3
3
|
|
|
4
4
|
import { User } from '@things-factory/auth-base'
|
|
5
5
|
import { getPermittedBizplaceIds } from '@things-factory/biz-base'
|
|
6
|
-
import { buildQuery, Domain, getRepository, ListParam } from '@things-factory/shell'
|
|
6
|
+
import { buildQuery, Domain, getRepository, ListParam, getQueryBuilderFromListParams } from '@things-factory/shell'
|
|
7
7
|
|
|
8
8
|
import { InventoryChange } from './inventory-change'
|
|
9
9
|
import { InventoryChangeList } from './inventory-change-types'
|
|
@@ -22,7 +22,7 @@ export class InventoryChangeQuery {
|
|
|
22
22
|
|
|
23
23
|
@Query(returns => InventoryChangeList)
|
|
24
24
|
async inventoryChanges(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<InventoryChangeList> {
|
|
25
|
-
const { domain, user } = context.state
|
|
25
|
+
const { domain, user, tx } = context.state
|
|
26
26
|
|
|
27
27
|
let bizplaces: any[]
|
|
28
28
|
if (!params.filters.find(filter => filter.name === 'bizplace')) {
|
|
@@ -32,8 +32,13 @@ export class InventoryChangeQuery {
|
|
|
32
32
|
params.filters = [...params.filters.filter(filter => filter.name != 'bizplace')]
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
const qb: SelectQueryBuilder<InventoryChange> =
|
|
36
|
-
|
|
35
|
+
const qb: SelectQueryBuilder<InventoryChange> = getQueryBuilderFromListParams({
|
|
36
|
+
repository: getRepository(InventoryChange),
|
|
37
|
+
params,
|
|
38
|
+
domain,
|
|
39
|
+
alias: 'ic',
|
|
40
|
+
searchables: ['palletId']
|
|
41
|
+
})
|
|
37
42
|
|
|
38
43
|
qb.innerJoinAndSelect('ic.domain', 'dm')
|
|
39
44
|
.leftJoinAndSelect('ic.bizplace', 'biz')
|
|
@@ -87,6 +87,35 @@ export class InventoryHistoryQuery {
|
|
|
87
87
|
return { items, total }
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
@Query(returns => InventoryHistoryList)
|
|
91
|
+
async renewInventoryHistories(
|
|
92
|
+
@Args() params: ListParam,
|
|
93
|
+
@Ctx() context: ResolverContext
|
|
94
|
+
): Promise<InventoryHistoryList> {
|
|
95
|
+
const { domain, user } = context.state
|
|
96
|
+
|
|
97
|
+
if (!params.filters.find((filter: any) => filter.name === 'bizplace')) {
|
|
98
|
+
params.filters.push({
|
|
99
|
+
name: 'bizplace',
|
|
100
|
+
operator: 'in',
|
|
101
|
+
value: await getPermittedBizplaceIds(domain, user)
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const convertedParams = convertListParams(params)
|
|
106
|
+
let [items, total] = await getRepository(InventoryHistory).findAndCount({
|
|
107
|
+
...convertedParams,
|
|
108
|
+
relations: ['domain', 'bizplace', 'product', 'location', 'warehouse', 'creator', 'updater'],
|
|
109
|
+
order: {
|
|
110
|
+
...convertedParams.order,
|
|
111
|
+
palletId: 'DESC',
|
|
112
|
+
createdAt: 'ASC'
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
return { items, total }
|
|
117
|
+
}
|
|
118
|
+
|
|
90
119
|
@Query(returns => InventoryHistory)
|
|
91
120
|
async inventoryHistory(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<InventoryHistory> {
|
|
92
121
|
const { domain } = context.state
|
|
@@ -82,7 +82,8 @@ export class InventoryUtil {
|
|
|
82
82
|
refOrder: any,
|
|
83
83
|
changedQty: number,
|
|
84
84
|
changedUom: number,
|
|
85
|
-
transactionType: string
|
|
85
|
+
transactionType: string,
|
|
86
|
+
description?: string
|
|
86
87
|
): Promise<Inventory> {
|
|
87
88
|
if (inventory.id) {
|
|
88
89
|
inventory = await this.updateInventory(inventory)
|
|
@@ -90,7 +91,16 @@ export class InventoryUtil {
|
|
|
90
91
|
inventory = await this.createInventory(inventory)
|
|
91
92
|
}
|
|
92
93
|
|
|
93
|
-
await generateInventoryHistory(
|
|
94
|
+
await generateInventoryHistory(
|
|
95
|
+
inventory,
|
|
96
|
+
refOrder,
|
|
97
|
+
transactionType,
|
|
98
|
+
changedQty,
|
|
99
|
+
changedUom,
|
|
100
|
+
this.user,
|
|
101
|
+
this.trxMgr,
|
|
102
|
+
description || null
|
|
103
|
+
)
|
|
94
104
|
|
|
95
105
|
return inventory
|
|
96
106
|
}
|
|
@@ -121,7 +131,8 @@ export async function generateInventoryHistory(
|
|
|
121
131
|
qty: number,
|
|
122
132
|
uomValue: number,
|
|
123
133
|
user: User,
|
|
124
|
-
trxMgr?: EntityManager
|
|
134
|
+
trxMgr?: EntityManager,
|
|
135
|
+
description?: string
|
|
125
136
|
): Promise<InventoryHistory> {
|
|
126
137
|
const invHistoryRepo: Repository<InventoryHistory> =
|
|
127
138
|
trxMgr?.getRepository(InventoryHistory) || getRepository(InventoryHistory)
|
|
@@ -164,6 +175,7 @@ export async function generateInventoryHistory(
|
|
|
164
175
|
inventoryHistory = {
|
|
165
176
|
...inventory,
|
|
166
177
|
name: InventoryNoGenerator.inventoryHistoryName(),
|
|
178
|
+
description,
|
|
167
179
|
inventory,
|
|
168
180
|
seq: seq,
|
|
169
181
|
status: remainQty == 0 ? INVENTORY_STATUS.TERMINATED : inventory.status,
|