[ADD] API Function for using in docx templates: Transpile numbers (and currency numbers) into a words
This commit is contained in:
parent
c0e11e5227
commit
7f7488e62e
@ -322,6 +322,23 @@ action = ctx
|
|||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Functions -->
|
||||||
|
|
||||||
|
<record id="contract_field_number2words" model="res.partner.contract.field">
|
||||||
|
<field name="name">Number in Words</field>
|
||||||
|
<field name="technical_name">number2words</field>
|
||||||
|
<field name="description">Function</field>
|
||||||
|
<field name="sequence">-1</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="contract_field_currency2words" model="res.partner.contract.field">
|
||||||
|
<field name="name">Currency Number in Words</field>
|
||||||
|
<field name="technical_name">currency2words</field>
|
||||||
|
<field name="description">Function</field>
|
||||||
|
<field name="sequence">-1</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
<!-- Common fields -->
|
<!-- Common fields -->
|
||||||
|
|
||||||
<record id="contract_field_contract_number" model="res.partner.contract.field">
|
<record id="contract_field_contract_number" model="res.partner.contract.field">
|
||||||
|
@ -1,11 +1,26 @@
|
|||||||
import io
|
import io
|
||||||
|
|
||||||
from docxtpl import DocxTemplate
|
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):
|
def get_document_from_values_stream(path_to_template: str, vals: dict):
|
||||||
doc = DocxTemplate(path_to_template)
|
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()
|
file_stream = io.BytesIO()
|
||||||
doc.save(file_stream)
|
doc.save(file_stream)
|
||||||
file_stream.seek(0)
|
file_stream.seek(0)
|
||||||
|
|
||||||
return file_stream
|
return file_stream
|
||||||
|
45
utils/num2words.py
Normal file
45
utils/num2words.py
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user