DROP TABLE IF EXISTS sqlpage_txn;
CREATE TABLE IF NOT EXISTS sqlpage_txn AS (
SELECT
  t.ts AT TIME ZONE 'UTC' AS ts,
  t.description,
  s.code,
  p.name AS product,
  c.name AS category,
  g.name AS "group",
  t.organic,
  t.price,
  CASE
    WHEN ut.name = 'Count' THEN t.quantity
    ELSE t.quantity * convert_unit(u.name, CASE
      WHEN ut.name = 'Volume' THEN $unit_volume
      WHEN ut.name = 'Mass' THEN $unit_mass
    END, p.name)
  END AS quantity,
  CASE
    WHEN ut.name = 'Count' THEN u.name
    WHEN ut.name = 'Volume' THEN $unit_volume
    WHEN ut.name = 'Mass' THEN $unit_mass
  END AS unit
FROM transactions t
JOIN products p ON (product_id = p.id)
JOIN categories c ON (category_id = c.id)
JOIN groups g ON (group_id = g.id)
JOIN stores s ON (store_id = s.id)
JOIN units u ON (t.unit_id = u.id)
JOIN unit_types ut ON (u.unit_type_id = ut.id)
WHERE
  (p.name IN (SELECT v#>>'{}' FROM json_array_elements($products::json) j(v)) OR $products IS NULL)
AND
  (c.name IN (SELECT v#>>'{}' FROM json_array_elements($categories::json) j(v)) OR $categories IS NULL)
AND
  (g.name IN (SELECT v#>>'{}' FROM json_array_elements($groups::json) j(v)) OR $groups IS NULL)
AND
  CASE
    WHEN ut.name = 'Count'
    THEN (u.name IN (SELECT v#>>'{}' FROM json_array_elements($unit_count::json) j(v)) OR $unit_count IS NULL)
    ELSE TRUE
  END
AND
  ((ts AT TIME ZONE 'UTC') AT TIME ZONE 'Pacific/Auckland')::date
  BETWEEN $start::date AND $end::date
AND
  (t.id IN (
    SELECT transaction_id FROM tags_map
    WHERE tag_id IN (
      SELECT id FROM tags tg
      WHERE tg.name IN (SELECT v#>>'{}' FROM json_array_elements($tags::json) j(v))
    )
  ) OR $tags IS NULL)
ORDER BY ts DESC
LIMIT 1000);