core/counter: add generic operation logs and implements it for Sellings and Refilling deletions

This commit is contained in:
2019-11-13 23:14:21 +01:00
parent 129f2e53ee
commit e634cda318
13 changed files with 467 additions and 192 deletions

View File

@ -23,6 +23,7 @@
#
import importlib
import threading
from django.conf import settings
from django.utils.functional import SimpleLazyObject
from django.contrib.auth import get_user
@ -54,3 +55,22 @@ class AuthenticationMiddleware(DjangoAuthenticationMiddleware):
"'account.middleware.AuthenticationMiddleware'."
)
request.user = SimpleLazyObject(lambda: get_cached_user(request))
class RequestMiddleware:
"""
Allow to access current request in signals
This is a hack that looks into the thread
!!! Do not use if your operation is asynchronus !!!
Mainly used for log purpose
"""
def __init__(self, get_response, thread_local=threading.local()):
self.get_response = get_response
self.thread_local = thread_local
def __call__(self, request):
self.thread_local.current_request = request
response = self.get_response(request)
return response

View File

@ -0,0 +1,52 @@
# Generated by Django 2.2.6 on 2019-11-13 21:17
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("core", "0033_auto_20191006_0049"),
]
operations = [
migrations.CreateModel(
name="OperationLog",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("date", models.DateTimeField(auto_now_add=True, verbose_name="date")),
("label", models.CharField(max_length=255, verbose_name="label")),
(
"operation_type",
models.CharField(
choices=[
("SELLING_DELETION", "Selling deletion"),
("REFILLING_DELETION", "Refilling deletion"),
],
default="SELLING_DELETION",
max_length=40,
verbose_name="operation type",
),
),
(
"operator",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="logs",
to=settings.AUTH_USER_MODEL,
),
),
],
),
]

View File

@ -1454,3 +1454,27 @@ class Gift(models.Model):
def is_owned_by(self, user):
return user.is_board_member or user.is_root
class OperationLog(models.Model):
"""
General purpose log object to register operations
"""
date = models.DateTimeField(_("date"), auto_now_add=True)
label = models.CharField(_("label"), max_length=255)
operator = models.ForeignKey(
User, related_name="logs", on_delete=models.SET_NULL, null=True
)
operation_type = models.CharField(
_("operation type"),
max_length=40,
choices=settings.SITH_LOG_OPERATION_TYPE,
default=settings.SITH_LOG_OPERATION_TYPE[0][0],
)
def is_owned_by(self, user):
return user.is_root
def __str__(self):
return "%s - %s - %s" % (self.operation_type, self.label, self.operator)

View File

@ -63,7 +63,7 @@
<td>{{ i.amount }} €</td>
<td>{{ i.get_payment_method_display() }}</td>
{% if i.is_owned_by(user) %}
<td><a href="{{ url('counter:refilling_delete', refilling_id=i.id) }}">Delete</a></td>
<td><a href="{{ url('counter:refilling_delete', refilling_id=i.id) }}">{% trans %}Delete{% endtrans %}</a></td>
{% endif %}
</tr>
{% endfor %}

View File

@ -13,6 +13,7 @@
{% if user.is_root %}
<li><a href="{{ url('core:group_list') }}">{% trans %}Groups{% endtrans %}</a></li>
<li><a href="{{ url('rootplace:merge') }}">{% trans %}Merge users{% endtrans %}</a></li>
<li><a href="{{ url('rootplace:operation_logs') }}">{% trans %}Operation logs{% endtrans %}</a></li>
<li><a href="{{ url('rootplace:delete_forum_messages') }}">{% trans %}Delete user's forum messages{% endtrans %}</a></li>
{% endif %}
{% if user.can_create_subscription or user.is_root %}