|
@@ -5,9 +5,11 @@
|
|
|
# All rights reserved
|
|
|
#
|
|
|
# THIS SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY
|
|
|
-
|
|
|
+from txn_view import get_statement as get_session_transactions_statement
|
|
|
try:
|
|
|
import psycopg2
|
|
|
+ from psycopg2.sql import SQL
|
|
|
+ from db_utils import cursor_as_dict
|
|
|
MOCK = False
|
|
|
except:
|
|
|
from faker import Faker
|
|
@@ -137,6 +139,13 @@ class mock_cur(object):
|
|
|
def close(self):
|
|
|
pass
|
|
|
|
|
|
+try:
|
|
|
+ from db_credentials import HOST, PASSWORD
|
|
|
+ host = f'host={HOST}'
|
|
|
+ password = f'password={PASSWORD}'
|
|
|
+except:
|
|
|
+ host = ''
|
|
|
+ password = ''
|
|
|
|
|
|
if MOCK:
|
|
|
records = [{
|
|
@@ -189,7 +198,7 @@ if MOCK:
|
|
|
else:
|
|
|
import os
|
|
|
user = os.getenv('USER')
|
|
|
- conn = psycopg2.connect(f"dbname=das user={user}")
|
|
|
+ conn = psycopg2.connect(f"{host} dbname=das user={user} {password}")
|
|
|
cur = conn.cursor()
|
|
|
|
|
|
palette = [
|
|
@@ -210,13 +219,14 @@ side_pane = [
|
|
|
]
|
|
|
bottom_pane = [
|
|
|
'description',
|
|
|
+ 'dbview',
|
|
|
]
|
|
|
|
|
|
cols = [
|
|
|
c for c in filter(
|
|
|
lambda x: x is not None,
|
|
|
itertools.chain(
|
|
|
- *grid_layout, side_pane, bottom_pane
|
|
|
+ *grid_layout, side_pane, set(bottom_pane) - set(['dbview'])
|
|
|
)
|
|
|
)
|
|
|
]
|
|
@@ -240,17 +250,21 @@ display_map = {
|
|
|
}
|
|
|
display = lambda data, name: display_map[name](data) if name in display_map else data
|
|
|
|
|
|
-cur.execute("SELECT * FROM transaction_view;")
|
|
|
-if not MOCK:
|
|
|
- col_idx_map = dict([ (d.name, i) for i,d in enumerate(cur.description) if d.name in cols ])
|
|
|
+cur.execute("BEGIN")
|
|
|
|
|
|
-def records(cursor, col_idx_map):
|
|
|
- for row in cursor.fetchall():
|
|
|
- yield dict([
|
|
|
- (name, display(row[i], name)) for name, i in col_idx_map.items()
|
|
|
- ])
|
|
|
- cur.execute("SELECT * FROM transaction_view;")
|
|
|
+def get_session_transactions(date, store):
|
|
|
+ #print(cur.mogrify(get_session_transactions_statement(date,store,full_name=True)).decode("utf-8"))
|
|
|
+ cur.execute(get_session_transactions_statement(date,store,full_name=True))
|
|
|
+ return '\n'.join(map(lambda x: '|'.join(map(str, x)), cur.fetchall()))
|
|
|
+
|
|
|
+def get_transactions_statement():
|
|
|
+ return SQL("SELECT * FROM transaction_view")
|
|
|
|
|
|
+def get_transactions(cursor):
|
|
|
+ cur.execute(get_transactions_statement())
|
|
|
+ yield from map(lambda x: dict([
|
|
|
+ (k, display(v, k)) for k,v in x.items()
|
|
|
+ ]), cursor_as_dict(cur))
|
|
|
|
|
|
def record_matches(record, strict=None, **kwargs):
|
|
|
strict = strict or []
|
|
@@ -283,7 +297,7 @@ def suggestions(name, exclude=NON_IDENTIFIER_COLUMNS, **kwargs):
|
|
|
[ kwargs.pop(k) for k in exclude if k in kwargs]
|
|
|
yield from filter(lambda x: record_matches(
|
|
|
x, strict=[ k for k in kwargs if k != name ], **kwargs
|
|
|
- ), records(cur, col_idx_map))
|
|
|
+ ), get_transactions(cur))
|
|
|
|
|
|
def show_or_exit(key):
|
|
|
if isinstance(key, tuple):
|
|
@@ -616,10 +630,17 @@ class GroceryTransactionEditor(urwid.WidgetPlaceholder):
|
|
|
def update_transaction(self):
|
|
|
for k in self.edit_fields:
|
|
|
self.edit_fields[k].set_edit_text(self.data[k])
|
|
|
+ date, store = self.data['ts'], self.data['store']
|
|
|
+ self.text_fields['dbview'].set_text(
|
|
|
+ get_session_transactions(date, store) if None not in (
|
|
|
+ date or None, store or None
|
|
|
+ ) else ''
|
|
|
+ )
|
|
|
self.organic_checkbox.set_state(True if self.data['organic'] == 'true' else False)
|
|
|
|
|
|
def transaction(self):
|
|
|
self.edit_fields = OrderedDict()
|
|
|
+ self.text_fields = OrderedDict()
|
|
|
for k in self.data:
|
|
|
if k in side_pane and k != 'unit':
|
|
|
ef = AutoCompleteFloatEdit(('bg', k), apply_change_func=self._autocomplete)
|
|
@@ -633,8 +654,8 @@ class GroceryTransactionEditor(urwid.WidgetPlaceholder):
|
|
|
|
|
|
header = urwid.Text(u'Fill Transaction', 'center')
|
|
|
_copyright = urwid.Text(COPYRIGHT, 'center')
|
|
|
- button = urwid.Button(('streak', u'Done'))
|
|
|
- urwid.connect_signal(button, 'click', lambda w: self.save_and_clear())
|
|
|
+ done_button = urwid.Button(('streak', u'Done'))
|
|
|
+ urwid.connect_signal(done_button, 'click', lambda w: self.save_and_clear())
|
|
|
banner = urwid.Pile([
|
|
|
urwid.Padding(header, 'center', width=('relative', 100)),
|
|
|
urwid.Padding(_copyright, 'center', width=('relative', 100)),
|
|
@@ -643,6 +664,16 @@ class GroceryTransactionEditor(urwid.WidgetPlaceholder):
|
|
|
fields = dict([
|
|
|
(k, urwid.LineBox(urwid.AttrMap(self.edit_fields[k], 'streak'), title=k.title(), title_align='left')) for k in self.edit_fields
|
|
|
])
|
|
|
+ txn_view = urwid.Text('')
|
|
|
+ self.text_fields.update({'dbview': txn_view})
|
|
|
+ fields.update({
|
|
|
+ 'dbview': urwid.LineBox(
|
|
|
+ urwid.AttrMap(txn_view, 'streak'),
|
|
|
+ title="Session Data",
|
|
|
+ title_align='left',
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
side_pane_widget = (12, urwid.Pile([
|
|
|
fields[r] if r is not None else urwid.Divider() for r in side_pane
|
|
|
]))
|
|
@@ -670,7 +701,7 @@ class GroceryTransactionEditor(urwid.WidgetPlaceholder):
|
|
|
),
|
|
|
*[ fields[c] if c is not None else urwid.Divider() for c in bottom_pane ],
|
|
|
urwid.Divider(),
|
|
|
- button,
|
|
|
+ done_button,
|
|
|
])
|
|
|
widget = urwid.Filler(widget, 'top')
|
|
|
widget = urwid.AttrMap(widget, 'bg')
|