Renamed the "eid" field to "id" in the LineItemForm form, since the problem is found. It was the "id" property of the enclosing FormField. If we extract the form from FormField, we can still access the "id" field.

This commit is contained in:
依瑪貓 2023-03-20 23:06:57 +08:00
parent d4fe91ec4a
commit 079dc1ab6d
8 changed files with 30 additions and 39 deletions

View File

@ -89,8 +89,8 @@ class KeepCurrencyWhenHavingOffset:
== offset.c.original_line_item_id), == offset.c.original_line_item_id),
isouter=True)\ isouter=True)\
.filter(JournalEntryLineItem.id .filter(JournalEntryLineItem.id
.in_({x.eid.data for x in form.line_items .in_({x.id.data for x in form.line_items
if x.eid.data is not None}))\ if x.id.data is not None}))\
.group_by(JournalEntryLineItem.id, .group_by(JournalEntryLineItem.id,
JournalEntryLineItem.currency_code)\ JournalEntryLineItem.currency_code)\
.having(sa.func.count(offset.c.id) > 0).all() .having(sa.func.count(offset.c.id) > 0).all()
@ -160,8 +160,8 @@ class CurrencyForm(FlaskForm):
if x.original_line_item_id.data is not None} if x.original_line_item_id.data is not None}
if len(original_line_item_id) > 0: if len(original_line_item_id) > 0:
return True return True
line_item_id: set[int] = {x.eid.data for x in line_item_forms line_item_id: set[int] = {x.id.data for x in line_item_forms
if x.eid.data is not None} if x.id.data is not None}
select: sa.Select = sa.select(sa.func.count(JournalEntryLineItem.id))\ select: sa.Select = sa.select(sa.func.count(JournalEntryLineItem.id))\
.filter(JournalEntryLineItem.original_line_item_id .filter(JournalEntryLineItem.original_line_item_id
.in_(line_item_id)) .in_(line_item_id))

View File

@ -98,7 +98,7 @@ class CannotDeleteOriginalLineItemsWithOffset:
existing_matched_original_line_item_id: set[int] \ existing_matched_original_line_item_id: set[int] \
= {x.id for x in form.obj.line_items if len(x.offsets) > 0} = {x.id for x in form.obj.line_items if len(x.offsets) > 0}
line_item_id_in_form: set[int] \ line_item_id_in_form: set[int] \
= {x.eid.data for x in form.line_items if x.eid.data is not None} = {x.id.data for x in form.line_items if x.id.data is not None}
for line_item_id in existing_matched_original_line_item_id: for line_item_id in existing_matched_original_line_item_id:
if line_item_id not in line_item_id_in_form: if line_item_id not in line_item_id_in_form:
raise ValidationError(lazy_gettext( raise ValidationError(lazy_gettext(
@ -273,8 +273,8 @@ class JournalEntryForm(FlaskForm):
if self.__original_line_item_options is None: if self.__original_line_item_options is None:
self.__original_line_item_options \ self.__original_line_item_options \
= get_selectable_original_line_items( = get_selectable_original_line_items(
{x.eid.data for x in self.line_items {x.id.data for x in self.line_items
if x.eid.data is not None}, if x.id.data is not None},
self._is_need_payable, self._is_need_receivable) self._is_need_payable, self._is_need_receivable)
return self.__original_line_item_options return self.__original_line_item_options
@ -300,8 +300,8 @@ class JournalEntryForm(FlaskForm):
:return: The maximum available date. :return: The maximum available date.
""" """
line_item_id: set[int] = {x.eid.data for x in self.line_items line_item_id: set[int] = {x.id.data for x in self.line_items
if x.eid.data is not None} if x.id.data is not None}
select: sa.Select = sa.select(sa.func.min(JournalEntry.date))\ select: sa.Select = sa.select(sa.func.min(JournalEntry.date))\
.join(JournalEntryLineItem)\ .join(JournalEntryLineItem)\
.filter(JournalEntryLineItem.original_line_item_id .filter(JournalEntryLineItem.original_line_item_id
@ -360,7 +360,7 @@ class LineItemCollector(t.Generic[T], ABC):
:return: None. :return: None.
""" """
line_item: JournalEntryLineItem | None \ line_item: JournalEntryLineItem | None \
= self.__line_items_by_id.get(form.eid.data) = self.__line_items_by_id.get(form.id.data)
if line_item is not None: if line_item is not None:
line_item.currency_code = currency_code line_item.currency_code = currency_code
form.populate_obj(line_item) form.populate_obj(line_item)
@ -427,8 +427,8 @@ class LineItemCollector(t.Generic[T], ABC):
recv_no: set[int] = {x.no.data for x in forms if x.no.data is not None} recv_no: set[int] = {x.no.data for x in forms if x.no.data is not None}
missing_recv_no: int = 100 if len(recv_no) == 0 else max(recv_no) + 100 missing_recv_no: int = 100 if len(recv_no) == 0 else max(recv_no) + 100
forms.sort(key=lambda x: (x.no.data or missing_recv_no, forms.sort(key=lambda x: (x.no.data or missing_recv_no,
missing_no if x.eid.data is None else missing_no if x.id.data is None else
self.__no_by_id.get(x.eid.data, missing_no), self.__no_by_id.get(x.id.data, missing_no),
ord_by_form.get(x))) ord_by_form.get(x)))
def _sort_currency_forms(self, forms: list[CurrencyForm]) -> None: def _sort_currency_forms(self, forms: list[CurrencyForm]) -> None:

View File

@ -167,11 +167,11 @@ class KeepAccountWhenHavingOffset:
def __call__(self, form: FlaskForm, field: StringField) -> None: def __call__(self, form: FlaskForm, field: StringField) -> None:
assert isinstance(form, LineItemForm) assert isinstance(form, LineItemForm)
if field.data is None or form.eid.data is None: if field.data is None or form.id.data is None:
return return
line_item: JournalEntryLineItem | None = db.session\ line_item: JournalEntryLineItem | None = db.session\
.query(JournalEntryLineItem)\ .query(JournalEntryLineItem)\
.filter(JournalEntryLineItem.id == form.eid.data)\ .filter(JournalEntryLineItem.id == form.id.data)\
.options(selectinload(JournalEntryLineItem.offsets)).first() .options(selectinload(JournalEntryLineItem.offsets)).first()
if line_item is None or len(line_item.offsets) == 0: if line_item is None or len(line_item.offsets) == 0:
return return
@ -269,7 +269,7 @@ class NotLessThanOffsetTotal:
def __call__(self, form: FlaskForm, field: DecimalField) -> None: def __call__(self, form: FlaskForm, field: DecimalField) -> None:
assert isinstance(form, LineItemForm) assert isinstance(form, LineItemForm)
if field.data is None or form.eid.data is None: if field.data is None or form.id.data is None:
return return
is_debit: bool = isinstance(form, DebitLineItemForm) is_debit: bool = isinstance(form, DebitLineItemForm)
select_offset_total: sa.Select = sa.select(sa.func.sum(sa.case( select_offset_total: sa.Select = sa.select(sa.func.sum(sa.case(
@ -277,7 +277,7 @@ class NotLessThanOffsetTotal:
JournalEntryLineItem.amount), JournalEntryLineItem.amount),
else_=-JournalEntryLineItem.amount)))\ else_=-JournalEntryLineItem.amount)))\
.filter(be(JournalEntryLineItem.original_line_item_id .filter(be(JournalEntryLineItem.original_line_item_id
== form.eid.data)) == form.id.data))
offset_total: Decimal | None = db.session.scalar(select_offset_total) offset_total: Decimal | None = db.session.scalar(select_offset_total)
if offset_total is not None and field.data < offset_total: if offset_total is not None and field.data < offset_total:
raise ValidationError(lazy_gettext( raise ValidationError(lazy_gettext(
@ -287,7 +287,7 @@ class NotLessThanOffsetTotal:
class LineItemForm(FlaskForm): class LineItemForm(FlaskForm):
"""The base form to create or edit a line item.""" """The base form to create or edit a line item."""
eid = IntegerField() id = IntegerField()
"""The existing line item ID.""" """The existing line item ID."""
no = IntegerField() no = IntegerField()
"""The order in the currency.""" """The order in the currency."""
@ -384,11 +384,11 @@ class LineItemForm(FlaskForm):
""" """
if not hasattr(self, "__offsets"): if not hasattr(self, "__offsets"):
def get_offsets() -> list[JournalEntryLineItem]: def get_offsets() -> list[JournalEntryLineItem]:
if not self.is_need_offset or self.eid.data is None: if not self.is_need_offset or self.id.data is None:
return [] return []
return JournalEntryLineItem.query\ return JournalEntryLineItem.query\
.filter(JournalEntryLineItem.original_line_item_id .filter(JournalEntryLineItem.original_line_item_id
== self.eid.data)\ == self.id.data)\
.options(selectinload(JournalEntryLineItem.journal_entry), .options(selectinload(JournalEntryLineItem.journal_entry),
selectinload(JournalEntryLineItem.account), selectinload(JournalEntryLineItem.account),
selectinload(JournalEntryLineItem.offsets) selectinload(JournalEntryLineItem.offsets)
@ -405,7 +405,7 @@ class LineItemForm(FlaskForm):
""" """
if not hasattr(self, "__offset_total"): if not hasattr(self, "__offset_total"):
def get_offset_total(): def get_offset_total():
if not self.is_need_offset or self.eid.data is None: if not self.is_need_offset or self.id.data is None:
return None return None
is_debit: bool = isinstance(self, DebitLineItemForm) is_debit: bool = isinstance(self, DebitLineItemForm)
return sum([x.amount if x.is_debit != is_debit else -x.amount return sum([x.amount if x.is_debit != is_debit else -x.amount
@ -419,7 +419,7 @@ class LineItemForm(FlaskForm):
:return: The net balance. :return: The net balance.
""" """
if not self.is_need_offset or self.eid.data is None \ if not self.is_need_offset or self.id.data is None \
or self.amount.data is None: or self.amount.data is None:
return None return None
return self.amount.data - self.offset_total return self.amount.data - self.offset_total
@ -439,7 +439,7 @@ class LineItemForm(FlaskForm):
class DebitLineItemForm(LineItemForm): class DebitLineItemForm(LineItemForm):
"""The form to create or edit a debit line item.""" """The form to create or edit a debit line item."""
eid = IntegerField() id = IntegerField()
"""The existing line item ID.""" """The existing line item ID."""
no = IntegerField() no = IntegerField()
"""The order in the currency.""" """The order in the currency."""
@ -489,7 +489,7 @@ class DebitLineItemForm(LineItemForm):
class CreditLineItemForm(LineItemForm): class CreditLineItemForm(LineItemForm):
"""The form to create or edit a credit line item.""" """The form to create or edit a credit line item."""
eid = IntegerField() id = IntegerField()
"""The existing line item ID.""" """The existing line item ID."""
no = IntegerField() no = IntegerField()
"""The order in the currency.""" """The order in the currency."""

View File

@ -679,15 +679,6 @@ class JournalEntryLineItem(db.Model):
amount=format_amount(self.amount))) amount=format_amount(self.amount)))
return getattr(self, "__str") return getattr(self, "__str")
@property
def eid(self) -> int | None:
"""Returns the line item ID. This is the alternative name of the
ID field, to work with WTForms.
:return: The line item ID.
"""
return self.id
@property @property
def account_code(self) -> str: def account_code(self) -> str:
"""Returns the account code. """Returns the account code.

View File

@ -21,8 +21,8 @@ First written: 2023/2/25
#} #}
{# <ul> For SonarQube not to complain about incorrect HTML #} {# <ul> For SonarQube not to complain about incorrect HTML #}
<li id="accounting-currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}" class="list-group-item list-group-item-action d-flex justify-content-between accounting-currency-{{ currency_index }}-{{ debit_credit }} {% if form.offsets %} accounting-matched-line-item {% endif %}" data-currency-index="{{ currency_index }}" data-debit-credit="{{ debit_credit }}" data-line-item-index="{{ line_item_index }}" {% if form.is_need_offset %} data-is-need-offset="true" {% endif %}> <li id="accounting-currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}" class="list-group-item list-group-item-action d-flex justify-content-between accounting-currency-{{ currency_index }}-{{ debit_credit }} {% if form.offsets %} accounting-matched-line-item {% endif %}" data-currency-index="{{ currency_index }}" data-debit-credit="{{ debit_credit }}" data-line-item-index="{{ line_item_index }}" {% if form.is_need_offset %} data-is-need-offset="true" {% endif %}>
{% if form.eid.data %} {% if form.id.data %}
<input type="hidden" name="currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-eid" value="{{ form.eid.data }}"> <input type="hidden" name="currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-id" value="{{ form.id.data }}">
{% endif %} {% endif %}
<input id="accounting-currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-no" type="hidden" name="currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-no" value="{{ line_item_index }}"> <input id="accounting-currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-no" type="hidden" name="currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-no" value="{{ line_item_index }}">
<input id="accounting-currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-original-line-item-id" class="accounting-original-line-item-id" type="hidden" name="currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-original_line_item_id" value="{{ form.original_line_item_id.data|accounting_default }}" data-date="{{ form.original_line_item_date|accounting_default }}" data-text="{{ form.original_line_item_text|accounting_default }}"> <input id="accounting-currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-original-line-item-id" class="accounting-original-line-item-id" type="hidden" name="currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-original_line_item_id" value="{{ form.original_line_item_id.data|accounting_default }}" data-date="{{ form.original_line_item_date|accounting_default }}" data-text="{{ form.original_line_item_text|accounting_default }}">

View File

@ -369,7 +369,7 @@ class OffsetTestCase(unittest.TestCase):
# Not deleting matched original line items # Not deleting matched original line items
form = journal_entry_data.update_form(self.csrf_token) form = journal_entry_data.update_form(self.csrf_token)
del form["currency-1-debit-1-eid"] del form["currency-1-debit-1-id"]
response = self.client.post(update_uri, data=form) response = self.client.post(update_uri, data=form)
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(response.headers["Location"], edit_uri) self.assertEqual(response.headers["Location"], edit_uri)
@ -697,7 +697,7 @@ class OffsetTestCase(unittest.TestCase):
# Not deleting matched original line items # Not deleting matched original line items
form = journal_entry_data.update_form(self.csrf_token) form = journal_entry_data.update_form(self.csrf_token)
del form["currency-1-credit-1-eid"] del form["currency-1-credit-1-id"]
response = self.client.post(update_uri, data=form) response = self.client.post(update_uri, data=form)
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(response.headers["Location"], edit_uri) self.assertEqual(response.headers["Location"], edit_uri)

View File

@ -166,7 +166,7 @@ def get_unchanged_update_form(journal_entry_id: int, app: Flask,
line_item_index: int = __get_new_index(line_item_indices_used) line_item_index: int = __get_new_index(line_item_indices_used)
line_item_no = line_item_no + 3 + randbelow(3) line_item_no = line_item_no + 3 + randbelow(3)
prefix = f"{currency_prefix}-debit-{line_item_index}" prefix = f"{currency_prefix}-debit-{line_item_index}"
form[f"{prefix}-eid"] = str(line_item.id) form[f"{prefix}-id"] = str(line_item.id)
form[f"{prefix}-no"] = str(line_item_no) form[f"{prefix}-no"] = str(line_item_no)
form[f"{prefix}-account_code"] = line_item.account.code form[f"{prefix}-account_code"] = line_item.account.code
form[f"{prefix}-description"] \ form[f"{prefix}-description"] \
@ -180,7 +180,7 @@ def get_unchanged_update_form(journal_entry_id: int, app: Flask,
line_item_index: int = __get_new_index(line_item_indices_used) line_item_index: int = __get_new_index(line_item_indices_used)
line_item_no = line_item_no + 3 + randbelow(3) line_item_no = line_item_no + 3 + randbelow(3)
prefix = f"{currency_prefix}-credit-{line_item_index}" prefix = f"{currency_prefix}-credit-{line_item_index}"
form[f"{prefix}-eid"] = str(line_item.id) form[f"{prefix}-id"] = str(line_item.id)
form[f"{prefix}-no"] = str(line_item_no) form[f"{prefix}-no"] = str(line_item_no)
form[f"{prefix}-account_code"] = line_item.account.code form[f"{prefix}-account_code"] = line_item.account.code
form[f"{prefix}-description"] \ form[f"{prefix}-description"] \

View File

@ -66,7 +66,7 @@ class JournalEntryLineItemData:
f"{prefix}-description": self.description, f"{prefix}-description": self.description,
f"{prefix}-amount": str(self.amount)} f"{prefix}-amount": str(self.amount)}
if is_update and self.id != -1: if is_update and self.id != -1:
form[f"{prefix}-eid"] = str(self.id) form[f"{prefix}-id"] = str(self.id)
form[f"{prefix}-no"] = str(index) if self.no == -1 else str(self.no) form[f"{prefix}-no"] = str(index) if self.no == -1 else str(self.no)
if self.original_line_item is not None: if self.original_line_item is not None:
assert self.original_line_item.id != -1 assert self.original_line_item.id != -1