rez_core 5.0.27 → 5.0.29

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 (478) hide show
  1. package/.prettierrc +3 -3
  2. package/README.md +99 -99
  3. package/dist/module/auth/guards/role.guard.js +3 -3
  4. package/dist/module/auth/services/auth.service.js +2 -2
  5. package/dist/module/entity_json/controller/entity_json.controller.d.ts +11 -1
  6. package/dist/module/entity_json/controller/entity_json.controller.js +14 -0
  7. package/dist/module/entity_json/controller/entity_json.controller.js.map +1 -1
  8. package/dist/module/entity_json/entity/entityJson.entity.d.ts +10 -0
  9. package/dist/module/entity_json/entity/entityJson.entity.js +55 -0
  10. package/dist/module/entity_json/entity/entityJson.entity.js.map +1 -0
  11. package/dist/module/entity_json/entity_json.module.js +4 -2
  12. package/dist/module/entity_json/entity_json.module.js.map +1 -1
  13. package/dist/module/entity_json/service/entityJson.repository.d.ts +7 -0
  14. package/dist/module/entity_json/service/entityJson.repository.js +45 -0
  15. package/dist/module/entity_json/service/entityJson.repository.js.map +1 -0
  16. package/dist/module/entity_json/service/entity_json.service.d.ts +14 -4
  17. package/dist/module/entity_json/service/entity_json.service.js +84 -57
  18. package/dist/module/entity_json/service/entity_json.service.js.map +1 -1
  19. package/dist/module/filter/repository/saved-filter.repository.js +4 -4
  20. package/dist/module/filter/service/filter-evaluator.service.js +2 -2
  21. package/dist/module/filter/service/filter.service.js +106 -36
  22. package/dist/module/filter/service/filter.service.js.map +1 -1
  23. package/dist/module/integration/examples/usage.example.js +9 -9
  24. package/dist/module/integration/service/integration.service.js +1 -1
  25. package/dist/module/integration/service/wrapper.service.js +26 -26
  26. package/dist/module/linked_attributes/controller/linked_attributes.controller.d.ts +2 -0
  27. package/dist/module/linked_attributes/controller/linked_attributes.controller.js +26 -0
  28. package/dist/module/linked_attributes/controller/linked_attributes.controller.js.map +1 -1
  29. package/dist/module/linked_attributes/entity/linked_attribute.entity.d.ts +1 -0
  30. package/dist/module/linked_attributes/entity/linked_attribute.entity.js +4 -0
  31. package/dist/module/linked_attributes/entity/linked_attribute.entity.js.map +1 -1
  32. package/dist/module/linked_attributes/service/linked_attributes.service.d.ts +6 -1
  33. package/dist/module/linked_attributes/service/linked_attributes.service.js +61 -2
  34. package/dist/module/linked_attributes/service/linked_attributes.service.js.map +1 -1
  35. package/dist/module/listmaster/service/list-master-item.service.js +2 -2
  36. package/dist/module/listmaster/service/list-master.service.js +13 -2
  37. package/dist/module/listmaster/service/list-master.service.js.map +1 -1
  38. package/dist/module/mapper/service/field-mapper.service.js +4 -4
  39. package/dist/module/mapper/service/mapper.service.js +2 -2
  40. package/dist/module/meta/controller/attribute-master.controller.d.ts +2 -3
  41. package/dist/module/meta/controller/attribute-master.controller.js +2 -12
  42. package/dist/module/meta/controller/attribute-master.controller.js.map +1 -1
  43. package/dist/module/meta/entity/attribute-master.entity.d.ts +1 -0
  44. package/dist/module/meta/entity/attribute-master.entity.js +4 -0
  45. package/dist/module/meta/entity/attribute-master.entity.js.map +1 -1
  46. package/dist/module/meta/repository/entity-attribute-update.repository.js +3 -3
  47. package/dist/module/meta/repository/entity-master.repository.js +6 -6
  48. package/dist/module/meta/service/entity-dynamic.service.js +44 -44
  49. package/dist/module/meta/service/entity-list.service.js +3 -3
  50. package/dist/module/meta/service/entity-master.service.js +3 -3
  51. package/dist/module/meta/service/entity-relation.service.js +9 -9
  52. package/dist/module/meta/service/entity-service-impl.service.js +3 -3
  53. package/dist/module/meta/service/resolver.service.js +3 -3
  54. package/dist/module/module/repository/menu.repository.js +12 -12
  55. package/dist/module/notification/controller/otp.controller.d.ts +1 -31
  56. package/dist/module/notification/service/notification.service.js +10 -10
  57. package/dist/module/notification/service/otp.service.d.ts +1 -31
  58. package/dist/module/notification/service/otp.service.js +1 -0
  59. package/dist/module/notification/service/otp.service.js.map +1 -1
  60. package/dist/module/user/controller/login.controller.js +20 -19
  61. package/dist/module/user/controller/login.controller.js.map +1 -1
  62. package/dist/module/user/service/login.service.d.ts +3 -57
  63. package/dist/module/user/service/login.service.js +12 -2
  64. package/dist/module/user/service/login.service.js.map +1 -1
  65. package/dist/module/user/service/role.service.js +4 -4
  66. package/dist/module/user/service/user-session.service.js +2 -2
  67. package/dist/module/user/service/user.service.js +1 -1
  68. package/dist/module/user/service/user.service.js.map +1 -1
  69. package/dist/module/workflow/repository/action.repository.js +20 -20
  70. package/dist/module/workflow/repository/comm-template.repository.js +6 -6
  71. package/dist/module/workflow/repository/form-master.repository.js +2 -2
  72. package/dist/module/workflow/repository/stage-group.repository.js +20 -20
  73. package/dist/module/workflow/repository/stage-movement.repository.js +17 -17
  74. package/dist/module/workflow/repository/stage.repository.js +8 -8
  75. package/dist/module/workflow/service/action-template-mapping.service.js +31 -31
  76. package/dist/module/workflow/service/action.service.js +7 -7
  77. package/dist/module/workflow/service/entity-modification.service.js +3 -7
  78. package/dist/module/workflow/service/entity-modification.service.js.map +1 -1
  79. package/dist/module/workflow/service/stage-group.service.js +2 -2
  80. package/dist/module/workflow/service/stage.service.js +2 -2
  81. package/dist/module/workflow/service/task.service.js +35 -35
  82. package/dist/module/workflow/service/workflow-list-master.service.js +15 -15
  83. package/dist/module/workflow/service/workflow-meta.service.js +27 -27
  84. package/dist/module/workflow/service/workflow-meta.service.js.map +1 -1
  85. package/dist/module/workflow/service/workflow.service.js +2 -2
  86. package/dist/module/workflow-automation/service/schedule-handler.service.d.ts +11 -5
  87. package/dist/module/workflow-automation/service/schedule-handler.service.js +59 -27
  88. package/dist/module/workflow-automation/service/schedule-handler.service.js.map +1 -1
  89. package/dist/module/workflow-automation/service/workflow-automation-engine.service.d.ts +4 -3
  90. package/dist/module/workflow-automation/service/workflow-automation-engine.service.js +12 -4
  91. package/dist/module/workflow-automation/service/workflow-automation-engine.service.js.map +1 -1
  92. package/dist/module/workflow-automation/service/workflow-automation.service.js +4 -2
  93. package/dist/module/workflow-automation/service/workflow-automation.service.js.map +1 -1
  94. package/dist/module/workflow-automation/workflow-automation.module.js +6 -0
  95. package/dist/module/workflow-automation/workflow-automation.module.js.map +1 -1
  96. package/dist/module/workflow-schedule/processors/schedule.processor.js +4 -4
  97. package/dist/module/workflow-schedule/service/workflow-schedule.service.js +10 -10
  98. package/dist/module/workflow-schedule/service/workflow-schedule.service.js.map +1 -1
  99. package/dist/tsconfig.build.tsbuildinfo +1 -1
  100. package/dist/utils/service/reflection-helper.service.js +2 -2
  101. package/docs/modules/event-driven-integration-design.md +91 -91
  102. package/docs/modules/integration.md +250 -250
  103. package/eslint.config.mjs +34 -34
  104. package/nest-cli.json +14 -14
  105. package/package.json +124 -124
  106. package/src/app.controller.ts +12 -12
  107. package/src/app.module.ts +66 -66
  108. package/src/app.service.ts +8 -8
  109. package/src/config/bull.config.ts +69 -69
  110. package/src/config/config.module.ts +17 -17
  111. package/src/config/database.config.ts +48 -48
  112. package/src/constant/global.constant.ts +67 -67
  113. package/src/core.module.ts +88 -88
  114. package/src/decorators/roles.decorator.ts +7 -7
  115. package/src/dtos/response.dto.ts +6 -6
  116. package/src/dtos/response.ts +5 -5
  117. package/src/index.ts +1 -1
  118. package/src/module/auth/auth.module.ts +49 -49
  119. package/src/module/auth/controller/auth.controller.ts +28 -28
  120. package/src/module/auth/guards/google-auth.guard.ts +9 -9
  121. package/src/module/auth/guards/jwt.guard.ts +22 -22
  122. package/src/module/auth/guards/role.guard.ts +68 -68
  123. package/src/module/auth/services/auth.service.ts +50 -50
  124. package/src/module/auth/services/jwt.service.ts +11 -11
  125. package/src/module/auth/strategies/google.strategy.ts +54 -54
  126. package/src/module/auth/strategies/jwt.strategy.ts +58 -58
  127. package/src/module/auth/strategies/local.strategy.ts +13 -13
  128. package/src/module/dashboard/controller/dashboard.controller.ts +36 -36
  129. package/src/module/dashboard/dashboard.module.ts +21 -21
  130. package/src/module/dashboard/entity/dashboard_page_data.entity.ts +27 -27
  131. package/src/module/dashboard/entity/widget_master.entity.ts +18 -18
  132. package/src/module/dashboard/repository/dashboard.repository.ts +42 -42
  133. package/src/module/dashboard/service/dashboard.service.ts +73 -73
  134. package/src/module/dev/dev.module.ts +12 -12
  135. package/src/module/dev/service/dev.service.ts +7 -7
  136. package/src/module/enterprise/controller/organization.controller.ts +36 -36
  137. package/src/module/enterprise/enterprise.module.ts +30 -30
  138. package/src/module/enterprise/entity/enterprise.entity.ts +37 -37
  139. package/src/module/enterprise/entity/organization-app-mapping.entity.ts +13 -13
  140. package/src/module/enterprise/entity/organization.entity.ts +92 -92
  141. package/src/module/enterprise/repository/enterprise.repository.ts +31 -31
  142. package/src/module/enterprise/repository/organization.repository.ts +26 -26
  143. package/src/module/enterprise/repository/school.repository.ts +278 -278
  144. package/src/module/enterprise/service/brand.service.ts +5 -5
  145. package/src/module/enterprise/service/enterprise.service.ts +16 -16
  146. package/src/module/enterprise/service/organization-app-mapping.service.ts +4 -4
  147. package/src/module/enterprise/service/organization.service.ts +145 -145
  148. package/src/module/entity_json/controller/entity_json.controller.ts +47 -47
  149. package/src/module/entity_json/entity/entityJson.entity.ts +39 -0
  150. package/src/module/entity_json/entity_json.module.ts +18 -15
  151. package/src/module/entity_json/service/entityJson.repository.ts +37 -0
  152. package/src/module/entity_json/service/entity_json.service.ts +234 -265
  153. package/src/module/filter/controller/filter.controller.ts +84 -84
  154. package/src/module/filter/dto/filter-request.dto.ts +38 -38
  155. package/src/module/filter/entity/saved-filter-detail.entity.ts +41 -41
  156. package/src/module/filter/entity/saved-filter-master.entity.ts +23 -23
  157. package/src/module/filter/filter.module.ts +31 -31
  158. package/src/module/filter/repository/saved-filter.repository.ts +168 -168
  159. package/src/module/filter/service/filter-evaluator.service.ts +86 -86
  160. package/src/module/filter/service/filter.service.ts +1144 -1051
  161. package/src/module/filter/service/saved-filter.service.ts +170 -170
  162. package/src/module/ics/controller/ics.controller.ts +21 -21
  163. package/src/module/ics/dto/ics.dto.ts +55 -55
  164. package/src/module/ics/ics.module.ts +13 -13
  165. package/src/module/ics/service/ics.service.ts +57 -57
  166. package/src/module/integration/controller/calender-event.controller.ts +31 -31
  167. package/src/module/integration/controller/integration.controller.ts +662 -662
  168. package/src/module/integration/controller/wrapper.controller.ts +37 -37
  169. package/src/module/integration/dto/create-config.dto.ts +526 -526
  170. package/src/module/integration/entity/integration-config.entity.ts +112 -112
  171. package/src/module/integration/entity/integration-entity-mapper.entity.ts +14 -14
  172. package/src/module/integration/entity/integration-source.entity.ts +17 -17
  173. package/src/module/integration/entity/user-integration.entity.ts +71 -71
  174. package/src/module/integration/examples/usage.example.ts +338 -338
  175. package/src/module/integration/factories/base.factory.ts +7 -7
  176. package/src/module/integration/factories/email.factory.ts +49 -49
  177. package/src/module/integration/factories/integration.factory.ts +121 -121
  178. package/src/module/integration/factories/sms.factory.ts +51 -51
  179. package/src/module/integration/factories/telephone.factory.ts +41 -41
  180. package/src/module/integration/factories/whatsapp.factory.ts +56 -56
  181. package/src/module/integration/integration.module.ts +110 -110
  182. package/src/module/integration/service/calendar-event.service.ts +118 -118
  183. package/src/module/integration/service/integration-entity-mapper.service.ts +17 -17
  184. package/src/module/integration/service/integration-queue.service.ts +229 -229
  185. package/src/module/integration/service/integration.service.ts +2633 -2633
  186. package/src/module/integration/service/oauth.service.ts +224 -224
  187. package/src/module/integration/service/wrapper.service.ts +701 -701
  188. package/src/module/integration/strategies/email/gmail-api.strategy.ts +280 -280
  189. package/src/module/integration/strategies/email/outlook-api.strategy.ts +44 -44
  190. package/src/module/integration/strategies/email/outlook.strategy.ts +64 -64
  191. package/src/module/integration/strategies/email/sendgrid-api.strategy.ts +260 -260
  192. package/src/module/integration/strategies/integration.strategy.ts +97 -97
  193. package/src/module/integration/strategies/sms/gupshup-sms.strategy.ts +146 -146
  194. package/src/module/integration/strategies/sms/msg91-sms.strategy.ts +164 -164
  195. package/src/module/integration/strategies/sms/tubelight-sms.strategy.ts +163 -163
  196. package/src/module/integration/strategies/telephone/ozonetel-voice.strategy.ts +238 -238
  197. package/src/module/integration/strategies/telephone/tubelight-voice.strategy.ts +210 -210
  198. package/src/module/integration/strategies/whatsapp/gupshup-whatsapp.strategy.ts +359 -359
  199. package/src/module/integration/strategies/whatsapp/tubelight-whatsapp.strategy.ts +372 -372
  200. package/src/module/integration/strategies/whatsapp/whatsapp-cloud.strategy.ts +403 -403
  201. package/src/module/integration/strategies/whatsapp/whatsapp.strategy.ts +57 -57
  202. package/src/module/layout/controller/layout.controller.ts +47 -47
  203. package/src/module/layout/entity/header-items.entity.ts +28 -28
  204. package/src/module/layout/entity/header-section.entity.ts +19 -19
  205. package/src/module/layout/layout.module.ts +21 -21
  206. package/src/module/layout/repository/header-items.repository.ts +18 -18
  207. package/src/module/layout/repository/header-section.repository.ts +22 -22
  208. package/src/module/layout/service/header-section.service.ts +25 -25
  209. package/src/module/layout_preference/controller/layout_preference.controller.ts +73 -73
  210. package/src/module/layout_preference/entity/layout_preference.entity.ts +28 -28
  211. package/src/module/layout_preference/layout_preference.module.ts +22 -22
  212. package/src/module/layout_preference/repository/layout_preference.repository.ts +65 -65
  213. package/src/module/layout_preference/service/layout_preference.service.ts +191 -191
  214. package/src/module/lead/controller/lead.controller.ts +30 -30
  215. package/src/module/lead/lead.module.ts +14 -14
  216. package/src/module/lead/repository/lead.repository.ts +41 -41
  217. package/src/module/lead/service/lead.service.ts +54 -54
  218. package/src/module/linked_attributes/controller/linked_attributes.controller.ts +34 -10
  219. package/src/module/linked_attributes/entity/linked_attribute.entity.ts +51 -48
  220. package/src/module/linked_attributes/linked_attributes.module.ts +16 -16
  221. package/src/module/linked_attributes/repository/linked_attribute.repository.ts +12 -12
  222. package/src/module/linked_attributes/service/linked_attributes.service.ts +102 -22
  223. package/src/module/listmaster/controller/list-master.controller.ts +230 -230
  224. package/src/module/listmaster/entity/list-master-items.entity.ts +43 -43
  225. package/src/module/listmaster/entity/list-master.entity.ts +33 -33
  226. package/src/module/listmaster/listmaster.module.ts +46 -46
  227. package/src/module/listmaster/repository/list-master-items.repository.ts +173 -173
  228. package/src/module/listmaster/repository/list-master.repository.ts +46 -46
  229. package/src/module/listmaster/service/list-master-engine.ts +19 -19
  230. package/src/module/listmaster/service/list-master-extension.interface.ts +4 -4
  231. package/src/module/listmaster/service/list-master-item.service.ts +292 -292
  232. package/src/module/listmaster/service/list-master-registry.ts +15 -15
  233. package/src/module/listmaster/service/list-master.service.ts +558 -535
  234. package/src/module/mapper/controller/field-mapper.controller.ts +76 -76
  235. package/src/module/mapper/controller/mapper.controller.ts +20 -20
  236. package/src/module/mapper/dto/field-mapper.dto.ts +14 -14
  237. package/src/module/mapper/entity/field-lovs.entity.ts +19 -19
  238. package/src/module/mapper/entity/field-mapper.entity.ts +53 -53
  239. package/src/module/mapper/entity/mapper.entity.ts +16 -16
  240. package/src/module/mapper/mapper.module.ts +34 -34
  241. package/src/module/mapper/repository/field-lovs.repository.ts +35 -35
  242. package/src/module/mapper/repository/field-mapper.repository.ts +42 -42
  243. package/src/module/mapper/repository/mapper.repository.ts +15 -15
  244. package/src/module/mapper/service/field-mapper.service.ts +271 -271
  245. package/src/module/mapper/service/mapper.service.ts +79 -79
  246. package/src/module/master/controller/master.controller.ts +74 -74
  247. package/src/module/master/service/master.service.ts +483 -483
  248. package/src/module/meta/controller/app-master.controller.ts +38 -38
  249. package/src/module/meta/controller/attribute-master.controller.ts +84 -86
  250. package/src/module/meta/controller/entity-dynamic.controller.ts +125 -125
  251. package/src/module/meta/controller/entity-master.controller.ts +41 -41
  252. package/src/module/meta/controller/entity-relation.controller.ts +36 -36
  253. package/src/module/meta/controller/entity.controller.ts +392 -392
  254. package/src/module/meta/controller/entity.public.controller.ts +75 -75
  255. package/src/module/meta/controller/media.controller.ts +107 -107
  256. package/src/module/meta/controller/meta.controller.ts +96 -96
  257. package/src/module/meta/controller/view-master.controller.ts +86 -86
  258. package/src/module/meta/dto/entity-list-data.dto.ts +6 -6
  259. package/src/module/meta/dto/entity-tab.dto.ts +4 -4
  260. package/src/module/meta/dto/entity-table.dto.ts +9 -9
  261. package/src/module/meta/entity/app-master.entity.ts +34 -34
  262. package/src/module/meta/entity/attribute-master.entity.ts +92 -89
  263. package/src/module/meta/entity/base-entity.entity.ts +75 -75
  264. package/src/module/meta/entity/entity-master.entity.ts +85 -85
  265. package/src/module/meta/entity/entity-relation-data.entity.ts +29 -29
  266. package/src/module/meta/entity/entity-relation.entity.ts +23 -23
  267. package/src/module/meta/entity/entity-table-column.entity.ts +61 -61
  268. package/src/module/meta/entity/entity-table.entity.ts +50 -50
  269. package/src/module/meta/entity/media-data.entity.ts +32 -32
  270. package/src/module/meta/entity/preference.entity.ts +62 -62
  271. package/src/module/meta/entity/view-master.entity.ts +41 -41
  272. package/src/module/meta/entity.module.ts +166 -166
  273. package/src/module/meta/repository/app-master.repository.ts +20 -20
  274. package/src/module/meta/repository/attribute-master.repository.ts +138 -138
  275. package/src/module/meta/repository/entity-attribute-update.repository.ts +44 -44
  276. package/src/module/meta/repository/entity-master.repository.ts +111 -111
  277. package/src/module/meta/repository/entity-table-column.repository.ts +39 -39
  278. package/src/module/meta/repository/entity-table.repository.ts +53 -53
  279. package/src/module/meta/repository/media-data.repository.ts +50 -50
  280. package/src/module/meta/repository/preference.repository.ts +20 -20
  281. package/src/module/meta/repository/user-app-mapping.repository.ts +28 -28
  282. package/src/module/meta/repository/view-master.repository.ts +42 -42
  283. package/src/module/meta/service/app-master.service.ts +37 -37
  284. package/src/module/meta/service/attribute-master.service.ts +130 -130
  285. package/src/module/meta/service/common.service.ts +9 -9
  286. package/src/module/meta/service/entity-attribute-update.service.ts +28 -28
  287. package/src/module/meta/service/entity-dynamic.service.ts +809 -809
  288. package/src/module/meta/service/entity-list.service.ts +205 -205
  289. package/src/module/meta/service/entity-master.service.ts +175 -175
  290. package/src/module/meta/service/entity-realation-data.service.ts +9 -9
  291. package/src/module/meta/service/entity-relation.service.ts +87 -87
  292. package/src/module/meta/service/entity-service-impl.service.ts +525 -525
  293. package/src/module/meta/service/entity-table-column.service.ts +39 -39
  294. package/src/module/meta/service/entity-table.service.ts +150 -150
  295. package/src/module/meta/service/entity-validation.service.ts +187 -187
  296. package/src/module/meta/service/entity.service.ts +67 -67
  297. package/src/module/meta/service/field-group.service.ts +103 -103
  298. package/src/module/meta/service/media-data.service.ts +507 -507
  299. package/src/module/meta/service/populate-meta.service.ts +193 -193
  300. package/src/module/meta/service/preference.service.ts +16 -16
  301. package/src/module/meta/service/resolver.service.ts +271 -271
  302. package/src/module/meta/service/section-master.service.ts +104 -104
  303. package/src/module/meta/service/update-form-json.service.ts +22 -22
  304. package/src/module/meta/service/user-app-mapping.service.ts +17 -17
  305. package/src/module/meta/service/view-master.service.ts +127 -127
  306. package/src/module/microservice-client/microservice-clients.module.ts +13 -13
  307. package/src/module/microservice-client/service/microservice-client-factory.ts +37 -37
  308. package/src/module/microservice-client/service/microservice-clients.ts +4 -4
  309. package/src/module/module/controller/menu.controller.ts +15 -15
  310. package/src/module/module/controller/module-access.controller.ts +134 -134
  311. package/src/module/module/entity/menu.entity.ts +43 -43
  312. package/src/module/module/entity/module-access.entity.ts +25 -25
  313. package/src/module/module/entity/module-action.entity.ts +17 -17
  314. package/src/module/module/entity/module.entity.ts +52 -52
  315. package/src/module/module/module.module.ts +42 -42
  316. package/src/module/module/repository/menu.repository.ts +184 -184
  317. package/src/module/module/repository/module-access.repository.ts +344 -344
  318. package/src/module/module/service/menu.service.ts +82 -82
  319. package/src/module/module/service/module-access.service.ts +194 -194
  320. package/src/module/notification/controller/notification.controller.ts +58 -58
  321. package/src/module/notification/controller/otp.controller.ts +117 -117
  322. package/src/module/notification/entity/notification.entity.ts +26 -26
  323. package/src/module/notification/entity/otp.entity.ts +28 -28
  324. package/src/module/notification/firebase-admin.config.ts +22 -22
  325. package/src/module/notification/notification.module.ts +69 -69
  326. package/src/module/notification/repository/otp.repository.ts +27 -27
  327. package/src/module/notification/service/email.service.ts +127 -127
  328. package/src/module/notification/service/notification.service.ts +160 -160
  329. package/src/module/notification/service/otp.service.ts +133 -132
  330. package/src/module/third-party-module/entity/third-party-api-registry.entity.ts +52 -52
  331. package/src/module/third-party-module/repository/third-party-api-registry.repository.ts +20 -20
  332. package/src/module/third-party-module/service/api-registry.service.ts +13 -13
  333. package/src/module/third-party-module/third-party.module.ts +12 -12
  334. package/src/module/user/controller/login.controller.ts +198 -197
  335. package/src/module/user/controller/user.controller.ts +40 -40
  336. package/src/module/user/dto/create-user.dto.ts +62 -62
  337. package/src/module/user/dto/update-user.dto.ts +4 -4
  338. package/src/module/user/entity/role.entity.ts +33 -33
  339. package/src/module/user/entity/user-role-mapping.entity.ts +38 -38
  340. package/src/module/user/entity/user-session.entity.ts +73 -73
  341. package/src/module/user/entity/user.entity.ts +59 -59
  342. package/src/module/user/repository/role.repository.ts +96 -96
  343. package/src/module/user/repository/user-role-mapping.repository.ts +126 -126
  344. package/src/module/user/repository/user.repository.ts +50 -50
  345. package/src/module/user/repository/userSession.repository.ts +33 -33
  346. package/src/module/user/service/login.service.ts +326 -304
  347. package/src/module/user/service/role.service.ts +189 -189
  348. package/src/module/user/service/user-role-mapping.service.ts +98 -98
  349. package/src/module/user/service/user-session.service.ts +168 -168
  350. package/src/module/user/service/user.service.ts +368 -365
  351. package/src/module/user/user.module.ts +65 -65
  352. package/src/module/workflow/controller/action-category.controller.ts +54 -54
  353. package/src/module/workflow/controller/action-resource-mapping.controller.ts +23 -23
  354. package/src/module/workflow/controller/action-template-mapping.controller.ts +35 -35
  355. package/src/module/workflow/controller/action.controller.ts +111 -111
  356. package/src/module/workflow/controller/activity-log.controller.ts +55 -55
  357. package/src/module/workflow/controller/comm-template.controller.ts +43 -43
  358. package/src/module/workflow/controller/entity-modification.controller.ts +35 -35
  359. package/src/module/workflow/controller/form-master.controller.ts +43 -43
  360. package/src/module/workflow/controller/stage-group.controller.ts +48 -48
  361. package/src/module/workflow/controller/stage.controller.ts +50 -50
  362. package/src/module/workflow/controller/task.controller.ts +77 -77
  363. package/src/module/workflow/controller/workflow-list-master.controller.ts +44 -44
  364. package/src/module/workflow/controller/workflow-meta.controller.ts +80 -80
  365. package/src/module/workflow/controller/workflow.controller.ts +67 -67
  366. package/src/module/workflow/entity/action-category.entity.ts +38 -38
  367. package/src/module/workflow/entity/action-data.entity.ts +55 -55
  368. package/src/module/workflow/entity/action-resources-mapping.entity.ts +29 -29
  369. package/src/module/workflow/entity/action-template-mapping.entity.ts +17 -17
  370. package/src/module/workflow/entity/action.entity.ts +53 -53
  371. package/src/module/workflow/entity/activity-log.entity.ts +43 -43
  372. package/src/module/workflow/entity/comm-template.entity.ts +43 -43
  373. package/src/module/workflow/entity/entity-modification.entity.ts +38 -38
  374. package/src/module/workflow/entity/form.entity.ts +25 -25
  375. package/src/module/workflow/entity/stage-action-mapping.entity.ts +17 -17
  376. package/src/module/workflow/entity/stage-group.entity.ts +23 -23
  377. package/src/module/workflow/entity/stage-movement-data.entity.ts +38 -38
  378. package/src/module/workflow/entity/stage.entity.ts +20 -20
  379. package/src/module/workflow/entity/task-data.entity.ts +88 -88
  380. package/src/module/workflow/entity/template-attach-mapper.entity.ts +30 -30
  381. package/src/module/workflow/entity/workflow-data.entity.ts +11 -11
  382. package/src/module/workflow/entity/workflow-level-mapping.entity.ts +18 -18
  383. package/src/module/workflow/entity/workflow.entity.ts +20 -20
  384. package/src/module/workflow/repository/action-category.repository.ts +79 -79
  385. package/src/module/workflow/repository/action-data.repository.ts +334 -334
  386. package/src/module/workflow/repository/action.repository.ts +323 -323
  387. package/src/module/workflow/repository/activity-log.repository.ts +148 -148
  388. package/src/module/workflow/repository/comm-template.repository.ts +149 -149
  389. package/src/module/workflow/repository/form-master.repository.ts +59 -59
  390. package/src/module/workflow/repository/stage-group.repository.ts +197 -197
  391. package/src/module/workflow/repository/stage-movement.repository.ts +246 -246
  392. package/src/module/workflow/repository/stage.repository.ts +172 -172
  393. package/src/module/workflow/repository/task.repository.ts +134 -134
  394. package/src/module/workflow/repository/workflow.repository.ts +42 -42
  395. package/src/module/workflow/service/action-category.service.ts +33 -33
  396. package/src/module/workflow/service/action-data.service.ts +62 -62
  397. package/src/module/workflow/service/action-resources-mapping.service.ts +10 -10
  398. package/src/module/workflow/service/action-template-mapping.service.ts +115 -115
  399. package/src/module/workflow/service/action.service.ts +279 -279
  400. package/src/module/workflow/service/activity-log.service.ts +107 -107
  401. package/src/module/workflow/service/comm-template.service.ts +180 -180
  402. package/src/module/workflow/service/entity-modification.service.ts +61 -67
  403. package/src/module/workflow/service/form-master.service.ts +35 -35
  404. package/src/module/workflow/service/populate-workflow.service.ts +303 -303
  405. package/src/module/workflow/service/stage-action-mapping.service.ts +5 -5
  406. package/src/module/workflow/service/stage-group.service.ts +342 -342
  407. package/src/module/workflow/service/stage.service.ts +199 -199
  408. package/src/module/workflow/service/task.service.ts +558 -558
  409. package/src/module/workflow/service/workflow-list-master.service.ts +60 -60
  410. package/src/module/workflow/service/workflow-meta.service.ts +654 -654
  411. package/src/module/workflow/service/workflow.service.ts +205 -205
  412. package/src/module/workflow/workflow.module.ts +178 -178
  413. package/src/module/workflow-automation/SCHEDULING_GUIDE.md +145 -145
  414. package/src/module/workflow-automation/controller/workflow-automation.controller.ts +43 -43
  415. package/src/module/workflow-automation/entity/workflow-automation-action.entity.ts +26 -26
  416. package/src/module/workflow-automation/entity/workflow-automation.entity.ts +40 -40
  417. package/src/module/workflow-automation/interface/action.decorator.ts +7 -7
  418. package/src/module/workflow-automation/interface/action.interface.ts +5 -5
  419. package/src/module/workflow-automation/service/action-registery.service.ts +35 -35
  420. package/src/module/workflow-automation/service/schedule-handler.service.ts +168 -149
  421. package/src/module/workflow-automation/service/workflow-automation-engine.service.ts +224 -214
  422. package/src/module/workflow-automation/service/workflow-automation.service.ts +515 -508
  423. package/src/module/workflow-automation/workflow-automation.module.ts +54 -47
  424. package/src/module/workflow-schedule/INSTALLATION.md +244 -244
  425. package/src/module/workflow-schedule/MULTI_PROJECT_GUIDE.md +196 -196
  426. package/src/module/workflow-schedule/README.md +422 -422
  427. package/src/module/workflow-schedule/constants/schedule.constants.ts +48 -48
  428. package/src/module/workflow-schedule/controller/workflow-schedule.controller.ts +255 -255
  429. package/src/module/workflow-schedule/docs/CLAUDE_CODE_GUIDE.md +510 -510
  430. package/src/module/workflow-schedule/docs/CLAUDE_CODE_PROMPT.md +362 -362
  431. package/src/module/workflow-schedule/docs/RUN_CLAUDE_CODE.sh +68 -68
  432. package/src/module/workflow-schedule/dto/create-schedule.dto.ts +147 -147
  433. package/src/module/workflow-schedule/dto/get-execution-logs.dto.ts +119 -119
  434. package/src/module/workflow-schedule/dto/update-schedule.dto.ts +96 -96
  435. package/src/module/workflow-schedule/entities/scheduled-workflow.entity.ts +148 -148
  436. package/src/module/workflow-schedule/entities/workflow-execution-log.entity.ts +154 -154
  437. package/src/module/workflow-schedule/interfaces/schedule-job-data.interface.ts +53 -53
  438. package/src/module/workflow-schedule/interfaces/workflow-schedule-options.interface.ts +12 -12
  439. package/src/module/workflow-schedule/processors/schedule.processor.ts +584 -584
  440. package/src/module/workflow-schedule/service/workflow-schedule.service.ts +600 -600
  441. package/src/module/workflow-schedule/workflow-schedule.module.ts +67 -67
  442. package/src/resources/dev.properties.yaml +31 -31
  443. package/src/resources/local.properties.yaml +27 -27
  444. package/src/resources/properties.module.ts +12 -12
  445. package/src/resources/properties.yaml.ts +11 -11
  446. package/src/resources/uat.properties.yaml +31 -31
  447. package/src/table.config.ts +130 -130
  448. package/src/utils/dto/excel-data.dto.ts +14 -14
  449. package/src/utils/dto/excelsheet-data.dto.ts +5 -5
  450. package/src/utils/service/base64util.service.ts +18 -18
  451. package/src/utils/service/clockIDGenUtil.service.ts +21 -21
  452. package/src/utils/service/codeGenerator.service.ts +22 -22
  453. package/src/utils/service/dateUtil.service.ts +17 -17
  454. package/src/utils/service/encryptUtil.service.ts +97 -97
  455. package/src/utils/service/excel-helper.service.ts +72 -72
  456. package/src/utils/service/excelUtil.service.ts +15 -15
  457. package/src/utils/service/file-util.service.ts +11 -11
  458. package/src/utils/service/json-util.service.ts +23 -23
  459. package/src/utils/service/loggingUtil.service.ts +88 -88
  460. package/src/utils/service/reflection-helper.service.ts +62 -62
  461. package/src/utils/service/wbsCodeGen.service.ts +8 -8
  462. package/src/utils/utils.module.ts +27 -27
  463. package/tsconfig.build.json +4 -4
  464. package/tsconfig.json +24 -24
  465. package/.claude/settings.local.json +0 -26
  466. package/.idea/250218_nodejs_core.iml +0 -9
  467. package/.idea/codeStyles/Project.xml +0 -59
  468. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  469. package/.idea/copilot.data.migration.agent.xml +0 -6
  470. package/.idea/copilot.data.migration.ask.xml +0 -6
  471. package/.idea/copilot.data.migration.ask2agent.xml +0 -6
  472. package/.idea/copilot.data.migration.edit.xml +0 -6
  473. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  474. package/.idea/misc.xml +0 -6
  475. package/.idea/modules.xml +0 -8
  476. package/.idea/prettier.xml +0 -6
  477. package/.idea/vcs.xml +0 -6
  478. package/server.log +0 -850
@@ -1,558 +1,558 @@
1
- import { Inject, Injectable } from '@nestjs/common';
2
- import { EntityServiceImpl } from 'src/module/meta/service/entity-service-impl.service';
3
- import { UserData } from 'src/module/user/entity/user.entity';
4
- import { TaskRepository } from '../repository/task.repository';
5
- import { ActionDataService } from './action-data.service';
6
- import { DataSource, EntityManager } from 'typeorm';
7
- import { ActivityLogService } from './activity-log.service';
8
- import { ACTIVITY_CATEGORIES } from '../repository/activity-log.repository';
9
- import { MediaDataService } from 'src/module/meta/service/media-data.service';
10
- import { ActionHandler } from 'src/module/workflow-automation/interface/action.decorator';
11
- import * as moment from 'moment';
12
- import { ConfigService } from '@nestjs/config';
13
- import axios from 'axios';
14
- import { ChecksumAlgorithm } from '@aws-sdk/client-s3';
15
-
16
- @Injectable()
17
- @ActionHandler('add_task')
18
- export class TaskService extends EntityServiceImpl {
19
- constructor(
20
- private readonly taskRepository: TaskRepository,
21
- private readonly actionDataService: ActionDataService,
22
- private readonly dataSource: DataSource,
23
- @Inject('ActivityLogService')
24
- private readonly activityLogService: ActivityLogService,
25
- private readonly mediaDataService: MediaDataService,
26
- private readonly configService: ConfigService,
27
- ) {
28
- super();
29
- }
30
- name: string = 'add_task';
31
-
32
- async execute(payload: any): Promise<any> {
33
- let { entity, user, config } = payload;
34
-
35
- const { organization_id, level_id, level_type } = entity;
36
-
37
- if (entity.entity_type !== 'LEAD') {
38
- entity = await this.getEntityData('LEAD', entity.parent_id, user);
39
- }
40
-
41
- // 3. Build entityData
42
- const entityData = {
43
- mapped_entity_id: entity.id,
44
- mapped_entity_type: entity.entity_type,
45
- task_owner: entity.lead_owner,
46
- stage_id: entity.stageId,
47
- status: config.status,
48
- due_date: Date.now() + 2,
49
- due_time: Date.now(),
50
- description: config.description,
51
- is_mandatory: config.is_mandatory,
52
- name: config.name,
53
- entity_type: 'TASK',
54
- };
55
-
56
- return await this.createEntity(entityData, user);
57
- }
58
-
59
- async createEntity(
60
- entityData: any,
61
- loggedInUser: any,
62
- manager?: EntityManager | null,
63
- appcode?: string,
64
- ): Promise<any> {
65
- if (entityData && typeof entityData['is_mandatory'] === 'string') {
66
- entityData['is_mandatory'] = entityData['is_mandatory'] === '1';
67
- }
68
-
69
- // handling the date string for due_date and reminder_date
70
- if (entityData?.due_date) {
71
- // Interpret input 'YYYY-MM-DD' as local midnight (IST)
72
- entityData.due_date = moment(entityData.due_date, 'YYYY-MM-DD')
73
- .startOf('day') // 00:00 local time
74
- .toDate(); // Convert to JS Date object for TypeORM
75
- }
76
-
77
- if (entityData?.reminder_date) {
78
- entityData.reminder_date = moment(entityData.reminder_date, 'YYYY-MM-DD')
79
- .startOf('day')
80
- .toDate();
81
- }
82
-
83
- const createdEntity = await super.createEntity(
84
- entityData,
85
- loggedInUser,
86
- manager,
87
- appcode,
88
- );
89
-
90
- try {
91
- const logData = {
92
- mapped_entity_id: createdEntity.mapped_entity_id,
93
- mapped_entity_type: createdEntity.mapped_entity_type,
94
- title: `Task added`,
95
- description: `A new task ${createdEntity.name} was added`,
96
- category: ACTIVITY_CATEGORIES.TASK,
97
- action: 'add',
98
- appcode: loggedInUser.appcode,
99
- };
100
-
101
- await this.activityLogService.logActivity(logData, loggedInUser);
102
- } catch (error) {
103
- console.error(
104
- 'Failed to log activity for meeting:',
105
- error?.message || error,
106
- );
107
- // Logging should not block main flow
108
- }
109
-
110
- let relationData = await this.dataSource.query(
111
- `SELECT * FROM frm_entity_relation WHERE source_entity_type = $1 AND target_entity_type = $2`,
112
- [createdEntity.mapped_entity_type, createdEntity.entity_type],
113
- );
114
-
115
- if (relationData) {
116
- await this.dataSource.query(
117
- `INSERT INTO frm_entity_relation_data (organization_id, source_entity_id, source_entity_type, target_entity_id, target_entity_type, relation_type) VALUES ($1, $2, $3, $4, $5 , $6)`,
118
- [
119
- loggedInUser.organization_id,
120
- createdEntity.mapped_entity_id,
121
- createdEntity.mapped_entity_type,
122
- createdEntity.id,
123
- createdEntity.entity_type,
124
- relationData[0]?.relation_type,
125
- ],
126
- );
127
- }
128
-
129
- return createdEntity;
130
- }
131
-
132
- async updateEntity(
133
- entityData,
134
- loggedInUser: UserData,
135
- appcode?: string,
136
- ): Promise<any> {
137
- const taskStatusQuery = `
138
- SELECT name
139
- FROM frm_list_master_items
140
- WHERE id = $1
141
- AND organization_id = $2
142
- AND listtype = 'TKST'
143
- LIMIT 1;
144
- `;
145
-
146
- const statusRows = await this.dataSource.query(taskStatusQuery, [
147
- entityData.status,
148
- loggedInUser.organization_id,
149
- ]);
150
-
151
- const oldStatusQuery = `
152
- SELECT *
153
- FROM frm_wf_task_data
154
- WHERE id = $1
155
- AND organization_id = $2
156
- LIMIT 1;
157
- `;
158
-
159
- const [oldRow] = await this.dataSource.query(oldStatusQuery, [
160
- entityData.id,
161
- loggedInUser.organization_id,
162
- ]);
163
-
164
- const oldStatusRows = await this.dataSource.query(taskStatusQuery, [
165
- oldRow.status,
166
- loggedInUser.organization_id,
167
- ]);
168
-
169
- const isStatusChanged =
170
- statusRows.length > 0 &&
171
- oldStatusRows.length > 0 &&
172
- statusRows[0].name !== oldStatusRows[0].name;
173
-
174
- const isCompletedStatus =
175
- statusRows.length > 0 &&
176
- statusRows[0].name?.toLowerCase() === 'completed';
177
-
178
- // Sync flags based on status
179
- entityData.is_completed = isCompletedStatus;
180
- entityData.is_done = isCompletedStatus;
181
-
182
- const isMandatory =
183
- String(entityData.is_mandatory).toLowerCase() === 'true' ||
184
- entityData.is_mandatory === true ||
185
- entityData.is_mandatory === 1 ||
186
- entityData.is_mandatory === '1';
187
-
188
- const updatedEntity = await super.updateEntity(
189
- {
190
- ...entityData,
191
- is_mandatory: isMandatory,
192
- },
193
- loggedInUser,
194
- appcode,
195
- );
196
-
197
- // Convert boolean back to "1" / "0" for response
198
- if (updatedEntity && typeof updatedEntity['is_mandatory'] === 'boolean') {
199
- updatedEntity['is_mandatory'] = updatedEntity['is_mandatory'] ? '1' : '0';
200
- }
201
-
202
- try {
203
- if (isCompletedStatus && isStatusChanged) {
204
- const completedLogData = {
205
- mapped_entity_id: updatedEntity.mapped_entity_id,
206
- mapped_entity_type: updatedEntity.mapped_entity_type,
207
- title: `Task completed`,
208
- description: `${updatedEntity.code} was marked as completed`,
209
- category: ACTIVITY_CATEGORIES.TASK,
210
- action: 'completed',
211
- appcode: loggedInUser.appcode,
212
- };
213
-
214
- await this.activityLogService.logActivity(
215
- completedLogData,
216
- loggedInUser,
217
- );
218
- } else {
219
- const editLogData = {
220
- mapped_entity_id: updatedEntity.mapped_entity_id,
221
- mapped_entity_type: updatedEntity.mapped_entity_type,
222
- title: `Task edited`,
223
- description: `${updatedEntity.code} was edited`,
224
- category: ACTIVITY_CATEGORIES.TASK,
225
- action: 'edit',
226
- appcode: loggedInUser.appcode,
227
- };
228
-
229
- await this.activityLogService.logActivity(editLogData, loggedInUser);
230
- }
231
- } catch (error) {
232
- console.error(
233
- 'Failed to log activity for task:',
234
- error?.message || error,
235
- );
236
- // Don't block main flow
237
- }
238
-
239
- return updatedEntity;
240
- }
241
-
242
- async getAllTaskByUserIdandStageId(
243
- loggedInUser: UserData,
244
- data,
245
- ): Promise<any> {
246
- const taskData = await this.taskRepository.getAllTaskByUserIdAndStageId({
247
- user_id: data.user_id,
248
- stage_id: data.stage_id,
249
- mapped_entity_type: data.mapped_entity_type,
250
- mapped_entity_id: data.mapped_entity_id,
251
- });
252
-
253
- const grouped: { mandatory: any[]; non_mandatory: any[] } = {
254
- mandatory: [],
255
- non_mandatory: [],
256
- };
257
-
258
- for (const task of taskData) {
259
- if (task && task.is_mandatory) {
260
- grouped.mandatory.push(task);
261
- } else {
262
- grouped.non_mandatory.push(task);
263
- }
264
- }
265
-
266
- return grouped;
267
- }
268
-
269
- async getAllTask(
270
- loggedInUser: UserData,
271
- data: {
272
- mapped_entity_type: string;
273
- mapped_entity_id: number;
274
- status?: string;
275
- mandatory?: boolean;
276
- overdue?: boolean;
277
- },
278
- ): Promise<any[]> {
279
- const { mapped_entity_type, mapped_entity_id, status, mandatory, overdue } =
280
- data;
281
-
282
- const whereClauses: string[] = [];
283
- const params: any[] = [];
284
- let idx = 1;
285
-
286
- // Required filters
287
- whereClauses.push(`t.mapped_entity_type = $${idx++}`);
288
- params.push(mapped_entity_type);
289
-
290
- whereClauses.push(`t.mapped_entity_id::text = $${idx++}`);
291
- params.push(String(mapped_entity_id));
292
-
293
- // Optional: status (stored as varchar)
294
- if (status) {
295
- whereClauses.push(`t.status::text = $${idx++}`);
296
- params.push(String(status));
297
- }
298
-
299
- // Optional: mandatory (stored as varchar '0' / '1')
300
- if (mandatory !== undefined) {
301
- whereClauses.push(`t.is_mandatory::text = $${idx++}`);
302
- params.push(mandatory ? "1" : "0");
303
- }
304
-
305
- // Optional: overdue
306
- if (overdue) {
307
- whereClauses.push(`
308
- (
309
- t.due_date < CURRENT_DATE
310
- OR (t.due_date = CURRENT_DATE AND t.due_time < CURRENT_TIME)
311
- )
312
- `);
313
-
314
- // Only include tasks NOT done
315
- whereClauses.push(`t.is_done::text = $${idx++}`);
316
- params.push("0"); // varchar field
317
- }
318
-
319
- // Final SQL
320
- const sql = `
321
- SELECT
322
- t.*,
323
- sg.name AS stage_group_name,
324
- s.name AS stage_name,
325
- a.name AS action_name
326
- FROM frm_wf_task_data t
327
- LEFT JOIN frm_wf_stage s ON t.stage_id::text = s.id::text
328
- LEFT JOIN frm_wf_stage_group sg ON s.stage_group_id = sg.id
329
- LEFT JOIN frm_wf_action a ON t.action_id::text = a.id::text
330
- WHERE ${whereClauses.join(" AND ")}
331
- ORDER BY t.created_date DESC
332
- `;
333
-
334
- const taskData = await this.dataSource.query(sql, params);
335
-
336
- // -------------------------------
337
- // PROFILE IMAGE MAPPING
338
- // -------------------------------
339
- if (taskData?.length) {
340
- for (const task of taskData) {
341
- try {
342
- const baseUrl =
343
- this.configService.get<string>("REDIRECT_BE_URL");
344
-
345
- const queryParams = new URLSearchParams({
346
- loggedInUser: JSON.stringify(loggedInUser),
347
- }).toString();
348
-
349
- const response = await axios.get(
350
- `${baseUrl}/users/profile-image-url/${task.task_owner}?entity_type=USR&${queryParams}`,
351
- { headers: { "Content-Type": "application/json" } },
352
- );
353
-
354
- task.created_by_name = response.data.name;
355
- task.task_owner_name = response.data.name;
356
- task.task_owner_profile = response.data.profile_image;
357
- } catch (err) {
358
- console.error("⚠ Error fetching profile:", err.message);
359
- }
360
- }
361
- }
362
-
363
- if (!taskData.length) return [];
364
-
365
- // -------------------------------
366
- // FETCH TKST STATUS LABELS
367
- // -------------------------------
368
- const statusSql = `
369
- SELECT id, name
370
- FROM frm_list_master_items
371
- WHERE organization_id = $1
372
- AND listtype = 'TKST'
373
- `;
374
-
375
- const allStatuses = await this.dataSource.query(statusSql, [
376
- loggedInUser.organization_id,
377
- ]);
378
-
379
- const statusMap = new Map(
380
- allStatuses.map((row) => [String(row.id), row.name]),
381
- );
382
-
383
- // -------------------------------
384
- // FINAL MAPPING
385
- // -------------------------------
386
- return taskData.map((task) => ({
387
- ...task,
388
- task_status: statusMap.get(String(task.status)) || null,
389
- action_name:
390
- task.action_id === "0" || task.action_id === 0
391
- ? "Generic"
392
- : task.action_name,
393
- is_mandatory: task.is_mandatory === "1" ? "1" : "0",
394
- }));
395
- }
396
-
397
- async getEntityData(entityType: string, id: number, loggedInUser: any) {
398
- const taskData = await super.getEntityData(entityType, id, loggedInUser);
399
-
400
- if (taskData?.due_date) {
401
- taskData.due_date = moment(taskData.due_date)
402
- .local() // convert from UTC to local
403
- .format('YYYY-MM-DD'); // return just the date string
404
- }
405
-
406
- if (taskData?.reminder_date) {
407
- taskData.reminder_date = moment(taskData.reminder_date)
408
- .local()
409
- .format('YYYY-MM-DD');
410
- }
411
-
412
- return taskData;
413
- }
414
-
415
- async saveActionData(
416
- action: any,
417
- loggedInUser: UserData,
418
- mapped_entity_id: number,
419
- mapped_entity_type: string,
420
- ): Promise<any> {
421
- await this.taskRepository.saveActionDataInTask(
422
- action,
423
- loggedInUser,
424
- mapped_entity_id,
425
- mapped_entity_type,
426
- );
427
- }
428
-
429
- async moveTask(
430
- loggedInUser: UserData,
431
- body: {
432
- mapped_entity_type: string;
433
- mapped_entity_id: number;
434
- stage_id: number;
435
- action_id: number;
436
- reason_code?: string | number;
437
- remark?: string;
438
- stage_group_id?: number;
439
- },
440
- ): Promise<any> {
441
- // Logic to move task based on the provided body parameters
442
- // This could involve updating the task's stage, action, etc.
443
-
444
- // update task status
445
- this.taskRepository.updateTaskStatus(
446
- loggedInUser,
447
- body.mapped_entity_type,
448
- body.mapped_entity_id,
449
- body.stage_id,
450
- body.action_id,
451
- );
452
-
453
- // update action status
454
- await this.actionDataService.updateActionStatus(
455
- loggedInUser,
456
- body.mapped_entity_type,
457
- body.mapped_entity_id,
458
- body.stage_id,
459
- body.action_id,
460
- );
461
-
462
- if (body.reason_code || body.remark) {
463
- await this.createSystemNote(
464
- {
465
- reason_code: body.reason_code!,
466
- remark: body.remark || '',
467
- mapped_entity_id: body.mapped_entity_id,
468
- stage_id: body.stage_id,
469
- action_id: body.action_id,
470
- stage_group_id: body.stage_group_id,
471
- },
472
- loggedInUser,
473
- );
474
- }
475
-
476
- return 'Task moved successfully';
477
- }
478
-
479
- async deleteEntity(
480
- entity_type: string,
481
- taskId: number,
482
- loggedInUser: UserData,
483
- ): Promise<any> {
484
- // Fetch the task before deleting
485
- const task: any = await super.getEntityData(
486
- entity_type,
487
- taskId,
488
- loggedInUser,
489
- );
490
-
491
- if (!task) {
492
- throw new Error('Task not found');
493
- }
494
-
495
- // Check if the task is system-generated
496
- if (task.is_system) {
497
- throw new Error('Cannot delete system-generated tasks');
498
- }
499
-
500
- // Perform the deletion
501
- await super.deleteEntity(entity_type, taskId, loggedInUser);
502
-
503
- // Try to log the delete activity
504
- try {
505
- const logData = {
506
- mapped_entity_id: task.mapped_entity_id,
507
- mapped_entity_type: task.mapped_entity_type,
508
- title: `Task deleted`,
509
- description: `${task.name} was deleted`,
510
- category: ACTIVITY_CATEGORIES.TASK,
511
- action: 'delete',
512
- appcode: loggedInUser.appcode,
513
- };
514
-
515
- await this.activityLogService.logActivity(logData, loggedInUser);
516
- } catch (error) {
517
- console.error(
518
- 'Failed to log activity for task deletion:',
519
- error?.message || error,
520
- );
521
- }
522
-
523
- return { message: 'Task deleted successfully' };
524
- }
525
-
526
- async createSystemNote(
527
- entity: {
528
- reason_code: string | number;
529
- remark: string;
530
- mapped_entity_id: number;
531
- stage_id: number;
532
- action_id: number;
533
- stage_group_id?: number;
534
- },
535
- loggedInUser: any,
536
- ) {
537
- if (!entity || !entity.mapped_entity_id || !entity.reason_code) return null;
538
-
539
- const [reason] = await this.dataSource.query(
540
- `SELECT name FROM frm_list_master_items WHERE id = $1 AND organization_id = $2`,
541
- [entity.reason_code, loggedInUser.organization_id],
542
- );
543
-
544
- const notePayload = {
545
- note_title: reason ? reason.name : entity.reason_code,
546
- note: entity.remark,
547
- is_system: true,
548
- mapped_entity_type: 'LEAD',
549
- entity_type: 'NOTE',
550
- mapped_entity_id: entity.mapped_entity_id,
551
- stage_id: entity.stage_id,
552
- action_id: entity.action_id,
553
- stage_group_id: entity.stage_group_id,
554
- } as any;
555
-
556
- return await super.createEntity(notePayload, loggedInUser);
557
- }
558
- }
1
+ import { Inject, Injectable } from '@nestjs/common';
2
+ import { EntityServiceImpl } from 'src/module/meta/service/entity-service-impl.service';
3
+ import { UserData } from 'src/module/user/entity/user.entity';
4
+ import { TaskRepository } from '../repository/task.repository';
5
+ import { ActionDataService } from './action-data.service';
6
+ import { DataSource, EntityManager } from 'typeorm';
7
+ import { ActivityLogService } from './activity-log.service';
8
+ import { ACTIVITY_CATEGORIES } from '../repository/activity-log.repository';
9
+ import { MediaDataService } from 'src/module/meta/service/media-data.service';
10
+ import { ActionHandler } from 'src/module/workflow-automation/interface/action.decorator';
11
+ import * as moment from 'moment';
12
+ import { ConfigService } from '@nestjs/config';
13
+ import axios from 'axios';
14
+ import { ChecksumAlgorithm } from '@aws-sdk/client-s3';
15
+
16
+ @Injectable()
17
+ @ActionHandler('add_task')
18
+ export class TaskService extends EntityServiceImpl {
19
+ constructor(
20
+ private readonly taskRepository: TaskRepository,
21
+ private readonly actionDataService: ActionDataService,
22
+ private readonly dataSource: DataSource,
23
+ @Inject('ActivityLogService')
24
+ private readonly activityLogService: ActivityLogService,
25
+ private readonly mediaDataService: MediaDataService,
26
+ private readonly configService: ConfigService,
27
+ ) {
28
+ super();
29
+ }
30
+ name: string = 'add_task';
31
+
32
+ async execute(payload: any): Promise<any> {
33
+ let { entity, user, config } = payload;
34
+
35
+ const { organization_id, level_id, level_type } = entity;
36
+
37
+ if (entity.entity_type !== 'LEAD') {
38
+ entity = await this.getEntityData('LEAD', entity.parent_id, user);
39
+ }
40
+
41
+ // 3. Build entityData
42
+ const entityData = {
43
+ mapped_entity_id: entity.id,
44
+ mapped_entity_type: entity.entity_type,
45
+ task_owner: entity.lead_owner,
46
+ stage_id: entity.stageId,
47
+ status: config.status,
48
+ due_date: Date.now() + 2,
49
+ due_time: Date.now(),
50
+ description: config.description,
51
+ is_mandatory: config.is_mandatory,
52
+ name: config.name,
53
+ entity_type: 'TASK',
54
+ };
55
+
56
+ return await this.createEntity(entityData, user);
57
+ }
58
+
59
+ async createEntity(
60
+ entityData: any,
61
+ loggedInUser: any,
62
+ manager?: EntityManager | null,
63
+ appcode?: string,
64
+ ): Promise<any> {
65
+ if (entityData && typeof entityData['is_mandatory'] === 'string') {
66
+ entityData['is_mandatory'] = entityData['is_mandatory'] === '1';
67
+ }
68
+
69
+ // handling the date string for due_date and reminder_date
70
+ if (entityData?.due_date) {
71
+ // Interpret input 'YYYY-MM-DD' as local midnight (IST)
72
+ entityData.due_date = moment(entityData.due_date, 'YYYY-MM-DD')
73
+ .startOf('day') // 00:00 local time
74
+ .toDate(); // Convert to JS Date object for TypeORM
75
+ }
76
+
77
+ if (entityData?.reminder_date) {
78
+ entityData.reminder_date = moment(entityData.reminder_date, 'YYYY-MM-DD')
79
+ .startOf('day')
80
+ .toDate();
81
+ }
82
+
83
+ const createdEntity = await super.createEntity(
84
+ entityData,
85
+ loggedInUser,
86
+ manager,
87
+ appcode,
88
+ );
89
+
90
+ try {
91
+ const logData = {
92
+ mapped_entity_id: createdEntity.mapped_entity_id,
93
+ mapped_entity_type: createdEntity.mapped_entity_type,
94
+ title: `Task added`,
95
+ description: `A new task ${createdEntity.name} was added`,
96
+ category: ACTIVITY_CATEGORIES.TASK,
97
+ action: 'add',
98
+ appcode: loggedInUser.appcode,
99
+ };
100
+
101
+ await this.activityLogService.logActivity(logData, loggedInUser);
102
+ } catch (error) {
103
+ console.error(
104
+ 'Failed to log activity for meeting:',
105
+ error?.message || error,
106
+ );
107
+ // Logging should not block main flow
108
+ }
109
+
110
+ let relationData = await this.dataSource.query(
111
+ `SELECT * FROM frm_entity_relation WHERE source_entity_type = $1 AND target_entity_type = $2`,
112
+ [createdEntity.mapped_entity_type, createdEntity.entity_type],
113
+ );
114
+
115
+ if (relationData) {
116
+ await this.dataSource.query(
117
+ `INSERT INTO frm_entity_relation_data (organization_id, source_entity_id, source_entity_type, target_entity_id, target_entity_type, relation_type) VALUES ($1, $2, $3, $4, $5 , $6)`,
118
+ [
119
+ loggedInUser.organization_id,
120
+ createdEntity.mapped_entity_id,
121
+ createdEntity.mapped_entity_type,
122
+ createdEntity.id,
123
+ createdEntity.entity_type,
124
+ relationData[0]?.relation_type,
125
+ ],
126
+ );
127
+ }
128
+
129
+ return createdEntity;
130
+ }
131
+
132
+ async updateEntity(
133
+ entityData,
134
+ loggedInUser: UserData,
135
+ appcode?: string,
136
+ ): Promise<any> {
137
+ const taskStatusQuery = `
138
+ SELECT name
139
+ FROM frm_list_master_items
140
+ WHERE id = $1
141
+ AND organization_id = $2
142
+ AND listtype = 'TKST'
143
+ LIMIT 1;
144
+ `;
145
+
146
+ const statusRows = await this.dataSource.query(taskStatusQuery, [
147
+ entityData.status,
148
+ loggedInUser.organization_id,
149
+ ]);
150
+
151
+ const oldStatusQuery = `
152
+ SELECT *
153
+ FROM frm_wf_task_data
154
+ WHERE id = $1
155
+ AND organization_id = $2
156
+ LIMIT 1;
157
+ `;
158
+
159
+ const [oldRow] = await this.dataSource.query(oldStatusQuery, [
160
+ entityData.id,
161
+ loggedInUser.organization_id,
162
+ ]);
163
+
164
+ const oldStatusRows = await this.dataSource.query(taskStatusQuery, [
165
+ oldRow.status,
166
+ loggedInUser.organization_id,
167
+ ]);
168
+
169
+ const isStatusChanged =
170
+ statusRows.length > 0 &&
171
+ oldStatusRows.length > 0 &&
172
+ statusRows[0].name !== oldStatusRows[0].name;
173
+
174
+ const isCompletedStatus =
175
+ statusRows.length > 0 &&
176
+ statusRows[0].name?.toLowerCase() === 'completed';
177
+
178
+ // Sync flags based on status
179
+ entityData.is_completed = isCompletedStatus;
180
+ entityData.is_done = isCompletedStatus;
181
+
182
+ const isMandatory =
183
+ String(entityData.is_mandatory).toLowerCase() === 'true' ||
184
+ entityData.is_mandatory === true ||
185
+ entityData.is_mandatory === 1 ||
186
+ entityData.is_mandatory === '1';
187
+
188
+ const updatedEntity = await super.updateEntity(
189
+ {
190
+ ...entityData,
191
+ is_mandatory: isMandatory,
192
+ },
193
+ loggedInUser,
194
+ appcode,
195
+ );
196
+
197
+ // Convert boolean back to "1" / "0" for response
198
+ if (updatedEntity && typeof updatedEntity['is_mandatory'] === 'boolean') {
199
+ updatedEntity['is_mandatory'] = updatedEntity['is_mandatory'] ? '1' : '0';
200
+ }
201
+
202
+ try {
203
+ if (isCompletedStatus && isStatusChanged) {
204
+ const completedLogData = {
205
+ mapped_entity_id: updatedEntity.mapped_entity_id,
206
+ mapped_entity_type: updatedEntity.mapped_entity_type,
207
+ title: `Task completed`,
208
+ description: `${updatedEntity.code} was marked as completed`,
209
+ category: ACTIVITY_CATEGORIES.TASK,
210
+ action: 'completed',
211
+ appcode: loggedInUser.appcode,
212
+ };
213
+
214
+ await this.activityLogService.logActivity(
215
+ completedLogData,
216
+ loggedInUser,
217
+ );
218
+ } else {
219
+ const editLogData = {
220
+ mapped_entity_id: updatedEntity.mapped_entity_id,
221
+ mapped_entity_type: updatedEntity.mapped_entity_type,
222
+ title: `Task edited`,
223
+ description: `${updatedEntity.code} was edited`,
224
+ category: ACTIVITY_CATEGORIES.TASK,
225
+ action: 'edit',
226
+ appcode: loggedInUser.appcode,
227
+ };
228
+
229
+ await this.activityLogService.logActivity(editLogData, loggedInUser);
230
+ }
231
+ } catch (error) {
232
+ console.error(
233
+ 'Failed to log activity for task:',
234
+ error?.message || error,
235
+ );
236
+ // Don't block main flow
237
+ }
238
+
239
+ return updatedEntity;
240
+ }
241
+
242
+ async getAllTaskByUserIdandStageId(
243
+ loggedInUser: UserData,
244
+ data,
245
+ ): Promise<any> {
246
+ const taskData = await this.taskRepository.getAllTaskByUserIdAndStageId({
247
+ user_id: data.user_id,
248
+ stage_id: data.stage_id,
249
+ mapped_entity_type: data.mapped_entity_type,
250
+ mapped_entity_id: data.mapped_entity_id,
251
+ });
252
+
253
+ const grouped: { mandatory: any[]; non_mandatory: any[] } = {
254
+ mandatory: [],
255
+ non_mandatory: [],
256
+ };
257
+
258
+ for (const task of taskData) {
259
+ if (task && task.is_mandatory) {
260
+ grouped.mandatory.push(task);
261
+ } else {
262
+ grouped.non_mandatory.push(task);
263
+ }
264
+ }
265
+
266
+ return grouped;
267
+ }
268
+
269
+ async getAllTask(
270
+ loggedInUser: UserData,
271
+ data: {
272
+ mapped_entity_type: string;
273
+ mapped_entity_id: number;
274
+ status?: string;
275
+ mandatory?: boolean;
276
+ overdue?: boolean;
277
+ },
278
+ ): Promise<any[]> {
279
+ const { mapped_entity_type, mapped_entity_id, status, mandatory, overdue } =
280
+ data;
281
+
282
+ const whereClauses: string[] = [];
283
+ const params: any[] = [];
284
+ let idx = 1;
285
+
286
+ // Required filters
287
+ whereClauses.push(`t.mapped_entity_type = $${idx++}`);
288
+ params.push(mapped_entity_type);
289
+
290
+ whereClauses.push(`t.mapped_entity_id::text = $${idx++}`);
291
+ params.push(String(mapped_entity_id));
292
+
293
+ // Optional: status (stored as varchar)
294
+ if (status) {
295
+ whereClauses.push(`t.status::text = $${idx++}`);
296
+ params.push(String(status));
297
+ }
298
+
299
+ // Optional: mandatory (stored as varchar '0' / '1')
300
+ if (mandatory !== undefined) {
301
+ whereClauses.push(`t.is_mandatory::text = $${idx++}`);
302
+ params.push(mandatory ? "1" : "0");
303
+ }
304
+
305
+ // Optional: overdue
306
+ if (overdue) {
307
+ whereClauses.push(`
308
+ (
309
+ t.due_date < CURRENT_DATE
310
+ OR (t.due_date = CURRENT_DATE AND t.due_time < CURRENT_TIME)
311
+ )
312
+ `);
313
+
314
+ // Only include tasks NOT done
315
+ whereClauses.push(`t.is_done::text = $${idx++}`);
316
+ params.push("0"); // varchar field
317
+ }
318
+
319
+ // Final SQL
320
+ const sql = `
321
+ SELECT
322
+ t.*,
323
+ sg.name AS stage_group_name,
324
+ s.name AS stage_name,
325
+ a.name AS action_name
326
+ FROM frm_wf_task_data t
327
+ LEFT JOIN frm_wf_stage s ON t.stage_id::text = s.id::text
328
+ LEFT JOIN frm_wf_stage_group sg ON s.stage_group_id = sg.id
329
+ LEFT JOIN frm_wf_action a ON t.action_id::text = a.id::text
330
+ WHERE ${whereClauses.join(" AND ")}
331
+ ORDER BY t.created_date DESC
332
+ `;
333
+
334
+ const taskData = await this.dataSource.query(sql, params);
335
+
336
+ // -------------------------------
337
+ // PROFILE IMAGE MAPPING
338
+ // -------------------------------
339
+ if (taskData?.length) {
340
+ for (const task of taskData) {
341
+ try {
342
+ const baseUrl =
343
+ this.configService.get<string>("REDIRECT_BE_URL");
344
+
345
+ const queryParams = new URLSearchParams({
346
+ loggedInUser: JSON.stringify(loggedInUser),
347
+ }).toString();
348
+
349
+ const response = await axios.get(
350
+ `${baseUrl}/users/profile-image-url/${task.task_owner}?entity_type=USR&${queryParams}`,
351
+ { headers: { "Content-Type": "application/json" } },
352
+ );
353
+
354
+ task.created_by_name = response.data.name;
355
+ task.task_owner_name = response.data.name;
356
+ task.task_owner_profile = response.data.profile_image;
357
+ } catch (err) {
358
+ console.error("⚠ Error fetching profile:", err.message);
359
+ }
360
+ }
361
+ }
362
+
363
+ if (!taskData.length) return [];
364
+
365
+ // -------------------------------
366
+ // FETCH TKST STATUS LABELS
367
+ // -------------------------------
368
+ const statusSql = `
369
+ SELECT id, name
370
+ FROM frm_list_master_items
371
+ WHERE organization_id = $1
372
+ AND listtype = 'TKST'
373
+ `;
374
+
375
+ const allStatuses = await this.dataSource.query(statusSql, [
376
+ loggedInUser.organization_id,
377
+ ]);
378
+
379
+ const statusMap = new Map(
380
+ allStatuses.map((row) => [String(row.id), row.name]),
381
+ );
382
+
383
+ // -------------------------------
384
+ // FINAL MAPPING
385
+ // -------------------------------
386
+ return taskData.map((task) => ({
387
+ ...task,
388
+ task_status: statusMap.get(String(task.status)) || null,
389
+ action_name:
390
+ task.action_id === "0" || task.action_id === 0
391
+ ? "Generic"
392
+ : task.action_name,
393
+ is_mandatory: task.is_mandatory === "1" ? "1" : "0",
394
+ }));
395
+ }
396
+
397
+ async getEntityData(entityType: string, id: number, loggedInUser: any) {
398
+ const taskData = await super.getEntityData(entityType, id, loggedInUser);
399
+
400
+ if (taskData?.due_date) {
401
+ taskData.due_date = moment(taskData.due_date)
402
+ .local() // convert from UTC to local
403
+ .format('YYYY-MM-DD'); // return just the date string
404
+ }
405
+
406
+ if (taskData?.reminder_date) {
407
+ taskData.reminder_date = moment(taskData.reminder_date)
408
+ .local()
409
+ .format('YYYY-MM-DD');
410
+ }
411
+
412
+ return taskData;
413
+ }
414
+
415
+ async saveActionData(
416
+ action: any,
417
+ loggedInUser: UserData,
418
+ mapped_entity_id: number,
419
+ mapped_entity_type: string,
420
+ ): Promise<any> {
421
+ await this.taskRepository.saveActionDataInTask(
422
+ action,
423
+ loggedInUser,
424
+ mapped_entity_id,
425
+ mapped_entity_type,
426
+ );
427
+ }
428
+
429
+ async moveTask(
430
+ loggedInUser: UserData,
431
+ body: {
432
+ mapped_entity_type: string;
433
+ mapped_entity_id: number;
434
+ stage_id: number;
435
+ action_id: number;
436
+ reason_code?: string | number;
437
+ remark?: string;
438
+ stage_group_id?: number;
439
+ },
440
+ ): Promise<any> {
441
+ // Logic to move task based on the provided body parameters
442
+ // This could involve updating the task's stage, action, etc.
443
+
444
+ // update task status
445
+ this.taskRepository.updateTaskStatus(
446
+ loggedInUser,
447
+ body.mapped_entity_type,
448
+ body.mapped_entity_id,
449
+ body.stage_id,
450
+ body.action_id,
451
+ );
452
+
453
+ // update action status
454
+ await this.actionDataService.updateActionStatus(
455
+ loggedInUser,
456
+ body.mapped_entity_type,
457
+ body.mapped_entity_id,
458
+ body.stage_id,
459
+ body.action_id,
460
+ );
461
+
462
+ if (body.reason_code || body.remark) {
463
+ await this.createSystemNote(
464
+ {
465
+ reason_code: body.reason_code!,
466
+ remark: body.remark || '',
467
+ mapped_entity_id: body.mapped_entity_id,
468
+ stage_id: body.stage_id,
469
+ action_id: body.action_id,
470
+ stage_group_id: body.stage_group_id,
471
+ },
472
+ loggedInUser,
473
+ );
474
+ }
475
+
476
+ return 'Task moved successfully';
477
+ }
478
+
479
+ async deleteEntity(
480
+ entity_type: string,
481
+ taskId: number,
482
+ loggedInUser: UserData,
483
+ ): Promise<any> {
484
+ // Fetch the task before deleting
485
+ const task: any = await super.getEntityData(
486
+ entity_type,
487
+ taskId,
488
+ loggedInUser,
489
+ );
490
+
491
+ if (!task) {
492
+ throw new Error('Task not found');
493
+ }
494
+
495
+ // Check if the task is system-generated
496
+ if (task.is_system) {
497
+ throw new Error('Cannot delete system-generated tasks');
498
+ }
499
+
500
+ // Perform the deletion
501
+ await super.deleteEntity(entity_type, taskId, loggedInUser);
502
+
503
+ // Try to log the delete activity
504
+ try {
505
+ const logData = {
506
+ mapped_entity_id: task.mapped_entity_id,
507
+ mapped_entity_type: task.mapped_entity_type,
508
+ title: `Task deleted`,
509
+ description: `${task.name} was deleted`,
510
+ category: ACTIVITY_CATEGORIES.TASK,
511
+ action: 'delete',
512
+ appcode: loggedInUser.appcode,
513
+ };
514
+
515
+ await this.activityLogService.logActivity(logData, loggedInUser);
516
+ } catch (error) {
517
+ console.error(
518
+ 'Failed to log activity for task deletion:',
519
+ error?.message || error,
520
+ );
521
+ }
522
+
523
+ return { message: 'Task deleted successfully' };
524
+ }
525
+
526
+ async createSystemNote(
527
+ entity: {
528
+ reason_code: string | number;
529
+ remark: string;
530
+ mapped_entity_id: number;
531
+ stage_id: number;
532
+ action_id: number;
533
+ stage_group_id?: number;
534
+ },
535
+ loggedInUser: any,
536
+ ) {
537
+ if (!entity || !entity.mapped_entity_id || !entity.reason_code) return null;
538
+
539
+ const [reason] = await this.dataSource.query(
540
+ `SELECT name FROM frm_list_master_items WHERE id = $1 AND organization_id = $2`,
541
+ [entity.reason_code, loggedInUser.organization_id],
542
+ );
543
+
544
+ const notePayload = {
545
+ note_title: reason ? reason.name : entity.reason_code,
546
+ note: entity.remark,
547
+ is_system: true,
548
+ mapped_entity_type: 'LEAD',
549
+ entity_type: 'NOTE',
550
+ mapped_entity_id: entity.mapped_entity_id,
551
+ stage_id: entity.stage_id,
552
+ action_id: entity.action_id,
553
+ stage_group_id: entity.stage_group_id,
554
+ } as any;
555
+
556
+ return await super.createEntity(notePayload, loggedInUser);
557
+ }
558
+ }