def load_departments(): """ Loads departments from connected Uber instance :return: """ REQUEST_HEADERS = {'X-Auth-Token': cfg.uber_authkey} # data being sent to API request_data = {'method': 'dept.list'} request = requests.post(url=cfg.api_endpoint, json=request_data, headers=REQUEST_HEADERS) response = json.loads(request.text) response = response['result'].items() # print('loading departments') session = models.new_sesh() for dept in response: try: mydept = session.query(Department).filter_by(id=dept[0]).one() if not mydept.name == dept[1]: mydept.name = dept[1] except sqlalchemy.orm.exc.NoResultFound: mydept = Department() mydept.id = dept[0] mydept.name = dept[1] session.add(mydept) session.commit() session.close() return
def dummy_data(count, startorder): """ create dummy data for testing :return: """ session = models.new_sesh() count = int(count) depts = session.query(Department).all() meals = session.query(models.meal.Meal).all() # attendees = session.query(models.attendee.Attendee).all() i = 0 while i < count: order = copy.deepcopy(startorder) attend = models.attendee.Attendee() attend.public_id = str(uuid.uuid4()) session.add(attend) order.attendee_id = attend.public_id meal = random.choice(meals) order.meal_id = meal.id dept = random.choice(depts) order.department_id = dept.id session.add(order) i += 1 session.commit() session.close()
def ss_eligible(badge_num): """ Looks up attendee badge number in Uber and returns whether they are eligible to use Staff Suite. General eligiblity to get food, not eligiblity for any specific meal :param badge_num: attendee's badge number for lookup :return: returns True or False """ response = lookup_attendee(badge_num, full=True) if "error" in response: print('------------Error looking up attendee eligibility for ' + badge_num + ' --------------') return False attendee = response['result'] # attendees who have have already worked required hours for eligibility if attendee['worked_hours'] >= cfg.ss_hours: return True # non-staff who are signed up for at least <current year's hours req> and have worked at least one shift if attendee['badge_type_label'] == "Attendee": if attendee['weighted_hours'] >= cfg.ss_hours: if attendee['worked_hours'] > 0: return True # Guests and Contractors automatically get access if attendee['badge_type_label'] in ["Guest", "Contractor", "Staff"]: return True # Department Heads always get access if response['result']['is_dept_head']: return True # Staff who have signed up for at least <event required> hours. # Having already worked a shift this event not required for people with Staff status # if attendee['badge_type_label'] == "Staff": # if attendee["weighted_hours"] >= cfg.ss_hours: # return True if response['result']['public_id'] in cfg.food_managers: return True session = models.new_sesh() if is_vip(attendee['badge_num'], session): return True # shiftless departments are exempt from eligibility requirements depts = session.query(models.department.Department).filter_by(is_shiftless=True).all() for dept in depts: if dept.name in attendee['assigned_depts_labels']: return True # if nothing above matches, not eligible. return False
def is_vip(badge, session=None): """ Checks if provided badge is in VIP list """ if not session: session = models.new_sesh() vip_list = session.query(models.attendee.Attendee).filter_by(is_vip=True).all() for vip in vip_list: if badge == vip.badge_num: return True return False
def get_vip_list(): """ Returns list of VIPs formated as "badge_num, full_name" string """ session = models.new_sesh() vips = session.query(models.attendee.Attendee).filter_by(is_vip=True).order_by(models.attendee.Attendee.badge_num).all() vip_list = list() for vip in vips: vip_list.append(str(vip.badge_num) + ", " + vip.full_name) return vip_list
def dummy_data(count, startorder): """ create dummy data for testing :startorder: starting order is provided so some basic fields can be valid without having to be filled out. :return: """ # do not want to create dummy data in live DB!!! if cfg.env == "prod": print("-----------Tried to create dummy data but this server is marked as live!-----------") return session = models.new_sesh() count = int(count) depts = session.query(Department).all() meals = session.query(models.meal.Meal).all() i = 0 while i < count: order = copy.deepcopy(startorder) attend = models.attendee.Attendee() attend.public_id = str(uuid.uuid4()) session.add(attend) order.attendee_id = attend.public_id meal = random.choice(meals) order.meal_id = meal.id dept = random.choice(depts) order.department_id = dept.id session.add(order) i += 1 session.commit() session.close() return
def load_departments(): """ Loads departments from connected Uber instance :return: """ REQUEST_HEADERS = {'X-Auth-Token': cfg.uber_authkey} request_data = {'method': 'dept.list'} request = requests.post(url=cfg.api_endpoint, json=request_data, headers=REQUEST_HEADERS) response = json.loads(request.text) response = response['result'].items() session = models.new_sesh() for dept in response: try: mydept = session.query(Department).filter_by(id=dept[0]).one() if not mydept.name == dept[1]: mydept.name = dept[1] except sqlalchemy.orm.exc.NoResultFound: mydept = Department() mydept.id = dept[0] mydept.name = dept[1] session.add(mydept) request_data = {'method': 'dept.jobs', "params": {"department_id": dept[0]}} request = requests.post(url=cfg.api_endpoint, json=request_data, headers=REQUEST_HEADERS) dept_details = json.loads(request.text) # this checks if changed before updating because my memory tells me # fewer changed records makes the SQL commit faster if not mydept.is_shiftless == dept_details['result']['is_shiftless']: mydept.is_shiftless = dept_details['result']['is_shiftless'] session.commit() session.close() return
def carryout_eligible(shifts, response, meal_start, meal_end): """ Takes a list of shifts and checks if they overlap the given meal period Uses rules for allowable gaps configured in system :param shifts: List of shift objects. Concurrent shifts must already be merged or this will not work correctly! :param response : full response from attendee lookup from Uber API :param meal_start : date object for the meal start in python dateutil datetime format :param meal_end : date object for the meal end in python dateutil datetime format :return: returns True or False """ # need to check combined if shift starts within <<buffer>> after start of meal time or earlier # AND ends within <<buffer>exc> before end of meal time or later """code section for buffer, commented out cause not using buffer for Super 2020 meal_buffer = relativedelta(minutes=cfg.schedule_tolerance) # print("Meal start: {} Meal End {}".format(str(meal_start),str(meal_end))) for shift in shifts: # print("shift start : {} Shift end: {}".format(str(shift.start),str(shift.end))) sdelta = relativedelta((meal_start + meal_buffer), shift.start) start_delta = sdelta.minutes + (sdelta.hours * 60) edelta = relativedelta(shift.end, (meal_end - meal_buffer)) end_delta = edelta.minutes + (edelta.hours * 60) if start_delta >= 0 and end_delta >= 0 and sdelta.days == 0: # start_delta.days being anything other than 0 means the shift is more than 24 hours from the meal return True """ # rd is negative if first before second # ss=shift start, se = shift end. ms=meal start, me= meal end # if ss after ms AND before me then good # if se after ms AND before me then good # if ss before ms AND se after me then good # if the shift is more than a day before or after the meal days != 0 # if there are no shifts, skip processing if len(shifts) != 0: # this code checks for if shift start during meal period # this will also catch entire shifts that happen inside part of meal period for shift in shifts: ss_ms = relativedelta(meal_start, shift.start) ss_ms_delta = ss_ms.minutes + (ss_ms.hours * 60) ss_me = relativedelta(meal_end, shift.start) ss_me_delta = ss_me.minutes + (ss_me.hours * 60) if ss_ms_delta < 0 and ss_me_delta > 0 and ss_ms.days == 0: # print('ss after ms AND before me then good') return True # this code checks for if shift end during meal period se_ms = relativedelta(meal_start, shift.end) se_ms_delta = se_ms.minutes + (se_ms.hours * 60) se_me = relativedelta(meal_end, shift.end) se_me_delta = se_me.minutes + (se_me.hours * 60) if se_ms_delta < 0 and se_me_delta > 0 and ss_ms.days == 0: # print('se after ms AND before me then good') return True # this code checks for if shift start is before/= AND shift end is after/= meal period # this will also catch shifts that happen during the exact start and end time of the meal period if ss_ms_delta >= 0 and se_me_delta <= 0 and ss_ms.days == 0: # print('if ss before ms AND se after me then good') return True if response['result']['is_dept_head']: return True if response['result']['badge_type_label'] in ["Contractor", "Guest"]: return True if response['result']['public_id'] in cfg.food_managers: return True session = models.new_sesh() if is_vip(response['result']['badge_num'], session): return True shiftless_depts = session.query(models.department.Department).filter_by(is_shiftless=True).all() for dept in shiftless_depts: if dept.name in response['result']['assigned_depts_labels']: session.close() return True session.close() # if none of the shifts match the meal period and attendee is not exempt, return false. return False
def add_access(badge, usertype=None): """ Adds provided badge number (or barcode) to selected access list :param badge: :param usertype: 'admin' or 'staff' or 'food_manager' :return: """ if badge[0] == "~": badge = barcode_to_badge(badge) else: try: badge = int(badge) except ValueError: raise HTTPRedirect("Not a number?") if not badge: raise HTTPRedirect("config?message=Badge not found") session = models.new_sesh() try: attend = session.query(models.attendee.Attendee).filter_by(badge_num=badge).one() except sqlalchemy.orm.exc.NoResultFound: response = lookup_attendee(badge) if 'error' in response: session.close() # admin or staff would be added using config page, Food Manager would be from dept_orders page if usertype == 'admin' or usertype == 'staff': raise HTTPRedirect("config?message=Badge " + str(badge) + " is not found in Reggie") else: raise HTTPRedirect("dept_order_selection?message=Badge " + str(badge) + " is not found in Reggie") attend = models.attendee.Attendee() attend.badge_num = response['result']['badge_num'] attend.public_id = response['result']['public_id'] attend.full_name = response['result']['full_name'] session.add(attend) session.commit() if usertype == 'admin' and attend.public_id not in cfg.admin_list: cfg.admin_list.append(attend.public_id) if usertype == 'staff' and attend.public_id not in cfg.staffer_list: cfg.staffer_list.append(attend.public_id) if usertype == 'food_manager' and attend.public_id not in cfg.food_managers: if is_dh(attend.public_id): session.close() raise HTTPRedirect("dept_order_selection?message=Badge " + str(badge) + "is already a Department Head") if is_admin(attend.public_id): session.close() raise HTTPRedirect("dept_order_selection?message=Badge " + str(badge) + "is already a Tuber Eats Admin") cfg.food_managers.append(attend.public_id) manager_list = ',\n'.join(cfg.food_managers) managerfile = open('food_managers.cfg', 'w') managerfile.write(manager_list) managerfile.close() session.close() return True session.close() return False