diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | db.vala | 25 | ||||
-rw-r--r-- | main.vala | 12 | ||||
-rw-r--r-- | ui.vala | 30 | ||||
-rw-r--r-- | user-interface.ui | 140 |
5 files changed, 208 insertions, 3 deletions
@@ -1,8 +1,8 @@ PREFIX=/usr/local # web.vala (currently disabled) -barcode-scanner: main.vala device.vala db.vala - valac-0.16 --output $@ --pkg posix --pkg linux --pkg libsoup-2.4 --pkg sqlite3 $^ +barcode-scanner: main.vala device.vala db.vala ui.vala + valac-0.16 --output $@ --pkg posix --pkg linux --pkg libsoup-2.4 --pkg sqlite3 --pkg gtk+-3.0 --pkg gee-1.0 $^ shop.db: create_db.sql sqlite3 shop.db < create_db.sql @@ -1,6 +1,7 @@ public class Database { private Sqlite.Database db; private Sqlite.Statement product_stmt; + private Sqlite.Statement products_stmt; private Sqlite.Statement purchase_stmt1; private Sqlite.Statement purchase_stmt2; private Sqlite.Statement undo_stmt1; @@ -14,6 +15,7 @@ public class Database { bool logged_in = false; bool stock_mode = false; private static string product_query = "SELECT name FROM products WHERE id = ?"; + private static string products_query = "SELECT id, name FROM products"; private static string purchase_query1 = "INSERT INTO purchases ('user', 'product', 'timestamp') VALUES (?, ?, ?)"; private static string purchase_query2 = "UPDATE products SET amount = amount - 1 WHERE id = ?"; private static string undo_query1 = "SELECT product FROM purchases WHERE user = ? ORDER BY timestamp DESC LIMIT 1"; @@ -46,6 +48,11 @@ public class Database { error("could not prepare article statement!"); } + rc = this.db.prepare_v2(products_query, -1, out products_stmt); + if(rc != Sqlite.OK) { + error("could not prepare products statement!"); + } + rc = this.db.prepare_v2(undo_query1, -1, out undo_stmt1); if(rc != Sqlite.OK) { error("could not prepare first undo statement!"); @@ -91,6 +98,16 @@ public class Database { return true; } + public Gee.HashMap<string,string> get_products() { + var result = new Gee.HashMap<string,string>(null, null); + this.products_stmt.reset(); + + while(this.products_stmt.step() == Sqlite.ROW) + result[this.products_stmt.column_text(0)] = this.products_stmt.column_text(1); + + return result; + } + public bool buy(uint64 article) { if(is_logged_in()) { int rc = 0; @@ -209,6 +226,14 @@ public class Database { public bool add_stock_product(uint64 amount) { if(is_in_stock_mode() && product != 0) { + return restock(this.product, amount); + } + + return false; + } + + public bool restock(uint64 product, uint64 amount) { + if(is_logged_in()) { int rc = 0; int64 timestamp = (new DateTime.now_utc()).to_unix(); @@ -1,7 +1,10 @@ public Device dev; public Database db; +public Gtk.Builder builder; public static int main(string[] args) { + Gtk.init (ref args); + if(args.length < 2) { stderr.printf("%s <device>\n", args[0]); return 1; @@ -9,13 +12,20 @@ public static int main(string[] args) { dev = new Device(args[1], 9600, 8, 1); db = new Database("shop.db"); + builder = new Gtk.Builder(); + try { + builder.add_from_file("user-interface.ui"); + } catch(Error e) { + stderr.printf ("Could not load UI: %s\n", e.message); + return 1; + } dev.received_barcode.connect((data) => { if(interpret(data)) dev.blink(10); }); - new MainLoop(null, false).run(); + Gtk.main(); return 0; } @@ -0,0 +1,30 @@ +public void restock_dialog() { + var window = builder.get_object("restock_dialog") as Gtk.Window; + window.show_all(); + + /* product combobox */ + var box = builder.get_object("comboboxtext1") as Gtk.ComboBoxText; + foreach(var entry in db.get_products().entries) { + box.append(entry.key, entry.value); + } + + /* spinner button */ + var spinner = builder.get_object("spinbutton1") as Gtk.SpinButton; + + /* dialog buttons */ + var cancel = builder.get_object("button-restock-cancel") as Gtk.Button; + var ok = builder.get_object("button-restock-add") as Gtk.Button; + + cancel.clicked.connect(() => { + window.destroy(); + }); + + ok.clicked.connect(() => { + var id = box.get_active_id(); + var product = (id != null) ? uint64.parse(id) : 0; + var amount = (int) spinner.get_value(); + + if(db.restock(product, amount)) + window.destroy(); + }); +} diff --git a/user-interface.ui b/user-interface.ui new file mode 100644 index 0000000..55266f5 --- /dev/null +++ b/user-interface.ui @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <!-- interface-requires gtk+ 3.0 --> + <object class="GtkAdjustment" id="adjustment1"> + <property name="upper">100</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkDialog" id="restock_dialog"> + <property name="can_focus">False</property> + <property name="border_width">5</property> + <property name="title" translatable="yes">restock</property> + <property name="type_hint">dialog</property> + <child internal-child="vbox"> + <object class="GtkBox" id="dialog-vbox1"> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">5</property> + <child internal-child="action_area"> + <object class="GtkButtonBox" id="dialog-action_area1"> + <property name="can_focus">False</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="button-restock-cancel"> + <property name="label">gtk-cancel</property> + <property name="use_action_appearance">False</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="button-restock-add"> + <property name="label">gtk-add</property> + <property name="use_action_appearance">False</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkGrid" id="grid1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="row_spacing">5</property> + <property name="column_spacing">5</property> + <child> + <object class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Product</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Amount</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="spinbutton1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="max_length">3</property> + <property name="invisible_char">•</property> + <property name="adjustment">adjustment1</property> + <property name="climb_rate">1</property> + <property name="numeric">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkComboBoxText" id="comboboxtext1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="entry_text_column">0</property> + <property name="id_column">1</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="0">button-restock-cancel</action-widget> + <action-widget response="0">button-restock-add</action-widget> + </action-widgets> + </object> +</interface> |