From 30eb738c25033c2aa48b95735acc13dd45993678 Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Thu, 23 Dec 2021 19:28:25 +0100 Subject: [PATCH 01/20] applications relations entreprises --- app/__init__.py | 4 + app/entreprises/__init__.py | 25 ++ app/entreprises/forms.py | 120 ++++++ app/entreprises/models.py | 52 +++ app/entreprises/routes.py | 374 ++++++++++++++++++ app/models/__init__.py | 6 - app/models/departements.py | 2 +- app/models/entreprises.py | 69 ---- app/models/etudiants.py | 8 + app/models/formsemestre.py | 6 + app/templates/entreprises/_contact.html | 13 + app/templates/entreprises/_offre.html | 15 + .../entreprises/delete_confirmation.html | 14 + app/templates/entreprises/entreprises.html | 65 +++ .../entreprises/fiche_entreprise.html | 70 ++++ app/templates/entreprises/form.html | 71 ++++ ...a_creation_tables_relations_entreprises.py | 127 ++++++ 17 files changed, 965 insertions(+), 76 deletions(-) create mode 100644 app/entreprises/__init__.py create mode 100644 app/entreprises/forms.py create mode 100644 app/entreprises/models.py create mode 100644 app/entreprises/routes.py delete mode 100644 app/models/entreprises.py create mode 100644 app/templates/entreprises/_contact.html create mode 100644 app/templates/entreprises/_offre.html create mode 100644 app/templates/entreprises/delete_confirmation.html create mode 100644 app/templates/entreprises/entreprises.html create mode 100644 app/templates/entreprises/fiche_entreprise.html create mode 100644 app/templates/entreprises/form.html create mode 100644 migrations/versions/f62d3a0bde1a_creation_tables_relations_entreprises.py diff --git a/app/__init__.py b/app/__init__.py index 0943a91f6..0ea6bb52c 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -199,6 +199,10 @@ def create_app(config_class=DevConfig): app.register_blueprint(auth_bp, url_prefix="/auth") + from app.entreprises import bp as entreprises_bp + + app.register_blueprint(entreprises_bp, url_prefix="/ScoDoc/entreprises") + from app.views import scodoc_bp from app.views import scolar_bp from app.views import notes_bp diff --git a/app/entreprises/__init__.py b/app/entreprises/__init__.py new file mode 100644 index 000000000..d9358508e --- /dev/null +++ b/app/entreprises/__init__.py @@ -0,0 +1,25 @@ +"""entreprises.__init__ +""" + +from flask import Blueprint +from app.scodoc import sco_etud +from app.auth.models import User + +bp = Blueprint("entreprises", __name__) + +LOGS_LEN = 10 + +@bp.app_template_filter() +def format_prenom(s): + return sco_etud.format_prenom(s) + +@bp.app_template_filter() +def format_nom(s): + return sco_etud.format_nom(s) + +@bp.app_template_filter() +def get_nomcomplet(s): + user = User.query.filter_by(user_name=s).first() + return user.get_nomcomplet(); + +from app.entreprises import routes \ No newline at end of file diff --git a/app/entreprises/forms.py b/app/entreprises/forms.py new file mode 100644 index 000000000..f7fd62816 --- /dev/null +++ b/app/entreprises/forms.py @@ -0,0 +1,120 @@ +from flask import flash +from markupsafe import Markup +from flask.app import Flask +import requests, re +from flask_wtf import FlaskForm +from wtforms import StringField, SubmitField, TextAreaField, SelectField, FileField +from wtforms.fields.html5 import EmailField, DateField +from wtforms.validators import ValidationError, DataRequired, Email +from app.entreprises.models import Entreprise +from app.models import Identite +from app.auth.models import User +from app.scodoc import sco_etud +from sqlalchemy import text + +DATA_REQUIRED_ERROR_MESSAGE = "Ce champ est requis" + +class EntrepriseCreationForm(FlaskForm): + siret = StringField("SIRET", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)], render_kw={"placeholder": "Numéro composé de 14 chiffres"}) + nom_entreprise = StringField("Nom de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + adresse = StringField("Adresse de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + codepostal = StringField("Code postal de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + ville = StringField("Ville de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + pays = StringField("Pays de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + + nom_contact = StringField("Nom du contact", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + prenom_contact = StringField("Prénom du contact", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + telephone = StringField("Téléphone du contact", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + mail = EmailField("Mail du contact", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE), Email(message="Adresse e-mail invalide")]) + submit = SubmitField("Envoyer") + + def validate_siret(self, siret): + siret = siret.data.strip() + if re.match("^\d{14}$", siret) == None: + raise ValidationError("Format incorrect") + req = requests.get(f"https://entreprise.data.gouv.fr/api/sirene/v1/siret/{siret}") + if req.status_code != 200: + raise ValidationError("SIRET inexistant") + entreprise = Entreprise.query.filter_by(siret=siret).first() + if entreprise is not None: + lien = f"ici" + raise ValidationError(Markup(f"Entreprise déjà présent, lien vers la fiche : {lien}")) + +class EntrepriseModificationForm(FlaskForm): + siret = StringField("SIRET", validators=[], render_kw={"disabled":""}) + nom = StringField("Nom de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + adresse = StringField("Adresse", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + codepostal = StringField("Code postal", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + ville = StringField("Ville", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + pays = StringField("Pays", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + submit = SubmitField("Modifier") + +class OffreCreationForm(FlaskForm): + intitule = StringField("Intitulé", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + description = TextAreaField("Description", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + type_offre = SelectField("Type de l'offre", choices=[('Stage'), ('Alternance')], validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + missions = TextAreaField("Missions", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + duree = StringField("Durée", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + ficher = FileField("Fichier", validators=[]) + submit = SubmitField("Envoyer") + +class OffreModificationForm(FlaskForm): + intitule = StringField("Intitulé", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + description = TextAreaField("Description", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + type_offre = SelectField("Type de l'offre", choices=[('Stage'), ('Alternance')], validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + missions = TextAreaField("Missions", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + duree = StringField("Durée", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + submit = SubmitField("Modifier") + +class ContactCreationForm(FlaskForm): + nom = StringField("Nom", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + prenom = StringField("Prénom", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + telephone = StringField("Téléphone", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + mail = EmailField("Mail", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE), Email(message="Adresse e-mail invalide")]) + submit = SubmitField("Envoyer") + +class ContactModificationForm(FlaskForm): + nom = StringField("Nom", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + prenom = StringField("Prénom", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + telephone = StringField("Téléphone", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + mail = EmailField("Mail", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE), Email(message="Adresse e-mail invalide")]) + submit = SubmitField("Modifier") + +class HistoriqueCreationForm(FlaskForm): + etudiant = StringField("Étudiant", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)], render_kw={"placeholder": "Tapez le nom de l'étudiant puis selectionnez"}) + type_offre = SelectField("Type de l'offre", choices=[('Stage'), ('Alternance')], validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + date_debut = DateField("Date début", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + date_fin = DateField("Date fin", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + submit = SubmitField("Envoyer") + + def validate(self): + rv = FlaskForm.validate(self) + if not rv: + return False + + if self.date_debut.data > self.date_fin.data: + self.date_debut.errors.append("Les dates sont incompatibles") + self.date_fin.errors.append("Les dates sont incompatibles") + return False + return True + + def validate_etudiant(self, etudiant): + etudiant_data = 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_data).first() + if etudiant is None: + raise ValidationError("Champ incorrect (selectionnez dans la liste)") + +class EnvoiOffreForm(FlaskForm): + responsable = StringField("Responsable de formation", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + submit = SubmitField("Envoyer") + + def validate_responsable(self, responsable): + 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() + if responsable is None: + raise ValidationError("Champ incorrect (selectionnez dans la liste)") + +class SuppressionConfirmationForm(FlaskForm): + submit = SubmitField("Supprimer") \ No newline at end of file diff --git a/app/entreprises/models.py b/app/entreprises/models.py new file mode 100644 index 000000000..a079cacf8 --- /dev/null +++ b/app/entreprises/models.py @@ -0,0 +1,52 @@ +from app import db + +class Entreprise(db.Model): + __tablename__ = "entreprises" + id = db.Column(db.Integer, primary_key=True) + siret = db.Column(db.Text) + nom = db.Column(db.Text) + adresse = db.Column(db.Text) + codepostal = db.Column(db.Text) + ville = db.Column(db.Text) + pays = db.Column(db.Text) + contacts = db.relationship('EntrepriseContact', backref='entreprise', lazy='dynamic') + offres = db.relationship('EntrepriseOffre', backref='entreprise', lazy='dynamic') + +class EntrepriseContact(db.Model): + __tablename__ = "entreprise_contact" + id = db.Column(db.Integer, primary_key=True) + entreprise_id = db.Column(db.Integer, db.ForeignKey("entreprises.id")) + nom = db.Column(db.Text) + prenom = db.Column(db.Text) + telephone = db.Column(db.Text) + mail = db.Column(db.Text) + +class EntrepriseOffre(db.Model): + __tablename__ = "entreprise_offre" + id = db.Column(db.Integer, primary_key=True) + entreprise_id = db.Column(db.Integer, db.ForeignKey("entreprises.id")) + date_ajout = db.Column(db.DateTime(timezone=True), server_default=db.func.now()) + intitule = db.Column(db.Text) + description = db.Column(db.Text) + type_offre = db.Column(db.Text) + missions = db.Column(db.Text) + duree = db.Column(db.Text) + +class EntrepriseLog(db.Model): + __tablename__ = "entreprise_log" + id = db.Column(db.Integer, primary_key=True) + date = db.Column(db.DateTime(timezone=True), server_default=db.func.now()) + authenticated_user = db.Column(db.Text) + object = db.Column(db.Integer) + text = db.Column(db.Text) + +class EntrepriseHistory(db.Model): + __tablename__ = "entreprise_history" + id = db.Column(db.Integer, primary_key=True) + entreprise_id = db.Column(db.Integer, db.ForeignKey("entreprises.id")) + etudid = db.Column(db.Integer) + type_offre = db.Column(db.Text) + date_debut = db.Column(db.Date) + date_fin = db.Column(db.Date) + formation_text = db.Column(db.Text) + formation_scodoc = db.Column(db.Integer) diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py new file mode 100644 index 000000000..b74390873 --- /dev/null +++ b/app/entreprises/routes.py @@ -0,0 +1,374 @@ +from flask import render_template, redirect, url_for, request, flash +from flask.json import jsonify +from flask_login import current_user +from app.decorators import permission_required +from app.entreprises import LOGS_LEN +from app.scodoc.sco_permissions import Permission +from app.entreprises.forms import ( + EntrepriseCreationForm, + EntrepriseModificationForm, + SuppressionConfirmationForm, + OffreCreationForm, + OffreModificationForm, + ContactCreationForm, + ContactModificationForm, + HistoriqueCreationForm, + EnvoiOffreForm +) +from app.entreprises import bp +from app.entreprises.models import ( + Entreprise, + EntrepriseOffre, + EntrepriseContact, + EntrepriseLog, + EntrepriseHistory +) +from app.models import ( + Identite +) +from app.auth.models import User +from app.scodoc.sco_find_etud import search_etud_by_name +from app import db +from app.scodoc import sco_etud +from sqlalchemy import text + +@bp.route("/", methods=["GET", "POST"]) +def index(): + entreprises = Entreprise.query.all() + logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).limit(LOGS_LEN).all() + return render_template("entreprises/entreprises.html", title=("Entreprises"), entreprises=entreprises, logs=logs) + +@bp.route("/add_entreprise", methods=["GET", "POST"]) +def add_entreprise(): + form = EntrepriseCreationForm() + if form.validate_on_submit(): + entreprise = Entreprise( + nom=form.nom_entreprise.data.strip(), + siret=form.siret.data.strip(), + adresse=form.adresse.data.strip(), + codepostal=form.codepostal.data.strip(), + ville=form.ville.data.strip(), + pays=form.pays.data.strip() + ) + db.session.add(entreprise) + db.session.commit() + db.session.refresh(entreprise) + contact = EntrepriseContact( + entreprise_id=entreprise.id, + nom=form.nom_contact.data.strip(), + prenom=form.prenom_contact.data.strip(), + telephone=form.telephone.data.strip(), + mail=form.mail.data.strip() + ) + db.session.add(contact) + nom_entreprise = f"{entreprise.nom}" + log = EntrepriseLog( + authenticated_user = current_user.user_name, + text = f"{nom_entreprise} - Création de la fiche entreprise ({entreprise.nom}) avec un contact", + ) + db.session.add(log) + db.session.commit() + flash("L'entreprise a été ajouté à la liste.") + return redirect(url_for("entreprises.index")) + return render_template("entreprises/form.html", title=("Ajout entreprise + contact"), form=form) + +@bp.route("/edit_entreprise/", methods=["GET", "POST"]) +def edit_entreprise(id): + entreprise = Entreprise.query.filter_by(id=id).first_or_404() + form = EntrepriseModificationForm() + if form.validate_on_submit(): + nom_entreprise = f"{form.nom.data.strip()}" + if entreprise.nom != form.nom.data.strip(): + log = EntrepriseLog( + authenticated_user = current_user.user_name, + object = entreprise.id, + text = f"{nom_entreprise} - Modification du nom (ancien nom : {entreprise.nom})", + ) + entreprise.nom = form.nom.data.strip() + db.session.add(log) + if entreprise.adresse != form.adresse.data.strip(): + log = EntrepriseLog( + authenticated_user = current_user.user_name, + object = entreprise.id, + text = f"{nom_entreprise} - Modification de l'adresse (ancienne adresse : {entreprise.adresse})", + ) + entreprise.adresse = form.adresse.data.strip() + db.session.add(log) + if entreprise.codepostal != form.codepostal.data.strip(): + log = EntrepriseLog( + authenticated_user = current_user.user_name, + object = entreprise.id, + text = f"{nom_entreprise} - Modification du code postal (ancien code postal : {entreprise.codepostal})", + ) + entreprise.codepostal = form.codepostal.data.strip() + db.session.add(log) + if entreprise.ville != form.ville.data.strip(): + log = EntrepriseLog( + authenticated_user = current_user.user_name, + object = entreprise.id, + text = f"{nom_entreprise} - Modification de la ville (ancienne ville : {entreprise.ville})", + ) + entreprise.ville = form.ville.data.strip() + db.session.add(log) + if entreprise.pays != form.pays.data.strip(): + log = EntrepriseLog( + authenticated_user = current_user.user_name, + object = entreprise.id, + text = f"{nom_entreprise} - Modification du pays (ancien pays : {entreprise.pays})", + ) + entreprise.pays = form.pays.data.strip() + db.session.add(log) + db.session.commit() + flash("L'entreprise a été modifié.") + return redirect(url_for("entreprises.fiche_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 + return render_template("entreprises/form.html", title=("Modification entreprise"), form=form) + +@bp.route("/delete_entreprise/", methods=["GET", "POST"]) +def delete_entreprise(id): + entreprise = Entreprise.query.filter_by(id=id).first_or_404() + form = SuppressionConfirmationForm() + if form.validate_on_submit(): + db.session.delete(entreprise) + log = EntrepriseLog( + authenticated_user = current_user.user_name, + object = entreprise.id, + text = f"Suppression de la fiche entreprise ({entreprise.nom})", + ) + db.session.add(log) + db.session.commit() + flash("L'entreprise a été supprimé de la liste.") + return redirect(url_for("entreprises.index")) + return render_template("entreprises/delete_confirmation.html", title=("Supression entreprise"), form=form) + +@bp.route("/fiche_entreprise/", methods=["GET", "POST"]) +def fiche_entreprise(id): + entreprise = Entreprise.query.filter_by(id=id).first_or_404() + offres = entreprise.offres + contacts = entreprise.contacts + logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).filter_by(object=id).limit(LOGS_LEN).all() + historique = db.session.query(EntrepriseHistory, Identite).order_by(EntrepriseHistory.date_debut.desc()).\ + filter_by(entreprise_id=id).\ + join(Identite, Identite.id == EntrepriseHistory.etudid).all() + return render_template("entreprises/fiche_entreprise.html", title=("Fiche entreprise"), entreprise=entreprise, contacts=contacts, offres=offres, logs=logs, historique=historique) + +@bp.route("/add_offre/", methods=["GET", "POST"]) +def add_offre(id): + entreprise = Entreprise.query.filter_by(id=id).first_or_404() + form = OffreCreationForm() + 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() + ) + log = EntrepriseLog( + authenticated_user = current_user.user_name, + object = entreprise.id, + text = "Création d'une offre", + ) + db.session.add(log) + db.session.add(offre) + db.session.commit() + flash("L'offre a été ajouté à la fiche entreprise.") + return redirect(url_for("entreprises.fiche_entreprise", id=entreprise.id)) + return render_template("entreprises/form.html", title=("Ajout offre"), form=form) + +@bp.route("/edit_offre/", methods=["GET", "POST"]) +def edit_offre(id): + offre = EntrepriseOffre.query.filter_by(id=id).first_or_404() + form = OffreModificationForm() + 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() + log = EntrepriseLog( + authenticated_user = current_user.user_name, + object = offre.entreprise_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", 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 + return render_template("entreprises/form.html", title=("Modification offre"), form=form) + +@bp.route("/delete_offre/", methods=["GET", "POST"]) +def delete_offre(id): + offre = EntrepriseOffre.query.filter_by(id=id).first_or_404() + entreprise_id = offre.entreprise.id + form = SuppressionConfirmationForm() + if form.validate_on_submit(): + db.session.delete(offre) + log = EntrepriseLog( + authenticated_user = current_user.user_name, + object = offre.entreprise_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", id=entreprise_id)) + return render_template("entreprises/delete_confirmation.html", title=("Supression offre"), form=form) + +@bp.route("/add_contact/", methods=["GET", "POST"]) +def add_contact(id): + entreprise = Entreprise.query.filter_by(id=id).first_or_404() + form = ContactCreationForm() + if form.validate_on_submit(): + contact = EntrepriseContact( + entreprise_id=entreprise.id, + nom=form.nom.data.strip(), + prenom=form.prenom.data.strip(), + telephone=form.telephone.data.strip(), + mail=form.mail.data.strip() + ) + log = EntrepriseLog( + authenticated_user = current_user.user_name, + object = entreprise.id, + text = "Création d'un contact", + ) + db.session.add(log) + db.session.add(contact) + db.session.commit() + flash("Le contact a été ajouté à la fiche entreprise.") + return redirect(url_for("entreprises.fiche_entreprise", id=entreprise.id)) + return render_template("entreprises/form.html", title=("Ajout contact"), form=form) + +@bp.route("/edit_contact/", methods=["GET", "POST"]) +def edit_contact(id): + contact = EntrepriseContact.query.filter_by(id=id).first_or_404() + form = ContactModificationForm() + if form.validate_on_submit(): + contact.nom = form.nom.data.strip() + contact.prenom = form.prenom.data.strip() + contact.telephone = form.telephone.data.strip() + contact.mail = form.mail.data.strip() + log = EntrepriseLog( + authenticated_user = current_user.user_name, + object = contact.entreprise_id, + text = "Modification d'un contact", + ) + db.session.add(log) + db.session.commit() + flash("Le contact a été modifié.") + return redirect(url_for("entreprises.fiche_entreprise", id=contact.entreprise.id)) + elif request.method == 'GET': + form.nom.data = contact.nom + form.prenom.data = contact.prenom + form.telephone.data = contact.telephone + form.mail.data = contact.mail + return render_template("entreprises/form.html", title=("Modification contact"), form=form) + +@bp.route("/delete_contact/", methods=["GET", "POST"]) +def delete_contact(id): + contact = EntrepriseContact.query.filter_by(id=id).first_or_404() + entreprise_id = contact.entreprise.id + form = SuppressionConfirmationForm() + if form.validate_on_submit(): + contact_count = EntrepriseContact.query.filter_by(entreprise_id=contact.entreprise.id).count() + if contact_count == 1: + flash("Le contact n'a pas été supprimé de la fiche entreprise. (1 contact minimum)") + return redirect(url_for("entreprises.fiche_entreprise", id=entreprise_id)) + else: + db.session.delete(contact) + log = EntrepriseLog( + authenticated_user = current_user.user_name, + object = contact.entreprise_id, + text = "Suppression d'un contact", + ) + db.session.add(log) + db.session.commit() + flash("Le contact a été supprimé de la fiche entreprise.") + return redirect(url_for("entreprises.fiche_entreprise", id=entreprise_id)) + return render_template("entreprises/delete_confirmation.html", title=("Supression contact"), form=form) + +@bp.route("/add_historique/", methods=["GET", "POST"]) +def add_historique(id): + entreprise = Entreprise.query.filter_by(id=id).first_or_404() + form = HistoriqueCreationForm() + 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) + historique = EntrepriseHistory( + 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 + ) + db.session.add(historique) + db.session.commit() + flash("L'étudiant a été ajouté sur la fiche entreprise.") + return redirect(url_for("entreprises.fiche_entreprise", id=entreprise.id)) + return render_template("entreprises/form.html", title=("Ajout historique"), form=form) + +@bp.route("/etudiants") +def json_etudiants(): + term = request.args.get('term').strip() + etudiants = Identite.query.filter(Identite.nom.ilike(f"%{term}%")).all() + list = [] + content = {} + for etudiant in etudiants: + 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"{etudiant.inscription_courante().formsemestre.titre}" + } + else: + content = { + "id": f"{etudiant.id}", + "value": value + } + list.append(content) + content = {} + return jsonify(results=list) + +@bp.route("/envoyer_offre/", methods=["GET", "POST"]) +def envoyer_offre(id): + form = EnvoiOffreForm() + if form.validate_on_submit(): + print("tmp") # faire l'envoie du mail + return render_template("entreprises/form.html", title=("Envoyer une offre"), form=form) + +@bp.route("/responsables") +def json_responsables(): + 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)).all() + list = [] + content = {} + for responsable in responsables: + value = f"{responsable.get_nomplogin()}" + content = { + "id": f"{responsable.id}", + "value": value, + "info": "" + } + list.append(content) + content = {} + return jsonify(results=list) \ No newline at end of file diff --git a/app/models/__init__.py b/app/models/__init__.py index 0fee7bc48..642e31873 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -14,12 +14,6 @@ from app.models.raw_sql_init import create_database_functions from app.models.absences import Absence, AbsenceNotification, BilletAbsence from app.models.departements import Departement - -from app.models.entreprises import ( - Entreprise, - EntrepriseCorrespondant, - EntrepriseContact, -) from app.models.etudiants import ( Identite, Adresse, diff --git a/app/models/departements.py b/app/models/departements.py index 0734e35b0..7ed2f4b56 100644 --- a/app/models/departements.py +++ b/app/models/departements.py @@ -19,7 +19,7 @@ class Departement(db.Model): db.Boolean(), nullable=False, default=True, server_default="true" ) # sur page d'accueil - entreprises = db.relationship("Entreprise", lazy="dynamic", backref="departement") + # entreprises = db.relationship("Entreprise", lazy="dynamic", backref="departement") etudiants = db.relationship("Identite", lazy="dynamic", backref="departement") formations = db.relationship("Formation", lazy="dynamic", backref="departement") formsemestres = db.relationship( diff --git a/app/models/entreprises.py b/app/models/entreprises.py deleted file mode 100644 index bdb5672a8..000000000 --- a/app/models/entreprises.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: UTF-8 -* - -"""Gestion des absences -""" - -from app import db -from app.models import APO_CODE_STR_LEN -from app.models import SHORT_STR_LEN -from app.models import CODE_STR_LEN - - -class Entreprise(db.Model): - """une entreprise""" - - __tablename__ = "entreprises" - id = db.Column(db.Integer, primary_key=True) - entreprise_id = db.synonym("id") - dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True) - nom = db.Column(db.Text) - adresse = db.Column(db.Text) - ville = db.Column(db.Text) - codepostal = db.Column(db.Text) - pays = db.Column(db.Text) - contact_origine = db.Column(db.Text) - secteur = db.Column(db.Text) - note = db.Column(db.Text) - privee = db.Column(db.Text) - localisation = db.Column(db.Text) - # -1 inconnue, 0, 25, 50, 75, 100: - qualite_relation = db.Column(db.Integer) - plus10salaries = db.Column(db.Boolean()) - date_creation = db.Column(db.DateTime(timezone=True), server_default=db.func.now()) - - -class EntrepriseCorrespondant(db.Model): - """Personne contact en entreprise""" - - __tablename__ = "entreprise_correspondant" - id = db.Column(db.Integer, primary_key=True) - entreprise_corresp_id = db.synonym("id") - entreprise_id = db.Column(db.Integer, db.ForeignKey("entreprises.id")) - nom = db.Column(db.Text) - prenom = db.Column(db.Text) - civilite = db.Column(db.Text) - fonction = db.Column(db.Text) - phone1 = db.Column(db.Text) - phone2 = db.Column(db.Text) - mobile = db.Column(db.Text) - mail1 = db.Column(db.Text) - mail2 = db.Column(db.Text) - fax = db.Column(db.Text) - note = db.Column(db.Text) - - -class EntrepriseContact(db.Model): - """Evènement (contact) avec une entreprise""" - - __tablename__ = "entreprise_contact" - id = db.Column(db.Integer, primary_key=True) - entreprise_contact_id = db.synonym("id") - date = db.Column(db.DateTime(timezone=True)) - type_contact = db.Column(db.Text) - entreprise_id = db.Column(db.Integer, db.ForeignKey("entreprises.id")) - entreprise_corresp_id = db.Column( - db.Integer, db.ForeignKey("entreprise_correspondant.id") - ) - etudid = db.Column(db.Integer) # sans contrainte pour garder logs après suppression - description = db.Column(db.Text) - enseignant = db.Column(db.Text) diff --git a/app/models/etudiants.py b/app/models/etudiants.py index 0ae36bd28..0f81ad6bf 100644 --- a/app/models/etudiants.py +++ b/app/models/etudiants.py @@ -107,6 +107,14 @@ class Identite(db.Model): ] return r[0] if r else None + def inscription_courante_date(self, date_debut, date_fin): + r = [ + ins + for ins in self.formsemestre_inscriptions + if ins.formsemestre.est_courant_date(date_debut, date_fin) + ] + return r[0] if r else None + def etat_inscription(self, formsemestre_id): """etat de l'inscription de cet étudiant au semestre: False si pas inscrit, ou scu.INSCRIT, DEMISSION, DEF diff --git a/app/models/formsemestre.py b/app/models/formsemestre.py index 450ea2ccf..dc13c1cc8 100644 --- a/app/models/formsemestre.py +++ b/app/models/formsemestre.py @@ -146,6 +146,12 @@ class FormSemestre(db.Model): today = datetime.date.today() return (self.date_debut <= today) and (today <= self.date_fin) + def est_courant_date(self, date_debut, date_fin) -> bool: + """Vrai si la date actuelle (now) est dans le semestre + (les dates de début et fin sont incluses) + """ + return (self.date_debut <= date_debut) and (date_fin <= self.date_fin) + def est_decale(self): """Vrai si semestre "décalé" c'est à dire semestres impairs commençant entre janvier et juin diff --git a/app/templates/entreprises/_contact.html b/app/templates/entreprises/_contact.html new file mode 100644 index 000000000..eff3a8cb2 --- /dev/null +++ b/app/templates/entreprises/_contact.html @@ -0,0 +1,13 @@ +
+

+ Nom : {{ contact.nom }}
+ Prénom : {{ contact.prenom }}
+ Téléphone : {{ contact.telephone }}
+ Mail : {{ contact.mail }}
+

+ + +
\ No newline at end of file diff --git a/app/templates/entreprises/_offre.html b/app/templates/entreprises/_offre.html new file mode 100644 index 000000000..e64f3c16c --- /dev/null +++ b/app/templates/entreprises/_offre.html @@ -0,0 +1,15 @@ +
+

+ Intitulé : {{ offre.intitule }}
+ Description : {{ offre.description }}
+ Type de l'offre : {{ offre.type_offre }}
+ Missions : {{ offre.missions }}
+ Durée : {{ offre.duree }}
+

+ + +
\ No newline at end of file diff --git a/app/templates/entreprises/delete_confirmation.html b/app/templates/entreprises/delete_confirmation.html new file mode 100644 index 000000000..06b75b6ad --- /dev/null +++ b/app/templates/entreprises/delete_confirmation.html @@ -0,0 +1,14 @@ +{% extends 'base.html' %} +{% import 'bootstrap/wtf.html' as wtf %} + +{% block app_content %} +

{{ title }}

+
+
Cliquez sur le bouton supprimer pour confirmer votre supression
+
+
+
+ {{ wtf.quick_form(form) }} +
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/entreprises/entreprises.html b/app/templates/entreprises/entreprises.html new file mode 100644 index 000000000..4ca2860ee --- /dev/null +++ b/app/templates/entreprises/entreprises.html @@ -0,0 +1,65 @@ +{% extends 'base.html' %} + +{% block app_content %} + + {% if logs %} +
+

Dernières opérations

+
    + {% for log in logs %} +
  • {{ log.date.strftime('%d %b %Hh%M') }}{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet }}
  • + {% endfor %} +
+
+ {% endif %} +
+

Liste des entreprises

+ {% if entreprises %} +
+ + + + + + + + + + + {% for entreprise in entreprises %} + + + + + + + + + + {% endfor %} +
SIRETNomAdresseCode postalVillePaysAction
{{ entreprise.siret }}{{ entreprise.nom }}{{ entreprise.adresse }}{{ entreprise.codepostal }}{{ entreprise.ville }}{{ entreprise.pays }} + +
+
+ {% else %} +
Aucune entreprise présent dans la base
+
+
+ {% endif %} + Ajouter une entreprise +
+{% endblock %} \ No newline at end of file diff --git a/app/templates/entreprises/fiche_entreprise.html b/app/templates/entreprises/fiche_entreprise.html new file mode 100644 index 000000000..5667d1328 --- /dev/null +++ b/app/templates/entreprises/fiche_entreprise.html @@ -0,0 +1,70 @@ +{% extends 'base.html' %} + +{% block app_content %} + {% if logs %} +
+

Dernières opérations sur cette fiche

+
    + {% for log in logs %} +
  • + {{ log.date.strftime('%d %b %Hh%M') }} + {{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet }} +
  • + {% endfor %} +
+
+ {% endif %} + {% if historique %} +
+

Historique

+
    + {% for data in historique %} +
  • + {{ data[0].date_debut.strftime('%d/%m/%Y') }} - {{ data[0].date_fin.strftime('%d/%m/%Y') }} + {{ data[0].type_offre }} réalisé par {{ data[1].nom|format_nom }} {{ data[1].prenom|format_prenom }} +
  • + {% endfor %} +
+
+ {% endif %} +
+

Fiche entreprise - {{ entreprise.nom }} ({{ entreprise.siret }})

+ +
+

+ SIRET : {{ entreprise.siret }}
+ Nom : {{ entreprise.nom }}
+ Adresse : {{ entreprise.adresse }}
+ Code postal : {{ entreprise.codepostal }}
+ Ville : {{ entreprise.ville }}
+ Pays : {{ entreprise.pays }} +

+
+ + {% if contacts %} +
+ {% for contact in contacts %} + Contact {{loop.index}} + {% include 'entreprises/_contact.html' %} + {% endfor %} +
+ {% endif %} + + {% if offres %} +
+ {% for offre in offres %} + Offre {{loop.index}} (ajouté le {{offre.date_ajout.strftime('%d/%m/%Y') }}) + {% include 'entreprises/_offre.html' %} + {% endfor %} +
+ {% endif %} + + +
+{% endblock %} \ No newline at end of file diff --git a/app/templates/entreprises/form.html b/app/templates/entreprises/form.html new file mode 100644 index 000000000..2efa5aedc --- /dev/null +++ b/app/templates/entreprises/form.html @@ -0,0 +1,71 @@ +{% extends 'base.html' %} +{% import 'bootstrap/wtf.html' as wtf %} + +{% block styles %} +{{super()}} + + +{% endblock %} + +{% block app_content %} +

{{ title }}

+
+
+
+ {{ wtf.quick_form(form, novalidate=True) }} +
+
+ +{% endblock %} \ No newline at end of file diff --git a/migrations/versions/f62d3a0bde1a_creation_tables_relations_entreprises.py b/migrations/versions/f62d3a0bde1a_creation_tables_relations_entreprises.py new file mode 100644 index 000000000..ae414038b --- /dev/null +++ b/migrations/versions/f62d3a0bde1a_creation_tables_relations_entreprises.py @@ -0,0 +1,127 @@ +"""creation tables relations entreprises + +Revision ID: f62d3a0bde1a +Revises: 39818df276aa +Create Date: 2021-12-10 11:25:04.135491 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = 'f62d3a0bde1a' +down_revision = '91be8a06d423' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('entreprise_log', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('date', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True), + sa.Column('authenticated_user', sa.Text(), nullable=True), + sa.Column('object', sa.Integer(), nullable=True), + sa.Column('text', sa.Text(), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('entreprise_history', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('entreprise_id', sa.Integer(), nullable=True), + sa.Column('etudid', sa.Integer(), nullable=True), + sa.Column('type_offre', sa.Text(), nullable=True), + sa.Column('date_debut', sa.Date(), nullable=True), + sa.Column('date_fin', sa.Date(), nullable=True), + sa.Column('formation_text', sa.Text(), nullable=True), + sa.Column('formation_scodoc', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['entreprise_id'], ['entreprises.id'], ), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('entreprise_offre', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('entreprise_id', sa.Integer(), nullable=True), + sa.Column('date_ajout', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True), + sa.Column('intitule', sa.Text(), nullable=True), + sa.Column('description', sa.Text(), nullable=True), + sa.Column('type_offre', sa.Text(), nullable=True), + sa.Column('missions', sa.Text(), nullable=True), + sa.Column('duree', sa.Text(), nullable=True), + sa.ForeignKeyConstraint(['entreprise_id'], ['entreprises.id'], ), + sa.PrimaryKeyConstraint('id') + ) + + op.drop_constraint('entreprise_contact_entreprise_corresp_id_fkey', 'entreprise_contact', type_='foreignkey') + op.drop_table('entreprise_correspondant') + op.add_column('entreprise_contact', sa.Column('nom', sa.Text(), nullable=True)) + op.add_column('entreprise_contact', sa.Column('prenom', sa.Text(), nullable=True)) + op.add_column('entreprise_contact', sa.Column('telephone', sa.Text(), nullable=True)) + op.add_column('entreprise_contact', sa.Column('mail', sa.Text(), nullable=True)) + op.drop_column('entreprise_contact', 'date') + op.drop_column('entreprise_contact', 'description') + op.drop_column('entreprise_contact', 'type_contact') + op.drop_column('entreprise_contact', 'enseignant') + op.drop_column('entreprise_contact', 'entreprise_corresp_id') + op.drop_column('entreprise_contact', 'etudid') + + op.add_column('entreprises', sa.Column('siret', sa.Text(), nullable=True)) + op.drop_index('ix_entreprises_dept_id', table_name='entreprises') + op.drop_constraint('entreprises_dept_id_fkey', 'entreprises', type_='foreignkey') + op.drop_column('entreprises', 'localisation') + op.drop_column('entreprises', 'contact_origine') + op.drop_column('entreprises', 'qualite_relation') + op.drop_column('entreprises', 'secteur') + op.drop_column('entreprises', 'plus10salaries') + op.drop_column('entreprises', 'dept_id') + op.drop_column('entreprises', 'privee') + op.drop_column('entreprises', 'date_creation') + op.drop_column('entreprises', 'note') + # ### end Alembic commands ### + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('entreprises', sa.Column('note', sa.TEXT(), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('date_creation', postgresql.TIMESTAMP(timezone=True), server_default=sa.text('now()'), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('privee', sa.TEXT(), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('dept_id', sa.INTEGER(), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('plus10salaries', sa.BOOLEAN(), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('secteur', sa.TEXT(), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('qualite_relation', sa.INTEGER(), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('contact_origine', sa.TEXT(), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('localisation', sa.TEXT(), autoincrement=False, nullable=True)) + op.create_foreign_key('entreprises_dept_id_fkey', 'entreprises', 'departement', ['dept_id'], ['id']) + op.create_index('ix_entreprises_dept_id', 'entreprises', ['dept_id'], unique=False) + op.drop_column('entreprises', 'siret') + op.add_column('entreprise_contact', sa.Column('etudid', sa.INTEGER(), autoincrement=False, nullable=True)) + op.add_column('entreprise_contact', sa.Column('entreprise_corresp_id', sa.INTEGER(), autoincrement=False, nullable=True)) + op.add_column('entreprise_contact', sa.Column('enseignant', sa.TEXT(), autoincrement=False, nullable=True)) + op.add_column('entreprise_contact', sa.Column('type_contact', sa.TEXT(), autoincrement=False, nullable=True)) + op.add_column('entreprise_contact', sa.Column('description', sa.TEXT(), autoincrement=False, nullable=True)) + op.add_column('entreprise_contact', sa.Column('date', postgresql.TIMESTAMP(timezone=True), autoincrement=False, nullable=True)) + op.create_table('entreprise_correspondant', + sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column('entreprise_id', sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column('nom', sa.TEXT(), autoincrement=False, nullable=True), + sa.Column('prenom', sa.TEXT(), autoincrement=False, nullable=True), + sa.Column('civilite', sa.TEXT(), autoincrement=False, nullable=True), + sa.Column('fonction', sa.TEXT(), autoincrement=False, nullable=True), + sa.Column('phone1', sa.TEXT(), autoincrement=False, nullable=True), + sa.Column('phone2', sa.TEXT(), autoincrement=False, nullable=True), + sa.Column('mobile', sa.TEXT(), autoincrement=False, nullable=True), + sa.Column('mail1', sa.TEXT(), autoincrement=False, nullable=True), + sa.Column('mail2', sa.TEXT(), autoincrement=False, nullable=True), + sa.Column('fax', sa.TEXT(), autoincrement=False, nullable=True), + sa.Column('note', sa.TEXT(), autoincrement=False, nullable=True), + sa.ForeignKeyConstraint(['entreprise_id'], ['entreprises.id'], name='entreprise_correspondant_entreprise_id_fkey'), + sa.PrimaryKeyConstraint('id', name='entreprise_correspondant_pkey') + ) + op.create_foreign_key('entreprise_contact_entreprise_corresp_id_fkey', 'entreprise_contact', 'entreprise_correspondant', ['entreprise_corresp_id'], ['id']) + op.drop_column('entreprise_contact', 'mail') + op.drop_column('entreprise_contact', 'telephone') + op.drop_column('entreprise_contact', 'prenom') + op.drop_column('entreprise_contact', 'nom') + + op.drop_table('entreprise_offre') + op.drop_table('entreprise_history') + op.drop_table('entreprise_log') + # ### end Alembic commands ### \ No newline at end of file From 93d026d2ac527b8b54b0bd80a9d6a98ffcacd848 Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Thu, 23 Dec 2021 23:19:31 +0100 Subject: [PATCH 02/20] cascade sur les offres et les contacts --- app/entreprises/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/entreprises/models.py b/app/entreprises/models.py index a079cacf8..a04d115bc 100644 --- a/app/entreprises/models.py +++ b/app/entreprises/models.py @@ -9,8 +9,8 @@ class Entreprise(db.Model): codepostal = db.Column(db.Text) ville = db.Column(db.Text) pays = db.Column(db.Text) - contacts = db.relationship('EntrepriseContact', backref='entreprise', lazy='dynamic') - offres = db.relationship('EntrepriseOffre', backref='entreprise', lazy='dynamic') + contacts = db.relationship('EntrepriseContact', backref='entreprise', lazy='dynamic', cascade="all, delete-orphan") + offres = db.relationship('EntrepriseOffre', backref='entreprise', lazy='dynamic', cascade="all, delete-orphan") class EntrepriseContact(db.Model): __tablename__ = "entreprise_contact" From d740244d253713d2df3ab79ff9bac60651a18e4d Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Thu, 23 Dec 2021 23:21:47 +0100 Subject: [PATCH 03/20] ajout page contacts --- app/entreprises/routes.py | 45 +++++++++++-------- app/templates/entreprises/contacts.html | 43 ++++++++++++++++++ app/templates/entreprises/entreprises.html | 11 +---- .../entreprises/fiche_entreprise.html | 4 +- app/templates/entreprises/form.html | 32 +++++++------ 5 files changed, 92 insertions(+), 43 deletions(-) create mode 100644 app/templates/entreprises/contacts.html diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index b74390873..628a52335 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -32,12 +32,30 @@ from app import db from app.scodoc import sco_etud from sqlalchemy import text -@bp.route("/", methods=["GET", "POST"]) +@bp.route("/", methods=["GET"]) def index(): entreprises = Entreprise.query.all() logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).limit(LOGS_LEN).all() return render_template("entreprises/entreprises.html", title=("Entreprises"), entreprises=entreprises, logs=logs) +@bp.route("/contacts", methods=["GET"]) +def contacts(): + contacts = db.session.query(EntrepriseContact, Entreprise).\ + join(Entreprise, EntrepriseContact.entreprise_id == Entreprise.id).all() + logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).limit(LOGS_LEN).all() + return render_template("entreprises/contacts.html", title=("Contacts"), contacts=contacts, logs=logs) + +@bp.route("/fiche_entreprise/", methods=["GET"]) +def fiche_entreprise(id): + entreprise = Entreprise.query.filter_by(id=id).first_or_404() + offres = entreprise.offres + contacts = entreprise.contacts + logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).filter_by(object=id).limit(LOGS_LEN).all() + historique = db.session.query(EntrepriseHistory, Identite).order_by(EntrepriseHistory.date_debut.desc()).\ + filter_by(entreprise_id=id).\ + join(Identite, Identite.id == EntrepriseHistory.etudid).all() + return render_template("entreprises/fiche_entreprise.html", title=("Fiche entreprise"), entreprise=entreprise, contacts=contacts, offres=offres, logs=logs, historique=historique) + @bp.route("/add_entreprise", methods=["GET", "POST"]) def add_entreprise(): form = EntrepriseCreationForm() @@ -147,17 +165,6 @@ def delete_entreprise(id): return redirect(url_for("entreprises.index")) return render_template("entreprises/delete_confirmation.html", title=("Supression entreprise"), form=form) -@bp.route("/fiche_entreprise/", methods=["GET", "POST"]) -def fiche_entreprise(id): - entreprise = Entreprise.query.filter_by(id=id).first_or_404() - offres = entreprise.offres - contacts = entreprise.contacts - logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).filter_by(object=id).limit(LOGS_LEN).all() - historique = db.session.query(EntrepriseHistory, Identite).order_by(EntrepriseHistory.date_debut.desc()).\ - filter_by(entreprise_id=id).\ - join(Identite, Identite.id == EntrepriseHistory.etudid).all() - return render_template("entreprises/fiche_entreprise.html", title=("Fiche entreprise"), entreprise=entreprise, contacts=contacts, offres=offres, logs=logs, historique=historique) - @bp.route("/add_offre/", methods=["GET", "POST"]) def add_offre(id): entreprise = Entreprise.query.filter_by(id=id).first_or_404() @@ -326,6 +333,13 @@ def add_historique(id): return redirect(url_for("entreprises.fiche_entreprise", id=entreprise.id)) return render_template("entreprises/form.html", title=("Ajout historique"), form=form) +@bp.route("/envoyer_offre/", methods=["GET", "POST"]) +def envoyer_offre(id): + form = EnvoiOffreForm() + if form.validate_on_submit(): + print("tmp") # faire l'envoie du mail + return render_template("entreprises/form.html", title=("Envoyer une offre"), form=form) + @bp.route("/etudiants") def json_etudiants(): term = request.args.get('term').strip() @@ -348,13 +362,6 @@ def json_etudiants(): list.append(content) content = {} return jsonify(results=list) - -@bp.route("/envoyer_offre/", methods=["GET", "POST"]) -def envoyer_offre(id): - form = EnvoiOffreForm() - if form.validate_on_submit(): - print("tmp") # faire l'envoie du mail - return render_template("entreprises/form.html", title=("Envoyer une offre"), form=form) @bp.route("/responsables") def json_responsables(): diff --git a/app/templates/entreprises/contacts.html b/app/templates/entreprises/contacts.html new file mode 100644 index 000000000..7f1433334 --- /dev/null +++ b/app/templates/entreprises/contacts.html @@ -0,0 +1,43 @@ +{% extends 'base.html' %} + +{% block app_content %} + {% if logs %} +
+

Dernières opérations

+
    + {% for log in logs %} +
  • {{ log.date.strftime('%d %b %Hh%M') }}{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet }}
  • + {% endfor %} +
+
+ {% endif %} +
+

Liste des contacts

+ {% if contacts %} +
+ + + + + + + + + {% for contact in contacts %} + + + + + + + + {% endfor %} +
NomPrenomTelephoneMailEntreprise
{{ contact[0].nom }}{{ contact[0].prenom }}{{ contact[0].telephone }}{{ contact[0].mail }}{{ contact[1].nom }}
+
+ {% else %} +
Aucun contact présent dans la base
+
+
+ {% endif %} +
+{% endblock %} \ No newline at end of file diff --git a/app/templates/entreprises/entreprises.html b/app/templates/entreprises/entreprises.html index 4ca2860ee..a33dd7e77 100644 --- a/app/templates/entreprises/entreprises.html +++ b/app/templates/entreprises/entreprises.html @@ -1,13 +1,6 @@ {% extends 'base.html' %} {% block app_content %} - {% if logs %}

Dernières opérations

@@ -22,7 +15,7 @@

Liste des entreprises

{% if entreprises %}
- +
@@ -35,7 +28,7 @@ {% for entreprise in entreprises %} - + diff --git a/app/templates/entreprises/fiche_entreprise.html b/app/templates/entreprises/fiche_entreprise.html index 5667d1328..b84980366 100644 --- a/app/templates/entreprises/fiche_entreprise.html +++ b/app/templates/entreprises/fiche_entreprise.html @@ -21,7 +21,9 @@ {% for data in historique %}
  • {{ data[0].date_debut.strftime('%d/%m/%Y') }} - {{ data[0].date_fin.strftime('%d/%m/%Y') }} - {{ data[0].type_offre }} réalisé par {{ data[1].nom|format_nom }} {{ data[1].prenom|format_prenom }} + + {{ data[0].type_offre }} réalisé par {{ data[1].nom|format_nom }} {{ data[1].prenom|format_prenom }} en {{ data[0].formation_text }} +
  • {% endfor %} diff --git a/app/templates/entreprises/form.html b/app/templates/entreprises/form.html index 2efa5aedc..25cb579dd 100644 --- a/app/templates/entreprises/form.html +++ b/app/templates/entreprises/form.html @@ -47,25 +47,29 @@ if(response.ok) return response.json() else { - document.getElementById("nom_entreprise").value = '' - document.getElementById("adresse").value = '' - document.getElementById("codepostal").value = '' - document.getElementById("ville").value = '' - document.getElementById("pays").value = '' - throw new Error("404") + emptyForm() } }) - .then(function(response) { - data = JSON.parse(JSON.stringify(response)) - document.getElementById("nom_entreprise").value = data.etablissement.l1_normalisee - document.getElementById("adresse").value = data.etablissement.l4_normalisee - document.getElementById("codepostal").value = data.etablissement.code_postal - document.getElementById("ville").value = data.etablissement.libelle_commune - document.getElementById("pays").value = 'France' - }) + .then(response => fillForm(response)) .catch(err => err) } } + + function fillForm(response) { + document.getElementById("nom_entreprise").value = response.etablissement.l1_normalisee + document.getElementById("adresse").value = response.etablissement.l4_normalisee + document.getElementById("codepostal").value = response.etablissement.code_postal + document.getElementById("ville").value = response.etablissement.libelle_commune + document.getElementById("pays").value = 'FRANCE' + } + + function emptyForm() { + document.getElementById("nom_entreprise").value = '' + document.getElementById("adresse").value = '' + document.getElementById("codepostal").value = '' + document.getElementById("ville").value = '' + document.getElementById("pays").value = '' + } } {% endblock %} \ No newline at end of file From 4b6f91b3040ce10d9b9ebfc6ccd06d2ce8dce8d6 Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Fri, 24 Dec 2021 09:50:25 +0100 Subject: [PATCH 04/20] delete-role --- scodoc.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scodoc.py b/scodoc.py index 94c8a7f09..1be505527 100755 --- a/scodoc.py +++ b/scodoc.py @@ -248,6 +248,16 @@ def edit_role(rolename, addpermissionname=None, removepermissionname=None): # e db.session.add(role) db.session.commit() +@app.cli.command() +@click.argument("rolename") +def delete_role(rolename): + """Delete a role""" + role = Role.query.filter_by(name=rolename).first() + if role is None: + sys.stderr.write(f"delete_role: role {rolename} does not exists\n") + return 1 + db.session.delete(role) + db.session.commit() @app.cli.command() @click.argument("username") From 3b2805627883092f41cac2d41e910f1c50ab06a7 Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Fri, 24 Dec 2021 10:43:12 +0100 Subject: [PATCH 05/20] ajout table entreprise_envoi_offre --- app/entreprises/models.py | 12 ++- app/entreprises/routes.py | 8 +- ..._creation_tables_relations_entreprises.py} | 75 ++++++++++++------- 3 files changed, 60 insertions(+), 35 deletions(-) rename migrations/versions/{f62d3a0bde1a_creation_tables_relations_entreprises.py => f3b62d64efa3_creation_tables_relations_entreprises.py} (88%) diff --git a/app/entreprises/models.py b/app/entreprises/models.py index a04d115bc..b4ac1a4b3 100644 --- a/app/entreprises/models.py +++ b/app/entreprises/models.py @@ -20,6 +20,8 @@ class EntrepriseContact(db.Model): prenom = db.Column(db.Text) telephone = db.Column(db.Text) mail = db.Column(db.Text) + poste = db.Column(db.Text) + service = db.Column(db.Text) class EntrepriseOffre(db.Model): __tablename__ = "entreprise_offre" @@ -40,8 +42,8 @@ class EntrepriseLog(db.Model): object = db.Column(db.Integer) text = db.Column(db.Text) -class EntrepriseHistory(db.Model): - __tablename__ = "entreprise_history" +class EntrepriseEtudiant(db.Model): + __tablename__ = "entreprise_etudiant" id = db.Column(db.Integer, primary_key=True) entreprise_id = db.Column(db.Integer, db.ForeignKey("entreprises.id")) etudid = db.Column(db.Integer) @@ -50,3 +52,9 @@ class EntrepriseHistory(db.Model): date_fin = db.Column(db.Date) formation_text = db.Column(db.Text) formation_scodoc = db.Column(db.Integer) + +class EntrepriseEnvoiOffre(db.Model): + __tablename__ = "entreprise_envoi_offre" + id = db.Column(db.Integer, primary_key=True) + user_id = db.Column(db.Integer, db.ForeignKey("user.id")) + offre_id = db.Column(db.Integer, db.ForeignKey("entreprise_offre.id")) \ No newline at end of file diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index 628a52335..681f12425 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -21,7 +21,7 @@ from app.entreprises.models import ( EntrepriseOffre, EntrepriseContact, EntrepriseLog, - EntrepriseHistory + EntrepriseEtudiant ) from app.models import ( Identite @@ -51,9 +51,9 @@ def fiche_entreprise(id): offres = entreprise.offres contacts = entreprise.contacts logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).filter_by(object=id).limit(LOGS_LEN).all() - historique = db.session.query(EntrepriseHistory, Identite).order_by(EntrepriseHistory.date_debut.desc()).\ + historique = db.session.query(EntrepriseEtudiant, Identite).order_by(EntrepriseEtudiant.date_debut.desc()).\ filter_by(entreprise_id=id).\ - join(Identite, Identite.id == EntrepriseHistory.etudid).all() + join(Identite, Identite.id == EntrepriseEtudiant.etudid).all() return render_template("entreprises/fiche_entreprise.html", title=("Fiche entreprise"), entreprise=entreprise, contacts=contacts, offres=offres, logs=logs, historique=historique) @bp.route("/add_entreprise", methods=["GET", "POST"]) @@ -316,7 +316,7 @@ def add_historique(id): 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) - historique = EntrepriseHistory( + historique = EntrepriseEtudiant( entreprise_id = entreprise.id, etudid = etudiant.id, type_offre = form.type_offre.data.strip(), diff --git a/migrations/versions/f62d3a0bde1a_creation_tables_relations_entreprises.py b/migrations/versions/f3b62d64efa3_creation_tables_relations_entreprises.py similarity index 88% rename from migrations/versions/f62d3a0bde1a_creation_tables_relations_entreprises.py rename to migrations/versions/f3b62d64efa3_creation_tables_relations_entreprises.py index ae414038b..cc524777b 100644 --- a/migrations/versions/f62d3a0bde1a_creation_tables_relations_entreprises.py +++ b/migrations/versions/f3b62d64efa3_creation_tables_relations_entreprises.py @@ -1,8 +1,8 @@ """creation tables relations entreprises -Revision ID: f62d3a0bde1a -Revises: 39818df276aa -Create Date: 2021-12-10 11:25:04.135491 +Revision ID: f3b62d64efa3 +Revises: 91be8a06d423 +Create Date: 2021-12-24 10:36:27.150085 """ from alembic import op @@ -10,7 +10,7 @@ import sqlalchemy as sa from sqlalchemy.dialects import postgresql # revision identifiers, used by Alembic. -revision = 'f62d3a0bde1a' +revision = 'f3b62d64efa3' down_revision = '91be8a06d423' branch_labels = None depends_on = None @@ -26,7 +26,8 @@ def upgrade(): sa.Column('text', sa.Text(), nullable=True), sa.PrimaryKeyConstraint('id') ) - op.create_table('entreprise_history', + + op.create_table('entreprise_etudiant', sa.Column('id', sa.Integer(), nullable=False), sa.Column('entreprise_id', sa.Integer(), nullable=True), sa.Column('etudid', sa.Integer(), nullable=True), @@ -38,6 +39,7 @@ def upgrade(): sa.ForeignKeyConstraint(['entreprise_id'], ['entreprises.id'], ), sa.PrimaryKeyConstraint('id') ) + op.create_table('entreprise_offre', sa.Column('id', sa.Integer(), nullable=False), sa.Column('entreprise_id', sa.Integer(), nullable=True), @@ -51,53 +53,65 @@ def upgrade(): sa.PrimaryKeyConstraint('id') ) + op.create_table('entreprise_envoi_offre', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=True), + sa.Column('offre_id', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['offre_id'], ['entreprise_offre.id'], ), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id') + ) + op.drop_constraint('entreprise_contact_entreprise_corresp_id_fkey', 'entreprise_contact', type_='foreignkey') op.drop_table('entreprise_correspondant') op.add_column('entreprise_contact', sa.Column('nom', sa.Text(), nullable=True)) op.add_column('entreprise_contact', sa.Column('prenom', sa.Text(), nullable=True)) op.add_column('entreprise_contact', sa.Column('telephone', sa.Text(), nullable=True)) op.add_column('entreprise_contact', sa.Column('mail', sa.Text(), nullable=True)) - op.drop_column('entreprise_contact', 'date') + op.add_column('entreprise_contact', sa.Column('poste', sa.Text(), nullable=True)) + op.add_column('entreprise_contact', sa.Column('service', sa.Text(), nullable=True)) op.drop_column('entreprise_contact', 'description') - op.drop_column('entreprise_contact', 'type_contact') op.drop_column('entreprise_contact', 'enseignant') - op.drop_column('entreprise_contact', 'entreprise_corresp_id') + op.drop_column('entreprise_contact', 'date') + op.drop_column('entreprise_contact', 'type_contact') op.drop_column('entreprise_contact', 'etudid') + op.drop_column('entreprise_contact', 'entreprise_corresp_id') op.add_column('entreprises', sa.Column('siret', sa.Text(), nullable=True)) op.drop_index('ix_entreprises_dept_id', table_name='entreprises') op.drop_constraint('entreprises_dept_id_fkey', 'entreprises', type_='foreignkey') - op.drop_column('entreprises', 'localisation') - op.drop_column('entreprises', 'contact_origine') op.drop_column('entreprises', 'qualite_relation') - op.drop_column('entreprises', 'secteur') - op.drop_column('entreprises', 'plus10salaries') - op.drop_column('entreprises', 'dept_id') - op.drop_column('entreprises', 'privee') - op.drop_column('entreprises', 'date_creation') op.drop_column('entreprises', 'note') + op.drop_column('entreprises', 'contact_origine') + op.drop_column('entreprises', 'plus10salaries') + op.drop_column('entreprises', 'privee') + op.drop_column('entreprises', 'secteur') + op.drop_column('entreprises', 'date_creation') + op.drop_column('entreprises', 'dept_id') + op.drop_column('entreprises', 'localisation') # ### end Alembic commands ### + def downgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.add_column('entreprises', sa.Column('note', sa.TEXT(), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('date_creation', postgresql.TIMESTAMP(timezone=True), server_default=sa.text('now()'), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('privee', sa.TEXT(), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('dept_id', sa.INTEGER(), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('plus10salaries', sa.BOOLEAN(), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('secteur', sa.TEXT(), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('qualite_relation', sa.INTEGER(), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('contact_origine', sa.TEXT(), autoincrement=False, nullable=True)) op.add_column('entreprises', sa.Column('localisation', sa.TEXT(), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('dept_id', sa.INTEGER(), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('date_creation', postgresql.TIMESTAMP(timezone=True), server_default=sa.text('now()'), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('secteur', sa.TEXT(), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('privee', sa.TEXT(), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('plus10salaries', sa.BOOLEAN(), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('contact_origine', sa.TEXT(), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('note', sa.TEXT(), autoincrement=False, nullable=True)) + op.add_column('entreprises', sa.Column('qualite_relation', sa.INTEGER(), autoincrement=False, nullable=True)) op.create_foreign_key('entreprises_dept_id_fkey', 'entreprises', 'departement', ['dept_id'], ['id']) op.create_index('ix_entreprises_dept_id', 'entreprises', ['dept_id'], unique=False) op.drop_column('entreprises', 'siret') - op.add_column('entreprise_contact', sa.Column('etudid', sa.INTEGER(), autoincrement=False, nullable=True)) op.add_column('entreprise_contact', sa.Column('entreprise_corresp_id', sa.INTEGER(), autoincrement=False, nullable=True)) - op.add_column('entreprise_contact', sa.Column('enseignant', sa.TEXT(), autoincrement=False, nullable=True)) + op.add_column('entreprise_contact', sa.Column('etudid', sa.INTEGER(), autoincrement=False, nullable=True)) op.add_column('entreprise_contact', sa.Column('type_contact', sa.TEXT(), autoincrement=False, nullable=True)) - op.add_column('entreprise_contact', sa.Column('description', sa.TEXT(), autoincrement=False, nullable=True)) op.add_column('entreprise_contact', sa.Column('date', postgresql.TIMESTAMP(timezone=True), autoincrement=False, nullable=True)) + op.add_column('entreprise_contact', sa.Column('enseignant', sa.TEXT(), autoincrement=False, nullable=True)) + op.add_column('entreprise_contact', sa.Column('description', sa.TEXT(), autoincrement=False, nullable=True)) op.create_table('entreprise_correspondant', sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False), sa.Column('entreprise_id', sa.INTEGER(), autoincrement=False, nullable=True), @@ -116,12 +130,15 @@ def downgrade(): sa.PrimaryKeyConstraint('id', name='entreprise_correspondant_pkey') ) op.create_foreign_key('entreprise_contact_entreprise_corresp_id_fkey', 'entreprise_contact', 'entreprise_correspondant', ['entreprise_corresp_id'], ['id']) + op.drop_column('entreprise_contact', 'service') + op.drop_column('entreprise_contact', 'poste') op.drop_column('entreprise_contact', 'mail') op.drop_column('entreprise_contact', 'telephone') op.drop_column('entreprise_contact', 'prenom') op.drop_column('entreprise_contact', 'nom') - + + op.drop_table('entreprise_envoi_offre') op.drop_table('entreprise_offre') - op.drop_table('entreprise_history') + op.drop_table('entreprise_etudiant') op.drop_table('entreprise_log') - # ### end Alembic commands ### \ No newline at end of file + # ### end Alembic commands ### From 5024658a87ae38fc5202afc90e6edb9dde393aed Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Fri, 24 Dec 2021 10:46:36 +0100 Subject: [PATCH 06/20] ajout colonne date_envoi --- app/entreprises/models.py | 3 ++- .../f3b62d64efa3_creation_tables_relations_entreprises.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/entreprises/models.py b/app/entreprises/models.py index b4ac1a4b3..ec963be20 100644 --- a/app/entreprises/models.py +++ b/app/entreprises/models.py @@ -57,4 +57,5 @@ class EntrepriseEnvoiOffre(db.Model): __tablename__ = "entreprise_envoi_offre" id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey("user.id")) - offre_id = db.Column(db.Integer, db.ForeignKey("entreprise_offre.id")) \ No newline at end of file + offre_id = db.Column(db.Integer, db.ForeignKey("entreprise_offre.id")) + date_envoi = db.Column(db.DateTime(timezone=True), server_default=db.func.now()) \ No newline at end of file diff --git a/migrations/versions/f3b62d64efa3_creation_tables_relations_entreprises.py b/migrations/versions/f3b62d64efa3_creation_tables_relations_entreprises.py index cc524777b..7d629e280 100644 --- a/migrations/versions/f3b62d64efa3_creation_tables_relations_entreprises.py +++ b/migrations/versions/f3b62d64efa3_creation_tables_relations_entreprises.py @@ -57,6 +57,7 @@ def upgrade(): sa.Column('id', sa.Integer(), nullable=False), sa.Column('user_id', sa.Integer(), nullable=True), sa.Column('offre_id', sa.Integer(), nullable=True), + sa.Column('date_envoi', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True), sa.ForeignKeyConstraint(['offre_id'], ['entreprise_offre.id'], ), sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), sa.PrimaryKeyConstraint('id') From 0beea0dfc692a36abbdc6fd8f2ec2cf22f31e894 Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Fri, 24 Dec 2021 10:59:02 +0100 Subject: [PATCH 07/20] separation script pour chaque template html de formulaire --- app/entreprises/routes.py | 6 +- .../entreprises/ajout_entreprise.html | 56 ++++++++++++++++++ .../entreprises/ajout_historique.html | 31 ++++++++++ .../entreprises/envoi_offre_form.html | 31 ++++++++++ app/templates/entreprises/form.html | 57 ------------------- 5 files changed, 121 insertions(+), 60 deletions(-) create mode 100644 app/templates/entreprises/ajout_entreprise.html create mode 100644 app/templates/entreprises/ajout_historique.html create mode 100644 app/templates/entreprises/envoi_offre_form.html diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index 681f12425..4808cbebe 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -88,7 +88,7 @@ def add_entreprise(): db.session.commit() flash("L'entreprise a été ajouté à la liste.") return redirect(url_for("entreprises.index")) - return render_template("entreprises/form.html", title=("Ajout entreprise + contact"), form=form) + return render_template("entreprises/ajout_entreprise.html", title=("Ajout entreprise + contact"), form=form) @bp.route("/edit_entreprise/", methods=["GET", "POST"]) def edit_entreprise(id): @@ -331,14 +331,14 @@ def add_historique(id): db.session.commit() flash("L'étudiant a été ajouté sur la fiche entreprise.") return redirect(url_for("entreprises.fiche_entreprise", id=entreprise.id)) - return render_template("entreprises/form.html", title=("Ajout historique"), form=form) + return render_template("entreprises/ajout_historique.html", title=("Ajout historique"), form=form) @bp.route("/envoyer_offre/", methods=["GET", "POST"]) def envoyer_offre(id): form = EnvoiOffreForm() if form.validate_on_submit(): print("tmp") # faire l'envoie du mail - return render_template("entreprises/form.html", title=("Envoyer une offre"), form=form) + return render_template("entreprises/envoi_offre_form.html", title=("Envoyer une offre"), form=form) @bp.route("/etudiants") def json_etudiants(): diff --git a/app/templates/entreprises/ajout_entreprise.html b/app/templates/entreprises/ajout_entreprise.html new file mode 100644 index 000000000..76a9619e4 --- /dev/null +++ b/app/templates/entreprises/ajout_entreprise.html @@ -0,0 +1,56 @@ +{% extends 'base.html' %} +{% import 'bootstrap/wtf.html' as wtf %} + +{% block styles %} +{{super()}} + + +{% endblock %} + +{% block app_content %} +

    {{ title }}

    +
    +
    +
    + {{ wtf.quick_form(form, novalidate=True) }} +
    +
    + +{% endblock %} \ No newline at end of file diff --git a/app/templates/entreprises/ajout_historique.html b/app/templates/entreprises/ajout_historique.html new file mode 100644 index 000000000..f4da2661b --- /dev/null +++ b/app/templates/entreprises/ajout_historique.html @@ -0,0 +1,31 @@ +{% extends 'base.html' %} +{% import 'bootstrap/wtf.html' as wtf %} + +{% block styles %} +{{super()}} + + +{% endblock %} + +{% block app_content %} +

    {{ title }}

    +
    +
    +
    + {{ wtf.quick_form(form, novalidate=True) }} +
    +
    + +{% endblock %} \ No newline at end of file diff --git a/app/templates/entreprises/envoi_offre_form.html b/app/templates/entreprises/envoi_offre_form.html new file mode 100644 index 000000000..c9db2c6c1 --- /dev/null +++ b/app/templates/entreprises/envoi_offre_form.html @@ -0,0 +1,31 @@ +{% extends 'base.html' %} +{% import 'bootstrap/wtf.html' as wtf %} + +{% block styles %} +{{super()}} + + +{% endblock %} + +{% block app_content %} +

    {{ title }}

    +
    +
    +
    + {{ wtf.quick_form(form, novalidate=True) }} +
    +
    + +{% endblock %} \ No newline at end of file diff --git a/app/templates/entreprises/form.html b/app/templates/entreprises/form.html index 25cb579dd..26add23e1 100644 --- a/app/templates/entreprises/form.html +++ b/app/templates/entreprises/form.html @@ -15,61 +15,4 @@ {{ wtf.quick_form(form, novalidate=True) }} - {% endblock %} \ No newline at end of file From 9477106e9a4547c2bd5a332028d8deb4bcd678be Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Fri, 24 Dec 2021 12:12:41 +0100 Subject: [PATCH 08/20] =?UTF-8?q?empeche=20les=20doublons=20sur=20contact?= =?UTF-8?q?=20dans=20une=20m=C3=AAme=20entreprise?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/entreprises/forms.py | 23 +++++++++++++++++-- app/entreprises/routes.py | 2 +- .../entreprises/ajout_entreprise.html | 3 +++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/app/entreprises/forms.py b/app/entreprises/forms.py index f7fd62816..d2f3762b6 100644 --- a/app/entreprises/forms.py +++ b/app/entreprises/forms.py @@ -3,10 +3,10 @@ from markupsafe import Markup from flask.app import Flask import requests, re from flask_wtf import FlaskForm -from wtforms import StringField, SubmitField, TextAreaField, SelectField, FileField +from wtforms import StringField, SubmitField, TextAreaField, SelectField, FileField, HiddenField from wtforms.fields.html5 import EmailField, DateField from wtforms.validators import ValidationError, DataRequired, Email -from app.entreprises.models import Entreprise +from app.entreprises.models import Entreprise, EntrepriseContact from app.models import Identite from app.auth.models import User from app.scodoc import sco_etud @@ -71,8 +71,27 @@ class ContactCreationForm(FlaskForm): prenom = StringField("Prénom", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) telephone = StringField("Téléphone", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) mail = EmailField("Mail", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE), Email(message="Adresse e-mail invalide")]) + hidden_entreprise_id = HiddenField() submit = SubmitField("Envoyer") + def validate(self): + rv = FlaskForm.validate(self) + if not rv: + return False + + contact = EntrepriseContact.query.filter_by( + entreprise_id = self.hidden_entreprise_id.data, + nom = self.nom.data, + prenom = self.prenom.data + ).first() + + if contact is not None: + self.nom.errors.append("Ce contact existe déjà (même nom et prénom)") + self.prenom.errors.append("") + return False + + return True + class ContactModificationForm(FlaskForm): nom = StringField("Nom", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) prenom = StringField("Prénom", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index 4808cbebe..1791199e5 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -238,7 +238,7 @@ def delete_offre(id): @bp.route("/add_contact/", methods=["GET", "POST"]) def add_contact(id): entreprise = Entreprise.query.filter_by(id=id).first_or_404() - form = ContactCreationForm() + form = ContactCreationForm(hidden_entreprise_id=entreprise.id) if form.validate_on_submit(): contact = EntrepriseContact( entreprise_id=entreprise.id, diff --git a/app/templates/entreprises/ajout_entreprise.html b/app/templates/entreprises/ajout_entreprise.html index 76a9619e4..6b0ba311e 100644 --- a/app/templates/entreprises/ajout_entreprise.html +++ b/app/templates/entreprises/ajout_entreprise.html @@ -12,6 +12,9 @@
    +

    + Les champs s'autocomplète selon le SIRET +

    {{ wtf.quick_form(form, novalidate=True) }}
    From 178016b682c3767754454f0f44f02b4b78cb6e57 Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Fri, 24 Dec 2021 16:07:36 +0100 Subject: [PATCH 09/20] =?UTF-8?q?ajout=20page=20offres,=20insertion=20en?= =?UTF-8?q?=20base=20des=20diff=C3=A9rents=20objets,=20enrichissement=20de?= =?UTF-8?q?s=20champs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/entreprises/forms.py | 4 +++- app/entreprises/routes.py | 32 +++++++++++++++++++++---- app/templates/entreprises/contacts.html | 1 - app/templates/entreprises/offres.html | 28 ++++++++++++++++++++++ 4 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 app/templates/entreprises/offres.html diff --git a/app/entreprises/forms.py b/app/entreprises/forms.py index d2f3762b6..502db347d 100644 --- a/app/entreprises/forms.py +++ b/app/entreprises/forms.py @@ -67,11 +67,13 @@ class OffreModificationForm(FlaskForm): submit = SubmitField("Modifier") class ContactCreationForm(FlaskForm): + hidden_entreprise_id = HiddenField() nom = StringField("Nom", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) prenom = StringField("Prénom", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) telephone = StringField("Téléphone", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) mail = EmailField("Mail", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE), Email(message="Adresse e-mail invalide")]) - hidden_entreprise_id = HiddenField() + poste = StringField("Poste", validators=[]) + service = StringField("Service", validators=[]) submit = SubmitField("Envoyer") def validate(self): diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index 1791199e5..7570c806d 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -21,7 +21,8 @@ from app.entreprises.models import ( EntrepriseOffre, EntrepriseContact, EntrepriseLog, - EntrepriseEtudiant + EntrepriseEtudiant, + EntrepriseEnvoiOffre ) from app.models import ( Identite @@ -52,10 +53,16 @@ def fiche_entreprise(id): contacts = entreprise.contacts logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).filter_by(object=id).limit(LOGS_LEN).all() historique = db.session.query(EntrepriseEtudiant, Identite).order_by(EntrepriseEtudiant.date_debut.desc()).\ - filter_by(entreprise_id=id).\ + filter(EntrepriseEtudiant.entreprise_id == id).\ join(Identite, Identite.id == EntrepriseEtudiant.etudid).all() return render_template("entreprises/fiche_entreprise.html", title=("Fiche entreprise"), entreprise=entreprise, contacts=contacts, offres=offres, logs=logs, historique=historique) +@bp.route("/offres", methods=["GET"]) +def offres(): + offres_recus = db.session.query(EntrepriseEnvoiOffre, EntrepriseOffre).filter(EntrepriseEnvoiOffre.user_id == current_user.id).\ + join(EntrepriseOffre, EntrepriseOffre.id == EntrepriseEnvoiOffre.offre_id).all() + return render_template("entreprises/offres.html", title=("Offres"), offres_recus=offres_recus) + @bp.route("/add_entreprise", methods=["GET", "POST"]) def add_entreprise(): form = EntrepriseCreationForm() @@ -245,7 +252,9 @@ def add_contact(id): nom=form.nom.data.strip(), prenom=form.prenom.data.strip(), telephone=form.telephone.data.strip(), - mail=form.mail.data.strip() + mail=form.mail.data.strip(), + poste=form.poste.data.strip(), + service=form.service.data.strip() ) log = EntrepriseLog( authenticated_user = current_user.user_name, @@ -268,6 +277,8 @@ def edit_contact(id): contact.prenom = form.prenom.data.strip() contact.telephone = form.telephone.data.strip() contact.mail = form.mail.data.strip() + contact.poste = form.poste.data.strip() + contact.service = form.service.data.strip() log = EntrepriseLog( authenticated_user = current_user.user_name, object = contact.entreprise_id, @@ -282,6 +293,8 @@ def edit_contact(id): form.prenom.data = contact.prenom form.telephone.data = contact.telephone form.mail.data = contact.mail + form.poste.data = contact.poste + form.service.data = contact.service return render_template("entreprises/form.html", title=("Modification contact"), form=form) @bp.route("/delete_contact/", methods=["GET", "POST"]) @@ -335,9 +348,20 @@ def add_historique(id): @bp.route("/envoyer_offre/", methods=["GET", "POST"]) def envoyer_offre(id): + offre = EntrepriseOffre.query.filter_by(id=id).first_or_404() form = EnvoiOffreForm() if form.validate_on_submit(): - print("tmp") # faire l'envoie du mail + responsable_data = form.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( + user_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", id=offre.entreprise_id)) return render_template("entreprises/envoi_offre_form.html", title=("Envoyer une offre"), form=form) @bp.route("/etudiants") diff --git a/app/templates/entreprises/contacts.html b/app/templates/entreprises/contacts.html index 7f1433334..fdf2a747b 100644 --- a/app/templates/entreprises/contacts.html +++ b/app/templates/entreprises/contacts.html @@ -36,7 +36,6 @@
    {% else %}
    Aucun contact présent dans la base
    -
    {% endif %} diff --git a/app/templates/entreprises/offres.html b/app/templates/entreprises/offres.html new file mode 100644 index 000000000..717364b9b --- /dev/null +++ b/app/templates/entreprises/offres.html @@ -0,0 +1,28 @@ +{% extends 'base.html' %} + +{% block app_content %} +
    +

    {{ title }}

    + {% if offres_recus %} +
    +
    + {% for offre in offres_recus %} +
    +

    + Date envoi : {{ offre[0].date_envoi.strftime('%d/%m/%Y %H:%M') }}
    + Intitulé : {{ offre[1].intitule }}
    + Description : {{ offre[1].description }}
    + Type de l'offre : {{ offre[1].type_offre }}
    + Missions : {{ offre[1].missions }}
    + Durée : {{ offre[1].duree }}
    +

    +
    + {% endfor %} +
    +
    + {% else %} +
    Aucune offre reçue
    +
    + {% endif %} +
    +{% endblock %} \ No newline at end of file From 2a6d63cf03db2002d849e1527607f4940feffe99 Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Fri, 24 Dec 2021 18:10:19 +0100 Subject: [PATCH 10/20] export liste entreprises --- app/entreprises/models.py | 9 +++++++ app/entreprises/routes.py | 28 ++++++++++++++++++---- app/templates/entreprises/entreprises.html | 7 +++++- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/app/entreprises/models.py b/app/entreprises/models.py index ec963be20..d88a88127 100644 --- a/app/entreprises/models.py +++ b/app/entreprises/models.py @@ -12,6 +12,15 @@ class Entreprise(db.Model): contacts = db.relationship('EntrepriseContact', backref='entreprise', lazy='dynamic', cascade="all, delete-orphan") offres = db.relationship('EntrepriseOffre', backref='entreprise', lazy='dynamic', cascade="all, delete-orphan") + def to_dict(self): + return { + "siret": self.siret, + "nom": self.nom, + "adresse": self.adresse, + "codepostal": self.codepostal, + "pays": self.pays + } + class EntrepriseContact(db.Model): __tablename__ = "entreprise_contact" id = db.Column(db.Integer, primary_key=True) diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index 7570c806d..118e7e032 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -1,9 +1,10 @@ -from flask import render_template, redirect, url_for, request, flash +from flask import render_template, redirect, url_for, request, flash, send_file from flask.json import jsonify from flask_login import current_user from app.decorators import permission_required -from app.entreprises import LOGS_LEN + from app.scodoc.sco_permissions import Permission +from app.entreprises import LOGS_LEN from app.entreprises.forms import ( EntrepriseCreationForm, EntrepriseModificationForm, @@ -30,7 +31,8 @@ from app.models import ( from app.auth.models import User from app.scodoc.sco_find_etud import search_etud_by_name from app import db -from app.scodoc import sco_etud +from app.scodoc import sco_etud, sco_excel +import app.scodoc.sco_utils as scu from sqlalchemy import text @bp.route("/", methods=["GET"]) @@ -402,4 +404,22 @@ def json_responsables(): } list.append(content) content = {} - return jsonify(results=list) \ No newline at end of file + return jsonify(results=list) + +@bp.route("/export_entreprises") +def export_entreprises(): + entreprises = Entreprise.query.all() + keys=[ + "siret", + "nom", + "adresse", + "ville", + "codepostal", + "pays" + ] + titles = keys[:] + L = [[entreprise.to_dict().get(k, "") for k in keys] for entreprise in entreprises] + title = "entreprises" + xlsx = sco_excel.excel_simple_table(titles=titles, lines=L, sheet_name=title) + filename = title + return scu.send_file(xlsx, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE) \ No newline at end of file diff --git a/app/templates/entreprises/entreprises.html b/app/templates/entreprises/entreprises.html index a33dd7e77..62d1fc11a 100644 --- a/app/templates/entreprises/entreprises.html +++ b/app/templates/entreprises/entreprises.html @@ -53,6 +53,11 @@
    {% endif %} - Ajouter une entreprise +
    + Ajouter une entreprise + {% if entreprises %} + Exporter la liste des entreprises + {% endif %} +
    {% endblock %} \ No newline at end of file From 5684f57ca5c0388ed4d7b580a460d66448a5af18 Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Mon, 27 Dec 2021 11:48:58 +0100 Subject: [PATCH 11/20] export liste contacts --- app/entreprises/forms.py | 29 +++++---- app/entreprises/models.py | 17 ++++- app/entreprises/routes.py | 64 +++++++++++++------ app/templates/entreprises/contacts.html | 6 +- app/templates/entreprises/entreprises.html | 1 - ..._creation_table_relations_entreprrises.py} | 4 +- 6 files changed, 83 insertions(+), 38 deletions(-) rename migrations/versions/{f3b62d64efa3_creation_tables_relations_entreprises.py => 2dfafee725ae_creation_table_relations_entreprrises.py} (99%) diff --git a/app/entreprises/forms.py b/app/entreprises/forms.py index 502db347d..1965c9cba 100644 --- a/app/entreprises/forms.py +++ b/app/entreprises/forms.py @@ -1,8 +1,7 @@ from flask import flash -from markupsafe import Markup -from flask.app import Flask -import requests, re from flask_wtf import FlaskForm +from markupsafe import Markup +import requests, re from wtforms import StringField, SubmitField, TextAreaField, SelectField, FileField, HiddenField from wtforms.fields.html5 import EmailField, DateField from wtforms.validators import ValidationError, DataRequired, Email @@ -20,13 +19,15 @@ class EntrepriseCreationForm(FlaskForm): adresse = StringField("Adresse de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) codepostal = StringField("Code postal de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) ville = StringField("Ville de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) - pays = StringField("Pays de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) + pays = StringField("Pays de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)], render_kw={"style": "margin-bottom: 50px;"}) nom_contact = StringField("Nom du contact", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) prenom_contact = StringField("Prénom du contact", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) telephone = StringField("Téléphone du contact", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) mail = EmailField("Mail du contact", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE), Email(message="Adresse e-mail invalide")]) - submit = SubmitField("Envoyer") + poste = StringField("Poste du contact", validators=[]) + service = StringField("Service du contact", validators=[]) + submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"}) def validate_siret(self, siret): siret = siret.data.strip() @@ -47,7 +48,7 @@ class EntrepriseModificationForm(FlaskForm): codepostal = StringField("Code postal", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) ville = StringField("Ville", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) pays = StringField("Pays", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) - submit = SubmitField("Modifier") + submit = SubmitField("Modifier", render_kw={"style": "margin-bottom: 10px;"}) class OffreCreationForm(FlaskForm): intitule = StringField("Intitulé", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) @@ -56,7 +57,7 @@ class OffreCreationForm(FlaskForm): missions = TextAreaField("Missions", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) duree = StringField("Durée", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) ficher = FileField("Fichier", validators=[]) - submit = SubmitField("Envoyer") + submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"}) class OffreModificationForm(FlaskForm): intitule = StringField("Intitulé", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) @@ -64,7 +65,7 @@ class OffreModificationForm(FlaskForm): type_offre = SelectField("Type de l'offre", choices=[('Stage'), ('Alternance')], validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) missions = TextAreaField("Missions", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) duree = StringField("Durée", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) - submit = SubmitField("Modifier") + submit = SubmitField("Modifier", render_kw={"style": "margin-bottom: 10px;"}) class ContactCreationForm(FlaskForm): hidden_entreprise_id = HiddenField() @@ -74,7 +75,7 @@ class ContactCreationForm(FlaskForm): mail = EmailField("Mail", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE), Email(message="Adresse e-mail invalide")]) poste = StringField("Poste", validators=[]) service = StringField("Service", validators=[]) - submit = SubmitField("Envoyer") + submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"}) def validate(self): rv = FlaskForm.validate(self) @@ -99,14 +100,16 @@ class ContactModificationForm(FlaskForm): prenom = StringField("Prénom", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) telephone = StringField("Téléphone", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) mail = EmailField("Mail", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE), Email(message="Adresse e-mail invalide")]) - submit = SubmitField("Modifier") + poste = StringField("Poste", validators=[]) + service = StringField("Service", validators=[]) + submit = SubmitField("Modifier", render_kw={"style": "margin-bottom: 10px;"}) class HistoriqueCreationForm(FlaskForm): etudiant = StringField("Étudiant", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)], render_kw={"placeholder": "Tapez le nom de l'étudiant puis selectionnez"}) type_offre = SelectField("Type de l'offre", choices=[('Stage'), ('Alternance')], validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) date_debut = DateField("Date début", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) date_fin = DateField("Date fin", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) - submit = SubmitField("Envoyer") + submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"}) def validate(self): rv = FlaskForm.validate(self) @@ -128,7 +131,7 @@ class HistoriqueCreationForm(FlaskForm): class EnvoiOffreForm(FlaskForm): responsable = StringField("Responsable de formation", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) - submit = SubmitField("Envoyer") + submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"}) def validate_responsable(self, responsable): responsable_data = responsable.data.upper().strip() @@ -138,4 +141,4 @@ class EnvoiOffreForm(FlaskForm): raise ValidationError("Champ incorrect (selectionnez dans la liste)") class SuppressionConfirmationForm(FlaskForm): - submit = SubmitField("Supprimer") \ No newline at end of file + submit = SubmitField("Supprimer", render_kw={"style": "margin-bottom: 10px;"}) \ No newline at end of file diff --git a/app/entreprises/models.py b/app/entreprises/models.py index d88a88127..f31c11af8 100644 --- a/app/entreprises/models.py +++ b/app/entreprises/models.py @@ -12,30 +12,41 @@ class Entreprise(db.Model): contacts = db.relationship('EntrepriseContact', backref='entreprise', lazy='dynamic', cascade="all, delete-orphan") offres = db.relationship('EntrepriseOffre', backref='entreprise', lazy='dynamic', cascade="all, delete-orphan") - def to_dict(self): + def to_dict_export(self): return { "siret": self.siret, "nom": self.nom, "adresse": self.adresse, "codepostal": self.codepostal, + "ville": self.ville, "pays": self.pays } class EntrepriseContact(db.Model): __tablename__ = "entreprise_contact" id = db.Column(db.Integer, primary_key=True) - entreprise_id = db.Column(db.Integer, db.ForeignKey("entreprises.id")) + entreprise_id = db.Column(db.Integer, db.ForeignKey("entreprises.id", ondelete="cascade")) nom = db.Column(db.Text) prenom = db.Column(db.Text) telephone = db.Column(db.Text) mail = db.Column(db.Text) poste = db.Column(db.Text) service = db.Column(db.Text) + + def to_dict_export(self): + return { + "nom": self.nom, + "prenom": self.prenom, + "telephone": self.telephone, + "mail": self.mail, + "poste": self.poste, + "service": self.service + } class EntrepriseOffre(db.Model): __tablename__ = "entreprise_offre" id = db.Column(db.Integer, primary_key=True) - entreprise_id = db.Column(db.Integer, db.ForeignKey("entreprises.id")) + entreprise_id = db.Column(db.Integer, db.ForeignKey("entreprises.id", ondelete="cascade")) date_ajout = db.Column(db.DateTime(timezone=True), server_default=db.func.now()) intitule = db.Column(db.Text) description = db.Column(db.Text) diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index 118e7e032..b85c9938f 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -1,9 +1,9 @@ -from flask import render_template, redirect, url_for, request, flash, send_file +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.scodoc.sco_permissions import Permission from app.entreprises import LOGS_LEN from app.entreprises.forms import ( EntrepriseCreationForm, @@ -30,9 +30,11 @@ from app.models import ( ) from app.auth.models import User from app.scodoc.sco_find_etud import search_etud_by_name -from app import db +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 @bp.route("/", methods=["GET"]) @@ -85,7 +87,9 @@ def add_entreprise(): nom=form.nom_contact.data.strip(), prenom=form.prenom_contact.data.strip(), telephone=form.telephone.data.strip(), - mail=form.mail.data.strip() + mail=form.mail.data.strip(), + poste=form.poste.data.strip(), + service=form.service.data.strip() ) db.session.add(contact) nom_entreprise = f"{entreprise.nom}" @@ -409,17 +413,41 @@ def json_responsables(): @bp.route("/export_entreprises") def export_entreprises(): entreprises = Entreprise.query.all() - keys=[ - "siret", - "nom", - "adresse", - "ville", - "codepostal", - "pays" - ] - titles = keys[:] - L = [[entreprise.to_dict().get(k, "") for k in keys] for entreprise in entreprises] - title = "entreprises" - xlsx = sco_excel.excel_simple_table(titles=titles, lines=L, sheet_name=title) - filename = title - return scu.send_file(xlsx, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE) \ No newline at end of file + if entreprises: + keys=[ + "siret", + "nom", + "adresse", + "ville", + "codepostal", + "pays" + ] + titles = keys[:] + L = [[entreprise.to_dict_export().get(k, "") for k in keys] for entreprise in entreprises] + title = "entreprises" + xlsx = sco_excel.excel_simple_table(titles=titles, lines=L, sheet_name=title) + filename = title + return scu.send_file(xlsx, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE) + else: + abort(404) + +@bp.route("/export_contacts") +def export_contacts(): + contacts = EntrepriseContact.query.all() + if contacts: + keys=[ + "nom", + "prenom", + "telephone", + "mail", + "poste", + "service" + ] + titles = keys[:] + L = [[contact.to_dict_export().get(k, "") for k in keys] for contact in contacts] + title = "contacts" + xlsx = sco_excel.excel_simple_table(titles=titles, lines=L, sheet_name=title) + filename = title + return scu.send_file(xlsx, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE) + else: + abort(404) \ No newline at end of file diff --git a/app/templates/entreprises/contacts.html b/app/templates/entreprises/contacts.html index fdf2a747b..87112710f 100644 --- a/app/templates/entreprises/contacts.html +++ b/app/templates/entreprises/contacts.html @@ -33,10 +33,14 @@
    {% endfor %}
    SIRET Nom
    {{ entreprise.siret }}{{ entreprise.nom }}{{ entreprise.nom }} {{ entreprise.adresse }} {{ entreprise.codepostal }} {{ entreprise.ville }}
    -
    {% else %}
    Aucun contact présent dans la base
    {% endif %} +
    + {% if contacts %} + Exporter la liste des contacts + {% endif %} +
    {% endblock %} \ No newline at end of file diff --git a/app/templates/entreprises/entreprises.html b/app/templates/entreprises/entreprises.html index 62d1fc11a..a52f75805 100644 --- a/app/templates/entreprises/entreprises.html +++ b/app/templates/entreprises/entreprises.html @@ -47,7 +47,6 @@ {% endfor %} -
    {% else %}
    Aucune entreprise présent dans la base

    diff --git a/migrations/versions/f3b62d64efa3_creation_tables_relations_entreprises.py b/migrations/versions/2dfafee725ae_creation_table_relations_entreprrises.py similarity index 99% rename from migrations/versions/f3b62d64efa3_creation_tables_relations_entreprises.py rename to migrations/versions/2dfafee725ae_creation_table_relations_entreprrises.py index 7d629e280..126147c27 100644 --- a/migrations/versions/f3b62d64efa3_creation_tables_relations_entreprises.py +++ b/migrations/versions/2dfafee725ae_creation_table_relations_entreprrises.py @@ -36,7 +36,7 @@ def upgrade(): sa.Column('date_fin', sa.Date(), nullable=True), sa.Column('formation_text', sa.Text(), nullable=True), sa.Column('formation_scodoc', sa.Integer(), nullable=True), - sa.ForeignKeyConstraint(['entreprise_id'], ['entreprises.id'], ), + sa.ForeignKeyConstraint(['entreprise_id'], ['entreprises.id'], ondelete='cascade'), sa.PrimaryKeyConstraint('id') ) @@ -49,7 +49,7 @@ def upgrade(): sa.Column('type_offre', sa.Text(), nullable=True), sa.Column('missions', sa.Text(), nullable=True), sa.Column('duree', sa.Text(), nullable=True), - sa.ForeignKeyConstraint(['entreprise_id'], ['entreprises.id'], ), + sa.ForeignKeyConstraint(['entreprise_id'], ['entreprises.id'], ondelete='cascade'), sa.PrimaryKeyConstraint('id') ) From a7ef5d81c528f21cb05b13ac3a4e5761b9393672 Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Mon, 27 Dec 2021 19:00:38 +0100 Subject: [PATCH 12/20] =?UTF-8?q?attacher=20un=20fichier=20(pdf,=20docx)?= =?UTF-8?q?=20=C3=A0=20une=20offre=20(stock=C3=A9s=20sur=20disque)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/entreprises/forms.py | 7 +-- app/entreprises/models.py | 1 + app/entreprises/routes.py | 45 ++++++++++++++----- app/templates/entreprises/_offre.html | 3 ++ app/templates/entreprises/entreprises.html | 2 +- ...e_creation_table_relations_entreprrises.py | 1 + 6 files changed, 43 insertions(+), 16 deletions(-) diff --git a/app/entreprises/forms.py b/app/entreprises/forms.py index 1965c9cba..1ce49cc02 100644 --- a/app/entreprises/forms.py +++ b/app/entreprises/forms.py @@ -2,8 +2,9 @@ from flask import flash from flask_wtf import FlaskForm from markupsafe import Markup import requests, re -from wtforms import StringField, SubmitField, TextAreaField, SelectField, FileField, HiddenField +from wtforms import StringField, SubmitField, TextAreaField, SelectField, HiddenField from wtforms.fields.html5 import EmailField, DateField +from flask_wtf.file import FileField, FileAllowed from wtforms.validators import ValidationError, DataRequired, Email from app.entreprises.models import Entreprise, EntrepriseContact from app.models import Identite @@ -14,7 +15,7 @@ from sqlalchemy import text DATA_REQUIRED_ERROR_MESSAGE = "Ce champ est requis" class EntrepriseCreationForm(FlaskForm): - siret = StringField("SIRET", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)], render_kw={"placeholder": "Numéro composé de 14 chiffres"}) + siret = StringField("SIRET", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)], render_kw={"placeholder": "Numéro composé de 14 chiffres", "maxlength": "14"}) nom_entreprise = StringField("Nom de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) adresse = StringField("Adresse de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) codepostal = StringField("Code postal de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) @@ -56,7 +57,7 @@ class OffreCreationForm(FlaskForm): type_offre = SelectField("Type de l'offre", choices=[('Stage'), ('Alternance')], validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) missions = TextAreaField("Missions", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) duree = StringField("Durée", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) - ficher = FileField("Fichier", validators=[]) + fichier = FileField("Fichier", validators=[FileAllowed(['pdf', 'docx'], 'Fichier .pdf ou .docx uniquement')]) submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"}) class OffreModificationForm(FlaskForm): diff --git a/app/entreprises/models.py b/app/entreprises/models.py index f31c11af8..3e2211e22 100644 --- a/app/entreprises/models.py +++ b/app/entreprises/models.py @@ -53,6 +53,7 @@ class EntrepriseOffre(db.Model): type_offre = db.Column(db.Text) missions = db.Column(db.Text) duree = db.Column(db.Text) + filename = db.Column(db.Text) class EntrepriseLog(db.Model): __tablename__ = "entreprise_log" diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index b85c9938f..db11ff33f 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -1,3 +1,6 @@ +import os +from config import Config + from flask import render_template, redirect, url_for, request, flash, send_file, abort from flask.json import jsonify from flask_login import current_user @@ -36,6 +39,7 @@ import app.scodoc.sco_utils as scu from app import db from sqlalchemy import text +from werkzeug.utils import secure_filename, send_from_directory @bp.route("/", methods=["GET"]) def index(): @@ -50,7 +54,7 @@ def contacts(): logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).limit(LOGS_LEN).all() return render_template("entreprises/contacts.html", title=("Contacts"), contacts=contacts, logs=logs) -@bp.route("/fiche_entreprise/", methods=["GET"]) +@bp.route("/fiche_entreprise/", methods=["GET"]) def fiche_entreprise(id): entreprise = Entreprise.query.filter_by(id=id).first_or_404() offres = entreprise.offres @@ -103,7 +107,7 @@ def add_entreprise(): return redirect(url_for("entreprises.index")) return render_template("entreprises/ajout_entreprise.html", title=("Ajout entreprise + contact"), form=form) -@bp.route("/edit_entreprise/", methods=["GET", "POST"]) +@bp.route("/edit_entreprise/", methods=["GET", "POST"]) def edit_entreprise(id): entreprise = Entreprise.query.filter_by(id=id).first_or_404() form = EntrepriseModificationForm() @@ -161,7 +165,7 @@ def edit_entreprise(id): form.pays.data = entreprise.pays return render_template("entreprises/form.html", title=("Modification entreprise"), form=form) -@bp.route("/delete_entreprise/", methods=["GET", "POST"]) +@bp.route("/delete_entreprise/", methods=["GET", "POST"]) def delete_entreprise(id): entreprise = Entreprise.query.filter_by(id=id).first_or_404() form = SuppressionConfirmationForm() @@ -178,7 +182,7 @@ def delete_entreprise(id): return redirect(url_for("entreprises.index")) return render_template("entreprises/delete_confirmation.html", title=("Supression entreprise"), form=form) -@bp.route("/add_offre/", methods=["GET", "POST"]) +@bp.route("/add_offre/", methods=["GET", "POST"]) def add_offre(id): entreprise = Entreprise.query.filter_by(id=id).first_or_404() form = OffreCreationForm() @@ -191,19 +195,29 @@ def add_offre(id): missions=form.missions.data.strip(), duree=form.duree.data.strip() ) + db.session.add(offre) + db.session.commit() + if form.fichier.data is not None: + db.session.refresh(offre) + path = os.path.join(Config.SCODOC_VAR_DIR, "entreprises", f"{entreprise.id}", f"{offre.id}") + os.makedirs(path) + file = form.fichier.data + filename = secure_filename(file.filename) + file.save(os.path.join(path, filename)) + offre.offre_filename = f"{filename}" + db.session.commit() log = EntrepriseLog( authenticated_user = current_user.user_name, object = entreprise.id, text = "Création d'une offre", ) db.session.add(log) - db.session.add(offre) db.session.commit() flash("L'offre a été ajouté à la fiche entreprise.") return redirect(url_for("entreprises.fiche_entreprise", id=entreprise.id)) return render_template("entreprises/form.html", title=("Ajout offre"), form=form) -@bp.route("/edit_offre/", methods=["GET", "POST"]) +@bp.route("/edit_offre/", methods=["GET", "POST"]) def edit_offre(id): offre = EntrepriseOffre.query.filter_by(id=id).first_or_404() form = OffreModificationForm() @@ -230,7 +244,7 @@ def edit_offre(id): form.duree.data = offre.duree return render_template("entreprises/form.html", title=("Modification offre"), form=form) -@bp.route("/delete_offre/", methods=["GET", "POST"]) +@bp.route("/delete_offre/", methods=["GET", "POST"]) def delete_offre(id): offre = EntrepriseOffre.query.filter_by(id=id).first_or_404() entreprise_id = offre.entreprise.id @@ -248,7 +262,7 @@ def delete_offre(id): return redirect(url_for("entreprises.fiche_entreprise", id=entreprise_id)) return render_template("entreprises/delete_confirmation.html", title=("Supression offre"), form=form) -@bp.route("/add_contact/", methods=["GET", "POST"]) +@bp.route("/add_contact/", methods=["GET", "POST"]) def add_contact(id): entreprise = Entreprise.query.filter_by(id=id).first_or_404() form = ContactCreationForm(hidden_entreprise_id=entreprise.id) @@ -274,7 +288,7 @@ def add_contact(id): return redirect(url_for("entreprises.fiche_entreprise", id=entreprise.id)) return render_template("entreprises/form.html", title=("Ajout contact"), form=form) -@bp.route("/edit_contact/", methods=["GET", "POST"]) +@bp.route("/edit_contact/", methods=["GET", "POST"]) def edit_contact(id): contact = EntrepriseContact.query.filter_by(id=id).first_or_404() form = ContactModificationForm() @@ -303,7 +317,7 @@ def edit_contact(id): form.service.data = contact.service return render_template("entreprises/form.html", title=("Modification contact"), form=form) -@bp.route("/delete_contact/", methods=["GET", "POST"]) +@bp.route("/delete_contact/", methods=["GET", "POST"]) def delete_contact(id): contact = EntrepriseContact.query.filter_by(id=id).first_or_404() entreprise_id = contact.entreprise.id @@ -326,7 +340,7 @@ def delete_contact(id): return redirect(url_for("entreprises.fiche_entreprise", id=entreprise_id)) return render_template("entreprises/delete_confirmation.html", title=("Supression contact"), form=form) -@bp.route("/add_historique/", methods=["GET", "POST"]) +@bp.route("/add_historique/", methods=["GET", "POST"]) def add_historique(id): entreprise = Entreprise.query.filter_by(id=id).first_or_404() form = HistoriqueCreationForm() @@ -352,7 +366,7 @@ def add_historique(id): return redirect(url_for("entreprises.fiche_entreprise", id=entreprise.id)) return render_template("entreprises/ajout_historique.html", title=("Ajout historique"), form=form) -@bp.route("/envoyer_offre/", methods=["GET", "POST"]) +@bp.route("/envoyer_offre/", methods=["GET", "POST"]) def envoyer_offre(id): offre = EntrepriseOffre.query.filter_by(id=id).first_or_404() form = EnvoiOffreForm() @@ -449,5 +463,12 @@ def export_contacts(): xlsx = sco_excel.excel_simple_table(titles=titles, lines=L, sheet_name=title) filename = title return scu.send_file(xlsx, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE) + else: + abort(404) + +@bp.route("/download_offre///") +def download_offre(entreprise_id, offre_id, filename): + if os.path.isfile(os.path.join(Config.SCODOC_VAR_DIR, "entreprises", f"{entreprise_id}", f"{offre_id}", f"{filename}")): + return send_file(os.path.join(Config.SCODOC_VAR_DIR, "entreprises", f"{entreprise_id}", f"{offre_id}", f"{filename}"), as_attachment=True) else: abort(404) \ No newline at end of file diff --git a/app/templates/entreprises/_offre.html b/app/templates/entreprises/_offre.html index e64f3c16c..581ad7afd 100644 --- a/app/templates/entreprises/_offre.html +++ b/app/templates/entreprises/_offre.html @@ -5,6 +5,9 @@ Type de l'offre : {{ offre.type_offre }}
    Missions : {{ offre.missions }}
    Durée : {{ offre.duree }}
    + {% if offre.offre_filename %} + Téléchargez le fichier de l'offre + {% endif %}

    diff --git a/app/templates/entreprises/entreprises.html b/app/templates/entreprises/entreprises.html index a52f75805..85854efb3 100644 --- a/app/templates/entreprises/entreprises.html +++ b/app/templates/entreprises/entreprises.html @@ -38,7 +38,7 @@ Action -
    {% endif %} -
    +
    Ajouter une entreprise {% if entreprises %} Exporter la liste des entreprises diff --git a/app/templates/entreprises/fiche_entreprise.html b/app/templates/entreprises/fiche_entreprise.html index b84980366..f3cc68269 100644 --- a/app/templates/entreprises/fiche_entreprise.html +++ b/app/templates/entreprises/fiche_entreprise.html @@ -55,7 +55,7 @@ {% if offres %}
    {% for offre in offres %} - Offre {{loop.index}} (ajouté le {{offre.date_ajout.strftime('%d/%m/%Y') }}) + Offre {{loop.index}} (ajouté le {{offre[0].date_ajout.strftime('%d/%m/%Y') }}) {% include 'entreprises/_offre.html' %} {% endfor %}
    diff --git a/migrations/versions/2dfafee725ae_creation_table_relations_entreprrises.py b/migrations/versions/2dfafee725ae_creation_table_relations_entreprrises.py index 3d4867570..126147c27 100644 --- a/migrations/versions/2dfafee725ae_creation_table_relations_entreprrises.py +++ b/migrations/versions/2dfafee725ae_creation_table_relations_entreprrises.py @@ -49,7 +49,6 @@ def upgrade(): sa.Column('type_offre', sa.Text(), nullable=True), sa.Column('missions', sa.Text(), nullable=True), sa.Column('duree', sa.Text(), nullable=True), - sa.Column('filename', sa.Text(), nullable=True), sa.ForeignKeyConstraint(['entreprise_id'], ['entreprises.id'], ondelete='cascade'), sa.PrimaryKeyConstraint('id') ) From 45a8b31cf1042b57765f480e428edfecea8f9123 Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Tue, 28 Dec 2021 21:26:36 +0100 Subject: [PATCH 15/20] correction --- app/entreprises/routes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index 99d1cabe2..862fe1785 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -525,7 +525,7 @@ def export_entreprises(): keys = ["siret", "nom", "adresse", "ville", "codepostal", "pays"] titles = keys[:] L = [ - [entreprise.to_dict_export().get(k, "") for k in keys] + [entreprise.to_dict().get(k, "") for k in keys] for entreprise in entreprises ] title = "entreprises" @@ -543,7 +543,7 @@ def export_contacts(): keys = ["nom", "prenom", "telephone", "mail", "poste", "service"] titles = keys[:] L = [ - [contact.to_dict_export().get(k, "") for k in keys] for contact in contacts + [contact.to_dict().get(k, "") for k in keys] for contact in contacts ] title = "contacts" xlsx = sco_excel.excel_simple_table(titles=titles, lines=L, sheet_name=title) From 6fd234ef8571c275070657990e7e989b1da52acf Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Wed, 29 Dec 2021 10:36:45 +0100 Subject: [PATCH 16/20] format code --- app/entreprises/routes.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index 862fe1785..50ea4de90 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -542,9 +542,7 @@ def export_contacts(): if contacts: keys = ["nom", "prenom", "telephone", "mail", "poste", "service"] titles = keys[:] - L = [ - [contact.to_dict().get(k, "") for k in keys] for contact in contacts - ] + L = [[contact.to_dict().get(k, "") for k in keys] for contact in contacts] title = "contacts" xlsx = sco_excel.excel_simple_table(titles=titles, lines=L, sheet_name=title) filename = title From 41b50e0c1c4266cabd96f1880e1868055349db11 Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Wed, 29 Dec 2021 10:54:05 +0100 Subject: [PATCH 17/20] remove print --- app/entreprises/routes.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index 50ea4de90..db42affe6 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -87,7 +87,6 @@ def fiche_entreprise(id): file = [os.path.basename(dir), os.path.basename(file)] files.append(file) offres_with_files.append([offre, files]) - print(offres_with_files) contacts = entreprise.contacts logs = ( EntrepriseLog.query.order_by(EntrepriseLog.date.desc()) From 065bcfe1a01e6a03046daad26b62aa21364f33e6 Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Wed, 29 Dec 2021 11:10:30 +0100 Subject: [PATCH 18/20] correction offres qui ne s'affichaient pas --- app/entreprises/routes.py | 9 ++++++--- app/templates/entreprises/ajout_entreprise.html | 6 ------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index db42affe6..12309d58a 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -75,18 +75,21 @@ def fiche_entreprise(id): offres = entreprise.offres offres_with_files = [] for offre in offres: + files = [] path = os.path.join( - Config.SCODOC_VAR_DIR, "entreprises", f"{entreprise.id}", f"{offre.id}" + Config.SCODOC_VAR_DIR, + "entreprises", + f"{offre.entreprise_id}", + f"{offre.id}", ) if os.path.exists(path): - files = [] 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_with_files.append([offre, files]) + offres_with_files.append([offre, files]) contacts = entreprise.contacts logs = ( EntrepriseLog.query.order_by(EntrepriseLog.date.desc()) diff --git a/app/templates/entreprises/ajout_entreprise.html b/app/templates/entreprises/ajout_entreprise.html index 6b0ba311e..4a70e83d5 100644 --- a/app/templates/entreprises/ajout_entreprise.html +++ b/app/templates/entreprises/ajout_entreprise.html @@ -1,12 +1,6 @@ {% extends 'base.html' %} {% import 'bootstrap/wtf.html' as wtf %} -{% block styles %} -{{super()}} - - -{% endblock %} - {% block app_content %}

    {{ title }}


    From 4d2d2f20fbee39671d7bb65732c7e951bb4d9537 Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Wed, 29 Dec 2021 11:26:41 +0100 Subject: [PATCH 19/20] update migration version --- app/entreprises/routes.py | 3 +- ...e_creation_table_relations_entreprrises.py | 330 ++++++++++++------ 2 files changed, 221 insertions(+), 112 deletions(-) diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index 12309d58a..590dd313c 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -34,14 +34,13 @@ from app.entreprises.models import ( ) from app.models import Identite from app.auth.models import User -from app.scodoc.sco_find_etud import search_etud_by_name 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 -from werkzeug.utils import secure_filename, send_from_directory +from werkzeug.utils import secure_filename @bp.route("/", methods=["GET"]) diff --git a/migrations/versions/2dfafee725ae_creation_table_relations_entreprrises.py b/migrations/versions/2dfafee725ae_creation_table_relations_entreprrises.py index 126147c27..05adc3566 100644 --- a/migrations/versions/2dfafee725ae_creation_table_relations_entreprrises.py +++ b/migrations/versions/2dfafee725ae_creation_table_relations_entreprrises.py @@ -10,136 +10,246 @@ import sqlalchemy as sa from sqlalchemy.dialects import postgresql # revision identifiers, used by Alembic. -revision = 'f3b62d64efa3' -down_revision = '91be8a06d423' +revision = "f3b62d64efa3" +down_revision = "91be8a06d423" branch_labels = None depends_on = None def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.create_table('entreprise_log', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('date', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True), - sa.Column('authenticated_user', sa.Text(), nullable=True), - sa.Column('object', sa.Integer(), nullable=True), - sa.Column('text', sa.Text(), nullable=True), - sa.PrimaryKeyConstraint('id') + op.create_table( + "entreprise_log", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column( + "date", + sa.DateTime(timezone=True), + server_default=sa.text("now()"), + nullable=True, + ), + sa.Column("authenticated_user", sa.Text(), nullable=True), + sa.Column("object", sa.Integer(), nullable=True), + sa.Column("text", sa.Text(), nullable=True), + sa.PrimaryKeyConstraint("id"), ) - op.create_table('entreprise_etudiant', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('entreprise_id', sa.Integer(), nullable=True), - sa.Column('etudid', sa.Integer(), nullable=True), - sa.Column('type_offre', sa.Text(), nullable=True), - sa.Column('date_debut', sa.Date(), nullable=True), - sa.Column('date_fin', sa.Date(), nullable=True), - sa.Column('formation_text', sa.Text(), nullable=True), - sa.Column('formation_scodoc', sa.Integer(), nullable=True), - sa.ForeignKeyConstraint(['entreprise_id'], ['entreprises.id'], ondelete='cascade'), - sa.PrimaryKeyConstraint('id') + op.create_table( + "entreprise_etudiant", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("entreprise_id", sa.Integer(), nullable=True), + sa.Column("etudid", sa.Integer(), nullable=True), + sa.Column("type_offre", sa.Text(), nullable=True), + sa.Column("date_debut", sa.Date(), nullable=True), + sa.Column("date_fin", sa.Date(), nullable=True), + sa.Column("formation_text", sa.Text(), nullable=True), + sa.Column("formation_scodoc", sa.Integer(), nullable=True), + sa.ForeignKeyConstraint( + ["entreprise_id"], ["entreprises.id"], ondelete="cascade" + ), + sa.PrimaryKeyConstraint("id"), ) - op.create_table('entreprise_offre', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('entreprise_id', sa.Integer(), nullable=True), - sa.Column('date_ajout', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True), - sa.Column('intitule', sa.Text(), nullable=True), - sa.Column('description', sa.Text(), nullable=True), - sa.Column('type_offre', sa.Text(), nullable=True), - sa.Column('missions', sa.Text(), nullable=True), - sa.Column('duree', sa.Text(), nullable=True), - sa.ForeignKeyConstraint(['entreprise_id'], ['entreprises.id'], ondelete='cascade'), - sa.PrimaryKeyConstraint('id') + op.create_table( + "entreprise_offre", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("entreprise_id", sa.Integer(), nullable=True), + sa.Column( + "date_ajout", + sa.DateTime(timezone=True), + server_default=sa.text("now()"), + nullable=True, + ), + sa.Column("intitule", sa.Text(), nullable=True), + sa.Column("description", sa.Text(), nullable=True), + sa.Column("type_offre", sa.Text(), nullable=True), + sa.Column("missions", sa.Text(), nullable=True), + sa.Column("duree", sa.Text(), nullable=True), + sa.ForeignKeyConstraint( + ["entreprise_id"], ["entreprises.id"], ondelete="cascade" + ), + sa.PrimaryKeyConstraint("id"), ) - op.create_table('entreprise_envoi_offre', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('user_id', sa.Integer(), nullable=True), - sa.Column('offre_id', sa.Integer(), nullable=True), - sa.Column('date_envoi', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True), - sa.ForeignKeyConstraint(['offre_id'], ['entreprise_offre.id'], ), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), - sa.PrimaryKeyConstraint('id') + op.create_table( + "entreprise_envoi_offre", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("sender_id", sa.Integer(), nullable=True), + sa.Column("receiver_id", sa.Integer(), nullable=True), + sa.Column("offre_id", sa.Integer(), nullable=True), + sa.Column( + "date_envoi", + sa.DateTime(timezone=True), + server_default=sa.text("now()"), + nullable=True, + ), + sa.ForeignKeyConstraint( + ["offre_id"], + ["entreprise_offre.id"], + ), + sa.ForeignKeyConstraint( + ["sender_id"], + ["user.id"], + ), + sa.ForeignKeyConstraint( + ["receiver_id"], + ["user.id"], + ), + sa.PrimaryKeyConstraint("id"), ) - op.drop_constraint('entreprise_contact_entreprise_corresp_id_fkey', 'entreprise_contact', type_='foreignkey') - op.drop_table('entreprise_correspondant') - op.add_column('entreprise_contact', sa.Column('nom', sa.Text(), nullable=True)) - op.add_column('entreprise_contact', sa.Column('prenom', sa.Text(), nullable=True)) - op.add_column('entreprise_contact', sa.Column('telephone', sa.Text(), nullable=True)) - op.add_column('entreprise_contact', sa.Column('mail', sa.Text(), nullable=True)) - op.add_column('entreprise_contact', sa.Column('poste', sa.Text(), nullable=True)) - op.add_column('entreprise_contact', sa.Column('service', sa.Text(), nullable=True)) - op.drop_column('entreprise_contact', 'description') - op.drop_column('entreprise_contact', 'enseignant') - op.drop_column('entreprise_contact', 'date') - op.drop_column('entreprise_contact', 'type_contact') - op.drop_column('entreprise_contact', 'etudid') - op.drop_column('entreprise_contact', 'entreprise_corresp_id') + op.drop_constraint( + "entreprise_contact_entreprise_corresp_id_fkey", + "entreprise_contact", + type_="foreignkey", + ) + op.drop_table("entreprise_correspondant") + op.add_column("entreprise_contact", sa.Column("nom", sa.Text(), nullable=True)) + op.add_column("entreprise_contact", sa.Column("prenom", sa.Text(), nullable=True)) + op.add_column( + "entreprise_contact", sa.Column("telephone", sa.Text(), nullable=True) + ) + op.add_column("entreprise_contact", sa.Column("mail", sa.Text(), nullable=True)) + op.add_column("entreprise_contact", sa.Column("poste", sa.Text(), nullable=True)) + op.add_column("entreprise_contact", sa.Column("service", sa.Text(), nullable=True)) + op.drop_column("entreprise_contact", "description") + op.drop_column("entreprise_contact", "enseignant") + op.drop_column("entreprise_contact", "date") + op.drop_column("entreprise_contact", "type_contact") + op.drop_column("entreprise_contact", "etudid") + op.drop_column("entreprise_contact", "entreprise_corresp_id") - op.add_column('entreprises', sa.Column('siret', sa.Text(), nullable=True)) - op.drop_index('ix_entreprises_dept_id', table_name='entreprises') - op.drop_constraint('entreprises_dept_id_fkey', 'entreprises', type_='foreignkey') - op.drop_column('entreprises', 'qualite_relation') - op.drop_column('entreprises', 'note') - op.drop_column('entreprises', 'contact_origine') - op.drop_column('entreprises', 'plus10salaries') - op.drop_column('entreprises', 'privee') - op.drop_column('entreprises', 'secteur') - op.drop_column('entreprises', 'date_creation') - op.drop_column('entreprises', 'dept_id') - op.drop_column('entreprises', 'localisation') + op.add_column("entreprises", sa.Column("siret", sa.Text(), nullable=True)) + op.drop_index("ix_entreprises_dept_id", table_name="entreprises") + op.drop_constraint("entreprises_dept_id_fkey", "entreprises", type_="foreignkey") + op.drop_column("entreprises", "qualite_relation") + op.drop_column("entreprises", "note") + op.drop_column("entreprises", "contact_origine") + op.drop_column("entreprises", "plus10salaries") + op.drop_column("entreprises", "privee") + op.drop_column("entreprises", "secteur") + op.drop_column("entreprises", "date_creation") + op.drop_column("entreprises", "dept_id") + op.drop_column("entreprises", "localisation") # ### end Alembic commands ### def downgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.add_column('entreprises', sa.Column('localisation', sa.TEXT(), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('dept_id', sa.INTEGER(), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('date_creation', postgresql.TIMESTAMP(timezone=True), server_default=sa.text('now()'), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('secteur', sa.TEXT(), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('privee', sa.TEXT(), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('plus10salaries', sa.BOOLEAN(), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('contact_origine', sa.TEXT(), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('note', sa.TEXT(), autoincrement=False, nullable=True)) - op.add_column('entreprises', sa.Column('qualite_relation', sa.INTEGER(), autoincrement=False, nullable=True)) - op.create_foreign_key('entreprises_dept_id_fkey', 'entreprises', 'departement', ['dept_id'], ['id']) - op.create_index('ix_entreprises_dept_id', 'entreprises', ['dept_id'], unique=False) - op.drop_column('entreprises', 'siret') - op.add_column('entreprise_contact', sa.Column('entreprise_corresp_id', sa.INTEGER(), autoincrement=False, nullable=True)) - op.add_column('entreprise_contact', sa.Column('etudid', sa.INTEGER(), autoincrement=False, nullable=True)) - op.add_column('entreprise_contact', sa.Column('type_contact', sa.TEXT(), autoincrement=False, nullable=True)) - op.add_column('entreprise_contact', sa.Column('date', postgresql.TIMESTAMP(timezone=True), autoincrement=False, nullable=True)) - op.add_column('entreprise_contact', sa.Column('enseignant', sa.TEXT(), autoincrement=False, nullable=True)) - op.add_column('entreprise_contact', sa.Column('description', sa.TEXT(), autoincrement=False, nullable=True)) - op.create_table('entreprise_correspondant', - sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column('entreprise_id', sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column('nom', sa.TEXT(), autoincrement=False, nullable=True), - sa.Column('prenom', sa.TEXT(), autoincrement=False, nullable=True), - sa.Column('civilite', sa.TEXT(), autoincrement=False, nullable=True), - sa.Column('fonction', sa.TEXT(), autoincrement=False, nullable=True), - sa.Column('phone1', sa.TEXT(), autoincrement=False, nullable=True), - sa.Column('phone2', sa.TEXT(), autoincrement=False, nullable=True), - sa.Column('mobile', sa.TEXT(), autoincrement=False, nullable=True), - sa.Column('mail1', sa.TEXT(), autoincrement=False, nullable=True), - sa.Column('mail2', sa.TEXT(), autoincrement=False, nullable=True), - sa.Column('fax', sa.TEXT(), autoincrement=False, nullable=True), - sa.Column('note', sa.TEXT(), autoincrement=False, nullable=True), - sa.ForeignKeyConstraint(['entreprise_id'], ['entreprises.id'], name='entreprise_correspondant_entreprise_id_fkey'), - sa.PrimaryKeyConstraint('id', name='entreprise_correspondant_pkey') + op.add_column( + "entreprises", + sa.Column("localisation", sa.TEXT(), autoincrement=False, nullable=True), ) - op.create_foreign_key('entreprise_contact_entreprise_corresp_id_fkey', 'entreprise_contact', 'entreprise_correspondant', ['entreprise_corresp_id'], ['id']) - op.drop_column('entreprise_contact', 'service') - op.drop_column('entreprise_contact', 'poste') - op.drop_column('entreprise_contact', 'mail') - op.drop_column('entreprise_contact', 'telephone') - op.drop_column('entreprise_contact', 'prenom') - op.drop_column('entreprise_contact', 'nom') + op.add_column( + "entreprises", + sa.Column("dept_id", sa.INTEGER(), autoincrement=False, nullable=True), + ) + op.add_column( + "entreprises", + sa.Column( + "date_creation", + postgresql.TIMESTAMP(timezone=True), + server_default=sa.text("now()"), + autoincrement=False, + nullable=True, + ), + ) + op.add_column( + "entreprises", + sa.Column("secteur", sa.TEXT(), autoincrement=False, nullable=True), + ) + op.add_column( + "entreprises", + sa.Column("privee", sa.TEXT(), autoincrement=False, nullable=True), + ) + op.add_column( + "entreprises", + sa.Column("plus10salaries", sa.BOOLEAN(), autoincrement=False, nullable=True), + ) + op.add_column( + "entreprises", + sa.Column("contact_origine", sa.TEXT(), autoincrement=False, nullable=True), + ) + op.add_column( + "entreprises", sa.Column("note", sa.TEXT(), autoincrement=False, nullable=True) + ) + op.add_column( + "entreprises", + sa.Column("qualite_relation", sa.INTEGER(), autoincrement=False, nullable=True), + ) + op.create_foreign_key( + "entreprises_dept_id_fkey", "entreprises", "departement", ["dept_id"], ["id"] + ) + op.create_index("ix_entreprises_dept_id", "entreprises", ["dept_id"], unique=False) + op.drop_column("entreprises", "siret") + op.add_column( + "entreprise_contact", + sa.Column( + "entreprise_corresp_id", sa.INTEGER(), autoincrement=False, nullable=True + ), + ) + op.add_column( + "entreprise_contact", + sa.Column("etudid", sa.INTEGER(), autoincrement=False, nullable=True), + ) + op.add_column( + "entreprise_contact", + sa.Column("type_contact", sa.TEXT(), autoincrement=False, nullable=True), + ) + op.add_column( + "entreprise_contact", + sa.Column( + "date", + postgresql.TIMESTAMP(timezone=True), + autoincrement=False, + nullable=True, + ), + ) + op.add_column( + "entreprise_contact", + sa.Column("enseignant", sa.TEXT(), autoincrement=False, nullable=True), + ) + op.add_column( + "entreprise_contact", + sa.Column("description", sa.TEXT(), autoincrement=False, nullable=True), + ) + op.create_table( + "entreprise_correspondant", + sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("entreprise_id", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("nom", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("prenom", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("civilite", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("fonction", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("phone1", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("phone2", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("mobile", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("mail1", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("mail2", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("fax", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("note", sa.TEXT(), autoincrement=False, nullable=True), + sa.ForeignKeyConstraint( + ["entreprise_id"], + ["entreprises.id"], + name="entreprise_correspondant_entreprise_id_fkey", + ), + sa.PrimaryKeyConstraint("id", name="entreprise_correspondant_pkey"), + ) + op.create_foreign_key( + "entreprise_contact_entreprise_corresp_id_fkey", + "entreprise_contact", + "entreprise_correspondant", + ["entreprise_corresp_id"], + ["id"], + ) + op.drop_column("entreprise_contact", "service") + op.drop_column("entreprise_contact", "poste") + op.drop_column("entreprise_contact", "mail") + op.drop_column("entreprise_contact", "telephone") + op.drop_column("entreprise_contact", "prenom") + op.drop_column("entreprise_contact", "nom") - op.drop_table('entreprise_envoi_offre') - op.drop_table('entreprise_offre') - op.drop_table('entreprise_etudiant') - op.drop_table('entreprise_log') + op.drop_table("entreprise_envoi_offre") + op.drop_table("entreprise_offre") + op.drop_table("entreprise_etudiant") + op.drop_table("entreprise_log") # ### end Alembic commands ### From b26adbeef1a0557aee5126409b76ebdfbd48acce Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Wed, 29 Dec 2021 14:41:33 +0100 Subject: [PATCH 20/20] comment & function name --- app/models/etudiants.py | 5 +- app/models/formsemestre.py | 5 +- app/templates/entreprises/_contact.html | 1 + app/templates/entreprises/_offre.html | 1 + .../entreprises/ajout_entreprise.html | 1 + .../entreprises/ajout_historique.html | 1 + app/templates/entreprises/contacts.html | 1 + .../entreprises/delete_confirmation.html | 1 + app/templates/entreprises/entreprises.html | 1 + .../entreprises/envoi_offre_form.html | 1 + .../entreprises/fiche_entreprise.html | 130 +++++++++--------- app/templates/entreprises/form.html | 1 + app/templates/entreprises/offres.html | 1 + 13 files changed, 84 insertions(+), 66 deletions(-) diff --git a/app/models/etudiants.py b/app/models/etudiants.py index 0f81ad6bf..2dab949c4 100644 --- a/app/models/etudiants.py +++ b/app/models/etudiants.py @@ -108,10 +108,13 @@ class Identite(db.Model): return r[0] if r else None def inscription_courante_date(self, date_debut, date_fin): + """La première inscription à un formsemestre incluant la + période [date_debut, date_fin] + """ r = [ ins for ins in self.formsemestre_inscriptions - if ins.formsemestre.est_courant_date(date_debut, date_fin) + if ins.formsemestre.contient_periode(date_debut, date_fin) ] return r[0] if r else None diff --git a/app/models/formsemestre.py b/app/models/formsemestre.py index dc13c1cc8..28be41559 100644 --- a/app/models/formsemestre.py +++ b/app/models/formsemestre.py @@ -146,8 +146,9 @@ class FormSemestre(db.Model): today = datetime.date.today() return (self.date_debut <= today) and (today <= self.date_fin) - def est_courant_date(self, date_debut, date_fin) -> bool: - """Vrai si la date actuelle (now) est dans le semestre + def contient_periode(self, date_debut, date_fin) -> bool: + """Vrai si l'intervalle [date_debut, date_fin] est + inclus dans le semestre. (les dates de début et fin sont incluses) """ return (self.date_debut <= date_debut) and (date_fin <= self.date_fin) diff --git a/app/templates/entreprises/_contact.html b/app/templates/entreprises/_contact.html index eff3a8cb2..0eb8ebfee 100644 --- a/app/templates/entreprises/_contact.html +++ b/app/templates/entreprises/_contact.html @@ -1,3 +1,4 @@ +{# -*- mode: jinja-html -*- #}

    Nom : {{ contact.nom }}
    diff --git a/app/templates/entreprises/_offre.html b/app/templates/entreprises/_offre.html index fd21211d2..ea69110e9 100644 --- a/app/templates/entreprises/_offre.html +++ b/app/templates/entreprises/_offre.html @@ -1,3 +1,4 @@ +{# -*- mode: jinja-html -*- #}

    Intitulé : {{ offre[0].intitule }}
    diff --git a/app/templates/entreprises/ajout_entreprise.html b/app/templates/entreprises/ajout_entreprise.html index 4a70e83d5..15cf174fb 100644 --- a/app/templates/entreprises/ajout_entreprise.html +++ b/app/templates/entreprises/ajout_entreprise.html @@ -1,3 +1,4 @@ +{# -*- mode: jinja-html -*- #} {% extends 'base.html' %} {% import 'bootstrap/wtf.html' as wtf %} diff --git a/app/templates/entreprises/ajout_historique.html b/app/templates/entreprises/ajout_historique.html index f4da2661b..c0a546d59 100644 --- a/app/templates/entreprises/ajout_historique.html +++ b/app/templates/entreprises/ajout_historique.html @@ -1,3 +1,4 @@ +{# -*- mode: jinja-html -*- #} {% extends 'base.html' %} {% import 'bootstrap/wtf.html' as wtf %} diff --git a/app/templates/entreprises/contacts.html b/app/templates/entreprises/contacts.html index 87112710f..54d77bd55 100644 --- a/app/templates/entreprises/contacts.html +++ b/app/templates/entreprises/contacts.html @@ -1,3 +1,4 @@ +{# -*- mode: jinja-html -*- #} {% extends 'base.html' %} {% block app_content %} diff --git a/app/templates/entreprises/delete_confirmation.html b/app/templates/entreprises/delete_confirmation.html index 06b75b6ad..4894bca3e 100644 --- a/app/templates/entreprises/delete_confirmation.html +++ b/app/templates/entreprises/delete_confirmation.html @@ -1,3 +1,4 @@ +{# -*- mode: jinja-html -*- #} {% extends 'base.html' %} {% import 'bootstrap/wtf.html' as wtf %} diff --git a/app/templates/entreprises/entreprises.html b/app/templates/entreprises/entreprises.html index 9cbe2330f..fe790a8d6 100644 --- a/app/templates/entreprises/entreprises.html +++ b/app/templates/entreprises/entreprises.html @@ -1,3 +1,4 @@ +{# -*- mode: jinja-html -*- #} {% extends 'base.html' %} {% block app_content %} diff --git a/app/templates/entreprises/envoi_offre_form.html b/app/templates/entreprises/envoi_offre_form.html index c9db2c6c1..f67cb4e40 100644 --- a/app/templates/entreprises/envoi_offre_form.html +++ b/app/templates/entreprises/envoi_offre_form.html @@ -1,3 +1,4 @@ +{# -*- mode: jinja-html -*- #} {% extends 'base.html' %} {% import 'bootstrap/wtf.html' as wtf %} diff --git a/app/templates/entreprises/fiche_entreprise.html b/app/templates/entreprises/fiche_entreprise.html index f3cc68269..d34531207 100644 --- a/app/templates/entreprises/fiche_entreprise.html +++ b/app/templates/entreprises/fiche_entreprise.html @@ -1,72 +1,76 @@ +{# -*- mode: jinja-html -*- #} {% extends 'base.html' %} {% block app_content %} - {% if logs %} -

    -

    Dernières opérations sur cette fiche

    -
      - {% for log in logs %} -
    • - {{ log.date.strftime('%d %b %Hh%M') }} - {{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet }} -
    • - {% endfor %} -
    -
    - {% endif %} - {% if historique %} -
    -

    Historique

    -
      - {% for data in historique %} -
    • - {{ data[0].date_debut.strftime('%d/%m/%Y') }} - {{ data[0].date_fin.strftime('%d/%m/%Y') }} - - {{ data[0].type_offre }} réalisé par {{ data[1].nom|format_nom }} {{ data[1].prenom|format_prenom }} en {{ data[0].formation_text }} - -
    • - {% endfor %} -
    -
    - {% endif %} -
    -

    Fiche entreprise - {{ entreprise.nom }} ({{ entreprise.siret }})

    +{% if logs %} +
    +

    Dernières opérations sur cette fiche

    +
      + {% for log in logs %} +
    • + {{ log.date.strftime('%d %b %Hh%M') }} + {{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet }} +
    • + {% endfor %} +
    +
    +{% endif %} +{% if historique %} +
    +

    Historique

    +
      + {% for data in historique %} +
    • + {{ data[0].date_debut.strftime('%d/%m/%Y') }} - {{ + data[0].date_fin.strftime('%d/%m/%Y') }} + + {{ data[0].type_offre }} réalisé par {{ data[1].nom|format_nom }} {{ data[1].prenom|format_prenom }} en + {{ data[0].formation_text }} + +
    • + {% endfor %} +
    +
    +{% endif %} +
    +

    Fiche entreprise - {{ entreprise.nom }} ({{ entreprise.siret }})

    -
    -

    - SIRET : {{ entreprise.siret }}
    - Nom : {{ entreprise.nom }}
    - Adresse : {{ entreprise.adresse }}
    - Code postal : {{ entreprise.codepostal }}
    - Ville : {{ entreprise.ville }}
    - Pays : {{ entreprise.pays }} -

    -
    +
    +

    + SIRET : {{ entreprise.siret }}
    + Nom : {{ entreprise.nom }}
    + Adresse : {{ entreprise.adresse }}
    + Code postal : {{ entreprise.codepostal }}
    + Ville : {{ entreprise.ville }}
    + Pays : {{ entreprise.pays }} +

    +
    - {% if contacts %} -
    + {% if contacts %} +
    {% for contact in contacts %} - Contact {{loop.index}} - {% include 'entreprises/_contact.html' %} + Contact {{loop.index}} + {% include 'entreprises/_contact.html' %} {% endfor %} -
    - {% endif %} - - {% if offres %} -
    - {% for offre in offres %} - Offre {{loop.index}} (ajouté le {{offre[0].date_ajout.strftime('%d/%m/%Y') }}) - {% include 'entreprises/_offre.html' %} - {% endfor %} -
    - {% endif %} - -
    + {% endif %} + + {% if offres %} +
    + {% for offre in offres %} + Offre {{loop.index}} (ajouté le {{offre[0].date_ajout.strftime('%d/%m/%Y') }}) + {% include 'entreprises/_offre.html' %} + {% endfor %} +
    + {% endif %} + + +
    {% endblock %} \ No newline at end of file diff --git a/app/templates/entreprises/form.html b/app/templates/entreprises/form.html index 26add23e1..066224d8b 100644 --- a/app/templates/entreprises/form.html +++ b/app/templates/entreprises/form.html @@ -1,3 +1,4 @@ +{# -*- mode: jinja-html -*- #} {% extends 'base.html' %} {% import 'bootstrap/wtf.html' as wtf %} diff --git a/app/templates/entreprises/offres.html b/app/templates/entreprises/offres.html index 717364b9b..ff3ab9bdc 100644 --- a/app/templates/entreprises/offres.html +++ b/app/templates/entreprises/offres.html @@ -1,3 +1,4 @@ +{# -*- mode: jinja-html -*- #} {% extends 'base.html' %} {% block app_content %}