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

[Dépôt de besoin] : Déplacement des champs "description" et "date de clôture" #924

Merged
merged 6 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion lemarche/templates/tenders/_detail_card.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ <h2>
</ul>
{% endif %}
<!-- tender constraints -->
{% if source_form or not source_form and tender.constraints %}
{% if tender.constraints %}
SebastienReuiller marked this conversation as resolved.
Show resolved Hide resolved
<hr class="my-5">
<h2>Contraintes techniques spécifiques</h2>
<p>{{ tender.constraints|default:"-"|safe|linebreaks }}</p>
Expand Down
1 change: 0 additions & 1 deletion lemarche/templates/tenders/create_step_contact.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
</div>
{% endif %}
{% bootstrap_field form.response_kind %}
{% bootstrap_field form.deadline_date %}
</div>
</div>
{% endblock %}
Original file line number Diff line number Diff line change
@@ -1,28 +1,17 @@
{% extends "tenders/create_base.html" %}
{% load bootstrap4 static %}
{% block step_title %}Description du besoin{% endblock %}
{% block step_title_again %}Description du besoin{% endblock %}
{% block step_title %}Détail du besoin{% endblock %}
SebastienReuiller marked this conversation as resolved.
Show resolved Hide resolved
{% block step_title_again %}Détail du besoin{% endblock %}
{% block step_subtitle %}
Veuillez détailler au maximum votre besoin pour que les prestataires inclusifs puissent se positionner.
{% endblock %}
{% block content_form %}
{% csrf_token %}
<div class="row">
<div class="col-12 col-lg-7">{% bootstrap_field form.description %}</div>
<div class="col-12 col-lg-5">
<div class="c-form-conseil">
<div>
<p>
<i class="ri-lightbulb-line ri-lg mr-1"></i><strong>Conseil</strong>
<br>
Décrivez en détail votre besoin pour permettre aux prestataires inclusifs de vous faire des réponses personnalisées.
</p>
</div>
</div>
</div>
<div class="col-12 col-lg-7">{% bootstrap_field form.start_working_date %}</div>
</div>
<div class="row">
<div class="col-12 col-lg-7">{% bootstrap_field form.start_working_date %}</div>
<div class="col-12 col-lg-7">{% bootstrap_field form.deadline_date %}</div>
</div>
<div class="row">
<div class="col-12 col-lg-7">{% bootstrap_field form.external_link %}</div>
Expand All @@ -48,7 +37,7 @@ <h4>Questions à poser aux prestataires ciblés</h4>
</div>
</template>
<input type="hidden"
name="description-questions_list"
name="detail-questions_list"
:value="getValue()"
value="form.questions_list">
</div>
Expand Down Expand Up @@ -174,10 +163,10 @@ <h4>Questions à poser aux prestataires ciblés</h4>
Alpine.data('TenderQuestionForm', TenderQuestionForm);
});
document.addEventListener('DOMContentLoaded', function () {
const selectDesciptionAmount = document.getElementById('id_description-amount');
const divWhyIsBlank = document.getElementById('id_description-why_amount_is_blank');
toggleRadioSelectElement(divWhyIsBlank, selectDesciptionAmount.value);
selectDesciptionAmount.addEventListener("change", function () {
const selectDetailAmount = document.getElementById('id_detail-amount');
const divWhyIsBlank = document.getElementById('id_detail-why_amount_is_blank');
toggleRadioSelectElement(divWhyIsBlank, selectDetailAmount.value);
selectDetailAmount.addEventListener("change", function () {
toggleRadioSelectElement(divWhyIsBlank, this.value);
});
});
Expand Down
14 changes: 14 additions & 0 deletions lemarche/templates/tenders/create_step_general.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@
</div>
</div>
</div>
<div class="row">
<div class="col-12 col-lg-7">{% bootstrap_field form.description %}</div>
<div class="col-12 col-lg-5">
<div class="c-form-conseil">
SebastienReuiller marked this conversation as resolved.
Show resolved Hide resolved
<div>
<p>
<i class="ri-lightbulb-line ri-lg mr-1"></i><strong>Conseil pour la description</strong>
<br>
Décrivez en détail votre besoin pour permettre aux prestataires inclusifs de vous faire des réponses personnalisées.
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12 col-lg-7">
{% bootstrap_field form.sectors form_group_class="form-group form-group-required use-multiselect" %}
Expand Down
64 changes: 32 additions & 32 deletions lemarche/www/tenders/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Meta:
fields = [
"kind",
"title",
"description",
"sectors",
"location", # generated by js
"is_country_area",
Expand All @@ -42,6 +43,7 @@ def __init__(self, *args, **kwargs):
self.fields["kind"].choices = self.FORM_KIND_CHOICES
self.fields["location"].to_field_name = "slug"
# required fields
self.fields["description"].required = True
# self.fields["perimeters"].required = True # JS
# label, placeholder & help_text
self.fields["title"].widget.attrs["placeholder"] = "Ex : Devis rénovation façade"
Expand All @@ -59,7 +61,7 @@ def clean(self):
self.add_error("sectors", msg_field_missing.format(Sector._meta.verbose_name_plural))


class TenderCreateStepDescriptionForm(forms.ModelForm):
class TenderCreateStepDetailForm(forms.ModelForm):
# fields from previous step
kind = None

Expand All @@ -68,31 +70,36 @@ class TenderCreateStepDescriptionForm(forms.ModelForm):
class Meta:
model = Tender
fields = [
"description",
"start_working_date",
"deadline_date",
"external_link",
"amount",
"why_amount_is_blank",
"accept_share_amount",
]
widgets = {
"start_working_date": forms.widgets.DateInput(attrs={"class": "form-control", "type": "date"}),
"deadline_date": forms.widgets.DateInput(attrs={"class": "form-control", "type": "date"}),
"why_amount_is_blank": forms.widgets.RadioSelect,
"amount": forms.Select(attrs={"x-model": "formData.amount", "x-on:change": "getImpactMessage()"}),
}

def __init__(self, kind, questions_list=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self.kind = kind

# required fields
self.fields["deadline_date"].required = True

if self.instance.deadline_date:
self.initial["deadline_date"] = self.instance.deadline_date.isoformat()
if questions_list:
self.initial["questions_list"] = questions_list
# to remove blank option
self.fields["why_amount_is_blank"].choices = self.fields["why_amount_is_blank"].choices[1:]
if self.instance.start_working_date:
self.initial["start_working_date"] = self.instance.start_working_date.isoformat()

# required fields
self.fields["description"].required = True
# label, placeholder & help_text
if self.kind != tender_constants.KIND_TENDER:
self.fields["external_link"].label = "Lien à partager"
Expand All @@ -115,10 +122,29 @@ def clean_questions_list(self):
questions.pop(index)
return questions

def clean(self):
super().clean()
today = date.today()
max_deadline_date = self.cleaned_data.get("start_working_date")
deadline_date = self.cleaned_data.get("deadline_date")
# check that deadline_date < start_working_date
if max_deadline_date and deadline_date and (deadline_date > max_deadline_date):
self.add_error(
"deadline_date",
(
"La date de clôture des réponses ne doit pas être supérieure à la date "
f"de début d'intervention ({max_deadline_date})."
),
)
# check that deadline_date > today
if deadline_date and (deadline_date < today):
self.add_error(
"deadline_date", "La date de clôture des réponses ne doit pas être antérieure à aujourd'hui."
)


class TenderCreateStepContactForm(forms.ModelForm):
# fields from previous step
max_deadline_date = None
external_link = None
user_is_anonymous = None
user_does_not_have_company_name = None
Expand All @@ -140,31 +166,22 @@ class Meta:
"contact_email",
"contact_phone",
"response_kind",
"deadline_date",
]
widgets = {
"deadline_date": forms.widgets.DateInput(attrs={"class": "form-control", "type": "date"}),
}
labels = {
"contact_first_name": "Prénom",
"contact_last_name": "Nom",
"contact_email": "E-mail",
"contact_phone": "Téléphone",
}

def __init__(self, max_deadline_date, external_link, user: User, *args, **kwargs):
def __init__(self, external_link, user: User, *args, **kwargs):
super().__init__(*args, **kwargs)
self.max_deadline_date = max_deadline_date
self.external_link = external_link
self.user = user
user_is_anonymous = not user.is_authenticated

if self.instance.deadline_date:
self.initial["deadline_date"] = self.instance.deadline_date.isoformat()

# required fields
self.fields["response_kind"].required = True
self.fields["deadline_date"].required = True
if user_is_anonymous:
self.fields["contact_first_name"].required = True
self.fields["contact_last_name"].required = True
Expand All @@ -185,23 +202,6 @@ def __init__(self, max_deadline_date, external_link, user: User, *args, **kwargs

def clean(self):
super().clean()
today = date.today()
# check that deadline_date < start_working_date
if (
self.max_deadline_date
and self.cleaned_data.get("deadline_date")
and (self.cleaned_data.get("deadline_date") > self.max_deadline_date)
):
self.add_error(
"deadline_date",
f"La date de clôture des réponses ne doit pas être supérieure à la date de début d'intervention ({self.max_deadline_date}).", # noqa
)
# check that deadline_date > today
if self.cleaned_data.get("deadline_date") and (self.cleaned_data.get("deadline_date") < today):
self.add_error(
"deadline_date", "La date de clôture des réponses ne doit pas être antérieure à aujourd'hui."
)

if not self.user.is_authenticated:
# contact_email must be filled if RESPONSE_KIND_EMAIL
if self.cleaned_data.get("response_kind") and (
Expand Down
14 changes: 7 additions & 7 deletions lemarche/www/tenders/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,17 @@ def _generate_fake_data_form(
"tender_create_multi_step_view-current_step": "general",
"general-kind": tender_not_saved.kind,
"general-title": tender_not_saved.title,
"general-description": tender_not_saved.description,
"general-sectors": cls.sectors,
"general-location": cls.location_slug,
"general-is_country_area": tender_not_saved.is_country_area,
} | _step_1
step_2 = {
"tender_create_multi_step_view-current_step": "description",
"description-description": tender_not_saved.description,
"description-start_working_date": tender_not_saved.start_working_date,
"description-external_link": tender_not_saved.external_link,
"description-amount": tender_constants.AMOUNT_RANGE_1000_MORE,
"tender_create_multi_step_view-current_step": "detail",
"detail-start_working_date": tender_not_saved.start_working_date,
"detail-deadline_date": tender_not_saved.deadline_date,
"detail-external_link": tender_not_saved.external_link,
"detail-amount": tender_constants.AMOUNT_RANGE_1000_MORE,
} | _step_2
step_3 = {
"tender_create_multi_step_view-current_step": "contact",
Expand All @@ -62,7 +63,6 @@ def _generate_fake_data_form(
"contact-contact_phone": "0123456789",
"contact-contact_company_name": "TEST",
"contact-response_kind": [Tender.RESPONSE_KIND_EMAIL],
"contact-deadline_date": tender_not_saved.deadline_date,
} | _step_3
step_4 = {
"tender_create_multi_step_view-current_step": "survey",
Expand Down Expand Up @@ -189,7 +189,7 @@ def test_tender_wizard_form_questions_list(self):
{"text": "Êtes-vous disponible tout l'été ? "},
]
tenders_step_data = self._generate_fake_data_form(
_step_2={"description-questions_list": json.dumps(initial_data_questions_list)} # json field
_step_2={"detail-questions_list": json.dumps(initial_data_questions_list)} # json field
)

self._check_every_step(tenders_step_data, final_redirect_page=reverse("siae:search_results"))
Expand Down
2 changes: 1 addition & 1 deletion lemarche/www/tenders/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def get_or_create_user(request_user, tender_dict: dict, source=User.SOURCE_TENDE
user = request_user
need_to_be_saved = False
if not user.phone:
user.phone = tender_dict.get("contact_phone")
user.phone = tender_dict.get("contact_phone", "")
need_to_be_saved = True
if not user.company_name:
user.company_name = tender_dict.get("contact_company_name")
Expand Down
14 changes: 6 additions & 8 deletions lemarche/www/tenders/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from lemarche.www.tenders.forms import (
TenderCreateStepConfirmationForm,
TenderCreateStepContactForm,
TenderCreateStepDescriptionForm,
TenderCreateStepDetailForm,
TenderCreateStepGeneralForm,
TenderCreateStepSurveyForm,
)
Expand Down Expand Up @@ -64,22 +64,22 @@ class TenderCreateMultiStepView(SessionWizardView):
Vous pourrez revenir plus tard pour le publier. Vous le retrouverez dans votre tableau de bord.
"""
STEP_GENERAL = "general"
STEP_DESCRIPTION = "description"
STEP_DETAIL = "detail"
STEP_CONTACT = "contact"
STEP_SURVEY = "survey"
STEP_CONFIRMATION = "confirmation"

TEMPLATES = {
STEP_GENERAL: "tenders/create_step_general.html",
STEP_DESCRIPTION: "tenders/create_step_description.html",
STEP_DETAIL: "tenders/create_step_detail.html",
STEP_CONTACT: "tenders/create_step_contact.html",
STEP_SURVEY: "tenders/create_step_survey.html",
STEP_CONFIRMATION: "tenders/create_step_confirmation.html",
}

form_list = [
(STEP_GENERAL, TenderCreateStepGeneralForm),
(STEP_DESCRIPTION, TenderCreateStepDescriptionForm),
(STEP_DETAIL, TenderCreateStepDetailForm),
(STEP_CONTACT, TenderCreateStepContactForm),
(STEP_SURVEY, TenderCreateStepSurveyForm),
(STEP_CONFIRMATION, TenderCreateStepConfirmationForm),
Expand All @@ -103,14 +103,12 @@ def get_form_kwargs(self, step):
Initial data
"""
kwargs = super().get_form_kwargs(step)
if step == self.STEP_DESCRIPTION:
if step == self.STEP_DETAIL:
kwargs["kind"] = self.get_cleaned_data_for_step(self.STEP_GENERAL).get("kind")
if self.instance.id:
kwargs["questions_list"] = list(self.instance.questions_list())
if step == self.STEP_CONTACT:
cleaned_data_description = self.get_cleaned_data_for_step(self.STEP_DESCRIPTION)
kwargs["max_deadline_date"] = cleaned_data_description.get("start_working_date")
kwargs["external_link"] = cleaned_data_description.get("external_link")
kwargs["external_link"] = self.get_cleaned_data_for_step(self.STEP_DETAIL).get("external_link")
kwargs["user"] = self.request.user
return kwargs

Expand Down