@platform-modules/foreign-ministry 1.3.335 → 1.3.336

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.
Files changed (361) hide show
  1. package/.env +6 -5
  2. package/dist/i18n/workflow-chat-i18n.d.ts +5 -0
  3. package/dist/i18n/workflow-chat-i18n.js +21 -0
  4. package/dist/i18n/workflow-chat-i18n.json +320 -0
  5. package/dist/i18n/workflow-chat-message.builder.d.ts +316 -0
  6. package/dist/i18n/workflow-chat-message.builder.js +891 -0
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.js +1 -0
  9. package/dist/models/AppointmentChatModel.d.ts +2 -0
  10. package/dist/models/AppointmentChatModel.js +8 -0
  11. package/dist/models/AppointmentWorkflowModel.d.ts +2 -0
  12. package/dist/models/AppointmentWorkflowModel.js +8 -0
  13. package/dist/models/AssistanceCitizensAbroadChatModel.d.ts +2 -0
  14. package/dist/models/AssistanceCitizensAbroadChatModel.js +8 -0
  15. package/dist/models/AssistanceCitizensAbroadWorkflowModel.d.ts +1 -0
  16. package/dist/models/AssistanceCitizensAbroadWorkflowModel.js +4 -0
  17. package/dist/models/ChildrensEducationChatModel.d.ts +2 -0
  18. package/dist/models/ChildrensEducationChatModel.js +8 -0
  19. package/dist/models/ChildrensEducationWorkflowModel.d.ts +1 -0
  20. package/dist/models/ChildrensEducationWorkflowModel.js +4 -0
  21. package/dist/models/DiplomaticAcademyChatModel.d.ts +2 -0
  22. package/dist/models/DiplomaticAcademyChatModel.js +8 -0
  23. package/dist/models/DiplomaticAcademyWorkflowModel.d.ts +2 -0
  24. package/dist/models/DiplomaticAcademyWorkflowModel.js +8 -0
  25. package/dist/models/DiplomaticChatsModel.d.ts +2 -0
  26. package/dist/models/DiplomaticChatsModel.js +8 -0
  27. package/dist/models/DiplomaticWorkFlowModel.d.ts +2 -0
  28. package/dist/models/DiplomaticWorkFlowModel.js +8 -0
  29. package/dist/models/DocumentTranslationChatModel.d.ts +2 -0
  30. package/dist/models/DocumentTranslationChatModel.js +8 -0
  31. package/dist/models/DocumentTranslationWorkflowModel.d.ts +2 -0
  32. package/dist/models/DocumentTranslationWorkflowModel.js +8 -0
  33. package/dist/models/EarlyCheckoutChatModel.d.ts +2 -0
  34. package/dist/models/EarlyCheckoutChatModel.js +8 -0
  35. package/dist/models/EarlyCheckoutWorkflowModel.d.ts +2 -0
  36. package/dist/models/EarlyCheckoutWorkflowModel.js +8 -0
  37. package/dist/models/EmbassyEvaluationChatModel.d.ts +1 -0
  38. package/dist/models/EmbassyEvaluationChatModel.js +4 -0
  39. package/dist/models/EmbassyEvaluationWorkflowModel.d.ts +1 -0
  40. package/dist/models/EmbassyEvaluationWorkflowModel.js +4 -0
  41. package/dist/models/EmployeeCardChatsModel.d.ts +2 -0
  42. package/dist/models/EmployeeCardChatsModel.js +8 -0
  43. package/dist/models/EmployeeCardWorkFlowModel.d.ts +2 -0
  44. package/dist/models/EmployeeCardWorkFlowModel.js +8 -0
  45. package/dist/models/EmployeeEvaluationChatModel.d.ts +1 -0
  46. package/dist/models/EmployeeEvaluationChatModel.js +4 -0
  47. package/dist/models/EmployeeEvaluationWorkflowModel.d.ts +1 -0
  48. package/dist/models/EmployeeEvaluationWorkflowModel.js +4 -0
  49. package/dist/models/EmployeeOfMonthNominationChatModel.d.ts +1 -0
  50. package/dist/models/EmployeeOfMonthNominationChatModel.js +4 -0
  51. package/dist/models/EmployeeOfMonthNominationWorkflowModel.d.ts +1 -0
  52. package/dist/models/EmployeeOfMonthNominationWorkflowModel.js +4 -0
  53. package/dist/models/EmployeeOfMonthSupportNominationChatModel.d.ts +1 -0
  54. package/dist/models/EmployeeOfMonthSupportNominationChatModel.js +4 -0
  55. package/dist/models/EmployeeOfMonthSupportNominationWorkflowModel.d.ts +1 -0
  56. package/dist/models/EmployeeOfMonthSupportNominationWorkflowModel.js +4 -0
  57. package/dist/models/FinancialChatsModel.d.ts +2 -0
  58. package/dist/models/FinancialChatsModel.js +8 -0
  59. package/dist/models/FinancialWorkFlowModel.d.ts +2 -0
  60. package/dist/models/FinancialWorkFlowModel.js +8 -0
  61. package/dist/models/FoodChatModel.d.ts +1 -0
  62. package/dist/models/FoodChatModel.js +4 -0
  63. package/dist/models/FoodWorkflowModel.d.ts +2 -0
  64. package/dist/models/FoodWorkflowModel.js +8 -0
  65. package/dist/models/GatePassChatsModel.d.ts +2 -0
  66. package/dist/models/GatePassChatsModel.js +8 -0
  67. package/dist/models/GatePassWorkFlowModel.d.ts +2 -0
  68. package/dist/models/GatePassWorkFlowModel.js +8 -0
  69. package/dist/models/GeneralServiceChatsModel.d.ts +2 -0
  70. package/dist/models/GeneralServiceChatsModel.js +8 -0
  71. package/dist/models/GeneralServiceWorkFlowModel.d.ts +2 -0
  72. package/dist/models/GeneralServiceWorkFlowModel.js +8 -0
  73. package/dist/models/HallChatModel.d.ts +1 -0
  74. package/dist/models/HallChatModel.js +4 -0
  75. package/dist/models/HallWorkflowModel.d.ts +2 -0
  76. package/dist/models/HallWorkflowModel.js +8 -0
  77. package/dist/models/HousingRentalAccommodationChatModel.d.ts +2 -0
  78. package/dist/models/HousingRentalAccommodationChatModel.js +8 -0
  79. package/dist/models/HousingRentalAccommodationWorkflowModel.d.ts +1 -0
  80. package/dist/models/HousingRentalAccommodationWorkflowModel.js +4 -0
  81. package/dist/models/HousingRentalVehicleChatModel.d.ts +2 -0
  82. package/dist/models/HousingRentalVehicleChatModel.js +8 -0
  83. package/dist/models/HousingRentalVehicleWorkflowModel.d.ts +1 -0
  84. package/dist/models/HousingRentalVehicleWorkflowModel.js +4 -0
  85. package/dist/models/InitiatorEmployeeNominationChatModel.d.ts +1 -0
  86. package/dist/models/InitiatorEmployeeNominationChatModel.js +4 -0
  87. package/dist/models/InitiatorEmployeeNominationWorkflowModel.d.ts +1 -0
  88. package/dist/models/InitiatorEmployeeNominationWorkflowModel.js +4 -0
  89. package/dist/models/InnovativeEmployeeNominationChatModel.d.ts +1 -0
  90. package/dist/models/InnovativeEmployeeNominationChatModel.js +4 -0
  91. package/dist/models/InnovativeEmployeeNominationWorkflowModel.d.ts +1 -0
  92. package/dist/models/InnovativeEmployeeNominationWorkflowModel.js +4 -0
  93. package/dist/models/IpeGrievanceChatModel.d.ts +1 -0
  94. package/dist/models/IpeGrievanceChatModel.js +4 -0
  95. package/dist/models/IpeGrievanceWorkflowModel.d.ts +1 -0
  96. package/dist/models/IpeGrievanceWorkflowModel.js +4 -0
  97. package/dist/models/LMSCourseExternalLecturerChatModel.d.ts +2 -0
  98. package/dist/models/LMSCourseExternalLecturerChatModel.js +8 -0
  99. package/dist/models/LMSCourseExternalLecturerWorkflowModel.d.ts +2 -0
  100. package/dist/models/LMSCourseExternalLecturerWorkflowModel.js +8 -0
  101. package/dist/models/LMSExternalCourseParticipationChatModel.d.ts +2 -0
  102. package/dist/models/LMSExternalCourseParticipationChatModel.js +8 -0
  103. package/dist/models/LMSExternalCourseParticipationWorkflowModel.d.ts +2 -0
  104. package/dist/models/LMSExternalCourseParticipationWorkflowModel.js +8 -0
  105. package/dist/models/LMSExternalEntityTrainedChatModel.d.ts +2 -0
  106. package/dist/models/LMSExternalEntityTrainedChatModel.js +8 -0
  107. package/dist/models/LMSExternalEntityTrainedWorkflowModel.d.ts +2 -0
  108. package/dist/models/LMSExternalEntityTrainedWorkflowModel.js +8 -0
  109. package/dist/models/LanguageCourseChatModel.d.ts +2 -0
  110. package/dist/models/LanguageCourseChatModel.js +8 -0
  111. package/dist/models/LanguageCourseWorkflowModel.d.ts +2 -0
  112. package/dist/models/LanguageCourseWorkflowModel.js +8 -0
  113. package/dist/models/LeaveChatModel.d.ts +2 -0
  114. package/dist/models/LeaveChatModel.js +8 -0
  115. package/dist/models/LeaveWorkFlowModel.d.ts +2 -0
  116. package/dist/models/LeaveWorkFlowModel.js +8 -0
  117. package/dist/models/MediaChatModel.d.ts +2 -0
  118. package/dist/models/MediaChatModel.js +8 -0
  119. package/dist/models/MediaWorkflowModel.d.ts +2 -0
  120. package/dist/models/MediaWorkflowModel.js +8 -0
  121. package/dist/models/MedicalExpensesChatModel.d.ts +2 -0
  122. package/dist/models/MedicalExpensesChatModel.js +8 -0
  123. package/dist/models/MedicalExpensesWorkflowModel.d.ts +1 -0
  124. package/dist/models/MedicalExpensesWorkflowModel.js +4 -0
  125. package/dist/models/MeetingChatModel.d.ts +2 -0
  126. package/dist/models/MeetingChatModel.js +8 -0
  127. package/dist/models/MeetingWorkflowModel.d.ts +2 -0
  128. package/dist/models/MeetingWorkflowModel.js +8 -0
  129. package/dist/models/MissionBankAccountChatModel.d.ts +2 -0
  130. package/dist/models/MissionBankAccountChatModel.js +8 -0
  131. package/dist/models/MissionBankAccountWorkflowModel.d.ts +2 -0
  132. package/dist/models/MissionBankAccountWorkflowModel.js +8 -0
  133. package/dist/models/MissionContractsChatModel.d.ts +2 -0
  134. package/dist/models/MissionContractsChatModel.js +8 -0
  135. package/dist/models/MissionContractsWorkflowModel.d.ts +1 -0
  136. package/dist/models/MissionContractsWorkflowModel.js +4 -0
  137. package/dist/models/MissionTravelChatModel.d.ts +1 -0
  138. package/dist/models/MissionTravelChatModel.js +4 -0
  139. package/dist/models/MissionTravelWorkflowModel.d.ts +2 -0
  140. package/dist/models/MissionTravelWorkflowModel.js +8 -0
  141. package/dist/models/NationalDayCelebrationsChatModel.d.ts +2 -0
  142. package/dist/models/NationalDayCelebrationsChatModel.js +8 -0
  143. package/dist/models/NationalDayCelebrationsWorkflowModel.d.ts +1 -0
  144. package/dist/models/NationalDayCelebrationsWorkflowModel.js +4 -0
  145. package/dist/models/RecruitmentDomesticWorkersChatModel.d.ts +2 -0
  146. package/dist/models/RecruitmentDomesticWorkersChatModel.js +8 -0
  147. package/dist/models/RecruitmentDomesticWorkersWorkflowModel.d.ts +1 -0
  148. package/dist/models/RecruitmentDomesticWorkersWorkflowModel.js +4 -0
  149. package/dist/models/RegisterCandidateChatModel.d.ts +2 -0
  150. package/dist/models/RegisterCandidateChatModel.js +8 -0
  151. package/dist/models/RegisterCandidateWorkflowModel.d.ts +2 -0
  152. package/dist/models/RegisterCandidateWorkflowModel.js +8 -0
  153. package/dist/models/RegisterVacancyChatModel.d.ts +2 -0
  154. package/dist/models/RegisterVacancyChatModel.js +8 -0
  155. package/dist/models/RegisterVacancyWorkflowModel.d.ts +2 -0
  156. package/dist/models/RegisterVacancyWorkflowModel.js +8 -0
  157. package/dist/models/RepatriationCitizensChatModel.d.ts +2 -0
  158. package/dist/models/RepatriationCitizensChatModel.js +8 -0
  159. package/dist/models/RepatriationCitizensWorkflowModel.d.ts +1 -0
  160. package/dist/models/RepatriationCitizensWorkflowModel.js +4 -0
  161. package/dist/models/RequestParcelChatModel.d.ts +2 -0
  162. package/dist/models/RequestParcelChatModel.js +8 -0
  163. package/dist/models/RequestParcelWorkflowModel.d.ts +2 -0
  164. package/dist/models/RequestParcelWorkflowModel.js +8 -0
  165. package/dist/models/RequestPassportChatModel.d.ts +2 -0
  166. package/dist/models/RequestPassportChatModel.js +8 -0
  167. package/dist/models/RequestPassportWorkflowModel.d.ts +2 -0
  168. package/dist/models/RequestPassportWorkflowModel.js +8 -0
  169. package/dist/models/ResignationTerminationChatModel.d.ts +2 -0
  170. package/dist/models/ResignationTerminationChatModel.js +8 -0
  171. package/dist/models/ResignationTerminationWorkflowModel.d.ts +2 -0
  172. package/dist/models/ResignationTerminationWorkflowModel.js +8 -0
  173. package/dist/models/RetiredCardChatsModel.d.ts +2 -0
  174. package/dist/models/RetiredCardChatsModel.js +8 -0
  175. package/dist/models/RetiredCardWorkFlowModel.d.ts +2 -0
  176. package/dist/models/RetiredCardWorkFlowModel.js +8 -0
  177. package/dist/models/SecurityChatsModel.d.ts +2 -0
  178. package/dist/models/SecurityChatsModel.js +8 -0
  179. package/dist/models/SlaApprovalsViewModel.js +47 -47
  180. package/dist/models/SlaMyRequestsViewModel.js +52 -52
  181. package/dist/models/StayAfterHoursChatModel.d.ts +2 -0
  182. package/dist/models/StayAfterHoursChatModel.js +8 -0
  183. package/dist/models/StayAfterHoursWorkflowModel.d.ts +2 -0
  184. package/dist/models/StayAfterHoursWorkflowModel.js +8 -0
  185. package/dist/models/TransferAllowanceChatModel.d.ts +2 -0
  186. package/dist/models/TransferAllowanceChatModel.js +8 -0
  187. package/dist/models/TransferAllowanceWorkflowModel.d.ts +1 -0
  188. package/dist/models/TransferAllowanceWorkflowModel.js +4 -0
  189. package/dist/models/TransferMissionChatModel.d.ts +2 -0
  190. package/dist/models/TransferMissionChatModel.js +8 -0
  191. package/dist/models/TransferMissionWorkflowModel.d.ts +2 -0
  192. package/dist/models/TransferMissionWorkflowModel.js +8 -0
  193. package/dist/models/TransferSalaryBankAccountChatModel.d.ts +2 -0
  194. package/dist/models/TransferSalaryBankAccountChatModel.js +8 -0
  195. package/dist/models/TransferSalaryBankAccountWorkflowModel.d.ts +1 -0
  196. package/dist/models/TransferSalaryBankAccountWorkflowModel.js +4 -0
  197. package/dist/models/UpdateAttendanceChatModel.d.ts +1 -0
  198. package/dist/models/UpdateAttendanceChatModel.js +4 -0
  199. package/dist/models/UpdateAttendanceWorkflowModel.d.ts +2 -0
  200. package/dist/models/UpdateAttendanceWorkflowModel.js +8 -0
  201. package/package.json +1 -1
  202. package/scripts/check-column-types.js +38 -38
  203. package/scripts/check-service-tables.js +42 -42
  204. package/scripts/sync-sla-reports-sql.js +95 -95
  205. package/sql/add_fm_workflow_chat_arabic_columns.sql +153 -0
  206. package/sql/sla-reports-sync.manifest.json +9 -8
  207. package/sql/sla_reports_admin_procedures.sql +283 -283
  208. package/sql/sla_reports_approvals_workbook.sql +383 -383
  209. package/sql/sla_reports_procedures.sql +874 -874
  210. package/sql/sla_requests_status_data_fix.sql +6 -0
  211. package/sql/sla_requests_status_to_varchar.sql +28 -28
  212. package/sql/vw_sla_approvals.sql +108 -108
  213. package/sql/vw_sla_my_requests.sql +55 -55
  214. package/src/data-source.ts +686 -686
  215. package/src/helpers/employee-evaluation-request.utils.ts +178 -178
  216. package/src/helpers/evaluation-eligibility.utils.ts +126 -126
  217. package/src/i18n/workflow-chat-i18n.json +320 -0
  218. package/src/i18n/workflow-chat-i18n.ts +5 -0
  219. package/src/i18n/workflow-chat-message.builder.ts +1405 -0
  220. package/src/index.ts +620 -618
  221. package/src/models/AppointmentChatModel.ts +6 -0
  222. package/src/models/AppointmentWorkflowModel.ts +6 -0
  223. package/src/models/AssistanceCitizensAbroadChatModel.ts +6 -0
  224. package/src/models/AssistanceCitizensAbroadWorkflowModel.ts +3 -0
  225. package/src/models/ChildrensEducationChatModel.ts +6 -0
  226. package/src/models/ChildrensEducationWorkflowModel.ts +3 -0
  227. package/src/models/DiplomaticAcademyChatModel.ts +6 -0
  228. package/src/models/DiplomaticAcademyRequestModel.ts +80 -80
  229. package/src/models/DiplomaticAcademyWorkflowModel.ts +6 -0
  230. package/src/models/DiplomaticChatsModel.ts +6 -0
  231. package/src/models/DiplomaticWorkFlowModel.ts +6 -0
  232. package/src/models/DocumentTranslationChatModel.ts +6 -0
  233. package/src/models/DocumentTranslationWorkflowModel.ts +6 -0
  234. package/src/models/DocumentationFileModel.ts +40 -40
  235. package/src/models/EarlyCheckoutChatModel.ts +6 -0
  236. package/src/models/EarlyCheckoutWorkflowModel.ts +6 -0
  237. package/src/models/EmbassyEvaluationChatModel.ts +3 -0
  238. package/src/models/EmbassyEvaluationCycleModel.ts +45 -45
  239. package/src/models/EmbassyEvaluationRequestModel.ts +59 -59
  240. package/src/models/EmbassyEvaluationWorkflowModel.ts +3 -0
  241. package/src/models/EmployeeCardChatsModel.ts +6 -0
  242. package/src/models/EmployeeCardWorkFlowModel.ts +8 -2
  243. package/src/models/EmployeeEvaluationAnswerModel.ts +26 -26
  244. package/src/models/EmployeeEvaluationChatModel.ts +3 -0
  245. package/src/models/EmployeeEvaluationWorkflowModel.ts +3 -0
  246. package/src/models/EmployeeOfMonthNominationChatModel.ts +3 -0
  247. package/src/models/EmployeeOfMonthNominationWorkflowModel.ts +3 -0
  248. package/src/models/EmployeeOfMonthSupportNominationChatModel.ts +3 -0
  249. package/src/models/EmployeeOfMonthSupportNominationWorkflowModel.ts +3 -0
  250. package/src/models/EvaluationEligibilitySettingModel.ts +51 -51
  251. package/src/models/EvaluationFormModel.ts +44 -44
  252. package/src/models/FinancialChatsModel.ts +6 -0
  253. package/src/models/FinancialWorkFlowModel.ts +6 -0
  254. package/src/models/FoodChatModel.ts +3 -0
  255. package/src/models/FoodWorkflowModel.ts +6 -0
  256. package/src/models/GatePassChatsModel.ts +6 -0
  257. package/src/models/GatePassWorkFlowModel.ts +8 -2
  258. package/src/models/GeneralServiceChatsModel.ts +6 -0
  259. package/src/models/GeneralServiceWorkFlowModel.ts +6 -0
  260. package/src/models/HallChatModel.ts +3 -0
  261. package/src/models/HallWorkflowModel.ts +6 -0
  262. package/src/models/HousingRentalAccommodationChatModel.ts +6 -0
  263. package/src/models/HousingRentalAccommodationWorkflowModel.ts +3 -0
  264. package/src/models/HousingRentalVehicleChatModel.ts +6 -0
  265. package/src/models/HousingRentalVehicleWorkflowModel.ts +3 -0
  266. package/src/models/InitiatorEmployeeNominationChatModel.ts +3 -0
  267. package/src/models/InitiatorEmployeeNominationWorkflowModel.ts +3 -0
  268. package/src/models/InnovativeEmployeeNominationChatModel.ts +3 -0
  269. package/src/models/InnovativeEmployeeNominationWorkflowModel.ts +3 -0
  270. package/src/models/IpeGrievanceChatModel.ts +3 -0
  271. package/src/models/IpeGrievanceWorkflowModel.ts +3 -0
  272. package/src/models/LMSCourseExternalLecturerChatModel.ts +6 -0
  273. package/src/models/LMSCourseExternalLecturerWorkflowModel.ts +6 -0
  274. package/src/models/LMSExternalCourseParticipationChatModel.ts +6 -0
  275. package/src/models/LMSExternalCourseParticipationWorkflowModel.ts +6 -0
  276. package/src/models/LMSExternalEntityTrainedChatModel.ts +6 -0
  277. package/src/models/LMSExternalEntityTrainedPersonModel.ts +45 -45
  278. package/src/models/LMSExternalEntityTrainedWorkflowModel.ts +6 -0
  279. package/src/models/LanguageCourseChatModel.ts +6 -0
  280. package/src/models/LanguageCourseRequestModel.ts +67 -67
  281. package/src/models/LanguageCourseWorkflowModel.ts +6 -0
  282. package/src/models/LeaveApprovalsModel.ts +66 -66
  283. package/src/models/LeaveChatModel.ts +7 -1
  284. package/src/models/LeaveConfigModel.ts +71 -71
  285. package/src/models/LeaveWorkFlowModel.ts +6 -0
  286. package/src/models/MediaChatModel.ts +6 -0
  287. package/src/models/MediaWorkflowModel.ts +6 -0
  288. package/src/models/MedicalExpensesChatModel.ts +6 -0
  289. package/src/models/MedicalExpensesWorkflowModel.ts +3 -0
  290. package/src/models/MeetingChatModel.ts +6 -0
  291. package/src/models/MeetingWorkflowModel.ts +6 -0
  292. package/src/models/MissionBankAccountChatModel.ts +6 -0
  293. package/src/models/MissionBankAccountWorkflowModel.ts +6 -0
  294. package/src/models/MissionContractsChatModel.ts +6 -0
  295. package/src/models/MissionContractsWorkflowModel.ts +3 -0
  296. package/src/models/MissionTravelApprovalModel.ts +101 -101
  297. package/src/models/MissionTravelAttachmentModel.ts +56 -56
  298. package/src/models/MissionTravelChatModel.ts +55 -52
  299. package/src/models/MissionTravelPersonModel.ts +105 -105
  300. package/src/models/MissionTravelWorkflowModel.ts +60 -54
  301. package/src/models/NationalDayCelebrationsChatModel.ts +6 -0
  302. package/src/models/NationalDayCelebrationsWorkflowModel.ts +3 -0
  303. package/src/models/ProjectContactsModel.ts +51 -51
  304. package/src/models/ProjectFaqModel.ts +36 -36
  305. package/src/models/ProjectInvoicesModel.ts +41 -41
  306. package/src/models/ProjectModel.ts +75 -75
  307. package/src/models/ProjectTasksModel.ts +75 -75
  308. package/src/models/RecruitmentDomesticWorkersChatModel.ts +6 -0
  309. package/src/models/RecruitmentDomesticWorkersWorkflowModel.ts +3 -0
  310. package/src/models/RegisterCandidateChatModel.ts +6 -0
  311. package/src/models/RegisterCandidateWorkflowModel.ts +6 -0
  312. package/src/models/RegisterVacancyChatModel.ts +6 -0
  313. package/src/models/RegisterVacancyWorkflowModel.ts +6 -0
  314. package/src/models/RepatriationCitizensChatModel.ts +6 -0
  315. package/src/models/RepatriationCitizensWorkflowModel.ts +3 -0
  316. package/src/models/RequestParcelChatModel.ts +6 -0
  317. package/src/models/RequestParcelWorkflowModel.ts +6 -0
  318. package/src/models/RequestPassportChatModel.ts +6 -0
  319. package/src/models/RequestPassportWorkflowModel.ts +6 -0
  320. package/src/models/ResignationTerminationChatModel.ts +6 -0
  321. package/src/models/ResignationTerminationWorkflowModel.ts +6 -0
  322. package/src/models/RetiredCardChatsModel.ts +6 -0
  323. package/src/models/RetiredCardWorkFlowModel.ts +8 -2
  324. package/src/models/SecurityChatsModel.ts +6 -0
  325. package/src/models/ServiceSlaApprovalModel.ts +63 -63
  326. package/src/models/ServicesNotificationConfigsModel.ts +55 -55
  327. package/src/models/SlaApprovalsViewModel.ts +135 -135
  328. package/src/models/SlaMyRequestsViewModel.ts +172 -172
  329. package/src/models/SlaRequestModel.ts +57 -57
  330. package/src/models/StayAfterHoursChatModel.ts +6 -0
  331. package/src/models/StayAfterHoursWorkflowModel.ts +6 -0
  332. package/src/models/TransferAllowanceChatModel.ts +6 -0
  333. package/src/models/TransferAllowanceWorkflowModel.ts +3 -0
  334. package/src/models/TransferMissionChatModel.ts +6 -0
  335. package/src/models/TransferMissionWorkflowModel.ts +6 -0
  336. package/src/models/TransferSalaryBankAccountChatModel.ts +6 -0
  337. package/src/models/TransferSalaryBankAccountWorkflowModel.ts +3 -0
  338. package/src/models/UpdateAttendanceChatModel.ts +3 -0
  339. package/src/models/UpdateAttendanceWorkflowModel.ts +6 -0
  340. package/src/sla-report-views.ts +3 -3
  341. package/tsconfig.json +1 -0
  342. package/dist/helpers/sla-request-status.helper.d.ts +0 -3
  343. package/dist/helpers/sla-request-status.helper.js +0 -36
  344. package/dist/models/EmbassyEvaluationDepartmentSettingModel.d.ts +0 -14
  345. package/dist/models/EmbassyEvaluationDepartmentSettingModel.js +0 -56
  346. package/dist/models/EvaluationMastersModel.d.ts +0 -16
  347. package/dist/models/EvaluationMastersModel.js +0 -67
  348. package/dist/models/EvaluationQuestionMasterModel.d.ts +0 -10
  349. package/dist/models/EvaluationQuestionMasterModel.js +0 -42
  350. package/dist/models/EvaluationSectionMasterModel.d.ts +0 -7
  351. package/dist/models/EvaluationSectionMasterModel.js +0 -36
  352. package/dist/models/EvaluationWorkflowModel.d.ts +0 -60
  353. package/dist/models/EvaluationWorkflowModel.js +0 -215
  354. package/dist/models/IneligibleForEvaluationModel.d.ts +0 -8
  355. package/dist/models/IneligibleForEvaluationModel.js +0 -44
  356. package/dist/models/MissionTravelClassConfigModel.d.ts +0 -10
  357. package/dist/models/MissionTravelClassConfigModel.js +0 -50
  358. package/dist/models/MissionTravelPerdiemModel.d.ts +0 -10
  359. package/dist/models/MissionTravelPerdiemModel.js +0 -54
  360. package/dist/models/UuidAuditModel.d.ts +0 -9
  361. package/dist/models/UuidAuditModel.js +0 -41
@@ -0,0 +1,891 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.enrichCancellationChatMessage = exports.enrichCancellationWorkflowLog = void 0;
7
+ exports.getWorkflowChatI18nCatalog = getWorkflowChatI18nCatalog;
8
+ exports.resolveBilingualName = resolveBilingualName;
9
+ exports.pickLocalizedName = pickLocalizedName;
10
+ exports.pickArabicName = pickArabicName;
11
+ exports.resolveActorDisplayNames = resolveActorDisplayNames;
12
+ exports.joinDeptSectionBilingualLabels = joinDeptSectionBilingualLabels;
13
+ exports.joinDeptSectionArabicLabels = joinDeptSectionArabicLabels;
14
+ exports.formatWorkflowCommentSuffix = formatWorkflowCommentSuffix;
15
+ exports.formatChatCommentSuffix = formatChatCommentSuffix;
16
+ exports.renderSynchronizedWorkflowMessage = renderSynchronizedWorkflowMessage;
17
+ exports.renderSynchronizedChatMessage = renderSynchronizedChatMessage;
18
+ exports.buildBilingualFromTemplate = buildBilingualFromTemplate;
19
+ exports.workflowTemplate = workflowTemplate;
20
+ exports.chatTemplate = chatTemplate;
21
+ exports.buildSynchronizedWorkflowMessage = buildSynchronizedWorkflowMessage;
22
+ exports.buildSynchronizedChatMessage = buildSynchronizedChatMessage;
23
+ exports.buildWorkflowLogUpdateFields = buildWorkflowLogUpdateFields;
24
+ exports.toWorkflowPersistFields = toWorkflowPersistFields;
25
+ exports.toChatPersistFields = toChatPersistFields;
26
+ exports.toContentChatPersistFields = toContentChatPersistFields;
27
+ exports.buildApprovalWorkflowContent = buildApprovalWorkflowContent;
28
+ exports.buildHumanApprovalWorkflowContent = buildHumanApprovalWorkflowContent;
29
+ exports.buildApprovalChatMessage = buildApprovalChatMessage;
30
+ exports.buildClosedChatMessage = buildClosedChatMessage;
31
+ exports.buildClosedWorkflowMessage = buildClosedWorkflowMessage;
32
+ exports.buildRequestForChangeChatMessage = buildRequestForChangeChatMessage;
33
+ exports.buildAttachmentUploadedChatMessage = buildAttachmentUploadedChatMessage;
34
+ exports.buildUserOrAttachmentChatMessage = buildUserOrAttachmentChatMessage;
35
+ exports.buildTaskInProgressChatMessage = buildTaskInProgressChatMessage;
36
+ exports.buildTaskCompletedChatMessage = buildTaskCompletedChatMessage;
37
+ exports.buildTaskStatusUpdatedChatMessage = buildTaskStatusUpdatedChatMessage;
38
+ exports.buildItHelpdeskAssignedChatMessage = buildItHelpdeskAssignedChatMessage;
39
+ exports.buildItHelpdeskReassignedChatMessage = buildItHelpdeskReassignedChatMessage;
40
+ exports.buildRequestSubmittedWithRefChatMessage = buildRequestSubmittedWithRefChatMessage;
41
+ exports.buildSecurityAccessApprovalChatMessage = buildSecurityAccessApprovalChatMessage;
42
+ exports.buildItHelpdeskReassignModifiers = buildItHelpdeskReassignModifiers;
43
+ exports.buildItHelpdeskMuscatWorkflowLog = buildItHelpdeskMuscatWorkflowLog;
44
+ exports.buildLogisticsActualReturnChatMessage = buildLogisticsActualReturnChatMessage;
45
+ exports.buildLogisticsActualReturnNotificationBody = buildLogisticsActualReturnNotificationBody;
46
+ exports.buildLogisticsActualReturnNotificationTitle = buildLogisticsActualReturnNotificationTitle;
47
+ exports.buildItHelpdeskCloseNotificationMessage = buildItHelpdeskCloseNotificationMessage;
48
+ exports.buildFmNotificationContent = buildFmNotificationContent;
49
+ exports.buildFmNotificationPayload = buildFmNotificationPayload;
50
+ exports.resolveWorkflowStatusAr = resolveWorkflowStatusAr;
51
+ exports.resolveChatStatusAr = resolveChatStatusAr;
52
+ exports.extractBilingualActorsFromRecord = extractBilingualActorsFromRecord;
53
+ exports.resolveWorkflowContentAr = resolveWorkflowContentAr;
54
+ exports.resolveChatMessageAr = resolveChatMessageAr;
55
+ exports.enrichWorkflowLog = enrichWorkflowLog;
56
+ exports.enrichChatMessage = enrichChatMessage;
57
+ /**
58
+ * FM standard bilingual workflow/chat message builder.
59
+ *
60
+ * All services MUST use these helpers (never hardcode message strings).
61
+ * Templates live in workflow-chat-i18n.json; dynamic values use parallel EN/AR params.
62
+ */
63
+ const workflow_chat_i18n_json_1 = __importDefault(require("./workflow-chat-i18n.json"));
64
+ const WORKFLOW_TEMPLATES = workflow_chat_i18n_json_1.default.workflowTemplates;
65
+ const CHAT_TEMPLATES = workflow_chat_i18n_json_1.default.chatTemplates;
66
+ const NOTIFICATION_TEMPLATES = workflow_chat_i18n_json_1.default.notificationTemplates ?? {};
67
+ const WORKFLOW_STATUS_LABELS = workflow_chat_i18n_json_1.default.workflowStatusLabels;
68
+ const CHAT_STATUS_LABELS = workflow_chat_i18n_json_1.default.chatStatusLabels;
69
+ function getWorkflowChatI18nCatalog() {
70
+ return workflow_chat_i18n_json_1.default;
71
+ }
72
+ function interpolate(template, params = {}) {
73
+ return template.replace(/\{\{(\w+)\}\}/g, (_, key) => params[key] ?? '');
74
+ }
75
+ /** Arabic DB column preferred; English fallback so AR keeps identical structure to EN. */
76
+ function resolveBilingualName(englishName, arabicName) {
77
+ const ar = arabicName?.trim();
78
+ if (ar)
79
+ return ar;
80
+ return englishName?.trim() || '';
81
+ }
82
+ function pickLocalizedName(englishName, arabicName, fallback = '') {
83
+ return resolveBilingualName(englishName, arabicName) || fallback;
84
+ }
85
+ /** @deprecated Use resolveBilingualName */
86
+ function pickArabicName(arabicName) {
87
+ return arabicName?.trim() || '';
88
+ }
89
+ function joinLabels(...parts) {
90
+ return parts.map((p) => p?.trim()).filter(Boolean).join(' - ');
91
+ }
92
+ /** Build parallel EN / AR actor label from role OR dept+section. */
93
+ function resolveActorDisplayNames(actors) {
94
+ if (actors.roleName?.trim()) {
95
+ const en = actors.roleName.trim();
96
+ return { en, ar: resolveBilingualName(en, actors.roleArabicName) };
97
+ }
98
+ const en = joinLabels(actors.deptName, actors.sectionName);
99
+ const ar = joinLabels(resolveBilingualName(actors.deptName, actors.deptArabicName), resolveBilingualName(actors.sectionName, actors.sectionArabicName));
100
+ return { en, ar };
101
+ }
102
+ /** @deprecated Use resolveActorDisplayNames */
103
+ function joinDeptSectionBilingualLabels(deptEn, deptAr, sectEn, sectAr) {
104
+ return resolveActorDisplayNames({
105
+ deptName: deptEn,
106
+ deptArabicName: deptAr,
107
+ sectionName: sectEn,
108
+ sectionArabicName: sectAr,
109
+ });
110
+ }
111
+ /** @deprecated Use resolveActorDisplayNames */
112
+ function joinDeptSectionArabicLabels(deptArabic, sectionArabic) {
113
+ return joinLabels(deptArabic, sectionArabic);
114
+ }
115
+ function formatWorkflowCommentSuffix(comment) {
116
+ const text = comment?.trim();
117
+ return text ? `: ${text}` : '';
118
+ }
119
+ function formatChatCommentSuffix(comment) {
120
+ const text = comment?.trim();
121
+ return text ? ` - ${text}` : '';
122
+ }
123
+ /** Core renderer — always pass explicit EN and AR param objects with the same keys. */
124
+ function renderSynchronizedWorkflowMessage(templateKey, enParams, arParams) {
125
+ const tpl = WORKFLOW_TEMPLATES[templateKey];
126
+ if (!tpl)
127
+ return { en: templateKey, ar: templateKey };
128
+ return {
129
+ en: interpolate(tpl.en, enParams),
130
+ ar: interpolate(tpl.ar, arParams),
131
+ };
132
+ }
133
+ function renderSynchronizedChatMessage(templateKey, enParams, arParams) {
134
+ const tpl = CHAT_TEMPLATES[templateKey];
135
+ if (!tpl)
136
+ return { en: templateKey, ar: templateKey };
137
+ return {
138
+ en: interpolate(tpl.en, enParams),
139
+ ar: interpolate(tpl.ar, arParams),
140
+ };
141
+ }
142
+ function buildBilingualFromTemplate(templateCatalog, key, params = {}, arParams) {
143
+ const tpl = templateCatalog[key];
144
+ if (!tpl)
145
+ return { en: key, ar: key };
146
+ const arabicParams = arParams ?? params;
147
+ return {
148
+ en: interpolate(tpl.en, params),
149
+ ar: interpolate(tpl.ar, arabicParams),
150
+ };
151
+ }
152
+ function workflowTemplate(key, params = {}, arParams) {
153
+ return buildBilingualFromTemplate(WORKFLOW_TEMPLATES, key, params, arParams);
154
+ }
155
+ function chatTemplate(key, params = {}, arParams) {
156
+ return buildBilingualFromTemplate(CHAT_TEMPLATES, key, params, arParams);
157
+ }
158
+ /**
159
+ * Standard entry point for workflow `content` + `content_ar`.
160
+ * Use for every workflow log insert/update across all CAA modules.
161
+ */
162
+ function buildSynchronizedWorkflowMessage(ctx) {
163
+ const commentWf = formatWorkflowCommentSuffix(ctx.comment);
164
+ const { en: actorEn, ar: actorAr } = resolveActorDisplayNames(ctx);
165
+ switch (ctx.action) {
166
+ case 'request_submitted':
167
+ return workflowTemplate('request_submitted');
168
+ case 'notification_sent_pending':
169
+ return workflowTemplate('notification_sent_pending');
170
+ case 'notification_sent_successfully':
171
+ return workflowTemplate('notification_sent_successfully');
172
+ case 'approval_in_progress':
173
+ return actorEn
174
+ ? renderSynchronizedWorkflowMessage('request_approval_in_progress_from', { name: actorEn }, { name: actorAr })
175
+ : workflowTemplate('request_approval_in_progress');
176
+ case 'approval_pending':
177
+ return actorEn
178
+ ? renderSynchronizedWorkflowMessage('request_approval_pending_from', { name: actorEn }, { name: actorAr })
179
+ : workflowTemplate('request_approval_pending');
180
+ case 'approved':
181
+ return actorEn
182
+ ? renderSynchronizedWorkflowMessage('request_approved_by', { name: actorEn, comment: commentWf }, { name: actorAr, comment: commentWf })
183
+ : renderSynchronizedWorkflowMessage('request_approved', { comment: commentWf }, { comment: commentWf });
184
+ case 'rejected':
185
+ return actorEn
186
+ ? renderSynchronizedWorkflowMessage('request_rejected_by', { name: actorEn, comment: commentWf }, { name: actorAr, comment: commentWf })
187
+ : renderSynchronizedWorkflowMessage('request_rejected', { comment: commentWf }, { comment: commentWf });
188
+ case 'returned_for_modification':
189
+ return actorEn
190
+ ? renderSynchronizedWorkflowMessage('request_returned_for_modification_by', { name: actorEn, comment: commentWf }, { name: actorAr, comment: commentWf })
191
+ : renderSynchronizedWorkflowMessage('request_returned_for_modification', { comment: commentWf }, { comment: commentWf });
192
+ case 'approval_pending_update':
193
+ return actorEn
194
+ ? renderSynchronizedWorkflowMessage('request_approval_pending_from', { name: actorEn, comment: commentWf }, { name: actorAr, comment: commentWf })
195
+ : renderSynchronizedWorkflowMessage('request_approval_pending', { comment: commentWf }, { comment: commentWf });
196
+ default:
197
+ return workflowTemplate('request_submitted');
198
+ }
199
+ }
200
+ /**
201
+ * Standard entry point for chat `message` + `message_ar`.
202
+ * Use for every chat insert/update across all CAA modules.
203
+ */
204
+ function buildSynchronizedChatMessage(ctx) {
205
+ const commentChat = formatChatCommentSuffix(ctx.comment);
206
+ switch (ctx.action) {
207
+ case 'cancellation_submitted': {
208
+ const userEn = ctx.userName?.trim() || 'Unknown User';
209
+ const userAr = resolveBilingualName(userEn, ctx.userArabicName);
210
+ const employeeId = String(ctx.employeeId ?? 'N/A');
211
+ return chatTemplate('cancellation_submitted_by', { userName: userEn, employeeId }, { userName: userAr, employeeId });
212
+ }
213
+ case 'request_submitted': {
214
+ const userEn = ctx.userName?.trim() || 'Unknown User';
215
+ const userAr = resolveBilingualName(userEn, ctx.userArabicName);
216
+ const employeeId = String(ctx.employeeId ?? 'N/A');
217
+ return chatTemplate('request_submitted_by', { userName: userEn, employeeId }, { userName: userAr, employeeId });
218
+ }
219
+ case 'request_received':
220
+ return chatTemplate('request_received');
221
+ case 'approved':
222
+ case 'rejected':
223
+ case 'returned_for_modification': {
224
+ const roleEn = ctx.roleName?.trim() || 'Unknown Role';
225
+ const roleAr = resolveBilingualName(roleEn, ctx.roleArabicName);
226
+ const key = ctx.action === 'approved'
227
+ ? 'request_approved_by_role'
228
+ : ctx.action === 'rejected'
229
+ ? 'request_rejected_by_role'
230
+ : 'request_returned_for_modification_by_role';
231
+ return renderSynchronizedChatMessage(key, { roleName: roleEn, comment: commentChat }, { roleName: roleAr, comment: commentChat });
232
+ }
233
+ default:
234
+ return chatTemplate('request_received');
235
+ }
236
+ }
237
+ // ─── Backward-compatible aliases used by Cancellation pilot ───────────────────
238
+ /** Standard workflow log UPDATE fields for all CAA module repositories. */
239
+ function buildWorkflowLogUpdateFields(params) {
240
+ let action;
241
+ if (params.approvalStatus === 'Approved')
242
+ action = 'approved';
243
+ else if (params.approvalStatus === 'Rejected')
244
+ action = 'rejected';
245
+ else if (params.approvalStatus === 'Returned for Modification')
246
+ action = 'returned_for_modification';
247
+ else
248
+ action = 'approval_pending_update';
249
+ const bilingual = buildSynchronizedWorkflowMessage({
250
+ action,
251
+ roleName: params.roleName,
252
+ roleArabicName: params.roleArabicName,
253
+ comment: params.comment,
254
+ });
255
+ return {
256
+ content: bilingual.en,
257
+ content_ar: bilingual.ar,
258
+ status: params.workflowStatus,
259
+ status_ar: resolveWorkflowStatusAr(params.workflowStatus),
260
+ };
261
+ }
262
+ /** Bilingual workflow insert fields from builder output. */
263
+ function toWorkflowPersistFields(bilingual, status) {
264
+ return {
265
+ content: bilingual.en,
266
+ content_ar: bilingual.ar,
267
+ status,
268
+ status_ar: resolveWorkflowStatusAr(status),
269
+ };
270
+ }
271
+ /** Bilingual chat insert fields from builder output (message column). */
272
+ function toChatPersistFields(bilingual, status) {
273
+ return {
274
+ message: bilingual.en,
275
+ message_ar: bilingual.ar,
276
+ status,
277
+ status_ar: resolveChatStatusAr(status),
278
+ };
279
+ }
280
+ /** Bilingual chat insert fields for models using `content` column (Leave, Financial, etc.). */
281
+ function toContentChatPersistFields(bilingual, status) {
282
+ return {
283
+ content: bilingual.en,
284
+ content_ar: bilingual.ar,
285
+ status,
286
+ status_ar: resolveChatStatusAr(status),
287
+ };
288
+ }
289
+ function buildApprovalWorkflowContent(params) {
290
+ const status = params.status;
291
+ let action;
292
+ if (status === 'Approved')
293
+ action = 'approved';
294
+ else if (status === 'Rejected')
295
+ action = 'rejected';
296
+ else if (status === 'Returned for Modification')
297
+ action = 'returned_for_modification';
298
+ else
299
+ action = 'approval_pending_update';
300
+ return buildSynchronizedWorkflowMessage({
301
+ action,
302
+ roleName: params.roleName,
303
+ roleArabicName: params.roleArabicName,
304
+ comment: params.comment,
305
+ });
306
+ }
307
+ function buildHumanApprovalWorkflowContent(params) {
308
+ return buildSynchronizedWorkflowMessage({
309
+ action: params.isFirst ? 'approval_in_progress' : 'approval_pending',
310
+ roleName: params.roleName,
311
+ roleArabicName: params.roleArabicName,
312
+ deptName: params.deptName,
313
+ deptArabicName: params.deptArabicName,
314
+ sectionName: params.sectionName,
315
+ sectionArabicName: params.sectionArabicName,
316
+ });
317
+ }
318
+ function buildApprovalChatMessage(params) {
319
+ if (params.status === 'Closed') {
320
+ return buildClosedChatMessage({
321
+ roleName: params.roleName,
322
+ roleArabicName: params.roleArabicName,
323
+ comment: params.comment,
324
+ });
325
+ }
326
+ if (params.status === 'Request For Change' || params.status === 'RFC') {
327
+ return buildRequestForChangeChatMessage({
328
+ roleName: params.roleName,
329
+ roleArabicName: params.roleArabicName,
330
+ comment: params.comment,
331
+ variant: 'by',
332
+ });
333
+ }
334
+ let action = 'approved';
335
+ if (params.status === 'Rejected')
336
+ action = 'rejected';
337
+ else if (params.status === 'Returned for Modification')
338
+ action = 'returned_for_modification';
339
+ return buildSynchronizedChatMessage({
340
+ action,
341
+ roleName: params.roleName,
342
+ roleArabicName: params.roleArabicName,
343
+ comment: params.comment,
344
+ });
345
+ }
346
+ // ─── Specialized chat/workflow builders ─────────────────────────────────────
347
+ function formatDotCommentSuffix(comment) {
348
+ const text = comment?.trim();
349
+ return text ? `. Comment: ${text}` : '';
350
+ }
351
+ function formatColonCommentSuffix(comment) {
352
+ const text = comment?.trim();
353
+ return text ? `: ${text}` : '';
354
+ }
355
+ function formatReassignCommentSuffix(comment) {
356
+ const text = comment?.trim();
357
+ return text ? `:${text}` : '';
358
+ }
359
+ function buildClosedChatMessage(params) {
360
+ const roleEn = params.roleName?.trim() || 'Unknown Role';
361
+ const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
362
+ const comment = formatDotCommentSuffix(params.comment);
363
+ return renderSynchronizedChatMessage('request_closed_by_role', { roleName: roleEn, comment }, { roleName: roleAr, comment });
364
+ }
365
+ function buildClosedWorkflowMessage(params) {
366
+ const comment = formatWorkflowCommentSuffix(params.comment);
367
+ const roleEn = params.roleName?.trim();
368
+ if (roleEn) {
369
+ const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
370
+ return renderSynchronizedWorkflowMessage('request_closed_by', { name: roleEn, comment }, { name: roleAr, comment });
371
+ }
372
+ return renderSynchronizedWorkflowMessage('request_closed', { comment }, { comment });
373
+ }
374
+ function buildRequestForChangeChatMessage(params) {
375
+ const roleEn = params.roleName?.trim() || 'Unknown Role';
376
+ const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
377
+ const comment = params.variant === 'requested_by'
378
+ ? formatChatCommentSuffix(params.comment)
379
+ : formatColonCommentSuffix(params.comment);
380
+ const key = params.variant === 'requested_by'
381
+ ? 'request_for_change_requested_by_role'
382
+ : 'request_for_change_by_role';
383
+ return renderSynchronizedChatMessage(key, { roleName: roleEn, comment }, { roleName: roleAr, comment });
384
+ }
385
+ function buildAttachmentUploadedChatMessage(fileName) {
386
+ const name = fileName?.trim() || 'file';
387
+ return renderSynchronizedChatMessage('attachment_uploaded', { fileName: name }, { fileName: name });
388
+ }
389
+ /** User-typed chat text, or bilingual [Attachment] placeholder when empty. */
390
+ function buildUserOrAttachmentChatMessage(userMessage) {
391
+ const text = userMessage?.trim();
392
+ if (text)
393
+ return { en: text, ar: text };
394
+ return chatTemplate('attachment_placeholder');
395
+ }
396
+ function buildTaskInProgressChatMessage(params) {
397
+ const roleEn = params.roleName?.trim() || 'Employee';
398
+ const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
399
+ return renderSynchronizedChatMessage('task_status_in_progress_by_role', { roleName: roleEn }, { roleName: roleAr });
400
+ }
401
+ function buildTaskCompletedChatMessage(params) {
402
+ const roleEn = params.roleName?.trim() || 'Employee';
403
+ const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
404
+ const comment = formatDotCommentSuffix(params.comment);
405
+ return renderSynchronizedChatMessage('task_completed_by_role', { roleName: roleEn, comment }, { roleName: roleAr, comment });
406
+ }
407
+ function buildTaskStatusUpdatedChatMessage(status, statusAr) {
408
+ const statusEn = status?.trim() || 'Updated';
409
+ const statusArResolved = statusAr?.trim() || resolveChatStatusAr(statusEn) || statusEn;
410
+ return renderSynchronizedChatMessage('task_status_updated', { status: statusEn }, { status: statusArResolved });
411
+ }
412
+ function buildItHelpdeskAssignedChatMessage(params) {
413
+ const assignedRoleEn = params.assignedRoleName?.trim() || 'Role';
414
+ const assignedRoleAr = resolveBilingualName(assignedRoleEn, params.assignedRoleArabicName);
415
+ const assignedUserEn = params.assignedUserName?.trim() || 'User';
416
+ const assignedUserAr = resolveBilingualName(assignedUserEn, params.assignedUserArabicName);
417
+ const comment = params.comment?.trim() ? ` - ${params.comment.trim()}` : '';
418
+ const templateKey = params.level === 1 ? 'it_helpdesk_hos_assigned' : 'it_helpdesk_technician_assigned';
419
+ const enParams = {
420
+ assignedRoleName: assignedRoleEn,
421
+ assignedUserName: assignedUserEn,
422
+ comment,
423
+ };
424
+ const arParams = {
425
+ assignedRoleName: assignedRoleAr,
426
+ assignedUserName: assignedUserAr,
427
+ comment,
428
+ };
429
+ if (params.level !== 1) {
430
+ enParams.level = String(params.level);
431
+ arParams.level = String(params.level);
432
+ }
433
+ return renderSynchronizedChatMessage(templateKey, enParams, arParams);
434
+ }
435
+ function buildItHelpdeskReassignedChatMessage(params) {
436
+ const approverEn = params.approverRoleName?.trim() || 'Role';
437
+ const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
438
+ const comment = formatReassignCommentSuffix(params.comment);
439
+ if (params.level === 1) {
440
+ const reassignedEn = params.reassignedRoleName?.trim() || 'Role';
441
+ const reassignedAr = resolveBilingualName(reassignedEn, params.reassignedRoleArabicName);
442
+ return renderSynchronizedChatMessage('it_helpdesk_reassigned_to_role', { approverRoleName: approverEn, reassignedRoleName: reassignedEn, comment }, { approverRoleName: approverAr, reassignedRoleName: reassignedAr, comment });
443
+ }
444
+ if (params.level === 2) {
445
+ return renderSynchronizedChatMessage('it_helpdesk_reassigned_to_l3', { approverRoleName: approverEn, comment }, { approverRoleName: approverAr, comment });
446
+ }
447
+ const level = String(params.level);
448
+ return renderSynchronizedChatMessage('it_helpdesk_reassigned_generic', { approverRoleName: approverEn, level, comment }, { approverRoleName: approverAr, level, comment });
449
+ }
450
+ function buildRequestSubmittedWithRefChatMessage(params) {
451
+ const userEn = params.userName?.trim() || 'Unknown User';
452
+ const userAr = resolveBilingualName(userEn, params.userArabicName);
453
+ const labelEn = params.requestLabel?.trim() || 'Request';
454
+ const labelAr = params.requestLabelAr?.trim() || labelEn;
455
+ const requestId = String(params.requestId);
456
+ const employeeId = String(params.employeeId ?? 'N/A');
457
+ return renderSynchronizedChatMessage('request_submitted_with_ref', { requestLabel: labelEn, requestId, userName: userEn, employeeId }, { requestLabel: labelAr, requestId, userName: userAr, employeeId });
458
+ }
459
+ function buildSecurityAccessApprovalChatMessage(params) {
460
+ const statusWord = params.decision === 'approve' ? 'approved' : 'rejected';
461
+ const statusWordAr = params.decision === 'approve' ? 'الموافقة على' : 'رفض';
462
+ const comment = params.comment?.trim() ? ` Comment: ${params.comment.trim()}` : '';
463
+ const labelEn = params.productLabel?.trim() || 'Security Access';
464
+ const labelAr = params.productLabelAr?.trim() || labelEn;
465
+ return renderSynchronizedChatMessage('security_access_approval_step', {
466
+ productLabel: labelEn,
467
+ requestId: String(params.requestId),
468
+ statusWord,
469
+ approvalLevel: String(params.approvalLevel),
470
+ comment,
471
+ statusWordAr,
472
+ }, {
473
+ productLabel: labelAr,
474
+ requestId: String(params.requestId),
475
+ statusWord,
476
+ approvalLevel: String(params.approvalLevel),
477
+ comment,
478
+ statusWordAr,
479
+ });
480
+ }
481
+ function renderSynchronizedNotificationMessage(templateKey, enParams, arParams) {
482
+ const tpl = NOTIFICATION_TEMPLATES[templateKey];
483
+ if (!tpl)
484
+ return { en: templateKey, ar: templateKey };
485
+ return {
486
+ en: interpolate(tpl.en, enParams),
487
+ ar: interpolate(tpl.ar, arParams),
488
+ };
489
+ }
490
+ function normalizeDisplayValue(value) {
491
+ if (value === undefined || value === null || String(value).trim() === '')
492
+ return 'Not specified';
493
+ return String(value);
494
+ }
495
+ function normalizeDisplayDate(value) {
496
+ if (value === undefined || value === null || String(value).trim() === '')
497
+ return 'Not specified';
498
+ const d = new Date(value);
499
+ if (!isNaN(d.getTime()))
500
+ return d.toISOString().slice(0, 10);
501
+ return String(value);
502
+ }
503
+ function buildItHelpdeskReassignModifiers(params) {
504
+ let en = '';
505
+ let ar = '';
506
+ if (params.sectionFrom != null &&
507
+ params.sectionTo != null &&
508
+ params.sectionFrom !== params.sectionTo) {
509
+ en += ` (Section modified from ${params.sectionFrom} to ${params.sectionTo})`;
510
+ ar += ` (تم تعديل القسم من ${params.sectionFrom} إلى ${params.sectionTo})`;
511
+ }
512
+ if (params.departmentFrom != null &&
513
+ params.departmentTo != null &&
514
+ params.departmentFrom !== params.departmentTo) {
515
+ en += ` (Department modified from ${params.departmentFrom} to ${params.departmentTo})`;
516
+ ar += ` (تم تعديل الإدارة من ${params.departmentFrom} إلى ${params.departmentTo})`;
517
+ }
518
+ return { en, ar };
519
+ }
520
+ function buildItHelpdeskMuscatWorkflowLog(params) {
521
+ const comment = formatColonCommentSuffix('comment' in params ? params.comment : undefined);
522
+ const modifiers = 'modifiers' in params && params.modifiers ? params.modifiers : { en: '', ar: '' };
523
+ switch (params.variant) {
524
+ case 'hos_assigned': {
525
+ const approverEn = params.approverRoleName.trim();
526
+ const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
527
+ const assignedEn = params.assignedRoleName.trim();
528
+ const assignedAr = resolveBilingualName(assignedEn, params.assignedRoleArabicName);
529
+ return renderSynchronizedWorkflowMessage('it_helpdesk_wf_hos_assigned', { approverRoleName: approverEn, assignedRoleName: assignedEn, comment }, { approverRoleName: approverAr, assignedRoleName: assignedAr, comment });
530
+ }
531
+ case 'technician_assigned': {
532
+ const approverEn = params.approverRoleName.trim();
533
+ const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
534
+ return renderSynchronizedWorkflowMessage('it_helpdesk_wf_technician_assigned', { level: String(params.level), approverRoleName: approverEn, comment }, { level: String(params.level), approverRoleName: approverAr, comment });
535
+ }
536
+ case 'reassigned_technician': {
537
+ const approverEn = params.approverRoleName.trim();
538
+ const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
539
+ return renderSynchronizedWorkflowMessage('it_helpdesk_wf_reassigned_technician', { approverRoleName: approverEn, comment, modifiers: modifiers.en }, { approverRoleName: approverAr, comment, modifiers: modifiers.ar });
540
+ }
541
+ case 'reassigned_l3': {
542
+ const approverEn = params.approverRoleName.trim();
543
+ const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
544
+ return renderSynchronizedWorkflowMessage('it_helpdesk_wf_reassigned_l3', { approverRoleName: approverEn, comment, modifiers: modifiers.en }, { approverRoleName: approverAr, comment, modifiers: modifiers.ar });
545
+ }
546
+ case 'reassigned_generic': {
547
+ const approverEn = params.approverRoleName.trim();
548
+ const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
549
+ const level = String(params.level ?? '');
550
+ return renderSynchronizedWorkflowMessage('it_helpdesk_wf_reassigned_generic', { approverRoleName: approverEn, level, comment, modifiers: modifiers.en }, { approverRoleName: approverAr, level, comment, modifiers: modifiers.ar });
551
+ }
552
+ case 'closed_level1': {
553
+ const approverEn = params.approverRoleName.trim();
554
+ const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
555
+ return renderSynchronizedWorkflowMessage('it_helpdesk_wf_closed_request', { approverRoleName: approverEn, comment }, { approverRoleName: approverAr, comment });
556
+ }
557
+ case 'closed_level2': {
558
+ const approverEn = params.approverRoleName.trim();
559
+ const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
560
+ return renderSynchronizedWorkflowMessage('it_helpdesk_wf_closed_request_cap', { approverRoleName: approverEn, comment }, { approverRoleName: approverAr, comment });
561
+ }
562
+ case 'l3_approved': {
563
+ const roleEn = params.roleName.trim();
564
+ const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
565
+ const userEn = params.userName.trim();
566
+ const userAr = resolveBilingualName(userEn, params.userArabicName);
567
+ return renderSynchronizedWorkflowMessage('it_helpdesk_wf_l3_approved_by', { roleName: roleEn, userName: userEn, comment }, { roleName: roleAr, userName: userAr, comment });
568
+ }
569
+ case 'l3_rejected': {
570
+ const roleEn = params.roleName.trim();
571
+ const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
572
+ const userEn = params.userName.trim();
573
+ const userAr = resolveBilingualName(userEn, params.userArabicName);
574
+ return renderSynchronizedWorkflowMessage('it_helpdesk_wf_l3_rejected_by', { roleName: roleEn, userName: userEn, comment }, { roleName: roleAr, userName: userAr, comment });
575
+ }
576
+ case 'level_approved': {
577
+ const approverEn = params.approverRoleName.trim();
578
+ const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
579
+ return renderSynchronizedWorkflowMessage('it_helpdesk_wf_level_approved', { level: String(params.level), approverRoleName: approverEn, comment }, { level: String(params.level), approverRoleName: approverAr, comment });
580
+ }
581
+ case 'rejected':
582
+ case 'l3_step_rejected': {
583
+ const key = params.variant === 'l3_step_rejected'
584
+ ? 'it_helpdesk_wf_l3_step_rejected'
585
+ : 'it_helpdesk_wf_rejected';
586
+ const roleEn = params.approverRoleName.trim();
587
+ const roleAr = resolveBilingualName(roleEn, params.approverRoleArabicName);
588
+ return renderSynchronizedWorkflowMessage(key, { approverRoleName: roleEn, roleName: roleEn, comment }, { approverRoleName: roleAr, roleName: roleAr, comment });
589
+ }
590
+ case 'generic_status': {
591
+ const approverEn = params.approverRoleName.trim();
592
+ const approverAr = resolveBilingualName(approverEn, params.approverRoleArabicName);
593
+ const statusEn = params.status.toLowerCase();
594
+ const statusAr = resolveChatStatusAr(params.status) ?? statusEn;
595
+ return renderSynchronizedWorkflowMessage('it_helpdesk_wf_status_by_role', { status: statusEn, statusAr, approverRoleName: approverEn, comment }, { status: statusEn, statusAr, approverRoleName: approverAr, comment });
596
+ }
597
+ case 'technician_completed': {
598
+ const roleEn = params.roleName.trim();
599
+ const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
600
+ return renderSynchronizedWorkflowMessage('it_helpdesk_wf_technician_completed', { roleName: roleEn, comment }, { roleName: roleAr, comment });
601
+ }
602
+ case 'routing_rejected':
603
+ return renderSynchronizedWorkflowMessage('it_helpdesk_wf_routing_rejected', { comment }, { comment });
604
+ case 'routing_resolved':
605
+ return workflowTemplate('it_helpdesk_wf_routing_resolved');
606
+ default:
607
+ return workflowTemplate('request_submitted');
608
+ }
609
+ }
610
+ function buildLogisticsActualReturnChatMessage(params) {
611
+ const roleEn = params.roleName.trim() || 'Unknown Role';
612
+ const roleAr = resolveBilingualName(roleEn, params.roleArabicName);
613
+ const date = normalizeDisplayDate(params.returnDetails.actual_return_date);
614
+ const time = normalizeDisplayValue(params.returnDetails.actual_vehicle_return_time);
615
+ const reason = normalizeDisplayValue(params.returnDetails.reason);
616
+ return renderSynchronizedChatMessage('logistics_actual_return_updated', { roleName: roleEn, date, time, reason }, { roleName: roleAr, date, time, reason });
617
+ }
618
+ function buildLogisticsActualReturnNotificationBody(params) {
619
+ const requestLabel = params.requestTypeLabel
620
+ ? `${params.requestTypeLabel} Request`
621
+ : 'Vehicle Request';
622
+ const requestLabelAr = params.requestTypeLabel
623
+ ? `طلب ${params.requestTypeLabel}`
624
+ : 'طلب المركبة';
625
+ const requestId = normalizeDisplayValue(params.requestId);
626
+ const en = [
627
+ `${requestLabel} #${requestId}`,
628
+ `Actual Return Date: ${normalizeDisplayDate(params.actual_return_date)}`,
629
+ `Actual Return Time: ${normalizeDisplayValue(params.actual_vehicle_return_time)}`,
630
+ `Reason: ${normalizeDisplayValue(params.reason)}`,
631
+ ].join('\n');
632
+ const ar = [
633
+ `${requestLabelAr} رقم ${requestId}`,
634
+ `تاريخ الإرجاع الفعلي: ${normalizeDisplayDate(params.actual_return_date)}`,
635
+ `وقت الإرجاع الفعلي: ${normalizeDisplayValue(params.actual_vehicle_return_time)}`,
636
+ `السبب: ${normalizeDisplayValue(params.reason)}`,
637
+ ].join('\n');
638
+ return { en, ar };
639
+ }
640
+ function buildLogisticsActualReturnNotificationTitle(params) {
641
+ const requestLabel = params.requestTypeLabel || 'Vehicle';
642
+ const requestId = String(params.requestId ?? '');
643
+ return renderSynchronizedNotificationMessage('logistics_actual_return_title', { requestLabel, requestId }, { requestLabel, requestId });
644
+ }
645
+ function buildItHelpdeskCloseNotificationMessage(params) {
646
+ const requestId = String(params.requestId);
647
+ const key = params.status === 'Rejected'
648
+ ? 'it_helpdesk_notif_request_rejected'
649
+ : 'it_helpdesk_notif_request_closed';
650
+ return renderSynchronizedNotificationMessage(key, { requestId }, { requestId });
651
+ }
652
+ function formatNotificationCommentSuffix(comment) {
653
+ const text = comment?.trim();
654
+ return text ? `. Reason: ${text}` : '';
655
+ }
656
+ function formatNotificationCommentSuffixAr(comment) {
657
+ const text = comment?.trim();
658
+ return text ? `. السبب: ${text}` : '';
659
+ }
660
+ /** Standard FM notification title + body for workflow events. */
661
+ function buildFmNotificationContent(params) {
662
+ const serviceLabel = params.serviceLabel?.trim() || 'Request';
663
+ const serviceLabelAr = params.serviceLabelAr?.trim() || serviceLabel;
664
+ const requestId = String(params.requestId);
665
+ const level = String(params.level ?? '');
666
+ const pendingCount = String(params.pendingCount ?? '0');
667
+ const commentEn = formatNotificationCommentSuffix(params.comment);
668
+ const commentAr = formatNotificationCommentSuffixAr(params.comment);
669
+ switch (params.event) {
670
+ case 'submitted':
671
+ return {
672
+ title: renderSynchronizedNotificationMessage('fm_request_submitted_title', {}, {}),
673
+ body: renderSynchronizedNotificationMessage('fm_request_submitted_body', { serviceLabel, requestId }, { serviceLabelAr, requestId }),
674
+ };
675
+ case 'received_for_approval':
676
+ return {
677
+ title: renderSynchronizedNotificationMessage('fm_request_received_title', {}, {}),
678
+ body: renderSynchronizedNotificationMessage('fm_request_received_body', { serviceLabel, requestId }, { serviceLabelAr, requestId }),
679
+ };
680
+ case 'approved':
681
+ return {
682
+ title: renderSynchronizedNotificationMessage('fm_request_approved_title', {}, {}),
683
+ body: renderSynchronizedNotificationMessage('fm_request_approved_body', { serviceLabel, requestId, comment: commentEn }, { serviceLabelAr, requestId, comment: commentAr }),
684
+ };
685
+ case 'approved_intermediate':
686
+ return {
687
+ title: renderSynchronizedNotificationMessage('fm_level_approved_title', { level }, { level }),
688
+ body: renderSynchronizedNotificationMessage('fm_request_approved_intermediate_body', { serviceLabel, requestId, level, pendingCount, comment: commentEn }, { serviceLabelAr, requestId, level, pendingCount, comment: commentAr }),
689
+ };
690
+ case 'rejected':
691
+ return {
692
+ title: renderSynchronizedNotificationMessage('fm_request_rejected_title', {}, {}),
693
+ body: renderSynchronizedNotificationMessage('fm_request_rejected_body', { serviceLabel, requestId, comment: commentEn }, { serviceLabelAr, requestId, comment: commentAr }),
694
+ };
695
+ case 'approval_required':
696
+ default:
697
+ return {
698
+ title: level
699
+ ? renderSynchronizedNotificationMessage('fm_approval_required_level_title', { level }, { level })
700
+ : renderSynchronizedNotificationMessage('fm_approval_required_title', {}, {}),
701
+ body: renderSynchronizedNotificationMessage('fm_approval_required_body', { serviceLabel, requestId, level }, { serviceLabelAr, requestId, level }),
702
+ };
703
+ }
704
+ }
705
+ /** Build FM notification `content` JSON with bilingual title/data fields. */
706
+ function buildFmNotificationPayload(params) {
707
+ const bilingual = buildFmNotificationContent(params);
708
+ return {
709
+ title: bilingual.title.en,
710
+ title_ar: bilingual.title.ar,
711
+ data: bilingual.body.en,
712
+ data_ar: bilingual.body.ar,
713
+ requestId: params.requestId,
714
+ requestType: params.requestType,
715
+ status: params.status,
716
+ level: params.level ?? null,
717
+ comment: params.comment ?? '',
718
+ bypassedLevels: params.bypassedLevels ?? null,
719
+ timestamp: new Date().toISOString(),
720
+ ...(params.extra ?? {}),
721
+ };
722
+ }
723
+ // ─── Status labels ───────────────────────────────────────────────────────────
724
+ function resolveWorkflowStatusAr(status) {
725
+ if (status == null || status === '')
726
+ return null;
727
+ return WORKFLOW_STATUS_LABELS[status] ?? status;
728
+ }
729
+ function resolveChatStatusAr(status) {
730
+ if (status == null || status === '')
731
+ return null;
732
+ return CHAT_STATUS_LABELS[status] ?? status;
733
+ }
734
+ // ─── Legacy row enrichment (read API) ────────────────────────────────────────
735
+ /** Pull bilingual actor fields from joined relations on workflow/chat rows. */
736
+ function extractBilingualActorsFromRecord(record) {
737
+ const role = (record.approver_role ?? record.role);
738
+ const user = (record.approver_user ?? record.user);
739
+ const dept = (record.approver_department ?? record.department);
740
+ const section = (record.approver_section ?? record.section);
741
+ return {
742
+ roleName: role?.name != null ? String(role.name) : null,
743
+ roleArabicName: role?.arabic_name != null ? String(role.arabic_name) : null,
744
+ deptName: dept?.department_name != null ? String(dept.department_name) : null,
745
+ deptArabicName: dept?.department_arabic_name != null ? String(dept.department_arabic_name) : null,
746
+ sectionName: section?.section_name != null ? String(section.section_name) : null,
747
+ sectionArabicName: section?.section_arabic_name != null ? String(section.section_arabic_name) : null,
748
+ userName: user?.employee_name != null ? String(user.employee_name) : null,
749
+ userArabicName: user?.employee_arabic_name != null ? String(user.employee_arabic_name) : null,
750
+ employeeId: user?.employee_id != null ? String(user.employee_id) : null,
751
+ };
752
+ }
753
+ /** Arabic actor label for workflow templates (role, dept+section, or user). */
754
+ function resolveArabicWorkflowActorName(actors, parsedEnglishName) {
755
+ if (actors) {
756
+ const { ar } = resolveActorDisplayNames(actors);
757
+ if (ar)
758
+ return ar;
759
+ if (actors.userName?.trim()) {
760
+ return resolveBilingualName(actors.userName, actors.userArabicName);
761
+ }
762
+ }
763
+ return parsedEnglishName?.trim() || '';
764
+ }
765
+ /** Arabic role/user label for chat templates. */
766
+ function resolveArabicChatRoleName(actors, parsedEnglishRole) {
767
+ if (actors?.roleName?.trim()) {
768
+ return resolveBilingualName(actors.roleName, actors.roleArabicName);
769
+ }
770
+ if (actors?.userName?.trim()) {
771
+ return resolveBilingualName(actors.userName, actors.userArabicName);
772
+ }
773
+ return resolveBilingualName(parsedEnglishRole, actors?.roleArabicName);
774
+ }
775
+ function resolveWorkflowContentAr(content, actors) {
776
+ if (content == null || content.trim() === '')
777
+ return null;
778
+ const normalized = content.trim();
779
+ for (const tpl of Object.values(WORKFLOW_TEMPLATES)) {
780
+ if (tpl.en === normalized)
781
+ return tpl.ar;
782
+ }
783
+ const commentIdx = normalized.indexOf(': ');
784
+ if (commentIdx > 0) {
785
+ const baseEn = normalized.slice(0, commentIdx).trim();
786
+ const commentText = normalized.slice(commentIdx + 2).trim();
787
+ const commentSuffix = formatWorkflowCommentSuffix(commentText);
788
+ for (const tpl of Object.values(WORKFLOW_TEMPLATES)) {
789
+ if (!tpl.en.includes('{{comment}}'))
790
+ continue;
791
+ const withoutComment = tpl.en.replace('{{comment}}', '');
792
+ if (withoutComment.includes('{{name}}')) {
793
+ const staticPrefix = withoutComment.replace('{{name}}', '').trim();
794
+ if (baseEn.startsWith(staticPrefix)) {
795
+ const namePartEn = baseEn.slice(staticPrefix.length).trim();
796
+ const nameAr = resolveArabicWorkflowActorName(actors, namePartEn);
797
+ return interpolate(tpl.ar, { name: nameAr, comment: commentSuffix });
798
+ }
799
+ }
800
+ else if (withoutComment.trim() === baseEn) {
801
+ return interpolate(tpl.ar, { comment: commentSuffix });
802
+ }
803
+ }
804
+ }
805
+ const inProgressPrefix = WORKFLOW_TEMPLATES.request_approval_in_progress_from?.en.split('{{name}}')[0].trim();
806
+ if (inProgressPrefix && normalized.startsWith(inProgressPrefix)) {
807
+ const namePartEn = normalized.slice(inProgressPrefix.length).trim();
808
+ const nameAr = resolveArabicWorkflowActorName(actors, namePartEn);
809
+ return interpolate(WORKFLOW_TEMPLATES.request_approval_in_progress_from.ar, { name: nameAr });
810
+ }
811
+ const pendingPrefix = WORKFLOW_TEMPLATES.request_approval_pending_from?.en.split('{{name}}')[0].trim();
812
+ if (pendingPrefix && normalized.startsWith(pendingPrefix)) {
813
+ const namePartEn = normalized.slice(pendingPrefix.length).trim();
814
+ const nameAr = resolveArabicWorkflowActorName(actors, namePartEn);
815
+ return interpolate(WORKFLOW_TEMPLATES.request_approval_pending_from.ar, { name: nameAr });
816
+ }
817
+ return null;
818
+ }
819
+ function resolveChatMessageAr(message, actors) {
820
+ if (message == null || message.trim() === '')
821
+ return null;
822
+ const normalized = message.trim();
823
+ for (const tpl of Object.values(CHAT_TEMPLATES)) {
824
+ if (tpl.en === normalized)
825
+ return tpl.ar;
826
+ }
827
+ for (const tplKey of ['request_submitted_by', 'cancellation_submitted_by']) {
828
+ const submittedTpl = CHAT_TEMPLATES[tplKey];
829
+ if (!submittedTpl)
830
+ continue;
831
+ const prefix = submittedTpl.en.split('{{userName}}')[0];
832
+ if (!normalized.startsWith(prefix))
833
+ continue;
834
+ const afterPrefix = normalized.slice(prefix.length);
835
+ const parenMatch = afterPrefix.match(/^(.+?) \((.+)\)$/);
836
+ if (parenMatch) {
837
+ const userEn = parenMatch[1].trim();
838
+ const employeeId = parenMatch[2].trim();
839
+ const userAr = actors?.userName?.trim()
840
+ ? resolveBilingualName(actors.userName, actors.userArabicName)
841
+ : resolveBilingualName(userEn, actors?.userArabicName);
842
+ return interpolate(submittedTpl.ar, { userName: userAr, employeeId });
843
+ }
844
+ }
845
+ for (const tpl of Object.values(CHAT_TEMPLATES)) {
846
+ if (!tpl.en.includes('{{roleName}}'))
847
+ continue;
848
+ const prefix = tpl.en.split('{{roleName}}')[0];
849
+ if (!normalized.startsWith(prefix))
850
+ continue;
851
+ const rest = normalized.slice(prefix.length);
852
+ const commentIdx = rest.lastIndexOf(' - ');
853
+ const roleNameEn = commentIdx >= 0 ? rest.slice(0, commentIdx) : rest;
854
+ const commentSuffix = commentIdx >= 0 ? rest.slice(commentIdx) : '';
855
+ const roleNameAr = resolveArabicChatRoleName(actors, roleNameEn.trim());
856
+ return interpolate(tpl.ar, { roleName: roleNameAr, comment: commentSuffix });
857
+ }
858
+ return null;
859
+ }
860
+ /** Generic workflow log enricher — use in all module repositories. */
861
+ function enrichWorkflowLog(log) {
862
+ const status = log.status != null ? String(log.status) : null;
863
+ const content = log.content != null ? String(log.content) : null;
864
+ const actors = extractBilingualActorsFromRecord(log);
865
+ return {
866
+ ...log,
867
+ content_ar: log.content_ar ?? resolveWorkflowContentAr(content, actors),
868
+ status_ar: log.status_ar ?? resolveWorkflowStatusAr(status),
869
+ };
870
+ }
871
+ /** Generic chat enricher — use in all module repositories. Handles `message` or `content` column. */
872
+ function enrichChatMessage(chat) {
873
+ const status = chat.status != null ? String(chat.status) : null;
874
+ const message = chat.message != null
875
+ ? String(chat.message)
876
+ : chat.content != null
877
+ ? String(chat.content)
878
+ : null;
879
+ const actors = extractBilingualActorsFromRecord(chat);
880
+ const resolvedAr = chat.message_ar ?? chat.content_ar ?? resolveChatMessageAr(message, actors);
881
+ return {
882
+ ...chat,
883
+ message_ar: chat.message_ar ?? (chat.message != null ? resolvedAr : chat.message_ar),
884
+ content_ar: chat.content_ar ?? (chat.content != null ? resolvedAr : chat.content_ar),
885
+ status_ar: chat.status_ar ?? resolveChatStatusAr(status),
886
+ };
887
+ }
888
+ /** @deprecated Use enrichWorkflowLog */
889
+ exports.enrichCancellationWorkflowLog = enrichWorkflowLog;
890
+ /** @deprecated Use enrichChatMessage */
891
+ exports.enrichCancellationChatMessage = enrichChatMessage;