Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import calendar
- from dateutil import rrule
- from datetime import datetime, timedelta
- from collections import defaultdict
- from datetime import datetime
- from django.contrib.auth.models import User
- from .models import (Account, Doctor, Ticket, DoctorOfftime, Appointments,
- Personal_Workchedule, DoctorMedicalPositions, MedicalPositions)
- # from pprint import pprint
- def exclude_projected_tiket(date: datetime, timeTiket) -> list:
- """Исключаю зарезервированное время из сгенерированного списка исходя по времени по опредедённому приёму"""
- free_tiket = []
- appointments = Appointments.objects.filter(
- appointment_date = date
- )
- for ticket in timeTiket:
- for index, time in enumerate(ticket):
- time_current_doctor = [time.appointment_time for time in appointments.filter(doctor__id = time[1])]
- ticketTime = datetime.strptime(str(time[0]), "%H:%M:%S").time()
- if ticketTime in time_current_doctor:
- del time
- else:
- free_tiket.append([str(ticketTime), time[1]])
- return free_tiket
- _slice_previous_week = lambda index_week, month : [month.pop(0) for index in range(len(month)) if index < index_week]
- def get_free_ticket(date: datetime, select_reception: str, user: int, positionId: int, doctor: list = []) -> list:
- # Проверяю передан ли конкретный врач
- if doctor:
- listDoctor = [doctor]
- else:
- if positionId: # Формирую список врачей (их id) если конкретный доктор не выбран , получаю их по выбранной специализации
- # и проверяю их выходные дни
- _check_doctorOfftime = lambda id: not DoctorOfftime.objects.filter(doctor__id = id, start_date__gte = date, end_date__lte = date).exists()
- listDoctor = list(filter( _check_doctorOfftime ,
- [positions.doctor.id for positions in DoctorMedicalPositions.objects.filter(
- polyclinic__id = Account.objects.get(user = user).polyclinic.id,
- position__id = positionId,
- )]))
- else:
- listDoctor = []
- list_talons = []
- workchedule = Personal_Workchedule.objects.filter(doctor__id__in = listDoctor, date = datetime.strptime(date, '%Y-%m-%d'))
- """Получаю рабочий график на {date} число"""
- ticket = []
- for chedule in workchedule:
- interval = timedelta(minutes=int(chedule.count_of_minute_on_one_see))
- if select_reception == 'OMS':
- time_start = timedelta(hours=chedule.OMS_start_time.hour, minutes=chedule.OMS_start_time.minute, seconds=0)
- time_end = timedelta(hours=chedule.OMS_end_time.hour, minutes=chedule.OMS_end_time.minute, seconds=0)
- """Расчитываю временной диапозон по времени от начала до конца приёма по ОМС с {interval} периодом"""
- ticket.append([(str(time[0]), chedule.doctor.id) for time in Personal_Workchedule.calculation_of_coupons(time_start, time_end, interval)])
- if select_reception == 'DMS':
- time_start = timedelta(hours=chedule.DMS_start_time.hour, minutes=chedule.DMS_start_time.minute, seconds=0)
- time_end = timedelta(hours=chedule.DMS_end_time.hour, minutes=chedule.DMS_end_time.minute, seconds=0)
- """Расчитываю временной диапозон по времени от начала до конца приёма по ДМС с {interval} периодом"""
- ticket.append([(str(time[0]), chedule.doctor.id) for time in Personal_Workchedule.calculation_of_coupons(time_start, time_end, interval)])
- if select_reception == 'PAYED':
- time_start = timedelta(hours=chedule.other_start_time.hour, minutes=chedule.other_start_time.minute, seconds=0)
- time_end = timedelta(hours=chedule.other_end_time.hour, minutes=chedule.other_end_time.minute, seconds=0)
- """Расчитываю временной диапозон по времени от начала до конца приёма по ДРУГИМ ВОПРОСАМ с {interval} периодом"""
- ticket.append([(str(time[0]), chedule.doctor.id) for time in Personal_Workchedule.calculation_of_coupons(time_start, time_end, interval)])
- free_ticket = exclude_projected_tiket(date, ticket)
- """Исключаю забронированное время из расчитанного динамическим путём"""
- """Сортирую полученный список по ключ время и значением список врачей по которым он принемает если врачей несколько"""
- for ticket in free_ticket:
- ticketTime = ticket[0]
- if list_talons:
- for value in list_talons:
- if ticketTime in value:
- value[ticketTime].append((ticket[1]))
- else:
- value[ticketTime] = [(ticket[1])]
- else:
- list_talons.append({ticket[0] : [ticket[1]]})
- if list_talons:
- countTicket = len(list_talons[0])
- else: countTicket = len(list_talons)
- return (date, countTicket, list_talons)
- def generate_month(year: int, month: int, select_reception: str, user: id, positionId: id, doctorId: int = 0) -> tuple:
- """Первый день месяца"""
- first_day_of_month = datetime(year, month, 1)
- """Последний день месяца"""
- last_day_of_month = first_day_of_month.replace(day=calendar.monthrange(year, month)[1])
- """Сгенерированные календарные дни"""
- range_date = rrule.rrule(rrule.DAILY, dtstart=first_day_of_month, until=last_day_of_month)
- """Последний день предыдущего месяца"""
- last_day_of_last_month = first_day_of_month - timedelta(days=1)
- """Кол-во недель в месяце"""
- max_week = len(calendar.monthcalendar(year, month))
- """Кол-во дней в недели"""
- DAYS_WEEK = 7
- dict_days = defaultdict(lambda: [])
- for i in range(DAYS_WEEK):
- for day in range_date:
- if day.weekday() == i:
- dict_days[i].append(day)
- """Получаем индекс элемента с первым и последним числом"""
- first_day_of_week = 0
- for index, value in dict_days.items():
- for date in value:
- if first_day_of_month.day == date.day:
- first_day_of_week = index
- if last_day_of_month.day == date.day:
- last_day_of_week = index
- month_list = [] # Список с неделями
- """Заполнием пустую матрицу"""
- for i in range(max_week):
- week = [0 for i in range(DAYS_WEEK)]
- month_list.append(week)
- index = 0
- """Индекс последнего дня предыдущего месяца"""
- pre_date = first_day_of_week
- while pre_date:
- pre_date -= 1
- date = datetime.strftime(last_day_of_last_month-timedelta(days=pre_date), '%Y-%m-%d')
- tikets = get_free_ticket(date, select_reception,user,positionId, doctorId)
- month_list[0][index] = {
- 'date': tikets[0],
- 'count_ticket' : tikets[1] ,
- 'ticket' : tikets[2],
- 'is_weekend' : True if index in [5,6] else False
- }
- index += 1
- index = 0
- """Первого дня следующего месяца"""
- last_index = last_day_of_week
- while last_index < DAYS_WEEK:
- date = datetime.strftime(last_day_of_month + timedelta(days=index), '%Y-%m-%d')
- tikets = get_free_ticket(date, select_reception,user,positionId, doctorId)
- month_list[-1][last_index] = {
- 'date': tikets[0],
- 'count_ticket' : tikets[1],
- 'ticket' : tikets[2],
- 'is_weekend' : True if index in [5,6] else False
- }
- last_index += 1
- index += 1
- """Формируем календарь с вложенными параметрами"""
- for week_num, weeks in enumerate(month_list):
- for index, value in enumerate(weeks):
- if first_day_of_week <= index and week_num < len(dict_days[index]):
- date = datetime.strftime(dict_days[index][week_num], '%Y-%m-%d')
- tikets = get_free_ticket(date, select_reception, user, positionId, doctorId)
- month_list[week_num][index] = {
- 'date': tikets[0],
- 'count_ticket' : tikets[1] ,
- 'ticket' : tikets[2],
- 'is_weekend' : True if index in [5,6] else False
- }
- if index < first_day_of_week and len(dict_days[index]) > week_num >= 0:
- date = datetime.strftime(dict_days[index][week_num], '%Y-%m-%d')
- tikets = get_free_ticket(date, select_reception, user, positionId, doctorId)
- month_list[week_num + 1][index] = {
- 'date': tikets[0],
- 'count_ticket' : tikets[1] ,
- 'ticket' : tikets[2],
- 'is_weekend' : True if index in [5,6] else False
- }
- """Удаление прошедшей недели"""
- if datetime.today().month == month:
- for element in range(len(month_list)):
- if element < len(month_list):
- for value in month_list[element]:
- if datetime.strftime(datetime.today(), '%Y-%m-%d') == value['date']:
- _slice_previous_week(element, month_list)
- break
- return (
- (first_day_of_month.strftime('%b').title(), year),
- month_list
- )
Add Comment
Please, Sign In to add comment