From 7f7488e62ed47fbeded5819a8c098595980c102e Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Thu, 5 Mar 2020 17:57:29 +0500 Subject: [PATCH] [ADD] API Function for using in docx templates: Transpile numbers (and currency numbers) into a words --- data/fields_default.xml | 17 ++++++++++++++++ utils/docxtpl.py | 17 +++++++++++++++- utils/num2words.py | 45 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 utils/num2words.py diff --git a/data/fields_default.xml b/data/fields_default.xml index aef6727..c7b78e5 100644 --- a/data/fields_default.xml +++ b/data/fields_default.xml @@ -322,6 +322,23 @@ action = ctx + + + + Number in Words + number2words + Function + -1 + + + + Currency Number in Words + currency2words + Function + -1 + + + diff --git a/utils/docxtpl.py b/utils/docxtpl.py index c3d46a9..9971000 100644 --- a/utils/docxtpl.py +++ b/utils/docxtpl.py @@ -1,11 +1,26 @@ import io + from docxtpl import DocxTemplate +from jinja2 import Environment as Jinja2Environment + +from .num2words import num2words_, num2words_currency def get_document_from_values_stream(path_to_template: str, vals: dict): doc = DocxTemplate(path_to_template) - doc.render(vals) + + jinja_env = Jinja2Environment() + + functions = { + "number2words": num2words_, + "currency2words": num2words_currency, + } + jinja_env.globals.update(**functions) + + doc.render(vals, jinja_env) + file_stream = io.BytesIO() doc.save(file_stream) file_stream.seek(0) + return file_stream diff --git a/utils/num2words.py b/utils/num2words.py new file mode 100644 index 0000000..b050a87 --- /dev/null +++ b/utils/num2words.py @@ -0,0 +1,45 @@ +from num2words import num2words +from num2words import CONVERTER_CLASSES, CONVERTES_TYPES + + +# Can use params: +# ~ number: int, float or validate string +# ~ to: num2words.CONVERTER_TYPES +# ~ lang: num2words.CONVERTER_CLASSES +# ~ currency: num2words.CONVERTER_CLASSES.CURRENCY_FORMS + + +# Jinja2 Global Method +def num2words_(number, **kwargs): + if _performConvert(number): + if "lang" not in kwargs: + kwargs["lang"] = "ru" + if "to" not in kwargs or kwargs["to"] not in CONVERTES_TYPES: + kwargs["to"] = "cardinal" + return num2words(number, **kwargs) + + +# Jinja2 Global Method +def num2words_currency(number, **kwargs): + if _performConvert(number): + if "lang" not in kwargs: + kwargs["lang"] = "ru" + if "to" not in kwargs or kwargs["to"] not in CONVERTES_TYPES: + kwargs["to"] = "currency" + if "currency" not in kwargs: + kwargs["currency"] = "RUB" + return num2words(number, **kwargs) + + +def _performConvert(number): + if isinstance(number, int) or isinstance(number, float): + return True + + if isinstance(number, str): + try: + number = float(number) + return True + except ValueError: + return False + + return False