Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • web-et-numerique/factory/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server
1 result
Show changes
Showing
with 321 additions and 127 deletions
......@@ -4,7 +4,9 @@ import { Observable } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { Page } from './schemas/page.schema';
import { rewriteGhostImgUrl } from '../shared/utils';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('pages')
@Controller('pages')
export class PagesController {
private readonly logger = new Logger(PagesController.name);
......
import { Document } from 'mongoose';
export interface IParameters extends Document {
lockdownInfoDisplay: boolean;
}
import { getModelToken } from '@nestjs/mongoose';
import { Test, TestingModule } from '@nestjs/testing';
import { ParametersController } from './parameters.controller';
import { ParametersService } from './parameters.service';
import { Parameters } from './schemas/parameters.schema';
describe('ParametersController', () => {
let controller: ParametersController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
ParametersService,
{
provide: getModelToken('Parameters'),
useValue: Parameters,
},
],
controllers: [ParametersController],
}).compile();
controller = module.get<ParametersController>(ParametersController);
});
it('should be defined', async () => {
expect(controller).toBeDefined();
});
it('should get parameters', async () => {
const result = { lockdownInfoDisplay: false };
jest.spyOn(controller, 'getParameters').mockImplementation(async (): Promise<Parameters> => result);
expect(await controller.getParameters()).toBe(result);
});
it('should set lockdownInfoDisplay', async () => {
const result = { lockdownInfoDisplay: false };
jest
.spyOn(controller, 'setParameterLockdownInfoDisplay')
.mockImplementation(async (): Promise<Parameters> => result);
const lockdownInfoDisplayValue = { lockdownInfoDisplay: false };
expect(await controller.setParameterLockdownInfoDisplay(lockdownInfoDisplayValue)).toBe(result);
});
});
import { Body, Controller, Post, Get, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { Roles } from '../users/decorators/roles.decorator';
import { RolesGuard } from '../users/guards/roles.guard';
import { ParametersService } from './parameters.service';
import { Parameters } from './schemas/parameters.schema';
@Controller('parameters')
export class ParametersController {
constructor(private parametersService: ParametersService) {}
@Get()
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
public async getParameters(): Promise<Parameters> {
return this.parametersService.getParameters();
}
@Post()
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
public async setParameterLockdownInfoDisplay(@Body() data: { lockdownInfoDisplay: boolean }): Promise<Parameters> {
return this.parametersService.setParameterLockdownInfoDisplay(data.lockdownInfoDisplay);
}
}
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { ParametersController } from './parameters.controller';
import { ParametersService } from './parameters.service';
import { Parameters, ParametersSchema } from './schemas/parameters.schema';
@Module({
imports: [MongooseModule.forFeature([{ name: Parameters.name, schema: ParametersSchema }])],
controllers: [ParametersController],
providers: [ParametersService],
})
export class ParametersModule {}
import { getModelToken } from '@nestjs/mongoose';
import { Test, TestingModule } from '@nestjs/testing';
import { mockParametersModel } from '../../test/mock/services/parameters.mock.service';
import { IParameters } from './interface/parameters.interface';
import { ParametersService } from './parameters.service';
import { Parameters } from './schemas/parameters.schema';
describe('ParametersService', () => {
let service: ParametersService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
ParametersService,
{
provide: getModelToken(Parameters.name),
useValue: mockParametersModel,
},
],
}).compile();
service = module.get<ParametersService>(ParametersService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
it('should get parameters', async () => {
const result: IParameters = { lockdownInfoDisplay: false } as IParameters;
jest.spyOn(service, 'getParameters').mockImplementation(async (): Promise<Parameters> => result);
expect(await service.getParameters()).toBe(result);
});
it('should set Parameter LockdownInfoDisplay', async () => {
const result: IParameters = { lockdownInfoDisplay: false } as IParameters;
jest.spyOn(service, 'setParameterLockdownInfoDisplay').mockImplementation(async (): Promise<Parameters> => result);
expect(await service.setParameterLockdownInfoDisplay(false)).toBe(result);
});
});
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { IParameters } from './interface/parameters.interface';
import { Parameters } from './schemas/parameters.schema';
@Injectable()
export class ParametersService {
constructor(@InjectModel(Parameters.name) private parametersModel: Model<IParameters>) {}
public async getParameters(): Promise<Parameters> {
const parameters = await this.parametersModel.findOne();
if (!parameters) {
throw new HttpException('Parameters not found', HttpStatus.NOT_FOUND);
}
return parameters;
}
public async setParameterLockdownInfoDisplay(lockdownInfoDisplay: boolean): Promise<Parameters> {
const parameters = await this.parametersModel.findOne();
if (!parameters) {
throw new HttpException('Parameters not found', HttpStatus.NOT_FOUND);
}
parameters.lockdownInfoDisplay = lockdownInfoDisplay;
await parameters.save();
return parameters;
}
}
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
export type ParametersDocument = Parameters & Document;
@Schema({ timestamps: { createdAt: 'createdAt', updatedAt: 'updatedAt' } })
export class Parameters {
@Prop({ required: true })
lockdownInfoDisplay: boolean;
}
export const ParametersSchema = SchemaFactory.createForClass(Parameters);
import { Body, Controller, Delete, Get, Param, Post, Put, Request, UseGuards } from '@nestjs/common';
import { ApiBody, ApiParam } from '@nestjs/swagger';
import { ApiBody, ApiParam, ApiTags } from '@nestjs/swagger';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { StructuresService } from '../structures/services/structures.service';
import { IsPersonalOfferOwnerGuard } from '../users/guards/isPersonalOfferOwner.guard';
......@@ -10,6 +10,7 @@ import { PersonalOfferDto } from './dto/personal-offer.dto';
import { PersonalOffersService } from './personal-offers.service';
import { PersonalOfferDocument } from './schemas/personal-offer.schema';
@ApiTags('personnal-offers')
@Controller('personal-offers')
export class PersonalOffersController {
constructor(
......
import { Controller, Get, HttpException, HttpService, HttpStatus, Logger, Param, Query } from '@nestjs/common';
import { Observable } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { ApiQuery } from '@nestjs/swagger';
import { ApiQuery, ApiTags } from '@nestjs/swagger';
import { Post } from './schemas/post.schema';
import { PostsService } from './posts.service';
import { Tag } from './schemas/tag.schema';
import { PostWithMeta } from './schemas/postWithMeta.schema';
@ApiTags('posts')
@Controller('posts')
export class PostsController {
private readonly logger = new Logger(PostsController.name);
......
......@@ -6,8 +6,8 @@ import { PersonalOfferDocument } from '../../personal-offers/schemas/personal-of
export class StructureDto {
numero: string;
createdAt: string;
updatedAt: string;
createdAt: Date;
updatedAt: Date;
deletedAt: Date;
@IsNotEmpty()
......
......@@ -2,18 +2,16 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Type } from 'class-transformer';
import { ArrayNotEmpty, IsNotEmpty, ValidateNested } from 'class-validator';
import { Document, Types } from 'mongoose';
import { Address } from './address.schema';
import { Week } from '../../shared/schemas/week.schema';
import { PersonalOfferDocument } from '../../personal-offers/schemas/personal-offer.schema';
import { Week } from '../../shared/schemas/week.schema';
import { Address } from './address.schema';
export type StructureDocument = Structure & Document;
@Schema({ timestamps: true })
@Schema({ timestamps: { createdAt: 'createdAt', updatedAt: 'updatedAt' } })
export class Structure {
constructor(data: Partial<Structure> = {}) {
this.structureName = data.structureName;
this.createdAt = data.createdAt;
this.updatedAt = data.updatedAt;
this.numero = data.numero;
this.structureType = data.structureType;
this.description = data.description;
......@@ -59,12 +57,6 @@ export class Structure {
@Prop()
numero: string;
@Prop()
createdAt: string;
@Prop()
updatedAt: string;
@Prop()
@IsNotEmpty()
structureName: string;
......@@ -196,6 +188,12 @@ export class Structure {
@Prop({ type: [{ type: Types.ObjectId, ref: 'PersonalOffer' }] })
personalOffers: PersonalOfferDocument[];
@Prop()
createdAt: Date;
@Prop()
updatedAt: Date;
}
export const StructureSchema = SchemaFactory.createForClass(Structure);
......
......@@ -2,22 +2,25 @@ import { HttpModule } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { getModelToken } from '@nestjs/mongoose';
import { Test, TestingModule } from '@nestjs/testing';
import * as bcrypt from 'bcrypt';
import { Types } from 'mongoose';
import { personalOffersDataMock } from '../../../test/mock/data/personalOffers.mock.data';
import { structuresDocumentDataMock } from '../../../test/mock/data/structures.mock.data';
import { mockParametersModel } from '../../../test/mock/services/parameters.mock.service';
import { UsersServiceMock } from '../../../test/mock/services/user.mock.service';
import { CategoriesFormationsService } from '../../categories/services/categories-formations.service';
import { ConfigurationService } from '../../configuration/configuration.service';
import { MailerModule } from '../../mailer/mailer.module';
import { ParametersService } from '../../parameters/parameters.service';
import { Parameters } from '../../parameters/schemas/parameters.schema';
import { PersonalOfferDocument } from '../../personal-offers/schemas/personal-offer.schema';
import { SearchModule } from '../../search/search.module';
import { IUser } from '../../users/interfaces/user.interface';
import { UsersService } from '../../users/services/users.service';
import { StructureDto } from '../dto/structure.dto';
import { Structure, StructureDocument } from '../schemas/structure.schema';
import { StructuresSearchService } from './structures-search.service';
import { StructuresService } from './structures.service';
import { IUser } from '../../users/interfaces/user.interface';
import * as bcrypt from 'bcrypt';
import { personalOffersDataMock } from '../../../test/mock/data/personalOffers.mock.data';
import { PersonalOfferDocument } from '../../personal-offers/schemas/personal-offer.schema';
import { structuresDocumentDataMock } from '../../../test/mock/data/structures.mock.data';
function hashPassword() {
return bcrypt.hashSync(process.env.USER_PWD, process.env.SALT);
......@@ -227,6 +230,7 @@ describe('StructuresService', () => {
providers: [
StructuresService,
ConfigurationService,
ParametersService,
{
provide: StructuresSearchService,
useValue: structuresSearchServiceMock,
......@@ -244,6 +248,10 @@ describe('StructuresService', () => {
provide: UsersService,
useClass: UsersServiceMock,
},
{
provide: getModelToken(Parameters.name),
useValue: mockParametersModel,
},
],
}).compile();
......@@ -418,22 +426,22 @@ describe('StructuresService', () => {
.mockResolvedValueOnce({
_id: Types.ObjectId('61e9260b2ac971550065e261'),
coord: [4.844309, 45.865288],
createdAt: 'Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)',
updatedAt: 'Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)',
createdAt: new Date('Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)'),
updatedAt: new Date('Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)'),
__v: 0,
} as StructureDocument)
.mockResolvedValueOnce({
_id: Types.ObjectId('61e9260b2ac971550065e261'),
coord: [4.844309, 45.865288],
createdAt: 'Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)',
updatedAt: 'Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)',
createdAt: new Date('Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)'),
updatedAt: new Date('Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)'),
dataShareConsentDate: null,
} as StructureDocument)
.mockResolvedValueOnce({
_id: Types.ObjectId('61e9260b2ac971550065e261'),
coord: [4.844309, 45.865288],
createdAt: 'Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)',
updatedAt: 'Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)',
createdAt: new Date('Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)'),
updatedAt: new Date('Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)'),
dataShareConsentDate: new Date(),
} as StructureDocument);
const res = await service.getAllDataConsentPendingStructures(user);
......@@ -468,23 +476,23 @@ describe('StructuresService', () => {
.mockResolvedValueOnce({
_id: Types.ObjectId('61e9260b2ac971550065e261'),
coord: [4.844309, 45.865288],
createdAt: 'Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)',
updatedAt: 'Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)',
createdAt: new Date('Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)'),
updatedAt: new Date('Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)'),
dataShareConsentDate: null,
__v: 0,
} as StructureDocument)
.mockResolvedValueOnce({
_id: Types.ObjectId('61e9260b2ac971550065e261'),
coord: [4.844309, 45.865288],
createdAt: 'Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)',
updatedAt: 'Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)',
createdAt: new Date('Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)'),
updatedAt: new Date('Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)'),
dataShareConsentDate: null,
} as StructureDocument)
.mockResolvedValueOnce({
_id: Types.ObjectId('61e9260b2ac971550065e261'),
coord: [4.844309, 45.865288],
createdAt: 'Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)',
updatedAt: 'Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)',
createdAt: new Date('Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)'),
updatedAt: new Date('Thu Jan 20 2022 10:06:19 GMT+0100 (heure normale d’Europe centrale)'),
dataShareConsentDate: new Date(),
} as StructureDocument);
const res = await service.getAllDataConsentPendingStructures(user);
......
import { HttpException, HttpService, Injectable, HttpStatus, Logger } from '@nestjs/common';
import { HttpException, HttpService, HttpStatus, Injectable, Logger } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Types, Model, FilterQuery, DocumentDefinition } from 'mongoose';
import { Observable } from 'rxjs';
import { Cron, CronExpression } from '@nestjs/schedule';
import { AxiosResponse } from 'axios';
import { Structure, StructureDocument } from '../schemas/structure.schema';
import * as ejs from 'ejs';
import { StructureDto } from '../dto/structure.dto';
import { UsersService } from '../../users/services/users.service';
import { User } from '../../users/schemas/user.schema';
import { MailerService } from '../../mailer/mailer.service';
import { Cron, CronExpression } from '@nestjs/schedule';
import { DateTime } from 'luxon';
import { IUser } from '../../users/interfaces/user.interface';
import * as _ from 'lodash';
import { OwnerDto } from '../../users/dto/owner.dto';
import { StructuresSearchService } from './structures-search.service';
import { CategoriesFormationsModule } from '../../categories/schemas/categoriesFormationsModule.schema';
import { DateTime } from 'luxon';
import { DocumentDefinition, FilterQuery, Model, Types } from 'mongoose';
import { Observable } from 'rxjs';
import { UnclaimedStructureDto } from '../../admin/dto/unclaimed-structure-dto';
import { CategoriesModule } from '../../categories/categories.module';
import { CategoriesAccompagnement } from '../../categories/schemas/categoriesAccompagnement.schema';
import { CategoriesFormations } from '../../categories/schemas/categoriesFormations.schema';
import { CategoriesFormationsModule } from '../../categories/schemas/categoriesFormationsModule.schema';
import { CategoriesOthers } from '../../categories/schemas/categoriesOthers.schema';
import { UnclaimedStructureDto } from '../../admin/dto/unclaimed-structure-dto';
import { depRegex } from '../common/regex';
import { CategoriesFormationsService } from '../../categories/services/categories-formations.service';
import { MailerService } from '../../mailer/mailer.service';
import { ParametersService } from '../../parameters/parameters.service';
import { PersonalOfferDocument } from '../../personal-offers/schemas/personal-offer.schema';
import { IUser } from '../../users/interfaces/user.interface';
import { User } from '../../users/schemas/user.schema';
import { UsersService } from '../../users/services/users.service';
import { depRegex } from '../common/regex';
import { StructureDto } from '../dto/structure.dto';
import { Structure, StructureDocument } from '../schemas/structure.schema';
import { StructuresSearchService } from './structures-search.service';
@Injectable()
export class StructuresService {
private readonly logger = new Logger(StructuresService.name);
constructor(
private readonly httpService: HttpService,
private readonly userService: UsersService,
private readonly mailerService: MailerService,
private structuresSearchService: StructuresSearchService,
private categoriesFormationsService: CategoriesFormationsService,
private parametersService: ParametersService,
@InjectModel(Structure.name) private structureModel: Model<StructureDocument>
) {}
async initiateStructureIndex(): Promise<StructureDocument[]> {
Logger.log('Reset structures indexes', StructuresService.name);
this.logger.log('Reset structures indexes');
await this.structuresSearchService.dropIndex();
await this.structuresSearchService.createStructureIndex();
return this.populateES();
......@@ -56,6 +58,7 @@ export class StructuresService {
async searchForStructures(text: string, filters?: Array<any>, fields?: string[]): Promise<StructureDocument[]> {
const results = await this.structuresSearchService.search(text, fields);
const ids = results.map((result) => result.structureId);
let structures;
let multipleFilters = filters ? filters.filter((elem) => Object.keys(elem)[0].length == 0) : null;
filters = filters?.filter((elem) => Object.keys(elem)[0].length != 0);
if (multipleFilters) {
......@@ -67,47 +70,47 @@ export class StructuresService {
}
//we match ids from Elasticsearch with ids from mongoDB (and filters) and sort the result according to ElasticSearch order.
if (filters?.length > 0 && multipleFilters?.length == 0) {
return (
await this.structureModel
.find({
_id: { $in: ids },
$and: [...this.parseFilter(filters), { deletedAt: { $exists: false }, accountVerified: true }],
})
.populate('personalOffers')
.exec()
).sort((a, b) => ids.indexOf(a.id) - ids.indexOf(b.id));
structures = await this.structureModel
.find({
_id: { $in: ids },
$and: [...this.parseFilter(filters), { deletedAt: { $exists: false }, accountVerified: true }],
})
.populate('personalOffers')
.exec();
} else if (filters?.length > 0 && multipleFilters?.length > 0) {
return (
await this.structureModel
.find({
_id: { $in: ids },
$or: [...this.parseFilter(multipleFilters)],
$and: [...this.parseFilter(filters), { deletedAt: { $exists: false }, accountVerified: true }],
})
.populate('personalOffers')
.exec()
).sort((a, b) => ids.indexOf(a.id) - ids.indexOf(b.id));
structures = await this.structureModel
.find({
_id: { $in: ids },
$or: [...this.parseFilter(multipleFilters)],
$and: [...this.parseFilter(filters), { deletedAt: { $exists: false }, accountVerified: true }],
})
.populate('personalOffers')
.exec();
} else if (filters?.length == 0 && multipleFilters?.length > 0) {
return (
await this.structureModel
.find({
_id: { $in: ids },
$or: [...this.parseFilter(multipleFilters), { deletedAt: { $exists: false }, accountVerified: true }],
})
.populate('personalOffers')
.exec()
).sort((a, b) => ids.indexOf(a.id) - ids.indexOf(b.id));
structures = await this.structureModel
.find({
_id: { $in: ids },
$or: [...this.parseFilter(multipleFilters), { deletedAt: { $exists: false }, accountVerified: true }],
})
.populate('personalOffers')
.exec();
} else {
return (
await this.structureModel
.find({
_id: { $in: ids },
$and: [{ deletedAt: { $exists: false }, accountVerified: true }],
})
.populate('personalOffers')
.exec()
).sort((a, b) => ids.indexOf(a.id) - ids.indexOf(b.id));
structures = await this.structureModel
.find({
_id: { $in: ids },
$and: [{ deletedAt: { $exists: false }, accountVerified: true }],
})
.populate('personalOffers')
.exec();
}
await structures.sort((a, b) => ids.indexOf(a.id) - ids.indexOf(b.id));
if (!(await this.parametersService.getParameters()).lockdownInfoDisplay) {
structures.map((structure: StructureDocument) => {
structure.lockdownActivity = '';
});
}
return structures;
}
public async create(idUser: string, structure: StructureDto): Promise<Structure> {
......@@ -210,8 +213,8 @@ export class StructuresService {
}
public async findAll(): Promise<StructureDocument[]> {
Logger.debug('findAll', StructuresService.name);
const structures = await this.structureModel.find({ deletedAt: { $exists: false } }).exec();
this.logger.debug('findAll');
let structures = await this.structureModel.find({ deletedAt: { $exists: false } }).exec();
// Update structures coord and address before sending them
await Promise.all(
structures.map((structure: StructureDocument) => {
......@@ -225,10 +228,13 @@ export class StructuresService {
}
})
);
return this.structureModel
.find({ deletedAt: { $exists: false }, accountVerified: true })
.populate('personalOffers')
.exec();
structures = await this.structureModel.find({ deletedAt: { $exists: false }, accountVerified: true }).exec();
if (!(await this.parametersService.getParameters()).lockdownInfoDisplay) {
await structures.map((structure: StructureDocument) => {
structure.lockdownActivity = '';
});
}
return structures;
}
public async findAllUnclaimed(): Promise<UnclaimedStructureDto[]> {
......@@ -243,6 +249,7 @@ export class StructuresService {
unclaimedStructures.push({
structureId: structure.id,
structureName: structure.structureName,
createdAt: structure.createdAt,
updatedAt: structure.updatedAt,
});
}
......@@ -274,10 +281,7 @@ export class StructuresService {
.populate('personalOffers')
.exec();
// Update structures coord and address before sending them
Logger.debug(
'Find all formated structures, only returning structures who consented to data sharing',
StructuresService.name
);
this.logger.debug('Find all formated structures, only returning structures who consented to data sharing');
await Promise.all(
structures.map((structure: StructureDocument) => {
// If structure has no address, add it
......@@ -304,9 +308,6 @@ export class StructuresService {
if (this.hasTempMail(structure)) {
structure.contactMail = null;
}
// Format date
structure.createdAt = new Date(structure.createdAt).toISOString();
structure.updatedAt = new Date(structure.updatedAt).toISOString();
// Add referentiel
structure.proceduresAccompaniment = this.mapModules(
structure.proceduresAccompaniment,
......@@ -421,7 +422,7 @@ export class StructuresService {
if (address && address.geometry) {
structure.coord = address.geometry.coordinates;
} else {
Logger.error(
this.logger.error(
`No coord found for: ${structure.address.numero} ${structure.address.street} ${structure.address.commune}`,
StructuresService.name
);
......@@ -435,7 +436,7 @@ export class StructuresService {
if (address && address.geometry) {
structure.coord = address.geometry.coordinates;
} else {
Logger.error(
this.logger.error(
`No coord found for: ${structure.address.numero} ${structure.address.street} ${structure.address.commune}`,
StructuresService.name
);
......@@ -443,7 +444,7 @@ export class StructuresService {
}
resolve(structure);
} else {
Logger.error(
this.logger.error(
`No structure found for: ${structure.address.numero} ${structure.address.street} ${structure.address.commune}`,
StructuresService.name
);
......@@ -452,8 +453,8 @@ export class StructuresService {
});
},
(err) => {
Logger.error(`Request error: ${err.config.url}`, StructuresService.name);
Logger.error(err);
this.logger.error(`Request error: ${err.config.url}`, 'StructureService');
this.logger.error(err);
reject(err);
}
);
......@@ -480,9 +481,9 @@ export class StructuresService {
const reqBal = `https://download.data.grandlyon.com/geocoding/photon-bal/api?q=${data.searchQuery}&lang=fr&limit=500&osm_tag=:!construction&osm_tag=:!bus_stop`;
const requestGroup = (url): Promise<{ features: { geometry: any; type: string; properties: any }[] }> =>
new Promise((resolve) => {
Logger.debug(`Search request: ${encodeURI(url)}`, StructuresService.name);
const requestGroup = (url): Promise<{ features: { geometry: {}; type: string; properties: {} }[] }> =>
new Promise((resolve, reject) => {
this.logger.debug(`Search request: ${encodeURI(url)}`, 'StructureService');
return this.httpService
.request({
url: encodeURI(url),
......@@ -491,7 +492,7 @@ export class StructuresService {
})
.subscribe(
(reply) => {
Logger.debug(`Search request response length : ${reply.data.features.length}`, StructuresService.name);
this.logger.debug(`Search request response length : ${reply.data.features.length}`, 'StructureService');
reply.data.features = reply.data.features
.filter((doc) => doc.properties.postcode && doc.properties.postcode.match(depRegex))
.sort((a, b) => {
......@@ -500,8 +501,8 @@ export class StructuresService {
return resolve(reply.data);
},
(err) => {
Logger.error(`Search - Request error: ${err.config.url}`, StructuresService.name);
Logger.error(err);
this.logger.error(`Search - Request error: ${err.config.url}`, 'StructureService');
this.logger.error(err);
}
);
});
......@@ -566,7 +567,7 @@ export class StructuresService {
public getCoord(numero: string, address: string, zipcode: string, scope: string): Observable<AxiosResponse<any>> {
const req =
`https://download.data.grandlyon.com/geocoding/${scope}/api?q=` + numero + ' ' + address + ' ' + zipcode;
Logger.debug('Print getCoord' + req, StructuresService.name);
this.logger.debug('Print getCoord' + req);
return this.httpService.get(encodeURI(req));
}
......@@ -633,14 +634,16 @@ export class StructuresService {
@Cron(CronExpression.EVERY_DAY_AT_4AM)
public async checkOutdatedStructuresInfo(): Promise<void> {
const OUTDATED_MONT_TO_CHECK = 6;
this.logger.debug('checkOutdatedStructuresInfo');
const OUTDATED_MONTH_TO_CHECK = 6;
const structureList = await this.findAll();
const local = DateTime.local().setZone('Europe/Paris');
// const local = DateTime.now().toObject();
// Get outdated structures
const filteredList = structureList.filter((structure) => {
const updateDate = DateTime.fromFormat(structure.updatedAt.split(' GMT')[0], 'EEE MMM dd yyyy HH:mm:ss');
const diff = local.diff(updateDate, ['months']);
if (diff.values.months > OUTDATED_MONT_TO_CHECK) {
const updatedDate = DateTime.fromISO(structure.updatedAt.toISOString());
const diff = updatedDate.diffNow('month').months;
if (Math.abs(diff) > OUTDATED_MONTH_TO_CHECK) {
this.logger.debug(`found outdated structure : ${structure.structureName}`);
return true;
}
});
......@@ -730,15 +733,15 @@ export class StructuresService {
public async findWithOwners(
idStructure: string,
emailUser: string
): Promise<{ structure: Structure; owners: OwnerDto[] }> {
): Promise<{ structure: Structure; owners: IUser[] }> {
const structure = await this.findOne(idStructure);
if (!structure) {
throw new HttpException('Invalid structure id', HttpStatus.BAD_REQUEST);
}
const owners =
typeof emailUser == 'undefined'
? await this.userService.getStructureOwnersMails(structure._id, '')
: await this.userService.getStructureOwnersMails(structure._id, emailUser);
? await this.userService.getStructureOwnersDetails(structure._id, '')
: await this.userService.getStructureOwnersDetails(structure._id, emailUser);
return { structure: structure, owners: owners };
}
......@@ -747,7 +750,7 @@ export class StructuresService {
if (!structure) {
throw new HttpException('Invalid structure id', HttpStatus.BAD_REQUEST);
}
const owners = await this.userService.getStructureOwnersMails(structure._id, '');
const owners = await this.userService.getStructureOwnersDetails(structure._id, '');
const admins = await this.userService.getAdmins();
const emails = owners.map((owner) => owner.email).concat(admins.map((admin) => admin.email));
const uniqueEmails = [...new Set(emails)];
......
import { Controller, Get } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { StructureType } from './structure-type.schema';
import { StructureTypeService } from './structure-type.service';
@ApiTags('structures')
@Controller('structure-type')
export class StructureTypeController {
constructor(private readonly structureTypeService: StructureTypeService) {}
......
......@@ -91,6 +91,7 @@ describe('AuthController', () => {
deletedAt: null,
remoteAccompaniment: null,
dataShareConsentDate: null,
personalOffers: [],
...structure,
});
expect(res.structureName).toBe('a');
......
......@@ -13,7 +13,7 @@ import {
Query,
UseGuards,
} from '@nestjs/common';
import { ApiParam } from '@nestjs/swagger';
import { ApiParam, ApiTags } from '@nestjs/swagger';
import { Types } from 'mongoose';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { CategoriesAccompagnementService } from '../categories/services/categories-accompagnement.service';
......@@ -23,18 +23,20 @@ import { CreateTempUserDto } from '../temp-user/dto/create-temp-user.dto';
import { TempUserService } from '../temp-user/temp-user.service';
import { Roles } from '../users/decorators/roles.decorator';
import { IsStructureOwnerGuard } from '../users/guards/isStructureOwner.guard';
import { RolesGuard } from '../users/guards/roles.guard';
import { User } from '../users/schemas/user.schema';
import { UsersService } from '../users/services/users.service';
import { depRegex } from './common/regex';
import { CreateStructureDto } from './dto/create-structure.dto';
import { QueryStructure } from './dto/query-structure.dto';
import { StructureDto } from './dto/structure.dto';
import { Structure, StructureDocument } from './schemas/structure.schema';
import { StructuresService } from './services/structures.service';
import { RolesGuard } from '../users/guards/roles.guard';
import { depRegex } from './common/regex';
@ApiTags('structures')
@Controller('structures')
export class StructuresController {
private readonly logger = new Logger(StructuresController.name);
constructor(
private readonly httpService: HttpService,
private readonly structureService: StructuresService,
......@@ -105,7 +107,7 @@ export class StructuresController {
@Get()
public async findAll(): Promise<Structure[]> {
Logger.debug(`findAll`, StructuresController.name);
this.logger.debug('findAll');
return this.structureService.findAll();
}
......
......@@ -13,12 +13,15 @@ import { StructureType, StructureTypeSchema } from './structure-type/structure-t
import { CategoriesModule } from '../categories/categories.module';
import { StructuresSearchService } from './services/structures-search.service';
import { SearchModule } from '../search/search.module';
import { ParametersService } from '../parameters/parameters.service';
import { Parameters, ParametersSchema } from '../parameters/schemas/parameters.schema';
@Module({
imports: [
MongooseModule.forFeature([
{ name: Structure.name, schema: StructureSchema },
{ name: StructureType.name, schema: StructureTypeSchema },
{ name: Parameters.name, schema: ParametersSchema },
]),
HttpModule,
MailerModule,
......@@ -29,6 +32,12 @@ import { SearchModule } from '../search/search.module';
],
controllers: [StructuresController, StructureTypeController],
exports: [StructuresService, StructureTypeService],
providers: [StructuresSearchService, StructuresService, StructureTypeService, ApticStructuresService],
providers: [
StructuresSearchService,
StructuresService,
StructureTypeService,
ApticStructuresService,
ParametersService,
],
})
export class StructuresModule {}
import { Body, Controller, Get, Post, UseGuards } from '@nestjs/common';
import { ApiOperation, ApiResponse } from '@nestjs/swagger';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { Roles } from '../users/decorators/roles.decorator';
import { RolesGuard } from '../users/guards/roles.guard';
......@@ -7,6 +7,7 @@ import { PgisCoord } from './interfaces/pgis.coord';
import { TclStopPoint } from './tclStopPoint.schema';
import { TclStopPointService } from './tclStopPoint.service';
@ApiTags('tcl')
@Controller('tcl')
export class TclStopPointController {
constructor(private tclStopPointService: TclStopPointService) {}
......
......@@ -13,7 +13,7 @@ import {
Request,
UseGuards,
} from '@nestjs/common';
import { ApiBearerAuth, ApiOperation, ApiParam } from '@nestjs/swagger';
import { ApiBearerAuth, ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger';
import { MergeEmployerDto } from '../../admin/dto/merge-employer.dto';
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { hasAdminRole } from '../../shared/utils';
......@@ -25,6 +25,7 @@ import { Employer } from '../schemas/employer.schema';
import { EmployerService } from '../services/employer.service';
import { UsersService } from '../services/users.service';
@ApiTags('employer')
@Controller('employer')
export class EmployerController {
private readonly logger = new Logger(EmployerController.name);
......