Browse Source

use db function to convert unit

Daniel Sheffield 2 years ago
parent
commit
1de8d64873
1 changed files with 42 additions and 26 deletions
  1. 42 26
      app/price_view.py

+ 42 - 26
app/price_view.py

@@ -48,11 +48,12 @@ def get_where(unit, product=None, category=None, group=None, organic=None, limit
                 interval=SQL("{literal}::interval").format(literal=Literal(limit))
                 interval=SQL("{literal}::interval").format(literal=Literal(limit))
             )
             )
         )
         )
-    where.append(
-        SQL("(SELECT id FROM units WHERE name = {unit}) = conv._to").format(
-            unit=Literal(unit),
-        )
-    )
+    where.append(SQL(
+        '(SELECT convert_unit(units.name, {unit}, {product}) IS NOT NULL)'
+    ).format(
+        unit=Literal(unit),
+        product=Literal(product)
+    ))
     return SQL('').join([
     return SQL('').join([
         SQL("WHERE"
         SQL("WHERE"
             "\n      "),
             "\n      "),
@@ -69,34 +70,54 @@ def get_historic_prices_statement(unit, sort=None, product=None, category=None,
         ),
         ),
     ]) if sort is not None else SQL('')
     ]) if sort is not None else SQL('')
 
 
-    _with = SQL("""WITH conv AS (
-    SELECT
-        _1._from, _1._to, factor FROM conversions AS _1
-    UNION
-    SELECT _2._to, _2._from, 1/_2.factor FROM conversions AS _2
-    UNION
-    SELECT _3._from, _3._from, 1 FROM conversions AS _3
-    UNION
-    SELECT _4.id AS _from, _4.id AS _to, 1 FROM units AS _4
-)""")
     select = OrderedDict([
     select = OrderedDict([
         ('id', Identifier('transactions','id')),
         ('id', Identifier('transactions','id')),
         ('ts_raw', SQL("""(transactions.ts AT TIME ZONE 'UTC')::timestamp without time zone""")),
         ('ts_raw', SQL("""(transactions.ts AT TIME ZONE 'UTC')::timestamp without time zone""")),
         ('%d/%m/%y %_I%P', SQL("""(transactions.ts AT TIME ZONE 'UTC')::timestamp without time zone""")),
         ('%d/%m/%y %_I%P', SQL("""(transactions.ts AT TIME ZONE 'UTC')::timestamp without time zone""")),
         ('code', Identifier('stores', 'code')),
         ('code', Identifier('stores', 'code')),
-        ('$/unit', SQL("""TRUNC(price / (quantity * factor), 4)""")),
-        ('avg', SQL(f"""TRUNC(sum(price) OVER {partition} / sum(quantity * factor) OVER {partition}, 4)""")),
-        ('min', SQL(f"""TRUNC(min(price / (quantity * factor)) OVER {partition}, 4)""")),
-        ('max', SQL(f"""TRUNC(max(price / (quantity * factor)) OVER {partition}, 4)""")),
+        ('$/unit', SQL(
+            f"""TRUNC(price / (quantity * (
+  SELECT convert_unit(units.name,{{unit}}, {{product}}))), 4)"""
+        ).format(
+            unit=Literal(unit),
+            product=Literal(product)
+        )),
+        ('avg', SQL(
+            f"""TRUNC(sum(price) OVER {partition} / sum(quantity * (
+  SELECT convert_unit(units.name, {{unit}}, {{product}}))) OVER {partition}, 4
+)"""
+        ).format(
+            unit=Literal(unit),
+            product=Literal(product)
+        )),
+        ('min', SQL(
+            f"""TRUNC(min(price / (quantity * (
+  SELECT convert_unit(units.name, {{unit}}, {{product}})))) OVER {partition}, 4)"""
+        ).format(
+            unit=Literal(unit),
+            product=Literal(product)
+        )),
+        ('max', SQL(
+            f"""TRUNC(max(price / (quantity * (
+  SELECT convert_unit(units.name, {{unit}}, {{product}})))) OVER {partition}, 4)"""
+        ).format(
+            unit=Literal(unit),
+            product=Literal(product)
+        )),
         ('price', SQL(f"""TRUNC(price, 4)::numeric""")),
         ('price', SQL(f"""TRUNC(price, 4)::numeric""")),
-        ('quantity', SQL(f"""TRUNC(quantity*factor, 4)::numeric""")),
+        ('quantity', SQL(
+            f"""TRUNC(quantity*(
+  SELECT convert_unit(units.name, {{unit}}, {{product}})), 4)::numeric
+""").format(
+    unit=Literal(unit),
+    product=Literal(product)
+        )),
         ('product', Identifier('products','name')),
         ('product', Identifier('products','name')),
         ('category', Identifier('categories', 'name')),
         ('category', Identifier('categories', 'name')),
         ('group', Identifier('groups', 'name')),
         ('group', Identifier('groups', 'name')),
         ('organic', Identifier('organic')),
         ('organic', Identifier('organic')),
     ])
     ])
     statement = SQL('\n').join([
     statement = SQL('\n').join([
-        _with,
         SQL('').join([
         SQL('').join([
             SQL("SELECT"
             SQL("SELECT"
                 "\n  "),
                 "\n  "),
@@ -110,11 +131,6 @@ def get_historic_prices_statement(unit, sort=None, product=None, category=None,
                 "\n       "),
                 "\n       "),
             SQL("\n  JOIN ").join([
             SQL("\n  JOIN ").join([
                 SQL("transactions"),
                 SQL("transactions"),
-                SQL("{table} ON ({table}.{key} = {index})").format(
-                    table=Identifier('conv'),
-                    key=Identifier('_from'),
-                    index=Identifier('unit_id'),
-                ),
                 SQL("{table} ON {table}.{key} = {index}").format(
                 SQL("{table} ON {table}.{key} = {index}").format(
                     table=Identifier('units'),
                     table=Identifier('units'),
                     key=Identifier('id'),
                     key=Identifier('id'),