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!' )
app = OrderShipApp() app.run() sys.exit(0) # Cmd de test 8042 cmd_nr = raw_input( '#Commande: ' ) if not cmd_nr.isdigit(): raise ValueError( '%s is not a number' % cmd_nr ) orders = h.get_last_orders( int(cmd_nr), 1 ) if len( orders ) <= 0: raise ValueError( 'order %s not found' % cmd_nr ) order = orders[0] customer = h.get_customer( order.id_customer ) print( '--- Order ID : %i ---' % order.id ) print( 'Shop ID : %s' % order.id_shop ) # print( 'Carrier ID : %i' % order.id_carrier ) # print( 'current state: %i' % order.current_state ) # print( 'Customer ID : %i' % order.id_customer ) print( 'Customer : %s' % customer.customer_name ) print( 'Cust.EMail : %s' % customer.email ) print( 'Carrier : %s' % h.carriers.carrier_from_id( order.id_carrier ).name ) print( 'Current State: %s' % h.order_states.order_state_from_id( order.current_state ).name ) print( 'valid : %i' % order.valid ) print( 'payment : %s' % order.payment ) print( 'total HTVA : %.2f' % order.total_paid_tax_excl ) print( 'total Paid : %.2f' % order.total_paid ) print( 'Shipping Nr : %s' % order.shipping_number )