Replaced the direct database add with the relationship append in the JournalEntryCollector class, to fix the PostgreSQL error that the new journal entries are added when the transaction is not added yet.

This commit is contained in:
依瑪貓 2023-02-28 00:04:32 +08:00
parent 5613657c8f
commit fff89a9957

View File

@ -284,13 +284,11 @@ class TransactionForm(FlaskForm):
self.__set_date(obj, self.date.data) self.__set_date(obj, self.date.data)
obj.note = self.note.data obj.note = self.note.data
entries: list[JournalEntry] = obj.entries
collector_cls: t.Type[JournalEntryCollector] = self.collector collector_cls: t.Type[JournalEntryCollector] = self.collector
collector: collector_cls = collector_cls(self, obj.id, entries, collector: collector_cls = collector_cls(self, obj)
obj.currencies)
collector.collect() collector.collect()
to_delete: set[int] = {x.id for x in entries to_delete: set[int] = {x.id for x in obj.entries
if x.id not in collector.to_keep} if x.id not in collector.to_keep}
if len(to_delete) > 0: if len(to_delete) > 0:
JournalEntry.query.filter(JournalEntry.id.in_(to_delete)).delete() JournalEntry.query.filter(JournalEntry.id.in_(to_delete)).delete()
@ -373,27 +371,24 @@ T = t.TypeVar("T", bound=TransactionForm)
class JournalEntryCollector(t.Generic[T], ABC): class JournalEntryCollector(t.Generic[T], ABC):
"""The journal entry collector.""" """The journal entry collector."""
def __init__(self, form: T, txn_id: int, entries: list[JournalEntry], def __init__(self, form: T, obj: Transaction):
currencies: list[TransactionCurrency]):
"""Constructs the journal entry collector. """Constructs the journal entry collector.
:param form: The transaction form. :param form: The transaction form.
:param txn_id: The transaction ID. :param obj: The transaction.
:param entries: The existing journal entries.
:param currencies: The currencies in the transaction.
""" """
self.form: T = form self.form: T = form
"""The transaction form.""" """The transaction form."""
self.entries: list[JournalEntry] = entries self.__obj: Transaction = obj
"""The transaction object."""
self.__entries: list[JournalEntry] = list(obj.entries)
"""The existing journal entries.""" """The existing journal entries."""
self.txn_id: int = txn_id
"""The transaction ID."""
self.__entries_by_id: dict[int, JournalEntry] \ self.__entries_by_id: dict[int, JournalEntry] \
= {x.id: x for x in entries} = {x.id: x for x in self.__entries}
"""A dictionary from the entry ID to their entries.""" """A dictionary from the entry ID to their entries."""
self.__no_by_id: dict[int, int] = {x.id: x.no for x in entries} self.__no_by_id: dict[int, int] = {x.id: x.no for x in self.__entries}
"""A dictionary from the entry number to their entries.""" """A dictionary from the entry number to their entries."""
self.__currencies: list[TransactionCurrency] = currencies self.__currencies: list[TransactionCurrency] = obj.currencies
"""The currencies in the transaction.""" """The currencies in the transaction."""
self._debit_no: int = 1 self._debit_no: int = 1
"""The number index for the debit entries.""" """The number index for the debit entries."""
@ -420,7 +415,6 @@ class JournalEntryCollector(t.Generic[T], ABC):
""" """
entry: JournalEntry | None = self.__entries_by_id.get(form.eid.data) entry: JournalEntry | None = self.__entries_by_id.get(form.eid.data)
if entry is not None: if entry is not None:
self.to_keep.add(entry.id)
entry.currency_code = currency_code entry.currency_code = currency_code
form.populate_obj(entry) form.populate_obj(entry)
entry.no = no entry.no = no
@ -428,12 +422,12 @@ class JournalEntryCollector(t.Generic[T], ABC):
self.form.is_modified = True self.form.is_modified = True
else: else:
entry = JournalEntry() entry = JournalEntry()
entry.transaction_id = self.txn_id
entry.currency_code = currency_code entry.currency_code = currency_code
form.populate_obj(entry) form.populate_obj(entry)
entry.no = no entry.no = no
db.session.add(entry) self.__obj.entries.append(entry)
self.form.is_modified = True self.form.is_modified = True
self.to_keep.add(entry.id)
def _make_cash_entry(self, forms: list[JournalEntryForm], is_debit: bool, def _make_cash_entry(self, forms: list[JournalEntryForm], is_debit: bool,
currency_code: str, no: int) -> None: currency_code: str, no: int) -> None:
@ -447,14 +441,13 @@ class JournalEntryCollector(t.Generic[T], ABC):
:param no: The number of the entry. :param no: The number of the entry.
:return: None. :return: None.
""" """
candidates: list[JournalEntry] = [x for x in self.entries candidates: list[JournalEntry] = [x for x in self.__entries
if x.is_debit == is_debit if x.is_debit == is_debit
and x.currency_code == currency_code] and x.currency_code == currency_code]
entry: JournalEntry entry: JournalEntry
if len(candidates) > 0: if len(candidates) > 0:
candidates.sort(key=lambda x: x.no) candidates.sort(key=lambda x: x.no)
entry = candidates[0] entry = candidates[0]
self.to_keep.add(entry.id)
entry.account_id = Account.cash().id entry.account_id = Account.cash().id
entry.summary = None entry.summary = None
entry.amount = sum([x.amount.data for x in forms]) entry.amount = sum([x.amount.data for x in forms])
@ -464,15 +457,15 @@ class JournalEntryCollector(t.Generic[T], ABC):
else: else:
entry = JournalEntry() entry = JournalEntry()
entry.id = new_id(JournalEntry) entry.id = new_id(JournalEntry)
entry.transaction_id = self.txn_id
entry.is_debit = is_debit entry.is_debit = is_debit
entry.currency_code = currency_code entry.currency_code = currency_code
entry.account_id = Account.cash().id entry.account_id = Account.cash().id
entry.summary = None entry.summary = None
entry.amount = sum([x.amount.data for x in forms]) entry.amount = sum([x.amount.data for x in forms])
entry.no = no entry.no = no
db.session.add(entry) self.__obj.entries.append(entry)
self.form.is_modified = True self.form.is_modified = True
self.to_keep.add(entry.id)
def _sort_entry_forms(self, forms: list[JournalEntryForm]) -> None: def _sort_entry_forms(self, forms: list[JournalEntryForm]) -> None:
"""Sorts the journal entry forms. """Sorts the journal entry forms.