Skip to content

Commit

Permalink
Merge pull request #3853 from GeotrekCE/feat_separate_date_into_2_fields
Browse files Browse the repository at this point in the history
Add end date to Intervention model (refs #3825)
  • Loading branch information
Chatewgne authored Jan 2, 2024
2 parents f6ecc55 + 5d90c1a commit efc9d7b
Show file tree
Hide file tree
Showing 32 changed files with 326 additions and 67 deletions.
3 changes: 2 additions & 1 deletion docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ CHANGELOG
- Add rules fixture on sensitive area (#3470)
- Change condition on signage & blade to select many of them (#3847)
- Allow to set headers in requests from Parsers (#3861)
- Sort bladeType alphabetically #3821
- Sort bladeType alphabetically (#3821)
- Update ``Intervention`` model to have begin & end date (#3825)

**Documentation**

Expand Down
8 changes: 5 additions & 3 deletions docs/install/advanced-configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1109,7 +1109,8 @@ A (nearly?) exhaustive list of attributes available for display and export as co
"uuid",
]
COLUMNS_LISTS["intervention_view"] = [
"date",
"begin_date",
"end_date",
"type",
"target",
"status",
Expand Down Expand Up @@ -1579,7 +1580,8 @@ A (nearly?) exhaustive list of attributes available for display and export as co
]
COLUMNS_LISTS["intervention_export"] = [
"name",
"date",
"begin_date",
"end_date",
"type",
"target",
"status",
Expand Down Expand Up @@ -2028,6 +2030,7 @@ An exhaustive list of form fields hideable in each module.
"description",
"type",
"subcontracting",
"end_date",
"length",
"width",
"height",
Expand All @@ -2038,7 +2041,6 @@ An exhaustive list of form fields hideable in each module.
"subcontract_cost",
],
HIDDEN_FORM_FIELDS["project"] = [
"type",
"type",
"domain",
"end_year",
Expand Down
5 changes: 3 additions & 2 deletions geotrek/feedback/fixtures/test-integration.json
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@
"pk": 1,
"fields": {
"label": "Intervention résolue",
"text": "Pris en charge par ##supervisor## le ##intervention_date##"
"text": "Pris en charge par ##supervisor## le ##intervention_end_date##"
}
},
{
Expand Down Expand Up @@ -299,7 +299,8 @@
],
"target_id": 12,
"name": "Intervention on report",
"date": "2022-05-17",
"begin_date": "2022-05-17",
"end_date": "2022-05-17",
"status": 3,
"date_insert": "2012-05-17T14:33:34.307Z",
"date_update": "2012-05-17T14:33:34.307Z"
Expand Down
2 changes: 1 addition & 1 deletion geotrek/feedback/static/feedback/workflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ function display_predefined_email_in_email_field() {
} else {
text = predefined_emails[selected]["text"];
text = text.replace(/##supervisor##/g, resolved_intervention_info["username"]);
text = text.replace(/##intervention_date##/g, resolved_intervention_info["date"]);
text = text.replace(/##intervention_end_date##/g, resolved_intervention_info["end_date"]);
$('#id_message_sentinel').val(text);
$('#id_message_administrators').val(text);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ <h3>{% trans "Attributes" %}</h3>
<td colspan="3">
{% if perms.maintenance.add_intervention %}
<h3>{% trans "Intervention" %}</h3>
{% with columns="name,status,stake,total_cost,date" %}
{% with columns="name,status,stake,total_cost,begin_date,end_date" %}
{% valuetable report.interventions.all columns=columns %}
{% endwith %}
{% if not suricate_workflow_enabled %}
Expand Down
2 changes: 1 addition & 1 deletion geotrek/feedback/templatetags/feedback_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def resolved_intervention_info(report):
username = user.username

resolved_intervention_info = {
"date": report.interventions.first().date.strftime("%d/%m/%Y") if report.interventions else None,
"end_date": report.interventions.first().end_date.strftime("%d/%m/%Y") if report.interventions else None,
"username": username
}
return json.dumps(resolved_intervention_info)
Expand Down
8 changes: 5 additions & 3 deletions geotrek/feedback/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def setUpTestData(cls):
cls.filed_report_1 = ReportFactory(status=cls.filed_status, external_uuid=uuid.uuid4())
cls.filed_report_2 = ReportFactory(status=cls.filed_status, external_uuid=uuid.uuid4())
cls.waiting_report = ReportFactory(status=cls.waiting_status, uses_timers=True, external_uuid=uuid.uuid4())
cls.intervention = ReportInterventionFactory(date=datetime(year=1997, month=4, day=4).date())
cls.intervention = ReportInterventionFactory(begin_date=datetime(year=1997, month=11, day=10).date(), end_date=datetime(year=1997, month=11, day=11).date())
cls.waiting_report = ReportFactory(status=cls.waiting_status, uses_timers=True, external_uuid=uuid.uuid4())
cls.solved_intervention_report = ReportFactory(status=cls.solved_intervention_status, external_uuid=uuid.uuid4())
cls.predefined_email_1 = PredefinedEmailFactory()
Expand Down Expand Up @@ -257,7 +257,7 @@ def test_workflow_program_step(self):
user = SuperUserFactory(username="admin", password="dadadad")
data = {
'name': "test_interv",
'date': "2025-12-12",
'begin_date': "2025-12-12",
'status': 2,
'structure': user.profile.structure.pk,
}
Expand All @@ -283,9 +283,11 @@ def test_solving_report_intervention(self, mocked_post):
)
# Trigger resolving intervention
user = SuperUserFactory(username="admin", password="dadadad")
end_date = interv.begin_date
data = {
'name': interv.name,
'date': interv.date,
'begin_date': interv.begin_date,
'end_date': end_date,
'status': 3, # pk for "Terminée" from fixtures
'structure': user.profile.structure.pk
}
Expand Down
8 changes: 4 additions & 4 deletions geotrek/feedback/tests/test_template_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def setUpTestData(cls):
cls.user2 = UserFactory(username="Kurt")
UserProfileFactory.create(user=cls.user2)
cls.solved_status = ReportStatusFactory(identifier='solved_intervention', color="#448654")
cls.intervention_solved_1 = ReportInterventionFactory(date=datetime(year=1997, month=4, day=4).date())
cls.intervention_solved_1 = ReportInterventionFactory(begin_date=datetime(year=1997, month=11, day=10).date(), end_date=datetime(year=1997, month=11, day=11).date())
# Simulate user created intervention
LogEntry.objects.log_action(
user_id=cls.user1.pk,
Expand All @@ -36,7 +36,7 @@ def setUpTestData(cls):
cls.status_1 = cls.report_1.status
cls.report_1.status = cls.solved_status
cls.report_1.save()
cls.intervention_solved_2 = ReportInterventionFactory(date=datetime(year=1997, month=5, day=4).date())
cls.intervention_solved_2 = ReportInterventionFactory(begin_date=datetime(year=1997, month=11, day=10).date(), end_date=datetime(year=1997, month=11, day=11).date())
# Simulate user created intervention
LogEntry.objects.log_action(
user_id=cls.user2.pk,
Expand All @@ -55,11 +55,11 @@ def setUpTestData(cls):

def test_resolved_intervention_username(self):
self.assertEqual(
"{\"date\": \"04/04/1997\", \"username\": \"Communaut\\u00e9 des Communes des Communaut\\u00e9s Communataires\"}",
"{\"end_date\": \"11/11/1997\", \"username\": \"Communaut\\u00e9 des Communes des Communaut\\u00e9s Communataires\"}",
resolved_intervention_info(self.report_1)
)
self.assertEqual(
"{\"date\": \"04/05/1997\", \"username\": \"Kurt\"}",
"{\"end_date\": \"11/11/1997\", \"username\": \"Kurt\"}",
resolved_intervention_info(self.report_2)
)

Expand Down
10 changes: 9 additions & 1 deletion geotrek/infrastructure/filters.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
from django.utils.translation import gettext_lazy as _
from django_filters import CharFilter, MultipleChoiceFilter, ModelMultipleChoiceFilter, ChoiceFilter
from geotrek.altimetry.filters import AltimetryAllGeometriesFilterSet
Expand Down Expand Up @@ -36,6 +37,13 @@ class Meta(StructureRelatedFilterSet.Meta):

def filter_intervention_year(self, qs, name, value):
infrastructure_ct = ContentType.objects.get_for_model(Infrastructure)
interventions = Intervention.objects.filter(target_type=infrastructure_ct, date__year__in=value) \
q_1 = Q()
for subvalue in value:
# Intervention started in year 'subvalue', ended in year 'subvalue',
# or was ongoing in year 'subvalue'
q_1 = q_1 | Q(begin_date__year__lt=subvalue, end_date__year__gt=subvalue)
q = Q(begin_date__year__in=value) | Q(end_date__year__in=value) | q_1
q = Q(q, target_type=infrastructure_ct)
interventions = Intervention.objects.filter(q) \
.values_list('target_id', flat=True)
return qs.filter(id__in=interventions).distinct()
8 changes: 4 additions & 4 deletions geotrek/infrastructure/tests/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ def test_intervention_filter(self):

# Bad signage: intervention with wrong year
bad_topo = self.factory()
InterventionFactory(target=bad_topo, date=bad_date_year)
InterventionFactory(target=bad_topo, begin_date=bad_date_year)

# Good signage: intervention with the good year
good_topo = self.factory()
InterventionFactory(target=good_topo, date=good_date_year)
InterventionFactory(target=good_topo, begin_date=good_date_year)

data = {
'intervention_year': year
Expand All @@ -105,11 +105,11 @@ def test_duplicate_implantation_year_filter(self):

# Bad signage: intervention with wrong year
topo_1 = self.factory()
InterventionFactory(target=topo_1, date=year_t)
InterventionFactory(target=topo_1, begin_date=year_t)

# Good signage: intervention with the good year
topo_2 = self.factory()
InterventionFactory(target=topo_2, date=year_t)
InterventionFactory(target=topo_2, begin_date=year_t)

response = self.client.get(model.get_list_url())
self.assertContains(response, '<option value="2014">2014</option>', count=1)
Expand Down
15 changes: 11 additions & 4 deletions geotrek/maintenance/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
from django.conf import settings
from django.contrib.gis.geos import GeometryCollection
from django.utils.translation import gettext_lazy as _
from django_filters import ChoiceFilter, MultipleChoiceFilter
from django_filters import ChoiceFilter, MultipleChoiceFilter, DateFromToRangeFilter

from mapentity.filters import PolygonFilter, PythonPolygonFilter

from geotrek.altimetry.filters import AltimetryPointFilterSet
from geotrek.authent.filters import StructureRelatedFilterSet
from geotrek.common.filters import OptionalRangeFilter, RightFilter
from geotrek.common.widgets import OneLineRangeWidget
from geotrek.zoning.filters import (IntersectionFilterCity, IntersectionFilterDistrict,
IntersectionFilterRestrictedArea, IntersectionFilterRestrictedAreaType,
ZoningFilterSet)
Expand Down Expand Up @@ -121,6 +122,13 @@ class AltimetryInterventionFilterSet(AltimetryPointFilterSet):
slope = OptionalRangeFilter(label=_('slope'))


class CustomDateFromToRangeFilter(DateFromToRangeFilter):
def __init__(self, *args, **kwargs):
super(DateFromToRangeFilter, self).__init__(*args, **kwargs)
self.field.fields[0].label = _('min %s') % self.field.label
self.field.fields[1].label = _('max %s') % self.field.label


class InterventionFilterSet(AltimetryInterventionFilterSet, ZoningFilterSet, StructureRelatedFilterSet):
ON_CHOICES = (('infrastructure', _("Infrastructure")), ('signage', _("Signage")), ('blade', _("Blade")),
('topology', _("Path")), ('trek', _("Trek")), ('poi', _("POI")), ('service', _("Service")),
Expand All @@ -130,8 +138,8 @@ class InterventionFilterSet(AltimetryInterventionFilterSet, ZoningFilterSet, Str
ON_CHOICES += (('course', _("Outdoor Course")), ('site', _("Outdoor Site")),)

bbox = PolygonTopologyFilter(lookup_expr='intersects')
year = MultipleChoiceFilter(choices=lambda: Intervention.objects.year_choices(),
field_name='date', lookup_expr='year', label=_("Year"))
begin_date = CustomDateFromToRangeFilter(lookup_expr='icontains', widget=OneLineRangeWidget(attrs={'type': 'date', 'class': 'minmax-field', 'title': _('Filter by begin date range')},), label=_('begin date'))
end_date = CustomDateFromToRangeFilter(lookup_expr='icontains', widget=OneLineRangeWidget(attrs={'type': 'date', 'class': 'minmax-field', 'title': _('Filter by end date range')},), label=_('end date'))
on = ChoiceFilter(field_name='target_type__model', choices=ON_CHOICES, label=_("On"), empty_label=_("On"))
area_type = InterventionIntersectionFilterRestrictedAreaType(label=_('Restricted area type'), required=False,
lookup_expr='intersects')
Expand All @@ -148,7 +156,6 @@ class Meta(StructureRelatedFilterSet.Meta):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.fields['year'].choices = Intervention.objects.year_choices()


class ProjectFilterSet(StructureRelatedFilterSet):
Expand Down
28 changes: 23 additions & 5 deletions geotrek/maintenance/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from django.forms import FloatField
from django.forms.models import inlineformset_factory
from django.utils.translation import gettext_lazy as _

from geotrek.common.forms import CommonForm
from geotrek.core.fields import TopologyField
from geotrek.core.models import Topology
Expand Down Expand Up @@ -64,8 +63,14 @@ class InterventionForm(CommonForm):

topology = TopologyField(label="")
length = FloatField(required=False, label=_("Length"))
project = forms.ModelChoiceField(required=False, label=_("Project"),
queryset=Project.objects.existing())
project = forms.ModelChoiceField(
required=False, label=_("Project"),
queryset=Project.objects.existing()
)
end_date = forms.DateField(
required=False,
widget=forms.DateInput(attrs={"data-date-orientation": "bottom auto"}),
)

geomfields = ['topology']
leftpanel_scrollable = False
Expand All @@ -74,7 +79,8 @@ class InterventionForm(CommonForm):
Div(
'structure',
'name',
'date',
'begin_date',
'end_date',
'status',
'disorders',
'type',
Expand All @@ -97,7 +103,7 @@ class InterventionForm(CommonForm):
class Meta(CommonForm.Meta):
model = Intervention
fields = CommonForm.Meta.fields + \
['structure', 'name', 'date', 'status', 'disorders', 'type', 'description', 'subcontracting', 'length', 'width',
['structure', 'name', 'begin_date', 'end_date', 'status', 'disorders', 'type', 'description', 'subcontracting', 'length', 'width',
'height', 'stake', 'project', 'access', 'material_cost', 'heliport_cost', 'subcontract_cost', 'topology']

def __init__(self, *args, target_type=None, target_id=None, **kwargs):
Expand Down Expand Up @@ -143,6 +149,18 @@ def __init__(self, *args, target_type=None, target_id=None, **kwargs):
or self.instance.geom.geom_type == 'LineString'))
self.fields['length'].widget.attrs['readonly'] = editable

if 'geotrek.feedback' in settings.INSTALLED_APPS and settings.SURICATE_WORKFLOW_ENABLED:
if self.instance.pk and self.instance.target and hasattr(self.instance.target, "report_interventions"):
self.fields["end_date"].required = True

def clean(self, *args, **kwargs):
clean_data = super().clean(*args, **kwargs)
begin_date = clean_data.get('begin_date')
end_date = clean_data.get('end_date')
if end_date and begin_date > end_date:
self.add_error('end_date', _('Begin date is after end date'))
return clean_data

def save(self, *args, **kwargs):
target = self.instance.target
if 'geotrek.feedback' in settings.INSTALLED_APPS and settings.SURICATE_WORKFLOW_ENABLED and isinstance(target, Report):
Expand Down
27 changes: 25 additions & 2 deletions geotrek/maintenance/locale/de/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-12-16 09:52+0000\n"
"POT-Creation-Date: 2023-12-11 15:38+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand All @@ -33,6 +33,14 @@ msgstr ""
msgid "slope"
msgstr ""

#, python-format
msgid "min %s"
msgstr ""

#, python-format
msgid "max %s"
msgstr ""

msgid "Infrastructure"
msgstr ""

Expand Down Expand Up @@ -63,7 +71,16 @@ msgstr ""
msgid "Outdoor Site"
msgstr ""

msgid "Year"
msgid "Filter by begin date range"
msgstr ""

msgid "begin date"
msgstr ""

msgid "Filter by end date range"
msgstr ""

msgid "end date"
msgstr ""

msgid "On"
Expand Down Expand Up @@ -117,6 +134,12 @@ msgstr ""
msgid "When ?"
msgstr ""

msgid "Begin date"
msgstr ""

msgid "End date"
msgstr ""

msgid "Subcontracting"
msgstr ""

Expand Down
Loading

0 comments on commit efc9d7b

Please sign in to comment.