Forráskód Böngészése

show only one of last,min,avg,max price and allow toggling between them

Daniel Sheffield 2 éve
szülő
commit
67f3d1d726
2 módosított fájl, 27 hozzáadás és 8 törlés
  1. 22 7
      app/activities/RecipeEditor.py
  2. 5 1
      app/price_view.py

+ 22 - 7
app/activities/RecipeEditor.py

@@ -8,6 +8,7 @@ from xml.etree.ElementTree import fromstring, ParseError
 from markdown import markdown
 from itertools import chain, product
 from decimal import Decimal, InvalidOperation
+from collections import OrderedDict
 from typing import List, Tuple, Union, Iterable, Callable
 from urwid import (
     connect_signal,
@@ -20,6 +21,7 @@ from urwid import (
     LineBox,
     Padding,
     Pile,
+    RadioButton,
     Text,
 )
 from urwid.numedit import FloatEdit
@@ -323,11 +325,11 @@ class RecipeEditor(FocusWidget):
 
             assert len(df['avg'].unique()) == 1, f"There should be only one average price: {df['avg'].unique()}"
 
-            _avg, _min, _max = list(
-                map(Decimal,df[['avg','min','max']].iloc[0])
+            _last, _avg, _min, _max = list(
+                map(Decimal,df[['last', 'avg','min','max']].iloc[0])
             )
             self.prices[r[0].get_edit_text()] = [
-                i*quantity for i in (_min, _avg, _max)
+                i*quantity for i in (_last, _min, _avg, _max)
             ]
 
         for k in list(self.prices):
@@ -335,10 +337,14 @@ class RecipeEditor(FocusWidget):
                 del self.prices[k]
 
         price = [
-            sum([self.prices[p][i] for p in self.prices]) for i in range(3)
+            sum([self.prices[p][i] for p in self.prices]) for i in range(4)
         ]
+        price_as = next(filter(
+            lambda x: self.price_as[x[1]].state,
+            enumerate(self.price_as)
+        ))[0]
         self.price.set_text(
-            f'Cost: {not_found}{", ".join([str(p) for p in price])}'
+            f'Cost: {not_found}{price[price_as]}'
         )
         notice = ''
         ingredients = list(filter(lambda x: x, map(lambda x: x[0].get_edit_text(), self.ingredients)))
@@ -368,6 +374,15 @@ class RecipeEditor(FocusWidget):
         fname: str,
         recipe: dict,
     ):
+        button_group = []
+        self.price_as = OrderedDict([
+          ('last', RadioButton(button_group, ('streak', 'Last'), state="first True")),
+          ('min', RadioButton(button_group, ('streak', 'Min'), state="first True")),
+          ('avg', RadioButton(button_group, ('streak', 'Avg'), state="first True")),
+          ('max', RadioButton(button_group, ('streak', 'Max'), state="first True")),
+        ])
+        for b in self.price_as.values():
+            connect_signal(b, 'postchange', lambda w,_: self.update(w))
         self.fname = Edit('', fname)
         self.prices = dict()
         self.components = dict()
@@ -395,8 +410,8 @@ class RecipeEditor(FocusWidget):
             self.organic,
             LineBox(self.instructions, title=f'Instructions'),
             self.feeds,
-            self.price,
-            LineBox(self.notice, title='Errors'),
+            Columns([self.price, *[(9, w) for _,w in self.price_as.items()], Divider()]),
+            LineBox(self.notice, title='Errors', title_align='left'),
         ]
         self.activity_manager = activity_manager
         self.query_manager = query_manager

+ 5 - 1
app/price_view.py

@@ -58,7 +58,7 @@ def get_where(unit, product=None, category=None, group=None, organic=None, limit
     ])
 
 def get_historic_prices_statement(unit, sort=None, product=None, category=None, group=None, organic=None, limit='90 days'):
-    partition = f"(PARTITION BY {'organic,' if organic is not None else ''} product_id)"
+    partition = f"(PARTITION BY {'organic,' if organic is not None else ''} product_id ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)"
     organic_sort = f"{'organic,' if organic is not None else ''}"
     sort_sql = SQL('').join([
         SQL('{sort} {direction},').format(
@@ -75,6 +75,10 @@ def get_historic_prices_statement(unit, sort=None, product=None, category=None,
         ('$/unit', SQL("""TRUNC(
     price / quantity / convert_unit(units.name, {unit}, {product}), 4
 )""").format(unit=Literal(unit), product=Literal(product))),
+        ('last', SQL(f"""TRUNC(last_value(
+    price / quantity / convert_unit(units.name, {{unit}}, {{product}})
+) OVER {partition}, 4)
+""").format(unit=Literal(unit), product=Literal(product))),
         ('avg', SQL(f"""TRUNC(sum(price) OVER {partition} / sum(
     quantity * convert_unit(units.name, {{unit}}, {{product}})
 ) OVER {partition}, 4)