Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Structures): SiaeActivity : formulaire pour créer une nouvelle activité #1278

Merged
merged 3 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions lemarche/static/js/siae_geo_range_field.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// disable geo range custom distance if geo range is not CUSTOM
document.addEventListener('DOMContentLoaded', function() {
let geoRangeCustomDistanceInput = document.getElementById('id_geo_range_custom_distance');

let geoRangeRadios = document.querySelectorAll('input[type=radio][name="geo_range"]');
// init
geoRangeRadios.forEach(radio => {
if (radio.checked && radio.value !== 'CUSTOM') {
geoRangeCustomDistanceInput.disabled = true;
}
});
// on change
geoRangeRadios.forEach(radio => radio.addEventListener('change', () => {
if (radio.value !== 'CUSTOM') {
geoRangeCustomDistanceInput.disabled = true;
} else {
geoRangeCustomDistanceInput.disabled = false;
}
}));
});
7 changes: 6 additions & 1 deletion lemarche/templates/dashboard/siae_edit_activities.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@

{% block content_siae_form %}
<div class="row mb-3">
<div class="col-12">
<div class="col-lg-8">
<h3>Ajoutez vos secteurs d'activité et recevez des opportunités commerciales ciblées</h3>
</div>
<div class="col-lg-4">
<a href="{% url 'dashboard_siaes:siae_edit_activities_create' siae.slug %}" id="siae-activities-create-btn" class="btn btn-primary w-100 btn-ico mt-2">
<i class="ri-add-fill ri-lg mr-2"></i>Ajouter un secteur d'activité
</a>
</div>
</div>

{% if siae.activities.count %}
Expand Down
161 changes: 161 additions & 0 deletions lemarche/templates/dashboard/siae_edit_activities_create.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
{% extends "layouts/base.html" %}
{% load static bootstrap4 %}

{% block title %}Ajouter une activité{{ block.super }}{% endblock %}

{% block breadcrumbs %}
<section>
<div class="container">
<div class="row">
<div class="col-12 col-lg">
<nav class="c-breadcrumb c-breadcrumb--marche" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ HOME_PAGE_PATH }}">Accueil</a></li>
<li class="breadcrumb-item"><a href="{% url 'dashboard:home' %}">Tableau de bord</a></li>
<li class="breadcrumb-item" title="{{ siae.name_display }} : modifier"><a href="{% url 'dashboard_siaes:siae_edit_activities' siae.slug %}">{{ siae.name_display }} : modifier</a></li>
<li class="breadcrumb-item active" aria-current="page">Ajouter une activité</li>
</ol>
</nav>
</div>
</div>
</div>
</section>
{% endblock %}

{% block content %}
<section class="s-section mb-0">
<div class="s-section__container container">
<div class="s-section__row row">
<div class="s-section__col col-12">
<form method="POST" action="" class="mb-3 mb-lg-5">
{% csrf_token %}

{% bootstrap_form_errors form type="all" %}

<div class="row mb-3 mb-lg-5">
<div class="col-12">
<h3>Ajouter une activité</h3>
</div>
</div>

<div class="row mb-3 mb-lg-5">
<div class="col-12 col-lg-8">
<div class="bg-white d-block rounded-lg shadow-lg p-3 p-lg-5">
<fieldset>
{% bootstrap_field form.sector_group %}
</fieldset>
<fieldset>
<legend class="h5">{{ form.sectors.label }} <strong class="fs-base">*</strong></legend>
{% bootstrap_field form.sectors show_label=False form_check_class="form-check checkbox-title" %}
</fieldset>
</div>
</div>
<div class="col-12 col-lg-4">
<div class="alert alert-info mt-3 mt-lg-0" role="alert">
<p class="mb-1">
<i class="ri-information-line ri-lg"></i>
<strong>Secteur d'activité</strong>
</p>
<p class="mb-0">
Améliorez votre référencement en indiquant tous les secteurs d'activités sur lesquels votre struture est positionnée.
</p>
</div>
</div>
</div>

<div class="row mb-3 mb-lg-5">
<div class="col-12 col-lg-8">
<div class="bg-white d-block rounded-lg shadow-lg p-3 p-lg-5">
<fieldset>
{% bootstrap_field form.presta_type %}
</fieldset>
</div>
</div>
<div class="col-12 col-lg-4">
<div class="alert alert-info mt-3 mt-lg-0" role="alert">
<p class="mb-1">
<i class="ri-information-line ri-lg"></i>
<strong>Type de prestation</strong>
</p>
<p class="mb-0">
Vous pourrez ensuite détailler vos prestations dans la section <i>offre commerciale</i>.
</p>
</div>
</div>
</div>

<div class="row mb-3 mb-lg-5">
<div class="col-12 col-lg-8">
<div class="bg-white d-block rounded-lg shadow-lg p-3 p-lg-5">
<fieldset>
<legend class="h4">{{ form.geo_range.label }} <strong class="fs-base">*</strong></legend>
{% bootstrap_field form.geo_range show_label=False %}
{{ form.geo_range_custom_distance }}
</fieldset>
</div>
</div>
<div class="col-12 col-lg-4">
<div class="alert alert-info mt-3 mt-lg-0" role="alert">
<p class="mb-1">
<i class="ri-information-line ri-lg"></i>
<strong>Périmètre d'intervention</strong>
</p>
<p class="mb-0">
Le périmètre d'intervention est un critère essentiel dans le choix des acheteurs. Il est nécessaire de bien le renseigner.
</p>
</div>
</div>
</div>

<div class="row mt-3 mt-lg-5">
<div class="col-12 col-lg-8">
<button type="submit" class="btn btn-primary">
<span>Enregistrer</span>
</button>
<a class="btn btn-outline-primary" href="{% url 'dashboard_siaes:siae_edit_activities' siae.slug %}">
<span>Annuler</span>
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
{% endblock %}

{% block extra_js %}
<script type="text/javascript" src="{% static 'js/siae_geo_range_field.js' %}"></script>
<script type="text/javascript">
// dynamic sector display based on sector group selection
document.addEventListener('DOMContentLoaded', function() {
let sectorGroupSelect = document.getElementById('id_sector_group');
let sectorGroupSelectOptions = sectorGroupSelect.children;
let sectorRadios = document.querySelectorAll('#id_sectors input[type="checkbox"][name="sectors"]');
let sectorGroupLabels = Array.from(document.querySelectorAll('#id_sectors label[class="form-check-label"]')).filter(label => !label.htmlFor);
let sectorLabels = Array.from(document.querySelectorAll('#id_sectors label[class="form-check-label"]')).filter(label => label.htmlFor);
// hide all sector group titles
sectorGroupLabels.forEach(label => label.style.display = 'none');
// init: hide all sector titles
sectorLabels.forEach(label => label.style.display = 'none');
// on sector group change
sectorGroupSelect.addEventListener('change', (event) => {
// unselect all sectors + hide them
sectorRadios.forEach(checkbox => checkbox.checked = false);
sectorLabels.forEach(label => label.style.display = 'none');
// show only sectors of selected sector group
if (event.target.value) {
let selectedSectorGroupName = Array.from(sectorGroupSelectOptions).filter(option => option.value === event.target.value)[0].innerText;
let selectedSectorGroupLabel = sectorGroupLabels.find(label => label.innerText === selectedSectorGroupName);
Array.from(selectedSectorGroupLabel.parentNode.children).forEach(child => {
if (child.firstElementChild && child.firstElementChild.htmlFor) {
// child.firstElementChild.style.display = 'block';
let selectedSectorGroupLabelSectorLabel = sectorLabels.find(label => label.htmlFor === child.firstElementChild.htmlFor);
selectedSectorGroupLabelSectorLabel.style.display = 'block';
}
});
}
})
});
</script>
{% endblock %}
23 changes: 1 addition & 22 deletions lemarche/templates/dashboard/siae_edit_search.html
Original file line number Diff line number Diff line change
Expand Up @@ -92,26 +92,5 @@ <h3>Réferencez efficacement votre structure dans les résultats de recherche</h
{% endblock %}

{% block extra_js %}
<script type="text/javascript">
// disable geo range custom distance if geo range is not CUSTOM
document.addEventListener('DOMContentLoaded', function() {
let geoRangeCustomDistanceInput = document.getElementById('id_geo_range_custom_distance');

let geoRangeRadios = document.querySelectorAll('input[type=radio][name="geo_range"]');
// init
geoRangeRadios.forEach(radio => {
if (radio.checked && radio.value !== 'CUSTOM') {
geoRangeCustomDistanceInput.disabled = true;
}
});
// on change
geoRangeRadios.forEach(radio => radio.addEventListener('change', () => {
if (radio.value !== 'CUSTOM') {
geoRangeCustomDistanceInput.disabled = true;
} else {
geoRangeCustomDistanceInput.disabled = false;
}
}));
});
</script>
<script type="text/javascript" src="{% static 'js/siae_geo_range_field.js' %}"></script>
{% endblock %}
27 changes: 27 additions & 0 deletions lemarche/www/dashboard_siaes/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from lemarche.siaes import constants as siae_constants
from lemarche.siaes.models import (
Siae,
SiaeActivity,
SiaeClientReference,
SiaeGroup,
SiaeImage,
Expand Down Expand Up @@ -230,3 +231,29 @@ class SiaeUserRequestForm(forms.ModelForm):
class Meta:
model = SiaeUserRequest
fields = []


class SiaeActivitiesCreateForm(forms.ModelForm):
sectors = GroupedModelMultipleChoiceField(
label="Activités",
queryset=Sector.objects.form_filter_queryset(),
choices_groupby="group",
required=True,
widget=forms.CheckboxSelectMultiple,
)
presta_type = forms.MultipleChoiceField(
label=Siae._meta.get_field("presta_type").verbose_name,
choices=siae_constants.PRESTA_CHOICES,
required=True,
widget=forms.CheckboxSelectMultiple,
)
geo_range = forms.ChoiceField(
label=Siae._meta.get_field("geo_range").verbose_name,
choices=siae_constants.GEO_RANGE_CHOICES,
required=True,
widget=forms.RadioSelect,
)

class Meta:
model = SiaeActivity
fields = ["sector_group", "sectors", "presta_type", "geo_range", "geo_range_custom_distance"] # location
2 changes: 2 additions & 0 deletions lemarche/www/dashboard_siaes/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from lemarche.www.dashboard_siaes.views import (
SiaeEditActivitiesDeleteView,
SiaeEditActivitiesCreateView,
SiaeEditActivitiesView,
SiaeEditContactView,
SiaeEditInfoView,
Expand Down Expand Up @@ -36,6 +37,7 @@
path("contact/", SiaeEditContactView.as_view(), name="siae_edit_contact"),
path("recherche/", SiaeEditSearchView.as_view(), name="siae_edit_search"),
path("activites/", SiaeEditActivitiesView.as_view(), name="siae_edit_activities"),
path("activites/creer", SiaeEditActivitiesCreateView.as_view(), name="siae_edit_activities_create"),
path(
"activites/<str:activity_id>/supprimer/",
SiaeEditActivitiesDeleteView.as_view(),
Expand Down
38 changes: 37 additions & 1 deletion lemarche/www/dashboard_siaes/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
from django.urls import reverse_lazy
from django.utils import timezone
from django.utils.safestring import mark_safe
from django.views.generic import DeleteView, DetailView, ListView, UpdateView
from django.views.generic import CreateView, DeleteView, DetailView, ListView, UpdateView
from django.views.generic.edit import FormMixin

from lemarche.siaes.models import Siae, SiaeActivity, SiaeUser, SiaeUserRequest
from lemarche.utils.apis import api_brevo
from lemarche.utils.mixins import SiaeMemberRequiredMixin, SiaeUserAndNotMemberRequiredMixin, SiaeUserRequiredMixin
from lemarche.utils.s3 import S3Upload
from lemarche.www.dashboard_siaes.forms import (
SiaeActivitiesCreateForm,
SiaeClientReferenceFormSet,
SiaeEditContactForm,
SiaeEditInfoForm,
Expand Down Expand Up @@ -145,6 +146,41 @@ def get_success_message(self, cleaned_data):
return mark_safe(f"Votre activité <strong>{self.object.sector_group}</strong> a été supprimée avec succès.")


class SiaeEditActivitiesCreateView(SiaeMemberRequiredMixin, CreateView):
template_name = "dashboard/siae_edit_activities_create.html"
form_class = SiaeActivitiesCreateForm
# success_url = reverse_lazy("dashboard_siaes:siae_edit_activities")
# success_message = "Votre activité a été crée avec succès."

def get(self, request, *args, **kwargs):
self.siae = Siae.objects.get(slug=self.kwargs.get("slug"))
return super().get(request, *args, **kwargs)

def form_valid(self, form):
siae_activity = form.save(commit=False)
siae_activity.siae = Siae.objects.get(slug=self.kwargs.get("slug"))
siae_activity.save()
form.save_m2m()

messages.add_message(
self.request,
messages.SUCCESS,
self.get_success_message(form.cleaned_data),
)
return HttpResponseRedirect(self.get_success_url())

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["siae"] = self.siae
return context

def get_success_url(self):
return reverse_lazy("dashboard_siaes:siae_edit_activities", args=[self.kwargs.get("slug")])

def get_success_message(self, cleaned_data):
return mark_safe(f"Votre activité <strong>{cleaned_data['sector_group']}</strong> a été crée avec succès.")


class SiaeEditInfoView(SiaeMemberRequiredMixin, SuccessMessageMixin, UpdateView):
form_class = SiaeEditInfoForm
template_name = "dashboard/siae_edit_info.html"
Expand Down
Loading