@platform-modules/civil-aviation-authority 2.3.265 → 2.3.267
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 +7 -22
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/models/AnnualIncrementRequestEmployeeModel.d.ts +2 -1
- package/dist/models/AnnualIncrementRequestEmployeeModel.js +7 -2
- package/dist/models/AnnualIncrementRequestModel.d.ts +2 -1
- package/dist/models/AnnualIncrementRequestModel.js +7 -2
- package/dist/models/EmployeeSecurityDriveOwnerModel.d.ts +13 -0
- package/dist/models/EmployeeSecurityDriveOwnerModel.js +54 -0
- package/dist/models/ITApprovalSettings.d.ts +7 -0
- package/dist/models/ITApprovalSettings.js +40 -0
- package/dist/models/ITServicesTypesMuscatModel.d.ts +6 -0
- package/dist/models/ITServicesTypesMuscatModel.js +34 -0
- package/dist/models/ITServicesTypesSalalahModel.d.ts +6 -0
- package/dist/models/ITServicesTypesSalalahModel.js +34 -0
- package/dist/models/SlaApprovalsViewModel.js +47 -47
- package/dist/models/SlaMyRequestsViewModel.js +50 -50
- package/dist/models/Workflows.d.ts +9 -0
- package/dist/models/Workflows.js +31 -0
- package/package.json +1 -1
- package/scripts/sync-sla-reports-sql.js +98 -94
- package/sql/README.md +21 -25
- package/sql/sla-reports-sync.manifest.json +7 -7
- package/sql/sla_reports_admin_procedures.sql +283 -283
- package/sql/sla_reports_approvals_workbook.sql +383 -383
- package/sql/sla_reports_procedures.sql +874 -874
- package/sql/vw_sla_approvals.sql +108 -108
- package/sql/vw_sla_my_requests.sql +53 -53
- package/src/data-source.ts +517 -517
- package/src/index.ts +496 -495
- package/src/models/AccessCardRequestModel.ts +135 -135
- package/src/models/AccommodationApprovalModel.ts +8 -8
- package/src/models/AccommodationRequestModel.ts +8 -8
- package/src/models/AirportEntryPermitModel.ts +276 -276
- package/src/models/AnnualIncrementRequestEmployeeModel.ts +6 -1
- package/src/models/AnnualIncrementRequestModel.ts +6 -1
- package/src/models/AnnualTrainingPlanRequestModel.ts +153 -153
- package/src/models/AppealAgainstAdministrativeDecisionRequestModel.ts +23 -23
- package/src/models/CAAServices.ts +33 -33
- package/src/models/CAASubServices.ts +33 -33
- package/src/models/CAIRatingMasterModel.ts +39 -39
- package/src/models/CSRMBusinessImpactRatingMasterModel.ts +25 -25
- package/src/models/CSRMLikelihoodMasterModel.ts +25 -25
- package/src/models/CashAllowanceLeaveRequestModel.ts +11 -11
- package/src/models/DepartmentsModel.ts +25 -25
- package/src/models/DocumentDriveModel.ts +28 -28
- package/src/models/DocumentFolderModel.ts +45 -45
- package/src/models/EmployeeSecurityDriveOwnerModel.ts +32 -0
- package/src/models/HotelApprovalModel.ts +83 -83
- package/src/models/HousingContractCancelApprovalModel.ts +64 -64
- package/src/models/HousingContractCancelChatModel.ts +56 -56
- package/src/models/HousingContractRenewalApprovalModel.ts +64 -64
- package/src/models/HousingContractRenewalChatModel.ts +59 -59
- package/src/models/HrServiceRequestModel.ts +193 -193
- package/src/models/ITRequestAttachmentModel.ts +73 -73
- package/src/models/ITRequestChatModel.ts +74 -74
- package/src/models/ItApprovalsModel.ts +84 -84
- package/src/models/ItWorkflowModel.ts +55 -55
- package/src/models/LegalConsultationApprovalModel.ts +65 -65
- package/src/models/MissionTravelPassportExpiryNotificationConfigModel.ts +36 -36
- package/src/models/NotificationModel.ts +89 -89
- package/src/models/PerformanceCyclePeriodModel.ts +26 -26
- package/src/models/PerformanceGoalMasterModel.ts +27 -27
- package/src/models/PerformanceManagementRequestGoalModel.ts +46 -46
- package/src/models/PerformanceManagementRequestModel.ts +14 -14
- package/src/models/PromotionRequestModel.ts +11 -11
- package/src/models/ResidentialUnitRentalApprovalModel.ts +143 -143
- package/src/models/ResidentialUnitRentalChatModel.ts +56 -56
- package/src/models/ResidentialUnitRentalRequestModel.ts +218 -218
- package/src/models/RespondToEnquiriesRequestModel.ts +31 -31
- package/src/models/ServiceExtensionAfter60ApprovalModel.ts +87 -87
- package/src/models/ServiceSlaApprovalModel.ts +64 -64
- package/src/models/ServicesNotificationConfigModel.ts +55 -55
- package/src/models/SkillsEnhancementRequestModel.ts +17 -17
- package/src/models/SlaApprovalsViewModel.ts +135 -135
- package/src/models/SlaMyRequestsViewModel.ts +170 -170
- package/src/models/SlaRequestModel.ts +65 -65
- package/src/models/StudyLeaveRequestModel.ts +144 -144
- package/src/models/TrainingRequestModel.ts +164 -164
- package/src/models/TrainingRoomBookingRequestModel.ts +142 -142
- package/src/models/TrainingRoomNotificationConfigModel.ts +30 -30
- package/src/models/UserSkillModel.ts +56 -56
- package/src/models/role.ts +34 -34
- package/src/models/user.ts +233 -233
- package/src/sla/sla-table-sync.service.ts +90 -90
- package/dist/models/DocumentMetadataModel.d.ts +0 -45
- package/dist/models/DocumentMetadataModel.js +0 -171
- package/dist/models/DocumentationDepartmentsModel.d.ts +0 -13
- package/dist/models/DocumentationDepartmentsModel.js +0 -53
- package/dist/models/FolderModel.d.ts +0 -16
- package/dist/models/FolderModel.js +0 -85
- package/dist/models/ImportExportMaterialModels.d.ts +0 -92
- package/dist/models/ImportExportMaterialModels.js +0 -307
- package/dist/models/PermissionModel.d.ts +0 -18
- package/dist/models/PermissionModel.js +0 -68
- package/dist/models/SecurityAccessApprovalModel.d.ts +0 -23
- package/dist/models/SecurityAccessApprovalModel.js +0 -82
- package/dist/models/SecurityAccessAttachmentModel.d.ts +0 -12
- package/dist/models/SecurityAccessAttachmentModel.js +0 -56
- package/dist/models/SecurityAccessChatModel.d.ts +0 -12
- package/dist/models/SecurityAccessChatModel.js +0 -56
- package/dist/models/SecurityAccessRequestModel.d.ts +0 -25
- package/dist/models/SecurityAccessRequestModel.js +0 -80
- package/dist/models/SecurityAccessWorkflowModel.d.ts +0 -24
- package/dist/models/SecurityAccessWorkflowModel.js +0 -84
- package/dist/models/ServiceExtensionAfterAge60Models.d.ts +0 -93
- package/dist/models/ServiceExtensionAfterAge60Models.js +0 -312
- package/dist/models/UUIDBaseModel.d.ts +0 -14
- package/dist/models/UUIDBaseModel.js +0 -66
- package/dist/models/WorkingHoursExtensionModels.d.ts +0 -88
- package/dist/models/WorkingHoursExtensionModels.js +0 -295
|
@@ -1,874 +1,874 @@
|
|
|
1
|
-
-- SLA Reports stored procedures (Reports_Service)
|
|
2
|
-
-- Applied via: npm run sync:sla-sql (shared_models/scripts/sync-sla-reports-sql.js)
|
|
3
|
-
-- Or: psql -U <user> -d <database> -f shared_models/sql/sla_reports_procedures.sql
|
|
4
|
-
|
|
5
|
-
-- ---------------------------------------------------------------------------
|
|
6
|
-
-- Helper: approver row matches user (same semantics as User_Service SLA dashboard)
|
|
7
|
-
-- ---------------------------------------------------------------------------
|
|
8
|
-
CREATE OR REPLACE FUNCTION sla_approval_matches_user(p_sa_alias TEXT, p_user_id INT)
|
|
9
|
-
RETURNS TEXT
|
|
10
|
-
LANGUAGE sql
|
|
11
|
-
IMMUTABLE
|
|
12
|
-
AS $$
|
|
13
|
-
SELECT format('(
|
|
14
|
-
%1$s.approver_user_id = %2$s
|
|
15
|
-
OR %1$s.delegate_user_id = %2$s
|
|
16
|
-
OR (
|
|
17
|
-
%1$s.approver_user_id IS NULL
|
|
18
|
-
AND %1$s.delegate_user_id IS NULL
|
|
19
|
-
AND %1$s.approver_role_id IS NOT NULL
|
|
20
|
-
AND %1$s.department_id IS NOT NULL
|
|
21
|
-
AND EXISTS (
|
|
22
|
-
SELECT 1 FROM user_role ur
|
|
23
|
-
WHERE ur.user_id = %2$s
|
|
24
|
-
AND ur.role_id = %1$s.approver_role_id
|
|
25
|
-
AND ur.department_id = %1$s.department_id
|
|
26
|
-
AND (
|
|
27
|
-
%1$s.section_id IS NULL
|
|
28
|
-
OR (%1$s.section_id IS NOT NULL AND (ur.section_id = %1$s.section_id OR ur.section_id IS NULL))
|
|
29
|
-
)
|
|
30
|
-
AND ur.is_deleted = false AND ur.is_active = true
|
|
31
|
-
)
|
|
32
|
-
)
|
|
33
|
-
OR (
|
|
34
|
-
%1$s.approver_user_id IS NULL
|
|
35
|
-
AND %1$s.delegate_user_id IS NULL
|
|
36
|
-
AND %1$s.approver_role_id IS NULL
|
|
37
|
-
AND %1$s.department_id IS NOT NULL
|
|
38
|
-
AND %1$s.section_id IS NOT NULL
|
|
39
|
-
AND EXISTS (
|
|
40
|
-
SELECT 1 FROM users u
|
|
41
|
-
WHERE u.id = %2$s AND COALESCE(u.is_deleted, false) = false
|
|
42
|
-
AND u.department = %1$s.department_id AND u.section = %1$s.section_id
|
|
43
|
-
)
|
|
44
|
-
)
|
|
45
|
-
OR (
|
|
46
|
-
%1$s.approver_user_id IS NULL
|
|
47
|
-
AND %1$s.delegate_user_id IS NULL
|
|
48
|
-
AND %1$s.approver_role_id IS NULL
|
|
49
|
-
AND %1$s.department_id IS NOT NULL
|
|
50
|
-
AND %1$s.section_id IS NULL
|
|
51
|
-
AND EXISTS (
|
|
52
|
-
SELECT 1 FROM users u
|
|
53
|
-
WHERE u.id = %2$s AND COALESCE(u.is_deleted, false) = false
|
|
54
|
-
AND u.department = %1$s.department_id
|
|
55
|
-
)
|
|
56
|
-
)
|
|
57
|
-
)', p_sa_alias, p_user_id);
|
|
58
|
-
$$;
|
|
59
|
-
|
|
60
|
-
-- ---------------------------------------------------------------------------
|
|
61
|
-
-- MY REQUESTS — paginated view
|
|
62
|
-
-- ---------------------------------------------------------------------------
|
|
63
|
-
CREATE OR REPLACE FUNCTION sp_sla_my_requests_view(
|
|
64
|
-
p_user_id INT,
|
|
65
|
-
p_service_ids INT[] DEFAULT NULL,
|
|
66
|
-
p_sub_service_ids INT[] DEFAULT NULL,
|
|
67
|
-
p_statuses TEXT[] DEFAULT ARRAY['Pending','In Progress','Approved','Rejected'],
|
|
68
|
-
p_from_date DATE DEFAULT NULL,
|
|
69
|
-
p_to_date DATE DEFAULT NULL,
|
|
70
|
-
p_search_text TEXT DEFAULT NULL,
|
|
71
|
-
p_page INT DEFAULT 1,
|
|
72
|
-
p_limit INT DEFAULT 50,
|
|
73
|
-
p_sort_by TEXT DEFAULT 'created_at',
|
|
74
|
-
p_sort_order TEXT DEFAULT 'DESC'
|
|
75
|
-
)
|
|
76
|
-
RETURNS TABLE (
|
|
77
|
-
sla_request_id INT,
|
|
78
|
-
request_id INT,
|
|
79
|
-
service_id INT,
|
|
80
|
-
sub_service_id INT,
|
|
81
|
-
service_name TEXT,
|
|
82
|
-
sub_service_name TEXT,
|
|
83
|
-
status TEXT,
|
|
84
|
-
user_id INT,
|
|
85
|
-
user_name TEXT,
|
|
86
|
-
workflow_execution_id TEXT,
|
|
87
|
-
created_at TIMESTAMPTZ,
|
|
88
|
-
updated_at TIMESTAMPTZ,
|
|
89
|
-
total_count BIGINT
|
|
90
|
-
)
|
|
91
|
-
LANGUAGE plpgsql
|
|
92
|
-
STABLE
|
|
93
|
-
AS $$
|
|
94
|
-
DECLARE
|
|
95
|
-
v_offset INT;
|
|
96
|
-
v_limit INT;
|
|
97
|
-
v_sort_col TEXT;
|
|
98
|
-
v_sort_dir TEXT;
|
|
99
|
-
v_sql TEXT;
|
|
100
|
-
BEGIN
|
|
101
|
-
v_limit := LEAST(GREATEST(COALESCE(p_limit, 50), 1), 200);
|
|
102
|
-
v_offset := GREATEST(COALESCE(p_page, 1) - 1, 0) * v_limit;
|
|
103
|
-
|
|
104
|
-
v_sort_col := CASE lower(trim(p_sort_by))
|
|
105
|
-
WHEN 'updated_at' THEN 'sr.updated_at'
|
|
106
|
-
WHEN 'id' THEN 'sr.id'
|
|
107
|
-
WHEN 'status' THEN 'sr.status'
|
|
108
|
-
WHEN 'request_id' THEN 'sr.request_id'
|
|
109
|
-
ELSE 'sr.created_at'
|
|
110
|
-
END;
|
|
111
|
-
|
|
112
|
-
v_sort_dir := CASE WHEN upper(trim(p_sort_order)) = 'ASC' THEN 'ASC' ELSE 'DESC' END;
|
|
113
|
-
|
|
114
|
-
v_sql := format($q$
|
|
115
|
-
SELECT
|
|
116
|
-
sr.id::INT,
|
|
117
|
-
sr.request_id::INT,
|
|
118
|
-
sr.service_id::INT,
|
|
119
|
-
sr.sub_service_id::INT,
|
|
120
|
-
svc.name::TEXT,
|
|
121
|
-
subsvc.sub_service_name::TEXT,
|
|
122
|
-
sr.status::TEXT,
|
|
123
|
-
sr.user_id::INT,
|
|
124
|
-
TRIM(COALESCE(u.employee_name, ''))::TEXT,
|
|
125
|
-
sr.workflow_execution_id::TEXT,
|
|
126
|
-
sr.created_at,
|
|
127
|
-
sr.updated_at,
|
|
128
|
-
COUNT(*) OVER()::BIGINT
|
|
129
|
-
FROM sla_requests sr
|
|
130
|
-
LEFT JOIN caa_services svc ON svc.id = sr.service_id
|
|
131
|
-
LEFT JOIN caa_sub_services subsvc ON subsvc.id = sr.sub_service_id
|
|
132
|
-
LEFT JOIN users u ON u.id = sr.user_id
|
|
133
|
-
WHERE sr.is_deleted = false
|
|
134
|
-
AND sr.user_id = %1$s
|
|
135
|
-
AND sr.status::TEXT = ANY($1)
|
|
136
|
-
AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
|
|
137
|
-
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
|
|
138
|
-
AND ($4 IS NULL OR sr.created_at::date >= $4)
|
|
139
|
-
AND ($5 IS NULL OR sr.created_at::date <= $5)
|
|
140
|
-
AND ($6 IS NULL OR trim($6) = '' OR CAST(sr.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
|
|
141
|
-
ORDER BY %2$s %3$s
|
|
142
|
-
LIMIT %4$s OFFSET %5$s
|
|
143
|
-
$q$, p_user_id, v_sort_col, v_sort_dir, v_limit, v_offset);
|
|
144
|
-
|
|
145
|
-
RETURN QUERY EXECUTE v_sql
|
|
146
|
-
USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text;
|
|
147
|
-
END;
|
|
148
|
-
$$;
|
|
149
|
-
|
|
150
|
-
-- ---------------------------------------------------------------------------
|
|
151
|
-
-- MY REQUESTS — full export (download)
|
|
152
|
-
-- ---------------------------------------------------------------------------
|
|
153
|
-
CREATE OR REPLACE FUNCTION sp_sla_my_requests_download(
|
|
154
|
-
p_user_id INT,
|
|
155
|
-
p_service_ids INT[] DEFAULT NULL,
|
|
156
|
-
p_sub_service_ids INT[] DEFAULT NULL,
|
|
157
|
-
p_statuses TEXT[] DEFAULT ARRAY['Pending','In Progress','Approved','Rejected'],
|
|
158
|
-
p_from_date DATE DEFAULT NULL,
|
|
159
|
-
p_to_date DATE DEFAULT NULL,
|
|
160
|
-
p_search_text TEXT DEFAULT NULL,
|
|
161
|
-
p_sort_by TEXT DEFAULT 'created_at',
|
|
162
|
-
p_sort_order TEXT DEFAULT 'DESC'
|
|
163
|
-
)
|
|
164
|
-
RETURNS TABLE (
|
|
165
|
-
sla_request_id INT,
|
|
166
|
-
request_id INT,
|
|
167
|
-
service_id INT,
|
|
168
|
-
sub_service_id INT,
|
|
169
|
-
service_name TEXT,
|
|
170
|
-
sub_service_name TEXT,
|
|
171
|
-
status TEXT,
|
|
172
|
-
user_id INT,
|
|
173
|
-
user_name TEXT,
|
|
174
|
-
workflow_execution_id TEXT,
|
|
175
|
-
created_at TIMESTAMPTZ,
|
|
176
|
-
updated_at TIMESTAMPTZ
|
|
177
|
-
)
|
|
178
|
-
LANGUAGE plpgsql
|
|
179
|
-
STABLE
|
|
180
|
-
AS $$
|
|
181
|
-
DECLARE
|
|
182
|
-
v_sort_col TEXT;
|
|
183
|
-
v_sort_dir TEXT;
|
|
184
|
-
v_sql TEXT;
|
|
185
|
-
BEGIN
|
|
186
|
-
v_sort_col := CASE lower(trim(p_sort_by))
|
|
187
|
-
WHEN 'updated_at' THEN 'sr.updated_at'
|
|
188
|
-
WHEN 'id' THEN 'sr.id'
|
|
189
|
-
WHEN 'status' THEN 'sr.status'
|
|
190
|
-
WHEN 'request_id' THEN 'sr.request_id'
|
|
191
|
-
ELSE 'sr.created_at'
|
|
192
|
-
END;
|
|
193
|
-
v_sort_dir := CASE WHEN upper(trim(p_sort_order)) = 'ASC' THEN 'ASC' ELSE 'DESC' END;
|
|
194
|
-
|
|
195
|
-
v_sql := format($q$
|
|
196
|
-
SELECT
|
|
197
|
-
sr.id::INT,
|
|
198
|
-
sr.request_id::INT,
|
|
199
|
-
sr.service_id::INT,
|
|
200
|
-
sr.sub_service_id::INT,
|
|
201
|
-
svc.name::TEXT,
|
|
202
|
-
subsvc.sub_service_name::TEXT,
|
|
203
|
-
sr.status::TEXT,
|
|
204
|
-
sr.user_id::INT,
|
|
205
|
-
TRIM(COALESCE(u.employee_name, ''))::TEXT,
|
|
206
|
-
sr.workflow_execution_id::TEXT,
|
|
207
|
-
sr.created_at,
|
|
208
|
-
sr.updated_at
|
|
209
|
-
FROM sla_requests sr
|
|
210
|
-
LEFT JOIN caa_services svc ON svc.id = sr.service_id
|
|
211
|
-
LEFT JOIN caa_sub_services subsvc ON subsvc.id = sr.sub_service_id
|
|
212
|
-
LEFT JOIN users u ON u.id = sr.user_id
|
|
213
|
-
WHERE sr.is_deleted = false
|
|
214
|
-
AND sr.user_id = %1$s
|
|
215
|
-
AND sr.status::TEXT = ANY($1)
|
|
216
|
-
AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
|
|
217
|
-
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
|
|
218
|
-
AND ($4 IS NULL OR sr.created_at::date >= $4)
|
|
219
|
-
AND ($5 IS NULL OR sr.created_at::date <= $5)
|
|
220
|
-
AND ($6 IS NULL OR trim($6) = '' OR CAST(sr.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
|
|
221
|
-
ORDER BY %2$s %3$s
|
|
222
|
-
$q$, p_user_id, v_sort_col, v_sort_dir);
|
|
223
|
-
|
|
224
|
-
RETURN QUERY EXECUTE v_sql
|
|
225
|
-
USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text;
|
|
226
|
-
END;
|
|
227
|
-
$$;
|
|
228
|
-
|
|
229
|
-
-- ---------------------------------------------------------------------------
|
|
230
|
-
-- APPROVALS — paginated view
|
|
231
|
-
-- ---------------------------------------------------------------------------
|
|
232
|
-
DROP FUNCTION IF EXISTS sp_sla_approvals_view(
|
|
233
|
-
INT,
|
|
234
|
-
INT[],
|
|
235
|
-
INT[],
|
|
236
|
-
TEXT[],
|
|
237
|
-
TEXT[],
|
|
238
|
-
DATE,
|
|
239
|
-
DATE,
|
|
240
|
-
TEXT,
|
|
241
|
-
INT,
|
|
242
|
-
INT,
|
|
243
|
-
TEXT,
|
|
244
|
-
TEXT
|
|
245
|
-
);
|
|
246
|
-
CREATE OR REPLACE FUNCTION sp_sla_approvals_view(
|
|
247
|
-
p_approver_user_id INT,
|
|
248
|
-
p_service_ids INT[] DEFAULT NULL,
|
|
249
|
-
p_sub_service_ids INT[] DEFAULT NULL,
|
|
250
|
-
p_request_statuses TEXT[] DEFAULT ARRAY['Pending','In Progress','Approved','Rejected'],
|
|
251
|
-
p_approval_statuses TEXT[] DEFAULT ARRAY['In Progress','Approved','Rejected'],
|
|
252
|
-
p_from_date DATE DEFAULT NULL,
|
|
253
|
-
p_to_date DATE DEFAULT NULL,
|
|
254
|
-
p_search_text TEXT DEFAULT NULL,
|
|
255
|
-
p_page INT DEFAULT 1,
|
|
256
|
-
p_limit INT DEFAULT 50,
|
|
257
|
-
p_sort_by TEXT DEFAULT 'created_at',
|
|
258
|
-
p_sort_order TEXT DEFAULT 'DESC'
|
|
259
|
-
)
|
|
260
|
-
RETURNS TABLE (
|
|
261
|
-
sla_approval_id INT,
|
|
262
|
-
source_approval_id INT,
|
|
263
|
-
request_id INT,
|
|
264
|
-
service_id INT,
|
|
265
|
-
sub_service_id INT,
|
|
266
|
-
service_name TEXT,
|
|
267
|
-
sub_service_name TEXT,
|
|
268
|
-
department_id INT,
|
|
269
|
-
department_name TEXT,
|
|
270
|
-
section_id INT,
|
|
271
|
-
section_name TEXT,
|
|
272
|
-
role_id INT,
|
|
273
|
-
role_name TEXT,
|
|
274
|
-
approval_status TEXT,
|
|
275
|
-
request_status TEXT,
|
|
276
|
-
level INT,
|
|
277
|
-
approver_user_id INT,
|
|
278
|
-
approver_user_name TEXT,
|
|
279
|
-
delegate_user_id INT,
|
|
280
|
-
delegate_user_name TEXT,
|
|
281
|
-
approved_by INT,
|
|
282
|
-
approved_by_name TEXT,
|
|
283
|
-
comment TEXT,
|
|
284
|
-
created_at TIMESTAMPTZ,
|
|
285
|
-
updated_at TIMESTAMPTZ,
|
|
286
|
-
total_count BIGINT
|
|
287
|
-
)
|
|
288
|
-
LANGUAGE plpgsql
|
|
289
|
-
STABLE
|
|
290
|
-
AS $$
|
|
291
|
-
DECLARE
|
|
292
|
-
v_offset INT;
|
|
293
|
-
v_limit INT;
|
|
294
|
-
v_sort_col TEXT;
|
|
295
|
-
v_sort_dir TEXT;
|
|
296
|
-
v_match TEXT;
|
|
297
|
-
v_sql TEXT;
|
|
298
|
-
BEGIN
|
|
299
|
-
v_limit := LEAST(GREATEST(COALESCE(p_limit, 50), 1), 200);
|
|
300
|
-
v_offset := GREATEST(COALESCE(p_page, 1) - 1, 0) * v_limit;
|
|
301
|
-
v_match := sla_approval_matches_user('sa', p_approver_user_id);
|
|
302
|
-
|
|
303
|
-
v_sort_col := CASE lower(trim(p_sort_by))
|
|
304
|
-
WHEN 'updated_at' THEN 'sa.updated_at'
|
|
305
|
-
WHEN 'id' THEN 'sa.id'
|
|
306
|
-
WHEN 'approval_status' THEN 'sa.approval_status'
|
|
307
|
-
WHEN 'level' THEN 'sa.level'
|
|
308
|
-
WHEN 'request_id' THEN 'sa.request_id'
|
|
309
|
-
ELSE 'sa.created_at'
|
|
310
|
-
END;
|
|
311
|
-
v_sort_dir := CASE WHEN upper(trim(p_sort_order)) = 'ASC' THEN 'ASC' ELSE 'DESC' END;
|
|
312
|
-
|
|
313
|
-
v_sql := format($q$
|
|
314
|
-
SELECT
|
|
315
|
-
sa.id::INT,
|
|
316
|
-
sa.source_approval_id::INT,
|
|
317
|
-
sa.request_id::INT,
|
|
318
|
-
sa.service_id::INT,
|
|
319
|
-
sa.sub_service_id::INT,
|
|
320
|
-
svc.name::TEXT,
|
|
321
|
-
subsvc.sub_service_name::TEXT,
|
|
322
|
-
sa.department_id::INT,
|
|
323
|
-
TRIM(COALESCE(dept.department_name, ''))::TEXT,
|
|
324
|
-
sa.section_id::INT,
|
|
325
|
-
TRIM(COALESCE(sec.section_name, ''))::TEXT,
|
|
326
|
-
sa.approver_role_id::INT,
|
|
327
|
-
TRIM(COALESCE(r.name, ''))::TEXT,
|
|
328
|
-
sa.approval_status::TEXT,
|
|
329
|
-
sr.status::TEXT,
|
|
330
|
-
sa.level::INT,
|
|
331
|
-
sa.approver_user_id::INT,
|
|
332
|
-
TRIM(COALESCE(au.employee_name, ''))::TEXT,
|
|
333
|
-
sa.delegate_user_id::INT,
|
|
334
|
-
TRIM(COALESCE(du.employee_name, ''))::TEXT,
|
|
335
|
-
sa.approved_by::INT,
|
|
336
|
-
TRIM(COALESCE(ab.employee_name, ''))::TEXT,
|
|
337
|
-
sa.comment::TEXT,
|
|
338
|
-
sa.created_at,
|
|
339
|
-
sa.updated_at,
|
|
340
|
-
COUNT(*) OVER()::BIGINT
|
|
341
|
-
FROM sla_approval sa
|
|
342
|
-
INNER JOIN sla_requests sr
|
|
343
|
-
ON sr.request_id = sa.request_id AND sr.is_deleted = false
|
|
344
|
-
LEFT JOIN caa_services svc ON svc.id = sa.service_id
|
|
345
|
-
LEFT JOIN caa_sub_services subsvc ON subsvc.id = sa.sub_service_id
|
|
346
|
-
LEFT JOIN departments dept ON dept.id = sa.department_id AND COALESCE(dept.is_deleted, false) = false
|
|
347
|
-
LEFT JOIN sections sec ON sec.id = sa.section_id AND COALESCE(sec.is_deleted, false) = false
|
|
348
|
-
LEFT JOIN role r ON r.id = sa.approver_role_id AND COALESCE(r.is_deleted, false) = false
|
|
349
|
-
LEFT JOIN users au ON au.id = sa.approver_user_id
|
|
350
|
-
LEFT JOIN users du ON du.id = sa.delegate_user_id
|
|
351
|
-
LEFT JOIN users ab ON ab.id = sa.approved_by
|
|
352
|
-
WHERE sa.is_deleted = false
|
|
353
|
-
AND sr.user_id != %1$s
|
|
354
|
-
AND (sa.service_id = sr.service_id OR sa.service_id IS NULL)
|
|
355
|
-
AND (sa.sub_service_id = sr.sub_service_id OR sa.sub_service_id IS NULL)
|
|
356
|
-
AND %2$s
|
|
357
|
-
AND (sa.approval_status = ANY($1) OR sa.approval_status IS NULL)
|
|
358
|
-
AND sr.status::TEXT = ANY($2)
|
|
359
|
-
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.service_id = ANY($3))
|
|
360
|
-
AND ($4 IS NULL OR cardinality($4) = 0 OR sr.sub_service_id = ANY($4))
|
|
361
|
-
AND ($5 IS NULL OR sr.created_at::date >= $5)
|
|
362
|
-
AND ($6 IS NULL OR sr.created_at::date <= $6)
|
|
363
|
-
AND ($7 IS NULL OR trim($7) = '' OR CAST(sr.request_id AS TEXT) ILIKE '%%' || trim($7) || '%%')
|
|
364
|
-
ORDER BY %3$s %4$s, sa.id DESC
|
|
365
|
-
LIMIT %5$s OFFSET %6$s
|
|
366
|
-
$q$, p_approver_user_id, v_match, v_sort_col, v_sort_dir, v_limit, v_offset);
|
|
367
|
-
|
|
368
|
-
RETURN QUERY EXECUTE v_sql
|
|
369
|
-
USING p_approval_statuses, p_request_statuses, p_service_ids, p_sub_service_ids,
|
|
370
|
-
p_from_date, p_to_date, p_search_text;
|
|
371
|
-
END;
|
|
372
|
-
$$;
|
|
373
|
-
|
|
374
|
-
-- ---------------------------------------------------------------------------
|
|
375
|
-
-- APPROVALS — full export (download)
|
|
376
|
-
-- ---------------------------------------------------------------------------
|
|
377
|
-
CREATE OR REPLACE FUNCTION sp_sla_approvals_download(
|
|
378
|
-
p_approver_user_id INT,
|
|
379
|
-
p_service_ids INT[] DEFAULT NULL,
|
|
380
|
-
p_sub_service_ids INT[] DEFAULT NULL,
|
|
381
|
-
p_request_statuses TEXT[] DEFAULT ARRAY['Pending','In Progress','Approved','Rejected'],
|
|
382
|
-
p_approval_statuses TEXT[] DEFAULT ARRAY['In Progress','Approved','Rejected'],
|
|
383
|
-
p_from_date DATE DEFAULT NULL,
|
|
384
|
-
p_to_date DATE DEFAULT NULL,
|
|
385
|
-
p_search_text TEXT DEFAULT NULL,
|
|
386
|
-
p_sort_by TEXT DEFAULT 'created_at',
|
|
387
|
-
p_sort_order TEXT DEFAULT 'DESC'
|
|
388
|
-
)
|
|
389
|
-
RETURNS TABLE (
|
|
390
|
-
sla_approval_id INT,
|
|
391
|
-
source_approval_id INT,
|
|
392
|
-
request_id INT,
|
|
393
|
-
service_id INT,
|
|
394
|
-
sub_service_id INT,
|
|
395
|
-
service_name TEXT,
|
|
396
|
-
sub_service_name TEXT,
|
|
397
|
-
approval_status TEXT,
|
|
398
|
-
request_status TEXT,
|
|
399
|
-
level INT,
|
|
400
|
-
approver_user_id INT,
|
|
401
|
-
approver_user_name TEXT,
|
|
402
|
-
delegate_user_id INT,
|
|
403
|
-
delegate_user_name TEXT,
|
|
404
|
-
approved_by INT,
|
|
405
|
-
approved_by_name TEXT,
|
|
406
|
-
comment TEXT,
|
|
407
|
-
created_at TIMESTAMPTZ,
|
|
408
|
-
updated_at TIMESTAMPTZ
|
|
409
|
-
)
|
|
410
|
-
LANGUAGE plpgsql
|
|
411
|
-
STABLE
|
|
412
|
-
AS $$
|
|
413
|
-
DECLARE
|
|
414
|
-
v_sort_col TEXT;
|
|
415
|
-
v_sort_dir TEXT;
|
|
416
|
-
v_match TEXT;
|
|
417
|
-
v_sql TEXT;
|
|
418
|
-
BEGIN
|
|
419
|
-
v_match := sla_approval_matches_user('sa', p_approver_user_id);
|
|
420
|
-
|
|
421
|
-
v_sort_col := CASE lower(trim(p_sort_by))
|
|
422
|
-
WHEN 'updated_at' THEN 'sa.updated_at'
|
|
423
|
-
WHEN 'id' THEN 'sa.id'
|
|
424
|
-
WHEN 'approval_status' THEN 'sa.approval_status'
|
|
425
|
-
WHEN 'level' THEN 'sa.level'
|
|
426
|
-
WHEN 'request_id' THEN 'sa.request_id'
|
|
427
|
-
ELSE 'sa.created_at'
|
|
428
|
-
END;
|
|
429
|
-
v_sort_dir := CASE WHEN upper(trim(p_sort_order)) = 'ASC' THEN 'ASC' ELSE 'DESC' END;
|
|
430
|
-
|
|
431
|
-
v_sql := format($q$
|
|
432
|
-
SELECT
|
|
433
|
-
sa.id::INT,
|
|
434
|
-
sa.source_approval_id::INT,
|
|
435
|
-
sa.request_id::INT,
|
|
436
|
-
sa.service_id::INT,
|
|
437
|
-
sa.sub_service_id::INT,
|
|
438
|
-
svc.name::TEXT,
|
|
439
|
-
subsvc.sub_service_name::TEXT,
|
|
440
|
-
sa.approval_status::TEXT,
|
|
441
|
-
sr.status::TEXT,
|
|
442
|
-
sa.level::INT,
|
|
443
|
-
sa.approver_user_id::INT,
|
|
444
|
-
TRIM(COALESCE(au.employee_name, ''))::TEXT,
|
|
445
|
-
sa.delegate_user_id::INT,
|
|
446
|
-
TRIM(COALESCE(du.employee_name, ''))::TEXT,
|
|
447
|
-
sa.approved_by::INT,
|
|
448
|
-
TRIM(COALESCE(ab.employee_name, ''))::TEXT,
|
|
449
|
-
sa.comment::TEXT,
|
|
450
|
-
sa.created_at,
|
|
451
|
-
sa.updated_at
|
|
452
|
-
FROM sla_approval sa
|
|
453
|
-
INNER JOIN sla_requests sr
|
|
454
|
-
ON sr.request_id = sa.request_id AND sr.is_deleted = false
|
|
455
|
-
LEFT JOIN caa_services svc ON svc.id = sa.service_id
|
|
456
|
-
LEFT JOIN caa_sub_services subsvc ON subsvc.id = sa.sub_service_id
|
|
457
|
-
LEFT JOIN users au ON au.id = sa.approver_user_id
|
|
458
|
-
LEFT JOIN users du ON du.id = sa.delegate_user_id
|
|
459
|
-
LEFT JOIN users ab ON ab.id = sa.approved_by
|
|
460
|
-
WHERE sa.is_deleted = false
|
|
461
|
-
AND sr.user_id != %1$s
|
|
462
|
-
AND (sa.service_id = sr.service_id OR sa.service_id IS NULL)
|
|
463
|
-
AND (sa.sub_service_id = sr.sub_service_id OR sa.sub_service_id IS NULL)
|
|
464
|
-
AND %2$s
|
|
465
|
-
AND (sa.approval_status = ANY($1) OR sa.approval_status IS NULL)
|
|
466
|
-
AND sr.status::TEXT = ANY($2)
|
|
467
|
-
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.service_id = ANY($3))
|
|
468
|
-
AND ($4 IS NULL OR cardinality($4) = 0 OR sr.sub_service_id = ANY($4))
|
|
469
|
-
AND ($5 IS NULL OR sr.created_at::date >= $5)
|
|
470
|
-
AND ($6 IS NULL OR sr.created_at::date <= $6)
|
|
471
|
-
AND ($7 IS NULL OR trim($7) = '' OR CAST(sr.request_id AS TEXT) ILIKE '%%' || trim($7) || '%%')
|
|
472
|
-
ORDER BY %3$s %4$s, sa.id DESC
|
|
473
|
-
$q$, p_approver_user_id, v_match, v_sort_col, v_sort_dir);
|
|
474
|
-
|
|
475
|
-
RETURN QUERY EXECUTE v_sql
|
|
476
|
-
USING p_approval_statuses, p_request_statuses, p_service_ids, p_sub_service_ids,
|
|
477
|
-
p_from_date, p_to_date, p_search_text;
|
|
478
|
-
END;
|
|
479
|
-
$$;
|
|
480
|
-
|
|
481
|
-
-- ---------------------------------------------------------------------------
|
|
482
|
-
-- Helpers: Excel export (my requests)
|
|
483
|
-
-- ---------------------------------------------------------------------------
|
|
484
|
-
CREATE OR REPLACE FUNCTION sla_excel_header_label(p_key TEXT)
|
|
485
|
-
RETURNS TEXT
|
|
486
|
-
LANGUAGE sql
|
|
487
|
-
IMMUTABLE
|
|
488
|
-
AS $$
|
|
489
|
-
SELECT trim(
|
|
490
|
-
initcap(
|
|
491
|
-
regexp_replace(
|
|
492
|
-
regexp_replace(COALESCE(p_key, ''), '[_-]+', ' ', 'g'),
|
|
493
|
-
'\s+',
|
|
494
|
-
' ',
|
|
495
|
-
'g'
|
|
496
|
-
)
|
|
497
|
-
)
|
|
498
|
-
);
|
|
499
|
-
$$;
|
|
500
|
-
|
|
501
|
-
CREATE OR REPLACE FUNCTION sla_request_field_cell(p_fields JSONB, p_key TEXT)
|
|
502
|
-
RETURNS TEXT
|
|
503
|
-
LANGUAGE sql
|
|
504
|
-
IMMUTABLE
|
|
505
|
-
AS $$
|
|
506
|
-
SELECT CASE
|
|
507
|
-
WHEN p_fields IS NULL OR NOT (p_fields ? p_key) THEN NULL
|
|
508
|
-
WHEN jsonb_typeof(p_fields -> p_key) IN ('object', 'array') THEN (p_fields -> p_key)::TEXT
|
|
509
|
-
ELSE p_fields ->> p_key
|
|
510
|
-
END;
|
|
511
|
-
$$;
|
|
512
|
-
|
|
513
|
-
CREATE OR REPLACE FUNCTION sla_excel_sheet_name(p_sub_service_name TEXT)
|
|
514
|
-
RETURNS TEXT
|
|
515
|
-
LANGUAGE sql
|
|
516
|
-
IMMUTABLE
|
|
517
|
-
AS $$
|
|
518
|
-
SELECT LEFT(
|
|
519
|
-
CASE
|
|
520
|
-
WHEN COALESCE(trim(p_sub_service_name), '') = '' THEN 'Requests'
|
|
521
|
-
ELSE trim(p_sub_service_name) || ' Requests'
|
|
522
|
-
END,
|
|
523
|
-
31
|
|
524
|
-
);
|
|
525
|
-
$$;
|
|
526
|
-
|
|
527
|
-
DROP FUNCTION IF EXISTS sla_excel_approvals_sheet_name(TEXT);
|
|
528
|
-
|
|
529
|
-
CREATE OR REPLACE FUNCTION sla_excel_approvals_sheet_name(p_sub_service_name TEXT)
|
|
530
|
-
RETURNS TEXT
|
|
531
|
-
LANGUAGE sql
|
|
532
|
-
IMMUTABLE
|
|
533
|
-
AS $$
|
|
534
|
-
SELECT LEFT(
|
|
535
|
-
CASE
|
|
536
|
-
WHEN COALESCE(trim(p_sub_service_name), '') = '' THEN 'Approvals'
|
|
537
|
-
ELSE trim(p_sub_service_name) || ' Approvals'
|
|
538
|
-
END,
|
|
539
|
-
31
|
|
540
|
-
);
|
|
541
|
-
$$;
|
|
542
|
-
|
|
543
|
-
-- ---------------------------------------------------------------------------
|
|
544
|
-
-- MY REQUESTS — Approvals sheet (vw_sla_approvals joined to filtered my-requests)
|
|
545
|
-
-- p_user_scope_sql: e.g. 'v.user_id = 5' or 'TRUE' (admin all users)
|
|
546
|
-
-- ---------------------------------------------------------------------------
|
|
547
|
-
DROP FUNCTION IF EXISTS sla_my_requests_approvals_excel_sheet(TEXT, TEXT[], INT[], INT[], DATE, DATE, TEXT, INT);
|
|
548
|
-
|
|
549
|
-
CREATE OR REPLACE FUNCTION sla_my_requests_approvals_excel_sheet(
|
|
550
|
-
p_user_scope_sql TEXT,
|
|
551
|
-
p_statuses TEXT[],
|
|
552
|
-
p_service_ids INT[],
|
|
553
|
-
p_sub_service_ids INT[],
|
|
554
|
-
p_from_date DATE,
|
|
555
|
-
p_to_date DATE,
|
|
556
|
-
p_search_text TEXT,
|
|
557
|
-
p_start_sheet_order INT
|
|
558
|
-
)
|
|
559
|
-
RETURNS TABLE (
|
|
560
|
-
sheet_order INT,
|
|
561
|
-
sub_service_id INT,
|
|
562
|
-
sub_service_name TEXT,
|
|
563
|
-
sheet_name TEXT,
|
|
564
|
-
headers JSONB,
|
|
565
|
-
rows JSONB
|
|
566
|
-
)
|
|
567
|
-
LANGUAGE plpgsql
|
|
568
|
-
STABLE
|
|
569
|
-
AS $$
|
|
570
|
-
DECLARE
|
|
571
|
-
v_sub RECORD;
|
|
572
|
-
v_approval RECORD;
|
|
573
|
-
v_sheet_order INT;
|
|
574
|
-
v_sheet_label TEXT;
|
|
575
|
-
v_headers_labels TEXT[] := ARRAY[
|
|
576
|
-
'Request ID', 'Service ID', 'Service Name', 'Sub Service ID', 'Sub Service Name',
|
|
577
|
-
'SLA Approval ID', 'Source Approval ID', 'Level', 'Approval Status', 'Request Status',
|
|
578
|
-
'Approval Role ID', 'Approval Role Name', 'Approval Department ID', 'Approval Department Name',
|
|
579
|
-
'Approval Section ID', 'Approval Section Name',
|
|
580
|
-
'Approver User ID', 'Approver User Name', 'Delegate User ID', 'Delegate User Name',
|
|
581
|
-
'Approved By ID', 'Approved By Name', 'Comment', 'Created At', 'Updated At'
|
|
582
|
-
];
|
|
583
|
-
v_cells TEXT[];
|
|
584
|
-
v_all_rows JSONB;
|
|
585
|
-
BEGIN
|
|
586
|
-
v_sheet_order := p_start_sheet_order;
|
|
587
|
-
|
|
588
|
-
FOR v_sub IN
|
|
589
|
-
EXECUTE format($q$
|
|
590
|
-
SELECT DISTINCT
|
|
591
|
-
COALESCE(sr.sub_service_id, 0) AS sub_service_id_num,
|
|
592
|
-
COALESCE(NULLIF(trim(subsvc.sub_service_name), ''), NULLIF(trim(v.sub_service_name), ''), 'Uncategorized') AS sub_service_name
|
|
593
|
-
FROM vw_sla_my_requests v
|
|
594
|
-
INNER JOIN sla_requests sr ON sr.id = v.sla_request_id AND COALESCE(sr.is_deleted, false) = false
|
|
595
|
-
LEFT JOIN caa_sub_services subsvc ON subsvc.id = sr.sub_service_id
|
|
596
|
-
WHERE %s
|
|
597
|
-
AND v.status = ANY($1)
|
|
598
|
-
AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
|
|
599
|
-
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
|
|
600
|
-
AND ($4 IS NULL OR v.created_at::date >= $4)
|
|
601
|
-
AND ($5 IS NULL OR v.created_at::date <= $5)
|
|
602
|
-
AND ($6 IS NULL OR trim($6) = '' OR CAST(v.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
|
|
603
|
-
ORDER BY sub_service_name ASC
|
|
604
|
-
$q$, p_user_scope_sql)
|
|
605
|
-
USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text
|
|
606
|
-
LOOP
|
|
607
|
-
v_sheet_order := v_sheet_order + 1;
|
|
608
|
-
v_sheet_label := sla_excel_approvals_sheet_name(v_sub.sub_service_name);
|
|
609
|
-
v_all_rows := '[]'::jsonb;
|
|
610
|
-
|
|
611
|
-
FOR v_approval IN
|
|
612
|
-
EXECUTE format($q$
|
|
613
|
-
SELECT
|
|
614
|
-
va.request_id,
|
|
615
|
-
sr.service_id,
|
|
616
|
-
va.service_name,
|
|
617
|
-
sr.sub_service_id,
|
|
618
|
-
va.sub_service_name,
|
|
619
|
-
va.sla_approval_id,
|
|
620
|
-
va.source_approval_id,
|
|
621
|
-
va.level,
|
|
622
|
-
va.approval_status,
|
|
623
|
-
va.request_status,
|
|
624
|
-
va.approval_role_id,
|
|
625
|
-
va.approval_role_name,
|
|
626
|
-
va.approval_department_id,
|
|
627
|
-
va.approval_department_name,
|
|
628
|
-
va.approval_section_id,
|
|
629
|
-
va.approval_section_name,
|
|
630
|
-
va.approver_user_id,
|
|
631
|
-
va.approver_user_name,
|
|
632
|
-
va.delegate_user_id,
|
|
633
|
-
va.delegate_user_name,
|
|
634
|
-
va.approved_by,
|
|
635
|
-
va.approved_by_name,
|
|
636
|
-
va.comment,
|
|
637
|
-
va.created_at,
|
|
638
|
-
va.updated_at
|
|
639
|
-
FROM vw_sla_my_requests v
|
|
640
|
-
INNER JOIN sla_requests sr
|
|
641
|
-
ON sr.id = v.sla_request_id AND COALESCE(sr.is_deleted, false) = false
|
|
642
|
-
INNER JOIN vw_sla_approvals va
|
|
643
|
-
ON va.request_id = v.request_id
|
|
644
|
-
AND (va.service_id = sr.service_id OR va.service_id IS NULL)
|
|
645
|
-
AND (va.sub_service_id = sr.sub_service_id OR va.sub_service_id IS NULL)
|
|
646
|
-
WHERE %s
|
|
647
|
-
AND v.status = ANY($1)
|
|
648
|
-
AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
|
|
649
|
-
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
|
|
650
|
-
AND ($4 IS NULL OR v.created_at::date >= $4)
|
|
651
|
-
AND ($5 IS NULL OR v.created_at::date <= $5)
|
|
652
|
-
AND ($6 IS NULL OR trim($6) = '' OR CAST(v.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
|
|
653
|
-
AND COALESCE(sr.sub_service_id, 0) = %2$s
|
|
654
|
-
ORDER BY va.request_id ASC, va.level ASC NULLS LAST, va.sla_approval_id ASC
|
|
655
|
-
$q$, p_user_scope_sql, v_sub.sub_service_id_num)
|
|
656
|
-
USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text
|
|
657
|
-
LOOP
|
|
658
|
-
v_cells := ARRAY[
|
|
659
|
-
COALESCE(v_approval.request_id::TEXT, ''),
|
|
660
|
-
COALESCE(v_approval.service_id::TEXT, ''),
|
|
661
|
-
COALESCE(v_approval.service_name, ''),
|
|
662
|
-
COALESCE(v_approval.sub_service_id::TEXT, ''),
|
|
663
|
-
COALESCE(v_approval.sub_service_name, ''),
|
|
664
|
-
COALESCE(v_approval.sla_approval_id::TEXT, ''),
|
|
665
|
-
COALESCE(v_approval.source_approval_id::TEXT, ''),
|
|
666
|
-
COALESCE(v_approval.level::TEXT, ''),
|
|
667
|
-
COALESCE(v_approval.approval_status, ''),
|
|
668
|
-
COALESCE(v_approval.request_status, ''),
|
|
669
|
-
COALESCE(v_approval.approval_role_id::TEXT, ''),
|
|
670
|
-
COALESCE(v_approval.approval_role_name, ''),
|
|
671
|
-
COALESCE(v_approval.approval_department_id::TEXT, ''),
|
|
672
|
-
COALESCE(v_approval.approval_department_name, ''),
|
|
673
|
-
COALESCE(v_approval.approval_section_id::TEXT, ''),
|
|
674
|
-
COALESCE(v_approval.approval_section_name, ''),
|
|
675
|
-
COALESCE(v_approval.approver_user_id::TEXT, ''),
|
|
676
|
-
COALESCE(v_approval.approver_user_name, ''),
|
|
677
|
-
COALESCE(v_approval.delegate_user_id::TEXT, ''),
|
|
678
|
-
COALESCE(v_approval.delegate_user_name, ''),
|
|
679
|
-
COALESCE(v_approval.approved_by::TEXT, ''),
|
|
680
|
-
COALESCE(v_approval.approved_by_name, ''),
|
|
681
|
-
COALESCE(v_approval.comment, ''),
|
|
682
|
-
COALESCE(to_char(v_approval.created_at AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS'), ''),
|
|
683
|
-
COALESCE(to_char(v_approval.updated_at AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS'), '')
|
|
684
|
-
];
|
|
685
|
-
v_all_rows := v_all_rows || jsonb_build_array(to_jsonb(v_cells));
|
|
686
|
-
END LOOP;
|
|
687
|
-
|
|
688
|
-
sheet_order := v_sheet_order;
|
|
689
|
-
sub_service_id := NULLIF(v_sub.sub_service_id_num, 0);
|
|
690
|
-
sub_service_name := v_sub.sub_service_name;
|
|
691
|
-
sheet_name := v_sheet_label;
|
|
692
|
-
headers := to_jsonb(v_headers_labels);
|
|
693
|
-
rows := v_all_rows;
|
|
694
|
-
RETURN NEXT;
|
|
695
|
-
END LOOP;
|
|
696
|
-
END;
|
|
697
|
-
$$;
|
|
698
|
-
|
|
699
|
-
-- ---------------------------------------------------------------------------
|
|
700
|
-
-- MY REQUESTS — Excel workbook payload (one result row per sub-service sheet)
|
|
701
|
-
-- Uses vw_sla_my_requests; flattening and dynamic columns are built in the database.
|
|
702
|
-
-- ---------------------------------------------------------------------------
|
|
703
|
-
CREATE OR REPLACE FUNCTION sp_sla_my_requests_excel_export(
|
|
704
|
-
p_user_id INT,
|
|
705
|
-
p_service_ids INT[] DEFAULT NULL,
|
|
706
|
-
p_sub_service_ids INT[] DEFAULT NULL,
|
|
707
|
-
p_statuses TEXT[] DEFAULT ARRAY['Pending','In Progress','Approved','Rejected'],
|
|
708
|
-
p_from_date DATE DEFAULT NULL,
|
|
709
|
-
p_to_date DATE DEFAULT NULL,
|
|
710
|
-
p_search_text TEXT DEFAULT NULL,
|
|
711
|
-
p_sort_by TEXT DEFAULT 'created_at',
|
|
712
|
-
p_sort_order TEXT DEFAULT 'DESC'
|
|
713
|
-
)
|
|
714
|
-
RETURNS TABLE (
|
|
715
|
-
sheet_order INT,
|
|
716
|
-
sub_service_id INT,
|
|
717
|
-
sub_service_name TEXT,
|
|
718
|
-
sheet_name TEXT,
|
|
719
|
-
headers JSONB,
|
|
720
|
-
rows JSONB
|
|
721
|
-
)
|
|
722
|
-
LANGUAGE plpgsql
|
|
723
|
-
STABLE
|
|
724
|
-
AS $$
|
|
725
|
-
DECLARE
|
|
726
|
-
v_sort_col TEXT;
|
|
727
|
-
v_sort_dir TEXT;
|
|
728
|
-
v_sub RECORD;
|
|
729
|
-
v_row RECORD;
|
|
730
|
-
v_dyn_keys TEXT[];
|
|
731
|
-
v_dyn_labels TEXT[];
|
|
732
|
-
v_common_labels TEXT[] := ARRAY[
|
|
733
|
-
'SLA Request ID', 'Request ID', 'User', 'Status', 'Created At',
|
|
734
|
-
'Created By', 'Department', 'Section'
|
|
735
|
-
];
|
|
736
|
-
v_headers_labels TEXT[];
|
|
737
|
-
v_headers_json JSONB;
|
|
738
|
-
v_cells TEXT[];
|
|
739
|
-
v_all_rows JSONB;
|
|
740
|
-
v_k TEXT;
|
|
741
|
-
v_sheet_order INT := 0;
|
|
742
|
-
BEGIN
|
|
743
|
-
v_sort_col := CASE lower(trim(p_sort_by))
|
|
744
|
-
WHEN 'updated_at' THEN 'v.created_at'
|
|
745
|
-
WHEN 'id' THEN 'v.sla_request_id'
|
|
746
|
-
WHEN 'status' THEN 'v.status'
|
|
747
|
-
WHEN 'request_id' THEN 'v.request_id'
|
|
748
|
-
ELSE 'v.created_at'
|
|
749
|
-
END;
|
|
750
|
-
v_sort_dir := CASE WHEN upper(trim(p_sort_order)) = 'ASC' THEN 'ASC' ELSE 'DESC' END;
|
|
751
|
-
|
|
752
|
-
FOR v_sub IN
|
|
753
|
-
EXECUTE format($q$
|
|
754
|
-
SELECT DISTINCT
|
|
755
|
-
COALESCE(sr.sub_service_id, 0) AS sub_service_id_num,
|
|
756
|
-
COALESCE(NULLIF(trim(subsvc.sub_service_name), ''), NULLIF(trim(v.sub_service_name), ''), 'Uncategorized') AS sub_service_name
|
|
757
|
-
FROM vw_sla_my_requests v
|
|
758
|
-
INNER JOIN sla_requests sr ON sr.id = v.sla_request_id AND COALESCE(sr.is_deleted, false) = false
|
|
759
|
-
LEFT JOIN caa_sub_services subsvc ON subsvc.id = sr.sub_service_id
|
|
760
|
-
WHERE v.user_id = %1$s
|
|
761
|
-
AND v.status = ANY($1)
|
|
762
|
-
AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
|
|
763
|
-
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
|
|
764
|
-
AND ($4 IS NULL OR v.created_at::date >= $4)
|
|
765
|
-
AND ($5 IS NULL OR v.created_at::date <= $5)
|
|
766
|
-
AND ($6 IS NULL OR trim($6) = '' OR CAST(v.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
|
|
767
|
-
ORDER BY sub_service_name ASC
|
|
768
|
-
$q$, p_user_id)
|
|
769
|
-
USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text
|
|
770
|
-
LOOP
|
|
771
|
-
v_sheet_order := v_sheet_order + 1;
|
|
772
|
-
|
|
773
|
-
SELECT COALESCE(array_agg(DISTINCT keys.k ORDER BY keys.k), ARRAY[]::TEXT[])
|
|
774
|
-
INTO v_dyn_keys
|
|
775
|
-
FROM vw_sla_my_requests v
|
|
776
|
-
INNER JOIN sla_requests sr ON sr.id = v.sla_request_id AND COALESCE(sr.is_deleted, false) = false
|
|
777
|
-
CROSS JOIN LATERAL jsonb_object_keys(COALESCE(v.request_fields, '{}'::jsonb)) AS keys(k)
|
|
778
|
-
WHERE v.user_id = p_user_id
|
|
779
|
-
AND v.status = ANY(p_statuses)
|
|
780
|
-
AND (p_service_ids IS NULL OR cardinality(p_service_ids) = 0 OR sr.service_id = ANY(p_service_ids))
|
|
781
|
-
AND (p_sub_service_ids IS NULL OR cardinality(p_sub_service_ids) = 0 OR sr.sub_service_id = ANY(p_sub_service_ids))
|
|
782
|
-
AND (p_from_date IS NULL OR v.created_at::date >= p_from_date)
|
|
783
|
-
AND (p_to_date IS NULL OR v.created_at::date <= p_to_date)
|
|
784
|
-
AND (p_search_text IS NULL OR trim(p_search_text) = '' OR CAST(v.request_id AS TEXT) ILIKE '%' || trim(p_search_text) || '%')
|
|
785
|
-
AND COALESCE(sr.sub_service_id, 0) = v_sub.sub_service_id_num;
|
|
786
|
-
|
|
787
|
-
v_dyn_labels := ARRAY[]::TEXT[];
|
|
788
|
-
IF v_dyn_keys IS NOT NULL THEN
|
|
789
|
-
FOREACH v_k IN ARRAY v_dyn_keys
|
|
790
|
-
LOOP
|
|
791
|
-
v_dyn_labels := array_append(v_dyn_labels, sla_excel_header_label(v_k));
|
|
792
|
-
END LOOP;
|
|
793
|
-
END IF;
|
|
794
|
-
|
|
795
|
-
v_headers_labels := ARRAY(
|
|
796
|
-
SELECT sla_excel_header_label(lbl)
|
|
797
|
-
FROM unnest(v_common_labels || COALESCE(v_dyn_labels, ARRAY[]::TEXT[])) AS u(lbl)
|
|
798
|
-
);
|
|
799
|
-
v_headers_json := to_jsonb(v_headers_labels);
|
|
800
|
-
v_all_rows := '[]'::jsonb;
|
|
801
|
-
|
|
802
|
-
FOR v_row IN
|
|
803
|
-
EXECUTE format($q$
|
|
804
|
-
SELECT
|
|
805
|
-
v.sla_request_id,
|
|
806
|
-
v.request_id,
|
|
807
|
-
v.status,
|
|
808
|
-
v.created_at,
|
|
809
|
-
v.created_by,
|
|
810
|
-
v.req_user_department_id,
|
|
811
|
-
v.req_user_section_id,
|
|
812
|
-
v.request_fields,
|
|
813
|
-
TRIM(COALESCE(u.employee_name, '')) AS user_name
|
|
814
|
-
FROM vw_sla_my_requests v
|
|
815
|
-
INNER JOIN sla_requests sr ON sr.id = v.sla_request_id AND COALESCE(sr.is_deleted, false) = false
|
|
816
|
-
LEFT JOIN users u ON u.id = v.user_id AND COALESCE(u.is_deleted, false) = false
|
|
817
|
-
WHERE v.user_id = %1$s
|
|
818
|
-
AND v.status = ANY($1)
|
|
819
|
-
AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
|
|
820
|
-
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
|
|
821
|
-
AND ($4 IS NULL OR v.created_at::date >= $4)
|
|
822
|
-
AND ($5 IS NULL OR v.created_at::date <= $5)
|
|
823
|
-
AND ($6 IS NULL OR trim($6) = '' OR CAST(v.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
|
|
824
|
-
AND COALESCE(sr.sub_service_id, 0) = %2$s
|
|
825
|
-
ORDER BY %3$s %4$s, v.sla_request_id ASC
|
|
826
|
-
$q$, p_user_id, v_sub.sub_service_id_num, v_sort_col, v_sort_dir)
|
|
827
|
-
USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text
|
|
828
|
-
LOOP
|
|
829
|
-
v_cells := ARRAY[
|
|
830
|
-
COALESCE(v_row.sla_request_id::TEXT, ''),
|
|
831
|
-
COALESCE(v_row.request_id::TEXT, ''),
|
|
832
|
-
COALESCE(v_row.user_name, ''),
|
|
833
|
-
COALESCE(v_row.status, ''),
|
|
834
|
-
COALESCE(to_char(v_row.created_at AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS'), ''),
|
|
835
|
-
COALESCE(v_row.created_by, ''),
|
|
836
|
-
COALESCE(v_row.req_user_department_id, ''),
|
|
837
|
-
COALESCE(v_row.req_user_section_id, '')
|
|
838
|
-
];
|
|
839
|
-
|
|
840
|
-
IF v_dyn_keys IS NOT NULL THEN
|
|
841
|
-
FOREACH v_k IN ARRAY v_dyn_keys
|
|
842
|
-
LOOP
|
|
843
|
-
v_cells := array_append(v_cells, COALESCE(sla_request_field_cell(v_row.request_fields, v_k), ''));
|
|
844
|
-
END LOOP;
|
|
845
|
-
END IF;
|
|
846
|
-
|
|
847
|
-
v_all_rows := v_all_rows || jsonb_build_array(to_jsonb(v_cells));
|
|
848
|
-
END LOOP;
|
|
849
|
-
|
|
850
|
-
sheet_order := v_sheet_order;
|
|
851
|
-
sub_service_id := NULLIF(v_sub.sub_service_id_num, 0);
|
|
852
|
-
sub_service_name := v_sub.sub_service_name;
|
|
853
|
-
sheet_name := sla_excel_sheet_name(v_sub.sub_service_name);
|
|
854
|
-
headers := v_headers_json;
|
|
855
|
-
rows := v_all_rows;
|
|
856
|
-
RETURN NEXT;
|
|
857
|
-
END LOOP;
|
|
858
|
-
|
|
859
|
-
RETURN QUERY
|
|
860
|
-
SELECT *
|
|
861
|
-
FROM sla_my_requests_approvals_excel_sheet(
|
|
862
|
-
format('v.user_id = %s', p_user_id),
|
|
863
|
-
p_statuses,
|
|
864
|
-
p_service_ids,
|
|
865
|
-
p_sub_service_ids,
|
|
866
|
-
p_from_date,
|
|
867
|
-
p_to_date,
|
|
868
|
-
p_search_text,
|
|
869
|
-
v_sheet_order + 1
|
|
870
|
-
);
|
|
871
|
-
|
|
872
|
-
RETURN;
|
|
873
|
-
END;
|
|
874
|
-
$$;
|
|
1
|
+
-- SLA Reports stored procedures (Reports_Service)
|
|
2
|
+
-- Applied via: npm run sync:sla-sql (shared_models/scripts/sync-sla-reports-sql.js)
|
|
3
|
+
-- Or: psql -U <user> -d <database> -f shared_models/sql/sla_reports_procedures.sql
|
|
4
|
+
|
|
5
|
+
-- ---------------------------------------------------------------------------
|
|
6
|
+
-- Helper: approver row matches user (same semantics as User_Service SLA dashboard)
|
|
7
|
+
-- ---------------------------------------------------------------------------
|
|
8
|
+
CREATE OR REPLACE FUNCTION sla_approval_matches_user(p_sa_alias TEXT, p_user_id INT)
|
|
9
|
+
RETURNS TEXT
|
|
10
|
+
LANGUAGE sql
|
|
11
|
+
IMMUTABLE
|
|
12
|
+
AS $$
|
|
13
|
+
SELECT format('(
|
|
14
|
+
%1$s.approver_user_id = %2$s
|
|
15
|
+
OR %1$s.delegate_user_id = %2$s
|
|
16
|
+
OR (
|
|
17
|
+
%1$s.approver_user_id IS NULL
|
|
18
|
+
AND %1$s.delegate_user_id IS NULL
|
|
19
|
+
AND %1$s.approver_role_id IS NOT NULL
|
|
20
|
+
AND %1$s.department_id IS NOT NULL
|
|
21
|
+
AND EXISTS (
|
|
22
|
+
SELECT 1 FROM user_role ur
|
|
23
|
+
WHERE ur.user_id = %2$s
|
|
24
|
+
AND ur.role_id = %1$s.approver_role_id
|
|
25
|
+
AND ur.department_id = %1$s.department_id
|
|
26
|
+
AND (
|
|
27
|
+
%1$s.section_id IS NULL
|
|
28
|
+
OR (%1$s.section_id IS NOT NULL AND (ur.section_id = %1$s.section_id OR ur.section_id IS NULL))
|
|
29
|
+
)
|
|
30
|
+
AND ur.is_deleted = false AND ur.is_active = true
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
OR (
|
|
34
|
+
%1$s.approver_user_id IS NULL
|
|
35
|
+
AND %1$s.delegate_user_id IS NULL
|
|
36
|
+
AND %1$s.approver_role_id IS NULL
|
|
37
|
+
AND %1$s.department_id IS NOT NULL
|
|
38
|
+
AND %1$s.section_id IS NOT NULL
|
|
39
|
+
AND EXISTS (
|
|
40
|
+
SELECT 1 FROM users u
|
|
41
|
+
WHERE u.id = %2$s AND COALESCE(u.is_deleted, false) = false
|
|
42
|
+
AND u.department = %1$s.department_id AND u.section = %1$s.section_id
|
|
43
|
+
)
|
|
44
|
+
)
|
|
45
|
+
OR (
|
|
46
|
+
%1$s.approver_user_id IS NULL
|
|
47
|
+
AND %1$s.delegate_user_id IS NULL
|
|
48
|
+
AND %1$s.approver_role_id IS NULL
|
|
49
|
+
AND %1$s.department_id IS NOT NULL
|
|
50
|
+
AND %1$s.section_id IS NULL
|
|
51
|
+
AND EXISTS (
|
|
52
|
+
SELECT 1 FROM users u
|
|
53
|
+
WHERE u.id = %2$s AND COALESCE(u.is_deleted, false) = false
|
|
54
|
+
AND u.department = %1$s.department_id
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
)', p_sa_alias, p_user_id);
|
|
58
|
+
$$;
|
|
59
|
+
|
|
60
|
+
-- ---------------------------------------------------------------------------
|
|
61
|
+
-- MY REQUESTS — paginated view
|
|
62
|
+
-- ---------------------------------------------------------------------------
|
|
63
|
+
CREATE OR REPLACE FUNCTION sp_sla_my_requests_view(
|
|
64
|
+
p_user_id INT,
|
|
65
|
+
p_service_ids INT[] DEFAULT NULL,
|
|
66
|
+
p_sub_service_ids INT[] DEFAULT NULL,
|
|
67
|
+
p_statuses TEXT[] DEFAULT ARRAY['Pending','In Progress','Approved','Rejected'],
|
|
68
|
+
p_from_date DATE DEFAULT NULL,
|
|
69
|
+
p_to_date DATE DEFAULT NULL,
|
|
70
|
+
p_search_text TEXT DEFAULT NULL,
|
|
71
|
+
p_page INT DEFAULT 1,
|
|
72
|
+
p_limit INT DEFAULT 50,
|
|
73
|
+
p_sort_by TEXT DEFAULT 'created_at',
|
|
74
|
+
p_sort_order TEXT DEFAULT 'DESC'
|
|
75
|
+
)
|
|
76
|
+
RETURNS TABLE (
|
|
77
|
+
sla_request_id INT,
|
|
78
|
+
request_id INT,
|
|
79
|
+
service_id INT,
|
|
80
|
+
sub_service_id INT,
|
|
81
|
+
service_name TEXT,
|
|
82
|
+
sub_service_name TEXT,
|
|
83
|
+
status TEXT,
|
|
84
|
+
user_id INT,
|
|
85
|
+
user_name TEXT,
|
|
86
|
+
workflow_execution_id TEXT,
|
|
87
|
+
created_at TIMESTAMPTZ,
|
|
88
|
+
updated_at TIMESTAMPTZ,
|
|
89
|
+
total_count BIGINT
|
|
90
|
+
)
|
|
91
|
+
LANGUAGE plpgsql
|
|
92
|
+
STABLE
|
|
93
|
+
AS $$
|
|
94
|
+
DECLARE
|
|
95
|
+
v_offset INT;
|
|
96
|
+
v_limit INT;
|
|
97
|
+
v_sort_col TEXT;
|
|
98
|
+
v_sort_dir TEXT;
|
|
99
|
+
v_sql TEXT;
|
|
100
|
+
BEGIN
|
|
101
|
+
v_limit := LEAST(GREATEST(COALESCE(p_limit, 50), 1), 200);
|
|
102
|
+
v_offset := GREATEST(COALESCE(p_page, 1) - 1, 0) * v_limit;
|
|
103
|
+
|
|
104
|
+
v_sort_col := CASE lower(trim(p_sort_by))
|
|
105
|
+
WHEN 'updated_at' THEN 'sr.updated_at'
|
|
106
|
+
WHEN 'id' THEN 'sr.id'
|
|
107
|
+
WHEN 'status' THEN 'sr.status'
|
|
108
|
+
WHEN 'request_id' THEN 'sr.request_id'
|
|
109
|
+
ELSE 'sr.created_at'
|
|
110
|
+
END;
|
|
111
|
+
|
|
112
|
+
v_sort_dir := CASE WHEN upper(trim(p_sort_order)) = 'ASC' THEN 'ASC' ELSE 'DESC' END;
|
|
113
|
+
|
|
114
|
+
v_sql := format($q$
|
|
115
|
+
SELECT
|
|
116
|
+
sr.id::INT,
|
|
117
|
+
sr.request_id::INT,
|
|
118
|
+
sr.service_id::INT,
|
|
119
|
+
sr.sub_service_id::INT,
|
|
120
|
+
svc.name::TEXT,
|
|
121
|
+
subsvc.sub_service_name::TEXT,
|
|
122
|
+
sr.status::TEXT,
|
|
123
|
+
sr.user_id::INT,
|
|
124
|
+
TRIM(COALESCE(u.employee_name, ''))::TEXT,
|
|
125
|
+
sr.workflow_execution_id::TEXT,
|
|
126
|
+
sr.created_at,
|
|
127
|
+
sr.updated_at,
|
|
128
|
+
COUNT(*) OVER()::BIGINT
|
|
129
|
+
FROM sla_requests sr
|
|
130
|
+
LEFT JOIN caa_services svc ON svc.id = sr.service_id
|
|
131
|
+
LEFT JOIN caa_sub_services subsvc ON subsvc.id = sr.sub_service_id
|
|
132
|
+
LEFT JOIN users u ON u.id = sr.user_id
|
|
133
|
+
WHERE sr.is_deleted = false
|
|
134
|
+
AND sr.user_id = %1$s
|
|
135
|
+
AND sr.status::TEXT = ANY($1)
|
|
136
|
+
AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
|
|
137
|
+
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
|
|
138
|
+
AND ($4 IS NULL OR sr.created_at::date >= $4)
|
|
139
|
+
AND ($5 IS NULL OR sr.created_at::date <= $5)
|
|
140
|
+
AND ($6 IS NULL OR trim($6) = '' OR CAST(sr.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
|
|
141
|
+
ORDER BY %2$s %3$s
|
|
142
|
+
LIMIT %4$s OFFSET %5$s
|
|
143
|
+
$q$, p_user_id, v_sort_col, v_sort_dir, v_limit, v_offset);
|
|
144
|
+
|
|
145
|
+
RETURN QUERY EXECUTE v_sql
|
|
146
|
+
USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text;
|
|
147
|
+
END;
|
|
148
|
+
$$;
|
|
149
|
+
|
|
150
|
+
-- ---------------------------------------------------------------------------
|
|
151
|
+
-- MY REQUESTS — full export (download)
|
|
152
|
+
-- ---------------------------------------------------------------------------
|
|
153
|
+
CREATE OR REPLACE FUNCTION sp_sla_my_requests_download(
|
|
154
|
+
p_user_id INT,
|
|
155
|
+
p_service_ids INT[] DEFAULT NULL,
|
|
156
|
+
p_sub_service_ids INT[] DEFAULT NULL,
|
|
157
|
+
p_statuses TEXT[] DEFAULT ARRAY['Pending','In Progress','Approved','Rejected'],
|
|
158
|
+
p_from_date DATE DEFAULT NULL,
|
|
159
|
+
p_to_date DATE DEFAULT NULL,
|
|
160
|
+
p_search_text TEXT DEFAULT NULL,
|
|
161
|
+
p_sort_by TEXT DEFAULT 'created_at',
|
|
162
|
+
p_sort_order TEXT DEFAULT 'DESC'
|
|
163
|
+
)
|
|
164
|
+
RETURNS TABLE (
|
|
165
|
+
sla_request_id INT,
|
|
166
|
+
request_id INT,
|
|
167
|
+
service_id INT,
|
|
168
|
+
sub_service_id INT,
|
|
169
|
+
service_name TEXT,
|
|
170
|
+
sub_service_name TEXT,
|
|
171
|
+
status TEXT,
|
|
172
|
+
user_id INT,
|
|
173
|
+
user_name TEXT,
|
|
174
|
+
workflow_execution_id TEXT,
|
|
175
|
+
created_at TIMESTAMPTZ,
|
|
176
|
+
updated_at TIMESTAMPTZ
|
|
177
|
+
)
|
|
178
|
+
LANGUAGE plpgsql
|
|
179
|
+
STABLE
|
|
180
|
+
AS $$
|
|
181
|
+
DECLARE
|
|
182
|
+
v_sort_col TEXT;
|
|
183
|
+
v_sort_dir TEXT;
|
|
184
|
+
v_sql TEXT;
|
|
185
|
+
BEGIN
|
|
186
|
+
v_sort_col := CASE lower(trim(p_sort_by))
|
|
187
|
+
WHEN 'updated_at' THEN 'sr.updated_at'
|
|
188
|
+
WHEN 'id' THEN 'sr.id'
|
|
189
|
+
WHEN 'status' THEN 'sr.status'
|
|
190
|
+
WHEN 'request_id' THEN 'sr.request_id'
|
|
191
|
+
ELSE 'sr.created_at'
|
|
192
|
+
END;
|
|
193
|
+
v_sort_dir := CASE WHEN upper(trim(p_sort_order)) = 'ASC' THEN 'ASC' ELSE 'DESC' END;
|
|
194
|
+
|
|
195
|
+
v_sql := format($q$
|
|
196
|
+
SELECT
|
|
197
|
+
sr.id::INT,
|
|
198
|
+
sr.request_id::INT,
|
|
199
|
+
sr.service_id::INT,
|
|
200
|
+
sr.sub_service_id::INT,
|
|
201
|
+
svc.name::TEXT,
|
|
202
|
+
subsvc.sub_service_name::TEXT,
|
|
203
|
+
sr.status::TEXT,
|
|
204
|
+
sr.user_id::INT,
|
|
205
|
+
TRIM(COALESCE(u.employee_name, ''))::TEXT,
|
|
206
|
+
sr.workflow_execution_id::TEXT,
|
|
207
|
+
sr.created_at,
|
|
208
|
+
sr.updated_at
|
|
209
|
+
FROM sla_requests sr
|
|
210
|
+
LEFT JOIN caa_services svc ON svc.id = sr.service_id
|
|
211
|
+
LEFT JOIN caa_sub_services subsvc ON subsvc.id = sr.sub_service_id
|
|
212
|
+
LEFT JOIN users u ON u.id = sr.user_id
|
|
213
|
+
WHERE sr.is_deleted = false
|
|
214
|
+
AND sr.user_id = %1$s
|
|
215
|
+
AND sr.status::TEXT = ANY($1)
|
|
216
|
+
AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
|
|
217
|
+
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
|
|
218
|
+
AND ($4 IS NULL OR sr.created_at::date >= $4)
|
|
219
|
+
AND ($5 IS NULL OR sr.created_at::date <= $5)
|
|
220
|
+
AND ($6 IS NULL OR trim($6) = '' OR CAST(sr.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
|
|
221
|
+
ORDER BY %2$s %3$s
|
|
222
|
+
$q$, p_user_id, v_sort_col, v_sort_dir);
|
|
223
|
+
|
|
224
|
+
RETURN QUERY EXECUTE v_sql
|
|
225
|
+
USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text;
|
|
226
|
+
END;
|
|
227
|
+
$$;
|
|
228
|
+
|
|
229
|
+
-- ---------------------------------------------------------------------------
|
|
230
|
+
-- APPROVALS — paginated view
|
|
231
|
+
-- ---------------------------------------------------------------------------
|
|
232
|
+
DROP FUNCTION IF EXISTS sp_sla_approvals_view(
|
|
233
|
+
INT,
|
|
234
|
+
INT[],
|
|
235
|
+
INT[],
|
|
236
|
+
TEXT[],
|
|
237
|
+
TEXT[],
|
|
238
|
+
DATE,
|
|
239
|
+
DATE,
|
|
240
|
+
TEXT,
|
|
241
|
+
INT,
|
|
242
|
+
INT,
|
|
243
|
+
TEXT,
|
|
244
|
+
TEXT
|
|
245
|
+
);
|
|
246
|
+
CREATE OR REPLACE FUNCTION sp_sla_approvals_view(
|
|
247
|
+
p_approver_user_id INT,
|
|
248
|
+
p_service_ids INT[] DEFAULT NULL,
|
|
249
|
+
p_sub_service_ids INT[] DEFAULT NULL,
|
|
250
|
+
p_request_statuses TEXT[] DEFAULT ARRAY['Pending','In Progress','Approved','Rejected'],
|
|
251
|
+
p_approval_statuses TEXT[] DEFAULT ARRAY['In Progress','Approved','Rejected'],
|
|
252
|
+
p_from_date DATE DEFAULT NULL,
|
|
253
|
+
p_to_date DATE DEFAULT NULL,
|
|
254
|
+
p_search_text TEXT DEFAULT NULL,
|
|
255
|
+
p_page INT DEFAULT 1,
|
|
256
|
+
p_limit INT DEFAULT 50,
|
|
257
|
+
p_sort_by TEXT DEFAULT 'created_at',
|
|
258
|
+
p_sort_order TEXT DEFAULT 'DESC'
|
|
259
|
+
)
|
|
260
|
+
RETURNS TABLE (
|
|
261
|
+
sla_approval_id INT,
|
|
262
|
+
source_approval_id INT,
|
|
263
|
+
request_id INT,
|
|
264
|
+
service_id INT,
|
|
265
|
+
sub_service_id INT,
|
|
266
|
+
service_name TEXT,
|
|
267
|
+
sub_service_name TEXT,
|
|
268
|
+
department_id INT,
|
|
269
|
+
department_name TEXT,
|
|
270
|
+
section_id INT,
|
|
271
|
+
section_name TEXT,
|
|
272
|
+
role_id INT,
|
|
273
|
+
role_name TEXT,
|
|
274
|
+
approval_status TEXT,
|
|
275
|
+
request_status TEXT,
|
|
276
|
+
level INT,
|
|
277
|
+
approver_user_id INT,
|
|
278
|
+
approver_user_name TEXT,
|
|
279
|
+
delegate_user_id INT,
|
|
280
|
+
delegate_user_name TEXT,
|
|
281
|
+
approved_by INT,
|
|
282
|
+
approved_by_name TEXT,
|
|
283
|
+
comment TEXT,
|
|
284
|
+
created_at TIMESTAMPTZ,
|
|
285
|
+
updated_at TIMESTAMPTZ,
|
|
286
|
+
total_count BIGINT
|
|
287
|
+
)
|
|
288
|
+
LANGUAGE plpgsql
|
|
289
|
+
STABLE
|
|
290
|
+
AS $$
|
|
291
|
+
DECLARE
|
|
292
|
+
v_offset INT;
|
|
293
|
+
v_limit INT;
|
|
294
|
+
v_sort_col TEXT;
|
|
295
|
+
v_sort_dir TEXT;
|
|
296
|
+
v_match TEXT;
|
|
297
|
+
v_sql TEXT;
|
|
298
|
+
BEGIN
|
|
299
|
+
v_limit := LEAST(GREATEST(COALESCE(p_limit, 50), 1), 200);
|
|
300
|
+
v_offset := GREATEST(COALESCE(p_page, 1) - 1, 0) * v_limit;
|
|
301
|
+
v_match := sla_approval_matches_user('sa', p_approver_user_id);
|
|
302
|
+
|
|
303
|
+
v_sort_col := CASE lower(trim(p_sort_by))
|
|
304
|
+
WHEN 'updated_at' THEN 'sa.updated_at'
|
|
305
|
+
WHEN 'id' THEN 'sa.id'
|
|
306
|
+
WHEN 'approval_status' THEN 'sa.approval_status'
|
|
307
|
+
WHEN 'level' THEN 'sa.level'
|
|
308
|
+
WHEN 'request_id' THEN 'sa.request_id'
|
|
309
|
+
ELSE 'sa.created_at'
|
|
310
|
+
END;
|
|
311
|
+
v_sort_dir := CASE WHEN upper(trim(p_sort_order)) = 'ASC' THEN 'ASC' ELSE 'DESC' END;
|
|
312
|
+
|
|
313
|
+
v_sql := format($q$
|
|
314
|
+
SELECT
|
|
315
|
+
sa.id::INT,
|
|
316
|
+
sa.source_approval_id::INT,
|
|
317
|
+
sa.request_id::INT,
|
|
318
|
+
sa.service_id::INT,
|
|
319
|
+
sa.sub_service_id::INT,
|
|
320
|
+
svc.name::TEXT,
|
|
321
|
+
subsvc.sub_service_name::TEXT,
|
|
322
|
+
sa.department_id::INT,
|
|
323
|
+
TRIM(COALESCE(dept.department_name, ''))::TEXT,
|
|
324
|
+
sa.section_id::INT,
|
|
325
|
+
TRIM(COALESCE(sec.section_name, ''))::TEXT,
|
|
326
|
+
sa.approver_role_id::INT,
|
|
327
|
+
TRIM(COALESCE(r.name, ''))::TEXT,
|
|
328
|
+
sa.approval_status::TEXT,
|
|
329
|
+
sr.status::TEXT,
|
|
330
|
+
sa.level::INT,
|
|
331
|
+
sa.approver_user_id::INT,
|
|
332
|
+
TRIM(COALESCE(au.employee_name, ''))::TEXT,
|
|
333
|
+
sa.delegate_user_id::INT,
|
|
334
|
+
TRIM(COALESCE(du.employee_name, ''))::TEXT,
|
|
335
|
+
sa.approved_by::INT,
|
|
336
|
+
TRIM(COALESCE(ab.employee_name, ''))::TEXT,
|
|
337
|
+
sa.comment::TEXT,
|
|
338
|
+
sa.created_at,
|
|
339
|
+
sa.updated_at,
|
|
340
|
+
COUNT(*) OVER()::BIGINT
|
|
341
|
+
FROM sla_approval sa
|
|
342
|
+
INNER JOIN sla_requests sr
|
|
343
|
+
ON sr.request_id = sa.request_id AND sr.is_deleted = false
|
|
344
|
+
LEFT JOIN caa_services svc ON svc.id = sa.service_id
|
|
345
|
+
LEFT JOIN caa_sub_services subsvc ON subsvc.id = sa.sub_service_id
|
|
346
|
+
LEFT JOIN departments dept ON dept.id = sa.department_id AND COALESCE(dept.is_deleted, false) = false
|
|
347
|
+
LEFT JOIN sections sec ON sec.id = sa.section_id AND COALESCE(sec.is_deleted, false) = false
|
|
348
|
+
LEFT JOIN role r ON r.id = sa.approver_role_id AND COALESCE(r.is_deleted, false) = false
|
|
349
|
+
LEFT JOIN users au ON au.id = sa.approver_user_id
|
|
350
|
+
LEFT JOIN users du ON du.id = sa.delegate_user_id
|
|
351
|
+
LEFT JOIN users ab ON ab.id = sa.approved_by
|
|
352
|
+
WHERE sa.is_deleted = false
|
|
353
|
+
AND sr.user_id != %1$s
|
|
354
|
+
AND (sa.service_id = sr.service_id OR sa.service_id IS NULL)
|
|
355
|
+
AND (sa.sub_service_id = sr.sub_service_id OR sa.sub_service_id IS NULL)
|
|
356
|
+
AND %2$s
|
|
357
|
+
AND (sa.approval_status = ANY($1) OR sa.approval_status IS NULL)
|
|
358
|
+
AND sr.status::TEXT = ANY($2)
|
|
359
|
+
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.service_id = ANY($3))
|
|
360
|
+
AND ($4 IS NULL OR cardinality($4) = 0 OR sr.sub_service_id = ANY($4))
|
|
361
|
+
AND ($5 IS NULL OR sr.created_at::date >= $5)
|
|
362
|
+
AND ($6 IS NULL OR sr.created_at::date <= $6)
|
|
363
|
+
AND ($7 IS NULL OR trim($7) = '' OR CAST(sr.request_id AS TEXT) ILIKE '%%' || trim($7) || '%%')
|
|
364
|
+
ORDER BY %3$s %4$s, sa.id DESC
|
|
365
|
+
LIMIT %5$s OFFSET %6$s
|
|
366
|
+
$q$, p_approver_user_id, v_match, v_sort_col, v_sort_dir, v_limit, v_offset);
|
|
367
|
+
|
|
368
|
+
RETURN QUERY EXECUTE v_sql
|
|
369
|
+
USING p_approval_statuses, p_request_statuses, p_service_ids, p_sub_service_ids,
|
|
370
|
+
p_from_date, p_to_date, p_search_text;
|
|
371
|
+
END;
|
|
372
|
+
$$;
|
|
373
|
+
|
|
374
|
+
-- ---------------------------------------------------------------------------
|
|
375
|
+
-- APPROVALS — full export (download)
|
|
376
|
+
-- ---------------------------------------------------------------------------
|
|
377
|
+
CREATE OR REPLACE FUNCTION sp_sla_approvals_download(
|
|
378
|
+
p_approver_user_id INT,
|
|
379
|
+
p_service_ids INT[] DEFAULT NULL,
|
|
380
|
+
p_sub_service_ids INT[] DEFAULT NULL,
|
|
381
|
+
p_request_statuses TEXT[] DEFAULT ARRAY['Pending','In Progress','Approved','Rejected'],
|
|
382
|
+
p_approval_statuses TEXT[] DEFAULT ARRAY['In Progress','Approved','Rejected'],
|
|
383
|
+
p_from_date DATE DEFAULT NULL,
|
|
384
|
+
p_to_date DATE DEFAULT NULL,
|
|
385
|
+
p_search_text TEXT DEFAULT NULL,
|
|
386
|
+
p_sort_by TEXT DEFAULT 'created_at',
|
|
387
|
+
p_sort_order TEXT DEFAULT 'DESC'
|
|
388
|
+
)
|
|
389
|
+
RETURNS TABLE (
|
|
390
|
+
sla_approval_id INT,
|
|
391
|
+
source_approval_id INT,
|
|
392
|
+
request_id INT,
|
|
393
|
+
service_id INT,
|
|
394
|
+
sub_service_id INT,
|
|
395
|
+
service_name TEXT,
|
|
396
|
+
sub_service_name TEXT,
|
|
397
|
+
approval_status TEXT,
|
|
398
|
+
request_status TEXT,
|
|
399
|
+
level INT,
|
|
400
|
+
approver_user_id INT,
|
|
401
|
+
approver_user_name TEXT,
|
|
402
|
+
delegate_user_id INT,
|
|
403
|
+
delegate_user_name TEXT,
|
|
404
|
+
approved_by INT,
|
|
405
|
+
approved_by_name TEXT,
|
|
406
|
+
comment TEXT,
|
|
407
|
+
created_at TIMESTAMPTZ,
|
|
408
|
+
updated_at TIMESTAMPTZ
|
|
409
|
+
)
|
|
410
|
+
LANGUAGE plpgsql
|
|
411
|
+
STABLE
|
|
412
|
+
AS $$
|
|
413
|
+
DECLARE
|
|
414
|
+
v_sort_col TEXT;
|
|
415
|
+
v_sort_dir TEXT;
|
|
416
|
+
v_match TEXT;
|
|
417
|
+
v_sql TEXT;
|
|
418
|
+
BEGIN
|
|
419
|
+
v_match := sla_approval_matches_user('sa', p_approver_user_id);
|
|
420
|
+
|
|
421
|
+
v_sort_col := CASE lower(trim(p_sort_by))
|
|
422
|
+
WHEN 'updated_at' THEN 'sa.updated_at'
|
|
423
|
+
WHEN 'id' THEN 'sa.id'
|
|
424
|
+
WHEN 'approval_status' THEN 'sa.approval_status'
|
|
425
|
+
WHEN 'level' THEN 'sa.level'
|
|
426
|
+
WHEN 'request_id' THEN 'sa.request_id'
|
|
427
|
+
ELSE 'sa.created_at'
|
|
428
|
+
END;
|
|
429
|
+
v_sort_dir := CASE WHEN upper(trim(p_sort_order)) = 'ASC' THEN 'ASC' ELSE 'DESC' END;
|
|
430
|
+
|
|
431
|
+
v_sql := format($q$
|
|
432
|
+
SELECT
|
|
433
|
+
sa.id::INT,
|
|
434
|
+
sa.source_approval_id::INT,
|
|
435
|
+
sa.request_id::INT,
|
|
436
|
+
sa.service_id::INT,
|
|
437
|
+
sa.sub_service_id::INT,
|
|
438
|
+
svc.name::TEXT,
|
|
439
|
+
subsvc.sub_service_name::TEXT,
|
|
440
|
+
sa.approval_status::TEXT,
|
|
441
|
+
sr.status::TEXT,
|
|
442
|
+
sa.level::INT,
|
|
443
|
+
sa.approver_user_id::INT,
|
|
444
|
+
TRIM(COALESCE(au.employee_name, ''))::TEXT,
|
|
445
|
+
sa.delegate_user_id::INT,
|
|
446
|
+
TRIM(COALESCE(du.employee_name, ''))::TEXT,
|
|
447
|
+
sa.approved_by::INT,
|
|
448
|
+
TRIM(COALESCE(ab.employee_name, ''))::TEXT,
|
|
449
|
+
sa.comment::TEXT,
|
|
450
|
+
sa.created_at,
|
|
451
|
+
sa.updated_at
|
|
452
|
+
FROM sla_approval sa
|
|
453
|
+
INNER JOIN sla_requests sr
|
|
454
|
+
ON sr.request_id = sa.request_id AND sr.is_deleted = false
|
|
455
|
+
LEFT JOIN caa_services svc ON svc.id = sa.service_id
|
|
456
|
+
LEFT JOIN caa_sub_services subsvc ON subsvc.id = sa.sub_service_id
|
|
457
|
+
LEFT JOIN users au ON au.id = sa.approver_user_id
|
|
458
|
+
LEFT JOIN users du ON du.id = sa.delegate_user_id
|
|
459
|
+
LEFT JOIN users ab ON ab.id = sa.approved_by
|
|
460
|
+
WHERE sa.is_deleted = false
|
|
461
|
+
AND sr.user_id != %1$s
|
|
462
|
+
AND (sa.service_id = sr.service_id OR sa.service_id IS NULL)
|
|
463
|
+
AND (sa.sub_service_id = sr.sub_service_id OR sa.sub_service_id IS NULL)
|
|
464
|
+
AND %2$s
|
|
465
|
+
AND (sa.approval_status = ANY($1) OR sa.approval_status IS NULL)
|
|
466
|
+
AND sr.status::TEXT = ANY($2)
|
|
467
|
+
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.service_id = ANY($3))
|
|
468
|
+
AND ($4 IS NULL OR cardinality($4) = 0 OR sr.sub_service_id = ANY($4))
|
|
469
|
+
AND ($5 IS NULL OR sr.created_at::date >= $5)
|
|
470
|
+
AND ($6 IS NULL OR sr.created_at::date <= $6)
|
|
471
|
+
AND ($7 IS NULL OR trim($7) = '' OR CAST(sr.request_id AS TEXT) ILIKE '%%' || trim($7) || '%%')
|
|
472
|
+
ORDER BY %3$s %4$s, sa.id DESC
|
|
473
|
+
$q$, p_approver_user_id, v_match, v_sort_col, v_sort_dir);
|
|
474
|
+
|
|
475
|
+
RETURN QUERY EXECUTE v_sql
|
|
476
|
+
USING p_approval_statuses, p_request_statuses, p_service_ids, p_sub_service_ids,
|
|
477
|
+
p_from_date, p_to_date, p_search_text;
|
|
478
|
+
END;
|
|
479
|
+
$$;
|
|
480
|
+
|
|
481
|
+
-- ---------------------------------------------------------------------------
|
|
482
|
+
-- Helpers: Excel export (my requests)
|
|
483
|
+
-- ---------------------------------------------------------------------------
|
|
484
|
+
CREATE OR REPLACE FUNCTION sla_excel_header_label(p_key TEXT)
|
|
485
|
+
RETURNS TEXT
|
|
486
|
+
LANGUAGE sql
|
|
487
|
+
IMMUTABLE
|
|
488
|
+
AS $$
|
|
489
|
+
SELECT trim(
|
|
490
|
+
initcap(
|
|
491
|
+
regexp_replace(
|
|
492
|
+
regexp_replace(COALESCE(p_key, ''), '[_-]+', ' ', 'g'),
|
|
493
|
+
'\s+',
|
|
494
|
+
' ',
|
|
495
|
+
'g'
|
|
496
|
+
)
|
|
497
|
+
)
|
|
498
|
+
);
|
|
499
|
+
$$;
|
|
500
|
+
|
|
501
|
+
CREATE OR REPLACE FUNCTION sla_request_field_cell(p_fields JSONB, p_key TEXT)
|
|
502
|
+
RETURNS TEXT
|
|
503
|
+
LANGUAGE sql
|
|
504
|
+
IMMUTABLE
|
|
505
|
+
AS $$
|
|
506
|
+
SELECT CASE
|
|
507
|
+
WHEN p_fields IS NULL OR NOT (p_fields ? p_key) THEN NULL
|
|
508
|
+
WHEN jsonb_typeof(p_fields -> p_key) IN ('object', 'array') THEN (p_fields -> p_key)::TEXT
|
|
509
|
+
ELSE p_fields ->> p_key
|
|
510
|
+
END;
|
|
511
|
+
$$;
|
|
512
|
+
|
|
513
|
+
CREATE OR REPLACE FUNCTION sla_excel_sheet_name(p_sub_service_name TEXT)
|
|
514
|
+
RETURNS TEXT
|
|
515
|
+
LANGUAGE sql
|
|
516
|
+
IMMUTABLE
|
|
517
|
+
AS $$
|
|
518
|
+
SELECT LEFT(
|
|
519
|
+
CASE
|
|
520
|
+
WHEN COALESCE(trim(p_sub_service_name), '') = '' THEN 'Requests'
|
|
521
|
+
ELSE trim(p_sub_service_name) || ' Requests'
|
|
522
|
+
END,
|
|
523
|
+
31
|
|
524
|
+
);
|
|
525
|
+
$$;
|
|
526
|
+
|
|
527
|
+
DROP FUNCTION IF EXISTS sla_excel_approvals_sheet_name(TEXT);
|
|
528
|
+
|
|
529
|
+
CREATE OR REPLACE FUNCTION sla_excel_approvals_sheet_name(p_sub_service_name TEXT)
|
|
530
|
+
RETURNS TEXT
|
|
531
|
+
LANGUAGE sql
|
|
532
|
+
IMMUTABLE
|
|
533
|
+
AS $$
|
|
534
|
+
SELECT LEFT(
|
|
535
|
+
CASE
|
|
536
|
+
WHEN COALESCE(trim(p_sub_service_name), '') = '' THEN 'Approvals'
|
|
537
|
+
ELSE trim(p_sub_service_name) || ' Approvals'
|
|
538
|
+
END,
|
|
539
|
+
31
|
|
540
|
+
);
|
|
541
|
+
$$;
|
|
542
|
+
|
|
543
|
+
-- ---------------------------------------------------------------------------
|
|
544
|
+
-- MY REQUESTS — Approvals sheet (vw_sla_approvals joined to filtered my-requests)
|
|
545
|
+
-- p_user_scope_sql: e.g. 'v.user_id = 5' or 'TRUE' (admin all users)
|
|
546
|
+
-- ---------------------------------------------------------------------------
|
|
547
|
+
DROP FUNCTION IF EXISTS sla_my_requests_approvals_excel_sheet(TEXT, TEXT[], INT[], INT[], DATE, DATE, TEXT, INT);
|
|
548
|
+
|
|
549
|
+
CREATE OR REPLACE FUNCTION sla_my_requests_approvals_excel_sheet(
|
|
550
|
+
p_user_scope_sql TEXT,
|
|
551
|
+
p_statuses TEXT[],
|
|
552
|
+
p_service_ids INT[],
|
|
553
|
+
p_sub_service_ids INT[],
|
|
554
|
+
p_from_date DATE,
|
|
555
|
+
p_to_date DATE,
|
|
556
|
+
p_search_text TEXT,
|
|
557
|
+
p_start_sheet_order INT
|
|
558
|
+
)
|
|
559
|
+
RETURNS TABLE (
|
|
560
|
+
sheet_order INT,
|
|
561
|
+
sub_service_id INT,
|
|
562
|
+
sub_service_name TEXT,
|
|
563
|
+
sheet_name TEXT,
|
|
564
|
+
headers JSONB,
|
|
565
|
+
rows JSONB
|
|
566
|
+
)
|
|
567
|
+
LANGUAGE plpgsql
|
|
568
|
+
STABLE
|
|
569
|
+
AS $$
|
|
570
|
+
DECLARE
|
|
571
|
+
v_sub RECORD;
|
|
572
|
+
v_approval RECORD;
|
|
573
|
+
v_sheet_order INT;
|
|
574
|
+
v_sheet_label TEXT;
|
|
575
|
+
v_headers_labels TEXT[] := ARRAY[
|
|
576
|
+
'Request ID', 'Service ID', 'Service Name', 'Sub Service ID', 'Sub Service Name',
|
|
577
|
+
'SLA Approval ID', 'Source Approval ID', 'Level', 'Approval Status', 'Request Status',
|
|
578
|
+
'Approval Role ID', 'Approval Role Name', 'Approval Department ID', 'Approval Department Name',
|
|
579
|
+
'Approval Section ID', 'Approval Section Name',
|
|
580
|
+
'Approver User ID', 'Approver User Name', 'Delegate User ID', 'Delegate User Name',
|
|
581
|
+
'Approved By ID', 'Approved By Name', 'Comment', 'Created At', 'Updated At'
|
|
582
|
+
];
|
|
583
|
+
v_cells TEXT[];
|
|
584
|
+
v_all_rows JSONB;
|
|
585
|
+
BEGIN
|
|
586
|
+
v_sheet_order := p_start_sheet_order;
|
|
587
|
+
|
|
588
|
+
FOR v_sub IN
|
|
589
|
+
EXECUTE format($q$
|
|
590
|
+
SELECT DISTINCT
|
|
591
|
+
COALESCE(sr.sub_service_id, 0) AS sub_service_id_num,
|
|
592
|
+
COALESCE(NULLIF(trim(subsvc.sub_service_name), ''), NULLIF(trim(v.sub_service_name), ''), 'Uncategorized') AS sub_service_name
|
|
593
|
+
FROM vw_sla_my_requests v
|
|
594
|
+
INNER JOIN sla_requests sr ON sr.id = v.sla_request_id AND COALESCE(sr.is_deleted, false) = false
|
|
595
|
+
LEFT JOIN caa_sub_services subsvc ON subsvc.id = sr.sub_service_id
|
|
596
|
+
WHERE %s
|
|
597
|
+
AND v.status = ANY($1)
|
|
598
|
+
AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
|
|
599
|
+
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
|
|
600
|
+
AND ($4 IS NULL OR v.created_at::date >= $4)
|
|
601
|
+
AND ($5 IS NULL OR v.created_at::date <= $5)
|
|
602
|
+
AND ($6 IS NULL OR trim($6) = '' OR CAST(v.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
|
|
603
|
+
ORDER BY sub_service_name ASC
|
|
604
|
+
$q$, p_user_scope_sql)
|
|
605
|
+
USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text
|
|
606
|
+
LOOP
|
|
607
|
+
v_sheet_order := v_sheet_order + 1;
|
|
608
|
+
v_sheet_label := sla_excel_approvals_sheet_name(v_sub.sub_service_name);
|
|
609
|
+
v_all_rows := '[]'::jsonb;
|
|
610
|
+
|
|
611
|
+
FOR v_approval IN
|
|
612
|
+
EXECUTE format($q$
|
|
613
|
+
SELECT
|
|
614
|
+
va.request_id,
|
|
615
|
+
sr.service_id,
|
|
616
|
+
va.service_name,
|
|
617
|
+
sr.sub_service_id,
|
|
618
|
+
va.sub_service_name,
|
|
619
|
+
va.sla_approval_id,
|
|
620
|
+
va.source_approval_id,
|
|
621
|
+
va.level,
|
|
622
|
+
va.approval_status,
|
|
623
|
+
va.request_status,
|
|
624
|
+
va.approval_role_id,
|
|
625
|
+
va.approval_role_name,
|
|
626
|
+
va.approval_department_id,
|
|
627
|
+
va.approval_department_name,
|
|
628
|
+
va.approval_section_id,
|
|
629
|
+
va.approval_section_name,
|
|
630
|
+
va.approver_user_id,
|
|
631
|
+
va.approver_user_name,
|
|
632
|
+
va.delegate_user_id,
|
|
633
|
+
va.delegate_user_name,
|
|
634
|
+
va.approved_by,
|
|
635
|
+
va.approved_by_name,
|
|
636
|
+
va.comment,
|
|
637
|
+
va.created_at,
|
|
638
|
+
va.updated_at
|
|
639
|
+
FROM vw_sla_my_requests v
|
|
640
|
+
INNER JOIN sla_requests sr
|
|
641
|
+
ON sr.id = v.sla_request_id AND COALESCE(sr.is_deleted, false) = false
|
|
642
|
+
INNER JOIN vw_sla_approvals va
|
|
643
|
+
ON va.request_id = v.request_id
|
|
644
|
+
AND (va.service_id = sr.service_id OR va.service_id IS NULL)
|
|
645
|
+
AND (va.sub_service_id = sr.sub_service_id OR va.sub_service_id IS NULL)
|
|
646
|
+
WHERE %s
|
|
647
|
+
AND v.status = ANY($1)
|
|
648
|
+
AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
|
|
649
|
+
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
|
|
650
|
+
AND ($4 IS NULL OR v.created_at::date >= $4)
|
|
651
|
+
AND ($5 IS NULL OR v.created_at::date <= $5)
|
|
652
|
+
AND ($6 IS NULL OR trim($6) = '' OR CAST(v.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
|
|
653
|
+
AND COALESCE(sr.sub_service_id, 0) = %2$s
|
|
654
|
+
ORDER BY va.request_id ASC, va.level ASC NULLS LAST, va.sla_approval_id ASC
|
|
655
|
+
$q$, p_user_scope_sql, v_sub.sub_service_id_num)
|
|
656
|
+
USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text
|
|
657
|
+
LOOP
|
|
658
|
+
v_cells := ARRAY[
|
|
659
|
+
COALESCE(v_approval.request_id::TEXT, ''),
|
|
660
|
+
COALESCE(v_approval.service_id::TEXT, ''),
|
|
661
|
+
COALESCE(v_approval.service_name, ''),
|
|
662
|
+
COALESCE(v_approval.sub_service_id::TEXT, ''),
|
|
663
|
+
COALESCE(v_approval.sub_service_name, ''),
|
|
664
|
+
COALESCE(v_approval.sla_approval_id::TEXT, ''),
|
|
665
|
+
COALESCE(v_approval.source_approval_id::TEXT, ''),
|
|
666
|
+
COALESCE(v_approval.level::TEXT, ''),
|
|
667
|
+
COALESCE(v_approval.approval_status, ''),
|
|
668
|
+
COALESCE(v_approval.request_status, ''),
|
|
669
|
+
COALESCE(v_approval.approval_role_id::TEXT, ''),
|
|
670
|
+
COALESCE(v_approval.approval_role_name, ''),
|
|
671
|
+
COALESCE(v_approval.approval_department_id::TEXT, ''),
|
|
672
|
+
COALESCE(v_approval.approval_department_name, ''),
|
|
673
|
+
COALESCE(v_approval.approval_section_id::TEXT, ''),
|
|
674
|
+
COALESCE(v_approval.approval_section_name, ''),
|
|
675
|
+
COALESCE(v_approval.approver_user_id::TEXT, ''),
|
|
676
|
+
COALESCE(v_approval.approver_user_name, ''),
|
|
677
|
+
COALESCE(v_approval.delegate_user_id::TEXT, ''),
|
|
678
|
+
COALESCE(v_approval.delegate_user_name, ''),
|
|
679
|
+
COALESCE(v_approval.approved_by::TEXT, ''),
|
|
680
|
+
COALESCE(v_approval.approved_by_name, ''),
|
|
681
|
+
COALESCE(v_approval.comment, ''),
|
|
682
|
+
COALESCE(to_char(v_approval.created_at AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS'), ''),
|
|
683
|
+
COALESCE(to_char(v_approval.updated_at AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS'), '')
|
|
684
|
+
];
|
|
685
|
+
v_all_rows := v_all_rows || jsonb_build_array(to_jsonb(v_cells));
|
|
686
|
+
END LOOP;
|
|
687
|
+
|
|
688
|
+
sheet_order := v_sheet_order;
|
|
689
|
+
sub_service_id := NULLIF(v_sub.sub_service_id_num, 0);
|
|
690
|
+
sub_service_name := v_sub.sub_service_name;
|
|
691
|
+
sheet_name := v_sheet_label;
|
|
692
|
+
headers := to_jsonb(v_headers_labels);
|
|
693
|
+
rows := v_all_rows;
|
|
694
|
+
RETURN NEXT;
|
|
695
|
+
END LOOP;
|
|
696
|
+
END;
|
|
697
|
+
$$;
|
|
698
|
+
|
|
699
|
+
-- ---------------------------------------------------------------------------
|
|
700
|
+
-- MY REQUESTS — Excel workbook payload (one result row per sub-service sheet)
|
|
701
|
+
-- Uses vw_sla_my_requests; flattening and dynamic columns are built in the database.
|
|
702
|
+
-- ---------------------------------------------------------------------------
|
|
703
|
+
CREATE OR REPLACE FUNCTION sp_sla_my_requests_excel_export(
|
|
704
|
+
p_user_id INT,
|
|
705
|
+
p_service_ids INT[] DEFAULT NULL,
|
|
706
|
+
p_sub_service_ids INT[] DEFAULT NULL,
|
|
707
|
+
p_statuses TEXT[] DEFAULT ARRAY['Pending','In Progress','Approved','Rejected'],
|
|
708
|
+
p_from_date DATE DEFAULT NULL,
|
|
709
|
+
p_to_date DATE DEFAULT NULL,
|
|
710
|
+
p_search_text TEXT DEFAULT NULL,
|
|
711
|
+
p_sort_by TEXT DEFAULT 'created_at',
|
|
712
|
+
p_sort_order TEXT DEFAULT 'DESC'
|
|
713
|
+
)
|
|
714
|
+
RETURNS TABLE (
|
|
715
|
+
sheet_order INT,
|
|
716
|
+
sub_service_id INT,
|
|
717
|
+
sub_service_name TEXT,
|
|
718
|
+
sheet_name TEXT,
|
|
719
|
+
headers JSONB,
|
|
720
|
+
rows JSONB
|
|
721
|
+
)
|
|
722
|
+
LANGUAGE plpgsql
|
|
723
|
+
STABLE
|
|
724
|
+
AS $$
|
|
725
|
+
DECLARE
|
|
726
|
+
v_sort_col TEXT;
|
|
727
|
+
v_sort_dir TEXT;
|
|
728
|
+
v_sub RECORD;
|
|
729
|
+
v_row RECORD;
|
|
730
|
+
v_dyn_keys TEXT[];
|
|
731
|
+
v_dyn_labels TEXT[];
|
|
732
|
+
v_common_labels TEXT[] := ARRAY[
|
|
733
|
+
'SLA Request ID', 'Request ID', 'User', 'Status', 'Created At',
|
|
734
|
+
'Created By', 'Department', 'Section'
|
|
735
|
+
];
|
|
736
|
+
v_headers_labels TEXT[];
|
|
737
|
+
v_headers_json JSONB;
|
|
738
|
+
v_cells TEXT[];
|
|
739
|
+
v_all_rows JSONB;
|
|
740
|
+
v_k TEXT;
|
|
741
|
+
v_sheet_order INT := 0;
|
|
742
|
+
BEGIN
|
|
743
|
+
v_sort_col := CASE lower(trim(p_sort_by))
|
|
744
|
+
WHEN 'updated_at' THEN 'v.created_at'
|
|
745
|
+
WHEN 'id' THEN 'v.sla_request_id'
|
|
746
|
+
WHEN 'status' THEN 'v.status'
|
|
747
|
+
WHEN 'request_id' THEN 'v.request_id'
|
|
748
|
+
ELSE 'v.created_at'
|
|
749
|
+
END;
|
|
750
|
+
v_sort_dir := CASE WHEN upper(trim(p_sort_order)) = 'ASC' THEN 'ASC' ELSE 'DESC' END;
|
|
751
|
+
|
|
752
|
+
FOR v_sub IN
|
|
753
|
+
EXECUTE format($q$
|
|
754
|
+
SELECT DISTINCT
|
|
755
|
+
COALESCE(sr.sub_service_id, 0) AS sub_service_id_num,
|
|
756
|
+
COALESCE(NULLIF(trim(subsvc.sub_service_name), ''), NULLIF(trim(v.sub_service_name), ''), 'Uncategorized') AS sub_service_name
|
|
757
|
+
FROM vw_sla_my_requests v
|
|
758
|
+
INNER JOIN sla_requests sr ON sr.id = v.sla_request_id AND COALESCE(sr.is_deleted, false) = false
|
|
759
|
+
LEFT JOIN caa_sub_services subsvc ON subsvc.id = sr.sub_service_id
|
|
760
|
+
WHERE v.user_id = %1$s
|
|
761
|
+
AND v.status = ANY($1)
|
|
762
|
+
AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
|
|
763
|
+
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
|
|
764
|
+
AND ($4 IS NULL OR v.created_at::date >= $4)
|
|
765
|
+
AND ($5 IS NULL OR v.created_at::date <= $5)
|
|
766
|
+
AND ($6 IS NULL OR trim($6) = '' OR CAST(v.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
|
|
767
|
+
ORDER BY sub_service_name ASC
|
|
768
|
+
$q$, p_user_id)
|
|
769
|
+
USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text
|
|
770
|
+
LOOP
|
|
771
|
+
v_sheet_order := v_sheet_order + 1;
|
|
772
|
+
|
|
773
|
+
SELECT COALESCE(array_agg(DISTINCT keys.k ORDER BY keys.k), ARRAY[]::TEXT[])
|
|
774
|
+
INTO v_dyn_keys
|
|
775
|
+
FROM vw_sla_my_requests v
|
|
776
|
+
INNER JOIN sla_requests sr ON sr.id = v.sla_request_id AND COALESCE(sr.is_deleted, false) = false
|
|
777
|
+
CROSS JOIN LATERAL jsonb_object_keys(COALESCE(v.request_fields, '{}'::jsonb)) AS keys(k)
|
|
778
|
+
WHERE v.user_id = p_user_id
|
|
779
|
+
AND v.status = ANY(p_statuses)
|
|
780
|
+
AND (p_service_ids IS NULL OR cardinality(p_service_ids) = 0 OR sr.service_id = ANY(p_service_ids))
|
|
781
|
+
AND (p_sub_service_ids IS NULL OR cardinality(p_sub_service_ids) = 0 OR sr.sub_service_id = ANY(p_sub_service_ids))
|
|
782
|
+
AND (p_from_date IS NULL OR v.created_at::date >= p_from_date)
|
|
783
|
+
AND (p_to_date IS NULL OR v.created_at::date <= p_to_date)
|
|
784
|
+
AND (p_search_text IS NULL OR trim(p_search_text) = '' OR CAST(v.request_id AS TEXT) ILIKE '%' || trim(p_search_text) || '%')
|
|
785
|
+
AND COALESCE(sr.sub_service_id, 0) = v_sub.sub_service_id_num;
|
|
786
|
+
|
|
787
|
+
v_dyn_labels := ARRAY[]::TEXT[];
|
|
788
|
+
IF v_dyn_keys IS NOT NULL THEN
|
|
789
|
+
FOREACH v_k IN ARRAY v_dyn_keys
|
|
790
|
+
LOOP
|
|
791
|
+
v_dyn_labels := array_append(v_dyn_labels, sla_excel_header_label(v_k));
|
|
792
|
+
END LOOP;
|
|
793
|
+
END IF;
|
|
794
|
+
|
|
795
|
+
v_headers_labels := ARRAY(
|
|
796
|
+
SELECT sla_excel_header_label(lbl)
|
|
797
|
+
FROM unnest(v_common_labels || COALESCE(v_dyn_labels, ARRAY[]::TEXT[])) AS u(lbl)
|
|
798
|
+
);
|
|
799
|
+
v_headers_json := to_jsonb(v_headers_labels);
|
|
800
|
+
v_all_rows := '[]'::jsonb;
|
|
801
|
+
|
|
802
|
+
FOR v_row IN
|
|
803
|
+
EXECUTE format($q$
|
|
804
|
+
SELECT
|
|
805
|
+
v.sla_request_id,
|
|
806
|
+
v.request_id,
|
|
807
|
+
v.status,
|
|
808
|
+
v.created_at,
|
|
809
|
+
v.created_by,
|
|
810
|
+
v.req_user_department_id,
|
|
811
|
+
v.req_user_section_id,
|
|
812
|
+
v.request_fields,
|
|
813
|
+
TRIM(COALESCE(u.employee_name, '')) AS user_name
|
|
814
|
+
FROM vw_sla_my_requests v
|
|
815
|
+
INNER JOIN sla_requests sr ON sr.id = v.sla_request_id AND COALESCE(sr.is_deleted, false) = false
|
|
816
|
+
LEFT JOIN users u ON u.id = v.user_id AND COALESCE(u.is_deleted, false) = false
|
|
817
|
+
WHERE v.user_id = %1$s
|
|
818
|
+
AND v.status = ANY($1)
|
|
819
|
+
AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
|
|
820
|
+
AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
|
|
821
|
+
AND ($4 IS NULL OR v.created_at::date >= $4)
|
|
822
|
+
AND ($5 IS NULL OR v.created_at::date <= $5)
|
|
823
|
+
AND ($6 IS NULL OR trim($6) = '' OR CAST(v.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
|
|
824
|
+
AND COALESCE(sr.sub_service_id, 0) = %2$s
|
|
825
|
+
ORDER BY %3$s %4$s, v.sla_request_id ASC
|
|
826
|
+
$q$, p_user_id, v_sub.sub_service_id_num, v_sort_col, v_sort_dir)
|
|
827
|
+
USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text
|
|
828
|
+
LOOP
|
|
829
|
+
v_cells := ARRAY[
|
|
830
|
+
COALESCE(v_row.sla_request_id::TEXT, ''),
|
|
831
|
+
COALESCE(v_row.request_id::TEXT, ''),
|
|
832
|
+
COALESCE(v_row.user_name, ''),
|
|
833
|
+
COALESCE(v_row.status, ''),
|
|
834
|
+
COALESCE(to_char(v_row.created_at AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS'), ''),
|
|
835
|
+
COALESCE(v_row.created_by, ''),
|
|
836
|
+
COALESCE(v_row.req_user_department_id, ''),
|
|
837
|
+
COALESCE(v_row.req_user_section_id, '')
|
|
838
|
+
];
|
|
839
|
+
|
|
840
|
+
IF v_dyn_keys IS NOT NULL THEN
|
|
841
|
+
FOREACH v_k IN ARRAY v_dyn_keys
|
|
842
|
+
LOOP
|
|
843
|
+
v_cells := array_append(v_cells, COALESCE(sla_request_field_cell(v_row.request_fields, v_k), ''));
|
|
844
|
+
END LOOP;
|
|
845
|
+
END IF;
|
|
846
|
+
|
|
847
|
+
v_all_rows := v_all_rows || jsonb_build_array(to_jsonb(v_cells));
|
|
848
|
+
END LOOP;
|
|
849
|
+
|
|
850
|
+
sheet_order := v_sheet_order;
|
|
851
|
+
sub_service_id := NULLIF(v_sub.sub_service_id_num, 0);
|
|
852
|
+
sub_service_name := v_sub.sub_service_name;
|
|
853
|
+
sheet_name := sla_excel_sheet_name(v_sub.sub_service_name);
|
|
854
|
+
headers := v_headers_json;
|
|
855
|
+
rows := v_all_rows;
|
|
856
|
+
RETURN NEXT;
|
|
857
|
+
END LOOP;
|
|
858
|
+
|
|
859
|
+
RETURN QUERY
|
|
860
|
+
SELECT *
|
|
861
|
+
FROM sla_my_requests_approvals_excel_sheet(
|
|
862
|
+
format('v.user_id = %s', p_user_id),
|
|
863
|
+
p_statuses,
|
|
864
|
+
p_service_ids,
|
|
865
|
+
p_sub_service_ids,
|
|
866
|
+
p_from_date,
|
|
867
|
+
p_to_date,
|
|
868
|
+
p_search_text,
|
|
869
|
+
v_sheet_order + 1
|
|
870
|
+
);
|
|
871
|
+
|
|
872
|
+
RETURN;
|
|
873
|
+
END;
|
|
874
|
+
$$;
|