def handle(self, restock_string): user = self.msg.connection.contact #Check permissions. Unregistered users will receive an unhelpful error message. if not user.role: self.respond("You do not have permission to use this command.") return True restock_list = self.parse_restock_string(restock_string) errors = [] response = "" for code, amount in restock_list: #ignore incorrect codes if amount <= 0: #no matching product code errors.append(code) else: target_product = Product.by_code(code) current_stock = Stock.get_existing(user.alias, code) if current_stock is None: s = Stock(seller=user, product=target_product, stock_amount=amount) s.save() response += "%s %s, " % (amount, target_product.display_name) else: current_stock.stock_amount += amount current_stock.save() response += "%s %s, " % (amount, target_product.display_name) if response: response = response[:-2] + " added. " if errors: for err in errors: response += "%s " % err response += "not recognized. " self.respond("%sCurrent stock: %s" % (response, self.get_current_stock(user)))
def sales(request, template_name="retail/sales.html"): if request.user.is_staff: org = None else: org = request.user.get_profile().organization sale = None if org: sale_form = SaleForm(instance=sale, initial={'purchase_date': datetime.now()}) sale_form.fields['seller'].queryset=Contact.objects.filter(organization=org) sale_form.fields['purchase_date'] else: sale_form = None if request.method == "POST": sale_form = SaleForm(data=request.POST) if sale_form.is_valid(): #since sale.product is excluded from the form, get it from the #first two characters of the serial no. The form validation #checks that the product exists, and is in stock for the seller #so this is probably a safe way to do it sale = sale_form.save(commit=False) sale.product = Product.by_code(sale.serial[0:2].upper()) sale.save() return HttpResponseRedirect(reverse(sales)) if org: stb = SaleTable(Sale.objects.filter(seller__organization=request.user.get_profile().organization), request) else: stb = SaleTable(Sale.objects.all(), request) return render_to_response( "retail/sales.html", { "organization": org, "sale_table": stb, "sale_form": sale_form, }, context_instance=RequestContext(request) )
def verify_sale(self, input, rep): """ parsing and error checking for sales """ #assume a valid sale, change status to 0 if we encounter an error status = 1 errors = [] data_list = input.split() if len(data_list) < 7: status = 0 errors.append("Sale missing information. Please check the format and try again") return ([status, errors]) #check serial number sn = data_list[0].upper() #FIXME Loosening the length check temporarily to accomodate new #Envirofit SN format ############################################################## if len(sn) < 7: errors.append("SN too short") if sn[0:2].isdigit(): errors.append("SN must start with a product code") #get product code #this assumes product codes are all letters, and they're the only letters in a serial number #FIXME (?) Chaning this to accomodate Envirofit, but maybe it's #better anyway? ############################################################## #product_code = (''.join([l for l in sn if l.isalpha()])).upper() product_code = sn[0:2] prod = Product.by_code(product_code) if not prod: errors.append("product %s not found" % product_code) #check product owner's name if not ((data_list[1] + data_list[2]).isalpha()): errors.append("cust name not understood") if (len(data_list[1]) < 2 or len(data_list[2]) < 2): errors.append("cust name too short") else: first = data_list[1].title() last = data_list[2].title() #check phone if not (data_list[3].isdigit()): errors.append("phone # can only be digits") if len(data_list[3]) < 10: errors.append("phone # is mising digits") #check price price = Decimal(data_list[4]) if price > 50: errors.append("price is too high") if price < 4: errors.append("price is too low") #check region #this is a placeholder for now region = data_list[5].upper() #take anything left as free text description des = ' '.join(d.capitalize() for d in data_list[6:]) if errors: #something went wrong, return error messages status = 0 return ([status, errors]) else: #nothing went wrong, return sale data sale_dict = dict ({'seller': rep, 'serial': sn, 'product': prod, 'fname': data_list[1].capitalize(), 'lname': data_list[2].capitalize(), 'pri_phone': data_list[3], 'purchase_price': price, 'purchase_date': datetime.now(), 'region': region, 'description': des}) return ([status, sale_dict, product_code])
def handle(self, text): stocker = self.msg.connection.contact args = text.partition(" ") if args[0] == "cancel": self.cancel_restocks(stocker) return True target_alias = args[0].lower() restock_list = self.parse_restock_string(args[2].lower()) if not restock_list: self.help() return True # confirm that alias exists try: target = Contact.objects.get(alias=target_alias) except: self.respond("Sorry, user %s was not found. Please check your spelling and try again" % target_alias) return True errors = [] stockouts = [] pending = [] response = "" notification = "" # admin must create this user, for holding pending stock transactions nobody = Contact.by_alias("nobody") for code, amount in restock_list: if amount == 0: errors.append(code) if amount == -1 or code == "": self.respond( "Missing product code or amount. Restock messages cannot contain spaces.\nExample: restock dnombo 5ew" ) return True else: current_stock = Stock.get_existing(stocker.alias, code) # make sure the initiator of the transaction has enough stock if current_stock is None or current_stock.stock_amount < amount: stockouts.append(code) else: target_product = Product.by_code(code) s = Stock(seller=nobody, product=target_product, stock_amount=amount) s.save() pending.append(s) current_stock.stock_amount -= amount current_stock.save() if pending: # create the transaction object and add stock to be moved trans = StockTransaction(initiator=stocker, recipient=target, status=2, date_initiated=datetime.now()) trans.save() # need to generate a primary key before adding products for p in pending: trans.to_transfer.add(p) response += "%s %s " % (p.stock_amount, p.product.display_name) notification += "%s %s " % (p.stock_amount, p.product.display_name) trans.save() response += "sent to %s. " % target.alias if stockouts: for out in stockouts: response += "%s " % out response += "out of stock. " if errors: for err in errors: response += "%s " % err response += "not recognized." self.respond(response) if notification: notification += "being sent by %s. Reply 'yes' to accept, 'no' to reject." % stocker.alias target.message(notification)
def verify_sale(self, input, rep): """ parsing and error checking for sales """ #assume a valid sale, change status to 0 if we encounter an error status = 1 errors = [] data_list = input.split() if len(data_list) < 7: status = 0 errors.append( "Sale missing information. Please check the format and try again" ) return ([status, errors]) #check serial number sn = data_list[0].upper() #FIXME Loosening the length check temporarily to accomodate new #Envirofit SN format ############################################################## if len(sn) < 7: errors.append("SN too short") if sn[0:2].isdigit(): errors.append("SN must start with a product code") #get product code #this assumes product codes are all letters, and they're the only letters in a serial number #FIXME (?) Chaning this to accomodate Envirofit, but maybe it's #better anyway? ############################################################## #product_code = (''.join([l for l in sn if l.isalpha()])).upper() product_code = sn[0:2] prod = Product.by_code(product_code) if not prod: errors.append("product %s not found" % product_code) #check product owner's name if not ((data_list[1] + data_list[2]).isalpha()): errors.append("cust name not understood") if (len(data_list[1]) < 2 or len(data_list[2]) < 2): errors.append("cust name too short") else: first = data_list[1].title() last = data_list[2].title() #check phone if not (data_list[3].isdigit()): errors.append("phone # can only be digits") if len(data_list[3]) < 10: errors.append("phone # is mising digits") #check price price = Decimal(data_list[4]) if price > 50: errors.append("price is too high") if price < 4: errors.append("price is too low") #check region #this is a placeholder for now region = data_list[5].upper() #take anything left as free text description des = ' '.join(d.capitalize() for d in data_list[6:]) if errors: #something went wrong, return error messages status = 0 return ([status, errors]) else: #nothing went wrong, return sale data sale_dict = dict({ 'seller': rep, 'serial': sn, 'product': prod, 'fname': data_list[1].capitalize(), 'lname': data_list[2].capitalize(), 'pri_phone': data_list[3], 'purchase_price': price, 'purchase_date': datetime.now(), 'region': region, 'description': des }) return ([status, sale_dict, product_code])
def handle(self, text): stocker = self.msg.connection.contact args = text.partition(' ') if args[0] == 'cancel': self.cancel_restocks(stocker) return True target_alias = args[0].lower() restock_list = self.parse_restock_string(args[2].lower()) if not restock_list: self.help() return True # confirm that alias exists try: target = Contact.objects.get(alias=target_alias) except: self.respond( "Sorry, user %s was not found. Please check your spelling and try again" % target_alias) return True errors = [] stockouts = [] pending = [] response = "" notification = "" #admin must create this user, for holding pending stock transactions nobody = Contact.by_alias("nobody") for code, amount in restock_list: if amount == 0: errors.append(code) if amount == -1 or code == '': self.respond( "Missing product code or amount. Restock messages cannot contain spaces.\nExample: restock dnombo 5ew" ) return True else: current_stock = Stock.get_existing(stocker.alias, code) #make sure the initiator of the transaction has enough stock if current_stock is None or current_stock.stock_amount < amount: stockouts.append(code) else: target_product = Product.by_code(code) s = Stock(seller=nobody, product=target_product, stock_amount=amount) s.save() pending.append(s) current_stock.stock_amount -= amount current_stock.save() if pending: #create the transaction object and add stock to be moved trans = StockTransaction(initiator=stocker, recipient=target, status=2, date_initiated=datetime.now()) trans.save( ) #need to generate a primary key before adding products for p in pending: trans.to_transfer.add(p) response += "%s %s " % (p.stock_amount, p.product.display_name) notification += "%s %s " % (p.stock_amount, p.product.display_name) trans.save() response += "sent to %s. " % target.alias if stockouts: for out in stockouts: response += "%s " % out response += "out of stock. " if errors: for err in errors: response += "%s " % err response += "not recognized." self.respond(response) if notification: notification += "being sent by %s. Reply 'yes' to accept, 'no' to reject." % stocker.alias target.message(notification)