@things-factory/operato-hub 4.3.562 → 4.3.564

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 (48) hide show
  1. package/dist-server/graphql/resolvers/email/send-emails.js +3 -2
  2. package/dist-server/graphql/resolvers/email/send-emails.js.map +1 -1
  3. package/dist-server/graphql/resolvers/reports/admiral-asn-report.js +127 -0
  4. package/dist-server/graphql/resolvers/reports/admiral-asn-report.js.map +1 -0
  5. package/dist-server/graphql/resolvers/reports/aging-report.js +146 -0
  6. package/dist-server/graphql/resolvers/reports/aging-report.js.map +1 -0
  7. package/dist-server/graphql/resolvers/reports/asn-report.js +126 -0
  8. package/dist-server/graphql/resolvers/reports/asn-report.js.map +1 -0
  9. package/dist-server/graphql/resolvers/reports/custom-elccl-fn-dispatch-report.js +1 -1
  10. package/dist-server/graphql/resolvers/reports/index.js +5 -1
  11. package/dist-server/graphql/resolvers/reports/index.js.map +1 -1
  12. package/dist-server/graphql/resolvers/reports/receiving-report.js +82 -0
  13. package/dist-server/graphql/resolvers/reports/receiving-report.js.map +1 -0
  14. package/dist-server/graphql/types/reports/admiral-asn-report-list.js +14 -0
  15. package/dist-server/graphql/types/reports/admiral-asn-report-list.js.map +1 -0
  16. package/dist-server/graphql/types/reports/admiral-asn-report.js +21 -0
  17. package/dist-server/graphql/types/reports/admiral-asn-report.js.map +1 -0
  18. package/dist-server/graphql/types/reports/aging-report-list.js +14 -0
  19. package/dist-server/graphql/types/reports/aging-report-list.js.map +1 -0
  20. package/dist-server/graphql/types/reports/aging-report.js +29 -0
  21. package/dist-server/graphql/types/reports/aging-report.js.map +1 -0
  22. package/dist-server/graphql/types/reports/asn-report-list.js +14 -0
  23. package/dist-server/graphql/types/reports/asn-report-list.js.map +1 -0
  24. package/dist-server/graphql/types/reports/asn-report.js +21 -0
  25. package/dist-server/graphql/types/reports/asn-report.js.map +1 -0
  26. package/dist-server/graphql/types/reports/index.js +21 -1
  27. package/dist-server/graphql/types/reports/index.js.map +1 -1
  28. package/dist-server/graphql/types/reports/receiving-report-list.js +14 -0
  29. package/dist-server/graphql/types/reports/receiving-report-list.js.map +1 -0
  30. package/dist-server/graphql/types/reports/receiving-report.js +22 -0
  31. package/dist-server/graphql/types/reports/receiving-report.js.map +1 -0
  32. package/package.json +31 -31
  33. package/server/graphql/resolvers/email/send-emails.ts +3 -2
  34. package/server/graphql/resolvers/reports/admiral-asn-report.ts +142 -0
  35. package/server/graphql/resolvers/reports/aging-report.ts +161 -0
  36. package/server/graphql/resolvers/reports/asn-report.ts +141 -0
  37. package/server/graphql/resolvers/reports/custom-elccl-fn-dispatch-report.ts +1 -1
  38. package/server/graphql/resolvers/reports/index.ts +10 -1
  39. package/server/graphql/resolvers/reports/receiving-report.ts +87 -0
  40. package/server/graphql/types/reports/admiral-asn-report-list.ts +8 -0
  41. package/server/graphql/types/reports/admiral-asn-report.ts +15 -0
  42. package/server/graphql/types/reports/aging-report-list.ts +8 -0
  43. package/server/graphql/types/reports/aging-report.ts +23 -0
  44. package/server/graphql/types/reports/asn-report-list.ts +8 -0
  45. package/server/graphql/types/reports/asn-report.ts +15 -0
  46. package/server/graphql/types/reports/index.ts +21 -1
  47. package/server/graphql/types/reports/receiving-report-list.ts +8 -0
  48. package/server/graphql/types/reports/receiving-report.ts +16 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admiral-asn-report.js","sourceRoot":"","sources":["../../../../server/graphql/types/reports/admiral-asn-report.ts"],"names":[],"mappings":";;;;;;AAAA,8DAA6B;AAEhB,QAAA,gBAAgB,GAAG,IAAA,qBAAG,EAAA;;;;;;;;;;;;CAYlC,CAAA"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AgingReportList = void 0;
7
+ const graphql_tag_1 = __importDefault(require("graphql-tag"));
8
+ exports.AgingReportList = (0, graphql_tag_1.default) `
9
+ type AgingReportList {
10
+ items: [AgingReport]
11
+ total: Int
12
+ }
13
+ `;
14
+ //# sourceMappingURL=aging-report-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aging-report-list.js","sourceRoot":"","sources":["../../../../server/graphql/types/reports/aging-report-list.ts"],"names":[],"mappings":";;;;;;AAAA,8DAA6B;AAEhB,QAAA,eAAe,GAAG,IAAA,qBAAG,EAAA;;;;;CAKjC,CAAA"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AgingReport = void 0;
7
+ const graphql_tag_1 = __importDefault(require("graphql-tag"));
8
+ exports.AgingReport = (0, graphql_tag_1.default) `
9
+ type AgingReport {
10
+ productSku: Int
11
+ productName: String
12
+ pallet: Int
13
+ qtyAvailable: Int
14
+ lotId: String
15
+ batchId: String
16
+ receiptDate: String
17
+ expDate: String
18
+ mfgDate: String
19
+ stockStatus: String
20
+ defaultUom: String
21
+ daysInWarehouse: Int
22
+ daysToExpire: Int
23
+ monthsInWarehouse: Int
24
+ monthsToExpire: Int
25
+ totalPallet: String
26
+ totalQtyAvailable: String
27
+ }
28
+ `;
29
+ //# sourceMappingURL=aging-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aging-report.js","sourceRoot":"","sources":["../../../../server/graphql/types/reports/aging-report.ts"],"names":[],"mappings":";;;;;;AAAA,8DAA6B;AAEhB,QAAA,WAAW,GAAG,IAAA,qBAAG,EAAA;;;;;;;;;;;;;;;;;;;;CAoB7B,CAAA"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AsnReportList = void 0;
7
+ const graphql_tag_1 = __importDefault(require("graphql-tag"));
8
+ exports.AsnReportList = (0, graphql_tag_1.default) `
9
+ type AsnReportList {
10
+ items: [AsnReport]
11
+ total: Int
12
+ }
13
+ `;
14
+ //# sourceMappingURL=asn-report-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asn-report-list.js","sourceRoot":"","sources":["../../../../server/graphql/types/reports/asn-report-list.ts"],"names":[],"mappings":";;;;;;AAAA,8DAA6B;AAEhB,QAAA,aAAa,GAAG,IAAA,qBAAG,EAAA;;;;;CAK/B,CAAA"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AsnReport = void 0;
7
+ const graphql_tag_1 = __importDefault(require("graphql-tag"));
8
+ exports.AsnReport = (0, graphql_tag_1.default) `
9
+ type AsnReport {
10
+ dateReceived: String
11
+ doNumber: String
12
+ sku: String
13
+ descr: String
14
+ qty: Int
15
+ palletId: String
16
+ mfgDate: String
17
+ expiryDate: String
18
+ remark: String
19
+ }
20
+ `;
21
+ //# sourceMappingURL=asn-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asn-report.js","sourceRoot":"","sources":["../../../../server/graphql/types/reports/asn-report.ts"],"names":[],"mappings":";;;;;;AAAA,8DAA6B;AAEhB,QAAA,SAAS,GAAG,IAAA,qBAAG,EAAA;;;;;;;;;;;;CAY3B,CAAA"}
@@ -9,11 +9,23 @@ const shortage_report_list_1 = require("./shortage-report-list");
9
9
  const shortage_report_type_1 = require("./shortage-report-type");
10
10
  const custom_elccl_fn_dispatch_report_1 = require("./custom-elccl-fn-dispatch-report");
11
11
  const custom_elccl_fn_dispatch_report_list_1 = require("./custom-elccl-fn-dispatch-report-list");
12
+ const aging_report_1 = require("./aging-report");
13
+ const aging_report_list_1 = require("./aging-report-list");
14
+ const asn_report_1 = require("./asn-report");
15
+ const asn_report_list_1 = require("./asn-report-list");
16
+ const admiral_asn_report_1 = require("./admiral-asn-report");
17
+ const admiral_asn_report_list_1 = require("./admiral-asn-report-list");
18
+ const receiving_report_1 = require("./receiving-report");
19
+ const receiving_report_list_1 = require("./receiving-report-list");
12
20
  exports.Query = `
13
21
  inboundOrderDetailsReport(filters: [Filter!], pagination: Pagination, sortings: [Sorting!]): InboundOrderDetailsReportList @transaction
14
22
  outboundOrderDetailsReport(filters: [Filter!], pagination: Pagination, sortings: [Sorting!]): OutboundOrderDetailsReportList @transaction
15
23
  shortageReport(filters: [Filter!], pagination: Pagination, sortings: [Sorting!]):ShortageReportList @transaction
16
24
  customElcclDispatchReport(filters: [Filter!], pagination: Pagination, sortings: [Sorting!]): CustomElcclDispatchReportList @transaction
25
+ agingReport(filters: [Filter!], pagination: Pagination, sortings: [Sorting!]): AgingReportList @transaction
26
+ asnReport(filters: [Filter!], pagination: Pagination, sortings: [Sorting!]): AsnReportList @transaction
27
+ admiralAsnReport(filters: [Filter!], pagination: Pagination, sortings: [Sorting!]): AdmiralAsnReportList @transaction
28
+ receivingReport(filters: [Filter!], pagination: Pagination, sortings: [Sorting!]): ReceivingReportList @transaction
17
29
  `;
18
30
  exports.Types = [
19
31
  inbound_order_details_report_1.InboundOrderDetailsReport,
@@ -23,6 +35,14 @@ exports.Types = [
23
35
  shortage_report_type_1.ShortageReport,
24
36
  shortage_report_list_1.ShortageReportList,
25
37
  custom_elccl_fn_dispatch_report_1.CustomElcclDispatchReport,
26
- custom_elccl_fn_dispatch_report_list_1.CustomElcclDispatchReportList
38
+ custom_elccl_fn_dispatch_report_list_1.CustomElcclDispatchReportList,
39
+ receiving_report_1.ReceivingReport,
40
+ receiving_report_list_1.ReceivingReportList,
41
+ aging_report_1.AgingReport,
42
+ aging_report_list_1.AgingReportList,
43
+ asn_report_1.AsnReport,
44
+ asn_report_list_1.AsnReportList,
45
+ admiral_asn_report_1.AdmiralAsnReport,
46
+ admiral_asn_report_list_1.AdmiralAsnReportList
27
47
  ];
28
48
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../server/graphql/types/reports/index.ts"],"names":[],"mappings":";;;AAAA,iFAA0E;AAC1E,2FAAmF;AACnF,mFAA4E;AAC5E,6FAAqF;AACrF,iEAA2D;AAC3D,iEAAuD;AACvD,uFAA6E;AAC7E,iGAAsF;AAEzE,QAAA,KAAK,GAAG;;;;;CAKpB,CAAA;AAEY,QAAA,KAAK,GAAG;IACnB,wDAAyB;IACzB,iEAA6B;IAC7B,0DAA0B;IAC1B,mEAA8B;IAC9B,qCAAc;IACd,yCAAkB;IAClB,2DAAyB;IACzB,oEAA6B;CAC9B,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../server/graphql/types/reports/index.ts"],"names":[],"mappings":";;;AAAA,iFAA0E;AAC1E,2FAAmF;AACnF,mFAA4E;AAC5E,6FAAqF;AACrF,iEAA2D;AAC3D,iEAAuD;AACvD,uFAA6E;AAC7E,iGAAsF;AACtF,iDAA4C;AAC5C,2DAAqD;AACrD,6CAAwC;AACxC,uDAAiD;AACjD,6DAAuD;AACvD,uEAAgE;AAChE,yDAAoD;AACpD,mEAA6D;AAEhD,QAAA,KAAK,GAAG;;;;;;;;;CASpB,CAAA;AAEY,QAAA,KAAK,GAAG;IACnB,wDAAyB;IACzB,iEAA6B;IAC7B,0DAA0B;IAC1B,mEAA8B;IAC9B,qCAAc;IACd,yCAAkB;IAClB,2DAAyB;IACzB,oEAA6B;IAC7B,kCAAe;IACf,2CAAmB;IACnB,0BAAW;IACX,mCAAe;IACf,sBAAS;IACT,+BAAa;IACb,qCAAgB;IAChB,8CAAoB;CACrB,CAAA"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ReceivingReportList = void 0;
7
+ const graphql_tag_1 = __importDefault(require("graphql-tag"));
8
+ exports.ReceivingReportList = (0, graphql_tag_1.default) `
9
+ type ReceivingReportList {
10
+ items: [ReceivingReport]
11
+ total: Int
12
+ }
13
+ `;
14
+ //# sourceMappingURL=receiving-report-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receiving-report-list.js","sourceRoot":"","sources":["../../../../server/graphql/types/reports/receiving-report-list.ts"],"names":[],"mappings":";;;;;;AAAA,8DAA6B;AAEhB,QAAA,mBAAmB,GAAG,IAAA,qBAAG,EAAA;;;;;CAKrC,CAAA"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ReceivingReport = void 0;
7
+ const graphql_tag_1 = __importDefault(require("graphql-tag"));
8
+ exports.ReceivingReport = (0, graphql_tag_1.default) `
9
+ type ReceivingReport {
10
+ arrivedDate: String
11
+ receiptId: String
12
+ receiptIdType: String
13
+ batch: String
14
+ mfgDate: String
15
+ expDate: String
16
+ item: String
17
+ itemDesc: String
18
+ quantity: String
19
+ qtyUm: String
20
+ }
21
+ `;
22
+ //# sourceMappingURL=receiving-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receiving-report.js","sourceRoot":"","sources":["../../../../server/graphql/types/reports/receiving-report.ts"],"names":[],"mappings":";;;;;;AAAA,8DAA6B;AAEhB,QAAA,eAAe,GAAG,IAAA,qBAAG,EAAA;;;;;;;;;;;;;CAajC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/operato-hub",
3
- "version": "4.3.562",
3
+ "version": "4.3.564",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -55,44 +55,44 @@
55
55
  "@operato/scene-tab": "^0.1.8",
56
56
  "@operato/scene-table": "^0.1.8",
57
57
  "@operato/scene-wheel-sorter": "^0.1.8",
58
- "@things-factory/api": "^4.3.535",
58
+ "@things-factory/api": "^4.3.563",
59
59
  "@things-factory/apptool-ui": "^4.3.535",
60
- "@things-factory/attachment-base": "^4.3.535",
61
- "@things-factory/auth-base": "^4.3.535",
62
- "@things-factory/auth-ui": "^4.3.535",
63
- "@things-factory/biz-base": "^4.3.535",
64
- "@things-factory/biz-ui": "^4.3.535",
65
- "@things-factory/board-service": "^4.3.535",
66
- "@things-factory/board-ui": "^4.3.535",
67
- "@things-factory/code-ui": "^4.3.535",
60
+ "@things-factory/attachment-base": "^4.3.563",
61
+ "@things-factory/auth-base": "^4.3.563",
62
+ "@things-factory/auth-ui": "^4.3.563",
63
+ "@things-factory/biz-base": "^4.3.563",
64
+ "@things-factory/biz-ui": "^4.3.563",
65
+ "@things-factory/board-service": "^4.3.563",
66
+ "@things-factory/board-ui": "^4.3.563",
67
+ "@things-factory/code-ui": "^4.3.563",
68
68
  "@things-factory/component-ui": "^4.3.534",
69
69
  "@things-factory/context-ui": "^4.3.535",
70
- "@things-factory/document-template-ui": "^4.3.535",
70
+ "@things-factory/document-template-ui": "^4.3.563",
71
71
  "@things-factory/export-ui": "^4.3.535",
72
72
  "@things-factory/export-ui-csv": "^4.3.535",
73
73
  "@things-factory/export-ui-excel": "^4.3.535",
74
- "@things-factory/geography": "^4.3.535",
74
+ "@things-factory/geography": "^4.3.563",
75
75
  "@things-factory/grist-ui": "^4.3.535",
76
76
  "@things-factory/help": "^4.3.535",
77
77
  "@things-factory/i18n-base": "^4.3.535",
78
78
  "@things-factory/import-ui": "^4.3.535",
79
79
  "@things-factory/import-ui-excel": "^4.3.535",
80
- "@things-factory/integration-accounting": "^4.3.562",
81
- "@things-factory/integration-fulfillment": "^4.3.562",
82
- "@things-factory/integration-lmd": "^4.3.562",
83
- "@things-factory/integration-marketplace": "^4.3.562",
84
- "@things-factory/integration-pos": "^4.3.562",
85
- "@things-factory/integration-powrup": "^4.3.562",
86
- "@things-factory/integration-sellercraft": "^4.3.562",
87
- "@things-factory/integration-sftp": "^4.3.562",
88
- "@things-factory/lite-menu": "^4.3.535",
89
- "@things-factory/marketplace-base": "^4.3.562",
80
+ "@things-factory/integration-accounting": "^4.3.563",
81
+ "@things-factory/integration-fulfillment": "^4.3.563",
82
+ "@things-factory/integration-lmd": "^4.3.563",
83
+ "@things-factory/integration-marketplace": "^4.3.563",
84
+ "@things-factory/integration-pos": "^4.3.563",
85
+ "@things-factory/integration-powrup": "^4.3.563",
86
+ "@things-factory/integration-sellercraft": "^4.3.563",
87
+ "@things-factory/integration-sftp": "^4.3.563",
88
+ "@things-factory/lite-menu": "^4.3.563",
89
+ "@things-factory/marketplace-base": "^4.3.563",
90
90
  "@things-factory/more-ui": "^4.3.535",
91
- "@things-factory/notification": "^4.3.535",
91
+ "@things-factory/notification": "^4.3.563",
92
92
  "@things-factory/pdf": "^4.3.534",
93
- "@things-factory/product-ui": "^4.3.535",
94
- "@things-factory/resource-ui": "^4.3.535",
95
- "@things-factory/sales-base": "^4.3.562",
93
+ "@things-factory/product-ui": "^4.3.563",
94
+ "@things-factory/resource-ui": "^4.3.563",
95
+ "@things-factory/sales-base": "^4.3.563",
96
96
  "@things-factory/scene-data-transform": "^4.3.534",
97
97
  "@things-factory/scene-excel": "^4.3.534",
98
98
  "@things-factory/scene-firebase": "^4.3.534",
@@ -104,12 +104,12 @@
104
104
  "@things-factory/scene-mqtt": "^4.3.534",
105
105
  "@things-factory/scene-restful": "^4.3.534",
106
106
  "@things-factory/scene-visualizer": "^4.3.534",
107
- "@things-factory/setting-ui": "^4.3.535",
107
+ "@things-factory/setting-ui": "^4.3.563",
108
108
  "@things-factory/shell": "^4.3.535",
109
109
  "@things-factory/system-ui": "^4.3.535",
110
- "@things-factory/transport-base": "^4.3.535",
111
- "@things-factory/warehouse-base": "^4.3.562",
112
- "@things-factory/worksheet-base": "^4.3.562",
110
+ "@things-factory/transport-base": "^4.3.563",
111
+ "@things-factory/warehouse-base": "^4.3.563",
112
+ "@things-factory/worksheet-base": "^4.3.563",
113
113
  "cron-parser": "^4.7.0",
114
114
  "koa2-swagger-ui": "^5.0.2",
115
115
  "swagger-jsdoc": "^5.0.0",
@@ -122,5 +122,5 @@
122
122
  "resolutions": {
123
123
  "core-js": "^3.16.0"
124
124
  },
125
- "gitHead": "23e29a852185cced85f48b9bfff6cdabe479199d"
125
+ "gitHead": "603113d785b5ad7930d8c34a73fa7e3aa2a91d37"
126
126
  }
@@ -195,9 +195,10 @@ async function processEmailCronJob(email, fromDate, toDate) {
195
195
 
196
196
  if (enableDateAtSubjectSettings?.value == 'true') {
197
197
  const newDate = new Date()
198
- const formattedDate = newDate.toISOString().split('T')[0]
198
+ const formattedDate = newDate.toLocaleDateString('en-GB').split('/').join('.')
199
+ const shortDate = formattedDate.slice(0, 6) + formattedDate.slice(-2)
199
200
  attachments.push({
200
- filename: `${bizplace.name} - ${attachment.name} - ${formattedDate}.xlsx`,
201
+ filename: `${attachment.name} (Dated ${shortDate}).xlsx`,
201
202
  content: excelResponse,
202
203
  contentType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
203
204
  })
@@ -0,0 +1,142 @@
1
+ import { EntityManager } from 'typeorm'
2
+ import { Bizplace } from '@things-factory/biz-base'
3
+ import { ListParam } from '@things-factory/shell'
4
+
5
+ export const admiralAsnReport = {
6
+ async admiralAsnReport(_: any, params: ListParam, context: any) {
7
+ try {
8
+ const { tx }: { tx: EntityManager } = context.state
9
+
10
+ // Fetch all bizplace filters from params
11
+ let bizplaceFilters = params.filters.filter(data => data.name === 'bizplace')
12
+
13
+ if (!bizplaceFilters || bizplaceFilters.length === 0)
14
+ throw 'Invalid input: At least one Bizplace filter is required'
15
+
16
+ // Extract bizplace IDs from filters
17
+ const bizplaceIds = bizplaceFilters.map(filter => filter.value)
18
+
19
+ if (!bizplaceIds || bizplaceIds.length === 0) throw 'Invalid input: No Bizplace IDs provided'
20
+
21
+ // Query the database for matching Bizplaces to ensure they exist
22
+ const bizplaces: Bizplace[] = await tx.getRepository(Bizplace).findByIds(bizplaceIds)
23
+
24
+ if (!bizplaces || bizplaces.length === 0) throw 'Invalid input: None of the provided Bizplaces were found'
25
+
26
+ // Create temporary table for report
27
+ await tx.query(
28
+ `
29
+ create temp table temp_inbound_order_report on commit drop as (
30
+ select
31
+ to_char((grn.created_at + interval '8 hours')::date,'dd/mm/yyyy') as "date_received",
32
+ an.delivery_order_no as "do_number",
33
+ p.sku as "sku",
34
+ p.name as "descr",
35
+ coalesce(oi.actual_pack_qty, 0) as "qty",
36
+ i.pallet_id as "pallet_id",
37
+ to_char(i.manufacture_date, 'DD/MM/YYYY') as "mfg_date",
38
+ to_char(i.expiration_date, 'DD/MM/YYYY') as "expiry_date",
39
+ i.batch_id as "remark"
40
+ from arrival_notices an
41
+ inner join order_products op on an.id = op.arrival_notice_id
42
+ inner join order_inventories oi
43
+ on op.arrival_notice_id = oi.arrival_notice_id
44
+ and op.product_id = oi.product_id
45
+ and op.product_detail_id = oi.product_detail_id
46
+ and oi.batch_id = op.batch_id
47
+ inner join products p on p.id = op.product_id
48
+ inner join inventories i on i.id = oi.inventory_id
49
+ inner join goods_receival_notes grn on an.id = grn.arrival_notice_id
50
+ where p.sku = '1000221'
51
+ and i.bizplace_id = ANY($1)
52
+ and grn.created_at::date = (NOW()::date - interval '1 day')
53
+ order by "date_received", "pallet_id"
54
+ )
55
+ `,
56
+ [bizplaceIds]
57
+ )
58
+
59
+ // Fetch detailed results
60
+ const result: any = await tx.query(`
61
+ select *
62
+ from temp_inbound_order_report
63
+ `)
64
+
65
+ // Fetch aggregated totals grouped by D/O Number
66
+ const totals = await tx.query(`
67
+ select
68
+ do_number,
69
+ SUM(COALESCE(qty, 0)) as total_qty
70
+ from temp_inbound_order_report
71
+ group by do_number
72
+ order by do_number
73
+ `)
74
+
75
+ // Map detailed results
76
+ let items = result.map(itm => ({
77
+ dateReceived: itm.date_received,
78
+ doNumber: itm.do_number,
79
+ sku: itm.sku,
80
+ descr: itm.descr,
81
+ qty: itm.qty && !isNaN(itm.qty) ? parseInt(itm.qty, 10) : 0,
82
+ palletId: itm.pallet_id,
83
+ mfgDate: itm.mfg_date,
84
+ expiryDate: itm.expiry_date,
85
+ remark: itm.remark
86
+ }))
87
+
88
+ // Map aggregated totals
89
+ let totalItems = totals.map(total => ({
90
+ doNumber: total.do_number,
91
+ qty: total.total_qty && !isNaN(total.total_qty) ? parseInt(total.total_qty, 10) : 0
92
+ }))
93
+
94
+ // Insert total counts into the items array
95
+ totalItems.forEach(total => {
96
+ // Find the last index of items matching the current total description
97
+ const lastIndex = items.findLastIndex(item => item.doNumber === total.doNumber)
98
+
99
+ if (lastIndex !== -1) {
100
+ items.splice(lastIndex + 1, 0, {
101
+ dateReceived: null,
102
+ doNumber: `${total.doNumber} Total`,
103
+ sku: null,
104
+ descr: null,
105
+ qty: total.qty,
106
+ palletId: null,
107
+ mfgDate: null,
108
+ expiryDate: null,
109
+ remark: null
110
+ })
111
+ }
112
+ })
113
+
114
+ // Calculate grand total
115
+ const grandTotalQty = totalItems.reduce((sum, total) => {
116
+ const qty = !isNaN(total.qty) ? parseInt(total.qty, 10) : 0
117
+ return sum + qty
118
+ }, 0)
119
+
120
+ // Append the grand total row at the end
121
+ items.push({
122
+ dateReceived: null,
123
+ doNumber: 'Grand Total',
124
+ sku: null,
125
+ descr: null,
126
+ qty: grandTotalQty,
127
+ palletId: null,
128
+ mfgDate: null,
129
+ expiryDate: null,
130
+ remark: null
131
+ })
132
+
133
+ // Return the modified items with inserted totals
134
+ return {
135
+ items,
136
+ totals: totalItems
137
+ }
138
+ } catch (error) {
139
+ throw error
140
+ }
141
+ }
142
+ }
@@ -0,0 +1,161 @@
1
+ import { EntityManager } from 'typeorm'
2
+ import { Bizplace } from '@things-factory/biz-base'
3
+ import { ListParam } from '@things-factory/shell'
4
+
5
+ export const agingReport = {
6
+ async agingReport(_: any, params: ListParam, context: any) {
7
+ try {
8
+ const { tx }: { tx: EntityManager } = context.state
9
+
10
+ // Fetch all bizplace filters from params
11
+ let bizplaceFilters = params.filters.filter(data => data.name === 'bizplace')
12
+
13
+ if (!bizplaceFilters || bizplaceFilters.length === 0)
14
+ throw 'Invalid input: At least one Bizplace filter is required'
15
+
16
+ // Extract bizplace IDs from filters
17
+ const bizplaceIds = bizplaceFilters.map(filter => filter.value)
18
+
19
+ if (!bizplaceIds || bizplaceIds.length === 0) throw 'Invalid input: No Bizplace IDs provided'
20
+
21
+ // Query the database for matching Bizplaces to ensure they exist
22
+ const bizplaces: Bizplace[] = await tx.getRepository(Bizplace).findByIds(bizplaceIds)
23
+
24
+ if (!bizplaces || bizplaces.length === 0) throw 'Invalid input: None of the provided Bizplaces were found'
25
+
26
+ // Create temporary table for report
27
+ await tx.query(
28
+ `
29
+ create temp table temp_inbound_order_report on commit drop as (
30
+ select
31
+ p.sku as "item",
32
+ p.name as "description",
33
+ count(DISTINCT i.pallet_id) as "pallet",
34
+ coalesce(sum(i.qty - coalesce(i.locked_qty,0)),0) as "qty_available",
35
+ i.pallet_id as "lot_id",
36
+ i.batch_id as "batch_id",
37
+ to_char(grn.created_at+interval '8hours','dd/mm/yyyy') as "receipt_date",
38
+ to_char(i.expiration_date,'dd/mm/yyyy') as "exp_date",
39
+ to_char(i.manufacture_date,'dd/mm/yyyy') as "mfg_date",
40
+ 'Available' as "stock_status",
41
+ i.packing_type as "default_uom",
42
+ extract(day from now()+interval '8 hours'-grn.created_at+interval '8 hours') as "days_in_warehouse",
43
+ extract(day from now()+interval '8 hours'-i.expiration_date+interval '8 hours') as "days_to_expire",
44
+ extract(month from age(now()+interval '8 hours',grn.created_at+interval '8 hours')) as "months_in_warehouse",
45
+ extract(year from age(now()+interval '8 hours',i.expiration_date+interval '8 hours')) * 12 + extract(month from age(now()+interval '8 hours',i.expiration_date+interval '8 hours')) as "months_to_expire"
46
+ from inventories i
47
+ inner join products p on p.id = i.product_id
48
+ left join order_products op on op.id = i.order_product_id::uuid
49
+ left join arrival_notices an on an.id = op.arrival_notice_id
50
+ left join goods_receival_notes grn on an.id = grn.arrival_notice_id
51
+ where i.bizplace_id = ANY($1)
52
+ and i.status = 'STORED' and i.expiration_date is not null
53
+ group by p.sku, p.name, i.pallet_id, i.batch_id,
54
+ grn.created_at, i.expiration_date, i.manufacture_date, i.packing_type
55
+ )
56
+ `,
57
+ [bizplaceIds]
58
+ )
59
+
60
+ // Fetch detailed results
61
+ const result: any = await tx.query(`
62
+ select *
63
+ from temp_inbound_order_report
64
+ `)
65
+
66
+ // Fetch aggregated totals grouped by description
67
+ const totals = await tx.query(`
68
+ select
69
+ description,
70
+ count(pallet) as total_pallet,
71
+ sum(qty_available) as total_qty_available
72
+ from temp_inbound_order_report
73
+ group by description
74
+ order by description
75
+ `)
76
+
77
+ // Map detailed results
78
+ let items = result.map(itm => ({
79
+ productSku: itm.item,
80
+ productName: itm.description,
81
+ pallet: itm.pallet,
82
+ qtyAvailable: itm.qty_available,
83
+ lotId: itm.lot_id,
84
+ batchId: itm.batch_id,
85
+ receiptDate: itm.receipt_date,
86
+ expDate: itm.exp_date,
87
+ mfgDate: itm.mfg_date,
88
+ stockStatus: itm.stock_status,
89
+ defaultUom: itm.default_uom,
90
+ daysInWarehouse: itm.days_in_warehouse,
91
+ daysToExpire: itm.days_to_expire,
92
+ monthsInWarehouse: itm.months_in_warehouse,
93
+ monthsToExpire: itm.months_to_expire
94
+ }))
95
+
96
+ // Map aggregated totals
97
+ let totalItems = totals.map(total => ({
98
+ productName: total.description,
99
+ totalPallet: total.total_pallet,
100
+ totalQtyAvailable: total.total_qty_available
101
+ }))
102
+
103
+ // Insert total counts into the items array
104
+ totalItems.forEach(total => {
105
+ const lastIndex = items.findLastIndex(item => item.productName === total.productName)
106
+
107
+ // If a matching description is found, insert the total row after the last matching item
108
+ if (lastIndex !== -1) {
109
+ items.splice(lastIndex + 1, 0, {
110
+ productSku: items[lastIndex].productSku,
111
+ productName: `${total.productName} Total`,
112
+ pallet: total.totalPallet,
113
+ qtyAvailable: total.totalQtyAvailable,
114
+ lotId: null,
115
+ batchId: null,
116
+ receiptDate: null,
117
+ expDate: null,
118
+ mfgDate: null,
119
+ stockStatus: null,
120
+ defaultUom: null,
121
+ daysInWarehouse: null,
122
+ daysToExpire: null,
123
+ monthsInWarehouse: null,
124
+ monthsToExpire: null
125
+ })
126
+ }
127
+ })
128
+
129
+ // Calculate grand total
130
+ const grandTotalPallet = totalItems.reduce((sum, item) => sum + parseInt(item.totalPallet), 0)
131
+ const grandTotalQtyAvailable = totalItems.reduce((sum, item) => sum + parseInt(item.totalQtyAvailable), 0)
132
+
133
+ // Append the grand total row at the end
134
+ items.push({
135
+ productSku: null,
136
+ productName: 'Grand Total',
137
+ pallet: grandTotalPallet,
138
+ qtyAvailable: grandTotalQtyAvailable,
139
+ lotId: null,
140
+ batchId: null,
141
+ receiptDate: null,
142
+ expDate: null,
143
+ mfgDate: null,
144
+ stockStatus: null,
145
+ defaultUom: null,
146
+ daysInWarehouse: null,
147
+ daysToExpire: null,
148
+ monthsInWarehouse: null,
149
+ monthsToExpire: null
150
+ })
151
+
152
+ // Return the modified items with inserted totals
153
+ return {
154
+ items,
155
+ totals: totalItems
156
+ }
157
+ } catch (error) {
158
+ throw error
159
+ }
160
+ }
161
+ }