diff --git a/src/modules/organisation/api/organisation.controller.ts b/src/modules/organisation/api/organisation.controller.ts index c8d818af5..e804b50db 100644 --- a/src/modules/organisation/api/organisation.controller.ts +++ b/src/modules/organisation/api/organisation.controller.ts @@ -1,6 +1,6 @@ -import { Mapper } from '@automapper/core'; -import { getMapperToken } from '@automapper/nestjs'; -import { Body, Controller, Get, Inject, NotFoundException, Param, Post, Put, Query, UseFilters } from '@nestjs/common'; +// import { Mapper } from '@automapper/core'; +// import { getMapperToken } from '@automapper/nestjs'; +import { Body, Controller, Get, NotFoundException, Param, Post, Put, Query, UseFilters } from '@nestjs/common'; import { ApiBadRequestResponse, ApiBearerAuth, @@ -19,15 +19,15 @@ import { SchulConnexValidationErrorFilter } from '../../../shared/error/schulcon import { Paged, PagingHeadersObject } from '../../../shared/paging/index.js'; import { PagedResponse } from '../../../shared/paging/paged.response.js'; import { CreateOrganisationBodyParams } from './create-organisation.body.params.js'; -import { CreateOrganisationDto } from './create-organisation.dto.js'; -import { CreatedOrganisationDto } from './created-organisation.dto.js'; +// import { CreateOrganisationDto } from './create-organisation.dto.js'; +// import { CreatedOrganisationDto } from './created-organisation.dto.js'; import { FindOrganisationQueryParams } from './find-organisation-query.param.js'; import { OrganisationByIdParams } from './organisation-by-id.params.js'; -import { OrganisationResponseLegacy } from './organisation.response.legacy.js'; -import { OrganisationUc } from './organisation.uc.js'; +// import { OrganisationResponseLegacy } from './organisation.response.legacy.js'; +// import { OrganisationUc } from './organisation.uc.js'; import { UpdateOrganisationBodyParams } from './update-organisation.body.params.js'; -import { UpdateOrganisationDto } from './update-organisation.dto.js'; -import { UpdatedOrganisationDto } from './updated-organisation.dto.js'; +// import { UpdateOrganisationDto } from './update-organisation.dto.js'; +// import { UpdatedOrganisationDto } from './updated-organisation.dto.js'; import { OrganisationByIdBodyParams } from './organisation-by-id.body.params.js'; import { OrganisationRepository } from '../persistence/organisation.repository.js'; import { OrganisationScope } from '../persistence/organisation.scope.js'; @@ -38,14 +38,19 @@ import { Permissions } from '../../authentication/api/permissions.decorator.js'; import { PersonPermissions } from '../../authentication/domain/person-permissions.js'; import { OrganisationID } from '../../../shared/types/aggregate-ids.types.js'; import { OrganisationRootChildrenResponse } from './organisation.root-children.response.js'; -import { EntityNotFoundError } from '../../../shared/error/index.js'; +import { DomainError, EntityNotFoundError } from '../../../shared/error/index.js'; import { DbiamOrganisationError } from './dbiam-organisation.error.js'; import { OrganisationExceptionFilter } from './organisation-exception-filter.js'; import { OrganisationSpecificationError } from '../specification/error/organisation-specification.error.js'; import { OrganisationByIdQueryParams } from './organisation-by-id.query.js'; import { OrganisationsTyp } from '../domain/organisation.enums.js'; +import { ConfigService } from '@nestjs/config'; +import { ServerConfig } from '../../../shared/config/server.config.js'; +import { OrganisationService } from '../domain/organisation.service.js'; +import { DataConfig } from '../../../shared/config/data.config.js'; // DONE +//done @UseFilters(new SchulConnexValidationErrorFilter(), new OrganisationExceptionFilter()) @ApiTags('organisationen') @ApiBearerAuth() @@ -53,9 +58,11 @@ import { OrganisationsTyp } from '../domain/organisation.enums.js'; @Controller({ path: 'organisationen' }) export class OrganisationController { public constructor( - private readonly uc: OrganisationUc, + // private readonly uc: OrganisationUc, private readonly organisationRepository: OrganisationRepository, - @Inject(getMapperToken()) private readonly mapper: Mapper, + //@Inject(getMapperToken()) private readonly mapper: Mapper, + private readonly config: ConfigService, + private readonly organisationService: OrganisationService, ) {} @Post() @@ -65,22 +72,35 @@ export class OrganisationController { @ApiForbiddenResponse({ description: 'Not permitted to create the organisation.' }) @ApiInternalServerErrorResponse({ description: 'Internal server error while creating the organisation.' }) public async createOrganisation(@Body() params: CreateOrganisationBodyParams): Promise { - const result: Organisation | SchulConnexError | OrganisationSpecificationError = - await this.uc.createOrganisation(params); + const ROOT_ORGANISATION_ID: string = this.config.getOrThrow('DATA').ROOT_ORGANISATION_ID; - if (result instanceof Organisation) { - return new OrganisationResponse(result); - } - if (result instanceof OrganisationSpecificationError) { - throw result; + const organisation: Organisation = Organisation.createNew( + params.administriertVon ?? ROOT_ORGANISATION_ID, + params.zugehoerigZu ?? ROOT_ORGANISATION_ID, + params.kennung, + params.name, + params.namensergaenzung, + params.kuerzel, + params.typ, + params.traegerschaft, + ); + const result: Result, DomainError> = await this.organisationService.createOrganisation( + organisation, + ); + if (!result.ok) { + throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException( + SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(result.error), + ); } - throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException(result); + + return new OrganisationResponse(result.value); } /// !!!! warning: test this with partical and not!!! /// Todo add the find by to the aggrigate /// Todo update and save etc add to the repo // done + //done @Put(':organisationId') @ApiOkResponse({ description: 'The organisation was successfully updated.', @@ -114,33 +134,46 @@ export class OrganisationController { existingOrganisation.traegerschaft = body.traegerschaft; existingOrganisation.updatedAt = new Date(); - const response: Organisation | SchulConnexError | OrganisationSpecificationError = - await this.uc.updateOrganisation(existingOrganisation); + const result: Result, DomainError> = await this.organisationService.updateOrganisation( + existingOrganisation, + ); - if (response instanceof Organisation) { - return new OrganisationResponse(response); - } - if (response instanceof OrganisationSpecificationError) { - throw response; + if (result.ok) { + return new OrganisationResponse(result.value); + } else { + // Avoid passing OrganisationSpecificationError to SchulConnexErrorMapper + if (result.error instanceof OrganisationSpecificationError) { + throw result.error; + } + throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException( + SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(result.error), + ); } - throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException(response); } // Done + // findRootOrganisation + //Done + @Get('root') - @ApiOkResponse({ description: 'The organization was successfully pulled.', type: OrganisationResponse }) - @ApiUnauthorizedResponse({ description: 'Not authorized to get the organization.' }) - @ApiNotFoundResponse({ description: 'The organization does not exist.' }) - @ApiForbiddenResponse({ description: 'Insufficient permissions to get the organization.' }) - @ApiInternalServerErrorResponse({ description: 'Internal server error while getting the organization.' }) + @ApiOkResponse({ description: 'The root organization was successfully retrieved.', type: OrganisationResponse }) + @ApiUnauthorizedResponse({ description: 'Not authorized to get the root organization.' }) + @ApiNotFoundResponse({ description: 'The root organization does not exist.' }) + @ApiForbiddenResponse({ description: 'Insufficient permissions to get the root organization.' }) + @ApiInternalServerErrorResponse({ description: 'Internal server error while getting the root organization.' }) public async getRootOrganisation(): Promise { - const result: OrganisationResponse | SchulConnexError = await this.uc.findRootOrganisation(); + const ROOT_ORGANISATION_ID: string = this.config.getOrThrow('DATA').ROOT_ORGANISATION_ID; + const result: Result, DomainError> = await this.organisationService.findOrganisationById( + ROOT_ORGANISATION_ID, + ); - if (result instanceof OrganisationResponse) { - return result; + if (result.ok) { + return new OrganisationResponse(result.value); } - throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException(result); + throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException( + SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(result.error), + ); } // Done @@ -168,6 +201,7 @@ export class OrganisationController { } // Done + //Done @Get(':organisationId') @ApiOkResponse({ description: 'The organization was successfully pulled.', type: OrganisationResponse }) @ApiBadRequestResponse({ description: 'Organization ID is required' }) @@ -176,14 +210,17 @@ export class OrganisationController { @ApiForbiddenResponse({ description: 'Insufficient permissions to get the organization.' }) @ApiInternalServerErrorResponse({ description: 'Internal server error while getting the organization.' }) public async findOrganisationById(@Param() params: OrganisationByIdParams): Promise { - const result: OrganisationResponse | SchulConnexError = await this.uc.findOrganisationById( + const result: Result, DomainError> = await this.organisationService.findOrganisationById( params.organisationId, ); - if (result instanceof OrganisationResponse) { - return result; + if (result.ok) { + return new OrganisationResponse(result.value); + } else { + throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException( + SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(result.error), + ); } - throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException(result); } // Done @@ -251,10 +288,12 @@ export class OrganisationController { // TODO starting here lots of mappers in the uc // Done + //Done + // findAdministriertVon @Get(':organisationId/administriert') @ApiOkResponse({ description: 'The organizations were successfully returned.', - type: [OrganisationResponseLegacy], + type: [OrganisationResponse], headers: PagingHeadersObject, }) @ApiUnauthorizedResponse({ description: 'Not authorized to get organizations.' }) @@ -263,8 +302,17 @@ export class OrganisationController { public async getAdministrierteOrganisationen( @Param() routeParams: OrganisationByIdParams, @Query() queryParams: OrganisationByIdQueryParams, - ): Promise> { - const result: Paged | SchulConnexError = await this.uc.findAdministriertVon( + ): Promise> { + const parentOrg: Result, DomainError> = await this.organisationService.findOrganisationById( + routeParams.organisationId, + ); + if (!parentOrg.ok) { + throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException( + SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(parentOrg.error), + ); + } + + const result: Paged> = await this.organisationService.findAllAdministriertVon( routeParams.organisationId, queryParams.searchFilter, ); @@ -272,12 +320,24 @@ export class OrganisationController { if (result instanceof SchulConnexError) { throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException(result); } - const response: PagedResponse = new PagedResponse(result); + + const organisations: OrganisationResponse[] = result.items.map( + (item: Organisation) => new OrganisationResponse(item), + ); + + const response: PagedResponse = new PagedResponse({ + total: result.total, + offset: result.offset, + limit: result.limit, + items: organisations, + }); return response; } // Done + // setAdministriertVon + //Done @Post(':organisationId/administriert') @ApiCreatedResponse({ description: 'The organisation was successfully updated.' }) @ApiBadRequestResponse({ description: 'The organisation could not be modified.', type: DbiamOrganisationError }) @@ -288,20 +348,23 @@ export class OrganisationController { @Param() params: OrganisationByIdParams, @Body() body: OrganisationByIdBodyParams, ): Promise { - const result: void | SchulConnexError | OrganisationSpecificationError = await this.uc.setAdministriertVon( - params.organisationId, - body.organisationId, - ); + const res: Result = + await this.organisationService.setAdministriertVon(params.organisationId, body.organisationId); - if (result instanceof OrganisationSpecificationError) { - throw result; - } - if (result) { - throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException(result); + if (!res.ok) { + // Avoid passing OrganisationSpecificationError to SchulConnexErrorMapper + if (res.error instanceof OrganisationSpecificationError) { + throw res.error; + } + throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException( + SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(res.error), + ); } } // Done + // findZugehoerigZu + //Done @Get(':organisationId/zugehoerig') @ApiOkResponse({ description: 'The organizations were successfully returned.', @@ -314,19 +377,40 @@ export class OrganisationController { public async getZugehoerigeOrganisationen( @Param() params: OrganisationByIdParams, ): Promise> { - const result: Paged | SchulConnexError = await this.uc.findZugehoerigZu( + const parentOrg: Result, DomainError> = await this.organisationService.findOrganisationById( + params.organisationId, + ); + if (!parentOrg.ok) { + throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException( + SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(parentOrg.error), + ); + } + + const result: Paged> = await this.organisationService.findAllZugehoerigZu( params.organisationId, ); if (result instanceof SchulConnexError) { throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException(result); } - const response: PagedResponse = new PagedResponse(result); + + const organisations: OrganisationResponse[] = result.items.map( + (item: Organisation) => new OrganisationResponse(item), + ); + + const response: PagedResponse = new PagedResponse({ + total: result.total, + offset: result.offset, + limit: result.limit, + items: organisations, + }); return response; } // Done + // setZugehoerigZu + //Done @Post(':organisationId/zugehoerig') @ApiCreatedResponse({ description: 'The organisation was successfully updated.' }) @ApiBadRequestResponse({ description: 'The organisation could not be modified.', type: DbiamOrganisationError }) @@ -337,16 +421,19 @@ export class OrganisationController { @Param() params: OrganisationByIdParams, @Body() body: OrganisationByIdBodyParams, ): Promise { - const result: void | SchulConnexError | OrganisationSpecificationError = await this.uc.setZugehoerigZu( + const res: Result = await this.organisationService.setZugehoerigZu( params.organisationId, body.organisationId, ); - if (result instanceof OrganisationSpecificationError) { - throw result; - } - if (result) { - throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException(result); + if (!res.ok) { + // Avoid passing OrganisationSpecificationError to SchulConnexErrorMapper + if (res.error instanceof OrganisationSpecificationError) { + throw res.error; + } + throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException( + SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(res.error), + ); } } } diff --git a/src/modules/organisation/api/organisation.uc.spec.ts b/src/modules/organisation/api/organisation.uc.spec.ts deleted file mode 100644 index 6ffebd7e4..000000000 --- a/src/modules/organisation/api/organisation.uc.spec.ts +++ /dev/null @@ -1,341 +0,0 @@ -import { DeepMocked, createMock } from '@golevelup/ts-jest'; -import { Test, TestingModule } from '@nestjs/testing'; -import { ConfigTestModule, DoFactory, MapperTestModule } from '../../../../test/utils/index.js'; -import { EntityCouldNotBeCreated } from '../../../shared/error/entity-could-not-be-created.error.js'; -import { EntityNotFoundError } from '../../../shared/error/entity-not-found.error.js'; -import { SchulConnexError } from '../../../shared/error/schul-connex.error.js'; -import { Paged } from '../../../shared/paging/paged.js'; -import { OrganisationDo } from '../domain/organisation.do.js'; -import { OrganisationsTyp } from '../domain/organisation.enums.js'; -import { OrganisationService } from '../domain/organisation.service.js'; -import { CreateOrganisationDto } from './create-organisation.dto.js'; -import { CreatedOrganisationDto } from './created-organisation.dto.js'; -import { FindOrganisationDto } from './find-organisation.dto.js'; -import { OrganisationApiMapperProfile } from './organisation-api.mapper.profile.js'; -import { OrganisationResponseLegacy } from './organisation.response.legacy.js'; -import { OrganisationUc } from './organisation.uc.js'; -import { UpdateOrganisationDto } from './update-organisation.dto.js'; -import { UpdatedOrganisationDto } from './updated-organisation.dto.js'; -import { EntityCouldNotBeUpdated } from '../../../shared/error/entity-could-not-be-updated.error.js'; -import { OrganisationSpecificationError } from '../specification/error/organisation-specification.error.js'; - -describe('OrganisationUc', () => { - let module: TestingModule; - let organisationUc: OrganisationUc; - let organisationServiceMock: DeepMocked; - - beforeAll(async () => { - module = await Test.createTestingModule({ - imports: [MapperTestModule, ConfigTestModule], - providers: [ - OrganisationUc, - OrganisationApiMapperProfile, - { - provide: OrganisationService, - useValue: createMock(), - }, - ], - }).compile(); - organisationUc = module.get(OrganisationUc); - organisationServiceMock = module.get(OrganisationService); - }); - - afterAll(async () => { - await module.close(); - }); - - beforeEach(() => { - jest.resetAllMocks(); - }); - - it('should be defined', () => { - expect(organisationUc).toBeDefined(); - }); - - describe('createOrganisation', () => { - describe('when result is ok', () => { - it('should create an organisation', async () => { - organisationServiceMock.createOrganisation.mockResolvedValue({ - ok: true, - value: DoFactory.createOrganisation(true), - }); - await expect(organisationUc.createOrganisation({} as CreateOrganisationDto)).resolves.toBeInstanceOf( - CreatedOrganisationDto, - ); - }); - }); - - describe('when result is not ok and instance of OrganisationSpecificationError', () => { - it('should return an error', async () => { - organisationServiceMock.createOrganisation.mockResolvedValue({ - ok: false, - error: new OrganisationSpecificationError('error', undefined), - }); - await expect(organisationUc.createOrganisation({} as CreateOrganisationDto)).resolves.toBeInstanceOf( - OrganisationSpecificationError, - ); - }); - }); - - describe('when result is not ok', () => { - it('should return an error', async () => { - organisationServiceMock.createOrganisation.mockResolvedValue({ - ok: false, - error: new EntityCouldNotBeCreated(''), - }); - await expect(organisationUc.createOrganisation({} as CreateOrganisationDto)).resolves.toBeInstanceOf( - SchulConnexError, - ); - }); - }); - }); - - describe('updateOrganisation', () => { - describe('when result is ok', () => { - it('should update an organisation', async () => { - organisationServiceMock.updateOrganisation.mockResolvedValue({ - ok: true, - value: DoFactory.createOrganisation(true), - }); - await expect(organisationUc.updateOrganisation({} as UpdateOrganisationDto)).resolves.toBeInstanceOf( - UpdatedOrganisationDto, - ); - }); - }); - - describe('when result is not ok and instance of OrganisationSpecificationError', () => { - it('should return an error', async () => { - organisationServiceMock.updateOrganisation.mockResolvedValue({ - ok: false, - error: new OrganisationSpecificationError('error', undefined), - }); - await expect(organisationUc.updateOrganisation({} as UpdateOrganisationDto)).resolves.toBeInstanceOf( - OrganisationSpecificationError, - ); - }); - }); - - describe('when result is not ok', () => { - it('should return an error', async () => { - organisationServiceMock.updateOrganisation.mockResolvedValue({ - ok: false, - error: new EntityCouldNotBeCreated(''), - }); - await expect(organisationUc.updateOrganisation({} as UpdateOrganisationDto)).resolves.toBeInstanceOf( - SchulConnexError, - ); - }); - }); - }); - - describe('findOrganisationById', () => { - it('should find an organisation by its id', async () => { - const organisation: OrganisationDo = DoFactory.createOrganisation(true); - organisationServiceMock.findOrganisationById.mockResolvedValue({ - ok: true, - value: organisation, - }); - await expect(organisationUc.findOrganisationById(organisation.id)).resolves.not.toThrow(); - }); - - it('should throw an error', async () => { - const organisation: OrganisationDo = DoFactory.createOrganisation(true); - organisationServiceMock.findOrganisationById.mockResolvedValue({ - ok: false, - error: new EntityNotFoundError(''), - }); - await expect(organisationUc.findOrganisationById(organisation.id)).resolves.toBeInstanceOf( - SchulConnexError, - ); - }); - }); - - describe('findRootOrganisation', () => { - it('should find the root organisation', async () => { - const organisation: OrganisationDo = DoFactory.createOrganisation(true); - organisationServiceMock.findOrganisationById.mockResolvedValue({ - ok: true, - value: organisation, - }); - await expect(organisationUc.findRootOrganisation()).resolves.not.toThrow(); - }); - - it('should throw an error', async () => { - organisationServiceMock.findOrganisationById.mockResolvedValue({ - ok: false, - error: new EntityNotFoundError(''), - }); - await expect(organisationUc.findRootOrganisation()).resolves.toBeInstanceOf(SchulConnexError); - }); - }); - - describe('setAdministriertVon', () => { - it('should find the root organisation', async () => { - organisationServiceMock.setAdministriertVon.mockResolvedValue({ - ok: true, - value: undefined, - }); - await expect(organisationUc.setAdministriertVon('', '')).resolves.not.toThrow(); - }); - - describe('when result is not ok and instance of OrganisationSpecificationError', () => { - it('should return an error', async () => { - organisationServiceMock.setAdministriertVon.mockResolvedValue({ - ok: false, - error: new OrganisationSpecificationError('error', undefined), - }); - - await expect(organisationUc.setAdministriertVon('', '')).resolves.toBeInstanceOf( - OrganisationSpecificationError, - ); - }); - }); - - describe('when result is not ok', () => { - it('should throw an error', async () => { - organisationServiceMock.setAdministriertVon.mockResolvedValue({ - ok: false, - error: new EntityCouldNotBeUpdated('', ''), - }); - - await expect(organisationUc.setAdministriertVon('', '')).resolves.toBeInstanceOf(SchulConnexError); - }); - }); - }); - - describe('setZugehoerigZu', () => { - it('should find the root organisation', async () => { - organisationServiceMock.setZugehoerigZu.mockResolvedValue({ - ok: true, - value: undefined, - }); - await expect(organisationUc.setZugehoerigZu('', '')).resolves.not.toThrow(); - }); - - describe('when result is not ok and instance of OrganisationSpecificationError', () => { - it('should throw an error if result is not ok and instanceof OrganisationSpecificationError', async () => { - organisationServiceMock.setZugehoerigZu.mockResolvedValue({ - ok: false, - error: new OrganisationSpecificationError('error', undefined), - }); - - await expect(organisationUc.setZugehoerigZu('', '')).resolves.toBeInstanceOf( - OrganisationSpecificationError, - ); - }); - }); - - describe('when result is not ok', () => { - it('should throw an error', async () => { - organisationServiceMock.setZugehoerigZu.mockResolvedValue({ - ok: false, - error: new EntityCouldNotBeUpdated('', ''), - }); - - await expect(organisationUc.setZugehoerigZu('', '')).resolves.toBeInstanceOf(SchulConnexError); - }); - }); - }); - - describe('findAdministriertVon', () => { - describe('when parent organisation exists', () => { - it('should return all found organisations', async () => { - const organisationDos: OrganisationDo[] = DoFactory.createMany( - 2, - true, - DoFactory.createOrganisation, - ); - - organisationServiceMock.findOrganisationById.mockResolvedValueOnce({ - ok: true, - value: DoFactory.createOrganisation(true), - }); - - organisationServiceMock.findAllAdministriertVon.mockResolvedValue({ - total: organisationDos.length, - offset: 0, - limit: 0, - items: organisationDos, - }); - - const result: Paged | SchulConnexError = - await organisationUc.findAdministriertVon(''); - - expect(result).not.toBeInstanceOf(SchulConnexError); - - if (!(result instanceof SchulConnexError)) { - expect(result.total).toBe(2); - expect(result.items).toHaveLength(2); - expect(result.items[0]?.name).toEqual(organisationDos[0]?.name); - expect(result.items[1]?.name).toEqual(organisationDos[1]?.name); - expect(result.items[0]?.kennung).toEqual(organisationDos[0]?.kennung); - expect(result.items[1]?.kennung).toEqual(organisationDos[1]?.kennung); - expect(result.items[0]?.typ).toEqual(organisationDos[0]?.typ); - expect(result.items[1]?.typ).toEqual(organisationDos[1]?.typ); - } - }); - }); - - describe('when no parent organisation exists', () => { - it('should throw error', async () => { - organisationServiceMock.findOrganisationById.mockResolvedValueOnce({ - ok: false, - error: new EntityNotFoundError(), - }); - - await expect(organisationUc.findAdministriertVon('')).resolves.toBeInstanceOf(SchulConnexError); - }); - }); - }); - - describe('findZugehoerigZu', () => { - describe('when parent organisation exists', () => { - it('should return all found organisations', async () => { - const organisationDos: OrganisationDo[] = DoFactory.createMany( - 2, - true, - DoFactory.createOrganisation, - ); - - organisationServiceMock.findOrganisationById.mockResolvedValueOnce({ - ok: true, - value: DoFactory.createOrganisation(true), - }); - - organisationServiceMock.findAllZugehoerigZu.mockResolvedValue({ - total: organisationDos.length, - offset: 0, - limit: 0, - items: organisationDos, - }); - - const result: Paged | SchulConnexError = - await organisationUc.findZugehoerigZu(''); - - expect(result).not.toBeInstanceOf(SchulConnexError); - - if (!(result instanceof SchulConnexError)) { - expect(result.total).toBe(2); - expect(result.items).toHaveLength(2); - expect(result.items[0]?.name).toEqual(organisationDos[0]?.name); - expect(result.items[1]?.name).toEqual(organisationDos[1]?.name); - expect(result.items[0]?.kennung).toEqual(organisationDos[0]?.kennung); - expect(result.items[1]?.kennung).toEqual(organisationDos[1]?.kennung); - expect(result.items[0]?.typ).toEqual(organisationDos[0]?.typ); - expect(result.items[1]?.typ).toEqual(organisationDos[1]?.typ); - } - }); - }); - - describe('when no parent organisation exists', () => { - it('should throw error', async () => { - organisationServiceMock.findOrganisationById.mockResolvedValueOnce({ - ok: false, - error: new EntityNotFoundError(), - }); - - await expect(organisationUc.findZugehoerigZu('')).resolves.toBeInstanceOf(SchulConnexError); - }); - }); - }); -}); diff --git a/src/modules/organisation/api/organisation.uc.ts b/src/modules/organisation/api/organisation.uc.ts deleted file mode 100644 index 5730cd142..000000000 --- a/src/modules/organisation/api/organisation.uc.ts +++ /dev/null @@ -1,188 +0,0 @@ -import { Mapper } from '@automapper/core'; -import { getMapperToken } from '@automapper/nestjs'; -import { Inject, Injectable } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { DomainError } from '../../../shared/error/domain.error.js'; -import { SchulConnexErrorMapper } from '../../../shared/error/schul-connex-error.mapper.js'; -import { SchulConnexError } from '../../../shared/error/schul-connex.error.js'; -import { Paged } from '../../../shared/paging/paged.js'; -import { OrganisationDo } from '../domain/organisation.do.js'; -import { OrganisationService } from '../domain/organisation.service.js'; -import { CreateOrganisationDto } from './create-organisation.dto.js'; -import { CreatedOrganisationDto } from './created-organisation.dto.js'; -import { FindOrganisationDto } from './find-organisation.dto.js'; -import { OrganisationResponseLegacy } from './organisation.response.legacy.js'; -import { UpdateOrganisationDto } from './update-organisation.dto.js'; -import { UpdatedOrganisationDto } from './updated-organisation.dto.js'; -import { ServerConfig, DataConfig } from '../../../shared/config/index.js'; -import { OrganisationSpecificationError } from '../specification/error/organisation-specification.error.js'; -import { Organisation } from '../domain/organisation.js'; -import { CreateOrganisationBodyParams } from './create-organisation.body.params.js'; -import { OrganisationResponse } from './organisation.response.js'; - -@Injectable() -export class OrganisationUc { - private readonly ROOT_ORGANISATION_ID: string; - - public constructor( - private readonly organisationService: OrganisationService, - @Inject(getMapperToken()) private readonly mapper: Mapper, - config: ConfigService, - ) { - this.ROOT_ORGANISATION_ID = config.getOrThrow('DATA').ROOT_ORGANISATION_ID; - } - - public async createOrganisation( - organisationInput: CreateOrganisationBodyParams, - ): Promise | SchulConnexError | OrganisationSpecificationError> { - const organisation: Organisation = Organisation.createNew( - organisationInput.administriertVon ?? this.ROOT_ORGANISATION_ID, - organisationInput.zugehoerigZu ?? this.ROOT_ORGANISATION_ID, - organisationInput.kennung, - organisationInput.name, - organisationInput.namensergaenzung, - organisationInput.kuerzel, - organisationInput.typ, - organisationInput.traegerschaft, - ); - - const result: Result, DomainError> = await this.organisationService.createOrganisation( - organisation, - ); - - if (result.ok) { - return result.value; - } - //avoid passing OrganisationSpecificationError to SchulConnexErrorMapper - if (result.error instanceof OrganisationSpecificationError) { - return result.error; - } - - return SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(result.error); - } - - public async updateOrganisation( - organisation: Organisation, - ): Promise | SchulConnexError | OrganisationSpecificationError> { - const result: Result, DomainError> = await this.organisationService.updateOrganisation( - organisation, - ); - - if (result.ok) { - return result.value; - } - //avoid passing OrganisationSpecificationError to SchulConnexErrorMapper - if (result.error instanceof OrganisationSpecificationError) { - return result.error; - } - return SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(result.error); - } - - public async findOrganisationById(id: string): Promise { - const result: Result, DomainError> = await this.organisationService.findOrganisationById(id); - if (result.ok) { - return new OrganisationResponse(result.value); - } - return SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(result.error); - } - - public async findRootOrganisation(): Promise { - const result: Result, DomainError> = await this.organisationService.findOrganisationById( - this.ROOT_ORGANISATION_ID, - ); - - if (result.ok) { - return new OrganisationResponse(result.value); - } - - return SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(result.error); - } - - public async setAdministriertVon( - parentOrganisationId: string, - childOrganisationId: string, - ): Promise { - const res: Result = - await this.organisationService.setAdministriertVon(parentOrganisationId, childOrganisationId); - - if (!res.ok) { - //avoid passing OrganisationSpecificationError to SchulConnexErrorMapper - if (res.error instanceof OrganisationSpecificationError) { - return res.error; - } - return SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(res.error); - } - } - - public async setZugehoerigZu( - parentOrganisationId: string, - childOrganisationId: string, - ): Promise { - const res: Result = await this.organisationService.setZugehoerigZu( - parentOrganisationId, - childOrganisationId, - ); - - if (!res.ok) { - //avoid passing OrganisationSpecificationError to SchulConnexErrorMapper - if (res.error instanceof OrganisationSpecificationError) { - return res.error; - } - return SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(res.error); - } - } - - public async findAdministriertVon( - parentOrganisationId: string, - searchFilter?: string, - ): Promise | SchulConnexError> { - const parentOrg: Result, DomainError> = await this.organisationService.findOrganisationById( - parentOrganisationId, - ); - if (!parentOrg.ok) { - return SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(parentOrg.error); - } - - const result: Paged> = await this.organisationService.findAllAdministriertVon( - parentOrganisationId, - searchFilter, - ); - - const organisations: OrganisationResponse[] = result.items.map( - (item: Organisation) => new OrganisationResponse(item), - ); - - return { - total: result.total, - offset: result.offset, - limit: result.limit, - items: organisations, - }; - } - - public async findZugehoerigZu( - parentOrganisationId: string, - ): Promise | SchulConnexError> { - const parentOrg: Result< - OrganisationDo, - DomainError - > = await this.organisationService.findOrganisationById(parentOrganisationId); - if (!parentOrg.ok) { - return SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(parentOrg.error); - } - - const result: Paged> = - await this.organisationService.findAllZugehoerigZu(parentOrganisationId); - - const organisations: OrganisationResponse[] = result.items.map( - (item: Organisation) => new OrganisationResponse(item), - ); - - return { - total: result.total, - offset: result.offset, - limit: result.limit, - items: organisations, - }; - } -} diff --git a/src/modules/organisation/organisation-api.module.ts b/src/modules/organisation/organisation-api.module.ts index 222f7c8a4..52a1efc02 100644 --- a/src/modules/organisation/organisation-api.module.ts +++ b/src/modules/organisation/organisation-api.module.ts @@ -2,13 +2,12 @@ import { Module } from '@nestjs/common'; import { LoggerModule } from '../../core/logging/logger.module.js'; import { OrganisationController } from './api/organisation.controller.js'; import { OrganisationModule } from './organisation.module.js'; -import { OrganisationUc } from './api/organisation.uc.js'; import { OrganisationApiMapperProfile } from './api/organisation-api.mapper.profile.js'; import { EventModule } from '../../core/eventbus/index.js'; @Module({ imports: [LoggerModule.register(OrganisationModule.name), OrganisationModule, EventModule], - providers: [OrganisationApiMapperProfile, OrganisationUc], + providers: [OrganisationApiMapperProfile], controllers: [OrganisationController], }) export class OrganisationApiModule {}