organizations.service.ts 8.36 KB
Newer Older
1
import { Injectable, Logger, InternalServerErrorException, NotFoundException, ForbiddenException } from '@nestjs/common';
2
import { Organization } from './organization.entity';
3
import { InjectRepository } from '@nestjs/typeorm';
4
5
6
import { LinksService } from '../links/links.service';
import { OrganizationsRO, OrganizationDTO } from './organization.dto';
import { OrganizationRepository } from './organization.repository';
7
import * as uuidv4 from 'uuid/v4';
FORESTIER Fabien's avatar
FORESTIER Fabien committed
8
import { ConfigService } from '../configuration/config.service';
9
10
11
12

@Injectable()
export class OrganizationsService {

13
14
  private logger: Logger;

15
16
  constructor(
    @InjectRepository(Organization)
17
    private organizationRepository: OrganizationRepository,
18
    private linksService: LinksService,
FORESTIER Fabien's avatar
FORESTIER Fabien committed
19
    private _configService: ConfigService,
20
21
22
  ) {
    this.logger = new Logger(OrganizationsService.name);
  }
23

FORESTIER Fabien's avatar
FORESTIER Fabien committed
24
  async findAll(userGroups, query): Promise<OrganizationsRO> {
25
    try {
26
27
      this.logger.log('Entering function', `${OrganizationsService.name} - ${this.findAll.name}`);

28
29
30
      const qb = await this.organizationRepository
        .createQueryBuilder('organization')
        .leftJoinAndSelect('organization.links', 'links');
31
32

      const [key, value] = query.q ? query.q.split(':') : [null, null];
FORESTIER Fabien's avatar
FORESTIER Fabien committed
33

34
      // Only admin can see drafts
FORESTIER Fabien's avatar
FORESTIER Fabien committed
35
36
37
38
39
40
      if (!userGroups || !userGroups.includes(this._configService.config.groupNames.admin)) {
        qb.where(`organization.published = true`);
        key && value ? qb.andWhere(`organization.${key} = :value`, { value }) : null;
      } else {
        key && value ? qb.where(`organization.${key} = :value`, { value }) : null;
      }
41
42
43
44
45
46
47
48
49

      // Sorting
      if ('sort_by' in query) {
        const sort = query.sort_by ? query.sort_by.split('.') : ['name', 'ASC'];
        sort[1] = sort[1].toUpperCase();
        qb.orderBy('organization.' + sort[0], sort[1]);
      }

      const organizationsCount = await qb.getCount().catch((error) => {
50
        this.logger.error(`Error while getting the count of organizations.`, `${error}`, `${OrganizationsService.name} - ${this.findAll.name}`);
51
52
53
54
55
56
57
58
59
60
61
62
        throw new InternalServerErrorException({ error, message: 'Error while getting the count of organizations.' });
      });

      if ('limit' in query) {
        qb.limit(query.limit);
      }

      if ('offset' in query) {
        qb.offset(query.offset);
      }

      const organizations = await qb.getMany().catch((error) => {
63
        this.logger.error(`Error while getting the list of organizations.`, `${error}`, `${OrganizationsService.name} - ${this.findAll.name}`);
64
65
66
67
68
69
        throw new InternalServerErrorException({ error, message: 'Error while getting the list of organizations.' });
      });

      return { organizations, organizationsCount };
    } catch (error) {
      throw error;
70
    }
71
72
  }

73
  async findOne(userGroups, id) {
74
    try {
75
76
      this.logger.log('Entering function', `${OrganizationsService.name} - ${this.findOne.name}`);

77
      const organization = await this.organizationRepository.findOne(id).catch((error) => {
78
        this.logger.error(`Error while looking the organization with id ${id}.`, `${error}`, `${OrganizationsService.name} - ${this.findOne.name}`);
79
80
81
        throw new InternalServerErrorException({ error, message: 'Error while looking the organization with id ${id}.' });
      });

82
83
84
85
86
87
88
89
90
      if (!organization) {
        throw new NotFoundException({ message: 'No organization with such id have been found' });
      }

      // Only admin can see an unpublished data producer
      if ((!userGroups || !userGroups.includes(this._configService.config.groupNames.admin)) && organization.published === false) {
        throw new ForbiddenException({ message: 'You don\'t have access to this data producer' });
      }

91
92
93
94
      return organization;
    } catch (error) {
      throw error;
    }
95
96
  }

97
  async findLinks(userGroups, id) {
98
    try {
99
100
      this.logger.log('Entering function', `${OrganizationsService.name} - ${this.findLinks.name}`);

101
      const organization = await this.organizationRepository.findOne(id).catch((error) => {
102
        this.logger.error(
103
          `Error while looking for the link of the organization with id ${id}.`, `${error}`, `${OrganizationsService.name} - ${this.findLinks.name}`,
104
        );
105
106
107
108
109
110
        throw new InternalServerErrorException({ error, message: 'Error while looking for the link of the organization with id ${id}.' });
      });

      if (!organization) {
        throw new NotFoundException({ message: 'No organization with such id have been found' });
      }
111
112
113
114
115
116

      // Only admin can see an unpublished data producer
      if ((!userGroups || !userGroups.includes(this._configService.config.groupNames.admin)) && organization.published === false) {
        throw new ForbiddenException({ message: 'You don\'t have access to this data producer' });
      }

117
118
119
120
      return organization.links;
    } catch (error) {
      throw error;
    }
121
122
  }

123
  async create(organization: OrganizationDTO) {
124
    try {
125
126
      this.logger.log('Entering function', `${OrganizationsService.name} - ${this.create.name}`);

127
128
      // cf https://github.com/typeorm/typeorm/issues/2924#issuecomment-430265476
      const organizationEntity = Object.assign(new Organization(), organization);
129
130
131
132
133
134
135
      organizationEntity.id = uuidv4();

      organizationEntity.links.forEach((link) => {
        if (!link.id) {
          link.id = uuidv4();
        }
      });
136
137

      const organizationCreated = await this.organizationRepository.save(organizationEntity).catch((error) => {
138
        this.logger.error(`Error saving the organization into the database.`, `${error}`, `${OrganizationsService.name} - ${this.create.name}`);
139
140
141
        throw new InternalServerErrorException({ error, message: 'Error saving the organization into the database.' });
      });

142
143
      this.logger.log('Organization created:', `${OrganizationsService.name} - ${this.findAll.name}`);
      this.logger.log(organizationCreated, `${OrganizationsService.name} - ${this.findAll.name}`);
144
145
146

      return organizationCreated;
    } catch (error) {
147
      this.logger.error('Failed to create the organization.', `${error}`, `${OrganizationsService.name} - ${this.create.name}`);
148
149
      throw error;
    }
150
151
  }

152
  async update(id, organization: OrganizationDTO) {
153
    try {
154
155
      this.logger.log('Entering function', `${OrganizationsService.name} - ${this.update.name}`);

156
      const toUpdate = await this.organizationRepository.findOne(id).catch((error) => {
157
        this.logger.error(`Error while looking for the organization with the id ${id}.`, `${error}`, `${OrganizationsService.name} - ${this.update.name}`);
158
159
160
161
162
163
164
        throw new InternalServerErrorException({ error, message: 'Error while looking for the organization.' });
      });

      if (!toUpdate) {
        throw new NotFoundException({ message: 'No item exists with the given id' });
      }

165
166
167
168
169
170
      const updated = Object.assign(toUpdate, organization);
      updated.links.forEach((link) => {
        if (!link.id) {
          link.id = uuidv4();
        }
      });
171

172
      const saved = await this.organizationRepository.save(updated).catch((error) => {
173
        this.logger.error(`Error while updating the organization.`, `${error}`, `${OrganizationsService.name} - ${this.update.name}`);
174
175
176
177
178
179
180
181
        throw new InternalServerErrorException({ error, message: 'Error while updating the organization.' });
      });

      this.linksService.deleteOrphans();

      return saved;
    } catch (error) {
      throw error;
182
    }
183
184
  }

185
186
  async delete(id): Promise<any> {
    try {
187
188
189
      this.logger.log('Entering function', `${OrganizationsService.name} - ${this.delete.name}`);

      const toDelete = await this.organizationRepository.findOne(id).catch((error) => {
190
        this.logger.error(`Error while looking the organization with id ${id}.`, `${error}`, `${OrganizationsService.name} - ${this.delete.name}`);
191
192
        throw new InternalServerErrorException({ error, message: 'Error while looking the organization with id ${id}.' });
      });
193
194
195
196
197
198

      if (!toDelete) {
        throw new NotFoundException({ message: 'No organization exists with the given id' });
      }

      return await this.organizationRepository.delete(id).catch((error) => {
199
        this.logger.error(`Error while deleting the organization with id ${id}.`, `${error}`, `${OrganizationsService.name} - ${this.delete.name}`);
200
201
202
203
204
        throw new InternalServerErrorException({ error, message: 'Error while deleting the organization with id ${id}.' });
      });
    } catch (error) {
      throw error;
    }
205
206
  }
}