diff --git a/src/accounting/account/forms.py b/src/accounting/account/forms.py index ba03fdd..24904b4 100644 --- a/src/accounting/account/forms.py +++ b/src/accounting/account/forms.py @@ -53,6 +53,21 @@ class BaseAccountAvailable: "The base account is not available.")) +class NoOffsetNominalAccount: + """The validator to check nominal account is not to be offset.""" + + def __call__(self, form: FlaskForm, field: BooleanField) -> None: + if not field.data: + return + if not isinstance(form, AccountForm): + return + if form.base_code.data is None: + return + if form.base_code.data[0] not in {"1", "2"}: + raise ValidationError(lazy_gettext( + "A nominal account does not need offset.")) + + class AccountForm(FlaskForm): """The form to create or edit an account.""" base_code = StringField( @@ -66,7 +81,8 @@ class AccountForm(FlaskForm): filters=[strip_text], validators=[DataRequired(lazy_gettext("Please fill in the title"))]) """The title.""" - is_offset_needed = BooleanField() + is_offset_needed = BooleanField( + validators=[NoOffsetNominalAccount()]) """Whether the the entries of this account need offset.""" def populate_obj(self, obj: Account) -> None: @@ -87,7 +103,10 @@ class AccountForm(FlaskForm): obj.base_code = self.base_code.data obj.no = count + 1 obj.title = self.title.data - obj.is_offset_needed = self.is_offset_needed.data + if self.base_code.data[0] in {"1", "2"}: + obj.is_offset_needed = self.is_offset_needed.data + else: + obj.is_offset_needed = False if is_new: current_user_pk: int = get_current_user_pk() obj.created_by_id = current_user_pk diff --git a/src/accounting/static/js/account-form.js b/src/accounting/static/js/account-form.js index 0c63919..a388a6b 100644 --- a/src/accounting/static/js/account-form.js +++ b/src/accounting/static/js/account-form.js @@ -43,6 +43,8 @@ function initializeBaseAccountSelector() { const base = document.getElementById("accounting-base"); const baseCode = document.getElementById("accounting-base-code"); const baseContent = document.getElementById("accounting-base-content"); + const isOffsetNeededControl = document.getElementById("accounting-is-offset-needed-control"); + const isOffsetNeeded = document.getElementById("accounting-is-offset-needed"); const options = Array.from(document.getElementsByClassName("accounting-base-option")); const btnClear = document.getElementById("accounting-btn-clear-base"); selector.addEventListener("show.bs.modal", () => { @@ -64,6 +66,14 @@ function initializeBaseAccountSelector() { option.onclick = () => { baseCode.value = option.dataset.code; baseContent.innerText = option.dataset.content; + if (["1", "2"].includes(option.dataset.content.substring(0, 1))) { + isOffsetNeededControl.classList.remove("d-none"); + isOffsetNeeded.disabled = false; + } else { + isOffsetNeededControl.classList.add("d-none"); + isOffsetNeeded.disabled = true; + isOffsetNeeded.checked = false; + } btnClear.classList.add("btn-danger"); btnClear.classList.remove("btn-secondary") btnClear.disabled = false; diff --git a/src/accounting/templates/accounting/account/include/form.html b/src/accounting/templates/accounting/account/include/form.html index 7d7b4ce..292907c 100644 --- a/src/accounting/templates/accounting/account/include/form.html +++ b/src/accounting/templates/accounting/account/include/form.html @@ -62,7 +62,7 @@ First written: 2023/2/1