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:
parent
d8e0e30c41
commit
354f1ff3d8
@ -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.")
|
||||||
|
3
src/accounting/data/currencies.csv
Normal file
3
src/accounting/data/currencies.csv
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
code,name,l10n-zh_Hant,l10n-zh_Hans
|
||||||
|
TWD,New Taiwan dollar,新臺幣,新台币
|
||||||
|
USD,United States dollar,美元,美元
|
|
@ -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):
|
||||||
|
Loading…
Reference in New Issue
Block a user