def main(): def progressHandler(prestaProgressEvent): if prestaProgressEvent.is_finished: print('%s' % prestaProgressEvent.msg) else: print('%i/%i - %s' % (prestaProgressEvent.current_step, prestaProgressEvent.max_step, prestaProgressEvent.msg)) # A CachedPrestaHelper is a PrestaHelper with cache capabilities cachedphelper = CachedPrestaHelper(config.presta_api_url, config.presta_api_key, debug=False, progressCallback=progressHandler) # Force loading cache # cachedphelper.load_from_webshop() #tester = CachedPrestaHelperTest( cachedphelper ) #tester.test_cache() print('******************************************************************') print('* Cache statistics *') print('******************************************************************') print('Type of Helper is %s' % type(cachedphelper)) print('#Carriers = %s' % len(cachedphelper.carriers)) print('#OrderStates = %s' % len(cachedphelper.order_states)) print('#Products = %i' % len(cachedphelper.products)) print('#suppliers = %i' % len(cachedphelper.suppliers)) print('#categories = %i' % len(cachedphelper.categories)) print('#stock availables = %i' % len(cachedphelper.stock_availables)) #print('mise à jour des qty' ) #cachedphelper.stock_availables.update_quantities() #print( 'Voila, c est fait' ) print('******************************************************************') print('* Derniers Messages client *') print('******************************************************************') """ affiche les x derniers messages clients """ id = cachedphelper.get_lastcustomermessage_id() print('last message id: %s' % id) custmsgs = cachedphelper.get_lastcustomermessages(id, 10) for custmsg in reversed(custmsgs): # CustomerMessageData print('--- id: %s---------------' % custmsg.id) print(' date_add: %s' % custmsg.date_add) print(' read : %s' % custmsg.read) print(' Employee: %s' % custmsg.id_employee) print(' id_customer_thread: %s' % custmsg.id_customer_thread) print(custmsg.message) print('') # Ensure cache file to be saved (and will be automatically reloaded) #cachedphelper.save_cache_file() # read char on keyboard print('Press a key to continue:') char = sys.stdin.read(1) return 0
def __init__( self ): self.config = Config() self.h = CachedPrestaHelper( self.config.presta_api_url, self.config.presta_api_key, debug= False ) self.output = PrestaOut() self.state = AppState.WAIT_ORDER # Loaded order self.order = None self.joined_order = [] # other order joined to the shipping self.customer = None self.carrier = '' self.shipping_number = '' self.output.writeln( "Application initialized" )
def main(): def progressHandler( prestaProgressEvent ): if prestaProgressEvent.is_finished: print( '%s' %prestaProgressEvent.msg ) else: print( '%i/%i - %s' % ( prestaProgressEvent.current_step, prestaProgressEvent.max_step, prestaProgressEvent.msg ) ) # A CachedPrestaHelper is a PrestaHelper with cache capabilities cachedphelper = CachedPrestaHelper( config.presta_api_url, config.presta_api_key, debug = False, progressCallback = progressHandler ) # Force loading cache # cachedphelper.load_from_webshop() #tester = CachedPrestaHelperTest( cachedphelper ) #tester.test_cache() print( '******************************************************************' ) print( '* Cache statistics *' ) print( '******************************************************************' ) print( 'Type of Helper is %s' % type(cachedphelper) ) print( '#Carriers = %s' % len(cachedphelper.carriers) ) print( '#OrderStates = %s' % len( cachedphelper.order_states ) ) print( '#Products = %i' % len( cachedphelper.products ) ) print( '#suppliers = %i' % len( cachedphelper.suppliers ) ) print( '#categories = %i' % len( cachedphelper.categories ) ) print( '#stock availables = %i' % len( cachedphelper.stock_availables ) ) #print('mise à jour des qty' ) #cachedphelper.stock_availables.update_quantities() #print( 'Voila, c est fait' ) print( '******************************************************************' ) print( '* Derniers Messages client *' ) print( '******************************************************************' ) """ affiche les x derniers messages clients """ id = cachedphelper.get_lastcustomermessage_id() print( 'last message id: %s' % id ) custmsgs = cachedphelper.get_lastcustomermessages( id, 10 ) for custmsg in reversed(custmsgs): # CustomerMessageData print( '--- id: %s---------------' % custmsg.id ) print( ' date_add: %s' % custmsg.date_add ) print( ' read : %s' % custmsg.read ) print( ' Employee: %s' % custmsg.id_employee ) print( ' id_customer_thread: %s' % custmsg.id_customer_thread ) print( custmsg.message ) print( '' ) # Ensure cache file to be saved (and will be automatically reloaded) #cachedphelper.save_cache_file() # read char on keyboard print( 'Press a key to continue:' ) char = sys.stdin.read(1) return 0
def main(): global cachedHelper """ Simply create the global reference cachedHelper. Useful for interfactive debugging """ # just create the needed object logging.info( 'create cachedHelper object' ) cachedHelper = CachedPrestaHelper( config.presta_api_url, config.presta_api_key, debug = False ) value = raw_input( 'Rafraichir le cache (y/n)' ) if value == 'y': logging.info( 'Force cache refreshing from WebShop' ) cachedHelper.load_from_webshop() logging.info( 'Saving cache file' ) cachedHelper.save_cache_file() logging.info( 'file saved' ) else: logging.info( 'Data not refreshed from the WebShop' )
def __init__( self, screen ): self.screen = screen (self.height, self.width) = screen.getmaxyx() self.subwin = [] # Subwin list self.create_subwin() # Create a SysLog handler self.logger = logging.getLogger() self.logger.setLevel( logging.DEBUG ) # Follow the log with # tail -f /var/log/syslog # formatter = logging.Formatter('%(asctime)s :: %(levelname)s :: %(message)s') # also mention the python filename in the log formatter = logging.Formatter( os.path.basename(__file__)+' :: %(levelname)s :: %(message)s') sys_handler = SysLogHandler( address = '/dev/log') sys_handler.setLevel( LOGGING_LEVEL ) sys_handler.setFormatter( formatter ) self.logger.addHandler( sys_handler ) self.logger.info( 'Starting app' ) self.config = Config() self.cachedphelper = CachedPrestaHelper( self.config.presta_api_url, self.config.presta_api_key, debug = False ) #, progressCallback = progressHandler ) # initialize global variables self.initialize_globals()
def main(): def progressHandler(prestaProgressEvent): if prestaProgressEvent.is_finished: print('%s' % prestaProgressEvent.msg) else: print('%i/%i - %s' % (prestaProgressEvent.current_step, prestaProgressEvent.max_step, prestaProgressEvent.msg)) def initialize_globals(): """ Initialize the global var @ startup or @ reload """ global ID_SUPPLIER_PARAMS _item = cachedphelper.suppliers.supplier_from_name("PARAMS") #for _item in cachedphelper.suppliers: # print( '%i - %s' % (_item.id,_item.name) ) if _item != None: ID_SUPPLIER_PARAMS = _item.id print('Catched PARAMS supplier :-). ID: %i' % ID_SUPPLIER_PARAMS) # A CachedPrestaHelper is a PrestaHelper with cache capabilities cachedphelper = CachedPrestaHelper(config.presta_api_url, config.presta_api_key, debug=False, progressCallback=progressHandler) # Force loading cache # cachedphelper.load_from_webshop() #tester = CachedPrestaHelperTest( cachedphelper ) #tester.test_cache() print('******************************************************************') print('* Cache statistics *') print('******************************************************************') print('Type of Helper is %s' % type(cachedphelper)) print('#Carriers = %s' % len(cachedphelper.carriers)) print('#OrderStates = %s' % len(cachedphelper.order_states)) print('#Products = %i' % len(cachedphelper.products)) print('#suppliers = %i' % len(cachedphelper.suppliers)) print('#categories = %i' % len(cachedphelper.categories)) print('#stock availables = %i' % len(cachedphelper.stock_availables)) print('#product suppliers available = %i' % len(cachedphelper.product_suppliers)) print('******************************************************************') print('') initialize_globals() #print('mise à jour des qty' ) #cachedphelper.stock_availables.update_quantities() #print( 'Voila, c est fait' ) value = '' while value != '+q': try: value = raw_input('What to do: ') # -- COMMANDS ------------------------------------------ # +q, +s, +r g = re_command.match(value) if g: cmd = g.groups()[0] if cmd == 'q': return if cmd == 's': print('Saving cache...') cachedphelper.save_cache_file() if cmd == 'r': print('Contacting WebShop and reloading...') cachedphelper.load_from_webshop() initialize_globals() # reinit global variables if cmd == 'e': # export the inventory list lst = build_inventory_list(cachedphelper) sorted_lst = sorted(lst, key=lambda cargo: cargo.reference) root = export_to_xmltree(sorted_lst) tree = etree.ElementTree(root) root = Tk() root.filename = tkFileDialog.asksaveasfilename( title="Exporter vers fichier XML", filetypes=(("xml", "*.xml"), ("all files", "*.*"))) if (root.filename == u''): print('User abort!') root.destroy() continue tree.write(root.filename) root.destroy() print('exported to %s' % root.filename) if cmd == 'h': help() # restart loop continue # -- SEARCH ------------------------------------------- # GSM, /-LIPO, #g = re_search_text.match( value ) #if g: # # Text to search = groups()[0] if "demo" or groups()[1] if "/-lipo" # txt = g.groups()[0] if g.groups()[0] else g.groups()[1] # list_products( cachedphelper, key = txt ) # continue except Exception as err: print('[ERROR] %s' % err) traceback.print_exc() # eof While return
def main(): cachedHelper = CachedPrestaHelper(config.presta_api_url, config.presta_api_key, debug=False) lcd = EuropeLcdMatrix(config.lcd_device) lcd.create_european_charset() lcd.clear_screen() lcd.autoscroll(False) lcd.activate_lcd(True) lcd.write_european_pos(1, 1, u'LcdOrderTrack') lcd.write_european_pos(2, 1, u' starting...') # default values for variable last_order_id = -1 last_order_data = None bNewPayment = False paid_count = 0 bankwire_count = 0 # Locate the ID_Payment for "Paiement par carte sur place" PAY_AT_MCH = None for order_state in cachedHelper.order_states: if cachedHelper.order_states.name_from_id( order_state.id).upper().find(u'CARTE SUR PLACE') >= 0: PAY_AT_MCH = order_state.id try: # Force initial update last_update_time = time.time() - UPDATE_DELAY while True: if math.floor(time.time() - last_update_time) >= UPDATE_DELAY: lcd.clear_screen() lcd.write_european(u'Updating...') # Identifying the last Order! last_order_id = cachedHelper.get_lastorder_id() last_orders_data = cachedHelper.get_last_orders(last_order_id, count=1) # bOpenOrder = cachedHelper.order_states.is_open_order( last_orders_data[0].current_state ) # Exclude the REAPPROVISIONNEMENT state from light # the LCD. Payment is effectively DONE but # no work/shipping has to be prepared # New order with "Payment sur place" will deliver money shortly # so it is also like a "new payment" --> switch on the light bNewPayment = (cachedHelper.order_states.is_new_order( last_orders_data[0].current_state) or (cachedHelper.order_states.name_from_id( last_orders_data[0].current_state).upper(). find(u'CARTE SUR PLACE') >= 0)) and ( last_orders_data[0].current_state != OrderStateList.ORDER_STATE_REPLENISH) # Activate LCD when receiving a new payment setLcdColor(lcd, cachedHelper, last_orders_data[0]) lcd.activate_lcd(bNewPayment) paid_count = len( cachedHelper.get_order_ids( cachedHelper.order_states.ORDER_STATE_PAID)) bankwire_count = len( cachedHelper.get_order_ids( cachedHelper.order_states.ORDER_STATE_WAIT_BANKWIRE)) # Also add the "Paiement par carte sur place" in Bankwire count if PAY_AT_MCH: bankwire_count += len( cachedHelper.get_order_ids(PAY_AT_MCH)) last_update_time = time.time() else: sInfo = u'upd in %i sec' % int( UPDATE_DELAY - math.floor(time.time() - last_update_time)) sInfo = (sInfo[:16]).ljust(16) lcd.write_european_pos(2, 1, sInfo) time.sleep(2) # Show Count of payments sPayInfo = u'Pay %s | Vir %s' % (paid_count, bankwire_count) sPayInfo = sPayInfo.center(16) lcd.write_european_pos(1, 1, sPayInfo) # Show information about last Order showOrderInfo(lcd, cachedHelper, last_orders_data[0]) except Exception, e: lcd.clear_screen() lcd.write_european_pos('KABOUM!!') lcd.write_european_pos(2, 1, u'Restart in 5 Min') logging.exception(e) time.sleep(5 * 60) os.system('sudo reboot') return 0
def main(): def progressHandler( prestaProgressEvent ): if prestaProgressEvent.is_finished: print( '%s' %prestaProgressEvent.msg ) else: print( '%i/%i - %s' % ( prestaProgressEvent.current_step, prestaProgressEvent.max_step, prestaProgressEvent.msg ) ) def initialize_globals(): """ Initialize the global var @ startup or @ reload """ global ID_SUPPLIER_PARAMS _item = cachedphelper.suppliers.supplier_from_name( "PARAMS" ) #for _item in cachedphelper.suppliers: # print( '%i - %s' % (_item.id,_item.name) ) if _item != None: ID_SUPPLIER_PARAMS = _item.id print( 'Catched PARAMS supplier :-). ID: %i' % ID_SUPPLIER_PARAMS ) # A CachedPrestaHelper is a PrestaHelper with cache capabilities cachedphelper = CachedPrestaHelper( config.presta_api_url, config.presta_api_key, debug = False, progressCallback = progressHandler ) # Force loading cache # cachedphelper.load_from_webshop() #tester = CachedPrestaHelperTest( cachedphelper ) #tester.test_cache() print( '******************************************************************' ) print( '* Cache statistics *' ) print( '******************************************************************' ) print( 'Type of Helper is %s' % type(cachedphelper) ) print( '#Carriers = %s' % len(cachedphelper.carriers) ) print( '#OrderStates = %s' % len( cachedphelper.order_states ) ) print( '#Products = %i' % len( cachedphelper.products ) ) print( '#suppliers = %i' % len( cachedphelper.suppliers ) ) print( '#categories = %i' % len( cachedphelper.categories ) ) print( '#stock availables = %i' % len( cachedphelper.stock_availables ) ) print( '#product suppliers available = %i' % len( cachedphelper.product_suppliers ) ) print( '******************************************************************' ) print( '' ) initialize_globals() #print('mise à jour des qty' ) #cachedphelper.stock_availables.update_quantities() #print( 'Voila, c est fait' ) value = '' while value != '+q': print( '='*40 ) print( ' +r : reload cache | +s : save cache' ) print( ' +12: ean12 to ean13 | +e : create ean13' ) print( ' id : id product to print | partial_code: to search' ) print( ' +ol: On demand label (Large)| +al : address label' ) print( ' +os: On demand label (Short)| +openl : open for... label' ) print( ' +ok: On demand label (King) | +w : Warranty') print( ' +q : quit ' ) print( '='*40 ) print( '' ) value = raw_input( 'What to do: ' ) if value == '+q': pass elif value == '+r': print( 'Contacting WebShop and reloading...' ) cachedphelper.load_from_webshop() initialize_globals() # reinit global variables elif value == '+s': print( 'Saving cache...' ) cachedphelper.save_cache_file() elif value == '+12': ean12_to_ean13() elif value == '+e': product_id_to_ean13() elif value == '+ol': #On_demand Large label ondemand_label_large() elif value == '+os': #On_demand Short label ondemand_label_short() elif value == '+ok': #On_demand King Size Label line1 = raw_input( 'Line 1: ' ) if line1 == '+q' or line1 == '': continue line2 = raw_input( 'Line 2: ' ) print_ondemand_label_kingsize( line1, line2 ) elif value == '+al': # adress Label value = raw_input( 'How many labels or +q: ' ) if value == '+q' or value=='0': continue if value == '': value = '1' qty = int( value ) if qty > 25: qty = 25 print( 'Max 25 labels allowed! Value sharped to 25.' ) print_ondemand_label_large( 'MC Hobby SPRL', [ unicode( config.company_address[0] ), unicode( config.company_address[1] ), unicode( config.company_address[2] ), unicode( u'TVA/VAT: %s' % config.company_vat ), unicode( u'Phone : %s' % config.company_phone ), unicode( u'Web : %s' % config.company_url ) ], qty ) elif value == '+openl': value = raw_input( 'How many labels or +q: ' ) if value == '+q' or value=='0': continue if value == '': value = '1' qty = int( value ) if qty > 25: qty = 25 print( 'Max 25 labels allowed! Value sharped to 25.' ) print_ondemand_label_large( 'Votre produit ouvert pour:', [u'[ ] ajout de matériel', u'[ ] contrôle qualité', u'', u'', u'MC Hobby SPRL' ], qty ) elif value == '+w': prefix_str = raw_input( 'Préfix ou +q (ex:ELI-MEGA) : ' ) if value == '+q': continue counter_start = raw_input( 'N° première étiquette ou +q (ex:150021): ' ) if counter_start == '+q': continue counter_start = int( counter_start ) how_many_label= raw_input( "Combien d'étiquette ou +q : " ) if how_many_label == '+q': continue how_many_label = int( how_many_label ) print_warranty_label_large( prefix_text = prefix_str, counter_start = counter_start, label_count = how_many_label ) elif value.isdigit(): print_for_product( cachedphelper, int(value) ) else: print( 'Looking for product %s...' % value ) list_products( cachedphelper, value ) return
class OrderShipApp(): def __init__( self ): self.config = Config() self.h = CachedPrestaHelper( self.config.presta_api_url, self.config.presta_api_key, debug= False ) self.output = PrestaOut() self.state = AppState.WAIT_ORDER # Loaded order self.order = None self.joined_order = [] # other order joined to the shipping self.customer = None self.carrier = '' self.shipping_number = '' self.output.writeln( "Application initialized" ) def test_storage_paths( self ): # Test the existence of data path and write access, raise exception in case of error self.output.writeln( "Testing paths..." ) with open( os.path.join(self.config.order_ship_data_path, 'testfile.txt'), "a") as f: f.write( 'test access @ %s \r\n' % datetime.datetime.now() ) def order_filename( self, order ): """ Return a tuple (filepath, filename) to use in order to store the order-data """ # order.date_add have the format '2019-08-21 16:02:29' # '2019-08-21 16:02:29' => '201908'... Store by year and month return ( os.path.join( self.config.order_ship_data_path, order.date_add.replace('-','')[0:6] ), '%s.scan' % order.id ) def is_order_file_exists( self, order ): """ Check if a data file is already stored for that order """ path, filename = self.order_filename( order ) try: os.makedirs( path ) except: pass # don't raise error is path already exists return os.path.exists( os.path.join(path, filename) ) def beep( self, success=False, notif=False ): """ Rely of audio output to signal error """ #os.system( "mpg123 %s" % "error.mp3" ) _name = 'error.mp3' if success: _name = 'tada.mp3' if notif: _name = 'notif.mp3' r_ = subprocess.Popen(['mpg123',_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE ) def get_cmd( self, prompt='> ', debug=False ): """ request an command. Return a tuple (cmd_type, cmd_texte) """ global re_add_remove_several_id v = '' while len(v)==0: v = v = raw_input( prompt ) v = v.strip() # Manage the multiplier case _cmd_multiplier = 1 g = re_add_remove_several_id.match( v ) if g: # Extract the data - Qty and ID sign = g.groups()[0] qty = int( g.groups()[1] ) remain = g.groups()[2] # Evaluate Multiplier _cmd_multiplier = qty if sign!="-" else -1*qty v = remain # command = everything after * sign # decode command _cmd_type = None _cmd_data = None _ean_type = ean_type( v ) if _ean_type == EanType.VERB: # decode a VERB barre code _cmd_type = CMD.VERB _cmd_data = VERBS[v] # Convert ean to VERB text # Special VERB to translate in action if _cmd_data == 'APPEND': _cmd_type = CMD.APPEND_ORDER elif _ean_type == EanType.CARRIER: # decode the CARRIER barre code _cmd_type = CMD.SET_CARRIER _cmd_data = CARRIERS[v] # Convert ean to CARRIER name elif _ean_type == EanType.PRODUCT: # Retreive the product ID from EAN _lst = self.h.products.search_products_for_ean( v ) if len(_lst)==0: _cmd_type = CMD.RAW _cmd_data = v else: _cmd_type = CMD.SCAN_PRODUCT _cmd_data = _lst[0].id elif _ean_type == EanType.ORDER: # Extract the order ID _cmd_type = CMD.LOAD_ORDER _cmd_data = int(v[-8:-1]) # Extract order ID from ean else: # it is EanType.UNDEFINED _cmd_type = CMD.RAW _cmd_data = v if debug: print( "Cmd type, data, mult : %s, %s, %i - EanType %s" % (CMD(_cmd_type).name, _cmd_data, _cmd_multiplier,EanType(_ean_type).name) ) return (_cmd_type, _cmd_data, _cmd_multiplier ) # , _ean_type ) def check_scanned( self ): # Check if the scanned items correspond to the order ! _flag = True self.output.writeln( '-'*80) self.output.writeln( 'Order : %s' % self.order.id ) for _joined_order in self.joined_order: self.output.writeln( ' joined %s' % _joined_order.id ) self.output.writeln( 'Carrier : %s' % (self.carrier if self.carrier else '-!-') ) if len(self.carrier)==0: _flag = False self.output.writeln( 'Ship Nr : %s' % (self.shipping_number if self.shipping_number else '-!-') ) if len(self.shipping_number)==0: _flag = False self.output.writeln( '-'*80) self.output.writeln( 'Status| Scan | Order | Detail ' ) self.output.writeln( '-'*80) for row in self.order.rows: _ok = row.ordered_qty == self.scan[row.id_product] _status = 'OK' if _ok else '-!-' if not(_ok): _flag = False self.output.writeln( '%5s | %4i | %5i | %s ' % (_status,self.scan[row.id_product],row.ordered_qty,row) ) return _flag def reset_all( self ): self.order = None self.joined_order = [] # Other order added to the shipping self.scan = None self.customer = None self.state = AppState.WAIT_ORDER self.carrier = '' self.shipping_number = '' self.output.reset_carbon_copy() for i in range( 5 ): print( " " ) # Do not register this message self.output.writeln( "Reset done!" ) for i in range( 5 ): print( " " ) # Do not register this message def run( self ): """ Main application loop """ # Test access to data_path self.test_storage_paths() self.output.set_carbon_copy() cmd_type,cmd_data, cmd_mult = CMD.RAW, '', 1 while not((cmd_type==CMD.RAW) and (cmd_data.upper()=='EXIT')): cmd_type,cmd_data,cmd_mult = self.get_cmd( prompt="%-13s > "%AppState(self.state).name, debug=False) # -- Append extra info to CarbonCopy ------------------------------- self.output.carbon_copy.append( 'CMD: %s, %s, %s' % (cmd_type,cmd_data,cmd_mult)) # -- Reset All ----------------------------------------------------- if (cmd_type == CMD.VERB and cmd_data == 'RESET' ): self.reset_all() continue # -- Loading an order ---------------------------------------------- if (self.state == AppState.WAIT_ORDER) and (cmd_type == CMD.LOAD_ORDER): self.output.writeln( "Loading order %s" % cmd_data ) # load the order orders = self.h.get_last_orders( int(cmd_data), 1 ) if len( orders ) <= 0: self.output.writeln( "[ERROR] order %s not found!" % (cmd_data) ) self.beep() continue # Check if the order has already been managed if self.is_order_file_exists( orders[0] ): self.output.writeln( "[ERROR] scanfile already exists for this order!" ) self.output.writeln( "[ERROR] %s/%s" % self.order_filename( orders[0]) ) self.beep() continue # Skip remaining of loading # Start managing the order self.order = orders[0] self.joined_order = [] self.carrier = '' self.shipping_number = '' self.customer = self.h.get_customer( self.order.id_customer ) self.state = AppState.CONTROL_ORDER self.output.reset_carbon_copy() # we will keep a copy of everything self.output.writeln( '--- Order ID : %i ---' % self.order.id ) # self.output.writeln( 'Shop ID : %s' % order.id_shop ) self.output.writeln( 'Customer : %s' % self.customer.customer_name ) self.output.writeln( 'Cust.EMail : %s' % self.customer.email ) self.output.writeln( 'Order Date : %s' % self.order.date_add ) # Content the order self.scan = {} for row in self.order.rows: self.output.writeln( row ) self.scan[row.id_product] = 0 continue # -- Scan Product -------------------------------------------------- if (cmd_type == CMD.SCAN_PRODUCT): if self.state != AppState.CONTROL_ORDER: self.output.writeln("[ERROR] No order loaded") self.beep() else: # Is the product in the order list if any( [ int(cmd_data) == int(product.id_product) for product in self.order.rows ] ): _items = [ product for product in self.order.rows if int(cmd_data) == int(product.id_product) ] _product = _items[0] if cmd_mult + self.scan[_product.id_product] > _product.ordered_qty : self.output.writeln( '[ERROR] %i * %s (%s) product CANNOT BE ADDED!' % (cmd_mult, _product.reference, _product.id_product) ) self.output.writeln( '[ERROR] Ordered: %i, Current Scan: %i' %(_product.ordered_qty,self.scan[_product.id_product]) ) self.beep() else: self.scan[_product.id_product] = self.scan[_product.id_product] + cmd_mult else: self.output.writeln( "[ERROR] Product %s not in the order!" % cmd_data ) self.beep() continue # -- Append order -------------------------------------------------- # User selected APPEND ORDER carcode if (cmd_type == CMD.APPEND_ORDER): if self.state != AppState.CONTROL_ORDER: self.output.writeln("[ERROR] No order loaded") self.beep() else: self.output.writeln("SELECT order TO APPEND to shipping!") self.state = AppState.APPEND_ORDER self.beep( notif=True ) continue # user selected an order if (self.state == AppState.APPEND_ORDER) and (cmd_type == CMD.LOAD_ORDER): self.output.writeln( "Append order %s" % cmd_data ) # load the order orders = self.h.get_last_orders( int(cmd_data), 1 ) if len( orders ) <= 0: self.output.writeln( "[ERROR] order %s not found!" % (cmd_data) ) self.beep() continue # Check if the order has already been managed if self.is_order_file_exists( orders[0] ): self.output.writeln( "[ERROR] scanfile already exists for this order!" ) self.output.writeln( "[ERROR] %s/%s" % self.order_filename( orders[0]) ) self.beep() continue # Skip remaining of loading # Start appending the loaded order self.joined_order.append( orders[0] ) for row in orders[0].rows: # rows in joined order self.output.writeln( "Append %s" % row ) if not( row.id_product in self.scan ): self.scan[row.id_product] = 0 _matching_rows = [ _row for _row in self.order.rows if _row.id_product == row.id_product ] if len( _matching_rows )>0: _matching_rows[0].ordered_qty += row.ordered_qty # Appending qty to existing order's row else: self.order.rows.append( row ) self.output.writeln( "Order %i succesfuly added" % orders[0].id ) self.state = AppState.CONTROL_ORDER # Return to control order state continue # user selected CANCEL BarCode if (self.state == AppState.APPEND_ORDER) and (cmd_type == CMD.VERB and cmd_data == 'CANCEL' ): self.output.writeln( "Order appending canceled!") self.state = AppState.CONTROL_ORDER continue # -- Capture Carrier ----------------------------------------------- if (cmd_type == CMD.SET_CARRIER ): if self.state != AppState.CONTROL_ORDER: self.output.writeln("[ERROR] No order loaded") self.beep() else: self.state = AppState.WAIT_SHIPPING self.carrier = cmd_data self.beep( notif=True ) continue # -- Capture Number ----------------------------------------------- if ((cmd_type == CMD.RAW) and (self.state == AppState.WAIT_SHIPPING) ): if len(cmd_data)>0 : self.shipping_number = cmd_data # GetBack to previous state self.state = AppState.CONTROL_ORDER continue # -- Check --------------------------------------------------------- if (cmd_type == CMD.VERB and cmd_data == 'CHECK' ): if self.state != AppState.CONTROL_ORDER: self.output.writeln("[ERROR] No order loaded") self.beep() else: # Did it worked properly ? if not( self.check_scanned() ): self.beep() else: self.beep( success=True ) continue # -- Finalize ------------------------------------------------------ if (cmd_type == CMD.VERB and cmd_data == 'FINALIZE' ): if self.state != AppState.CONTROL_ORDER: self.output.writeln("[ERROR] No order loaded") self.beep() else: if not( self.check_scanned() ): self.beep() continue self.output.writeln("") self.output.writeln("ORDER ID %i CHECK SUCCESSFULLY" % self.order.id ) self.output.writeln("CUSTOMER : %s" % self.customer.customer_name ) self.output.writeln("OPERATION DATE : %s" % datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S") ) # Save the scan file. _path, _filename = self.order_filename(self.order) self.output.save_carbon_copy( os.path.join( _path, _filename ) ) # Save all the joined order for _joined_order in self.joined_order: _joined_filename = os.path.join( *(self.order_filename(_joined_order) )) with codecs.open( _joined_filename , 'w', 'utf-8' ) as f: f.write( '--- Order ID : %s ---\r\n' % _joined_order.id ) f.write( 'JOINED TO ORDER : %s\r\n' % self.order.id ) f.write( 'SEE SCAN : %s\r\n' % os.path.join( _path, _filename ) ) # Mention original filename1 f.write( 'OPERATION DATE : %s' % datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S") ) # Reset for next scan session self.reset_all() self.beep( success=True ) continue # == Reaching this Point --> Error ===s============================== self.output.writeln("[ERROR] UNKNOWN instruction scan or ean scan!") self.beep() self.output.writeln( 'User exit!' )
from prestaapi import PrestaHelper, CachedPrestaHelper, OrderStateList from output import PrestaOut from config import Config from pprint import pprint import logging import sys, os, codecs import re, subprocess import signal import datetime # debugging from xml.etree import ElementTree # from enum import Enum config = Config() h = CachedPrestaHelper( config.presta_api_url, config.presta_api_key, debug= False ) #print ("#products = %i" % ( len( h.products ) ) ) class AppState( Enum ): WAIT_ORDER = 0 CONTROL_ORDER = 1 WAIT_SHIPPING = 2 CONTROLED = 3 APPEND_ORDER = 4 # Wait state to append an order class CMD( Enum ): RAW = 0 VERB = 1 # The text value is one of the Verbs dic SET_CARRIER = 2 # Setting the CARRIERS (one of CARRIERS dic), so setting the CARRIER LOAD_ORDER = 3 # Loading an ORDER SCAN_PRODUCT= 4 # Scanning a product
def main(): def progressHandler(prestaProgressEvent): if prestaProgressEvent.is_finished: print('%s' % prestaProgressEvent.msg) else: print('%i/%i - %s' % (prestaProgressEvent.current_step, prestaProgressEvent.max_step, prestaProgressEvent.msg)) def initialize_globals(): """ Initialize the global var @ startup or @ reload """ global ID_SUPPLIER_PARAMS _item = cachedphelper.suppliers.supplier_from_name("PARAMS") #for _item in cachedphelper.suppliers: # print( '%i - %s' % (_item.id,_item.name) ) if _item != None: ID_SUPPLIER_PARAMS = _item.id print('Catched PARAMS supplier :-). ID: %i' % ID_SUPPLIER_PARAMS) # A CachedPrestaHelper is a PrestaHelper with cache capabilities cachedphelper = CachedPrestaHelper(config.presta_api_url, config.presta_api_key, debug=False, progressCallback=progressHandler) # Force loading cache # cachedphelper.load_from_webshop() #tester = CachedPrestaHelperTest( cachedphelper ) #tester.test_cache() print('******************************************************************') print('* Cache statistics *') print('******************************************************************') print('Type of Helper is %s' % type(cachedphelper)) print('#Carriers = %s' % len(cachedphelper.carriers)) print('#OrderStates = %s' % len(cachedphelper.order_states)) print('#Products = %i' % len(cachedphelper.products)) print('#suppliers = %i' % len(cachedphelper.suppliers)) print('#categories = %i' % len(cachedphelper.categories)) print('#stock availables = %i' % len(cachedphelper.stock_availables)) print('#product suppliers available = %i' % len(cachedphelper.product_suppliers)) print('******************************************************************') print('') initialize_globals() #print('mise à jour des qty' ) #cachedphelper.stock_availables.update_quantities() #print( 'Voila, c est fait' ) value = '' while value != '+q': print('=' * 40) print(' +r : reload cache | +s : save cache') print(' +12: ean12 to ean13 | +e : create ean13') print(' id : id product to print | partial_code: to search') print(' +ol: On demand label (Large)| +al : address label') print( ' +os: On demand label (Short)| +openl : open for... label') print(' +ok: On demand label (King) | +w : Warranty') print(' +q : quit ') print('=' * 40) print('') value = raw_input('What to do: ') if value == '+q': pass elif value == '+r': print('Contacting WebShop and reloading...') cachedphelper.load_from_webshop() initialize_globals() # reinit global variables elif value == '+s': print('Saving cache...') cachedphelper.save_cache_file() elif value == '+12': ean12_to_ean13() elif value == '+e': product_id_to_ean13() elif value == '+ol': #On_demand Large label ondemand_label_large() elif value == '+os': #On_demand Short label ondemand_label_short() elif value == '+ok': #On_demand King Size Label line1 = raw_input('Line 1: ') if line1 == '+q' or line1 == '': continue line2 = raw_input('Line 2: ') print_ondemand_label_kingsize(line1, line2) elif value == '+al': # adress Label value = raw_input('How many labels or +q: ') if value == '+q' or value == '0': continue if value == '': value = '1' qty = int(value) if qty > 25: qty = 25 print('Max 25 labels allowed! Value sharped to 25.') print_ondemand_label_large('MC Hobby SPRL', [ unicode(config.company_address[0]), unicode(config.company_address[1]), unicode(config.company_address[2]), unicode(u'TVA/VAT: %s' % config.company_vat), unicode(u'Phone : %s' % config.company_phone), unicode(u'Web : %s' % config.company_url) ], qty) elif value == '+openl': value = raw_input('How many labels or +q: ') if value == '+q' or value == '0': continue if value == '': value = '1' qty = int(value) if qty > 25: qty = 25 print('Max 25 labels allowed! Value sharped to 25.') print_ondemand_label_large('Votre produit ouvert pour:', [ u'[ ] ajout de matériel', u'[ ] contrôle qualité', u'', u'', u'MC Hobby SPRL' ], qty) elif value == '+w': prefix_str = raw_input('Préfix ou +q (ex:ELI-MEGA) : ') if value == '+q': continue counter_start = raw_input( 'N° première étiquette ou +q (ex:150021): ') if counter_start == '+q': continue counter_start = int(counter_start) how_many_label = raw_input( "Combien d'étiquette ou +q : ") if how_many_label == '+q': continue how_many_label = int(how_many_label) print_warranty_label_large(prefix_text=prefix_str, counter_start=counter_start, label_count=how_many_label) elif value.isdigit(): print_for_product(cachedphelper, int(value)) else: print('Looking for product %s...' % value) list_products(cachedphelper, value) return
class MyApp: def __init__( self, screen ): self.screen = screen (self.height, self.width) = screen.getmaxyx() self.subwin = [] # Subwin list self.create_subwin() # Create a SysLog handler self.logger = logging.getLogger() self.logger.setLevel( logging.DEBUG ) # Follow the log with # tail -f /var/log/syslog # formatter = logging.Formatter('%(asctime)s :: %(levelname)s :: %(message)s') # also mention the python filename in the log formatter = logging.Formatter( os.path.basename(__file__)+' :: %(levelname)s :: %(message)s') sys_handler = SysLogHandler( address = '/dev/log') sys_handler.setLevel( LOGGING_LEVEL ) sys_handler.setFormatter( formatter ) self.logger.addHandler( sys_handler ) self.logger.info( 'Starting app' ) self.config = Config() self.cachedphelper = CachedPrestaHelper( self.config.presta_api_url, self.config.presta_api_key, debug = False ) #, progressCallback = progressHandler ) # initialize global variables self.initialize_globals() def initialize_globals( self ): """ Initialize the global var @ startup or @ reload """ global ID_SUPPLIER_PARAMS _item = self.cachedphelper.suppliers.supplier_from_name( "PARAMS" ) #for _item in cachedphelper.suppliers: # print( '%i - %s' % (_item.id,_item.name) ) if _item != None: ID_SUPPLIER_PARAMS = _item.id self.logger.info( 'Catched PARAMS supplier :-). ID: %i' % ID_SUPPLIER_PARAMS ) def create_subwin(self): self.wresult = curses.newwin(self.height-1,self.width,0,0) # NLines, NCols, begin_y, begin_x self.wresult.border() self.wresult.addstr(0,2,"[ Result ]") self.wresult.addstr(1,1,"%i , %i" % self.wresult.getmaxyx() ) self.subwin.append( (self.wresult,self.wresult_redraw) ) self.status = curses.newwin(2,self.width,self.height-1,0) # min 2 lines height!!! def wresult_redraw(self): """ redraw the subwin background """ self.wresult.clear() self.wresult.border() self.wresult.addstr( 0, 2, "[ Result ]" ) #def draw_screen(self) def status_redraw( self, input_text=None, input_data=None, info=None ): """ redraw the status bar """ self.status.addstr( 0, 0, " "*self.width, curses.A_REVERSE ) # Only draw information in the second part of the screen info = '| +h for Help' if info==None else '| %s'%info info = info + ' '*(self.width//2-len(info)) self.status.addstr( 0, self.width//2, '%s' % info, curses.A_REVERSE ) # Draw input_text and input_data in the first part of the screen if input_text or input_data: _s = "%s%s" % (input_text,input_data if input_data else '') self.status.addstr( 0, 1, _s, curses.A_REVERSE ) self.status.refresh() def screen_redraw( self ): """ Draw every subwindow THEN refresh the whole terminal """ self.screen.clear() # full screen redraw for win, redraw in self.subwin: redraw() self.status_redraw() # Refresh the output self.refresh() def refresh( self ): """ makes curses refreshing the whole terminal content """ for win, redraw in self.subwin: win.refresh() self.status.refresh() def input( self, text = '?' ): """ capture a string from the keyboard, each characters in the status bar. returns a tuple (input_string,last_ch_ascii_code) """ _r = '' self.status_redraw( input_text=text, input_data=_r ) ch = 0 while True: ch = self.status.getch() self.logger.debug( 'getch returned %i' % ch ) if ch in (13,10): # CR/LF break elif ch == 127: # backspace if len(_r)>0: _r = _r[:-1] elif ch == 27: # escape if len(_r)>0: # First time, we clear the input _r = '' else: break # Second time (so when empty): we exit the input elif 31 <= ch < 256: _r = _r + chr(ch) # Display the current value self.status_redraw( input_text=text, input_data=_r ) self.status.refresh() # Clear input field zone in the status bar self.status_redraw( input_text=None, input_data=None ) self.logger.debug( 'input() returns with "%s" and last key %i' % (_r,ch) ) return (_r,ch) def search_products( self, key=None, ean=None, id=None ): """ Search for a product based on its partial reference code (key) -OR- its ean -OR- product ID. :return: None or a list of product """ result = None if key: assert isinstance( key, str ), 'Key must be a string' if len( key ) < 3: print( 'searching product requires at least 3 characters' ) return result = self.cachedphelper.products.search_products_from_partialref( key ) elif ean: assert isinstance( ean, str ), 'Key must be a string' result = self.cachedphelper.products.search_products_for_ean( ean ) elif id: assert isinstance( id, int ), 'ID must be an integer' _r = self.cachedphelper.products.product_from_id( id ) result = [_r] if _r else None return result def display_products( self, products, auto_select=False ): """ Display a list of products in the wresult Windows :param products: list of product to display. :param auto_select: automaticaly select the first row WHEN it is the unique row! """ self.logger.debug('display_products') iTopIndex = 0 # Index of the TOP record in the products list iSelected = 0 # Index of the ITEM currently selected hClient = self.wresult.getmaxyx()[0] - 2 # Height of the client area wclient = self.wresult.getmaxyx()[1] - 2 while products and len( products )>0: # At least one item self.wresult_redraw() iRow = 0 for i in range(iTopIndex,iTopIndex+hClient): # self.logger.debug( '%i' % i) if i >= len(products): continue item = products[i] _s = '%4i: %s (%6.2f) %6.2f EUR' % (item.id,item.reference.ljust(20),item.price,item.price*1.21) self.wresult.addstr( iRow+1,1, _s, curses.A_REVERSE if i == iSelected else 0 ) iRow += 1 self.wresult.refresh() # auto_select if len( products )==1 and auto_select: return products[0] # user input self.status_redraw( input_text='browsing result...') ch = self.status.getch() self.logger.debug( 'getch returned %i' % ch ) if ch in (13,10): # CR/LF return products[iSelected] #elif ch == 27: #ESC -- also returned with escape sequence.... # return None elif ch == 66: # arrow down # Select next iSelected += 1 if iSelected >= len( products ): iSelected = len( products )-1 # Keep selected row visible if iSelected >= (iTopIndex + hClient): iTopIndex += 1 elif ch == 65: # arrow up iSelected -= 1 if iSelected <= 0: iSelected = 0 # Keep selected row visible if iSelected < iTopIndex: iTopIndex = iSelected # Always return something return None def run( self ): self.screen_redraw() while True: (_cmd,_ch) = self.input( text='Cmd?' ) # special commands if _cmd.upper() == '+Q': break # Exit the software elif _cmd.upper() == '+R': self.status_redraw( info='Contacting WebShop and reloading...' ) self.cachedphelper.load_from_webshop() self.initialize_globals() # reinit global variables self.screen_redraw() self.status_redraw( info='Data reloaded!') sleep( 1 ) continue elif _cmd.upper() == '+S': print( 'Saving cache...' ) self.status_redraw( info = 'Saving cache...') self.cachedphelper.save_cache_file() self.screen_redraw() self.status_redraw( info='Data saved!' ) sleep( 1 ) continue elif _cmd.upper() == '+H': # Display the Help self.wresult_redraw() for idx, line in enumerate( HELP_MESSAGE.split('\n') ): self.wresult.addstr( 1+idx,1, line ) self.wresult.refresh() self.status_redraw(input_text='Press return to continue') self.wresult.getch() self.wresult_redraw() _l = None # List of products if _cmd.isdigit(): if len(_cmd)<=5: # we are looking for a product ID _l = self.search_products( id=int(_cmd) ) else: _l = self.search_products( ean=_cmd ) else: if len(_cmd)<3: self.status_redraw( input_text='Min. 3 chars!!!' ) sleep( 1 ) else: _l = self.search_products( key=_cmd ) # Show the product on the screen self.display_products( _l, auto_select=True ) self.refresh()
def main2(): def progressHandler( prestaProgressEvent ): if prestaProgressEvent.is_finished: print( '%s' %prestaProgressEvent.msg ) else: print( '%i/%i - %s' % ( prestaProgressEvent.current_step, prestaProgressEvent.max_step, prestaProgressEvent.msg ) ) # A CachedPrestaHelper is a PrestaHelper with cache capabilities cachedphelper = CachedPrestaHelper( config.presta_api_url, config.presta_api_key, debug = False, progressCallback = progressHandler ) # Force loading cache # cachedphelper.load_from_webshop() #tester = CachedPrestaHelperTest( cachedphelper ) #tester.test_cache() print( '******************************************************************' ) print( '* Cache statistics *' ) print( '******************************************************************' ) print( 'Type of Helper is %s' % type(cachedphelper) ) print( '#Carriers = %s' % len(cachedphelper.carriers) ) print( '#OrderStates = %s' % len( cachedphelper.order_states ) ) print( '#Products = %i' % len( cachedphelper.products ) ) print( '#suppliers = %i' % len( cachedphelper.suppliers ) ) print( '#categories = %i' % len( cachedphelper.categories ) ) print( '#stock availables = %i' % len( cachedphelper.stock_availables ) ) print( '#product suppliers available = %i' % len( cachedphelper.product_suppliers ) ) print( '******************************************************************' ) print( '' ) initialize_globals() #print('mise à jour des qty' ) #cachedphelper.stock_availables.update_quantities() #print( 'Voila, c est fait' ) value = '' while value != '+q': print( '='*40 ) print( ' +r : reload cache | +s : save cache' ) print( ' +q : quit ' ) print( '='*40 ) print( '' ) value = raw_input( 'What to do: ' ) if value == '+q': pass elif value == '+r': print( 'Contacting WebShop and reloading...' ) cachedphelper.load_from_webshop() initialize_globals() # reinit global variables elif value == '+s': print( 'Saving cache...' ) cachedphelper.save_cache_file() elif value.isdigit(): if len(value)<=5: # we are looking for a product ID list_products( cachedphelper, id=int(value) ) else: list_products( cachedphelper, ean=value ) else: print( 'Looking for product %s...' % value ) list_products( cachedphelper, key=value ) return