diff --git a/backend/accounts/viewsets.py b/backend/accounts/viewsets.py index ca9991af..60b75448 100644 --- a/backend/accounts/viewsets.py +++ b/backend/accounts/viewsets.py @@ -2,6 +2,7 @@ from rest_framework.pagination import PageNumberPagination from rest_framework import viewsets, status, filters from django.db.models import Q +from django.core.exceptions import ValidationError from rest_framework.response import Response from django.contrib.auth.models import User @@ -270,7 +271,7 @@ def create(self, request): def update(self, request, pk): return update_entry(self, request, pk) - + class AccountLedgerViewSet(viewsets.ModelViewSet): serializer_class = AccountLedgerSerializer queryset = AccountLedger.objects.all() @@ -325,6 +326,12 @@ def create(self, request): data_set['created_by'] = self.request.user.id data_set['modified_by'] = self.request.user.id + sewer_equal = data_set['sewer_credits'] == data_set['sewer_cap'] + data_set['sewer_trans'] + non_sewer_equal = data_set['non_sewer_credits'] == data_set['roads'] + data_set['parks'] + data_set['open_space'] + data_set['storm'] + + if not (sewer_equal and non_sewer_equal): + raise ValidationError('Ensure sums for both sewer and non-sewer equal the sum of each of their parts.') + if 'lot' in self.request.data: serializer = AccountLedgerSerializer(data=data_set) if serializer.is_valid(raise_exception=True): diff --git a/frontend/js/components/AccountLedgerForm.js b/frontend/js/components/AccountLedgerForm.js index af0eb496..2668123c 100644 --- a/frontend/js/components/AccountLedgerForm.js +++ b/frontend/js/components/AccountLedgerForm.js @@ -105,6 +105,9 @@ class AccountLedgerForm extends React.Component { ); })(agreements.agreements)); + const sewerEqual = activeForm.sewer_credits == activeForm.sewer_cap + activeForm.sewer_trans; + const nonSewerEqual = activeForm.non_sewer_credits == activeForm.parks + activeForm.storm + activeForm.roads + activeForm.open_space; + const submitEnabled = !!accounts.accountFrom && !!accounts.accountFrom.id && !!accounts.accountTo && !!accounts.accountTo.id && @@ -118,7 +121,9 @@ class AccountLedgerForm extends React.Component { activeForm.open_space && activeForm.sewer_cap && activeForm.sewer_trans && - activeForm.entry_date; + activeForm.entry_date && + sewerEqual && + nonSewerEqual; const currentPlat = !!plats && !!plats.currentPlat && plats.currentPlat; const currentAccountBalance = !!accounts.accountFrom && accounts.accountFrom.current_account_balance; @@ -397,11 +402,11 @@ class AccountLedgerForm extends React.Component {
- + onSubmit(activeForm.plat_lot)} > {currentUser.is_superuser || (currentUser.profile && currentUser.profile.is_supervisor) ?
Submit / Approve
:
Submit
} - {!submitEnabled ? ( -
-
- * All required fields must be filled. -
- ) : null - }
+ /> +
+
+
+
+ * All required fields must be filled. +
+ * Ensure Sewer Capacity and Sewer Transmission equal Sewer Credits. +
+ * Ensure Roads, Parks, Open Spaces, and Storm Water equal Non-Sewer Credits.
@@ -708,6 +715,9 @@ function mapDispatchToProps(dispatch, params) { if (selectedAccountLedger) { dispatch(putAccountLedger(selectedAccountLedger)) .then((data) => { + if (!!data.error) { + dispatch(flashMessageSet(`Error: ${data.error}`, 'danger')); + } if (data.response) { hashHistory.push(`credit-transfer/summary/${selectedAccountLedger}`); } @@ -715,6 +725,9 @@ function mapDispatchToProps(dispatch, params) { } else { dispatch(postAccountLedger()) .then((data_post) => { + if (!!data_post.error) { + dispatch(flashMessageSet(`Error: ${data_post.message}`, 'danger')); + } if (data_post.response && data_post.response.id) { if (event === 'plat') { hashHistory.push('credit-transfer'); diff --git a/frontend/js/components/ReportsAdditional.js b/frontend/js/components/ReportsAdditional.js index f336edf4..226c4767 100644 --- a/frontend/js/components/ReportsAdditional.js +++ b/frontend/js/components/ReportsAdditional.js @@ -62,7 +62,7 @@ class ReportsAdditional extends React.Component { >Transaction CSV
-
+