Moved the currency data from the "accounting.currency.commands" module into the currencies.csv file, separating the code and the data. Rewrote the test case to test against each all the content imported. The locales are read from the CSV file instead of hard-coded in the code, so that the translations are not hard-coded to Mandarin.

This commit is contained in:
依瑪貓 2023-02-08 10:50:20 +08:00
parent d8e0e30c41
commit 354f1ff3d8
3 changed files with 48 additions and 22 deletions

View File

@ -17,11 +17,14 @@
"""The console commands for the currency management. """The console commands for the currency management.
""" """
import csv
import os import os
import typing as t
import click import click
from flask.cli import with_appcontext from flask.cli import with_appcontext
from accounting import data_dir
from accounting.database import db from accounting.database import db
from accounting.models import Currency, CurrencyL10n from accounting.models import Currency, CurrencyL10n
from accounting.utils.user import has_user, get_user_pk from accounting.utils.user import has_user, get_user_pk
@ -54,25 +57,29 @@ def __validate_username(ctx: click.core.Context, param: click.core.Option,
@with_appcontext @with_appcontext
def init_currencies_command(username: str) -> None: def init_currencies_command(username: str) -> None:
"""Initializes the currencies.""" """Initializes the currencies."""
data: list[CurrencyData] = [ existing_codes: set[str] = {x.code for x in Currency.query.all()}
("TWD", "New Taiwan dollar", "新臺幣", "新台币"),
("USD", "United States dollar", "美元", "美元"), with open(data_dir / "currencies.csv") as fh:
] data: list[dict[str, str]] = [x for x in csv.DictReader(fh)]
creator_pk: int = get_user_pk(username) to_add: list[dict[str, str]] = [x for x in data
existing: list[Currency] = Currency.query.all() if x["code"] not in existing_codes]
existing_code: set[str] = {x.code for x in existing}
to_add: list[CurrencyData] = [x for x in data if x[0] not in existing_code]
if len(to_add) == 0: if len(to_add) == 0:
click.echo("No more currency to add.") click.echo("No more currency to add.")
return return
db.session.bulk_save_objects( creator_pk: int = get_user_pk(username)
[Currency(code=x[0], name_l10n=x[1], currency_data: list[dict[str, t.Any]] = [{"code": x["code"],
created_by_id=creator_pk, updated_by_id=creator_pk) "name_l10n": x["name"],
for x in data]) "created_by_id": creator_pk,
db.session.bulk_save_objects( "updated_by_id": creator_pk}
[CurrencyL10n(currency_code=x[0], locale=y[0], name=y[1]) for x in to_add]
for x in data for y in (("zh_Hant", x[2]), ("zh_Hans", x[3]))]) locales: list[str] = [x[5:] for x in to_add[0] if x.startswith("l10n-")]
l10n_data: list[dict[str, str]] = [{"currency_code": x["code"],
"locale": y,
"name": x[f"l10n-{y}"]}
for x in to_add for y in locales]
db.session.bulk_insert_mappings(Currency, currency_data)
db.session.bulk_insert_mappings(CurrencyL10n, l10n_data)
db.session.commit() db.session.commit()
click.echo(F"{len(to_add)} added. Currencies initialized.") click.echo(F"{len(to_add)} added. Currencies initialized.")

View File

@ -0,0 +1,3 @@
code,name,l10n-zh_Hant,l10n-zh_Hans
TWD,New Taiwan dollar,新臺幣,新台币
USD,United States dollar,美元,美元
1 code name l10n-zh_Hant l10n-zh_Hans
2 TWD New Taiwan dollar 新臺幣 新台币
3 USD United States dollar 美元 美元

View File

@ -17,7 +17,9 @@
"""The test for the currency management. """The test for the currency management.
""" """
import csv
import time import time
import typing as t
import unittest import unittest
import httpx import httpx
@ -83,20 +85,34 @@ class CurrencyCommandTestCase(unittest.TestCase):
:return: None. :return: None.
""" """
from accounting.models import Currency, CurrencyL10n from accounting import data_dir
from accounting.models import Currency
with open(data_dir / "currencies.csv") as fh:
data: dict[dict[str, t.Any]] \
= {x["code"]: {"code": x["code"],
"name": x["name"],
"l10n": {y[5:]: x[y]
for y in x if y.startswith("l10n-")}}
for x in csv.DictReader(fh)}
runner: FlaskCliRunner = self.app.test_cli_runner() runner: FlaskCliRunner = self.app.test_cli_runner()
with self.app.app_context(): with self.app.app_context():
result: Result = runner.invoke( result: Result = runner.invoke(
args=["accounting-init-currencies", "-u", "editor"]) args=["accounting-init-currencies", "-u", "editor"])
self.assertEqual(result.exit_code, 0) self.assertEqual(result.exit_code, 0)
currencies: list[Currency] = Currency.query.all() currencies: list[Currency] = Currency.query.all()
l10n: list[CurrencyL10n] = CurrencyL10n.query.all()
self.assertEqual(len(currencies), 2) self.assertEqual(len(currencies), len(data))
self.assertEqual(len(l10n), 2 * 2)
l10n_keys: set[str] = {f"{x.currency_code}-{x.locale}" for x in l10n}
for currency in currencies: for currency in currencies:
self.assertIn(f"{currency.code}-zh_Hant", l10n_keys) self.assertIn(currency.code, data)
self.assertIn(f"{currency.code}-zh_Hant", l10n_keys) self.assertEqual(currency.name_l10n, data[currency.code]["name"])
l10n: dict[str, str] = {x.locale: x.name for x in currency.l10n}
self.assertEqual(len(l10n), len(data[currency.code]["l10n"]))
for locale in l10n:
self.assertIn(locale, data[currency.code]["l10n"])
self.assertEqual(l10n[locale],
data[currency.code]["l10n"][locale])
class CurrencyTestCase(unittest.TestCase): class CurrencyTestCase(unittest.TestCase):