Added support to sort the accounts under the same base account.

This commit is contained in:
2023-02-03 09:21:07 +08:00
parent eeb05b8616
commit 5238168b2d
7 changed files with 341 additions and 21 deletions

View File

@ -18,6 +18,7 @@
"""
import sqlalchemy as sa
from flask import request
from flask_wtf import FlaskForm
from wtforms import StringField, BooleanField
from wtforms.validators import DataRequired, ValidationError
@ -128,3 +129,48 @@ def sort_accounts_in(base_code: str, exclude: int) -> None:
for i in range(len(accounts)):
if accounts[i].no != i + 1:
accounts[i].no = i + 1
class AccountSortForm:
"""The form to sort the accounts."""
def __init__(self, base: BaseAccount):
"""Constructs the form to sort the accounts under a base account.
:param base: The base account.
"""
self.base: BaseAccount = base
self.is_modified: bool = False
def save_order(self) -> None:
"""Saves the order of the account.
:return:
"""
accounts: list[Account] = self.base.accounts
# Collects the specified order.
orders: dict[Account, int] = {}
for account in accounts:
if f"{account.id}-no" in request.form:
try:
orders[account] = int(request.form[f"{account.id}-no"])
except ValueError:
pass
# Missing and invalid orders are appended to the end.
missing: list[Account] = [x for x in accounts if x not in orders]
if len(missing) > 0:
next_no: int = 1 if len(orders) == 0 else max(orders.values()) + 1
for account in missing:
orders[account] = next_no
# Sort by the specified order first, and their original order.
accounts = sorted(accounts, key=lambda x: (orders[x], x.no, x.code))
# Update the orders.
with db.session.no_autoflush:
for i in range(len(accounts)):
if accounts[i].no != i + 1:
accounts[i].no = i + 1
self.is_modified = True

View File

@ -29,7 +29,7 @@ from accounting.models import Account, BaseAccount
from accounting.utils.next_url import inherit_next, or_next
from accounting.utils.pagination import Pagination
from accounting.utils.permission import can_view, has_permission, can_edit
from .forms import AccountForm, sort_accounts_in
from .forms import AccountForm, sort_accounts_in, AccountSortForm
bp: Blueprint = Blueprint("account", __name__)
"""The view blueprint for the account management."""
@ -162,3 +162,33 @@ def delete_account(account: Account) -> redirect:
db.session.commit()
flash(lazy_gettext("The account is deleted successfully."), "success")
return redirect(or_next(url_for("accounting.account.list")))
@bp.get("/sort/<baseAccount:base>", endpoint="sort-form")
@has_permission(can_edit)
def show_sort_form(base: BaseAccount) -> str:
"""Shows the form to sort the accounts under a base account.
:param base: The base account.
:return: The form to sort the accounts under the base account.
"""
return render_template("accounting/account/sort.html",
base=base)
@bp.post("/sort/<baseAccount:base>", endpoint="sort")
@has_permission(can_edit)
def sort_accounts(base: BaseAccount) -> redirect:
"""Sorts the accounts under a base account.
:param base: The base account.
:return: Sorts the accounts under the base account.
"""
form: AccountSortForm = AccountSortForm(base)
form.save_order()
if not form.is_modified:
flash(lazy_gettext("The order was not modified."), "success")
return redirect(or_next(url_for("accounting.account.list")))
db.session.commit()
flash(lazy_gettext("The order is updated successfully."), "success")
return redirect(or_next(url_for("accounting.account.list")))