@platform-modules/foreign-ministry 1.3.342 → 1.3.351
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/data-source.js +2 -0
- package/dist/helpers/employee-evaluation-request.utils.d.ts +6 -0
- package/dist/helpers/employee-evaluation-request.utils.js +83 -5
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -3
- package/dist/models/ChatbotQnsAnsMappingModel.d.ts +8 -0
- package/dist/models/ChatbotQnsAnsMappingModel.js +40 -0
- package/dist/models/EmployeeEvaluationRequestModel.d.ts +1 -0
- package/dist/models/EmployeeEvaluationRequestModel.js +4 -0
- package/dist/models/SlaApprovalsViewModel.js +8 -1
- package/package.json +1 -1
- package/sql/add_employee_evaluation_requests_is_draft.sql +2 -0
- package/sql/create_chatbot_qns_ans_mapping.sql +25 -0
- package/sql/sla_reports_admin_procedures.sql +24 -6
- package/sql/sla_reports_approvals_workbook.sql +47 -0
- package/sql/vw_sla_approvals.sql +8 -1
- package/src/data-source.ts +2 -0
- package/src/helpers/employee-evaluation-request.utils.ts +87 -7
- package/src/index.ts +2 -0
- package/src/models/ChatbotQnsAnsMappingModel.ts +21 -0
- package/src/models/EmployeeEvaluationRequestModel.ts +3 -0
- package/src/models/SlaApprovalsViewModel.ts +8 -1
package/dist/data-source.js
CHANGED
|
@@ -332,6 +332,7 @@ const EmbassyEvaluationAttachmentModel_1 = require("./models/EmbassyEvaluationAt
|
|
|
332
332
|
const SlaRequestModel_1 = require("./models/SlaRequestModel");
|
|
333
333
|
const ServiceSlaApprovalModel_1 = require("./models/ServiceSlaApprovalModel");
|
|
334
334
|
const SlaConfigModel_1 = require("./models/SlaConfigModel");
|
|
335
|
+
const ChatbotQnsAnsMappingModel_1 = require("./models/ChatbotQnsAnsMappingModel");
|
|
335
336
|
exports.AppDataSource = new typeorm_1.DataSource({
|
|
336
337
|
type: 'postgres',
|
|
337
338
|
host: process.env.DB_HOST || 'localhost',
|
|
@@ -670,5 +671,6 @@ exports.AppDataSource = new typeorm_1.DataSource({
|
|
|
670
671
|
SlaRequestModel_1.SlaRequest,
|
|
671
672
|
ServiceSlaApprovalModel_1.ServiceSlaApproval,
|
|
672
673
|
SlaConfigModel_1.SlaConfig,
|
|
674
|
+
ChatbotQnsAnsMappingModel_1.ChatbotQnsAnsMapping,
|
|
673
675
|
],
|
|
674
676
|
});
|
|
@@ -16,6 +16,11 @@ export declare function normalizeEmployeeSubmissions(raw: unknown): {
|
|
|
16
16
|
employees: NormalizedEmployeeSubmission[];
|
|
17
17
|
error?: string;
|
|
18
18
|
};
|
|
19
|
+
/** Relaxed validation for draft saves — employees/answers may be empty or partial. */
|
|
20
|
+
export declare function normalizeEmployeeDraftSubmissions(raw: unknown): {
|
|
21
|
+
employees: NormalizedEmployeeSubmission[];
|
|
22
|
+
error?: string;
|
|
23
|
+
};
|
|
19
24
|
/** Resolve max employees from active exception cycle for the evaluation month. */
|
|
20
25
|
export declare function resolveMaxEmployeesPerRequest(manager: EntityManager, month: number): Promise<number>;
|
|
21
26
|
export declare function persistEmployeeEvaluationScores(manager: EntityManager, opts: {
|
|
@@ -23,6 +28,7 @@ export declare function persistEmployeeEvaluationScores(manager: EntityManager,
|
|
|
23
28
|
formId: number;
|
|
24
29
|
createdBy: string;
|
|
25
30
|
employees: NormalizedEmployeeSubmission[];
|
|
31
|
+
isDraft?: boolean;
|
|
26
32
|
}): Promise<{
|
|
27
33
|
totalScore: number;
|
|
28
34
|
averageScore: number;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DEFAULT_MAX_EMPLOYEES_PER_REQUEST = void 0;
|
|
4
4
|
exports.normalizeEmployeeSubmissions = normalizeEmployeeSubmissions;
|
|
5
|
+
exports.normalizeEmployeeDraftSubmissions = normalizeEmployeeDraftSubmissions;
|
|
5
6
|
exports.resolveMaxEmployeesPerRequest = resolveMaxEmployeesPerRequest;
|
|
6
7
|
exports.persistEmployeeEvaluationScores = persistEmployeeEvaluationScores;
|
|
7
8
|
const EmployeeEvaluationAnswerModel_1 = require("../models/EmployeeEvaluationAnswerModel");
|
|
@@ -69,6 +70,78 @@ function normalizeEmployeeSubmissions(raw) {
|
|
|
69
70
|
}
|
|
70
71
|
return { employees };
|
|
71
72
|
}
|
|
73
|
+
/** Relaxed validation for draft saves — employees/answers may be empty or partial. */
|
|
74
|
+
function normalizeEmployeeDraftSubmissions(raw) {
|
|
75
|
+
if (raw == null || raw === undefined) {
|
|
76
|
+
return { employees: [] };
|
|
77
|
+
}
|
|
78
|
+
if (!Array.isArray(raw)) {
|
|
79
|
+
return { employees: [], error: 'employees must be an array when provided' };
|
|
80
|
+
}
|
|
81
|
+
if (raw.length === 0) {
|
|
82
|
+
return { employees: [] };
|
|
83
|
+
}
|
|
84
|
+
const seen = new Set();
|
|
85
|
+
const employees = [];
|
|
86
|
+
for (const item of raw) {
|
|
87
|
+
if (item == null || typeof item !== 'object') {
|
|
88
|
+
return { employees: [], error: 'Each employee entry must be an object' };
|
|
89
|
+
}
|
|
90
|
+
const o = item;
|
|
91
|
+
const user_id = Number(o.user_id ?? o.employee_id);
|
|
92
|
+
if (!Number.isFinite(user_id) || user_id <= 0) {
|
|
93
|
+
return { employees: [], error: 'Each employee must have a valid user_id' };
|
|
94
|
+
}
|
|
95
|
+
if (seen.has(user_id)) {
|
|
96
|
+
return { employees: [], error: `Duplicate user_id ${user_id} in employees list` };
|
|
97
|
+
}
|
|
98
|
+
seen.add(user_id);
|
|
99
|
+
const answersRaw = o.answers;
|
|
100
|
+
const answers = [];
|
|
101
|
+
if (answersRaw != null) {
|
|
102
|
+
if (!Array.isArray(answersRaw)) {
|
|
103
|
+
return { employees: [], error: `Employee ${user_id} answers must be an array when provided` };
|
|
104
|
+
}
|
|
105
|
+
const qSeen = new Set();
|
|
106
|
+
for (const a of answersRaw) {
|
|
107
|
+
if (a == null || typeof a !== 'object')
|
|
108
|
+
continue;
|
|
109
|
+
const ar = a;
|
|
110
|
+
const section_id = Number(ar.section_id);
|
|
111
|
+
const question_id = Number(ar.question_id);
|
|
112
|
+
const score = Number(ar.score);
|
|
113
|
+
if (!Number.isFinite(section_id) || !Number.isFinite(question_id)) {
|
|
114
|
+
return {
|
|
115
|
+
employees: [],
|
|
116
|
+
error: `section_id and question_id required for employee ${user_id} when answer is provided`,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (!Number.isFinite(score) || score < 0) {
|
|
120
|
+
return {
|
|
121
|
+
employees: [],
|
|
122
|
+
error: `score must be a non-negative number for employee ${user_id}, question ${question_id}`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
if (qSeen.has(question_id)) {
|
|
126
|
+
return { employees: [], error: `Duplicate question_id ${question_id} for employee ${user_id}` };
|
|
127
|
+
}
|
|
128
|
+
qSeen.add(question_id);
|
|
129
|
+
answers.push({
|
|
130
|
+
section_id,
|
|
131
|
+
question_id,
|
|
132
|
+
score,
|
|
133
|
+
remarks: ar.remarks != null ? String(ar.remarks) : null,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
employees.push({
|
|
138
|
+
user_id,
|
|
139
|
+
is_rca: o.is_rca !== undefined ? Boolean(o.is_rca) : false,
|
|
140
|
+
answers,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return { employees };
|
|
144
|
+
}
|
|
72
145
|
/** Resolve max employees from active exception cycle for the evaluation month. */
|
|
73
146
|
async function resolveMaxEmployeesPerRequest(manager, month) {
|
|
74
147
|
const rows = await manager
|
|
@@ -86,7 +159,7 @@ async function resolveMaxEmployeesPerRequest(manager, month) {
|
|
|
86
159
|
return exports.DEFAULT_MAX_EMPLOYEES_PER_REQUEST;
|
|
87
160
|
}
|
|
88
161
|
async function persistEmployeeEvaluationScores(manager, opts) {
|
|
89
|
-
const { requestId, formId, createdBy, employees } = opts;
|
|
162
|
+
const { requestId, formId, createdBy, employees, isDraft = false } = opts;
|
|
90
163
|
let requestTotal = 0;
|
|
91
164
|
for (const emp of employees) {
|
|
92
165
|
let personTotal = 0;
|
|
@@ -95,11 +168,16 @@ async function persistEmployeeEvaluationScores(manager, opts) {
|
|
|
95
168
|
where: { id: ans.question_id, is_deleted: false },
|
|
96
169
|
});
|
|
97
170
|
const questionSectionId = qMeta?.form_section_id;
|
|
98
|
-
if (!
|
|
99
|
-
|
|
171
|
+
if (!isDraft) {
|
|
172
|
+
if (!qMeta || questionSectionId == null || questionSectionId !== ans.section_id) {
|
|
173
|
+
throw new Error(`Invalid question ${ans.question_id} for section ${ans.section_id}`);
|
|
174
|
+
}
|
|
175
|
+
if (qMeta.max_score != null && ans.score > qMeta.max_score) {
|
|
176
|
+
throw new Error(`score ${ans.score} exceeds max_score ${qMeta.max_score} for question ${ans.question_id}`);
|
|
177
|
+
}
|
|
100
178
|
}
|
|
101
|
-
if (qMeta.
|
|
102
|
-
throw new Error(`
|
|
179
|
+
else if (qMeta && qMeta.form_section_id != null && qMeta.form_section_id !== ans.section_id) {
|
|
180
|
+
throw new Error(`Invalid question ${ans.question_id} for section ${ans.section_id}`);
|
|
103
181
|
}
|
|
104
182
|
personTotal += ans.score;
|
|
105
183
|
await manager.save(EmployeeEvaluationAnswerModel_1.EmployeeEvaluationAnswers, manager.create(EmployeeEvaluationAnswerModel_1.EmployeeEvaluationAnswers, {
|
package/dist/index.d.ts
CHANGED
|
@@ -98,6 +98,7 @@ export * from './models/UpdateAttendanceWorkflowModel';
|
|
|
98
98
|
export * from './models/SlaRequestModel';
|
|
99
99
|
export * from './models/ServiceSlaApprovalModel';
|
|
100
100
|
export * from './models/SlaConfigModel';
|
|
101
|
+
export * from './models/ChatbotQnsAnsMappingModel';
|
|
101
102
|
export * from './models/GeneralServiceRequestsModel';
|
|
102
103
|
export * from './models/GeneralServiceApprovalsModel';
|
|
103
104
|
export * from './models/GeneralServiceWorkFlowModel';
|
|
@@ -410,7 +411,7 @@ export type { FmServicesNotificationConfigRecipient, CollectFmServicesNotificati
|
|
|
410
411
|
export * from './models/MoodleUsersModel';
|
|
411
412
|
export { EvaluationEligibilitySetting, EvaluationEligibilitySettingEmployee, } from './models/EvaluationEligibilitySettingModel';
|
|
412
413
|
export { isEvaluationEligibilityWindowOpen, isCalendarMonthInEligibilityRange, mmDdWindowsOverlap, mmDdSortKey, parseMonthDay, parseEligibilityDateRange, parseEvaluationEndDay, parseMonthRange, } from './helpers/evaluation-eligibility.utils';
|
|
413
|
-
export { DEFAULT_MAX_EMPLOYEES_PER_REQUEST, normalizeEmployeeSubmissions, resolveMaxEmployeesPerRequest, persistEmployeeEvaluationScores, } from './helpers/employee-evaluation-request.utils';
|
|
414
|
+
export { DEFAULT_MAX_EMPLOYEES_PER_REQUEST, normalizeEmployeeSubmissions, normalizeEmployeeDraftSubmissions, resolveMaxEmployeesPerRequest, persistEmployeeEvaluationScores, } from './helpers/employee-evaluation-request.utils';
|
|
414
415
|
export type { EmployeeEvaluationSubmitAnswer, EmployeeEvaluationSubmitEmployee, NormalizedEmployeeSubmission, } from './helpers/employee-evaluation-request.utils';
|
|
415
416
|
export { EmployeeEvaluationRequests, EmployeeEvaluationRequestStatus, EmployeeEvaluationRoutingBucket, } from './models/EmployeeEvaluationRequestModel';
|
|
416
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 = 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;
|
|
21
21
|
__exportStar(require("./models/user"), exports);
|
|
22
22
|
__exportStar(require("./models/role"), exports);
|
|
23
23
|
__exportStar(require("./models/user-sessions"), exports);
|
|
@@ -118,6 +118,7 @@ __exportStar(require("./models/UpdateAttendanceWorkflowModel"), exports);
|
|
|
118
118
|
__exportStar(require("./models/SlaRequestModel"), exports);
|
|
119
119
|
__exportStar(require("./models/ServiceSlaApprovalModel"), exports);
|
|
120
120
|
__exportStar(require("./models/SlaConfigModel"), exports);
|
|
121
|
+
__exportStar(require("./models/ChatbotQnsAnsMappingModel"), exports);
|
|
121
122
|
__exportStar(require("./models/GeneralServiceRequestsModel"), exports);
|
|
122
123
|
__exportStar(require("./models/GeneralServiceApprovalsModel"), exports);
|
|
123
124
|
__exportStar(require("./models/GeneralServiceWorkFlowModel"), exports);
|
|
@@ -516,6 +517,7 @@ Object.defineProperty(exports, "parseMonthRange", { enumerable: true, get: funct
|
|
|
516
517
|
var employee_evaluation_request_utils_1 = require("./helpers/employee-evaluation-request.utils");
|
|
517
518
|
Object.defineProperty(exports, "DEFAULT_MAX_EMPLOYEES_PER_REQUEST", { enumerable: true, get: function () { return employee_evaluation_request_utils_1.DEFAULT_MAX_EMPLOYEES_PER_REQUEST; } });
|
|
518
519
|
Object.defineProperty(exports, "normalizeEmployeeSubmissions", { enumerable: true, get: function () { return employee_evaluation_request_utils_1.normalizeEmployeeSubmissions; } });
|
|
520
|
+
Object.defineProperty(exports, "normalizeEmployeeDraftSubmissions", { enumerable: true, get: function () { return employee_evaluation_request_utils_1.normalizeEmployeeDraftSubmissions; } });
|
|
519
521
|
Object.defineProperty(exports, "resolveMaxEmployeesPerRequest", { enumerable: true, get: function () { return employee_evaluation_request_utils_1.resolveMaxEmployeesPerRequest; } });
|
|
520
522
|
Object.defineProperty(exports, "persistEmployeeEvaluationScores", { enumerable: true, get: function () { return employee_evaluation_request_utils_1.persistEmployeeEvaluationScores; } });
|
|
521
523
|
var EmployeeEvaluationRequestModel_1 = require("./models/EmployeeEvaluationRequestModel");
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BaseModel } from "./BaseModel";
|
|
2
|
+
export declare class ChatbotQnsAnsMapping extends BaseModel {
|
|
3
|
+
service_id: number;
|
|
4
|
+
sub_service_id: number;
|
|
5
|
+
question: Record<string, unknown> | unknown[];
|
|
6
|
+
answer: Record<string, unknown> | unknown[];
|
|
7
|
+
constructor();
|
|
8
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ChatbotQnsAnsMapping = void 0;
|
|
13
|
+
const typeorm_1 = require("typeorm");
|
|
14
|
+
const BaseModel_1 = require("./BaseModel");
|
|
15
|
+
let ChatbotQnsAnsMapping = class ChatbotQnsAnsMapping extends BaseModel_1.BaseModel {
|
|
16
|
+
constructor() {
|
|
17
|
+
super();
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
exports.ChatbotQnsAnsMapping = ChatbotQnsAnsMapping;
|
|
21
|
+
__decorate([
|
|
22
|
+
(0, typeorm_1.Column)({ type: "int", nullable: false }),
|
|
23
|
+
__metadata("design:type", Number)
|
|
24
|
+
], ChatbotQnsAnsMapping.prototype, "service_id", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, typeorm_1.Column)({ type: "int", nullable: false }),
|
|
27
|
+
__metadata("design:type", Number)
|
|
28
|
+
], ChatbotQnsAnsMapping.prototype, "sub_service_id", void 0);
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, typeorm_1.Column)({ type: "jsonb", nullable: false }),
|
|
31
|
+
__metadata("design:type", Object)
|
|
32
|
+
], ChatbotQnsAnsMapping.prototype, "question", void 0);
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, typeorm_1.Column)({ type: "jsonb", nullable: false }),
|
|
35
|
+
__metadata("design:type", Object)
|
|
36
|
+
], ChatbotQnsAnsMapping.prototype, "answer", void 0);
|
|
37
|
+
exports.ChatbotQnsAnsMapping = ChatbotQnsAnsMapping = __decorate([
|
|
38
|
+
(0, typeorm_1.Entity)({ name: "chatbot_qns_ans_mapping" }),
|
|
39
|
+
__metadata("design:paramtypes", [])
|
|
40
|
+
], ChatbotQnsAnsMapping);
|
|
@@ -34,6 +34,7 @@ export declare class EmployeeEvaluationRequests extends BaseModel {
|
|
|
34
34
|
total_score: number | null;
|
|
35
35
|
average_score: number | null;
|
|
36
36
|
employee_count: number;
|
|
37
|
+
is_draft: boolean;
|
|
37
38
|
/** Form structure snapshot at request creation (sections/questions). */
|
|
38
39
|
dynamic_evaluation_form: Record<string, unknown> | null;
|
|
39
40
|
}
|
|
@@ -111,6 +111,10 @@ __decorate([
|
|
|
111
111
|
(0, typeorm_1.Column)({ type: 'int', default: 0, nullable: false }),
|
|
112
112
|
__metadata("design:type", Number)
|
|
113
113
|
], EmployeeEvaluationRequests.prototype, "employee_count", void 0);
|
|
114
|
+
__decorate([
|
|
115
|
+
(0, typeorm_1.Column)({ type: 'boolean', default: false, nullable: false }),
|
|
116
|
+
__metadata("design:type", Boolean)
|
|
117
|
+
], EmployeeEvaluationRequests.prototype, "is_draft", void 0);
|
|
114
118
|
__decorate([
|
|
115
119
|
(0, typeorm_1.Column)({ type: 'jsonb', nullable: true }),
|
|
116
120
|
__metadata("design:type", Object)
|
|
@@ -40,7 +40,14 @@ SELECT
|
|
|
40
40
|
sa.updated_at AS updated_at
|
|
41
41
|
FROM sla_approval sa
|
|
42
42
|
INNER JOIN sla_requests sr
|
|
43
|
-
ON sr.
|
|
43
|
+
ON sr.id = (
|
|
44
|
+
SELECT MIN(sr2.id)
|
|
45
|
+
FROM sla_requests sr2
|
|
46
|
+
WHERE sr2.request_id = sa.request_id
|
|
47
|
+
AND COALESCE(sr2.is_deleted, false) = false
|
|
48
|
+
AND (sa.service_id IS NULL OR sr2.service_id = sa.service_id)
|
|
49
|
+
AND (sa.sub_service_id IS NULL OR sr2.sub_service_id = sa.sub_service_id)
|
|
50
|
+
)
|
|
44
51
|
LEFT JOIN fm_services svc
|
|
45
52
|
ON svc.id = sa.service_id AND COALESCE(svc.is_deleted, false) = false
|
|
46
53
|
LEFT JOIN fm_sub_services subsvc
|
package/package.json
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-- Chatbot Q&A mapping master table (User Service)
|
|
2
|
+
-- PostgreSQL
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS chatbot_qns_ans_mapping (
|
|
5
|
+
id SERIAL PRIMARY KEY,
|
|
6
|
+
service_id INTEGER NOT NULL,
|
|
7
|
+
sub_service_id INTEGER NOT NULL,
|
|
8
|
+
question JSONB NOT NULL,
|
|
9
|
+
answer JSONB NOT NULL,
|
|
10
|
+
created_by VARCHAR NULL,
|
|
11
|
+
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
12
|
+
updated_by VARCHAR NULL,
|
|
13
|
+
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
14
|
+
is_deleted BOOLEAN DEFAULT FALSE
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
CREATE INDEX IF NOT EXISTS idx_chatbot_qns_ans_mapping_service_sub_service
|
|
18
|
+
ON chatbot_qns_ans_mapping (service_id, sub_service_id)
|
|
19
|
+
WHERE is_deleted = FALSE;
|
|
20
|
+
|
|
21
|
+
CREATE INDEX IF NOT EXISTS idx_chatbot_qns_ans_mapping_question_gin
|
|
22
|
+
ON chatbot_qns_ans_mapping USING GIN (question);
|
|
23
|
+
|
|
24
|
+
CREATE INDEX IF NOT EXISTS idx_chatbot_qns_ans_mapping_answer_gin
|
|
25
|
+
ON chatbot_qns_ans_mapping USING GIN (answer);
|
|
@@ -19,13 +19,15 @@ $$;
|
|
|
19
19
|
-- Admin list views: served by Reports_Service TypeORM (sla-my-requests-view.query.ts, sla-approvals-view.query.ts)
|
|
20
20
|
|
|
21
21
|
-- ---------------------------------------------------------------------------
|
|
22
|
-
-- ADMIN — my requests Excel (optional
|
|
22
|
+
-- ADMIN — my requests Excel (optional p_target_user_ids INT[])
|
|
23
23
|
-- Per sub-service Requests + Approvals sheets (same as user my-requests download)
|
|
24
24
|
-- ---------------------------------------------------------------------------
|
|
25
25
|
DROP FUNCTION IF EXISTS sp_sla_admin_my_requests_excel_export(INT, INT[], INT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT);
|
|
26
|
+
DROP FUNCTION IF EXISTS sp_sla_admin_my_requests_excel_export(INT, INT[], INT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT, TEXT);
|
|
27
|
+
DROP FUNCTION IF EXISTS sp_sla_admin_my_requests_excel_export(INT[], INT[], INT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT, TEXT);
|
|
26
28
|
|
|
27
29
|
CREATE OR REPLACE FUNCTION sp_sla_admin_my_requests_excel_export(
|
|
28
|
-
|
|
30
|
+
p_target_user_ids INT[] DEFAULT NULL,
|
|
29
31
|
p_service_ids INT[] DEFAULT NULL,
|
|
30
32
|
p_sub_service_ids INT[] DEFAULT NULL,
|
|
31
33
|
p_statuses TEXT[] DEFAULT ARRAY['Pending','In Progress','Approved','Rejected'],
|
|
@@ -65,10 +67,20 @@ DECLARE
|
|
|
65
67
|
v_k TEXT;
|
|
66
68
|
v_sheet_order INT := 0;
|
|
67
69
|
v_user_filter TEXT;
|
|
70
|
+
v_user_scope TEXT;
|
|
68
71
|
BEGIN
|
|
72
|
+
IF p_target_user_ids IS NULL OR cardinality(p_target_user_ids) = 0 THEN
|
|
73
|
+
v_user_scope := 'TRUE';
|
|
74
|
+
ELSE
|
|
75
|
+
v_user_scope := format(
|
|
76
|
+
'v.user_id = ANY (ARRAY[%s]::int[])',
|
|
77
|
+
array_to_string(p_target_user_ids, ',')
|
|
78
|
+
);
|
|
79
|
+
END IF;
|
|
80
|
+
|
|
69
81
|
v_user_filter := format(
|
|
70
82
|
'(%s) AND (%s)',
|
|
71
|
-
|
|
83
|
+
v_user_scope,
|
|
72
84
|
COALESCE(NULLIF(trim(p_extra_filter_sql), ''), 'TRUE')
|
|
73
85
|
);
|
|
74
86
|
|
|
@@ -256,15 +268,21 @@ $$;
|
|
|
256
268
|
|
|
257
269
|
-- ---------------------------------------------------------------------------
|
|
258
270
|
-- ADMIN — approvals Excel
|
|
259
|
-
-- Per sub-service Requests + Approvals; optional
|
|
271
|
+
-- Per sub-service Requests + Approvals; optional approver user id(s) (NULL/empty = all queues)
|
|
260
272
|
-- Does not exclude own requests (unlike user approvals download)
|
|
261
273
|
-- ---------------------------------------------------------------------------
|
|
262
274
|
DROP FUNCTION IF EXISTS sp_sla_admin_approvals_excel_export(
|
|
263
275
|
INT, INT[], INT[], TEXT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT
|
|
264
276
|
);
|
|
277
|
+
DROP FUNCTION IF EXISTS sp_sla_admin_approvals_excel_export(
|
|
278
|
+
INT, INT[], INT[], TEXT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT, TEXT
|
|
279
|
+
);
|
|
280
|
+
DROP FUNCTION IF EXISTS sp_sla_admin_approvals_excel_export(
|
|
281
|
+
INT[], INT[], INT[], TEXT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT, TEXT
|
|
282
|
+
);
|
|
265
283
|
|
|
266
284
|
CREATE OR REPLACE FUNCTION sp_sla_admin_approvals_excel_export(
|
|
267
|
-
|
|
285
|
+
p_target_approver_user_ids INT[] DEFAULT NULL,
|
|
268
286
|
p_service_ids INT[] DEFAULT NULL,
|
|
269
287
|
p_sub_service_ids INT[] DEFAULT NULL,
|
|
270
288
|
p_request_statuses TEXT[] DEFAULT ARRAY['Pending','In Progress','Approved','Rejected'],
|
|
@@ -283,7 +301,7 @@ LANGUAGE plpgsql
|
|
|
283
301
|
STABLE
|
|
284
302
|
AS $$
|
|
285
303
|
DECLARE
|
|
286
|
-
v_exists TEXT :=
|
|
304
|
+
v_exists TEXT := sla_approval_queue_exists_sql_any(p_target_approver_user_ids);
|
|
287
305
|
v_own TEXT := COALESCE(NULLIF(trim(p_extra_filter_sql), ''), 'TRUE');
|
|
288
306
|
BEGIN
|
|
289
307
|
RETURN QUERY
|
|
@@ -96,6 +96,53 @@ AS $$
|
|
|
96
96
|
END;
|
|
97
97
|
$$;
|
|
98
98
|
|
|
99
|
+
-- Admin: any of multiple approver user ids (NULL/empty = all queues)
|
|
100
|
+
CREATE OR REPLACE FUNCTION sla_approval_queue_exists_sql_any(p_user_ids INT[])
|
|
101
|
+
RETURNS TEXT
|
|
102
|
+
LANGUAGE plpgsql
|
|
103
|
+
STABLE
|
|
104
|
+
AS $$
|
|
105
|
+
DECLARE
|
|
106
|
+
v_id INT;
|
|
107
|
+
v_parts TEXT[] := ARRAY[]::TEXT[];
|
|
108
|
+
v_match TEXT;
|
|
109
|
+
BEGIN
|
|
110
|
+
IF p_user_ids IS NULL OR cardinality(p_user_ids) = 0 THEN
|
|
111
|
+
RETURN sla_approval_queue_exists_sql_optional(NULL);
|
|
112
|
+
END IF;
|
|
113
|
+
|
|
114
|
+
IF cardinality(p_user_ids) = 1 THEN
|
|
115
|
+
RETURN sla_approval_queue_exists_sql(p_user_ids[1]);
|
|
116
|
+
END IF;
|
|
117
|
+
|
|
118
|
+
FOREACH v_id IN ARRAY p_user_ids LOOP
|
|
119
|
+
IF v_id IS NOT NULL AND v_id > 0 THEN
|
|
120
|
+
v_parts := array_append(v_parts, '(' || sla_approval_matches_user('appr', v_id) || ')');
|
|
121
|
+
END IF;
|
|
122
|
+
END LOOP;
|
|
123
|
+
|
|
124
|
+
IF cardinality(v_parts) = 0 THEN
|
|
125
|
+
RETURN sla_approval_queue_exists_sql_optional(NULL);
|
|
126
|
+
END IF;
|
|
127
|
+
|
|
128
|
+
v_match := array_to_string(v_parts, ' OR ');
|
|
129
|
+
|
|
130
|
+
RETURN format(
|
|
131
|
+
'EXISTS (
|
|
132
|
+
SELECT 1
|
|
133
|
+
FROM sla_approval appr
|
|
134
|
+
WHERE appr.request_id = sr.request_id
|
|
135
|
+
AND COALESCE(appr.is_deleted, false) = false
|
|
136
|
+
AND (appr.service_id = sr.service_id OR appr.service_id IS NULL)
|
|
137
|
+
AND (appr.sub_service_id = sr.sub_service_id OR appr.sub_service_id IS NULL)
|
|
138
|
+
AND (%s)
|
|
139
|
+
AND (appr.approval_status = ANY($1) OR appr.approval_status IS NULL)
|
|
140
|
+
)',
|
|
141
|
+
v_match
|
|
142
|
+
);
|
|
143
|
+
END;
|
|
144
|
+
$$;
|
|
145
|
+
|
|
99
146
|
DROP FUNCTION IF EXISTS sp_sla_approvals_workbook_excel_export(
|
|
100
147
|
TEXT, TEXT, INT[], INT[], TEXT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT
|
|
101
148
|
);
|
package/sql/vw_sla_approvals.sql
CHANGED
|
@@ -70,7 +70,14 @@ FROM sla_approval sa
|
|
|
70
70
|
|
|
71
71
|
INNER JOIN sla_requests sr
|
|
72
72
|
|
|
73
|
-
ON sr.
|
|
73
|
+
ON sr.id = (
|
|
74
|
+
SELECT MIN(sr2.id)
|
|
75
|
+
FROM sla_requests sr2
|
|
76
|
+
WHERE sr2.request_id = sa.request_id
|
|
77
|
+
AND COALESCE(sr2.is_deleted, false) = false
|
|
78
|
+
AND (sa.service_id IS NULL OR sr2.service_id = sa.service_id)
|
|
79
|
+
AND (sa.sub_service_id IS NULL OR sr2.sub_service_id = sa.sub_service_id)
|
|
80
|
+
)
|
|
74
81
|
|
|
75
82
|
LEFT JOIN fm_services svc
|
|
76
83
|
|
package/src/data-source.ts
CHANGED
|
@@ -343,6 +343,7 @@ import { EmbassyEvaluationRequestAttachment } from './models/EmbassyEvaluationAt
|
|
|
343
343
|
import { SlaRequest } from './models/SlaRequestModel';
|
|
344
344
|
import { ServiceSlaApproval } from './models/ServiceSlaApprovalModel';
|
|
345
345
|
import { SlaConfig } from './models/SlaConfigModel';
|
|
346
|
+
import { ChatbotQnsAnsMapping } from './models/ChatbotQnsAnsMappingModel';
|
|
346
347
|
|
|
347
348
|
export const AppDataSource = new DataSource({
|
|
348
349
|
type: 'postgres',
|
|
@@ -682,5 +683,6 @@ export const AppDataSource = new DataSource({
|
|
|
682
683
|
SlaRequest,
|
|
683
684
|
ServiceSlaApproval,
|
|
684
685
|
SlaConfig,
|
|
686
|
+
ChatbotQnsAnsMapping,
|
|
685
687
|
],
|
|
686
688
|
});
|
|
@@ -85,6 +85,81 @@ export function normalizeEmployeeSubmissions(raw: unknown): {
|
|
|
85
85
|
return { employees };
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
/** Relaxed validation for draft saves — employees/answers may be empty or partial. */
|
|
89
|
+
export function normalizeEmployeeDraftSubmissions(raw: unknown): {
|
|
90
|
+
employees: NormalizedEmployeeSubmission[];
|
|
91
|
+
error?: string;
|
|
92
|
+
} {
|
|
93
|
+
if (raw == null || raw === undefined) {
|
|
94
|
+
return { employees: [] };
|
|
95
|
+
}
|
|
96
|
+
if (!Array.isArray(raw)) {
|
|
97
|
+
return { employees: [], error: 'employees must be an array when provided' };
|
|
98
|
+
}
|
|
99
|
+
if (raw.length === 0) {
|
|
100
|
+
return { employees: [] };
|
|
101
|
+
}
|
|
102
|
+
const seen = new Set<number>();
|
|
103
|
+
const employees: NormalizedEmployeeSubmission[] = [];
|
|
104
|
+
for (const item of raw) {
|
|
105
|
+
if (item == null || typeof item !== 'object') {
|
|
106
|
+
return { employees: [], error: 'Each employee entry must be an object' };
|
|
107
|
+
}
|
|
108
|
+
const o = item as Record<string, unknown>;
|
|
109
|
+
const user_id = Number(o.user_id ?? o.employee_id);
|
|
110
|
+
if (!Number.isFinite(user_id) || user_id <= 0) {
|
|
111
|
+
return { employees: [], error: 'Each employee must have a valid user_id' };
|
|
112
|
+
}
|
|
113
|
+
if (seen.has(user_id)) {
|
|
114
|
+
return { employees: [], error: `Duplicate user_id ${user_id} in employees list` };
|
|
115
|
+
}
|
|
116
|
+
seen.add(user_id);
|
|
117
|
+
const answersRaw = o.answers;
|
|
118
|
+
const answers: EmployeeEvaluationSubmitAnswer[] = [];
|
|
119
|
+
if (answersRaw != null) {
|
|
120
|
+
if (!Array.isArray(answersRaw)) {
|
|
121
|
+
return { employees: [], error: `Employee ${user_id} answers must be an array when provided` };
|
|
122
|
+
}
|
|
123
|
+
const qSeen = new Set<number>();
|
|
124
|
+
for (const a of answersRaw) {
|
|
125
|
+
if (a == null || typeof a !== 'object') continue;
|
|
126
|
+
const ar = a as Record<string, unknown>;
|
|
127
|
+
const section_id = Number(ar.section_id);
|
|
128
|
+
const question_id = Number(ar.question_id);
|
|
129
|
+
const score = Number(ar.score);
|
|
130
|
+
if (!Number.isFinite(section_id) || !Number.isFinite(question_id)) {
|
|
131
|
+
return {
|
|
132
|
+
employees: [],
|
|
133
|
+
error: `section_id and question_id required for employee ${user_id} when answer is provided`,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (!Number.isFinite(score) || score < 0) {
|
|
137
|
+
return {
|
|
138
|
+
employees: [],
|
|
139
|
+
error: `score must be a non-negative number for employee ${user_id}, question ${question_id}`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
if (qSeen.has(question_id)) {
|
|
143
|
+
return { employees: [], error: `Duplicate question_id ${question_id} for employee ${user_id}` };
|
|
144
|
+
}
|
|
145
|
+
qSeen.add(question_id);
|
|
146
|
+
answers.push({
|
|
147
|
+
section_id,
|
|
148
|
+
question_id,
|
|
149
|
+
score,
|
|
150
|
+
remarks: ar.remarks != null ? String(ar.remarks) : null,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
employees.push({
|
|
155
|
+
user_id,
|
|
156
|
+
is_rca: o.is_rca !== undefined ? Boolean(o.is_rca) : false,
|
|
157
|
+
answers,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
return { employees };
|
|
161
|
+
}
|
|
162
|
+
|
|
88
163
|
/** Resolve max employees from active exception cycle for the evaluation month. */
|
|
89
164
|
export async function resolveMaxEmployeesPerRequest(
|
|
90
165
|
manager: EntityManager,
|
|
@@ -113,9 +188,10 @@ export async function persistEmployeeEvaluationScores(
|
|
|
113
188
|
formId: number;
|
|
114
189
|
createdBy: string;
|
|
115
190
|
employees: NormalizedEmployeeSubmission[];
|
|
191
|
+
isDraft?: boolean;
|
|
116
192
|
}
|
|
117
193
|
): Promise<{ totalScore: number; averageScore: number; employeeCount: number }> {
|
|
118
|
-
const { requestId, formId, createdBy, employees } = opts;
|
|
194
|
+
const { requestId, formId, createdBy, employees, isDraft = false } = opts;
|
|
119
195
|
let requestTotal = 0;
|
|
120
196
|
|
|
121
197
|
for (const emp of employees) {
|
|
@@ -125,14 +201,18 @@ export async function persistEmployeeEvaluationScores(
|
|
|
125
201
|
where: { id: ans.question_id, is_deleted: false },
|
|
126
202
|
});
|
|
127
203
|
const questionSectionId = qMeta?.form_section_id;
|
|
128
|
-
if (!
|
|
204
|
+
if (!isDraft) {
|
|
205
|
+
if (!qMeta || questionSectionId == null || questionSectionId !== ans.section_id) {
|
|
206
|
+
throw new Error(`Invalid question ${ans.question_id} for section ${ans.section_id}`);
|
|
207
|
+
}
|
|
208
|
+
if (qMeta.max_score != null && ans.score > qMeta.max_score) {
|
|
209
|
+
throw new Error(
|
|
210
|
+
`score ${ans.score} exceeds max_score ${qMeta.max_score} for question ${ans.question_id}`
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
} else if (qMeta && qMeta.form_section_id != null && qMeta.form_section_id !== ans.section_id) {
|
|
129
214
|
throw new Error(`Invalid question ${ans.question_id} for section ${ans.section_id}`);
|
|
130
215
|
}
|
|
131
|
-
if (qMeta.max_score != null && ans.score > qMeta.max_score) {
|
|
132
|
-
throw new Error(
|
|
133
|
-
`score ${ans.score} exceeds max_score ${qMeta.max_score} for question ${ans.question_id}`
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
216
|
personTotal += ans.score;
|
|
137
217
|
await manager.save(
|
|
138
218
|
EmployeeEvaluationAnswers,
|
package/src/index.ts
CHANGED
|
@@ -98,6 +98,7 @@ export * from './models/UpdateAttendanceWorkflowModel';
|
|
|
98
98
|
export * from './models/SlaRequestModel';
|
|
99
99
|
export * from './models/ServiceSlaApprovalModel';
|
|
100
100
|
export * from './models/SlaConfigModel';
|
|
101
|
+
export * from './models/ChatbotQnsAnsMappingModel';
|
|
101
102
|
export * from './models/GeneralServiceRequestsModel';
|
|
102
103
|
export * from './models/GeneralServiceApprovalsModel';
|
|
103
104
|
export * from './models/GeneralServiceWorkFlowModel';
|
|
@@ -459,6 +460,7 @@ export {
|
|
|
459
460
|
export {
|
|
460
461
|
DEFAULT_MAX_EMPLOYEES_PER_REQUEST,
|
|
461
462
|
normalizeEmployeeSubmissions,
|
|
463
|
+
normalizeEmployeeDraftSubmissions,
|
|
462
464
|
resolveMaxEmployeesPerRequest,
|
|
463
465
|
persistEmployeeEvaluationScores,
|
|
464
466
|
} from './helpers/employee-evaluation-request.utils';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Column, Entity } from "typeorm";
|
|
2
|
+
import { BaseModel } from "./BaseModel";
|
|
3
|
+
|
|
4
|
+
@Entity({ name: "chatbot_qns_ans_mapping" })
|
|
5
|
+
export class ChatbotQnsAnsMapping extends BaseModel {
|
|
6
|
+
@Column({ type: "int", nullable: false })
|
|
7
|
+
service_id: number;
|
|
8
|
+
|
|
9
|
+
@Column({ type: "int", nullable: false })
|
|
10
|
+
sub_service_id: number;
|
|
11
|
+
|
|
12
|
+
@Column({ type: "jsonb", nullable: false })
|
|
13
|
+
question: Record<string, unknown> | unknown[];
|
|
14
|
+
|
|
15
|
+
@Column({ type: "jsonb", nullable: false })
|
|
16
|
+
answer: Record<string, unknown> | unknown[];
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -84,6 +84,9 @@ export class EmployeeEvaluationRequests extends BaseModel {
|
|
|
84
84
|
@Column({ type: 'int', default: 0, nullable: false })
|
|
85
85
|
employee_count: number;
|
|
86
86
|
|
|
87
|
+
@Column({ type: 'boolean', default: false, nullable: false })
|
|
88
|
+
is_draft: boolean;
|
|
89
|
+
|
|
87
90
|
/** Form structure snapshot at request creation (sections/questions). */
|
|
88
91
|
@Column({ type: 'jsonb', nullable: true })
|
|
89
92
|
dynamic_evaluation_form: Record<string, unknown> | null;
|
|
@@ -29,7 +29,14 @@ SELECT
|
|
|
29
29
|
sa.updated_at AS updated_at
|
|
30
30
|
FROM sla_approval sa
|
|
31
31
|
INNER JOIN sla_requests sr
|
|
32
|
-
ON sr.
|
|
32
|
+
ON sr.id = (
|
|
33
|
+
SELECT MIN(sr2.id)
|
|
34
|
+
FROM sla_requests sr2
|
|
35
|
+
WHERE sr2.request_id = sa.request_id
|
|
36
|
+
AND COALESCE(sr2.is_deleted, false) = false
|
|
37
|
+
AND (sa.service_id IS NULL OR sr2.service_id = sa.service_id)
|
|
38
|
+
AND (sa.sub_service_id IS NULL OR sr2.sub_service_id = sa.sub_service_id)
|
|
39
|
+
)
|
|
33
40
|
LEFT JOIN fm_services svc
|
|
34
41
|
ON svc.id = sa.service_id AND COALESCE(svc.is_deleted, false) = false
|
|
35
42
|
LEFT JOIN fm_sub_services subsvc
|