diff --git a/app/entreprises/forms.py b/app/entreprises/forms.py index ff95217a2..33b5c22de 100644 --- a/app/entreprises/forms.py +++ b/app/entreprises/forms.py @@ -123,12 +123,9 @@ class EntrepriseCreationForm(FlaskForm): self.prenom_correspondant.errors.append("Ce champ est requis") validate = False if not self.telephone.data.strip() and not self.mail.data.strip(): - self.telephone.errors.append( - "Saisir un moyen de contact (mail ou téléphone)" - ) - self.mail.errors.append( - "Saisir un moyen de contact (mail ou téléphone)" - ) + msg = "Saisir un moyen de contact (mail ou téléphone)" + self.telephone.errors.append(msg) + self.mail.errors.append(msg) validate = False return validate @@ -173,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): widget = ListWidget(prefix_label=False) option_widget = CheckboxInput() @@ -313,10 +319,9 @@ class CorrespondantCreationForm(FlaskForm): validate = False if not self.telephone.data and not self.mail.data: - self.telephone.errors.append( - "Saisir un moyen de contact (mail ou téléphone)" - ) - self.mail.errors.append("Saisir un moyen de contact (mail ou téléphone)") + msg = "Saisir un moyen de contact (mail ou téléphone)" + self.telephone.errors.append(msg) + self.mail.errors.append(msg) validate = False return validate @@ -399,10 +404,9 @@ class CorrespondantModificationForm(FlaskForm): validate = False if not self.telephone.data and not self.mail.data: - self.telephone.errors.append( - "Saisir un moyen de contact (mail ou téléphone)" - ) - self.mail.errors.append("Saisir un moyen de contact (mail ou téléphone)") + msg = "Saisir un moyen de contact (mail ou téléphone)" + self.telephone.errors.append(msg) + self.mail.errors.append(msg) validate = False return validate diff --git a/app/entreprises/models.py b/app/entreprises/models.py index f04d1a231..4a318d24a 100644 --- a/app/entreprises/models.py +++ b/app/entreprises/models.py @@ -9,16 +9,18 @@ class Entreprise(db.Model): adresse = db.Column(db.Text) codepostal = 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) active = db.Column(db.Boolean, default=True) notes_active = db.Column(db.Text) - correspondants = db.relationship( - "EntrepriseCorrespondant", + + sites = db.relationship( + "EntrepriseSite", backref="entreprise", lazy="dynamic", cascade="all, delete-orphan", ) + offres = db.relationship( "EntrepriseOffre", backref="entreprise", @@ -37,13 +39,24 @@ class Entreprise(db.Model): } -# class EntrepriseSite(db.Model): -# __tablename__ = "are_sites" -# id = db.Column(db.Integer, primary_key=True) -# entreprise_id = db.Column( -# db.Integer, db.ForeignKey("are_entreprises.id", ondelete="cascade") -# ) -# nom = db.Column(db.Text) +class EntrepriseSite(db.Model): + __tablename__ = "are_sites" + id = db.Column(db.Integer, primary_key=True) + entreprise_id = db.Column( + db.Integer, db.ForeignKey("are_entreprises.id", ondelete="cascade") + ) + 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): @@ -52,7 +65,7 @@ class EntrepriseCorrespondant(db.Model): entreprise_id = db.Column( 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) prenom = db.Column(db.Text) diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index d7c6ec132..edb536177 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -16,6 +16,7 @@ from app.entreprises.forms import ( DesactivationConfirmationForm, EntrepriseCreationForm, EntrepriseModificationForm, + SiteCreationForm, SuppressionConfirmationForm, OffreCreationForm, OffreModificationForm, @@ -37,6 +38,7 @@ from app.entreprises.models import ( EntrepriseCorrespondant, EntrepriseLog, EntrepriseContact, + EntrepriseSite, EntrepriseStageApprentissage, EntrepriseEnvoiOffre, EntrepriseOffreDepartement, @@ -146,9 +148,7 @@ def fiche_entreprise(id): offre_with_files = are.get_offre_files_and_depts(offre, depts) if offre_with_files is not None: offres_with_files.append(offre_with_files) - correspondants = [] - if current_user.has_permission(Permission.RelationsEntreprisesCorrespondants, None): - correspondants = entreprise.correspondants[:] + sites = entreprise.sites[:] logs = ( EntrepriseLog.query.order_by(EntrepriseLog.date.desc()) .filter_by(object=id) @@ -166,7 +166,7 @@ def fiche_entreprise(id): "entreprises/fiche_entreprise.html", title="Fiche entreprise", entreprise=entreprise, - correspondants=correspondants, + sites=sites, offres=offres_with_files, logs=logs, stages_apprentissages=stages_apprentissages, @@ -297,10 +297,22 @@ def add_entreprise(): ) db.session.add(entreprise) 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(): - db.session.refresh(entreprise) + db.session.refresh(site) correspondant = EntrepriseCorrespondant( entreprise_id=entreprise.id, + site_id=site.id, civilite=form.civilite.data, nom=form.nom_correspondant.data.strip(), prenom=form.prenom_correspondant.data.strip(), @@ -716,20 +728,57 @@ def expired(id): return redirect(url_for("entreprises.fiche_entreprise", id=offre.entreprise_id)) -@bp.route("/fiche_entreprise//add_correspondant", methods=["GET", "POST"]) +@bp.route( + "/fiche_entreprise//add_site", + methods=["GET", "POST"], +) @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//add_correspondant/", + methods=["GET", "POST"], +) +@permission_required(Permission.RelationsEntreprisesChange) +def add_correspondant(id_entreprise, id_site): """ Permet d'ajouter un correspondant a une entreprise """ - entreprise = Entreprise.query.filter_by(id=id, visible=True).first_or_404( - description=f"entreprise {id} inconnue" + entreprise = Entreprise.query.filter_by( + 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) if form.validate_on_submit(): for correspondant_entry in form.correspondants.entries: correspondant = EntrepriseCorrespondant( entreprise_id=entreprise.id, + site_id=site.id, civilite=correspondant_entry.civilite.data, nom=correspondant_entry.nom.data.strip(), prenom=correspondant_entry.prenom.data.strip(), @@ -789,7 +838,7 @@ def edit_correspondant(id): db.session.commit() flash("Le correspondant a été modifié.") return redirect( - url_for("entreprises.fiche_entreprise", id=correspondant.entreprise.id) + url_for("entreprises.fiche_entreprise", id=correspondant.entreprise_id) ) elif request.method == "GET": form.civilite.data = correspondant.civilite diff --git a/app/static/css/entreprises.css b/app/static/css/entreprises.css index 1f4e5f233..436288666 100644 --- a/app/static/css/entreprises.css +++ b/app/static/css/entreprises.css @@ -54,23 +54,24 @@ margin-bottom: -5px; } -.entreprise, .correspondant, .offre { +.entreprise, .correspondant, .offre, .site{ border: solid 2px; border-radius: 10px; padding: 10px; margin-bottom: 10px; + margin-top: 10px; } -.correspondants-et-offres { +.sites-et-offres { display: flex; justify-content: space-between; } -.correspondants-et-offres > div { +.sites-et-offres > div { flex: 1 0 0; } -.correspondants-et-offres > div:nth-child(2) { +.sites-et-offres > div:nth-child(2) { margin-left: 20px; } diff --git a/app/templates/entreprises/fiche_entreprise.html b/app/templates/entreprises/fiche_entreprise.html index 938be46be..c58dfeb71 100644 --- a/app/templates/entreprises/fiche_entreprise.html +++ b/app/templates/entreprises/fiche_entreprise.html @@ -37,24 +37,39 @@ - {% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
+ {% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} Modifier + Désactiver Supprimer + Ajouter site Ajouter offre - Ajouter correspondant {% endif %} Liste contacts Voir les offres expirées -
+
-
- {% if correspondants %} +
+ {% if sites %}
-

Correspondants

- {% for correspondant in correspondants %} - {% include 'entreprises/_correspondant.html' %} +

Sites

+ {% for site in sites %} +
+ Nom : {{ site.nom }}
+ Adresse : {{ site.adresse }}
+ Code postal : {{ site.codepostal }}
+ Ville : {{ site.ville }}
+ Pays : {{ site.pays }} + {% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} +
Ajouter correspondant + {% endif %} + {% if current_user.has_permission(current_user.Permission.RelationsEntreprisesCorrespondants, None) %} + {% for correspondant in site.correspondants %} + {% include 'entreprises/_correspondant.html' %} + {% endfor %} + {% endif %} +
{% endfor %}
{% endif %} @@ -63,7 +78,7 @@

Offres - Voir les offres expirées

{% for offre in offres %} - {% include 'entreprises/_offre.html' %} + {% include 'entreprises/_offre.html' %} {% endfor %}
{% endif %} diff --git a/migrations/versions/01d13209021e_ajout_colonnes_tables_relations_.py b/migrations/versions/01d13209021e_ajout_colonnes_tables_relations_.py deleted file mode 100644 index 94a586f5d..000000000 --- a/migrations/versions/01d13209021e_ajout_colonnes_tables_relations_.py +++ /dev/null @@ -1,40 +0,0 @@ -"""ajout colonnes tables relations entreprises - -Revision ID: 01d13209021e -Revises: e97b2a10f86c -Create Date: 2022-04-21 21:02:01.319876 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = "01d13209021e" -down_revision = "e97b2a10f86c" -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - 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.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_column("are_correspondants", "notes") - op.drop_column("are_correspondants", "origine") - op.drop_column("are_correspondants", "civilite") - # ### end Alembic commands ### diff --git a/migrations/versions/d5b3bdd1d622_ajout_colonnes_tables_relations_.py b/migrations/versions/d5b3bdd1d622_ajout_colonnes_tables_relations_.py new file mode 100644 index 000000000..dd5a5982b --- /dev/null +++ b/migrations/versions/d5b3bdd1d622_ajout_colonnes_tables_relations_.py @@ -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 ###