diff --git a/apps/logs/api/views.py b/apps/logs/api/views.py index b3b9b166fb94c2ada7f66a5a8cbcbb42da425187..4160d609ff45179653b3fcde9609ee6513565585 100644 --- a/apps/logs/api/views.py +++ b/apps/logs/api/views.py @@ -19,5 +19,5 @@ class ChangelogViewSet(ReadOnlyProtectedModelViewSet): serializer_class = ChangelogSerializer filter_backends = [DjangoFilterBackend, OrderingFilter] filterset_fields = ['model', 'action', "instance_pk", 'user', 'ip', ] - ordering_fields = ['timestamp', ] - ordering = ['-timestamp', ] + ordering_fields = ['timestamp', 'id', ] + ordering = ['-id', ] diff --git a/apps/logs/signals.py b/apps/logs/signals.py index 12d22155c15eedcc65b318f3a38e8faf7399c932..bc8eec44b1b3fe118e13e9e41951d2bad0ddda7e 100644 --- a/apps/logs/signals.py +++ b/apps/logs/signals.py @@ -81,19 +81,27 @@ def save_object(sender, instance, **kwargs): if instance.last_login != previous.last_login: return - # On crée notre propre sérialiseur JSON pour pouvoir sauvegarder les modèles + fields = '__all__' + if previous: + # On ne garde que les champs modifiés + changed_fields = [] + for field in instance._meta.fields: + if getattr(instance, field.name) != getattr(previous, field.name): + changed_fields.append(field.name) + + if len(changed_fields) == 0: + # Pas de log s'il n'y a pas de modification + return + + # On crée notre propre sérialiseur JSON pour pouvoir sauvegarder les modèles avec uniquement les champs modifiés class CustomSerializer(ModelSerializer): class Meta: model = instance.__class__ - fields = '__all__' + fields = changed_fields previous_json = JSONRenderer().render(CustomSerializer(previous).data).decode("UTF-8") if previous else None instance_json = JSONRenderer().render(CustomSerializer(instance).data).decode("UTF-8") - if previous_json == instance_json: - # Pas de log s'il n'y a pas de modification - return - Changelog.objects.create(user=user, ip=ip, model=ContentType.objects.get_for_model(instance), diff --git a/apps/note/models/transactions.py b/apps/note/models/transactions.py index b3a541a14af3b3e43cd50d3a73f59320810710fb..f57cc9b55f627b0d27cd5da5d40d05066b231aaa 100644 --- a/apps/note/models/transactions.py +++ b/apps/note/models/transactions.py @@ -167,26 +167,35 @@ class Transaction(PolymorphicModel): previous_source_balance = self.source.balance previous_dest_balance = self.destination.balance + source_balance = self.source.balance + dest_balance = self.destination.balance + created = self.pk is None to_transfer = self.amount * self.quantity if not created: # Revert old transaction old_transaction = Transaction.objects.get(pk=self.pk) + # Check that nothing important changed + for field_name in ["source_id", "destination_id", "quantity", "amount"]: + if getattr(self, field_name) != getattr(old_transaction, field_name): + raise ValidationError(_("You can't update the {field} on a Transaction. " + "Please invalidate it and create one other.").format(field=field_name)) + + if old_transaction.valid == self.valid: + # Don't change anything + return 0, 0 if old_transaction.valid: - self.source.balance += to_transfer - self.destination.balance -= to_transfer + source_balance += to_transfer + dest_balance -= to_transfer if self.valid: - self.source.balance -= to_transfer - self.destination.balance += to_transfer + source_balance -= to_transfer + dest_balance += to_transfer # When a transaction is declared valid, we ensure that the invalidity reason is null, if it was # previously invalid self.invalidity_reason = None - source_balance = self.source.balance - dest_balance = self.destination.balance - if source_balance > 2147483647 or source_balance < -2147483648\ or dest_balance > 2147483647 or dest_balance < -2147483648: raise ValidationError(_("The note balances must be between - 21 474 836.47 € and 21 474 836.47 €.")) diff --git a/apps/permission/fixtures/initial.json b/apps/permission/fixtures/initial.json index 80e38f6a163e1f5805c580396bea49fb95f159c2..192b9391bb1092cdc5a01924d0574d23efe4ce16 100644 --- a/apps/permission/fixtures/initial.json +++ b/apps/permission/fixtures/initial.json @@ -2456,7 +2456,7 @@ 47, 49, 50, - 140 + 141 ] } }, diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py index 2e0ff8f5b327516d62dfd982c2126aba7dd3e80b..2aa303ed5f061c4840121021c190bfcd1d5d29ab 100644 --- a/note_kfet/settings/base.py +++ b/note_kfet/settings/base.py @@ -46,6 +46,7 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', 'django.forms', + 'django_filters', # API 'rest_framework', diff --git a/note_kfet/static/js/base.js b/note_kfet/static/js/base.js index 9db1d958af099fcd1d7eefaa413dc41fb7fb7b50..36e8ec84d4a1b1416099b5045c73b8671d1126f8 100644 --- a/note_kfet/static/js/base.js +++ b/note_kfet/static/js/base.js @@ -349,8 +349,15 @@ function autoCompleteNote(field_id, note_list_id, notes, notes_display, alias_pr // When a validate button is clicked, we switch the validation status function de_validate(id, validated) { + let validate_obj = $("#validate_" + id); + + if (validate_obj.data("pending")) + // The button is already clicked + return; + let invalidity_reason = $("#invalidity_reason_" + id).val(); - $("#validate_" + id).html("<strong style=\"font-size: 16pt;\">⟳</strong>"); + validate_obj.html("<strong style=\"font-size: 16pt;\">⟳</strong>"); + validate_obj.data("pending", true); // Perform a PATCH request to the API in order to update the transaction // If the user has insufficient rights, an error message will appear