@platform-modules/civil-aviation-authority 2.3.281 → 2.3.290
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/i18n/workflow-chat-i18n.json +162 -1
- package/dist/i18n/workflow-chat-message.builder.d.ts +182 -3
- package/dist/i18n/workflow-chat-message.builder.js +469 -17
- package/dist/models/AccessCardChatModel.d.ts +2 -0
- package/dist/models/AccessCardChatModel.js +8 -0
- package/dist/models/AccessCardWorkflowModel.d.ts +2 -0
- package/dist/models/AccessCardWorkflowModel.js +8 -0
- package/dist/models/AccommodationChatModel.d.ts +2 -0
- package/dist/models/AccommodationChatModel.js +8 -0
- package/dist/models/AccommodationWorkflowModel.d.ts +2 -0
- package/dist/models/AccommodationWorkflowModel.js +8 -0
- package/dist/models/AirportEntryPermitChatModel.d.ts +2 -0
- package/dist/models/AirportEntryPermitChatModel.js +8 -0
- package/dist/models/AirportEntryPermitWorkflowModel.d.ts +2 -0
- package/dist/models/AirportEntryPermitWorkflowModel.js +8 -0
- package/dist/models/AnnualTrainingPlanChatModel.d.ts +2 -0
- package/dist/models/AnnualTrainingPlanChatModel.js +8 -0
- package/dist/models/AnnualTrainingPlanWorkflowModel.d.ts +2 -0
- package/dist/models/AnnualTrainingPlanWorkflowModel.js +8 -0
- package/dist/models/AssignTasksEmpChatModel.d.ts +2 -0
- package/dist/models/AssignTasksEmpChatModel.js +8 -0
- package/dist/models/AssignTasksEmpWorkflowModel.d.ts +2 -0
- package/dist/models/AssignTasksEmpWorkflowModel.js +8 -0
- package/dist/models/ComplaintLostPropertyReportChatModel.d.ts +2 -0
- package/dist/models/ComplaintLostPropertyReportChatModel.js +8 -0
- package/dist/models/ComplaintLostPropertyReportWorkflowModel.d.ts +2 -0
- package/dist/models/ComplaintLostPropertyReportWorkflowModel.js +8 -0
- package/dist/models/DutyMissionChatModel.d.ts +2 -0
- package/dist/models/DutyMissionChatModel.js +8 -0
- package/dist/models/DutyMissionWorkflowModel.d.ts +2 -0
- package/dist/models/DutyMissionWorkflowModel.js +8 -0
- package/dist/models/EventSupportChatModel.d.ts +2 -0
- package/dist/models/EventSupportChatModel.js +8 -0
- package/dist/models/EventSupportWorkflowModel.d.ts +2 -0
- package/dist/models/EventSupportWorkflowModel.js +8 -0
- package/dist/models/FollowUpReportChatModel.d.ts +2 -0
- package/dist/models/FollowUpReportChatModel.js +8 -0
- package/dist/models/FollowUpReportWorkflowModel.d.ts +2 -0
- package/dist/models/FollowUpReportWorkflowModel.js +8 -0
- package/dist/models/FoodChatModel.d.ts +2 -0
- package/dist/models/FoodChatModel.js +8 -0
- package/dist/models/FoodWorkflowModel.d.ts +2 -0
- package/dist/models/FoodWorkflowModel.js +8 -0
- package/dist/models/HallChatModel.d.ts +2 -0
- package/dist/models/HallChatModel.js +8 -0
- package/dist/models/HallWorkflowModel.d.ts +2 -0
- package/dist/models/HallWorkflowModel.js +8 -0
- package/dist/models/HotelChatModel.d.ts +2 -0
- package/dist/models/HotelChatModel.js +8 -0
- package/dist/models/HotelWorkFlowModel.d.ts +2 -0
- package/dist/models/HotelWorkFlowModel.js +8 -0
- package/dist/models/HousingContractCancelChatModel.d.ts +2 -0
- package/dist/models/HousingContractCancelChatModel.js +8 -0
- package/dist/models/HousingContractCancelWorkflowModel.d.ts +2 -0
- package/dist/models/HousingContractCancelWorkflowModel.js +8 -0
- package/dist/models/HousingContractRenewalChatModel.d.ts +2 -0
- package/dist/models/HousingContractRenewalChatModel.js +8 -0
- package/dist/models/HousingContractRenewalWorkflowModel.d.ts +2 -0
- package/dist/models/HousingContractRenewalWorkflowModel.js +8 -0
- package/dist/models/HrServiceChatModel.d.ts +2 -0
- package/dist/models/HrServiceChatModel.js +8 -0
- package/dist/models/HrServiceWorkflowModel.d.ts +2 -0
- package/dist/models/HrServiceWorkflowModel.js +8 -0
- package/dist/models/ITRequestChatModel.d.ts +2 -0
- package/dist/models/ITRequestChatModel.js +8 -0
- package/dist/models/ImportExportMaterialChatModel.d.ts +2 -0
- package/dist/models/ImportExportMaterialChatModel.js +8 -0
- package/dist/models/ImportExportMaterialWorkflowModel.d.ts +2 -0
- package/dist/models/ImportExportMaterialWorkflowModel.js +8 -0
- package/dist/models/InformationSecurityChatModel.d.ts +2 -0
- package/dist/models/InformationSecurityChatModel.js +8 -0
- package/dist/models/InformationSecurityWorkflowModel.d.ts +2 -0
- package/dist/models/InformationSecurityWorkflowModel.js +8 -0
- package/dist/models/ItWorkflowModel.d.ts +2 -0
- package/dist/models/ItWorkflowModel.js +8 -0
- package/dist/models/LegalComplaintChatModel.d.ts +2 -0
- package/dist/models/LegalComplaintChatModel.js +8 -0
- package/dist/models/LegalComplaintWorkflowModel.d.ts +2 -0
- package/dist/models/LegalComplaintWorkflowModel.js +8 -0
- package/dist/models/LegalConsultationChatModel.d.ts +2 -0
- package/dist/models/LegalConsultationChatModel.js +8 -0
- package/dist/models/LegalConsultationWorkflowModel.d.ts +2 -0
- package/dist/models/LegalConsultationWorkflowModel.js +8 -0
- package/dist/models/LegalContractReviewChatModel.d.ts +2 -0
- package/dist/models/LegalContractReviewChatModel.js +8 -0
- package/dist/models/LegalContractReviewWorkflowModel.d.ts +2 -0
- package/dist/models/LegalContractReviewWorkflowModel.js +8 -0
- package/dist/models/LogisticsChatModel.d.ts +2 -0
- package/dist/models/LogisticsChatModel.js +8 -0
- package/dist/models/LogisticsVehicleMaintenanceChatModel.d.ts +2 -0
- package/dist/models/LogisticsVehicleMaintenanceChatModel.js +8 -0
- package/dist/models/LogisticsVehicleMaintenanceWorkflowModel.d.ts +2 -0
- package/dist/models/LogisticsVehicleMaintenanceWorkflowModel.js +8 -0
- package/dist/models/LogisticsWorkflowModel.d.ts +2 -0
- package/dist/models/LogisticsWorkflowModel.js +8 -0
- package/dist/models/MaintenanceChatModel.d.ts +2 -0
- package/dist/models/MaintenanceChatModel.js +8 -0
- package/dist/models/MaintenanceExternalStationsChatModel.d.ts +2 -0
- package/dist/models/MaintenanceExternalStationsChatModel.js +8 -0
- package/dist/models/MaintenanceExternalStationsWorkflowModel.d.ts +2 -0
- package/dist/models/MaintenanceExternalStationsWorkflowModel.js +8 -0
- package/dist/models/MaintenanceWorkflowModel.d.ts +2 -0
- package/dist/models/MaintenanceWorkflowModel.js +8 -0
- package/dist/models/MediaPublicationsChatModel.d.ts +2 -0
- package/dist/models/MediaPublicationsChatModel.js +8 -0
- package/dist/models/MediaPublicationsWorkflowModel.d.ts +2 -0
- package/dist/models/MediaPublicationsWorkflowModel.js +8 -0
- package/dist/models/MultiPurposeHallChatModel.d.ts +2 -0
- package/dist/models/MultiPurposeHallChatModel.js +8 -0
- package/dist/models/MultiPurposeHallWorkflowModel.d.ts +2 -0
- package/dist/models/MultiPurposeHallWorkflowModel.js +8 -0
- package/dist/models/RequestForCoverageChatModel.d.ts +2 -0
- package/dist/models/RequestForCoverageChatModel.js +8 -0
- package/dist/models/RequestForCoverageWorkflowModel.d.ts +2 -0
- package/dist/models/RequestForCoverageWorkflowModel.js +8 -0
- package/dist/models/RequestForPresidentsCoverageChatModel.d.ts +2 -0
- package/dist/models/RequestForPresidentsCoverageChatModel.js +8 -0
- package/dist/models/RequestForPresidentsCoverageWorkflowModel.d.ts +2 -0
- package/dist/models/RequestForPresidentsCoverageWorkflowModel.js +8 -0
- package/dist/models/ResidentialUnitRentalChatModel.d.ts +2 -0
- package/dist/models/ResidentialUnitRentalChatModel.js +8 -0
- package/dist/models/ResidentialUnitRentalWorkflowModel.d.ts +2 -0
- package/dist/models/ResidentialUnitRentalWorkflowModel.js +8 -0
- package/dist/models/RespondToEnquiriesChatModel.d.ts +2 -0
- package/dist/models/RespondToEnquiriesChatModel.js +8 -0
- package/dist/models/RespondToEnquiriesWorkflowModel.d.ts +2 -0
- package/dist/models/RespondToEnquiriesWorkflowModel.js +8 -0
- package/dist/models/ScholarshipChatModel.d.ts +2 -0
- package/dist/models/ScholarshipChatModel.js +8 -0
- package/dist/models/ScholarshipWorkflowModel.d.ts +2 -0
- package/dist/models/ScholarshipWorkflowModel.js +8 -0
- package/dist/models/SecurityAwarenessChatModel.d.ts +2 -0
- package/dist/models/SecurityAwarenessChatModel.js +8 -0
- package/dist/models/SecurityAwarenessWorkflowModel.d.ts +2 -0
- package/dist/models/SecurityAwarenessWorkflowModel.js +8 -0
- package/dist/models/SecurityThreatChatModel.d.ts +2 -0
- package/dist/models/SecurityThreatChatModel.js +8 -0
- package/dist/models/SecurityThreatWorkflowModel.d.ts +2 -0
- package/dist/models/SecurityThreatWorkflowModel.js +8 -0
- package/dist/models/ServiceExtensionAfter60ChatModel.d.ts +2 -0
- package/dist/models/ServiceExtensionAfter60ChatModel.js +8 -0
- package/dist/models/ServiceExtensionAfter60WorkflowModel.d.ts +2 -0
- package/dist/models/ServiceExtensionAfter60WorkflowModel.js +8 -0
- package/dist/models/StudyLeaveChatModel.d.ts +2 -0
- package/dist/models/StudyLeaveChatModel.js +8 -0
- package/dist/models/StudyLeaveWorkflowModel.d.ts +2 -0
- package/dist/models/StudyLeaveWorkflowModel.js +8 -0
- package/dist/models/TrainingChatModel.d.ts +2 -0
- package/dist/models/TrainingChatModel.js +8 -0
- package/dist/models/TrainingRoomBookingChatModel.d.ts +2 -0
- package/dist/models/TrainingRoomBookingChatModel.js +8 -0
- package/dist/models/TrainingRoomBookingWorkflowModel.d.ts +2 -0
- package/dist/models/TrainingRoomBookingWorkflowModel.js +8 -0
- package/dist/models/TrainingWorkflowModel.d.ts +2 -0
- package/dist/models/TrainingWorkflowModel.js +8 -0
- package/dist/models/VipHallChatModel.d.ts +2 -0
- package/dist/models/VipHallChatModel.js +8 -0
- package/dist/models/VipHallWorkflowModel.d.ts +2 -0
- package/dist/models/VipHallWorkflowModel.js +8 -0
- package/dist/models/VpnRequestChatModel.d.ts +2 -0
- package/dist/models/VpnRequestChatModel.js +8 -0
- package/dist/models/VpnWorkflowModel.d.ts +2 -0
- package/dist/models/VpnWorkflowModel.js +8 -0
- package/dist/models/WorkingHoursExtensionChatModel.d.ts +2 -0
- package/dist/models/WorkingHoursExtensionChatModel.js +8 -0
- package/dist/models/WorkingHoursExtensionWorkflowModel.d.ts +2 -0
- package/dist/models/WorkingHoursExtensionWorkflowModel.js +8 -0
- package/package.json +1 -1
- package/sql/add_all_workflow_chat_arabic_columns.sql +1 -0
- package/src/i18n/workflow-chat-i18n.json +162 -1
- package/src/i18n/workflow-chat-message.builder.ts +760 -17
- package/src/models/AccessCardChatModel.ts +8 -2
- package/src/models/AccessCardWorkflowModel.ts +8 -2
- package/src/models/AccommodationChatModel.ts +8 -2
- package/src/models/AccommodationWorkflowModel.ts +8 -2
- package/src/models/AirportEntryPermitChatModel.ts +8 -2
- package/src/models/AirportEntryPermitWorkflowModel.ts +8 -2
- package/src/models/AnnualTrainingPlanChatModel.ts +8 -2
- package/src/models/AnnualTrainingPlanWorkflowModel.ts +8 -2
- package/src/models/AssignTasksEmpChatModel.ts +8 -2
- package/src/models/AssignTasksEmpWorkflowModel.ts +8 -2
- package/src/models/ComplaintLostPropertyReportChatModel.ts +8 -2
- package/src/models/ComplaintLostPropertyReportWorkflowModel.ts +8 -2
- package/src/models/DutyMissionChatModel.ts +8 -2
- package/src/models/DutyMissionWorkflowModel.ts +8 -2
- package/src/models/EventSupportChatModel.ts +8 -2
- package/src/models/EventSupportWorkflowModel.ts +8 -2
- package/src/models/FollowUpReportChatModel.ts +8 -2
- package/src/models/FollowUpReportWorkflowModel.ts +8 -2
- package/src/models/FoodChatModel.ts +8 -2
- package/src/models/FoodWorkflowModel.ts +8 -2
- package/src/models/HallChatModel.ts +8 -2
- package/src/models/HallWorkflowModel.ts +8 -2
- package/src/models/HotelChatModel.ts +8 -2
- package/src/models/HotelWorkFlowModel.ts +8 -2
- package/src/models/HousingContractCancelChatModel.ts +8 -2
- package/src/models/HousingContractCancelWorkflowModel.ts +8 -2
- package/src/models/HousingContractRenewalChatModel.ts +8 -2
- package/src/models/HousingContractRenewalWorkflowModel.ts +8 -2
- package/src/models/HrServiceChatModel.ts +8 -2
- package/src/models/HrServiceWorkflowModel.ts +8 -2
- package/src/models/ITRequestChatModel.ts +8 -2
- package/src/models/ImportExportMaterialChatModel.ts +8 -2
- package/src/models/ImportExportMaterialWorkflowModel.ts +8 -2
- package/src/models/InformationSecurityChatModel.ts +8 -2
- package/src/models/InformationSecurityWorkflowModel.ts +8 -2
- package/src/models/ItWorkflowModel.ts +8 -2
- package/src/models/LegalComplaintChatModel.ts +8 -2
- package/src/models/LegalComplaintWorkflowModel.ts +8 -2
- package/src/models/LegalConsultationChatModel.ts +8 -2
- package/src/models/LegalConsultationWorkflowModel.ts +8 -2
- package/src/models/LegalContractReviewChatModel.ts +8 -2
- package/src/models/LegalContractReviewWorkflowModel.ts +8 -2
- package/src/models/LogisticsChatModel.ts +8 -2
- package/src/models/LogisticsVehicleMaintenanceChatModel.ts +8 -2
- package/src/models/LogisticsVehicleMaintenanceWorkflowModel.ts +8 -2
- package/src/models/LogisticsWorkflowModel.ts +8 -2
- package/src/models/MaintenanceChatModel.ts +8 -2
- package/src/models/MaintenanceExternalStationsChatModel.ts +8 -2
- package/src/models/MaintenanceExternalStationsWorkflowModel.ts +8 -2
- package/src/models/MaintenanceWorkflowModel.ts +8 -2
- package/src/models/MediaPublicationsChatModel.ts +8 -2
- package/src/models/MediaPublicationsWorkflowModel.ts +8 -2
- package/src/models/MultiPurposeHallChatModel.ts +8 -2
- package/src/models/MultiPurposeHallWorkflowModel.ts +8 -2
- package/src/models/RequestForCoverageChatModel.ts +8 -2
- package/src/models/RequestForCoverageWorkflowModel.ts +8 -2
- package/src/models/RequestForPresidentsCoverageChatModel.ts +8 -2
- package/src/models/RequestForPresidentsCoverageWorkflowModel.ts +8 -2
- package/src/models/ResidentialUnitRentalChatModel.ts +8 -2
- package/src/models/ResidentialUnitRentalWorkflowModel.ts +8 -2
- package/src/models/RespondToEnquiriesChatModel.ts +8 -2
- package/src/models/RespondToEnquiriesWorkflowModel.ts +8 -2
- package/src/models/ScholarshipChatModel.ts +8 -2
- package/src/models/ScholarshipWorkflowModel.ts +8 -2
- package/src/models/SecurityAwarenessChatModel.ts +8 -2
- package/src/models/SecurityAwarenessWorkflowModel.ts +8 -2
- package/src/models/SecurityThreatChatModel.ts +8 -2
- package/src/models/SecurityThreatWorkflowModel.ts +8 -2
- package/src/models/ServiceExtensionAfter60ChatModel.ts +8 -2
- package/src/models/ServiceExtensionAfter60WorkflowModel.ts +8 -2
- package/src/models/StudyLeaveChatModel.ts +8 -2
- package/src/models/StudyLeaveWorkflowModel.ts +8 -2
- package/src/models/TrainingChatModel.ts +8 -2
- package/src/models/TrainingRoomBookingChatModel.ts +8 -2
- package/src/models/TrainingRoomBookingWorkflowModel.ts +8 -2
- package/src/models/TrainingWorkflowModel.ts +8 -2
- package/src/models/VipHallChatModel.ts +8 -2
- package/src/models/VipHallWorkflowModel.ts +8 -2
- package/src/models/VpnRequestChatModel.ts +8 -2
- package/src/models/VpnWorkflowModel.ts +8 -2
- package/src/models/WorkingHoursExtensionChatModel.ts +8 -2
- package/src/models/WorkingHoursExtensionWorkflowModel.ts +8 -2
|
@@ -20,11 +20,33 @@ exports.workflowTemplate = workflowTemplate;
|
|
|
20
20
|
exports.chatTemplate = chatTemplate;
|
|
21
21
|
exports.buildSynchronizedWorkflowMessage = buildSynchronizedWorkflowMessage;
|
|
22
22
|
exports.buildSynchronizedChatMessage = buildSynchronizedChatMessage;
|
|
23
|
+
exports.buildWorkflowLogUpdateFields = buildWorkflowLogUpdateFields;
|
|
24
|
+
exports.toWorkflowPersistFields = toWorkflowPersistFields;
|
|
25
|
+
exports.toChatPersistFields = toChatPersistFields;
|
|
23
26
|
exports.buildApprovalWorkflowContent = buildApprovalWorkflowContent;
|
|
24
27
|
exports.buildHumanApprovalWorkflowContent = buildHumanApprovalWorkflowContent;
|
|
25
28
|
exports.buildApprovalChatMessage = buildApprovalChatMessage;
|
|
29
|
+
exports.buildClosedChatMessage = buildClosedChatMessage;
|
|
30
|
+
exports.buildClosedWorkflowMessage = buildClosedWorkflowMessage;
|
|
31
|
+
exports.buildRequestForChangeChatMessage = buildRequestForChangeChatMessage;
|
|
32
|
+
exports.buildAttachmentUploadedChatMessage = buildAttachmentUploadedChatMessage;
|
|
33
|
+
exports.buildUserOrAttachmentChatMessage = buildUserOrAttachmentChatMessage;
|
|
34
|
+
exports.buildTaskInProgressChatMessage = buildTaskInProgressChatMessage;
|
|
35
|
+
exports.buildTaskCompletedChatMessage = buildTaskCompletedChatMessage;
|
|
36
|
+
exports.buildTaskStatusUpdatedChatMessage = buildTaskStatusUpdatedChatMessage;
|
|
37
|
+
exports.buildItHelpdeskAssignedChatMessage = buildItHelpdeskAssignedChatMessage;
|
|
38
|
+
exports.buildItHelpdeskReassignedChatMessage = buildItHelpdeskReassignedChatMessage;
|
|
39
|
+
exports.buildRequestSubmittedWithRefChatMessage = buildRequestSubmittedWithRefChatMessage;
|
|
40
|
+
exports.buildSecurityAccessApprovalChatMessage = buildSecurityAccessApprovalChatMessage;
|
|
41
|
+
exports.buildItHelpdeskReassignModifiers = buildItHelpdeskReassignModifiers;
|
|
42
|
+
exports.buildItHelpdeskMuscatWorkflowLog = buildItHelpdeskMuscatWorkflowLog;
|
|
43
|
+
exports.buildLogisticsActualReturnChatMessage = buildLogisticsActualReturnChatMessage;
|
|
44
|
+
exports.buildLogisticsActualReturnNotificationBody = buildLogisticsActualReturnNotificationBody;
|
|
45
|
+
exports.buildLogisticsActualReturnNotificationTitle = buildLogisticsActualReturnNotificationTitle;
|
|
46
|
+
exports.buildItHelpdeskCloseNotificationMessage = buildItHelpdeskCloseNotificationMessage;
|
|
26
47
|
exports.resolveWorkflowStatusAr = resolveWorkflowStatusAr;
|
|
27
48
|
exports.resolveChatStatusAr = resolveChatStatusAr;
|
|
49
|
+
exports.extractBilingualActorsFromRecord = extractBilingualActorsFromRecord;
|
|
28
50
|
exports.resolveWorkflowContentAr = resolveWorkflowContentAr;
|
|
29
51
|
exports.resolveChatMessageAr = resolveChatMessageAr;
|
|
30
52
|
exports.enrichWorkflowLog = enrichWorkflowLog;
|
|
@@ -38,6 +60,7 @@ exports.enrichChatMessage = enrichChatMessage;
|
|
|
38
60
|
const workflow_chat_i18n_json_1 = __importDefault(require("./workflow-chat-i18n.json"));
|
|
39
61
|
const WORKFLOW_TEMPLATES = workflow_chat_i18n_json_1.default.workflowTemplates;
|
|
40
62
|
const CHAT_TEMPLATES = workflow_chat_i18n_json_1.default.chatTemplates;
|
|
63
|
+
const NOTIFICATION_TEMPLATES = workflow_chat_i18n_json_1.default.notificationTemplates ?? {};
|
|
41
64
|
const WORKFLOW_STATUS_LABELS = workflow_chat_i18n_json_1.default.workflowStatusLabels;
|
|
42
65
|
const CHAT_STATUS_LABELS = workflow_chat_i18n_json_1.default.chatStatusLabels;
|
|
43
66
|
function getWorkflowChatI18nCatalog() {
|
|
@@ -184,6 +207,12 @@ function buildSynchronizedChatMessage(ctx) {
|
|
|
184
207
|
const employeeId = String(ctx.employeeId ?? 'N/A');
|
|
185
208
|
return chatTemplate('cancellation_submitted_by', { userName: userEn, employeeId }, { userName: userAr, employeeId });
|
|
186
209
|
}
|
|
210
|
+
case 'request_submitted': {
|
|
211
|
+
const userEn = ctx.userName?.trim() || 'Unknown User';
|
|
212
|
+
const userAr = resolveBilingualName(userEn, ctx.userArabicName);
|
|
213
|
+
const employeeId = String(ctx.employeeId ?? 'N/A');
|
|
214
|
+
return chatTemplate('request_submitted_by', { userName: userEn, employeeId }, { userName: userAr, employeeId });
|
|
215
|
+
}
|
|
187
216
|
case 'request_received':
|
|
188
217
|
return chatTemplate('request_received');
|
|
189
218
|
case 'approved':
|
|
@@ -203,6 +232,48 @@ function buildSynchronizedChatMessage(ctx) {
|
|
|
203
232
|
}
|
|
204
233
|
}
|
|
205
234
|
// ─── Backward-compatible aliases used by Cancellation pilot ───────────────────
|
|
235
|
+
/** Standard workflow log UPDATE fields for all CAA module repositories. */
|
|
236
|
+
function buildWorkflowLogUpdateFields(params) {
|
|
237
|
+
let action;
|
|
238
|
+
if (params.approvalStatus === 'Approved')
|
|
239
|
+
action = 'approved';
|
|
240
|
+
else if (params.approvalStatus === 'Rejected')
|
|
241
|
+
action = 'rejected';
|
|
242
|
+
else if (params.approvalStatus === 'Returned for Modification')
|
|
243
|
+
action = 'returned_for_modification';
|
|
244
|
+
else
|
|
245
|
+
action = 'approval_pending_update';
|
|
246
|
+
const bilingual = buildSynchronizedWorkflowMessage({
|
|
247
|
+
action,
|
|
248
|
+
roleName: params.roleName,
|
|
249
|
+
roleArabicName: params.roleArabicName,
|
|
250
|
+
comment: params.comment,
|
|
251
|
+
});
|
|
252
|
+
return {
|
|
253
|
+
content: bilingual.en,
|
|
254
|
+
content_ar: bilingual.ar,
|
|
255
|
+
status: params.workflowStatus,
|
|
256
|
+
status_ar: resolveWorkflowStatusAr(params.workflowStatus),
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
/** Bilingual workflow insert fields from builder output. */
|
|
260
|
+
function toWorkflowPersistFields(bilingual, status) {
|
|
261
|
+
return {
|
|
262
|
+
content: bilingual.en,
|
|
263
|
+
content_ar: bilingual.ar,
|
|
264
|
+
status,
|
|
265
|
+
status_ar: resolveWorkflowStatusAr(status),
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
/** Bilingual chat insert fields from builder output. */
|
|
269
|
+
function toChatPersistFields(bilingual, status) {
|
|
270
|
+
return {
|
|
271
|
+
message: bilingual.en,
|
|
272
|
+
message_ar: bilingual.ar,
|
|
273
|
+
status,
|
|
274
|
+
status_ar: resolveChatStatusAr(status),
|
|
275
|
+
};
|
|
276
|
+
}
|
|
206
277
|
function buildApprovalWorkflowContent(params) {
|
|
207
278
|
const status = params.status;
|
|
208
279
|
let action;
|
|
@@ -233,6 +304,21 @@ function buildHumanApprovalWorkflowContent(params) {
|
|
|
233
304
|
});
|
|
234
305
|
}
|
|
235
306
|
function buildApprovalChatMessage(params) {
|
|
307
|
+
if (params.status === 'Closed') {
|
|
308
|
+
return buildClosedChatMessage({
|
|
309
|
+
roleName: params.roleName,
|
|
310
|
+
roleArabicName: params.roleArabicName,
|
|
311
|
+
comment: params.comment,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
if (params.status === 'Request For Change' || params.status === 'RFC') {
|
|
315
|
+
return buildRequestForChangeChatMessage({
|
|
316
|
+
roleName: params.roleName,
|
|
317
|
+
roleArabicName: params.roleArabicName,
|
|
318
|
+
comment: params.comment,
|
|
319
|
+
variant: 'by',
|
|
320
|
+
});
|
|
321
|
+
}
|
|
236
322
|
let action = 'approved';
|
|
237
323
|
if (params.status === 'Rejected')
|
|
238
324
|
action = 'rejected';
|
|
@@ -245,6 +331,312 @@ function buildApprovalChatMessage(params) {
|
|
|
245
331
|
comment: params.comment,
|
|
246
332
|
});
|
|
247
333
|
}
|
|
334
|
+
// ─── Specialized chat/workflow builders ─────────────────────────────────────
|
|
335
|
+
function formatDotCommentSuffix(comment) {
|
|
336
|
+
const text = comment?.trim();
|
|
337
|
+
return text ? `. Comment: ${text}` : '';
|
|
338
|
+
}
|
|
339
|
+
function formatColonCommentSuffix(comment) {
|
|
340
|
+
const text = comment?.trim();
|
|
341
|
+
return text ? `: ${text}` : '';
|
|
342
|
+
}
|
|
343
|
+
function formatReassignCommentSuffix(comment) {
|
|
344
|
+
const text = comment?.trim();
|
|
345
|
+
return text ? `:${text}` : '';
|
|
346
|
+
}
|
|
347
|
+
function buildClosedChatMessage(params) {
|
|
348
|
+
const roleEn = params.roleName?.trim() || 'Unknown Role';
|
|
349
|
+
const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
|
|
350
|
+
const comment = formatDotCommentSuffix(params.comment);
|
|
351
|
+
return renderSynchronizedChatMessage('request_closed_by_role', { roleName: roleEn, comment }, { roleName: roleAr, comment });
|
|
352
|
+
}
|
|
353
|
+
function buildClosedWorkflowMessage(params) {
|
|
354
|
+
const comment = formatWorkflowCommentSuffix(params.comment);
|
|
355
|
+
const roleEn = params.roleName?.trim();
|
|
356
|
+
if (roleEn) {
|
|
357
|
+
const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
|
|
358
|
+
return renderSynchronizedWorkflowMessage('request_closed_by', { name: roleEn, comment }, { name: roleAr, comment });
|
|
359
|
+
}
|
|
360
|
+
return renderSynchronizedWorkflowMessage('request_closed', { comment }, { comment });
|
|
361
|
+
}
|
|
362
|
+
function buildRequestForChangeChatMessage(params) {
|
|
363
|
+
const roleEn = params.roleName?.trim() || 'Unknown Role';
|
|
364
|
+
const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
|
|
365
|
+
const comment = params.variant === 'requested_by'
|
|
366
|
+
? formatChatCommentSuffix(params.comment)
|
|
367
|
+
: formatColonCommentSuffix(params.comment);
|
|
368
|
+
const key = params.variant === 'requested_by'
|
|
369
|
+
? 'request_for_change_requested_by_role'
|
|
370
|
+
: 'request_for_change_by_role';
|
|
371
|
+
return renderSynchronizedChatMessage(key, { roleName: roleEn, comment }, { roleName: roleAr, comment });
|
|
372
|
+
}
|
|
373
|
+
function buildAttachmentUploadedChatMessage(fileName) {
|
|
374
|
+
const name = fileName?.trim() || 'file';
|
|
375
|
+
return renderSynchronizedChatMessage('attachment_uploaded', { fileName: name }, { fileName: name });
|
|
376
|
+
}
|
|
377
|
+
/** User-typed chat text, or bilingual [Attachment] placeholder when empty. */
|
|
378
|
+
function buildUserOrAttachmentChatMessage(userMessage) {
|
|
379
|
+
const text = userMessage?.trim();
|
|
380
|
+
if (text)
|
|
381
|
+
return { en: text, ar: text };
|
|
382
|
+
return chatTemplate('attachment_placeholder');
|
|
383
|
+
}
|
|
384
|
+
function buildTaskInProgressChatMessage(params) {
|
|
385
|
+
const roleEn = params.roleName?.trim() || 'Employee';
|
|
386
|
+
const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
|
|
387
|
+
return renderSynchronizedChatMessage('task_status_in_progress_by_role', { roleName: roleEn }, { roleName: roleAr });
|
|
388
|
+
}
|
|
389
|
+
function buildTaskCompletedChatMessage(params) {
|
|
390
|
+
const roleEn = params.roleName?.trim() || 'Employee';
|
|
391
|
+
const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
|
|
392
|
+
const comment = formatDotCommentSuffix(params.comment);
|
|
393
|
+
return renderSynchronizedChatMessage('task_completed_by_role', { roleName: roleEn, comment }, { roleName: roleAr, comment });
|
|
394
|
+
}
|
|
395
|
+
function buildTaskStatusUpdatedChatMessage(status, statusAr) {
|
|
396
|
+
const statusEn = status?.trim() || 'Updated';
|
|
397
|
+
const statusArResolved = statusAr?.trim() || resolveChatStatusAr(statusEn) || statusEn;
|
|
398
|
+
return renderSynchronizedChatMessage('task_status_updated', { status: statusEn }, { status: statusArResolved });
|
|
399
|
+
}
|
|
400
|
+
function buildItHelpdeskAssignedChatMessage(params) {
|
|
401
|
+
const assignedRoleEn = params.assignedRoleName?.trim() || 'Role';
|
|
402
|
+
const assignedRoleAr = resolveBilingualName(assignedRoleEn, params.assignedRoleArabicName);
|
|
403
|
+
const assignedUserEn = params.assignedUserName?.trim() || 'User';
|
|
404
|
+
const assignedUserAr = resolveBilingualName(assignedUserEn, params.assignedUserArabicName);
|
|
405
|
+
const comment = params.comment?.trim() ? ` - ${params.comment.trim()}` : '';
|
|
406
|
+
const templateKey = params.level === 1 ? 'it_helpdesk_hos_assigned' : 'it_helpdesk_technician_assigned';
|
|
407
|
+
const enParams = {
|
|
408
|
+
assignedRoleName: assignedRoleEn,
|
|
409
|
+
assignedUserName: assignedUserEn,
|
|
410
|
+
comment,
|
|
411
|
+
};
|
|
412
|
+
const arParams = {
|
|
413
|
+
assignedRoleName: assignedRoleAr,
|
|
414
|
+
assignedUserName: assignedUserAr,
|
|
415
|
+
comment,
|
|
416
|
+
};
|
|
417
|
+
if (params.level !== 1) {
|
|
418
|
+
enParams.level = String(params.level);
|
|
419
|
+
arParams.level = String(params.level);
|
|
420
|
+
}
|
|
421
|
+
return renderSynchronizedChatMessage(templateKey, enParams, arParams);
|
|
422
|
+
}
|
|
423
|
+
function buildItHelpdeskReassignedChatMessage(params) {
|
|
424
|
+
const approverEn = params.approverRoleName?.trim() || 'Role';
|
|
425
|
+
const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
|
|
426
|
+
const comment = formatReassignCommentSuffix(params.comment);
|
|
427
|
+
if (params.level === 1) {
|
|
428
|
+
const reassignedEn = params.reassignedRoleName?.trim() || 'Role';
|
|
429
|
+
const reassignedAr = resolveBilingualName(reassignedEn, params.reassignedRoleArabicName);
|
|
430
|
+
return renderSynchronizedChatMessage('it_helpdesk_reassigned_to_role', { approverRoleName: approverEn, reassignedRoleName: reassignedEn, comment }, { approverRoleName: approverAr, reassignedRoleName: reassignedAr, comment });
|
|
431
|
+
}
|
|
432
|
+
if (params.level === 2) {
|
|
433
|
+
return renderSynchronizedChatMessage('it_helpdesk_reassigned_to_l3', { approverRoleName: approverEn, comment }, { approverRoleName: approverAr, comment });
|
|
434
|
+
}
|
|
435
|
+
const level = String(params.level);
|
|
436
|
+
return renderSynchronizedChatMessage('it_helpdesk_reassigned_generic', { approverRoleName: approverEn, level, comment }, { approverRoleName: approverAr, level, comment });
|
|
437
|
+
}
|
|
438
|
+
function buildRequestSubmittedWithRefChatMessage(params) {
|
|
439
|
+
const userEn = params.userName?.trim() || 'Unknown User';
|
|
440
|
+
const userAr = resolveBilingualName(userEn, params.userArabicName);
|
|
441
|
+
const labelEn = params.requestLabel?.trim() || 'Request';
|
|
442
|
+
const labelAr = params.requestLabelAr?.trim() || labelEn;
|
|
443
|
+
const requestId = String(params.requestId);
|
|
444
|
+
const employeeId = String(params.employeeId ?? 'N/A');
|
|
445
|
+
return renderSynchronizedChatMessage('request_submitted_with_ref', { requestLabel: labelEn, requestId, userName: userEn, employeeId }, { requestLabel: labelAr, requestId, userName: userAr, employeeId });
|
|
446
|
+
}
|
|
447
|
+
function buildSecurityAccessApprovalChatMessage(params) {
|
|
448
|
+
const statusWord = params.decision === 'approve' ? 'approved' : 'rejected';
|
|
449
|
+
const statusWordAr = params.decision === 'approve' ? 'الموافقة على' : 'رفض';
|
|
450
|
+
const comment = params.comment?.trim() ? ` Comment: ${params.comment.trim()}` : '';
|
|
451
|
+
const labelEn = params.productLabel?.trim() || 'Security Access';
|
|
452
|
+
const labelAr = params.productLabelAr?.trim() || labelEn;
|
|
453
|
+
return renderSynchronizedChatMessage('security_access_approval_step', {
|
|
454
|
+
productLabel: labelEn,
|
|
455
|
+
requestId: String(params.requestId),
|
|
456
|
+
statusWord,
|
|
457
|
+
approvalLevel: String(params.approvalLevel),
|
|
458
|
+
comment,
|
|
459
|
+
statusWordAr,
|
|
460
|
+
}, {
|
|
461
|
+
productLabel: labelAr,
|
|
462
|
+
requestId: String(params.requestId),
|
|
463
|
+
statusWord,
|
|
464
|
+
approvalLevel: String(params.approvalLevel),
|
|
465
|
+
comment,
|
|
466
|
+
statusWordAr,
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
function renderSynchronizedNotificationMessage(templateKey, enParams, arParams) {
|
|
470
|
+
const tpl = NOTIFICATION_TEMPLATES[templateKey];
|
|
471
|
+
if (!tpl)
|
|
472
|
+
return { en: templateKey, ar: templateKey };
|
|
473
|
+
return {
|
|
474
|
+
en: interpolate(tpl.en, enParams),
|
|
475
|
+
ar: interpolate(tpl.ar, arParams),
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
function normalizeDisplayValue(value) {
|
|
479
|
+
if (value === undefined || value === null || String(value).trim() === '')
|
|
480
|
+
return 'Not specified';
|
|
481
|
+
return String(value);
|
|
482
|
+
}
|
|
483
|
+
function normalizeDisplayDate(value) {
|
|
484
|
+
if (value === undefined || value === null || String(value).trim() === '')
|
|
485
|
+
return 'Not specified';
|
|
486
|
+
const d = new Date(value);
|
|
487
|
+
if (!isNaN(d.getTime()))
|
|
488
|
+
return d.toISOString().slice(0, 10);
|
|
489
|
+
return String(value);
|
|
490
|
+
}
|
|
491
|
+
function buildItHelpdeskReassignModifiers(params) {
|
|
492
|
+
let en = '';
|
|
493
|
+
let ar = '';
|
|
494
|
+
if (params.sectionFrom != null &&
|
|
495
|
+
params.sectionTo != null &&
|
|
496
|
+
params.sectionFrom !== params.sectionTo) {
|
|
497
|
+
en += ` (Section modified from ${params.sectionFrom} to ${params.sectionTo})`;
|
|
498
|
+
ar += ` (تم تعديل القسم من ${params.sectionFrom} إلى ${params.sectionTo})`;
|
|
499
|
+
}
|
|
500
|
+
if (params.departmentFrom != null &&
|
|
501
|
+
params.departmentTo != null &&
|
|
502
|
+
params.departmentFrom !== params.departmentTo) {
|
|
503
|
+
en += ` (Department modified from ${params.departmentFrom} to ${params.departmentTo})`;
|
|
504
|
+
ar += ` (تم تعديل الإدارة من ${params.departmentFrom} إلى ${params.departmentTo})`;
|
|
505
|
+
}
|
|
506
|
+
return { en, ar };
|
|
507
|
+
}
|
|
508
|
+
function buildItHelpdeskMuscatWorkflowLog(params) {
|
|
509
|
+
const comment = formatColonCommentSuffix('comment' in params ? params.comment : undefined);
|
|
510
|
+
const modifiers = 'modifiers' in params && params.modifiers ? params.modifiers : { en: '', ar: '' };
|
|
511
|
+
switch (params.variant) {
|
|
512
|
+
case 'hos_assigned': {
|
|
513
|
+
const approverEn = params.approverRoleName.trim();
|
|
514
|
+
const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
|
|
515
|
+
const assignedEn = params.assignedRoleName.trim();
|
|
516
|
+
const assignedAr = resolveBilingualName(assignedEn, params.assignedRoleArabicName);
|
|
517
|
+
return renderSynchronizedWorkflowMessage('it_helpdesk_wf_hos_assigned', { approverRoleName: approverEn, assignedRoleName: assignedEn, comment }, { approverRoleName: approverAr, assignedRoleName: assignedAr, comment });
|
|
518
|
+
}
|
|
519
|
+
case 'technician_assigned': {
|
|
520
|
+
const approverEn = params.approverRoleName.trim();
|
|
521
|
+
const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
|
|
522
|
+
return renderSynchronizedWorkflowMessage('it_helpdesk_wf_technician_assigned', { level: String(params.level), approverRoleName: approverEn, comment }, { level: String(params.level), approverRoleName: approverAr, comment });
|
|
523
|
+
}
|
|
524
|
+
case 'reassigned_technician': {
|
|
525
|
+
const approverEn = params.approverRoleName.trim();
|
|
526
|
+
const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
|
|
527
|
+
return renderSynchronizedWorkflowMessage('it_helpdesk_wf_reassigned_technician', { approverRoleName: approverEn, comment, modifiers: modifiers.en }, { approverRoleName: approverAr, comment, modifiers: modifiers.ar });
|
|
528
|
+
}
|
|
529
|
+
case 'reassigned_l3': {
|
|
530
|
+
const approverEn = params.approverRoleName.trim();
|
|
531
|
+
const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
|
|
532
|
+
return renderSynchronizedWorkflowMessage('it_helpdesk_wf_reassigned_l3', { approverRoleName: approverEn, comment, modifiers: modifiers.en }, { approverRoleName: approverAr, comment, modifiers: modifiers.ar });
|
|
533
|
+
}
|
|
534
|
+
case 'reassigned_generic': {
|
|
535
|
+
const approverEn = params.approverRoleName.trim();
|
|
536
|
+
const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
|
|
537
|
+
const level = String(params.level ?? '');
|
|
538
|
+
return renderSynchronizedWorkflowMessage('it_helpdesk_wf_reassigned_generic', { approverRoleName: approverEn, level, comment, modifiers: modifiers.en }, { approverRoleName: approverAr, level, comment, modifiers: modifiers.ar });
|
|
539
|
+
}
|
|
540
|
+
case 'closed_level1': {
|
|
541
|
+
const approverEn = params.approverRoleName.trim();
|
|
542
|
+
const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
|
|
543
|
+
return renderSynchronizedWorkflowMessage('it_helpdesk_wf_closed_request', { approverRoleName: approverEn, comment }, { approverRoleName: approverAr, comment });
|
|
544
|
+
}
|
|
545
|
+
case 'closed_level2': {
|
|
546
|
+
const approverEn = params.approverRoleName.trim();
|
|
547
|
+
const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
|
|
548
|
+
return renderSynchronizedWorkflowMessage('it_helpdesk_wf_closed_request_cap', { approverRoleName: approverEn, comment }, { approverRoleName: approverAr, comment });
|
|
549
|
+
}
|
|
550
|
+
case 'l3_approved': {
|
|
551
|
+
const roleEn = params.roleName.trim();
|
|
552
|
+
const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
|
|
553
|
+
const userEn = params.userName.trim();
|
|
554
|
+
const userAr = resolveBilingualName(userEn, params.userArabicName);
|
|
555
|
+
return renderSynchronizedWorkflowMessage('it_helpdesk_wf_l3_approved_by', { roleName: roleEn, userName: userEn, comment }, { roleName: roleAr, userName: userAr, comment });
|
|
556
|
+
}
|
|
557
|
+
case 'l3_rejected': {
|
|
558
|
+
const roleEn = params.roleName.trim();
|
|
559
|
+
const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
|
|
560
|
+
const userEn = params.userName.trim();
|
|
561
|
+
const userAr = resolveBilingualName(userEn, params.userArabicName);
|
|
562
|
+
return renderSynchronizedWorkflowMessage('it_helpdesk_wf_l3_rejected_by', { roleName: roleEn, userName: userEn, comment }, { roleName: roleAr, userName: userAr, comment });
|
|
563
|
+
}
|
|
564
|
+
case 'level_approved': {
|
|
565
|
+
const approverEn = params.approverRoleName.trim();
|
|
566
|
+
const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
|
|
567
|
+
return renderSynchronizedWorkflowMessage('it_helpdesk_wf_level_approved', { level: String(params.level), approverRoleName: approverEn, comment }, { level: String(params.level), approverRoleName: approverAr, comment });
|
|
568
|
+
}
|
|
569
|
+
case 'rejected':
|
|
570
|
+
case 'l3_step_rejected': {
|
|
571
|
+
const key = params.variant === 'l3_step_rejected'
|
|
572
|
+
? 'it_helpdesk_wf_l3_step_rejected'
|
|
573
|
+
: 'it_helpdesk_wf_rejected';
|
|
574
|
+
const roleEn = params.approverRoleName.trim();
|
|
575
|
+
const roleAr = resolveBilingualName(roleEn, params.approverRoleArabicName);
|
|
576
|
+
return renderSynchronizedWorkflowMessage(key, { approverRoleName: roleEn, roleName: roleEn, comment }, { approverRoleName: roleAr, roleName: roleAr, comment });
|
|
577
|
+
}
|
|
578
|
+
case 'generic_status': {
|
|
579
|
+
const approverEn = params.approverRoleName.trim();
|
|
580
|
+
const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
|
|
581
|
+
const statusEn = params.status.toLowerCase();
|
|
582
|
+
const statusAr = resolveChatStatusAr(params.status) ?? statusEn;
|
|
583
|
+
return renderSynchronizedWorkflowMessage('it_helpdesk_wf_status_by_role', { status: statusEn, statusAr, approverRoleName: approverEn, comment }, { status: statusEn, statusAr, approverRoleName: approverAr, comment });
|
|
584
|
+
}
|
|
585
|
+
case 'technician_completed': {
|
|
586
|
+
const roleEn = params.roleName.trim();
|
|
587
|
+
const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
|
|
588
|
+
return renderSynchronizedWorkflowMessage('it_helpdesk_wf_technician_completed', { roleName: roleEn, comment }, { roleName: roleAr, comment });
|
|
589
|
+
}
|
|
590
|
+
case 'routing_rejected':
|
|
591
|
+
return renderSynchronizedWorkflowMessage('it_helpdesk_wf_routing_rejected', { comment }, { comment });
|
|
592
|
+
case 'routing_resolved':
|
|
593
|
+
return workflowTemplate('it_helpdesk_wf_routing_resolved');
|
|
594
|
+
default:
|
|
595
|
+
return workflowTemplate('request_submitted');
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
function buildLogisticsActualReturnChatMessage(params) {
|
|
599
|
+
const roleEn = params.roleName.trim() || 'Unknown Role';
|
|
600
|
+
const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
|
|
601
|
+
const date = normalizeDisplayDate(params.returnDetails.actual_return_date);
|
|
602
|
+
const time = normalizeDisplayValue(params.returnDetails.actual_vehicle_return_time);
|
|
603
|
+
const reason = normalizeDisplayValue(params.returnDetails.reason);
|
|
604
|
+
return renderSynchronizedChatMessage('logistics_actual_return_updated', { roleName: roleEn, date, time, reason }, { roleName: roleAr, date, time, reason });
|
|
605
|
+
}
|
|
606
|
+
function buildLogisticsActualReturnNotificationBody(params) {
|
|
607
|
+
const requestLabel = params.requestTypeLabel
|
|
608
|
+
? `${params.requestTypeLabel} Request`
|
|
609
|
+
: 'Vehicle Request';
|
|
610
|
+
const requestLabelAr = params.requestTypeLabel
|
|
611
|
+
? `طلب ${params.requestTypeLabel}`
|
|
612
|
+
: 'طلب المركبة';
|
|
613
|
+
const requestId = normalizeDisplayValue(params.requestId);
|
|
614
|
+
const en = [
|
|
615
|
+
`${requestLabel} #${requestId}`,
|
|
616
|
+
`Actual Return Date: ${normalizeDisplayDate(params.actual_return_date)}`,
|
|
617
|
+
`Actual Return Time: ${normalizeDisplayValue(params.actual_vehicle_return_time)}`,
|
|
618
|
+
`Reason: ${normalizeDisplayValue(params.reason)}`,
|
|
619
|
+
].join('\n');
|
|
620
|
+
const ar = [
|
|
621
|
+
`${requestLabelAr} رقم ${requestId}`,
|
|
622
|
+
`تاريخ الإرجاع الفعلي: ${normalizeDisplayDate(params.actual_return_date)}`,
|
|
623
|
+
`وقت الإرجاع الفعلي: ${normalizeDisplayValue(params.actual_vehicle_return_time)}`,
|
|
624
|
+
`السبب: ${normalizeDisplayValue(params.reason)}`,
|
|
625
|
+
].join('\n');
|
|
626
|
+
return { en, ar };
|
|
627
|
+
}
|
|
628
|
+
function buildLogisticsActualReturnNotificationTitle(params) {
|
|
629
|
+
const requestLabel = params.requestTypeLabel || 'Vehicle';
|
|
630
|
+
const requestId = String(params.requestId ?? '');
|
|
631
|
+
return renderSynchronizedNotificationMessage('logistics_actual_return_title', { requestLabel, requestId }, { requestLabel, requestId });
|
|
632
|
+
}
|
|
633
|
+
function buildItHelpdeskCloseNotificationMessage(params) {
|
|
634
|
+
const requestId = String(params.requestId);
|
|
635
|
+
const key = params.status === 'Rejected'
|
|
636
|
+
? 'it_helpdesk_notif_request_rejected'
|
|
637
|
+
: 'it_helpdesk_notif_request_closed';
|
|
638
|
+
return renderSynchronizedNotificationMessage(key, { requestId }, { requestId });
|
|
639
|
+
}
|
|
248
640
|
// ─── Status labels ───────────────────────────────────────────────────────────
|
|
249
641
|
function resolveWorkflowStatusAr(status) {
|
|
250
642
|
if (status == null || status === '')
|
|
@@ -257,7 +649,47 @@ function resolveChatStatusAr(status) {
|
|
|
257
649
|
return CHAT_STATUS_LABELS[status] ?? status;
|
|
258
650
|
}
|
|
259
651
|
// ─── Legacy row enrichment (read API) ────────────────────────────────────────
|
|
260
|
-
|
|
652
|
+
/** Pull bilingual actor fields from joined relations on workflow/chat rows. */
|
|
653
|
+
function extractBilingualActorsFromRecord(record) {
|
|
654
|
+
const role = (record.approver_role ?? record.role);
|
|
655
|
+
const user = (record.approver_user ?? record.user);
|
|
656
|
+
const dept = (record.approver_department ?? record.department);
|
|
657
|
+
const section = (record.approver_section ?? record.section);
|
|
658
|
+
return {
|
|
659
|
+
roleName: role?.name != null ? String(role.name) : null,
|
|
660
|
+
roleArabicName: role?.arabic_name != null ? String(role.arabic_name) : null,
|
|
661
|
+
deptName: dept?.department_name != null ? String(dept.department_name) : null,
|
|
662
|
+
deptArabicName: dept?.department_arabic_name != null ? String(dept.department_arabic_name) : null,
|
|
663
|
+
sectionName: section?.section_name != null ? String(section.section_name) : null,
|
|
664
|
+
sectionArabicName: section?.section_arabic_name != null ? String(section.section_arabic_name) : null,
|
|
665
|
+
userName: user?.employee_name != null ? String(user.employee_name) : null,
|
|
666
|
+
userArabicName: user?.employee_arabic_name != null ? String(user.employee_arabic_name) : null,
|
|
667
|
+
employeeId: user?.employee_id != null ? String(user.employee_id) : null,
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
/** Arabic actor label for workflow templates (role, dept+section, or user). */
|
|
671
|
+
function resolveArabicWorkflowActorName(actors, parsedEnglishName) {
|
|
672
|
+
if (actors) {
|
|
673
|
+
const { ar } = resolveActorDisplayNames(actors);
|
|
674
|
+
if (ar)
|
|
675
|
+
return ar;
|
|
676
|
+
if (actors.userName?.trim()) {
|
|
677
|
+
return resolveBilingualName(actors.userName, actors.userArabicName);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
return parsedEnglishName?.trim() || '';
|
|
681
|
+
}
|
|
682
|
+
/** Arabic role/user label for chat templates. */
|
|
683
|
+
function resolveArabicChatRoleName(actors, parsedEnglishRole) {
|
|
684
|
+
if (actors?.roleName?.trim()) {
|
|
685
|
+
return resolveBilingualName(actors.roleName, actors.roleArabicName);
|
|
686
|
+
}
|
|
687
|
+
if (actors?.userName?.trim()) {
|
|
688
|
+
return resolveBilingualName(actors.userName, actors.userArabicName);
|
|
689
|
+
}
|
|
690
|
+
return resolveBilingualName(parsedEnglishRole, actors?.roleArabicName);
|
|
691
|
+
}
|
|
692
|
+
function resolveWorkflowContentAr(content, actors) {
|
|
261
693
|
if (content == null || content.trim() === '')
|
|
262
694
|
return null;
|
|
263
695
|
const normalized = content.trim();
|
|
@@ -277,8 +709,9 @@ function resolveWorkflowContentAr(content) {
|
|
|
277
709
|
if (withoutComment.includes('{{name}}')) {
|
|
278
710
|
const staticPrefix = withoutComment.replace('{{name}}', '').trim();
|
|
279
711
|
if (baseEn.startsWith(staticPrefix)) {
|
|
280
|
-
const
|
|
281
|
-
|
|
712
|
+
const namePartEn = baseEn.slice(staticPrefix.length).trim();
|
|
713
|
+
const nameAr = resolveArabicWorkflowActorName(actors, namePartEn);
|
|
714
|
+
return interpolate(tpl.ar, { name: nameAr, comment: commentSuffix });
|
|
282
715
|
}
|
|
283
716
|
}
|
|
284
717
|
else if (withoutComment.trim() === baseEn) {
|
|
@@ -288,17 +721,19 @@ function resolveWorkflowContentAr(content) {
|
|
|
288
721
|
}
|
|
289
722
|
const inProgressPrefix = WORKFLOW_TEMPLATES.request_approval_in_progress_from?.en.split('{{name}}')[0].trim();
|
|
290
723
|
if (inProgressPrefix && normalized.startsWith(inProgressPrefix)) {
|
|
291
|
-
const
|
|
292
|
-
|
|
724
|
+
const namePartEn = normalized.slice(inProgressPrefix.length).trim();
|
|
725
|
+
const nameAr = resolveArabicWorkflowActorName(actors, namePartEn);
|
|
726
|
+
return interpolate(WORKFLOW_TEMPLATES.request_approval_in_progress_from.ar, { name: nameAr });
|
|
293
727
|
}
|
|
294
728
|
const pendingPrefix = WORKFLOW_TEMPLATES.request_approval_pending_from?.en.split('{{name}}')[0].trim();
|
|
295
729
|
if (pendingPrefix && normalized.startsWith(pendingPrefix)) {
|
|
296
|
-
const
|
|
297
|
-
|
|
730
|
+
const namePartEn = normalized.slice(pendingPrefix.length).trim();
|
|
731
|
+
const nameAr = resolveArabicWorkflowActorName(actors, namePartEn);
|
|
732
|
+
return interpolate(WORKFLOW_TEMPLATES.request_approval_pending_from.ar, { name: nameAr });
|
|
298
733
|
}
|
|
299
734
|
return null;
|
|
300
735
|
}
|
|
301
|
-
function resolveChatMessageAr(message) {
|
|
736
|
+
function resolveChatMessageAr(message, actors) {
|
|
302
737
|
if (message == null || message.trim() === '')
|
|
303
738
|
return null;
|
|
304
739
|
const normalized = message.trim();
|
|
@@ -306,6 +741,24 @@ function resolveChatMessageAr(message) {
|
|
|
306
741
|
if (tpl.en === normalized)
|
|
307
742
|
return tpl.ar;
|
|
308
743
|
}
|
|
744
|
+
for (const tplKey of ['request_submitted_by', 'cancellation_submitted_by']) {
|
|
745
|
+
const submittedTpl = CHAT_TEMPLATES[tplKey];
|
|
746
|
+
if (!submittedTpl)
|
|
747
|
+
continue;
|
|
748
|
+
const prefix = submittedTpl.en.split('{{userName}}')[0];
|
|
749
|
+
if (!normalized.startsWith(prefix))
|
|
750
|
+
continue;
|
|
751
|
+
const afterPrefix = normalized.slice(prefix.length);
|
|
752
|
+
const parenMatch = afterPrefix.match(/^(.+?) \((.+)\)$/);
|
|
753
|
+
if (parenMatch) {
|
|
754
|
+
const userEn = parenMatch[1].trim();
|
|
755
|
+
const employeeId = parenMatch[2].trim();
|
|
756
|
+
const userAr = actors?.userName?.trim()
|
|
757
|
+
? resolveBilingualName(actors.userName, actors.userArabicName)
|
|
758
|
+
: resolveBilingualName(userEn, actors?.userArabicName);
|
|
759
|
+
return interpolate(submittedTpl.ar, { userName: userAr, employeeId });
|
|
760
|
+
}
|
|
761
|
+
}
|
|
309
762
|
for (const tpl of Object.values(CHAT_TEMPLATES)) {
|
|
310
763
|
if (!tpl.en.includes('{{roleName}}'))
|
|
311
764
|
continue;
|
|
@@ -314,13 +767,10 @@ function resolveChatMessageAr(message) {
|
|
|
314
767
|
continue;
|
|
315
768
|
const rest = normalized.slice(prefix.length);
|
|
316
769
|
const commentIdx = rest.lastIndexOf(' - ');
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
return interpolate(tpl.ar, { roleName: rest, comment: '' });
|
|
770
|
+
const roleNameEn = commentIdx >= 0 ? rest.slice(0, commentIdx) : rest;
|
|
771
|
+
const commentSuffix = commentIdx >= 0 ? rest.slice(commentIdx) : '';
|
|
772
|
+
const roleNameAr = resolveArabicChatRoleName(actors, roleNameEn.trim());
|
|
773
|
+
return interpolate(tpl.ar, { roleName: roleNameAr, comment: commentSuffix });
|
|
324
774
|
}
|
|
325
775
|
return null;
|
|
326
776
|
}
|
|
@@ -328,9 +778,10 @@ function resolveChatMessageAr(message) {
|
|
|
328
778
|
function enrichWorkflowLog(log) {
|
|
329
779
|
const status = log.status != null ? String(log.status) : null;
|
|
330
780
|
const content = log.content != null ? String(log.content) : null;
|
|
781
|
+
const actors = extractBilingualActorsFromRecord(log);
|
|
331
782
|
return {
|
|
332
783
|
...log,
|
|
333
|
-
content_ar: log.content_ar ?? resolveWorkflowContentAr(content),
|
|
784
|
+
content_ar: log.content_ar ?? resolveWorkflowContentAr(content, actors),
|
|
334
785
|
status_ar: log.status_ar ?? resolveWorkflowStatusAr(status),
|
|
335
786
|
};
|
|
336
787
|
}
|
|
@@ -338,9 +789,10 @@ function enrichWorkflowLog(log) {
|
|
|
338
789
|
function enrichChatMessage(chat) {
|
|
339
790
|
const status = chat.status != null ? String(chat.status) : null;
|
|
340
791
|
const message = chat.message != null ? String(chat.message) : null;
|
|
792
|
+
const actors = extractBilingualActorsFromRecord(chat);
|
|
341
793
|
return {
|
|
342
794
|
...chat,
|
|
343
|
-
message_ar: chat.message_ar ?? resolveChatMessageAr(message),
|
|
795
|
+
message_ar: chat.message_ar ?? resolveChatMessageAr(message, actors),
|
|
344
796
|
status_ar: chat.status_ar ?? resolveChatStatusAr(status),
|
|
345
797
|
};
|
|
346
798
|
}
|
|
@@ -14,7 +14,9 @@ export declare class AccessCardRequestChat extends BaseModel {
|
|
|
14
14
|
user_id: number;
|
|
15
15
|
role_id: number;
|
|
16
16
|
message: string;
|
|
17
|
+
message_ar: string | null;
|
|
17
18
|
messageType: AccessCardMessageType;
|
|
18
19
|
status: string;
|
|
20
|
+
status_ar: string | null;
|
|
19
21
|
constructor(request_id: number, user_id: number, role_id: number, message: string, service_id?: number, sub_service_id?: number, messageType?: AccessCardMessageType, status?: AccessCardApprovalStatus);
|
|
20
22
|
}
|
|
@@ -59,6 +59,10 @@ __decorate([
|
|
|
59
59
|
(0, typeorm_1.Column)({ type: "text", nullable: false }),
|
|
60
60
|
__metadata("design:type", String)
|
|
61
61
|
], AccessCardRequestChat.prototype, "message", void 0);
|
|
62
|
+
__decorate([
|
|
63
|
+
(0, typeorm_1.Column)({ type: "text", nullable: true }),
|
|
64
|
+
__metadata("design:type", Object)
|
|
65
|
+
], AccessCardRequestChat.prototype, "message_ar", void 0);
|
|
62
66
|
__decorate([
|
|
63
67
|
(0, typeorm_1.Column)({
|
|
64
68
|
type: "enum",
|
|
@@ -72,6 +76,10 @@ __decorate([
|
|
|
72
76
|
(0, typeorm_1.Column)({ type: 'text', nullable: true }),
|
|
73
77
|
__metadata("design:type", String)
|
|
74
78
|
], AccessCardRequestChat.prototype, "status", void 0);
|
|
79
|
+
__decorate([
|
|
80
|
+
(0, typeorm_1.Column)({ type: "varchar", length: 100, nullable: true }),
|
|
81
|
+
__metadata("design:type", Object)
|
|
82
|
+
], AccessCardRequestChat.prototype, "status_ar", void 0);
|
|
75
83
|
exports.AccessCardRequestChat = AccessCardRequestChat = __decorate([
|
|
76
84
|
(0, typeorm_1.Entity)({ name: "access_card_request_chat" }),
|
|
77
85
|
__metadata("design:paramtypes", [Number, Number, Number, String, Number, Number, String, String])
|
|
@@ -9,7 +9,9 @@ export declare class AccessCardWorkflow extends BaseModel {
|
|
|
9
9
|
service_id: number | null;
|
|
10
10
|
sub_service_id: number | null;
|
|
11
11
|
content: string;
|
|
12
|
+
content_ar: string | null;
|
|
12
13
|
status: AccessCardWorkflowStatus;
|
|
14
|
+
status_ar: string | null;
|
|
13
15
|
user_id: number | null;
|
|
14
16
|
role_id: number | null;
|
|
15
17
|
department_id: number | null;
|
|
@@ -49,6 +49,10 @@ __decorate([
|
|
|
49
49
|
(0, typeorm_1.Column)({ type: "varchar", length: 500, nullable: false }),
|
|
50
50
|
__metadata("design:type", String)
|
|
51
51
|
], AccessCardWorkflow.prototype, "content", void 0);
|
|
52
|
+
__decorate([
|
|
53
|
+
(0, typeorm_1.Column)({ type: "varchar", length: 500, nullable: true }),
|
|
54
|
+
__metadata("design:type", Object)
|
|
55
|
+
], AccessCardWorkflow.prototype, "content_ar", void 0);
|
|
52
56
|
__decorate([
|
|
53
57
|
(0, typeorm_1.Column)({
|
|
54
58
|
type: "enum",
|
|
@@ -58,6 +62,10 @@ __decorate([
|
|
|
58
62
|
}),
|
|
59
63
|
__metadata("design:type", String)
|
|
60
64
|
], AccessCardWorkflow.prototype, "status", void 0);
|
|
65
|
+
__decorate([
|
|
66
|
+
(0, typeorm_1.Column)({ type: "varchar", length: 100, nullable: true }),
|
|
67
|
+
__metadata("design:type", Object)
|
|
68
|
+
], AccessCardWorkflow.prototype, "status_ar", void 0);
|
|
61
69
|
__decorate([
|
|
62
70
|
(0, typeorm_1.Column)({ type: "integer", nullable: true }),
|
|
63
71
|
__metadata("design:type", Object)
|
|
@@ -12,10 +12,12 @@ export declare class AccommodationChat extends BaseModel {
|
|
|
12
12
|
sub_service_id: number;
|
|
13
13
|
user_id: number;
|
|
14
14
|
message: string;
|
|
15
|
+
message_ar: string | null;
|
|
15
16
|
message_type: string;
|
|
16
17
|
is_internal: boolean;
|
|
17
18
|
approver_role_id: number;
|
|
18
19
|
status: string;
|
|
20
|
+
status_ar: string | null;
|
|
19
21
|
created_by: number;
|
|
20
22
|
constructor();
|
|
21
23
|
}
|