def response_stock_item(stock_item): """ Returns relevant stock_item information """ serials = stock_item.serial_numbers.replace( ',', ',\n') if stock_item.serial_numbers else '' item_name = stock_item.id_item.name + item_utils.concat_traits( stock_item.id_item) res = { "id": stock_item.id, "id_item": stock_item.id_item, "item_name": item_name, "item_barcode": item_barcode(stock_item.id_item), "purchase_qty": str(stock_item.purchase_qty or 0), "price": str(DQ(stock_item.price or 0)), "base_price": str(DQ(stock_item.base_price or 0)), "price2": str(DQ(stock_item.price2 or 0)), "price3": str(DQ(stock_item.price3 or 0)), "taxes": str(DQ(stock_item.taxes) or 0), "serial_numbers": serials, "earnp_base_price": 0, "earnp_price2": 0, "earnp_price3": 0 } if stock_item.price: price = DQ(stock_item.price) + DQ(stock_item.taxes) for target in ['base_price', 'price2', 'price3']: earnp = DQ(((stock_item[target] or 0) / price - 1) * 100, True, True) earnp = max(0, earnp) res['earnp_' + target] = earnp return res
def response_stock_item(stock_item): """ Returns relevant stock_item information """ serials = stock_item.serial_numbers.replace(',', ',\n') if stock_item.serial_numbers else '' item_name = stock_item.id_item.name + item_utils.concat_traits(stock_item.id_item) res = { "id": stock_item.id , "id_item": stock_item.id_item , "item_name": item_name , "item_barcode": item_barcode(stock_item.id_item) , "purchase_qty": str(stock_item.purchase_qty or 0) , "price": str(DQ(stock_item.price or 0)) , "base_price": str(DQ(stock_item.base_price or 0)) , "price2": str(DQ(stock_item.price2 or 0)) , "price3": str(DQ(stock_item.price3 or 0)) , "taxes": str(DQ(stock_item.taxes) or 0) , "serial_numbers": serials , "earnp_base_price": 0 , "earnp_price2": 0 , "earnp_price3": 0 } if stock_item.price: price = DQ(stock_item.price) + DQ(stock_item.taxes) for target in ['base_price', 'price2', 'price3']: earnp = DQ( ((stock_item[target] or 0) / price - 1) * 100, True, True ) earnp = max(0, earnp) res['earnp_' + target] = earnp return res
def fill(): """ Used to add items to the specified purchase args: [purchase_id, current_stock_item] """ import supert Supert = supert.Supert() purchase = db.purchase(request.args(0)) valid_purchase(purchase) current_stock_item = db.stock_item(request.args(1)) if current_stock_item: current_stock_item = Storage(response_stock_item(current_stock_item)) if current_stock_item and current_stock_item.id_purchase != purchase.id: session.flash = T('Invalid stock item') current_stock_item == None buttons = [ A(T('Commit'), _class="btn btn-primary", _href=URL('commit', args=purchase.id)) , A(T('Complete later'), _class="btn btn-default", _href=URL('save', args=purchase.id)) , A(T('Cancel'), _class="btn btn-default", _href=URL('cancel', args=purchase.id)) ] form = SQLFORM(db.purchase, purchase.id, buttons=buttons, formstyle="bootstrap3_stacked", showid=False, _id="purchase_form") def stock_item_options(row): return supert.OPTION_BTN('edit', url=URL('fill', args=[purchase.id, row.id], vars=request.vars) , title=T("modify") ) stock_items_table = Supert.SUPERT( db.stock_item.id_purchase == purchase.id , fields=[ dict(fields=[ 'id_item.name' ], label_as=T('Name')), dict(fields=['id_item','id_item.sku','id_item.ean','id_item.upc' ], custom_format=lambda r, f : item_barcode(r[f[0]]), label_as=T('Barcode') ), dict(fields=['purchase_qty'], custom_format=lambda r, f : SPAN(DQ(r[f[0]], True, True), _id="s_item_%s_%s" % (r.id, f[0])), label_as=T('Quantity') ), dict(fields=['price', 'taxes'], custom_format=lambda r, f : SPAN(DQ(r[f[0]] + r[f[1]], True), _id="s_item_%s_%s" % (r.id, f[0])), label_as=T('Buy Price') ) ] , options_func=stock_item_options , global_options=[] ) return locals()
def set_bag_item(bag_item, discounts=None): """ modifies bag item data, in order to display it properly, this method does not modify the database """ if discounts is None: discounts = [] session = current.session item = bag_item.id_item bag_item.product_name = item.name + " " + item_utils.concat_traits(item) if discounts is None: discounts = [] # stores the price without discounts real_price = bag_item.sale_price + (bag_item.discount or 0) # discount percentage discount_p = 0 try: discount_p = DQ(1.0) - bag_item.sale_price / real_price except: pass item.base_price -= item.base_price * discount_p bag_item.total_sale_price = str( DQ(bag_item.sale_price + bag_item.sale_taxes, True)) bag_item.base_price = money_format(DQ(item.base_price, True)) if item.base_price else 0 bag_item.price2 = money_format( DQ(item.price2 - item.price2 * discount_p, True)) if item.price2 else 0 bag_item.price3 = money_format( DQ(item.price3 - item.price3 * discount_p, True)) if item.price3 else 0 bag_item.sale_price = money_format(DQ(bag_item.sale_price or 0, True)) # add taxes without discounts real_price += bag_item_taxes(bag_item, real_price) bag_item.price_no_discount = real_price bag_item.measure_unit = item.id_measure_unit.symbol bag_item.barcode = item_utils.item_barcode(item) bag_item.stock = item_utils.item_stock_qty(item, session.store) bag_item.has_inventory = item.has_inventory bag_item.discount_percentage = int(discount_p * D(100.0)) bag_item.real_price = bag_item.sale_price return bag_item
def set_bag_item(bag_item, discounts=None): """ modifies bag item data, in order to display it properly, this method does not modify the database """ if discounts is None: discounts = [] session = current.session item = bag_item.id_item bag_item.product_name = item.name + " " + item_utils.concat_traits(item) if discounts is None: discounts = [] # stores the price without discounts real_price = bag_item.sale_price + (bag_item.discount or 0) # discount percentage discount_p = 0 try: discount_p = DQ(1.0) - bag_item.sale_price / real_price except: pass item.base_price -= item.base_price * discount_p bag_item.total_sale_price = str(DQ(bag_item.sale_price + bag_item.sale_taxes, True)) bag_item.base_price = money_format(DQ(item.base_price, True)) if item.base_price else 0 bag_item.price2 = money_format(DQ(item.price2 - item.price2 * discount_p, True)) if item.price2 else 0 bag_item.price3 = money_format(DQ(item.price3 - item.price3 * discount_p, True)) if item.price3 else 0 bag_item.sale_price = money_format(DQ(bag_item.sale_price or 0, True)) # add taxes without discounts real_price += bag_item_taxes(bag_item, real_price) bag_item.price_no_discount = real_price bag_item.measure_unit = item.id_measure_unit.symbol bag_item.barcode = item_utils.item_barcode(item) bag_item.stock = item_utils.item_stock_qty(item, session.store) bag_item.has_inventory = item.has_inventory bag_item.discount_percentage = int(discount_p * D(100.0)) bag_item.real_price = bag_item.sale_price return bag_item
def item_card(item): """ """ session = current.session auth = current.auth db = current.db T = current.T available = "Not available" available_class = "label label-danger" stock_qty = item_stock_qty(item, session.store) if stock_qty > 0: available_class = "label label-success" available = "Available" item_options = DIV() bg_style = "" images = db((db.item_image.id_item == db.item.id) & (db.item.id == item.id) & (db.item.is_active == True)).select(db.item_image.ALL) if images: bg_style = "background-image: url(%s);" % URL( 'static', 'uploads/' + images.first().sm) else: bg_style = "background-image: url(%s);" % URL('static', 'images/no_image.svg') brand_link = H4( A(item.id_brand.name, _href=URL('item', 'browse', vars=dict( brand=item.id_brand.id)))) if item.id_brand else H4( T('No brand')) item_price = (item.base_price or 0) + item_taxes(item, item.base_price) fix_item_price(item, item.base_price) item_price = item.discounted_price item_price_html = DIV() if item.discount_percentage > 0: item_price_html.append( DIV( T('before'), SPAN('$ ', SPAN(item.new_price, _class="old-price"), _class="right"))) item_price_html.append( DIV( T('discount'), SPAN(SPAN(item.discount_percentage), '%', _class="right text-danger"))) item_price_html.append( DIV(SPAN(T(available), _class=available_class + ' item-available'), H4('$ ', DQ(item_price, True), _class="item-price"), _class="item-card-bottom")) # concatenate all the item traits, this string will be appended to the item name traits_str = '' traits_ids = '' item_url = URL('item', 'get_item', args=item.id) item_name = item.name if item.traits: for trait in item.traits: traits_ids += str(trait.id) traits_str += trait.trait_option + ' ' if trait != item.traits[-1]: traits_ids += ',' item_url = URL('item', 'get_item', vars=dict(name=item.name, traits=traits_ids)) item_name = item.name + ' ' + traits_str elif item.description: item_name += ' - ' + item.description[:10] if len(item.description) > 10: item_name += '...' main_content = DIV(H4(A(item_name, _href=item_url)), brand_link, _class="item_data") # item options item_options = DIV(BUTTON(ICON('shopping_basket'), _type="button", _class="btn btn-default", _onclick="add_bag_item(%s)" % item.id), _class="btn-group item-options") if auth.has_membership('Employee'): main_content.append( P('# ', SPAN(item_barcode(item)), _class="item-barcode")) expand_btn = BUTTON(ICON('more_vert'), _type="button", _class="btn btn-default dropdown-toggle", data={'toggle': 'dropdown'}) item_options.append(expand_btn) options_ul = UL(_class="dropdown-menu") if auth.has_membership('Items info') or auth.has_membership( 'Items management') or auth.has_membership('Items prices'): options_ul.append( LI(A(T('Update'), _href=URL('item', 'update', args=item.id)))) options_ul.append( LI( A(T('Print labels'), _href=URL('item', 'labels', args=item.id)))) options_ul.append( LI( A(T('Add images'), _href=URL('item_image', 'create', args=item.id)))) if auth.has_membership('Analytics'): options_ul.append( LI( A(T('Analysis'), _href=URL('analytics', 'item_analysis', args=item.id)))) item_options.append(options_ul) return DIV(A('', _class="panel-heading", _style=bg_style, _href=item_url), DIV(main_content, item_options, item_price_html, _class="panel-body"), _class="panel panel-default item-card")
def item_card(item): """ """ session = current.session auth = current.auth db = current.db T = current.T available = "Not available" available_class = "label label-danger" stock_qty = item_stock_qty(item, session.store) if stock_qty > 0: available_class = "label label-success" available = "Available" item_options = DIV() bg_style = "" images = db( (db.item_image.id_item == db.item.id) & (db.item.id == item.id) & (db.item.is_active == True) ).select(db.item_image.ALL) if images: bg_style = "background-image: url(%s);" % URL('static','uploads/'+ images.first().sm) else: bg_style = "background-image: url(%s);" % URL('static', 'images/no_image.svg') brand_link = H4( A(item.id_brand.name, _href=URL('item', 'browse', vars=dict(brand=item.id_brand.id)) ) ) if item.id_brand else H4(T('No brand')) item_price = (item.base_price or 0) + item_taxes(item, item.base_price) fix_item_price(item, item.base_price) item_price = item.discounted_price item_price_html = DIV() if item.discount_percentage > 0: item_price_html.append(DIV(T('before'), SPAN('$ ', SPAN(item.new_price, _class="old-price"), _class="right"))) item_price_html.append( DIV(T('discount'), SPAN(SPAN(item.discount_percentage), '%', _class="right text-danger")) ) item_price_html.append( DIV( SPAN(T(available), _class=available_class + ' item-available'), H4('$ ', DQ(item_price, True), _class="item-price"), _class="item-card-bottom" ) ) # concatenate all the item traits, this string will be appended to the item name traits_str = '' traits_ids = '' item_url = URL('item', 'get_item', args=item.id) item_name = item.name if item.traits: for trait in item.traits: traits_ids += str(trait.id) traits_str += trait.trait_option + ' ' if trait != item.traits[-1]: traits_ids += ',' item_url = URL('item', 'get_item', vars=dict(name=item.name, traits=traits_ids)) item_name = item.name + ' ' + traits_str elif item.description: item_name += ' - ' + item.description[:10] if len(item.description) > 10: item_name += '...' main_content = DIV( H4(A(item_name, _href=item_url)), brand_link, _class="item_data" ) # item options item_options = DIV( BUTTON(ICON('shopping_basket'), _type="button", _class="btn btn-default", _onclick="add_bag_item(%s)" % item.id) , _class="btn-group item-options" ) if auth.has_membership('Employee'): main_content.append( P('# ', SPAN(item_barcode(item)), _class="item-barcode") ) expand_btn = BUTTON(ICON('more_vert'), _type="button", _class="btn btn-default dropdown-toggle", data={'toggle':'dropdown'}) item_options.append(expand_btn) options_ul = UL(_class="dropdown-menu") if auth.has_membership('Items info') or auth.has_membership('Items management') or auth.has_membership('Items prices'): options_ul.append( LI(A(T('Update'), _href=URL('item', 'update', args=item.id))) ) options_ul.append( LI(A(T('Print labels'), _href=URL('item', 'labels', args=item.id))) ) options_ul.append( LI(A(T('Add images'), _href=URL('item_image', 'create', args=item.id))) ) if auth.has_membership('Analytics'): options_ul.append( LI(A(T('Analysis'), _href=URL('analytics', 'item_analysis', args=item.id))) ) item_options.append(options_ul) return DIV( A('', _class="panel-heading", _style=bg_style, _href=item_url), DIV( main_content, item_options, item_price_html, _class="panel-body" ), _class="panel panel-default item-card" )
def ticket_item_list(items, concept=''): """ creates a table of items, if concept is specified, ignores the items list and uses concept as a unique item in the table, the table will be something like QTY CONCEPT PRICE -- <concept> $ -- """ items_list = TBODY() # items_list.append(HR()) subtotal = D(0) disable_taxes_list = False taxes = {} taxes_percentages = {} total = D(0) items = [] if not items else items if concept: items_list.append(TR( TD('--', _class="qty"), TD(concept, _class="name"), TD('--'), TD('$ --', _class="price"), _class="item" )) else: for item in items: # assume bag items are being received bag_item = item # TODO find a better way to identify if the list contains bag items or credit note items try: item.product_name except AttributeError: bag_item = item.id_bag_item if not bag_item: continue item_name = bag_item.product_name if bag_item.id_item.traits: for trait in bag_item.id_item.traits: item_name += ' ' + trait.trait_option item_price = bag_item.sale_price item_barcode = item_utils.item_barcode(bag_item.id_item) # get item taxes try: if bag_item.item_taxes: taxes_str = bag_item.item_taxes.split(',') for tax_str in taxes_str: tax_name, tax_percentage = tax_str.split(':') if not taxes_percentages.has_key(tax_name): taxes_percentages[tax_name] = DQ(tax_percentage, True, normalize=True) if not taxes.has_key(tax_name): taxes[tax_name] = 0 taxes[tax_name] += item_price * (D(tax_percentage) / DQ(100.0)) except: disable_taxes_list = True subtotal += item_price total += item_price + bag_item.sale_taxes item_quantity = DQ(item.quantity, True, normalize=True) item_price = DQ(item_price, True) items_list.append(TR( TD(item_quantity, _class="qty"), TD(item_barcode, _class="bc"), TD(item_name, _class="name"), TD('$ %s' % item_price, _class="price"), _class="item" )) items_list = TABLE( THEAD(TR( TH(T('QTY'), _class="qty"), TH(T('COD'), _class="qty"), TH(T('CONCEPT'), _class="name"), TH(T('PRICE'), _class="price"), _class="item" )), items_list, _id="items_list" ) if disable_taxes_list: taxes = {} taxes_percentages = {} return items_list, subtotal, total, taxes, taxes_percentages
def fill(): """ Used to add items to the specified purchase args: [purchase_id, current_stock_item] """ import supert Supert = supert.Supert() purchase = db.purchase(request.args(0)) valid_purchase(purchase) current_stock_item = db.stock_item(request.args(1)) if current_stock_item: current_stock_item = Storage(response_stock_item(current_stock_item)) if current_stock_item and current_stock_item.id_purchase != purchase.id: session.flash = T('Invalid stock item') current_stock_item == None buttons = [ A(T('Commit'), _class="btn btn-primary", _href=URL('commit', args=purchase.id)), A(T('Complete later'), _class="btn btn-default", _href=URL('save', args=purchase.id)), A(T('Cancel'), _class="btn btn-default", _href=URL('cancel', args=purchase.id)) ] form = SQLFORM(db.purchase, purchase.id, buttons=buttons, formstyle="bootstrap3_stacked", showid=False, _id="purchase_form") def stock_item_options(row): return supert.OPTION_BTN('edit', url=URL('fill', args=[purchase.id, row.id], vars=request.vars), title=T("modify")) stock_items_table = Supert.SUPERT( db.stock_item.id_purchase == purchase.id, fields=[ dict(fields=['id_item.name'], label_as=T('Name')), dict(fields=[ 'id_item', 'id_item.sku', 'id_item.ean', 'id_item.upc' ], custom_format=lambda r, f: item_barcode(r[f[0]]), label_as=T('Barcode')), dict(fields=['purchase_qty'], custom_format=lambda r, f: SPAN(DQ(r[f[0]], True, True), _id="s_item_%s_%s" % (r.id, f[0])), label_as=T('Quantity')), dict(fields=['price', 'taxes'], custom_format=lambda r, f: SPAN(DQ(r[f[0]] + r[f[1]], True), _id="s_item_%s_%s" % (r.id, f[0])), label_as=T('Buy Price')) ], options_func=stock_item_options, global_options=[]) return locals()
def ticket_item_list(items, concept=''): """ creates a table of items, if concept is specified, ignores the items list and uses concept as a unique item in the table, the table will be something like QTY CONCEPT PRICE -- <concept> $ -- """ items_list = TBODY() # items_list.append(HR()) subtotal = D(0) disable_taxes_list = False taxes = {} taxes_percentages = {} total = D(0) items = [] if not items else items if concept: items_list.append( TR(TD('--', _class="qty"), TD(concept, _class="name"), TD('--'), TD('$ --', _class="price"), _class="item")) else: for item in items: # assume bag items are being received bag_item = item # TODO find a better way to identify if the list contains bag items or credit note items try: item.product_name except AttributeError: bag_item = item.id_bag_item if not bag_item: continue item_name = bag_item.product_name if bag_item.id_item.traits: for trait in bag_item.id_item.traits: item_name += ' ' + trait.trait_option item_price = bag_item.sale_price item_barcode = item_utils.item_barcode(bag_item.id_item) # get item taxes try: if bag_item.item_taxes: taxes_str = bag_item.item_taxes.split(',') for tax_str in taxes_str: tax_name, tax_percentage = tax_str.split(':') if not taxes_percentages.has_key(tax_name): taxes_percentages[tax_name] = DQ(tax_percentage, True, normalize=True) if not taxes.has_key(tax_name): taxes[tax_name] = 0 taxes[tax_name] += item_price * (D(tax_percentage) / DQ(100.0)) except: disable_taxes_list = True subtotal += item_price total += item_price + bag_item.sale_taxes item_quantity = DQ(item.quantity, True, normalize=True) item_price = DQ(item_price, True) items_list.append( TR(TD(item_quantity, _class="qty"), TD(item_barcode, _class="bc"), TD(item_name, _class="name"), TD('$ %s' % item_price, _class="price"), _class="item")) items_list = TABLE(THEAD( TR(TH(T('QTY'), _class="qty"), TH(T('COD'), _class="qty"), TH(T('CONCEPT'), _class="name"), TH(T('PRICE'), _class="price"), _class="item")), items_list, _id="items_list") if disable_taxes_list: taxes = {} taxes_percentages = {} return items_list, subtotal, total, taxes, taxes_percentages