forked from ScoDoc/ScoDoc
Merge branch 'entreprises' of https://scodoc.org/git/arthur.zhu/ScoDoc into entreprises
This commit is contained in:
commit
4d50830bd0
@ -4,10 +4,11 @@
|
||||
from flask import Blueprint
|
||||
from app.scodoc import sco_etud
|
||||
from app.auth.models import User
|
||||
from app.models import Departement
|
||||
|
||||
bp = Blueprint("entreprises", __name__)
|
||||
|
||||
LOGS_LEN = 10
|
||||
LOGS_LEN = 5
|
||||
|
||||
|
||||
@bp.app_template_filter()
|
||||
@ -21,9 +22,21 @@ def format_nom(s):
|
||||
|
||||
|
||||
@bp.app_template_filter()
|
||||
def get_nomcomplet(s):
|
||||
def get_nomcomplet_by_username(s):
|
||||
user = User.query.filter_by(user_name=s).first()
|
||||
return user.get_nomcomplet()
|
||||
|
||||
|
||||
@bp.app_template_filter()
|
||||
def get_nomcomplet_by_id(id):
|
||||
user = User.query.filter_by(id=id).first()
|
||||
return user.get_nomcomplet()
|
||||
|
||||
|
||||
@bp.app_template_filter()
|
||||
def get_dept_acronym(id):
|
||||
dept = Departement.query.filter_by(id=id).first()
|
||||
return dept.acronym
|
||||
|
||||
|
||||
from app.entreprises import routes
|
||||
|
153
app/entreprises/app_relations_entreprises.py
Normal file
153
app/entreprises/app_relations_entreprises.py
Normal file
@ -0,0 +1,153 @@
|
||||
# -*- 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 os
|
||||
from config import Config
|
||||
import re
|
||||
import requests
|
||||
import glob
|
||||
|
||||
from flask_login import current_user
|
||||
|
||||
from app.entreprises.models import (
|
||||
Entreprise,
|
||||
EntrepriseContact,
|
||||
EntrepriseOffre,
|
||||
EntrepriseOffreDepartement,
|
||||
)
|
||||
|
||||
from app.models import Departement
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
|
||||
|
||||
def get_depts():
|
||||
"""
|
||||
Retourne une liste contenant les l'id des départements des roles de l'utilisateur courant
|
||||
"""
|
||||
depts = []
|
||||
for role in current_user.user_roles:
|
||||
dept_id = get_dept_id_by_acronym(role.dept)
|
||||
if dept_id is not None:
|
||||
depts.append(dept_id)
|
||||
return depts
|
||||
|
||||
|
||||
def get_dept_id_by_acronym(acronym):
|
||||
"""
|
||||
Retourne l'id d'un departement a l'aide de son acronym
|
||||
"""
|
||||
dept = Departement.query.filter_by(acronym=acronym).first()
|
||||
if dept is not None:
|
||||
return dept.id
|
||||
return None
|
||||
|
||||
|
||||
def check_offre_depts(depts, offre_depts):
|
||||
"""
|
||||
Retourne vrai si l'utilisateur a le droit de visibilité sur l'offre
|
||||
"""
|
||||
if current_user.has_permission(Permission.RelationsEntreprisesChange, None):
|
||||
return True
|
||||
for offre_dept in offre_depts:
|
||||
if offre_dept.dept_id in depts:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_offre_files_and_depts(offre: EntrepriseOffre, depts: list):
|
||||
"""
|
||||
Retourne l'offre, les fichiers attachés a l'offre et les département liés
|
||||
"""
|
||||
offre_depts = EntrepriseOffreDepartement.query.filter_by(offre_id=offre.id).all()
|
||||
if not offre_depts or check_offre_depts(depts, offre_depts):
|
||||
files = []
|
||||
path = os.path.join(
|
||||
Config.SCODOC_VAR_DIR,
|
||||
"entreprises",
|
||||
f"{offre.entreprise_id}",
|
||||
f"{offre.id}",
|
||||
)
|
||||
if os.path.exists(path):
|
||||
for dir in glob.glob(
|
||||
f"{path}/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]"
|
||||
):
|
||||
for _file in glob.glob(f"{dir}/*"):
|
||||
file = [os.path.basename(dir), os.path.basename(_file)]
|
||||
files.append(file)
|
||||
return [offre, files, offre_depts]
|
||||
return None
|
||||
|
||||
|
||||
def verif_contact_data(contact_data):
|
||||
"""
|
||||
Verifie les données d'une ligne Excel (contact)
|
||||
contact_data[0]: nom
|
||||
contact_data[1]: prenom
|
||||
contact_data[2]: telephone
|
||||
contact_data[3]: mail
|
||||
contact_data[4]: poste
|
||||
contact_data[5]: service
|
||||
contact_data[6]: entreprise_id
|
||||
"""
|
||||
# champs obligatoires
|
||||
if contact_data[0] == "" or contact_data[1] == "" or contact_data[6] == "":
|
||||
return False
|
||||
|
||||
# entreprise_id existant
|
||||
entreprise = Entreprise.query.filter_by(id=contact_data[6]).first()
|
||||
if entreprise is None:
|
||||
return False
|
||||
|
||||
# contact possède le meme nom et prénom dans la meme entreprise
|
||||
contact = EntrepriseContact.query.filter_by(
|
||||
nom=contact_data[0], prenom=contact_data[1], entreprise_id=contact_data[6]
|
||||
).first()
|
||||
if contact is not None:
|
||||
return False
|
||||
|
||||
if contact_data[2] == "" and contact_data[3] == "": # 1 moyen de contact
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def verif_entreprise_data(entreprise_data):
|
||||
"""
|
||||
Verifie les données d'une ligne Excel (entreprise)
|
||||
"""
|
||||
for data in entreprise_data: # champs obligatoires
|
||||
if data == "":
|
||||
return False
|
||||
siret = entreprise_data[0].strip() # vérification sur le siret
|
||||
if re.match("^\d{14}$", siret) is None:
|
||||
return False
|
||||
req = requests.get(f"https://entreprise.data.gouv.fr/api/sirene/v1/siret/{siret}")
|
||||
if req.status_code != 200:
|
||||
return False
|
||||
entreprise = Entreprise.query.filter_by(siret=siret).first()
|
||||
if entreprise is not None:
|
||||
return False
|
||||
return True
|
@ -31,70 +31,76 @@ 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
|
||||
from wtforms.fields import EmailField, DateField
|
||||
from wtforms.validators import ValidationError, DataRequired, Email
|
||||
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
|
||||
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 = StringField(
|
||||
siret = _build_string_field(
|
||||
"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_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 = 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=[DataRequired(message=CHAMP_REQUIS)],
|
||||
)
|
||||
mail = EmailField(
|
||||
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=[
|
||||
DataRequired(message=CHAMP_REQUIS),
|
||||
Email(message="Adresse e-mail invalide"),
|
||||
],
|
||||
validators=[Optional(), Email(message="Adresse e-mail invalide")],
|
||||
)
|
||||
poste = StringField("Poste du contact", validators=[])
|
||||
service = StringField("Service du contact", validators=[])
|
||||
submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"})
|
||||
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) == None:
|
||||
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}"
|
||||
@ -110,22 +116,22 @@ class EntrepriseCreationForm(FlaskForm):
|
||||
|
||||
|
||||
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;"})
|
||||
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 = StringField("Intitulé", validators=[DataRequired(message=CHAMP_REQUIS)])
|
||||
intitule = _build_string_field("Intitulé")
|
||||
description = TextAreaField(
|
||||
"Description", validators=[DataRequired(message=CHAMP_REQUIS)]
|
||||
)
|
||||
@ -134,15 +140,24 @@ class OffreCreationForm(FlaskForm):
|
||||
choices=[("Stage"), ("Alternance")],
|
||||
validators=[DataRequired(message=CHAMP_REQUIS)],
|
||||
)
|
||||
missions = TextAreaField(
|
||||
"Missions", 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)]
|
||||
)
|
||||
duree = StringField("Durée", validators=[DataRequired(message=CHAMP_REQUIS)])
|
||||
submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"})
|
||||
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 = StringField("Intitulé", validators=[DataRequired(message=CHAMP_REQUIS)])
|
||||
intitule = _build_string_field("Intitulé")
|
||||
description = TextAreaField(
|
||||
"Description", validators=[DataRequired(message=CHAMP_REQUIS)]
|
||||
)
|
||||
@ -151,73 +166,104 @@ class OffreModificationForm(FlaskForm):
|
||||
choices=[("Stage"), ("Alternance")],
|
||||
validators=[DataRequired(message=CHAMP_REQUIS)],
|
||||
)
|
||||
missions = TextAreaField(
|
||||
"Missions", 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)]
|
||||
)
|
||||
duree = StringField("Durée", validators=[DataRequired(message=CHAMP_REQUIS)])
|
||||
submit = SubmitField("Modifier", render_kw={"style": "margin-bottom: 10px;"})
|
||||
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 = StringField("Nom", validators=[DataRequired(message=CHAMP_REQUIS)])
|
||||
prenom = StringField("Prénom", validators=[DataRequired(message=CHAMP_REQUIS)])
|
||||
telephone = StringField(
|
||||
"Téléphone", validators=[DataRequired(message=CHAMP_REQUIS)]
|
||||
)
|
||||
mail = EmailField(
|
||||
nom = _build_string_field("Nom")
|
||||
prenom = _build_string_field("Prénom")
|
||||
telephone = _build_string_field("Téléphone", required=False)
|
||||
mail = StringField(
|
||||
"Mail",
|
||||
validators=[
|
||||
DataRequired(message=CHAMP_REQUIS),
|
||||
Email(message="Adresse e-mail invalide"),
|
||||
],
|
||||
validators=[Optional(), Email(message="Adresse e-mail invalide")],
|
||||
)
|
||||
poste = StringField("Poste", validators=[])
|
||||
service = StringField("Service", validators=[])
|
||||
submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"})
|
||||
poste = _build_string_field("Poste", required=False)
|
||||
service = _build_string_field("Service", required=False)
|
||||
submit = SubmitField("Envoyer", render_kw=SUBMIT_MARGE)
|
||||
|
||||
def validate(self):
|
||||
rv = FlaskForm.validate(self)
|
||||
if not rv:
|
||||
return False
|
||||
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("")
|
||||
return False
|
||||
validate = False
|
||||
|
||||
return True
|
||||
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):
|
||||
nom = StringField("Nom", validators=[DataRequired(message=CHAMP_REQUIS)])
|
||||
prenom = StringField("Prénom", validators=[DataRequired(message=CHAMP_REQUIS)])
|
||||
telephone = StringField(
|
||||
"Téléphone", validators=[DataRequired(message=CHAMP_REQUIS)]
|
||||
)
|
||||
mail = EmailField(
|
||||
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=[
|
||||
DataRequired(message=CHAMP_REQUIS),
|
||||
Email(message="Adresse e-mail invalide"),
|
||||
],
|
||||
validators=[Optional(), Email(message="Adresse e-mail invalide")],
|
||||
)
|
||||
poste = StringField("Poste", validators=[])
|
||||
service = StringField("Service", validators=[])
|
||||
submit = SubmitField("Modifier", render_kw={"style": "margin-bottom: 10px;"})
|
||||
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 = StringField(
|
||||
etudiant = _build_string_field(
|
||||
"Étudiant",
|
||||
validators=[DataRequired(message=CHAMP_REQUIS)],
|
||||
render_kw={"placeholder": "Tapez le nom de l'étudiant puis selectionnez"},
|
||||
render_kw={"placeholder": "Tapez le nom de l'étudiant"},
|
||||
)
|
||||
type_offre = SelectField(
|
||||
"Type de l'offre",
|
||||
@ -228,18 +274,23 @@ class HistoriqueCreationForm(FlaskForm):
|
||||
"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;"})
|
||||
submit = SubmitField("Envoyer", render_kw=SUBMIT_MARGE)
|
||||
|
||||
def validate(self):
|
||||
rv = FlaskForm.validate(self)
|
||||
if not rv:
|
||||
return False
|
||||
validate = True
|
||||
if not FlaskForm.validate(self):
|
||||
validate = False
|
||||
|
||||
if self.date_debut.data > self.date_fin.data:
|
||||
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")
|
||||
return False
|
||||
return True
|
||||
validate = False
|
||||
|
||||
return validate
|
||||
|
||||
def validate_etudiant(self, etudiant):
|
||||
etudiant_data = etudiant.data.upper().strip()
|
||||
@ -254,11 +305,11 @@ class HistoriqueCreationForm(FlaskForm):
|
||||
|
||||
|
||||
class EnvoiOffreForm(FlaskForm):
|
||||
responsable = StringField(
|
||||
responsable = _build_string_field(
|
||||
"Responsable de formation",
|
||||
validators=[DataRequired(message=CHAMP_REQUIS)],
|
||||
render_kw={"placeholder": "Tapez le nom du responsable de formation"},
|
||||
)
|
||||
submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"})
|
||||
submit = SubmitField("Envoyer", render_kw=SUBMIT_MARGE)
|
||||
|
||||
def validate_responsable(self, responsable):
|
||||
responsable_data = responsable.data.upper().strip()
|
||||
@ -282,8 +333,23 @@ class AjoutFichierForm(FlaskForm):
|
||||
FileAllowed(["pdf", "docx"], "Fichier .pdf ou .docx uniquement"),
|
||||
],
|
||||
)
|
||||
submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"})
|
||||
submit = SubmitField("Ajouter", render_kw=SUBMIT_MARGE)
|
||||
|
||||
|
||||
class SuppressionConfirmationForm(FlaskForm):
|
||||
submit = SubmitField("Supprimer", render_kw={"style": "margin-bottom: 10px;"})
|
||||
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)
|
||||
|
@ -2,7 +2,7 @@ from app import db
|
||||
|
||||
|
||||
class Entreprise(db.Model):
|
||||
__tablename__ = "entreprises"
|
||||
__tablename__ = "are_entreprises"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
siret = db.Column(db.Text)
|
||||
nom = db.Column(db.Text)
|
||||
@ -10,6 +10,7 @@ class Entreprise(db.Model):
|
||||
codepostal = db.Column(db.Text)
|
||||
ville = db.Column(db.Text)
|
||||
pays = db.Column(db.Text)
|
||||
visible = db.Column(db.Boolean, default=False)
|
||||
contacts = db.relationship(
|
||||
"EntrepriseContact",
|
||||
backref="entreprise",
|
||||
@ -28,17 +29,17 @@ class Entreprise(db.Model):
|
||||
"siret": self.siret,
|
||||
"nom": self.nom,
|
||||
"adresse": self.adresse,
|
||||
"codepostal": self.codepostal,
|
||||
"code_postal": self.codepostal,
|
||||
"ville": self.ville,
|
||||
"pays": self.pays,
|
||||
}
|
||||
|
||||
|
||||
class EntrepriseContact(db.Model):
|
||||
__tablename__ = "entreprise_contact"
|
||||
__tablename__ = "are_entreprise_contact"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
entreprise_id = db.Column(
|
||||
db.Integer, db.ForeignKey("entreprises.id", ondelete="cascade")
|
||||
db.Integer, db.ForeignKey("are_entreprises.id", ondelete="cascade")
|
||||
)
|
||||
nom = db.Column(db.Text)
|
||||
prenom = db.Column(db.Text)
|
||||
@ -55,31 +56,15 @@ class EntrepriseContact(db.Model):
|
||||
"mail": self.mail,
|
||||
"poste": self.poste,
|
||||
"service": self.service,
|
||||
}
|
||||
|
||||
def to_dict_export(self):
|
||||
entreprise = Entreprise.query.get(self.entreprise_id)
|
||||
return {
|
||||
"nom": self.nom,
|
||||
"prenom": self.prenom,
|
||||
"telephone": self.telephone,
|
||||
"mail": self.mail,
|
||||
"poste": self.poste,
|
||||
"service": self.service,
|
||||
"siret": entreprise.siret,
|
||||
"nom_entreprise": entreprise.nom,
|
||||
"adresse_entreprise": entreprise.adresse,
|
||||
"codepostal": entreprise.codepostal,
|
||||
"ville": entreprise.ville,
|
||||
"pays": entreprise.pays,
|
||||
"entreprise_id": self.entreprise_id,
|
||||
}
|
||||
|
||||
|
||||
class EntrepriseOffre(db.Model):
|
||||
__tablename__ = "entreprise_offre"
|
||||
__tablename__ = "are_entreprise_offre"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
entreprise_id = db.Column(
|
||||
db.Integer, db.ForeignKey("entreprises.id", ondelete="cascade")
|
||||
db.Integer, db.ForeignKey("are_entreprises.id", ondelete="cascade")
|
||||
)
|
||||
date_ajout = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
intitule = db.Column(db.Text)
|
||||
@ -87,6 +72,7 @@ class EntrepriseOffre(db.Model):
|
||||
type_offre = db.Column(db.Text)
|
||||
missions = db.Column(db.Text)
|
||||
duree = db.Column(db.Text)
|
||||
expiration_date = db.Column(db.Date)
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
@ -99,7 +85,7 @@ class EntrepriseOffre(db.Model):
|
||||
|
||||
|
||||
class EntrepriseLog(db.Model):
|
||||
__tablename__ = "entreprise_log"
|
||||
__tablename__ = "are_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)
|
||||
@ -108,9 +94,11 @@ class EntrepriseLog(db.Model):
|
||||
|
||||
|
||||
class EntrepriseEtudiant(db.Model):
|
||||
__tablename__ = "entreprise_etudiant"
|
||||
__tablename__ = "are_entreprise_etudiant"
|
||||
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("are_entreprises.id", ondelete="cascade")
|
||||
)
|
||||
etudid = db.Column(db.Integer)
|
||||
type_offre = db.Column(db.Text)
|
||||
date_debut = db.Column(db.Date)
|
||||
@ -120,18 +108,33 @@ class EntrepriseEtudiant(db.Model):
|
||||
|
||||
|
||||
class EntrepriseEnvoiOffre(db.Model):
|
||||
__tablename__ = "entreprise_envoi_offre"
|
||||
__tablename__ = "are_entreprise_envoi_offre"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
sender_id = db.Column(db.Integer, db.ForeignKey("user.id"))
|
||||
receiver_id = db.Column(db.Integer, db.ForeignKey("user.id"))
|
||||
offre_id = db.Column(db.Integer, db.ForeignKey("entreprise_offre.id"))
|
||||
sender_id = db.Column(db.Integer, db.ForeignKey("user.id", ondelete="cascade"))
|
||||
receiver_id = db.Column(db.Integer, db.ForeignKey("user.id", ondelete="cascade"))
|
||||
offre_id = db.Column(
|
||||
db.Integer, db.ForeignKey("are_entreprise_offre.id", ondelete="cascade")
|
||||
)
|
||||
date_envoi = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
|
||||
|
||||
class EntrepriseEnvoiOffreEtudiant(db.Model):
|
||||
__tablename__ = "entreprise_envoi_offre_etudiant"
|
||||
__tablename__ = "are_entreprise_envoi_offre_etudiant"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
sender_id = db.Column(db.Integer, db.ForeignKey("user.id"))
|
||||
receiver_id = db.Column(db.Integer, db.ForeignKey("identite.id"))
|
||||
offre_id = db.Column(db.Integer, db.ForeignKey("entreprise_offre.id"))
|
||||
sender_id = db.Column(db.Integer, db.ForeignKey("user.id", ondelete="cascade"))
|
||||
receiver_id = db.Column(
|
||||
db.Integer, db.ForeignKey("identite.id", ondelete="cascade")
|
||||
)
|
||||
offre_id = db.Column(
|
||||
db.Integer, db.ForeignKey("are_entreprise_offre.id", ondelete="cascade")
|
||||
)
|
||||
date_envoi = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
|
||||
|
||||
class EntrepriseOffreDepartement(db.Model):
|
||||
__tablename__ = "are_entreprise_offre_departement"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
offre_id = db.Column(
|
||||
db.Integer, db.ForeignKey("are_entreprise_offre.id", ondelete="cascade")
|
||||
)
|
||||
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id", ondelete="cascade"))
|
||||
|
File diff suppressed because it is too large
Load Diff
88
app/static/css/entreprises.css
Normal file
88
app/static/css/entreprises.css
Normal file
@ -0,0 +1,88 @@
|
||||
.nav-entreprise>ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.nav-entreprise li{
|
||||
list-style: none;
|
||||
display: inline-block;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.nav-entreprise>ul>li>a {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
padding: 15px;
|
||||
|
||||
}
|
||||
|
||||
.nav-entreprise>ul>li>a:hover {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.boutons .btn {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.btn-inverse {
|
||||
color: #ffffff;
|
||||
text-shadow: 0 -1px 0 rgb(0 0 0 / 25%);
|
||||
background-color: #363636;
|
||||
}
|
||||
|
||||
.btn-inverse:hover {
|
||||
color: #ffffff;
|
||||
background-color: #222222;
|
||||
*background-color: #151515;
|
||||
}
|
||||
|
||||
.fiche-entreprise .btn {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.offre .btn {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.parent-btn {
|
||||
margin-bottom: -5px;
|
||||
}
|
||||
|
||||
.entreprise, .contact, .offre {
|
||||
border: solid 2px;
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.contacts-et-offres {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.contacts-et-offres > div {
|
||||
flex: 1 0 0;
|
||||
}
|
||||
|
||||
.contacts-et-offres > div:nth-child(2) {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
#depts {
|
||||
list-style: none;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.offre-depts {
|
||||
display: inline-block;
|
||||
border: black solid 2px;
|
||||
border-radius: 5px;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.offre-recue {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<link rel="stylesheet" href="/ScoDoc/static/css/scodoc.css">
|
||||
<link rel="stylesheet" href="/ScoDoc/static/css/entreprises.css">
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
@ -35,6 +36,9 @@
|
||||
url_for('scolar.index_html', scodoc_dept=g.scodoc_dept)
|
||||
}}">Dept. {{ g.scodoc_dept }}</a></li>
|
||||
{% endif %}
|
||||
{% if not current_user.is_anonymous and current_user.has_permission(current_user.Permission.RelationsEntreprisesView, None) %}
|
||||
<li><a href="{{ url_for('entreprises.index') }}">Entreprises</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
{% if current_user.is_anonymous %}
|
||||
|
@ -1,20 +1,26 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
<div>
|
||||
<p>
|
||||
<div class="contact">
|
||||
<div>
|
||||
Nom : {{ contact.nom }}<br>
|
||||
Prénom : {{ contact.prenom }}<br>
|
||||
{% if contact.telephone %}
|
||||
Téléphone : {{ contact.telephone }}<br>
|
||||
{% endif %}
|
||||
{% if contact.mail %}
|
||||
Mail : {{ contact.mail }}<br>
|
||||
{% endif %}
|
||||
{% if contact.poste %}
|
||||
Poste : {{ contact.poste }}<br>
|
||||
{% endif %}
|
||||
{% if contact.service %}
|
||||
Service : {{ contact.service }}<br>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 10px;">
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<div class="parent-btn">
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.edit_contact', id=contact.id) }}">Modifier contact</a>
|
||||
<a class="btn btn-danger" href="{{ url_for('entreprises.delete_contact', id=contact.id) }}">Supprimer contact</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
@ -1,21 +1,34 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
<div>
|
||||
<p>
|
||||
<div class="offre">
|
||||
<div>
|
||||
Intitulé : {{ offre[0].intitule }}<br>
|
||||
Description : {{ offre[0].description }}<br>
|
||||
Type de l'offre : {{ offre[0].type_offre }}<br>
|
||||
Missions : {{ offre[0].missions }}<br>
|
||||
Durée : {{ offre[0].duree }}<br>
|
||||
{% if offre[2] %}
|
||||
Département(s) : {% for offre_dept in offre[2] %} <div class="offre-depts">{{ offre_dept.dept_id|get_dept_acronym }}</div> {% endfor %}<br>
|
||||
{% endif %}
|
||||
{% for fichier in offre[1] %}
|
||||
<a href="{{ url_for('entreprises.get_offre_file', entreprise_id=entreprise.id, offre_id=offre[0].id, filedir=fichier[0], filename=fichier[1] )}}">{{ fichier[1] }}</a>
|
||||
<a href="{{ url_for('entreprises.delete_offre_file', offre_id=offre[0].id, filedir=fichier[0] )}}" style="margin-left: 5px;"><img title="Supprimer fichier" alt="supprimer" width="10" height="9" border="0" src="/ScoDoc/static/icons/delete_small_img.png" /></a><br>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<a href="{{ url_for('entreprises.delete_offre_file', offre_id=offre[0].id, filedir=fichier[0] )}}" style="margin-left: 5px;"><img title="Supprimer fichier" alt="supprimer" width="10" height="9" border="0" src="/ScoDoc/static/icons/delete_small_img.png" /></a>
|
||||
{% endif %}
|
||||
<br>
|
||||
{% endfor %}
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<a href="{{ url_for('entreprises.add_offre_file', offre_id=offre[0].id) }}">Ajoutez un fichier</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 10px;">
|
||||
<div class="parent-btn">
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.edit_offre', id=offre[0].id) }}">Modifier l'offre</a>
|
||||
<a class="btn btn-danger" href="{{ url_for('entreprises.delete_offre', id=offre[0].id) }}">Supprimer l'offre</a>
|
||||
{% endif %}
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesSend, None) %}
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.envoyer_offre', id=offre[0].id) }}">Envoyer l'offre</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
@ -3,16 +3,17 @@
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<h1>Ajout entreprise avec contact</h1>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<p>
|
||||
Les champs s'autocomplète selon le SIRET
|
||||
Les champs s'auto complète selon le SIRET
|
||||
</p>
|
||||
{{ wtf.quick_form(form, novalidate=True) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.onload = function(e){
|
||||
document.getElementById("siret").addEventListener("keyup", autocomplete);
|
||||
@ -50,5 +51,12 @@
|
||||
document.getElementById("pays").value = ''
|
||||
}
|
||||
}
|
||||
|
||||
{# ajout margin-bottom sur le champ pays #}
|
||||
var champ_pays = document.getElementById("pays")
|
||||
if (champ_pays !== null) {
|
||||
var closest_form_group = champ_pays.closest(".form-group")
|
||||
closest_form_group.style.marginBottom = "50px"
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
@ -9,13 +9,14 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<h1>Ajout historique</h1>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
{{ wtf.quick_form(form, novalidate=True) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.onload = function(e) {
|
||||
var etudiants_options = {
|
||||
|
@ -2,19 +2,31 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block app_content %}
|
||||
{% include 'entreprises/nav.html' %}
|
||||
|
||||
{% if logs %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations</h3>
|
||||
<h3>Dernières opérations <a href="{{ url_for('entreprises.logs') }}">Voir tout</a></h3>
|
||||
<ul>
|
||||
{% for log in logs %}
|
||||
<li><span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span><span>{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet }}</span></li>
|
||||
<li><span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span><span>{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet_by_username }}</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="container boutons">
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesExport, None) %}
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.import_contacts') }}">Importer des contacts</a>
|
||||
{% endif %}
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesExport, None) and contacts.items %}
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.export_contacts') }}">Exporter la liste des contacts</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h1>Liste des contacts</h1>
|
||||
{% if contacts %}
|
||||
{% if contacts.items %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover">
|
||||
<tr>
|
||||
@ -26,7 +38,7 @@
|
||||
<th>Service</th>
|
||||
<th>Entreprise</th>
|
||||
</tr>
|
||||
{% for contact in contacts %}
|
||||
{% for contact in contacts.items %}
|
||||
<tr class="table-row active">
|
||||
<th>{{ contact[0].nom }}</th>
|
||||
<th>{{ contact[0].prenom }}</th>
|
||||
@ -38,15 +50,32 @@
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<a href="{{ url_for('entreprises.contacts', page=contacts.prev_num) }}" class="btn btn-default {% if contacts.page == 1 %}disabled{% endif %}">
|
||||
«
|
||||
</a>
|
||||
{% for page_num in contacts.iter_pages(left_edge=1, right_edge=1, left_current=1, right_current=2) %}
|
||||
{% if page_num %}
|
||||
{% if contacts.page == page_num %}
|
||||
<a href="{{ url_for('entreprises.contacts', page=page_num) }}" class="btn btn-inverse">{{ page_num }}</a>
|
||||
{% else %}
|
||||
<a href="{{ url_for('entreprises.contacts', page=page_num) }}" class="btn btn-default">{{ page_num }}</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
...
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<a href="{{ url_for('entreprises.contacts', page=contacts.next_num) }}" class="btn btn-default {% if contacts.page == contacts.pages %}disabled{% endif %}">
|
||||
»
|
||||
</a>
|
||||
</div>
|
||||
<p class="text-center">
|
||||
Page {{ contacts.page }} sur {{ contacts.pages }}
|
||||
</p>
|
||||
{% else %}
|
||||
<div>Aucun contact présent dans la base</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
{% if contacts %}
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.export_contacts') }}">Exporter la liste des contacts</a>
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.export_contacts_bis') }}">Exporter la liste des contacts avec leur entreprise</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -5,7 +5,7 @@
|
||||
{% block app_content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<br>
|
||||
<div style="color:red">Cliquez sur le bouton supprimer pour confirmer votre supression</div>
|
||||
<div style="color:red;">Cliquez sur le bouton Supprimer pour confirmer votre supression</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
|
@ -2,21 +2,38 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block app_content %}
|
||||
{% include 'entreprises/nav.html' %}
|
||||
|
||||
{% if logs %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations</h3>
|
||||
<h3>Dernières opérations <a href="{{ url_for('entreprises.logs') }}">Voir tout</a></h3>
|
||||
<ul>
|
||||
{% for log in logs %}
|
||||
<li><span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span><span>{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet }}</span></li>
|
||||
<li><span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span><span>{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet_by_username }}</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="container boutons">
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.add_entreprise') }}">Ajouter une entreprise</a>
|
||||
{% endif %}
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesExport, None) %}
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.import_entreprises') }}">Importer des entreprises</a>
|
||||
{% endif %}
|
||||
{% if entreprises %}
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesExport, None) and entreprises.items%}
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.export_entreprises') }}">Exporter la liste des entreprises</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h1>Liste des entreprises</h1>
|
||||
{% if entreprises %}
|
||||
{% if entreprises.items %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover">
|
||||
<table class="table table-bordered table-hover" style="margin-bottom:60px;">
|
||||
<tr>
|
||||
<th>SIRET</th>
|
||||
<th>Nom</th>
|
||||
@ -24,9 +41,11 @@
|
||||
<th>Code postal</th>
|
||||
<th>Ville</th>
|
||||
<th>Pays</th>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<th>Action</th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% for entreprise in entreprises %}
|
||||
{% for entreprise in entreprises.items %}
|
||||
<tr class="table-row active">
|
||||
<th><a href="{{ url_for('entreprises.fiche_entreprise', id=entreprise.id) }}">{{ entreprise.siret }}</a></th>
|
||||
<th>{{ entreprise.nom }}</th>
|
||||
@ -34,6 +53,7 @@
|
||||
<th>{{ entreprise.codepostal }}</th>
|
||||
<th>{{ entreprise.ville }}</th>
|
||||
<th>{{ entreprise.pays }}</th>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<th>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action
|
||||
@ -45,19 +65,37 @@
|
||||
</ul>
|
||||
</div>
|
||||
</th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<a href="{{ url_for('entreprises.index', page=entreprises.prev_num) }}" class="btn btn-default {% if entreprises.page == 1 %}disabled{% endif %}">
|
||||
«
|
||||
</a>
|
||||
{% for page_num in entreprises.iter_pages(left_edge=1, right_edge=1, left_current=1, right_current=2) %}
|
||||
{% if page_num %}
|
||||
{% if entreprises.page == page_num %}
|
||||
<a href="{{ url_for('entreprises.index', page=page_num) }}" class="btn btn-inverse">{{ page_num }}</a>
|
||||
{% else %}
|
||||
<a href="{{ url_for('entreprises.index', page=page_num) }}" class="btn btn-default">{{ page_num }}</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
...
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<a href="{{ url_for('entreprises.index', page=entreprises.next_num) }}" class="btn btn-default {% if entreprises.page == entreprises.pages %}disabled{% endif %}">
|
||||
»
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p class="text-center">
|
||||
Page {{ entreprises.page }} sur {{ entreprises.pages }}
|
||||
</p>
|
||||
{% else %}
|
||||
<div>Aucune entreprise présent dans la base</div>
|
||||
<br>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div style="margin-bottom: 20px;">
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.add_entreprise') }}">Ajouter une entreprise</a>
|
||||
{% if entreprises %}
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.export_entreprises') }}">Exporter la liste des entreprises</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
51
app/templates/entreprises/entreprises_validation.html
Normal file
51
app/templates/entreprises/entreprises_validation.html
Normal file
@ -0,0 +1,51 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block app_content %}
|
||||
{% include 'entreprises/nav.html' %}
|
||||
|
||||
{% if logs %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations</h3>
|
||||
<ul>
|
||||
{% for log in logs %}
|
||||
<li><span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span><span>{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet_by_username }}</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="container">
|
||||
<h1>Liste des entreprises à valider</h1>
|
||||
{% if entreprises %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover">
|
||||
<tr>
|
||||
<th>SIRET</th>
|
||||
<th>Nom</th>
|
||||
<th>Adresse</th>
|
||||
<th>Code postal</th>
|
||||
<th>Ville</th>
|
||||
<th>Pays</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
{% for entreprise in entreprises %}
|
||||
<tr class="table-row active">
|
||||
<th><a href="{{ url_for('entreprises.fiche_entreprise_validation', id=entreprise.id) }}">{{ entreprise.siret }}</a></th>
|
||||
<th>{{ entreprise.nom }}</th>
|
||||
<th>{{ entreprise.adresse }}</th>
|
||||
<th>{{ entreprise.codepostal }}</th>
|
||||
<th>{{ entreprise.ville }}</th>
|
||||
<th>{{ entreprise.pays }}</th>
|
||||
<th>
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.fiche_entreprise_validation', id=entreprise.id) }}">Voir</a>
|
||||
</th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div>Aucune entreprise à valider</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
@ -9,13 +9,14 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<h1>Envoyer une offre</h1>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
{{ wtf.quick_form(form, novalidate=True) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.onload = function(e) {
|
||||
var responsables_options = {
|
||||
|
@ -2,21 +2,22 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block app_content %}
|
||||
{% if logs %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations sur cette fiche</h3>
|
||||
{% if logs %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations sur cette fiche <a href="{{ url_for('entreprises.logs_entreprise', id=entreprise.id) }}">Voir tout</a></h3>
|
||||
<ul>
|
||||
{% for log in logs %}
|
||||
<li>
|
||||
<span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span>
|
||||
<span>{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet }}</span>
|
||||
<span>{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet_by_username }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if historique %}
|
||||
<div class="container">
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if historique %}
|
||||
<div class="container">
|
||||
<h3>Historique</h3>
|
||||
<ul>
|
||||
{% for data in historique %}
|
||||
@ -30,40 +31,24 @@
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="container">
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="container fiche-entreprise">
|
||||
<h2>Fiche entreprise - {{ entreprise.nom }} ({{ entreprise.siret }})</h2>
|
||||
|
||||
<div class="entreprise">
|
||||
<div>
|
||||
<p>
|
||||
SIRET : {{ entreprise.siret }}<br>
|
||||
Nom : {{ entreprise.nom }}<br>
|
||||
Adresse : {{ entreprise.adresse }}<br>
|
||||
Code postal : {{ entreprise.codepostal }}<br>
|
||||
Ville : {{ entreprise.ville }}<br>
|
||||
Pays : {{ entreprise.pays }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if contacts %}
|
||||
<div>
|
||||
{% for contact in contacts %}
|
||||
Contact {{loop.index}}
|
||||
{% include 'entreprises/_contact.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if offres %}
|
||||
<div>
|
||||
{% for offre in offres %}
|
||||
Offre {{loop.index}} (ajouté le {{offre[0].date_ajout.strftime('%d/%m/%Y') }})
|
||||
{% include 'entreprises/_offre.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<div>
|
||||
<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>
|
||||
@ -71,6 +56,29 @@
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.add_contact', id=entreprise.id) }}">Ajouter contact</a>
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.add_historique', id=entreprise.id) }}">Ajouter
|
||||
historique</a>
|
||||
{% endif %}
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.offres_expirees', id=entreprise.id) }}">Voir les offres expirées</a>
|
||||
<div>
|
||||
|
||||
|
||||
<div class="contacts-et-offres">
|
||||
{% if contacts %}
|
||||
<div>
|
||||
<h3>Contacts</h3>
|
||||
{% for contact in contacts %}
|
||||
{% include 'entreprises/_contact.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if offres %}
|
||||
<div>
|
||||
<h3>Offres - <a href="{{ url_for('entreprises.offres_expirees', id=entreprise.id) }}">Voir les offres expirées</a></h3>
|
||||
{% for offre in offres %}
|
||||
{% include 'entreprises/_offre.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
50
app/templates/entreprises/fiche_entreprise_validation.html
Normal file
50
app/templates/entreprises/fiche_entreprise_validation.html
Normal file
@ -0,0 +1,50 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="container">
|
||||
<h2>Fiche entreprise - {{ entreprise.nom }} ({{ entreprise.siret }})</h2>
|
||||
|
||||
<div class="entreprise">
|
||||
<div>
|
||||
SIRET : {{ entreprise.siret }}<br>
|
||||
Nom : {{ entreprise.nom }}<br>
|
||||
Adresse : {{ entreprise.adresse }}<br>
|
||||
Code postal : {{ entreprise.codepostal }}<br>
|
||||
Ville : {{ entreprise.ville }}<br>
|
||||
Pays : {{ entreprise.pays }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if contacts %}
|
||||
<div>
|
||||
{% for contact in contacts %}
|
||||
<div>
|
||||
<h3>Contact</h3>
|
||||
<div class="contact">
|
||||
Nom : {{ contact.nom }}<br>
|
||||
Prénom : {{ contact.prenom }}<br>
|
||||
{% if contact.telephone %}
|
||||
Téléphone : {{ contact.telephone }}<br>
|
||||
{% endif %}
|
||||
{% if contact.mail %}
|
||||
Mail : {{ contact.mail }}<br>
|
||||
{% endif %}
|
||||
{% if contact.poste %}
|
||||
Poste : {{ contact.poste }}<br>
|
||||
{% endif %}
|
||||
{% if contact.service %}
|
||||
Service : {{ contact.service }}<br>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
<a class="btn btn-success" href="{{ url_for('entreprises.validate_entreprise', id=entreprise.id) }}">Valider</a>
|
||||
<a class="btn btn-danger" href="{{ url_for('entreprises.delete_validation_entreprise', id=entreprise.id) }}">Supprimer</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -4,8 +4,6 @@
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/css/autosuggest_inquisitor.css" />
|
||||
<script src="/ScoDoc/static/libjs/AutoSuggest.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
@ -16,4 +14,13 @@
|
||||
{{ wtf.quick_form(form, novalidate=True) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
{# pour les formulaires offre #}
|
||||
var champ_depts = document.getElementById("depts")
|
||||
if (champ_depts !== null) {
|
||||
var closest_form_control = champ_depts.closest(".form-control")
|
||||
closest_form_control.classList.remove("form-control")
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
59
app/templates/entreprises/import_contacts.html
Normal file
59
app/templates/entreprises/import_contacts.html
Normal file
@ -0,0 +1,59 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>Importation contacts</h1>
|
||||
<br>
|
||||
<div>
|
||||
<a href="{{ url_for('entreprises.get_import_contacts_file_sample') }}">Obtenir la feuille excel à remplir</a>
|
||||
</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
{{ wtf.quick_form(form, novalidate=True) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not contacts_import %}
|
||||
<table class="table">
|
||||
<thead><tr><td><b>Attribut</b></td><td><b>Type</b></td><td><b>Description</b></td></tr></thead>
|
||||
<tr><td>nom</td><td>text</td><td>nom du contact</td></tr>
|
||||
<tr><td>prenom</td><td>text</td><td>prenom du contact</td></tr>
|
||||
<tr><td>telephone</td><td>text</td><td>telephone du contact</td></tr>
|
||||
<tr><td>mail</td><td>text</td><td>mail du contact</td></tr>
|
||||
<tr><td>poste</td><td>text</td><td>poste du contact</td></tr>
|
||||
<tr><td>service</td><td>text</td><td>service dans lequel travaille le contact</td></tr>
|
||||
<tr><td>entreprise_id</td><td>integer</td><td>l'id de l'entreprise</td></tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
{% if contacts_import %}
|
||||
<br><div>Importation de {{ contacts_import|length }} contact(s)</div>
|
||||
{% for contact in contacts_import %}
|
||||
<div class="contact">
|
||||
<div>
|
||||
Nom : {{ contact.nom }}<br>
|
||||
Prénom : {{ contact.prenom }}<br>
|
||||
{% if contact.telephone %}
|
||||
Téléphone : {{ contact.telephone }}<br>
|
||||
{% endif %}
|
||||
{% if contact.mail %}
|
||||
Mail : {{ contact.mail }}<br>
|
||||
{% endif %}
|
||||
{% if contact.poste %}
|
||||
Poste : {{ contact.poste }}<br>
|
||||
{% endif %}
|
||||
{% if contact.service %}
|
||||
Service : {{ contact.service }}<br>
|
||||
{% endif %}
|
||||
<a href="{{ url_for('entreprises.fiche_entreprise', id=contact.entreprise_id )}}">lien vers l'entreprise</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
49
app/templates/entreprises/import_entreprises.html
Normal file
49
app/templates/entreprises/import_entreprises.html
Normal file
@ -0,0 +1,49 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>Importation entreprises</h1>
|
||||
<br>
|
||||
<div>
|
||||
<a href="{{ url_for('entreprises.get_import_entreprises_file_sample') }}">Obtenir la feuille excel à remplir</a>
|
||||
</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
{{ wtf.quick_form(form, novalidate=True) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not entreprises_import %}
|
||||
<table class="table">
|
||||
<thead><tr><td><b>Attribut</b></td><td><b>Type</b></td><td><b>Description</b></td></tr></thead>
|
||||
<tr><td>siret</td><td>text</td><td>siret de l'entreprise</td></tr>
|
||||
<tr><td>nom</td><td>text</td><td>nom de l'entreprise</td></tr>
|
||||
<tr><td>adresse</td><td>text</td><td>adresse de l'entreprise</td></tr>
|
||||
<tr><td>ville</td><td>text</td><td>ville de l'entreprise</td></tr>
|
||||
<tr><td>code_postal</td><td>text</td><td>code postal de l'entreprise</td></tr>
|
||||
<tr><td>pays</td><td>text</td><td>pays de l'entreprise</td></tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
{% if entreprises_import %}
|
||||
<br><div>Importation de {{ entreprises_import|length }} entreprise(s)</div>
|
||||
{% for entreprise in entreprises_import %}
|
||||
<div class="entreprise">
|
||||
<div>
|
||||
SIRET : {{ entreprise.siret }}<br>
|
||||
Nom : {{ entreprise.nom }}<br>
|
||||
Adresse : {{ entreprise.adresse }}<br>
|
||||
Code postal : {{ entreprise.codepostal }}<br>
|
||||
Ville : {{ entreprise.ville }}<br>
|
||||
Pays : {{ entreprise.pays }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
43
app/templates/entreprises/logs.html
Normal file
43
app/templates/entreprises/logs.html
Normal file
@ -0,0 +1,43 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations</h3>
|
||||
{% if logs.items %}
|
||||
<ul>
|
||||
{% for log in logs.items %}
|
||||
<li><span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span><span>{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet_by_username }}</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<div class="text-center">
|
||||
<a href="{{ url_for('entreprises.logs', page=logs.prev_num) }}" class="btn btn-default {% if logs.page == 1 %}disabled{% endif %}">
|
||||
«
|
||||
</a>
|
||||
{% for page_num in logs.iter_pages(left_edge=1, right_edge=1, left_current=1, right_current=2) %}
|
||||
{% if page_num %}
|
||||
{% if logs.page == page_num %}
|
||||
<a href="{{ url_for('entreprises.logs', page=page_num) }}" class="btn btn-inverse">{{ page_num }}</a>
|
||||
{% else %}
|
||||
<a href="{{ url_for('entreprises.logs', page=page_num) }}" class="btn btn-default">{{ page_num }}</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
...
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<a href="{{ url_for('entreprises.logs', page=logs.next_num) }}" class="btn btn-default {% if logs.page == logs.pages %}disabled{% endif %}">
|
||||
»
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p class="text-center">
|
||||
Page {{ logs.page }} sur {{ logs.pages }}
|
||||
</p>
|
||||
{% else %}
|
||||
<div>Aucune opération</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
42
app/templates/entreprises/logs_entreprise.html
Normal file
42
app/templates/entreprises/logs_entreprise.html
Normal file
@ -0,0 +1,42 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations - {{ entreprise.nom }}</h3>
|
||||
{% if logs.items %}
|
||||
<ul>
|
||||
{% for log in logs.items %}
|
||||
<li><span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span><span>{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet_by_username }}</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<div class="text-center">
|
||||
<a href="{{ url_for('entreprises.logs_entreprise', id=entreprise.id, page=logs.prev_num) }}" class="btn btn-default {% if logs.page == 1 %}disabled{% endif %}">
|
||||
«
|
||||
</a>
|
||||
{% for page_num in logs.iter_pages(left_edge=1, right_edge=1, left_current=1, right_current=2) %}
|
||||
{% if page_num %}
|
||||
{% if logs.page == page_num %}
|
||||
<a href="{{ url_for('entreprises.logs_entreprise', id=entreprise.id, page=page_num) }}" class="btn btn-inverse">{{ page_num }}</a>
|
||||
{% else %}
|
||||
<a href="{{ url_for('entreprises.logs_entreprise', id=entreprise.id, page=page_num) }}" class="btn btn-default">{{ page_num }}</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
...
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<a href="{{ url_for('entreprises.logs_entreprise', id=entreprise.id, page=logs.next_num) }}" class="btn btn-default {% if logs.page == logs.pages %}disabled{% endif %}">
|
||||
»
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p class="text-center">
|
||||
Page {{ logs.page }} sur {{ logs.pages }}
|
||||
</p>
|
||||
{% else %}
|
||||
<div>Aucune opération</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
11
app/templates/entreprises/nav.html
Normal file
11
app/templates/entreprises/nav.html
Normal file
@ -0,0 +1,11 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
<nav class="nav-entreprise">
|
||||
<ul>
|
||||
<li><a href="{{ url_for('entreprises.index') }}">Entreprises</a></li>
|
||||
<li><a href="{{ url_for('entreprises.contacts') }}">Contacts</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) %}
|
||||
<li><a href="{{ url_for('entreprises.validation') }}">Entreprises à valider</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
@ -1,29 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="container">
|
||||
<h1>{{ title }}</h1>
|
||||
{% if offres_recus %}
|
||||
<div class="table-responsive">
|
||||
<div>
|
||||
{% for offre in offres_recus %}
|
||||
<div>
|
||||
<p>
|
||||
Date envoi : {{ offre[0].date_envoi.strftime('%d/%m/%Y %H:%M') }}<br>
|
||||
Intitulé : {{ offre[1].intitule }}<br>
|
||||
Description : {{ offre[1].description }}<br>
|
||||
Type de l'offre : {{ offre[1].type_offre }}<br>
|
||||
Missions : {{ offre[1].missions }}<br>
|
||||
Durée : {{ offre[1].duree }}<br>
|
||||
</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<br>
|
||||
{% else %}
|
||||
<div>Aucune offre reçue</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
15
app/templates/entreprises/offres_expirees.html
Normal file
15
app/templates/entreprises/offres_expirees.html
Normal file
@ -0,0 +1,15 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="container">
|
||||
<h1>Offres expirées - {{ entreprise.nom }}</h1>
|
||||
{% if offres_expirees %}
|
||||
{% for offre in offres_expirees %}
|
||||
{% include 'entreprises/_offre.html' %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div>Aucune offre expirées</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
34
app/templates/entreprises/offres_recues.html
Normal file
34
app/templates/entreprises/offres_recues.html
Normal file
@ -0,0 +1,34 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block app_content %}
|
||||
{% include 'entreprises/nav.html' %}
|
||||
|
||||
<div class="container">
|
||||
<h1>Offres reçues</h1>
|
||||
{% if offres_recues %}
|
||||
{% for offre in offres_recues %}
|
||||
<div class="offre offre-recue">
|
||||
<div>
|
||||
Envoyé le {{ offre[0].date_envoi.strftime('%d %B %Y à %H:%M') }} par {{ offre[0].sender_id|get_nomcomplet_by_id }}<br>
|
||||
Intitulé : {{ offre[1].intitule }}<br>
|
||||
Description : {{ offre[1].description }}<br>
|
||||
Type de l'offre : {{ offre[1].type_offre }}<br>
|
||||
Missions : {{ offre[1].missions }}<br>
|
||||
Durée : {{ offre[1].duree }}<br>
|
||||
<a href="{{ url_for('entreprises.fiche_entreprise', id=offre[1].entreprise_id) }}">lien vers l'entreprise</a><br>
|
||||
|
||||
{% for fichier in offre[2] %}
|
||||
<a href="{{ url_for('entreprises.get_offre_file', entreprise_id=offre[1].entreprise_id, offre_id=offre[1].id, filedir=fichier[0], filename=fichier[1]) }}">{{ fichier[1] }}</a><br>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div>
|
||||
<a href="{{ url_for('entreprises.delete_offre_recue', id=offre[0].id) }}" style="margin-left: 5px;"><img title="Supprimer fichier" alt="supprimer" width="16" height="16" border="0" src="/ScoDoc/static/icons/delete_small_img.png" /></a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div>Aucune offre reçue</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
15
app/templates/entreprises/validate_confirmation.html
Normal file
15
app/templates/entreprises/validate_confirmation.html
Normal file
@ -0,0 +1,15 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>Validation entreprise</h1>
|
||||
<br>
|
||||
<div style="color:green;">Cliquez sur le bouton Valider pour confirmer votre validation</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
{{ wtf.quick_form(form) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -0,0 +1,253 @@
|
||||
"""tables module gestion relations entreprises
|
||||
|
||||
Revision ID: 593451ab68b3
|
||||
Revises: c95d5a3bf0de
|
||||
Create Date: 2022-02-04 17:06:02.519231
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "593451ab68b3"
|
||||
down_revision = "c95d5a3bf0de"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table(
|
||||
"are_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(
|
||||
"are_entreprises",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("siret", sa.Text(), 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.Column("visible", sa.Boolean(), nullable=True),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
)
|
||||
op.create_table(
|
||||
"are_entreprise_contact",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("entreprise_id", sa.Integer(), nullable=True),
|
||||
sa.Column("nom", sa.Text(), nullable=True),
|
||||
sa.Column("prenom", sa.Text(), nullable=True),
|
||||
sa.Column("telephone", sa.Text(), nullable=True),
|
||||
sa.Column("mail", sa.Text(), nullable=True),
|
||||
sa.Column("poste", sa.Text(), nullable=True),
|
||||
sa.Column("service", sa.Text(), nullable=True),
|
||||
sa.ForeignKeyConstraint(
|
||||
["entreprise_id"], ["are_entreprises.id"], ondelete="cascade"
|
||||
),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
)
|
||||
op.create_table(
|
||||
"are_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"], ["are_entreprises.id"], ondelete="cascade"
|
||||
),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
)
|
||||
op.create_table(
|
||||
"are_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.Column("expiration_date", sa.Date(), nullable=True),
|
||||
sa.ForeignKeyConstraint(
|
||||
["entreprise_id"], ["are_entreprises.id"], ondelete="cascade"
|
||||
),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
)
|
||||
op.create_table(
|
||||
"are_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"], ["are_entreprise_offre.id"], ondelete="cascade"
|
||||
),
|
||||
sa.ForeignKeyConstraint(["receiver_id"], ["user.id"], ondelete="cascade"),
|
||||
sa.ForeignKeyConstraint(["sender_id"], ["user.id"], ondelete="cascade"),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
)
|
||||
op.create_table(
|
||||
"are_entreprise_envoi_offre_etudiant",
|
||||
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"], ["are_entreprise_offre.id"], ondelete="cascade"
|
||||
),
|
||||
sa.ForeignKeyConstraint(["receiver_id"], ["identite.id"], ondelete="cascade"),
|
||||
sa.ForeignKeyConstraint(["sender_id"], ["user.id"], ondelete="cascade"),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
)
|
||||
op.create_table(
|
||||
"are_entreprise_offre_departement",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("offre_id", sa.Integer(), nullable=True),
|
||||
sa.Column("dept_id", sa.Integer(), nullable=True),
|
||||
sa.ForeignKeyConstraint(["dept_id"], ["departement.id"], ondelete="cascade"),
|
||||
sa.ForeignKeyConstraint(
|
||||
["offre_id"], ["are_entreprise_offre.id"], ondelete="cascade"
|
||||
),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
)
|
||||
op.drop_table("entreprise_contact")
|
||||
op.drop_table("entreprise_correspondant")
|
||||
op.drop_index("ix_entreprises_dept_id", table_name="entreprises")
|
||||
op.drop_table("entreprises")
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table(
|
||||
"entreprises",
|
||||
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||
sa.Column("nom", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("adresse", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("ville", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("codepostal", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("pays", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("localisation", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("dept_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"date_creation",
|
||||
postgresql.TIMESTAMP(timezone=True),
|
||||
server_default=sa.text("now()"),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("secteur", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("privee", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("plus10salaries", sa.BOOLEAN(), autoincrement=False, nullable=True),
|
||||
sa.Column("contact_origine", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("note", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("qualite_relation", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.ForeignKeyConstraint(
|
||||
["dept_id"], ["departement.id"], name="entreprises_dept_id_fkey"
|
||||
),
|
||||
sa.PrimaryKeyConstraint("id", name="entreprises_pkey"),
|
||||
)
|
||||
op.create_table(
|
||||
"entreprise_correspondant",
|
||||
sa.Column(
|
||||
"id",
|
||||
sa.INTEGER(),
|
||||
server_default=sa.text(
|
||||
"nextval('entreprise_correspondant_id_seq'::regclass)"
|
||||
),
|
||||
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"),
|
||||
postgresql_ignore_search_path=False,
|
||||
)
|
||||
op.create_table(
|
||||
"entreprise_contact",
|
||||
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||
sa.Column("entreprise_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"entreprise_corresp_id", sa.INTEGER(), autoincrement=False, nullable=True
|
||||
),
|
||||
sa.Column("etudid", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column("type_contact", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column(
|
||||
"date",
|
||||
postgresql.TIMESTAMP(timezone=True),
|
||||
autoincrement=False,
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("enseignant", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("description", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.ForeignKeyConstraint(
|
||||
["entreprise_corresp_id"],
|
||||
["entreprise_correspondant.id"],
|
||||
name="entreprise_contact_entreprise_corresp_id_fkey",
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["entreprise_id"],
|
||||
["entreprises.id"],
|
||||
name="entreprise_contact_entreprise_id_fkey",
|
||||
),
|
||||
sa.PrimaryKeyConstraint("id", name="entreprise_contact_pkey"),
|
||||
)
|
||||
op.create_index("ix_entreprises_dept_id", "entreprises", ["dept_id"], unique=False)
|
||||
op.drop_table("are_entreprise_offre_departement")
|
||||
op.drop_table("are_entreprise_envoi_offre_etudiant")
|
||||
op.drop_table("are_entreprise_envoi_offre")
|
||||
op.drop_table("are_entreprise_offre")
|
||||
op.drop_table("are_entreprise_etudiant")
|
||||
op.drop_table("are_entreprise_contact")
|
||||
op.drop_table("are_entreprises")
|
||||
op.drop_table("are_entreprise_log")
|
||||
# ### end Alembic commands ###
|
Loading…
Reference in New Issue
Block a user