ScoDoc-Lille/app/entreprises/forms.py
2022-02-11 19:18:01 +01:00

356 lines
12 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,
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"
SUBMIT_MARGE = {"style": "margin-bottom: 10px;"}
def _build_string_field(label, required=True, render_kw=None):
if required:
return StringField(
label,
validators=[DataRequired(message=CHAMP_REQUIS)],
render_kw=render_kw,
)
else:
return StringField(label, validators=[Optional()], render_kw=render_kw)
class EntrepriseCreationForm(FlaskForm):
siret = _build_string_field(
"SIRET",
render_kw={"placeholder": "Numéro composé de 14 chiffres", "maxlength": "14"},
)
nom_entreprise = _build_string_field("Nom de l'entreprise")
adresse = _build_string_field("Adresse de l'entreprise")
codepostal = _build_string_field("Code postal de l'entreprise")
ville = _build_string_field("Ville de l'entreprise")
pays = _build_string_field("Pays de l'entreprise")
nom_contact = _build_string_field("Nom du contact")
prenom_contact = _build_string_field("Prénom du contact")
telephone = _build_string_field("Téléphone du contact", required=False)
mail = StringField(
"Mail du contact",
validators=[Optional(), Email(message="Adresse e-mail invalide")],
)
poste = _build_string_field("Poste du contact", required=False)
service = _build_string_field("Service du contact", required=False)
submit = SubmitField("Envoyer", render_kw=SUBMIT_MARGE)
def validate(self):
validate = True
if not FlaskForm.validate(self):
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
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", render_kw={"disabled": ""})
nom = _build_string_field("Nom de l'entreprise")
adresse = _build_string_field("Adresse")
codepostal = _build_string_field("Code postal")
ville = _build_string_field("Ville")
pays = _build_string_field("Pays")
submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
class MultiCheckboxField(SelectMultipleField):
widget = ListWidget(prefix_label=False)
option_widget = CheckboxInput()
class OffreCreationForm(FlaskForm):
intitule = _build_string_field("Intitulé")
description = TextAreaField(
"Description", validators=[DataRequired(message=CHAMP_REQUIS)]
)
type_offre = SelectField(
"Type de l'offre",
choices=[("Stage"), ("Alternance")],
validators=[DataRequired(message=CHAMP_REQUIS)],
)
missions = _build_string_field("Missions")
duree = _build_string_field("Durée")
depts = MultiCheckboxField("Départements", validators=[Optional()], coerce=int)
expiration_date = DateField(
"Date expiration", validators=[DataRequired(message=CHAMP_REQUIS)]
)
submit = SubmitField("Envoyer", render_kw=SUBMIT_MARGE)
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 = _build_string_field("Intitulé")
description = TextAreaField(
"Description", validators=[DataRequired(message=CHAMP_REQUIS)]
)
type_offre = SelectField(
"Type de l'offre",
choices=[("Stage"), ("Alternance")],
validators=[DataRequired(message=CHAMP_REQUIS)],
)
missions = _build_string_field("Missions")
duree = _build_string_field("Durée")
depts = MultiCheckboxField("Départements", validators=[Optional()], coerce=int)
expiration_date = DateField(
"Date expiration", validators=[DataRequired(message=CHAMP_REQUIS)]
)
submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
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 = _build_string_field("Nom")
prenom = _build_string_field("Prénom")
telephone = _build_string_field("Téléphone", required=False)
mail = StringField(
"Mail",
validators=[Optional(), Email(message="Adresse e-mail invalide")],
)
poste = _build_string_field("Poste", required=False)
service = _build_string_field("Service", required=False)
submit = SubmitField("Envoyer", render_kw=SUBMIT_MARGE)
def validate(self):
validate = True
if not FlaskForm.validate(self):
validate = 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("")
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 = _build_string_field("Nom")
prenom = _build_string_field("Prénom")
telephone = _build_string_field("Téléphone", required=False)
mail = StringField(
"Mail",
validators=[Optional(), Email(message="Adresse e-mail invalide")],
)
poste = _build_string_field("Poste", required=False)
service = _build_string_field("Service", required=False)
submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
def validate(self):
validate = True
if not FlaskForm.validate(self):
validate = 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()
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 = _build_string_field(
"Étudiant",
render_kw={"placeholder": "Tapez le nom de l'étudiant"},
)
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=SUBMIT_MARGE)
def validate(self):
validate = True
if not FlaskForm.validate(self):
validate = False
if (
self.date_debut.data
and self.date_fin.data
and 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")
validate = False
return validate
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 = _build_string_field(
"Responsable de formation",
render_kw={"placeholder": "Tapez le nom du responsable de formation"},
)
submit = SubmitField("Envoyer", render_kw=SUBMIT_MARGE)
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=SUBMIT_MARGE)
class SuppressionConfirmationForm(FlaskForm):
submit = SubmitField("Supprimer", render_kw=SUBMIT_MARGE)
class ValidationConfirmationForm(FlaskForm):
submit = SubmitField("Valider", render_kw=SUBMIT_MARGE)
class ImportForm(FlaskForm):
fichier = FileField(
"Fichier",
validators=[
FileRequired(message=CHAMP_REQUIS),
FileAllowed(["xlsx"], "Fichier .xlsx uniquement"),
],
)
submit = SubmitField("Importer", render_kw=SUBMIT_MARGE)