txn_view.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #
  2. # Copyright (c) Daniel Sheffield 2021
  3. #
  4. # All rights reserved
  5. #
  6. # THIS SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY
  7. from psycopg2.sql import (
  8. Identifier,
  9. SQL,
  10. Literal,
  11. Placeholder,
  12. Composed,
  13. )
  14. from collections import (
  15. OrderedDict,
  16. )
  17. def get_table_statement(alias):
  18. tables = {
  19. 'product': 'products',
  20. 'category': 'categories',
  21. 'group': 'groups',
  22. 'unit': 'store',
  23. }
  24. return SQL("SELECT {column} AS {alias} FROM {table}").format(
  25. column=Identifier(tables[alias], 'name'),
  26. table=Identifier(tables[alias]),
  27. alias=Identifier(alias),
  28. )
  29. def get_transactions_statement():
  30. return SQL("SELECT * FROM transaction_view")
  31. select = OrderedDict([
  32. ('id', Identifier('transactions','id')),
  33. ('ts', SQL("""date_part('day',ts)||'/'||date_part('month',ts)||' '||date_part('hour',ts)::int%12""")),
  34. ('store', Identifier('stores', 'name')),
  35. ('code', Identifier('stores', 'code')),
  36. ('description', Identifier('transactions','description')),
  37. ('volume', Identifier('quantity')),
  38. ('unit', Identifier('units', 'name')),
  39. ('price', Identifier('price')),
  40. ('$/unit', SQL("""TRUNC(price/quantity,4)""")),
  41. ('total', SQL("""sum(transactions.price) OVER (PARTITION BY transactions.ts::date ORDER BY transactions.id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)""")),
  42. ('group', Identifier('groups','name')),
  43. ('category', Identifier('categories','name')),
  44. ('product', Identifier('products','name')),
  45. ('organic', Identifier('organic')),
  46. ])
  47. def get_where(date, store, full_name=False, exact_time=False):
  48. where = [ ]
  49. if store is not None:
  50. where.append(SQL(' ').join([
  51. Identifier('stores', 'name' if full_name else 'code'),
  52. SQL('='),
  53. Literal(store)
  54. ]))
  55. where.append(
  56. SQL("{ts} at time zone 'utc' BETWEEN {date}::date AND {date}::date + {interval}::interval").format(
  57. ts=Identifier('ts'),
  58. date=Literal(str(date)),
  59. interval=Literal('23 hours 59 minutes 59 seconds'),
  60. ) if not exact_time else SQL("{ts} at time zone 'utc' = {date}").format(
  61. ts=Identifier('ts'),
  62. date=Literal(str(date)),
  63. )
  64. )
  65. return SQL('').join([
  66. SQL("WHERE"
  67. "\n "),
  68. SQL("\n AND ").join(where),
  69. ])
  70. def get_session_transactions_statement(date, store, full_name=False, exact_time=False):
  71. statement = SQL('\n').join([
  72. SQL('').join([
  73. SQL("SELECT"
  74. "\n "),
  75. SQL(','
  76. "\n ").join([
  77. SQL(' ').join([v, SQL('AS'), Identifier(f'{k}')]) for k, v in select.items()
  78. ])
  79. ]),
  80. SQL('').join([
  81. SQL("FROM"
  82. "\n "),
  83. SQL("\n JOIN ").join([
  84. SQL("transactions"),
  85. SQL("{table} ON {table}.{key} = {index}").format(
  86. table=Identifier('units'),
  87. key=Identifier('id'),
  88. index=Identifier('unit_id'),
  89. ),
  90. SQL("{table} ON {table}.{key} = {index}").format(
  91. table=Identifier('stores'),
  92. key=Identifier('id'),
  93. index=Identifier('store_id')
  94. ),
  95. SQL("{table} ON {table}.{key} = {index}").format(
  96. table=Identifier('products'),
  97. key=Identifier('id'),
  98. index=Identifier('product_id')
  99. ),
  100. SQL("{table} ON {table}.{key} = {index}").format(
  101. table=Identifier('categories'),
  102. key=Identifier('id'),
  103. index=Identifier('category_id')
  104. ),
  105. SQL("{table} ON {table}.{key} = {index}").format(
  106. table=Identifier('groups'),
  107. key=Identifier('id'),
  108. index=Identifier('group_id')
  109. ),
  110. ]),
  111. ]),
  112. get_where(date if exact_time else date.replace(
  113. hour=0, minute=0, second=0, microsecond=0
  114. ), store, full_name=full_name, exact_time=exact_time),
  115. SQL('ORDER BY {_id} DESC').format(_id=Identifier('transactions','id')),
  116. ])
  117. return statement