Merge branch 'entreprises' of https://scodoc.org/git/arthur.zhu/ScoDoc into entreprises

This commit is contained in:
Emmanuel Viennet 2022-04-27 09:42:32 +02:00
commit a5a1a84436
21 changed files with 433 additions and 163 deletions

View File

@ -39,4 +39,12 @@ def get_dept_acronym(id):
return dept.acronym return dept.acronym
@bp.app_template_filter()
def get_civilité(civ):
if civ == "H":
return "Monsieur"
else:
return "Madame"
from app.entreprises import routes from app.entreprises import routes

View File

@ -131,38 +131,46 @@ def send_email_notifications_entreprise(subject, entreprise: Entreprise):
def verif_correspondant_data(correspondant_data): def verif_correspondant_data(correspondant_data):
""" """
Verifie les données d'une ligne Excel (correspondant) Verifie les données d'une ligne Excel (correspondant)
correspondant_data[0]: nom correspondant_data[0]: civilite
correspondant_data[1]: prenom correspondant_data[1]: nom
correspondant_data[2]: telephone correspondant_data[2]: prenom
correspondant_data[3]: mail correspondant_data[3]: telephone
correspondant_data[4]: poste correspondant_data[4]: mail
correspondant_data[5]: service correspondant_data[5]: poste
correspondant_data[6]: entreprise_id correspondant_data[6]: service
correspondant_data[7]: origine
correspondant_data[8]: notes
correspondant_data[9]: entreprise_siret
""" """
# champs obligatoires # champs obligatoires
if ( if (
correspondant_data[0].strip() == "" correspondant_data[0].strip() == ""
or correspondant_data[1].strip() == "" or correspondant_data[1].strip() == ""
or correspondant_data[6].strip() == "" or correspondant_data[2].strip() == ""
or correspondant_data[9].strip() == ""
): ):
return False return False
# civilite entre H ou F
if correspondant_data[0].strip() not in ["H", "F"]:
return False
# entreprise_id existant # entreprise_id existant
entreprise = Entreprise.query.filter_by(siret=correspondant_data[6].strip()).first() entreprise = Entreprise.query.filter_by(siret=correspondant_data[9].strip()).first()
if entreprise is None: if entreprise is None:
return False return False
# correspondant possède le meme nom et prénom dans la meme entreprise # correspondant possède le meme nom et prénom dans la meme entreprise
correspondant = EntrepriseCorrespondant.query.filter_by( correspondant = EntrepriseCorrespondant.query.filter_by(
nom=correspondant_data[0].strip(), nom=correspondant_data[1].strip(),
prenom=correspondant_data[1].strip(), prenom=correspondant_data[2].strip(),
entreprise_id=entreprise.id, entreprise_id=entreprise.id,
).first() ).first()
if correspondant is not None: if correspondant is not None:
return False return False
if ( if (
correspondant_data[2].strip() == "" and correspondant_data[3].strip() == "" correspondant_data[3].strip() == "" and correspondant_data[4].strip() == ""
): # 1 moyen de contact ): # 1 moyen de contact
return False return False
@ -182,7 +190,7 @@ def verif_entreprise_data(entreprise_data):
if data.strip() == "": if data.strip() == "":
return False return False
if EntreprisePreferences.get_check_siret(): if EntreprisePreferences.get_check_siret():
siret = entreprise_data[0].replace(" ", "") # vérification sur le siret siret = entreprise_data[0].strip().replace(" ", "") # vérification sur le siret
if re.match("^\d{14}$", siret) is None: if re.match("^\d{14}$", siret) is None:
return False return False
try: try:

View File

@ -80,6 +80,11 @@ class EntrepriseCreationForm(FlaskForm):
ville = _build_string_field("Ville de l'entreprise (*)") ville = _build_string_field("Ville de l'entreprise (*)")
pays = _build_string_field("Pays de l'entreprise", required=False) pays = _build_string_field("Pays de l'entreprise", required=False)
civilite = SelectField(
"Civilité du correspondant",
choices=[("M", "Monsieur"), ("F", "Madame")],
validators=[DataRequired(message=CHAMP_REQUIS)],
)
nom_correspondant = _build_string_field("Nom du correspondant", required=False) nom_correspondant = _build_string_field("Nom du correspondant", required=False)
prenom_correspondant = _build_string_field( prenom_correspondant = _build_string_field(
"Prénom du correspondant", required=False "Prénom du correspondant", required=False
@ -91,6 +96,8 @@ class EntrepriseCreationForm(FlaskForm):
) )
poste = _build_string_field("Poste du correspondant", required=False) poste = _build_string_field("Poste du correspondant", required=False)
service = _build_string_field("Service du correspondant", required=False) service = _build_string_field("Service du correspondant", required=False)
origine = _build_string_field("Origine du correspondant", required=False)
notes = _build_string_field("Notes sur le correspondant", required=False)
submit = SubmitField("Envoyer", render_kw=SUBMIT_MARGE) submit = SubmitField("Envoyer", render_kw=SUBMIT_MARGE)
@ -106,6 +113,8 @@ class EntrepriseCreationForm(FlaskForm):
or self.mail.data.strip() or self.mail.data.strip()
or self.poste.data.strip() or self.poste.data.strip()
or self.service.data.strip() or self.service.data.strip()
or self.origine.data.strip()
or self.notes.data.strip()
): ):
if not self.nom_correspondant.data.strip(): if not self.nom_correspondant.data.strip():
self.nom_correspondant.errors.append("Ce champ est requis") self.nom_correspondant.errors.append("Ce champ est requis")
@ -114,19 +123,16 @@ class EntrepriseCreationForm(FlaskForm):
self.prenom_correspondant.errors.append("Ce champ est requis") self.prenom_correspondant.errors.append("Ce champ est requis")
validate = False validate = False
if not self.telephone.data.strip() and not self.mail.data.strip(): if not self.telephone.data.strip() and not self.mail.data.strip():
self.telephone.errors.append( msg = "Saisir un moyen de contact (mail ou téléphone)"
"Saisir un moyen de contact (mail ou téléphone)" self.telephone.errors.append(msg)
) self.mail.errors.append(msg)
self.mail.errors.append(
"Saisir un moyen de contact (mail ou téléphone)"
)
validate = False validate = False
return validate return validate
def validate_siret(self, siret): def validate_siret(self, siret):
if EntreprisePreferences.get_check_siret(): if EntreprisePreferences.get_check_siret():
siret_data = siret.data.replace(" ", "") siret_data = siret.data.strip().replace(" ", "")
self.siret.data = siret_data self.siret.data = siret_data
if re.match("^\d{14}$", siret_data) is None: if re.match("^\d{14}$", siret_data) is None:
raise ValidationError("Format incorrect") raise ValidationError("Format incorrect")
@ -164,6 +170,15 @@ class EntrepriseModificationForm(FlaskForm):
} }
class SiteCreationForm(FlaskForm):
nom = _build_string_field("Nom du site (*)")
adresse = _build_string_field("Adresse (*)")
codepostal = _build_string_field("Code postal (*)")
ville = _build_string_field("Ville (*)")
pays = _build_string_field("Pays", required=False)
submit = SubmitField("Envoyer", render_kw=SUBMIT_MARGE)
class MultiCheckboxField(SelectMultipleField): class MultiCheckboxField(SelectMultipleField):
widget = ListWidget(prefix_label=False) widget = ListWidget(prefix_label=False)
option_widget = CheckboxInput() option_widget = CheckboxInput()
@ -184,11 +199,11 @@ class OffreCreationForm(FlaskForm):
"Missions (*)", validators=[DataRequired(message=CHAMP_REQUIS)] "Missions (*)", validators=[DataRequired(message=CHAMP_REQUIS)]
) )
duree = _build_string_field("Durée (*)") duree = _build_string_field("Durée (*)")
depts = MultiCheckboxField("Départements", validators=[Optional()], coerce=int) depts = MultiCheckboxField("Départements (*)", validators=[Optional()], coerce=int)
expiration_date = DateField("Date expiration", validators=[Optional()]) expiration_date = DateField("Date expiration", validators=[Optional()])
correspondant = SelectField("Correspondant à contacté", validators=[Optional()]) correspondant = SelectField("Correspondant à contacté", validators=[Optional()])
fichier = FileField( fichier = FileField(
"Fichier (*)", "Fichier",
validators=[ validators=[
Optional(), Optional(),
FileAllowed(["pdf", "docx"], "Fichier .pdf ou .docx uniquement"), FileAllowed(["pdf", "docx"], "Fichier .pdf ou .docx uniquement"),
@ -237,7 +252,7 @@ class OffreModificationForm(FlaskForm):
"Missions (*)", validators=[DataRequired(message=CHAMP_REQUIS)] "Missions (*)", validators=[DataRequired(message=CHAMP_REQUIS)]
) )
duree = _build_string_field("Durée (*)") duree = _build_string_field("Durée (*)")
depts = MultiCheckboxField("Départements", validators=[Optional()], coerce=int) depts = MultiCheckboxField("Départements (*)", validators=[Optional()], coerce=int)
expiration_date = DateField("Date expiration", validators=[Optional()]) expiration_date = DateField("Date expiration", validators=[Optional()])
correspondant = SelectField("Correspondant à contacté", validators=[Optional()]) correspondant = SelectField("Correspondant à contacté", validators=[Optional()])
submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE) submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
@ -269,6 +284,12 @@ class OffreModificationForm(FlaskForm):
class CorrespondantCreationForm(FlaskForm): class CorrespondantCreationForm(FlaskForm):
civilite = SelectField(
"Civilité (*)",
choices=[("H", "Monsieur"), ("F", "Madame")],
validators=[DataRequired(message=CHAMP_REQUIS)],
render_kw={"class": "form-control"},
)
nom = _build_string_field("Nom (*)", render_kw={"class": "form-control"}) nom = _build_string_field("Nom (*)", render_kw={"class": "form-control"})
prenom = _build_string_field("Prénom (*)", render_kw={"class": "form-control"}) prenom = _build_string_field("Prénom (*)", render_kw={"class": "form-control"})
telephone = _build_string_field( telephone = _build_string_field(
@ -285,14 +306,12 @@ class CorrespondantCreationForm(FlaskForm):
service = _build_string_field( service = _build_string_field(
"Service", required=False, render_kw={"class": "form-control"} "Service", required=False, render_kw={"class": "form-control"}
) )
# depts = MultiCheckboxField("Départements", validators=[Optional()], coerce=int) origine = _build_string_field(
"Origine", required=False, render_kw={"class": "form-control"}
# def __init__(self, *args, **kwargs): )
# super().__init__(*args, **kwargs) notes = _build_string_field(
"Notes", required=False, render_kw={"class": "form-control"}
# self.depts.choices = [ )
# (dept.id, dept.acronym) for dept in Departement.query.all()
# ]
def validate(self): def validate(self):
validate = True validate = True
@ -300,10 +319,9 @@ class CorrespondantCreationForm(FlaskForm):
validate = False validate = False
if not self.telephone.data and not self.mail.data: if not self.telephone.data and not self.mail.data:
self.telephone.errors.append( msg = "Saisir un moyen de contact (mail ou téléphone)"
"Saisir un moyen de contact (mail ou téléphone)" self.telephone.errors.append(msg)
) self.mail.errors.append(msg)
self.mail.errors.append("Saisir un moyen de contact (mail ou téléphone)")
validate = False validate = False
return validate return validate
@ -321,7 +339,7 @@ class CorrespondantsCreationForm(FlaskForm):
correspondant_list = [] correspondant_list = []
for entry in self.correspondants.entries: for entry in self.correspondants.entries:
if entry.nom.data.strip() and entry.prenom.data.strip(): if entry.nom.data and entry.prenom.data:
if ( if (
entry.nom.data.strip(), entry.nom.data.strip(),
entry.prenom.data.strip(), entry.prenom.data.strip(),
@ -351,6 +369,11 @@ class CorrespondantsCreationForm(FlaskForm):
class CorrespondantModificationForm(FlaskForm): class CorrespondantModificationForm(FlaskForm):
hidden_correspondant_id = HiddenField() hidden_correspondant_id = HiddenField()
hidden_entreprise_id = HiddenField() hidden_entreprise_id = HiddenField()
civilite = SelectField(
"Civilité (*)",
choices=[("H", "Monsieur"), ("F", "Madame")],
validators=[DataRequired(message=CHAMP_REQUIS)],
)
nom = _build_string_field("Nom (*)") nom = _build_string_field("Nom (*)")
prenom = _build_string_field("Prénom (*)") prenom = _build_string_field("Prénom (*)")
telephone = _build_string_field("Téléphone (*)", required=False) telephone = _build_string_field("Téléphone (*)", required=False)
@ -360,16 +383,10 @@ class CorrespondantModificationForm(FlaskForm):
) )
poste = _build_string_field("Poste", required=False) poste = _build_string_field("Poste", required=False)
service = _build_string_field("Service", required=False) service = _build_string_field("Service", required=False)
# depts = MultiCheckboxField("Départements", validators=[Optional()], coerce=int) origine = _build_string_field("Origine", required=False)
notes = _build_string_field("Notes", required=False)
submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE) 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()
# ]
def validate(self): def validate(self):
validate = True validate = True
if not FlaskForm.validate(self): if not FlaskForm.validate(self):
@ -387,10 +404,9 @@ class CorrespondantModificationForm(FlaskForm):
validate = False validate = False
if not self.telephone.data and not self.mail.data: if not self.telephone.data and not self.mail.data:
self.telephone.errors.append( msg = "Saisir un moyen de contact (mail ou téléphone)"
"Saisir un moyen de contact (mail ou téléphone)" self.telephone.errors.append(msg)
) self.mail.errors.append(msg)
self.mail.errors.append("Saisir un moyen de contact (mail ou téléphone)")
validate = False validate = False
return validate return validate
@ -593,6 +609,11 @@ class SuppressionConfirmationForm(FlaskForm):
submit = SubmitField("Supprimer", render_kw=SUBMIT_MARGE) submit = SubmitField("Supprimer", render_kw=SUBMIT_MARGE)
class DesactivationConfirmationForm(FlaskForm):
notes_active = TextAreaField("Notes sur la désactivation", validators=[Optional()])
submit = SubmitField("Désactiver", render_kw=SUBMIT_MARGE)
class ValidationConfirmationForm(FlaskForm): class ValidationConfirmationForm(FlaskForm):
submit = SubmitField("Valider", render_kw=SUBMIT_MARGE) submit = SubmitField("Valider", render_kw=SUBMIT_MARGE)

View File

@ -9,14 +9,18 @@ class Entreprise(db.Model):
adresse = db.Column(db.Text) adresse = db.Column(db.Text)
codepostal = db.Column(db.Text) codepostal = db.Column(db.Text)
ville = db.Column(db.Text) ville = db.Column(db.Text)
pays = db.Column(db.Text, default="FRANCE") pays = db.Column(db.Text)
visible = db.Column(db.Boolean, default=False) visible = db.Column(db.Boolean, default=False)
correspondants = db.relationship( active = db.Column(db.Boolean, default=True)
"EntrepriseCorrespondant", notes_active = db.Column(db.Text)
sites = db.relationship(
"EntrepriseSite",
backref="entreprise", backref="entreprise",
lazy="dynamic", lazy="dynamic",
cascade="all, delete-orphan", cascade="all, delete-orphan",
) )
offres = db.relationship( offres = db.relationship(
"EntrepriseOffre", "EntrepriseOffre",
backref="entreprise", backref="entreprise",
@ -35,13 +39,24 @@ class Entreprise(db.Model):
} }
# class EntrepriseSite(db.Model): class EntrepriseSite(db.Model):
# __tablename__ = "are_sites" __tablename__ = "are_sites"
# id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
# entreprise_id = db.Column( entreprise_id = db.Column(
# db.Integer, db.ForeignKey("are_entreprises.id", ondelete="cascade") db.Integer, db.ForeignKey("are_entreprises.id", ondelete="cascade")
# ) )
# nom = 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)
correspondants = db.relationship(
"EntrepriseCorrespondant",
backref="site",
lazy="dynamic",
cascade="all, delete-orphan",
)
class EntrepriseCorrespondant(db.Model): class EntrepriseCorrespondant(db.Model):
@ -50,23 +65,29 @@ class EntrepriseCorrespondant(db.Model):
entreprise_id = db.Column( entreprise_id = db.Column(
db.Integer, db.ForeignKey("are_entreprises.id", ondelete="cascade") db.Integer, db.ForeignKey("are_entreprises.id", ondelete="cascade")
) )
# site_id = db.Column(db.Integer, db.ForeignKey("are_sites.id", ondelete="cascade")) site_id = db.Column(db.Integer, db.ForeignKey("are_sites.id", ondelete="cascade"))
civilite = db.Column(db.String(1))
nom = db.Column(db.Text) nom = db.Column(db.Text)
prenom = db.Column(db.Text) prenom = db.Column(db.Text)
telephone = db.Column(db.Text) telephone = db.Column(db.Text)
mail = db.Column(db.Text) mail = db.Column(db.Text)
poste = db.Column(db.Text) poste = db.Column(db.Text)
service = db.Column(db.Text) service = db.Column(db.Text)
origine = db.Column(db.Text)
notes = db.Column(db.Text)
def to_dict(self): def to_dict(self):
entreprise = Entreprise.query.filter_by(id=self.entreprise_id).first() entreprise = Entreprise.query.filter_by(id=self.entreprise_id).first()
return { return {
"civilite": self.civilite,
"nom": self.nom, "nom": self.nom,
"prenom": self.prenom, "prenom": self.prenom,
"telephone": self.telephone, "telephone": self.telephone,
"mail": self.mail, "mail": self.mail,
"poste": self.poste, "poste": self.poste,
"service": self.service, "service": self.service,
"origine": self.origine,
"notes": self.notes,
"entreprise_siret": entreprise.siret, "entreprise_siret": entreprise.siret,
} }
@ -161,15 +182,6 @@ class EntrepriseOffreDepartement(db.Model):
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id", ondelete="cascade")) dept_id = db.Column(db.Integer, db.ForeignKey("departement.id", ondelete="cascade"))
# class EntrepriseCorrespondantDepartement(db.Model):
# __tablename__ = "are_correspondant_departement"
# id = db.Column(db.Integer, primary_key=True)
# correspondant_id = db.Column(
# db.Integer, db.ForeignKey("are_correspondants.id", ondelete="cascade")
# )
# dept_id = db.Column(db.Integer, db.ForeignKey("departement.id", ondelete="cascade"))
class EntreprisePreferences(db.Model): class EntreprisePreferences(db.Model):
__tablename__ = "are_preferences" __tablename__ = "are_preferences"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)

View File

@ -13,8 +13,10 @@ from app.decorators import permission_required
from app.entreprises import LOGS_LEN from app.entreprises import LOGS_LEN
from app.entreprises.forms import ( from app.entreprises.forms import (
CorrespondantsCreationForm, CorrespondantsCreationForm,
DesactivationConfirmationForm,
EntrepriseCreationForm, EntrepriseCreationForm,
EntrepriseModificationForm, EntrepriseModificationForm,
SiteCreationForm,
SuppressionConfirmationForm, SuppressionConfirmationForm,
OffreCreationForm, OffreCreationForm,
OffreModificationForm, OffreModificationForm,
@ -36,6 +38,7 @@ from app.entreprises.models import (
EntrepriseCorrespondant, EntrepriseCorrespondant,
EntrepriseLog, EntrepriseLog,
EntrepriseContact, EntrepriseContact,
EntrepriseSite,
EntrepriseStageApprentissage, EntrepriseStageApprentissage,
EntrepriseEnvoiOffre, EntrepriseEnvoiOffre,
EntrepriseOffreDepartement, EntrepriseOffreDepartement,
@ -59,7 +62,7 @@ def index():
""" """
Permet d'afficher une page avec la liste des entreprises (visible) et une liste des dernières opérations Permet d'afficher une page avec la liste des entreprises (visible) et une liste des dernières opérations
""" """
entreprises = Entreprise.query.filter_by(visible=True) entreprises = Entreprise.query.filter_by(visible=True, active=True)
logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).limit(LOGS_LEN).all() logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).limit(LOGS_LEN).all()
return render_template( return render_template(
"entreprises/entreprises.html", "entreprises/entreprises.html",
@ -101,7 +104,7 @@ def validation():
@bp.route("/correspondants", methods=["GET"]) @bp.route("/correspondants", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesView) @permission_required(Permission.RelationsEntreprisesCorrespondants)
def correspondants(): def correspondants():
""" """
Permet d'afficher une page avec la liste des correspondants des entreprises visibles et une liste des dernières opérations Permet d'afficher une page avec la liste des correspondants des entreprises visibles et une liste des dernières opérations
@ -109,7 +112,7 @@ def correspondants():
correspondants = ( correspondants = (
db.session.query(EntrepriseCorrespondant, Entreprise) db.session.query(EntrepriseCorrespondant, Entreprise)
.join(Entreprise, EntrepriseCorrespondant.entreprise_id == Entreprise.id) .join(Entreprise, EntrepriseCorrespondant.entreprise_id == Entreprise.id)
.filter_by(visible=True) .filter_by(visible=True, active=True)
) )
logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).limit(LOGS_LEN).all() logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).limit(LOGS_LEN).all()
return render_template( return render_template(
@ -129,9 +132,9 @@ def fiche_entreprise(id):
La fiche entreprise comporte les informations de l'entreprise, les correspondants de l'entreprise et La fiche entreprise comporte les informations de l'entreprise, les correspondants de l'entreprise et
les offres de l'entreprise. les offres de l'entreprise.
""" """
entreprise = Entreprise.query.filter_by(id=id, visible=True).first_or_404( entreprise = Entreprise.query.filter_by(
description=f"fiche entreprise {id} inconnue" id=id, visible=True, active=True
) ).first_or_404(description=f"fiche entreprise {id} inconnue")
offres_with_files = [] offres_with_files = []
depts = are.get_depts() depts = are.get_depts()
for offre in entreprise.offres: for offre in entreprise.offres:
@ -145,7 +148,7 @@ def fiche_entreprise(id):
offre_with_files = are.get_offre_files_and_depts(offre, depts) offre_with_files = are.get_offre_files_and_depts(offre, depts)
if offre_with_files is not None: if offre_with_files is not None:
offres_with_files.append(offre_with_files) offres_with_files.append(offre_with_files)
correspondants = entreprise.correspondants[:] sites = entreprise.sites[:]
logs = ( logs = (
EntrepriseLog.query.order_by(EntrepriseLog.date.desc()) EntrepriseLog.query.order_by(EntrepriseLog.date.desc())
.filter_by(object=id) .filter_by(object=id)
@ -163,7 +166,7 @@ def fiche_entreprise(id):
"entreprises/fiche_entreprise.html", "entreprises/fiche_entreprise.html",
title="Fiche entreprise", title="Fiche entreprise",
entreprise=entreprise, entreprise=entreprise,
correspondants=correspondants, sites=sites,
offres=offres_with_files, offres=offres_with_files,
logs=logs, logs=logs,
stages_apprentissages=stages_apprentissages, stages_apprentissages=stages_apprentissages,
@ -294,16 +297,31 @@ def add_entreprise():
) )
db.session.add(entreprise) db.session.add(entreprise)
db.session.commit() db.session.commit()
if form.nom_correspondant.data.strip():
db.session.refresh(entreprise) db.session.refresh(entreprise)
site = EntrepriseSite(
entreprise_id=entreprise.id,
nom=form.nom_entreprise.data.strip(),
adresse=form.adresse.data.strip(),
codepostal=form.codepostal.data.strip(),
ville=form.ville.data.strip(),
pays=form.pays.data.strip() if form.pays.data.strip() else "FRANCE",
)
db.session.add(site)
db.session.commit()
if form.nom_correspondant.data.strip():
db.session.refresh(site)
correspondant = EntrepriseCorrespondant( correspondant = EntrepriseCorrespondant(
entreprise_id=entreprise.id, entreprise_id=entreprise.id,
site_id=site.id,
civilite=form.civilite.data,
nom=form.nom_correspondant.data.strip(), nom=form.nom_correspondant.data.strip(),
prenom=form.prenom_correspondant.data.strip(), prenom=form.prenom_correspondant.data.strip(),
telephone=form.telephone.data.strip(), telephone=form.telephone.data.strip(),
mail=form.mail.data.strip(), mail=form.mail.data.strip(),
poste=form.poste.data.strip(), poste=form.poste.data.strip(),
service=form.service.data.strip(), service=form.service.data.strip(),
origine=form.origine.data.strip(),
notes=form.notes.data.strip(),
) )
db.session.add(correspondant) db.session.add(correspondant)
if current_user.has_permission(Permission.RelationsEntreprisesValidate, None): if current_user.has_permission(Permission.RelationsEntreprisesValidate, None):
@ -404,39 +422,27 @@ def edit_entreprise(id):
) )
@bp.route("/fiche_entreprise/delete_entreprise/<int:id>", methods=["GET", "POST"]) @bp.route("/fiche_entreprise/desactiver/<int:id>", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntreprisesChange)
def delete_entreprise(id): def fiche_entreprise_desactiver(id):
""" """
Permet de supprimer une entreprise de la base avec un formulaire de confirmation Permet de désactiver une entreprise
""" """
entreprise = Entreprise.query.filter_by(id=id, visible=True).first_or_404( entreprise = Entreprise.query.filter_by(id=id, visible=True).first_or_404(
description=f"entreprise {id} inconnue" description=f"entreprise {id} inconnue"
) )
form = SuppressionConfirmationForm() form = DesactivationConfirmationForm()
if form.validate_on_submit(): if form.validate_on_submit():
db.session.delete(entreprise) entreprise.notes_active = form.notes_active.data.strip()
# supprime les fichiers attachés aux offres entreprise.active = False
path = os.path.join(
Config.SCODOC_VAR_DIR,
"entreprises",
f"{entreprise.id}",
)
if os.path.isdir(path):
shutil.rmtree(path)
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() db.session.commit()
flash("L'entreprise a été supprimé de la liste.") flash("L'entreprise a été désactivé.")
return redirect(url_for("entreprises.index")) return redirect(url_for("entreprises.index"))
return render_template( return render_template(
"entreprises/delete_confirmation.html", "entreprises/confirmation_form.html",
title="Supression entreprise", title="Désactiver entreprise",
form=form, form=form,
info_message="Cliquez sur le bouton Désactiver pour confirmer la désactivation",
) )
@ -489,9 +495,10 @@ def delete_validation_entreprise(id):
flash("L'entreprise a été supprimé de la liste des entreprise à valider.") flash("L'entreprise a été supprimé de la liste des entreprise à valider.")
return redirect(url_for("entreprises.validation")) return redirect(url_for("entreprises.validation"))
return render_template( return render_template(
"entreprises/delete_confirmation.html", "entreprises/confirmation_form.html",
title="Supression entreprise", title="Supression entreprise",
form=form, form=form,
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
) )
@ -645,9 +652,10 @@ def delete_offre(id):
flash("L'offre a été supprimé de la fiche entreprise.") flash("L'offre a été supprimé de la fiche entreprise.")
return redirect(url_for("entreprises.fiche_entreprise", id=entreprise_id)) return redirect(url_for("entreprises.fiche_entreprise", id=entreprise_id))
return render_template( return render_template(
"entreprises/delete_confirmation.html", "entreprises/confirmation_form.html",
title="Supression offre", title="Supression offre",
form=form, form=form,
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
) )
@ -683,26 +691,66 @@ def expired(id):
return redirect(url_for("entreprises.fiche_entreprise", id=offre.entreprise_id)) return redirect(url_for("entreprises.fiche_entreprise", id=offre.entreprise_id))
@bp.route("/fiche_entreprise/<int:id>/add_correspondant", methods=["GET", "POST"]) @bp.route(
"/fiche_entreprise/<int:id>/add_site",
methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntreprisesChange)
def add_correspondant(id): def add_site(id):
entreprise = Entreprise.query.filter_by(id=id, visible=True).first_or_404(
description=f"entreprise {id} inconnue"
)
form = SiteCreationForm()
if form.validate_on_submit():
site = EntrepriseSite(
entreprise_id=entreprise.id,
nom=form.nom.data.strip(),
adresse=form.adresse.data.strip(),
codepostal=form.codepostal.data.strip(),
ville=form.ville.data.strip(),
pays=form.pays.data.strip() if form.pays.data.strip() else "FRANCE",
)
db.session.add(site)
db.session.commit()
flash("Le site a été créé et ajouté à la fiche entreprise")
return redirect(url_for("entreprises.fiche_entreprise", id=entreprise.id))
return render_template(
"entreprises/form.html",
title="Ajout site",
form=form,
)
@bp.route(
"/fiche_entreprise/<int:id_entreprise>/add_correspondant/<int:id_site>",
methods=["GET", "POST"],
)
@permission_required(Permission.RelationsEntreprisesChange)
def add_correspondant(id_entreprise, id_site):
""" """
Permet d'ajouter un correspondant a une entreprise Permet d'ajouter un correspondant a une entreprise
""" """
entreprise = Entreprise.query.filter_by(id=id, visible=True).first_or_404( entreprise = Entreprise.query.filter_by(
description=f"entreprise {id} inconnue" id=id_entreprise, visible=True
).first_or_404(description=f"entreprise {id_entreprise} inconnue")
site = EntrepriseSite.query.filter_by(id=id_site).first_or_404(
description=f"site {id_site} inconnue"
) )
form = CorrespondantsCreationForm(hidden_entreprise_id=entreprise.id) form = CorrespondantsCreationForm(hidden_entreprise_id=entreprise.id)
if form.validate_on_submit(): if form.validate_on_submit():
for correspondant_entry in form.correspondants.entries: for correspondant_entry in form.correspondants.entries:
correspondant = EntrepriseCorrespondant( correspondant = EntrepriseCorrespondant(
entreprise_id=entreprise.id, entreprise_id=entreprise.id,
site_id=site.id,
civilite=correspondant_entry.civilite.data,
nom=correspondant_entry.nom.data.strip(), nom=correspondant_entry.nom.data.strip(),
prenom=correspondant_entry.prenom.data.strip(), prenom=correspondant_entry.prenom.data.strip(),
telephone=correspondant_entry.telephone.data.strip(), telephone=correspondant_entry.telephone.data.strip(),
mail=correspondant_entry.mail.data.strip(), mail=correspondant_entry.mail.data.strip(),
poste=correspondant_entry.poste.data.strip(), poste=correspondant_entry.poste.data.strip(),
service=correspondant_entry.service.data.strip(), service=correspondant_entry.service.data.strip(),
origine=correspondant_entry.origine.data.strip(),
notes=correspondant_entry.notes.data.strip(),
) )
log = EntrepriseLog( log = EntrepriseLog(
authenticated_user=current_user.user_name, authenticated_user=current_user.user_name,
@ -735,12 +783,15 @@ def edit_correspondant(id):
hidden_correspondant_id=correspondant.id, hidden_correspondant_id=correspondant.id,
) )
if form.validate_on_submit(): if form.validate_on_submit():
correspondant.civilite = form.civilite.data
correspondant.nom = form.nom.data.strip() correspondant.nom = form.nom.data.strip()
correspondant.prenom = form.prenom.data.strip() correspondant.prenom = form.prenom.data.strip()
correspondant.telephone = form.telephone.data.strip() correspondant.telephone = form.telephone.data.strip()
correspondant.mail = form.mail.data.strip() correspondant.mail = form.mail.data.strip()
correspondant.poste = form.poste.data.strip() correspondant.poste = form.poste.data.strip()
correspondant.service = form.service.data.strip() correspondant.service = form.service.data.strip()
correspondant.origine = form.origine.data.strip()
correspondant.notes = form.notes.data.strip()
log = EntrepriseLog( log = EntrepriseLog(
authenticated_user=current_user.user_name, authenticated_user=current_user.user_name,
object=correspondant.entreprise_id, object=correspondant.entreprise_id,
@ -750,15 +801,18 @@ def edit_correspondant(id):
db.session.commit() db.session.commit()
flash("Le correspondant a été modifié.") flash("Le correspondant a été modifié.")
return redirect( return redirect(
url_for("entreprises.fiche_entreprise", id=correspondant.entreprise.id) url_for("entreprises.fiche_entreprise", id=correspondant.entreprise_id)
) )
elif request.method == "GET": elif request.method == "GET":
form.civilite.data = correspondant.civilite
form.nom.data = correspondant.nom form.nom.data = correspondant.nom
form.prenom.data = correspondant.prenom form.prenom.data = correspondant.prenom
form.telephone.data = correspondant.telephone form.telephone.data = correspondant.telephone
form.mail.data = correspondant.mail form.mail.data = correspondant.mail
form.poste.data = correspondant.poste form.poste.data = correspondant.poste
form.service.data = correspondant.service form.service.data = correspondant.service
form.origine.data = correspondant.origine
form.notes.data = correspondant.notes
return render_template( return render_template(
"entreprises/form.html", "entreprises/form.html",
title="Modification correspondant", title="Modification correspondant",
@ -790,9 +844,10 @@ def delete_correspondant(id):
url_for("entreprises.fiche_entreprise", id=correspondant.entreprise_id) url_for("entreprises.fiche_entreprise", id=correspondant.entreprise_id)
) )
return render_template( return render_template(
"entreprises/delete_confirmation.html", "entreprises/confirmation_form.html",
title="Supression correspondant", title="Supression correspondant",
form=form, form=form,
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
) )
@ -1016,9 +1071,10 @@ def delete_stage_apprentissage(id):
) )
) )
return render_template( return render_template(
"entreprises/delete_confirmation.html", "entreprises/confirmation_form.html",
title="Supression stage/apprentissage", title="Supression stage/apprentissage",
form=form, form=form,
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
) )
@ -1243,12 +1299,15 @@ def export_correspondants():
) )
if correspondants: if correspondants:
keys = [ keys = [
"civilite",
"nom", "nom",
"prenom", "prenom",
"telephone", "telephone",
"mail", "mail",
"poste", "poste",
"service", "service",
"origine",
"notes",
"entreprise_siret", "entreprise_siret",
] ]
titles = keys[:] titles = keys[:]
@ -1272,12 +1331,15 @@ def get_import_correspondants_file_sample():
Permet de récupérer un fichier exemple vide pour pouvoir importer des correspondants Permet de récupérer un fichier exemple vide pour pouvoir importer des correspondants
""" """
keys = [ keys = [
"civilite",
"nom", "nom",
"prenom", "prenom",
"telephone", "telephone",
"mail", "mail",
"poste", "poste",
"service", "service",
"origine",
"notes",
"entreprise_siret", "entreprise_siret",
] ]
titles = keys[:] titles = keys[:]
@ -1306,12 +1368,15 @@ def import_correspondants():
correspondant_list = [] correspondant_list = []
ligne = 0 ligne = 0
titles = [ titles = [
"civilite",
"nom", "nom",
"prenom", "prenom",
"telephone", "telephone",
"mail", "mail",
"poste", "poste",
"service", "service",
"origine",
"notes",
"entreprise_siret", "entreprise_siret",
] ]
if data[1][0] != titles: if data[1][0] != titles:
@ -1326,29 +1391,32 @@ def import_correspondants():
if ( if (
are.verif_correspondant_data(correspondant_data) are.verif_correspondant_data(correspondant_data)
and ( and (
correspondant_data[0].strip(),
correspondant_data[1].strip(), correspondant_data[1].strip(),
correspondant_data[6].strip(), correspondant_data[2].strip(),
correspondant_data[9].strip(),
) )
not in correspondant_list not in correspondant_list
): ):
correspondant_list.append( correspondant_list.append(
( (
correspondant_data[0].strip(),
correspondant_data[1].strip(), correspondant_data[1].strip(),
correspondant_data[6].strip(), correspondant_data[2].strip(),
correspondant_data[9].strip(),
) )
) )
entreprise = Entreprise.query.filter_by( entreprise = Entreprise.query.filter_by(
siret=correspondant_data[6].strip() siret=correspondant_data[9].strip()
).first() ).first()
correspondant = EntrepriseCorrespondant( correspondant = EntrepriseCorrespondant(
nom=correspondant_data[0].strip(), civilite=correspondant_data[0].strip(),
prenom=correspondant_data[1].strip(), nom=correspondant_data[1].strip(),
telephone=correspondant_data[2].strip(), prenom=correspondant_data[2].strip(),
mail=correspondant_data[3].strip(), telephone=correspondant_data[3].strip(),
poste=correspondant_data[4].strip(), mail=correspondant_data[4].strip(),
service=correspondant_data[5].strip(), poste=correspondant_data[5].strip(),
service=correspondant_data[6].strip(),
origine=correspondant_data[7].strip(),
notes=correspondant_data[8].strip(),
entreprise_id=entreprise.id, entreprise_id=entreprise.id,
) )
correspondants_import.append(correspondant) correspondants_import.append(correspondant)
@ -1480,9 +1548,10 @@ def delete_offre_file(offre_id, filedir):
url_for("entreprises.fiche_entreprise", id=offre.entreprise_id) url_for("entreprises.fiche_entreprise", id=offre.entreprise_id)
) )
return render_template( return render_template(
"entreprises/delete_confirmation.html", "entreprises/confirmation_form.html",
title="Suppression fichier d'une offre", title="Suppression fichier d'une offre",
form=form, form=form,
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
) )

View File

@ -47,6 +47,7 @@ _SCO_PERMISSIONS = (
), ),
(1 << 25, "RelationsEntreprisesSend", "Envoyer des offres"), (1 << 25, "RelationsEntreprisesSend", "Envoyer des offres"),
(1 << 26, "RelationsEntreprisesValidate", "Valide les entreprises"), (1 << 26, "RelationsEntreprisesValidate", "Valide les entreprises"),
(1 << 27, "RelationsEntreprisesCorrespondants", "Voir les correspondants"),
) )

View File

@ -62,7 +62,11 @@ SCO_ROLES_DEFAULTS = {
# ObservateurEntreprise est un observateur de l'application entreprise # ObservateurEntreprise est un observateur de l'application entreprise
"ObservateurEntreprise": (p.RelationsEntreprisesView,), "ObservateurEntreprise": (p.RelationsEntreprisesView,),
# UtilisateurEntreprise est un utilisateur de l'application entreprise (droit de modification) # UtilisateurEntreprise est un utilisateur de l'application entreprise (droit de modification)
"UtilisateurEntreprise": (p.RelationsEntreprisesView, p.RelationsEntreprisesChange), "UtilisateurEntreprise": (
p.RelationsEntreprisesView,
p.RelationsEntreprisesChange,
p.RelationsEntreprisesCorrespondants,
),
# AdminEntreprise est un admin de l'application entreprise (toutes les actions possibles de l'application) # AdminEntreprise est un admin de l'application entreprise (toutes les actions possibles de l'application)
"AdminEntreprise": ( "AdminEntreprise": (
p.RelationsEntreprisesView, p.RelationsEntreprisesView,
@ -70,6 +74,7 @@ SCO_ROLES_DEFAULTS = {
p.RelationsEntreprisesExport, p.RelationsEntreprisesExport,
p.RelationsEntreprisesSend, p.RelationsEntreprisesSend,
p.RelationsEntreprisesValidate, p.RelationsEntreprisesValidate,
p.RelationsEntreprisesCorrespondants,
), ),
# Super Admin est un root: création/suppression de départements # Super Admin est un root: création/suppression de départements
# _tous_ les droits # _tous_ les droits

View File

@ -40,6 +40,11 @@
*background-color: #151515; *background-color: #151515;
} }
.btn-remove {
margin-top: 5px;
margin-bottom: 5px;
}
.fiche-entreprise .btn { .fiche-entreprise .btn {
margin-top: 5px; margin-top: 5px;
margin-bottom: 5px; margin-bottom: 5px;
@ -54,23 +59,24 @@
margin-bottom: -5px; margin-bottom: -5px;
} }
.entreprise, .correspondant, .offre { .entreprise, .correspondant, .offre, .site{
border: solid 2px; border: solid 2px;
border-radius: 10px; border-radius: 10px;
padding: 10px; padding: 10px;
margin-bottom: 10px; margin-bottom: 10px;
margin-top: 10px;
} }
.correspondants-et-offres { .sites-et-offres {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
} }
.correspondants-et-offres > div { .sites-et-offres > div {
flex: 1 0 0; flex: 1 0 0;
} }
.correspondants-et-offres > div:nth-child(2) { .sites-et-offres > div:nth-child(2) {
margin-left: 20px; margin-left: 20px;
} }

View File

@ -1,6 +1,7 @@
{# -*- mode: jinja-html -*- #} {# -*- mode: jinja-html -*- #}
<div class="correspondant"> <div class="correspondant">
<div> <div>
Civilité : {{ correspondant.civilite|get_civilité }}<br>
Nom : {{ correspondant.nom }}<br> Nom : {{ correspondant.nom }}<br>
Prénom : {{ correspondant.prenom }}<br> Prénom : {{ correspondant.prenom }}<br>
{% if correspondant.telephone %} {% if correspondant.telephone %}
@ -15,6 +16,12 @@
{% if correspondant.service %} {% if correspondant.service %}
Service : {{ correspondant.service }}<br> Service : {{ correspondant.service }}<br>
{% endif %} {% endif %}
{% if correspondant.origine %}
Origine : {{ correspondant.origine }}<br>
{% endif %}
{% if correspondant.notes %}
Notes : {{ correspondant.notes }}<br>
{% endif %}
</div> </div>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}

View File

@ -1,6 +1,6 @@
{# -*- mode: jinja-html -*- #} {# -*- mode: jinja-html -*- #}
<div class="offre"> <div class="offre">
<div> <div style="word-break:break-all; text-align: justify;">
Ajouté le {{ offre[0].date_ajout.strftime('%d/%m/%y') }} à {{ offre[0].date_ajout.strftime('%Hh%M') }}<br> Ajouté le {{ offre[0].date_ajout.strftime('%d/%m/%y') }} à {{ offre[0].date_ajout.strftime('%Hh%M') }}<br>
Intitulé : {{ offre[0].intitule }}<br> Intitulé : {{ offre[0].intitule }}<br>
Description : {{ offre[0].description }}<br> Description : {{ offre[0].description }}<br>

View File

@ -35,6 +35,14 @@
</div> </div>
<script> <script>
let allCorrepondantsFieldWrapper = document.getElementById('correspondants');
let allCorrepondantsForm = allCorrepondantsFieldWrapper.getElementsByTagName('li');
for(let i = 0; i < allCorrepondantsForm.length; i++) {
let form_id = allCorrepondantsForm[i].getElementsByTagName('table')[0].id
if(form_id.split('-')[1] != 0)
allCorrepondantsForm[i].insertAdjacentHTML('beforeend', `<div class="btn btn-default btn-remove" onclick="deleteForm('${form_id}')">Retirer ce correspondant</div>`)
}
window.onload = function(e) { window.onload = function(e) {
let addCorrespondantFieldBtn = document.getElementById('add-correspondant-field'); let addCorrespondantFieldBtn = document.getElementById('add-correspondant-field');
addCorrespondantFieldBtn.addEventListener('click', function(e){ addCorrespondantFieldBtn.addEventListener('click', function(e){
@ -48,9 +56,16 @@
} }
let newFieldName = `correspondants-${Math.max(...correspondantInputIds) + 1}`; let newFieldName = `correspondants-${Math.max(...correspondantInputIds) + 1}`;
allCorrepondantsFieldWrapper.insertAdjacentHTML('beforeend',` allCorrepondantsFieldWrapper.insertAdjacentHTML('beforeend',`
<li><label for="${newFieldName}">Correspondants-${Math.max(...correspondantInputIds) + 1}</label> <table id="${newFieldName}"><tr><th><label for="${newFieldName}-nom">Nom (*)</label></th><td><input class="form-control" id="${newFieldName}-nom" name="${newFieldName}-nom" required type="text" value=""></td></tr><tr><th><label for="${newFieldName}-prenom">Prénom (*)</label></th><td><input class="form-control" id="${newFieldName}-prenom" name="${newFieldName}-prenom" required type="text" value=""></td></tr><tr><th><label for="${newFieldName}-telephone">Téléphone (*)</label></th><td><input class="form-control" id="${newFieldName}-telephone" name="${newFieldName}-telephone" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-mail">Mail (*)</label></th><td><input class="form-control" id="${newFieldName}-mail" name="${newFieldName}-mail" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-poste">Poste</label></th><td><input class="form-control" id="${newFieldName}-poste" name="${newFieldName}-poste" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-service">Service</label></th><td><input class="form-control" id="${newFieldName}-service" name="${newFieldName}-service" type="text" value=""></td></tr></table><input id="${newFieldName}-csrf_token" name="${newFieldName}-csrf_token" type="hidden" value=${csrf_token}></li> <li><label for="${newFieldName}">Correspondants-${Math.max(...correspondantInputIds) + 1}</label><table id="${newFieldName}"><tr><th><label for="${newFieldName}-civilite">Civilité (*)</label></th><td><select class="form-control" id="${newFieldName}-civilite" name="${newFieldName}-civilite" required><option value="H">Monsieur</option><option value="F">Madame</option></select></td></tr><tr><th><label for="${newFieldName}-nom">Nom (*)</label></th><td><input class="form-control" id="${newFieldName}-nom" name="${newFieldName}-nom" required type="text" value=""></td></tr><tr><th><label for="${newFieldName}-prenom">Prénom (*)</label></th><td><input class="form-control" id="${newFieldName}-prenom" name="${newFieldName}-prenom" required type="text" value=""></td></tr><tr><th><label for="${newFieldName}-telephone">Téléphone (*)</label></th><td><input class="form-control" id="${newFieldName}-telephone" name="${newFieldName}-telephone" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-mail">Mail (*)</label></th><td><input class="form-control" id="${newFieldName}-mail" name="${newFieldName}-mail" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-poste">Poste</label></th><td><input class="form-control" id="${newFieldName}-poste" name="${newFieldName}-poste" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-service">Service</label></th><td><input class="form-control" id="${newFieldName}-service" name="${newFieldName}-service" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-origine">Origine</label></th><td><input class="form-control" id="${newFieldName}-origine" name="${newFieldName}-origine" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-notes">Notes</label></th><td><input class="form-control" id="${newFieldName}-notes" name="${newFieldName}-notes" type="text" value=""></td></tr></table><input id="${newFieldName}-csrf_token" name="${newFieldName}-csrf_token" type="hidden" value=${csrf_token}><div class="btn btn-default btn-remove" onclick="deleteForm('${newFieldName}')">Retirer ce correspondant</div></li>
`); `);
}); });
} }
function deleteForm(x) {
var li_form = document.querySelector(`label[for=${x}]`).closest('li');
if (li_form) {
li_form.remove()
}
}
</script> </script>
{% endblock %} {% endblock %}

View File

@ -5,7 +5,7 @@
{% block app_content %} {% block app_content %}
<h1>{{ title }}</h1> <h1>{{ title }}</h1>
<br> <br>
<div style="color:red;">Cliquez sur le bouton Supprimer pour confirmer votre supression</div> <div style="color:red;">{{ info_message }}</div>
<br> <br>
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">

View File

@ -67,7 +67,7 @@
</a> </a>
<ul class="dropdown-menu pull-left"> <ul class="dropdown-menu pull-left">
<li><a href="{{ url_for('entreprises.edit_entreprise', id=entreprise.id) }}">Modifier</a></li> <li><a href="{{ url_for('entreprises.edit_entreprise', id=entreprise.id) }}">Modifier</a></li>
<li><a href="{{ url_for('entreprises.delete_entreprise', id=entreprise.id) }}" style="color:red">Supprimer</a></li> <li><a href="{{ url_for('entreprises.fiche_entreprise_desactiver', id=entreprise.id)}}" style="color:red">Désactiver</a></li>
</ul> </ul>
</div> </div>
</td> </td>

View File

@ -36,6 +36,14 @@
</div> </div>
<script> <script>
let allResponsablesFieldWrapper = document.getElementById('responsables');
let allResponsablesField = allResponsablesFieldWrapper.getElementsByTagName('li');
for(let i = 0; i < allResponsablesField.length; i++) {
let form_id = allResponsablesField[i].getElementsByTagName('input')[0].id
if(form_id.split('-')[1] != 0)
allResponsablesField[i].insertAdjacentHTML('beforeend', `<div class="btn btn-default btn-remove" onclick="deleteForm('${form_id}')">Retirer</div>`)
}
window.onload = function(e) { window.onload = function(e) {
var responsables_options = { var responsables_options = {
script: "/ScoDoc/entreprises/responsables?", script: "/ScoDoc/entreprises/responsables?",
@ -63,10 +71,17 @@
} }
let newFieldName = `responsables-${Math.max(...responsableInputIds) + 1}`; let newFieldName = `responsables-${Math.max(...responsableInputIds) + 1}`;
allResponsablesFieldWrapper.insertAdjacentHTML('beforeend',` allResponsablesFieldWrapper.insertAdjacentHTML('beforeend',`
<li><label for="${newFieldName}">Responsable (*)</label> <input class="form-control" id="${newFieldName}" name="${newFieldName}" type="text" value="" placeholder="Tapez le nom du responsable de formation"></li> <li><label for="${newFieldName}">Responsable (*)</label><input class="form-control" id="${newFieldName}" name="${newFieldName}" type="text" value="" placeholder="Tapez le nom du responsable de formation"><div class="btn btn-default btn-remove" onclick="deleteForm('${newFieldName}')">Retirer</div></li>
`); `);
var as_r = new bsn.AutoSuggest(newFieldName, responsables_options); var as_r = new bsn.AutoSuggest(newFieldName, responsables_options);
}); });
} }
function deleteForm(x) {
var li_form = document.querySelector(`label[for=${x}]`).closest('li');
if (li_form) {
li_form.remove()
}
}
</script> </script>
{% endblock %} {% endblock %}

View File

@ -37,25 +37,39 @@
</div> </div>
</div> </div>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
<div> <div>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
<a class="btn btn-primary" href="{{ url_for('entreprises.edit_entreprise', id=entreprise.id) }}">Modifier</a> <a class="btn btn-primary" href="{{ url_for('entreprises.edit_entreprise', id=entreprise.id) }}">Modifier</a>
<a class="btn btn-danger" href="{{ url_for('entreprises.delete_entreprise', id=entreprise.id) }}">Supprimer</a> <a class="btn btn-danger" href="{{ url_for('entreprises.fiche_entreprise_desactiver', id=entreprise.id) }}">Désactiver</a>
<a class="btn btn-primary" href="{{ url_for('entreprises.add_site', id=entreprise.id) }}">Ajouter site</a>
<a class="btn btn-primary" href="{{ url_for('entreprises.add_offre', id=entreprise.id) }}">Ajouter offre</a> <a class="btn btn-primary" href="{{ url_for('entreprises.add_offre', id=entreprise.id) }}">Ajouter offre</a>
<a class="btn btn-primary" href="{{ url_for('entreprises.add_correspondant', id=entreprise.id) }}">Ajouter correspondant</a>
{% endif %} {% endif %}
<a class="btn btn-primary" href="{{ url_for('entreprises.contacts', id=entreprise.id) }}">Liste contacts</a> <a class="btn btn-primary" href="{{ url_for('entreprises.contacts', id=entreprise.id) }}">Liste contacts</a>
<a class="btn btn-primary" href="{{ url_for('entreprises.offres_expirees', id=entreprise.id) }}">Voir les offres expirées</a> <a class="btn btn-primary" href="{{ url_for('entreprises.offres_expirees', id=entreprise.id) }}">Voir les offres expirées</a>
<div> </div>
<div class="correspondants-et-offres"> <div class="sites-et-offres">
{% if correspondants %} {% if sites %}
<div> <div>
<h3>Correspondants</h3> <h3>Sites</h3>
{% for correspondant in correspondants %} {% for site in sites %}
<div class="site">
Nom : {{ site.nom }}<br>
Adresse : {{ site.adresse }}<br>
Code postal : {{ site.codepostal }}<br>
Ville : {{ site.ville }}<br>
Pays : {{ site.pays }}
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
<br><a class="btn btn-primary" href="{{ url_for('entreprises.add_correspondant', id_entreprise=entreprise.id, id_site=site.id) }}">Ajouter correspondant</a>
{% endif %}
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesCorrespondants, None) %}
{% for correspondant in site.correspondants %}
{% include 'entreprises/_correspondant.html' %} {% include 'entreprises/_correspondant.html' %}
{% endfor %} {% endfor %}
{% endif %}
</div>
{% endfor %}
</div> </div>
{% endif %} {% endif %}
@ -71,20 +85,20 @@
</div> </div>
<div style="margin-bottom: 10px;"> <div style="margin-bottom: 10px;">
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
<a class="btn btn-primary" href="{{ url_for('entreprises.add_stage_apprentissage', id=entreprise.id) }}">Ajouter stage ou apprentissage</a>
{% endif %}
<h3>Liste des stages et apprentissages réalisés au sein de l'entreprise</h3> <h3>Liste des stages et apprentissages réalisés au sein de l'entreprise</h3>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
<a class="btn btn-primary" href="{{ url_for('entreprises.add_stage_apprentissage', id=entreprise.id) }}" style="margin-bottom:10px;">Ajouter stage ou apprentissage</a>
{% endif %}
<table id="table-stages-apprentissages"> <table id="table-stages-apprentissages">
<thead> <thead>
<tr> <tr>
<td data-priority="">Date début</td> <td data-priority="3">Date début</td>
<td data-priority="">Date fin</td> <td data-priority="4">Date fin</td>
<td data-priority="">Durée</td> <td data-priority="5">Durée</td>
<td data-priority="">Type</td> <td data-priority="2">Type</td>
<td data-priority="">Étudiant</td> <td data-priority="1">Étudiant</td>
<td data-priority="">Formation</td> <td data-priority="6">Formation</td>
<td data-priority="">Notes</td> <td data-priority="7">Notes</td>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
<td data-priority="3">Action</td> <td data-priority="3">Action</td>
{% endif %} {% endif %}

View File

@ -23,15 +23,15 @@
<script> <script>
{# pour les formulaires offre #} {# pour les formulaires offre #}
var champ_depts = document.getElementById("depts") var champ_depts = document.getElementById("depts")
if (champ_depts !== null) { if (champ_depts) {
var closest_form_control = champ_depts.closest(".form-control") var closest_form_control = champ_depts.closest(".form-control")
closest_form_control.classList.remove("form-control") closest_form_control.classList.remove("form-control")
} }
if(document.getElementById("expiration_date") !== null && document.getElementById("expiration_date").value === "") if(document.getElementById("expiration_date") && document.getElementById("expiration_date").value === "")
expiration() expiration()
if(document.getElementById("type_offre") !== null) if(document.getElementById("type_offre"))
document.getElementById("type_offre").addEventListener("change", expiration); document.getElementById("type_offre").addEventListener("change", expiration);
function expiration() { function expiration() {

View File

@ -25,13 +25,16 @@
{% if not correspondants_import %} {% if not correspondants_import %}
<table class="table"> <table class="table">
<thead><tr><td><b>Attribut</b></td><td><b>Type</b></td><td><b>Description</b></td></tr></thead> <thead><tr><td><b>Attribut</b></td><td><b>Type</b></td><td><b>Description</b></td></tr></thead>
<tr><td>civilite</td><td>text</td><td>civilite du correspondant (H ou F)</td></tr>
<tr><td>nom</td><td>text</td><td>nom du correspondant</td></tr> <tr><td>nom</td><td>text</td><td>nom du correspondant</td></tr>
<tr><td>prenom</td><td>text</td><td>prenom du correspondant</td></tr> <tr><td>prenom</td><td>text</td><td>prenom du correspondant</td></tr>
<tr><td>telephone</td><td>text</td><td>telephone du correspondant</td></tr> <tr><td>telephone</td><td>text</td><td>telephone du correspondant</td></tr>
<tr><td>mail</td><td>text</td><td>mail du correspondant</td></tr> <tr><td>mail</td><td>text</td><td>mail du correspondant</td></tr>
<tr><td>poste</td><td>text</td><td>poste du correspondant</td></tr> <tr><td>poste</td><td>text</td><td>poste du correspondant</td></tr>
<tr><td>service</td><td>text</td><td>service dans lequel travaille le correspondant</td></tr> <tr><td>service</td><td>text</td><td>service dans lequel travaille le correspondant</td></tr>
<tr><td>entreprise_siret</td><td>integer</td><td>SIRET de l'entreprise</td></tr> <tr><td>origine</td><td>text</td><td>origine du correspondant</td></tr>
<tr><td>notes</td><td>text</td><td>notes sur le correspondant</td></tr>
<tr><td>entreprise_siret</td><td>text</td><td>SIRET de l'entreprise</td></tr>
</table> </table>
{% endif %} {% endif %}
@ -40,6 +43,7 @@
{% for correspondant in correspondants_import %} {% for correspondant in correspondants_import %}
<div class="correspondant"> <div class="correspondant">
<div> <div>
Civilité : {{ correspondant.civilite|get_civilité }}<br>
Nom : {{ correspondant.nom }}<br> Nom : {{ correspondant.nom }}<br>
Prénom : {{ correspondant.prenom }}<br> Prénom : {{ correspondant.prenom }}<br>
{% if correspondant.telephone %} {% if correspondant.telephone %}
@ -54,7 +58,13 @@
{% if correspondant.service %} {% if correspondant.service %}
Service : {{ correspondant.service }}<br> Service : {{ correspondant.service }}<br>
{% endif %} {% endif %}
<a href="{{ url_for('entreprises.fiche_entreprise', id=correspondant.entreprise_id )}}">lien vers l'entreprise</a> {% if correspondant.origine %}
Origine : {{ correspondant.origine }}<br>
{% endif %}
{% if correspondant.notes %}
Notes : {{ correspondant.notes }}<br>
{% endif %}
<a href="{{ url_for('entreprises.fiche_entreprise', id=correspondant.entreprise_id )}}" target="_blank">lien vers l'entreprise</a>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}

View File

@ -2,7 +2,9 @@
<nav class="nav-entreprise"> <nav class="nav-entreprise">
<ul> <ul>
<li><a href="{{ url_for('entreprises.index') }}">Entreprises</a></li> <li><a href="{{ url_for('entreprises.index') }}">Entreprises</a></li>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesCorrespondants, None) %}
<li><a href="{{ url_for('entreprises.correspondants') }}">Correspondants</a></li> <li><a href="{{ url_for('entreprises.correspondants') }}">Correspondants</a></li>
{% endif %}
<li><a href="{{ url_for('entreprises.offres_recues') }}">Offres reçues</a></li> <li><a href="{{ url_for('entreprises.offres_recues') }}">Offres reçues</a></li>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesValidate, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntreprisesValidate, None) %}
<li><a href="{{ url_for('entreprises.validation') }}">Entreprises à valider</a></li> <li><a href="{{ url_for('entreprises.validation') }}">Entreprises à valider</a></li>

View File

@ -9,7 +9,7 @@
{% if offres_recues %} {% if offres_recues %}
{% for offre in offres_recues %} {% for offre in offres_recues %}
<div class="offre offre-recue"> <div class="offre offre-recue">
<div> <div style="word-break:break-all; text-align: justify;">
Envoyé le {{ offre[0].date_envoi.strftime('%d/%m/%Y') }} à {{ offre[0].date_envoi.strftime('%Hh%M') }} par {{ offre[0].sender_id|get_nomcomplet_by_id }}<br> Envoyé le {{ offre[0].date_envoi.strftime('%d/%m/%Y') }} à {{ offre[0].date_envoi.strftime('%Hh%M') }} par {{ offre[0].sender_id|get_nomcomplet_by_id }}<br>
Intitulé : {{ offre[1].intitule }}<br> Intitulé : {{ offre[1].intitule }}<br>
Description : {{ offre[1].description }}<br> Description : {{ offre[1].description }}<br>
@ -20,12 +20,20 @@
{% if offre[1].correspondant_id %} {% if offre[1].correspondant_id %}
Contacté {{ offre[3].nom }} {{ offre[3].prenom }} Contacté {{ offre[3].nom }} {{ offre[3].prenom }}
{% if offre[3].mail and offre[3].telephone %} {% if offre[3].mail and offre[3].telephone %}
({{ offre[3].mail }} - {{ offre[3].telephone }})<br> ({{ offre[3].mail }} - {{ offre[3].telephone }})
{% else %} {% else %}
({{ offre[3].mail }}{{offre[3].telephone}})<br> ({{ offre[3].mail }}{{ offre[3].telephone }})
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if offre[3].poste %}
, poste : {{ offre[3].poste }}
{% endif %}
{% if offre[3].service %}
, service : {{ offre[3].service }}
{% endif %}
<br>
<a href="{{ url_for('entreprises.fiche_entreprise', id=offre[1].entreprise_id) }}">lien vers l'entreprise</a><br> <a href="{{ url_for('entreprises.fiche_entreprise', id=offre[1].entreprise_id) }}">lien vers l'entreprise</a><br>
{% for fichier in offre[2] %} {% for fichier in offre[2] %}

View File

@ -0,0 +1,65 @@
"""ajout colonnes tables relations entreprises, sites
Revision ID: d5b3bdd1d622
Revises: e97b2a10f86c
Create Date: 2022-04-25 18:29:50.841280
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "d5b3bdd1d622"
down_revision = "e97b2a10f86c"
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"are_sites",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("entreprise_id", sa.Integer(), nullable=True),
sa.Column("nom", sa.Text(), nullable=True),
sa.Column("adresse", sa.Text(), nullable=True),
sa.Column("codepostal", sa.Text(), nullable=True),
sa.Column("ville", sa.Text(), nullable=True),
sa.Column("pays", sa.Text(), nullable=True),
sa.ForeignKeyConstraint(
["entreprise_id"], ["are_entreprises.id"], ondelete="cascade"
),
sa.PrimaryKeyConstraint("id"),
)
op.add_column(
"are_correspondants", sa.Column("site_id", sa.Integer(), nullable=True)
)
op.add_column(
"are_correspondants", sa.Column("civilite", sa.String(length=1), nullable=True)
)
op.add_column("are_correspondants", sa.Column("origine", sa.Text(), nullable=True))
op.add_column("are_correspondants", sa.Column("notes", sa.Text(), nullable=True))
op.create_foreign_key(
None, "are_correspondants", "are_sites", ["site_id"], ["id"], ondelete="cascade"
)
op.add_column("are_entreprises", sa.Column("active", sa.Boolean(), nullable=True))
op.add_column(
"are_entreprises", sa.Column("notes_active", sa.Text(), nullable=True)
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("are_entreprises", "notes_active")
op.drop_column("are_entreprises", "active")
op.drop_constraint(
"are_correspondants_site_id_fkey", "are_correspondants", type_="foreignkey"
)
op.drop_column("are_correspondants", "notes")
op.drop_column("are_correspondants", "origine")
op.drop_column("are_correspondants", "civilite")
op.drop_column("are_correspondants", "site_id")
op.drop_table("are_sites")
# ### end Alembic commands ###

View File

@ -93,7 +93,9 @@ def upgrade():
def downgrade(): def downgrade():
# ### commands auto generated by Alembic - please adjust! ### # ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, "are_offres", type_="foreignkey") op.drop_constraint(
"are_offres_correspondant_id_fkey", "are_offres", type_="foreignkey"
)
op.drop_column("are_offres", "correspondant_id") op.drop_column("are_offres", "correspondant_id")
op.add_column( op.add_column(
"are_contacts", "are_contacts",
@ -121,8 +123,10 @@ def downgrade():
op.add_column( op.add_column(
"are_contacts", sa.Column("nom", sa.TEXT(), autoincrement=False, nullable=True) "are_contacts", sa.Column("nom", sa.TEXT(), autoincrement=False, nullable=True)
) )
op.drop_constraint(None, "are_contacts", type_="foreignkey") op.drop_constraint(
op.drop_constraint(None, "are_contacts", type_="foreignkey") "are_contacts_entreprise_fkey", "are_contacts", type_="foreignkey"
)
op.drop_constraint("are_contacts_user_fkey", "are_contacts", type_="foreignkey")
op.create_foreign_key( op.create_foreign_key(
"are_contacts_entreprise_id_fkey", "are_contacts_entreprise_id_fkey",
"are_contacts", "are_contacts",