From a57953c210ab355d2d51c9b7c7a63710f27911dc Mon Sep 17 00:00:00 2001 From: Arthur ZHU Date: Tue, 15 Feb 2022 18:24:10 +0100 Subject: [PATCH] =?UTF-8?q?visibilit=C3=A9=20offres=20li=C3=A9s=20d=C3=A9p?= =?UTF-8?q?artement(s),=20divers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/entreprises/app_relations_entreprises.py | 153 +++++++++++++++++++ app/entreprises/routes.py | 116 ++------------ app/templates/entreprises/offres_recues.html | 1 + 3 files changed, 166 insertions(+), 104 deletions(-) create mode 100644 app/entreprises/app_relations_entreprises.py diff --git a/app/entreprises/app_relations_entreprises.py b/app/entreprises/app_relations_entreprises.py new file mode 100644 index 000000000..c47000ce3 --- /dev/null +++ b/app/entreprises/app_relations_entreprises.py @@ -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 diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index 5135470e4..e3226c712 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -3,8 +3,6 @@ from config import Config from datetime import datetime, date import glob import shutil -import re -import requests from flask import render_template, redirect, url_for, request, flash, send_file, abort from flask.json import jsonify @@ -37,6 +35,7 @@ from app.entreprises.models import ( EntrepriseEnvoiOffre, EntrepriseOffreDepartement, ) +from app.entreprises import app_relations_entreprises as are from app.models import Identite from app.auth.models import User from app.scodoc.sco_permissions import Permission @@ -45,7 +44,6 @@ import app.scodoc.sco_utils as scu from app import db from sqlalchemy import text -from app.models.departements import Departement from werkzeug.utils import secure_filename @@ -121,21 +119,6 @@ def contacts(): ) -# temp -def get_dept_id(acronym): - dept = Departement.query.filter_by(acronym=acronym).first() - if dept is not None: - return dept.id - return None - - -def check_offre_dept(depts, offre_depts): - for offre_dept in offre_depts: - if offre_dept.dept_id in depts: - return True - return False - - @bp.route("/fiche_entreprise/", methods=["GET"]) @permission_required(Permission.RelationsEntreprisesView) def fiche_entreprise(id): @@ -147,32 +130,12 @@ def fiche_entreprise(id): """ entreprise = Entreprise.query.filter_by(id=id, visible=True).first_or_404() offres_with_files = [] - depts = [] - for role in current_user.user_roles: - dept_id = get_dept_id(role.dept) - if dept_id is not None: - depts.append(dept_id) + depts = are.get_depts() for offre in entreprise.offres: if date.today() < offre.expiration_date: - offre_depts = EntrepriseOffreDepartement.query.filter_by( - offre_id=offre.id - ).all() - if not offre_depts or check_offre_dept(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) - offres_with_files.append([offre, files, offre_depts]) + offre_with_files = are.get_offre_files_and_depts(offre, depts) + if offre_with_files is not None: + offres_with_files.append(offre_with_files) contacts = entreprise.contacts[:] logs = ( EntrepriseLog.query.order_by(EntrepriseLog.date.desc()) @@ -278,28 +241,13 @@ def offres_expirees(id): Permet d'afficher la liste des offres expirés d'une entreprise """ entreprise = Entreprise.query.filter_by(id=id, visible=True).first_or_404() - offres = entreprise.offres offres_expirees_with_files = [] - for offre in offres: + depts = are.get_depts() + for offre in entreprise.offres: if date.today() > offre.expiration_date: - 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) - offre_depts = EntrepriseOffreDepartement.query.filter_by( - offre_id=offre.id - ).all() - offres_expirees_with_files.append([offre, files, offre_depts]) + offre_expiree_with_files = are.get_offre_files_and_depts(offre, depts) + if offre_expiree_with_files is not None: + offres_expirees_with_files.append(offre_expiree_with_files) return render_template( "entreprises/offres_expirees.html", title="Offres expirées", @@ -936,22 +884,6 @@ def get_import_entreprises_file_sample(): return scu.send_file(xlsx, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE) -def verif_entreprise_data(entreprise_data): - for data in entreprise_data: - if data == "": - return False - siret = entreprise_data[0].strip() - 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 - - @bp.route("/import_entreprises", methods=["GET", "POST"]) @permission_required(Permission.RelationsEntreprisesExport) def import_entreprises(): @@ -981,7 +913,7 @@ def import_entreprises(): for entreprise_data in data[1][1:]: ligne += 1 if ( - verif_entreprise_data(entreprise_data) + are.verif_entreprise_data(entreprise_data) and entreprise_data[0] not in siret_list ): siret_list.append(entreprise_data[0]) @@ -1084,30 +1016,6 @@ def get_import_contacts_file_sample(): return scu.send_file(xlsx, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE) -def verif_contact_data(contact_data): - # champ nom, prenom et entreprise_id obligatoire - 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 - - # 1 moyen de contact - if contact_data[2] == "" and contact_data[3] == "": - return False - - return True - - @bp.route("/import_contacts", methods=["GET", "POST"]) @permission_required(Permission.RelationsEntreprisesExport) def import_contacts(): @@ -1145,7 +1053,7 @@ def import_contacts(): for contact_data in data[1][1:]: ligne += 1 if ( - verif_contact_data(contact_data) + are.verif_contact_data(contact_data) and (contact_data[0], contact_data[1], contact_data[6]) not in contact_list ): diff --git a/app/templates/entreprises/offres_recues.html b/app/templates/entreprises/offres_recues.html index e4de166eb..2d3c9698e 100644 --- a/app/templates/entreprises/offres_recues.html +++ b/app/templates/entreprises/offres_recues.html @@ -16,6 +16,7 @@ Type de l'offre : {{ offre[1].type_offre }}
Missions : {{ offre[1].missions }}
Durée : {{ offre[1].duree }}
+ lien vers l'entreprise
{% for fichier in offre[2] %} {{ fichier[1] }}