class Like(db.Model): """Mapping user likes to warbles.""" __tablename__ = 'likes' id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='cascade')) message_id = db.Column(db.Integer, db.ForeignKey('messages.id', ondelete='cascade'), unique=True)
class Note(db.Model): """A single note""" __tablename__ = "notes" cust_id = db.Column(db.String(32), db.ForeignKey('customers.id', ondelete='CASCADE'), primary_key=True) driver_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), primary_key=True) note = db.Column(db.Text, nullable=False) driver = db.relationship('User', backref='notes') customer = db.relationship('Customer', backref='notes') def serialize(self): return { "cust_id": self.cust_id, "driver_id": self.driver_id, "note": self.note } @classmethod def get(cls, cust_id, driver_id): return cls.query.get((cust_id, driver_id)) @classmethod def delete(cls, cust_id, driver_id): note = cls.get(cust_id=cust_id, driver_id=driver_id) if note: db.session.delete(note) db.session.commit() return True else: return False @classmethod def create_or_update_note(cls, cust_id, driver_id, new_note): try: note = cls.get(cust_id=cust_id, driver_id=driver_id) if note: note.note = new_note else: note = cls(cust_id=cust_id, driver_id=driver_id, note=new_note) db.session.add(note) db.session.commit() return note except: db.session.rollback() return False
class Follow(db.Model): """Connection of a follower <-> followed_user.""" __tablename__ = 'follows' user_being_followed_id = db.Column( db.Integer, db.ForeignKey('users.id', ondelete="cascade"), primary_key=True, ) user_following_id = db.Column( db.Integer, db.ForeignKey('users.id', ondelete="cascade"), primary_key=True, )
class Message(db.Model): """An individual message ("warble").""" __tablename__ = 'messages' id = db.Column( db.Integer, primary_key=True, ) text = db.Column( db.String(140), nullable=False, ) timestamp = db.Column( db.DateTime, nullable=False, default=datetime.utcnow(), ) user_id = db.Column( db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), nullable=False, ) user = db.relationship('User') def __repr__(self): return f"<Message #{self.id}: u_id={self.user_id}>"
class Delivery(db.Model): """A single delivery""" __tablename__ = "deliveries" id = db.Column(db.Integer, autoincrement=True, primary_key=True) driver_id = db.Column(db.Integer, db.ForeignKey( 'users.id', ondelete='CASCADE')) driver = db.relationship('User', backref='deliveries') orders = db.relationship('Order', backref='delivery') @classmethod def save_delivery(cls, delivery, driver_id, api_id): date = delivery['date'] store = delivery['store'] orders = delivery['orders'] old_deliveries = set() delivery = Delivery(driver_id=driver_id) db.session.add(delivery) db.session.commit() ###### # A little wasteful, good optimization possibility, I think for order in orders: # maybe change this to a hash of the phone and address customer_id = Customer.make_id_from_phone(order['phone']) customer = Customer.create_or_get( id=customer_id) # name = order['name'].split(' ')[0] db_order = Order.get(order['num'], date, store, api_id) if db_order: old_deliveries.add(db_order.del_id) db_order.del_id = delivery.id db_order.driver_id = driver_id db_order.cust_id = customer_id else: db_order = Order( num=order['num'], date=date, store=store, api_id=api_id, del_id=delivery.id, cust_id=customer_id, driver_id=driver_id) db.session.add(db_order) db.session.commit() Delivery.dispose_of_empty_dels(old_deliveries) return delivery @classmethod def dispose_of_empty_dels(cls, del_ids): for del_id in del_ids: d = cls.query.get(del_id) if len(d.orders) == 0: db.session.delete(d) db.session.commit()
class WeekCode(db.Model): """represets one week of data(so we don't write the same week twice)""" __tablename__ = "week_codes" code = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey( 'users.id', ondelete='CASCADE'), primary_key=True) @classmethod def add(cls, code, user_id): """add a code to the db""" db_entry = cls(code=code, user_id=user_id) db.session.add(db_entry) try: db.session.commit() return True except: return False @classmethod def get_codes_for_user(cls, user_id, limit = 8): """gets the codes for a specified user. defaults to limiting to 3""" week_codes = cls.query.filter_by(user_id=user_id).order_by( cls.code.desc()).limit(limit).all() return [w.code for w in week_codes]
class Order(db.Model): """A single order""" __tablename__ = "orders" id = db.Column(db.Integer, primary_key=True) num = db.Column(db.Integer) date = db.Column(db.Date) store = db.Column(db.Text) api_id = db.Column(db.Text) tip = db.Column(db.Float, server_default='0') del_id = db.Column(db.Integer, db.ForeignKey( 'deliveries.id', ondelete='CASCADE')) cust_id = db.Column(db.String(32), db.ForeignKey( 'customers.id', ondelete='SET NULL')) driver_id = db.Column(db.Integer, db.ForeignKey( 'users.id', ondelete='CASCADE')) driver = db.relationship('User', backref='orders') customer = db.relationship('Customer', backref='orders') def serialize(self): return {"id": self.id, "num": self.num, "tip": self.tip, "date": self.date, "del_id": self.del_id, "cust_id": self.cust_id, "driver_id": self.driver_id, "store": self.store, "api_id": self.api_id } def update_db(self): db.session.add(self) db.session.commit() @classmethod def get(cls, num, date, store, api_id): return cls.query.filter_by(num=num, date=date, store=store, api_id=api_id).first() @classmethod def get_orders_for_day(cls, driver_id, date=date_class.today()): """ Returns {num, tip, date, del_id, cust_id, driver_id, customer:{id, name, phone, address} """ result = db.session.query( Order, Customer).join( Customer, Customer.id == Order.cust_id).filter( Order.driver_id == driver_id, Order.date == date).all() return Order.compile_orders_and_customers(result) @classmethod def get_orders_for(cls, driver_id): """ Returns 213, 04-19-21, 8425-881-7843 """ result = db.session.query( Order, Customer).join( Customer, Customer.id == Order.cust_id).filter( Order.driver_id == driver_id).order_by(Order.date.desc(), Order.num.desc()).all() orders = Order.compile_orders_and_customers(result) orders_list = {} for order in orders: orders_for_date = orders_list.get(order['date'], []) orders_for_date.append(order) orders_list[order['date']] = orders_for_date return orders_list @classmethod def make_id_from_date_and_num(cls, date, num): return f'{date}|{num}' @ classmethod def compile_orders_and_customers(cls, order_array): return [{**order.serialize(), "customer": {**customer.serialize()}} for (order, customer) in order_array]
class Schedule(db.Model): """A single shift""" __tablename__ = "schedules" id = db.Column( db.Integer, autoincrement=True, primary_key=True) start = db.Column(db.DateTime, nullable=False) end = db.Column(db.DateTime, nullable=False) shift_type = db.Column(db.String(20)) user_id = db.Column(db.Integer, db.ForeignKey( 'users.id', ondelete='CASCADE')) def get_shift_length(self): """gets the length of the shift returns a datetime.timedelta object """ return self.end-self.start def get_shift_hours(self): """gets the length of the shift in hours """ delta = self.get_shift_length() # 60 seconds in a min, 60 mins in a hour return delta.total_seconds() / 60 / 60 @classmethod def get_future_shifts(cls, user_id): """returns a list of shifts for user_id that end on or after today""" #get a timestamp for the beginning of the day today = datetime.date.today() return cls.query.filter( Schedule.user_id == user_id, Schedule.end >= today ).order_by(Schedule.start).all() @classmethod def get_last(cls, user_id, delta=None): """returns a list of shifts for user_id that start on or before today optionally the delta param further limits the results to shits that end on or after today - delta""" #get a timestamp at the end of the day today = datetime.datetime.today() + datetime.timedelta(hours=11, minutes=59) if delta: return cls.query.filter( Schedule.user_id == user_id, Schedule.start <= today, Schedule.end >= (datetime.date.today() - delta) ).all() else: return cls.query.filter( Schedule.user_id == user_id, Schedule.start <= today ).all() @classmethod def add_from_pag(cls, schedules, user_id): """adds a list of schedules from the pag api""" #weeks that are already in the DB used_codes = WeekCode.get_codes_for_user(user_id, limit=10) for week in schedules: code = week['pag_code'] if int(code) not in used_codes: # for each week in schedules, # add the pag_code to WeekCode WeekCode.add(code, user_id) for shift in week['schedule']: # for every shift, make a new schedule db_shift = Schedule( start=shift['start'], end=shift['end'], shift_type=shift['shift_type'], user_id=user_id) db.session.add(db_shift) db.session.commit() @classmethod def add_from_demo(cls, schedules, user_id): """adds a list of schedules from the demo api""" used_codes = WeekCode.get_codes_for_user(user_id, limit=10) for week in schedules: # for each week in schedules, # add the week_code to WeekCode code = week['week_code'] if int(code) not in used_codes: WeekCode.add(code, user_id) for shift in week['schedule']: # for every shift, make a new schedule db_shift = Schedule( start=shift['start'], end=shift['end'], shift_type=shift['shift_type'], user_id=user_id) db.session.add(db_shift) db.session.commit()