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:
parent
d4fe91ec4a
commit
079dc1ab6d
@ -89,8 +89,8 @@ class KeepCurrencyWhenHavingOffset:
|
||||
== offset.c.original_line_item_id),
|
||||
isouter=True)\
|
||||
.filter(JournalEntryLineItem.id
|
||||
.in_({x.eid.data for x in form.line_items
|
||||
if x.eid.data is not None}))\
|
||||
.in_({x.id.data for x in form.line_items
|
||||
if x.id.data is not None}))\
|
||||
.group_by(JournalEntryLineItem.id,
|
||||
JournalEntryLineItem.currency_code)\
|
||||
.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 len(original_line_item_id) > 0:
|
||||
return True
|
||||
line_item_id: set[int] = {x.eid.data for x in line_item_forms
|
||||
if x.eid.data is not None}
|
||||
line_item_id: set[int] = {x.id.data for x in line_item_forms
|
||||
if x.id.data is not None}
|
||||
select: sa.Select = sa.select(sa.func.count(JournalEntryLineItem.id))\
|
||||
.filter(JournalEntryLineItem.original_line_item_id
|
||||
.in_(line_item_id))
|
||||
|
@ -98,7 +98,7 @@ class CannotDeleteOriginalLineItemsWithOffset:
|
||||
existing_matched_original_line_item_id: set[int] \
|
||||
= {x.id for x in form.obj.line_items if len(x.offsets) > 0}
|
||||
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:
|
||||
if line_item_id not in line_item_id_in_form:
|
||||
raise ValidationError(lazy_gettext(
|
||||
@ -273,8 +273,8 @@ class JournalEntryForm(FlaskForm):
|
||||
if self.__original_line_item_options is None:
|
||||
self.__original_line_item_options \
|
||||
= get_selectable_original_line_items(
|
||||
{x.eid.data for x in self.line_items
|
||||
if x.eid.data is not None},
|
||||
{x.id.data for x in self.line_items
|
||||
if x.id.data is not None},
|
||||
self._is_need_payable, self._is_need_receivable)
|
||||
return self.__original_line_item_options
|
||||
|
||||
@ -300,8 +300,8 @@ class JournalEntryForm(FlaskForm):
|
||||
|
||||
:return: The maximum available date.
|
||||
"""
|
||||
line_item_id: set[int] = {x.eid.data for x in self.line_items
|
||||
if x.eid.data is not None}
|
||||
line_item_id: set[int] = {x.id.data for x in self.line_items
|
||||
if x.id.data is not None}
|
||||
select: sa.Select = sa.select(sa.func.min(JournalEntry.date))\
|
||||
.join(JournalEntryLineItem)\
|
||||
.filter(JournalEntryLineItem.original_line_item_id
|
||||
@ -360,7 +360,7 @@ class LineItemCollector(t.Generic[T], ABC):
|
||||
:return: 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:
|
||||
line_item.currency_code = currency_code
|
||||
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}
|
||||
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,
|
||||
missing_no if x.eid.data is None else
|
||||
self.__no_by_id.get(x.eid.data, missing_no),
|
||||
missing_no if x.id.data is None else
|
||||
self.__no_by_id.get(x.id.data, missing_no),
|
||||
ord_by_form.get(x)))
|
||||
|
||||
def _sort_currency_forms(self, forms: list[CurrencyForm]) -> None:
|
||||
|
@ -167,11 +167,11 @@ class KeepAccountWhenHavingOffset:
|
||||
|
||||
def __call__(self, form: FlaskForm, field: StringField) -> None:
|
||||
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
|
||||
line_item: JournalEntryLineItem | None = db.session\
|
||||
.query(JournalEntryLineItem)\
|
||||
.filter(JournalEntryLineItem.id == form.eid.data)\
|
||||
.filter(JournalEntryLineItem.id == form.id.data)\
|
||||
.options(selectinload(JournalEntryLineItem.offsets)).first()
|
||||
if line_item is None or len(line_item.offsets) == 0:
|
||||
return
|
||||
@ -269,7 +269,7 @@ class NotLessThanOffsetTotal:
|
||||
|
||||
def __call__(self, form: FlaskForm, field: DecimalField) -> None:
|
||||
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
|
||||
is_debit: bool = isinstance(form, DebitLineItemForm)
|
||||
select_offset_total: sa.Select = sa.select(sa.func.sum(sa.case(
|
||||
@ -277,7 +277,7 @@ class NotLessThanOffsetTotal:
|
||||
JournalEntryLineItem.amount),
|
||||
else_=-JournalEntryLineItem.amount)))\
|
||||
.filter(be(JournalEntryLineItem.original_line_item_id
|
||||
== form.eid.data))
|
||||
== form.id.data))
|
||||
offset_total: Decimal | None = db.session.scalar(select_offset_total)
|
||||
if offset_total is not None and field.data < offset_total:
|
||||
raise ValidationError(lazy_gettext(
|
||||
@ -287,7 +287,7 @@ class NotLessThanOffsetTotal:
|
||||
|
||||
class LineItemForm(FlaskForm):
|
||||
"""The base form to create or edit a line item."""
|
||||
eid = IntegerField()
|
||||
id = IntegerField()
|
||||
"""The existing line item ID."""
|
||||
no = IntegerField()
|
||||
"""The order in the currency."""
|
||||
@ -384,11 +384,11 @@ class LineItemForm(FlaskForm):
|
||||
"""
|
||||
if not hasattr(self, "__offsets"):
|
||||
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 JournalEntryLineItem.query\
|
||||
.filter(JournalEntryLineItem.original_line_item_id
|
||||
== self.eid.data)\
|
||||
== self.id.data)\
|
||||
.options(selectinload(JournalEntryLineItem.journal_entry),
|
||||
selectinload(JournalEntryLineItem.account),
|
||||
selectinload(JournalEntryLineItem.offsets)
|
||||
@ -405,7 +405,7 @@ class LineItemForm(FlaskForm):
|
||||
"""
|
||||
if not hasattr(self, "__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
|
||||
is_debit: bool = isinstance(self, DebitLineItemForm)
|
||||
return sum([x.amount if x.is_debit != is_debit else -x.amount
|
||||
@ -419,7 +419,7 @@ class LineItemForm(FlaskForm):
|
||||
|
||||
: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:
|
||||
return None
|
||||
return self.amount.data - self.offset_total
|
||||
@ -439,7 +439,7 @@ class LineItemForm(FlaskForm):
|
||||
|
||||
class DebitLineItemForm(LineItemForm):
|
||||
"""The form to create or edit a debit line item."""
|
||||
eid = IntegerField()
|
||||
id = IntegerField()
|
||||
"""The existing line item ID."""
|
||||
no = IntegerField()
|
||||
"""The order in the currency."""
|
||||
@ -489,7 +489,7 @@ class DebitLineItemForm(LineItemForm):
|
||||
|
||||
class CreditLineItemForm(LineItemForm):
|
||||
"""The form to create or edit a credit line item."""
|
||||
eid = IntegerField()
|
||||
id = IntegerField()
|
||||
"""The existing line item ID."""
|
||||
no = IntegerField()
|
||||
"""The order in the currency."""
|
||||
|
@ -679,15 +679,6 @@ class JournalEntryLineItem(db.Model):
|
||||
amount=format_amount(self.amount)))
|
||||
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
|
||||
def account_code(self) -> str:
|
||||
"""Returns the account code.
|
||||
|
@ -21,8 +21,8 @@ First written: 2023/2/25
|
||||
#}
|
||||
{# <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 %}>
|
||||
{% if form.eid.data %}
|
||||
<input type="hidden" name="currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-eid" value="{{ form.eid.data }}">
|
||||
{% if form.id.data %}
|
||||
<input type="hidden" name="currency-{{ currency_index }}-{{ debit_credit }}-{{ line_item_index }}-id" value="{{ form.id.data }}">
|
||||
{% 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 }}-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 }}">
|
||||
|
@ -369,7 +369,7 @@ class OffsetTestCase(unittest.TestCase):
|
||||
|
||||
# Not deleting matched original line items
|
||||
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)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(response.headers["Location"], edit_uri)
|
||||
@ -697,7 +697,7 @@ class OffsetTestCase(unittest.TestCase):
|
||||
|
||||
# Not deleting matched original line items
|
||||
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)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(response.headers["Location"], edit_uri)
|
||||
|
@ -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_no = line_item_no + 3 + randbelow(3)
|
||||
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}-account_code"] = line_item.account.code
|
||||
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_no = line_item_no + 3 + randbelow(3)
|
||||
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}-account_code"] = line_item.account.code
|
||||
form[f"{prefix}-description"] \
|
||||
|
@ -66,7 +66,7 @@ class JournalEntryLineItemData:
|
||||
f"{prefix}-description": self.description,
|
||||
f"{prefix}-amount": str(self.amount)}
|
||||
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)
|
||||
if self.original_line_item is not None:
|
||||
assert self.original_line_item.id != -1
|
||||
|
Loading…
Reference in New Issue
Block a user