def __init__(self, db='orders.db'): self.pm = PeopleManager() self.tm = TeamManager() self.cm = CoffeeManager() self.db = sqlite3.connect(db) self.db.execute('create table if not exists orders (name text, document text, unique (name))') self.orders = self.retrieve()
class OrderManager(object): '''Manages orders''' def __init__(self, db='orders.db'): self.pm = PeopleManager() self.tm = TeamManager() self.cm = CoffeeManager() self.db = sqlite3.connect(db) self.db.execute('create table if not exists orders (name text, document text, unique (name))') self.orders = self.retrieve() def retrieve(self): rows = self.db.execute('select * from orders') return [self.make_from_row(row) for row in rows] def add(self, name, team): team = self.find_team(team) o = Order() o.name = name o.team = team self.orders.append(o) def create_item(self, person, coffee, pounds, quantity, personal): return Item(person, coffee, pounds, quantity, personal) def add_item(self, order, person, coffee, lbs, qty, personal): o = self.find(order) p = self.pm.find(person) c = self.cm.find(coffee) if len(o) != 1: #print('Did not find a unique order match for "%s"' % order) return False o = o[0] if len(p) != 1: #print('Did not find a unique person match for "%s"' % person) return False p = p[0] if len(c) != 1: #print('Did not find a unique coffee match for "%s"' % coffee) return False # TODO remove the list/obj inconsistencies so stuff like this can go away if isinstance(o.team, list): o.team = o.team[0] if isinstance(p.team, list): p.team = p.team[0] if o.team.name != p.team: #print('%s is not on team %s, forcing personal order' % (p.name, o.team)) personal = True item = self.create_item(p, c[0], lbs, qty, personal) o.items.append(item) return True def remove_item(self, order, who, coffee): o = self.find(order)[0] who = self.pm.find(who)[0] c = self.cm.find(coffee)[0] allitems = [i for i in o.items] eligible = [i for i in o.items if i.person.name == who.name and i.coffee.name == c.name] #print('Found %s coffee to remove' % len(eligible)) for e in eligible: o.items.remove(e) def update_item(self, order, who, coffee, pounds, quantity): o = self.find(order)[0] who = self.pm.find(who)[0] eligible = [i for i in o.items if i.person.name == who.name and i.coffee.name == coffee] if len(eligible) > 1: raise Exception('Too many matching items (%s) to update' % len(eligible)) c = eligible[0] c.quantity = quantity c.pounds = pounds def find(self, search): return [o for o in self.orders if search in o.name] def find_team(self, teamname): team = self.tm.find(teamname) if len(team) != 1: print('failed to find a unique team with search "%s"' % teamname) return None return team def remove(self, name): eligible = [o for o in self.orders if o.name == name] for e in eligible: self.orders.remove(e) def commit(self): self.db.execute('delete from orders') for o in self.orders: try: self.db.execute('insert into orders values (?, ?)', (o.name, json.dumps(o, cls=OrderJSONEncoder))) except sqlite3.IntegrityError: print('failed to add order "%s" because an order with that name already exists' % o.name) self.db.commit() def print(self): for o in self.orders: print(o) def clear(self): self.db.execute('drop table orders') self.db.commit() def make_from_row(self, row): name = row[0] return self.deserialize(row[1]) def deserialize(self, doc): doc = json.loads(doc) o = Order() o.name = doc['name'] o.date = datetime.datetime.strptime(doc['date'], '%Y-%m-%dT%H:%M:%S.%f') if isinstance(doc['team'], list): doc['team'] = doc['team'][0] o.team = Team(doc['team']['name'], doc['team']['description']) for i in doc['items']: p = self.pm.find(i['person'])[0] c = self.cm.find(i['coffee'])[0] lbs = i['pounds'] qty = i['quantity'] item = Item(p, c, lbs, qty, i['personal']) o.items.append(item) return o def teamtotal(self, order): return sum([(i.quantity * i.coffee.prices[i.pounds]) for i in order.items if not i.personal]) def personaltotal(self, order): return sum([(i.quantity * i.coffee.prices[i.pounds]) for i in order.items if i.personal]) def grandtotal(self, order): return self.teamtotal(order) + self.personaltotal(order) def individualtotal(self, order, who): '''if on team: teamtotal / numonteam + personalorder, otherwise: personalorder''' summo = 0 who = self.pm.find(who)[0] if order.team.name == who.team: num_on_team = len([p for p in self.pm.people if p.team == order.team.name]) summo = self.teamtotal(order) / float(num_on_team) summo += sum([i.quantity*i.coffee.prices[i.pounds] for i in order.items if i.personal and i.person.name == who.name]) else: summo = sum([i.quantity * i.coffee.prices[i.pounds] for i in order.items if i.personal and i.person.name == who.name]) return summo def totals(self, order): cur = locale.currency s = [] o = self.find(order)[0] s.append(''' Team Total......%s Personal Total..%s Grand Total.....%s Individual Totals:''' % (cur(self.teamtotal(o)), cur(self.personaltotal(o)), cur(self.grandtotal(o)))) unique_people = set([i.person.name for i in o.items]) for p in unique_people: s.append('\t%s: %s' % (p, locale.currency(self.individualtotal(o, p)))) return ''.join(s)