def test_interval_timesheet(): entries = ['2018-04-10T05:43:00', '2018-04-10T09:28:00', '2018-04-10T09:46:00', '2018-04-10T11:05:00', '2018-04-12T02:26:00','2018-04-12T05:42:00','2018-04-12T05:56:00','2018-04-12T07:42:00', '2018-04-13T09:43:00','2018-04-13T10:30:00',] timesheet = TimeSheet(entries) interval_duration = timesheet.interval_duration('2018-04-10') assert str(interval_duration) == '0:18:00'
def test_get_interval_clock_in(): entries = ['2018-04-10T05:43:00', '2018-04-10T09:28:00', '2018-04-10T09:46:00', '2018-04-10T11:05:00', '2018-04-12T02:26:00','2018-04-12T05:42:00','2018-04-12T05:56:00','2018-04-12T07:42:00', '2018-04-13T09:43:00','2018-04-13T10:30:00', '2018-04-14T10:00:00', '2018-04-14T09:00:00'] timesheet = TimeSheet(entries) assert str(timesheet.interval_clock_in('2018-04-10')) == '2018-04-10 09:46:00' assert str(timesheet.interval_clock_in('2018-04-12')) == '2018-04-12 05:56:00' assert timesheet.interval_clock_in('2018-04-14') == None
def test_get_clock_out(): entries = ['2018-04-10T05:43:00', '2018-04-10T09:28:00', '2018-04-10T09:46:00', '2018-04-10T11:05:00', '2018-04-12T02:26:00','2018-04-12T05:42:00','2018-04-12T05:56:00','2018-04-12T07:42:00', '2018-04-13T09:43:00','2018-04-13T10:30:00', '2018-04-14T10:00:00', '2018-04-14T09:00:00'] timesheet = TimeSheet(entries) assert str(timesheet.clock_out('2018-04-10')) == '2018-04-10 11:05:00' assert str(timesheet.clock_out('2018-04-12')) == '2018-04-12 07:42:00' assert str(timesheet.clock_out('2018-04-14')) == '2018-04-14 10:00:00'
def punch_in(self): if self._is_clocked_in(self._get_newest()): return self._response() ts = datetime.datetime.utcnow() t = TimeSheet(time_in=ts, user_id=1) t.save() ts_iso = ts.isoformat() return self._response(response={"ts": ts_iso})
def test_balance_summary(): entries = ['2018-04-12T08:00:00','2018-04-12T12:00:00','2018-04-12T13:00:00','2018-04-12T19:00:00'] timesheet = TimeSheet(entries) employee = Employee(timesheet, default_workload, default_processor) history = employee.history(datetime(2018, 4,12), datetime(2018, 4,16)) balance_summary = employee.balance_summary_in_minutes(history) assert (balance_summary.total_seconds() / 60) == -960
def test_history_just_one_day(): entries = ['2018-04-12T08:00:00','2018-04-12T12:00:00','2018-04-12T13:00:00','2018-04-12T19:00:00'] timesheet = TimeSheet(entries) employee = Employee(timesheet, default_workload, default_processor) history = employee.history(datetime(2018, 4,12), datetime(2018, 4,12)) assert len(history) == 1 assert history[0]['day'] == '2018-04-12' assert history[0]['balance'] == 60
def test_total_interval_duration(): entries = ['2018-04-10T05:43:00', '2018-04-10T09:28:00', '2018-04-10T09:46:00', '2018-04-10T11:05:00', '2018-04-12T08:00:00','2018-04-12T12:00:00','2018-04-12T13:00:00','2018-04-12T20:00:00', '2018-04-16T08:00:00','2018-04-16T09:00:00','2018-04-16T13:00:00','2018-04-16T14:00:00',] timesheet = TimeSheet(entries) employee = Employee(timesheet, default_workload, default_processor) assert str(employee.total_interval_duration('2018-04-10')) == '0:18:00' assert str(employee.total_interval_duration('2018-04-12')) == '1:00:00'
def test_map_timesheet(): entries = ['2018-04-10T05:43:00', '2018-04-10T09:28:00', '2018-04-10T09:46:00', '2018-04-10T11:05:00', '2018-04-12T02:26:00','2018-04-12T05:42:00','2018-04-12T05:56:00','2018-04-12T07:42:00', '2018-04-13T09:43:00','2018-04-13T10:30:00',] timesheet = TimeSheet(entries) assert len(timesheet.entry_by_day['2018-04-10']) == 4 assert len(timesheet.entry_by_day['2018-04-13']) == 2 assert timesheet.entry_by_day['2018-04-13'][0] == '2018-04-13T09:43:00' assert timesheet.entry_by_day['2018-04-13'][1] == '2018-04-13T10:30:00'
def punch_out(self): try: row_id = self._get_newest() if not self._is_clocked_in(row_id): return self._response() except Exception: return self._response() ts = datetime.datetime.utcnow() q = TimeSheet.update(time_out=ts).where(TimeSheet.id == row_id) q.execute() ts_iso = ts.isoformat() return self._response(response={"ts": ts_iso})
def test_history_between_two_days(): entries = ['2018-04-12T08:00:00','2018-04-12T12:00:00','2018-04-12T13:00:00','2018-04-12T19:00:00'] timesheet = TimeSheet(entries) employee = Employee(timesheet, default_workload, default_processor) history = employee.history(datetime(2018, 4,12), datetime(2018, 4,16)) assert len(history) == 5 assert history[0]['day'] == '2018-04-12' assert history[0]['balance'] == 60 assert history[1]['day'] == '2018-04-13' assert history[1]['balance'] == -480 assert history[2]['day'] == '2018-04-14' assert history[2]['balance'] == 0 assert history[3]['day'] == '2018-04-15' assert history[3]['balance'] == 0 assert history[4]['day'] == '2018-04-16' assert history[4]['balance'] == -540
def test_with_holidays(): entries = ['2018-04-12T08:00:00','2018-04-12T12:00:00','2018-04-12T13:00:00','2018-04-12T18:00:00', '2018-04-13T08:00:00','2018-04-13T12:00:00','2018-04-13T13:00:00','2018-04-13T19:00:00', '2018-04-17T08:00:00','2018-04-17T12:00:00','2018-04-17T13:00:00','2018-04-17T19:00:00', '2018-04-18T08:00:00','2018-04-18T20:00:00', '2018-04-19T10:00:00','2018-04-19T12:00:00','2018-04-19T12:30:00','2018-04-19T13:30:00', ] holidays_processor = lambda minutes, workload_date: pos_processor_workload(minutes, workload_date, ['2018-04-19', '2018-04-13']) timesheet = TimeSheet(entries) employee = Employee(timesheet, default_workload, holidays_processor) response = employee.response(datetime(2018, 4,12), datetime(2018, 4,19), '123456') assert response['pis_number'] == '123456' assert response['summary']['balance'] == '08:00'
def _get_todays_records(self, day_offset=0): # get today today = datetime.datetime.now() # apply offset today = today + datetime.timedelta(days=day_offset) # drop everything smaller than day and for some reason # today.replace(hour=0, minute=0, second=0, microsecond=0) # was not working at all. so this is my work around day = datetime.datetime(today.year, today.month, today.day) # make time deltas for some UTC math # central time is 6 hours before utc td_hours = datetime.timedelta(hours=6) td_day = datetime.timedelta(days=1) date_min = day + td_hours date_max = date_min + td_day return TimeSheet.select().where( TimeSheet.time_in <= date_max, TimeSheet.time_in >= date_min)
def main(): args = handle_arguments() json_args = transform_filled_values(args, load_to_json) ask_input = lambda param : json.load(input(f'Enter the {param} param input: ')) user_input = fill_empty_values(json_args, ask_input) pis = input('Retrieve balance from pis number: ') config = user_input['config'] timeclock = user_input['timeclock'] employee_config = find_by_pis_number(config['employees'], pis) employee_timeclock = find_by_pis_number(timeclock, pis) holidays_processor = lambda minutes, workload_date: pos_processor_workload(minutes, workload_date, config['holidays']) employee = Employee(TimeSheet(employee_timeclock['entries']), employee_config['workload'], holidays_processor) today = datetime.strptime(config['today'], '%Y-%m-%d') period_start = datetime.strptime(config['period_start'], '%Y-%m-%d') print(employee.response(period_start, today, pis))
def test_response(): entries = ['2018-04-12T08:00:00','2018-04-12T12:00:00','2018-04-12T13:00:00','2018-04-12T18:00:00', '2018-04-13T08:00:00','2018-04-13T12:00:00','2018-04-13T13:00:00','2018-04-13T19:00:00', '2018-04-17T08:00:00','2018-04-17T12:00:00','2018-04-17T13:00:00','2018-04-17T19:00:00', '2018-04-18T08:00:00','2018-04-18T20:00:00', '2018-04-19T10:00:00','2018-04-19T12:00:00','2018-04-19T12:30:00','2018-04-19T13:30:00', ] timesheet = TimeSheet(entries) employee = Employee(timesheet, default_workload, default_processor) response = employee.response(datetime(2018, 4,12), datetime(2018, 4,19), '123456') assert response['pis_number'] == '123456' assert response['summary']['balance'] == '-09:00' assert response['history'][0]['day'] == '2018-04-12' assert response['history'][0]['balance'] == '00:00' assert response['history'][1]['balance'] == '02:00' assert response['history'][2]['balance'] == '00:00' assert response['history'][3]['balance'] == '00:00' assert response['history'][4]['balance'] == '-09:00' assert response['history'][5]['balance'] == '01:00' assert response['history'][6]['balance'] == '03:00' assert response['history'][7]['balance'] == '-06:00'
def submit_time_sheet( request, employee ): # default period is current month months = tshelpers.months today = datetime.date.today() period = '%s %d' % ( months[ today.month - 1], today.year ) availableperiods = [] for month in months: availableperiods.append( '%s %d' % ( month, today.year ) ) timesheet_data = None message = '' if request.method == "POST": period = request.POST['period'] timesheet_data = tshelpers.generate_timesheet_data( employee, period ) timesheet_db = TimeSheet.objects.filter( employee = employee, period = timesheet_data['period'] ) message = None # it the time sheet has already been submitted, correct information needs to be presented # with respect to balances if timesheet_db.count() > 0: timesheet_data = tshelpers.generate_timesheet_data( employee, period, timesheet_db[0], False ) message = 'This time sheet has already been submitted' if timesheet_data['salary_sources'] == {}: message = "Time sheet can't be submitted.\nSalary assignment is missing." if request.POST['button'] == 'Submit': # check if already sumbitted if timesheet_data['salary_sources'] != {}: if timesheet_db.count() == 0: # need to calculate balances and use them here timesheet_obj = TimeSheet( employee = employee, period = timesheet_data['period'], submit_date = datetime.date.today(), approve_date = None, start_date = timesheet_data['dates'][0], end_date = timesheet_data['dates'][1] ) timesheet_obj.leave_balance_before_HOLS = timesheet_data['leave_data'][0] timesheet_obj.leave_balance_before_SICK = timesheet_data['leave_data'][1] timesheet_obj.leave_earn_HOLS = timesheet_data['leave_data'][2] timesheet_obj.leave_earn_SICK = timesheet_data['leave_data'][3] timesheet_obj.leave_used_HOLS = timesheet_data['leave_data'][4] timesheet_obj.leave_used_SICK = timesheet_data['leave_data'][5] timesheet_obj.leave_balance_HOLS = timesheet_data['leave_data'][6] timesheet_obj.leave_balance_SICK = timesheet_data['leave_data'][7] timesheet_obj.save() tshelpers.send_notification( request, "SUBMITTED", timesheet_obj ) message = 'Your time sheet for %s has been submitted for approval' % timesheet_data['period'] return render( request, "time_sheet_submit.html", {'employee': employee, 'period' : period, 'availableperiods' : availableperiods, 'timesheetdata': timesheet_data, 'viewdata' : timesheet_data, 'message' : message, } )
def test_workedtime_without_interval(): entries = ['2018-04-12T08:00:00','2018-04-12T20:00:00'] timesheet = TimeSheet(entries) employee = Employee(timesheet, default_workload, default_processor) assert str(employee.total_day_worked_time('2018-04-12')) == '12:00:00'
def test_workedtime_completed_workday_1_min_interval(): entries = ['2018-04-12T08:00:00','2018-04-12T12:00:00','2018-04-12T12:01:00','2018-04-12T18:00:00'] timesheet = TimeSheet(entries) employee = Employee(timesheet, default_workload, default_processor) assert str(employee.total_day_worked_time('2018-04-12')) == '9:59:00'
def _is_clocked_in(time_id): try: return TimeSheet.get(TimeSheet.id == time_id).time_out is None except Exception: return False
def test_workedtime_incomplete_workday(): entries = ['2018-04-12T08:00:00','2018-04-12T12:00:00','2018-04-12T12:10:00','2018-04-12T12:11:00'] timesheet = TimeSheet(entries) employee = Employee(timesheet, default_workload, default_processor) assert str(employee.total_day_worked_time('2018-04-12')) == '4:01:00'
def test_total_interval_duration_with_incomplete_workday(): entries = ['2018-04-16T08:00:00','2018-04-16T09:00:00','2018-04-16T13:00:00','2018-04-16T14:00:00',] timesheet = TimeSheet(entries) employee = Employee(timesheet, default_workload, default_processor) assert str(employee.total_interval_duration('2018-04-16')) == '0:00:00'
def _get_newest(): try: return TimeSheet.select().order_by(TimeSheet.id.desc())[0].id except Exception: pass
def test_total_interval_duration_without_interval(): entries = ['2018-04-12T08:00:00', '2018-04-12T20:00:00',] timesheet = TimeSheet(entries) employee = Employee(timesheet, default_workload, default_processor) assert str(employee.total_interval_duration('2018-04-12')) == '0:00:00'
def test_employee_valid_interval(): entries = ['2018-04-12T08:00:00','2018-04-12T12:00:00','2018-04-12T12:10:00','2018-04-12T20:11:00'] timesheet = TimeSheet(entries) employee = Employee(timesheet, default_workload, default_processor) assert employee.is_invalid_interval('2018-04-12') is False
def test_balance_with_debit(): entries = ['2018-04-12T08:00:00','2018-04-12T12:00:00','2018-04-12T13:00:00','2018-04-12T16:59:00'] timesheet = TimeSheet(entries) employee = Employee(timesheet, default_workload, default_processor) assert employee.balance_in_minutes('2018-04-12') == -61
def test_balance_without_interval(): entries = ['2018-04-12T08:00:00', '2018-04-12T09:00:00'] timesheet = TimeSheet(entries) employee = Employee(timesheet, default_workload, default_processor) assert employee.balance_in_minutes('2018-04-12') == -480
def submit_time_sheet(request, employee): # default period is current month months = tshelpers.months today = datetime.date.today() period = '%s %d' % (months[today.month - 1], today.year) availableperiods = [] for month in months: availableperiods.append('%s %d' % (month, today.year)) timesheet_data = None message = '' if request.method == "POST": period = request.POST['period'] timesheet_data = tshelpers.generate_timesheet_data(employee, period) timesheet_db = TimeSheet.objects.filter( employee=employee, period=timesheet_data['period']) message = None # it the time sheet has already been submitted, correct information needs to be presented # with respect to balances if timesheet_db.count() > 0: timesheet_data = tshelpers.generate_timesheet_data( employee, period, timesheet_db[0], False) message = 'This time sheet has already been submitted' if timesheet_data['salary_sources'] == {}: message = "Time sheet can't be submitted.\nSalary assignment is missing." if request.POST['button'] == 'Submit': # check if already sumbitted if timesheet_data['salary_sources'] != {}: if timesheet_db.count() == 0: # need to calculate balances and use them here timesheet_obj = TimeSheet( employee=employee, period=timesheet_data['period'], submit_date=datetime.date.today(), approve_date=None, start_date=timesheet_data['dates'][0], end_date=timesheet_data['dates'][1]) timesheet_obj.leave_balance_before_HOLS = timesheet_data[ 'leave_data'][0] timesheet_obj.leave_balance_before_SICK = timesheet_data[ 'leave_data'][1] timesheet_obj.leave_earn_HOLS = timesheet_data[ 'leave_data'][2] timesheet_obj.leave_earn_SICK = timesheet_data[ 'leave_data'][3] timesheet_obj.leave_used_HOLS = timesheet_data[ 'leave_data'][4] timesheet_obj.leave_used_SICK = timesheet_data[ 'leave_data'][5] timesheet_obj.leave_balance_HOLS = timesheet_data[ 'leave_data'][6] timesheet_obj.leave_balance_SICK = timesheet_data[ 'leave_data'][7] timesheet_obj.save() tshelpers.send_notification(request, "SUBMITTED", timesheet_obj) message = 'Your time sheet for %s has been submitted for approval' % timesheet_data[ 'period'] return render( request, "time_sheet_submit.html", { 'employee': employee, 'period': period, 'availableperiods': availableperiods, 'timesheetdata': timesheet_data, 'viewdata': timesheet_data, 'message': message, })