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)
예제 #2
0
    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()
예제 #3
0
    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
예제 #5
0
    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
예제 #6
0
    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
예제 #7
0
    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