def check_missing(self, date_from, date_until): """ :param date_from: :param date_until: :return: """ from date_tools import DateTools from os_class import Class from os_class_schedule import ClassSchedule T = current.T db = current.db dt = DateTools() error = False message = '' classes_added = 0 days_between = dt.days_between_dates(date_from, date_until) if days_between == False: error = True message = T("From date has to be smaller then until date.") if days_between > 92: error = True message = T("Gap between dates can not be more then 3 months") if not error: date = date_from while date <= date_until: cs = ClassSchedule(date) classes = cs.get_day_list() for cls in classes: if not cls['Cancelled'] or cls['Holiday']: # Check if item in db.teachers_payment_classes query = (db.teachers_payment_classes.classes_id == cls['ClassesID']) & \ (db.teachers_payment_classes.ClassDate == date) if db(query).count() == 0: os_cls = Class(cls['ClassesID'], date) result = os_cls.get_teacher_payment() if not result['error']: classes_added += 1 date += datetime.timedelta(days=1) message = classes_added return dict(error=error, message=message)
def _get_teacher_payment_set_travel_allowance(self, tpc_row): """ set db.teachers_payment_classes travel allowance """ from os_class_schedule import ClassSchedule from os_teacher import Teacher db = current.db if tpc_row and not tpc_row.Status == 'processed': cs = ClassSchedule( self.date, filter_id_teacher=tpc_row.auth_teacher_id, filter_id_school_location=self.cls.school_locations_id) class_start = datetime.datetime(self.date.year, self.date.month, self.date.day, self.cls.Starttime.hour, self.cls.Starttime.minute) # Add travel allowance if no class is found that ended 30 minutes before start of this class class_found = False rows = cs.get_day_rows() for row in rows: if not int(row.classes.id) == int(self.clsID): checked_class_start = datetime.datetime( self.date.year, self.date.month, self.date.day, row.classes.Endtime.hour, row.classes.Endtime.minute) checked_class_end = datetime.datetime( self.date.year, self.date.month, self.date.day, row.classes.Endtime.hour, row.classes.Endtime.minute) consecutive = ( (checked_class_end + datetime.timedelta(minutes=30)) >= class_start and checked_class_end <= class_start) if consecutive: class_found = True if not class_found: # Add travel allowance, there is no class which ends within 30 min in same location teacher = Teacher(tpc_row.auth_teacher_id) travel_allowance = teacher.get_payment_travel_allowance_location( self.cls.school_locations_id) if travel_allowance: tpc_row.TravelAllowance = travel_allowance.TravelAllowance tpc_row.tax_rates_id_travel_allowance = travel_allowance.tax_rates_id tpc_row.update_record()
def get_classes_revenue_summary_day(self, date): """ :param date: :return: """ from os_class import Class from os_class_schedule import ClassSchedule # Get class schedule for days cs = ClassSchedule(date) schedule = cs.get_day_list() revenue = { 'data': [], 'revenue_total': 0, 'teacher_payments': 0, 'balance': 0 } for cls in schedule: clsID = cls['ClassesID'] # Get revenue for each class class_revenue = self.get_class_revenue_summary(clsID, date) cls_object = Class(clsID, date) teacher_payment = cls_object.get_teacher_payment() if not teacher_payment['error']: tp_amount = teacher_payment['data']['ClassRate'] else: tp_amount = 0 cls['RevenueTotal'] = class_revenue['total']['amount'] cls['TeacherPayment'] = tp_amount cls['Balance'] = (cls['RevenueTotal'] - cls['TeacherPayment']) revenue['revenue_total'] += cls['RevenueTotal'] revenue['teacher_payments'] += cls['TeacherPayment'] revenue['balance'] += cls['Balance'] revenue['data'].append(cls) return revenue
def _get_customers_list_classes_recurring_reservations(self, year, month): """ Get list of classes a customer has a reservation for in a selected month """ from os_attendance_helper import AttendanceHelper from os_class_schedule import ClassSchedule from os_classes_reservations import ClassesReservations db = current.db ah = AttendanceHelper() crh = ClassesReservations() first_day = datetime.date(year, month, 1) last_day = get_last_day_month(first_day) data = {} date = first_day while date <= last_day: # get list of classes on date #print date cs = ClassSchedule(date) #print 'getting classes' classes = cs.get_day_list() reservations = crh.get_recurring_reservations_on_date(date) for cls in classes: if cls['Cancelled'] or cls['Holiday']: # Class is cancelled or in a holiday, nothing to do continue # Get list of bookings with status "attending" or "booked" #print 'getting attendance for class' attending = [] rows = ah.get_attendance_rows(cls['ClassesID'], date) for row in rows: # print row if row.classes_attendance.BookingStatus == 'booked' or \ row.classes_attendance.BookingStatus == 'attending': attending.append(row.auth_user.id) # if classes_id found on both lists, add class to reservations list for that customer for res in reservations: if res.classes_id == cls['ClassesID']: # add customer to list in case not already attending if not res.auth_customer_id in attending: #print res.auth_customer_id value = {'clsID': cls['ClassesID'], 'date': date} # print value # print '###############' try: data[res.auth_customer_id].append(value) except KeyError: data[res.auth_customer_id] = [value] date += datetime.timedelta(days=1) return data
def classes_add_get_list(self, date, list_type, cuID=None, teID=None): """ Get list of classes for a date list_type is expected to be in [ 'attendance', 'reservations', 'tp_fixed_rate' ] """ from os_attendance_helper import AttendanceHelper from os_class_schedule import ClassSchedule from os_gui import OsGui T = current.T db = current.db os_gui = OsGui() DATE_FORMAT = current.DATE_FORMAT session = current.session if list_type == 'attendance': session.classes_attendance_signin_back = 'cu_classes_attendance' ah = AttendanceHelper() # links = [ lambda row: ah.get_signin_buttons(row.classes.id, date, cuID) ] if session.classes_schedule_sort == 'location': orderby = db.school_locations.Name | db.classes.Starttime elif session.classes_schedule_sort == 'starttime': orderby = db.classes.Starttime | db.school_locations.Name else: orderby = db.school_locations.Name | db.classes.Starttime filter_id_teacher = None if list_type == 'tp_fixed_rate': filter_id_teacher = cuID cs = ClassSchedule(date, sorting=orderby, filter_id_teacher=filter_id_teacher) classes = cs.get_day_list() header = THEAD(TR(TH(T('Time')), TH(T('Location')), TH(T('Class')), TH(), TH() # buttons )) table = TABLE(header, _class='table table-striped table-hover') for c in classes: status = self._classes_add_get_list_get_cancelled_holiday(c) buttons = '' if list_type == 'reservations': buttons = self._classes_reservation_add_get_button(c['ClassesID']) elif list_type == 'attendance' and status == '': buttons = os_gui.get_button('noicon', URL('customers', 'classes_attendance_add_booking_options', vars={'cuID': cuID, 'clsID': c['ClassesID'], 'date': date.strftime(DATE_FORMAT)}), title='Check in', _class='pull-right') elif list_type == 'tp_fixed_rate': buttons = os_gui.get_button( 'noicon', URL('teachers', 'payment_fixed_rate_class', vars={'teID': teID, 'clsID': c['ClassesID']}), title=T('Set rate'), _class='pull-right' ) tr = TR( TD(c['Starttime'], ' - ', c['Endtime']), TD(c['Location']), TD(c['ClassType']), TD(status), TD(buttons) ) table.append(tr) return table
def get_upcoming_classes_formatted(self, days=3): """ Returns upcoming classes for teacher """ from os_gui import OsGui from os_class_schedule import ClassSchedule T = current.T db = current.db auth = current.auth os_gui = OsGui() DATE_FORMAT = current.DATE_FORMAT TODAY_LOCAL = current.globalenv['TODAY_LOCAL'] attendance_permission = (auth.has_membership(group_id='Admins') or auth.has_permission( 'update', 'classes_attendance')) date = TODAY_LOCAL delta = datetime.timedelta(days=1) header = THEAD( TR( TH(T('Class date')), TH(T('Time')), TH(T('Location')), TH(T('Class type')), TH(T('Teacher')), TH(T('Teacher2')), TH(), )) table = TABLE(header, _class='table table-hover') for day in range(0, days): cs = ClassSchedule(date, filter_id_teacher=self.id) rows = cs.get_day_rows() for i, row in enumerate(rows): if row.classes_otc.Status == 'cancelled' or row.school_holidays.id: continue repr_row = list(rows[i:i + 1].render())[0] result = cs._get_day_row_teacher_roles(row, repr_row) teacher = result['teacher_role'] teacher2 = result['teacher_role2'] attendance = '' if attendance_permission: attendance = os_gui.get_button( 'noicon', URL('classes', 'attendance', vars={ 'clsID': row.classes.id, 'date': date.strftime(DATE_FORMAT) }), title=T('Attendance'), _class=T('pull-right')) tr = TR( TD(date.strftime(DATE_FORMAT), _class='bold green' if day == 0 else ''), TD(repr_row.classes.Starttime, ' - ', repr_row.classes.Endtime), TD(repr_row.classes.school_locations_id), TD(repr_row.classes.school_classtypes_id), TD(teacher), TD(teacher2), TD(attendance)) table.append(tr) date += delta upcoming_classes = DIV( DIV(H3(T('My upcoming classes'), _class="box-title"), DIV(A(I(_class='fa fa-minus'), _href='#', _class='btn btn-box-tool', _title=T("Collapse"), **{'_data-widget': 'collapse'}), _class='box-tools pull-right'), _class='box-header with-border'), DIV(table, _class='box-body'), self._get_teacher_upcoming_classes_formatted_footer(), _class='box box-primary') return upcoming_classes
def get_classes(self, date_from, date_until=None, respect_booking_open=True): """ :param date_from: datetime.date :param date_until: datetime.date :return: [] Return list of upcoming classes """ import calendar from os_attendance_helper import AttendanceHelper from os_class_schedule import ClassSchedule from os_classes_reservations import ClassesReservations db = current.db TODAY_LOCAL = current.TODAY_LOCAL ah = AttendanceHelper() data = [] date = date_from if date_until is None: year = TODAY_LOCAL.year month = TODAY_LOCAL.month + 1 if month == 13: month = 1 year = TODAY_LOCAL.year + 1 date_until = datetime.date( year, month, calendar.monthrange( year, month, )[1]) # Last day of next month from today (local time) while date <= date_until: cs = ClassSchedule(date) classes = cs.get_day_list() for cls in classes: if (cls['Cancelled'] or cls['Holiday'] or not cls['ClassesID'] == self.row.classes_id or (respect_booking_open and cls['BookingOpen'] and cls['BookingOpen'] > date)): # Class is cancelled, in a holiday, not the class we're looking for # or not yet bookable -> nothing to do continue attending = [] rows = ah.get_attendance_rows(cls['ClassesID'], date) for row in rows: if row.classes_attendance.BookingStatus == 'booked' or \ row.classes_attendance.BookingStatus == 'attending': attending.append(row.auth_user.id) # add customer to list in case not already attending if not self.row.auth_customer_id in attending: value = {'clsID': cls['ClassesID'], 'date': date} data.append(value) date += datetime.timedelta(days=1) return data