Browse Source

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

Daniel Sheffield 2 years ago
parent
commit
67f3d1d726
2 changed files with 27 additions and 8 deletions
  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 markdown import markdown
 from itertools import chain, product
 from itertools import chain, product
 from decimal import Decimal, InvalidOperation
 from decimal import Decimal, InvalidOperation
+from collections import OrderedDict
 from typing import List, Tuple, Union, Iterable, Callable
 from typing import List, Tuple, Union, Iterable, Callable
 from urwid import (
 from urwid import (
     connect_signal,
     connect_signal,
@@ -20,6 +21,7 @@ from urwid import (
     LineBox,
     LineBox,
     Padding,
     Padding,
     Pile,
     Pile,
+    RadioButton,
     Text,
     Text,
 )
 )
 from urwid.numedit import FloatEdit
 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()}"
             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()] = [
             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):
         for k in list(self.prices):
@@ -335,10 +337,14 @@ class RecipeEditor(FocusWidget):
                 del self.prices[k]
                 del self.prices[k]
 
 
         price = [
         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(
         self.price.set_text(
-            f'Cost: {not_found}{", ".join([str(p) for p in price])}'
+            f'Cost: {not_found}{price[price_as]}'
         )
         )
         notice = ''
         notice = ''
         ingredients = list(filter(lambda x: x, map(lambda x: x[0].get_edit_text(), self.ingredients)))
         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,
         fname: str,
         recipe: dict,
         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.fname = Edit('', fname)
         self.prices = dict()
         self.prices = dict()
         self.components = dict()
         self.components = dict()
@@ -395,8 +410,8 @@ class RecipeEditor(FocusWidget):
             self.organic,
             self.organic,
             LineBox(self.instructions, title=f'Instructions'),
             LineBox(self.instructions, title=f'Instructions'),
             self.feeds,
             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.activity_manager = activity_manager
         self.query_manager = query_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'):
 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 ''}"
     organic_sort = f"{'organic,' if organic is not None else ''}"
     sort_sql = SQL('').join([
     sort_sql = SQL('').join([
         SQL('{sort} {direction},').format(
         SQL('{sort} {direction},').format(
@@ -75,6 +75,10 @@ def get_historic_prices_statement(unit, sort=None, product=None, category=None,
         ('$/unit', SQL("""TRUNC(
         ('$/unit', SQL("""TRUNC(
     price / quantity / convert_unit(units.name, {unit}, {product}), 4
     price / quantity / convert_unit(units.name, {unit}, {product}), 4
 )""").format(unit=Literal(unit), product=Literal(product))),
 )""").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(
         ('avg', SQL(f"""TRUNC(sum(price) OVER {partition} / sum(
     quantity * convert_unit(units.name, {{unit}}, {{product}})
     quantity * convert_unit(units.name, {{unit}}, {{product}})
 ) OVER {partition}, 4)
 ) OVER {partition}, 4)