mia-accounting/tests/test_site/reset.py

179 lines
5.7 KiB
Python
Raw Normal View History

# The Mia! Accounting Demonstration Website.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/4/12
# Copyright (c) 2023 imacat.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The data reset for the Mia! Accounting demonstration website.
"""
import csv
import typing as t
from datetime import date, timedelta
from decimal import Decimal
from pathlib import Path
import sqlalchemy as sa
from flask import Flask, Blueprint, url_for, flash, redirect, session, \
render_template
from flask_babel import lazy_gettext
from accounting.utils.cast import s
from . import db
from .auth import User, current_user
bp: Blueprint = Blueprint("reset", __name__, url_prefix="/")
@bp.get("reset", endpoint="reset-page")
def reset() -> str:
"""Resets the sample data.
:return: Redirection to the accounting application.
"""
return render_template("reset.html")
@bp.post("sample", endpoint="sample")
def reset_sample() -> redirect:
"""Resets the sample data.
:return: Redirection to the accounting application.
"""
__reset_database()
__populate_sample_data()
flash(s(lazy_gettext(
"The sample data are emptied and reset successfully.")), "success")
return redirect(url_for("accounting-report.default"))
@bp.post("reset", endpoint="clean-up")
def clean_up() -> redirect:
"""Clean-up the database data.
:return: Redirection to the accounting application.
"""
__reset_database()
db.session.commit()
flash(s(lazy_gettext("The database is emptied successfully.")), "success")
return redirect(url_for("accounting-report.default"))
def __populate_sample_data() -> None:
"""Populates the sample data.
:return: None.
"""
from accounting.models import Account, JournalEntry, JournalEntryLineItem
data_dir: Path = Path(__file__).parent / "data"
today: date = date.today()
user: User | None = current_user()
assert user is not None
def filter_journal_entry(data: dict[str, t.Any]) -> dict[str, t.Any]:
"""Filters the journal entry data from JSON.
:param data: The journal entry data.
:return: The journal entry data from JSON.
"""
data = data.copy()
data["id"] = int(data["id"])
data["date"] = today - timedelta(days=int(data["date"]))
data["no"] = int(data["no"])
if data["note"] == "":
data["note"] = None
data["created_by_id"] = user.id
data["updated_by_id"] = user.id
return data
def filter_line_item(data: dict[str, t.Any]) -> dict[str, t.Any]:
"""Filters the journal entry line item data from JSON.
:param data: The journal entry line item data.
:return: The journal entry line item data from JSON.
"""
data = data.copy()
data["id"] = int(data["id"])
data["journal_entry_id"] = int(data["journal_entry_id"])
if data["original_line_item_id"] == "":
data["original_line_item_id"] = None
else:
data["original_line_item_id"] = int(data["original_line_item_id"])
data["is_debit"] = bool(data["is_debit"])
data["no"] = int(data["no"])
data["account_id"] = Account.find_by_code(data["account_id"]).id
if data["description"] == "":
data["description"] = None
data["amount"] = Decimal(data["amount"])
return data
def import_journal_entries(file: Path) -> None:
"""Imports the journal entries.
:param file: The CSV file.
:return: None.
"""
with open(file) as fp:
reader: csv.DictReader = csv.DictReader(fp)
db.session.execute(sa.insert(JournalEntry),
[filter_journal_entry(x) for x in reader])
def import_line_items(file: Path) -> None:
"""Imports the journal entry line items.
:param file: The CSV file.
:return: None.
"""
with open(file) as fp:
reader: csv.DictReader = csv.DictReader(fp)
db.session.execute(sa.insert(JournalEntryLineItem),
[filter_line_item(x) for x in reader])
import_journal_entries(data_dir / "sample-journal_entries.csv")
import_line_items(data_dir / "sample-journal_entry_line_items.csv")
db.session.commit()
def __reset_database() -> None:
"""Resets the database.
:return: None.
"""
from accounting.models import Currency, CurrencyL10n, BaseAccount, \
BaseAccountL10n, Account, AccountL10n, JournalEntry, \
JournalEntryLineItem
from accounting.base_account import init_base_accounts_command
from accounting.account import init_accounts_command
from accounting.currency import init_currencies_command
JournalEntryLineItem.query.delete()
JournalEntry.query.delete()
CurrencyL10n.query.delete()
Currency.query.delete()
AccountL10n.query.delete()
Account.query.delete()
BaseAccountL10n.query.delete()
BaseAccount.query.delete()
init_base_accounts_command()
init_accounts_command(session["user"])
init_currencies_command(session["user"])
def init_app(app: Flask) -> None:
"""Initialize the localization.
:param app: The Flask application.
:return: None.
"""
app.register_blueprint(bp)