Browse Source

fix last $/unit NULL for unrelated unit causing no data to display at all and fix average calculated incorrectly when any unit conversions are NULL

Daniel Sheffield 1 year ago
parent
commit
ce28858bfd
1 changed files with 19 additions and 16 deletions
  1. 19 16
      app/data/PriceView.py

+ 19 - 16
app/data/PriceView.py

@@ -28,23 +28,26 @@ def get_selectors(
         ('code', Identifier('stores', 'code')),
         ('$/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}})
+    )""").format(unit=Literal(unit), product=Literal(product))),
+        ('last', SQL("""TRUNC(last_value(
+    price / quantity / convert_unit(units.name, {unit}, {product})
 ) OVER {window}, 4)
-""").format(unit=Literal(unit), product=Literal(product))),
-        ('avg', SQL(f"""TRUNC(sum(price) OVER {window} / sum(
-    quantity * convert_unit(units.name, {{unit}}, {{product}})
+""").format(unit=Literal(unit), product=Literal(product), window=window)),
+        ('avg', SQL("""TRUNC(sum(CASE
+    WHEN convert_unit(units.name, {unit}, {product}) IS NOT NULL THEN price
+    ELSE NULL
+END) OVER {window} / sum(
+    quantity * convert_unit(units.name, {unit}, {product})
 ) OVER {window}, 4)
-""").format(unit=Literal(unit), product=Literal(product))),
-        ('min', SQL(f"""TRUNC(min(
-    price / quantity / convert_unit(units.name, {{unit}}, {{product}})
+""").format(unit=Literal(unit), product=Literal(product), window=window)),
+        ('min', SQL("""TRUNC(min(
+    price / quantity / convert_unit(units.name, {unit}, {product})
 ) OVER {window}, 4)
-""").format(unit=Literal(unit), product=Literal(product))),
-        ('max', SQL(f"""TRUNC(max(
-    price / quantity / convert_unit(units.name, {{unit}}, {{product}})
+""").format(unit=Literal(unit), product=Literal(product), window=window)),
+        ('max', SQL("""TRUNC(max(
+    price / quantity / convert_unit(units.name, {unit}, {product})
 ) OVER {window}, 4)
-""").format(unit=Literal(unit), product=Literal(product))),
+""").format(unit=Literal(unit), product=Literal(product), window=window)),
         ('price', SQL("""TRUNC(price, 4)""")),
         ('quantity', SQL("""TRUNC(
     quantity * convert_unit(units.name, {unit}, {product}), 4
@@ -103,11 +106,11 @@ def get_where(product=None, category=None, group=None, organic=None, limit='90 d
     ])
 
 def get_historic_prices_statement(unit, sort=None, product=None, category=None, group=None, organic=None, limit='90 days'):
-    window = f"""(
+    window = SQL(f"""(
 PARTITION BY {'organic,' if organic is not None else ''} product_id
-ORDER BY ts
+ORDER BY convert_unit(units.name, {{unit}}, {{product}}) NULLS FIRST, ts
 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
-)"""
+)""").format(unit=Literal(unit), product=Literal(product))
     organic_sort = f"{'organic,' if organic is not None else ''}"
     sort_sql = SQL('').join([
         SQL('{sort} {direction},').format(