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

This commit is contained in:
Emmanuel Viennet 2022-01-04 11:41:15 +01:00
commit 51d75acb68
6 changed files with 307 additions and 5 deletions

View File

@ -57,6 +57,23 @@ class EntrepriseContact(db.Model):
"service": self.service, "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,
}
class EntrepriseOffre(db.Model): class EntrepriseOffre(db.Model):
__tablename__ = "entreprise_offre" __tablename__ = "entreprise_offre"
@ -71,6 +88,15 @@ class EntrepriseOffre(db.Model):
missions = db.Column(db.Text) missions = db.Column(db.Text)
duree = db.Column(db.Text) duree = db.Column(db.Text)
def to_dict(self):
return {
"intitule": self.intitule,
"description": self.description,
"type_offre": self.type_offre,
"missions": self.missions,
"duree": self.duree,
}
class EntrepriseLog(db.Model): class EntrepriseLog(db.Model):
__tablename__ = "entreprise_log" __tablename__ = "entreprise_log"
@ -100,3 +126,12 @@ class EntrepriseEnvoiOffre(db.Model):
receiver_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")) offre_id = db.Column(db.Integer, db.ForeignKey("entreprise_offre.id"))
date_envoi = db.Column(db.DateTime(timezone=True), server_default=db.func.now()) date_envoi = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
class EntrepriseEnvoiOffreEtudiant(db.Model):
__tablename__ = "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"))
date_envoi = db.Column(db.DateTime(timezone=True), server_default=db.func.now())

View File

@ -1,6 +1,6 @@
import os import os
from config import Config from config import Config
from datetime import datetime from datetime import datetime, timedelta
import glob import glob
import shutil import shutil
@ -45,6 +45,18 @@ from werkzeug.utils import secure_filename
@bp.route("/", methods=["GET"]) @bp.route("/", methods=["GET"])
def index(): def index():
"""
Permet d'afficher une page avec la liste des entreprises et une liste des dernières opérations
Retourne: template de la page (entreprises.html)
Arguments du template:
title:
titre de la page
entreprises:
liste des entreprises
logs:
liste des logs
"""
entreprises = Entreprise.query.all() entreprises = Entreprise.query.all()
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(
@ -57,6 +69,18 @@ def index():
@bp.route("/contacts", methods=["GET"]) @bp.route("/contacts", methods=["GET"])
def contacts(): def contacts():
"""
Permet d'afficher une page la liste des contacts et une liste des dernières opérations
Retourne: template de la page (contacts.html)
Arguments du template:
title:
titre de la page
contacts:
liste des contacts
logs:
liste des logs
"""
contacts = ( contacts = (
db.session.query(EntrepriseContact, Entreprise) db.session.query(EntrepriseContact, Entreprise)
.join(Entreprise, EntrepriseContact.entreprise_id == Entreprise.id) .join(Entreprise, EntrepriseContact.entreprise_id == Entreprise.id)
@ -70,10 +94,39 @@ def contacts():
@bp.route("/fiche_entreprise/<int:id>", methods=["GET"]) @bp.route("/fiche_entreprise/<int:id>", methods=["GET"])
def fiche_entreprise(id): def fiche_entreprise(id):
"""
Permet d'afficher la fiche entreprise d'une entreprise avec une liste des dernières opérations et
l'historique des étudiants ayant réaliser un stage ou une alternance dans cette entreprise.
La fiche entreprise comporte les informations de l'entreprise, les contacts de l'entreprise et
les offres de l'entreprise.
Arguments:
id:
l'id de l'entreprise
Retourne: template de la page (fiche_entreprise.html)
Arguments du template:
title:
titre de la page
entreprise:
un objet entreprise
contacts:
liste des contacts de l'entreprise
offres:
liste des offres de l'entreprise avec leurs fichiers
logs:
liste des logs
historique:
liste des étudiants ayant réaliser un stage ou une alternance dans l'entreprise
"""
entreprise = Entreprise.query.filter_by(id=id).first_or_404() entreprise = Entreprise.query.filter_by(id=id).first_or_404()
offres = entreprise.offres offres = entreprise.offres
offres_with_files = [] offres_with_files = []
for offre in offres: for offre in offres:
if datetime.now() - offre.date_ajout.replace(tzinfo=None) >= timedelta(
days=90
): # pour une date d'expiration ?
break
files = [] files = []
path = os.path.join( path = os.path.join(
Config.SCODOC_VAR_DIR, Config.SCODOC_VAR_DIR,
@ -116,19 +169,32 @@ def fiche_entreprise(id):
@bp.route("/offres", methods=["GET"]) @bp.route("/offres", methods=["GET"])
def offres(): def offres():
offres_recus = ( """
Permet d'afficher la page où l'on recoit les offres
Retourne: template de la page (offres.html)
Arguments du template:
title:
titre de la page
offres_recus:
liste des offres reçues
"""
offres_recues = (
db.session.query(EntrepriseEnvoiOffre, EntrepriseOffre) db.session.query(EntrepriseEnvoiOffre, EntrepriseOffre)
.filter(EntrepriseEnvoiOffre.receiver_id == current_user.id) .filter(EntrepriseEnvoiOffre.receiver_id == current_user.id)
.join(EntrepriseOffre, EntrepriseOffre.id == EntrepriseEnvoiOffre.offre_id) .join(EntrepriseOffre, EntrepriseOffre.id == EntrepriseEnvoiOffre.offre_id)
.all() .all()
) )
return render_template( return render_template(
"entreprises/offres.html", title=("Offres"), offres_recus=offres_recus "entreprises/offres.html", title=("Offres"), offres_recues=offres_recues
) )
@bp.route("/add_entreprise", methods=["GET", "POST"]) @bp.route("/add_entreprise", methods=["GET", "POST"])
def add_entreprise(): def add_entreprise():
"""
Permet d'ajouter une entreprise dans la base avec un formulaire
"""
form = EntrepriseCreationForm() form = EntrepriseCreationForm()
if form.validate_on_submit(): if form.validate_on_submit():
entreprise = Entreprise( entreprise = Entreprise(
@ -170,6 +236,13 @@ def add_entreprise():
@bp.route("/edit_entreprise/<int:id>", methods=["GET", "POST"]) @bp.route("/edit_entreprise/<int:id>", methods=["GET", "POST"])
def edit_entreprise(id): def edit_entreprise(id):
"""
Permet de modifier une entreprise de la base avec un formulaire
Arguments:
id:
l'id de l'entreprise
"""
entreprise = Entreprise.query.filter_by(id=id).first_or_404() entreprise = Entreprise.query.filter_by(id=id).first_or_404()
form = EntrepriseModificationForm() form = EntrepriseModificationForm()
if form.validate_on_submit(): if form.validate_on_submit():
@ -231,6 +304,13 @@ def edit_entreprise(id):
@bp.route("/delete_entreprise/<int:id>", methods=["GET", "POST"]) @bp.route("/delete_entreprise/<int:id>", methods=["GET", "POST"])
def delete_entreprise(id): def delete_entreprise(id):
"""
Permet de supprimer une entreprise de la base avec un formulaire de confirmation
Arguments:
id:
l'id de l'entreprise
"""
entreprise = Entreprise.query.filter_by(id=id).first_or_404() entreprise = Entreprise.query.filter_by(id=id).first_or_404()
form = SuppressionConfirmationForm() form = SuppressionConfirmationForm()
if form.validate_on_submit(): if form.validate_on_submit():
@ -253,6 +333,13 @@ def delete_entreprise(id):
@bp.route("/add_offre/<int:id>", methods=["GET", "POST"]) @bp.route("/add_offre/<int:id>", methods=["GET", "POST"])
def add_offre(id): def add_offre(id):
"""
Permet d'ajouter une offre a une entreprise
Arguments:
id:
l'id de l'entreprise
"""
entreprise = Entreprise.query.filter_by(id=id).first_or_404() entreprise = Entreprise.query.filter_by(id=id).first_or_404()
form = OffreCreationForm() form = OffreCreationForm()
if form.validate_on_submit(): if form.validate_on_submit():
@ -279,6 +366,13 @@ def add_offre(id):
@bp.route("/edit_offre/<int:id>", methods=["GET", "POST"]) @bp.route("/edit_offre/<int:id>", methods=["GET", "POST"])
def edit_offre(id): def edit_offre(id):
"""
Permet de modifier une offre
Arguments:
id:
l'id de l'offre
"""
offre = EntrepriseOffre.query.filter_by(id=id).first_or_404() offre = EntrepriseOffre.query.filter_by(id=id).first_or_404()
form = OffreModificationForm() form = OffreModificationForm()
if form.validate_on_submit(): if form.validate_on_submit():
@ -309,6 +403,13 @@ def edit_offre(id):
@bp.route("/delete_offre/<int:id>", methods=["GET", "POST"]) @bp.route("/delete_offre/<int:id>", methods=["GET", "POST"])
def delete_offre(id): def delete_offre(id):
"""
Permet de supprimer une offre
Arguments:
id:
l'id de l'offre
"""
offre = EntrepriseOffre.query.filter_by(id=id).first_or_404() offre = EntrepriseOffre.query.filter_by(id=id).first_or_404()
entreprise_id = offre.entreprise.id entreprise_id = offre.entreprise.id
form = SuppressionConfirmationForm() form = SuppressionConfirmationForm()
@ -330,6 +431,13 @@ def delete_offre(id):
@bp.route("/add_contact/<int:id>", methods=["GET", "POST"]) @bp.route("/add_contact/<int:id>", methods=["GET", "POST"])
def add_contact(id): def add_contact(id):
"""
Permet d'ajouter un contact a une entreprise
Arguments:
id:
l'id de l'entreprise
"""
entreprise = Entreprise.query.filter_by(id=id).first_or_404() entreprise = Entreprise.query.filter_by(id=id).first_or_404()
form = ContactCreationForm(hidden_entreprise_id=entreprise.id) form = ContactCreationForm(hidden_entreprise_id=entreprise.id)
if form.validate_on_submit(): if form.validate_on_submit():
@ -357,6 +465,13 @@ def add_contact(id):
@bp.route("/edit_contact/<int:id>", methods=["GET", "POST"]) @bp.route("/edit_contact/<int:id>", methods=["GET", "POST"])
def edit_contact(id): def edit_contact(id):
"""
Permet de modifier un contact
Arguments:
id:
l'id du contact
"""
contact = EntrepriseContact.query.filter_by(id=id).first_or_404() contact = EntrepriseContact.query.filter_by(id=id).first_or_404()
form = ContactModificationForm() form = ContactModificationForm()
if form.validate_on_submit(): if form.validate_on_submit():
@ -391,6 +506,13 @@ def edit_contact(id):
@bp.route("/delete_contact/<int:id>", methods=["GET", "POST"]) @bp.route("/delete_contact/<int:id>", methods=["GET", "POST"])
def delete_contact(id): def delete_contact(id):
"""
Permet de supprimer un contact
Arguments:
id:
l'id du contact
"""
contact = EntrepriseContact.query.filter_by(id=id).first_or_404() contact = EntrepriseContact.query.filter_by(id=id).first_or_404()
entreprise_id = contact.entreprise.id entreprise_id = contact.entreprise.id
form = SuppressionConfirmationForm() form = SuppressionConfirmationForm()
@ -421,6 +543,13 @@ def delete_contact(id):
@bp.route("/add_historique/<int:id>", methods=["GET", "POST"]) @bp.route("/add_historique/<int:id>", methods=["GET", "POST"])
def add_historique(id): def add_historique(id):
"""
Permet d'ajouter un étudiant ayant réalisé un stage ou une alternance sur la fiche entreprise de l'entreprise
Arguments:
id:
l'id de l'entreprise
"""
entreprise = Entreprise.query.filter_by(id=id).first_or_404() entreprise = Entreprise.query.filter_by(id=id).first_or_404()
form = HistoriqueCreationForm() form = HistoriqueCreationForm()
if form.validate_on_submit(): if form.validate_on_submit():
@ -458,6 +587,13 @@ def add_historique(id):
@bp.route("/envoyer_offre/<int:id>", methods=["GET", "POST"]) @bp.route("/envoyer_offre/<int:id>", methods=["GET", "POST"])
def envoyer_offre(id): def envoyer_offre(id):
"""
Permet d'envoyer une offre à un utilisateur
Arguments:
id:
l'id de l'offre
"""
offre = EntrepriseOffre.query.filter_by(id=id).first_or_404() offre = EntrepriseOffre.query.filter_by(id=id).first_or_404()
form = EnvoiOffreForm() form = EnvoiOffreForm()
if form.validate_on_submit(): if form.validate_on_submit():
@ -484,6 +620,18 @@ def envoyer_offre(id):
@bp.route("/etudiants") @bp.route("/etudiants")
def json_etudiants(): def json_etudiants():
"""
Permet de récuperer un JSON avec tous les étudiants
Arguments:
term:
le terme utilisé pour le filtre de l'autosuggest
Retourne:
le JSON de tous les étudiants (nom, prenom, formation actuelle?) correspondant au terme
"""
if request.args.get("term") == None:
abort(400)
term = request.args.get("term").strip() term = request.args.get("term").strip()
etudiants = Identite.query.filter(Identite.nom.ilike(f"%{term}%")).all() etudiants = Identite.query.filter(Identite.nom.ilike(f"%{term}%")).all()
list = [] list = []
@ -505,6 +653,18 @@ def json_etudiants():
@bp.route("/responsables") @bp.route("/responsables")
def json_responsables(): def json_responsables():
"""
Permet de récuperer un JSON avec tous les étudiants
Arguments:
term:
le terme utilisé pour le filtre de l'autosuggest
Retourne:
le JSON de tous les utilisateurs (nom, prenom, login) correspondant au terme
"""
if request.args.get("term") == None:
abort(400)
term = request.args.get("term").strip() term = request.args.get("term").strip()
responsables = User.query.filter( responsables = User.query.filter(
User.nom.ilike(f"%{term}%"), User.nom.is_not(None), User.prenom.is_not(None) User.nom.ilike(f"%{term}%"), User.nom.is_not(None), User.prenom.is_not(None)
@ -521,6 +681,9 @@ def json_responsables():
@bp.route("/export_entreprises") @bp.route("/export_entreprises")
def export_entreprises(): def export_entreprises():
"""
Permet d'exporter la liste des entreprises sous format excel (.xlsx)
"""
entreprises = Entreprise.query.all() entreprises = Entreprise.query.all()
if entreprises: if entreprises:
keys = ["siret", "nom", "adresse", "ville", "codepostal", "pays"] keys = ["siret", "nom", "adresse", "ville", "codepostal", "pays"]
@ -539,6 +702,9 @@ def export_entreprises():
@bp.route("/export_contacts") @bp.route("/export_contacts")
def export_contacts(): def export_contacts():
"""
Permet d'exporter la liste des contacts sous format excel (.xlsx)
"""
contacts = EntrepriseContact.query.all() contacts = EntrepriseContact.query.all()
if contacts: if contacts:
keys = ["nom", "prenom", "telephone", "mail", "poste", "service"] keys = ["nom", "prenom", "telephone", "mail", "poste", "service"]
@ -552,10 +718,56 @@ def export_contacts():
abort(404) abort(404)
@bp.route("/export_contacts_bis")
def export_contacts_bis():
"""
Permet d'exporter la liste des contacts avec leur entreprise sous format excel (.xlsx)
"""
contacts = EntrepriseContact.query.all()
if contacts:
keys = [
"nom",
"prenom",
"telephone",
"mail",
"poste",
"service",
"nom_entreprise",
"siret",
"adresse_entreprise",
"ville",
"codepostal",
"pays",
]
titles = keys[:]
L = [
[contact.to_dict_export().get(k, "") for k in keys] for contact in contacts
]
title = "contacts"
xlsx = sco_excel.excel_simple_table(titles=titles, lines=L, sheet_name=title)
filename = title
return scu.send_file(xlsx, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE)
else:
abort(404)
@bp.route( @bp.route(
"/get_offre_file/<int:entreprise_id>/<int:offre_id>/<string:filedir>/<string:filename>" "/get_offre_file/<int:entreprise_id>/<int:offre_id>/<string:filedir>/<string:filename>"
) )
def get_offre_file(entreprise_id, offre_id, filedir, filename): def get_offre_file(entreprise_id, offre_id, filedir, filename):
"""
Permet de télécharger un fichier d'une offre
Arguments:
entreprise_id:
l'id de l'entreprise
offre_id:
l'id de l'offre
filedir:
le répertoire du fichier
filename:
le nom du fichier
"""
if os.path.isfile( if os.path.isfile(
os.path.join( os.path.join(
Config.SCODOC_VAR_DIR, Config.SCODOC_VAR_DIR,
@ -583,6 +795,13 @@ def get_offre_file(entreprise_id, offre_id, filedir, filename):
@bp.route("/add_offre_file/<int:offre_id>", methods=["GET", "POST"]) @bp.route("/add_offre_file/<int:offre_id>", methods=["GET", "POST"])
def add_offre_file(offre_id): def add_offre_file(offre_id):
"""
Permet d'ajouter un fichier à une offre
Arguments:
offre_id:
l'id de l'offre
"""
offre = EntrepriseOffre.query.filter_by(id=offre_id).first_or_404() offre = EntrepriseOffre.query.filter_by(id=offre_id).first_or_404()
form = AjoutFichierForm() form = AjoutFichierForm()
if form.validate_on_submit(): if form.validate_on_submit():
@ -607,6 +826,15 @@ def add_offre_file(offre_id):
@bp.route("/delete_offre_file/<int:offre_id>/<string:filedir>", methods=["GET", "POST"]) @bp.route("/delete_offre_file/<int:offre_id>/<string:filedir>", methods=["GET", "POST"])
def delete_offre_file(offre_id, filedir): def delete_offre_file(offre_id, filedir):
"""
Permet de supprimer un fichier d'une offre
Arguments:
offre_id:
l'id de l'offre
filedir:
le répertoire du fichier
"""
offre = EntrepriseOffre.query.filter_by(id=offre_id).first_or_404() offre = EntrepriseOffre.query.filter_by(id=offre_id).first_or_404()
form = SuppressionConfirmationForm() form = SuppressionConfirmationForm()
if form.validate_on_submit(): if form.validate_on_submit():

View File

@ -5,6 +5,12 @@
Prénom : {{ contact.prenom }}<br> Prénom : {{ contact.prenom }}<br>
Téléphone : {{ contact.telephone }}<br> Téléphone : {{ contact.telephone }}<br>
Mail : {{ contact.mail }}<br> Mail : {{ contact.mail }}<br>
{% if contact.poste %}
Poste : {{ contact.poste }}<br>
{% endif %}
{% if contact.service %}
Service : {{ contact.service }}<br>
{% endif %}
</p> </p>
<div style="margin-bottom: 10px;"> <div style="margin-bottom: 10px;">

View File

@ -22,6 +22,8 @@
<th>Prenom</th> <th>Prenom</th>
<th>Telephone</th> <th>Telephone</th>
<th>Mail</th> <th>Mail</th>
<th>Poste</th>
<th>Service</th>
<th>Entreprise</th> <th>Entreprise</th>
</tr> </tr>
{% for contact in contacts %} {% for contact in contacts %}
@ -30,6 +32,8 @@
<th>{{ contact[0].prenom }}</th> <th>{{ contact[0].prenom }}</th>
<th>{{ contact[0].telephone }}</th> <th>{{ contact[0].telephone }}</th>
<th>{{ contact[0].mail }}</th> <th>{{ contact[0].mail }}</th>
<th>{{ contact[0].poste}}</th>
<th>{{ contact[0].service}}</th>
<th><a href="{{ url_for('entreprises.fiche_entreprise', id=contact[1].id) }}">{{ contact[1].nom }}</a></th> <th><a href="{{ url_for('entreprises.fiche_entreprise', id=contact[1].id) }}">{{ contact[1].nom }}</a></th>
</tr> </tr>
{% endfor %} {% endfor %}
@ -41,6 +45,7 @@
<div> <div>
{% if contacts %} {% 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') }}">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 %} {% endif %}
</div> </div>
</div> </div>

View File

@ -24,8 +24,8 @@
<span style="margin-right: 10px;">{{ data[0].date_debut.strftime('%d/%m/%Y') }} - {{ <span style="margin-right: 10px;">{{ data[0].date_debut.strftime('%d/%m/%Y') }} - {{
data[0].date_fin.strftime('%d/%m/%Y') }}</span> data[0].date_fin.strftime('%d/%m/%Y') }}</span>
<span style="margin-right: 10px;"> <span style="margin-right: 10px;">
{{ data[0].type_offre }} réalisé par {{ data[1].nom|format_nom }} {{ data[1].prenom|format_prenom }} en {{ data[0].type_offre }} réalisé par {{ data[1].nom|format_nom }} {{ data[1].prenom|format_prenom }}
{{ data[0].formation_text }} {% if data[0].formation_text %} en {{ data[0].formation_text }}{% endif %}
</span> </span>
</li> </li>
{% endfor %} {% endfor %}

View File

@ -97,6 +97,33 @@ def upgrade():
sa.PrimaryKeyConstraint("id"), sa.PrimaryKeyConstraint("id"),
) )
op.create_table(
"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"],
["entreprise_offre.id"],
),
sa.ForeignKeyConstraint(
["sender_id"],
["user.id"],
),
sa.ForeignKeyConstraint(
["receiver_id"],
["identite.id"],
),
sa.PrimaryKeyConstraint("id"),
)
op.drop_constraint( op.drop_constraint(
"entreprise_contact_entreprise_corresp_id_fkey", "entreprise_contact_entreprise_corresp_id_fkey",
"entreprise_contact", "entreprise_contact",
@ -249,6 +276,7 @@ def downgrade():
op.drop_column("entreprise_contact", "nom") op.drop_column("entreprise_contact", "nom")
op.drop_table("entreprise_envoi_offre") op.drop_table("entreprise_envoi_offre")
op.drop_table("entreprise_envoi_offre_etudiant")
op.drop_table("entreprise_offre") op.drop_table("entreprise_offre")
op.drop_table("entreprise_etudiant") op.drop_table("entreprise_etudiant")
op.drop_table("entreprise_log") op.drop_table("entreprise_log")