diff options
Diffstat (limited to 'src/scanner-session/scannersession.vala')
-rw-r--r-- | src/scanner-session/scannersession.vala | 386 |
1 files changed, 254 insertions, 132 deletions
diff --git a/src/scanner-session/scannersession.vala b/src/scanner-session/scannersession.vala index 9638ef5..796cf93 100644 --- a/src/scanner-session/scannersession.vala +++ b/src/scanner-session/scannersession.vala @@ -1,4 +1,5 @@ /* Copyright 2012-2013, Sebastian Reichel <sre@ring0.de> + * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,16 +17,19 @@ [DBus (name = "io.mainframe.shopsystem.ScannerSession")] public class ScannerSessionImplementation { private int user = 0; - private string name = "Guest"; + private string name = _("Guest"); private bool logged_in = false; private bool disabled = false; private string theme = "beep"; private Database db; private AudioPlayer audio; - private InputDevice dev; + private InputDevice devScanner; + private InputDevice devRfid; private Cli cli; + private ScannerSessionState state = ScannerSessionState.READY; + private DetailedProduct[] shoppingCard = {}; public signal void msg(MessageType type, string message); public signal void msg_overlay(string title, string message); @@ -33,14 +37,16 @@ public class ScannerSessionImplementation { public ScannerSessionImplementation() { try { db = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Database", "/io/mainframe/shopsystem/database"); - dev = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.InputDevice", "/io/mainframe/shopsystem/device"); + devScanner = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.InputDevice", "/io/mainframe/shopsystem/device/scanner"); + devRfid = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.InputDevice", "/io/mainframe/shopsystem/device/rfid"); cli = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Cli", "/io/mainframe/shopsystem/cli"); audio = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.AudioPlayer", "/io/mainframe/shopsystem/audio"); - dev.received_barcode.connect(handle_barcode); + devScanner.received_barcode.connect(handle_barcode); + devRfid.received_barcode.connect(handle_barcode); cli.received_barcode.connect(handle_barcode); } catch(IOError e) { - error("IOError: %s\n", e.message); + error(_("IO Error: %s\n"), e.message); } } @@ -51,19 +57,21 @@ public class ScannerSessionImplementation { msg(type, message); } - private void logout() { - logged_in = false; - } - - private bool login(int user) throws IOError { + private bool login(int user) throws DBusError, IOError { this.user = user; - try { - this.name = db.get_username(user); - this.disabled = db.user_is_disabled(user); - } catch(DatabaseError e) { - send_message(MessageType.ERROR, "Error (user=%d): %s", user, e.message); - return false; + if (user != 0) { + try { + this.name = db.get_username(user); + this.disabled = db.user_is_disabled(user); + } catch(DatabaseError e) { + send_message(MessageType.ERROR, _("Error (user=%d): %s"), user, e.message); + return false; + } + } else { + this.name = _("Guest"); + this.disabled = false; } + this.logged_in = true; try { @@ -78,141 +86,255 @@ public class ScannerSessionImplementation { return true; } - private void handle_barcode(string scannerdata) { - try { - stdout.printf("scannerdata: %s\n", scannerdata); - if(interpret(scannerdata)) - dev.blink(1000); - } catch(IOError e) { - send_message(MessageType.ERROR, "IOError: %s", e.message); - } catch(DatabaseError e) { - send_message(MessageType.ERROR, "DatabaseError: %s", e.message); - } - } - - private bool interpret(string scannerdata) throws DatabaseError, IOError { - if(scannerdata.has_prefix("USER ")) { - string str_id = scannerdata.substring(5); - int32 id = int.parse(str_id); + private ScannerSessionCodeType getCodeType(string scannerdata) { + if(scannerdata.has_prefix("USER ")){ + return ScannerSessionCodeType.USER; + } else if(scannerdata == "GUEST") { + return ScannerSessionCodeType.GUEST; + } else if(scannerdata == "UNDO") { + return ScannerSessionCodeType.UNDO; + } else if(scannerdata == "LOGOUT") { + return ScannerSessionCodeType.LOGOUT; + } else if(scannerdata.length == 10) { + return ScannerSessionCodeType.RFIDEM4100; + } else { + //Handle EAN Code + uint64 id = 0; + scannerdata.scanf("%llu", out id); /* check if scannerdata has valid format */ - if(scannerdata != "USER %d".printf(id)) { - audio.play_system("error.ogg"); - send_message(MessageType.ERROR, "Invalid User ID: %s", scannerdata); - return false; - } - - if(logged_in) { - send_message(MessageType.WARNING, "Last user forgot to logout"); - logout(); + if(scannerdata != "%llu".printf(id) && scannerdata != "%08llu".printf(id) && scannerdata != "%013llu".printf(id)) { + return ScannerSessionCodeType.UNKNOWN; } + return ScannerSessionCodeType.EAN; + } + } - if(login(id)) { - audio.play_user(theme, "login"); - send_message(MessageType.INFO, "Login: %s (%d)", name, user); - return true; - } else { + private void play_audio(AudioType audioType) throws DBusError, IOError { + switch (audioType) { + case AudioType.ERROR: audio.play_system("error.ogg"); - send_message(MessageType.ERROR, "Login failed (User ID = %d)", id); - return false; - } - } else if(scannerdata == "GUEST") { - if(logged_in) { - send_message(MessageType.WARNING, "Last user forgot to logout"); - logout(); - } - - if(login(0)) { + break; + case AudioType.LOGIN: audio.play_user(theme, "login"); - send_message(MessageType.INFO, "Login: %s (%d)", name, user); - return true; - } else { - audio.play_system("error.ogg"); - send_message(MessageType.ERROR, "Login failed (User ID = 0)"); - return false; - } - } else if(scannerdata == "UNDO") { - if(!logged_in) { - audio.play_system("error.ogg"); - send_message(MessageType.ERROR, "Can't undo if not logged in!"); - return false; - } else { - string product = db.undo(user); + break; + case AudioType.LOGOUT: + audio.play_user(theme, "logout"); + break; + case AudioType.PURCHASE: + audio.play_user(theme, "purchase"); + break; + case AudioType.INFO: + audio.play_user(theme, "login"); + break; + } + } - if(product != "") { - audio.play_user(theme, "purchase"); - send_message(MessageType.INFO, "Removed purchase of %s", product); - return true; + private ScannerResult handleReadyState(string scannerdata) throws DatabaseError, DBusError, IOError { + ScannerSessionCodeType codeType = getCodeType(scannerdata); + ScannerResult scannerResult = ScannerResult(); + switch (codeType) { + case ScannerSessionCodeType.USER: + int32 userid = int.parse(scannerdata.substring(5)); + if(login(userid)) { + scannerResult.type = MessageType.INFO; + scannerResult.message = _("Login: %s (%d)").printf(name, user); + scannerResult.audioType = AudioType.LOGIN; + shoppingCard = {}; + state = ScannerSessionState.USER; } else { - audio.play_user(theme, "error"); - send_message(MessageType.ERROR, "Couldn't undo last purchase!"); - return false; + scannerResult.type = MessageType.ERROR; + scannerResult.message = _("Login failed (User ID = %d)").printf(userid); + scannerResult.audioType = AudioType.ERROR; + state = ScannerSessionState.READY; + } + return scannerResult; + case ScannerSessionCodeType.GUEST: + if(login(0)) { + scannerResult.type = MessageType.INFO; + scannerResult.message = _("Login as Guest"); + scannerResult.audioType = AudioType.LOGIN; + shoppingCard = {}; + state = ScannerSessionState.USER; + } else { + scannerResult.type = MessageType.ERROR; + scannerResult.message = _("Login failed (Guest)"); + scannerResult.audioType = AudioType.ERROR; + state = ScannerSessionState.READY; + } + return scannerResult; + case ScannerSessionCodeType.EAN: + uint64 ean = 0; + scannerdata.scanf("%llu", out ean); + var p = DetailedProduct(); + try { + p = db.get_product_for_ean(ean); + } catch(IOError e) { + scannerResult.type = MessageType.ERROR; + scannerResult.message = _("Internal Error!"); + scannerResult.audioType = AudioType.ERROR; + return scannerResult; + } catch(DatabaseError e) { + if(e is DatabaseError.PRODUCT_NOT_FOUND) { + scannerResult.type = MessageType.ERROR; + scannerResult.message = _("Error: unknown product: %llu").printf(ean); + scannerResult.audioType = AudioType.ERROR; + } else { + scannerResult.type = MessageType.ERROR; + scannerResult.message = _("Error: %s").printf(e.message); + scannerResult.audioType = AudioType.ERROR; + } + return scannerResult; } - } - } else if(scannerdata == "LOGOUT") { - if(logged_in) { - audio.play_user(theme, "logout"); - send_message(MessageType.INFO, "Logout!"); - logout(); - return true; - } - return false; - } else { - uint64 id = 0; - scannerdata.scanf("%llu", out id); + var mprice = p.memberprice; + var gprice = p.guestprice; + var pname = p.name; - /* check if scannerdata has valid format */ - if(scannerdata != "%llu".printf(id) && scannerdata != "%08llu".printf(id) && scannerdata != "%013llu".printf(id)) { - audio.play_user(theme, "error"); - send_message(MessageType.ERROR, "invalid product: %s", scannerdata); - return false; - } + scannerResult.type = MessageType.INFO; + scannerResult.message = _("Article info: %s (Member: %s €, Guest: %s €").printf(@"$pname", @"$mprice", @"$gprice"); + scannerResult.audioType = AudioType.ERROR; + state = ScannerSessionState.READY; + return scannerResult; + case ScannerSessionCodeType.RFIDEM4100: + int user = db.get_userid_for_rfid(scannerdata); + scannerResult.nextScannerdata = @"USER $user"; + return scannerResult; + default: + state = ScannerSessionState.READY; + return scannerResult; + } + } - string name = "unknown product"; + private ScannerResult handleUserState(string scannerdata) throws DatabaseError, DBusError, IOError { + ScannerSessionCodeType codeType = getCodeType(scannerdata); + ScannerResult scannerResult = ScannerResult(); + switch (codeType) { + case ScannerSessionCodeType.EAN: + uint64 ean = 0; + scannerdata.scanf("%llu", out ean); + var p = DetailedProduct(); + try { + p = db.get_product_for_ean(ean); + } catch(IOError e) { + scannerResult.type = MessageType.ERROR; + scannerResult.message = _("Internal Error!"); + scannerResult.audioType = AudioType.ERROR; + return scannerResult; + } catch(DatabaseError e) { + if(e is DatabaseError.PRODUCT_NOT_FOUND) { + scannerResult.type = MessageType.ERROR; + scannerResult.message = _("Error: unknown product: %llu").printf(ean); + scannerResult.audioType = AudioType.ERROR; + } else { + scannerResult.type = MessageType.ERROR; + scannerResult.message = _("Error: %s").printf(e.message); + scannerResult.audioType = AudioType.ERROR; + } + return scannerResult; + } - try { - id = db.ean_alias_get(id); - name = db.get_product_name(id); - } catch(IOError e) { - audio.play_user(theme, "error"); - send_message(MessageType.ERROR, "Internal Error!"); - return false; - } catch(DatabaseError e) { - if(e is DatabaseError.PRODUCT_NOT_FOUND) { - audio.play_user(theme, "error"); - var msg = "Error: unknown product: %llu".printf(id); - send_message(MessageType.ERROR, msg); - msg_overlay("Attention", msg); + shoppingCard += p; + + Price price = p.memberprice; + + if(user == 0){ + price = p.guestprice; + } + + scannerResult.type = MessageType.INFO; + scannerResult.message = _("Article added to shopping card: %s (%s €)").printf(@"$(p.name)", @"$price"); + scannerResult.audioType = AudioType.PURCHASE; + state = ScannerSessionState.USER; + break; + case ScannerSessionCodeType.UNDO: + if(shoppingCard.length > 0){ + var removedProduct = shoppingCard[shoppingCard.length-1]; + shoppingCard = shoppingCard[0:shoppingCard.length-1]; + scannerResult.type = MessageType.INFO; + scannerResult.message = _("Removed last Item from Shopping Cart: %s").printf(@"$(removedProduct.name)"); + scannerResult.audioType = AudioType.INFO; } else { - audio.play_user(theme, "error"); - send_message(MessageType.ERROR, "Error: %s", e.message); + scannerResult.type = MessageType.INFO; + scannerResult.message = _("No more Items on your Shopping Cart"); + scannerResult.audioType = AudioType.ERROR; } - return false; - } + break; + case ScannerSessionCodeType.LOGOUT: + scannerResult = logout(); + break; + case ScannerSessionCodeType.USER: + case ScannerSessionCodeType.GUEST: + case ScannerSessionCodeType.RFIDEM4100: + /* Logout old user session (and buy articles) */ + scannerResult = logout(); + scannerResult.nextScannerdata = scannerdata; + break; + } - if(!logged_in) { - var mprice = db.get_product_price(1, id); - var gprice = db.get_product_price(0, id); - var msg = @"article info: $name (Member: $mprice €, Guest: $gprice €)"; - audio.play_system("error.ogg"); - send_message(MessageType.INFO, msg); - send_message(MessageType.ERROR, "Login required for purchase!"); - msg_overlay("Attention", "%s\nLogin required for purchase!".printf(msg)); + return scannerResult; + } - return false; + private ScannerResult buyShoppingCard() throws DatabaseError, DBusError, IOError { + ScannerResult scannerResult = ScannerResult(); + uint8 amountOfItems = 0; + Price totalPrice = 0; + uint8 i = 0; + DetailedProduct p = DetailedProduct(); + for(i = 0; i < shoppingCard.length; i++) { + p = shoppingCard[i]; + db.buy(user, p.ean); + amountOfItems++; + Price price = p.memberprice; + if(user == 0) { + price = p.guestprice; } + totalPrice += price; + } + scannerResult.type = MessageType.INFO; + scannerResult.message = @_("%s bought %d items for %s €").printf(@"$name", amountOfItems, @"$totalPrice"); + scannerResult.audioType = AudioType.INFO; + return scannerResult; + } - if(db.buy(user, id)) { - var price = db.get_product_price(user, id); - audio.play_user(theme, "purchase"); - send_message(MessageType.INFO, @"article bought: $name ($price €)"); - return true; - } else { - audio.play_user(theme, "error"); - send_message(MessageType.ERROR, "purchase failed!"); - return false; - } + private void handle_barcode(string scannerdata) { + try { + stdout.printf("scannerdata: %s\n", scannerdata); + if(interpret(scannerdata)) + devScanner.blink(1000); + } catch(DBusError e) { + send_message(MessageType.ERROR, _("DBus Error: %s"), e.message); + } catch(IOError e) { + send_message(MessageType.ERROR, _("IO Error: %s"), e.message); + } catch(DatabaseError e) { + send_message(MessageType.ERROR, _("Database Error: %s"), e.message); + } + } + + private bool interpret(string scannerdata) throws DatabaseError, DBusError, IOError { + ScannerResult scannerResult = ScannerResult(); + switch (state) { + case ScannerSessionState.READY: + scannerResult = handleReadyState(scannerdata); + break; + case ScannerSessionState.USER: + scannerResult = handleUserState(scannerdata); + break; } + + play_audio(scannerResult.audioType); + send_message(scannerResult.type, scannerResult.message); + if(scannerResult.nextScannerdata != null){ + interpret(scannerResult.nextScannerdata); + } + return true; + } + + private ScannerResult logout() throws DatabaseError, DBusError, IOError { + ScannerResult scannerResult = buyShoppingCard(); + scannerResult.audioType = AudioType.LOGOUT; + logged_in = false; + state = ScannerSessionState.READY; + return scannerResult; } } |