attacher un fichier (pdf, docx) à une offre (stockés sur disque)

This commit is contained in:
Arthur ZHU 2021-12-27 19:00:38 +01:00
parent 5684f57ca5
commit a7ef5d81c5
6 changed files with 43 additions and 16 deletions

View File

@ -2,8 +2,9 @@ from flask import flash
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from markupsafe import Markup from markupsafe import Markup
import requests, re import requests, re
from wtforms import StringField, SubmitField, TextAreaField, SelectField, FileField, HiddenField from wtforms import StringField, SubmitField, TextAreaField, SelectField, HiddenField
from wtforms.fields.html5 import EmailField, DateField from wtforms.fields.html5 import EmailField, DateField
from flask_wtf.file import FileField, FileAllowed
from wtforms.validators import ValidationError, DataRequired, Email from wtforms.validators import ValidationError, DataRequired, Email
from app.entreprises.models import Entreprise, EntrepriseContact from app.entreprises.models import Entreprise, EntrepriseContact
from app.models import Identite from app.models import Identite
@ -14,7 +15,7 @@ from sqlalchemy import text
DATA_REQUIRED_ERROR_MESSAGE = "Ce champ est requis" DATA_REQUIRED_ERROR_MESSAGE = "Ce champ est requis"
class EntrepriseCreationForm(FlaskForm): class EntrepriseCreationForm(FlaskForm):
siret = StringField("SIRET", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)], render_kw={"placeholder": "Numéro composé de 14 chiffres"}) siret = StringField("SIRET", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)], render_kw={"placeholder": "Numéro composé de 14 chiffres", "maxlength": "14"})
nom_entreprise = StringField("Nom de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) nom_entreprise = StringField("Nom de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)])
adresse = StringField("Adresse de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) adresse = StringField("Adresse de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)])
codepostal = StringField("Code postal de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) codepostal = StringField("Code postal de l'entreprise", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)])
@ -56,7 +57,7 @@ class OffreCreationForm(FlaskForm):
type_offre = SelectField("Type de l'offre", choices=[('Stage'), ('Alternance')], validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) type_offre = SelectField("Type de l'offre", choices=[('Stage'), ('Alternance')], validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)])
missions = TextAreaField("Missions", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) missions = TextAreaField("Missions", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)])
duree = StringField("Durée", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)]) duree = StringField("Durée", validators=[DataRequired(message=DATA_REQUIRED_ERROR_MESSAGE)])
ficher = FileField("Fichier", validators=[]) fichier = FileField("Fichier", validators=[FileAllowed(['pdf', 'docx'], 'Fichier .pdf ou .docx uniquement')])
submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"}) submit = SubmitField("Envoyer", render_kw={"style": "margin-bottom: 10px;"})
class OffreModificationForm(FlaskForm): class OffreModificationForm(FlaskForm):

View File

@ -53,6 +53,7 @@ class EntrepriseOffre(db.Model):
type_offre = db.Column(db.Text) type_offre = db.Column(db.Text)
missions = db.Column(db.Text) missions = db.Column(db.Text)
duree = db.Column(db.Text) duree = db.Column(db.Text)
filename = db.Column(db.Text)
class EntrepriseLog(db.Model): class EntrepriseLog(db.Model):
__tablename__ = "entreprise_log" __tablename__ = "entreprise_log"

View File

@ -1,3 +1,6 @@
import os
from config import Config
from flask import render_template, redirect, url_for, request, flash, send_file, abort from flask import render_template, redirect, url_for, request, flash, send_file, abort
from flask.json import jsonify from flask.json import jsonify
from flask_login import current_user from flask_login import current_user
@ -36,6 +39,7 @@ import app.scodoc.sco_utils as scu
from app import db from app import db
from sqlalchemy import text from sqlalchemy import text
from werkzeug.utils import secure_filename, send_from_directory
@bp.route("/", methods=["GET"]) @bp.route("/", methods=["GET"])
def index(): def index():
@ -50,7 +54,7 @@ def contacts():
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("entreprises/contacts.html", title=("Contacts"), contacts=contacts, logs=logs) return render_template("entreprises/contacts.html", title=("Contacts"), contacts=contacts, logs=logs)
@bp.route("/fiche_entreprise/<id>", methods=["GET"]) @bp.route("/fiche_entreprise/<int:id>", methods=["GET"])
def fiche_entreprise(id): def fiche_entreprise(id):
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
@ -103,7 +107,7 @@ def add_entreprise():
return redirect(url_for("entreprises.index")) return redirect(url_for("entreprises.index"))
return render_template("entreprises/ajout_entreprise.html", title=("Ajout entreprise + contact"), form=form) return render_template("entreprises/ajout_entreprise.html", title=("Ajout entreprise + contact"), form=form)
@bp.route("/edit_entreprise/<id>", methods=["GET", "POST"]) @bp.route("/edit_entreprise/<int:id>", methods=["GET", "POST"])
def edit_entreprise(id): def edit_entreprise(id):
entreprise = Entreprise.query.filter_by(id=id).first_or_404() entreprise = Entreprise.query.filter_by(id=id).first_or_404()
form = EntrepriseModificationForm() form = EntrepriseModificationForm()
@ -161,7 +165,7 @@ def edit_entreprise(id):
form.pays.data = entreprise.pays form.pays.data = entreprise.pays
return render_template("entreprises/form.html", title=("Modification entreprise"), form=form) return render_template("entreprises/form.html", title=("Modification entreprise"), form=form)
@bp.route("/delete_entreprise/<id>", methods=["GET", "POST"]) @bp.route("/delete_entreprise/<int:id>", methods=["GET", "POST"])
def delete_entreprise(id): def delete_entreprise(id):
entreprise = Entreprise.query.filter_by(id=id).first_or_404() entreprise = Entreprise.query.filter_by(id=id).first_or_404()
form = SuppressionConfirmationForm() form = SuppressionConfirmationForm()
@ -178,7 +182,7 @@ def delete_entreprise(id):
return redirect(url_for("entreprises.index")) return redirect(url_for("entreprises.index"))
return render_template("entreprises/delete_confirmation.html", title=("Supression entreprise"), form=form) return render_template("entreprises/delete_confirmation.html", title=("Supression entreprise"), form=form)
@bp.route("/add_offre/<id>", methods=["GET", "POST"]) @bp.route("/add_offre/<int:id>", methods=["GET", "POST"])
def add_offre(id): def add_offre(id):
entreprise = Entreprise.query.filter_by(id=id).first_or_404() entreprise = Entreprise.query.filter_by(id=id).first_or_404()
form = OffreCreationForm() form = OffreCreationForm()
@ -191,19 +195,29 @@ def add_offre(id):
missions=form.missions.data.strip(), missions=form.missions.data.strip(),
duree=form.duree.data.strip() duree=form.duree.data.strip()
) )
db.session.add(offre)
db.session.commit()
if form.fichier.data is not None:
db.session.refresh(offre)
path = os.path.join(Config.SCODOC_VAR_DIR, "entreprises", f"{entreprise.id}", f"{offre.id}")
os.makedirs(path)
file = form.fichier.data
filename = secure_filename(file.filename)
file.save(os.path.join(path, filename))
offre.offre_filename = f"{filename}"
db.session.commit()
log = EntrepriseLog( log = EntrepriseLog(
authenticated_user = current_user.user_name, authenticated_user = current_user.user_name,
object = entreprise.id, object = entreprise.id,
text = "Création d'une offre", text = "Création d'une offre",
) )
db.session.add(log) db.session.add(log)
db.session.add(offre)
db.session.commit() db.session.commit()
flash("L'offre a été ajouté à la fiche entreprise.") flash("L'offre a été ajouté à 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("entreprises/form.html", title=("Ajout offre"), form=form) return render_template("entreprises/form.html", title=("Ajout offre"), form=form)
@bp.route("/edit_offre/<id>", methods=["GET", "POST"]) @bp.route("/edit_offre/<int:id>", methods=["GET", "POST"])
def edit_offre(id): def edit_offre(id):
offre = EntrepriseOffre.query.filter_by(id=id).first_or_404() offre = EntrepriseOffre.query.filter_by(id=id).first_or_404()
form = OffreModificationForm() form = OffreModificationForm()
@ -230,7 +244,7 @@ def edit_offre(id):
form.duree.data = offre.duree form.duree.data = offre.duree
return render_template("entreprises/form.html", title=("Modification offre"), form=form) return render_template("entreprises/form.html", title=("Modification offre"), form=form)
@bp.route("/delete_offre/<id>", methods=["GET", "POST"]) @bp.route("/delete_offre/<int:id>", methods=["GET", "POST"])
def delete_offre(id): def delete_offre(id):
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
@ -248,7 +262,7 @@ def delete_offre(id):
return redirect(url_for("entreprises.fiche_entreprise", id=entreprise_id)) return redirect(url_for("entreprises.fiche_entreprise", id=entreprise_id))
return render_template("entreprises/delete_confirmation.html", title=("Supression offre"), form=form) return render_template("entreprises/delete_confirmation.html", title=("Supression offre"), form=form)
@bp.route("/add_contact/<id>", methods=["GET", "POST"]) @bp.route("/add_contact/<int:id>", methods=["GET", "POST"])
def add_contact(id): def add_contact(id):
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)
@ -274,7 +288,7 @@ def add_contact(id):
return redirect(url_for("entreprises.fiche_entreprise", id=entreprise.id)) return redirect(url_for("entreprises.fiche_entreprise", id=entreprise.id))
return render_template("entreprises/form.html", title=("Ajout contact"), form=form) return render_template("entreprises/form.html", title=("Ajout contact"), form=form)
@bp.route("/edit_contact/<id>", methods=["GET", "POST"]) @bp.route("/edit_contact/<int:id>", methods=["GET", "POST"])
def edit_contact(id): def edit_contact(id):
contact = EntrepriseContact.query.filter_by(id=id).first_or_404() contact = EntrepriseContact.query.filter_by(id=id).first_or_404()
form = ContactModificationForm() form = ContactModificationForm()
@ -303,7 +317,7 @@ def edit_contact(id):
form.service.data = contact.service form.service.data = contact.service
return render_template("entreprises/form.html", title=("Modification contact"), form=form) return render_template("entreprises/form.html", title=("Modification contact"), form=form)
@bp.route("/delete_contact/<id>", methods=["GET", "POST"]) @bp.route("/delete_contact/<int:id>", methods=["GET", "POST"])
def delete_contact(id): def delete_contact(id):
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
@ -326,7 +340,7 @@ def delete_contact(id):
return redirect(url_for("entreprises.fiche_entreprise", id=entreprise_id)) return redirect(url_for("entreprises.fiche_entreprise", id=entreprise_id))
return render_template("entreprises/delete_confirmation.html", title=("Supression contact"), form=form) return render_template("entreprises/delete_confirmation.html", title=("Supression contact"), form=form)
@bp.route("/add_historique/<id>", methods=["GET", "POST"]) @bp.route("/add_historique/<int:id>", methods=["GET", "POST"])
def add_historique(id): def add_historique(id):
entreprise = Entreprise.query.filter_by(id=id).first_or_404() entreprise = Entreprise.query.filter_by(id=id).first_or_404()
form = HistoriqueCreationForm() form = HistoriqueCreationForm()
@ -352,7 +366,7 @@ def add_historique(id):
return redirect(url_for("entreprises.fiche_entreprise", id=entreprise.id)) return redirect(url_for("entreprises.fiche_entreprise", id=entreprise.id))
return render_template("entreprises/ajout_historique.html", title=("Ajout historique"), form=form) return render_template("entreprises/ajout_historique.html", title=("Ajout historique"), form=form)
@bp.route("/envoyer_offre/<id>", methods=["GET", "POST"]) @bp.route("/envoyer_offre/<int:id>", methods=["GET", "POST"])
def envoyer_offre(id): def envoyer_offre(id):
offre = EntrepriseOffre.query.filter_by(id=id).first_or_404() offre = EntrepriseOffre.query.filter_by(id=id).first_or_404()
form = EnvoiOffreForm() form = EnvoiOffreForm()
@ -449,5 +463,12 @@ def export_contacts():
xlsx = sco_excel.excel_simple_table(titles=titles, lines=L, sheet_name=title) xlsx = sco_excel.excel_simple_table(titles=titles, lines=L, sheet_name=title)
filename = title filename = title
return scu.send_file(xlsx, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE) return scu.send_file(xlsx, filename, scu.XLSX_SUFFIX, scu.XLSX_MIMETYPE)
else:
abort(404)
@bp.route("/download_offre/<int:entreprise_id>/<int:offre_id>/<string:filename>")
def download_offre(entreprise_id, offre_id, filename):
if os.path.isfile(os.path.join(Config.SCODOC_VAR_DIR, "entreprises", f"{entreprise_id}", f"{offre_id}", f"{filename}")):
return send_file(os.path.join(Config.SCODOC_VAR_DIR, "entreprises", f"{entreprise_id}", f"{offre_id}", f"{filename}"), as_attachment=True)
else: else:
abort(404) abort(404)

View File

@ -5,6 +5,9 @@
Type de l'offre : {{ offre.type_offre }}<br> Type de l'offre : {{ offre.type_offre }}<br>
Missions : {{ offre.missions }}<br> Missions : {{ offre.missions }}<br>
Durée : {{ offre.duree }}<br> Durée : {{ offre.duree }}<br>
{% if offre.offre_filename %}
<a href="{{ url_for('entreprises.download_offre', entreprise_id=entreprise.id, offre_id=offre.id, filename=offre.filename) }}">Téléchargez le fichier de l'offre</a>
{% endif %}
</p> </p>
<div style="margin-bottom: 10px;"> <div style="margin-bottom: 10px;">

View File

@ -38,7 +38,7 @@
<a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action <a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action
<span class="caret"></span> <span class="caret"></span>
</a> </a>
<ul class="dropdown-menu"> <ul class="dropdown-menu pull-right">
<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.delete_entreprise', id=entreprise.id) }}" style="color:red">Supprimer</a></li>
</ul> </ul>

View File

@ -49,6 +49,7 @@ def upgrade():
sa.Column('type_offre', sa.Text(), nullable=True), sa.Column('type_offre', sa.Text(), nullable=True),
sa.Column('missions', sa.Text(), nullable=True), sa.Column('missions', sa.Text(), nullable=True),
sa.Column('duree', sa.Text(), nullable=True), sa.Column('duree', sa.Text(), nullable=True),
sa.Column('filename', sa.Text(), nullable=True),
sa.ForeignKeyConstraint(['entreprise_id'], ['entreprises.id'], ondelete='cascade'), sa.ForeignKeyConstraint(['entreprise_id'], ['entreprises.id'], ondelete='cascade'),
sa.PrimaryKeyConstraint('id') sa.PrimaryKeyConstraint('id')
) )