@platform-modules/foreign-ministry 1.3.355 → 1.3.358
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/helpers/employee-evaluation-request.utils.d.ts +12 -0
- package/dist/helpers/employee-evaluation-request.utils.js +85 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -3
- package/package.json +2 -2
- package/sql/sla_reports_admin_procedures.sql +1 -2
- package/sql/sla_reports_approvals_workbook.sql +2 -5
- package/sql/sla_reports_procedures.sql +2 -5
- package/src/helpers/employee-evaluation-request.utils.ts +127 -0
- package/src/index.ts +1 -0
|
@@ -34,3 +34,15 @@ export declare function persistEmployeeEvaluationScores(manager: EntityManager,
|
|
|
34
34
|
averageScore: number;
|
|
35
35
|
employeeCount: number;
|
|
36
36
|
}>;
|
|
37
|
+
/** Sync person_scores/answers on an existing request (draft update or draft promotion). */
|
|
38
|
+
export declare function syncEmployeeEvaluationScores(manager: EntityManager, opts: {
|
|
39
|
+
requestId: number;
|
|
40
|
+
formId: number;
|
|
41
|
+
createdBy: string;
|
|
42
|
+
employees: NormalizedEmployeeSubmission[];
|
|
43
|
+
validateAnswers?: boolean;
|
|
44
|
+
}): Promise<{
|
|
45
|
+
totalScore: number | null;
|
|
46
|
+
averageScore: number | null;
|
|
47
|
+
employeeCount: number;
|
|
48
|
+
}>;
|
|
@@ -5,6 +5,7 @@ exports.normalizeEmployeeSubmissions = normalizeEmployeeSubmissions;
|
|
|
5
5
|
exports.normalizeEmployeeDraftSubmissions = normalizeEmployeeDraftSubmissions;
|
|
6
6
|
exports.resolveMaxEmployeesPerRequest = resolveMaxEmployeesPerRequest;
|
|
7
7
|
exports.persistEmployeeEvaluationScores = persistEmployeeEvaluationScores;
|
|
8
|
+
exports.syncEmployeeEvaluationScores = syncEmployeeEvaluationScores;
|
|
8
9
|
const EmployeeEvaluationAnswerModel_1 = require("../models/EmployeeEvaluationAnswerModel");
|
|
9
10
|
const EmployeeEvaluationPersonScoreModel_1 = require("../models/EmployeeEvaluationPersonScoreModel");
|
|
10
11
|
const EmployeeEvaluationRequestModel_1 = require("../models/EmployeeEvaluationRequestModel");
|
|
@@ -213,3 +214,87 @@ async function persistEmployeeEvaluationScores(manager, opts) {
|
|
|
213
214
|
});
|
|
214
215
|
return { totalScore: requestTotal, averageScore, employeeCount };
|
|
215
216
|
}
|
|
217
|
+
/** Sync person_scores/answers on an existing request (draft update or draft promotion). */
|
|
218
|
+
async function syncEmployeeEvaluationScores(manager, opts) {
|
|
219
|
+
const { requestId, formId, createdBy, employees, validateAnswers = false } = opts;
|
|
220
|
+
const payloadUserIds = new Set(employees.map((e) => e.user_id));
|
|
221
|
+
const existingScores = await manager.find(EmployeeEvaluationPersonScoreModel_1.EmployeeEvaluationPersonScore, {
|
|
222
|
+
where: { request_id: requestId, is_deleted: false },
|
|
223
|
+
});
|
|
224
|
+
for (const ps of existingScores) {
|
|
225
|
+
if (!payloadUserIds.has(ps.user_id)) {
|
|
226
|
+
await manager.update(EmployeeEvaluationPersonScoreModel_1.EmployeeEvaluationPersonScore, { id: ps.id }, { is_deleted: true, updated_by: createdBy });
|
|
227
|
+
await manager.update(EmployeeEvaluationAnswerModel_1.EmployeeEvaluationAnswers, { request_id: requestId, user_id: ps.user_id, is_deleted: false }, { is_deleted: true, updated_by: createdBy });
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
for (const emp of employees) {
|
|
231
|
+
const existingPerson = existingScores.find((p) => p.user_id === emp.user_id);
|
|
232
|
+
if (existingPerson) {
|
|
233
|
+
await manager.update(EmployeeEvaluationPersonScoreModel_1.EmployeeEvaluationPersonScore, { id: existingPerson.id }, { is_rca: Boolean(emp.is_rca), updated_by: createdBy });
|
|
234
|
+
await manager.update(EmployeeEvaluationAnswerModel_1.EmployeeEvaluationAnswers, { request_id: requestId, user_id: emp.user_id, is_deleted: false }, { is_deleted: true, updated_by: createdBy });
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
await manager.save(EmployeeEvaluationPersonScoreModel_1.EmployeeEvaluationPersonScore, manager.create(EmployeeEvaluationPersonScoreModel_1.EmployeeEvaluationPersonScore, {
|
|
238
|
+
request_id: requestId,
|
|
239
|
+
user_id: emp.user_id,
|
|
240
|
+
is_rca: Boolean(emp.is_rca),
|
|
241
|
+
us_feedback: null,
|
|
242
|
+
total_score: null,
|
|
243
|
+
created_by: createdBy,
|
|
244
|
+
is_deleted: false,
|
|
245
|
+
}));
|
|
246
|
+
}
|
|
247
|
+
if (emp.answers.length > 0) {
|
|
248
|
+
let personTotal = 0;
|
|
249
|
+
for (const ans of emp.answers) {
|
|
250
|
+
const qMeta = await manager.findOne(EvaluationFormQuestionModel_1.EvaluationFormQuestion, {
|
|
251
|
+
where: { id: ans.question_id, is_deleted: false },
|
|
252
|
+
});
|
|
253
|
+
const questionSectionId = qMeta?.form_section_id;
|
|
254
|
+
if (validateAnswers) {
|
|
255
|
+
if (!qMeta || questionSectionId == null || questionSectionId !== ans.section_id) {
|
|
256
|
+
throw new Error(`Invalid question ${ans.question_id} for section ${ans.section_id}`);
|
|
257
|
+
}
|
|
258
|
+
if (qMeta.max_score != null && ans.score > qMeta.max_score) {
|
|
259
|
+
throw new Error(`score ${ans.score} exceeds max_score ${qMeta.max_score} for question ${ans.question_id}`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else if (qMeta &&
|
|
263
|
+
qMeta.form_section_id != null &&
|
|
264
|
+
qMeta.form_section_id !== ans.section_id) {
|
|
265
|
+
throw new Error(`Invalid question ${ans.question_id} for section ${ans.section_id}`);
|
|
266
|
+
}
|
|
267
|
+
personTotal += ans.score;
|
|
268
|
+
await manager.save(EmployeeEvaluationAnswerModel_1.EmployeeEvaluationAnswers, manager.create(EmployeeEvaluationAnswerModel_1.EmployeeEvaluationAnswers, {
|
|
269
|
+
request_id: requestId,
|
|
270
|
+
user_id: emp.user_id,
|
|
271
|
+
form_id: formId,
|
|
272
|
+
section_id: ans.section_id,
|
|
273
|
+
question_id: ans.question_id,
|
|
274
|
+
score: ans.score,
|
|
275
|
+
remarks: ans.remarks ?? null,
|
|
276
|
+
created_by: createdBy,
|
|
277
|
+
is_deleted: false,
|
|
278
|
+
}));
|
|
279
|
+
}
|
|
280
|
+
await manager.update(EmployeeEvaluationPersonScoreModel_1.EmployeeEvaluationPersonScore, { request_id: requestId, user_id: emp.user_id, is_deleted: false }, { total_score: personTotal, updated_by: createdBy });
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
const personRows = await manager.find(EmployeeEvaluationPersonScoreModel_1.EmployeeEvaluationPersonScore, {
|
|
284
|
+
where: { request_id: requestId, is_deleted: false },
|
|
285
|
+
});
|
|
286
|
+
const scores = personRows.map((p) => p.total_score ?? 0);
|
|
287
|
+
const requestTotal = scores.reduce((a, b) => a + b, 0);
|
|
288
|
+
const average = personRows.length ? requestTotal / personRows.length : 0;
|
|
289
|
+
await manager.update(EmployeeEvaluationRequestModel_1.EmployeeEvaluationRequests, { id: requestId }, {
|
|
290
|
+
total_score: personRows.length ? requestTotal : null,
|
|
291
|
+
average_score: personRows.length ? average : null,
|
|
292
|
+
employee_count: personRows.length,
|
|
293
|
+
updated_by: createdBy,
|
|
294
|
+
});
|
|
295
|
+
return {
|
|
296
|
+
totalScore: personRows.length ? requestTotal : null,
|
|
297
|
+
averageScore: personRows.length ? average : null,
|
|
298
|
+
employeeCount: personRows.length,
|
|
299
|
+
};
|
|
300
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -411,7 +411,7 @@ export type { FmServicesNotificationConfigRecipient, CollectFmServicesNotificati
|
|
|
411
411
|
export * from './models/MoodleUsersModel';
|
|
412
412
|
export { EvaluationEligibilitySetting, EvaluationEligibilitySettingEmployee, } from './models/EvaluationEligibilitySettingModel';
|
|
413
413
|
export { isEvaluationEligibilityWindowOpen, isCalendarMonthInEligibilityRange, mmDdWindowsOverlap, mmDdSortKey, parseMonthDay, parseEligibilityDateRange, parseEvaluationEndDay, parseMonthRange, } from './helpers/evaluation-eligibility.utils';
|
|
414
|
-
export { DEFAULT_MAX_EMPLOYEES_PER_REQUEST, normalizeEmployeeSubmissions, normalizeEmployeeDraftSubmissions, resolveMaxEmployeesPerRequest, persistEmployeeEvaluationScores, } from './helpers/employee-evaluation-request.utils';
|
|
414
|
+
export { DEFAULT_MAX_EMPLOYEES_PER_REQUEST, normalizeEmployeeSubmissions, normalizeEmployeeDraftSubmissions, resolveMaxEmployeesPerRequest, persistEmployeeEvaluationScores, syncEmployeeEvaluationScores, } from './helpers/employee-evaluation-request.utils';
|
|
415
415
|
export type { EmployeeEvaluationSubmitAnswer, EmployeeEvaluationSubmitEmployee, NormalizedEmployeeSubmission, } from './helpers/employee-evaluation-request.utils';
|
|
416
416
|
export { EmployeeEvaluationRequests, EmployeeEvaluationRequestStatus, EmployeeEvaluationRoutingBucket, } from './models/EmployeeEvaluationRequestModel';
|
|
417
417
|
export { EmployeeEvaluation, EmployeeEvaluationUsFeedback } from './models/EmployeeEvaluationModel';
|
package/dist/index.js
CHANGED
|
@@ -15,9 +15,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
exports.collectFmServicesNotificationConfigRecipients = exports.ServicesNotificationTriggerType = exports.AppointmentWorkFlowStatus = exports.AppointmentMessageType = exports.AppointmentAttendeeStatus = exports.AppointmentApprovalStatus = exports.AppointmentAttendees = exports.AppointmentWorkFlow = exports.AppointmentRequestChat = exports.AppointmentRequestAttachment = exports.AppointmentApprovalDetails = exports.AppointmentRequestStatus = exports.AppointmentRequests = exports.TravelClass = exports.MissionTravelWorkFlowStatus = exports.MissionTravelApprovalStatus = exports.AllowanceRatio = exports.DecisionType = exports.MissionType = exports.MissionTravelStatus = exports.GatePassMessageType = exports.GatePassWorkFlowStatus = exports.GatePassApprovalStatus = exports.GatePassType = exports.GatePassRequestStatus = exports.SecurityDeptMessageType = exports.SecurityDeptAccessType = exports.SecurityDeptRequestStatus = exports.RetiredCardMessageType = exports.RetiredCardWorkFlowStatus = exports.RetiredCardApprovalStatus = exports.RetiredCardAccessType = exports.RetiredCardRequestStatus = exports.TitleCategory = exports.ProfileUpdateRequestStatus = exports.StayAfterHoursTransactionStatus = exports.StayAfterHoursTransaction = exports.StayAfterHoursBalance = exports.EarlyCheckoutTransactionStatus = exports.EarlyCheckoutTransaction = exports.EarlyCheckoutFrequency = exports.EarlyCheckoutConfiguration = exports.EarlyCheckoutBalance = exports.LeaveTransactionStatus = exports.LeaveTransaction = exports.LeaveConfigurationGrades = exports.enumFrequency = exports.LeaveConfiguration = exports.ParcelDepartmentCategory = exports.RegisterCandidateExperienceActivity = void 0;
|
|
18
|
-
exports.
|
|
19
|
-
exports.
|
|
20
|
-
exports.EvaluationFormQuestionType = exports.EvaluationFormQuestion = void 0;
|
|
18
|
+
exports.InitiatorInitiativeType = exports.InitiatorEmployeeNominationRequestStatus = exports.InitiatorEmployeeNominationRequests = exports.IpeGrievanceRequestAttachment = exports.IpeGrievanceMessageType = exports.IpeGrievanceRequestChat = exports.IpeGrievanceWorkFlowStatus = exports.IpeGrievanceWorkFlow = exports.IpeGrievanceApprovalStatus = exports.IpeGrievanceApprovalDetails = exports.IpeGrievancePeriodRating = exports.IpeGrievanceExemptionReason = exports.IpeGrievancePeriodType = exports.IpeGrievanceFinalEvaluationResult = exports.IpeGrievanceRequestStatus = exports.IpeGrievanceRequests = exports.EmployeeEvaluationRequestAttachment = exports.EmployeeEvaluationMessageType = exports.EmployeeEvaluationRequestChat = exports.EmployeeEvaluationWorkFlowStatus = exports.EmployeeEvaluationWorkFlow = exports.EmployeeEvaluationApprovalStatus = exports.EmployeeEvaluationApprovalDetails = exports.EmployeeEvaluationPersonScore = exports.EmployeeEvaluationAnswers = exports.EmployeeEvaluationUsFeedback = exports.EmployeeEvaluation = exports.EmployeeEvaluationRoutingBucket = exports.EmployeeEvaluationRequestStatus = exports.EmployeeEvaluationRequests = exports.syncEmployeeEvaluationScores = exports.persistEmployeeEvaluationScores = exports.resolveMaxEmployeesPerRequest = exports.normalizeEmployeeDraftSubmissions = exports.normalizeEmployeeSubmissions = exports.DEFAULT_MAX_EMPLOYEES_PER_REQUEST = exports.parseMonthRange = exports.parseEvaluationEndDay = exports.parseEligibilityDateRange = exports.parseMonthDay = exports.mmDdSortKey = exports.mmDdWindowsOverlap = exports.isCalendarMonthInEligibilityRange = exports.isEvaluationEligibilityWindowOpen = exports.EvaluationEligibilitySettingEmployee = exports.EvaluationEligibilitySetting = exports.isPortalAdminFromRequest = exports.userHasPortalAdminRole = exports.parsePortalUserIdFromRequest = exports.sendFmServicesNotificationConfigNotifications = void 0;
|
|
19
|
+
exports.EvaluationFormType = exports.EvaluationForm = exports.EmbassyEvaluationRequestAttachment = exports.EmbassyEvaluationMessageType = exports.EmbassyEvaluationRequestChat = exports.EmbassyEvaluationWorkFlowStatus = exports.EmbassyEvaluationWorkFlow = exports.EmbassyEvaluationApprovalStatus = exports.EmbassyEvaluationApprovalDetails = exports.EmbassyEvaluationRequestStatus = exports.EmbassyEvaluationRequests = exports.EmbassyEvaluationResponse = exports.EmbassyEvaluationAssignmentStatus = exports.EmbassyEvaluationAssignment = exports.EmbassyEvaluationCycleStatus = exports.EmbassyEvaluationCycle = exports.EmployeeOfMonthSupportNominationRequestAttachment = exports.EmployeeOfMonthSupportNominationMessageType = exports.EmployeeOfMonthSupportNominationRequestChat = exports.EmployeeOfMonthSupportNominationWorkFlowStatus = exports.EmployeeOfMonthSupportNominationWorkFlow = exports.EmployeeOfMonthSupportNominationApprovalStatus = exports.EmployeeOfMonthSupportNominationApprovalDetails = exports.EmployeeOfMonthSupportNominationRequestStatus = exports.EmployeeOfMonthSupportNominationRequests = exports.EmployeeOfMonthNominationRequestAttachment = exports.EmployeeOfMonthNominationMessageType = exports.EmployeeOfMonthNominationRequestChat = exports.EmployeeOfMonthNominationWorkFlowStatus = exports.EmployeeOfMonthNominationWorkFlow = exports.EmployeeOfMonthNominationApprovalStatus = exports.EmployeeOfMonthNominationApprovalDetails = exports.EmployeeOfMonthNominationRequestStatus = exports.EmployeeOfMonthNominationRequests = exports.InnovativeEmployeeNominationRequestAttachment = exports.InnovativeEmployeeNominationMessageType = exports.InnovativeEmployeeNominationRequestChat = exports.InnovativeEmployeeNominationWorkFlowStatus = exports.InnovativeEmployeeNominationWorkFlow = exports.InnovativeEmployeeNominationApprovalStatus = exports.InnovativeEmployeeNominationApprovalDetails = exports.InnovativeEmployeeNominationRequestStatus = exports.InnovativeEmployeeNominationRequests = exports.InitiatorEmployeeNominationRequestAttachment = exports.InitiatorEmployeeNominationMessageType = exports.InitiatorEmployeeNominationRequestChat = exports.InitiatorEmployeeNominationWorkFlowStatus = exports.InitiatorEmployeeNominationWorkFlow = exports.InitiatorEmployeeNominationApprovalStatus = exports.InitiatorEmployeeNominationApprovalDetails = void 0;
|
|
20
|
+
exports.EvaluationFormQuestionType = exports.EvaluationFormQuestion = exports.EvaluationFormSection = void 0;
|
|
21
21
|
__exportStar(require("./models/user"), exports);
|
|
22
22
|
__exportStar(require("./models/role"), exports);
|
|
23
23
|
__exportStar(require("./models/user-sessions"), exports);
|
|
@@ -520,6 +520,7 @@ Object.defineProperty(exports, "normalizeEmployeeSubmissions", { enumerable: tru
|
|
|
520
520
|
Object.defineProperty(exports, "normalizeEmployeeDraftSubmissions", { enumerable: true, get: function () { return employee_evaluation_request_utils_1.normalizeEmployeeDraftSubmissions; } });
|
|
521
521
|
Object.defineProperty(exports, "resolveMaxEmployeesPerRequest", { enumerable: true, get: function () { return employee_evaluation_request_utils_1.resolveMaxEmployeesPerRequest; } });
|
|
522
522
|
Object.defineProperty(exports, "persistEmployeeEvaluationScores", { enumerable: true, get: function () { return employee_evaluation_request_utils_1.persistEmployeeEvaluationScores; } });
|
|
523
|
+
Object.defineProperty(exports, "syncEmployeeEvaluationScores", { enumerable: true, get: function () { return employee_evaluation_request_utils_1.syncEmployeeEvaluationScores; } });
|
|
523
524
|
var EmployeeEvaluationRequestModel_1 = require("./models/EmployeeEvaluationRequestModel");
|
|
524
525
|
Object.defineProperty(exports, "EmployeeEvaluationRequests", { enumerable: true, get: function () { return EmployeeEvaluationRequestModel_1.EmployeeEvaluationRequests; } });
|
|
525
526
|
Object.defineProperty(exports, "EmployeeEvaluationRequestStatus", { enumerable: true, get: function () { return EmployeeEvaluationRequestModel_1.EmployeeEvaluationRequestStatus; } });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platform-modules/foreign-ministry",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.358",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@platform-modules/foreign-ministry": "^1.3.
|
|
25
|
+
"@platform-modules/foreign-ministry": "^1.3.355",
|
|
26
26
|
"moment-timezone": "^0.6.0",
|
|
27
27
|
"pg": "^8.16.0",
|
|
28
28
|
"typeorm": "^0.3.17"
|
|
@@ -57,7 +57,7 @@ DECLARE
|
|
|
57
57
|
v_dyn_keys TEXT[];
|
|
58
58
|
v_dyn_labels TEXT[];
|
|
59
59
|
v_common_labels TEXT[] := ARRAY[
|
|
60
|
-
'
|
|
60
|
+
'Request ID', 'User', 'Status', 'Created At',
|
|
61
61
|
'Created By', 'Department', 'Section'
|
|
62
62
|
];
|
|
63
63
|
v_headers_labels TEXT[];
|
|
@@ -167,7 +167,6 @@ BEGIN
|
|
|
167
167
|
USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text
|
|
168
168
|
LOOP
|
|
169
169
|
v_cells := ARRAY[
|
|
170
|
-
COALESCE(v_row.sla_request_id::TEXT, ''),
|
|
171
170
|
COALESCE(v_row.request_id::TEXT, ''),
|
|
172
171
|
COALESCE(v_row.user_name, ''),
|
|
173
172
|
COALESCE(v_row.status, ''),
|
|
@@ -180,12 +180,12 @@ DECLARE
|
|
|
180
180
|
v_dyn_keys TEXT[];
|
|
181
181
|
v_dyn_labels TEXT[];
|
|
182
182
|
v_common_req_labels TEXT[] := ARRAY[
|
|
183
|
-
'
|
|
183
|
+
'Request ID', 'User', 'Status', 'Created At',
|
|
184
184
|
'Created By', 'Department', 'Section'
|
|
185
185
|
];
|
|
186
186
|
v_approval_headers TEXT[] := ARRAY[
|
|
187
187
|
'Request ID', 'Service ID', 'Service Name', 'Sub Service ID', 'Sub Service Name',
|
|
188
|
-
'
|
|
188
|
+
'Level', 'Approval Status', 'Request Status',
|
|
189
189
|
'Approval Role ID', 'Approval Role Name', 'Approval Department ID', 'Approval Department Name',
|
|
190
190
|
'Approval Section ID', 'Approval Section Name',
|
|
191
191
|
'Approver User ID', 'Approver User Name', 'Delegate User ID', 'Delegate User Name',
|
|
@@ -292,7 +292,6 @@ BEGIN
|
|
|
292
292
|
USING p_request_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text
|
|
293
293
|
LOOP
|
|
294
294
|
v_cells := ARRAY[
|
|
295
|
-
COALESCE(v_row.sla_request_id::TEXT, ''),
|
|
296
295
|
COALESCE(v_row.request_id::TEXT, ''),
|
|
297
296
|
COALESCE(v_row.user_name, ''),
|
|
298
297
|
COALESCE(v_row.status, ''),
|
|
@@ -394,8 +393,6 @@ BEGIN
|
|
|
394
393
|
COALESCE(v_approval.service_name, ''),
|
|
395
394
|
COALESCE(v_approval.sub_service_id::TEXT, ''),
|
|
396
395
|
COALESCE(v_approval.sub_service_name, ''),
|
|
397
|
-
COALESCE(v_approval.sla_approval_id::TEXT, ''),
|
|
398
|
-
COALESCE(v_approval.source_approval_id::TEXT, ''),
|
|
399
396
|
COALESCE(v_approval.level::TEXT, ''),
|
|
400
397
|
COALESCE(v_approval.approval_status, ''),
|
|
401
398
|
COALESCE(v_approval.request_status, ''),
|
|
@@ -574,7 +574,7 @@ DECLARE
|
|
|
574
574
|
v_sheet_label TEXT;
|
|
575
575
|
v_headers_labels TEXT[] := ARRAY[
|
|
576
576
|
'Request ID', 'Service ID', 'Service Name', 'Sub Service ID', 'Sub Service Name',
|
|
577
|
-
'
|
|
577
|
+
'Level', 'Approval Status', 'Request Status',
|
|
578
578
|
'Approval Role ID', 'Approval Role Name', 'Approval Department ID', 'Approval Department Name',
|
|
579
579
|
'Approval Section ID', 'Approval Section Name',
|
|
580
580
|
'Approver User ID', 'Approver User Name', 'Delegate User ID', 'Delegate User Name',
|
|
@@ -661,8 +661,6 @@ BEGIN
|
|
|
661
661
|
COALESCE(v_approval.service_name, ''),
|
|
662
662
|
COALESCE(v_approval.sub_service_id::TEXT, ''),
|
|
663
663
|
COALESCE(v_approval.sub_service_name, ''),
|
|
664
|
-
COALESCE(v_approval.sla_approval_id::TEXT, ''),
|
|
665
|
-
COALESCE(v_approval.source_approval_id::TEXT, ''),
|
|
666
664
|
COALESCE(v_approval.level::TEXT, ''),
|
|
667
665
|
COALESCE(v_approval.approval_status, ''),
|
|
668
666
|
COALESCE(v_approval.request_status, ''),
|
|
@@ -733,7 +731,7 @@ DECLARE
|
|
|
733
731
|
v_dyn_keys TEXT[];
|
|
734
732
|
v_dyn_labels TEXT[];
|
|
735
733
|
v_common_labels TEXT[] := ARRAY[
|
|
736
|
-
'
|
|
734
|
+
'Request ID', 'User', 'Status', 'Created At',
|
|
737
735
|
'Created By', 'Department', 'Section'
|
|
738
736
|
];
|
|
739
737
|
v_headers_labels TEXT[];
|
|
@@ -839,7 +837,6 @@ BEGIN
|
|
|
839
837
|
USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text
|
|
840
838
|
LOOP
|
|
841
839
|
v_cells := ARRAY[
|
|
842
|
-
COALESCE(v_row.sla_request_id::TEXT, ''),
|
|
843
840
|
COALESCE(v_row.request_id::TEXT, ''),
|
|
844
841
|
COALESCE(v_row.user_name, ''),
|
|
845
842
|
COALESCE(v_row.status, ''),
|
|
@@ -256,3 +256,130 @@ export async function persistEmployeeEvaluationScores(
|
|
|
256
256
|
|
|
257
257
|
return { totalScore: requestTotal, averageScore, employeeCount };
|
|
258
258
|
}
|
|
259
|
+
|
|
260
|
+
/** Sync person_scores/answers on an existing request (draft update or draft promotion). */
|
|
261
|
+
export async function syncEmployeeEvaluationScores(
|
|
262
|
+
manager: EntityManager,
|
|
263
|
+
opts: {
|
|
264
|
+
requestId: number;
|
|
265
|
+
formId: number;
|
|
266
|
+
createdBy: string;
|
|
267
|
+
employees: NormalizedEmployeeSubmission[];
|
|
268
|
+
validateAnswers?: boolean;
|
|
269
|
+
}
|
|
270
|
+
): Promise<{ totalScore: number | null; averageScore: number | null; employeeCount: number }> {
|
|
271
|
+
const { requestId, formId, createdBy, employees, validateAnswers = false } = opts;
|
|
272
|
+
const payloadUserIds = new Set(employees.map((e) => e.user_id));
|
|
273
|
+
|
|
274
|
+
const existingScores = await manager.find(EmployeeEvaluationPersonScore, {
|
|
275
|
+
where: { request_id: requestId, is_deleted: false },
|
|
276
|
+
});
|
|
277
|
+
for (const ps of existingScores) {
|
|
278
|
+
if (!payloadUserIds.has(ps.user_id)) {
|
|
279
|
+
await manager.update(
|
|
280
|
+
EmployeeEvaluationPersonScore,
|
|
281
|
+
{ id: ps.id },
|
|
282
|
+
{ is_deleted: true, updated_by: createdBy }
|
|
283
|
+
);
|
|
284
|
+
await manager.update(
|
|
285
|
+
EmployeeEvaluationAnswers,
|
|
286
|
+
{ request_id: requestId, user_id: ps.user_id, is_deleted: false },
|
|
287
|
+
{ is_deleted: true, updated_by: createdBy }
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
for (const emp of employees) {
|
|
293
|
+
const existingPerson = existingScores.find((p) => p.user_id === emp.user_id);
|
|
294
|
+
if (existingPerson) {
|
|
295
|
+
await manager.update(
|
|
296
|
+
EmployeeEvaluationPersonScore,
|
|
297
|
+
{ id: existingPerson.id },
|
|
298
|
+
{ is_rca: Boolean(emp.is_rca), updated_by: createdBy }
|
|
299
|
+
);
|
|
300
|
+
await manager.update(
|
|
301
|
+
EmployeeEvaluationAnswers,
|
|
302
|
+
{ request_id: requestId, user_id: emp.user_id, is_deleted: false },
|
|
303
|
+
{ is_deleted: true, updated_by: createdBy }
|
|
304
|
+
);
|
|
305
|
+
} else {
|
|
306
|
+
await manager.save(
|
|
307
|
+
EmployeeEvaluationPersonScore,
|
|
308
|
+
manager.create(EmployeeEvaluationPersonScore, {
|
|
309
|
+
request_id: requestId,
|
|
310
|
+
user_id: emp.user_id,
|
|
311
|
+
is_rca: Boolean(emp.is_rca),
|
|
312
|
+
us_feedback: null,
|
|
313
|
+
total_score: null,
|
|
314
|
+
created_by: createdBy,
|
|
315
|
+
is_deleted: false,
|
|
316
|
+
})
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (emp.answers.length > 0) {
|
|
321
|
+
let personTotal = 0;
|
|
322
|
+
for (const ans of emp.answers) {
|
|
323
|
+
const qMeta = await manager.findOne(EvaluationFormQuestion, {
|
|
324
|
+
where: { id: ans.question_id, is_deleted: false },
|
|
325
|
+
});
|
|
326
|
+
const questionSectionId = qMeta?.form_section_id;
|
|
327
|
+
if (validateAnswers) {
|
|
328
|
+
if (!qMeta || questionSectionId == null || questionSectionId !== ans.section_id) {
|
|
329
|
+
throw new Error(`Invalid question ${ans.question_id} for section ${ans.section_id}`);
|
|
330
|
+
}
|
|
331
|
+
if (qMeta.max_score != null && ans.score > qMeta.max_score) {
|
|
332
|
+
throw new Error(
|
|
333
|
+
`score ${ans.score} exceeds max_score ${qMeta.max_score} for question ${ans.question_id}`
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
} else if (
|
|
337
|
+
qMeta &&
|
|
338
|
+
qMeta.form_section_id != null &&
|
|
339
|
+
qMeta.form_section_id !== ans.section_id
|
|
340
|
+
) {
|
|
341
|
+
throw new Error(`Invalid question ${ans.question_id} for section ${ans.section_id}`);
|
|
342
|
+
}
|
|
343
|
+
personTotal += ans.score;
|
|
344
|
+
await manager.save(
|
|
345
|
+
EmployeeEvaluationAnswers,
|
|
346
|
+
manager.create(EmployeeEvaluationAnswers, {
|
|
347
|
+
request_id: requestId,
|
|
348
|
+
user_id: emp.user_id,
|
|
349
|
+
form_id: formId,
|
|
350
|
+
section_id: ans.section_id,
|
|
351
|
+
question_id: ans.question_id,
|
|
352
|
+
score: ans.score,
|
|
353
|
+
remarks: ans.remarks ?? null,
|
|
354
|
+
created_by: createdBy,
|
|
355
|
+
is_deleted: false,
|
|
356
|
+
})
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
await manager.update(
|
|
360
|
+
EmployeeEvaluationPersonScore,
|
|
361
|
+
{ request_id: requestId, user_id: emp.user_id, is_deleted: false },
|
|
362
|
+
{ total_score: personTotal, updated_by: createdBy }
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const personRows = await manager.find(EmployeeEvaluationPersonScore, {
|
|
368
|
+
where: { request_id: requestId, is_deleted: false },
|
|
369
|
+
});
|
|
370
|
+
const scores = personRows.map((p) => p.total_score ?? 0);
|
|
371
|
+
const requestTotal = scores.reduce((a, b) => a + b, 0);
|
|
372
|
+
const average = personRows.length ? requestTotal / personRows.length : 0;
|
|
373
|
+
await manager.update(EmployeeEvaluationRequests, { id: requestId }, {
|
|
374
|
+
total_score: personRows.length ? requestTotal : null,
|
|
375
|
+
average_score: personRows.length ? average : null,
|
|
376
|
+
employee_count: personRows.length,
|
|
377
|
+
updated_by: createdBy,
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
return {
|
|
381
|
+
totalScore: personRows.length ? requestTotal : null,
|
|
382
|
+
averageScore: personRows.length ? average : null,
|
|
383
|
+
employeeCount: personRows.length,
|
|
384
|
+
};
|
|
385
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -463,6 +463,7 @@ export {
|
|
|
463
463
|
normalizeEmployeeDraftSubmissions,
|
|
464
464
|
resolveMaxEmployeesPerRequest,
|
|
465
465
|
persistEmployeeEvaluationScores,
|
|
466
|
+
syncEmployeeEvaluationScores,
|
|
466
467
|
} from './helpers/employee-evaluation-request.utils';
|
|
467
468
|
export type {
|
|
468
469
|
EmployeeEvaluationSubmitAnswer,
|