Moved the sort_post_txn_records utility and the logic to create the form to TransactionForm in the accounting application.

This commit is contained in:
依瑪貓 2020-08-19 13:38:05 +08:00
parent 8770770b66
commit 6f019d23c0
4 changed files with 65 additions and 61 deletions

View File

@ -24,7 +24,7 @@ from typing import Optional, List, Dict
from django import forms from django import forms
from django.core.validators import RegexValidator from django.core.validators import RegexValidator
from django.db.models import Q, Max from django.db.models import Q, Max, Model
from django.db.models.functions import Length from django.db.models.functions import Length
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
@ -234,6 +234,67 @@ class TransactionForm(forms.Form):
self.txn_type = None self.txn_type = None
self.transaction = None self.transaction = None
@staticmethod
def from_post(post: Dict[str, str], txn_type: str, txn: Model):
TransactionForm._sort_post_txn_records(post)
form = TransactionForm(post)
form.txn_type = txn_type
form.transaction = txn
return form
@staticmethod
def _sort_post_txn_records(post: Dict[str, str]) -> None:
"""Sorts the records in the form by their specified order, so that the
form can be used to populate the data to return to the user.
Args:
post: The POSTed form.
"""
# Collects the available record numbers
record_no = {
"debit": [],
"credit": [],
}
for key in post.keys():
m = re.match(
"^(debit|credit)-([1-9][0-9]*)-(id|ord|account|summary|amount)",
key)
if m is None:
continue
record_type = m.group(1)
no = int(m.group(2))
if no not in record_no[record_type]:
record_no[record_type].append(no)
# Sorts these record numbers by their specified orders
for record_type in record_no.keys():
orders = {}
for no in record_no[record_type]:
try:
orders[no] = int(post[F"{record_type}-{no}-ord"])
except KeyError:
orders[no] = 9999
except ValueError:
orders[no] = 9999
record_no[record_type].sort(key=lambda n: orders[n])
# Constructs the sorted new form
new_post = {}
for record_type in record_no.keys():
for i in range(len(record_no[record_type])):
old_no = record_no[record_type][i]
no = i + 1
new_post[F"{record_type}-{no}-ord"] = str(no)
for attr in ["id", "account", "summary", "amount"]:
if F"{record_type}-{old_no}-{attr}" in post:
new_post[F"{record_type}-{no}-{attr}"] \
= post[F"{record_type}-{old_no}-{attr}"]
# Purges the old form and fills it with the new form
for x in [x for x in post.keys() if re.match(
"^(debit|credit)-([1-9][0-9]*)-(id|ord|account|summary|amount)",
x)]:
del post[x]
for key in new_post.keys():
post[key] = new_post[key]
def clean(self): def clean(self):
"""Validates the form globally. """Validates the form globally.

View File

@ -20,7 +20,7 @@
""" """
from django.test import TestCase from django.test import TestCase
from .utils import sort_post_txn_records from .forms import TransactionForm
class SortTransactionPostTestCase(TestCase): class SortTransactionPostTestCase(TestCase):
@ -51,7 +51,7 @@ class SortTransactionPostTestCase(TestCase):
"credit-7-summary": "", "credit-7-summary": "",
"credit-7-amount": "667", "credit-7-amount": "667",
} }
sort_post_txn_records(post) TransactionForm._sort_post_txn_records(post)
self.assertEqual(post.get("date"), "2020-07-15") self.assertEqual(post.get("date"), "2020-07-15")
self.assertEqual(post.get("notes"), "") self.assertEqual(post.get("notes"), "")
self.assertEqual(post.get("debit-1-ord"), "1") self.assertEqual(post.get("debit-1-ord"), "1")

View File

@ -580,59 +580,6 @@ def fill_txn_from_post(txn_type: str, txn: Transaction,
txn.records = records txn.records = records
def sort_post_txn_records(post: Dict[str, str]) -> None:
"""Sorts the records in the form by their specified order, so that the
form can be used to populate the data to return to the user.
Args:
post: The POSTed form.
"""
# Collects the available record numbers
record_no = {
"debit": [],
"credit": [],
}
for key in post.keys():
m = re.match(
"^(debit|credit)-([1-9][0-9]*)-(id|ord|account|summary|amount)",
key)
if m is None:
continue
record_type = m.group(1)
no = int(m.group(2))
if no not in record_no[record_type]:
record_no[record_type].append(no)
# Sorts these record numbers by their specified orders
for record_type in record_no.keys():
orders = {}
for no in record_no[record_type]:
try:
orders[no] = int(post[F"{record_type}-{no}-ord"])
except KeyError:
orders[no] = 9999
except ValueError:
orders[no] = 9999
record_no[record_type].sort(key=lambda n: orders[n])
# Constructs the sorted new form
new_post = {}
for record_type in record_no.keys():
for i in range(len(record_no[record_type])):
old_no = record_no[record_type][i]
no = i + 1
new_post[F"{record_type}-{no}-ord"] = str(no)
for attr in ["id", "account", "summary", "amount"]:
if F"{record_type}-{old_no}-{attr}" in post:
new_post[F"{record_type}-{no}-{attr}"]\
= post[F"{record_type}-{old_no}-{attr}"]
# Purges the old form and fills it with the new form
for x in [x for x in post.keys() if re.match(
"^(debit|credit)-([1-9][0-9]*)-(id|ord|account|summary|amount)",
x)]:
del post[x]
for key in new_post.keys():
post[key] = new_post[key]
def make_txn_form_from_model(txn_type: str, def make_txn_form_from_model(txn_type: str,
txn: Transaction) -> TransactionForm: txn: Transaction) -> TransactionForm:
"""Converts a transaction data model to a transaction form. """Converts a transaction data model to a transaction form.

View File

@ -823,11 +823,7 @@ class TransactionFormView(FormView):
def make_form_from_post(self, post: Dict[str, str]) -> TransactionForm: def make_form_from_post(self, post: Dict[str, str]) -> TransactionForm:
"""Creates and returns the form from the POST data.""" """Creates and returns the form from the POST data."""
utils.sort_post_txn_records(post) return TransactionForm.from_post(post, self.txn_type, self.object)
form = TransactionForm(post)
form.txn_type = self.txn_type
form.transaction = self.object
return form
def make_form_from_model(self, obj: Transaction) -> TransactionForm: def make_form_from_model(self, obj: Transaction) -> TransactionForm:
"""Creates and returns the form from a data model.""" """Creates and returns the form from a data model."""