Bladeren bron

refactored to reuse code

Daniel Sheffield 8 maanden geleden
bovenliggende
commit
84cfeb700c

+ 7 - 0
sqlpage/404.sql

@@ -0,0 +1,7 @@
+-- TODO set response code 404
+SET title = '404 '||COALESCE(''''||$title||'''','')||' not found';
+SELECT 'dynamic' AS component, sqlpage.run_sql('theme.sql') AS properties;
+SELECT 'alert' AS component
+, '404 - Not found' AS title
+, 'Check the URL is correct.' AS description
+;

+ 1 - 97
sqlpage/categories.sql

@@ -1,98 +1,2 @@
 SET title = 'Categories';
-SET products = COALESCE($products, sqlpage.cookie('products'));
-SET categories = COALESCE($categories, sqlpage.cookie('categories'));
-SET groups = COALESCE($groups, sqlpage.cookie('groups'));
-
-DROP TABLE IF EXISTS sqlpage_categories;
-CREATE TEMPORARY TABLE IF NOT EXISTS sqlpage_categories AS (
-SELECT
-  count(DISTINCT p.id) AS "Products",
-  count(DISTINCT c.id) AS "Categories",
-  count(DISTINCT g.id) AS "Groups",
-  p.name AS product,
-  c.name AS category,
-  g.name AS "group"
-FROM products p
-JOIN categories c ON p.category_id = c.id
-JOIN groups g ON c.group_id = g.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)
-GROUP BY ROLLUP ("group", category, product)
-);
-
-SET product_options = (
-SELECT
-  json_agg(json_build_object(
-    'label', value,
-    'value', value,
-    'selected', value IN (SELECT v#>>'{}' FROM json_array_elements($products::json) j(v))
-  ) ORDER BY value)
-FROM (
-  SELECT v#>>'{}'
-  FROM json_array_elements($products::json) j(v)
-  UNION
-  SELECT product
-  FROM sqlpage_categories
-) o(value)
-WHERE value IS NOT NULL
-);
-SET category_options = (
-SELECT
-  json_agg(json_build_object(
-    'label', value,
-    'value', value,
-    'selected', value IN (SELECT v#>>'{}' FROM json_array_elements($categories::json) j(v))
-  ) ORDER BY value)
-FROM (
-  SELECT v#>>'{}'
-  FROM json_array_elements($categories::json) j(v)
-  UNION
-  SELECT category
-  FROM sqlpage_categories
-) o(value)
-WHERE value IS NOT NULL
-);
-SET group_options = (
-SELECT
-  json_agg(json_build_object(
-    'label', value,
-    'value', value,
-    'selected', value IN (SELECT v#>>'{}' FROM json_array_elements($groups::json) j(v))
-  ) ORDER BY value)
-FROM (
-  SELECT v#>>'{}'
-  FROM json_array_elements($groups::json) j(v)
-  UNION
-  SELECT "group"
-  FROM sqlpage_categories
-) o(value)
-WHERE value IS NOT NULL
-);
-
-SELECT 'dynamic' AS component, sqlpage.run_sql('cookie.sql') AS properties;
-SELECT 'dynamic' AS component, sqlpage.run_sql('theme.sql') AS properties;
-SELECT 'dynamic' AS component, sqlpage.run_sql('nav.sql') AS properties;
-
-SELECT
-  'table' AS component,
-  TRUE AS search,
-  TRUE AS striped_rows,
-  TRUE AS small,
-  'Notice' AS markdown
-;
-
-SELECT
-  "Products",
-  COALESCE("category", "Categories"||'') "Category",
-  COALESCE("group", "Groups"||'') "Group"
-FROM sqlpage_categories q
-WHERE q.product IS NULL AND (q.category IS NOT NULL OR q.group IS NULL)
-ORDER BY product, category, "group"
-;
-
-SELECT '# No Data' AS "Notice"
-WHERE NOT EXISTS(SELECT * FROM sqlpage_categories LIMIT 1);
+SELECT 'dynamic' AS component, sqlpage.run_sql('entry.sql') AS properties;

+ 4 - 2
sqlpage/clear.sql

@@ -1,11 +1,13 @@
 SET products = NULL;
 SET categories = NULL;
 SET groups = NULL;
+SET start = NULL;
+SET end = NULL;
 SELECT 'dynamic' AS component, sqlpage.run_sql('cookie.sql') AS properties;
 SELECT
   'redirect' AS component,
   (SELECT CASE
-    WHEN $path IN ('/products.sql', '/categories.sql', '/groups.sql', '/tags.sql')
-    THEN $path ELSE '/transactions.sql'
+    WHEN $title IN ('Products', 'Categories', 'Groups', 'Tags')
+    THEN lower($title)||'.sql' ELSE 'transactions.sql'
     END
   ) AS link;

+ 11 - 0
sqlpage/cookie.sql

@@ -44,3 +44,14 @@ SELECT
   TRUE AS remove
 WHERE $groups IS NULL
 ;
+
+SELECT 'cookie' AS component
+, 'start' AS name
+, $start AS value
+, $start IS NULL AS remove
+;
+SELECT 'cookie' AS component
+, 'end' AS name
+, $end AS value
+, $end IS NULL AS remove
+;

+ 1 - 0
sqlpage/data/Categories.sql

@@ -0,0 +1 @@
+SELECT 'dynamic' AS component, sqlpage.run_sql('data/products.sql') AS properties;

+ 1 - 0
sqlpage/data/Groups.sql

@@ -0,0 +1 @@
+SELECT 'dynamic' AS component, sqlpage.run_sql('data/products.sql') AS properties;

+ 1 - 0
sqlpage/data/Products.sql

@@ -0,0 +1 @@
+SELECT 'dynamic' AS component, sqlpage.run_sql('data/products.sql') AS properties;

+ 42 - 0
sqlpage/data/Tags.sql

@@ -0,0 +1,42 @@
+DROP TABLE IF EXISTS sqlpage_tags;
+CREATE TABLE IF NOT EXISTS sqlpage_tags AS (
+SELECT * FROM (SELECT count(DISTINCT txn.id) AS "Uses", tg.name AS "Name"
+FROM tags tg
+JOIN tags_map tm ON tg.id = tm.tag_id
+JOIN transactions txn ON txn.id = tm.transaction_id
+JOIN products p ON p.id = txn.product_id
+JOIN categories c ON p.category_id = c.id
+JOIN groups g ON c.group_id = g.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
+  (tg.name IN (SELECT v#>>'{}' FROM json_array_elements($tags::json) j(v)) OR $tags IS NULL)
+AND
+  ((ts AT TIME ZONE 'UTC') AT TIME ZONE 'Pacific/Auckland')::date
+  BETWEEN $start::date AND $end::date
+GROUP BY tg.name
+ORDER BY 1 DESC, 2) q
+UNION ALL
+SELECT count(DISTINCT txn.id) AS "Uses", count(DISTINCT tg.name)||'' AS "Name"
+FROM tags tg
+JOIN tags_map tm ON tg.id = tm.tag_id
+JOIN transactions txn ON txn.id = tm.transaction_id
+JOIN products p ON p.id = txn.product_id
+JOIN categories c ON p.category_id = c.id
+JOIN groups g ON c.group_id = g.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
+  (tg.name IN (SELECT v#>>'{}' FROM json_array_elements($tags::json) j(v)) OR $tags IS NULL)
+AND
+  ((ts AT TIME ZONE 'UTC') AT TIME ZONE 'Pacific/Auckland')::date
+  BETWEEN $start::date AND $end::date
+);

+ 53 - 0
sqlpage/data/Transactions.sql

@@ -0,0 +1,53 @@
+DROP TABLE IF EXISTS sqlpage_txn;
+CREATE TABLE IF NOT EXISTS sqlpage_txn AS (
+SELECT
+  to_char(
+    (ts AT TIME ZONE 'UTC') AT TIME ZONE 'Pacific/Auckland', --COALESCE('$ParameterTZ', 'Pacific/Auckland'),
+    'Mon DD HH24:MI:SS'
+  ) AS "Time",
+  t.description AS Description,
+  s.code AS "Store",
+  p.name AS "Product",
+  c.name AS "Category",
+  g.name AS "Group",
+  CASE WHEN t.organic THEN 'yes' ELSE 'no' END AS "Organic",
+  to_char(t.price, 'FM999999999.00') AS "Price"
+  --to_char(quantity, '9.'||repeat('9',3-1)||'EEEE') AS Quantity,
+  -- to_char(CASE
+  -- WHEN ut.name = 'Count' THEN t.price
+  -- ELSE t.quantity * convert_unit(u.name, CASE
+  -- WHEN ut.name = 'Volume' THEN ouv.name
+  -- WHEN ut.name = 'Mass' THEN oum.name
+  -- END, p.name) END, 'FM999999999.000') AS "Quantity",
+  -- CASE
+  -- WHEN ut.name = 'Count' THEN u.name
+  -- WHEN ut.name = 'Volume' THEN ouv.name
+  -- WHEN ut.name = 'Mass' THEN oum.name
+  -- 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)
+--LEFT JOIN sqlpage_options ouv ON ouv.type = 'unit_volume' AND ut.name = 'Volume'
+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
+  ((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($groups::json) j(v))
+    )
+  ) OR $tags IS NULL)
+ORDER BY ts DESC
+LIMIT 100);

+ 29 - 0
sqlpage/data/products.sql

@@ -0,0 +1,29 @@
+DROP TABLE IF EXISTS sqlpage_products;
+CREATE TABLE IF NOT EXISTS sqlpage_products AS
+--(
+--   "Products" int,
+--   "Categories" int,
+--   "Groups" int,
+--   product text,
+--   category text,
+--   "group" text
+-- );
+--INSERT INTO sqlpage_products
+SELECT
+  count(DISTINCT p.id) AS "Products",
+  count(DISTINCT c.id) AS "Categories",
+  count(DISTINCT g.id) AS "Groups",
+  p.name AS "product",
+  c.name AS "category",
+  g.name AS "group"
+FROM products p
+JOIN categories c ON p.category_id = c.id
+JOIN groups g ON c.group_id = g.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)
+GROUP BY ROLLUP ("group", category, product)
+;

+ 87 - 0
sqlpage/entry.sql

@@ -0,0 +1,87 @@
+SET products = COALESCE($products, sqlpage.cookie('products'));
+SET categories = COALESCE($categories, sqlpage.cookie('categories'));
+SET groups = COALESCE($groups, sqlpage.cookie('groups'));
+SET start = (CASE
+  WHEN $start = '' OR $start IS NULL
+  THEN COALESCE(sqlpage.cookie('start'), to_char(now()-'30 days'::interval, 'YYYY-MM-DD'))
+  ELSE $start
+END);
+SET end = CASE
+  WHEN $end = '' OR $end IS NULL
+  THEN COALESCE(sqlpage.cookie('end'), to_char(now(), 'YYYY-MM-DD'))
+  ELSE $end
+END;
+
+SET page = CASE
+  WHEN $title IN ('Products', 'Categories', 'Groups', 'Tags', 'Transactions')
+  THEN $title||'.sql'
+  ELSE NULL
+END;
+
+SELECT 'redirect' AS component
+, '404.sql?title='||COALESCE($title, '') AS link
+WHERE $page IS NULL
+;
+
+SELECT 'dynamic' AS component
+, CASE
+  WHEN $title IN ('Transactions', 'Tags')
+  THEN sqlpage.run_sql('data/'||$page)
+  WHEN $title IN ('Products', 'Categories', 'Groups')
+  THEN sqlpage.run_sql('data/products.sql')
+END;
+
+SET product_options = (
+SELECT
+  json_agg(json_build_object(
+    'label', value,
+    'value', value,
+    'selected', value IN (SELECT v#>>'{}' FROM json_array_elements($products::json) j(v))
+  ) ORDER BY value)
+FROM (
+  SELECT v#>>'{}'
+  FROM json_array_elements($products::json) j(v)
+  UNION
+  SELECT product
+  FROM sqlpage_products
+) o(value)
+WHERE value IS NOT NULL
+);
+SET category_options = (
+SELECT
+  json_agg(json_build_object(
+    'label', value,
+    'value', value,
+    'selected', value IN (SELECT v#>>'{}' FROM json_array_elements($categories::json) j(v))
+  ) ORDER BY value)
+FROM (
+  SELECT v#>>'{}'
+  FROM json_array_elements($categories::json) j(v)
+  UNION
+  SELECT category
+  FROM sqlpage_products
+) o(value)
+WHERE value IS NOT NULL
+);
+SET group_options = (
+SELECT
+  json_agg(json_build_object(
+    'label', value,
+    'value', value,
+    'selected', value IN (SELECT v#>>'{}' FROM json_array_elements($groups::json) j(v))
+  ) ORDER BY value)
+FROM (
+  SELECT v#>>'{}'
+  FROM json_array_elements($groups::json) j(v)
+  UNION
+  SELECT "group"
+  FROM sqlpage_products
+) o(value)
+WHERE value IS NOT NULL
+);
+
+SELECT 'dynamic' AS component, sqlpage.run_sql('cookie.sql') AS properties;
+SELECT 'dynamic' AS component, sqlpage.run_sql('theme.sql') AS properties;
+SELECT 'dynamic' AS component, sqlpage.run_sql('nav.sql') AS properties;
+
+SELECT 'dynamic' AS component, sqlpage.run_sql('pages/'||$page) AS properties;

+ 1 - 97
sqlpage/groups.sql

@@ -1,98 +1,2 @@
 SET title = 'Groups';
-SET products = COALESCE($products, sqlpage.cookie('products'));
-SET categories = COALESCE($categories, sqlpage.cookie('categories'));
-SET groups = COALESCE($groups, sqlpage.cookie('groups'));
-
-DROP TABLE IF EXISTS sqlpage_groups;
-CREATE TEMPORARY TABLE IF NOT EXISTS sqlpage_groups AS (
-SELECT
-  count(DISTINCT p.id) AS "Products",
-  count(DISTINCT c.id) AS "Categories",
-  count(DISTINCT g.id) AS "Groups",
-  p.name AS product,
-  c.name AS category,
-  g.name AS "group"
-FROM products p
-JOIN categories c ON p.category_id = c.id
-JOIN groups g ON c.group_id = g.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)
-GROUP BY ROLLUP ("group", category, product)
-);
-
-SET product_options = (
-SELECT
-  json_agg(json_build_object(
-    'label', value,
-    'value', value,
-    'selected', value IN (SELECT v#>>'{}' FROM json_array_elements($products::json) j(v))
-  ) ORDER BY value)
-FROM (
-  SELECT v#>>'{}'
-  FROM json_array_elements($products::json) j(v)
-  UNION
-  SELECT product
-  FROM sqlpage_groups
-) o(value)
-WHERE value IS NOT NULL
-);
-SET category_options = (
-SELECT
-  json_agg(json_build_object(
-    'label', value,
-    'value', value,
-    'selected', value IN (SELECT v#>>'{}' FROM json_array_elements($categories::json) j(v))
-  ) ORDER BY value)
-FROM (
-  SELECT v#>>'{}'
-  FROM json_array_elements($categories::json) j(v)
-  UNION
-  SELECT category
-  FROM sqlpage_groups
-) o(value)
-WHERE value IS NOT NULL
-);
-SET group_options = (
-SELECT
-  json_agg(json_build_object(
-    'label', value,
-    'value', value,
-    'selected', value IN (SELECT v#>>'{}' FROM json_array_elements($groups::json) j(v))
-  ) ORDER BY value)
-FROM (
-  SELECT v#>>'{}'
-  FROM json_array_elements($groups::json) j(v)
-  UNION
-  SELECT "group"
-  FROM sqlpage_groups
-) o(value)
-WHERE value IS NOT NULL
-);
-
-SELECT 'dynamic' AS component, sqlpage.run_sql('cookie.sql') AS properties;
-SELECT 'dynamic' AS component, sqlpage.run_sql('theme.sql') AS properties;
-SELECT 'dynamic' AS component, sqlpage.run_sql('nav.sql') AS properties;
-
-SELECT
-  'table' AS component,
-  TRUE AS search,
-  TRUE AS striped_rows,
-  TRUE AS small,
-  'Notice' AS markdown
-;
-
-SELECT
-  "Products",
-  "Categories",
-  COALESCE("group", "Groups"||'') "Group"
-FROM sqlpage_groups q
-WHERE q.category IS NULL
-ORDER BY product, category, "group"
-;
-
-SELECT '# No Data' AS "Notice"
-WHERE NOT EXISTS(SELECT * FROM sqlpage_groups LIMIT 1);
+SELECT 'dynamic' AS component, sqlpage.run_sql('entry.sql') AS properties;

+ 80 - 94
sqlpage/nav.sql

@@ -1,102 +1,90 @@
-SELECT
-  'tab' AS component,
-  TRUE AS center
-;
+SELECT 'tab' AS component, TRUE AS center;
 
-SELECT
- 'products' AS id,
- 'Products' AS title,
- sqlpage.path() = '/products.sql' AS active,
- 'products.sql' AS link
+SELECT'Products' AS title
+, 'products' AS id
+, $title = 'Products' AS active
+, 'products.sql' AS link
 ;
-SELECT
- 'categories' AS id,
- 'Categories' AS title,
- sqlpage.path() = '/categories.sql' AS active,
- 'categories.sql' AS link
+SELECT 'Categories' AS title
+, 'categories' AS id
+, $title = 'Categories' AS active
+, 'categories.sql' AS link
 ;
-SELECT
- 'groups' AS id,
- 'Groups' AS title,
- sqlpage.path() = '/groups.sql' AS active,
- 'groups.sql' AS link
+SELECT 'Groups' AS title
+, 'groups' AS id
+, $title = 'Groups' AS active
+, 'groups.sql' AS link
 ;
-SELECT
- 'tags' AS id,
- 'Tags' AS title,
- sqlpage.path() = '/tags.sql' AS active,
- 'tags.sql' AS link
+SELECT 'Tags' AS title
+, 'tags' AS id
+, $title = 'Tags' AS active
+, 'tags.sql' AS link
 ;
-SELECT
- 'transactions' AS id,
- 'Transactions' AS title,
- sqlpage.path() = '/transactions.sql' AS active,
- 'transactions.sql' AS link
+SELECT 'Transactions' AS title
+, 'transactions' AS id
+, $title = 'Transactions' AS active
+, 'transactions.sql' AS link
 ;
 
-SELECT
-  'form' AS component,
-  'filter' AS id,
-  'get' AS method,
-  '' AS title,
-  'Apply' AS validate
+SELECT 'form' AS component
+, 'filter' AS id
+, 'get' AS method
+, '' AS title
+, 'Apply' AS validate
 ;
 
-SELECT
-  'path' AS name,
-  sqlpage.path() AS value,
-  'hidden' AS type
+-- SELECT
+--   'path' AS name,
+--   sqlpage.path() AS value,
+--   'hidden' AS type
+-- ;
+SELECT 'hidden' AS type
+, 'title' AS name
+, $title AS value
 ;
-
-SELECT
-  'products[]' AS name,
-  'Product' AS label,
-  4 AS width,
-  'select' AS type,
-  TRUE AS dropdown,
-  TRUE AS multiple,
-  $product_options AS options
+SELECT 'Product' AS label
+, 'products[]' AS name
+, 4 AS width
+, 'select' AS type
+, TRUE AS dropdown
+, TRUE AS multiple
+, $product_options AS options
 ;
-SELECT
-  'categories[]' AS name,
-  'Categories' AS label,
-  4 AS width,
-  'select' AS type,
-  TRUE AS dropdown,
-  TRUE AS multiple,
-  $category_options AS options
+SELECT 'Categories' AS label
+, 'categories[]' AS name
+, 4 AS width
+, 'select' AS type
+, TRUE AS dropdown
+, TRUE AS multiple
+, $category_options AS options
 ;
-SELECT
-  'groups[]' AS name,
-  'Groups' AS label,
-  4 AS width,
-  'select' AS type,
-  TRUE AS dropdown,
-  TRUE AS multiple,
-  $group_options AS options
+SELECT 'Groups' AS label
+, 'groups[]' AS name
+, 4 AS width
+, 'select' AS type
+, TRUE AS dropdown
+, TRUE AS multiple
+, $group_options AS options
 ;
---SELECT
---  'start' AS name,
---  'From' AS label,
---  2 AS width,
---  (SELECT COALESCE((SELECT name FROM sqlpage_options WHERE type = 'start'), to_char(now()-'30 days'::interval, 'YYYY-MM-DD'))) AS value,
---  'date' AS type
---;
---SELECT
---  'end' AS name,
---  'To' AS label,
---  2 AS width,
---  (SELECT COALESCE((SELECT name FROM sqlpage_options WHERE type = 'end'), to_char(now(), 'YYYY-MM-DD'))) AS value,
---  'date' AS type
---;
-SELECT
-  'tags[]' AS name,
-  'Tags' AS label,
-  4 AS width,
-  'select' AS "type",
-  TRUE AS dropdown,
-  TRUE AS multiple,
-  $tag_options AS options
+SELECT 'From' AS label
+, 'start' AS name
+, 2 AS width
+, $start AS value
+, 'date' AS type
+;
+SELECT 'To' AS label
+, 'end' AS name
+, 2 AS width
+, $end AS value
+, 'date' AS type
+;
+SELECT 'Tags' AS label
+, 'tags[]' AS name
+, 4 AS width
+, 'select' AS "type"
+, TRUE AS dropdown
+, TRUE AS multiple
+, $tag_options AS options
 ;
 --SELECT
 --  'unit_volume' AS name,
@@ -150,12 +138,10 @@ SELECT
 --AND
 --  o.session = sqlpage.cookie('session')
 --;
-SELECT
-  'clear' AS name,
-  'Clear' AS value,
-  '' AS label,
-  1 AS width,
-  'submit' AS type,
-  'clear.sql?path='||sqlpage.path() AS formaction
+SELECT 'Clear' AS value
+, 'clear' AS name
+, '' AS label
+, 1 AS width
+, 'submit' AS type
+, 'clear.sql?title='||$title AS formaction
 ;
-

+ 19 - 0
sqlpage/pages/Categories.sql

@@ -0,0 +1,19 @@
+SELECT
+  'table' AS component,
+  TRUE AS search,
+  TRUE AS striped_rows,
+  TRUE AS small,
+  'Notice' AS markdown
+;
+
+SELECT
+  "Products",
+  COALESCE("category", "Categories"||'') "Category",
+  COALESCE("group", "Groups"||'') "Group"
+FROM sqlpage_products q
+WHERE q.product IS NULL AND (q.category IS NOT NULL OR q.group IS NULL)
+ORDER BY product, category, "group"
+;
+
+SELECT '# No Data' AS "Notice"
+WHERE NOT EXISTS(SELECT * FROM sqlpage_products LIMIT 1);

+ 19 - 0
sqlpage/pages/Groups.sql

@@ -0,0 +1,19 @@
+SELECT
+  'table' AS component,
+  TRUE AS search,
+  TRUE AS striped_rows,
+  TRUE AS small,
+  'Notice' AS markdown
+;
+
+SELECT
+  "Products",
+  "Categories",
+  COALESCE("group", "Groups"||'') "Group"
+FROM sqlpage_products q
+WHERE q.category IS NULL
+ORDER BY product, category, "group"
+;
+
+SELECT '# No Data' AS "Notice"
+WHERE NOT EXISTS(SELECT * FROM sqlpage_products LIMIT 1);

+ 19 - 0
sqlpage/pages/Products.sql

@@ -0,0 +1,19 @@
+SELECT
+  'table' AS component,
+  TRUE AS search,
+  TRUE AS striped_rows,
+  TRUE AS small,
+  'Notice' AS markdown
+;
+
+SELECT
+  COALESCE("product", "Products"||'') "Product",
+  COALESCE("category", "Categories"||'') "Category",
+  COALESCE("group", "Groups"||'') "Group"
+FROM sqlpage_products q
+WHERE q.product IS NOT NULL OR q.group IS NULL
+ORDER BY product, category, "group"
+;
+
+SELECT '# No Data' AS "Notice"
+WHERE NOT EXISTS(SELECT * FROM sqlpage_products LIMIT 1);

+ 11 - 0
sqlpage/pages/Tags.sql

@@ -0,0 +1,11 @@
+SELECT
+  'table' AS component,
+  TRUE AS search,
+  TRUE AS striped_rows,
+  TRUE AS small,
+  'Notice' AS markdown
+;
+SELECT * FROM sqlpage_tags;
+
+SELECT '# No Data' AS "Notice"
+WHERE NOT EXISTS(SELECT * FROM sqlpage_tags LIMIT 1);

+ 15 - 0
sqlpage/pages/Transactions.sql

@@ -0,0 +1,15 @@
+SELECT
+  'table' AS component,
+  TRUE AS sort,
+  TRUE AS search,
+  TRUE AS striped_rows,
+  TRUE AS small,
+  'Price' AS align_right,
+  'Quantity' AS align_right,
+  'Unit' AS align_right,
+  'Notice' AS markdown
+;
+SELECT * FROM sqlpage_txn;
+
+SELECT '# No Data' AS "Notice"
+WHERE NOT EXISTS(SELECT * FROM sqlpage_txn LIMIT 1);

+ 8 - 97
sqlpage/products.sql

@@ -1,98 +1,9 @@
 SET title = 'Products';
-SET products = COALESCE($products, sqlpage.cookie('products'));
-SET categories = COALESCE($categories, sqlpage.cookie('categories'));
-SET groups = COALESCE($groups, sqlpage.cookie('groups'));
-
-DROP TABLE IF EXISTS sqlpage_products;
-CREATE TEMPORARY TABLE IF NOT EXISTS sqlpage_products AS (
-SELECT
-  count(DISTINCT p.id) AS "Products",
-  count(DISTINCT c.id) AS "Categories",
-  count(DISTINCT g.id) AS "Groups",
-  p.name AS product,
-  c.name AS category,
-  g.name AS "group"
-FROM products p
-JOIN categories c ON p.category_id = c.id
-JOIN groups g ON c.group_id = g.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)
-GROUP BY ROLLUP ("group", category, product)
-);
-
-SET product_options = (
-SELECT
-  json_agg(json_build_object(
-    'label', value,
-    'value', value,
-    'selected', value IN (SELECT v#>>'{}' FROM json_array_elements($products::json) j(v))
-  ) ORDER BY value)
-FROM (
-  SELECT v#>>'{}'
-  FROM json_array_elements($products::json) j(v)
-  UNION
-  SELECT product
-  FROM sqlpage_products
-) o(value)
-WHERE value IS NOT NULL
-);
-SET category_options = (
-SELECT
-  json_agg(json_build_object(
-    'label', value,
-    'value', value,
-    'selected', value IN (SELECT v#>>'{}' FROM json_array_elements($categories::json) j(v))
-  ) ORDER BY value)
-FROM (
-  SELECT v#>>'{}'
-  FROM json_array_elements($categories::json) j(v)
-  UNION
-  SELECT category
-  FROM sqlpage_products
-) o(value)
-WHERE value IS NOT NULL
-);
-SET group_options = (
-SELECT
-  json_agg(json_build_object(
-    'label', value,
-    'value', value,
-    'selected', value IN (SELECT v#>>'{}' FROM json_array_elements($groups::json) j(v))
-  ) ORDER BY value)
-FROM (
-  SELECT v#>>'{}'
-  FROM json_array_elements($groups::json) j(v)
-  UNION
-  SELECT "group"
-  FROM sqlpage_products
-) o(value)
-WHERE value IS NOT NULL
-);
-
-SELECT 'dynamic' AS component, sqlpage.run_sql('cookie.sql') AS properties;
-SELECT 'dynamic' AS component, sqlpage.run_sql('theme.sql') AS properties;
-SELECT 'dynamic' AS component, sqlpage.run_sql('nav.sql') AS properties;
-
-SELECT
-  'table' AS component,
-  TRUE AS search,
-  TRUE AS striped_rows,
-  TRUE AS small,
-  'Notice' AS markdown
-;
-
-SELECT
-  COALESCE("product", "Products"||'') "Product",
-  COALESCE("category", "Categories"||'') "Category",
-  COALESCE("group", "Groups"||'') "Group"
-FROM sqlpage_products q
-WHERE q.product IS NOT NULL OR q.group IS NULL
-ORDER BY product, category, "group"
-;
-
-SELECT '# No Data' AS "Notice"
-WHERE NOT EXISTS(SELECT * FROM sqlpage_products LIMIT 1);
+SELECT 'dynamic' AS component, sqlpage.run_sql('entry.sql') AS properties;
+-- SELECT
+--   'redirect' AS component,
+--   (SELECT CASE
+--     WHEN $title IN ('Products', 'Categories', 'Groups', 'Tags')
+--     THEN 'entry.sql?title='||$title ELSE 'transactions.sql'
+--     END
+--   ) AS link;

+ 2 - 94
sqlpage/tags.sql

@@ -1,94 +1,2 @@
-SELECT
-  'dynamic' as component,
-  sqlpage.run_sql('cookie.sql') AS properties
-;
-
-SELECT 'shell' AS component,
-  'dark' AS theme,
-  'Tags' AS title
-;
-
-SELECT
-  'dynamic' as component,
-  sqlpage.run_sql('nav.sql') AS properties
-;
-
-SELECT
-  'table' AS component,
-  TRUE AS search,
-  TRUE AS striped_rows,
-  TRUE AS small,
-  'Notice' AS markdown
-;
-
-DROP TABLE IF EXISTS sqlpage_tags;
-CREATE TEMPORARY TABLE IF NOT EXISTS sqlpage_tags AS (
-SELECT * FROM (SELECT count(DISTINCT txn.id) AS "Uses", tg.name AS "Name"
-FROM tags tg
-JOIN tags_map tm ON tg.id = tm.tag_id
-JOIN transactions txn ON txn.id = tm.transaction_id
-JOIN products p ON p.id = txn.product_id
-JOIN categories c ON p.category_id = c.id
-JOIN groups g ON c.group_id = g.id
-JOIN sqlpage_options op ON op.type = 'product' AND p.name = op.name
-JOIN sqlpage_options oc ON oc.type = 'category' AND c.name = oc.name
-JOIN sqlpage_options og ON og.type = 'group' AND g.name = og.name
-JOIN sqlpage_options ot ON ot.type = 'tag' AND tg.name = ot.name
-WHERE 
-  COALESCE(op.selected, oc.selected, og.selected, TRUE)
-AND
-  COALESCE(ot.selected, TRUE)
-AND
-  op.session = sqlpage.cookie('session')
-AND
-  oc.session = sqlpage.cookie('session')
-AND
-  og.session = sqlpage.cookie('session')
-AND
-  ot.session = sqlpage.cookie('session')
-AND
-  ((ts AT TIME ZONE 'UTC') AT TIME ZONE 'Pacific/Auckland')::date
-  BETWEEN (
-    SELECT name FROM sqlpage_options WHERE type = 'start'
-  )::date AND (
-    SELECT name FROM sqlpage_options WHERE type = 'end'
-  )::date
-GROUP BY tg.name
-ORDER BY 1 DESC, 2) q
-UNION ALL
-SELECT count(DISTINCT txn.id) AS "Uses", count(DISTINCT tg.name)||'' AS "Name"
-FROM tags tg
-JOIN tags_map tm ON tg.id = tm.tag_id
-JOIN transactions txn ON txn.id = tm.transaction_id
-JOIN products p ON p.id = txn.product_id
-JOIN categories c ON p.category_id = c.id
-JOIN groups g ON c.group_id = g.id
-JOIN sqlpage_options op ON op.type = 'product' AND p.name = op.name
-JOIN sqlpage_options oc ON oc.type = 'category' AND c.name = oc.name
-JOIN sqlpage_options og ON og.type = 'group' AND g.name = og.name
-JOIN sqlpage_options ot ON ot.type = 'tag' AND tg.name = ot.name
-WHERE
-  COALESCE(op.selected, oc.selected, og.selected, TRUE)
-AND
-  COALESCE(ot.selected, TRUE)
-AND
-  op.session = sqlpage.cookie('session')
-AND
-  oc.session = sqlpage.cookie('session')
-AND
-  og.session = sqlpage.cookie('session')
-AND
-  ot.session = sqlpage.cookie('session')
-AND
-  ((ts AT TIME ZONE 'UTC') AT TIME ZONE 'Pacific/Auckland')::date
-  BETWEEN (
-    SELECT name FROM sqlpage_options WHERE type = 'start'
-  )::date AND (
-    SELECT name FROM sqlpage_options WHERE type = 'end'
-  )::date
-);
-SELECT * FROM sqlpage_tags;
-
-SELECT 
-  '# No Data' AS "Notice"
-WHERE NOT EXISTS(SELECT * FROM sqlpage_tags LIMIT 1);
+SET title = 'Tags';
+SELECT 'dynamic' AS component, sqlpage.run_sql('entry.sql') AS properties;

+ 3 - 3
sqlpage/theme.sql

@@ -1,4 +1,4 @@
-SELECT 'shell' AS component,
-  'dark' AS theme,
-  $title AS title
+SELECT 'shell' AS component
+, 'dark' AS theme
+, $title AS title
 ;

+ 2 - 117
sqlpage/transactions.sql

@@ -1,117 +1,2 @@
-SELECT
-  'dynamic' as component,
-  sqlpage.run_sql('cookie.sql') AS properties
-;
-
-SELECT 'shell' AS component,
-  'dark' AS theme,
-  'Transactions' AS title
-;
-
-SELECT
-  'dynamic' as component,
-  sqlpage.run_sql('nav.sql') AS properties
-;
-
-SELECT
-  'table' AS component,
-  TRUE AS sort,
-  TRUE AS search,
-  TRUE AS striped_rows,
-  TRUE AS small,
-  'Price' AS align_right,
-  'Quantity' AS align_right,
-  'Unit' AS align_right,
-  'Notice' AS markdown
-;
-
-DROP TABLE IF EXISTS sqlpage_txn;
-CREATE TEMPORARY TABLE IF NOT EXISTS sqlpage_txn AS (
-SELECT
-  to_char(
-    (ts AT TIME ZONE 'UTC') AT TIME ZONE 'Pacific/Auckland', --COALESCE('$ParameterTZ', 'Pacific/Auckland'),
-    'Mon DD HH24:MI:SS'
-  ) AS "Time",
-  t.description AS Description,
-  s.code AS "Store",
-  p.name AS "Product",
-  c.name AS "Category",
-  g.name AS "Group",
-  CASE WHEN t.organic THEN 'yes' ELSE 'no' END AS "Organic",
-  to_char(t.price, 'FM999999999.00') AS "Price",
-  --to_char(quantity, '9.'||repeat('9',3-1)||'EEEE') AS Quantity,
-  to_char(CASE
-  WHEN ut.name = 'Count' THEN t.price
-  ELSE t.quantity * convert_unit(u.name, CASE
-  WHEN ut.name = 'Volume' THEN ouv.name
-  WHEN ut.name = 'Mass' THEN oum.name
-  END, p.name) END, 'FM999999999.000') AS "Quantity",
-  CASE
-  WHEN ut.name = 'Count' THEN u.name
-  WHEN ut.name = 'Volume' THEN ouv.name
-  WHEN ut.name = 'Mass' THEN oum.name
-  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)
-JOIN sqlpage_options op ON op.type = 'product' AND p.name = op.name
-JOIN sqlpage_options oc ON oc.type = 'category' AND c.name = oc.name
-JOIN sqlpage_options og ON og.type = 'group' AND g.name = og.name
-LEFT JOIN sqlpage_options ouv ON ouv.type = 'unit_volume' AND ut.name = 'Volume'
-AND
-  ouv.session = sqlpage.cookie('session')
-AND
-  COALESCE(ouv.selected, TRUE)
-LEFT JOIN sqlpage_options oum ON oum.type = 'unit_mass' AND ut.name = 'Mass'
-AND
-  oum.session = sqlpage.cookie('session')
-AND
-  COALESCE(oum.selected, TRUE)
-WHERE
-  COALESCE(op.selected, oc.selected, og.selected, TRUE)
-AND
-  op.session = sqlpage.cookie('session')
-AND
-  oc.session = sqlpage.cookie('session')
-AND
-  og.session = sqlpage.cookie('session')
-AND
-  ((ts AT TIME ZONE 'UTC') AT TIME ZONE 'Pacific/Auckland')::date
-  BETWEEN (
-    SELECT name FROM sqlpage_options WHERE type = 'start'
-  )::date AND (
-    SELECT name FROM sqlpage_options WHERE type = 'end'
-  )::date
-AND
-  (t.id IN (
-    SELECT
-      transaction_id
-    FROM tags_map
-    WHERE tag_id IN (
-      SELECT
-        id
-      FROM tags
-      JOIN sqlpage_options ot
-      ON ot.type = 'tag' AND ot.name = tags.name
-      WHERE COALESCE(ot.selected, TRUE)
-      AND ot.session = sqlpage.cookie('session')
-    )
-  ) OR NOT EXISTS (
-      SELECT 1 
-      FROM sqlpage_options ot
-      WHERE ot.selected IS TRUE
-      AND ot.session = sqlpage.cookie('session')
-      AND ot.type = 'tag'
-  )
-)
-ORDER BY ts DESC
-LIMIT 100);
-SELECT * FROM sqlpage_txn;
-
-SELECT 
-  '# No Data' AS "Notice"
-WHERE NOT EXISTS(SELECT * FROM sqlpage_txn LIMIT 1);
+SET title = 'Transactions';
+SELECT 'dynamic' AS component, sqlpage.run_sql('entry.sql') AS properties;