Merge pull request 'user_action_log_introduction' (#2) from user_action_log_introduction into master
Reviewed-on: SGD-Nord/konova#2
This commit is contained in:
		
						commit
						b7ab9f6f55
					
				@ -18,6 +18,24 @@ class CompensationTableFilter(InterventionTableFilter):
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def _filter_show_all(self, queryset, name, value) -> QuerySet:
 | 
			
		||||
        """ Filters queryset depending on value of 'show_all' setting
 | 
			
		||||
 | 
			
		||||
        Args:
 | 
			
		||||
            queryset ():
 | 
			
		||||
            name ():
 | 
			
		||||
            value ():
 | 
			
		||||
 | 
			
		||||
        Returns:
 | 
			
		||||
 | 
			
		||||
        """
 | 
			
		||||
        if not value:
 | 
			
		||||
            return queryset.filter(
 | 
			
		||||
                intervention__users__in=[self.user],  # requesting user has access
 | 
			
		||||
            )
 | 
			
		||||
        else:
 | 
			
		||||
            return queryset
 | 
			
		||||
 | 
			
		||||
    def _filter_show_recorded(self, queryset, name, value) -> QuerySet:
 | 
			
		||||
        """ Filters queryset depending on value of 'show_recorded' setting
 | 
			
		||||
 | 
			
		||||
@ -31,7 +49,7 @@ class CompensationTableFilter(InterventionTableFilter):
 | 
			
		||||
        """
 | 
			
		||||
        if not value:
 | 
			
		||||
            return queryset.filter(
 | 
			
		||||
                intervention__recorded_on=None,
 | 
			
		||||
                intervention__recorded=None,
 | 
			
		||||
            )
 | 
			
		||||
        else:
 | 
			
		||||
            return queryset
 | 
			
		||||
 | 
			
		||||
@ -12,8 +12,8 @@ from django.utils import timezone
 | 
			
		||||
from django.utils.timezone import now
 | 
			
		||||
 | 
			
		||||
from compensation.settings import COMPENSATION_IDENTIFIER_LENGTH, COMPENSATION_IDENTIFIER_TEMPLATE
 | 
			
		||||
from intervention.models import Intervention
 | 
			
		||||
from konova.models import BaseObject, BaseResource, Geometry
 | 
			
		||||
from intervention.models import Intervention, ResponsibilityData
 | 
			
		||||
from konova.models import BaseObject, BaseResource, Geometry, UuidModel
 | 
			
		||||
from konova.utils.generators import generate_random_string
 | 
			
		||||
from organisation.models import Organisation
 | 
			
		||||
 | 
			
		||||
@ -73,18 +73,19 @@ class Compensation(BaseObject):
 | 
			
		||||
    The compensation holds information about which actions have to be performed until which date, who is in charge
 | 
			
		||||
    of this, which legal authority is the point of contact, and so on.
 | 
			
		||||
    """
 | 
			
		||||
    registration_office = models.ForeignKey(Organisation, on_delete=models.SET_NULL, null=True, related_name="+")
 | 
			
		||||
    conservation_office = models.ForeignKey(Organisation, on_delete=models.SET_NULL, null=True, related_name="+")
 | 
			
		||||
    responsible = models.OneToOneField(
 | 
			
		||||
        ResponsibilityData,
 | 
			
		||||
        on_delete=models.SET_NULL,
 | 
			
		||||
        null=True,
 | 
			
		||||
        blank=True,
 | 
			
		||||
        help_text="Holds data on responsible organizations ('Zulassungsbehörde', 'Eintragungsstelle') and handler",
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    ground_definitions = models.CharField(max_length=500, null=True, blank=True)  # ToDo: Need to be M2M to laws!
 | 
			
		||||
    action_definitions = models.CharField(max_length=500, null=True, blank=True)  # ToDo: Need to be M2M to laws!
 | 
			
		||||
    before_states = models.ManyToManyField(CompensationState, blank=True, related_name='+', help_text="Refers to 'Ausgangszustand Biotop'")
 | 
			
		||||
    after_states = models.ManyToManyField(CompensationState, blank=True, related_name='+', help_text="Refers to 'Zielzustand Biotop'")
 | 
			
		||||
    actions = models.ManyToManyField(CompensationAction, help_text="Refers to 'Maßnahmen'")
 | 
			
		||||
 | 
			
		||||
    before_states = models.ManyToManyField(CompensationState, blank=True, related_name='+')
 | 
			
		||||
    after_states = models.ManyToManyField(CompensationState, blank=True, related_name='+')
 | 
			
		||||
    actions = models.ManyToManyField(CompensationAction)
 | 
			
		||||
 | 
			
		||||
    deadline_creation = models.ForeignKey("konova.Deadline", on_delete=models.SET_NULL, null=True, blank=True, related_name="+")
 | 
			
		||||
    deadline_maintaining = models.ForeignKey("konova.Deadline", on_delete=models.SET_NULL, null=True, blank=True, related_name="+")
 | 
			
		||||
    deadlines = models.ManyToManyField("konova.Deadline", null=True, blank=True, related_name="+")
 | 
			
		||||
 | 
			
		||||
    geometry = models.ForeignKey(Geometry, null=True, blank=True, on_delete=models.SET_NULL)
 | 
			
		||||
    documents = models.ManyToManyField("konova.Document", blank=True)
 | 
			
		||||
@ -100,9 +101,6 @@ class Compensation(BaseObject):
 | 
			
		||||
        related_name='compensations'
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # Users having access on this object
 | 
			
		||||
    users = models.ManyToManyField(User)
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def _generate_new_identifier() -> str:
 | 
			
		||||
        """ Generates a new identifier for the intervention object
 | 
			
		||||
@ -152,4 +150,5 @@ class EcoAccount(Compensation):
 | 
			
		||||
    An eco account is a kind of 'prepaid' compensation. It can be compared to an account that already has been filled
 | 
			
		||||
    with some kind of currency. From this account one is able to 'withdraw' currency for current projects.
 | 
			
		||||
    """
 | 
			
		||||
    handler = models.CharField(max_length=500, null=True, blank=True, help_text="Who is responsible for handling the actions")
 | 
			
		||||
    # Users having access on this object
 | 
			
		||||
    users = models.ManyToManyField(User)
 | 
			
		||||
 | 
			
		||||
@ -34,13 +34,13 @@ class CompensationTable(BaseTable):
 | 
			
		||||
        verbose_name=_("Checked"),
 | 
			
		||||
        orderable=True,
 | 
			
		||||
        empty_values=[],
 | 
			
		||||
        accessor="intervention__checked_on",
 | 
			
		||||
        accessor="intervention__checked",
 | 
			
		||||
    )
 | 
			
		||||
    r = tables.Column(
 | 
			
		||||
        verbose_name=_("Recorded"),
 | 
			
		||||
        orderable=True,
 | 
			
		||||
        empty_values=[],
 | 
			
		||||
        accessor="intervention__recorded_on",
 | 
			
		||||
        accessor="intervention__recorded",
 | 
			
		||||
    )
 | 
			
		||||
    e = tables.Column(
 | 
			
		||||
        verbose_name=_("Editable"),
 | 
			
		||||
@ -90,7 +90,7 @@ class CompensationTable(BaseTable):
 | 
			
		||||
    def render_c(self, value, record: Compensation):
 | 
			
		||||
        """ Renders the checked column for a compensation
 | 
			
		||||
 | 
			
		||||
        checked_on is set by the main object Intervention
 | 
			
		||||
        checked is set by the main object Intervention
 | 
			
		||||
 | 
			
		||||
        Args:
 | 
			
		||||
            value (str): The identifier value
 | 
			
		||||
@ -103,9 +103,10 @@ class CompensationTable(BaseTable):
 | 
			
		||||
        checked = value is not None
 | 
			
		||||
        tooltip = _("Not checked yet")
 | 
			
		||||
        if checked:
 | 
			
		||||
            value = value.timestamp
 | 
			
		||||
            value = localtime(value)
 | 
			
		||||
            checked_on = value.strftime(DEFAULT_DATE_TIME_FORMAT)
 | 
			
		||||
            tooltip = _("Checked on {} by {}").format(checked_on, record.intervention.checked_by)
 | 
			
		||||
            tooltip = _("Checked on {} by {}").format(checked_on, record.intervention.checked.user)
 | 
			
		||||
        html += self.render_checked_star(
 | 
			
		||||
            tooltip=tooltip,
 | 
			
		||||
            icn_filled=checked,
 | 
			
		||||
@ -126,9 +127,10 @@ class CompensationTable(BaseTable):
 | 
			
		||||
        checked = value is not None
 | 
			
		||||
        tooltip = _("Not registered yet")
 | 
			
		||||
        if checked:
 | 
			
		||||
            value = value.timestamp
 | 
			
		||||
            value = localtime(value)
 | 
			
		||||
            on = value.strftime(DEFAULT_DATE_TIME_FORMAT)
 | 
			
		||||
            tooltip = _("Registered on {} by {}").format(on, record.intervention.recorded_by)
 | 
			
		||||
            tooltip = _("Registered on {} by {}").format(on, record.intervention.recorded.user)
 | 
			
		||||
        html += self.render_bookmark(
 | 
			
		||||
            tooltip=tooltip,
 | 
			
		||||
            icn_filled=checked,
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,38 @@
 | 
			
		||||
from django.contrib import admin
 | 
			
		||||
 | 
			
		||||
from intervention.models import Intervention
 | 
			
		||||
from intervention.models import Intervention, ResponsibilityData, LegalData
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class InterventionAdmin(admin.ModelAdmin):
 | 
			
		||||
    list_display = [
 | 
			
		||||
        "id",
 | 
			
		||||
        "title",
 | 
			
		||||
        "process_type",
 | 
			
		||||
        "handler",
 | 
			
		||||
        "created_on",
 | 
			
		||||
        "deleted_on",
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ResponsibilityAdmin(admin.ModelAdmin):
 | 
			
		||||
    list_display = [
 | 
			
		||||
        "id",
 | 
			
		||||
        "registration_office",
 | 
			
		||||
        "registration_file_number",
 | 
			
		||||
        "conservation_office",
 | 
			
		||||
        "conservation_file_number",
 | 
			
		||||
        "handler",
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LegalAdmin(admin.ModelAdmin):
 | 
			
		||||
    list_display = [
 | 
			
		||||
        "id",
 | 
			
		||||
        "process_type",
 | 
			
		||||
        "law",
 | 
			
		||||
        "registration_date",
 | 
			
		||||
        "binding_date",
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
admin.site.register(Intervention, InterventionAdmin)
 | 
			
		||||
admin.site.register(ResponsibilityData, ResponsibilityAdmin)
 | 
			
		||||
admin.site.register(LegalData, LegalAdmin)
 | 
			
		||||
 | 
			
		||||
@ -117,7 +117,7 @@ class InterventionTableFilter(django_filters.FilterSet):
 | 
			
		||||
        """
 | 
			
		||||
        if not value:
 | 
			
		||||
            return queryset.filter(
 | 
			
		||||
                recorded_on=None,
 | 
			
		||||
                recorded=None,
 | 
			
		||||
            )
 | 
			
		||||
        else:
 | 
			
		||||
            return queryset
 | 
			
		||||
 | 
			
		||||
@ -12,47 +12,84 @@ from django.utils import timezone
 | 
			
		||||
from django.utils.timezone import now
 | 
			
		||||
 | 
			
		||||
from intervention.settings import INTERVENTION_IDENTIFIER_LENGTH, INTERVENTION_IDENTIFIER_TEMPLATE
 | 
			
		||||
from konova.models import BaseObject, Geometry
 | 
			
		||||
from konova.models import BaseObject, Geometry, UuidModel
 | 
			
		||||
from konova.utils.generators import generate_random_string
 | 
			
		||||
from organisation.models import Organisation
 | 
			
		||||
from user.models import UserActionLogEntry
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ResponsibilityData(UuidModel):
 | 
			
		||||
    """
 | 
			
		||||
    Holds intervention data about responsible organizations and their file numbers for this case
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    registration_office = models.ForeignKey(Organisation, on_delete=models.SET_NULL, null=True, related_name="+")
 | 
			
		||||
    registration_file_number = models.CharField(max_length=1000, blank=True, null=True)
 | 
			
		||||
    conservation_office = models.ForeignKey(Organisation, on_delete=models.SET_NULL, null=True, related_name="+")
 | 
			
		||||
    conservation_file_number = models.CharField(max_length=1000, blank=True, null=True)
 | 
			
		||||
    handler = models.CharField(max_length=500, null=True, blank=True, help_text="Refers to 'Eingriffsverursacher'")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LegalData(UuidModel):
 | 
			
		||||
    """
 | 
			
		||||
    Holds intervention legal data such as important dates, laws or responsible handler
 | 
			
		||||
    """
 | 
			
		||||
    # Refers to "zugelassen am"
 | 
			
		||||
    registration_date = models.DateField(null=True, blank=True, help_text="Refers to 'Zugelassen am'")
 | 
			
		||||
 | 
			
		||||
    # Refers to "Bestandskraft am"
 | 
			
		||||
    binding_date = models.DateField(null=True, blank=True, help_text="Refers to 'Bestandskraft am'")
 | 
			
		||||
 | 
			
		||||
    process_type = models.CharField(max_length=500, null=True, blank=True)
 | 
			
		||||
    law = models.CharField(max_length=500, null=True, blank=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Intervention(BaseObject):
 | 
			
		||||
    """
 | 
			
		||||
    Interventions are e.g. construction sites where nature used to be.
 | 
			
		||||
    """
 | 
			
		||||
    registration_office = models.ForeignKey(Organisation, on_delete=models.SET_NULL, null=True, related_name="+")
 | 
			
		||||
    registration_file_number = models.CharField(max_length=1000, blank=True, null=True)
 | 
			
		||||
    conservation_office = models.ForeignKey(Organisation, on_delete=models.SET_NULL, null=True, related_name="+")
 | 
			
		||||
    conservation_file_number = models.CharField(max_length=1000, blank=True, null=True)
 | 
			
		||||
 | 
			
		||||
    process_type = models.CharField(max_length=500, null=True, blank=True)
 | 
			
		||||
    law = models.CharField(max_length=500, null=True, blank=True)
 | 
			
		||||
    handler = models.CharField(max_length=500, null=True, blank=True, help_text="Who is responsible for this intervention?")
 | 
			
		||||
    responsible = models.OneToOneField(
 | 
			
		||||
        ResponsibilityData,
 | 
			
		||||
        on_delete=models.SET_NULL,
 | 
			
		||||
        null=True,
 | 
			
		||||
        blank=True,
 | 
			
		||||
        related_name='+',
 | 
			
		||||
        help_text="Holds data on responsible organizations ('Zulassungsbehörde', 'Eintragungsstelle')"
 | 
			
		||||
    )
 | 
			
		||||
    legal = models.OneToOneField(
 | 
			
		||||
        LegalData,
 | 
			
		||||
        on_delete=models.SET_NULL,
 | 
			
		||||
        null=True,
 | 
			
		||||
        blank=True,
 | 
			
		||||
        related_name='+',
 | 
			
		||||
        help_text="Holds data on legal dates or law"
 | 
			
		||||
    )
 | 
			
		||||
    geometry = models.ForeignKey(Geometry, null=True, blank=True, on_delete=models.SET_NULL)
 | 
			
		||||
    documents = models.ManyToManyField("konova.Document", blank=True)
 | 
			
		||||
 | 
			
		||||
    # Checks
 | 
			
		||||
    checked_on = models.DateTimeField(default=None, null=True, blank=True)
 | 
			
		||||
    checked_by = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL, related_name='+')
 | 
			
		||||
 | 
			
		||||
    # Refers to "zugelassen am"
 | 
			
		||||
    registration_date = models.DateField(null=True, blank=True)
 | 
			
		||||
 | 
			
		||||
    # Refers to "Bestandskraft am"
 | 
			
		||||
    binding_on = models.DateField(null=True, blank=True)
 | 
			
		||||
    # Checks - Refers to "Genehmigen" but optional
 | 
			
		||||
    checked = models.OneToOneField(
 | 
			
		||||
        UserActionLogEntry,
 | 
			
		||||
        on_delete=models.SET_NULL,
 | 
			
		||||
        null=True,
 | 
			
		||||
        blank=True,
 | 
			
		||||
        help_text="Holds data on user and timestamp of this action",
 | 
			
		||||
        related_name="+"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # Refers to "verzeichnen"
 | 
			
		||||
    recorded_on = models.DateTimeField(default=None, null=True, blank=True)
 | 
			
		||||
    recorded_by = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL, related_name='+')
 | 
			
		||||
    recorded = models.OneToOneField(
 | 
			
		||||
        UserActionLogEntry,
 | 
			
		||||
        on_delete=models.SET_NULL,
 | 
			
		||||
        null=True,
 | 
			
		||||
        blank=True,
 | 
			
		||||
        help_text="Holds data on user and timestamp of this action",
 | 
			
		||||
        related_name="+"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # Holds which intervention is simply a newer version of this dataset
 | 
			
		||||
    next_version = models.ForeignKey("Intervention", null=True, blank=True, on_delete=models.DO_NOTHING)
 | 
			
		||||
 | 
			
		||||
    # Compensation or payments, one-directional
 | 
			
		||||
    #payments = models.ManyToManyField(Payment, related_name="+", blank=True)
 | 
			
		||||
    #compensations = models.ManyToManyField(Compensation, related_name="+", blank=True)
 | 
			
		||||
 | 
			
		||||
    # Users having access on this object
 | 
			
		||||
    users = models.ManyToManyField(User)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -33,13 +33,13 @@ class InterventionTable(BaseTable):
 | 
			
		||||
        verbose_name=_("Checked"),
 | 
			
		||||
        orderable=True,
 | 
			
		||||
        empty_values=[],
 | 
			
		||||
        accessor="checked_on",
 | 
			
		||||
        accessor="checked",
 | 
			
		||||
    )
 | 
			
		||||
    r = tables.Column(
 | 
			
		||||
        verbose_name=_("Recorded"),
 | 
			
		||||
        orderable=True,
 | 
			
		||||
        empty_values=[],
 | 
			
		||||
        accessor="recorded_on",
 | 
			
		||||
        accessor="recorded",
 | 
			
		||||
    )
 | 
			
		||||
    e = tables.Column(
 | 
			
		||||
        verbose_name=_("Editable"),
 | 
			
		||||
@ -110,9 +110,10 @@ class InterventionTable(BaseTable):
 | 
			
		||||
        checked = value is not None
 | 
			
		||||
        tooltip = _("Not checked yet")
 | 
			
		||||
        if checked:
 | 
			
		||||
            value = value.timestamp
 | 
			
		||||
            value = localtime(value)
 | 
			
		||||
            checked_on = value.strftime(DEFAULT_DATE_TIME_FORMAT)
 | 
			
		||||
            tooltip = _("Checked on {} by {}").format(checked_on, record.checked_by)
 | 
			
		||||
            tooltip = _("Checked on {} by {}").format(checked_on, record.checked.user)
 | 
			
		||||
        html += self.render_checked_star(
 | 
			
		||||
            tooltip=tooltip,
 | 
			
		||||
            icn_filled=checked,
 | 
			
		||||
@ -133,9 +134,10 @@ class InterventionTable(BaseTable):
 | 
			
		||||
        checked = value is not None
 | 
			
		||||
        tooltip = _("Not registered yet")
 | 
			
		||||
        if checked:
 | 
			
		||||
            value = value.timestamp
 | 
			
		||||
            value = localtime(value)
 | 
			
		||||
            on = value.strftime(DEFAULT_DATE_TIME_FORMAT)
 | 
			
		||||
            tooltip = _("Registered on {} by {}").format(on, record.recorded_by)
 | 
			
		||||
            tooltip = _("Registered on {} by {}").format(on, record.recorded.user)
 | 
			
		||||
        html += self.render_bookmark(
 | 
			
		||||
            tooltip=tooltip,
 | 
			
		||||
            icn_filled=checked,
 | 
			
		||||
 | 
			
		||||
@ -64,41 +64,41 @@
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th scope="row">{% trans 'Process type' %}</th>
 | 
			
		||||
                        <td class="align-middle">{{intervention.process_type|default_if_none:""}}</td>
 | 
			
		||||
                        <td class="align-middle">{{intervention.legal.process_type|default_if_none:""}}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th scope="row">{% trans 'Law' %}</th>
 | 
			
		||||
                        <td class="align-middle">{{intervention.law|default_if_none:""}}</td>
 | 
			
		||||
                        <td class="align-middle">{{intervention.legal.law|default_if_none:""}}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th scope="row">{% trans 'Registration office' %}</th>
 | 
			
		||||
                        <td class="align-middle">{{intervention.registration_office|default_if_none:""}}</td>
 | 
			
		||||
                        <td class="align-middle">{{intervention.responsible.registration_office|default_if_none:""}}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th scope="row">{% trans 'Registration office file number' %}</th>
 | 
			
		||||
                        <td class="align-middle">{{intervention.registration_file_number|default_if_none:""}}</td>
 | 
			
		||||
                        <td class="align-middle">{{intervention.responsible.registration_file_number|default_if_none:""}}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th scope="row">{% trans 'Conservation office' %}</th>
 | 
			
		||||
                        <td class="align-middle">{{intervention.conservation_office|default_if_none:""}}</td>
 | 
			
		||||
                        <td class="align-middle">{{intervention.responsible.conservation_office|default_if_none:""}}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th scope="row">{% trans 'Conversation office file number' %}</th>
 | 
			
		||||
                        <td class="align-middle">{{intervention.conservation_file_number|default_if_none:""}}</td>
 | 
			
		||||
                        <td class="align-middle">{{intervention.responsible.conservation_file_number|default_if_none:""}}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th scope="row">{% trans 'Intervention handler' %}</th>
 | 
			
		||||
                        <td class="align-middle">{{intervention.handler|default_if_none:""}}</td>
 | 
			
		||||
                        <td class="align-middle">{{intervention.responsible.handler|default_if_none:""}}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th scope="row">{% trans 'Checked' %}</th>
 | 
			
		||||
                        <td class="align-middle">
 | 
			
		||||
                            {% if intervention.checked_on is None %}
 | 
			
		||||
                            {% if intervention.checked is None %}
 | 
			
		||||
                                <span>
 | 
			
		||||
                                    {% fa5_icon 'star' 'far' %}
 | 
			
		||||
                                </span>
 | 
			
		||||
                            {% else %}
 | 
			
		||||
                                <span class="check-star">
 | 
			
		||||
                                <span class="check-star" title="{% trans 'Checked on '%} {{intervention.checked.timestamp}} {% trans 'by' %} {{intervention.checked.user}}">
 | 
			
		||||
                                    {% fa5_icon 'star' %}
 | 
			
		||||
                                </span>
 | 
			
		||||
                            {% endif %}
 | 
			
		||||
@ -107,12 +107,12 @@
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th scope="row">{% trans 'Recorded' %}</th>
 | 
			
		||||
                        <td class="align-middle">
 | 
			
		||||
                            {% if intervention.recorded_on is None %}
 | 
			
		||||
                            {% if intervention.recorded is None %}
 | 
			
		||||
                                <span>
 | 
			
		||||
                                    {% fa5_icon 'bookmark' 'far' %}
 | 
			
		||||
                                </span>
 | 
			
		||||
                            {% else %}
 | 
			
		||||
                                <span class="registered-bookmark">
 | 
			
		||||
                                <span class="registered-bookmark" title="{% trans 'Recorded on '%} {{intervention.recorded.timestamp}} {% trans 'by' %} {{intervention.recorded.user}}">
 | 
			
		||||
                                    {% fa5_icon 'bookmark' %}
 | 
			
		||||
                                </span>
 | 
			
		||||
                            {% endif %}
 | 
			
		||||
@ -120,11 +120,11 @@
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th scope="row">{% trans 'Registration date' %}</th>
 | 
			
		||||
                        <td class="align-middle">{{intervention.registration_date|default_if_none:""}}</td>
 | 
			
		||||
                        <td class="align-middle">{{intervention.legal.registration_date|default_if_none:""}}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th scope="row">{% trans 'Binding on' %}</th>
 | 
			
		||||
                        <td class="align-middle">{{intervention.binding_on|default_if_none:""}}</td>
 | 
			
		||||
                        <td class="align-middle">{{intervention.legal.binding_on|default_if_none:""}}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th scope="row">{% trans 'Last modified' %}</th>
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@ Created on: 22.07.21
 | 
			
		||||
"""
 | 
			
		||||
from django.contrib import admin
 | 
			
		||||
 | 
			
		||||
from konova.models import Geometry, Document
 | 
			
		||||
from konova.models import Geometry, Document, Deadline
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GeometryAdmin(admin.ModelAdmin):
 | 
			
		||||
@ -28,5 +28,15 @@ class DocumentAdmin(admin.ModelAdmin):
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeadlineAdmin(admin.ModelAdmin):
 | 
			
		||||
    list_display = [
 | 
			
		||||
        "id",
 | 
			
		||||
        "type",
 | 
			
		||||
        "date",
 | 
			
		||||
        "comment",
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
admin.site.register(Geometry, GeometryAdmin)
 | 
			
		||||
admin.site.register(Document, DocumentAdmin)
 | 
			
		||||
admin.site.register(Deadline, DeadlineAdmin)
 | 
			
		||||
 | 
			
		||||
@ -47,3 +47,17 @@ class ServerMessageImportance(BaseEnum):
 | 
			
		||||
    DEFAULT = "DEFAULT"
 | 
			
		||||
    INFO = "INFO"
 | 
			
		||||
    WARNING = "WARNING"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserActionLogEntryEnum(BaseEnum):
 | 
			
		||||
    """
 | 
			
		||||
    Defines different possible user actions for UserActionLogEntry
 | 
			
		||||
    """
 | 
			
		||||
    CHECKED = "Checked"
 | 
			
		||||
    RECORDED = "Recorded"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeadlineTypeEnum(BaseEnum):
 | 
			
		||||
    MAINTAIN = "Maintain"
 | 
			
		||||
    CONTROL = "Control"
 | 
			
		||||
    OTHER = "Other"
 | 
			
		||||
@ -12,17 +12,27 @@ from django.contrib.auth.models import User
 | 
			
		||||
from django.contrib.gis.db.models import MultiPolygonField
 | 
			
		||||
from django.db import models
 | 
			
		||||
 | 
			
		||||
from konova.enums import DeadlineTypeEnum
 | 
			
		||||
from konova.settings import DEFAULT_SRID
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseResource(models.Model):
 | 
			
		||||
class UuidModel(models.Model):
 | 
			
		||||
    """
 | 
			
		||||
    A basic resource model, which defines attributes for every derived model
 | 
			
		||||
    Encapsules identifying via uuid
 | 
			
		||||
    """
 | 
			
		||||
    id = models.UUIDField(
 | 
			
		||||
        primary_key=True,
 | 
			
		||||
        default=uuid.uuid4,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        abstract = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseResource(UuidModel):
 | 
			
		||||
    """
 | 
			
		||||
    A basic resource model, which defines attributes for every derived model
 | 
			
		||||
    """
 | 
			
		||||
    created_on = models.DateTimeField(auto_now_add=True, null=True)
 | 
			
		||||
    created_by = models.ForeignKey(User, null=True, on_delete=models.SET_NULL, related_name="+")
 | 
			
		||||
 | 
			
		||||
@ -50,8 +60,9 @@ class Deadline(BaseResource):
 | 
			
		||||
    """
 | 
			
		||||
    Defines a deadline, which can be used to define dates with a semantic meaning
 | 
			
		||||
    """
 | 
			
		||||
    type = models.CharField(max_length=500, null=True, blank=True)
 | 
			
		||||
    type = models.CharField(max_length=255, null=True, blank=True, choices=DeadlineTypeEnum.as_choices(drop_empty_choice=True))
 | 
			
		||||
    date = models.DateField(null=True, blank=True)
 | 
			
		||||
    comment = models.CharField(max_length=1000, null=True, blank=True)
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return self.type
 | 
			
		||||
 | 
			
		||||
@ -78,7 +78,7 @@ def home_view(request: HttpRequest):
 | 
			
		||||
        next_version=None,
 | 
			
		||||
    )
 | 
			
		||||
    user_comps = comps.filter(
 | 
			
		||||
        users__in=[user]
 | 
			
		||||
        intervention__users__in=[user]
 | 
			
		||||
    )
 | 
			
		||||
    eco_accs = EcoAccount.objects.filter(
 | 
			
		||||
        deleted_on=None,
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
from django.contrib import admin
 | 
			
		||||
 | 
			
		||||
from user.models import UserNotification, KonovaUserExtension
 | 
			
		||||
from user.models import UserNotification, KonovaUserExtension, UserActionLogEntry
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserNotificationAdmin(admin.ModelAdmin):
 | 
			
		||||
@ -17,5 +17,15 @@ class KonovaUserExtensionAdmin(admin.ModelAdmin):
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserActionLogEntryAdmin(admin.ModelAdmin):
 | 
			
		||||
    list_display = [
 | 
			
		||||
        "id",
 | 
			
		||||
        "user",
 | 
			
		||||
        "timestamp",
 | 
			
		||||
        "action",
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
admin.site.register(UserNotification, UserNotificationAdmin)
 | 
			
		||||
admin.site.register(KonovaUserExtension, KonovaUserExtensionAdmin)
 | 
			
		||||
admin.site.register(UserActionLogEntry, UserActionLogEntryAdmin)
 | 
			
		||||
@ -1,6 +1,9 @@
 | 
			
		||||
import uuid
 | 
			
		||||
 | 
			
		||||
from django.contrib.auth.models import User
 | 
			
		||||
from django.db import models
 | 
			
		||||
 | 
			
		||||
from konova.enums import UserActionLogEntryEnum
 | 
			
		||||
from user.enums import UserNotificationEnum
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -36,3 +39,27 @@ class KonovaUserExtension(models.Model):
 | 
			
		||||
    """
 | 
			
		||||
    user = models.OneToOneField(User, on_delete=models.CASCADE)
 | 
			
		||||
    notifications = models.ManyToManyField(UserNotification, related_name="+")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserActionLogEntry(models.Model):
 | 
			
		||||
    """ Wraps a user action log entry
 | 
			
		||||
 | 
			
		||||
    Can be used for workflow related attributes like checking or recording.
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    id = models.UUIDField(
 | 
			
		||||
        primary_key=True,
 | 
			
		||||
        default=uuid.uuid4,
 | 
			
		||||
    )
 | 
			
		||||
    user = models.ForeignKey(User, related_name='+', on_delete=models.CASCADE, help_text="Performing user")
 | 
			
		||||
    timestamp = models.DateTimeField(auto_now_add=True, help_text="Timestamp of performed action")
 | 
			
		||||
    action = models.CharField(
 | 
			
		||||
        max_length=255,
 | 
			
		||||
        null=True,
 | 
			
		||||
        blank=True,
 | 
			
		||||
        help_text="Short name for performed action - optional",
 | 
			
		||||
        choices=UserActionLogEntryEnum.as_choices(drop_empty_choice=True),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return "{} | {} | {}".format(self.user.username, self.timestamp, self.action)
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user