diff --git a/docs/changelog.rst b/docs/changelog.rst index a9a5202d..8699fea0 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -13,6 +13,7 @@ CHANGELOG * Add contribution status * Send mail to managers when contribution is created * Send mail to contributor when contribution is created +* Add linked objects on contributions 1.1.0 (2023-13-06) ------------------------- diff --git a/georiviere/contribution/forms.py b/georiviere/contribution/forms.py index 847541ca..d2e252ad 100644 --- a/georiviere/contribution/forms.py +++ b/georiviere/contribution/forms.py @@ -1,14 +1,29 @@ -from crispy_forms.layout import Div +from crispy_forms.layout import Div, Field +from dal import autocomplete +from django.utils.translation import gettext_lazy as _ from geotrek.common.forms import CommonForm from georiviere.contribution.models import Contribution +from georiviere.knowledge.models import FollowUp, Knowledge +from georiviere.maintenance.models import Intervention -class ContributionForm(CommonForm): +class ContributionForm(autocomplete.FutureModelForm, CommonForm): can_delete = False geomfields = ['geom'] + linked_object = autocomplete.Select2GenericForeignKeyModelField( + model_choice=[ + (Knowledge, 'name'), + (Intervention, 'name'), + (FollowUp, 'name') + ], + label=_('Linked object'), + required=False, + initial=None, + ) + fieldslayout = [ Div( "description", @@ -19,12 +34,13 @@ class ContributionForm(CommonForm): "email_author", "assigned_user", "status_contribution", + Field('linked_object', css_class="chosen-select"), ) ] class Meta(CommonForm): fields = ["description", "severity", "published", "portal", "email_author", "geom", "assigned_user", - "status_contribution", "validated"] + "status_contribution", "validated", "linked_object"] model = Contribution def __init__(self, *args, **kwargs): @@ -35,3 +51,9 @@ def __init__(self, *args, **kwargs): def clean_portal(self): return self.instance.portal + + def clean_linked_object(self): + linked_object = self.cleaned_data['linked_object'] + if linked_object == "": + return None + return linked_object diff --git a/georiviere/contribution/migrations/0007_auto_20230725_1541.py b/georiviere/contribution/migrations/0007_auto_20230725_1541.py new file mode 100644 index 00000000..5cb2eb1b --- /dev/null +++ b/georiviere/contribution/migrations/0007_auto_20230725_1541.py @@ -0,0 +1,25 @@ +# Generated by Django 3.1.14 on 2023-07-25 15:41 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('contribution', '0006_contribution_publication_date'), + ] + + operations = [ + migrations.AddField( + model_name='contribution', + name='linked_object_id', + field=models.PositiveIntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='contribution', + name='linked_object_type', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype'), + ), + ] diff --git a/georiviere/contribution/models.py b/georiviere/contribution/models.py index b370274a..4ad3ff6e 100644 --- a/georiviere/contribution/models.py +++ b/georiviere/contribution/models.py @@ -2,6 +2,8 @@ from django.conf import settings from django.contrib.auth.models import User +from django.contrib.contenttypes.fields import GenericForeignKey +from django.contrib.contenttypes.models import ContentType from django.contrib.gis.db import models from django.core.mail import mail_managers from django.template.loader import render_to_string @@ -99,6 +101,9 @@ class Contribution(BasePublishableMixin, TimeStampedModelMixin, WatershedPropert ) validated = models.BooleanField(verbose_name=_("Validated"), default=False, help_text=_("Validate the contribution")) + linked_object_type = models.ForeignKey(ContentType, null=True, on_delete=models.CASCADE) + linked_object_id = models.PositiveIntegerField(blank=True, null=True) + linked_object = GenericForeignKey('linked_object_type', 'linked_object_id') class Meta: verbose_name = _("Contribution") @@ -108,6 +113,16 @@ class Meta: def category_verbose_name(cls): return _("Name") + @classproperty + def linked_object_verbose_name(cls): + return _("Linked object") + + @property + def linked_object_model_name(self): + if self.linked_object: + return self.linked_object._meta.verbose_name + return None + def __str__(self): if hasattr(self, 'potential_damage'): return f'{self.email_author} {ContributionPotentialDamage._meta.verbose_name.title()} ' \ diff --git a/georiviere/contribution/templates/contribution/contribution_detail_attributes.html b/georiviere/contribution/templates/contribution/contribution_detail_attributes.html index 90efab1a..9a186fd7 100644 --- a/georiviere/contribution/templates/contribution/contribution_detail_attributes.html +++ b/georiviere/contribution/templates/contribution/contribution_detail_attributes.html @@ -35,6 +35,10 @@ {{ object|verbose:"status_contribution" }} {{ object.status_contribution|default:"" }} + + {{ object|verbose:"linked_object" }} + {% if object.linked_object_model_name %}{{ object.linked_object_model_name }} : {% endif %}{{ object.linked_object|default:"" }} + {% if object.potential_damage %} {{ object.potential_damage|verbose:"type" }} diff --git a/georiviere/contribution/templates/contribution/contribution_list.html b/georiviere/contribution/templates/contribution/contribution_list.html index 3d0de1f5..0e10f82d 100644 --- a/georiviere/contribution/templates/contribution/contribution_list.html +++ b/georiviere/contribution/templates/contribution/contribution_list.html @@ -5,7 +5,6 @@ {% block extrabody %} {{ block.super }} -