Compare commits

...

16 Commits

Author SHA1 Message Date
leonard_montalbano
aba6330065 ajout des tests pour la version 'long' de etudiant_courant + correction routes et doc sur les fichiers api 2022-04-28 16:12:15 +02:00
07cdd29716 API: /etudiants/courant/long et /etudiants/courant 2022-04-28 03:24:37 +02:00
86ef24586d merge 2022-04-28 01:20:52 +02:00
c5904d75a8 Merge branch 'new_api' of https://scodoc.org/git/viennet/ScoDoc 2022-04-28 01:19:49 +02:00
7010aefab3 Merge pull request 'rectification de la route /departements' (#372) from leonard.montalbano/ScoDoc:new_api into new_api
Reviewed-on: https://scodoc.org/git/ScoDoc/ScoDoc/pulls/372
2022-04-28 09:20:09 +02:00
7866743eb8 Fix: list_abs_date 2022-04-28 01:14:25 +02:00
e90f3077f8 Fix: fusion permissions entreprise 2022-04-27 09:58:14 +02:00
5472d16f54 Merge branch 'entreprises' of https://scodoc.org/git/viennet/ScoDoc 2022-04-27 09:49:11 +02:00
a5a1a84436 Merge branch 'entreprises' of https://scodoc.org/git/arthur.zhu/ScoDoc into entreprises 2022-04-27 09:42:32 +02:00
3d91d2f456 plus de bouton, fonction 'supprimer' sur les entreprises 2022-04-26 20:25:21 +02:00
94f1e24d36 ajout bouton retirer sur les formulaires 2022-04-26 20:21:56 +02:00
128fa38d82 ajout site pour les entreprises, corrections de bugs 2022-04-25 20:49:21 +02:00
2349114eb3 changement import/export correspondants, formulaires 2022-04-22 11:27:17 +02:00
ff228aef4e desactiver entreprise, visibilité correspondants 2022-04-21 21:18:47 +02:00
196f80e210 fix downgrade, ajout colonnes sur les tables relations entreprises 2022-04-20 22:37:45 +02:00
cf0a136071 enrichissement correspondant, desactiver une entreprise 2022-04-20 22:37:04 +02:00
31 changed files with 580 additions and 282 deletions

View File

@ -93,7 +93,7 @@ def absences_just(etudid: int = None, nip: int = None, ine: int = None):
"jour": "Fri, 15 Apr 2022 00:00:00 GMT", "jour": "Fri, 15 Apr 2022 00:00:00 GMT",
"matin": false, "matin": false,
"estabs": true, "estabs": true,
"estjust": false, "estjust": true,
"description": "", "description": "",
"begin": "2022-04-15 12:00:00", "begin": "2022-04-15 12:00:00",
"end": "2022-04-15 17:59:59" "end": "2022-04-15 17:59:59"
@ -120,7 +120,11 @@ def absences_just(etudid: int = None, nip: int = None, ine: int = None):
@bp.route( @bp.route(
"/absences/abs_group_etat/?group_id=<int:group_id>&date_debut=date_debut&date_fin=date_fin", "/absences/abs_group_etat/<int:group_id>",
methods=["GET"],
)
@bp.route(
"/absences/abs_group_etat/group_id/<int:group_id>/date_debut/<string:date_debut>/date_fin/<string:date_fin>",
methods=["GET"], methods=["GET"],
) )
@token_permission_required(Permission.APIView) @token_permission_required(Permission.APIView)

View File

@ -12,12 +12,12 @@ from app.models import FormSemestreInscription, FormSemestre, Identite
from app.scodoc import sco_bulletins from app.scodoc import sco_bulletins
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc.sco_permissions import Permission from app.scodoc.sco_permissions import Permission
from app.scodoc import notesdb as ndb
@bp.route("/etudiants/courant", methods=["GET"]) @bp.route("/etudiants/courant", defaults={"long": False})
@bp.route("/etudiants/courant/long", defaults={"long": True})
@token_permission_required(Permission.APIView) @token_permission_required(Permission.APIView)
def etudiants_courant(): def etudiants_courant(long=False):
""" """
Retourne la liste des étudiants courant Retourne la liste des étudiants courant
@ -55,9 +55,11 @@ def etudiants_courant():
FormSemestre.date_debut <= app.db.func.now(), FormSemestre.date_debut <= app.db.func.now(),
FormSemestre.date_fin >= app.db.func.now(), FormSemestre.date_fin >= app.db.func.now(),
) )
if long:
data = [etu.to_dict_bul(include_urls=False) for etu in etuds] data = [etud.to_dict_bul(include_urls=False) for etud in etuds]
else:
data = [etud.to_dict_short() for etud in etuds]
print(jsonify(data))
return jsonify(data) return jsonify(data)

View File

@ -62,27 +62,27 @@ def evaluation_notes(evaluation_id: int):
evaluation_id : l'id d'une évaluation evaluation_id : l'id d'une évaluation
Exemple de résultat : Exemple de résultat :
{ {
"1": { "1": {
"id": 1, "id": 1,
"etudid": 10, "etudid": 10,
"evaluation_id": 1, "evaluation_id": 1,
"value": 15.0, "value": 15.0,
"comment": "", "comment": "",
"date": "Wed, 20 Apr 2022 06:49:05 GMT", "date": "Wed, 20 Apr 2022 06:49:05 GMT",
"uid": 2 "uid": 2
}, },
"2": { "2": {
"id": 2, "id": 2,
"etudid": 1, "etudid": 1,
"evaluation_id": 1, "evaluation_id": 1,
"value": 12.0, "value": 12.0,
"comment": "", "comment": "",
"date": "Wed, 20 Apr 2022 06:49:06 GMT", "date": "Wed, 20 Apr 2022 06:49:06 GMT",
"uid": 2 "uid": 2
}, },
... ...
} }
""" """
# Fonction utilisée : app.scodoc.sco_evaluation_db.do_evaluation_get_all_notes() # Fonction utilisée : app.scodoc.sco_evaluation_db.do_evaluation_get_all_notes()

View File

@ -177,7 +177,7 @@ def formation_export_by_formation_id(formation_id: int, export_ids=False):
try: try:
# Utilisation de la fonction formation_export # Utilisation de la fonction formation_export
data = formation_export(formation_id) data = formation_export(formation_id, export_ids)
except ValueError: except ValueError:
return error_response( return error_response(
409, 409,
@ -192,15 +192,15 @@ def formation_export_by_formation_id(formation_id: int, export_ids=False):
@token_permission_required(Permission.APIView) @token_permission_required(Permission.APIView)
def moduleimpls(moduleimpl_id: int): def moduleimpls(moduleimpl_id: int):
""" """
Retourne la liste des moduleimpl Retourne un module moduleimpl en fonction de son id
moduleimpl_id : l'id d'un moduleimpl moduleimpl_id : l'id d'un moduleimpl
""" """
# Récupération des tous les moduleimpl # Récupération des tous les moduleimpl
list_moduleimpls = models.ModuleImpl.query.filter_by(id=moduleimpl_id) moduleimpl = models.ModuleImpl.query.filter_by(id=moduleimpl_id).first_or_404()
# Mise en forme des données # Mise en forme des données
data = [moduleimpl.to_dict() for moduleimpl in list_moduleimpls] data = moduleimpl.to_dict()
return jsonify(data) return jsonify(data)
@ -208,7 +208,7 @@ def moduleimpls(moduleimpl_id: int):
@bp.route( @bp.route(
"/formations/moduleimpl/formsemestre/<int:formsemestre_id>/liste", "/formations/moduleimpl/formsemestre/<int:formsemestre_id>/liste",
methods=["GET"], methods=["GET"],
) # XXX TODO penser à changer la route sur la doc )
@token_permission_required(Permission.APIView) @token_permission_required(Permission.APIView)
def moduleimpls_sem(formsemestre_id: int): def moduleimpls_sem(formsemestre_id: int):
""" """

View File

@ -68,6 +68,35 @@ def formsemestre_apo(etape_apo: str):
Retourne les informations sur les formsemestres Retourne les informations sur les formsemestres
etape_apo : l'id d'une étape apogée etape_apo : l'id d'une étape apogée
Exemple de résultat :
{
"date_fin": "31/08/2022",
"resp_can_edit": false,
"dept_id": 1,
"etat": true,
"resp_can_change_ens": true,
"id": 1,
"modalite": "FI",
"ens_can_edit_eval": false,
"formation_id": 1,
"gestion_compensation": false,
"elt_sem_apo": null,
"semestre_id": 1,
"bul_hide_xml": false,
"elt_annee_apo": null,
"titre": "Semestre test",
"block_moyennes": false,
"scodoc7_id": null,
"date_debut": "01/09/2021",
"gestion_semestrielle": false,
"bul_bgcolor": "white",
"formsemestre_id": 1,
"titre_num": "Semestre test semestre 1",
"date_debut_iso": "2021-09-01",
"date_fin_iso": "2022-08-31",
"responsables": []
}
""" """
formsemestres = FormSemestre.query.filter( formsemestres = FormSemestre.query.filter(
FormSemestreEtape.etape_apo == etape_apo, FormSemestreEtape.etape_apo == etape_apo,

View File

@ -121,13 +121,13 @@ def etud_in_group(group_id: int, etat=None):
@bp.route( @bp.route(
"/partitions/set_groups?partition_id=<int:partition_id>&groups_lists=<int:groups_lists>&" "/partitions/set_groups/partition/<int:partition_id>/groups/<string:groups_id>/delete/<string:groups_to_delete>"
"groups_to_create=<int:groups_to_create>&groups_to_delete=<int:groups_to_delete>", "/create/<string:groups_to_create>",
methods=["POST"], methods=["POST"],
) )
@token_permission_required(Permission.APIEtudChangeGroups) @token_permission_required(Permission.APIEtudChangeGroups)
def set_groups( def set_groups(
partition_id: int, groups_lists: int, groups_to_delete: int, groups_to_create: int partition_id: int, groups_lists: str, groups_to_delete: str, groups_to_create: str
): ):
""" """
Set les groups Set les groups

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -141,7 +141,18 @@ class Identite(db.Model):
"Le mail associé à la première adrese de l'étudiant, ou None" "Le mail associé à la première adrese de l'étudiant, ou None"
return getattr(self.adresses[0], field) if self.adresses.count() > 0 else None return getattr(self.adresses[0], field) if self.adresses.count() > 0 else None
def to_dict_scodoc7(self): def to_dict_short(self) -> dict:
"""Les champs essentiels"""
return {
"id": self.id,
"nip": self.code_nip,
"nom": self.nom,
"nom_usuel": self.nom_usuel,
"prenom": self.prenom,
"civilite": self.civilite,
}
def to_dict_scodoc7(self) -> dict:
"""Représentation dictionnaire, """Représentation dictionnaire,
compatible ScoDoc7 mais sans infos admission compatible ScoDoc7 mais sans infos admission
""" """

View File

@ -423,17 +423,19 @@ def list_abs_date(etudid, beg_date=None, end_date=None):
print("On rentre") print("On rentre")
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
print("Juste avant le SQL")
cursor.execute( req = """SELECT jour, matin, estabs, estjust, description
"""SELECT jour, matin, estabs, estjust, description FROM ABSENCES A FROM ABSENCES A
WHERE A.ETUDID = %(etudid)s""" WHERE A.ETUDID = %(etudid)s""" + (
+ "" ""
if beg_date is None if beg_date is None
else """ else """
AND A.jour >= %(beg_date)s AND A.jour >= %(beg_date)s
AND A.jour <= %(end_date)s AND A.jour <= %(end_date)s
""", """
)
cursor.execute(
req,
vars(), vars(),
) )

View File

@ -47,6 +47,7 @@ _SCO_PERMISSIONS = (
), ),
(1 << 25, "RelationsEntreprisesSend", "Envoyer des offres"), (1 << 25, "RelationsEntreprisesSend", "Envoyer des offres"),
(1 << 26, "RelationsEntreprisesValidate", "Valide les entreprises"), (1 << 26, "RelationsEntreprisesValidate", "Valide les entreprises"),
(1 << 27, "RelationsEntreprisesCorrespondants", "Voir les correspondants"),
# 27 à 39 ... réservé pour "entreprises" # 27 à 39 ... réservé pour "entreprises"
# Api scodoc9 # Api scodoc9
(1 << 40, "APIView", "Voir"), (1 << 40, "APIView", "Voir"),

View File

@ -63,7 +63,11 @@ SCO_ROLES_DEFAULTS = {
# ObservateurEntreprise est un observateur de l'application entreprise # ObservateurEntreprise est un observateur de l'application entreprise
"ObservateurEntreprise": (p.RelationsEntreprisesView,), "ObservateurEntreprise": (p.RelationsEntreprisesView,),
# UtilisateurEntreprise est un utilisateur de l'application entreprise (droit de modification) # UtilisateurEntreprise est un utilisateur de l'application entreprise (droit de modification)
"UtilisateurEntreprise": (p.RelationsEntreprisesView, p.RelationsEntreprisesChange), "UtilisateurEntreprise": (
p.RelationsEntreprisesView,
p.RelationsEntreprisesChange,
p.RelationsEntreprisesCorrespondants,
),
# AdminEntreprise est un admin de l'application entreprise (toutes les actions possibles de l'application) # AdminEntreprise est un admin de l'application entreprise (toutes les actions possibles de l'application)
"AdminEntreprise": ( "AdminEntreprise": (
p.RelationsEntreprisesView, p.RelationsEntreprisesView,
@ -71,6 +75,7 @@ SCO_ROLES_DEFAULTS = {
p.RelationsEntreprisesExport, p.RelationsEntreprisesExport,
p.RelationsEntreprisesSend, p.RelationsEntreprisesSend,
p.RelationsEntreprisesValidate, p.RelationsEntreprisesValidate,
p.RelationsEntreprisesCorrespondants,
), ),
# LecteurAPI peut utiliser l'API en lecture # LecteurAPI peut utiliser l'API en lecture
"LecteurAPI": (p.APIView,), "LecteurAPI": (p.APIView,),

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
# -*- mode: python -*- # -*- mode: python -*-
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
SCOVERSION = "9.2.12" SCOVERSION = "9.2.14"
SCONAME = "ScoDoc" SCONAME = "ScoDoc"

View File

@ -23,85 +23,16 @@ import requests
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
# # etudiants
# def test_etudiants():
#
# fields = [
# "civilite",
# "code_ine",
# "code_nip",
# "date_naissance",
# "email",
# "emailperso",
# "etudid",
# "nom",
# "prenom",
# "nomprenom",
# "lieu_naissance",
# "dept_naissance",
# "nationalite",
# "boursier",
# "id",
# "domicile",
# "villedomicile",
# "telephone",
# "fax",
# "description",
# "codepostaldomicile",
# "paysdomicile",
# "telephonemobile",
# "typeadresse",
# ]
#
# r = requests.get(
# SCODOC_URL + "/ScoDoc/api/etudiants",
# headers=HEADERS,
# verify=CHECK_CERTIFICATE,
# )
# assert r.status_code == 200
# assert len(r.json()) == 16
#
# # Choisis aléatoirement un étudiant dans la liste des étudiants
# etu = r.json()[randint(0, len(r.json())) - 1]
#
# fields_OK = True
#
# # Vérifie si tous les champs sont bien présents
# for field in etu:
# if field not in fields:
# fields_OK = False
#
# assert fields_OK is True
# etudiants_courant # etudiants_courant
def test_etudiants_courant(): # XXX TODO pour Seb def test_etudiants_courant(): # XXX TODO pour Seb
fields = [ fields = [
"civilite",
"code_ine",
"code_nip",
"date_naissance",
"email",
"emailperso",
"etudid",
"nom",
"prenom",
"nomprenom",
"lieu_naissance",
"dept_naissance",
"nationalite",
"boursier",
"id", "id",
"domicile", "nip",
"villedomicile", "nom",
"telephone", "nom_usuel",
"fax", "prenom",
"description", "civilite",
"codepostaldomicile",
"paysdomicile",
"telephonemobile",
"typeadresse",
] ]
r = requests.get( r = requests.get(
@ -124,6 +55,55 @@ def test_etudiants_courant(): # XXX TODO pour Seb
assert fields_OK is True assert fields_OK is True
########## Version long################
fields_long = [
"civilite",
"code_ine",
"code_nip",
"date_naissance",
"email",
"emailperso",
"etudid",
"nom",
"prenom",
"nomprenom",
"lieu_naissance",
"dept_naissance",
"nationalite",
"boursier",
"id",
"codepostaldomicile",
"paysdomicile",
"telephonemobile",
"typeadresse",
"domicile",
"villedomicile",
"telephone",
"fax",
"description",
]
r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiants/courant/long",
headers=HEADERS,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 200
assert len(r.json()) == 16
# Choisis aléatoirement un étudiant dans la liste des étudiants
etu = r.json()[randint(0, len(r.json())) - 1]
fields_OK = True
# Vérifie si tous les champs sont bien présents
for field in etu:
if field not in fields_long:
fields_OK = False
assert fields_OK is True
# etudiant # etudiant
def test_etudiant(): # XXX TODO pour Seb def test_etudiant(): # XXX TODO pour Seb