8 Commits

7 changed files with 80 additions and 59 deletions

View File

@ -2,6 +2,16 @@ Change Log
========== ==========
Version 1.5.1
-------------
Released 2023/4/30
* Fixed the error calling the old ``setEnableDescriptionAccount``
method in the ``saveOriginalLineItem`` method of the JavaScript
``JournalEntryLineItemEditor`` class.
Version 1.5.0 Version 1.5.0
------------- -------------

View File

@ -24,7 +24,7 @@ from flask_sqlalchemy import SQLAlchemy
from accounting.utils.user import UserUtilityInterface from accounting.utils.user import UserUtilityInterface
VERSION: str = "1.5.0" VERSION: str = "1.5.1"
"""The package version.""" """The package version."""
db: SQLAlchemy = SQLAlchemy() db: SQLAlchemy = SQLAlchemy()
"""The database instance.""" """The database instance."""

View File

@ -22,7 +22,7 @@ from __future__ import annotations
import datetime as dt import datetime as dt
import re import re
from decimal import Decimal from decimal import Decimal
from typing import Type, Annotated, Self from typing import Type, Self
import sqlalchemy as sa import sqlalchemy as sa
from babel import Locale from babel import Locale
@ -34,18 +34,6 @@ from accounting import db
from accounting.locale import gettext from accounting.locale import gettext
from accounting.utils.user import user_cls, user_pk_column from accounting.utils.user import user_cls, user_pk_column
timestamp: Type[dt.datetime] \
= Annotated[dt.datetime, mapped_column(db.DateTime(timezone=True),
server_default=db.func.now())]
"""The timestamp."""
user_pk: Type[int] \
= Annotated[int, mapped_column(db.ForeignKey(user_pk_column,
onupdate="CASCADE"))]
"""The user primary key."""
random_pk: Type[int] \
= Annotated[int, mapped_column(primary_key=True, autoincrement=False)]
"""The random primary key."""
class BaseAccount(db.Model): class BaseAccount(db.Model):
"""A base account.""" """A base account."""
@ -126,18 +114,24 @@ class Account(db.Model):
"""The title.""" """The title."""
is_need_offset: Mapped[bool] = mapped_column(default=False) is_need_offset: Mapped[bool] = mapped_column(default=False)
"""Whether the journal entry line items of this account need offset.""" """Whether the journal entry line items of this account need offset."""
created_at: Mapped[timestamp] created_at: Mapped[dt.datetime] \
"""The time of creation.""" = mapped_column(db.DateTime(timezone=True),
created_by_id: Mapped[user_pk] = mapped_column() server_default=db.func.now())
"""The ID of the creator.""" """The date and time when this record was created."""
created_by_id: Mapped[int] \
= mapped_column(db.ForeignKey(user_pk_column, onupdate="CASCADE"))
"""The ID of the user who created the record."""
created_by: Mapped[user_cls] = db.relationship(foreign_keys=created_by_id) created_by: Mapped[user_cls] = db.relationship(foreign_keys=created_by_id)
"""The creator.""" """The user who created the record."""
updated_at: Mapped[timestamp] updated_at: Mapped[dt.datetime] \
"""The time of last update.""" = mapped_column(db.DateTime(timezone=True),
updated_by_id: Mapped[user_pk] = mapped_column() server_default=db.func.now())
"""The ID of the updator.""" """The date and time when this record was last updated."""
updated_by_id: Mapped[int] \
= mapped_column(db.ForeignKey(user_pk_column, onupdate="CASCADE"))
"""The ID of the last user who updated the record."""
updated_by: Mapped[user_cls] = db.relationship(foreign_keys=updated_by_id) updated_by: Mapped[user_cls] = db.relationship(foreign_keys=updated_by_id)
"""The updator.""" """The last user who updated the record."""
l10n: Mapped[list[AccountL10n]] \ l10n: Mapped[list[AccountL10n]] \
= db.relationship(back_populates="account", lazy=False) = db.relationship(back_populates="account", lazy=False)
"""The localized titles.""" """The localized titles."""
@ -376,19 +370,25 @@ class Currency(db.Model):
"""The code.""" """The code."""
name_l10n: Mapped[str] = mapped_column("name") name_l10n: Mapped[str] = mapped_column("name")
"""The name.""" """The name."""
created_at: Mapped[timestamp] created_at: Mapped[dt.datetime] \
"""The time of creation.""" = mapped_column(db.DateTime(timezone=True),
created_by_id: Mapped[user_pk] = mapped_column() server_default=db.func.now())
"""The ID of the creator.""" """The date and time when this record was created."""
created_by_id: Mapped[int] \
= mapped_column(db.ForeignKey(user_pk_column, onupdate="CASCADE"))
"""The ID of the user who created the record."""
created_by: Mapped[user_cls] = db.relationship(foreign_keys=created_by_id) created_by: Mapped[user_cls] = db.relationship(foreign_keys=created_by_id)
"""The creator.""" """The user who created the record."""
updated_at: Mapped[timestamp] updated_at: Mapped[dt.datetime] \
"""The time of last update.""" = mapped_column(db.DateTime(timezone=True),
updated_by_id: Mapped[user_pk] = mapped_column() server_default=db.func.now())
"""The ID of the updator.""" """The date and time when this record was last updated."""
updated_by_id: Mapped[int] \
= mapped_column(db.ForeignKey(user_pk_column, onupdate="CASCADE"))
"""The ID of the last user who updated the record."""
updated_by: Mapped[user_cls] \ updated_by: Mapped[user_cls] \
= db.relationship(foreign_keys=updated_by_id) = db.relationship(foreign_keys=updated_by_id)
"""The updator.""" """The last user who updated the record."""
l10n: Mapped[list[CurrencyL10n]] \ l10n: Mapped[list[CurrencyL10n]] \
= db.relationship(back_populates="currency", lazy=False) = db.relationship(back_populates="currency", lazy=False)
"""The localized names.""" """The localized names."""
@ -543,18 +543,24 @@ class JournalEntry(db.Model):
"""The account number under the date.""" """The account number under the date."""
note: Mapped[str | None] note: Mapped[str | None]
"""The note.""" """The note."""
created_at: Mapped[timestamp] created_at: Mapped[dt.datetime] \
"""The time of creation.""" = mapped_column(db.DateTime(timezone=True),
created_by_id: Mapped[user_pk] = mapped_column() server_default=db.func.now())
"""The ID of the creator.""" """The date and time when this record was created."""
created_by_id: Mapped[int] \
= mapped_column(db.ForeignKey(user_pk_column, onupdate="CASCADE"))
"""The ID of the user who created the record."""
created_by: Mapped[user_cls] = db.relationship(foreign_keys=created_by_id) created_by: Mapped[user_cls] = db.relationship(foreign_keys=created_by_id)
"""The creator.""" """The user who created the record."""
updated_at: Mapped[timestamp] updated_at: Mapped[dt.datetime] \
"""The time of last update.""" = mapped_column(db.DateTime(timezone=True),
updated_by_id: Mapped[user_pk] = mapped_column() server_default=db.func.now())
"""The ID of the updator.""" """The date and time when this record was last updated."""
updated_by_id: Mapped[int] \
= mapped_column(db.ForeignKey(user_pk_column, onupdate="CASCADE"))
"""The ID of the last user who updated the record."""
updated_by: Mapped[user_cls] = db.relationship(foreign_keys=updated_by_id) updated_by: Mapped[user_cls] = db.relationship(foreign_keys=updated_by_id)
"""The updator.""" """The last user who updated the record."""
line_items: Mapped[list[JournalEntryLineItem]] \ line_items: Mapped[list[JournalEntryLineItem]] \
= db.relationship(back_populates="journal_entry") = db.relationship(back_populates="journal_entry")
"""The line items.""" """The line items."""
@ -876,15 +882,21 @@ class Option(db.Model):
"""The name.""" """The name."""
value: Mapped[str] = mapped_column(db.Text) value: Mapped[str] = mapped_column(db.Text)
"""The option value.""" """The option value."""
created_at: Mapped[timestamp] created_at: Mapped[dt.datetime] \
"""The time of creation.""" = mapped_column(db.DateTime(timezone=True),
created_by_id: Mapped[user_pk] = mapped_column() server_default=db.func.now())
"""The ID of the creator.""" """The date and time when this record was created."""
created_by_id: Mapped[int] \
= mapped_column(db.ForeignKey(user_pk_column, onupdate="CASCADE"))
"""The ID of the user who created the record."""
created_by: Mapped[user_cls] = db.relationship(foreign_keys=created_by_id) created_by: Mapped[user_cls] = db.relationship(foreign_keys=created_by_id)
"""The creator.""" """The user who created the record."""
updated_at: Mapped[timestamp] updated_at: Mapped[dt.datetime] \
"""The time of last update.""" = mapped_column(db.DateTime(timezone=True),
updated_by_id: Mapped[user_pk] = mapped_column() server_default=db.func.now())
"""The ID of the updator.""" """The date and time when this record was last updated."""
updated_by_id: Mapped[int] \
= mapped_column(db.ForeignKey(user_pk_column, onupdate="CASCADE"))
"""The ID of the last user who updated the record."""
updated_by: Mapped[user_cls] = db.relationship(foreign_keys=updated_by_id) updated_by: Mapped[user_cls] = db.relationship(foreign_keys=updated_by_id)
"""The updator.""" """The last user who updated the record."""

View File

@ -143,7 +143,7 @@ class AccountsWithUnappliedOriginalLineItems(BaseReport):
:return: The response of the report for download. :return: The response of the report for download.
""" """
filename: str = f"unapplied-accounts.csv" filename: str = "unapplied-accounts.csv"
return csv_download(filename, get_csv_rows(self.__accounts)) return csv_download(filename, get_csv_rows(self.__accounts))
def html(self) -> str: def html(self) -> str:

View File

@ -144,7 +144,7 @@ class AccountsWithUnmatchedOffsets(BaseReport):
:return: The response of the report for download. :return: The response of the report for download.
""" """
filename: str = f"unapplied-accounts.csv" filename: str = "unmatched-accounts.csv"
return csv_download(filename, get_csv_rows(self.__accounts)) return csv_download(filename, get_csv_rows(self.__accounts))
def html(self) -> str: def html(self) -> str:

View File

@ -276,7 +276,6 @@ class JournalEntryLineItemEditor {
this.originalLineItemDate = originalLineItem.date; this.originalLineItemDate = originalLineItem.date;
this.originalLineItemText = originalLineItem.text; this.originalLineItemText = originalLineItem.text;
this.#originalLineItemText.innerText = originalLineItem.text; this.#originalLineItemText.innerText = originalLineItem.text;
this.#setEnableDescriptionAccount(false);
if (this.description === null) { if (this.description === null) {
if (originalLineItem.description === "") { if (originalLineItem.description === "") {
this.#descriptionControl.classList.remove("accounting-not-empty"); this.#descriptionControl.classList.remove("accounting-not-empty");

View File

@ -26,10 +26,10 @@ from accounting import db
def new_id(cls: Type[db.Model]): def new_id(cls: Type[db.Model]):
"""Returns a new random ID for the data model. """Generates and returns a new, unused random ID for the data model.
:param cls: The data model. :param cls: The data model.
:return: The generated new random ID. :return: The newly-generated, unused random ID.
""" """
while True: while True:
obj_id: int = 100000000 + randbelow(900000000) obj_id: int = 100000000 + randbelow(900000000)