ScoDoc-PE/app/entreprises/forms.py

378 lines
13 KiB
Python

# -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
##############################################################################
import re
import requests
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed, FileRequired
from markupsafe import Markup
from sqlalchemy import text
from wtforms import (
StringField,
SubmitField,
TextAreaField,
SelectField,
HiddenField,
SelectMultipleField,
)
from wtforms.fields import EmailField, DateField
from wtforms.validators import ValidationError, DataRequired, Email, Optional
from wtforms.widgets import ListWidget, CheckboxInput
from app.entreprises.models import Entreprise, EntrepriseContact
from app.models import Identite, Departement
from app.auth.models import User
CHAMP_REQUIS = "Ce champ est requis"
class EntrepriseCreationForm(FlaskForm):
siret = StringField(
"SIRET",
validators=[DataRequired(message=CHAMP_REQUIS)],
render_kw={"placeholder": "Numéro composé de 14 chiffres", "maxlength": "14"},
)
nom_entreprise = StringField(
"Nom de l'entreprise",
validators=[DataRequired(message=CHAMP_REQUIS)],
)
adresse = StringField(
"Adresse de l'entreprise",
validators=[DataRequired(message=CHAMP_REQUIS)],
)
codepostal = StringField(
"Code postal de l'entreprise",
validators=[DataRequired(message=CHAMP_REQUIS)],
)
ville = StringField(
"Ville de l'entreprise",
validators=[DataRequired(message=CHAMP_REQUIS)],
)
pays = StringField(
"Pays de l'entreprise",
validators=[DataRequired(message=CHAMP_REQUIS)],
render_kw={"style": "margin-bottom: 50px;"},
)
nom_contact = StringField(
"Nom du contact", validators=[DataRequired(message=CHAMP_REQUIS)]
)
prenom_contact = StringField(
"Prénom du contact",
validators=[DataRequired(message=CHAMP_REQUIS)],
)
telephone = StringField("Téléphone du contact", validators=[Optional()])
mail = EmailField(
"Mail du contact",
validators=[Optional(), Email(message="Adresse e-mail invalide")],
)
poste = StringField("Poste du contact", validators=[Optional()])
service = StringField("Service du contact", validators=[Optional()])
submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"})
def validate(self):
rv = FlaskForm.validate(self)
if not rv:
return False
if not self.telephone.data and not self.mail.data:
self.telephone.errors.append(
"Saisir un moyen de contact (mail ou téléphone)"
)
self.mail.errors.append("Saisir un moyen de contact (mail ou téléphone)")
return False
return True
def validate_siret(self, siret):
siret = siret.data.strip()
if re.match("^\d{14}$", siret) is 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'<a href="/ScoDoc/entreprises/fiche_entreprise/{entreprise.id}">ici</a>'
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=CHAMP_REQUIS)],
)
adresse = StringField("Adresse", validators=[DataRequired(message=CHAMP_REQUIS)])
codepostal = StringField(
"Code postal", validators=[DataRequired(message=CHAMP_REQUIS)]
)
ville = StringField("Ville", validators=[DataRequired(message=CHAMP_REQUIS)])
pays = StringField("Pays", validators=[DataRequired(message=CHAMP_REQUIS)])
submit = SubmitField("Modifier", render_kw={"style": "margin-bottom: 10px;"})
class MultiCheckboxField(SelectMultipleField):
widget = ListWidget(prefix_label=False)
option_widget = CheckboxInput()
class OffreCreationForm(FlaskForm):
intitule = StringField("Intitulé", validators=[DataRequired(message=CHAMP_REQUIS)])
description = TextAreaField(
"Description", validators=[DataRequired(message=CHAMP_REQUIS)]
)
type_offre = SelectField(
"Type de l'offre",
choices=[("Stage"), ("Alternance")],
validators=[DataRequired(message=CHAMP_REQUIS)],
)
missions = TextAreaField(
"Missions", validators=[DataRequired(message=CHAMP_REQUIS)]
)
duree = StringField("Durée", validators=[DataRequired(message=CHAMP_REQUIS)])
depts = MultiCheckboxField("Départements", validators=[Optional()], coerce=int)
expiration_date = DateField(
"Date expiration", validators=[DataRequired(message=CHAMP_REQUIS)]
)
submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"})
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.depts.choices = [
(dept.id, dept.acronym) for dept in Departement.query.all()
]
class OffreModificationForm(FlaskForm):
intitule = StringField("Intitulé", validators=[DataRequired(message=CHAMP_REQUIS)])
description = TextAreaField(
"Description", validators=[DataRequired(message=CHAMP_REQUIS)]
)
type_offre = SelectField(
"Type de l'offre",
choices=[("Stage"), ("Alternance")],
validators=[DataRequired(message=CHAMP_REQUIS)],
)
missions = TextAreaField(
"Missions", validators=[DataRequired(message=CHAMP_REQUIS)]
)
duree = StringField("Durée", validators=[DataRequired(message=CHAMP_REQUIS)])
depts = MultiCheckboxField("Départements", validators=[Optional()], coerce=int)
expiration_date = DateField(
"Date expiration", validators=[DataRequired(message=CHAMP_REQUIS)]
)
submit = SubmitField("Modifier", render_kw={"style": "margin-bottom: 10px;"})
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.depts.choices = [
(dept.id, dept.acronym) for dept in Departement.query.all()
]
class ContactCreationForm(FlaskForm):
hidden_entreprise_id = HiddenField()
nom = StringField("Nom", validators=[DataRequired(message=CHAMP_REQUIS)])
prenom = StringField("Prénom", validators=[DataRequired(message=CHAMP_REQUIS)])
telephone = StringField("Téléphone", validators=[Optional()])
mail = EmailField(
"Mail",
validators=[Optional(), Email(message="Adresse e-mail invalide")],
)
poste = StringField("Poste", validators=[Optional()])
service = StringField("Service", validators=[Optional()])
submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"})
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()
validate = True
if contact is not None:
self.nom.errors.append("Ce contact existe déjà (même nom et prénom)")
self.prenom.errors.append("")
validate = False
if not self.telephone.data and not self.mail.data:
self.telephone.errors.append(
"Saisir un moyen de contact (mail ou téléphone)"
)
self.mail.errors.append("Saisir un moyen de contact (mail ou téléphone)")
validate = False
return validate
class ContactModificationForm(FlaskForm):
hidden_contact_id = HiddenField()
hidden_entreprise_id = HiddenField()
nom = StringField("Nom", validators=[DataRequired(message=CHAMP_REQUIS)])
prenom = StringField("Prénom", validators=[DataRequired(message=CHAMP_REQUIS)])
telephone = StringField("Téléphone", validators=[Optional()])
mail = EmailField(
"Mail",
validators=[Optional(), Email(message="Adresse e-mail invalide")],
)
poste = StringField("Poste", validators=[Optional()])
service = StringField("Service", validators=[Optional()])
submit = SubmitField("Modifier", render_kw={"style": "margin-bottom: 10px;"})
def validate(self):
rv = FlaskForm.validate(self)
if not rv:
return False
contact = EntrepriseContact.query.filter(
EntrepriseContact.id != self.hidden_contact_id.data,
EntrepriseContact.entreprise_id == self.hidden_entreprise_id.data,
EntrepriseContact.nom == self.nom.data,
EntrepriseContact.prenom == self.prenom.data,
).first()
validate = True
if contact is not None:
self.nom.errors.append("Ce contact existe déjà (même nom et prénom)")
self.prenom.errors.append("")
validate = False
if not self.telephone.data and not self.mail.data:
self.telephone.errors.append(
"Saisir un moyen de contact (mail ou téléphone)"
)
self.mail.errors.append("Saisir un moyen de contact (mail ou téléphone)")
validate = False
return validate
class HistoriqueCreationForm(FlaskForm):
etudiant = StringField(
"Étudiant",
validators=[DataRequired(message=CHAMP_REQUIS)],
render_kw={"placeholder": "Tapez le nom de l'étudiant puis selectionnez"},
)
type_offre = SelectField(
"Type de l'offre",
choices=[("Stage"), ("Alternance")],
validators=[DataRequired(message=CHAMP_REQUIS)],
)
date_debut = DateField(
"Date début", validators=[DataRequired(message=CHAMP_REQUIS)]
)
date_fin = DateField("Date fin", validators=[DataRequired(message=CHAMP_REQUIS)])
submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"})
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=CHAMP_REQUIS)],
)
submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"})
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 AjoutFichierForm(FlaskForm):
fichier = FileField(
"Fichier",
validators=[
FileRequired(message=CHAMP_REQUIS),
FileAllowed(["pdf", "docx"], "Fichier .pdf ou .docx uniquement"),
],
)
submit = SubmitField("Ajouter", render_kw={"style": "margin-bottom: 10px;"})
class SuppressionConfirmationForm(FlaskForm):
submit = SubmitField("Supprimer", render_kw={"style": "margin-bottom: 10px;"})
class ValidationConfirmationForm(FlaskForm):
submit = SubmitField("Valider", render_kw={"style": "margin-bottom: 10px;"})
class ImportEntreprisesForm(FlaskForm):
fichier = FileField(
"Fichier",
validators=[
FileRequired(message=CHAMP_REQUIS),
FileAllowed(["xlsx"], "Fichier .xlsx uniquement"),
],
)
submit = SubmitField("Importer", render_kw={"style": "margin-bottom: 10px;"})