From 47a6cd9c62b2ea3c4a7e4e4551e1c58971b8276e Mon Sep 17 00:00:00 2001 From: Dragos-Paul Strat Date: Wed, 24 Jul 2024 17:39:12 +0300 Subject: [PATCH 1/5] feat: [590] wip work on adding the fields --- .../1721829705666-NewGeneralFields.ts | 41 +++++++++++++++++++ .../constants/errors.constants.ts | 14 +++++-- .../dto/create-organization-general.dto.ts | 25 +++++++++++ .../entities/organization-general.entity.ts | 19 +++++++++ .../services/organization-request.service.ts | 19 ++++++--- .../services/organization.service.ts | 34 ++++++++++++--- .../src/assets/locales/ro/translation.json | 6 +++ .../OrganizationGeneral.tsx | 16 ++++---- .../OrganizationGeneralConfig.ts | 20 +++++++++ 9 files changed, 170 insertions(+), 24 deletions(-) create mode 100644 backend/src/migrations/1721829705666-NewGeneralFields.ts diff --git a/backend/src/migrations/1721829705666-NewGeneralFields.ts b/backend/src/migrations/1721829705666-NewGeneralFields.ts new file mode 100644 index 00000000..0b55a34c --- /dev/null +++ b/backend/src/migrations/1721829705666-NewGeneralFields.ts @@ -0,0 +1,41 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class NewGeneralFields1721829705666 implements MigrationInterface { + name = 'NewGeneralFields1721829705666'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "organization_general" ADD "association_registry_number" text`, + ); + await queryRunner.query( + `ALTER TABLE "organization_general" ADD "association_registry_part" text`, + ); + await queryRunner.query( + `ALTER TABLE "organization_general" ADD "association_registry_section" text`, + ); + await queryRunner.query( + `ALTER TABLE "organization_general" ADD "association_registry_issuer" text`, + ); + await queryRunner.query( + `ALTER TABLE "organization_general" ADD "national_registry_number" text`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "organization_general" DROP COLUMN "national_registry_number"`, + ); + await queryRunner.query( + `ALTER TABLE "organization_general" DROP COLUMN "association_registry_issuer"`, + ); + await queryRunner.query( + `ALTER TABLE "organization_general" DROP COLUMN "association_registry_section"`, + ); + await queryRunner.query( + `ALTER TABLE "organization_general" DROP COLUMN "association_registry_part"`, + ); + await queryRunner.query( + `ALTER TABLE "organization_general" DROP COLUMN "association_registry_number"`, + ); + } +} diff --git a/backend/src/modules/organization/constants/errors.constants.ts b/backend/src/modules/organization/constants/errors.constants.ts index 9c504819..1702cb3c 100644 --- a/backend/src/modules/organization/constants/errors.constants.ts +++ b/backend/src/modules/organization/constants/errors.constants.ts @@ -175,9 +175,17 @@ export const ORGANIZATION_REQUEST_ERRORS = { message: 'An organization with this cui already exists', errorCode: 'REQ_007', }, - RAF_NUMBER_EXISTS: { - message: 'An organization with this rafNumber already exists', - errorCode: 'REQ_008', + + ASSOCIATION_REGISTRY_NUMBER_EXISTS: { + message: + 'An organization with this asscotiation registry number already exists', + errorCode: 'REQ_013', + }, + + NATIONAL_REGISTRY_NUMBER_EXISTS: { + message: + 'An organization with this national registry number already exists', + errorCode: 'REQ_014', }, ORGANIZATION_NAME_EXISTS: { message: 'An organization with this name already exists', diff --git a/backend/src/modules/organization/dto/create-organization-general.dto.ts b/backend/src/modules/organization/dto/create-organization-general.dto.ts index 0089ac6b..f22708d9 100644 --- a/backend/src/modules/organization/dto/create-organization-general.dto.ts +++ b/backend/src/modules/organization/dto/create-organization-general.dto.ts @@ -75,6 +75,31 @@ export class CreateOrganizationGeneralDto { @Trim() cui: string; + @IsString() + @MaxLength(30) + @Trim() + associationRegistryNumber: string; + + @IsString() + @MaxLength(20) + @Trim() + associationRegistryPart: string; + + @IsString() + @MaxLength(20) + @Trim() + associationRegistrySection: string; + + @IsString() + @MaxLength(100) + @Trim() + associationRegistryIssuer: string; + + @IsString() + @MaxLength(30) + @Trim() + nationalRegistryNumber: string; + /* Organization Register of Associations and Foundations Number @example 1249/A/2020 diff --git a/backend/src/modules/organization/entities/organization-general.entity.ts b/backend/src/modules/organization/entities/organization-general.entity.ts index 38add69d..6c8cce52 100644 --- a/backend/src/modules/organization/entities/organization-general.entity.ts +++ b/backend/src/modules/organization/entities/organization-general.entity.ts @@ -30,6 +30,25 @@ export class OrganizationGeneral extends BaseEntity { @Column({ type: 'text', name: 'cui', unique: true }) cui: string; + @Column({ type: 'text', name: 'association_registry_number', nullable: true }) + associationRegistryNumber: string; + + @Column({ type: 'text', name: 'association_registry_part', nullable: true }) + associationRegistryPart: string; + + @Column({ + type: 'text', + name: 'association_registry_section', + nullable: true, + }) + associationRegistrySection: string; + + @Column({ type: 'text', name: 'association_registry_issuer', nullable: true }) + associationRegistryIssuer: string; + + @Column({ type: 'text', name: 'national_registry_number', nullable: true }) + nationalRegistryNumber: string; + @Column({ type: 'text', name: 'raf_number', unique: true }) rafNumber: string; diff --git a/backend/src/modules/organization/services/organization-request.service.ts b/backend/src/modules/organization/services/organization-request.service.ts index dcf7b219..98689dea 100644 --- a/backend/src/modules/organization/services/organization-request.service.ts +++ b/backend/src/modules/organization/services/organization-request.service.ts @@ -172,13 +172,21 @@ export class OrganizationRequestService { if (organization) { // 2.1 validate organization general if (organization.general) { - const { cui, rafNumber, name, email, phone, alias } = - organization.general; + const { + cui, + name, + email, + phone, + alias, + associationRegistryNumber, + nationalRegistryNumber, + } = organization.general; errors.push( ...(await this.organizationService.validateOrganizationGeneral( cui, - rafNumber, + associationRegistryNumber, + nationalRegistryNumber, name, email, phone, @@ -340,9 +348,8 @@ export class OrganizationRequestService { public async sendRestrictRequest(organizationId: number): Promise { try { - const organization = await this.organizationService.findWithUsers( - organizationId, - ); + const organization = + await this.organizationService.findWithUsers(organizationId); this.eventEmitter.emit( EVENTS.DISABLE_ORGANIZATION_REQUEST, diff --git a/backend/src/modules/organization/services/organization.service.ts b/backend/src/modules/organization/services/organization.service.ts index 9cb4328f..41fc07ab 100644 --- a/backend/src/modules/organization/services/organization.service.ts +++ b/backend/src/modules/organization/services/organization.service.ts @@ -407,7 +407,15 @@ export class OrganizationService { 'organizationGeneral.phone': 'Organization Phone', 'organizationGeneral.yearCreated': 'Year Created', 'organizationGeneral.cui': 'CUI', - 'organizationGeneral.rafNumber': 'RAF Number', + 'organizationGeneral.associationRegistryNumber': + 'Association Registry Number', + 'organizationGeneral.associationRegistryPart': + 'Association Registry Part', + 'organizationGeneral.associationRegistrySection': + 'Association Registry Section', + 'organizationGeneral.associationRegistryIssuer': + 'Association Registry Issuer', + 'organizationGeneral.nationalRegistryNumber': 'National Registry Number', 'organizationGeneral.shortDescription': 'Short Description', 'organizationGeneral.description': 'Description', 'organizationGeneral.address': 'Address', @@ -1381,7 +1389,8 @@ export class OrganizationService { public async validateOrganizationGeneral( cui: string, - rafNumber: string, + associationRegistryNumber: string, + nationalRegistryNumber: string, name: string, email: string, phone: string, @@ -1410,15 +1419,28 @@ export class OrganizationService { ); } - const organizationWithRafNumber = + const organizationWithAssociationRegistryNumber = await this.organizationGeneralService.findOne({ - where: { rafNumber }, + where: { associationRegistryNumber }, }); - if (organizationWithRafNumber) { + if (organizationWithAssociationRegistryNumber) { errors.push( new BadRequestException( - ORGANIZATION_REQUEST_ERRORS.CREATE.RAF_NUMBER_EXISTS, + ORGANIZATION_REQUEST_ERRORS.CREATE.ASSOCIATION_REGISTRY_NUMBER_EXISTS, + ), + ); + } + + const organizationWithNationalRegistryNumber = + await this.organizationGeneralService.findOne({ + where: { nationalRegistryNumber }, + }); + + if (organizationWithNationalRegistryNumber) { + errors.push( + new BadRequestException( + ORGANIZATION_REQUEST_ERRORS.CREATE.NATIONAL_REGISTRY_NUMBER_EXISTS, ), ); } diff --git a/frontend/src/assets/locales/ro/translation.json b/frontend/src/assets/locales/ro/translation.json index 46676876..63a4937b 100644 --- a/frontend/src/assets/locales/ro/translation.json +++ b/frontend/src/assets/locales/ro/translation.json @@ -312,6 +312,12 @@ "label": "Număr de înregistrare în RAF*", "placeholder": "56/14.09.2020" }, + "association_registry_number": { + "required": "Numărul de înregistrare în Registrul Special este obligatoriu", + "max": "Numărul de înregistrare în Registrul Special poate avea maxim 30 de caractere", + "helper": "Numărul care apare pe Certificatul de înscriere a persoanei juridice fără scop patrimonial.", + "label": "Număr si data de înscriere în Registrul Special" + }, "city": { "required": "Localitatea este obligatorie", "label": "Localitate*" diff --git a/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneral.tsx b/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneral.tsx index 09c5270c..6ee5ea32 100644 --- a/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneral.tsx +++ b/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneral.tsx @@ -290,23 +290,22 @@ const OrganizationGeneral = () => { }} /> { return ( ); }} @@ -571,7 +570,6 @@ const OrganizationGeneral = () => { name={OrganizationGeneralConfig.hasSameAddress.key} control={control} render={({ field: { onChange, value } }) => { - console.log(value); return ( = { placeholder: '', }, }, + associationRegistryNumber: { + key: 'associationRegistryNumber', + rules: { + maxLength: { + value: 30, + message: translations.associationRegistryNumber.max, + }, + }, + config: { + type: 'text', + label: translations.associationRegistryNumber.label, + helperText: translations.associationRegistryNumber.helper, + placeholder: 'nr/zz.ll.aaaa', + }, + }, rafNumber: { key: 'rafNumber', rules: { From e5312eea32a5cf8809504ccf646696254c5a4ab1 Mon Sep 17 00:00:00 2001 From: Dragos-Paul Strat Date: Thu, 25 Jul 2024 12:00:55 +0300 Subject: [PATCH 2/5] feat: [590] add issuer table, migration and seed + adjustments for translations --- .../src/migrations/1721896584559-AddIssuer.ts | 34 + backend/src/migrations/seed/issuers.seed.ts | 970 ++++++++++++++++++ .../dto/create-organization-general.dto.ts | 4 +- backend/src/shared/entities/index.ts | 1 + backend/src/shared/entities/issuer.entity.ts | 8 + backend/src/shared/shared.module.ts | 2 + .../src/assets/locales/ro/translation.json | 30 +- .../components/CreateOrganizationGeneral.tsx | 102 +- .../OrganizationGeneral.tsx | 87 ++ .../OrganizationGeneralConfig.ts | 115 ++- 10 files changed, 1342 insertions(+), 11 deletions(-) create mode 100644 backend/src/migrations/1721896584559-AddIssuer.ts create mode 100644 backend/src/migrations/seed/issuers.seed.ts create mode 100644 backend/src/shared/entities/issuer.entity.ts diff --git a/backend/src/migrations/1721896584559-AddIssuer.ts b/backend/src/migrations/1721896584559-AddIssuer.ts new file mode 100644 index 00000000..cce38470 --- /dev/null +++ b/backend/src/migrations/1721896584559-AddIssuer.ts @@ -0,0 +1,34 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; +import { ISSUERS } from './seed/issuers.seed'; +import { Issuer } from 'src/shared/entities'; +export class AddIssuer1721896584559 implements MigrationInterface { + name = 'AddIssuer1721896584559'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "_issuer" ("id" SERIAL NOT NULL, "deleted_on" TIMESTAMP WITH TIME ZONE, "created_on" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_on" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "name" text NOT NULL, CONSTRAINT "PK_cfe878b7aa3dc098f2ac736adc6" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE INDEX "IDX_20b3d0cad6a13638d5d485eada" ON "_issuer" ("created_on") `, + ); + await queryRunner.manager + .createQueryBuilder() + .insert() + .into(Issuer) + .values(ISSUERS) + .execute(); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.manager + .createQueryBuilder() + .delete() + .from(Issuer) + .execute(); + + await queryRunner.query( + `DROP INDEX "public"."IDX_20b3d0cad6a13638d5d485eada"`, + ); + await queryRunner.query(`DROP TABLE "_issuer"`); + } +} diff --git a/backend/src/migrations/seed/issuers.seed.ts b/backend/src/migrations/seed/issuers.seed.ts new file mode 100644 index 00000000..299b11a9 --- /dev/null +++ b/backend/src/migrations/seed/issuers.seed.ts @@ -0,0 +1,970 @@ +export const ISSUERS = [ + { + id: 1, + name: 'Curtea de Apel ALBA IULIA', + }, + { + id: 2, + name: 'Tribunalul ALBA', + }, + { + id: 3, + name: 'Judecătoria AIUD', + }, + { + id: 4, + name: 'Judecătoria ALBA IULIA', + }, + { + id: 5, + name: 'Judecătoria BLAJ', + }, + { + id: 6, + name: 'Judecătoria CÂMPENI', + }, + { + id: 7, + name: 'Judecătoria SEBEŞ', + }, + { + id: 8, + name: 'Tribunalul ARAD', + }, + { + id: 9, + name: 'Judecătoria CHIŞINEU CRIŞ', + }, + { + id: 10, + name: 'Judecătoria GURA HONŢ', + }, + { + id: 11, + name: 'Judecătoria INEU', + }, + { + id: 12, + name: 'Judecătoria LIPOVA', + }, + { + id: 13, + name: 'Curtea de Apel PITEŞTI', + }, + { + id: 14, + name: 'Tribunalul ARGEŞ', + }, + { + id: 15, + name: 'Tribunalul Specializat ARGEŞ', + }, + { + id: 16, + name: 'Judecătoria CĂMPULUNG', + }, + { + id: 17, + name: 'Judecătoria COSTEŞTI', + }, + { + id: 18, + name: 'Judecătoria CURTEA DE ARGEŞ', + }, + { + id: 19, + name: 'Judecătoria PITEŞTI', + }, + { + id: 20, + name: 'Judecătoria TOPOLOVENI', + }, + { + id: 21, + name: 'Curtea de Apel BACĂU', + }, + { + id: 22, + name: 'Tribunalul BACĂU', + }, + { + id: 23, + name: 'Judecătoria BACĂU', + }, + { + id: 24, + name: 'Judecătoria BUHUŞI', + }, + { + id: 25, + name: 'Judecătoria MOINEŞTI', + }, + { + id: 26, + name: 'Judecătoria ONEŞTI', + }, + { + id: 27, + name: 'Judecătoria PODU TURCULUI', + }, + { + id: 28, + name: 'Curtea de Apel ORADEA', + }, + { + id: 29, + name: 'Tribunalul BIHOR', + }, + { + id: 30, + name: 'Judecătoria ALESD', + }, + { + id: 31, + name: 'Judecătoria BEIUŞ', + }, + { + id: 32, + name: 'Judecătoria MARGHITA', + }, + { + id: 33, + name: 'Judecătoria ORADEA', + }, + { + id: 34, + name: 'Judecătoria SALONTA', + }, + { + id: 35, + name: 'Tribunalul BISTRIŢA NĂSĂUD', + }, + { + id: 36, + name: 'Judecătoria BECLEAN', + }, + { + id: 37, + name: 'Judecătoria BISTRIŢA', + }, + { + id: 38, + name: 'Judecătoria NĂSĂUD', + }, + { + id: 39, + name: 'Tribunalul BOTOŞANI', + }, + { + id: 40, + name: 'Judecătoria BOTOŞANI', + }, + { + id: 41, + name: 'Judecătoria Darabani', + }, + { + id: 42, + name: 'Judecătoria DOROHOI', + }, + { + id: 43, + name: 'Judecătoria SĂVENI', + }, + { + id: 44, + name: 'Tribunalul BRĂILA', + }, + { + id: 45, + name: 'Judecătoria BRĂILA', + }, + { + id: 46, + name: 'Judecătoria FĂUREI', + }, + { + id: 47, + name: 'Judecătoria ÎNSURĂŢEI', + }, + { + id: 48, + name: 'Curtea de Apel BRAŞOV', + }, + { + id: 49, + name: 'Tribunalul BRAŞOV', + }, + { + id: 50, + name: 'Tribunalul pentru minori şi familie BRAŞOV', + }, + { + id: 51, + name: 'Judecătoria BRAŞOV', + }, + { + id: 52, + name: 'Judecătoria FĂGĂRAŞ', + }, + { + id: 53, + name: 'Judecătoria RUPEA', + }, + { + id: 54, + name: 'Judecătoria ZĂRNEŞTI', + }, + { + id: 55, + name: 'Curtea de Apel BUCUREŞTI', + }, + { + id: 56, + name: 'Curtea Militara de Apel BUCUREŞTI', + }, + { + id: 57, + name: 'Tribunalul BUCUREŞTI', + }, + { + id: 58, + name: 'Tribunalul Militar BUCUREŞTI', + }, + { + id: 59, + name: 'Tribunalul Militar Teritorial BUCUREŞTI', + }, + { + id: 60, + name: 'Judecătoria SECTORUL 1 BUCUREŞTI', + }, + { + id: 61, + name: 'Judecătoria SECTORUL 2 BUCUREŞTI', + }, + { + id: 62, + name: 'Judecătoria SECTORUL 3 BUCUREŞTI', + }, + { + id: 63, + name: 'Judecătoria SECTORUL 4 BUCUREŞTI', + }, + { + id: 64, + name: 'Judecătoria SECTORUL 5 BUCUREŞTI', + }, + { + id: 65, + name: 'Judecătoria SECTORUL 6 BUCUREŞTI', + }, + { + id: 66, + name: 'Tribunalul BUZĂU', + }, + { + id: 67, + name: 'Judecătoria BUZĂU', + }, + { + id: 68, + name: 'Judecătoria PĂTÂRLAGELE', + }, + { + id: 69, + name: 'Judecătoria POGOANELE', + }, + { + id: 70, + name: 'Judecătoria RÂMNICU SARAT', + }, + { + id: 71, + name: 'Tribunalul CĂLĂRAŞI', + }, + { + id: 72, + name: 'Judecătoria CĂLĂRAŞI', + }, + { + id: 73, + name: 'Judecătoria LEHLIU-GARA', + }, + { + id: 74, + name: 'Judecătoria OLTENIŢA', + }, + { + id: 75, + name: 'Tribunalul CARAŞ SEVERIN', + }, + { + id: 76, + name: 'Judecătoria CARANSEBEŞ', + }, + { + id: 77, + name: 'Judecătoria MOLDOVA-NOUĂ', + }, + { + id: 78, + name: 'Judecătoria ORAVIŢA', + }, + { + id: 79, + name: 'Judecătoria REŞITA', + }, + { + id: 80, + name: 'Curtea de Apel CLUJ', + }, + { + id: 81, + name: 'Tribunalul CLUJ', + }, + { + id: 82, + name: 'Tribunalul Militar CLUJ-NAPOCA', + }, + { + id: 83, + name: 'Tribunalul Specializat CLUJ', + }, + { + id: 84, + name: 'Judecătoria CLUJ-NAPOCA', + }, + { + id: 85, + name: 'Judecătoria DEJ', + }, + { + id: 86, + name: 'Judecătoria GHERLA', + }, + { + id: 87, + name: 'Judecătoria HUEDIN', + }, + { + id: 88, + name: 'Judecătoria TURDA', + }, + { + id: 89, + name: 'Curtea de Apel CONSTANŢA', + }, + { + id: 90, + name: 'Tribunalul CONSTANŢA', + }, + { + id: 91, + name: 'Judecătoria CONSTANŢA', + }, + { + id: 92, + name: 'Judecătoria MANGALIA', + }, + { + id: 93, + name: 'Judecătoria MEDGIDIA', + }, + { + id: 94, + name: 'Judecătoria HÂRŞOVA', + }, + { + id: 95, + name: 'Tribunalul COVASNA', + }, + { + id: 96, + name: 'Judecătoria ÎNTORSURA BUZĂULUI', + }, + { + id: 97, + name: 'Judecătoria SFÂNTU GHEORGHE', + }, + { + id: 98, + name: 'Judecătoria TÂRGU SECUIESC', + }, + { + id: 99, + name: 'Tribunalul DÂMBOVIŢA', + }, + { + id: 100, + name: 'Judecătoria GĂEŞTI', + }, + { + id: 101, + name: 'Judecătoria MORENI', + }, + { + id: 102, + name: 'Judecătoria PUCIOASA', + }, + { + id: 103, + name: 'Judecătoria RĂCARI', + }, + { + id: 104, + name: 'Judecătoria TÂRGOVIŞTE', + }, + { + id: 105, + name: 'Curtea de Apel CRAIOVA', + }, + { + id: 106, + name: 'Tribunalul DOLJ', + }, + { + id: 107, + name: 'Judecătoria BĂILEŞTI', + }, + { + id: 108, + name: 'Judecătoria CALAFAT', + }, + { + id: 109, + name: 'Judecătoria CRAIOVA', + }, + { + id: 110, + name: 'Judecătoria FILIAŞI', + }, + { + id: 111, + name: 'Judecătoria SEGARCEA', + }, + { + id: 112, + name: 'Curtea de Apel GALAŢI', + }, + { + id: 113, + name: 'Tribunalul GALAŢI', + }, + { + id: 114, + name: 'Judecătoria GALAŢI', + }, + { + id: 115, + name: 'Judecătoria TÂRGU BUJOR', + }, + { + id: 116, + name: 'Judecătoria TECUCI', + }, + { + id: 117, + name: 'Judecătoria LIEŞTI', + }, + { + id: 118, + name: 'Tribunalul GIURGIU', + }, + { + id: 119, + name: 'Judecătoria BOLINTIN VALE', + }, + { + id: 120, + name: 'Judecătoria GIURGIU', + }, + { + id: 121, + name: 'Tribunalul GORJ', + }, + { + id: 122, + name: 'Judecătoria MOTRU', + }, + { + id: 123, + name: 'Judecătoria NOVACI', + }, + { + id: 124, + name: 'Judecătoria TÂRGU-CĂRBUNEŞTI', + }, + { + id: 125, + name: 'Judecătoria TÂRGU JIU', + }, + { + id: 126, + name: 'Tribunalul HARGHITA', + }, + { + id: 127, + name: 'Judecătoria GHEORGHENI', + }, + { + id: 128, + name: 'Judecătoria MIERCUREA CIUC', + }, + { + id: 129, + name: 'Judecătoria ODORHEIUL SECUIESC', + }, + { + id: 130, + name: 'Judecătoria TOPLIŢA', + }, + { + id: 131, + name: 'Tribunalul HUNEDOARA', + }, + { + id: 132, + name: 'Judecătoria BRAD', + }, + { + id: 133, + name: 'Judecătoria DEVA', + }, + { + id: 134, + name: 'Judecătoria HAŢEG', + }, + { + id: 135, + name: 'Judecătoria HUNEDOARA', + }, + { + id: 136, + name: 'Judecătoria ORAŞTIE', + }, + { + id: 137, + name: 'Judecătoria PETROŞANI', + }, + { + id: 138, + name: 'Tribunalul IALOMIŢA', + }, + { + id: 139, + name: 'Judecătoria FETEŞTI', + }, + { + id: 140, + name: 'Judecătoria SLOBOZIA', + }, + { + id: 141, + name: 'Judecătoria URZICENI', + }, + { + id: 142, + name: 'Curtea de Apel IAŞI', + }, + { + id: 143, + name: 'Tribunalul IAŞI', + }, + { + id: 144, + name: 'Tribunalul Militar IAŞI', + }, + { + id: 145, + name: 'Judecătoria PAŞCANI', + }, + { + id: 146, + name: 'Judecătoria HÂRLĂU', + }, + { + id: 147, + name: 'Judecătoria IAŞI', + }, + { + id: 148, + name: 'Judecătoria RĂDUCĂNENI', + }, + { + id: 149, + name: 'Tribunalul ILFOV', + }, + { + id: 150, + name: 'Judecătoria BUFTEA', + }, + { + id: 151, + name: 'Judecătoria CORNETU', + }, + { + id: 152, + name: 'Tribunalul MARAMUREŞ', + }, + { + id: 153, + name: 'Judecătoria BAIA MARE', + }, + { + id: 154, + name: 'Judecătoria DRAGOMIREŞTI', + }, + { + id: 155, + name: 'Judecătoria SIGHETU MARMAŢIEI', + }, + { + id: 156, + name: 'Judecătoria TÂRGU LAPUŞ', + }, + { + id: 157, + name: 'Judecătoria VIŞEU DE SUS', + }, + { + id: 158, + name: 'Tribunalul MEHEDINŢI', + }, + { + id: 159, + name: 'Judecătoria BAIA DE ARAMĂ', + }, + { + id: 160, + name: 'Judecătoria DROBETA-TURNU SEVERIN', + }, + { + id: 161, + name: 'Judecătoria ORŞOVA', + }, + { + id: 162, + name: 'Judecătoria STREHAIA', + }, + { + id: 163, + name: 'Judecătoria VÂNJU MARE', + }, + { + id: 164, + name: 'Curtea de Apel TÂRGU MUREŞ', + }, + { + id: 165, + name: 'Tribunalul MUREŞ', + }, + { + id: 166, + name: 'Tribunalul Specializat MUREŞ', + }, + { + id: 167, + name: 'Judecătoria LUDUŞ', + }, + { + id: 168, + name: 'Judecătoria REGHIN', + }, + { + id: 169, + name: 'Judecătoria SIGHIŞOARA', + }, + { + id: 170, + name: 'Judecătoria TÂRGU MUREŞ', + }, + { + id: 171, + name: 'Judecătoria TÂRNAVENI', + }, + { + id: 172, + name: 'Tribunalul NEAMŢ', + }, + { + id: 173, + name: 'Judecătoria BICAZ', + }, + { + id: 174, + name: 'Judecătoria PIATRA-NEAMT', + }, + { + id: 175, + name: 'Judecătoria ROMAN', + }, + { + id: 176, + name: 'Judecătoria TÂRGU NEAMŢ', + }, + { + id: 177, + name: 'Tribunalul OLT', + }, + { + id: 178, + name: 'Judecătoria BALŞ', + }, + { + id: 179, + name: 'Judecătoria CARACAL', + }, + { + id: 180, + name: 'Judecătoria CORABIA', + }, + { + id: 181, + name: 'Judecătoria SLATINA', + }, + { + id: 182, + name: 'Curtea de Apel PLOIEŞTI', + }, + { + id: 183, + name: 'Tribunalul PRAHOVA', + }, + { + id: 184, + name: 'Judecătoria CÂMPINA', + }, + { + id: 185, + name: 'Judecătoria MIZIL', + }, + { + id: 186, + name: 'Judecătoria PLOIEŞTI', + }, + { + id: 187, + name: 'Judecătoria SINAIA', + }, + { + id: 188, + name: 'Judecătoria VĂLENII DE MUNTE', + }, + { + id: 189, + name: 'Tribunalul SĂLAJ', + }, + { + id: 190, + name: 'Judecătoria ŞIMLEUL SILVANIEI', + }, + { + id: 191, + name: 'Judecătoria ZALĂU', + }, + { + id: 192, + name: 'Judecătoria JIBOU', + }, + { + id: 193, + name: 'Tribunalul SATU MARE', + }, + { + id: 194, + name: 'Judecătoria CAREI', + }, + { + id: 195, + name: 'Judecătoria NEGREŞTI-OAŞ', + }, + { + id: 196, + name: 'Judecătoria SATU MARE', + }, + { + id: 197, + name: 'Tribunalul SIBIU', + }, + { + id: 198, + name: 'Judecătoria AGNITA', + }, + { + id: 199, + name: 'Judecătoria MEDIAŞ', + }, + { + id: 200, + name: 'Judecătoria SALIŞTE', + }, + { + id: 201, + name: 'Judecătoria SIBIU', + }, + { + id: 202, + name: 'Judecătoria AVRIG', + }, + { + id: 203, + name: 'Curtea de Apel SUCEAVA', + }, + { + id: 204, + name: 'Tribunalul SUCEAVA', + }, + { + id: 205, + name: 'Judecătoria CÂMPULUNG MOLDOVENESC', + }, + { + id: 206, + name: 'Judecătoria FĂLTICENI', + }, + { + id: 207, + name: 'Judecătoria GURA HUMORULUI', + }, + { + id: 208, + name: 'Judecătoria RĂDĂUŢI', + }, + { + id: 209, + name: 'Judecătoria SUCEAVA', + }, + { + id: 210, + name: 'Judecătoria VATRA DORNEI', + }, + { + id: 211, + name: 'Tribunalul TELEORMAN', + }, + { + id: 212, + name: 'Judecătoria ROŞIORI DE VEDE', + }, + { + id: 213, + name: 'Judecătoria TURNU MĂGURELE', + }, + { + id: 214, + name: 'Judecătoria VIDELE', + }, + { + id: 215, + name: 'Judecătoria ZIMNICEA', + }, + { + id: 216, + name: 'Judecătoria ALEXANDRIA', + }, + { + id: 217, + name: 'Curtea de Apel TIMIŞOARA', + }, + { + id: 218, + name: 'Tribunalul Militar TIMIŞOARA', + }, + { + id: 219, + name: 'Tribunalul TIMIŞ', + }, + { + id: 220, + name: 'Judecătoria FĂGET', + }, + { + id: 221, + name: 'Judecătoria DETA', + }, + { + id: 222, + name: 'Judecătoria LUGOJ', + }, + { + id: 223, + name: 'Judecătoria SÂNNICOLAUL MARE', + }, + { + id: 224, + name: 'Judecătoria TIMIŞOARA', + }, + { + id: 225, + name: 'Tribunalul TULCEA', + }, + { + id: 226, + name: 'Judecătoria BABADAG', + }, + { + id: 227, + name: 'Judecătoria MACIN', + }, + { + id: 228, + name: 'Judecătoria TULCEA', + }, + { + id: 229, + name: 'Tribunalul VÂLCEA', + }, + { + id: 230, + name: 'Judecătoria BĂLCEŞTI', + }, + { + id: 231, + name: 'Judecătoria BREZOI', + }, + { + id: 232, + name: 'Judecătoria DRĂGĂŞANI', + }, + { + id: 233, + name: 'Judecătoria HOREZU', + }, + { + id: 234, + name: 'Judecătoria RÂMNICU VALCEA', + }, + { + id: 235, + name: 'Tribunalul VASLUI', + }, + { + id: 236, + name: 'Judecătoria BÂRLAD', + }, + { + id: 237, + name: 'Judecătoria HUŞI', + }, + { + id: 238, + name: 'Judecătoria VASLUI', + }, + { + id: 239, + name: 'Tribunalul VRANCEA', + }, + { + id: 240, + name: 'Judecătoria ADJUD', + }, + { + id: 241, + name: 'Judecătoria FOCŞANI', + }, + { + id: 242, + name: 'Judecătoria PANCIU', + }, +]; diff --git a/backend/src/modules/organization/dto/create-organization-general.dto.ts b/backend/src/modules/organization/dto/create-organization-general.dto.ts index f22708d9..709fe005 100644 --- a/backend/src/modules/organization/dto/create-organization-general.dto.ts +++ b/backend/src/modules/organization/dto/create-organization-general.dto.ts @@ -81,12 +81,12 @@ export class CreateOrganizationGeneralDto { associationRegistryNumber: string; @IsString() - @MaxLength(20) + @MaxLength(10) @Trim() associationRegistryPart: string; @IsString() - @MaxLength(20) + @MaxLength(10) @Trim() associationRegistrySection: string; diff --git a/backend/src/shared/entities/index.ts b/backend/src/shared/entities/index.ts index 835d9bf8..62e0463f 100644 --- a/backend/src/shared/entities/index.ts +++ b/backend/src/shared/entities/index.ts @@ -6,3 +6,4 @@ export * from './federation.entity'; export * from './coalition.entity'; export * from './faculty.entity'; export * from './skill.entity'; +export * from './issuer.entity'; diff --git a/backend/src/shared/entities/issuer.entity.ts b/backend/src/shared/entities/issuer.entity.ts new file mode 100644 index 00000000..2b895d24 --- /dev/null +++ b/backend/src/shared/entities/issuer.entity.ts @@ -0,0 +1,8 @@ +import { BaseEntity } from 'src/common/base/base-entity.class'; +import { Column, Entity } from 'typeorm'; + +@Entity({ name: '_issuer' }) +export class Issuer extends BaseEntity { + @Column({ type: 'text', name: 'name' }) + name: string; +} diff --git a/backend/src/shared/shared.module.ts b/backend/src/shared/shared.module.ts index b7a4769c..dc13eab0 100644 --- a/backend/src/shared/shared.module.ts +++ b/backend/src/shared/shared.module.ts @@ -9,6 +9,7 @@ import { Domain, Faculty, Federation, + Issuer, Region, Skill, } from './entities'; @@ -35,6 +36,7 @@ import { Beneficiary } from 'src/modules/civic-center-service/entities/beneficia PracticeDomain, ServiceDomain, Beneficiary, + Issuer, ]), HttpModule, ], diff --git a/frontend/src/assets/locales/ro/translation.json b/frontend/src/assets/locales/ro/translation.json index 63a4937b..f2d6a412 100644 --- a/frontend/src/assets/locales/ro/translation.json +++ b/frontend/src/assets/locales/ro/translation.json @@ -316,7 +316,35 @@ "required": "Numărul de înregistrare în Registrul Special este obligatoriu", "max": "Numărul de înregistrare în Registrul Special poate avea maxim 30 de caractere", "helper": "Numărul care apare pe Certificatul de înscriere a persoanei juridice fără scop patrimonial.", - "label": "Număr si data de înscriere în Registrul Special" + "label": "Număr si data de înscriere în Registrul Special", + "placeholder": "123/14.09.2020" + }, + "association_registry_part": { + "required": "Partea din Registrul Special este obligatorie", + "max": "Partea din Registrul Special poate avea maxim 10 de caractere", + "helper": "Partea care apare pe Certificatul de înscriere a persoanei juridice fără scop patrimonial, după număr, și dată. A corespunde asociațiilor, B fundațiilor, C federațiilor.", + "label": "Partea", + "placeholder": "A" + }, + "association_registry_section": { + "required": "Secțiunea din Registrul Special este obligatorie", + "max": "Secțiunea din Registrul Special poate avea maxim 10 de caractere", + "helper": "Secțiunea care apare pe Certificatul de înscriere a persoanei juridice fără scop patrimonial, după număr, dată și parte.", + "label": "Secțiuna", + "placeholder": "I" + }, + "association_registry_issuer": { + "required": "Emitentul Registrului Special este obligatoriu", + "max": "Emitentul Registrului Special poate avea maxim 100 de caractere", + "helper": "Selectează din lista instanțelor de judecată, instanța care a conferit organizației statutul juridic. Instanța emitentă se află în antetul Certificatului de înscriere a persoanei juridice fără scop patrimonial.", + "label": "Instanța emitentă" + }, + "national_registry_number": { + "required": "Numărul de înregistrare în Registrul Național este obligatoriu", + "max": "Numărul de înregistrare în Registrul Național poate avea maxim 30 de caractere", + "helper": "Acest număr se regăsește pe extrasele din Registrul Național pe care le solicitați (de exemplu pentru actualizarea anuală a datelor la bancă). Numărul poate fi regăsit și pe site-ul Ministerului Justiției - https://www.just.ro/registrul-national-ong/", + "label": "Numărul de înregistrare în Registrul Național, oferit de Ministerul Justiției", + "placeholder": "123/A/2020" }, "city": { "required": "Localitatea este obligatorie", diff --git a/frontend/src/pages/create-organziation/components/CreateOrganizationGeneral.tsx b/frontend/src/pages/create-organziation/components/CreateOrganizationGeneral.tsx index e02a36d0..11ea75fa 100644 --- a/frontend/src/pages/create-organziation/components/CreateOrganizationGeneral.tsx +++ b/frontend/src/pages/create-organziation/components/CreateOrganizationGeneral.tsx @@ -258,20 +258,108 @@ const CreateOrganizationGeneral = () => { }} /> { return ( + ); + }} + /> + + { + return ( + + ); + }} + /> + + { + return ( + + ); + }} + /> + + { + return ( + + ); + }} + /> + + { + return ( + diff --git a/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneral.tsx b/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneral.tsx index 6ee5ea32..7d539123 100644 --- a/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneral.tsx +++ b/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneral.tsx @@ -311,6 +311,93 @@ const OrganizationGeneral = () => { }} /> + { + return ( + + ); + }} + /> + + { + return ( + + ); + }} + /> + + { + return ( + + ); + }} + /> + + { + return ( + + ); + }} + /> = { associationRegistryNumber: { key: 'associationRegistryNumber', rules: { + required: { + value: true, + message: translations.associationRegistryNumber.required, + }, maxLength: { value: 30, message: translations.associationRegistryNumber.max, @@ -357,7 +394,83 @@ export const OrganizationGeneralConfig: Record = { type: 'text', label: translations.associationRegistryNumber.label, helperText: translations.associationRegistryNumber.helper, - placeholder: 'nr/zz.ll.aaaa', + placeholder: translations.associationRegistryNumber.placeholder, + }, + }, + associationRegistryPart: { + key: 'associationRegistryPart', + rules: { + required: { + value: true, + message: translations.associationRegistryPart.required, + }, + maxLength: { + value: 10, + message: translations.associationRegistryPart.max, + }, + }, + config: { + type: 'text', + label: translations.associationRegistryPart.label, + helperText: translations.associationRegistryPart.helper, + placeholder: translations.associationRegistryPart.placeholder, + }, + }, + associationRegistrySection: { + key: 'associationRegistrySection', + rules: { + required: { + value: true, + message: translations.associationRegistrySection.required, + }, + maxLength: { + value: 10, + message: translations.associationRegistrySection.max, + }, + }, + config: { + type: 'text', + label: translations.associationRegistrySection.label, + helperText: translations.associationRegistrySection.helper, + placeholder: translations.associationRegistrySection.placeholder, + }, + }, + associationRegistryIssuer: { + key: 'associationRegistryIssuer', + rules: { + required: { + value: true, + message: translations.associationRegistryIssuer.required, + }, + maxLength: { + value: 100, + message: translations.associationRegistryIssuer.max, + }, + }, + config: { + type: 'text', + label: translations.associationRegistryIssuer.label, + helperText: translations.associationRegistryIssuer.helper, + placeholder: translations.associationRegistryIssuer.placeholder, + }, + }, + nationalRegistryNumber: { + key: 'nationalRegistryNumber', + rules: { + required: { + value: true, + message: translations.nationalRegistryNumber.required, + }, + maxLength: { + value: 30, + message: translations.nationalRegistryNumber.max, + }, + }, + config: { + type: 'text', + label: translations.nationalRegistryNumber.label, + helperText: translations.nationalRegistryNumber.helper, + placeholder: translations.nationalRegistryNumber.placeholder, }, }, rafNumber: { From 3836c2e167ebd7653b5bd3e68586dc098c1026ff Mon Sep 17 00:00:00 2001 From: Dragos-Paul Strat Date: Fri, 26 Jul 2024 11:35:33 +0300 Subject: [PATCH 3/5] feat: [590] wip new fields --- .../migrations/1721829705666-NewGeneralFields.ts | 16 ++++++++++++++-- .../dto/create-organization-general.dto.ts | 7 +++---- .../entities/organization-general.entity.ts | 15 ++++++++++++--- .../services/organization-general.service.ts | 8 +++++++- .../services/organization.service.ts | 1 + .../controllers/nomenclatures.controller.ts | 5 +++++ .../src/shared/services/nomenclatures.service.ts | 7 +++++++ .../src/common/interfaces/issuer.interface.ts | 3 +++ .../create-organziation/CreateOrganization.tsx | 3 ++- .../components/CreateOrganizationGeneral.tsx | 15 ++++++++------- .../interfaces/CreateOrganization.interface.ts | 8 +++++++- frontend/src/pages/organization/Organization.tsx | 3 ++- .../pages/organization/OrganizationProfile.tsx | 3 ++- .../OrganizationGeneral/OrganizationGeneral.tsx | 16 +++++++++------- .../interfaces/OrganizationGeneral.interface.ts | 6 +++++- .../src/pages/requests/components/Request.tsx | 3 ++- .../nomenclature/Nomenclature.queries.ts | 11 +++++++++++ .../nomenclature/Nomenclatures.service.ts | 4 ++++ .../OrganizationFormDataMapper.service.ts | 16 ++++++++++++++-- .../store/nomenclature/nomenclature.selectors.ts | 13 ++++++++++++- .../src/store/nomenclature/nomenclature.slice.ts | 5 +++++ frontend/src/store/store.ts | 3 +++ 22 files changed, 138 insertions(+), 33 deletions(-) create mode 100644 frontend/src/common/interfaces/issuer.interface.ts diff --git a/backend/src/migrations/1721829705666-NewGeneralFields.ts b/backend/src/migrations/1721829705666-NewGeneralFields.ts index 0b55a34c..f999e0a1 100644 --- a/backend/src/migrations/1721829705666-NewGeneralFields.ts +++ b/backend/src/migrations/1721829705666-NewGeneralFields.ts @@ -4,6 +4,9 @@ export class NewGeneralFields1721829705666 implements MigrationInterface { name = 'NewGeneralFields1721829705666'; public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "organization_general" ALTER COLUMN "raf_number" DROP NOT NULL`, + ); await queryRunner.query( `ALTER TABLE "organization_general" ADD "association_registry_number" text`, ); @@ -14,7 +17,10 @@ export class NewGeneralFields1721829705666 implements MigrationInterface { `ALTER TABLE "organization_general" ADD "association_registry_section" text`, ); await queryRunner.query( - `ALTER TABLE "organization_general" ADD "association_registry_issuer" text`, + `ALTER TABLE "organization_general" ADD "association_registry_issuer_id" integer`, + ); + await queryRunner.query( + `ALTER TABLE "organization_general" ADD CONSTRAINT "FK_302f085592ed8a6c5d06f1182ef" FOREIGN KEY ("association_registry_issuer_id") REFERENCES "_issuer"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, ); await queryRunner.query( `ALTER TABLE "organization_general" ADD "national_registry_number" text`, @@ -22,11 +28,17 @@ export class NewGeneralFields1721829705666 implements MigrationInterface { } public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "organization_general" ALTER COLUMN "raf_number" SET NOT NULL`, + ); await queryRunner.query( `ALTER TABLE "organization_general" DROP COLUMN "national_registry_number"`, ); await queryRunner.query( - `ALTER TABLE "organization_general" DROP COLUMN "association_registry_issuer"`, + `ALTER TABLE "organization_general" DROP CONSTRAINT "FK_302f085592ed8a6c5d06f1182ef"`, + ); + await queryRunner.query( + `ALTER TABLE "organization_general" DROP COLUMN "association_registry_issuer_id"`, ); await queryRunner.query( `ALTER TABLE "organization_general" DROP COLUMN "association_registry_section"`, diff --git a/backend/src/modules/organization/dto/create-organization-general.dto.ts b/backend/src/modules/organization/dto/create-organization-general.dto.ts index 709fe005..ae33713e 100644 --- a/backend/src/modules/organization/dto/create-organization-general.dto.ts +++ b/backend/src/modules/organization/dto/create-organization-general.dto.ts @@ -90,10 +90,9 @@ export class CreateOrganizationGeneralDto { @Trim() associationRegistrySection: string; - @IsString() - @MaxLength(100) - @Trim() - associationRegistryIssuer: string; + @IsNumber() + @ToNumber() + associationRegistryIssuerId: number; @IsString() @MaxLength(30) diff --git a/backend/src/modules/organization/entities/organization-general.entity.ts b/backend/src/modules/organization/entities/organization-general.entity.ts index 6c8cce52..3133b161 100644 --- a/backend/src/modules/organization/entities/organization-general.entity.ts +++ b/backend/src/modules/organization/entities/organization-general.entity.ts @@ -6,6 +6,7 @@ import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; import { ContactPerson } from '../interfaces/contact-person.interface'; import { OrganizationType } from '../enums/organization-type.enum'; import { Organization } from './organization.entity'; +import { Issuer } from 'src/shared/entities'; @Entity() export class OrganizationGeneral extends BaseEntity { @@ -43,13 +44,21 @@ export class OrganizationGeneral extends BaseEntity { }) associationRegistrySection: string; - @Column({ type: 'text', name: 'association_registry_issuer', nullable: true }) - associationRegistryIssuer: string; + @Column({ + type: 'integer', + name: 'association_registry_issuer_id', + nullable: true, + }) + associationRegistryIssuerId: number; + + @ManyToOne((type) => Issuer) + @JoinColumn({ name: 'association_registry_issuer_id' }) + associationRegistryIssuer: Issuer; @Column({ type: 'text', name: 'national_registry_number', nullable: true }) nationalRegistryNumber: string; - @Column({ type: 'text', name: 'raf_number', unique: true }) + @Column({ type: 'text', name: 'raf_number', unique: true, nullable: true }) rafNumber: string; @Column({ type: 'text', name: 'short_description', nullable: true }) diff --git a/backend/src/modules/organization/services/organization-general.service.ts b/backend/src/modules/organization/services/organization-general.service.ts index bab548e7..f15a2d81 100644 --- a/backend/src/modules/organization/services/organization-general.service.ts +++ b/backend/src/modules/organization/services/organization-general.service.ts @@ -90,7 +90,13 @@ export class OrganizationGeneralService { let organizationGeneral = await this.organizationGeneralRepository.get({ where: { id: organization.organizationGeneralId }, - relations: ['city', 'county', 'organizationCounty', 'organizationCity'], + relations: [ + 'city', + 'county', + 'organizationCounty', + 'organizationCity', + 'associationRegistryIssuer', + ], }); // Effect 1: Update financial data if CUI has changed diff --git a/backend/src/modules/organization/services/organization.service.ts b/backend/src/modules/organization/services/organization.service.ts index 41fc07ab..90d11472 100644 --- a/backend/src/modules/organization/services/organization.service.ts +++ b/backend/src/modules/organization/services/organization.service.ts @@ -560,6 +560,7 @@ export class OrganizationService { 'organizationGeneral.county', 'organizationGeneral.organizationCity', 'organizationGeneral.organizationCounty', + 'organizationGeneral.associationRegistryIssuer', 'organizationActivity', 'organizationActivity.federations', 'organizationActivity.coalitions', diff --git a/backend/src/shared/controllers/nomenclatures.controller.ts b/backend/src/shared/controllers/nomenclatures.controller.ts index 4a3baadb..26060590 100644 --- a/backend/src/shared/controllers/nomenclatures.controller.ts +++ b/backend/src/shared/controllers/nomenclatures.controller.ts @@ -73,4 +73,9 @@ export class NomenclaturesController { getBeneficiaries() { return this.nomenclaturesService.getBeneficiaries({}); } + + @Get('issuers') + getIssuers() { + return this.nomenclaturesService.getIssuers({}); + } } diff --git a/backend/src/shared/services/nomenclatures.service.ts b/backend/src/shared/services/nomenclatures.service.ts index 336ff626..af2d3746 100644 --- a/backend/src/shared/services/nomenclatures.service.ts +++ b/backend/src/shared/services/nomenclatures.service.ts @@ -5,6 +5,7 @@ import { County, Domain, Faculty, + Issuer, Region, Skill, } from 'src/shared/entities'; @@ -42,6 +43,8 @@ export class NomenclaturesService { private readonly serviceDomainRepository: Repository, @InjectRepository(Beneficiary) private readonly beneficiaryRepository: Repository, + @InjectRepository(Issuer) + private readonly issuersRepository: Repository, ) {} public getCity(conditions: FindOneOptions) { @@ -162,4 +165,8 @@ export class NomenclaturesService { public getBeneficiaries(conditions: FindManyOptions) { return this.beneficiaryRepository.find(conditions); } + + public getIssuers(conditions: FindManyOptions) { + return this.issuersRepository.find(conditions); + } } diff --git a/frontend/src/common/interfaces/issuer.interface.ts b/frontend/src/common/interfaces/issuer.interface.ts new file mode 100644 index 00000000..c1e7dfa9 --- /dev/null +++ b/frontend/src/common/interfaces/issuer.interface.ts @@ -0,0 +1,3 @@ +import { BaseNomenclatureEntity } from './base-nomenclature-entity.interface'; + +export interface Issuer extends BaseNomenclatureEntity {} diff --git a/frontend/src/pages/create-organziation/CreateOrganization.tsx b/frontend/src/pages/create-organziation/CreateOrganization.tsx index b65d0fd0..516716e9 100644 --- a/frontend/src/pages/create-organziation/CreateOrganization.tsx +++ b/frontend/src/pages/create-organziation/CreateOrganization.tsx @@ -7,7 +7,7 @@ import { InternalErrors } from '../../common/errors/internal-errors'; import { mapSelectToValue } from '../../common/helpers/format.helper'; import Header from '../../components/Header/Header'; import { Loading } from '../../components/loading/Loading'; -import { useCountiesQuery } from '../../services/nomenclature/Nomenclature.queries'; +import { useCountiesQuery, useIssuersQuery } from '../../services/nomenclature/Nomenclature.queries'; import { useCreateOrganizationRequestMutation } from '../../services/request/Request.queries'; import ProgressSteps from './components/ProgressSteps'; import { @@ -42,6 +42,7 @@ const CreateOrganization = () => { const { t } = useTranslation(['organization', 'common']); useCountiesQuery(); + useIssuersQuery(); useEffect(() => { const { activeStepIndex } = JSON.parse( diff --git a/frontend/src/pages/create-organziation/components/CreateOrganizationGeneral.tsx b/frontend/src/pages/create-organziation/components/CreateOrganizationGeneral.tsx index 11ea75fa..b75b1c5d 100644 --- a/frontend/src/pages/create-organziation/components/CreateOrganizationGeneral.tsx +++ b/frontend/src/pages/create-organziation/components/CreateOrganizationGeneral.tsx @@ -13,7 +13,7 @@ import Select from '../../../components/Select/Select'; import Textarea from '../../../components/Textarea/Textarea'; import ErrorsBanner from '../../../components/errors-banner/ErrorsBanner'; import SectionHeader from '../../../components/section-header/SectionHeader'; -import { useCitiesQuery } from '../../../services/nomenclature/Nomenclature.queries'; +import { useCitiesQuery, useIssuersQuery } from '../../../services/nomenclature/Nomenclature.queries'; import { useCreateOrganizationRequestValidationMutation } from '../../../services/request/Request.queries'; import { useNomenclature } from '../../../store/selectors'; import { OrganizationGeneralConfig } from '../../organization/components/OrganizationGeneral/OrganizationGeneralConfig'; @@ -31,7 +31,7 @@ const CreateOrganizationGeneral = () => { const [organizationCounty, setOrganizationCounty] = useState(); const [organizationCity, setOrganizationCity] = useState(); const [validationErrors, setValidationErrors] = useState([]); - const { cities, counties } = useNomenclature(); + const { cities, counties, issuers } = useNomenclature(); const [organization, setOrganization, logo, setLogo, , , activeStepIndex, setActiveStepIndex] = useOutletContext(); @@ -330,15 +330,16 @@ const CreateOrganizationGeneral = () => { control={control} render={({ field: { onChange, value } }) => { return ( - ); diff --git a/frontend/src/pages/create-organziation/interfaces/CreateOrganization.interface.ts b/frontend/src/pages/create-organziation/interfaces/CreateOrganization.interface.ts index 33f6a2c7..1f8a3ee5 100644 --- a/frontend/src/pages/create-organziation/interfaces/CreateOrganization.interface.ts +++ b/frontend/src/pages/create-organziation/interfaces/CreateOrganization.interface.ts @@ -1,5 +1,6 @@ import { City } from '../../../common/interfaces/city.interface'; import { County } from '../../../common/interfaces/county.interface'; +import { Issuer } from '../../../common/interfaces/issuer.interface'; import { Person } from '../../../common/interfaces/person.interface'; import { OrganizationAreaEnum } from '../../organization/components/OrganizationActivity/OrganizationActivityConfig'; import { OrganizationTypeEnum } from '../../organization/enums/OrganizationType.enum'; @@ -27,7 +28,12 @@ export interface ICreateOrganizationGeneral { phone: string; yearCreated: number; cui: string; - rafNumber: string; + associationRegistryNumber: string; + associationRegistryPart: string; + associationRegistrySection: string; + associationRegistryIssuerId: number; + associationRegistryIssuer: Issuer; + nationalRegistryNumber: string; shortDescription: string; description: string; logo?: string; diff --git a/frontend/src/pages/organization/Organization.tsx b/frontend/src/pages/organization/Organization.tsx index d7c0e521..e0634dc2 100644 --- a/frontend/src/pages/organization/Organization.tsx +++ b/frontend/src/pages/organization/Organization.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react'; import { Outlet, useLocation, useNavigate, useParams } from 'react-router-dom'; import { classNames } from '../../common/helpers/tailwind.helper'; import { useErrorToast } from '../../common/hooks/useToast'; -import { useCountiesQuery } from '../../services/nomenclature/Nomenclature.queries'; +import { useCountiesQuery, useIssuersQuery } from '../../services/nomenclature/Nomenclature.queries'; import { useOrganizationMutation, useOrganizationQuery, @@ -28,6 +28,7 @@ const Organization = () => { // TODO: Load nomenclature data on app init useCountiesQuery(); + useIssuersQuery(); // load organization data const { error } = useOrganizationQuery(id as string); diff --git a/frontend/src/pages/organization/OrganizationProfile.tsx b/frontend/src/pages/organization/OrganizationProfile.tsx index 04679cde..209be577 100644 --- a/frontend/src/pages/organization/OrganizationProfile.tsx +++ b/frontend/src/pages/organization/OrganizationProfile.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react'; import { Outlet, useLocation, useNavigate } from 'react-router-dom'; import { classNames } from '../../common/helpers/tailwind.helper'; import { useErrorToast, useSuccessToast } from '../../common/hooks/useToast'; -import { useCountiesQuery } from '../../services/nomenclature/Nomenclature.queries'; +import { useCountiesQuery, useIssuersQuery } from '../../services/nomenclature/Nomenclature.queries'; import { useOrganizationByProfileMutation, useOrganizationByProfileQuery, @@ -32,6 +32,7 @@ const OrganizationProfile = () => { // TODO: Load nomenclature data on app init useCountiesQuery(); + useIssuersQuery(); const { isLoading, mutate: updateOrganization } = useOrganizationByProfileMutation(); diff --git a/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneral.tsx b/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneral.tsx index 7d539123..bc4ce0c3 100644 --- a/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneral.tsx +++ b/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneral.tsx @@ -21,7 +21,7 @@ import SectionHeader from '../../../../components/section-header/SectionHeader'; import Select from '../../../../components/Select/Select'; import Textarea from '../../../../components/Textarea/Textarea'; import { useAuthContext } from '../../../../contexts/AuthContext'; -import { useCitiesQuery } from '../../../../services/nomenclature/Nomenclature.queries'; +import { useCitiesQuery, useIssuersQuery } from '../../../../services/nomenclature/Nomenclature.queries'; import { useNomenclature, useSelectedOrganization } from '../../../../store/selectors'; import { UserRole } from '../../../users/enums/UserRole.enum'; import { OrganizationContext } from '../../interfaces/OrganizationContext'; @@ -34,7 +34,7 @@ const OrganizationGeneral = () => { const [county, setCounty] = useState(); const [organizationCounty, setOrganizationCounty] = useState(); const [file, setFile] = useState(null); - const { counties } = useNomenclature(); + const { counties, issuers } = useNomenclature(); const { disabled, updateOrganization } = useOutletContext(); const { role } = useAuthContext(); const [validationErrors, setValidationErrors] = useState([]); @@ -145,6 +145,7 @@ const OrganizationGeneral = () => { countyId, organizationCountyId, organizationCityId, + associationRegistryIssuerId, ...organizationGeneralData } = data; @@ -362,15 +363,16 @@ const OrganizationGeneral = () => { control={control} render={({ field: { onChange, value } }) => { return ( - ); diff --git a/frontend/src/pages/organization/interfaces/OrganizationGeneral.interface.ts b/frontend/src/pages/organization/interfaces/OrganizationGeneral.interface.ts index 0b4d1f36..7d441c4c 100644 --- a/frontend/src/pages/organization/interfaces/OrganizationGeneral.interface.ts +++ b/frontend/src/pages/organization/interfaces/OrganizationGeneral.interface.ts @@ -13,7 +13,11 @@ export interface IOrganizationGeneral extends BaseEntity { phone: string; yearCreated: number; cui: string; - rafNumber: string; + associationRegistryNumber: string; + associationRegistryPart: string; + associationRegistrySection: string; + associationRegistryIssuerId: number; + nationalRegistryNumber: string; shortDescription: string; description: string; logo?: string; diff --git a/frontend/src/pages/requests/components/Request.tsx b/frontend/src/pages/requests/components/Request.tsx index ace8eaa8..1d9f1e32 100644 --- a/frontend/src/pages/requests/components/Request.tsx +++ b/frontend/src/pages/requests/components/Request.tsx @@ -9,7 +9,7 @@ import { IPageTab } from '../../../common/interfaces/tabs.interface'; import ConfirmationModal from '../../../components/confim-removal-modal/ConfirmationModal'; import ContentWrapper from '../../../components/content-wrapper/ContentWrapper'; import { Loading } from '../../../components/loading/Loading'; -import { useCountiesQuery } from '../../../services/nomenclature/Nomenclature.queries'; +import { useCountiesQuery, useIssuersQuery } from '../../../services/nomenclature/Nomenclature.queries'; import { useApproveOrganizationRequestMutation, useRejectOrganizationRequestMutation, @@ -38,6 +38,7 @@ const Request = () => { // TODO: Load nomenclature data on app init useCountiesQuery(); + useIssuersQuery(); // load organization data const { data: request, error, isLoading: dataLoading } = useOrganizationRequest(id || ''); diff --git a/frontend/src/services/nomenclature/Nomenclature.queries.ts b/frontend/src/services/nomenclature/Nomenclature.queries.ts index 224f44ac..b52fe426 100644 --- a/frontend/src/services/nomenclature/Nomenclature.queries.ts +++ b/frontend/src/services/nomenclature/Nomenclature.queries.ts @@ -16,12 +16,14 @@ import { getPracticeDomains, getServiceDomains, getBeneficiaries, + getIssuers, } from './Nomenclatures.service'; import { Coalition } from '../../common/interfaces/coalitions.interface'; import { Federation } from '../../common/interfaces/federations.interface'; import { Skill } from '../../common/interfaces/skill.interface'; import { Faculty } from '../../common/interfaces/faculty.interface'; import { alphabeticallySort } from '../../common/helpers/utils.helper'; +import { Issuer } from '../../common/interfaces/issuer.interface'; export const useCitiesQuery = (countyId: number) => { const { setCities } = useStore(); @@ -42,6 +44,15 @@ export const useCountiesQuery = () => { }); }; +export const useIssuersQuery = () => { + const { setIssuers } = useStore(); + return useQuery('issuers', () => getIssuers(), { + onSuccess: (data: Issuer[]) => { + setIssuers(data); + }, + }); +}; + export const useDomainsQuery = () => { const { setDomains } = useStore(); return useQuery('domains', () => getDomains(), { diff --git a/frontend/src/services/nomenclature/Nomenclatures.service.ts b/frontend/src/services/nomenclature/Nomenclatures.service.ts index d23ebaea..543fa81c 100644 --- a/frontend/src/services/nomenclature/Nomenclatures.service.ts +++ b/frontend/src/services/nomenclature/Nomenclatures.service.ts @@ -60,3 +60,7 @@ export const getSkills = (): Promise => { export const getFaculties = (): Promise => { return API.get(`/nomenclatures/faculties`).then((res) => res.data); }; + +export const getIssuers = (): Promise<{ id: number; name: string }[]> => { + return API.get(`/nomenclatures/issuers`).then((res) => res.data); +}; diff --git a/frontend/src/services/organization/OrganizationFormDataMapper.service.ts b/frontend/src/services/organization/OrganizationFormDataMapper.service.ts index f9dbf6c3..7390f232 100644 --- a/frontend/src/services/organization/OrganizationFormDataMapper.service.ts +++ b/frontend/src/services/organization/OrganizationFormDataMapper.service.ts @@ -19,8 +19,15 @@ export const mapOrganizationGeneralToFormData = ( general: ICreateOrganizationGeneral, organizationGeneralKey: string, ): FormData => { - const { city, county, contact, organizationCity, organizationCounty, ...organizationGeneral } = - general; + const { + city, + county, + contact, + organizationCity, + organizationCounty, + associationRegistryIssuer, + ...organizationGeneral + } = general; // map basic organization general fields let organizationGeneralPayload = mapEntityToFormData( @@ -33,6 +40,11 @@ export const mapOrganizationGeneralToFormData = ( organizationGeneralPayload.append(`${organizationGeneralKey}[countyId]`, county?.id.toString()); organizationGeneralPayload.append(`${organizationGeneralKey}[cityId]`, city?.id.toString()); + organizationGeneralPayload.append( + `${organizationGeneralKey}[associationRegistryIssuerId]`, + associationRegistryIssuer?.id.toString(), + ); + // map optional address dada if (organizationCity) { organizationGeneralPayload.append( diff --git a/frontend/src/store/nomenclature/nomenclature.selectors.ts b/frontend/src/store/nomenclature/nomenclature.selectors.ts index ef4735ae..f11fe9be 100644 --- a/frontend/src/store/nomenclature/nomenclature.selectors.ts +++ b/frontend/src/store/nomenclature/nomenclature.selectors.ts @@ -9,5 +9,16 @@ export const useNomenclature = () => { const coalitions = useStore((state) => state.coalitions); const skills = useStore((state) => state.skills); const faculties = useStore((state) => state.faculties); - return { counties, cities, domains, regions, federations, coalitions, skills, faculties }; + const issuers = useStore((state) => state.issuers); + return { + counties, + cities, + domains, + regions, + federations, + coalitions, + skills, + faculties, + issuers, + }; }; diff --git a/frontend/src/store/nomenclature/nomenclature.slice.ts b/frontend/src/store/nomenclature/nomenclature.slice.ts index afcc6299..c148e2b7 100644 --- a/frontend/src/store/nomenclature/nomenclature.slice.ts +++ b/frontend/src/store/nomenclature/nomenclature.slice.ts @@ -4,6 +4,7 @@ import { County } from '../../common/interfaces/county.interface'; import { Domain } from '../../common/interfaces/domain.interface'; import { Faculty } from '../../common/interfaces/faculty.interface'; import { Federation } from '../../common/interfaces/federations.interface'; +import { Issuer } from '../../common/interfaces/issuer.interface'; import { Region } from '../../common/interfaces/region.interface'; import { Skill } from '../../common/interfaces/skill.interface'; @@ -17,6 +18,7 @@ export const nomenclatureSlice = (set: any) => ({ coalitions: [], skills: [], faculties: [], + issuers: [], setCounties: (counties: County[]) => { set({ counties }); }, @@ -41,6 +43,9 @@ export const nomenclatureSlice = (set: any) => ({ setFaculties: (faculties: Faculty[]) => { set({ faculties }); }, + setIssuers: (issuers: Issuer[]) => { + set({ issuers }); + }, }); export default { nomenclatureSlice }; diff --git a/frontend/src/store/store.ts b/frontend/src/store/store.ts index a2b26eaf..5993583b 100644 --- a/frontend/src/store/store.ts +++ b/frontend/src/store/store.ts @@ -46,6 +46,7 @@ import { Skill } from '../common/interfaces/skill.interface'; import { Faculty } from '../common/interfaces/faculty.interface'; import { IFeedback } from '../pages/civic-center-service/interfaces/Feedback.interface'; import { feedbacksSlice } from './civic-center-service/Feedback.slice'; +import { Issuer } from '../common/interfaces/issuer.interface'; interface OrganizationState { organizations: PaginatedEntity; @@ -72,6 +73,7 @@ interface NomenclatureState { coalitions: Coalition[]; skills: Skill[]; faculties: Faculty[]; + issuers: Issuer[]; setCounties: (counties: County[]) => void; setCities: (cities: City[]) => void; setDomains: (domains: Domain[]) => void; @@ -80,6 +82,7 @@ interface NomenclatureState { setCoalitions: (coaltions: Coalition[]) => void; setSkills: (skills: Skill[]) => void; setFaculties: (faculties: Faculty[]) => void; + setIssuers: (issuers: Issuer[]) => void; } interface ProfileState { From ac931ca795622de1df8131bdc530de8764042aba Mon Sep 17 00:00:00 2001 From: Dragos-Paul Strat Date: Fri, 26 Jul 2024 14:34:19 +0300 Subject: [PATCH 4/5] feat: [590] fix the migrations --- ...{1721896584559-AddIssuer.ts => 1721829705666-AddIssuer.ts} | 4 ++-- ...-NewGeneralFields.ts => 1721899705666-NewGeneralFields.ts} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename backend/src/migrations/{1721896584559-AddIssuer.ts => 1721829705666-AddIssuer.ts} (92%) rename backend/src/migrations/{1721829705666-NewGeneralFields.ts => 1721899705666-NewGeneralFields.ts} (95%) diff --git a/backend/src/migrations/1721896584559-AddIssuer.ts b/backend/src/migrations/1721829705666-AddIssuer.ts similarity index 92% rename from backend/src/migrations/1721896584559-AddIssuer.ts rename to backend/src/migrations/1721829705666-AddIssuer.ts index cce38470..b9eaae49 100644 --- a/backend/src/migrations/1721896584559-AddIssuer.ts +++ b/backend/src/migrations/1721829705666-AddIssuer.ts @@ -1,8 +1,8 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; import { ISSUERS } from './seed/issuers.seed'; import { Issuer } from 'src/shared/entities'; -export class AddIssuer1721896584559 implements MigrationInterface { - name = 'AddIssuer1721896584559'; +export class AddIssuer1721829705666 implements MigrationInterface { + name = 'AddIssuer1721829705666'; public async up(queryRunner: QueryRunner): Promise { await queryRunner.query( diff --git a/backend/src/migrations/1721829705666-NewGeneralFields.ts b/backend/src/migrations/1721899705666-NewGeneralFields.ts similarity index 95% rename from backend/src/migrations/1721829705666-NewGeneralFields.ts rename to backend/src/migrations/1721899705666-NewGeneralFields.ts index f999e0a1..fc7d14b2 100644 --- a/backend/src/migrations/1721829705666-NewGeneralFields.ts +++ b/backend/src/migrations/1721899705666-NewGeneralFields.ts @@ -1,7 +1,7 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; -export class NewGeneralFields1721829705666 implements MigrationInterface { - name = 'NewGeneralFields1721829705666'; +export class NewGeneralFields1721899705666 implements MigrationInterface { + name = 'NewGeneralFields1721899705666'; public async up(queryRunner: QueryRunner): Promise { await queryRunner.query( From 5d4ca7a999caf7734313c17f749c8a4a41afd0bd Mon Sep 17 00:00:00 2001 From: Dragos-Paul Strat Date: Mon, 29 Jul 2024 14:37:00 +0300 Subject: [PATCH 5/5] feat: [590] fix comments --- .../services/organization-general.service.ts | 23 +++++++++++++++++++ .../src/assets/locales/ro/translation.json | 4 +++- .../create-organization-errors.class.ts | 4 ++++ .../nomenclature/Nomenclature.queries.ts | 4 +++- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/backend/src/modules/organization/services/organization-general.service.ts b/backend/src/modules/organization/services/organization-general.service.ts index f15a2d81..a66ed070 100644 --- a/backend/src/modules/organization/services/organization-general.service.ts +++ b/backend/src/modules/organization/services/organization-general.service.ts @@ -156,6 +156,14 @@ export class OrganizationGeneralService { { id: Not(orgGeneralId), alias: newDTO?.alias }, { id: Not(orgGeneralId), email: newDTO?.email }, { id: Not(orgGeneralId), phone: newDTO?.phone }, + { + id: Not(orgGeneralId), + nationalRegistryNumber: newDTO?.nationalRegistryNumber, + }, + { + id: Not(orgGeneralId), + associationRegistryNumber: newDTO?.associationRegistryNumber, + }, ], }); for (let i = 0; i < existing.length; i++) { @@ -179,6 +187,21 @@ export class OrganizationGeneralService { ORGANIZATION_REQUEST_ERRORS.CREATE.ORGANIZATION_PHONE_EXISTS, ); } + if ( + existing[i].nationalRegistryNumber === newDTO?.nationalRegistryNumber + ) { + errors.push( + ORGANIZATION_REQUEST_ERRORS.CREATE.NATIONAL_REGISTRY_NUMBER_EXISTS, + ); + } + if ( + existing[i].associationRegistryNumber === + newDTO?.associationRegistryNumber + ) { + errors.push( + ORGANIZATION_REQUEST_ERRORS.CREATE.ASSOCIATION_REGISTRY_NUMBER_EXISTS, + ); + } } if (errors.length) { diff --git a/frontend/src/assets/locales/ro/translation.json b/frontend/src/assets/locales/ro/translation.json index f2d6a412..bb999db0 100644 --- a/frontend/src/assets/locales/ro/translation.json +++ b/frontend/src/assets/locales/ro/translation.json @@ -183,6 +183,8 @@ "REQ_010": "Există deja o organizație cu acest alias", "REQ_011": "Există deja o organizație cu acest e-mail", "REQ_012": "Există deja o organizație cu acest număr de telefon", + "REQ_013": "Există deja o organizație cu acest Număr si data de înscriere în Registrul Special", + "REQ_014": "Există deja o organizație cu acest Numărul de înregistrare în Registrul Național", "REQ_002": "Există deja o cerere cu acest e-mail sau cu acest număr de telefon.", "ORG_026": "Eroare la actualizarea datelor generale" } @@ -330,7 +332,7 @@ "required": "Secțiunea din Registrul Special este obligatorie", "max": "Secțiunea din Registrul Special poate avea maxim 10 de caractere", "helper": "Secțiunea care apare pe Certificatul de înscriere a persoanei juridice fără scop patrimonial, după număr, dată și parte.", - "label": "Secțiuna", + "label": "Secțiunea", "placeholder": "I" }, "association_registry_issuer": { diff --git a/frontend/src/common/errors/entities/create-organization-errors.class.ts b/frontend/src/common/errors/entities/create-organization-errors.class.ts index 28edc389..4cf723a0 100644 --- a/frontend/src/common/errors/entities/create-organization-errors.class.ts +++ b/frontend/src/common/errors/entities/create-organization-errors.class.ts @@ -10,6 +10,8 @@ export const enum CREATE_ORGANIZARION_ERRORS { REQ_010 = 'REQ_010', REQ_011 = 'REQ_011', REQ_012 = 'REQ_012', + REQ_013 = 'REQ_013', + REQ_014 = 'REQ_014', FILE_002 = 'FILE_002', FILE_003 = 'FILE_003', FILE_004 = 'FILE_004', @@ -39,6 +41,8 @@ export class CreateOrganizationError extends ErrorClass { export const useIssuersQuery = () => { const { setIssuers } = useStore(); - return useQuery('issuers', () => getIssuers(), { + return useQuery(['issuers'], () => getIssuers(), { + cacheTime: 1000 * 60 * 60, + staleTime: 1000 * 60 * 60, onSuccess: (data: Issuer[]) => { setIssuers(data); },