From 359c33566241bf0ff7ad3b6db2aeaaf06d10d189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=9D=E7=91=AA=E8=B2=93?= Date: Wed, 26 Apr 2023 13:17:31 +0800 Subject: [PATCH] Revised the way to import from the datetime package, to avoid name conflict with the common "date" and "time" names. --- src/accounting/journal_entry/converters.py | 8 ++--- .../journal_entry/forms/line_item.py | 4 +-- src/accounting/journal_entry/forms/reorder.py | 8 ++--- src/accounting/journal_entry/views.py | 10 +++--- src/accounting/report/period/chooser.py | 10 +++--- src/accounting/report/period/description.py | 22 ++++++------ src/accounting/report/period/month_end.py | 6 ++-- src/accounting/report/period/parser.py | 20 +++++------ src/accounting/report/period/period.py | 14 ++++---- src/accounting/report/period/shortcuts.py | 34 +++++++++---------- src/accounting/report/period/specification.py | 18 +++++----- .../report/reports/income_expenses.py | 8 ++--- src/accounting/report/reports/journal.py | 6 ++-- src/accounting/report/reports/ledger.py | 8 ++--- src/accounting/report/reports/search.py | 12 +++---- src/accounting/report/reports/unapplied.py | 8 ++--- .../report/reports/unapplied_accounts.py | 4 +-- src/accounting/report/reports/unmatched.py | 8 ++--- .../report/reports/unmatched_accounts.py | 4 +-- src/accounting/report/utils/csv_export.py | 8 ++--- src/accounting/template_filters.py | 14 ++++---- tests/test_account.py | 6 ++-- tests/test_currency.py | 6 ++-- tests/test_description_editor.py | 4 +-- tests/test_journal_entry.py | 19 ++++++----- tests/test_option.py | 5 +-- tests/test_report.py | 6 ++-- tests/test_site/lib.py | 10 +++--- tests/test_site/reset.py | 14 ++++---- tests/testlib_journal_entry.py | 4 +-- 30 files changed, 156 insertions(+), 152 deletions(-) diff --git a/src/accounting/journal_entry/converters.py b/src/accounting/journal_entry/converters.py index ff58714..33b942f 100644 --- a/src/accounting/journal_entry/converters.py +++ b/src/accounting/journal_entry/converters.py @@ -17,7 +17,7 @@ """The path converters for the journal entry management. """ -from datetime import date +import datetime as dt from flask import abort from werkzeug.routing import BaseConverter @@ -82,18 +82,18 @@ class DateConverter(BaseConverter): """The date converter to convert the ISO date from and to the corresponding date in the routes.""" - def to_python(self, value: str) -> date: + def to_python(self, value: str) -> dt.date: """Converts an ISO date to a date. :param value: The ISO date. :return: The corresponding date. """ try: - return date.fromisoformat(value) + return dt.date.fromisoformat(value) except ValueError: abort(404) - def to_url(self, value: date) -> str: + def to_url(self, value: dt.date) -> str: """Converts a date to its ISO date. :param value: The date. diff --git a/src/accounting/journal_entry/forms/line_item.py b/src/accounting/journal_entry/forms/line_item.py index a1d735c..7b30c6c 100644 --- a/src/accounting/journal_entry/forms/line_item.py +++ b/src/accounting/journal_entry/forms/line_item.py @@ -17,7 +17,7 @@ """The line item sub-forms for the journal entry management. """ -from datetime import date +import datetime as dt from decimal import Decimal import sqlalchemy as sa @@ -307,7 +307,7 @@ class LineItemForm(FlaskForm): return getattr(self, "____original_line_item") @property - def original_line_item_date(self) -> date | None: + def original_line_item_date(self) -> dt.date | None: """Returns the text representation of the original line item. :return: The text representation of the original line item. diff --git a/src/accounting/journal_entry/forms/reorder.py b/src/accounting/journal_entry/forms/reorder.py index dd8858e..cd83570 100644 --- a/src/accounting/journal_entry/forms/reorder.py +++ b/src/accounting/journal_entry/forms/reorder.py @@ -17,7 +17,7 @@ """The reorder forms for the journal entry management. """ -from datetime import date +import datetime as dt import sqlalchemy as sa from flask import request @@ -26,7 +26,7 @@ from accounting import db from accounting.models import JournalEntry -def sort_journal_entries_in(journal_entry_date: date, +def sort_journal_entries_in(journal_entry_date: dt.date, exclude: int | None = None) -> None: """Sorts the journal entries under a date after changing the date or deleting a journal entry. @@ -50,12 +50,12 @@ def sort_journal_entries_in(journal_entry_date: date, class JournalEntryReorderForm: """The form to reorder the journal entries.""" - def __init__(self, journal_entry_date: date): + def __init__(self, journal_entry_date: dt.date): """Constructs the form to reorder the journal entries in a day. :param journal_entry_date: The date. """ - self.date: date = journal_entry_date + self.date: dt.date = journal_entry_date self.is_modified: bool = False def save_order(self) -> None: diff --git a/src/accounting/journal_entry/views.py b/src/accounting/journal_entry/views.py index a0988e4..5b9b900 100644 --- a/src/accounting/journal_entry/views.py +++ b/src/accounting/journal_entry/views.py @@ -17,7 +17,7 @@ """The views for the journal entry management. """ -from datetime import date +import datetime as dt from urllib.parse import parse_qsl, urlencode import sqlalchemy as sa @@ -30,9 +30,9 @@ from accounting.locale import lazy_gettext from accounting.models import JournalEntry from accounting.utils.cast import s from accounting.utils.flash_errors import flash_form_errors +from accounting.utils.journal_entry_types import JournalEntryType from accounting.utils.next_uri import inherit_next, or_next from accounting.utils.permission import has_permission, can_view, can_edit -from accounting.utils.journal_entry_types import JournalEntryType from accounting.utils.user import get_current_user_pk from .forms import sort_journal_entries_in, JournalEntryReorderForm from .template_filters import with_type, to_transfer, format_amount_input, \ @@ -67,7 +67,7 @@ def show_add_journal_entry_form(journal_entry_type: JournalEntryType) -> str: form.validate() else: form = journal_entry_op.form() - form.date.data = date.today() + form.date.data = dt.date.today() return journal_entry_op.render_create_template(form) @@ -188,7 +188,7 @@ def delete_journal_entry(journal_entry: JournalEntry) -> redirect: @bp.get("dates/", endpoint="order") @has_permission(can_view) -def show_journal_entry_order(journal_entry_date: date) -> str: +def show_journal_entry_order(journal_entry_date: dt.date) -> str: """Shows the order of the journal entries in a same date. :param journal_entry_date: The date. @@ -203,7 +203,7 @@ def show_journal_entry_order(journal_entry_date: date) -> str: @bp.post("dates/", endpoint="sort") @has_permission(can_edit) -def sort_journal_entries(journal_entry_date: date) -> redirect: +def sort_journal_entries(journal_entry_date: dt.date) -> redirect: """Reorders the journal entries in a date. :param journal_entry_date: The date. diff --git a/src/accounting/report/period/chooser.py b/src/accounting/report/period/chooser.py index 33d7189..11b43d8 100644 --- a/src/accounting/report/period/chooser.py +++ b/src/accounting/report/period/chooser.py @@ -20,8 +20,8 @@ This file is largely taken from the NanoParma ERP project, first written in 2021/9/16 by imacat (imacat@nanoparma.com). """ +import datetime as dt import typing as t -from datetime import date from accounting.models import JournalEntry from .period import Period @@ -63,10 +63,10 @@ class PeriodChooser: first: JournalEntry | None \ = JournalEntry.query.order_by(JournalEntry.date).first() - start: date | None = None if first is None else first.date + start: dt.date | None = None if first is None else first.date # Attributes - self.data_start: date | None = start + self.data_start: dt.date | None = start """The start of the data.""" self.has_data: bool = start is not None """Whether there is any data.""" @@ -80,8 +80,8 @@ class PeriodChooser: """The available years.""" if self.has_data: - today: date = date.today() - self.has_last_month = start < date(today.year, today.month, 1) + today: dt.date = dt.date.today() + self.has_last_month = start < dt.date(today.year, today.month, 1) self.has_last_year = start.year < today.year self.has_yesterday = start < today if start.year < today.year - 1: diff --git a/src/accounting/report/period/description.py b/src/accounting/report/period/description.py index 95caa4d..2fae1e8 100644 --- a/src/accounting/report/period/description.py +++ b/src/accounting/report/period/description.py @@ -17,12 +17,12 @@ """The period description composer. """ -from datetime import date, timedelta +import datetime as dt from accounting.locale import gettext -def get_desc(start: date | None, end: date | None) -> str: +def get_desc(start: dt.date | None, end: dt.date | None) -> str: """Returns the period description. :param start: The start of the period. @@ -46,7 +46,7 @@ def get_desc(start: date | None, end: date | None) -> str: return __get_day_desc(start, end) -def __get_since_desc(start: date) -> str: +def __get_since_desc(start: dt.date) -> str: """Returns the description without the end day. :param start: The start of the period. @@ -67,7 +67,7 @@ def __get_since_desc(start: date) -> str: return gettext("since %(start)s", start=get_start_desc()) -def __get_until_desc(end: date) -> str: +def __get_until_desc(end: dt.date) -> str: """Returns the description without the start day. :param end: The end of the period. @@ -81,14 +81,14 @@ def __get_until_desc(end: date) -> str: """ if end.month == 12 and end.day == 31: return str(end.year) - if (end + timedelta(days=1)).day == 1: + if (end + dt.timedelta(days=1)).day == 1: return __format_month(end) return __format_day(end) return gettext("until %(end)s", end=get_end_desc()) -def __get_year_desc(start: date, end: date) -> str: +def __get_year_desc(start: dt.date, end: dt.date) -> str: """Returns the description as a year range. :param start: The start of the period. @@ -105,7 +105,7 @@ def __get_year_desc(start: date, end: date) -> str: return __get_from_to_desc(start_text, str(end.year)) -def __get_month_desc(start: date, end: date) -> str: +def __get_month_desc(start: dt.date, end: dt.date) -> str: """Returns the description as a month range. :param start: The start of the period. @@ -113,7 +113,7 @@ def __get_month_desc(start: date, end: date) -> str: :return: The description as a month range. :raise ValueError: The period is not a month range. """ - if start.day != 1 or (end + timedelta(days=1)).day != 1: + if start.day != 1 or (end + dt.timedelta(days=1)).day != 1: raise ValueError start_text: str = __format_month(start) if start.year == end.year and start.month == end.month: @@ -123,7 +123,7 @@ def __get_month_desc(start: date, end: date) -> str: return __get_from_to_desc(start_text, __format_month(end)) -def __get_day_desc(start: date, end: date) -> str: +def __get_day_desc(start: dt.date, end: dt.date) -> str: """Returns the description as a day range. :param start: The start of the period. @@ -142,7 +142,7 @@ def __get_day_desc(start: date, end: date) -> str: return __get_from_to_desc(start_text, __format_day(end)) -def __format_month(month: date) -> str: +def __format_month(month: dt.date) -> str: """Formats a month. :param month: The month. @@ -151,7 +151,7 @@ def __format_month(month: date) -> str: return f"{month.year}/{month.month}" -def __format_day(day: date) -> str: +def __format_day(day: dt.date) -> str: """Formats a day. :param day: The day. diff --git a/src/accounting/report/period/month_end.py b/src/accounting/report/period/month_end.py index 8d6de25..ff13365 100644 --- a/src/accounting/report/period/month_end.py +++ b/src/accounting/report/period/month_end.py @@ -18,14 +18,14 @@ """ import calendar -from datetime import date +import datetime as dt -def month_end(day: date) -> date: +def month_end(day: dt.date) -> dt.date: """Returns the end day of month for a date. :param day: The date. :return: The end day of the month of that day. """ last_day: int = calendar.monthrange(day.year, day.month)[1] - return date(day.year, day.month, last_day) + return dt.date(day.year, day.month, last_day) diff --git a/src/accounting/report/period/parser.py b/src/accounting/report/period/parser.py index 53fbe26..338393e 100644 --- a/src/accounting/report/period/parser.py +++ b/src/accounting/report/period/parser.py @@ -18,9 +18,9 @@ """ import calendar +import datetime as dt import re import typing as t -from datetime import date from .period import Period from .shortcuts import ThisMonth, LastMonth, SinceLastMonth, ThisYear, \ @@ -57,7 +57,7 @@ def get_period(spec: str | None = None) -> Period: return Period(start, end) -def __parse_spec(text: str) -> tuple[date | None, date | None]: +def __parse_spec(text: str) -> tuple[dt.date | None, dt.date | None]: """Parses the period specification. :param text: The period specification. @@ -84,7 +84,7 @@ def __parse_spec(text: str) -> tuple[date | None, date | None]: raise ValueError -def __get_start(year: str, month: str | None, day: str | None) -> date: +def __get_start(year: str, month: str | None, day: str | None) -> dt.date: """Returns the start of the period from the date representation. :param year: The year. @@ -94,13 +94,13 @@ def __get_start(year: str, month: str | None, day: str | None) -> date: :raise ValueError: When the date is invalid. """ if day is not None: - return date(int(year), int(month), int(day)) + return dt.date(int(year), int(month), int(day)) if month is not None: - return date(int(year), int(month), 1) - return date(int(year), 1, 1) + return dt.date(int(year), int(month), 1) + return dt.date(int(year), 1, 1) -def __get_end(year: str, month: str | None, day: str | None) -> date: +def __get_end(year: str, month: str | None, day: str | None) -> dt.date: """Returns the end of the period from the date representation. :param year: The year. @@ -110,10 +110,10 @@ def __get_end(year: str, month: str | None, day: str | None) -> date: :raise ValueError: When the date is invalid. """ if day is not None: - return date(int(year), int(month), int(day)) + return dt.date(int(year), int(month), int(day)) if month is not None: year_n: int = int(year) month_n: int = int(month) day_n: int = calendar.monthrange(year_n, month_n)[1] - return date(year_n, month_n, day_n) - return date(int(year), 12, 31) + return dt.date(year_n, month_n, day_n) + return dt.date(int(year), 12, 31) diff --git a/src/accounting/report/period/period.py b/src/accounting/report/period/period.py index 22eef49..a8dcbab 100644 --- a/src/accounting/report/period/period.py +++ b/src/accounting/report/period/period.py @@ -20,8 +20,8 @@ This file is largely taken from the NanoParma ERP project, first written in 2021/9/16 by imacat (imacat@nanoparma.com). """ +import datetime as dt import typing as t -from datetime import date, timedelta from .description import get_desc from .month_end import month_end @@ -31,15 +31,15 @@ from .specification import get_spec class Period: """A date period.""" - def __init__(self, start: date | None, end: date | None): + def __init__(self, start: dt.date | None, end: dt.date | None): """Constructs a new date period. :param start: The start date, or None from the very beginning. :param end: The end date, or None till no end. """ - self.start: date | None = start + self.start: dt.date | None = start """The start of the period.""" - self.end: date | None = end + self.end: dt.date | None = end """The end of the period.""" self.is_default: bool = False """Whether the is the default period.""" @@ -95,8 +95,8 @@ class Period: self.is_a_month = self.start.day == 1 \ and self.end == month_end(self.start) self.is_type_month = self.is_a_month - self.is_a_year = self.start == date(self.start.year, 1, 1) \ - and self.end == date(self.start.year, 12, 31) + self.is_a_year = self.start == dt.date(self.start.year, 1, 1) \ + and self.end == dt.date(self.start.year, 12, 31) self.is_a_day = self.start == self.end def is_year(self, year: int) -> bool: @@ -126,4 +126,4 @@ class Period: """ if self.start is None: return None - return Period(None, self.start - timedelta(days=1)) + return Period(None, self.start - dt.timedelta(days=1)) diff --git a/src/accounting/report/period/shortcuts.py b/src/accounting/report/period/shortcuts.py index 74ed9d1..b08ac77 100644 --- a/src/accounting/report/period/shortcuts.py +++ b/src/accounting/report/period/shortcuts.py @@ -17,7 +17,7 @@ """The named shortcut periods. """ -from datetime import date, timedelta +import datetime as dt from accounting.locale import gettext from .month_end import month_end @@ -27,8 +27,8 @@ from .period import Period class ThisMonth(Period): """The period of this month.""" def __init__(self): - today: date = date.today() - this_month_start: date = date(today.year, today.month, 1) + today: dt.date = dt.date.today() + this_month_start: dt.date = dt.date(today.year, today.month, 1) super().__init__(this_month_start, month_end(today)) self.is_default = True self.is_this_month = True @@ -43,13 +43,13 @@ class ThisMonth(Period): class LastMonth(Period): """The period of this month.""" def __init__(self): - today: date = date.today() + today: dt.date = dt.date.today() year: int = today.year month: int = today.month - 1 if month < 1: year = year - 1 month = 12 - start: date = date(year, month, 1) + start: dt.date = dt.date(year, month, 1) super().__init__(start, month_end(start)) self.is_last_month = True @@ -63,13 +63,13 @@ class LastMonth(Period): class SinceLastMonth(Period): """The period of this month.""" def __init__(self): - today: date = date.today() + today: dt.date = dt.date.today() year: int = today.year month: int = today.month - 1 if month < 1: year = year - 1 month = 12 - start: date = date(year, month, 1) + start: dt.date = dt.date(year, month, 1) super().__init__(start, None) self.is_since_last_month = True @@ -82,9 +82,9 @@ class SinceLastMonth(Period): class ThisYear(Period): """The period of this year.""" def __init__(self): - year: int = date.today().year - start: date = date(year, 1, 1) - end: date = date(year, 12, 31) + year: int = dt.date.today().year + start: dt.date = dt.date(year, 1, 1) + end: dt.date = dt.date(year, 12, 31) super().__init__(start, end) self.is_this_year = True @@ -97,9 +97,9 @@ class ThisYear(Period): class LastYear(Period): """The period of last year.""" def __init__(self): - year: int = date.today().year - start: date = date(year - 1, 1, 1) - end: date = date(year - 1, 12, 31) + year: int = dt.date.today().year + start: dt.date = dt.date(year - 1, 1, 1) + end: dt.date = dt.date(year - 1, 12, 31) super().__init__(start, end) self.is_last_year = True @@ -112,7 +112,7 @@ class LastYear(Period): class Today(Period): """The period of today.""" def __init__(self): - today: date = date.today() + today: dt.date = dt.date.today() super().__init__(today, today) self.is_today = True @@ -125,7 +125,7 @@ class Today(Period): class Yesterday(Period): """The period of yesterday.""" def __init__(self): - yesterday: date = date.today() - timedelta(days=1) + yesterday: dt.date = dt.date.today() - dt.timedelta(days=1) super().__init__(yesterday, yesterday) self.is_yesterday = True @@ -163,6 +163,6 @@ class YearPeriod(Period): :param year: The year. """ - start: date = date(year, 1, 1) - end: date = date(year, 12, 31) + start: dt.date = dt.date(year, 1, 1) + end: dt.date = dt.date(year, 12, 31) super().__init__(start, end) diff --git a/src/accounting/report/period/specification.py b/src/accounting/report/period/specification.py index ddb7229..95f4623 100644 --- a/src/accounting/report/period/specification.py +++ b/src/accounting/report/period/specification.py @@ -17,10 +17,10 @@ """The period specification composer. """ -from datetime import date, timedelta +import datetime as dt -def get_spec(start: date | None, end: date | None) -> str: +def get_spec(start: dt.date | None, end: dt.date | None) -> str: """Returns the period specification. :param start: The start of the period. @@ -44,7 +44,7 @@ def get_spec(start: date | None, end: date | None) -> str: return __get_day_spec(start, end) -def __get_since_spec(start: date) -> str: +def __get_since_spec(start: dt.date) -> str: """Returns the period specification without the end day. :param start: The start of the period. @@ -57,7 +57,7 @@ def __get_since_spec(start: date) -> str: return start.strftime("%Y-%m-%d-") -def __get_until_spec(end: date) -> str: +def __get_until_spec(end: dt.date) -> str: """Returns the period specification without the start day. :param end: The end of the period. @@ -65,12 +65,12 @@ def __get_until_spec(end: date) -> str: """ if end.month == 12 and end.day == 31: return end.strftime("-%Y") - if (end + timedelta(days=1)).day == 1: + if (end + dt.timedelta(days=1)).day == 1: return end.strftime("-%Y-%m") return end.strftime("-%Y-%m-%d") -def __get_year_spec(start: date, end: date) -> str: +def __get_year_spec(start: dt.date, end: dt.date) -> str: """Returns the period specification as a year range. :param start: The start of the period. @@ -88,7 +88,7 @@ def __get_year_spec(start: date, end: date) -> str: return f"{start_spec}-{end_spec}" -def __get_month_spec(start: date, end: date) -> str: +def __get_month_spec(start: dt.date, end: dt.date) -> str: """Returns the period specification as a month range. :param start: The start of the period. @@ -96,7 +96,7 @@ def __get_month_spec(start: date, end: date) -> str: :return: The period specification as a month range. :raise ValueError: The period is not a month range. """ - if start.day != 1 or (end + timedelta(days=1)).day != 1: + if start.day != 1 or (end + dt.timedelta(days=1)).day != 1: raise ValueError start_spec: str = start.strftime("%Y-%m") if start.year == end.year and start.month == end.month: @@ -105,7 +105,7 @@ def __get_month_spec(start: date, end: date) -> str: return f"{start_spec}-{end_spec}" -def __get_day_spec(start: date, end: date) -> str: +def __get_day_spec(start: dt.date, end: dt.date) -> str: """Returns the period specification as a day range. :param start: The start of the period. diff --git a/src/accounting/report/reports/income_expenses.py b/src/accounting/report/reports/income_expenses.py index 137eca4..cb9ca43 100644 --- a/src/accounting/report/reports/income_expenses.py +++ b/src/accounting/report/reports/income_expenses.py @@ -17,7 +17,7 @@ """The income and expenses log. """ -from datetime import date +import datetime as dt from decimal import Decimal import sqlalchemy as sa @@ -53,7 +53,7 @@ class ReportLineItem: """Whether this is the brought-forward line item.""" self.is_total: bool = False """Whether this is the total line item.""" - self.date: date | None = None + self.date: dt.date | None = None """The date.""" self.account: Account | None = None """The account.""" @@ -213,7 +213,7 @@ class LineItemCollector: class CSVRow(BaseCSVRow): """A row in the CSV.""" - def __init__(self, journal_entry_date: date | str | None, + def __init__(self, journal_entry_date: dt.date | str | None, account: str | None, description: str | None, income: str | Decimal | None, @@ -230,7 +230,7 @@ class CSVRow(BaseCSVRow): :param balance: The balance. :param note: The note. """ - self.date: date | str | None = journal_entry_date + self.date: dt.date | str | None = journal_entry_date """The date.""" self.account: str | None = account """The account.""" diff --git a/src/accounting/report/reports/journal.py b/src/accounting/report/reports/journal.py index 91ef441..e86d44b 100644 --- a/src/accounting/report/reports/journal.py +++ b/src/accounting/report/reports/journal.py @@ -17,7 +17,7 @@ """The journal. """ -from datetime import date +import datetime as dt from decimal import Decimal import sqlalchemy as sa @@ -67,7 +67,7 @@ class ReportLineItem: class CSVRow(BaseCSVRow): """A row in the CSV.""" - def __init__(self, journal_entry_date: str | date, + def __init__(self, journal_entry_date: str | dt.date, currency: str, account: str, description: str | None, @@ -84,7 +84,7 @@ class CSVRow(BaseCSVRow): :param credit: The credit amount. :param note: The note. """ - self.date: str | date = journal_entry_date + self.date: str | dt.date = journal_entry_date """The date.""" self.currency: str = currency """The currency.""" diff --git a/src/accounting/report/reports/ledger.py b/src/accounting/report/reports/ledger.py index e48653b..866b0f7 100644 --- a/src/accounting/report/reports/ledger.py +++ b/src/accounting/report/reports/ledger.py @@ -17,7 +17,7 @@ """The ledger. """ -from datetime import date +import datetime as dt from decimal import Decimal import sqlalchemy as sa @@ -52,7 +52,7 @@ class ReportLineItem: """Whether this is the brought-forward line item.""" self.is_total: bool = False """Whether this is the total line item.""" - self.date: date | None = None + self.date: dt.date | None = None """The date.""" self.description: str | None = None """The description.""" @@ -196,7 +196,7 @@ class LineItemCollector: class CSVRow(BaseCSVRow): """A row in the CSV.""" - def __init__(self, journal_entry_date: date | str | None, + def __init__(self, journal_entry_date: dt.date | str | None, description: str | None, debit: str | Decimal | None, credit: str | Decimal | None, @@ -211,7 +211,7 @@ class CSVRow(BaseCSVRow): :param balance: The balance. :param note: The note. """ - self.date: date | str | None = journal_entry_date + self.date: dt.date | str | None = journal_entry_date """The date.""" self.description: str | None = description """The description.""" diff --git a/src/accounting/report/reports/search.py b/src/accounting/report/reports/search.py index d5c57c1..1a34ee5 100644 --- a/src/accounting/report/reports/search.py +++ b/src/accounting/report/reports/search.py @@ -17,7 +17,7 @@ """The search. """ -from datetime import datetime +import datetime as dt from decimal import Decimal import sqlalchemy as sa @@ -124,15 +124,15 @@ class LineItemCollector: """ conditions: list[sa.BinaryExpression] \ = [JournalEntry.note.icontains(k)] - journal_entry_date: datetime + journal_entry_date: dt.datetime try: - journal_entry_date = datetime.strptime(k, "%Y") + journal_entry_date = dt.datetime.strptime(k, "%Y") conditions.append(sa.extract("year", JournalEntry.date) == journal_entry_date.year) except ValueError: pass try: - journal_entry_date = datetime.strptime(k, "%Y/%m") + journal_entry_date = dt.datetime.strptime(k, "%Y/%m") conditions.append(sa.and_( sa.extract("year", JournalEntry.date) == journal_entry_date.year, @@ -141,7 +141,7 @@ class LineItemCollector: except ValueError: pass try: - journal_entry_date = datetime.strptime(f"2000/{k}", "%Y/%m/%d") + journal_entry_date = dt.datetime.strptime(f"2000/{k}", "%Y/%m/%d") conditions.append(sa.and_( sa.extract("month", JournalEntry.date) == journal_entry_date.month, @@ -150,7 +150,7 @@ class LineItemCollector: except ValueError: pass try: - journal_entry_date = datetime.strptime(k, "%Y/%m/%d") + journal_entry_date = dt.datetime.strptime(k, "%Y/%m/%d") conditions.append(sa.and_( sa.extract("year", JournalEntry.date) == journal_entry_date.year, diff --git a/src/accounting/report/reports/unapplied.py b/src/accounting/report/reports/unapplied.py index a3067ac..815c936 100644 --- a/src/accounting/report/reports/unapplied.py +++ b/src/accounting/report/reports/unapplied.py @@ -17,7 +17,7 @@ """The unapplied original line items. """ -from datetime import date +import datetime as dt from decimal import Decimal from flask import render_template, Response @@ -41,7 +41,7 @@ from accounting.utils.pagination import Pagination class CSVRow(BaseCSVRow): """A row in the CSV.""" - def __init__(self, journal_entry_date: str | date, currency: str, + def __init__(self, journal_entry_date: str | dt.date, currency: str, description: str | None, amount: str | Decimal, net_balance: str | Decimal): """Constructs a row in the CSV. @@ -52,7 +52,7 @@ class CSVRow(BaseCSVRow): :param amount: The amount. :param net_balance: The net balance. """ - self.date: str | date = journal_entry_date + self.date: str | dt.date = journal_entry_date """The date.""" self.currency: str = currency """The currency.""" @@ -64,7 +64,7 @@ class CSVRow(BaseCSVRow): """The net balance.""" @property - def values(self) -> list[str | date | Decimal | None]: + def values(self) -> list[str | dt.date | Decimal | None]: """Returns the values of the row. :return: The values of the row. diff --git a/src/accounting/report/reports/unapplied_accounts.py b/src/accounting/report/reports/unapplied_accounts.py index b90fe3b..01af1c4 100644 --- a/src/accounting/report/reports/unapplied_accounts.py +++ b/src/accounting/report/reports/unapplied_accounts.py @@ -17,7 +17,7 @@ """The accounts with unapplied original line items. """ -from datetime import date +import datetime as dt from decimal import Decimal from flask import render_template, Response @@ -49,7 +49,7 @@ class CSVRow(BaseCSVRow): """The number of unapplied original line items.""" @property - def values(self) -> list[str | date | Decimal | None]: + def values(self) -> list[str | dt.date | Decimal | None]: """Returns the values of the row. :return: The values of the row. diff --git a/src/accounting/report/reports/unmatched.py b/src/accounting/report/reports/unmatched.py index 965e7c1..d4fac42 100644 --- a/src/accounting/report/reports/unmatched.py +++ b/src/accounting/report/reports/unmatched.py @@ -17,7 +17,7 @@ """The unmatched offsets. """ -from datetime import date +import datetime as dt from decimal import Decimal from flask import render_template, Response @@ -40,7 +40,7 @@ from accounting.utils.pagination import Pagination class CSVRow(BaseCSVRow): """A row in the CSV.""" - def __init__(self, journal_entry_date: str | date, currency: str, + def __init__(self, journal_entry_date: str | dt.date, currency: str, description: str | None, debit: str | Decimal, credit: str | Decimal, balance: str | Decimal): """Constructs a row in the CSV. @@ -52,7 +52,7 @@ class CSVRow(BaseCSVRow): :param credit: The credit amount. :param balance: The balance. """ - self.date: str | date = journal_entry_date + self.date: str | dt.date = journal_entry_date """The date.""" self.currency: str = currency """The currency.""" @@ -66,7 +66,7 @@ class CSVRow(BaseCSVRow): """The balance.""" @property - def values(self) -> list[str | date | Decimal | None]: + def values(self) -> list[str | dt.date | Decimal | None]: """Returns the values of the row. :return: The values of the row. diff --git a/src/accounting/report/reports/unmatched_accounts.py b/src/accounting/report/reports/unmatched_accounts.py index e066713..055c9bd 100644 --- a/src/accounting/report/reports/unmatched_accounts.py +++ b/src/accounting/report/reports/unmatched_accounts.py @@ -17,7 +17,7 @@ """The accounts with unmatched offsets. """ -from datetime import date +import datetime as dt from decimal import Decimal from flask import render_template, Response @@ -49,7 +49,7 @@ class CSVRow(BaseCSVRow): """The number of unapplied original line items.""" @property - def values(self) -> list[str | date | Decimal | None]: + def values(self) -> list[str | dt.date | Decimal | None]: """Returns the values of the row. :return: The values of the row. diff --git a/src/accounting/report/utils/csv_export.py b/src/accounting/report/utils/csv_export.py index 613df51..7e3cede 100644 --- a/src/accounting/report/utils/csv_export.py +++ b/src/accounting/report/utils/csv_export.py @@ -18,8 +18,8 @@ """ import csv +import datetime as dt from abc import ABC, abstractmethod -from datetime import timedelta, date from decimal import Decimal from io import StringIO from urllib.parse import quote @@ -77,7 +77,7 @@ def period_spec(period: Period) -> str: return f"{start}-{end}" -def __get_start_str(start: date | None) -> str | None: +def __get_start_str(start: dt.date | None) -> str | None: """Returns the string representation of the start date. :param start: The start date. @@ -93,7 +93,7 @@ def __get_start_str(start: date | None) -> str | None: return start.strftime("%Y%m%d") -def __get_end_str(end: date | None) -> str | None: +def __get_end_str(end: dt.date | None) -> str | None: """Returns the string representation of the end date. :param end: The end date. @@ -104,6 +104,6 @@ def __get_end_str(end: date | None) -> str | None: return None if end.month == 12 and end.day == 31: return str(end.year) - if (end + timedelta(days=1)).day == 1: + if (end + dt.timedelta(days=1)).day == 1: return end.strftime("%Y%m") return end.strftime("%Y%m%d") diff --git a/src/accounting/template_filters.py b/src/accounting/template_filters.py index b3af320..7d93f23 100644 --- a/src/accounting/template_filters.py +++ b/src/accounting/template_filters.py @@ -17,8 +17,8 @@ """The template filters. """ +import datetime as dt import typing as t -from datetime import date, timedelta from decimal import Decimal from flask_babel import get_locale @@ -41,24 +41,24 @@ def format_amount(value: Decimal | None) -> str | None: return "{:,}".format(whole) + str(abs(frac))[1:] -def format_date(value: date) -> str: +def format_date(value: dt.date) -> str: """Formats a date to be human-friendly. :param value: The date. :return: The human-friendly date text. """ - today: date = date.today() + today: dt.date = dt.date.today() if value == today: return gettext("Today") - if value == today - timedelta(days=1): + if value == today - dt.timedelta(days=1): return gettext("Yesterday") - if value == today + timedelta(days=1): + if value == today + dt.timedelta(days=1): return gettext("Tomorrow") locale = str(get_locale()) if locale == "zh" or locale.startswith("zh_"): - if value == today - timedelta(days=2): + if value == today - dt.timedelta(days=2): return gettext("The day before yesterday") - if value == today + timedelta(days=2): + if value == today + dt.timedelta(days=2): return gettext("The day after tomorrow") if locale == "zh" or locale.startswith("zh_"): weekdays = ["一", "二", "三", "四", "五", "六", "日"] diff --git a/tests/test_account.py b/tests/test_account.py index 3da0f99..4c4b6a6 100644 --- a/tests/test_account.py +++ b/tests/test_account.py @@ -17,8 +17,8 @@ """The test for the account management. """ +import datetime as dt import unittest -from datetime import timedelta, date import httpx from flask import Flask @@ -461,7 +461,7 @@ class AccountTestCase(unittest.TestCase): account = Account.find_by_code(CASH.code) self.assertIsNotNone(account) account.created_at \ - = account.created_at - timedelta(seconds=5) + = account.created_at - dt.timedelta(seconds=5) account.updated_at = account.created_at db.session.commit() @@ -592,7 +592,7 @@ class AccountTestCase(unittest.TestCase): add_journal_entry(self.client, form={"csrf_token": self.csrf_token, "next": NEXT_URI, - "date": date.today().isoformat(), + "date": dt.date.today().isoformat(), "currency-1-code": "USD", "currency-1-credit-1-account_code": BANK.code, "currency-1-credit-1-amount": "20"}) diff --git a/tests/test_currency.py b/tests/test_currency.py index 7e55be3..9c243fe 100644 --- a/tests/test_currency.py +++ b/tests/test_currency.py @@ -17,8 +17,8 @@ """The test for the currency management. """ +import datetime as dt import unittest -from datetime import timedelta, date import httpx from flask import Flask @@ -384,7 +384,7 @@ class CurrencyTestCase(unittest.TestCase): currency = db.session.get(Currency, USD.code) self.assertIsNotNone(currency) currency.created_at \ - = currency.created_at - timedelta(seconds=5) + = currency.created_at - dt.timedelta(seconds=5) currency.updated_at = currency.created_at db.session.commit() @@ -534,7 +534,7 @@ class CurrencyTestCase(unittest.TestCase): add_journal_entry(self.client, form={"csrf_token": self.csrf_token, "next": NEXT_URI, - "date": date.today().isoformat(), + "date": dt.date.today().isoformat(), "currency-1-code": EUR.code, "currency-1-credit-1-account_code": "1111-001", "currency-1-credit-1-amount": "20"}) diff --git a/tests/test_description_editor.py b/tests/test_description_editor.py index 535e2d5..06ad83b 100644 --- a/tests/test_description_editor.py +++ b/tests/test_description_editor.py @@ -17,8 +17,8 @@ """The test for the description editor. """ +import datetime as dt import unittest -from datetime import date from flask import Flask @@ -149,7 +149,7 @@ def get_form_data(csrf_token: str) -> list[dict[str, str]]: :param csrf_token: The CSRF token. :return: A list of the form data. """ - journal_entry_date: str = date.today().isoformat() + journal_entry_date: str = dt.date.today().isoformat() return [{"csrf_token": csrf_token, "next": NEXT_URI, "date": journal_entry_date, diff --git a/tests/test_journal_entry.py b/tests/test_journal_entry.py index 2d95d81..58dbd36 100644 --- a/tests/test_journal_entry.py +++ b/tests/test_journal_entry.py @@ -17,8 +17,8 @@ """The test for the journal entry management. """ +import datetime as dt import unittest -from datetime import date, timedelta from decimal import Decimal import httpx @@ -500,7 +500,7 @@ class CashReceiptJournalEntryTestCase(unittest.TestCase): journal_entry = db.session.get(JournalEntry, journal_entry_id) self.assertIsNotNone(journal_entry) journal_entry.created_at \ - = journal_entry.created_at - timedelta(seconds=5) + = journal_entry.created_at - dt.timedelta(seconds=5) journal_entry.updated_at = journal_entry.created_at db.session.commit() @@ -576,7 +576,7 @@ class CashReceiptJournalEntryTestCase(unittest.TestCase): self.client, form={"csrf_token": self.csrf_token, "next": NEXT_URI, - "date": date.today().isoformat(), + "date": dt.date.today().isoformat(), "currency-1-code": line_item.currency_code, "currency-1-debit-1-original_line_item_id": line_item.id, "currency-1-debit-1-account_code": line_item.account_code, @@ -1112,7 +1112,7 @@ class CashDisbursementJournalEntryTestCase(unittest.TestCase): journal_entry = db.session.get(JournalEntry, journal_entry_id) self.assertIsNotNone(journal_entry) journal_entry.created_at \ - = journal_entry.created_at - timedelta(seconds=5) + = journal_entry.created_at - dt.timedelta(seconds=5) journal_entry.updated_at = journal_entry.created_at db.session.commit() @@ -1773,7 +1773,7 @@ class TransferJournalEntryTestCase(unittest.TestCase): journal_entry = db.session.get(JournalEntry, journal_entry_id) self.assertIsNotNone(journal_entry) journal_entry.created_at \ - = journal_entry.created_at - timedelta(seconds=5) + = journal_entry.created_at - dt.timedelta(seconds=5) journal_entry.updated_at = journal_entry.created_at db.session.commit() @@ -2124,9 +2124,9 @@ class JournalEntryReorderTestCase(unittest.TestCase): with self.app.app_context(): journal_entry_1: JournalEntry = db.session.get(JournalEntry, id_1) - journal_entry_date_2: date = journal_entry_1.date - journal_entry_date_1: date \ - = journal_entry_date_2 - timedelta(days=1) + journal_entry_date_2: dt.date = journal_entry_1.date + journal_entry_date_1: dt.date \ + = journal_entry_date_2 - dt.timedelta(days=1) journal_entry_1.date = journal_entry_date_1 journal_entry_1.no = 3 journal_entry_2: JournalEntry = db.session.get(JournalEntry, id_2) @@ -2176,7 +2176,8 @@ class JournalEntryReorderTestCase(unittest.TestCase): self.__get_add_disbursement_form()) with self.app.app_context(): - journal_entry_date: date = db.session.get(JournalEntry, id_1).date + journal_entry_date: dt.date \ + = db.session.get(JournalEntry, id_1).date response = self.client.post( f"{PREFIX}/dates/{journal_entry_date.isoformat()}", diff --git a/tests/test_option.py b/tests/test_option.py index 151859b..f6dcefd 100644 --- a/tests/test_option.py +++ b/tests/test_option.py @@ -17,8 +17,8 @@ """The test for the options. """ +import datetime as dt import unittest -from datetime import datetime, timedelta import httpx from flask import Flask @@ -286,7 +286,8 @@ class OptionTestCase(unittest.TestCase): with self.app.app_context(): option = db.session.get(Option, "recurring") self.assertIsNotNone(option) - timestamp: datetime = option.created_at - timedelta(seconds=5) + timestamp: dt.datetime \ + = option.created_at - dt.timedelta(seconds=5) option.created_at = timestamp option.updated_at = timestamp db.session.commit() diff --git a/tests/test_report.py b/tests/test_report.py index 8edc381..33bc528 100644 --- a/tests/test_report.py +++ b/tests/test_report.py @@ -17,8 +17,8 @@ """The test for the reports. """ +import datetime as dt import unittest -from datetime import date import httpx from flask import Flask @@ -446,11 +446,11 @@ class ReportTestData(BaseTestData): """The report test data.""" def _init_data(self) -> None: - today: date = date.today() + today: dt.date = dt.date.today() year: int = today.year - 5 month: int = today.month while True: - j_date: date = date(year, month, 5) + j_date: dt.date = dt.date(year, month, 5) if j_date > today: break self._add_simple_journal_entry( diff --git a/tests/test_site/lib.py b/tests/test_site/lib.py index 0a4035d..5d40f5b 100644 --- a/tests/test_site/lib.py +++ b/tests/test_site/lib.py @@ -19,9 +19,9 @@ """ from __future__ import annotations +import datetime as dt import typing as t from abc import ABC, abstractmethod -from datetime import date, timedelta from decimal import Decimal from secrets import randbelow @@ -167,7 +167,8 @@ class JournalEntryData: :param is_update: True for an update operation, or False otherwise :return: The journal entry as a form. """ - journal_entry_date: date = date.today() - timedelta(days=self.days) + journal_entry_date: dt.date \ + = dt.date.today() - dt.timedelta(days=self.days) form: dict[str, str] = {"csrf_token": csrf_token, "next": next_uri, "date": journal_entry_date.isoformat()} @@ -240,7 +241,8 @@ class BaseTestData(ABC): existing_j_id: set[int] = {x["id"] for x in self.__journal_entries} existing_l_id: set[int] = {x["id"] for x in self.__line_items} journal_entry_data.id = self.__new_id(existing_j_id) - j_date: date = date.today() - timedelta(days=journal_entry_data.days) + j_date: dt.date \ + = dt.date.today() - dt.timedelta(days=journal_entry_data.days) self.__journal_entries.append( {"id": journal_entry_data.id, "date": j_date, @@ -303,7 +305,7 @@ class BaseTestData(ABC): existing_id.add(obj_id) return obj_id - def __next_j_no(self, j_date: date) -> int: + def __next_j_no(self, j_date: dt.date) -> int: """Returns the next journal entry number in a day. :param j_date: The journal entry date. diff --git a/tests/test_site/reset.py b/tests/test_site/reset.py index b3eb1b3..8a7cfe3 100644 --- a/tests/test_site/reset.py +++ b/tests/test_site/reset.py @@ -17,7 +17,7 @@ """The data reset for the Mia! Accounting demonstration website. """ -from datetime import date, timedelta +import datetime as dt from flask import Flask, Blueprint, url_for, flash, redirect, session, \ render_template, current_app @@ -116,14 +116,14 @@ class SampleData(BaseTestData): :return: None. """ - today: date = date.today() + today: dt.date = dt.date.today() days: int year: int month: int # Recurring in USD - j_date: date = date(today.year - 5, today.month, today.day) - j_date = j_date + timedelta(days=(4 - j_date.weekday())) + j_date: dt.date = dt.date(today.year - 5, today.month, today.day) + j_date = j_date + dt.timedelta(days=(4 - j_date.weekday())) days = (today - j_date).days while True: if days < 0: @@ -147,7 +147,7 @@ class SampleData(BaseTestData): if month > 12: year = year + 1 month = 1 - days = (today - date(year, month, 1)).days + days = (today - dt.date(year, month, 1)).days if days < 0: break self.__add_journal_entry( @@ -159,12 +159,12 @@ class SampleData(BaseTestData): :return: None. """ - today: date = date.today() + today: dt.date = dt.date.today() year: int = today.year - 5 month: int = today.month while True: - days: int = (today - date(year, month, 5)).days + days: int = (today - dt.date(year, month, 5)).days if days < 0: break self.__add_journal_entry( diff --git a/tests/testlib_journal_entry.py b/tests/testlib_journal_entry.py index 32d2936..dc53b7f 100644 --- a/tests/testlib_journal_entry.py +++ b/tests/testlib_journal_entry.py @@ -17,8 +17,8 @@ """The common test libraries for the journal entry test cases. """ +import datetime as dt import re -from datetime import date from decimal import Decimal from secrets import randbelow @@ -41,7 +41,7 @@ def get_add_form(csrf_token: str) -> dict[str, str]: """ return {"csrf_token": csrf_token, "next": NEXT_URI, - "date": date.today().isoformat(), + "date": dt.date.today().isoformat(), "currency-0-code": "USD", "currency-0-debit-0-no": "16", "currency-0-debit-0-account_code": Accounts.CASH,