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:
		@@ -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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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."""
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user