@platform-modules/foreign-ministry 1.3.350 → 1.3.355

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/.env CHANGED
@@ -1,5 +1,5 @@
1
- DB_HOST=10.0.1.74
1
+ DB_HOST=169.58.34.60
2
2
  DB_PORT=5432
3
- DB_USER=appuser
4
- DB_PASS=hrms@fm1292
5
- DB_NAME=fm
3
+ DB_USER=postgres_admin_user
4
+ DB_PASS=pg_admin_user_pwd_caa_fa_$%^&OIukhjgcvbn
5
+ DB_NAME=FM
@@ -332,6 +332,7 @@ const EmbassyEvaluationAttachmentModel_1 = require("./models/EmbassyEvaluationAt
332
332
  const SlaRequestModel_1 = require("./models/SlaRequestModel");
333
333
  const ServiceSlaApprovalModel_1 = require("./models/ServiceSlaApprovalModel");
334
334
  const SlaConfigModel_1 = require("./models/SlaConfigModel");
335
+ const ChatbotQnsAnsMappingModel_1 = require("./models/ChatbotQnsAnsMappingModel");
335
336
  exports.AppDataSource = new typeorm_1.DataSource({
336
337
  type: 'postgres',
337
338
  host: process.env.DB_HOST || 'localhost',
@@ -670,5 +671,6 @@ exports.AppDataSource = new typeorm_1.DataSource({
670
671
  SlaRequestModel_1.SlaRequest,
671
672
  ServiceSlaApprovalModel_1.ServiceSlaApproval,
672
673
  SlaConfigModel_1.SlaConfig,
674
+ ChatbotQnsAnsMappingModel_1.ChatbotQnsAnsMapping,
673
675
  ],
674
676
  });
package/dist/index.d.ts CHANGED
@@ -98,6 +98,7 @@ export * from './models/UpdateAttendanceWorkflowModel';
98
98
  export * from './models/SlaRequestModel';
99
99
  export * from './models/ServiceSlaApprovalModel';
100
100
  export * from './models/SlaConfigModel';
101
+ export * from './models/ChatbotQnsAnsMappingModel';
101
102
  export * from './models/GeneralServiceRequestsModel';
102
103
  export * from './models/GeneralServiceApprovalsModel';
103
104
  export * from './models/GeneralServiceWorkFlowModel';
package/dist/index.js CHANGED
@@ -118,6 +118,7 @@ __exportStar(require("./models/UpdateAttendanceWorkflowModel"), exports);
118
118
  __exportStar(require("./models/SlaRequestModel"), exports);
119
119
  __exportStar(require("./models/ServiceSlaApprovalModel"), exports);
120
120
  __exportStar(require("./models/SlaConfigModel"), exports);
121
+ __exportStar(require("./models/ChatbotQnsAnsMappingModel"), exports);
121
122
  __exportStar(require("./models/GeneralServiceRequestsModel"), exports);
122
123
  __exportStar(require("./models/GeneralServiceApprovalsModel"), exports);
123
124
  __exportStar(require("./models/GeneralServiceWorkFlowModel"), exports);
@@ -0,0 +1,8 @@
1
+ import { BaseModel } from "./BaseModel";
2
+ export declare class ChatbotQnsAnsMapping extends BaseModel {
3
+ service_id: number;
4
+ sub_service_id: number;
5
+ question: Record<string, unknown> | unknown[];
6
+ answer: Record<string, unknown> | unknown[];
7
+ constructor();
8
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ChatbotQnsAnsMapping = void 0;
13
+ const typeorm_1 = require("typeorm");
14
+ const BaseModel_1 = require("./BaseModel");
15
+ let ChatbotQnsAnsMapping = class ChatbotQnsAnsMapping extends BaseModel_1.BaseModel {
16
+ constructor() {
17
+ super();
18
+ }
19
+ };
20
+ exports.ChatbotQnsAnsMapping = ChatbotQnsAnsMapping;
21
+ __decorate([
22
+ (0, typeorm_1.Column)({ type: "int", nullable: false }),
23
+ __metadata("design:type", Number)
24
+ ], ChatbotQnsAnsMapping.prototype, "service_id", void 0);
25
+ __decorate([
26
+ (0, typeorm_1.Column)({ type: "int", nullable: false }),
27
+ __metadata("design:type", Number)
28
+ ], ChatbotQnsAnsMapping.prototype, "sub_service_id", void 0);
29
+ __decorate([
30
+ (0, typeorm_1.Column)({ type: "jsonb", nullable: false }),
31
+ __metadata("design:type", Object)
32
+ ], ChatbotQnsAnsMapping.prototype, "question", void 0);
33
+ __decorate([
34
+ (0, typeorm_1.Column)({ type: "jsonb", nullable: false }),
35
+ __metadata("design:type", Object)
36
+ ], ChatbotQnsAnsMapping.prototype, "answer", void 0);
37
+ exports.ChatbotQnsAnsMapping = ChatbotQnsAnsMapping = __decorate([
38
+ (0, typeorm_1.Entity)({ name: "chatbot_qns_ans_mapping" }),
39
+ __metadata("design:paramtypes", [])
40
+ ], ChatbotQnsAnsMapping);
@@ -40,7 +40,14 @@ SELECT
40
40
  sa.updated_at AS updated_at
41
41
  FROM sla_approval sa
42
42
  INNER JOIN sla_requests sr
43
- ON sr.request_id = sa.request_id AND COALESCE(sr.is_deleted, false) = false
43
+ ON sr.id = (
44
+ SELECT MIN(sr2.id)
45
+ FROM sla_requests sr2
46
+ WHERE sr2.request_id = sa.request_id
47
+ AND COALESCE(sr2.is_deleted, false) = false
48
+ AND (sa.service_id IS NULL OR sr2.service_id = sa.service_id)
49
+ AND (sa.sub_service_id IS NULL OR sr2.sub_service_id = sa.sub_service_id)
50
+ )
44
51
  LEFT JOIN fm_services svc
45
52
  ON svc.id = sa.service_id AND COALESCE(svc.is_deleted, false) = false
46
53
  LEFT JOIN fm_sub_services subsvc
@@ -24,6 +24,9 @@ export declare class SlaMyRequestsView {
24
24
  request_id: number;
25
25
  /** Remaining `request_obj` keys after excluding workflow/common duplicates. */
26
26
  request_fields: Record<string, unknown>;
27
+ req_user_department_arabicname: string;
28
+ req_user_section_arabicname: string;
29
+ req_user_arabicname: string;
27
30
  }
28
31
  /** Flatten view row: fixed columns plus each entry in `request_fields`. */
29
32
  export declare function flattenSlaMyRequestsViewRow(row: SlaMyRequestsView): Record<string, unknown>;
@@ -73,8 +73,13 @@ SELECT
73
73
  - 'is_deleted'
74
74
  - 'sla_request'
75
75
  - 'sla_request_id'
76
- ) AS request_fields
76
+ ) AS request_fields,
77
+ TRIM(COALESCE(dept.department_arabic_name, ''))::TEXT AS req_user_department_arabicname,
78
+ TRIM(COALESCE(sec.section_arabic_name, ''))::TEXT AS req_user_section_arabicname,
79
+ TRIM(COALESCE(req_user.employee_arabic_name, ''))::TEXT AS req_user_arabicname
77
80
  FROM sla_requests sr
81
+ LEFT JOIN users req_user
82
+ ON req_user.id = sr.user_id AND COALESCE(req_user.is_deleted, false) = false
78
83
  LEFT JOIN users creator
79
84
  ON sr.created_by ~ '^[0-9]+$'
80
85
  AND creator.id = sr.created_by::integer
@@ -149,6 +154,18 @@ __decorate([
149
154
  (0, typeorm_1.ViewColumn)(),
150
155
  __metadata("design:type", Object)
151
156
  ], SlaMyRequestsView.prototype, "request_fields", void 0);
157
+ __decorate([
158
+ (0, typeorm_1.ViewColumn)(),
159
+ __metadata("design:type", String)
160
+ ], SlaMyRequestsView.prototype, "req_user_department_arabicname", void 0);
161
+ __decorate([
162
+ (0, typeorm_1.ViewColumn)(),
163
+ __metadata("design:type", String)
164
+ ], SlaMyRequestsView.prototype, "req_user_section_arabicname", void 0);
165
+ __decorate([
166
+ (0, typeorm_1.ViewColumn)(),
167
+ __metadata("design:type", String)
168
+ ], SlaMyRequestsView.prototype, "req_user_arabicname", void 0);
152
169
  exports.SlaMyRequestsView = SlaMyRequestsView = __decorate([
153
170
  (0, typeorm_1.ViewEntity)({
154
171
  name: "vw_sla_my_requests",
@@ -157,7 +174,7 @@ exports.SlaMyRequestsView = SlaMyRequestsView = __decorate([
157
174
  ], SlaMyRequestsView);
158
175
  /** Flatten view row: fixed columns plus each entry in `request_fields`. */
159
176
  function flattenSlaMyRequestsViewRow(row) {
160
- const { sla_request_id, user_id, service_id, sub_service_id, created_by, created_at, req_user_department_id, req_user_section_id, service_name, sub_service_name, status, request_id, request_fields, } = row;
177
+ const { sla_request_id, user_id, service_id, sub_service_id, created_by, created_at, req_user_department_id, req_user_section_id, service_name, sub_service_name, status, request_id, request_fields, req_user_department_arabicname, req_user_section_arabicname, req_user_arabicname, } = row;
161
178
  return {
162
179
  sla_request_id,
163
180
  user_id,
@@ -171,6 +188,9 @@ function flattenSlaMyRequestsViewRow(row) {
171
188
  sub_service_name,
172
189
  status,
173
190
  request_id,
191
+ req_user_department_arabicname,
192
+ req_user_section_arabicname,
193
+ req_user_arabicname,
174
194
  ...(request_fields ?? {}),
175
195
  };
176
196
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platform-modules/foreign-ministry",
3
- "version": "1.3.350",
3
+ "version": "1.3.355",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {
@@ -0,0 +1,25 @@
1
+ -- Chatbot Q&A mapping master table (User Service)
2
+ -- PostgreSQL
3
+
4
+ CREATE TABLE IF NOT EXISTS chatbot_qns_ans_mapping (
5
+ id SERIAL PRIMARY KEY,
6
+ service_id INTEGER NOT NULL,
7
+ sub_service_id INTEGER NOT NULL,
8
+ question JSONB NOT NULL,
9
+ answer JSONB NOT NULL,
10
+ created_by VARCHAR NULL,
11
+ created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
12
+ updated_by VARCHAR NULL,
13
+ updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
14
+ is_deleted BOOLEAN DEFAULT FALSE
15
+ );
16
+
17
+ CREATE INDEX IF NOT EXISTS idx_chatbot_qns_ans_mapping_service_sub_service
18
+ ON chatbot_qns_ans_mapping (service_id, sub_service_id)
19
+ WHERE is_deleted = FALSE;
20
+
21
+ CREATE INDEX IF NOT EXISTS idx_chatbot_qns_ans_mapping_question_gin
22
+ ON chatbot_qns_ans_mapping USING GIN (question);
23
+
24
+ CREATE INDEX IF NOT EXISTS idx_chatbot_qns_ans_mapping_answer_gin
25
+ ON chatbot_qns_ans_mapping USING GIN (answer);
@@ -19,13 +19,15 @@ $$;
19
19
  -- Admin list views: served by Reports_Service TypeORM (sla-my-requests-view.query.ts, sla-approvals-view.query.ts)
20
20
 
21
21
  -- ---------------------------------------------------------------------------
22
- -- ADMIN — my requests Excel (optional p_target_user_id)
22
+ -- ADMIN — my requests Excel (optional p_target_user_ids INT[])
23
23
  -- Per sub-service Requests + Approvals sheets (same as user my-requests download)
24
24
  -- ---------------------------------------------------------------------------
25
25
  DROP FUNCTION IF EXISTS sp_sla_admin_my_requests_excel_export(INT, INT[], INT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT);
26
+ DROP FUNCTION IF EXISTS sp_sla_admin_my_requests_excel_export(INT, INT[], INT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT, TEXT);
27
+ DROP FUNCTION IF EXISTS sp_sla_admin_my_requests_excel_export(INT[], INT[], INT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT, TEXT);
26
28
 
27
29
  CREATE OR REPLACE FUNCTION sp_sla_admin_my_requests_excel_export(
28
- p_target_user_id INT DEFAULT NULL,
30
+ p_target_user_ids INT[] DEFAULT NULL,
29
31
  p_service_ids INT[] DEFAULT NULL,
30
32
  p_sub_service_ids INT[] DEFAULT NULL,
31
33
  p_statuses TEXT[] DEFAULT ARRAY['Pending','In Progress','Approved','Rejected'],
@@ -65,10 +67,20 @@ DECLARE
65
67
  v_k TEXT;
66
68
  v_sheet_order INT := 0;
67
69
  v_user_filter TEXT;
70
+ v_user_scope TEXT;
68
71
  BEGIN
72
+ IF p_target_user_ids IS NULL OR cardinality(p_target_user_ids) = 0 THEN
73
+ v_user_scope := 'TRUE';
74
+ ELSE
75
+ v_user_scope := format(
76
+ 'v.user_id = ANY (ARRAY[%s]::int[])',
77
+ array_to_string(p_target_user_ids, ',')
78
+ );
79
+ END IF;
80
+
69
81
  v_user_filter := format(
70
82
  '(%s) AND (%s)',
71
- CASE WHEN p_target_user_id IS NULL THEN 'TRUE' ELSE format('v.user_id = %s', p_target_user_id) END,
83
+ v_user_scope,
72
84
  COALESCE(NULLIF(trim(p_extra_filter_sql), ''), 'TRUE')
73
85
  );
74
86
 
@@ -256,15 +268,21 @@ $$;
256
268
 
257
269
  -- ---------------------------------------------------------------------------
258
270
  -- ADMIN — approvals Excel
259
- -- Per sub-service Requests + Approvals; optional approver_user_id (NULL = all queues)
271
+ -- Per sub-service Requests + Approvals; optional approver user id(s) (NULL/empty = all queues)
260
272
  -- Does not exclude own requests (unlike user approvals download)
261
273
  -- ---------------------------------------------------------------------------
262
274
  DROP FUNCTION IF EXISTS sp_sla_admin_approvals_excel_export(
263
275
  INT, INT[], INT[], TEXT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT
264
276
  );
277
+ DROP FUNCTION IF EXISTS sp_sla_admin_approvals_excel_export(
278
+ INT, INT[], INT[], TEXT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT, TEXT
279
+ );
280
+ DROP FUNCTION IF EXISTS sp_sla_admin_approvals_excel_export(
281
+ INT[], INT[], INT[], TEXT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT, TEXT
282
+ );
265
283
 
266
284
  CREATE OR REPLACE FUNCTION sp_sla_admin_approvals_excel_export(
267
- p_target_approver_user_id INT DEFAULT NULL,
285
+ p_target_approver_user_ids INT[] DEFAULT NULL,
268
286
  p_service_ids INT[] DEFAULT NULL,
269
287
  p_sub_service_ids INT[] DEFAULT NULL,
270
288
  p_request_statuses TEXT[] DEFAULT ARRAY['Pending','In Progress','Approved','Rejected'],
@@ -283,7 +301,7 @@ LANGUAGE plpgsql
283
301
  STABLE
284
302
  AS $$
285
303
  DECLARE
286
- v_exists TEXT := sla_approval_queue_exists_sql_optional(p_target_approver_user_id);
304
+ v_exists TEXT := sla_approval_queue_exists_sql_any(p_target_approver_user_ids);
287
305
  v_own TEXT := COALESCE(NULLIF(trim(p_extra_filter_sql), ''), 'TRUE');
288
306
  BEGIN
289
307
  RETURN QUERY
@@ -96,6 +96,53 @@ AS $$
96
96
  END;
97
97
  $$;
98
98
 
99
+ -- Admin: any of multiple approver user ids (NULL/empty = all queues)
100
+ CREATE OR REPLACE FUNCTION sla_approval_queue_exists_sql_any(p_user_ids INT[])
101
+ RETURNS TEXT
102
+ LANGUAGE plpgsql
103
+ STABLE
104
+ AS $$
105
+ DECLARE
106
+ v_id INT;
107
+ v_parts TEXT[] := ARRAY[]::TEXT[];
108
+ v_match TEXT;
109
+ BEGIN
110
+ IF p_user_ids IS NULL OR cardinality(p_user_ids) = 0 THEN
111
+ RETURN sla_approval_queue_exists_sql_optional(NULL);
112
+ END IF;
113
+
114
+ IF cardinality(p_user_ids) = 1 THEN
115
+ RETURN sla_approval_queue_exists_sql(p_user_ids[1]);
116
+ END IF;
117
+
118
+ FOREACH v_id IN ARRAY p_user_ids LOOP
119
+ IF v_id IS NOT NULL AND v_id > 0 THEN
120
+ v_parts := array_append(v_parts, '(' || sla_approval_matches_user('appr', v_id) || ')');
121
+ END IF;
122
+ END LOOP;
123
+
124
+ IF cardinality(v_parts) = 0 THEN
125
+ RETURN sla_approval_queue_exists_sql_optional(NULL);
126
+ END IF;
127
+
128
+ v_match := array_to_string(v_parts, ' OR ');
129
+
130
+ RETURN format(
131
+ 'EXISTS (
132
+ SELECT 1
133
+ FROM sla_approval appr
134
+ WHERE appr.request_id = sr.request_id
135
+ AND COALESCE(appr.is_deleted, false) = false
136
+ AND (appr.service_id = sr.service_id OR appr.service_id IS NULL)
137
+ AND (appr.sub_service_id = sr.sub_service_id OR appr.sub_service_id IS NULL)
138
+ AND (%s)
139
+ AND (appr.approval_status = ANY($1) OR appr.approval_status IS NULL)
140
+ )',
141
+ v_match
142
+ );
143
+ END;
144
+ $$;
145
+
99
146
  DROP FUNCTION IF EXISTS sp_sla_approvals_workbook_excel_export(
100
147
  TEXT, TEXT, INT[], INT[], TEXT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT
101
148
  );
@@ -70,7 +70,14 @@ FROM sla_approval sa
70
70
 
71
71
  INNER JOIN sla_requests sr
72
72
 
73
- ON sr.request_id = sa.request_id AND COALESCE(sr.is_deleted, false) = false
73
+ ON sr.id = (
74
+ SELECT MIN(sr2.id)
75
+ FROM sla_requests sr2
76
+ WHERE sr2.request_id = sa.request_id
77
+ AND COALESCE(sr2.is_deleted, false) = false
78
+ AND (sa.service_id IS NULL OR sr2.service_id = sa.service_id)
79
+ AND (sa.sub_service_id IS NULL OR sr2.sub_service_id = sa.sub_service_id)
80
+ )
74
81
 
75
82
  LEFT JOIN fm_services svc
76
83
 
@@ -38,8 +38,13 @@ SELECT
38
38
  - 'is_deleted'
39
39
  - 'sla_request'
40
40
  - 'sla_request_id'
41
- ) AS request_fields
41
+ ) AS request_fields,
42
+ TRIM(COALESCE(dept.department_arabic_name, ''))::TEXT AS req_user_department_arabicname,
43
+ TRIM(COALESCE(sec.section_arabic_name, ''))::TEXT AS req_user_section_arabicname,
44
+ TRIM(COALESCE(req_user.employee_arabic_name, ''))::TEXT AS req_user_arabicname
42
45
  FROM sla_requests sr
46
+ LEFT JOIN users req_user
47
+ ON req_user.id = sr.user_id AND COALESCE(req_user.is_deleted, false) = false
43
48
  LEFT JOIN users creator
44
49
  ON sr.created_by ~ '^[0-9]+$'
45
50
  AND creator.id = sr.created_by::integer