rez_core 5.0.182 → 6.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +26 -0
- package/.idea/250218_nodejs_core.iml +8 -11
- package/.idea/codeStyles/Project.xml +58 -58
- package/.idea/codeStyles/codeStyleConfig.xml +4 -4
- package/.idea/copilot.data.migration.agent.xml +6 -0
- package/.idea/copilot.data.migration.ask.xml +6 -0
- package/.idea/copilot.data.migration.ask2agent.xml +6 -0
- package/.idea/copilot.data.migration.edit.xml +6 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +7 -7
- package/.idea/prettier.xml +6 -0
- package/.idea/vcs.xml +5 -5
- package/.prettierrc +3 -3
- package/README.md +99 -99
- package/dist/module/auth/guards/role.guard.js +3 -3
- package/dist/module/enterprise/controller/enterprise.controller.d.ts +12 -0
- package/dist/module/enterprise/controller/enterprise.controller.js +57 -0
- package/dist/module/enterprise/controller/enterprise.controller.js.map +1 -0
- package/dist/module/enterprise/controller/organization.controller.d.ts +11 -1
- package/dist/module/enterprise/controller/organization.controller.js +62 -2
- package/dist/module/enterprise/controller/organization.controller.js.map +1 -1
- package/dist/module/enterprise/enterprise.module.js +2 -1
- package/dist/module/enterprise/enterprise.module.js.map +1 -1
- package/dist/module/enterprise/entity/enterprise.entity.d.ts +1 -3
- package/dist/module/enterprise/entity/enterprise.entity.js +4 -12
- package/dist/module/enterprise/entity/enterprise.entity.js.map +1 -1
- package/dist/module/enterprise/entity/organization-app-mapping.entity.d.ts +4 -2
- package/dist/module/enterprise/entity/organization-app-mapping.entity.js +12 -7
- package/dist/module/enterprise/entity/organization-app-mapping.entity.js.map +1 -1
- package/dist/module/enterprise/entity/organization.entity.d.ts +1 -17
- package/dist/module/enterprise/entity/organization.entity.js +4 -72
- package/dist/module/enterprise/entity/organization.entity.js.map +1 -1
- package/dist/module/enterprise/repository/enterprise.repository.d.ts +2 -2
- package/dist/module/enterprise/repository/enterprise.repository.js +9 -4
- package/dist/module/enterprise/repository/enterprise.repository.js.map +1 -1
- package/dist/module/enterprise/service/enterprise.service.d.ts +2 -2
- package/dist/module/enterprise/service/enterprise.service.js +4 -4
- package/dist/module/enterprise/service/enterprise.service.js.map +1 -1
- package/dist/module/enterprise/service/organization.service.d.ts +2 -2
- package/dist/module/enterprise/service/organization.service.js +97 -20
- package/dist/module/enterprise/service/organization.service.js.map +1 -1
- package/dist/module/filter/service/filter.service.js +19 -19
- package/dist/module/integration/examples/usage.example.js +9 -9
- package/dist/module/meta/repository/attribute-master.repository.js +8 -8
- package/dist/module/meta/service/entity-dynamic.service.js +16 -16
- package/dist/module/meta/service/media-data.service.js +6 -6
- package/dist/module/meta/service/resolver.service.js +11 -11
- package/dist/module/module/repository/menu.repository.js +4 -4
- package/dist/module/notification/service/notification.service.js +6 -6
- package/dist/module/user/controller/login.controller.js +18 -18
- package/dist/module/workflow/repository/action.repository.js +2 -2
- package/dist/module/workflow/repository/stage.repository.js +8 -8
- package/dist/module/workflow/service/action-template-mapping.service.js +2 -2
- package/dist/module/workflow/service/action.service.js +5 -5
- package/dist/module/workflow/service/entity-modification.service.js +2 -2
- package/dist/module/workflow/service/task.service.js +8 -8
- package/dist/module/workflow-automation/service/schedule-handler.service.js +9 -9
- package/dist/table.config.d.ts +1 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/service/reflection-helper.service.js +2 -2
- package/docs/modules/event-driven-integration-design.md +91 -91
- package/docs/modules/integration.md +250 -250
- package/eslint.config.mjs +34 -34
- package/nest-cli.json +14 -14
- package/package.json +125 -125
- package/server.log +850 -0
- package/src/app.controller.ts +12 -12
- package/src/app.module.ts +68 -68
- package/src/app.service.ts +8 -8
- package/src/config/bull.config.ts +69 -69
- package/src/config/config.module.ts +17 -17
- package/src/config/database.config.ts +48 -48
- package/src/constant/global.constant.ts +67 -67
- package/src/core.module.ts +94 -94
- package/src/decorators/roles.decorator.ts +7 -7
- package/src/dtos/response.dto.ts +6 -6
- package/src/dtos/response.ts +5 -5
- package/src/index.ts +1 -1
- package/src/module/auth/auth.module.ts +49 -49
- package/src/module/auth/controller/auth.controller.ts +28 -28
- package/src/module/auth/guards/google-auth.guard.ts +9 -9
- package/src/module/auth/guards/jwt.guard.ts +22 -22
- package/src/module/auth/guards/role.guard.ts +68 -68
- package/src/module/auth/services/auth.service.ts +56 -56
- package/src/module/auth/services/jwt.service.ts +11 -11
- package/src/module/auth/strategies/google.strategy.ts +54 -54
- package/src/module/auth/strategies/jwt.strategy.ts +58 -58
- package/src/module/auth/strategies/local.strategy.ts +13 -13
- package/src/module/dashboard/controller/dashboard.controller.ts +38 -38
- package/src/module/dashboard/dashboard.module.ts +21 -21
- package/src/module/dashboard/entity/dashboard_page_data.entity.ts +27 -27
- package/src/module/dashboard/entity/widget_master.entity.ts +18 -18
- package/src/module/dashboard/repository/dashboard.repository.ts +49 -49
- package/src/module/dashboard/service/dashboard.service.ts +72 -72
- package/src/module/enterprise/controller/enterprise.controller.ts +40 -0
- package/src/module/enterprise/controller/organization.controller.ts +93 -36
- package/src/module/enterprise/enterprise.module.ts +46 -45
- package/src/module/enterprise/entity/enterprise.entity.ts +31 -37
- package/src/module/enterprise/entity/organization-app-mapping.entity.ts +18 -13
- package/src/module/enterprise/entity/organization.entity.ts +40 -92
- package/src/module/enterprise/repository/enterprise.repository.ts +39 -31
- package/src/module/enterprise/repository/organization.repository.ts +26 -26
- package/src/module/enterprise/repository/school.repository.ts +272 -272
- package/src/module/enterprise/service/brand.service.ts +5 -5
- package/src/module/enterprise/service/enterprise.service.ts +22 -16
- package/src/module/enterprise/service/organization-app-mapping.service.ts +4 -4
- package/src/module/enterprise/service/organization.service.ts +262 -145
- package/src/module/entity_json/controller/entity_json.controller.ts +47 -47
- package/src/module/entity_json/entity/entityJson.entity.ts +39 -39
- package/src/module/entity_json/entity_json.module.ts +18 -18
- package/src/module/entity_json/service/entityJson.repository.ts +37 -37
- package/src/module/entity_json/service/entity_json.service.ts +241 -241
- package/src/module/export/controller/export.controller.ts +83 -83
- package/src/module/export/export.module.ts +14 -14
- package/src/module/export/service/export.service.ts +105 -105
- package/src/module/filter/controller/filter.controller.ts +87 -87
- package/src/module/filter/dto/filter-request.dto.ts +39 -39
- package/src/module/filter/entity/saved-filter-detail.entity.ts +41 -41
- package/src/module/filter/entity/saved-filter-master.entity.ts +35 -35
- package/src/module/filter/filter.module.ts +33 -33
- package/src/module/filter/repository/saved-filter.repository.ts +247 -247
- package/src/module/filter/repository/saved.filter-detail.repository.ts +19 -19
- package/src/module/filter/service/filter-evaluator.service.ts +82 -82
- package/src/module/filter/service/filter.service.ts +1316 -1316
- package/src/module/filter/service/saved-filter.service.ts +164 -164
- package/src/module/ics/controller/ics.controller.ts +21 -21
- package/src/module/ics/dto/ics.dto.ts +55 -55
- package/src/module/ics/ics.module.ts +13 -13
- package/src/module/ics/service/ics.service.ts +57 -57
- package/src/module/integration/controller/calender-event.controller.ts +31 -31
- package/src/module/integration/controller/integration.controller.ts +662 -662
- package/src/module/integration/controller/wrapper.controller.ts +37 -37
- package/src/module/integration/dto/create-config.dto.ts +526 -526
- package/src/module/integration/entity/integration-config.entity.ts +112 -112
- package/src/module/integration/entity/integration-entity-mapper.entity.ts +14 -14
- package/src/module/integration/entity/integration-source.entity.ts +17 -17
- package/src/module/integration/entity/user-integration.entity.ts +71 -71
- package/src/module/integration/examples/usage.example.ts +338 -338
- package/src/module/integration/factories/base.factory.ts +7 -7
- package/src/module/integration/factories/email.factory.ts +49 -49
- package/src/module/integration/factories/integration.factory.ts +121 -121
- package/src/module/integration/factories/sms.factory.ts +51 -51
- package/src/module/integration/factories/telephone.factory.ts +41 -41
- package/src/module/integration/factories/whatsapp.factory.ts +56 -56
- package/src/module/integration/integration.module.ts +110 -110
- package/src/module/integration/service/calendar-event.service.ts +118 -118
- package/src/module/integration/service/integration-entity-mapper.service.ts +17 -17
- package/src/module/integration/service/integration-queue.service.ts +229 -229
- package/src/module/integration/service/integration.service.ts +2634 -2634
- package/src/module/integration/service/oauth.service.ts +224 -224
- package/src/module/integration/service/wrapper.service.ts +753 -753
- package/src/module/integration/strategies/email/gmail-api.strategy.ts +280 -280
- package/src/module/integration/strategies/email/outlook-api.strategy.ts +44 -44
- package/src/module/integration/strategies/email/outlook.strategy.ts +64 -64
- package/src/module/integration/strategies/email/sendgrid-api.strategy.ts +260 -260
- package/src/module/integration/strategies/integration.strategy.ts +97 -97
- package/src/module/integration/strategies/sms/gupshup-sms.strategy.ts +146 -146
- package/src/module/integration/strategies/sms/msg91-sms.strategy.ts +164 -164
- package/src/module/integration/strategies/sms/tubelight-sms.strategy.ts +163 -163
- package/src/module/integration/strategies/telephone/ozonetel-voice.strategy.ts +238 -238
- package/src/module/integration/strategies/telephone/tubelight-voice.strategy.ts +210 -210
- package/src/module/integration/strategies/whatsapp/gupshup-whatsapp.strategy.ts +359 -359
- package/src/module/integration/strategies/whatsapp/tubelight-whatsapp.strategy.ts +372 -372
- package/src/module/integration/strategies/whatsapp/whatsapp-cloud.strategy.ts +403 -403
- package/src/module/integration/strategies/whatsapp/whatsapp.strategy.ts +57 -57
- package/src/module/layout/controller/layout.controller.ts +47 -47
- package/src/module/layout/entity/header-items.entity.ts +28 -28
- package/src/module/layout/entity/header-section.entity.ts +19 -19
- package/src/module/layout/layout.module.ts +21 -21
- package/src/module/layout/repository/header-items.repository.ts +18 -18
- package/src/module/layout/repository/header-section.repository.ts +22 -22
- package/src/module/layout/service/header-section.service.ts +25 -25
- package/src/module/layout_preference/controller/layout_preference.controller.ts +76 -76
- package/src/module/layout_preference/entity/layout_preference.entity.ts +28 -28
- package/src/module/layout_preference/layout_preference.module.ts +22 -22
- package/src/module/layout_preference/repository/layout_preference.repository.ts +65 -65
- package/src/module/layout_preference/service/layout_preference.service.ts +191 -191
- package/src/module/lead/controller/lead.controller.ts +30 -30
- package/src/module/lead/lead.module.ts +14 -14
- package/src/module/lead/repository/lead.repository.ts +41 -41
- package/src/module/lead/service/lead.service.ts +54 -54
- package/src/module/linked_attributes/controller/linked_attributes.controller.ts +37 -37
- package/src/module/linked_attributes/entity/linked_attribute.entity.ts +51 -51
- package/src/module/linked_attributes/linked_attributes.module.ts +16 -16
- package/src/module/linked_attributes/repository/linked_attribute.repository.ts +12 -12
- package/src/module/linked_attributes/service/linked_attributes.service.ts +73 -73
- package/src/module/listmaster/controller/list-master.controller.ts +230 -230
- package/src/module/listmaster/entity/list-master-items.entity.ts +43 -43
- package/src/module/listmaster/entity/list-master.entity.ts +33 -33
- package/src/module/listmaster/listmaster.module.ts +46 -46
- package/src/module/listmaster/repository/list-master-items.repository.ts +173 -173
- package/src/module/listmaster/repository/list-master.repository.ts +56 -56
- package/src/module/listmaster/service/list-master-engine.ts +19 -19
- package/src/module/listmaster/service/list-master-extension.interface.ts +4 -4
- package/src/module/listmaster/service/list-master-item.service.ts +280 -280
- package/src/module/listmaster/service/list-master-registry.ts +15 -15
- package/src/module/listmaster/service/list-master.service.ts +527 -527
- package/src/module/mapper/controller/field-mapper.controller.ts +76 -76
- package/src/module/mapper/controller/mapper.controller.ts +20 -20
- package/src/module/mapper/dto/field-mapper.dto.ts +14 -14
- package/src/module/mapper/entity/field-lovs.entity.ts +19 -19
- package/src/module/mapper/entity/field-mapper.entity.ts +53 -53
- package/src/module/mapper/entity/mapper.entity.ts +16 -16
- package/src/module/mapper/mapper.module.ts +35 -35
- package/src/module/mapper/repository/field-lovs.repository.ts +35 -35
- package/src/module/mapper/repository/field-mapper.repository.ts +42 -42
- package/src/module/mapper/repository/mapper.repository.ts +32 -32
- package/src/module/mapper/service/field-mapper.service.ts +269 -269
- package/src/module/mapper/service/mapper.service.ts +80 -80
- package/src/module/master/controller/master.controller.ts +74 -74
- package/src/module/master/service/master.service.ts +484 -484
- package/src/module/meta/controller/app-master.controller.ts +38 -38
- package/src/module/meta/controller/attribute-master.controller.ts +84 -84
- package/src/module/meta/controller/entity-dynamic.controller.ts +125 -125
- package/src/module/meta/controller/entity-master.controller.ts +41 -41
- package/src/module/meta/controller/entity-relation.controller.ts +36 -36
- package/src/module/meta/controller/entity.controller.ts +308 -308
- package/src/module/meta/controller/entity.public.controller.ts +75 -75
- package/src/module/meta/controller/media.controller.ts +135 -135
- package/src/module/meta/controller/meta.controller.ts +101 -101
- package/src/module/meta/controller/view-master.controller.ts +79 -79
- package/src/module/meta/dto/entity-list-data.dto.ts +6 -6
- package/src/module/meta/dto/entity-tab.dto.ts +4 -4
- package/src/module/meta/dto/entity-table.dto.ts +12 -12
- package/src/module/meta/entity/app-master.entity.ts +37 -37
- package/src/module/meta/entity/attribute-master.entity.ts +92 -92
- package/src/module/meta/entity/base-entity.entity.ts +75 -75
- package/src/module/meta/entity/entity-master.entity.ts +85 -85
- package/src/module/meta/entity/entity-relation-data.entity.ts +29 -29
- package/src/module/meta/entity/entity-relation.entity.ts +23 -23
- package/src/module/meta/entity/entity-table-column.entity.ts +61 -61
- package/src/module/meta/entity/entity-table.entity.ts +50 -50
- package/src/module/meta/entity/media-data.entity.ts +32 -32
- package/src/module/meta/entity/preference.entity.ts +62 -62
- package/src/module/meta/entity/view-master.entity.ts +41 -41
- package/src/module/meta/entity.module.ts +165 -165
- package/src/module/meta/repository/app-master.repository.ts +20 -20
- package/src/module/meta/repository/attribute-master.repository.ts +164 -164
- package/src/module/meta/repository/entity-attribute-update.repository.ts +48 -48
- package/src/module/meta/repository/entity-master.repository.ts +120 -120
- package/src/module/meta/repository/entity-relation.repository.ts +22 -22
- package/src/module/meta/repository/entity-table-column.repository.ts +39 -39
- package/src/module/meta/repository/entity-table.repository.ts +53 -53
- package/src/module/meta/repository/media-data.repository.ts +50 -50
- package/src/module/meta/repository/preference.repository.ts +20 -20
- package/src/module/meta/repository/user-app-mapping.repository.ts +28 -28
- package/src/module/meta/repository/view-master.repository.ts +42 -42
- package/src/module/meta/service/app-master.service.ts +37 -37
- package/src/module/meta/service/attribute-master.service.ts +132 -132
- package/src/module/meta/service/common.service.ts +9 -9
- package/src/module/meta/service/entity-attribute-update.service.ts +26 -26
- package/src/module/meta/service/entity-dynamic.service.ts +824 -824
- package/src/module/meta/service/entity-master.service.ts +171 -171
- package/src/module/meta/service/entity-realation-data.service.ts +9 -9
- package/src/module/meta/service/entity-relation.service.ts +74 -74
- package/src/module/meta/service/entity-service-impl.service.ts +388 -388
- package/src/module/meta/service/entity-table-column.service.ts +26 -26
- package/src/module/meta/service/entity-table.service.ts +157 -157
- package/src/module/meta/service/entity-validation.service.ts +188 -188
- package/src/module/meta/service/entity.service.ts +49 -49
- package/src/module/meta/service/field-group.service.ts +103 -103
- package/src/module/meta/service/media-data.service.ts +591 -591
- package/src/module/meta/service/populate-meta.service.ts +222 -222
- package/src/module/meta/service/preference.service.ts +16 -16
- package/src/module/meta/service/resolver.service.ts +280 -280
- package/src/module/meta/service/section-master.service.ts +104 -104
- package/src/module/meta/service/update-form-json.service.ts +22 -22
- package/src/module/meta/service/user-app-mapping.service.ts +17 -17
- package/src/module/meta/service/view-master.service.ts +127 -127
- package/src/module/microservice-client/microservice-clients.module.ts +13 -13
- package/src/module/microservice-client/service/microservice-client-factory.ts +37 -37
- package/src/module/microservice-client/service/microservice-clients.ts +4 -4
- package/src/module/module/controller/menu.controller.ts +15 -15
- package/src/module/module/controller/module-access.controller.ts +133 -133
- package/src/module/module/entity/menu.entity.ts +43 -43
- package/src/module/module/entity/module-access.entity.ts +25 -25
- package/src/module/module/entity/module-action.entity.ts +17 -17
- package/src/module/module/entity/module.entity.ts +52 -52
- package/src/module/module/module.module.ts +42 -42
- package/src/module/module/repository/menu.repository.ts +186 -186
- package/src/module/module/repository/module-access.repository.ts +344 -344
- package/src/module/module/service/menu.service.ts +82 -82
- package/src/module/module/service/module-access.service.ts +189 -189
- package/src/module/notification/controller/notification.controller.ts +58 -58
- package/src/module/notification/controller/otp.controller.ts +117 -117
- package/src/module/notification/entity/notification.entity.ts +26 -26
- package/src/module/notification/entity/otp.entity.ts +28 -28
- package/src/module/notification/firebase-admin.config.ts +22 -22
- package/src/module/notification/notification.module.ts +69 -69
- package/src/module/notification/repository/otp.repository.ts +27 -27
- package/src/module/notification/service/email.service.ts +127 -127
- package/src/module/notification/service/notification.service.ts +164 -164
- package/src/module/notification/service/otp.service.ts +133 -133
- package/src/module/third-party-module/entity/third-party-api-registry.entity.ts +52 -52
- package/src/module/third-party-module/repository/third-party-api-registry.repository.ts +20 -20
- package/src/module/third-party-module/service/api-registry.service.ts +13 -13
- package/src/module/third-party-module/third-party.module.ts +12 -12
- package/src/module/user/controller/login.controller.ts +198 -198
- package/src/module/user/controller/user.controller.ts +40 -40
- package/src/module/user/dto/create-user.dto.ts +62 -62
- package/src/module/user/dto/update-user.dto.ts +4 -4
- package/src/module/user/entity/role.entity.ts +33 -33
- package/src/module/user/entity/user-role-mapping.entity.ts +38 -38
- package/src/module/user/entity/user-session.entity.ts +73 -73
- package/src/module/user/entity/user.entity.ts +62 -62
- package/src/module/user/repository/role.repository.ts +96 -96
- package/src/module/user/repository/user-role-mapping.repository.ts +126 -126
- package/src/module/user/repository/user.repository.ts +50 -50
- package/src/module/user/repository/userSession.repository.ts +33 -33
- package/src/module/user/service/login.service.ts +326 -326
- package/src/module/user/service/role.service.ts +197 -197
- package/src/module/user/service/user-role-mapping.service.ts +98 -98
- package/src/module/user/service/user-session.service.ts +200 -200
- package/src/module/user/service/user.service.ts +368 -368
- package/src/module/user/user.module.ts +65 -65
- package/src/module/workflow/controller/action-category.controller.ts +54 -54
- package/src/module/workflow/controller/action-resource-mapping.controller.ts +23 -23
- package/src/module/workflow/controller/action-template-mapping.controller.ts +35 -35
- package/src/module/workflow/controller/action.controller.ts +111 -111
- package/src/module/workflow/controller/activity-log.controller.ts +55 -55
- package/src/module/workflow/controller/comm-template.controller.ts +43 -43
- package/src/module/workflow/controller/entity-modification.controller.ts +35 -35
- package/src/module/workflow/controller/form-master.controller.ts +43 -43
- package/src/module/workflow/controller/stage-group.controller.ts +49 -49
- package/src/module/workflow/controller/stage.controller.ts +51 -51
- package/src/module/workflow/controller/task.controller.ts +77 -77
- package/src/module/workflow/controller/workflow-list-master.controller.ts +44 -44
- package/src/module/workflow/controller/workflow-meta.controller.ts +80 -80
- package/src/module/workflow/controller/workflow.controller.ts +67 -67
- package/src/module/workflow/entity/action-category.entity.ts +38 -38
- package/src/module/workflow/entity/action-data.entity.ts +55 -55
- package/src/module/workflow/entity/action-resources-mapping.entity.ts +29 -29
- package/src/module/workflow/entity/action-template-mapping.entity.ts +17 -17
- package/src/module/workflow/entity/action.entity.ts +53 -53
- package/src/module/workflow/entity/activity-log.entity.ts +43 -43
- package/src/module/workflow/entity/comm-template.entity.ts +43 -43
- package/src/module/workflow/entity/entity-modification.entity.ts +38 -38
- package/src/module/workflow/entity/form.entity.ts +25 -25
- package/src/module/workflow/entity/stage-action-mapping.entity.ts +17 -17
- package/src/module/workflow/entity/stage-group.entity.ts +23 -23
- package/src/module/workflow/entity/stage-movement-data.entity.ts +38 -38
- package/src/module/workflow/entity/stage.entity.ts +20 -20
- package/src/module/workflow/entity/task-data.entity.ts +88 -88
- package/src/module/workflow/entity/template-attach-mapper.entity.ts +30 -30
- package/src/module/workflow/entity/workflow-data.entity.ts +11 -11
- package/src/module/workflow/entity/workflow-level-mapping.entity.ts +18 -18
- package/src/module/workflow/entity/workflow.entity.ts +20 -20
- package/src/module/workflow/repository/action-category.repository.ts +79 -79
- package/src/module/workflow/repository/action-data.repository.ts +347 -347
- package/src/module/workflow/repository/action.repository.ts +339 -339
- package/src/module/workflow/repository/activity-log.repository.ts +148 -148
- package/src/module/workflow/repository/comm-template.repository.ts +157 -157
- package/src/module/workflow/repository/form-master.repository.ts +50 -50
- package/src/module/workflow/repository/stage-group.repository.ts +186 -186
- package/src/module/workflow/repository/stage-movement.repository.ts +217 -217
- package/src/module/workflow/repository/stage.repository.ts +160 -160
- package/src/module/workflow/repository/task.repository.ts +154 -154
- package/src/module/workflow/repository/workflow.repository.ts +42 -42
- package/src/module/workflow/service/action-category.service.ts +33 -33
- package/src/module/workflow/service/action-data.service.ts +62 -62
- package/src/module/workflow/service/action-resources-mapping.service.ts +10 -10
- package/src/module/workflow/service/action-template-mapping.service.ts +137 -137
- package/src/module/workflow/service/action.service.ts +302 -302
- package/src/module/workflow/service/activity-log.service.ts +107 -107
- package/src/module/workflow/service/comm-template.service.ts +181 -181
- package/src/module/workflow/service/entity-modification.service.ts +61 -61
- package/src/module/workflow/service/form-master.service.ts +35 -35
- package/src/module/workflow/service/populate-workflow.service.ts +320 -320
- package/src/module/workflow/service/stage-action-mapping.service.ts +5 -5
- package/src/module/workflow/service/stage-group.service.ts +325 -325
- package/src/module/workflow/service/stage.service.ts +197 -197
- package/src/module/workflow/service/task.service.ts +551 -551
- package/src/module/workflow/service/workflow-list-master.service.ts +68 -68
- package/src/module/workflow/service/workflow-meta.service.ts +640 -640
- package/src/module/workflow/service/workflow.service.ts +213 -213
- package/src/module/workflow/workflow.module.ts +180 -180
- package/src/module/workflow-automation/SCHEDULING_GUIDE.md +145 -145
- package/src/module/workflow-automation/controller/workflow-automation.controller.ts +43 -43
- package/src/module/workflow-automation/entity/workflow-automation-action.entity.ts +26 -26
- package/src/module/workflow-automation/entity/workflow-automation.entity.ts +40 -40
- package/src/module/workflow-automation/interface/action.decorator.ts +7 -7
- package/src/module/workflow-automation/interface/action.interface.ts +5 -5
- package/src/module/workflow-automation/service/action-registery.service.ts +35 -35
- package/src/module/workflow-automation/service/schedule-handler.service.ts +168 -168
- package/src/module/workflow-automation/service/workflow-automation-engine.service.ts +219 -219
- package/src/module/workflow-automation/service/workflow-automation.service.ts +476 -476
- package/src/module/workflow-automation/workflow-automation.module.ts +54 -54
- package/src/module/workflow-schedule/INSTALLATION.md +244 -244
- package/src/module/workflow-schedule/MULTI_PROJECT_GUIDE.md +196 -196
- package/src/module/workflow-schedule/README.md +422 -422
- package/src/module/workflow-schedule/constants/schedule.constants.ts +48 -48
- package/src/module/workflow-schedule/controller/workflow-schedule.controller.ts +253 -253
- package/src/module/workflow-schedule/docs/CLAUDE_CODE_GUIDE.md +510 -510
- package/src/module/workflow-schedule/docs/CLAUDE_CODE_PROMPT.md +362 -362
- package/src/module/workflow-schedule/docs/RUN_CLAUDE_CODE.sh +68 -68
- package/src/module/workflow-schedule/dto/create-schedule.dto.ts +147 -147
- package/src/module/workflow-schedule/dto/get-execution-logs.dto.ts +119 -119
- package/src/module/workflow-schedule/dto/update-schedule.dto.ts +96 -96
- package/src/module/workflow-schedule/entities/scheduled-workflow.entity.ts +148 -148
- package/src/module/workflow-schedule/entities/workflow-execution-log.entity.ts +154 -154
- package/src/module/workflow-schedule/interfaces/schedule-job-data.interface.ts +53 -53
- package/src/module/workflow-schedule/interfaces/workflow-schedule-options.interface.ts +12 -12
- package/src/module/workflow-schedule/processors/schedule.processor.ts +620 -620
- package/src/module/workflow-schedule/service/workflow-schedule.service.ts +597 -597
- package/src/module/workflow-schedule/workflow-schedule.module.ts +67 -67
- package/src/resources/dev.properties.yaml +31 -31
- package/src/resources/local.properties.yaml +27 -27
- package/src/resources/properties.module.ts +12 -12
- package/src/resources/properties.yaml.ts +11 -11
- package/src/resources/uat.properties.yaml +31 -31
- package/src/table.config.ts +133 -133
- package/src/utils/dto/excel-data.dto.ts +14 -14
- package/src/utils/dto/excelsheet-data.dto.ts +5 -5
- package/src/utils/service/base64util.service.ts +18 -18
- package/src/utils/service/clockIDGenUtil.service.ts +21 -21
- package/src/utils/service/codeGenerator.service.ts +22 -22
- package/src/utils/service/dateUtil.service.ts +17 -17
- package/src/utils/service/encryptUtil.service.ts +97 -97
- package/src/utils/service/excel-helper.service.ts +72 -72
- package/src/utils/service/excelUtil.service.ts +15 -15
- package/src/utils/service/file-util.service.ts +11 -11
- package/src/utils/service/json-util.service.ts +23 -23
- package/src/utils/service/loggingUtil.service.ts +88 -88
- package/src/utils/service/reflection-helper.service.ts +62 -62
- package/src/utils/service/wbsCodeGen.service.ts +8 -8
- package/src/utils/utils.module.ts +27 -27
- package/tsconfig.build.json +4 -4
- package/tsconfig.json +24 -24
|
@@ -1,824 +1,824 @@
|
|
|
1
|
-
import { BadRequestException, Injectable } from '@nestjs/common';
|
|
2
|
-
import { STATUS_ACTIVE } from 'src/constant/global.constant';
|
|
3
|
-
import { EntityManager, In } from 'typeorm';
|
|
4
|
-
import { UserData } from 'src/module/user/entity/user.entity';
|
|
5
|
-
import { MediaDataService } from './media-data.service';
|
|
6
|
-
import { ResolverService } from './resolver.service';
|
|
7
|
-
import { EntityMasterRepository } from '../repository/entity-master.repository';
|
|
8
|
-
import { ReflectionHelper } from '../../../utils/service/reflection-helper.service';
|
|
9
|
-
import { ConfigService } from '@nestjs/config';
|
|
10
|
-
|
|
11
|
-
@Injectable()
|
|
12
|
-
export class EntityDynamicService {
|
|
13
|
-
constructor(
|
|
14
|
-
private readonly entityManager: EntityManager,
|
|
15
|
-
private readonly mediaDataService: MediaDataService,
|
|
16
|
-
private readonly resolverService: ResolverService,
|
|
17
|
-
private readonly entityMasterRepo: EntityMasterRepository,
|
|
18
|
-
private readonly reflectionHelper: ReflectionHelper,
|
|
19
|
-
private readonly configService: ConfigService,
|
|
20
|
-
) {
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
schema = this.configService.get('DB_SCHEMA');
|
|
24
|
-
|
|
25
|
-
// -----------------------------
|
|
26
|
-
async createEntity(
|
|
27
|
-
entityType: string,
|
|
28
|
-
entityData: Record<string, any>,
|
|
29
|
-
loggedInUser: any,
|
|
30
|
-
mainID?: number,
|
|
31
|
-
): Promise<any> {
|
|
32
|
-
const organizationId = loggedInUser.organization_id;
|
|
33
|
-
const enterprise_id = loggedInUser.enterprise_id;
|
|
34
|
-
|
|
35
|
-
const tableName = await this.getTableName(entityType, enterprise_id);
|
|
36
|
-
const validAttributes = await this.getAttributeCodes(
|
|
37
|
-
entityType,
|
|
38
|
-
enterprise_id,
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
// -------------------------------------------------------
|
|
42
|
-
// AUTO fields
|
|
43
|
-
// -------------------------------------------------------
|
|
44
|
-
entityData.created_date = new Date();
|
|
45
|
-
|
|
46
|
-
if (loggedInUser) {
|
|
47
|
-
entityData.created_by = loggedInUser.id;
|
|
48
|
-
|
|
49
|
-
if (!entityData.organization_id)
|
|
50
|
-
entityData.organization_id = loggedInUser.organization_id;
|
|
51
|
-
|
|
52
|
-
if (!entityData.enterprise_id)
|
|
53
|
-
entityData.enterprise_id = loggedInUser.enterprise_id;
|
|
54
|
-
|
|
55
|
-
if (!entityData.level_type)
|
|
56
|
-
entityData.level_type = loggedInUser.level_type;
|
|
57
|
-
|
|
58
|
-
if (!entityData.level_id) entityData.level_id = loggedInUser.level_id;
|
|
59
|
-
|
|
60
|
-
if (!entityData.entity_type) entityData.entity_type = entityType;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// -------------------------------------------------------
|
|
64
|
-
// STATUS
|
|
65
|
-
// -------------------------------------------------------
|
|
66
|
-
const listMasterItemsRepo =
|
|
67
|
-
this.reflectionHelper.getRepoService('ListMasterItems');
|
|
68
|
-
const statusList = listMasterItemsRepo.find({
|
|
69
|
-
where: {
|
|
70
|
-
code: STATUS_ACTIVE,
|
|
71
|
-
organization_id: organizationId,
|
|
72
|
-
},
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
if (!entityData.status) entityData.status = statusList[0]?.id;
|
|
76
|
-
|
|
77
|
-
// -------------------------------------------------------
|
|
78
|
-
// AUTO-CODE GENERATION (POSTGRES SAFE)
|
|
79
|
-
// -------------------------------------------------------
|
|
80
|
-
const entityMaster = await this.entityMasterRepo.getEntityByMappedEntityType(entityType, loggedInUser.enterprise_id);
|
|
81
|
-
|
|
82
|
-
if (!entityData.code && entityData.entity_type && entityMaster) {
|
|
83
|
-
// Extract integer suffix
|
|
84
|
-
// const repo = this.reflectionHelper.getRepoService(entityMaster.entity_data_class);
|
|
85
|
-
|
|
86
|
-
const result = this.entityManager.query(
|
|
87
|
-
`SELECT MAX(id) as seq_no
|
|
88
|
-
FROM ${this.schema}.${entityMaster.db_table_name}`,
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
let maxSeq = Number(result[0]?.max_seq_no) || 0;
|
|
92
|
-
maxSeq++;
|
|
93
|
-
entityData.code = `${entityData.entity_type}${maxSeq}`;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// -------------------------------------------------------
|
|
97
|
-
// Parent ID
|
|
98
|
-
// -------------------------------------------------------
|
|
99
|
-
if (mainID) {
|
|
100
|
-
entityData.parent_id = mainID;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// -------------------------------------------------------
|
|
104
|
-
// BYPASS COLUMNS
|
|
105
|
-
// -------------------------------------------------------
|
|
106
|
-
const bypassColumns = [
|
|
107
|
-
'created_date',
|
|
108
|
-
'created_by',
|
|
109
|
-
'organization_id',
|
|
110
|
-
'enterprise_id',
|
|
111
|
-
'level_type',
|
|
112
|
-
'level_id',
|
|
113
|
-
'status',
|
|
114
|
-
'entity_type',
|
|
115
|
-
'code',
|
|
116
|
-
'parent_id',
|
|
117
|
-
];
|
|
118
|
-
|
|
119
|
-
for (const col of bypassColumns) {
|
|
120
|
-
if (!validAttributes.some((a) => a.attribute_key === col)) {
|
|
121
|
-
validAttributes.push({
|
|
122
|
-
attribute_key: col,
|
|
123
|
-
is_hidden: false,
|
|
124
|
-
db_datatype: 'text',
|
|
125
|
-
element_type: 'text',
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// -------------------------------------------------------
|
|
131
|
-
// BUILD INSERT QUERY (POSTGRES FORMAT)
|
|
132
|
-
// -------------------------------------------------------
|
|
133
|
-
const columns: string[] = [];
|
|
134
|
-
const values: any[] = [];
|
|
135
|
-
let idx = 1;
|
|
136
|
-
const placeholders: string[] = [];
|
|
137
|
-
|
|
138
|
-
for (const attr of validAttributes) {
|
|
139
|
-
if (attr.attribute_key === 'id') continue;
|
|
140
|
-
|
|
141
|
-
columns.push(attr.attribute_key);
|
|
142
|
-
values.push(entityData[attr.attribute_key] ?? null);
|
|
143
|
-
placeholders.push(`$${idx++}`);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const colList = columns.map((c) => `"${c}"`).join(', ');
|
|
147
|
-
const placeholderList = placeholders.join(', ');
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const sql = `
|
|
151
|
-
INSERT INTO ${this.schema}.${tableName} (${colList})
|
|
152
|
-
VALUES (${placeholderList}) RETURNING id
|
|
153
|
-
`;
|
|
154
|
-
|
|
155
|
-
const result = await this.entityManager.query(sql, values);
|
|
156
|
-
return result[0];
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// ----------------------------- get entity with relations
|
|
160
|
-
|
|
161
|
-
// ----------------------------- create entity with relations
|
|
162
|
-
async createEntityWithRelation(
|
|
163
|
-
entityType: string,
|
|
164
|
-
data: Record<string, any>,
|
|
165
|
-
loggedInUser: any,
|
|
166
|
-
): Promise<any> {
|
|
167
|
-
const enterpriseId = loggedInUser.enterprise_id;
|
|
168
|
-
const organizationId = loggedInUser.organization_id;
|
|
169
|
-
|
|
170
|
-
const repo = this.reflectionHelper.getRepoService('EntityRelation');
|
|
171
|
-
|
|
172
|
-
const getRelation = await repo.find({
|
|
173
|
-
where: {
|
|
174
|
-
enterprise_id: enterpriseId,
|
|
175
|
-
source_entity_type: entityType,
|
|
176
|
-
},
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
const { mappedEntities, ...mainData } = data;
|
|
180
|
-
|
|
181
|
-
// create main entity
|
|
182
|
-
const createdEntityData = await this.createEntity(
|
|
183
|
-
entityType,
|
|
184
|
-
mainData,
|
|
185
|
-
loggedInUser,
|
|
186
|
-
);
|
|
187
|
-
const mainID = createdEntityData.insertId || createdEntityData.id;
|
|
188
|
-
|
|
189
|
-
if (mappedEntities && getRelation.length > 0) {
|
|
190
|
-
for (const relation of getRelation) {
|
|
191
|
-
const targetEntityType = relation.target_entity_type;
|
|
192
|
-
const relationType = relation.relation_type;
|
|
193
|
-
|
|
194
|
-
if (!mappedEntities[targetEntityType]) continue;
|
|
195
|
-
|
|
196
|
-
// normalize: always array
|
|
197
|
-
const entityDataArray = Array.isArray(mappedEntities[targetEntityType])
|
|
198
|
-
? mappedEntities[targetEntityType]
|
|
199
|
-
: [mappedEntities[targetEntityType]];
|
|
200
|
-
|
|
201
|
-
for (const item of entityDataArray) {
|
|
202
|
-
const itemWithRef = {
|
|
203
|
-
...item,
|
|
204
|
-
entity_type: targetEntityType,
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
const createdRelatedEntity = await this.createEntity(
|
|
208
|
-
targetEntityType,
|
|
209
|
-
itemWithRef,
|
|
210
|
-
loggedInUser,
|
|
211
|
-
mainID, // this will pass for parent_id
|
|
212
|
-
);
|
|
213
|
-
|
|
214
|
-
const relationRepo =
|
|
215
|
-
this.reflectionHelper.getRepoService('EntityRelationData');
|
|
216
|
-
|
|
217
|
-
await relationRepo.save({
|
|
218
|
-
organizationId: organizationId,
|
|
219
|
-
enterprise_id: enterpriseId,
|
|
220
|
-
source_entity_id: mainID,
|
|
221
|
-
source_entity_type: entityType,
|
|
222
|
-
target_entity_id: createdRelatedEntity.id,
|
|
223
|
-
target_entity_type: targetEntityType,
|
|
224
|
-
relation_type: relationType,
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
return {
|
|
231
|
-
mainEntity: {
|
|
232
|
-
id: mainID,
|
|
233
|
-
entityType,
|
|
234
|
-
data: createdEntityData,
|
|
235
|
-
},
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// ----------------------------- get entity with relations
|
|
240
|
-
async getEntityWithRelation(
|
|
241
|
-
entityType: string,
|
|
242
|
-
id: number | string,
|
|
243
|
-
loggedInUser: any,
|
|
244
|
-
): Promise<any> {
|
|
245
|
-
const mainEntity = await this.getEntityByDataSource(
|
|
246
|
-
entityType,
|
|
247
|
-
id,
|
|
248
|
-
loggedInUser,
|
|
249
|
-
);
|
|
250
|
-
const relationRepo = this.reflectionHelper.getRepoService('EntityRelation');
|
|
251
|
-
const relatedEntityRepo =
|
|
252
|
-
this.reflectionHelper.getRepoService('EntityRelationData');
|
|
253
|
-
|
|
254
|
-
const relations = await relationRepo.find({
|
|
255
|
-
where: {
|
|
256
|
-
source_entity_type: entityType,
|
|
257
|
-
enterprise_id: loggedInUser.enterprise_id,
|
|
258
|
-
},
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
const targetTypes = relations.map((r) => r.target_entity_type);
|
|
262
|
-
|
|
263
|
-
if (targetTypes.length === 0) {
|
|
264
|
-
return {
|
|
265
|
-
entity_type: entityType,
|
|
266
|
-
...mainEntity,
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
const relatedEntities = await relatedEntityRepo.find({
|
|
271
|
-
where: {
|
|
272
|
-
source_entity_id: id,
|
|
273
|
-
target_entity_type: In(targetTypes),
|
|
274
|
-
},
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
// Format response to match create entity structure
|
|
278
|
-
const response: any = {
|
|
279
|
-
entity_type: entityType,
|
|
280
|
-
...mainEntity,
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
if (relatedEntities.length > 0) {
|
|
284
|
-
response.mappedEntities = await this.formatMappedEntities(
|
|
285
|
-
relatedEntities,
|
|
286
|
-
loggedInUser,
|
|
287
|
-
);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
return response;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// ----------------------------- formatMappedEntities
|
|
294
|
-
async formatMappedEntities(
|
|
295
|
-
relatedEntities: any[],
|
|
296
|
-
loggedInUser: any,
|
|
297
|
-
): Promise<any> {
|
|
298
|
-
const mappedEntities: any = {};
|
|
299
|
-
|
|
300
|
-
for (const relation of relatedEntities) {
|
|
301
|
-
const targetEntityType = relation.target_entity_type;
|
|
302
|
-
const targetEntityId = relation.target_entity_id;
|
|
303
|
-
|
|
304
|
-
const entityData = await this.getEntity(
|
|
305
|
-
targetEntityType,
|
|
306
|
-
targetEntityId,
|
|
307
|
-
loggedInUser,
|
|
308
|
-
);
|
|
309
|
-
|
|
310
|
-
if (!mappedEntities[targetEntityType]) {
|
|
311
|
-
mappedEntities[targetEntityType] = [];
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
mappedEntities[targetEntityType].push(entityData);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
return mappedEntities;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
// ----------------------------- update with relations
|
|
321
|
-
|
|
322
|
-
// ----------------------------- update entity with relations
|
|
323
|
-
async updateEntityWithRelations(
|
|
324
|
-
entityType: string,
|
|
325
|
-
id: number | string,
|
|
326
|
-
data: Record<string, any>,
|
|
327
|
-
loggedInUser: any,
|
|
328
|
-
): Promise<any> {
|
|
329
|
-
const organizationId = loggedInUser.organization_id;
|
|
330
|
-
const enterpriseId = loggedInUser.enterprise_id;
|
|
331
|
-
const { mappedEntities, ...mainData } = data;
|
|
332
|
-
|
|
333
|
-
// Update main entity
|
|
334
|
-
const updatedMainEntity = await this.updateEntity(
|
|
335
|
-
entityType,
|
|
336
|
-
id,
|
|
337
|
-
mainData,
|
|
338
|
-
loggedInUser,
|
|
339
|
-
);
|
|
340
|
-
|
|
341
|
-
const updatedRelations: Record<string, any> = {};
|
|
342
|
-
|
|
343
|
-
if (mappedEntities) {
|
|
344
|
-
const entityRelationRepo =
|
|
345
|
-
this.reflectionHelper.getRepoService('EntityRelation');
|
|
346
|
-
const getRelationDefs = await entityRelationRepo.find({
|
|
347
|
-
where: {
|
|
348
|
-
enterprise_id: enterpriseId,
|
|
349
|
-
source_entity_type: entityType,
|
|
350
|
-
},
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
for (const [targetEntityType, rawEntityData] of Object.entries(
|
|
354
|
-
mappedEntities,
|
|
355
|
-
)) {
|
|
356
|
-
const relationDef = getRelationDefs.find(
|
|
357
|
-
(r) => r.target_entity_type === targetEntityType,
|
|
358
|
-
);
|
|
359
|
-
if (!relationDef) continue;
|
|
360
|
-
|
|
361
|
-
const relationType = relationDef.relation_type;
|
|
362
|
-
const entityArray = Array.isArray(rawEntityData)
|
|
363
|
-
? rawEntityData
|
|
364
|
-
: [rawEntityData];
|
|
365
|
-
|
|
366
|
-
// Delete previous relations and related entities
|
|
367
|
-
// Create/update new entities & relations
|
|
368
|
-
const updatedEntities: any[] = [];
|
|
369
|
-
|
|
370
|
-
for (const item of entityArray) {
|
|
371
|
-
let targetEntityId;
|
|
372
|
-
let entityData;
|
|
373
|
-
|
|
374
|
-
if (item.id) {
|
|
375
|
-
// Update existing entity
|
|
376
|
-
await this.updateEntity(
|
|
377
|
-
targetEntityType,
|
|
378
|
-
item.id,
|
|
379
|
-
item,
|
|
380
|
-
loggedInUser,
|
|
381
|
-
Number(id), // pass main entity id as parent_id
|
|
382
|
-
);
|
|
383
|
-
targetEntityId = item.id;
|
|
384
|
-
entityData = await this.getEntity(
|
|
385
|
-
targetEntityType,
|
|
386
|
-
targetEntityId,
|
|
387
|
-
loggedInUser,
|
|
388
|
-
);
|
|
389
|
-
} else {
|
|
390
|
-
// Create new entity
|
|
391
|
-
const createdEntity = await this.createEntity(
|
|
392
|
-
targetEntityType,
|
|
393
|
-
item,
|
|
394
|
-
loggedInUser,
|
|
395
|
-
Number(id), // pass main entity id as parent_id
|
|
396
|
-
);
|
|
397
|
-
targetEntityId = createdEntity.insertId || createdEntity.id;
|
|
398
|
-
entityData = await this.getEntity(
|
|
399
|
-
targetEntityType,
|
|
400
|
-
targetEntityId,
|
|
401
|
-
loggedInUser,
|
|
402
|
-
);
|
|
403
|
-
|
|
404
|
-
// Insert relation as per new entity created
|
|
405
|
-
const entityRelationDataRepo =
|
|
406
|
-
this.reflectionHelper.getRepoService('EntityRelationData');
|
|
407
|
-
await entityRelationDataRepo.save({
|
|
408
|
-
organizationId: organizationId,
|
|
409
|
-
enterprise_id: enterpriseId,
|
|
410
|
-
source_entity_id: id,
|
|
411
|
-
source_entity_type: entityType,
|
|
412
|
-
target_entity_id: targetEntityId,
|
|
413
|
-
target_entity_type: targetEntityType,
|
|
414
|
-
relation_type: relationType,
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
if (relationType === 'ONE_TO_MANY') {
|
|
419
|
-
updatedEntities.push(entityData);
|
|
420
|
-
} else if (
|
|
421
|
-
relationType === 'ONE_TO_ONE' ||
|
|
422
|
-
relationType === 'MANY_TO_ONE'
|
|
423
|
-
) {
|
|
424
|
-
updatedEntities[0] = entityData; // single object
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// Assign to response mappedEntities
|
|
429
|
-
updatedRelations[targetEntityType] =
|
|
430
|
-
relationType === 'ONE_TO_MANY' ? updatedEntities : updatedEntities[0];
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
return {
|
|
435
|
-
mainEntity: {
|
|
436
|
-
id,
|
|
437
|
-
entityType,
|
|
438
|
-
data: updatedMainEntity,
|
|
439
|
-
},
|
|
440
|
-
relatedEntities: updatedRelations,
|
|
441
|
-
};
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
// -----------------------------
|
|
445
|
-
async updateEntity(
|
|
446
|
-
entityType: string,
|
|
447
|
-
id: number | string,
|
|
448
|
-
entityData: Record<string, any>,
|
|
449
|
-
loggedInUser: any,
|
|
450
|
-
mainID?: number,
|
|
451
|
-
): Promise<any> {
|
|
452
|
-
const enterprise_id = loggedInUser.enterprise_id;
|
|
453
|
-
|
|
454
|
-
const tableName = await this.getTableName(entityType, enterprise_id);
|
|
455
|
-
const validAttributes = await this.getAttributeCodes(
|
|
456
|
-
entityType,
|
|
457
|
-
enterprise_id,
|
|
458
|
-
);
|
|
459
|
-
|
|
460
|
-
const updates: string[] = [];
|
|
461
|
-
const values: any[] = [];
|
|
462
|
-
let idx = 1;
|
|
463
|
-
|
|
464
|
-
// Auto fields
|
|
465
|
-
entityData.modified_date = new Date();
|
|
466
|
-
if (loggedInUser) {
|
|
467
|
-
entityData.modified_by = loggedInUser.id;
|
|
468
|
-
|
|
469
|
-
if (!entityData.organization_id && entityData.entity_type !== 'ORG')
|
|
470
|
-
entityData.organization_id = loggedInUser.organization_id;
|
|
471
|
-
|
|
472
|
-
if (!entityData.enterprise_id)
|
|
473
|
-
entityData.enterprise_id = loggedInUser.enterprise_id;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
if (mainID) {
|
|
477
|
-
entityData.parent_id = mainID;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
// Add bypass columns if needed
|
|
481
|
-
const bypassColumns = [
|
|
482
|
-
'created_date',
|
|
483
|
-
'created_by',
|
|
484
|
-
'modified_date',
|
|
485
|
-
'modified_by',
|
|
486
|
-
'organization_id',
|
|
487
|
-
'enterprise_id',
|
|
488
|
-
'level_type',
|
|
489
|
-
'level_id',
|
|
490
|
-
'status',
|
|
491
|
-
'entity_type',
|
|
492
|
-
'code',
|
|
493
|
-
'parent_id',
|
|
494
|
-
];
|
|
495
|
-
|
|
496
|
-
for (const col of bypassColumns) {
|
|
497
|
-
if (!validAttributes.some((attr) => attr.attribute_key === col)) {
|
|
498
|
-
validAttributes.push({
|
|
499
|
-
attribute_key: col,
|
|
500
|
-
db_datatype: 'text',
|
|
501
|
-
element_type: 'text',
|
|
502
|
-
is_hidden: false,
|
|
503
|
-
});
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
// Build SET clause
|
|
508
|
-
for (const key of Object.keys(entityData)) {
|
|
509
|
-
if (validAttributes.some((attr) => attr.attribute_key === key)) {
|
|
510
|
-
updates.push(`${key} = $${idx++}`);
|
|
511
|
-
values.push(entityData[key]);
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
if (updates.length === 0) {
|
|
516
|
-
throw new Error('No valid attributes to update.');
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
// WHERE clause placeholder
|
|
520
|
-
const idPlaceholder = `$${idx}`;
|
|
521
|
-
values.push(id);
|
|
522
|
-
|
|
523
|
-
const updateQuery = `
|
|
524
|
-
UPDATE ${this.schema}.${tableName}
|
|
525
|
-
SET ${updates.join(', ')}
|
|
526
|
-
WHERE id = ${idPlaceholder}
|
|
527
|
-
`;
|
|
528
|
-
|
|
529
|
-
return await this.entityManager.query(updateQuery, values);
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
async getEntityByDataSource(
|
|
533
|
-
entityType: string,
|
|
534
|
-
id: number | string,
|
|
535
|
-
loggedInUser: any,
|
|
536
|
-
): Promise<any> {
|
|
537
|
-
const enterprise_id = loggedInUser.enterprise_id;
|
|
538
|
-
|
|
539
|
-
const dataSource = await this.getEntitySourceTableName(
|
|
540
|
-
entityType,
|
|
541
|
-
enterprise_id,
|
|
542
|
-
);
|
|
543
|
-
const validAttributes = await this.getAttributeCodes(
|
|
544
|
-
entityType,
|
|
545
|
-
enterprise_id,
|
|
546
|
-
false,
|
|
547
|
-
);
|
|
548
|
-
|
|
549
|
-
const columns = validAttributes
|
|
550
|
-
.map((attr) => `${attr.attribute_key}`)
|
|
551
|
-
.join(', ');
|
|
552
|
-
const selectQuery = `SELECT ${columns}
|
|
553
|
-
FROM ${dataSource}
|
|
554
|
-
WHERE id = $1`;
|
|
555
|
-
|
|
556
|
-
const result = await this.entityManager.query(selectQuery, [id]);
|
|
557
|
-
if (!result.length) return null;
|
|
558
|
-
|
|
559
|
-
const row = result[0];
|
|
560
|
-
|
|
561
|
-
// Convert boolean columns (1/0) into true/false
|
|
562
|
-
for (const attr of validAttributes) {
|
|
563
|
-
if (
|
|
564
|
-
attr.db_datatype == 'boolean' &&
|
|
565
|
-
row[attr.attribute_key] !== undefined
|
|
566
|
-
) {
|
|
567
|
-
row[attr.attribute_key] = row[attr.attribute_key] == 1 ? true : false;
|
|
568
|
-
} else if (
|
|
569
|
-
attr.element_type == 'upload' &&
|
|
570
|
-
row[attr.attribute_key] !== undefined
|
|
571
|
-
) {
|
|
572
|
-
row[attr.attribute_key] =
|
|
573
|
-
row[attr.attribute_key] != null
|
|
574
|
-
? await this.mediaDataService.getMediaDownloadUrl(
|
|
575
|
-
Number(row[attr.attribute_key]),
|
|
576
|
-
loggedInUser,
|
|
577
|
-
)
|
|
578
|
-
: null;
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
return row;
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
// -----------------------------
|
|
586
|
-
//TODO : make it normal getEntity function make another function if for resolve data
|
|
587
|
-
async getEntity(
|
|
588
|
-
entityType: string,
|
|
589
|
-
id: number | string,
|
|
590
|
-
loggedInUser: any,
|
|
591
|
-
): Promise<any> {
|
|
592
|
-
const enterprise_id = loggedInUser.enterprise_id;
|
|
593
|
-
|
|
594
|
-
const entityMaster = await this.entityMasterRepo.getEntityByMappedEntityType(entityType, enterprise_id);
|
|
595
|
-
if (!entityMaster) return null;
|
|
596
|
-
|
|
597
|
-
const validAttributes = await this.getAttributeCodes(
|
|
598
|
-
entityType,
|
|
599
|
-
enterprise_id,
|
|
600
|
-
);
|
|
601
|
-
|
|
602
|
-
// const entityRepo = this.reflectionHelper.getRepoService(entityMaster?.entity_data_class);
|
|
603
|
-
|
|
604
|
-
const columns = validAttributes.map(attr => `t.${attr.attribute_key}`);
|
|
605
|
-
|
|
606
|
-
// const result = await entityRepo.find({
|
|
607
|
-
// where: {
|
|
608
|
-
// id: id
|
|
609
|
-
// },
|
|
610
|
-
// select: columns
|
|
611
|
-
// });
|
|
612
|
-
const selectQuery = `SELECT ${columns}
|
|
613
|
-
FROM ${this.schema}.${entityMaster.db_table_name} t
|
|
614
|
-
WHERE id = $1`;
|
|
615
|
-
|
|
616
|
-
const result = await this.entityManager.query(selectQuery, [id]);
|
|
617
|
-
if (!result.length) return null;
|
|
618
|
-
|
|
619
|
-
const row = result[0];
|
|
620
|
-
|
|
621
|
-
// Convert boolean columns (1/0) into true/false
|
|
622
|
-
for (const attr of validAttributes) {
|
|
623
|
-
if (
|
|
624
|
-
attr.db_datatype == 'boolean' &&
|
|
625
|
-
row[attr.attribute_key] !== undefined
|
|
626
|
-
) {
|
|
627
|
-
row[attr.attribute_key] = row[attr.attribute_key] == 1 ? true : false;
|
|
628
|
-
} else if (
|
|
629
|
-
attr.element_type == 'upload' &&
|
|
630
|
-
row[attr.attribute_key] !== undefined
|
|
631
|
-
) {
|
|
632
|
-
row[attr.attribute_key] =
|
|
633
|
-
row[attr.attribute_key] != null
|
|
634
|
-
? await this.mediaDataService.getMediaDownloadUrl(
|
|
635
|
-
Number(row[attr.attribute_key]),
|
|
636
|
-
loggedInUser,
|
|
637
|
-
)
|
|
638
|
-
: null;
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
return row;
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
private async getEntitySourceTableName(
|
|
646
|
-
entityType: string,
|
|
647
|
-
enterprise_id: string,
|
|
648
|
-
): Promise<string> {
|
|
649
|
-
const result = await this.entityMasterRepo.getEntityByMappedEntityType(
|
|
650
|
-
entityType,
|
|
651
|
-
enterprise_id,
|
|
652
|
-
);
|
|
653
|
-
|
|
654
|
-
if (!result) {
|
|
655
|
-
console.log(`Entity type '${entityType}' not found in frm_entity_master`);
|
|
656
|
-
throw new BadRequestException();
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
return result.data_source;
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
// -----------------------------
|
|
663
|
-
private async getTableName(
|
|
664
|
-
entityType: string,
|
|
665
|
-
enterprise_id: string,
|
|
666
|
-
): Promise<string> {
|
|
667
|
-
let entityMaster = await this.entityMasterRepo.getEntityByMappedEntityType(
|
|
668
|
-
entityType,
|
|
669
|
-
enterprise_id,
|
|
670
|
-
);
|
|
671
|
-
|
|
672
|
-
if (!entityMaster) {
|
|
673
|
-
console.log(`Entity type '${entityType}' not found in frm_entity_master`);
|
|
674
|
-
throw new BadRequestException();
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
return entityMaster.db_table_name;
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
private async getAttributeCodes(
|
|
681
|
-
entityType: string,
|
|
682
|
-
enterprise_id: string,
|
|
683
|
-
isHidden = true,
|
|
684
|
-
) {
|
|
685
|
-
const attributeMasterRepo =
|
|
686
|
-
this.reflectionHelper.getRepoService('AttributeMaster');
|
|
687
|
-
|
|
688
|
-
const qb = attributeMasterRepo
|
|
689
|
-
.createQueryBuilder('fea')
|
|
690
|
-
.select('fea.attribute_key', 'attribute_key')
|
|
691
|
-
.addSelect('MAX(fea.db_datatype)', 'db_datatype')
|
|
692
|
-
.addSelect('MAX(fea.element_type)', 'element_type')
|
|
693
|
-
.addSelect('bool_or(fea.is_hidden)', 'is_hidden')
|
|
694
|
-
.where('fea.mapped_entity_type = :entityType', { entityType })
|
|
695
|
-
.andWhere('fea.enterprise_id = :enterprise_id', { enterprise_id });
|
|
696
|
-
|
|
697
|
-
if (isHidden) {
|
|
698
|
-
qb.andWhere('(fea.is_hidden IS NULL OR fea.is_hidden = false)');
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
qb.groupBy('fea.attribute_key');
|
|
702
|
-
|
|
703
|
-
const result = await qb.getRawMany();
|
|
704
|
-
|
|
705
|
-
return result.map((row: any) => ({
|
|
706
|
-
attribute_key: row.attribute_key,
|
|
707
|
-
db_datatype: row.db_datatype,
|
|
708
|
-
element_type: row.element_type,
|
|
709
|
-
is_hidden: row.is_hidden != null ? row.is_hidden === true : undefined,
|
|
710
|
-
}));
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
private async deleteEntity(
|
|
714
|
-
entityType: string,
|
|
715
|
-
id: number | string,
|
|
716
|
-
loggedInUser: any,
|
|
717
|
-
): Promise<any> {
|
|
718
|
-
const enterprise_id = loggedInUser.enterprise_id;
|
|
719
|
-
|
|
720
|
-
const tableName = await this.getTableName(entityType, enterprise_id);
|
|
721
|
-
|
|
722
|
-
const deleteQuery = `DELETE
|
|
723
|
-
FROM ${this.schema}.${tableName}
|
|
724
|
-
WHERE id = $1`;
|
|
725
|
-
const result = await this.entityManager.query(deleteQuery, [id]);
|
|
726
|
-
return result;
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
// -----------------------------
|
|
730
|
-
|
|
731
|
-
async getEntitiesDropdownList(
|
|
732
|
-
loggedInUser: any,
|
|
733
|
-
appcode?: string,
|
|
734
|
-
): Promise<any> {
|
|
735
|
-
|
|
736
|
-
const entityMasters = await this.entityMasterRepo.findByEnterpriseIdAndAppCode(loggedInUser.enterprise_id, appcode);
|
|
737
|
-
|
|
738
|
-
let dropdown = [] as any;
|
|
739
|
-
entityMasters.map(entityMaster => dropdown.push({
|
|
740
|
-
label: entityMaster.name,
|
|
741
|
-
value: entityMaster.mapped_entity_type,
|
|
742
|
-
}));
|
|
743
|
-
|
|
744
|
-
return dropdown;
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
async getCode(entityType: string, loggedInUser: any): Promise<string> {
|
|
748
|
-
const enterprise_id = loggedInUser.enterprise_id;
|
|
749
|
-
|
|
750
|
-
// 1. Get db_table_name from entity master
|
|
751
|
-
|
|
752
|
-
const result = await this.entityMasterRepo.getEntityByMappedEntityType(
|
|
753
|
-
entityType,
|
|
754
|
-
enterprise_id,
|
|
755
|
-
);
|
|
756
|
-
|
|
757
|
-
if (!result) {
|
|
758
|
-
throw new Error(
|
|
759
|
-
`Entity type '${entityType}' not found in frm_entity_master for enterprise '${enterprise_id}'`,
|
|
760
|
-
);
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
const tableName = result.db_table_name;
|
|
764
|
-
|
|
765
|
-
// 2. Get current max sequence number from that table
|
|
766
|
-
const seqResult = await this.entityManager.query(
|
|
767
|
-
`SELECT MAX(id) AS max_seq_no
|
|
768
|
-
FROM ${tableName}
|
|
769
|
-
WHERE entity_type = $1`,
|
|
770
|
-
[entityType],
|
|
771
|
-
);
|
|
772
|
-
|
|
773
|
-
let maxSeqNo = seqResult?.[0]?.max_seq_no
|
|
774
|
-
? Number(seqResult[0].max_seq_no)
|
|
775
|
-
: 0;
|
|
776
|
-
|
|
777
|
-
maxSeqNo += 1;
|
|
778
|
-
|
|
779
|
-
// 3. Return generated code
|
|
780
|
-
return `${entityType}${maxSeqNo}`;
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
async getResolvedEntity(
|
|
784
|
-
id: number,
|
|
785
|
-
entity: string,
|
|
786
|
-
loggedInUser: UserData,
|
|
787
|
-
): Promise<any> {
|
|
788
|
-
const leadData = await this.getEntityWithRelation(entity, id, loggedInUser);
|
|
789
|
-
|
|
790
|
-
const { mappedEntities, ...data } = leadData as any;
|
|
791
|
-
|
|
792
|
-
const resolvedData = await this.resolverService.getResolvedData(
|
|
793
|
-
loggedInUser,
|
|
794
|
-
data,
|
|
795
|
-
entity,
|
|
796
|
-
);
|
|
797
|
-
|
|
798
|
-
if (mappedEntities) {
|
|
799
|
-
resolvedData.mappedEntities = {};
|
|
800
|
-
for (const [entityType, entities] of Object.entries(mappedEntities)) {
|
|
801
|
-
if (Array.isArray(entities)) {
|
|
802
|
-
resolvedData.mappedEntities[entityType] = [];
|
|
803
|
-
for (const item of entities) {
|
|
804
|
-
const resolvedItem = await this.resolverService.getResolvedData(
|
|
805
|
-
loggedInUser,
|
|
806
|
-
item,
|
|
807
|
-
entityType,
|
|
808
|
-
);
|
|
809
|
-
resolvedData.mappedEntities[entityType].push(resolvedItem);
|
|
810
|
-
}
|
|
811
|
-
} else {
|
|
812
|
-
resolvedData.mappedEntities[entityType] =
|
|
813
|
-
await this.resolverService.getResolvedData(
|
|
814
|
-
loggedInUser,
|
|
815
|
-
entities,
|
|
816
|
-
entityType,
|
|
817
|
-
);
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
return resolvedData;
|
|
823
|
-
}
|
|
824
|
-
}
|
|
1
|
+
import { BadRequestException, Injectable } from '@nestjs/common';
|
|
2
|
+
import { STATUS_ACTIVE } from 'src/constant/global.constant';
|
|
3
|
+
import { EntityManager, In } from 'typeorm';
|
|
4
|
+
import { UserData } from 'src/module/user/entity/user.entity';
|
|
5
|
+
import { MediaDataService } from './media-data.service';
|
|
6
|
+
import { ResolverService } from './resolver.service';
|
|
7
|
+
import { EntityMasterRepository } from '../repository/entity-master.repository';
|
|
8
|
+
import { ReflectionHelper } from '../../../utils/service/reflection-helper.service';
|
|
9
|
+
import { ConfigService } from '@nestjs/config';
|
|
10
|
+
|
|
11
|
+
@Injectable()
|
|
12
|
+
export class EntityDynamicService {
|
|
13
|
+
constructor(
|
|
14
|
+
private readonly entityManager: EntityManager,
|
|
15
|
+
private readonly mediaDataService: MediaDataService,
|
|
16
|
+
private readonly resolverService: ResolverService,
|
|
17
|
+
private readonly entityMasterRepo: EntityMasterRepository,
|
|
18
|
+
private readonly reflectionHelper: ReflectionHelper,
|
|
19
|
+
private readonly configService: ConfigService,
|
|
20
|
+
) {
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
schema = this.configService.get('DB_SCHEMA');
|
|
24
|
+
|
|
25
|
+
// -----------------------------
|
|
26
|
+
async createEntity(
|
|
27
|
+
entityType: string,
|
|
28
|
+
entityData: Record<string, any>,
|
|
29
|
+
loggedInUser: any,
|
|
30
|
+
mainID?: number,
|
|
31
|
+
): Promise<any> {
|
|
32
|
+
const organizationId = loggedInUser.organization_id;
|
|
33
|
+
const enterprise_id = loggedInUser.enterprise_id;
|
|
34
|
+
|
|
35
|
+
const tableName = await this.getTableName(entityType, enterprise_id);
|
|
36
|
+
const validAttributes = await this.getAttributeCodes(
|
|
37
|
+
entityType,
|
|
38
|
+
enterprise_id,
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// -------------------------------------------------------
|
|
42
|
+
// AUTO fields
|
|
43
|
+
// -------------------------------------------------------
|
|
44
|
+
entityData.created_date = new Date();
|
|
45
|
+
|
|
46
|
+
if (loggedInUser) {
|
|
47
|
+
entityData.created_by = loggedInUser.id;
|
|
48
|
+
|
|
49
|
+
if (!entityData.organization_id)
|
|
50
|
+
entityData.organization_id = loggedInUser.organization_id;
|
|
51
|
+
|
|
52
|
+
if (!entityData.enterprise_id)
|
|
53
|
+
entityData.enterprise_id = loggedInUser.enterprise_id;
|
|
54
|
+
|
|
55
|
+
if (!entityData.level_type)
|
|
56
|
+
entityData.level_type = loggedInUser.level_type;
|
|
57
|
+
|
|
58
|
+
if (!entityData.level_id) entityData.level_id = loggedInUser.level_id;
|
|
59
|
+
|
|
60
|
+
if (!entityData.entity_type) entityData.entity_type = entityType;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// -------------------------------------------------------
|
|
64
|
+
// STATUS
|
|
65
|
+
// -------------------------------------------------------
|
|
66
|
+
const listMasterItemsRepo =
|
|
67
|
+
this.reflectionHelper.getRepoService('ListMasterItems');
|
|
68
|
+
const statusList = listMasterItemsRepo.find({
|
|
69
|
+
where: {
|
|
70
|
+
code: STATUS_ACTIVE,
|
|
71
|
+
organization_id: organizationId,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (!entityData.status) entityData.status = statusList[0]?.id;
|
|
76
|
+
|
|
77
|
+
// -------------------------------------------------------
|
|
78
|
+
// AUTO-CODE GENERATION (POSTGRES SAFE)
|
|
79
|
+
// -------------------------------------------------------
|
|
80
|
+
const entityMaster = await this.entityMasterRepo.getEntityByMappedEntityType(entityType, loggedInUser.enterprise_id);
|
|
81
|
+
|
|
82
|
+
if (!entityData.code && entityData.entity_type && entityMaster) {
|
|
83
|
+
// Extract integer suffix
|
|
84
|
+
// const repo = this.reflectionHelper.getRepoService(entityMaster.entity_data_class);
|
|
85
|
+
|
|
86
|
+
const result = this.entityManager.query(
|
|
87
|
+
`SELECT MAX(id) as seq_no
|
|
88
|
+
FROM ${this.schema}.${entityMaster.db_table_name}`,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
let maxSeq = Number(result[0]?.max_seq_no) || 0;
|
|
92
|
+
maxSeq++;
|
|
93
|
+
entityData.code = `${entityData.entity_type}${maxSeq}`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// -------------------------------------------------------
|
|
97
|
+
// Parent ID
|
|
98
|
+
// -------------------------------------------------------
|
|
99
|
+
if (mainID) {
|
|
100
|
+
entityData.parent_id = mainID;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// -------------------------------------------------------
|
|
104
|
+
// BYPASS COLUMNS
|
|
105
|
+
// -------------------------------------------------------
|
|
106
|
+
const bypassColumns = [
|
|
107
|
+
'created_date',
|
|
108
|
+
'created_by',
|
|
109
|
+
'organization_id',
|
|
110
|
+
'enterprise_id',
|
|
111
|
+
'level_type',
|
|
112
|
+
'level_id',
|
|
113
|
+
'status',
|
|
114
|
+
'entity_type',
|
|
115
|
+
'code',
|
|
116
|
+
'parent_id',
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
for (const col of bypassColumns) {
|
|
120
|
+
if (!validAttributes.some((a) => a.attribute_key === col)) {
|
|
121
|
+
validAttributes.push({
|
|
122
|
+
attribute_key: col,
|
|
123
|
+
is_hidden: false,
|
|
124
|
+
db_datatype: 'text',
|
|
125
|
+
element_type: 'text',
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// -------------------------------------------------------
|
|
131
|
+
// BUILD INSERT QUERY (POSTGRES FORMAT)
|
|
132
|
+
// -------------------------------------------------------
|
|
133
|
+
const columns: string[] = [];
|
|
134
|
+
const values: any[] = [];
|
|
135
|
+
let idx = 1;
|
|
136
|
+
const placeholders: string[] = [];
|
|
137
|
+
|
|
138
|
+
for (const attr of validAttributes) {
|
|
139
|
+
if (attr.attribute_key === 'id') continue;
|
|
140
|
+
|
|
141
|
+
columns.push(attr.attribute_key);
|
|
142
|
+
values.push(entityData[attr.attribute_key] ?? null);
|
|
143
|
+
placeholders.push(`$${idx++}`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const colList = columns.map((c) => `"${c}"`).join(', ');
|
|
147
|
+
const placeholderList = placeholders.join(', ');
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
const sql = `
|
|
151
|
+
INSERT INTO ${this.schema}.${tableName} (${colList})
|
|
152
|
+
VALUES (${placeholderList}) RETURNING id
|
|
153
|
+
`;
|
|
154
|
+
|
|
155
|
+
const result = await this.entityManager.query(sql, values);
|
|
156
|
+
return result[0];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ----------------------------- get entity with relations
|
|
160
|
+
|
|
161
|
+
// ----------------------------- create entity with relations
|
|
162
|
+
async createEntityWithRelation(
|
|
163
|
+
entityType: string,
|
|
164
|
+
data: Record<string, any>,
|
|
165
|
+
loggedInUser: any,
|
|
166
|
+
): Promise<any> {
|
|
167
|
+
const enterpriseId = loggedInUser.enterprise_id;
|
|
168
|
+
const organizationId = loggedInUser.organization_id;
|
|
169
|
+
|
|
170
|
+
const repo = this.reflectionHelper.getRepoService('EntityRelation');
|
|
171
|
+
|
|
172
|
+
const getRelation = await repo.find({
|
|
173
|
+
where: {
|
|
174
|
+
enterprise_id: enterpriseId,
|
|
175
|
+
source_entity_type: entityType,
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
const { mappedEntities, ...mainData } = data;
|
|
180
|
+
|
|
181
|
+
// create main entity
|
|
182
|
+
const createdEntityData = await this.createEntity(
|
|
183
|
+
entityType,
|
|
184
|
+
mainData,
|
|
185
|
+
loggedInUser,
|
|
186
|
+
);
|
|
187
|
+
const mainID = createdEntityData.insertId || createdEntityData.id;
|
|
188
|
+
|
|
189
|
+
if (mappedEntities && getRelation.length > 0) {
|
|
190
|
+
for (const relation of getRelation) {
|
|
191
|
+
const targetEntityType = relation.target_entity_type;
|
|
192
|
+
const relationType = relation.relation_type;
|
|
193
|
+
|
|
194
|
+
if (!mappedEntities[targetEntityType]) continue;
|
|
195
|
+
|
|
196
|
+
// normalize: always array
|
|
197
|
+
const entityDataArray = Array.isArray(mappedEntities[targetEntityType])
|
|
198
|
+
? mappedEntities[targetEntityType]
|
|
199
|
+
: [mappedEntities[targetEntityType]];
|
|
200
|
+
|
|
201
|
+
for (const item of entityDataArray) {
|
|
202
|
+
const itemWithRef = {
|
|
203
|
+
...item,
|
|
204
|
+
entity_type: targetEntityType,
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const createdRelatedEntity = await this.createEntity(
|
|
208
|
+
targetEntityType,
|
|
209
|
+
itemWithRef,
|
|
210
|
+
loggedInUser,
|
|
211
|
+
mainID, // this will pass for parent_id
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
const relationRepo =
|
|
215
|
+
this.reflectionHelper.getRepoService('EntityRelationData');
|
|
216
|
+
|
|
217
|
+
await relationRepo.save({
|
|
218
|
+
organizationId: organizationId,
|
|
219
|
+
enterprise_id: enterpriseId,
|
|
220
|
+
source_entity_id: mainID,
|
|
221
|
+
source_entity_type: entityType,
|
|
222
|
+
target_entity_id: createdRelatedEntity.id,
|
|
223
|
+
target_entity_type: targetEntityType,
|
|
224
|
+
relation_type: relationType,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
mainEntity: {
|
|
232
|
+
id: mainID,
|
|
233
|
+
entityType,
|
|
234
|
+
data: createdEntityData,
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// ----------------------------- get entity with relations
|
|
240
|
+
async getEntityWithRelation(
|
|
241
|
+
entityType: string,
|
|
242
|
+
id: number | string,
|
|
243
|
+
loggedInUser: any,
|
|
244
|
+
): Promise<any> {
|
|
245
|
+
const mainEntity = await this.getEntityByDataSource(
|
|
246
|
+
entityType,
|
|
247
|
+
id,
|
|
248
|
+
loggedInUser,
|
|
249
|
+
);
|
|
250
|
+
const relationRepo = this.reflectionHelper.getRepoService('EntityRelation');
|
|
251
|
+
const relatedEntityRepo =
|
|
252
|
+
this.reflectionHelper.getRepoService('EntityRelationData');
|
|
253
|
+
|
|
254
|
+
const relations = await relationRepo.find({
|
|
255
|
+
where: {
|
|
256
|
+
source_entity_type: entityType,
|
|
257
|
+
enterprise_id: loggedInUser.enterprise_id,
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
const targetTypes = relations.map((r) => r.target_entity_type);
|
|
262
|
+
|
|
263
|
+
if (targetTypes.length === 0) {
|
|
264
|
+
return {
|
|
265
|
+
entity_type: entityType,
|
|
266
|
+
...mainEntity,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const relatedEntities = await relatedEntityRepo.find({
|
|
271
|
+
where: {
|
|
272
|
+
source_entity_id: id,
|
|
273
|
+
target_entity_type: In(targetTypes),
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Format response to match create entity structure
|
|
278
|
+
const response: any = {
|
|
279
|
+
entity_type: entityType,
|
|
280
|
+
...mainEntity,
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
if (relatedEntities.length > 0) {
|
|
284
|
+
response.mappedEntities = await this.formatMappedEntities(
|
|
285
|
+
relatedEntities,
|
|
286
|
+
loggedInUser,
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
return response;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// ----------------------------- formatMappedEntities
|
|
294
|
+
async formatMappedEntities(
|
|
295
|
+
relatedEntities: any[],
|
|
296
|
+
loggedInUser: any,
|
|
297
|
+
): Promise<any> {
|
|
298
|
+
const mappedEntities: any = {};
|
|
299
|
+
|
|
300
|
+
for (const relation of relatedEntities) {
|
|
301
|
+
const targetEntityType = relation.target_entity_type;
|
|
302
|
+
const targetEntityId = relation.target_entity_id;
|
|
303
|
+
|
|
304
|
+
const entityData = await this.getEntity(
|
|
305
|
+
targetEntityType,
|
|
306
|
+
targetEntityId,
|
|
307
|
+
loggedInUser,
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
if (!mappedEntities[targetEntityType]) {
|
|
311
|
+
mappedEntities[targetEntityType] = [];
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
mappedEntities[targetEntityType].push(entityData);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return mappedEntities;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// ----------------------------- update with relations
|
|
321
|
+
|
|
322
|
+
// ----------------------------- update entity with relations
|
|
323
|
+
async updateEntityWithRelations(
|
|
324
|
+
entityType: string,
|
|
325
|
+
id: number | string,
|
|
326
|
+
data: Record<string, any>,
|
|
327
|
+
loggedInUser: any,
|
|
328
|
+
): Promise<any> {
|
|
329
|
+
const organizationId = loggedInUser.organization_id;
|
|
330
|
+
const enterpriseId = loggedInUser.enterprise_id;
|
|
331
|
+
const { mappedEntities, ...mainData } = data;
|
|
332
|
+
|
|
333
|
+
// Update main entity
|
|
334
|
+
const updatedMainEntity = await this.updateEntity(
|
|
335
|
+
entityType,
|
|
336
|
+
id,
|
|
337
|
+
mainData,
|
|
338
|
+
loggedInUser,
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
const updatedRelations: Record<string, any> = {};
|
|
342
|
+
|
|
343
|
+
if (mappedEntities) {
|
|
344
|
+
const entityRelationRepo =
|
|
345
|
+
this.reflectionHelper.getRepoService('EntityRelation');
|
|
346
|
+
const getRelationDefs = await entityRelationRepo.find({
|
|
347
|
+
where: {
|
|
348
|
+
enterprise_id: enterpriseId,
|
|
349
|
+
source_entity_type: entityType,
|
|
350
|
+
},
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
for (const [targetEntityType, rawEntityData] of Object.entries(
|
|
354
|
+
mappedEntities,
|
|
355
|
+
)) {
|
|
356
|
+
const relationDef = getRelationDefs.find(
|
|
357
|
+
(r) => r.target_entity_type === targetEntityType,
|
|
358
|
+
);
|
|
359
|
+
if (!relationDef) continue;
|
|
360
|
+
|
|
361
|
+
const relationType = relationDef.relation_type;
|
|
362
|
+
const entityArray = Array.isArray(rawEntityData)
|
|
363
|
+
? rawEntityData
|
|
364
|
+
: [rawEntityData];
|
|
365
|
+
|
|
366
|
+
// Delete previous relations and related entities
|
|
367
|
+
// Create/update new entities & relations
|
|
368
|
+
const updatedEntities: any[] = [];
|
|
369
|
+
|
|
370
|
+
for (const item of entityArray) {
|
|
371
|
+
let targetEntityId;
|
|
372
|
+
let entityData;
|
|
373
|
+
|
|
374
|
+
if (item.id) {
|
|
375
|
+
// Update existing entity
|
|
376
|
+
await this.updateEntity(
|
|
377
|
+
targetEntityType,
|
|
378
|
+
item.id,
|
|
379
|
+
item,
|
|
380
|
+
loggedInUser,
|
|
381
|
+
Number(id), // pass main entity id as parent_id
|
|
382
|
+
);
|
|
383
|
+
targetEntityId = item.id;
|
|
384
|
+
entityData = await this.getEntity(
|
|
385
|
+
targetEntityType,
|
|
386
|
+
targetEntityId,
|
|
387
|
+
loggedInUser,
|
|
388
|
+
);
|
|
389
|
+
} else {
|
|
390
|
+
// Create new entity
|
|
391
|
+
const createdEntity = await this.createEntity(
|
|
392
|
+
targetEntityType,
|
|
393
|
+
item,
|
|
394
|
+
loggedInUser,
|
|
395
|
+
Number(id), // pass main entity id as parent_id
|
|
396
|
+
);
|
|
397
|
+
targetEntityId = createdEntity.insertId || createdEntity.id;
|
|
398
|
+
entityData = await this.getEntity(
|
|
399
|
+
targetEntityType,
|
|
400
|
+
targetEntityId,
|
|
401
|
+
loggedInUser,
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
// Insert relation as per new entity created
|
|
405
|
+
const entityRelationDataRepo =
|
|
406
|
+
this.reflectionHelper.getRepoService('EntityRelationData');
|
|
407
|
+
await entityRelationDataRepo.save({
|
|
408
|
+
organizationId: organizationId,
|
|
409
|
+
enterprise_id: enterpriseId,
|
|
410
|
+
source_entity_id: id,
|
|
411
|
+
source_entity_type: entityType,
|
|
412
|
+
target_entity_id: targetEntityId,
|
|
413
|
+
target_entity_type: targetEntityType,
|
|
414
|
+
relation_type: relationType,
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (relationType === 'ONE_TO_MANY') {
|
|
419
|
+
updatedEntities.push(entityData);
|
|
420
|
+
} else if (
|
|
421
|
+
relationType === 'ONE_TO_ONE' ||
|
|
422
|
+
relationType === 'MANY_TO_ONE'
|
|
423
|
+
) {
|
|
424
|
+
updatedEntities[0] = entityData; // single object
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Assign to response mappedEntities
|
|
429
|
+
updatedRelations[targetEntityType] =
|
|
430
|
+
relationType === 'ONE_TO_MANY' ? updatedEntities : updatedEntities[0];
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
return {
|
|
435
|
+
mainEntity: {
|
|
436
|
+
id,
|
|
437
|
+
entityType,
|
|
438
|
+
data: updatedMainEntity,
|
|
439
|
+
},
|
|
440
|
+
relatedEntities: updatedRelations,
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// -----------------------------
|
|
445
|
+
async updateEntity(
|
|
446
|
+
entityType: string,
|
|
447
|
+
id: number | string,
|
|
448
|
+
entityData: Record<string, any>,
|
|
449
|
+
loggedInUser: any,
|
|
450
|
+
mainID?: number,
|
|
451
|
+
): Promise<any> {
|
|
452
|
+
const enterprise_id = loggedInUser.enterprise_id;
|
|
453
|
+
|
|
454
|
+
const tableName = await this.getTableName(entityType, enterprise_id);
|
|
455
|
+
const validAttributes = await this.getAttributeCodes(
|
|
456
|
+
entityType,
|
|
457
|
+
enterprise_id,
|
|
458
|
+
);
|
|
459
|
+
|
|
460
|
+
const updates: string[] = [];
|
|
461
|
+
const values: any[] = [];
|
|
462
|
+
let idx = 1;
|
|
463
|
+
|
|
464
|
+
// Auto fields
|
|
465
|
+
entityData.modified_date = new Date();
|
|
466
|
+
if (loggedInUser) {
|
|
467
|
+
entityData.modified_by = loggedInUser.id;
|
|
468
|
+
|
|
469
|
+
if (!entityData.organization_id && entityData.entity_type !== 'ORG')
|
|
470
|
+
entityData.organization_id = loggedInUser.organization_id;
|
|
471
|
+
|
|
472
|
+
if (!entityData.enterprise_id)
|
|
473
|
+
entityData.enterprise_id = loggedInUser.enterprise_id;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
if (mainID) {
|
|
477
|
+
entityData.parent_id = mainID;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// Add bypass columns if needed
|
|
481
|
+
const bypassColumns = [
|
|
482
|
+
'created_date',
|
|
483
|
+
'created_by',
|
|
484
|
+
'modified_date',
|
|
485
|
+
'modified_by',
|
|
486
|
+
'organization_id',
|
|
487
|
+
'enterprise_id',
|
|
488
|
+
'level_type',
|
|
489
|
+
'level_id',
|
|
490
|
+
'status',
|
|
491
|
+
'entity_type',
|
|
492
|
+
'code',
|
|
493
|
+
'parent_id',
|
|
494
|
+
];
|
|
495
|
+
|
|
496
|
+
for (const col of bypassColumns) {
|
|
497
|
+
if (!validAttributes.some((attr) => attr.attribute_key === col)) {
|
|
498
|
+
validAttributes.push({
|
|
499
|
+
attribute_key: col,
|
|
500
|
+
db_datatype: 'text',
|
|
501
|
+
element_type: 'text',
|
|
502
|
+
is_hidden: false,
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Build SET clause
|
|
508
|
+
for (const key of Object.keys(entityData)) {
|
|
509
|
+
if (validAttributes.some((attr) => attr.attribute_key === key)) {
|
|
510
|
+
updates.push(`${key} = $${idx++}`);
|
|
511
|
+
values.push(entityData[key]);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
if (updates.length === 0) {
|
|
516
|
+
throw new Error('No valid attributes to update.');
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// WHERE clause placeholder
|
|
520
|
+
const idPlaceholder = `$${idx}`;
|
|
521
|
+
values.push(id);
|
|
522
|
+
|
|
523
|
+
const updateQuery = `
|
|
524
|
+
UPDATE ${this.schema}.${tableName}
|
|
525
|
+
SET ${updates.join(', ')}
|
|
526
|
+
WHERE id = ${idPlaceholder}
|
|
527
|
+
`;
|
|
528
|
+
|
|
529
|
+
return await this.entityManager.query(updateQuery, values);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
async getEntityByDataSource(
|
|
533
|
+
entityType: string,
|
|
534
|
+
id: number | string,
|
|
535
|
+
loggedInUser: any,
|
|
536
|
+
): Promise<any> {
|
|
537
|
+
const enterprise_id = loggedInUser.enterprise_id;
|
|
538
|
+
|
|
539
|
+
const dataSource = await this.getEntitySourceTableName(
|
|
540
|
+
entityType,
|
|
541
|
+
enterprise_id,
|
|
542
|
+
);
|
|
543
|
+
const validAttributes = await this.getAttributeCodes(
|
|
544
|
+
entityType,
|
|
545
|
+
enterprise_id,
|
|
546
|
+
false,
|
|
547
|
+
);
|
|
548
|
+
|
|
549
|
+
const columns = validAttributes
|
|
550
|
+
.map((attr) => `${attr.attribute_key}`)
|
|
551
|
+
.join(', ');
|
|
552
|
+
const selectQuery = `SELECT ${columns}
|
|
553
|
+
FROM ${dataSource}
|
|
554
|
+
WHERE id = $1`;
|
|
555
|
+
|
|
556
|
+
const result = await this.entityManager.query(selectQuery, [id]);
|
|
557
|
+
if (!result.length) return null;
|
|
558
|
+
|
|
559
|
+
const row = result[0];
|
|
560
|
+
|
|
561
|
+
// Convert boolean columns (1/0) into true/false
|
|
562
|
+
for (const attr of validAttributes) {
|
|
563
|
+
if (
|
|
564
|
+
attr.db_datatype == 'boolean' &&
|
|
565
|
+
row[attr.attribute_key] !== undefined
|
|
566
|
+
) {
|
|
567
|
+
row[attr.attribute_key] = row[attr.attribute_key] == 1 ? true : false;
|
|
568
|
+
} else if (
|
|
569
|
+
attr.element_type == 'upload' &&
|
|
570
|
+
row[attr.attribute_key] !== undefined
|
|
571
|
+
) {
|
|
572
|
+
row[attr.attribute_key] =
|
|
573
|
+
row[attr.attribute_key] != null
|
|
574
|
+
? await this.mediaDataService.getMediaDownloadUrl(
|
|
575
|
+
Number(row[attr.attribute_key]),
|
|
576
|
+
loggedInUser,
|
|
577
|
+
)
|
|
578
|
+
: null;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
return row;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// -----------------------------
|
|
586
|
+
//TODO : make it normal getEntity function make another function if for resolve data
|
|
587
|
+
async getEntity(
|
|
588
|
+
entityType: string,
|
|
589
|
+
id: number | string,
|
|
590
|
+
loggedInUser: any,
|
|
591
|
+
): Promise<any> {
|
|
592
|
+
const enterprise_id = loggedInUser.enterprise_id;
|
|
593
|
+
|
|
594
|
+
const entityMaster = await this.entityMasterRepo.getEntityByMappedEntityType(entityType, enterprise_id);
|
|
595
|
+
if (!entityMaster) return null;
|
|
596
|
+
|
|
597
|
+
const validAttributes = await this.getAttributeCodes(
|
|
598
|
+
entityType,
|
|
599
|
+
enterprise_id,
|
|
600
|
+
);
|
|
601
|
+
|
|
602
|
+
// const entityRepo = this.reflectionHelper.getRepoService(entityMaster?.entity_data_class);
|
|
603
|
+
|
|
604
|
+
const columns = validAttributes.map(attr => `t.${attr.attribute_key}`);
|
|
605
|
+
|
|
606
|
+
// const result = await entityRepo.find({
|
|
607
|
+
// where: {
|
|
608
|
+
// id: id
|
|
609
|
+
// },
|
|
610
|
+
// select: columns
|
|
611
|
+
// });
|
|
612
|
+
const selectQuery = `SELECT ${columns}
|
|
613
|
+
FROM ${this.schema}.${entityMaster.db_table_name} t
|
|
614
|
+
WHERE id = $1`;
|
|
615
|
+
|
|
616
|
+
const result = await this.entityManager.query(selectQuery, [id]);
|
|
617
|
+
if (!result.length) return null;
|
|
618
|
+
|
|
619
|
+
const row = result[0];
|
|
620
|
+
|
|
621
|
+
// Convert boolean columns (1/0) into true/false
|
|
622
|
+
for (const attr of validAttributes) {
|
|
623
|
+
if (
|
|
624
|
+
attr.db_datatype == 'boolean' &&
|
|
625
|
+
row[attr.attribute_key] !== undefined
|
|
626
|
+
) {
|
|
627
|
+
row[attr.attribute_key] = row[attr.attribute_key] == 1 ? true : false;
|
|
628
|
+
} else if (
|
|
629
|
+
attr.element_type == 'upload' &&
|
|
630
|
+
row[attr.attribute_key] !== undefined
|
|
631
|
+
) {
|
|
632
|
+
row[attr.attribute_key] =
|
|
633
|
+
row[attr.attribute_key] != null
|
|
634
|
+
? await this.mediaDataService.getMediaDownloadUrl(
|
|
635
|
+
Number(row[attr.attribute_key]),
|
|
636
|
+
loggedInUser,
|
|
637
|
+
)
|
|
638
|
+
: null;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
return row;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
private async getEntitySourceTableName(
|
|
646
|
+
entityType: string,
|
|
647
|
+
enterprise_id: string,
|
|
648
|
+
): Promise<string> {
|
|
649
|
+
const result = await this.entityMasterRepo.getEntityByMappedEntityType(
|
|
650
|
+
entityType,
|
|
651
|
+
enterprise_id,
|
|
652
|
+
);
|
|
653
|
+
|
|
654
|
+
if (!result) {
|
|
655
|
+
console.log(`Entity type '${entityType}' not found in frm_entity_master`);
|
|
656
|
+
throw new BadRequestException();
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
return result.data_source;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// -----------------------------
|
|
663
|
+
private async getTableName(
|
|
664
|
+
entityType: string,
|
|
665
|
+
enterprise_id: string,
|
|
666
|
+
): Promise<string> {
|
|
667
|
+
let entityMaster = await this.entityMasterRepo.getEntityByMappedEntityType(
|
|
668
|
+
entityType,
|
|
669
|
+
enterprise_id,
|
|
670
|
+
);
|
|
671
|
+
|
|
672
|
+
if (!entityMaster) {
|
|
673
|
+
console.log(`Entity type '${entityType}' not found in frm_entity_master`);
|
|
674
|
+
throw new BadRequestException();
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
return entityMaster.db_table_name;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
private async getAttributeCodes(
|
|
681
|
+
entityType: string,
|
|
682
|
+
enterprise_id: string,
|
|
683
|
+
isHidden = true,
|
|
684
|
+
) {
|
|
685
|
+
const attributeMasterRepo =
|
|
686
|
+
this.reflectionHelper.getRepoService('AttributeMaster');
|
|
687
|
+
|
|
688
|
+
const qb = attributeMasterRepo
|
|
689
|
+
.createQueryBuilder('fea')
|
|
690
|
+
.select('fea.attribute_key', 'attribute_key')
|
|
691
|
+
.addSelect('MAX(fea.db_datatype)', 'db_datatype')
|
|
692
|
+
.addSelect('MAX(fea.element_type)', 'element_type')
|
|
693
|
+
.addSelect('bool_or(fea.is_hidden)', 'is_hidden')
|
|
694
|
+
.where('fea.mapped_entity_type = :entityType', { entityType })
|
|
695
|
+
.andWhere('fea.enterprise_id = :enterprise_id', { enterprise_id });
|
|
696
|
+
|
|
697
|
+
if (isHidden) {
|
|
698
|
+
qb.andWhere('(fea.is_hidden IS NULL OR fea.is_hidden = false)');
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
qb.groupBy('fea.attribute_key');
|
|
702
|
+
|
|
703
|
+
const result = await qb.getRawMany();
|
|
704
|
+
|
|
705
|
+
return result.map((row: any) => ({
|
|
706
|
+
attribute_key: row.attribute_key,
|
|
707
|
+
db_datatype: row.db_datatype,
|
|
708
|
+
element_type: row.element_type,
|
|
709
|
+
is_hidden: row.is_hidden != null ? row.is_hidden === true : undefined,
|
|
710
|
+
}));
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
private async deleteEntity(
|
|
714
|
+
entityType: string,
|
|
715
|
+
id: number | string,
|
|
716
|
+
loggedInUser: any,
|
|
717
|
+
): Promise<any> {
|
|
718
|
+
const enterprise_id = loggedInUser.enterprise_id;
|
|
719
|
+
|
|
720
|
+
const tableName = await this.getTableName(entityType, enterprise_id);
|
|
721
|
+
|
|
722
|
+
const deleteQuery = `DELETE
|
|
723
|
+
FROM ${this.schema}.${tableName}
|
|
724
|
+
WHERE id = $1`;
|
|
725
|
+
const result = await this.entityManager.query(deleteQuery, [id]);
|
|
726
|
+
return result;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// -----------------------------
|
|
730
|
+
|
|
731
|
+
async getEntitiesDropdownList(
|
|
732
|
+
loggedInUser: any,
|
|
733
|
+
appcode?: string,
|
|
734
|
+
): Promise<any> {
|
|
735
|
+
|
|
736
|
+
const entityMasters = await this.entityMasterRepo.findByEnterpriseIdAndAppCode(loggedInUser.enterprise_id, appcode);
|
|
737
|
+
|
|
738
|
+
let dropdown = [] as any;
|
|
739
|
+
entityMasters.map(entityMaster => dropdown.push({
|
|
740
|
+
label: entityMaster.name,
|
|
741
|
+
value: entityMaster.mapped_entity_type,
|
|
742
|
+
}));
|
|
743
|
+
|
|
744
|
+
return dropdown;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
async getCode(entityType: string, loggedInUser: any): Promise<string> {
|
|
748
|
+
const enterprise_id = loggedInUser.enterprise_id;
|
|
749
|
+
|
|
750
|
+
// 1. Get db_table_name from entity master
|
|
751
|
+
|
|
752
|
+
const result = await this.entityMasterRepo.getEntityByMappedEntityType(
|
|
753
|
+
entityType,
|
|
754
|
+
enterprise_id,
|
|
755
|
+
);
|
|
756
|
+
|
|
757
|
+
if (!result) {
|
|
758
|
+
throw new Error(
|
|
759
|
+
`Entity type '${entityType}' not found in frm_entity_master for enterprise '${enterprise_id}'`,
|
|
760
|
+
);
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
const tableName = result.db_table_name;
|
|
764
|
+
|
|
765
|
+
// 2. Get current max sequence number from that table
|
|
766
|
+
const seqResult = await this.entityManager.query(
|
|
767
|
+
`SELECT MAX(id) AS max_seq_no
|
|
768
|
+
FROM ${tableName}
|
|
769
|
+
WHERE entity_type = $1`,
|
|
770
|
+
[entityType],
|
|
771
|
+
);
|
|
772
|
+
|
|
773
|
+
let maxSeqNo = seqResult?.[0]?.max_seq_no
|
|
774
|
+
? Number(seqResult[0].max_seq_no)
|
|
775
|
+
: 0;
|
|
776
|
+
|
|
777
|
+
maxSeqNo += 1;
|
|
778
|
+
|
|
779
|
+
// 3. Return generated code
|
|
780
|
+
return `${entityType}${maxSeqNo}`;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
async getResolvedEntity(
|
|
784
|
+
id: number,
|
|
785
|
+
entity: string,
|
|
786
|
+
loggedInUser: UserData,
|
|
787
|
+
): Promise<any> {
|
|
788
|
+
const leadData = await this.getEntityWithRelation(entity, id, loggedInUser);
|
|
789
|
+
|
|
790
|
+
const { mappedEntities, ...data } = leadData as any;
|
|
791
|
+
|
|
792
|
+
const resolvedData = await this.resolverService.getResolvedData(
|
|
793
|
+
loggedInUser,
|
|
794
|
+
data,
|
|
795
|
+
entity,
|
|
796
|
+
);
|
|
797
|
+
|
|
798
|
+
if (mappedEntities) {
|
|
799
|
+
resolvedData.mappedEntities = {};
|
|
800
|
+
for (const [entityType, entities] of Object.entries(mappedEntities)) {
|
|
801
|
+
if (Array.isArray(entities)) {
|
|
802
|
+
resolvedData.mappedEntities[entityType] = [];
|
|
803
|
+
for (const item of entities) {
|
|
804
|
+
const resolvedItem = await this.resolverService.getResolvedData(
|
|
805
|
+
loggedInUser,
|
|
806
|
+
item,
|
|
807
|
+
entityType,
|
|
808
|
+
);
|
|
809
|
+
resolvedData.mappedEntities[entityType].push(resolvedItem);
|
|
810
|
+
}
|
|
811
|
+
} else {
|
|
812
|
+
resolvedData.mappedEntities[entityType] =
|
|
813
|
+
await this.resolverService.getResolvedData(
|
|
814
|
+
loggedInUser,
|
|
815
|
+
entities,
|
|
816
|
+
entityType,
|
|
817
|
+
);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
return resolvedData;
|
|
823
|
+
}
|
|
824
|
+
}
|