#114 Unshared Account Deductions

* enables deducting from unshared eco accounts
   * account must be recorded and not deleted, so users can use it for deductions
This commit is contained in:
mpeltriaux 2022-02-16 12:35:19 +01:00
parent 85f777f683
commit 5ccb63d27b
5 changed files with 13 additions and 20 deletions

View File

@ -10,7 +10,7 @@
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
{% if is_default_member and has_access %} {% if is_default_member and obj.recorded %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:acc:new-deduction' obj.id %}" title="{% trans 'Add new deduction' %}"> <button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:acc:new-deduction' obj.id %}" title="{% trans 'Add new deduction' %}">
{% fa5_icon 'plus' %} {% fa5_icon 'plus' %}
{% fa5_icon 'tree' %} {% fa5_icon 'tree' %}
@ -61,7 +61,7 @@
<td class="align-middle">{{ deduction.surface|floatformat:2|intcomma }} m²</td> <td class="align-middle">{{ deduction.surface|floatformat:2|intcomma }} m²</td>
<td class="align-middle">{{ deduction.created.timestamp|default_if_none:""|naturalday}}</td> <td class="align-middle">{{ deduction.created.timestamp|default_if_none:""|naturalday}}</td>
<td class="align-middle float-right"> <td class="align-middle float-right">
{% if is_default_member and has_access %} {% if is_default_member and has_access or is_default_member and user in deduction.intervention.shared_users %}
<button data-form-url="{% url 'compensation:acc:edit-deduction' deduction.account.id deduction.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit Deduction' %}"> <button data-form-url="{% url 'compensation:acc:edit-deduction' deduction.account.id deduction.id %}" class="btn btn-default btn-modal" title="{% trans 'Edit Deduction' %}">
{% fa5_icon 'edit' %} {% fa5_icon 'edit' %}
</button> </button>

View File

@ -231,7 +231,9 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
def test_edit_deduction(self): def test_edit_deduction(self):
test_surface = self.eco_account.get_available_rest()[0] test_surface = self.eco_account.get_available_rest()[0]
self.eco_account.set_recorded(self.superuser) self.eco_account.set_recorded(self.superuser)
self.intervention.share_with(self.superuser)
self.eco_account.refresh_from_db() self.eco_account.refresh_from_db()
self.assertIn(self.superuser, self.intervention.is_shared_with(self.superuser))
deduction = EcoAccountDeduction.objects.create( deduction = EcoAccountDeduction.objects.create(
intervention=self.intervention, intervention=self.intervention,

View File

@ -272,7 +272,6 @@ def remove_view(request: HttpRequest, id: str):
@login_required @login_required
@default_group_required @default_group_required
@shared_access_required(EcoAccount, "id")
def deduction_remove_view(request: HttpRequest, id: str, deduction_id: str): def deduction_remove_view(request: HttpRequest, id: str, deduction_id: str):
""" Renders a modal view for removing deductions """ Renders a modal view for removing deductions
@ -287,6 +286,8 @@ def deduction_remove_view(request: HttpRequest, id: str, deduction_id: str):
acc = get_object_or_404(EcoAccount, id=id) acc = get_object_or_404(EcoAccount, id=id)
try: try:
eco_deduction = acc.deductions.get(id=deduction_id) eco_deduction = acc.deductions.get(id=deduction_id)
if not eco_deduction.intervention.is_shared_with(request.user):
raise ObjectDoesNotExist()
except ObjectDoesNotExist: except ObjectDoesNotExist:
raise Http404("Unknown deduction") raise Http404("Unknown deduction")
@ -300,7 +301,6 @@ def deduction_remove_view(request: HttpRequest, id: str, deduction_id: str):
@login_required @login_required
@default_group_required @default_group_required
@shared_access_required(EcoAccount, "id")
def deduction_edit_view(request: HttpRequest, id: str, deduction_id: str): def deduction_edit_view(request: HttpRequest, id: str, deduction_id: str):
""" Renders a modal view for editing deductions """ Renders a modal view for editing deductions
@ -315,6 +315,8 @@ def deduction_edit_view(request: HttpRequest, id: str, deduction_id: str):
acc = get_object_or_404(EcoAccount, id=id) acc = get_object_or_404(EcoAccount, id=id)
try: try:
eco_deduction = acc.deductions.get(id=deduction_id) eco_deduction = acc.deductions.get(id=deduction_id)
if not eco_deduction.intervention.is_shared_with(request.user):
raise ObjectDoesNotExist
except ObjectDoesNotExist: except ObjectDoesNotExist:
raise Http404("Unknown deduction") raise Http404("Unknown deduction")
@ -679,7 +681,6 @@ def remove_document_view(request: HttpRequest, id: str, doc_id: str):
@login_required @login_required
@default_group_required @default_group_required
@shared_access_required(EcoAccount, "id")
def new_deduction_view(request: HttpRequest, id: str): def new_deduction_view(request: HttpRequest, id: str):
""" Renders a modal form view for creating deductions """ Renders a modal form view for creating deductions
@ -691,6 +692,8 @@ def new_deduction_view(request: HttpRequest, id: str):
""" """
acc = get_object_or_404(EcoAccount, id=id) acc = get_object_or_404(EcoAccount, id=id)
if not acc.recorded:
raise Http404()
form = NewDeductionModalForm(request.POST or None, instance=acc, request=request) form = NewDeductionModalForm(request.POST or None, instance=acc, request=request)
return form.process_request( return form.process_request(
request, request,

View File

@ -303,7 +303,6 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase):
Reasons for failing are: Reasons for failing are:
* EcoAccount does not provide enough 'deductable_surface' * EcoAccount does not provide enough 'deductable_surface'
* EcoAccount is not recorded (not "approved"), yet * EcoAccount is not recorded (not "approved"), yet
* EcoAccount is not shared with performing user
Args: Args:
new_url (str): The url to send the post data to new_url (str): The url to send the post data to
@ -315,7 +314,6 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase):
# Before running fail positive tests, we need to have an account in a (normally) fine working state # Before running fail positive tests, we need to have an account in a (normally) fine working state
self.assertIsNotNone(self.eco_account.recorded) # -> is recorded self.assertIsNotNone(self.eco_account.recorded) # -> is recorded
self.assertGreater(self.eco_account.deductable_surface, test_surface) # -> has more deductable surface than we need self.assertGreater(self.eco_account.deductable_surface, test_surface) # -> has more deductable surface than we need
self.assertIn(self.superuser, self.eco_account.users.all()) # -> is shared with the performing user
# Count the number of already existing deductions in total and for the account for later comparison # Count the number of already existing deductions in total and for the account for later comparison
num_deductions = self.eco_account.deductions.count() num_deductions = self.eco_account.deductions.count()
@ -333,20 +331,11 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase):
self.assertEqual(num_deductions, self.eco_account.deductions.count()) self.assertEqual(num_deductions, self.eco_account.deductions.count())
self.assertEqual(num_deductions_total, EcoAccountDeduction.objects.count()) self.assertEqual(num_deductions_total, EcoAccountDeduction.objects.count())
# Now restore the deductable surface to a valid size back again but remove the user from the shared list # Now restore the deductable surface to a valid size back again
self.eco_account.deductable_surface = test_surface + 100.00 self.eco_account.deductable_surface = test_surface + 100.00
self.eco_account.share_with_list([])
self.eco_account.save() self.eco_account.save()
# Now perform the (expected) failing request (again) # Remove the recording state
self.client_user.post(new_url, post_data)
# Expect no changes at all, since the account is not shared
self.assertEqual(num_deductions, self.eco_account.deductions.count())
self.assertEqual(num_deductions_total, EcoAccountDeduction.objects.count())
# Restore the sharing but remove the recording state
self.eco_account.share_with_list([self.superuser])
self.eco_account.recorded.delete() self.eco_account.recorded.delete()
self.eco_account.refresh_from_db() self.eco_account.refresh_from_db()
self.eco_account.save() self.eco_account.save()

View File

@ -25,7 +25,7 @@ from intervention.models import Intervention
class EcoAccountAutocomplete(Select2QuerySetView): class EcoAccountAutocomplete(Select2QuerySetView):
""" Autocomplete for ecoAccount entries """ Autocomplete for ecoAccount entries
Only returns entries that are accessible for the requesting user and already are recorded Only returns entries that are already recorded and not deleted
""" """
def get_queryset(self): def get_queryset(self):
@ -34,7 +34,6 @@ class EcoAccountAutocomplete(Select2QuerySetView):
qs = EcoAccount.objects.filter( qs = EcoAccount.objects.filter(
deleted=None, deleted=None,
recorded__isnull=False, recorded__isnull=False,
users__in=[self.request.user],
).order_by( ).order_by(
"identifier" "identifier"
) )