currency, settings.yaml and default currency

This commit is contained in:
Emi Vasilek 2023-11-17 21:36:26 +01:00
parent 21e68445e7
commit 3d49bc044d
5 changed files with 72 additions and 13 deletions

View file

@ -49,6 +49,7 @@ class Issues:
class Context: class Context:
def __init__(self) -> None: def __init__(self) -> None:
self.settings = Settings()
self.units: AUnits = FakeUnits(self) self.units: AUnits = FakeUnits(self)
self.default_unit = Unit(self, {"name": "piece"}) self.default_unit = Unit(self, {"name": "piece"})
self.ingredients: AIngredients = FakeIngredients(self) self.ingredients: AIngredients = FakeIngredients(self)
@ -70,6 +71,20 @@ class Context:
jsonschema.validate(instance=ingredientsdct, schema=ingredientsschema) jsonschema.validate(instance=ingredientsdct, schema=ingredientsschema)
self.ingredients.load(ingredientsdct) self.ingredients.load(ingredientsdct)
def load_settings(
self, settingsdct: Dict[str, Any], settingsschema: Dict[str, Any]
) -> None:
jsonschema.validate(instance=settingsdct, schema=settingsschema)
self.settings.load(settingsdct)
class Settings:
def __init__(self) -> None:
self.default_currency: Optional[str] = None
def load(self, settingsdct: Dict[str, Any]) -> None:
self.default_currency = settingsdct["default_currency"]
class Element: class Element:
def __init__(self, ctx: Context, dct: Dict[str, Any]) -> None: def __init__(self, ctx: Context, dct: Dict[str, Any]) -> None:
@ -249,22 +264,33 @@ class Ingredient(Element):
oldelem = elem oldelem = elem
return amount return amount
def getprice(self, amount: float, unit: Unit) -> Optional[float]: def getprice(self, amount: float, unit: Unit) -> Optional["PriceDB"]:
if "prices" not in self.dct: if "prices" not in self.dct:
return None return None
prices: List[float] = [] prices: List[PriceDB] = []
pricedbs: PriceDBs = self["prices"] pricedbs: PriceDBs = self["prices"]
for entry in pricedbs.pricedbs: for entry in pricedbs.pricedbs:
assert isinstance(entry, PriceDB) assert isinstance(entry, PriceDB)
entryamount: float = entry["amount"] entryamount: float = entry["amount"]
entryprice: float = entry["price"] entryprice: float = entry["price"]
entryunit: Unit = entry["unit"] entryunit: Unit = entry["unit"]
price = 0.0
if entryunit == unit: if entryunit == unit:
prices.append((amount / entryamount) * entryprice) price = (amount / entryamount) * entryprice
else: else:
newamount = self.convert(amount, unit, entryunit) pricex = self.convert(amount, unit, entryunit)
if newamount is not None: if pricex is not None:
prices.append((newamount / entryamount) * entryprice) price = (pricex / entryamount) * entryprice
newentry = PriceDB(
self.ctx,
{
"price": price,
"amount": amount,
"unit": unit["name"],
"currency": entry["currency"],
},
)
prices.append(newentry)
if len(prices) == 0: if len(prices) == 0:
return None return None
assert len(prices) == 1 assert len(prices) == 1
@ -334,6 +360,9 @@ class PriceDB(Element):
else: else:
self["unit"] = self.ctx.default_unit self["unit"] = self.ctx.default_unit
if "currency" not in dct:
self["currency"] = self.ctx.settings.default_currency
class IngredientInstance(Element): class IngredientInstance(Element):
def load(self, dct: Dict[str, Any]) -> None: def load(self, dct: Dict[str, Any]) -> None:
@ -393,15 +422,24 @@ class Recipe(Element):
price: Optional[int] = 0 price: Optional[int] = 0
ingswithprice = 0 ingswithprice = 0
ingswithoutprice = 0 ingswithoutprice = 0
currency = None
for ing in ingredients: for ing in ingredients:
if ing["price"] is None: if ing["price"] is None:
ingswithoutprice += 1 ingswithoutprice += 1
continue continue
ingswithprice += 1 ingswithprice += 1
price += ing["price"] price += ing["price"]["price"]
if ingswithoutprice != 0 or len(ingredients) == 0: cur_currency = ing["price"]["currency"]
price = None if currency is None:
self["price"] = price currency = cur_currency
elif currency != cur_currency:
# we don't know how to convert currencies yet
currency = None
break
if currency is None or ingswithoutprice != 0 or len(ingredients) == 0:
self["price"] = None
else:
self["price"] = PriceDB(self.ctx, {"price": price, "currency": currency})
class Builder: class Builder:
@ -455,6 +493,14 @@ class Builder:
self.outfiles.add(file) self.outfiles.add(file)
def load(self, dir: str) -> int: def load(self, dir: str) -> int:
if os.path.isfile(dir + "/settings.yaml"):
settingsdct = self.load_file(dir + "/settings.yaml")
settingsschema = self.load_file("schemas/settings.json")
self.ctx.load_settings(settingsdct, settingsschema)
retcode = self.ctx.issues.check()
if retcode != 0:
return 1
if os.path.isfile(dir + "/units.yaml"): if os.path.isfile(dir + "/units.yaml"):
unitsschema = self.load_file("schemas/units.json") unitsschema = self.load_file("schemas/units.json")
unitsdct = self.load_file(dir + "/units.yaml") unitsdct = self.load_file(dir + "/units.yaml")
@ -470,6 +516,7 @@ class Builder:
retcode = self.ctx.issues.check() retcode = self.ctx.issues.check()
if retcode != 0: if retcode != 0:
return 1 return 1
return 0 return 0
def run(self, dir: str) -> int: def run(self, dir: str) -> int:

View file

@ -20,7 +20,8 @@
"properties": { "properties": {
"price": { "type": "number" }, "price": { "type": "number" },
"amount": { "type": "integer" }, "amount": { "type": "integer" },
"unit": { "type": "string" } "unit": { "type": "string" },
"currency": { "type": "string" }
} }
} }
}, },

11
schemas/settings.json Normal file
View file

@ -0,0 +1,11 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/settings.json",
"title": "Settings",
"description": "Settings",
"type": "object",
"additionalProperties": false,
"properties": {
"default_currency": { "type": "string" }
}
}

View file

@ -1,5 +1,5 @@
{% macro price(price) -%} {% macro price(price) -%}
{% if price == None %}?{%else%}{{price|round(1)|numprint}}{% endif %} CZK {% if price != None and price is defined and price.price is defined %}{{price.price|round(1)|numprint}}{%else%}?{% endif %} {{price.currency}}
{%- endmacro %} {%- endmacro %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">

View file

@ -22,7 +22,7 @@
{% for ing in rec.ingredients %} {% for ing in rec.ingredients %}
<li>{{ingredient(ing)}}</li> <li>{{ingredient(ing)}}</li>
{% endfor %} {% endfor %}
{% if recipe.price != None %}price: {{price(rec.price)}}{%endif%} {% if rec.price != None %}price: {{price(rec.price)}}{%endif%}
{% endif %} {% endif %}
{% if rec.steps|length != 0 %} {% if rec.steps|length != 0 %}
<h3>Steps</h3> <h3>Steps</h3>