diff --git a/src/configuration/config.ts b/src/configuration/config.ts index 00bbfff6d98d45181cad4ed3e58d048e1467a3a5..c11b20a7bbb05ca05f67cc8d3cb4c717466df65c 100644 --- a/src/configuration/config.ts +++ b/src/configuration/config.ts @@ -29,5 +29,9 @@ export const config = { ejs: 'structureClaimValidation.ejs', json: 'structureClaimValidation.json', }, + structureOutdatedInfo: { + ejs: 'structureOutdatedInfo.ejs', + json: 'structureOutdatedInfo.json', + }, }, }; diff --git a/src/mailer/mail-templates/structureOutdatedInfo.ejs b/src/mailer/mail-templates/structureOutdatedInfo.ejs new file mode 100644 index 0000000000000000000000000000000000000000..945129e78a76c34c785757aa0aac6678f54dd0d2 --- /dev/null +++ b/src/mailer/mail-templates/structureOutdatedInfo.ejs @@ -0,0 +1,6 @@ +Bonjour<br /> +<br /> +La fiche de votre structure: <strong><%= name %></strong> n'a pas été mise a jour depuis 6mois. +<br /> +<br /> +Ce mail est un mail automatique. Merci de ne pas y répondre. diff --git a/src/mailer/mail-templates/structureOutdatedInfo.json b/src/mailer/mail-templates/structureOutdatedInfo.json new file mode 100644 index 0000000000000000000000000000000000000000..1782ea483e33fb07f29c92e7a12f758f23f2e395 --- /dev/null +++ b/src/mailer/mail-templates/structureOutdatedInfo.json @@ -0,0 +1,3 @@ +{ + "subject": "Votre fiche structure n'est plus a jour, Réseau des Acteurs de la Médiation Numérique de la Métropole de Lyon" +} diff --git a/src/structures/services/structures.service.ts b/src/structures/services/structures.service.ts index dde0166a7d25b2c8a654b68cecb487a870bea569..0833682530fa366ffe1ddddd7a91c87d34e5d9da 100644 --- a/src/structures/services/structures.service.ts +++ b/src/structures/services/structures.service.ts @@ -1,19 +1,23 @@ -import { HttpException, HttpService, Injectable, HttpStatus } from '@nestjs/common'; +import { HttpException, HttpService, Injectable, HttpStatus, Logger } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Types, Model } from 'mongoose'; import { Observable } from 'rxjs'; import { AxiosResponse } from 'axios'; import { Structure, StructureDocument } from '../schemas/structure.schema'; -import { Logger } from '@nestjs/common'; +import * as ejs from 'ejs'; import { structureDto } from '../dto/structure.dto'; import { UsersService } from '../../users/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'; @Injectable() export class StructuresService { constructor( private readonly httpService: HttpService, private readonly userService: UsersService, + private readonly mailerService: MailerService, @InjectModel(Structure.name) private structureModel: Model<StructureDocument> ) {} @@ -201,4 +205,60 @@ export class StructuresService { Logger.log(`Request : ${req}`, 'StructureService - getCoord'); return this.httpService.get(encodeURI(req)); } + + @Cron(CronExpression.EVERY_DAY_AT_4AM) + public async checkOutdatedStructuresInfo(): Promise<void> { + const OUTDATED_MONT_TO_CHECK = 6; + const structureList = await this.findAll(); + const local = DateTime.local().setZone('Europe/Paris'); + // 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) { + return true; + } + }); + // Get owners of outdated structures + const ownerList = await Promise.all( + filteredList.map(async (structure) => { + const owner = await this.userService.isStructureClaimed(structure._id.toString()); + if (owner) { + return { structure: structure, owner: owner }; + } + }) + ); + // Send email if possible and update user + ownerList + .filter((x) => x != undefined) + .forEach(async (data) => { + this.userService.findOne(data.owner.email).then((user) => { + // If mail is already sent, do not resend + if (user.structureOutdatedMailSent.includes(data.structure._id)) { + return; + } else { + this.sendOutdatedEmailToUser(data.owner.email, data.structure.structureName); + user.structureOutdatedMailSent.push(data.structure._id); + user.save(); + } + }); + }); + } + + /** + * Generate activation token and send it to user by email, in order to validate + * a new account. + * @param user User + */ + private async sendOutdatedEmailToUser(userEmail: string, structureName: string): Promise<any> { + const config = this.mailerService.config; + const ejsPath = this.mailerService.getTemplateLocation(config.templates.structureOutdatedInfo.ejs); + const jsonConfig = this.mailerService.loadJsonConfig(config.templates.structureOutdatedInfo.json); + + const html = await ejs.renderFile(ejsPath, { + config, + name: structureName, + }); + this.mailerService.send(userEmail, jsonConfig.subject, html); + } } diff --git a/src/users/interfaces/user.interface.ts b/src/users/interfaces/user.interface.ts index a348aacb00c6e783094341748b27b628bd1ac195..9ca1767ff8679c8263a3d1da920aaa6790828278 100644 --- a/src/users/interfaces/user.interface.ts +++ b/src/users/interfaces/user.interface.ts @@ -15,4 +15,5 @@ export interface IUser extends Document { newEmail: string; structuresLink: string[]; pendingStructuresLink: string[]; + structureOutdatedMailSent: string[]; } diff --git a/src/users/schemas/user.schema.ts b/src/users/schemas/user.schema.ts index 15261937b0258c939eb01d8cc41e0d8569a957bb..5accf9e7ce8c410006aa1a87e82d98c1d0d62adc 100644 --- a/src/users/schemas/user.schema.ts +++ b/src/users/schemas/user.schema.ts @@ -40,6 +40,9 @@ export class User { @Prop({ default: null }) pendingStructuresLink: string[]; + + @Prop({ default: null }) + structureOutdatedMailSent: string[]; } export const UserSchema = SchemaFactory.createForClass(User);