#86 Edit deductions
* adds support for editing deductions * adds tests * improves major base test logic
This commit is contained in:
@@ -60,9 +60,12 @@
|
||||
</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>
|
||||
<td class="align-middle float-right">
|
||||
{% if is_default_member and has_access %}
|
||||
<button data-form-url="{% url 'compensation:acc:remove-deduction' deduction.account.id deduction.id %}" class="btn btn-default btn-modal float-right" title="{% trans 'Remove 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' %}
|
||||
</button>
|
||||
<button data-form-url="{% url 'compensation:acc:remove-deduction' deduction.account.id deduction.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove Deduction' %}">
|
||||
{% fa5_icon 'trash' %}
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
@@ -21,29 +21,32 @@ class CompensationViewTestCase(BaseViewTestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls) -> None:
|
||||
super().setUpTestData()
|
||||
state = cls.create_dummy_states()
|
||||
cls.compensation.before_states.set([state])
|
||||
cls.compensation.after_states.set([state])
|
||||
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
state = self.create_dummy_states()
|
||||
self.compensation.before_states.set([state])
|
||||
self.compensation.after_states.set([state])
|
||||
|
||||
action = cls.create_dummy_action()
|
||||
cls.compensation.actions.set([action])
|
||||
action = self.create_dummy_action()
|
||||
self.compensation.actions.set([action])
|
||||
|
||||
# Prepare urls
|
||||
cls.index_url = reverse("compensation:index", args=())
|
||||
cls.new_url = reverse("compensation:new", args=(cls.intervention.id,))
|
||||
cls.new_id_url = reverse("compensation:new-id", args=())
|
||||
cls.detail_url = reverse("compensation:detail", args=(cls.compensation.id,))
|
||||
cls.log_url = reverse("compensation:log", args=(cls.compensation.id,))
|
||||
cls.edit_url = reverse("compensation:edit", args=(cls.compensation.id,))
|
||||
cls.remove_url = reverse("compensation:remove", args=(cls.compensation.id,))
|
||||
cls.report_url = reverse("compensation:report", args=(cls.compensation.id,))
|
||||
cls.state_new_url = reverse("compensation:new-state", args=(cls.compensation.id,))
|
||||
cls.action_new_url = reverse("compensation:new-action", args=(cls.compensation.id,))
|
||||
cls.deadline_new_url = reverse("compensation:new-deadline", args=(cls.compensation.id,))
|
||||
cls.new_doc_url = reverse("compensation:new-doc", args=(cls.compensation.id,))
|
||||
self.index_url = reverse("compensation:index", args=())
|
||||
self.new_url = reverse("compensation:new", args=(self.intervention.id,))
|
||||
self.new_id_url = reverse("compensation:new-id", args=())
|
||||
self.detail_url = reverse("compensation:detail", args=(self.compensation.id,))
|
||||
self.log_url = reverse("compensation:log", args=(self.compensation.id,))
|
||||
self.edit_url = reverse("compensation:edit", args=(self.compensation.id,))
|
||||
self.remove_url = reverse("compensation:remove", args=(self.compensation.id,))
|
||||
self.report_url = reverse("compensation:report", args=(self.compensation.id,))
|
||||
self.state_new_url = reverse("compensation:new-state", args=(self.compensation.id,))
|
||||
self.action_new_url = reverse("compensation:new-action", args=(self.compensation.id,))
|
||||
self.deadline_new_url = reverse("compensation:new-deadline", args=(self.compensation.id,))
|
||||
self.new_doc_url = reverse("compensation:new-doc", args=(self.compensation.id,))
|
||||
|
||||
cls.state_remove_url = reverse("compensation:state-remove", args=(cls.compensation.id, cls.comp_state.id,))
|
||||
cls.action_remove_url = reverse("compensation:action-remove", args=(cls.compensation.id, cls.comp_action.id,))
|
||||
self.state_remove_url = reverse("compensation:state-remove", args=(self.compensation.id, self.comp_state.id,))
|
||||
self.action_remove_url = reverse("compensation:action-remove", args=(self.compensation.id, self.comp_action.id,))
|
||||
|
||||
def test_anonymous_user(self):
|
||||
""" Check correct status code for all requests
|
||||
|
||||
@@ -21,17 +21,18 @@ class CompensationWorkflowTestCase(BaseWorkflowTestCase):
|
||||
def setUpTestData(cls):
|
||||
super().setUpTestData()
|
||||
|
||||
# Give the user shared access to the dummy intervention -> inherits the access to the compensation
|
||||
cls.intervention.share_with(cls.superuser)
|
||||
|
||||
# Make sure the intervention itself would be fine with valid data
|
||||
cls.intervention = cls.fill_out_intervention(cls.intervention)
|
||||
|
||||
# Make sure the compensation is linked to the intervention
|
||||
cls.intervention.compensations.set([cls.compensation])
|
||||
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
# Give the user shared access to the dummy intervention -> inherits the access to the compensation
|
||||
self.intervention.share_with(self.superuser)
|
||||
|
||||
# Make sure the intervention itself would be fine with valid data
|
||||
self.intervention = self.fill_out_intervention(self.intervention)
|
||||
|
||||
# Make sure the compensation is linked to the intervention
|
||||
self.intervention.compensations.set([self.compensation])
|
||||
|
||||
# Delete all existing compensations, which might be created by tests
|
||||
Compensation.objects.all().delete()
|
||||
|
||||
|
||||
@@ -25,28 +25,31 @@ class EcoAccountViewTestCase(CompensationViewTestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls) -> None:
|
||||
super().setUpTestData()
|
||||
state = cls.create_dummy_states()
|
||||
cls.eco_account.before_states.set([state])
|
||||
cls.eco_account.after_states.set([state])
|
||||
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
state = self.create_dummy_states()
|
||||
self.eco_account.before_states.set([state])
|
||||
self.eco_account.after_states.set([state])
|
||||
|
||||
action = cls.create_dummy_action()
|
||||
cls.eco_account.actions.set([action])
|
||||
action = self.create_dummy_action()
|
||||
self.eco_account.actions.set([action])
|
||||
|
||||
# Prepare urls
|
||||
cls.index_url = reverse("compensation:acc:index", args=())
|
||||
cls.new_url = reverse("compensation:acc:new", args=())
|
||||
cls.new_id_url = reverse("compensation:acc:new-id", args=())
|
||||
cls.detail_url = reverse("compensation:acc:detail", args=(cls.eco_account.id,))
|
||||
cls.log_url = reverse("compensation:acc:log", args=(cls.eco_account.id,))
|
||||
cls.edit_url = reverse("compensation:acc:edit", args=(cls.eco_account.id,))
|
||||
cls.remove_url = reverse("compensation:acc:remove", args=(cls.eco_account.id,))
|
||||
cls.report_url = reverse("compensation:acc:report", args=(cls.eco_account.id,))
|
||||
cls.state_new_url = reverse("compensation:acc:new-state", args=(cls.eco_account.id,))
|
||||
cls.action_new_url = reverse("compensation:acc:new-action", args=(cls.eco_account.id,))
|
||||
cls.deadline_new_url = reverse("compensation:acc:new-deadline", args=(cls.eco_account.id,))
|
||||
cls.new_doc_url = reverse("compensation:acc:new-doc", args=(cls.eco_account.id,))
|
||||
cls.state_remove_url = reverse("compensation:acc:state-remove", args=(cls.eco_account.id, cls.comp_state.id,))
|
||||
cls.action_remove_url = reverse("compensation:acc:action-remove", args=(cls.eco_account.id, cls.comp_action.id,))
|
||||
self.index_url = reverse("compensation:acc:index", args=())
|
||||
self.new_url = reverse("compensation:acc:new", args=())
|
||||
self.new_id_url = reverse("compensation:acc:new-id", args=())
|
||||
self.detail_url = reverse("compensation:acc:detail", args=(self.eco_account.id,))
|
||||
self.log_url = reverse("compensation:acc:log", args=(self.eco_account.id,))
|
||||
self.edit_url = reverse("compensation:acc:edit", args=(self.eco_account.id,))
|
||||
self.remove_url = reverse("compensation:acc:remove", args=(self.eco_account.id,))
|
||||
self.report_url = reverse("compensation:acc:report", args=(self.eco_account.id,))
|
||||
self.state_new_url = reverse("compensation:acc:new-state", args=(self.eco_account.id,))
|
||||
self.action_new_url = reverse("compensation:acc:new-action", args=(self.eco_account.id,))
|
||||
self.deadline_new_url = reverse("compensation:acc:new-deadline", args=(self.eco_account.id,))
|
||||
self.new_doc_url = reverse("compensation:acc:new-doc", args=(self.eco_account.id,))
|
||||
self.state_remove_url = reverse("compensation:acc:state-remove", args=(self.eco_account.id, self.comp_state.id,))
|
||||
self.action_remove_url = reverse("compensation:acc:action-remove", args=(self.eco_account.id, self.comp_action.id,))
|
||||
|
||||
def test_logged_in_no_groups_shared(self):
|
||||
""" Check correct status code for all requests
|
||||
|
||||
@@ -11,7 +11,7 @@ from django.contrib.gis.geos import MultiPolygon
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.urls import reverse
|
||||
|
||||
from compensation.models import EcoAccount
|
||||
from compensation.models import EcoAccount, EcoAccountDeduction
|
||||
from konova.settings import ETS_GROUP, DEFAULT_GROUP
|
||||
from konova.tests.test_views import BaseWorkflowTestCase
|
||||
from user.models import UserAction
|
||||
@@ -168,7 +168,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
|
||||
self.assertIn(recorded, self.eco_account.log.all())
|
||||
self.assertEqual(pre_record_log_count + 1, self.eco_account.log.count())
|
||||
|
||||
def test_deductability(self):
|
||||
def test_new_deduction(self):
|
||||
"""
|
||||
This tests the deductability of an eco account.
|
||||
|
||||
@@ -187,7 +187,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
|
||||
test_surface = 10.00
|
||||
post_data = {
|
||||
"surface": test_surface,
|
||||
"account": self.id,
|
||||
"account": self.eco_account.id,
|
||||
"intervention": self.intervention.id,
|
||||
}
|
||||
# Perform request --> expect to fail
|
||||
@@ -228,4 +228,75 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
|
||||
self.assertEqual(pre_deduction_int_log_count + 1, self.intervention.log.count())
|
||||
self.assertTrue(self.intervention.log.first().action == UserAction.EDITED)
|
||||
|
||||
def test_edit_deduction(self):
|
||||
test_surface = self.eco_account.get_available_rest()[0]
|
||||
self.eco_account.set_recorded(self.superuser)
|
||||
self.eco_account.refresh_from_db()
|
||||
|
||||
deduction = EcoAccountDeduction.objects.create(
|
||||
intervention=self.intervention,
|
||||
account=self.eco_account,
|
||||
surface=0
|
||||
)
|
||||
self.assertEqual(1, self.intervention.deductions.count())
|
||||
self.assertEqual(1, self.eco_account.deductions.count())
|
||||
|
||||
# Prepare url and form data to be posted
|
||||
new_url = reverse("compensation:acc:edit-deduction", args=(self.eco_account.id, deduction.id))
|
||||
post_data = {
|
||||
"intervention": deduction.intervention.id,
|
||||
"account": deduction.account.id,
|
||||
"surface": test_surface,
|
||||
}
|
||||
pre_edit_intervention_log_count = self.intervention.log.count()
|
||||
pre_edit_account_log_count = self.eco_account.log.count()
|
||||
num_deductions_intervention = self.intervention.deductions.count()
|
||||
num_deductions_account = self.eco_account.deductions.count()
|
||||
|
||||
self.client_user.post(new_url, post_data)
|
||||
|
||||
self.intervention.refresh_from_db()
|
||||
self.eco_account.refresh_from_db()
|
||||
deduction.refresh_from_db()
|
||||
|
||||
self.assertEqual(num_deductions_intervention, self.intervention.deductions.count())
|
||||
self.assertEqual(num_deductions_account, self.eco_account.deductions.count())
|
||||
self.assertEqual(deduction.surface, test_surface)
|
||||
|
||||
# Expect logs to be set
|
||||
self.assertEqual(pre_edit_intervention_log_count + 1, self.intervention.log.count())
|
||||
self.assertEqual(pre_edit_account_log_count + 1, self.eco_account.log.count())
|
||||
self.assertEqual(self.intervention.log.first().action, UserAction.EDITED)
|
||||
self.assertEqual(self.eco_account.log.first().action, UserAction.EDITED)
|
||||
|
||||
def test_remove_deduction(self):
|
||||
intervention = self.deduction.intervention
|
||||
account = self.deduction.account
|
||||
|
||||
# Prepare url and form data to be posted
|
||||
new_url = reverse("compensation:acc:remove-deduction", args=(account.id, self.deduction.id))
|
||||
post_data = {
|
||||
"confirm": True,
|
||||
}
|
||||
|
||||
intervention.share_with(self.superuser)
|
||||
account.share_with(self.superuser)
|
||||
|
||||
pre_edit_intervention_log_count = intervention.log.count()
|
||||
pre_edit_account_log_count = account.log.count()
|
||||
num_deductions_intervention = intervention.deductions.count()
|
||||
num_deductions_account = account.deductions.count()
|
||||
|
||||
self.client_user.post(new_url, post_data)
|
||||
|
||||
intervention.refresh_from_db()
|
||||
account.refresh_from_db()
|
||||
|
||||
self.assertEqual(num_deductions_intervention - 1, intervention.deductions.count())
|
||||
self.assertEqual(num_deductions_account - 1, account.deductions.count())
|
||||
|
||||
# Expect logs to be set
|
||||
self.assertEqual(pre_edit_intervention_log_count + 1, intervention.log.count())
|
||||
self.assertEqual(pre_edit_account_log_count + 1, account.log.count())
|
||||
self.assertEqual(intervention.log.first().action, UserAction.EDITED)
|
||||
self.assertEqual(account.log.first().action, UserAction.EDITED)
|
||||
|
||||
@@ -19,16 +19,18 @@ class PaymentViewTestCase(BaseViewTestCase):
|
||||
def setUpTestData(cls) -> None:
|
||||
super().setUpTestData()
|
||||
|
||||
cls.payment = Payment.objects.get_or_create(
|
||||
intervention=cls.intervention,
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
self.payment = Payment.objects.get_or_create(
|
||||
intervention=self.intervention,
|
||||
amount=1,
|
||||
due_on="2020-01-01",
|
||||
comment="Testcomment"
|
||||
)[0]
|
||||
|
||||
cls.new_url = reverse("compensation:pay:new", args=(cls.intervention.id,))
|
||||
cls.edit_url = reverse("compensation:pay:edit", args=(cls.intervention.id, cls.payment.id))
|
||||
cls.remove_url = reverse("compensation:pay:remove", args=(cls.intervention.id, cls.payment.id))
|
||||
self.new_url = reverse("compensation:pay:new", args=(self.intervention.id,))
|
||||
self.edit_url = reverse("compensation:pay:edit", args=(self.intervention.id, self.payment.id))
|
||||
self.remove_url = reverse("compensation:pay:remove", args=(self.intervention.id, self.payment.id))
|
||||
|
||||
def test_anonymous_user(self):
|
||||
""" Check correct status code for all requests
|
||||
|
||||
@@ -18,11 +18,13 @@ class PaymentWorkflowTestCase(BaseWorkflowTestCase):
|
||||
def setUpTestData(cls):
|
||||
super().setUpTestData()
|
||||
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
# Give the user shared access to the dummy intervention
|
||||
cls.intervention.share_with(cls.superuser)
|
||||
self.intervention.share_with(self.superuser)
|
||||
|
||||
cls.payment = Payment.objects.get_or_create(
|
||||
intervention=cls.intervention,
|
||||
self.payment = Payment.objects.get_or_create(
|
||||
intervention=self.intervention,
|
||||
amount=1,
|
||||
due_on="2020-01-01",
|
||||
comment="Testcomment"
|
||||
|
||||
@@ -34,7 +34,8 @@ urlpatterns = [
|
||||
path('document/<doc_id>/remove/', remove_document_view, name='remove-doc'),
|
||||
|
||||
# Eco-account deductions
|
||||
path('<id>/remove/<deduction_id>', deduction_remove_view, name='remove-deduction'),
|
||||
path('<id>/deduction/<deduction_id>/remove', deduction_remove_view, name='remove-deduction'),
|
||||
path('<id>/deduction/<deduction_id>/edit', deduction_edit_view, name='edit-deduction'),
|
||||
path('<id>/deduct/new', new_deduction_view, name='new-deduction'),
|
||||
|
||||
]
|
||||
@@ -19,7 +19,8 @@ from compensation.forms.modalForms import NewStateModalForm, NewActionModalForm,
|
||||
NewEcoAccountDocumentForm, RemoveCompensationActionModalForm, RemoveCompensationStateModalForm
|
||||
from compensation.models import EcoAccount, EcoAccountDocument, CompensationState, CompensationAction
|
||||
from compensation.tables import EcoAccountTable
|
||||
from intervention.forms.modalForms import NewDeductionModalForm, ShareModalForm, RemoveEcoAccountDeductionModalForm
|
||||
from intervention.forms.modalForms import NewDeductionModalForm, ShareModalForm, RemoveEcoAccountDeductionModalForm, \
|
||||
EditEcoAccountDeductionModalForm
|
||||
from konova.contexts import BaseContext
|
||||
from konova.decorators import any_group_check, default_group_required, conservation_office_group_required, \
|
||||
shared_access_required
|
||||
@@ -31,7 +32,8 @@ from konova.utils.documents import get_document, remove_document
|
||||
from konova.utils.generators import generate_qr_code
|
||||
from konova.utils.message_templates import IDENTIFIER_REPLACED, FORM_INVALID, DATA_UNSHARED, DATA_UNSHARED_EXPLANATION, \
|
||||
CANCEL_ACC_RECORDED_OR_DEDUCTED, DEDUCTION_REMOVED, DEDUCTION_ADDED, DOCUMENT_ADDED, COMPENSATION_STATE_REMOVED, \
|
||||
COMPENSATION_STATE_ADDED, COMPENSATION_ACTION_REMOVED, COMPENSATION_ACTION_ADDED, DEADLINE_ADDED, DEADLINE_REMOVED
|
||||
COMPENSATION_STATE_ADDED, COMPENSATION_ACTION_REMOVED, COMPENSATION_ACTION_ADDED, DEADLINE_ADDED, DEADLINE_REMOVED, \
|
||||
DEDUCTION_EDITED
|
||||
from konova.utils.user_checks import in_group
|
||||
|
||||
|
||||
@@ -294,6 +296,34 @@ def deduction_remove_view(request: HttpRequest, id: str, deduction_id: str):
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@default_group_required
|
||||
@shared_access_required(EcoAccount, "id")
|
||||
def deduction_edit_view(request: HttpRequest, id: str, deduction_id: str):
|
||||
""" Renders a modal view for editing deductions
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The incoming request
|
||||
id (str): The eco account's id
|
||||
deduction_id (str): The deduction's id
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
acc = get_object_or_404(EcoAccount, id=id)
|
||||
try:
|
||||
eco_deduction = acc.deductions.get(id=deduction_id)
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404("Unknown deduction")
|
||||
|
||||
form = EditEcoAccountDeductionModalForm(request.POST or None, instance=acc, deduction=eco_deduction, request=request)
|
||||
return form.process_request(
|
||||
request=request,
|
||||
msg_success=DEDUCTION_EDITED,
|
||||
redirect_url=reverse("compensation:acc:detail", args=(id,)) + "#related_data"
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@default_group_required
|
||||
@shared_access_required(EcoAccount, "id")
|
||||
|
||||
Reference in New Issue
Block a user