Services_MissionService.js

const CrudService = require("./CrudService");
const crypto = require("crypto");
const Logger = require("../Logger");
const config = require("../config");
const path = require("path");

/**
 * @extends Myintranet.Services.CrudService
 * @memberof Myintranet.Services
 * @inheritDoc
 */
class MissionService extends CrudService {
    constructor(db) {
        super(db.Mission);
        this.db = db;
    }

    async findByText(request) {
        let {text} = request.body;
        let {db} = this;
        let {user} = request.user;
        return new Promise((resolve, reject) => {
            db.Mission.findAll({
                where: {
                    [db.Sequelize.Op.or]: {
                        "$Client.denominationSocial$": {
                            [db.Sequelize.Op.like]: "%" + text + "%",
                        },
                        "$Employeur.denominationSocial$": {
                            [db.Sequelize.Op.like]: "%" + text + "%",
                        },
                        "$Consultant->Utilisateur.firstname$": {
                            [db.Sequelize.Op.like]: "%" + text + "%",
                        },
                        "$Consultant->Utilisateur.lastname$": {
                            [db.Sequelize.Op.like]: "%" + text + "%",
                        },
                    }

                },
                include: [
                    {model: db.Client, as: "Client"},
                    {model: db.Employeur, as: "Employeur"},
                    {model: db.Consultant, include: db.User, as: "Consultant"},
                ],
                order: [["createdAt", "DESC"]],
            })
                .then((users) => {
                    resolve(users);
                })
                .catch((err) => {
                    reject(err);
                });
        });
    }



    
    
    async delete(request) {
        //TODO: add action and control who can delete the mission
        let {db} = this;
        let id = this.__getIdFromRequest(request);
        let connected = request.user;
        let mission = await this.model.findOne({where: {id}});
    
        if (mission.dateEnd !== null && this.isAfterToday(mission.dateEnd)) {
          
            await db.Action.create({
                UtilisateurId: connected.id,
                meta: JSON.stringify(mission),
                type: "suppression",
                text: `<b>${connected.firstname} ${
                    connected.lastname
                }</b> a supprimé la mission : <b>${mission.title}</b> le : ${new Date(
                    Date.now()
                ).toLocaleString("fr-FR")}`,
            });
            return this.model.destroy({where: {id}});
        } else {
            // Mission does not have an end date, cannot be deleted
            throw new Error("La mission est en cours, elle ne peut pas être supprimée");
        }
    }
    

    isAfterToday(date) {
        let today = new Date(Date.now());
        let todayTime = today.getTime();
        let dateToCompare = new Date(date);
        let dateToCompareTime = dateToCompare.getTime();
        return dateToCompareTime < todayTime;
    }

    getAll(request) {
        let {db} = this;
        let connectedUser = request.user;
        let condition = {
            include: [
                db.Client,
                db.Employeur,
                db.Missionfiles,
                {model: db.Consultant, include: db.User},
            ],
        };
        if (connectedUser.type === "SuperAdmin") {
            return db.Mission.findAll(condition);
        } else if (connectedUser.type === "Admin") {
            return db.User.findOne({
                where: {id: connectedUser.id},
                include: {model: db.Employeur},
            }).then((admin) => {
                let employeursIds = admin.Employeurs.map((emp) => emp.id);
                condition.where = {
                    EmployeurId: {[db.Sequelize.Op.in]: employeursIds},
                };
                return db.Mission.findAll(condition);
            });
        } else {
            //Consultant
            throw new Error(
                "Un consultant ne peut pas consulter la liste des employeurs, seul un admin ou un super admin le peuvent!"
            );
        }
    }

    async getOne(request) {
        let {db} = this;
        let id = this.__getIdFromRequest(request);
        let condition = {
            where: {id},
            include: [
                db.Client,
                db.Employeur,
                db.Missionfiles,
                {model: db.Consultant, include: db.User},
            ],
        };


        let m = await this.model.findOne(condition);
        let mjson = m.toJSON();
        mjson.CraHistories = (await m.getCraHistories({order: [['year', 'ASC'], ['mounth', 'ASC']]}));
        mjson.PrevHistories = (await m.getPrevHistories({order: [['year', 'ASC'], ['mounth', 'ASC']]}));

        return mjson;
    }

    async getMissionHistory(request) {
        let {db} = this;
        let id = this.__getIdFromRequest(request);
        return db.Action.findAll({
            where: {
                MissionId: id,
            },
        });
    }

    async getPrevCraHistory(request) {
        let {db} = this;
        let {CraId, PrevId} = request.params;
        return await db.Action.findAll({
            where: {
                [db.Sequelize.Op.or]: {
                    PrevId,
                    CraId,
                },
            },
        });
    }

    // Update simple
    async update(request) {
        let mission = request.body,
            connected = request.user,
            files = request.files && request.files.length ? request.files : [request.files];
        let {db} = this;
        let id = this.__getIdFromRequest(request);
        const t = await db.sequelize.transaction();
        try {
            if (!id) {
                throw new Error("cant update with no id");
            } else {
                if (mission.dateEnd === "" || mission.dateEnd === "null") {
                    mission.dateEnd = null;
                }

                if (request.files) {
                    let consultant = await db.Consultant.findOne({
                        where: {id: mission.ConsultantId},
                        include: db.User,
                    });

                    let {contrat, avenant} = request.files;

                    if (contrat) {
                        await db.Missionfiles.destroy({where:{MissionId:mission.id,type:"contrat"},transaction: t})
                        contrat.MissionId = mission.id;
                        contrat.type = 'contrat';
                        await db.Missionfiles.create(contrat, {transaction: t});

                        let cfolder =
                            consultant.id +
                            "-" +
                            consultant.Utilisateur.firstname +
                            "-" +
                            consultant.Utilisateur.lastname;
                        let mfolder =
                            "mission-" + mission.id + "-" + mission.title;
                        await contrat.mv(
                            path.join(config.storageLocation, cfolder, mfolder, "contrat", contrat.name)
                        );
                    }
                    if (avenant) {
                        await db.Missionfiles.destroy({where:{MissionId:mission.id,type:"avenant"},transaction: t})
                        avenant.MissionId = mission.id;
                        avenant.type = 'avenant';
                        await db.Missionfiles.create(avenant, {transaction: t});


                        let cfolder =
                            consultant.id +
                            "-" +
                            consultant.Utilisateur.firstname +
                            "-" +
                            consultant.Utilisateur.lastname;
                        let mfolder =
                            "mission-" + mission.id + "-" + mission.title;
                        await avenant.mv(
                            path.join(config.storageLocation, cfolder, mfolder, "avenant", avenant.name)
                        );
                    }
                }

                await db.Mission.update(mission, {where: {id}, transaction: t});
                await t.commit();
                return await this.getOne(request);
            }
        } catch (e) {
            await t.rollback();
            throw e;
        }
    }

    async getConsultantMission() {
        try {
            let {db} = this;
            let condition = {
                include: [
                    db.Client,
                    db.Employeur,
                    {model: db.Consultant, include: db.User},
                ],
            };
            return await db.Mission.findAll(condition);
        } catch (e) {
            throw e;
        }
    }

    async add(request) {
        let mission = request.body,
       
            connected = request.user,
     
            files = request.files;
        let {db} = this;
        const t = await db.sequelize.transaction();
        console.log("cest une mission ",mission)
        try {
           
                mission.Consultant =JSON.parse(mission.Consultant)
            let consultant = await db.Consultant.findOne({
                where: {id: mission.ConsultantId},
                include: [db.User,db.Employeur]
            });
        
            let consultantEmployeurIds = mission.Consultant.Employeurs.map(emp => emp.id);
            if (!consultantEmployeurIds.includes(mission.EmployeurId)) {
                let missionEmployeur = await db.Employeur.findOne({
                    where: { id: mission.EmployeurId },
                });
                // console.log("Employeur ajouté à la DB :", missionEmployeur);
                await consultant.addEmployeurs(missionEmployeur, { transaction: t });
            }else{
                console.log("l'employeur existe déja dans le tableau des consultants")
            }
           
            
            if (mission.dateEnd === "" || mission.dateEnd === "null") {
                mission.dateEnd = null;
            }
            
            let createdMission = await db.Mission.create(mission,{transaction: t});
            createdMission.foldername = `${createdMission.id}-${createdMission.title}`;
        await createdMission.save({ transaction: t });

            
           
            await db.Action.create(
                {
                    UtilisateurId: connected.id,
                    meta: JSON.stringify(mission),
                    type: "creation",
                    text: `<b>${connected.firstname} ${
                        connected.lastname
                    }</b> a créé la mission : <b>${
                        createdMission.title
                    }</b> Pour le consultant : <b>${consultant.Utilisateur.firstname}-${
                        consultant.Utilisateur.lastname
                    }</b> le : ${new Date(Date.now()).toLocaleString("fr-FR")}`,
                },
                {transaction: t}
            );
            // console.log("voici la mission creer ", createdMission)
            if (!files) {
                Logger.warn(
                    "Mission cree sans avenant ni contrat" +
                    JSON.stringify(createdMission, undefined, 4)
                );
            } else {
                let {contrat, avenant} = files;
                if (!contrat) {
                    Logger.warn(
                        "Mission cree sans Contrat " +
                        JSON.stringify(createdMission, undefined, 4)
                    );
                } else {
                    contrat.MissionId = createdMission.id
                    contrat.type = 'contrat'
                    await db.Missionfiles.create(contrat, {
                        transaction: t
                    });


                    //traitement du fichier contrat
                    let cfolder =
                        consultant.id +
                        "-" +
                        consultant.Utilisateur.firstname +
                        "-" +
                        consultant.Utilisateur.lastname;
                    let mfolder =
                        "mission-" + createdMission.id + "-" + createdMission.title;
                    await contrat.mv(
                        path.join(
                            config.storageLocation,
                            cfolder,
                            mfolder,
                            "contrat",
                            contrat.name
                        )
                    );
                }
                if (!avenant) {
                    Logger.warn(
                        "Mission cree sans avenant " +
                        JSON.stringify(createdMission, undefined, 4)
                    );
                } else {
                    avenant.MissionId = createdMission.id
                    avenant.type = 'avenant'
                    await db.Missionfiles.create(avenant, {
                        transaction: t
                    });
                    //Traitement du fichier avenant
                    let cfolder =
                        consultant.id +
                        "-" +
                        consultant.Utilisateur.firstname +
                        "-" +
                        consultant.Utilisateur.lastname;
                    let mfolder =
                        "mission-" + createdMission.id + "-" + createdMission.title;
                    await avenant.mv(
                        path.join(
                            config.storageLocation,
                            cfolder,
                            mfolder,
                            "avenant",
                            avenant.name
                        )
                    );
                }
            }
            await t.commit();
            return await this.getOne({body: createdMission});
        } catch (e) {
            await t.rollback();
            throw e;
        }
    }


}

module.exports = MissionService;