def main(): form = cgi.FieldStorage() if 'categoryid' in form: print_headers(int(form.getvalue('categoryid'))) elif 'categoryname' in form: print_headers(catname=form.getvalue('categoryname')) else: print_headers() print '''<form name="category" action="category_info.py" method="get">''' print '''Input a category name''' print '''<input type="text" name="categoryname" size="4" /> <input type="submit" value="Display" />''' print '''</form>''' category = None if "categoryid" in form: categoryid = int(form.getvalue("categoryid")) category = db.get_category(categoryid) elif "categoryname" in form: try: category = db.get_category_byname(form.getvalue("categoryname")) except Exception: print '''Error: category '%s' not found''' % form.getvalue("categoryname") if category != None: print '''<b>Info for category %s:</b><br />''' % category print '''<b>Items in this category </b><br/><table> <thead> <th>ItemID</th> <th>Name</th> </thead>''' for item in db.get_items(show_categories=[category.get_name()], hide_categoryless=True): print '''<tr><td><a href="%s">%d</a></td><td>%s</td></tr>''' % (db.get_item_info_page_link(item.get_id()),item.get_id(), item.get_name()) print '''</table>'''
def main(): form = cgi.FieldStorage() idf.init(form,discontinued=True,distributors=True,categories=True) print_headers() print ''' <body> <div class="key"> Key: <span class="na"> very negative (produce, etc.) </span> <span class="bad"> slightly negative (counting error?) </span> <span class="out"> out (0 in stock) </span> <span class="low"> <14 day supply in stock </span> </div> <div>Click table headers to sort</div> <div>Click distributor to change</div> <div>Type and hit ENTER to change item number or to adjust quantity</div> <div>Boxes will be grayed out until the update happens to the database. If a box doesn't become normal after a few seconds, then likely something is wrong with the database or the server</div> <div>The Out in column estimates the number of days of stock left in store. It uses the average # units sold per day for the last 14 days to get its estimate</div> <div>The Spec column shows the estimated stock count for 'Speculate stock for date:' day. Speculation is based on average # units sold per day for the last 14 days. The default date is for the next Thursday</div> <div>The New count field is meant to change an item's count after doing a manual count. Deliveries should be logged under manage_prices. Type a new count and press ENTER </div> <div style="clear: both; height: 15px;"> </div>''' print '''<form name="options" action="catalog.py" method="get">''' options = idf.print_form() # prints out all of the options for item displaying print '''Speculate stock for date''' if "exp_date" in form: speculate_date = datetime.datetime.strptime(form.getvalue("exp_date"), spec_date_format) days_to_speculate = (speculate_date - datetime.datetime.now()).days print_dates(14, speculate_date) else: today = datetime.datetime.now() days_to_speculate = (6 - today.weekday() + 4) % 7 # weekday goes Monday=0, Sunday=6 so: 6-today = days to next sunday print_dates(14, today+datetime.timedelta(days=days_to_speculate)) print ''' <br /><input type="submit" value="Change options" /> </form>''' print '''<br /><br />''' print '''<table border=0 class="sortable" cellspacing=2 cellpadding=0> <thead class="col-header"><tr> <th class="th">dist (case size/units/price)</th> <th class="th">d item id</th> <th class="th">name</th> <th class="th">size</th> <th class="th">price</th> <th class="th">7d</th> <th class="th">14d</th> <th class="th">30d</th> <th class="th" class="sorttable_numeric">Out in</th> <th class="th">Spec</th> <th class="th">#stocked</th> <th class="th">New count</th> <th class="th">OP SKU</th> <th class="th">barcodes</th> <th class="th">Stocked</th> </thead><tbody id="item-stats">\n''' distributors = dict([(d.get_id(), d) for d in db.get_distributors()]) for item in db.get_items(**options): # Need to make these floats b/c comparison b/t Decimal and float work strangely count = float(item.get_count()) item_id = item.get_id() day7, day14, day30 = db.get_sales_in_multi_range(item_id,7,14,30) stock_strings = ['%.2f'%day7,'%.2f'%day14,'%.2f'%day30] dist_list = item.get_distributors() dist_count = len(dist_list) for i in range(max(1,dist_count)): # need the max in case the item has no distributors row_color = "" if count < -10.0: row_color = "na" elif count < 0.0: row_color = "bad" elif count < 1.0: row_color = "out" elif count < day14: row_color = "low" print '<tr id="tr_%d_%.2f" class="%s">' % (item_id, day14,row_color) print '<div class="div_%d">' % (item_id) if dist_count == 0: # don't have any distributors so we just print blanks in first two spots print '''<td> - </td> <td> - </td>''' else: d_i = dist_list[i] dist = distributors[d_i.get_dist_id()] case_str = '''%.2f''' % d_i.get_case_size() price_str = '''$%.2f''' % d_i.get_wholesale_price() print '''<td>''',str(dist),'(',case_str,' ',d_i.get_case_unit(),' ',price_str,') </td> <td>',d_i.get_dist_item_id(),' </td>''' print '''<td style='padding-left: 1em;'>''',str(item),'</td>''' print '''<td>''',item.get_size_str(),'''</td>''' print '''<td>''',item.get_price_str(),'''</td>''' print '<td>',stock_strings[0],'</td><td>',stock_strings[1],'</td><td>',stock_strings[2],'</td>' if count > 0: if float(day14) > 0: days_of_stock = float(count) *14.0/ float(day14) print '<td>','%.0f'%days_of_stock,' days</td>' else: print '''<td>No sales</td>''' else: print '''<td>0 days</td>''' speculated = count - day14/14*days_to_speculate # days_to_speculate determined outside of loop print '''<td id="%d_spec_%d" class="spec">''' % (item_id,i) print '%d'%speculated,'''</td>''' print '''<td id="%d_amt_%d" style="border-left: 1px solid #999; padding-left: 1em;">''' % (item_id, i) print int(count),'''</td>''' print '''<td><input class="count default" id="%d_count_%d" size="3" /></td>''' % (item_id,i) print '''<td style='text-align: center;'> <a href="''',db.get_item_info_page_link(item_id),'''" target="_blank">''',str(item_id),'''</a> </td>''' print '''<td>''',item.get_barcodes_str(),''' </td>''' if not item.get_is_discontinued(): print '''<td><input type="checkbox" id="%d_isStocked" onClick="discontinueItem(this)" checked /> </td>''' % (item_id,) else: print '''<td><input type="checkbox" id="%d_isStocked" onClick="discontinueItem(this)"/> </td>''' % (item_id,) print '''</div>''' print '''</tr>\n''' print '''</tbody></table>\n''' print '''</body></html>'''
def main(): form = cgi.FieldStorage() idf.init(form,discontinued=True,distributors=True,categories=True) print_headers() print ''' <body>''' print ''' <div class="key"> Key: <span class="na"> very negative (produce, etc.) </span> <span class="bad"> slightly negative (counting error?) </span> <span class="out"> out (0 in stock) </span> <span class="low"> <14 day supply in stock </span> </div> <div>Click table headers to sort</div> <div>Click distributor to change info there. + or - signs add or remove the distributor respectively. To change any of the other columns make your modifications and click the word update at the end of the row.</div> <div>Note that this currently only supports SINGLE barcodes, and needs to be redone (probably in a similar manner to categories etc) to support multiple </div> <div>The M-Edit checkbox allows you to add/remove things to multiple items at once </div> <div style="clear: both; height: 15px;"> </div>''' print '''</body></html>''' print_multi_add() print '''<form name="options" action="manage_items.py" method="get">''' options = idf.print_form() print '''<input type="submit" value="Change options" /> </form>''' print '''<br> <br>''' print '''<table border=0 id="main" class="sortable" cellspacing=0 cellpadding=0> <thead class="col-header"> <th class="th">M-Edit</th> <th class="th">Name</th> <th class="th">Dist Info</th> <th class="th">OP SKU</th> <th class="th">Barcodes</th> <th class="th">Category</th> <th class="th">Tax Category</th> <th class="th">Stocked</th> </thead><tbody id=\"item-stats\">\n''' for i,item in enumerate(db.get_items(**options)): count = item.get_count() item_id = item.get_id() day14 = db.get_sales_in_range(item_id,14) if count < -10.0: print '''<tr id="tr_%d" class="na" title="%d">''' % (item_id,day14) elif count < 0.0: print '''<tr id="tr_%d" class="bad" title="%d">''' % (item_id,day14) elif count < 1.0: print '''<tr id="tr_%d" class="out" title="%d">''' % (item_id,day14) elif count < day14: print '''<tr id="tr_%d" class="low" title="%d">''' % (item_id,day14) else: print '<tr id="tr_%d" title="%d">' % (item_id,day14) print '''<div class='div_%d'>''' % (item_id) print '''<td> <input class="multi" type="checkbox" id="%d" /></td>''' % (item_id,) print '''<td><input type="text" class="itemname" id="%d_name" value="%s" />[%s]''' % (item.get_id(), item.get_name(),item.get_size_str()) print '''<td id="%d_dist" style='border-left: 1px solid #999; border-right: 1px solid #999; padding-left: 1em;'> %s </td>''' % (item_id, item.get_distributors_str()) print '''<td style='text-align: center;'> <a href="%s" onclick="window.open(this.href,'_blank'); return false;">%d </a></td>''' % (db.get_item_info_page_link(item_id),item_id) barcode = item.get_first_barcode() if barcode != None: print '''<td> <input size="16" type="text" class="itembarcode" id="%d_%s_bc" value="%s" /> </td>''' % (item_id,barcode.get_barcode(), barcode.get_barcode()) else: print '''<td> <input size="16" type="text" class="itembarcode" id="%d_%s_bc" value="%s" /> </td>''' % (item_id, 'None', 'None') print '''<td style='border-left: 1px solid #999; border-right: 1px solid #999;' id='%d_cat'> %s </td>''' % (item_id, item.get_categories_str(), ) print '''<td style='border-right: 1px solid #999;' id='%d_tax'> %s </td>''' % (item_id, str(item.get_tax_category()), ) if not item.get_is_discontinued(): print '''<td><input type="checkbox" id="%d_isStocked" onClick="discontinueItem(this)" checked /> </td>''' % (item_id,) else: print '''<td><input type="checkbox" id="%d_isStocked" onClick="discontinueItem(this)"/> </td>''' % (item_id,) print '''</div>''' print '''</tr>\n''' print '''</tbody></table>\n''' print '''</body></html>'''
#!/usr/bin/env python # autocount_items.py # Patrick McQuighan # This script should be run periodically when the store is not open to perform an auto-update of the last_count and last_count_timestamp # fields of the database. It loops over all items in the database and updates the last_count field with the current value of get_count # This will improve performance of the catalog page (or any page displaying item counts) # This file is part of Marzipan, an open source point-of-sale system. # Copyright (C) 2015 Open Produce LLC # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import op_db_library as db for item in db.get_items(): newcount = item.get_count() item.auto_count(newcount)