@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.
@@ -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.InitiatorEmployeeNominationApprovalDetails = 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.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.EvaluationFormSection = 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 = void 0;
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.355",
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.338",
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
- 'SLA Request ID', 'Request ID', 'User', 'Status', 'Created At',
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
- 'SLA Request ID', 'Request ID', 'User', 'Status', 'Created At',
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
- 'SLA Approval ID', 'Source Approval ID', 'Level', 'Approval Status', 'Request Status',
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
- 'SLA Approval ID', 'Source Approval ID', 'Level', 'Approval Status', 'Request Status',
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
- 'SLA Request ID', 'Request ID', 'User', 'Status', 'Created At',
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,