import os
from config import Config
from datetime import datetime, date
import glob
import shutil

from flask import render_template, redirect, url_for, request, flash, send_file, abort
from flask.json import jsonify
from flask_login import current_user

from app.decorators import permission_required

from app.entreprises import LOGS_LEN, SIRET_PROVISOIRE_START
from app.entreprises.forms import (
    ActivationConfirmationForm,
    CorrespondantsCreationForm,
    DesactivationConfirmationForm,
    EntrepriseCreationForm,
    EntrepriseModificationForm,
    EntreprisesFilterForm,
    SiteCreationForm,
    SiteModificationForm,
    SuppressionConfirmationForm,
    OffreCreationForm,
    OffreModificationForm,
    CorrespondantModificationForm,
    ContactCreationForm,
    ContactModificationForm,
    StageApprentissageCreationForm,
    StageApprentissageModificationForm,
    EnvoiOffreForm,
    AjoutFichierForm,
    TaxeApprentissageForm,
    TaxeApprentissageModificationForm,
    ValidationConfirmationForm,
    ImportForm,
    PreferencesForm,
)
from app.entreprises import bp
from app.entreprises.models import (
    Entreprise,
    EntrepriseOffre,
    EntrepriseCorrespondant,
    EntrepriseHistorique,
    EntrepriseContact,
    EntrepriseSite,
    EntrepriseStageApprentissage,
    EntrepriseEnvoiOffre,
    EntrepriseOffreDepartement,
    EntreprisePreferences,
    EntrepriseTaxeApprentissage,
)
from app.entreprises import app_relations_entreprises as are
from app.models import Identite
from app.auth.models import User
from app.scodoc.sco_permissions import Permission
from app.scodoc import sco_etud, sco_excel
import app.scodoc.sco_utils as scu

from app import db
from sqlalchemy import text, sql
from werkzeug.utils import secure_filename


@bp.route("/", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesView)
def index():
    """
    Permet d'afficher une page avec la liste des entreprises (visible et active) et une liste des dernières opérations
    """
    entreprises = Entreprise.query.filter_by(visible=True, active=True)
    logs = (
        EntrepriseHistorique.query.order_by(EntrepriseHistorique.date.desc())
        .limit(LOGS_LEN)
        .all()
    )
    form = EntreprisesFilterForm()
    checked = [False, False, False]
    if request.method == "POST":
        checked = [form.active.data, form.association.data, form.siret_provisoire.data]
    if checked[0]:
        entreprises = Entreprise.query.filter_by(visible=True)
    if checked[1]:
        entreprises = Entreprise.query.filter_by(visible=True, association=True)
    if checked[2]:
        entreprises = Entreprise.query.filter_by(visible=True, siret_provisoire=True)
    if checked[1] and checked[2]:
        entreprises = Entreprise.query.filter_by(
            visible=True, association=True, siret_provisoire=True
        )
    return render_template(
        "entreprises/entreprises.j2",
        title="Entreprises",
        entreprises=entreprises,
        logs=logs,
        form=form,
        checked=checked,
    )


@bp.route("/logs", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesView)
def logs():
    """
    Permet d'afficher les logs (toutes les entreprises)
    """
    page = request.args.get("page", 1, type=int)
    logs = EntrepriseHistorique.query.order_by(
        EntrepriseHistorique.date.desc()
    ).paginate(page=page, per_page=20)
    return render_template(
        "entreprises/logs.j2",
        title="Logs",
        logs=logs,
    )


@bp.route("/correspondants", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesCorrespondants)
def correspondants():
    """
    Permet d'afficher une page avec la liste des correspondants des entreprises visibles et une liste des dernières opérations
    """
    correspondants = (
        db.session.query(EntrepriseCorrespondant, EntrepriseSite)
        .join(EntrepriseSite, EntrepriseCorrespondant.site_id == EntrepriseSite.id)
        .join(Entreprise, EntrepriseSite.entreprise_id == Entreprise.id)
        .filter_by(visible=True, active=True)
        .all()
    )
    logs = (
        EntrepriseHistorique.query.order_by(EntrepriseHistorique.date.desc())
        .limit(LOGS_LEN)
        .all()
    )
    return render_template(
        "entreprises/correspondants.j2",
        title="Correspondants",
        correspondants=correspondants,
        logs=logs,
    )


@bp.route("/validation", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesValidate)
def validation():
    """
    Permet d'afficher une page avec la liste des entreprises a valider (non visible)
    """
    entreprises = Entreprise.query.filter_by(visible=False).all()
    return render_template(
        "entreprises/entreprises_validation.j2",
        title="Validation entreprises",
        entreprises=entreprises,
    )


@bp.route("/fiche_entreprise_validation/<int:entreprise_id>", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesValidate)
def fiche_entreprise_validation(entreprise_id):
    """
    Permet d'afficher la fiche entreprise d'une entreprise a valider
    """
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=False
    ).first_or_404(
        description=f"fiche entreprise (validation) {entreprise_id} inconnue"
    )
    return render_template(
        "entreprises/fiche_entreprise_validation.j2",
        title="Validation fiche entreprise",
        entreprise=entreprise,
    )


@bp.route(
    "/fiche_entreprise_validation/<int:entreprise_id>/validate_entreprise",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesValidate)
def validate_entreprise(entreprise_id):
    """
    Permet de valider une entreprise
    """
    form = ValidationConfirmationForm()
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=False
    ).first_or_404(description=f"entreprise (validation) {entreprise_id} inconnue")
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for(
                "entreprises.fiche_entreprise_validation", entreprise_id=entreprise_id
            )
        )
    if form.validate_on_submit():
        entreprise.visible = True
        nom_entreprise = f"<a href=/ScoDoc/entreprises/fiche_entreprise/{entreprise.id}>{entreprise.nom}</a>"
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=entreprise.id,
            text=f"{nom_entreprise} - Validation de la fiche entreprise ({entreprise.nom})",
        )
        db.session.add(log)
        db.session.commit()
        flash("L'entreprise a été validé et ajouté à la liste.")
        return redirect(url_for("entreprises.validation"))
    return render_template(
        "entreprises/form_validate_confirmation.j2",
        title="Validation entreprise",
        form=form,
    )


@bp.route(
    "/fiche_entreprise_validation/<int:entreprise_id>/delete_validation_entreprise",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesValidate)
def delete_validation_entreprise(entreprise_id):
    """
    Permet de supprimer une entreprise en attente de validation avec une formulaire de validation
    """
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=False
    ).first_or_404(description=f"entreprise (validation) {entreprise_id} inconnue")
    form = SuppressionConfirmationForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for(
                "entreprises.fiche_entreprise_validation", entreprise_id=entreprise_id
            )
        )
    if form.validate_on_submit():
        db.session.delete(entreprise)
        db.session.commit()
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=entreprise.id,
            text=f"Non validation de la fiche entreprise ({entreprise.nom})",
        )
        db.session.add(log)
        flash("L'entreprise a été supprimé de la liste des entreprise à valider.")
        return redirect(url_for("entreprises.validation"))
    return render_template(
        "entreprises/form_confirmation.j2",
        title="Supression entreprise",
        form=form,
        info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
    )


@bp.route("/offres_recues", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesView)
def offres_recues():
    """
    Permet d'afficher la page où l'on peut voir les offres reçues
    """
    offres_recues = (
        db.session.query(EntrepriseEnvoiOffre, EntrepriseOffre)
        .filter(EntrepriseEnvoiOffre.receiver_id == current_user.id)
        .join(EntrepriseOffre, EntrepriseOffre.id == EntrepriseEnvoiOffre.offre_id)
        .all()
    )
    offres_recues_with_files = []
    for envoi_offre, offre in offres_recues:
        correspondant = EntrepriseCorrespondant.query.filter_by(
            id=offre.correspondant_id
        ).first()
        files = []
        path = os.path.join(
            Config.SCODOC_VAR_DIR,
            "entreprises",
            f"{offre.entreprise_id}",
            f"{offre.id}",
        )
        if os.path.exists(path):
            for dir in glob.glob(
                f"{path}/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]"
            ):
                for file in glob.glob(f"{dir}/*"):
                    file = [os.path.basename(dir), os.path.basename(file)]
                    files.append(file)
        offres_recues_with_files.append([envoi_offre, offre, files, correspondant])
    return render_template(
        "entreprises/offres_recues.j2",
        title="Offres reçues",
        offres_recues=offres_recues_with_files,
    )


@bp.route(
    "/offres_recues/delete_offre_recue/<int:envoi_offre_id>", methods=["GET", "POST"]
)
@permission_required(Permission.RelationsEntreprisesView)
def delete_offre_recue(envoi_offre_id):
    """
    Permet de supprimer une offre reçue
    """
    offre_recue = EntrepriseEnvoiOffre.query.filter_by(
        id=envoi_offre_id, receiver_id=current_user.id
    ).first_or_404(description=f"offre recu {envoi_offre_id} inconnue")
    db.session.delete(offre_recue)
    db.session.commit()
    return redirect(url_for("entreprises.offres_recues"))


@bp.route("/preferences", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesValidate)
def preferences():
    """
    Permet d'afficher la page des préférences du module gestion des relations entreprises
    """
    form = PreferencesForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(url_for("entreprises.index"))
    if form.validate_on_submit():
        EntreprisePreferences.set_email_notifications(form.mail_entreprise.data.strip())
        EntreprisePreferences.set_check_siret(int(form.check_siret.data))
        return redirect(url_for("entreprises.index"))
    elif request.method == "GET":
        form.mail_entreprise.data = EntreprisePreferences.get_email_notifications()
        form.check_siret.data = int(EntreprisePreferences.get_check_siret())
    return render_template(
        "entreprises/preferences.j2",
        title="Préférences",
        form=form,
    )


@bp.route("/add_entreprise", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesChange)
def add_entreprise():
    """
    Permet d'ajouter une entreprise dans la base avec un formulaire
    """
    form = EntrepriseCreationForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(url_for("entreprises.index"))
    if form.validate_on_submit():
        entreprise = Entreprise(
            nom=form.nom_entreprise.data.strip(),
            siret=form.siret.data.strip()
            if form.siret.data.strip()
            else f"{SIRET_PROVISOIRE_START}{datetime.now().strftime('%d%m%y%H%M%S')}",  # siret provisoire
            siret_provisoire=False if form.siret.data.strip() else True,
            association=form.association.data,
            adresse=form.adresse.data.strip(),
            codepostal=form.codepostal.data.strip(),
            ville=form.ville.data.strip(),
            pays=form.pays.data.strip() if form.pays.data.strip() else "FRANCE",
        )
        try:
            db.session.add(entreprise)
            db.session.commit()
            db.session.refresh(entreprise)
        except:
            db.session.rollback()
            flash("Une erreur est survenue veuillez réessayer.")
            return render_template(
                "entreprises/form_ajout_entreprise.j2",
                title="Ajout entreprise avec correspondant",
                form=form,
            )
        site = EntrepriseSite(
            entreprise_id=entreprise.id,
            nom=form.nom_entreprise.data.strip(),
            adresse=form.adresse.data.strip(),
            codepostal=form.codepostal.data.strip(),
            ville=form.ville.data.strip(),
            pays=form.pays.data.strip() if form.pays.data.strip() else "FRANCE",
        )
        db.session.add(site)
        db.session.commit()
        if form.nom_correspondant.data.strip():
            db.session.refresh(site)
            correspondant = EntrepriseCorrespondant(
                site_id=site.id,
                civilite=form.civilite.data,
                nom=form.nom_correspondant.data.strip(),
                prenom=form.prenom_correspondant.data.strip(),
                telephone=form.telephone.data.strip(),
                mail=form.mail.data.strip(),
                poste=form.poste.data.strip(),
                service=form.service.data.strip(),
                origine=form.origine.data.strip(),
                notes=form.notes.data.strip(),
            )
            db.session.add(correspondant)
        if current_user.has_permission(Permission.RelationsEntreprisesValidate, None):
            entreprise.visible = True
            lien_entreprise = f"<a href='{url_for('entreprises.fiche_entreprise', entreprise_id=entreprise.id)}'>{entreprise.nom}</a>"
            log = EntrepriseHistorique(
                authenticated_user=current_user.user_name,
                text=f"{lien_entreprise} - Création de la fiche entreprise ({entreprise.nom})",
                entreprise_id=entreprise.id,
            )
            db.session.add(log)
            db.session.commit()
            flash("L'entreprise a été ajouté à la liste.")
            return redirect(url_for("entreprises.index"))
        else:
            entreprise.visible = False
            db.session.commit()
            if EntreprisePreferences.get_email_notifications():
                are.send_email_notifications_entreprise(
                    "entreprise en attente de validation", entreprise
                )
            flash("L'entreprise a été ajouté à la liste pour la validation.")
            return redirect(url_for("entreprises.index"))
    return render_template(
        "entreprises/form_ajout_entreprise.j2",
        title="Ajout entreprise avec correspondant",
        form=form,
    )


@bp.route("/fiche_entreprise/<int:entreprise_id>", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesView)
def fiche_entreprise(entreprise_id):
    """
    Permet d'afficher la fiche entreprise d'une entreprise avec une liste des dernières opérations et
    l'historique des étudiants ayant réaliser un stage ou une alternance dans cette entreprise.
    La fiche entreprise comporte les informations de l'entreprise, les correspondants de l'entreprise et
    les offres de l'entreprise.
    """
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=True
    ).first_or_404(description=f"fiche entreprise {entreprise_id} inconnue")
    offres_with_files = are.get_offres_non_expirees_with_files(entreprise.offres)
    logs = (
        EntrepriseHistorique.query.order_by(EntrepriseHistorique.date.desc())
        .filter(EntrepriseHistorique.entreprise_id == entreprise.id)
        .limit(LOGS_LEN)
        .all()
    )
    stages_apprentissages = (
        db.session.query(EntrepriseStageApprentissage, Identite)
        .order_by(EntrepriseStageApprentissage.date_debut.desc())
        .filter(EntrepriseStageApprentissage.entreprise_id == entreprise.id)
        .join(Identite, Identite.id == EntrepriseStageApprentissage.etudid)
        .all()
    )
    taxes = (
        EntrepriseTaxeApprentissage.query.filter_by(entreprise_id=entreprise.id)
        .order_by(EntrepriseTaxeApprentissage.annee.desc())
        .all()
    )
    return render_template(
        "entreprises/fiche_entreprise.j2",
        title="Fiche entreprise",
        entreprise=entreprise,
        offres=offres_with_files,
        logs=logs,
        stages_apprentissages=stages_apprentissages,
        taxes=taxes,
    )


@bp.route("/fiche_entreprise/<int:entreprise_id>/logs", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesView)
def logs_entreprise(entreprise_id):
    """
    Permet d'afficher les logs d'une entreprise
    """
    page = request.args.get("page", 1, type=int)
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=True
    ).first_or_404(description=f"logs fiche entreprise {entreprise_id} inconnu")
    logs = (
        EntrepriseHistorique.query.order_by(EntrepriseHistorique.date.desc())
        .filter(EntrepriseHistorique.entreprise_id == entreprise.id)
        .paginate(page=page, per_page=20)
    )
    return render_template(
        "entreprises/logs_entreprise.j2",
        title="Logs",
        logs=logs,
        entreprise=entreprise,
    )


@bp.route("/fiche_entreprise/<int:entreprise_id>/offres_expirees")
@permission_required(Permission.RelationsEntreprisesView)
def offres_expirees(entreprise_id):
    """
    Permet d'afficher la liste des offres expirés d'une entreprise
    """
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=True
    ).first_or_404(description=f"fiche entreprise {entreprise_id} inconnue")
    offres_with_files = are.get_offres_expirees_with_files(entreprise.offres)
    return render_template(
        "entreprises/offres_expirees.j2",
        title="Offres expirées",
        entreprise=entreprise,
        offres_expirees=offres_with_files,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/edit_entreprise", methods=["GET", "POST"]
)
@permission_required(Permission.RelationsEntreprisesChange)
def edit_entreprise(entreprise_id):
    """
    Permet de modifier une entreprise de la base avec un formulaire
    """
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=True
    ).first_or_404(description=f"entreprise {entreprise_id} inconnue")
    form = EntrepriseModificationForm(siret=entreprise.siret)
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        lien_entreprise = f"<a href='{url_for('entreprises.fiche_entreprise', entreprise_id=entreprise.id)}'>{form.nom.data.strip()}</a>"
        logs_text = []
        if form.new_siret.data:
            logs_text.append(f"{lien_entreprise} - Modification du SIRET")
            entreprise.siret = form.new_siret.data.strip()
            entreprise.siret_provisoire = False
        if entreprise.nom != form.nom.data.strip():
            logs_text.append(
                f"{lien_entreprise} - Modification du nom (ancien nom: {entreprise.nom})"
            )
            entreprise.nom = form.nom.data.strip()

        if entreprise.adresse != form.adresse.data.strip():
            logs_text.append(
                f"{lien_entreprise} - Modification de l'adresse (ancienne adresse: {entreprise.adresse})"
            )
            entreprise.adresse = form.adresse.data.strip()

        if entreprise.codepostal != form.codepostal.data.strip():
            logs_text.append(
                f"{lien_entreprise} - Modification du code postal (ancien code postal: {entreprise.codepostal})"
            )
            entreprise.codepostal = form.codepostal.data.strip()

        if entreprise.ville != form.ville.data.strip():
            logs_text.append(
                f"{lien_entreprise} - Modification de la ville (ancienne ville: {entreprise.ville})"
            )
            entreprise.ville = form.ville.data.strip()

        if entreprise.pays != form.pays.data.strip() or not form.pays.data.strip():
            logs_text.append(
                f"{lien_entreprise} - Modification du pays (ancien pays: {entreprise.pays})"
            )
            entreprise.pays = (
                form.pays.data.strip() if form.pays.data.strip() else "FRANCE"
            )

        entreprise.association = form.association.data
        for log_text in logs_text:
            log = EntrepriseHistorique(
                authenticated_user=current_user.user_name,
                entreprise_id=entreprise.id,
                text=log_text,
            )
            db.session.add(log)
        db.session.commit()
        flash("L'entreprise a été modifié.")
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
        )
    elif request.method == "GET":
        form.siret.data = entreprise.siret
        form.nom.data = entreprise.nom
        form.adresse.data = entreprise.adresse
        form.codepostal.data = entreprise.codepostal
        form.ville.data = entreprise.ville
        form.pays.data = entreprise.pays
        form.association.data = entreprise.association
    return render_template(
        "entreprises/form_modification_entreprise.j2",
        title="Modification entreprise",
        form=form,
    )


@bp.route("/fiche_entreprise/<int:entreprise_id>/desactiver", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesChange)
def fiche_entreprise_desactiver(entreprise_id):
    """
    Permet de désactiver une entreprise
    """
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=True, active=True
    ).first_or_404(description=f"entreprise {entreprise_id} inconnue")
    form = DesactivationConfirmationForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        entreprise.notes_active = form.notes_active.data.strip()
        entreprise.active = False
        lien_entreprise = f"<a href='{url_for('entreprises.fiche_entreprise', entreprise_id=entreprise.id)}'>{entreprise.nom}</a>"
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=entreprise.id,
            text=f"{lien_entreprise} - Désactivation fiche entreprise",
        )
        db.session.add(log)
        db.session.commit()
        flash("L'entreprise a été désactivé.")
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
        )
    return render_template(
        "entreprises/form_confirmation.j2",
        title="Désactiver entreprise",
        form=form,
        info_message="Cliquez sur le bouton Modifier pour confirmer la désactivation",
    )


@bp.route("/fiche_entreprise/<int:entreprise_id>/activer", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesChange)
def fiche_entreprise_activer(entreprise_id):
    """
    Permet d'activer une entreprise
    """
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=True, active=False
    ).first_or_404(description=f"entreprise {entreprise_id} inconnue")
    form = ActivationConfirmationForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        entreprise.active = True
        lien_entreprise = f"<a href='{url_for('entreprises.fiche_entreprise', entreprise_id=entreprise.id)}'>{entreprise.nom}</a>"
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=entreprise.id,
            text=f"{lien_entreprise} - Activation fiche entreprise",
        )
        db.session.add(log)
        db.session.commit()
        flash("L'entreprise a été activé.")
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
        )
    return render_template(
        "entreprises/form_confirmation.j2",
        title="Activer entreprise",
        form=form,
        info_message="Cliquez sur le bouton Modifier pour confirmer l'activaction",
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/add_taxe_apprentissage",
    methods=["GET", "POST"],
)
def add_taxe_apprentissage(entreprise_id):
    """
    Permet d'ajouter une taxe d'apprentissage sur une fiche entreprise
    """
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=True
    ).first_or_404(description=f"entreprise {entreprise_id} inconnue")
    form = TaxeApprentissageForm(hidden_entreprise_id=entreprise.id)
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        taxe = EntrepriseTaxeApprentissage(
            entreprise_id=entreprise.id,
            annee=form.annee.data,
            montant=form.montant.data,
            notes=form.notes.data.strip(),
        )
        db.session.add(taxe)
        db.session.commit()
        db.session.refresh(taxe)
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=entreprise.id,
            object="taxe apprentissage",
            object_id=taxe.id,
            text=f"Création d'une taxe d'apprentissage",
        )
        db.session.add(log)
        db.session.commit()
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
        )
    return render_template(
        "entreprises/form.j2",
        title="Ajout taxe apprentissage",
        form=form,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/edit_taxe_apprentissage/<int:taxe_id>",
    methods=["GET", "POST"],
)
def edit_taxe_apprentissage(entreprise_id, taxe_id):
    """
    Permet de modifier une taxe d'apprentissage sur une fiche entreprise
    """
    taxe = EntrepriseTaxeApprentissage.query.filter_by(
        id=taxe_id, entreprise_id=entreprise_id
    ).first_or_404(
        description=f"taxe d'apprentissage {taxe_id} inconnue pour l'entreprise {entreprise_id}"
    )
    form = TaxeApprentissageModificationForm(annee=taxe.annee)
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        taxe.montant = form.montant.data
        taxe.notes = form.notes.data.strip()
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=taxe.entreprise_id,
            object="taxe apprentissage",
            object_id=taxe.id,
            text=f"Modification d'une taxe d'apprentissage",
        )
        db.session.add(log)
        db.session.commit()
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=taxe.entreprise_id)
        )
    elif request.method == "GET":
        form.montant.data = taxe.montant
        form.notes.data = taxe.notes
    return render_template(
        "entreprises/form.j2",
        title="Modification taxe apprentissage",
        form=form,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/delete_taxe_apprentissage/<int:taxe_id>",
    methods=["GET", "POST"],
)
def delete_taxe_apprentissage(entreprise_id, taxe_id):
    """
    Permet de modifier une taxe d'apprentissage sur une fiche entreprise
    """
    taxe = EntrepriseTaxeApprentissage.query.filter_by(
        id=taxe_id, entreprise_id=entreprise_id
    ).first_or_404(
        description=f"taxe d'apprentissage {taxe_id} inconnue pour l'entreprise {entreprise_id}"
    )
    form = SuppressionConfirmationForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        db.session.delete(taxe)
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=taxe.entreprise_id,
            object="taxe apprentissage",
            object_id=taxe.id,
            text=f"Suppression d'une taxe d'apprentissage",
        )
        db.session.add(log)
        db.session.commit()
        flash("La taxe d'apprentissage a été supprimé de la liste.")
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=taxe.entreprise_id)
        )
    return render_template(
        "entreprises/form_confirmation.j2",
        title="Supprimer taxe apprentissage",
        form=form,
        info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
    )


@bp.route("/fiche_entreprise/<int:entreprise_id>/add_offre", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesChange)
def add_offre(entreprise_id):
    """
    Permet d'ajouter une offre a une entreprise
    """
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=True
    ).first_or_404(description=f"entreprise {entreprise_id} inconnue")
    form = OffreCreationForm(hidden_entreprise_id=entreprise.id)
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        offre = EntrepriseOffre(
            entreprise_id=entreprise.id,
            intitule=form.intitule.data.strip(),
            description=form.description.data.strip(),
            type_offre=form.type_offre.data.strip(),
            missions=form.missions.data.strip(),
            duree=form.duree.data.strip(),
            expiration_date=form.expiration_date.data,
            correspondant_id=form.correspondant.data
            if form.correspondant.data != ""
            else None,
        )
        db.session.add(offre)
        db.session.commit()
        db.session.refresh(offre)
        for dept in form.depts.data:
            offre_dept = EntrepriseOffreDepartement(
                offre_id=offre.id,
                dept_id=dept,
            )
            db.session.add(offre_dept)
        if form.fichier.data:
            date = f"{datetime.now().strftime('%Y-%m-%d-%H-%M-%S')}"
            path = os.path.join(
                Config.SCODOC_VAR_DIR,
                "entreprises",
                f"{offre.entreprise_id}",
                f"{offre.id}",
                f"{date}",
            )
            os.makedirs(path)
            file = form.fichier.data
            filename = secure_filename(file.filename)
            file.save(os.path.join(path, filename))
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=entreprise.id,
            object="offre",
            object_id=offre.id,
            text="Création d'une offre",
        )
        db.session.add(log)
        db.session.commit()
        flash("L'offre a été ajouté à la fiche entreprise.")
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
        )
    return render_template(
        "entreprises/form.j2",
        title="Ajout offre",
        form=form,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/edit_offre/<int:offre_id>",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def edit_offre(entreprise_id, offre_id):
    """
    Permet de modifier une offre
    """
    offre = EntrepriseOffre.query.filter_by(
        id=offre_id, entreprise_id=entreprise_id
    ).first_or_404(
        description=f"offre {offre_id} inconnue pour l'entreprise {entreprise_id}"
    )
    offre_depts = EntrepriseOffreDepartement.query.filter_by(offre_id=offre.id).all()
    offre_depts_list = [(offre_dept.dept_id) for offre_dept in offre_depts]
    form = OffreModificationForm(
        hidden_entreprise_id=offre.entreprise_id, correspondant=offre.correspondant_id
    )
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        offre.intitule = form.intitule.data.strip()
        offre.description = form.description.data.strip()
        offre.type_offre = form.type_offre.data.strip()
        offre.missions = form.missions.data.strip()
        offre.duree = form.duree.data.strip()
        offre.expiration_date = form.expiration_date.data
        if form.correspondant.data == "":
            offre.correspondant_id = sql.null()
        else:
            offre.correspondant_id = form.correspondant.data
        if offre_depts_list != form.depts.data:
            for dept in form.depts.data:
                if dept not in offre_depts_list:
                    offre_dept = EntrepriseOffreDepartement(
                        offre_id=offre.id,
                        dept_id=dept,
                    )
                    db.session.add(offre_dept)
            for dept in offre_depts_list:
                if dept not in form.depts.data:
                    offre_dept = EntrepriseOffreDepartement.query.filter_by(
                        offre_id=offre.id, dept_id=dept
                    ).first_or_404()
                    db.session.delete(offre_dept)
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=offre.entreprise_id,
            object="offre",
            object_id=offre.id,
            text="Modification d'une offre",
        )
        db.session.add(log)
        db.session.commit()
        flash("L'offre a été modifié.")
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=offre.entreprise_id)
        )
    elif request.method == "GET":
        form.intitule.data = offre.intitule
        form.description.data = offre.description
        form.type_offre.data = offre.type_offre
        form.missions.data = offre.missions
        form.duree.data = offre.duree
        form.expiration_date.data = offre.expiration_date
        form.depts.data = offre_depts_list
    return render_template(
        "entreprises/form.j2",
        title="Modification offre",
        form=form,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/delete_offre/<int:offre_id>",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def delete_offre(entreprise_id, offre_id):
    """
    Permet de supprimer une offre
    """
    offre = EntrepriseOffre.query.filter_by(
        id=offre_id, entreprise_id=entreprise_id
    ).first_or_404(
        description=f"offre {offre_id} inconnue pour l'entreprise {entreprise_id}"
    )
    entreprise_id = offre.entreprise.id
    form = SuppressionConfirmationForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        db.session.delete(offre)
        path = os.path.join(
            Config.SCODOC_VAR_DIR,
            "entreprises",
            f"{entreprise_id}",
            f"{offre.id}",
        )
        if os.path.isdir(path):
            shutil.rmtree(path)
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=offre.entreprise_id,
            object="offre",
            object_id=offre.id,
            text="Suppression d'une offre",
        )
        db.session.add(log)
        db.session.commit()
        flash("L'offre a été supprimé de la fiche entreprise.")
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=offre.entreprise_id)
        )
    return render_template(
        "entreprises/form_confirmation.j2",
        title="Supression offre",
        form=form,
        info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/expired/<int:offre_id>",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def expired(entreprise_id, offre_id):
    """
    Permet de rendre expirée et non expirée une offre
    """
    offre = EntrepriseOffre.query.filter_by(
        id=offre_id, entreprise_id=entreprise_id
    ).first_or_404(
        description=f"offre {offre_id} inconnue pour l'entreprise {entreprise_id}"
    )
    offre.expired = not offre.expired
    db.session.commit()
    if offre.expired:
        flash("L'offre a été rendu expirée")
    else:
        flash("L'offre a été rendu non expirée")
    return redirect(
        url_for("entreprises.fiche_entreprise", entreprise_id=offre.entreprise_id)
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/add_site",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def add_site(entreprise_id):
    """
    Permet d'ajouter un site a une entreprise
    """
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=True
    ).first_or_404(description=f"entreprise {entreprise_id} inconnue")
    form = SiteCreationForm(hidden_entreprise_id=entreprise.id)
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        site = EntrepriseSite(
            entreprise_id=entreprise.id,
            nom=form.nom.data.strip(),
            adresse=form.adresse.data.strip(),
            codepostal=form.codepostal.data.strip(),
            ville=form.ville.data.strip(),
            pays=form.pays.data.strip() if form.pays.data.strip() else "FRANCE",
        )
        db.session.add(site)
        db.session.commit()
        db.session.refresh(site)
        lien_entreprise = f"<a href=/ScoDoc/entreprises/fiche_entreprise/{entreprise.id}>{entreprise.nom} - {form.nom.data.strip()}</a>"
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=entreprise.id,
            object="site",
            object_id=site.id,
            text=f"{lien_entreprise} - Création d'un site",
        )
        db.session.add(log)
        db.session.commit()
        flash("Le site a été créé et ajouté à la fiche entreprise")
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
        )
    return render_template(
        "entreprises/form.j2",
        title="Ajout site",
        form=form,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/edit_site/<int:site_id>",
    methods=["GET", "POST"],
)
def edit_site(entreprise_id, site_id):
    """
    Permet de modifier une offre
    """
    site = EntrepriseSite.query.filter_by(
        id=site_id, entreprise_id=entreprise_id
    ).first_or_404(
        description=f"site {site_id} inconnu pour l'entreprise {entreprise_id}"
    )
    form = SiteModificationForm(
        hidden_entreprise_id=site.entreprise_id, hidden_site_id=site.id
    )
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        site.nom = form.nom.data.strip()
        site.adresse = form.adresse.data.strip()
        site.codepostal = form.codepostal.data.strip()
        site.ville = form.ville.data.strip()
        site.pays = (form.pays.data.strip() if form.pays.data.strip() else "FRANCE",)
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=site.entreprise_id,
            object="site",
            object_id=site.id,
            text="Modification d'un site",
        )
        db.session.add(log)
        db.session.commit()
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=site.entreprise_id)
        )
    elif request.method == "GET":
        form.nom.data = site.nom
        form.adresse.data = site.adresse
        form.codepostal.data = site.codepostal
        form.ville.data = site.ville
        form.pays.data = site.pays
    return render_template(
        "entreprises/form.j2",
        title="Modification site",
        form=form,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/site/<int:site_id>/add_correspondant",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def add_correspondant(entreprise_id, site_id):
    """
    Permet d'ajouter un correspondant a une entreprise
    """
    site = EntrepriseSite.query.filter_by(
        id=site_id, entreprise_id=entreprise_id
    ).first_or_404(
        description=f"site {site_id} inconnue pour l'entreprise {entreprise_id}"
    )
    form = CorrespondantsCreationForm(hidden_site_id=site.id)
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        for correspondant_entry in form.correspondants.entries:
            correspondant = EntrepriseCorrespondant(
                site_id=site.id,
                civilite=correspondant_entry.civilite.data,
                nom=correspondant_entry.nom.data.strip(),
                prenom=correspondant_entry.prenom.data.strip(),
                telephone=correspondant_entry.telephone.data.strip(),
                mail=correspondant_entry.mail.data.strip(),
                poste=correspondant_entry.poste.data.strip(),
                service=correspondant_entry.service.data.strip(),
                origine=correspondant_entry.origine.data.strip(),
                notes=correspondant_entry.notes.data.strip(),
            )
            db.session.add(correspondant)
            db.session.commit()
            db.session.refresh(correspondant)
            log = EntrepriseHistorique(
                authenticated_user=current_user.user_name,
                entreprise_id=correspondant.site.entreprise.id,
                object="correspondant",
                object_id=correspondant.id,
                text="Création d'un correspondant",
            )
            db.session.add(log)
            db.session.commit()
            flash("Le correspondant a été ajouté à la fiche entreprise.")
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=site.entreprise_id)
        )
    return render_template(
        "entreprises/form_ajout_correspondants.j2",
        title="Ajout correspondant",
        form=form,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/site/<int:site_id>/edit_correspondant/<int:correspondant_id>",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def edit_correspondant(entreprise_id, site_id, correspondant_id):
    """
    Permet de modifier un correspondant
    """
    correspondant = (
        db.session.query(EntrepriseCorrespondant)
        .join(
            EntrepriseSite,
            EntrepriseCorrespondant.site_id == EntrepriseSite.id,
        )
        .join(Entreprise, EntrepriseSite.entreprise_id == Entreprise.id)
        .filter(
            EntrepriseCorrespondant.id == correspondant_id,
            EntrepriseCorrespondant.site_id == site_id,
            EntrepriseSite.entreprise_id == entreprise_id,
            Entreprise.visible == True,
        )
        .first_or_404(
            description=f"correspondant {correspondant_id} inconnu pour l'entreprise {entreprise_id} et le site {site_id}"
        )
    )
    form = CorrespondantModificationForm(
        hidden_site_id=correspondant.site.id,
        hidden_correspondant_id=correspondant.id,
        hidden_entreprise_id=entreprise_id,
        site=correspondant.site_id,
    )
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        correspondant.civilite = form.civilite.data
        correspondant.nom = form.nom.data.strip()
        correspondant.prenom = form.prenom.data.strip()
        correspondant.telephone = form.telephone.data.strip()
        correspondant.mail = form.mail.data.strip()
        correspondant.poste = form.poste.data.strip()
        correspondant.service = form.service.data.strip()
        correspondant.origine = form.origine.data.strip()
        correspondant.notes = form.notes.data.strip()
        correspondant.site_id = form.site.data
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=correspondant.site.entreprise.id,
            object="correspondant",
            object_id=correspondant.id,
            text="Modification d'un correspondant",
        )
        db.session.add(log)
        db.session.commit()
        flash("Le correspondant a été modifié.")
        return redirect(
            url_for(
                "entreprises.fiche_entreprise",
                entreprise_id=correspondant.site.entreprise.id,
            )
        )
    elif request.method == "GET":
        form.civilite.data = correspondant.civilite
        form.nom.data = correspondant.nom
        form.prenom.data = correspondant.prenom
        form.telephone.data = correspondant.telephone
        form.mail.data = correspondant.mail
        form.poste.data = correspondant.poste
        form.service.data = correspondant.service
        form.origine.data = correspondant.origine
        form.notes.data = correspondant.notes
    return render_template(
        "entreprises/form.j2",
        title="Modification correspondant",
        form=form,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/site/<int:site_id>/delete_correspondant/<int:correspondant_id>",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def delete_correspondant(entreprise_id, site_id, correspondant_id):
    """
    Permet de supprimer un correspondant
    """
    correspondant = (
        db.session.query(EntrepriseCorrespondant)
        .join(
            EntrepriseSite,
            EntrepriseCorrespondant.site_id == EntrepriseSite.id,
        )
        .join(Entreprise, EntrepriseSite.entreprise_id == Entreprise.id)
        .filter(
            EntrepriseCorrespondant.id == correspondant_id,
            EntrepriseCorrespondant.site_id == site_id,
            EntrepriseSite.entreprise_id == entreprise_id,
            Entreprise.visible == True,
        )
        .first_or_404(
            description=f"correspondant {correspondant_id} inconnu pour l'entreprise {entreprise_id} et le site {site_id}"
        )
    )
    form = SuppressionConfirmationForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        db.session.delete(correspondant)
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=correspondant.site.entreprise.id,
            object="correspondant",
            object_id=correspondant.id,
            text="Suppression d'un correspondant",
        )
        db.session.add(log)
        db.session.commit()
        flash("Le correspondant a été supprimé de la fiche entreprise.")
        return redirect(
            url_for(
                "entreprises.fiche_entreprise",
                entreprise_id=correspondant.site.entreprise.id,
            )
        )
    return render_template(
        "entreprises/form_confirmation.j2",
        title="Supression correspondant",
        form=form,
        info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
    )


@bp.route("/fiche_entreprise/<int:entreprise_id>/contacts")
@permission_required(Permission.RelationsEntreprisesView)
def contacts(entreprise_id):
    """
    Permet d'afficher une page avec la liste des contacts d'une entreprise
    """
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=True
    ).first_or_404(description=f"entreprise {entreprise_id} inconnue")
    contacts = EntrepriseContact.query.filter_by(entreprise=entreprise.id).all()
    return render_template(
        "entreprises/contacts.j2",
        title="Liste des contacts",
        contacts=contacts,
        entreprise=entreprise,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/contacts/add_contact",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def add_contact(entreprise_id):
    """
    Permet d'ajouter un contact avec une entreprise
    """
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=True
    ).first_or_404(description=f"entreprise {entreprise_id} inconnue")
    form = ContactCreationForm(
        date=f"{datetime.now().strftime('%Y-%m-%dT%H:%M')}",
        utilisateur=f"{current_user.nom} {current_user.prenom} ({current_user.user_name})"
        if current_user.nom and current_user.prenom
        else "",
    )
    if request.method == "POST" and form.cancel.data:
        return redirect(url_for("entreprises.contacts", entreprise_id=entreprise_id))
    if form.validate_on_submit():
        utilisateur_data = form.utilisateur.data.upper().strip()
        stm = text(
            "SELECT id, UPPER(CONCAT(nom, ' ', prenom, ' ', '(', user_name, ')')) FROM \"user\" WHERE UPPER(CONCAT(nom, ' ', prenom, ' ', '(', user_name, ')'))=:utilisateur_data"
        )
        utilisateur = (
            User.query.from_statement(stm)
            .params(utilisateur_data=utilisateur_data)
            .first()
        )
        contact = EntrepriseContact(
            date=form.date.data,
            user=utilisateur.id,
            entreprise=entreprise.id,
            notes=form.notes.data.strip(),
        )
        db.session.add(contact)
        db.session.commit()
        db.session.refresh(contact)
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=contact.entreprise,
            object="contact",
            object_id=contact.id,
            text="Création d'un contact",
        )
        db.session.add(log)
        db.session.commit()
        return redirect(url_for("entreprises.contacts", entreprise_id=entreprise.id))
    return render_template(
        "entreprises/form.j2",
        title="Ajout contact",
        form=form,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/contacts/edit_contact/<int:contact_id>",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def edit_contact(entreprise_id, contact_id):
    """
    Permet d'editer un contact avec une entreprise
    """
    contact = EntrepriseContact.query.filter_by(
        id=contact_id, entreprise=entreprise_id
    ).first_or_404(
        description=f"contact {contact_id} inconnu pour l'entreprise {entreprise_id}"
    )
    form = ContactModificationForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(url_for("entreprises.contacts", entreprise_id=entreprise_id))
    if form.validate_on_submit():
        utilisateur_data = form.utilisateur.data.upper().strip()
        stm = text(
            "SELECT id, UPPER(CONCAT(nom, ' ', prenom, ' ', '(', user_name, ')')) FROM \"user\" WHERE UPPER(CONCAT(nom, ' ', prenom, ' ', '(', user_name, ')'))=:utilisateur_data"
        )
        utilisateur = (
            User.query.from_statement(stm)
            .params(utilisateur_data=utilisateur_data)
            .first()
        )
        contact.date = form.date.data
        contact.user = utilisateur.id
        contact.notes = form.notes.data
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=contact.entreprise,
            object="contact",
            object_id=contact.id,
            text="Modification d'un contact",
        )
        db.session.add(log)
        db.session.commit()
        return redirect(
            url_for("entreprises.contacts", entreprise_id=contact.entreprise)
        )
    elif request.method == "GET":
        utilisateur = User.query.filter_by(id=contact.user).first()
        form.date.data = contact.date.strftime("%Y-%m-%dT%H:%M")
        form.utilisateur.data = (
            f"{utilisateur.nom} {utilisateur.prenom} ({utilisateur.user_name})"
        )
        form.notes.data = contact.notes
    return render_template(
        "entreprises/form.j2",
        title="Modification contact",
        form=form,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/contacts/delete_contact/<int:contact_id>",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def delete_contact(entreprise_id, contact_id):
    """
    Permet de supprimer un contact
    """
    contact = EntrepriseContact.query.filter_by(
        id=contact_id, entreprise=entreprise_id
    ).first_or_404(
        description=f"contact {contact_id} inconnu pour l'entreprise {entreprise_id}"
    )
    form = SuppressionConfirmationForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(url_for("entreprises.contacts", entreprise_id=entreprise_id))
    if form.validate_on_submit():
        db.session.delete(contact)
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=contact.entreprise,
            object="contact",
            object_id=contact.id,
            text="Suppression d'un contact",
        )
        db.session.add(log)
        db.session.commit()
        return redirect(
            url_for("entreprises.contacts", entreprise_id=contact.entreprise)
        )
    return render_template(
        "entreprises/form_confirmation.j2",
        title="Supression contact",
        form=form,
        info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/add_stage_apprentissage",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def add_stage_apprentissage(entreprise_id):
    """
    Permet d'ajouter un étudiant ayant réalisé un stage ou une alternance sur la fiche entreprise de l'entreprise
    """
    entreprise = Entreprise.query.filter_by(
        id=entreprise_id, visible=True
    ).first_or_404(description=f"entreprise {entreprise_id} inconnue")
    form = StageApprentissageCreationForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        etudiant_nomcomplet = form.etudiant.data.upper().strip()
        stm = text(
            "SELECT id, CONCAT(nom, ' ', prenom) as nom_prenom FROM Identite WHERE CONCAT(nom, ' ', prenom)=:nom_prenom"
        )
        etudiant = (
            Identite.query.from_statement(stm)
            .params(nom_prenom=etudiant_nomcomplet)
            .first()
        )
        formation = etudiant.inscription_courante_date(
            form.date_debut.data, form.date_fin.data
        )
        stage_apprentissage = EntrepriseStageApprentissage(
            entreprise_id=entreprise.id,
            etudid=etudiant.id,
            type_offre=form.type_offre.data.strip(),
            date_debut=form.date_debut.data,
            date_fin=form.date_fin.data,
            formation_text=formation.formsemestre.titre if formation else None,
            formation_scodoc=formation.formsemestre.formsemestre_id
            if formation
            else None,
            notes=form.notes.data.strip(),
        )
        db.session.add(stage_apprentissage)
        db.session.commit()
        db.session.refresh(stage_apprentissage)
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=stage_apprentissage.entreprise_id,
            object="stage apprentissage",
            object_id=stage_apprentissage.id,
            text="Création d'un stage/apprentissage",
        )
        db.session.add(log)
        db.session.commit()
        flash("L'étudiant a été ajouté sur la fiche entreprise.")
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
        )
    return render_template(
        "entreprises/form_ajout_stage_apprentissage.j2",
        title="Ajout stage / apprentissage",
        form=form,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/edit_stage_apprentissage/<int:stage_apprentissage_id>",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def edit_stage_apprentissage(entreprise_id, stage_apprentissage_id):
    """
    Permet de modifier un étudiant ayant réalisé un stage ou une alternance sur la fiche entreprise de l'entreprise
    """
    stage_apprentissage = EntrepriseStageApprentissage.query.filter_by(
        id=stage_apprentissage_id, entreprise_id=entreprise_id
    ).first_or_404(
        description=f"stage_apprentissage {stage_apprentissage_id} inconnue pour l'entreprise {entreprise_id}"
    )
    etudiant = Identite.query.filter_by(id=stage_apprentissage.etudid).first_or_404(
        description=f"etudiant {stage_apprentissage.etudid} inconnue"
    )
    form = StageApprentissageModificationForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        etudiant_nomcomplet = form.etudiant.data.upper().strip()
        stm = text(
            "SELECT id, CONCAT(nom, ' ', prenom) as nom_prenom FROM Identite WHERE CONCAT(nom, ' ', prenom)=:nom_prenom"
        )
        etudiant = (
            Identite.query.from_statement(stm)
            .params(nom_prenom=etudiant_nomcomplet)
            .first()
        )
        formation = etudiant.inscription_courante_date(
            form.date_debut.data, form.date_fin.data
        )
        stage_apprentissage.etudid = etudiant.id
        stage_apprentissage.type_offre = form.type_offre.data.strip()
        stage_apprentissage.date_debut = form.date_debut.data
        stage_apprentissage.date_fin = form.date_fin.data
        stage_apprentissage.formation_text = (
            formation.formsemestre.titre if formation else None,
        )
        stage_apprentissage.formation_scodoc = (
            formation.formsemestre.formsemestre_id if formation else None,
        )
        stage_apprentissage.notes = form.notes.data.strip()
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=stage_apprentissage.entreprise_id,
            object="stage apprentissage",
            object_id=stage_apprentissage.id,
            text="Modification d'un stage/apprentissage",
        )
        db.session.add(log)
        db.session.commit()
        return redirect(
            url_for(
                "entreprises.fiche_entreprise",
                entreprise_id=stage_apprentissage.entreprise_id,
            )
        )
    elif request.method == "GET":
        form.etudiant.data = f"{sco_etud.format_nom(etudiant.nom)} {sco_etud.format_prenom(etudiant.prenom)}"
        form.type_offre.data = stage_apprentissage.type_offre
        form.date_debut.data = stage_apprentissage.date_debut
        form.date_fin.data = stage_apprentissage.date_fin
        form.notes.data = stage_apprentissage.notes
    return render_template(
        "entreprises/form_ajout_stage_apprentissage.j2",
        title="Modification stage / apprentissage",
        form=form,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/delete_stage_apprentissage/<int:stage_apprentissage_id>",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def delete_stage_apprentissage(entreprise_id, stage_apprentissage_id):
    """
    Permet de supprimer un étudiant ayant réalisé un stage ou une alternance sur la fiche entreprise de l'entreprise
    """
    stage_apprentissage = EntrepriseStageApprentissage.query.filter_by(
        id=stage_apprentissage_id, entreprise_id=entreprise_id
    ).first_or_404(description=f"stage_apprentissage {stage_apprentissage_id} inconnu")
    form = SuppressionConfirmationForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        db.session.delete(stage_apprentissage)
        log = EntrepriseHistorique(
            authenticated_user=current_user.user_name,
            entreprise_id=stage_apprentissage.entreprise_id,
            object="stage apprentissage",
            object_id=stage_apprentissage.id,
            text="Suppression d'un stage/apprentissage",
        )
        db.session.add(log)
        db.session.commit()
        return redirect(
            url_for(
                "entreprises.fiche_entreprise",
                entreprise_id=stage_apprentissage.entreprise_id,
            )
        )
    return render_template(
        "entreprises/form_confirmation.j2",
        title="Supression stage/apprentissage",
        form=form,
        info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/envoyer_offre/<int:offre_id>",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesSend)
def envoyer_offre(entreprise_id, offre_id):
    """
    Permet d'envoyer une offre à un utilisateur ScoDoc
    """
    offre = EntrepriseOffre.query.filter_by(
        id=offre_id, entreprise_id=entreprise_id
    ).first_or_404(
        description=f"offre {offre_id} inconnue pour l'entreprise {entreprise_id}"
    )
    form = EnvoiOffreForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        for responsable in form.responsables.entries:
            if responsable.data.strip():
                responsable_data = responsable.data.upper().strip()
                stm = text(
                    "SELECT id, UPPER(CONCAT(nom, ' ', prenom, ' ', '(', user_name, ')')) FROM \"user\" WHERE UPPER(CONCAT(nom, ' ', prenom, ' ', '(', user_name, ')'))=:responsable_data"
                )
                responsable = (
                    User.query.from_statement(stm)
                    .params(responsable_data=responsable_data)
                    .first()
                )
                envoi_offre = EntrepriseEnvoiOffre(
                    sender_id=current_user.id,
                    receiver_id=responsable.id,
                    offre_id=offre.id,
                )
                db.session.add(envoi_offre)
                db.session.commit()
                flash(f"L'offre a été envoyé à {responsable.get_nomplogin()}.")
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=offre.entreprise_id)
        )
    return render_template(
        "entreprises/form_envoi_offre.j2",
        title="Envoyer une offre",
        form=form,
    )


@bp.route("/etudiants")
@permission_required(Permission.RelationsEntreprisesChange)
def json_etudiants():
    """
    Permet de récuperer un JSON avec tous les étudiants
    """
    if request.args.get("term") is None:
        abort(400)
    term = request.args.get("term").strip()
    etudiants = Identite.query.filter(Identite.nom.ilike(f"%{term}%")).limit(30).all()
    list = []
    for etudiant in etudiants:
        content = {}
        value = f"{sco_etud.format_nom(etudiant.nom)} {sco_etud.format_prenom(etudiant.prenom)}"
        if etudiant.inscription_courante() is not None:
            content = {
                "id": f"{etudiant.id}",
                "value": value,
                "info": f"Département {are.get_dept_acronym_by_id(etudiant.dept_id)} - {etudiant.inscription_courante().formsemestre.titre}",
            }
        else:
            content = {
                "id": f"{etudiant.id}",
                "value": value,
                "info": f"Département {are.get_dept_acronym_by_id(etudiant.dept_id)}",
            }
        list.append(content)
    return jsonify(results=list)


@bp.route("/responsables")
@permission_required(Permission.RelationsEntreprisesChange)
def json_responsables():
    """
    Permet de récuperer un JSON avec tous les utilisateurs ScoDoc
    """
    if request.args.get("term") is None:
        abort(400)
    term = request.args.get("term").strip()
    responsables = (
        User.query.filter(
            User.nom.ilike(f"%{term}%"), User.nom.is_not(None), User.prenom.is_not(None)
        )
        .limit(30)
        .all()
    )
    list = []

    for responsable in responsables:
        content = {}
        value = f"{responsable.get_nomplogin()}"
        content = {"id": f"{responsable.id}", "value": value}
        list.append(content)
    return jsonify(results=list)


@bp.route("/export_donnees")
@permission_required(Permission.RelationsEntreprisesExport)
def export_donnees():
    """
    Permet d'exporter la liste des entreprises sous format excel (.xlsx)
    """
    entreprise = Entreprise.query.filter_by(visible=True).first()
    if entreprise:
        wb = are.get_excel_book_are(export=True)
        xlsx = wb.generate()
        filename = "ExportApplicationRelationsEntreprises"
        return scu.send_file(xlsx, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE)
    else:
        return redirect(url_for("entreprises.index"))


@bp.route("/import_donnees/get_file_sample")
@permission_required(Permission.RelationsEntreprisesExport)
def import_donnees_get_file_sample():
    """
    Permet de récupérer un fichier exemple vide pour pouvoir importer des entreprises
    """
    wb = are.get_excel_book_are()
    xlsx = wb.generate()
    filename = "ImportApplicationRelationsEntreprises"
    return scu.send_file(xlsx, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE)


@bp.route("/import_donnees", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesExport)
def import_donnees():
    """
    Permet d'importer des entreprises à partir d'un fichier excel (.xlsx)
    """
    form = ImportForm()
    if form.validate_on_submit():
        file = form.fichier.data
        file_path = os.path.join(
            Config.SCODOC_VAR_DIR, "tmp", secure_filename(file.filename)
        )
        file.save(file_path)
        diag, lm = sco_excel.excel_workbook_to_list(file_path)
        os.remove(file_path)
        if lm is None or len(lm) < 2:
            flash("Veuillez utilisez la feuille excel à remplir")
            return redirect(url_for("entreprises.import_donnees"))
        entreprises_import = are.check_entreprises_import(lm[0])
        sites_import, correspondants_import = are.check_sites_import(lm[1])
        if (
            entreprises_import is False
            or sites_import is False
            or correspondants_import is False
            or (len(lm) > 2 and are.check_correspondants_import(lm[2]) is False)
        ):
            return redirect(url_for("entreprises.import_donnees"))
        for entreprise in entreprises_import:
            try:
                db.session.add(entreprise)
                db.session.commit()
                db.session.refresh(entreprise)
            except:
                db.session.rollback()
                flash("Une erreur est survenue veuillez réessayer.")
                return render_template(
                    "entreprises/import_donnees.j2",
                    title="Importation données",
                    form=form,
                )
            site = EntrepriseSite(
                entreprise_id=entreprise.id,
                nom=entreprise.nom,
                adresse=entreprise.adresse,
                codepostal=entreprise.codepostal,
                ville=entreprise.ville,
                pays=entreprise.pays,
            )
            db.session.add(site)
        for site in sites_import:
            db.session.add(site)
        correspondants = []
        for site, correspondant in correspondants_import:
            if site is None:
                db.session.add(correspondant)
            else:
                db.session.add(site)
                db.session.commit()
                db.session.refresh(site)
                correspondant.site_id = site.id
                db.session.add(correspondant)
            correspondants.append(correspondant)
        db.session.commit()
        flash(f"Importation réussie")
        return render_template(
            "entreprises/import_donnees.j2",
            title="Importation données",
            form=form,
            entreprises_import=entreprises_import,
            sites_import=sites_import,
            correspondants_import=correspondants,
        )
    return render_template(
        "entreprises/import_donnees.j2", title="Importation données", form=form
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/offre/<int:offre_id>/get_offre_file/<string:filedir>/<string:filename>"
)
@permission_required(Permission.RelationsEntreprisesView)
def get_offre_file(entreprise_id, offre_id, filedir, filename):
    """
    Permet de télécharger un fichier d'une offre
    """
    if os.path.isfile(
        os.path.join(
            Config.SCODOC_VAR_DIR,
            "entreprises",
            f"{entreprise_id}",
            f"{offre_id}",
            f"{filedir}",
            f"{filename}",
        )
    ):
        return send_file(
            os.path.join(
                Config.SCODOC_VAR_DIR,
                "entreprises",
                f"{entreprise_id}",
                f"{offre_id}",
                f"{filedir}",
                f"{filename}",
            ),
            as_attachment=True,
        )
    else:
        abort(404, description=f"fichier {filename} inconnu")


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/offre/<int:offre_id>/add_offre_file",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def add_offre_file(entreprise_id, offre_id):
    """
    Permet d'ajouter un fichier à une offre
    """
    offre = EntrepriseOffre.query.filter_by(
        id=offre_id, entreprise_id=entreprise_id
    ).first_or_404(
        description=f"offre {offre_id} inconnue pour l'entreprise {entreprise_id}"
    )
    form = AjoutFichierForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        date = f"{datetime.now().strftime('%Y-%m-%d-%H-%M-%S')}"
        path = os.path.join(
            Config.SCODOC_VAR_DIR,
            "entreprises",
            f"{offre.entreprise_id}",
            f"{offre.id}",
            f"{date}",
        )
        os.makedirs(path)
        file = form.fichier.data
        filename = secure_filename(file.filename)
        file.save(os.path.join(path, filename))
        flash("Le fichier a été ajouté a l'offre.")
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=offre.entreprise_id)
        )
    return render_template(
        "entreprises/form.j2",
        title="Ajout fichier à une offre",
        form=form,
    )


@bp.route(
    "/fiche_entreprise/<int:entreprise_id>/offre/<int:offre_id>/delete_offre_file/<string:filedir>",
    methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def delete_offre_file(entreprise_id, offre_id, filedir):
    """
    Permet de supprimer un fichier d'une offre
    """
    offre = EntrepriseOffre.query.filter_by(
        id=offre_id, entreprise_id=entreprise_id
    ).first_or_404(
        description=f"offre {offre_id} inconnue pour l'entreprise {entreprise_id}"
    )
    form = SuppressionConfirmationForm()
    if request.method == "POST" and form.cancel.data:
        return redirect(
            url_for("entreprises.fiche_entreprise", entreprise_id=entreprise_id)
        )
    if form.validate_on_submit():
        path = os.path.join(
            Config.SCODOC_VAR_DIR,
            "entreprises",
            f"{offre.entreprise_id}",
            f"{offre_id}",
            f"{filedir}",
        )
        if os.path.isdir(path):
            shutil.rmtree(path)
            flash("Le fichier relié à l'offre a été supprimé.")
            return redirect(
                url_for(
                    "entreprises.fiche_entreprise", entreprise_id=offre.entreprise_id
                )
            )
    return render_template(
        "entreprises/form_confirmation.j2",
        title="Suppression fichier d'une offre",
        form=form,
        info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
    )


@bp.errorhandler(404)
def not_found_error_handler(e):
    """
    Renvoie une page d'erreur pour l'erreur 404
    """
    return render_template("entreprises/error.j2", title="Erreur", e=e)
