Mochinov

Untitled

Aug 24th, 2021 (edited)
506
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.01 KB | None | 0 0
  1. import calendar
  2. from dateutil import rrule
  3. from datetime import datetime, timedelta
  4. from collections import defaultdict
  5. from datetime import datetime
  6. from django.contrib.auth.models import User
  7. from .models import (Account, Doctor, Ticket, DoctorOfftime, Appointments,
  8.                     Personal_Workchedule, DoctorMedicalPositions, MedicalPositions)
  9. # from pprint import pprint
  10.  
  11. def exclude_projected_tiket(date: datetime, timeTiket) -> list:
  12.     """Исключаю зарезервированное время из сгенерированного списка исходя по времени по опредедённому приёму"""
  13.     free_tiket = []
  14.     appointments = Appointments.objects.filter(
  15.         appointment_date = date
  16.     )
  17.     for ticket in timeTiket:
  18.         for index, time in enumerate(ticket):
  19.             time_current_doctor = [time.appointment_time for time in  appointments.filter(doctor__id  = time[1])]
  20.             ticketTime = datetime.strptime(str(time[0]), "%H:%M:%S").time()
  21.             if ticketTime in time_current_doctor:
  22.                 del time
  23.             else:
  24.                 free_tiket.append([str(ticketTime), time[1]])
  25.     return free_tiket
  26.  
  27.  
  28. _slice_previous_week = lambda index_week, month : [month.pop(0) for index in range(len(month)) if index < index_week]
  29. def get_free_ticket(date: datetime, select_reception: str, user: int, positionId: int,  doctor: list = []) -> list:
  30.     # Проверяю передан ли конкретный врач
  31.     if doctor:
  32.         listDoctor = [doctor]
  33.     else:
  34.         if positionId: # Формирую список врачей (их id) если конкретный доктор не выбран , получаю их по выбранной специализации
  35.                         # и проверяю их выходные дни
  36.             _check_doctorOfftime = lambda id: not DoctorOfftime.objects.filter(doctor__id = id, start_date__gte = date, end_date__lte = date).exists()
  37.             listDoctor = list(filter( _check_doctorOfftime ,
  38.             [positions.doctor.id for positions in DoctorMedicalPositions.objects.filter(
  39.                 polyclinic__id = Account.objects.get(user = user).polyclinic.id,
  40.                 position__id = positionId,
  41.             )]))
  42.         else:
  43.             listDoctor = []
  44.  
  45.     list_talons = []
  46.     workchedule =  Personal_Workchedule.objects.filter(doctor__id__in = listDoctor, date = datetime.strptime(date, '%Y-%m-%d'))
  47.     """Получаю рабочий график на {date} число"""
  48.     ticket = []
  49.     for chedule in workchedule:
  50.         interval = timedelta(minutes=int(chedule.count_of_minute_on_one_see))
  51.        
  52.         if select_reception == 'OMS':
  53.             time_start = timedelta(hours=chedule.OMS_start_time.hour, minutes=chedule.OMS_start_time.minute, seconds=0)
  54.             time_end = timedelta(hours=chedule.OMS_end_time.hour, minutes=chedule.OMS_end_time.minute, seconds=0)
  55.             """Расчитываю временной диапозон по времени от начала до конца приёма по ОМС с {interval} периодом"""
  56.             ticket.append([(str(time[0]), chedule.doctor.id) for time in Personal_Workchedule.calculation_of_coupons(time_start, time_end, interval)])
  57.  
  58.         if select_reception == 'DMS':
  59.  
  60.             time_start = timedelta(hours=chedule.DMS_start_time.hour, minutes=chedule.DMS_start_time.minute, seconds=0)
  61.             time_end = timedelta(hours=chedule.DMS_end_time.hour, minutes=chedule.DMS_end_time.minute, seconds=0)
  62.             """Расчитываю временной диапозон по времени от начала до конца приёма по ДМС с {interval} периодом"""
  63.             ticket.append([(str(time[0]), chedule.doctor.id) for time in Personal_Workchedule.calculation_of_coupons(time_start, time_end, interval)])
  64.  
  65.         if select_reception == 'PAYED':
  66.             time_start = timedelta(hours=chedule.other_start_time.hour, minutes=chedule.other_start_time.minute, seconds=0)
  67.             time_end = timedelta(hours=chedule.other_end_time.hour, minutes=chedule.other_end_time.minute, seconds=0)
  68.             """Расчитываю временной диапозон по времени от начала до конца приёма по ДРУГИМ ВОПРОСАМ с {interval} периодом"""
  69.             ticket.append([(str(time[0]), chedule.doctor.id) for time in Personal_Workchedule.calculation_of_coupons(time_start, time_end, interval)])
  70.  
  71.     free_ticket = exclude_projected_tiket(date, ticket)
  72.     """Исключаю забронированное время из расчитанного динамическим путём"""
  73.  
  74.     """Сортирую полученный список по ключ время и значением список врачей по которым он принемает если врачей несколько"""
  75.     for ticket in free_ticket:
  76.         ticketTime = ticket[0]
  77.         if list_talons:
  78.             for value in list_talons:
  79.                 if ticketTime in value:
  80.                     value[ticketTime].append((ticket[1]))
  81.                 else:
  82.                     value[ticketTime] = [(ticket[1])]
  83.         else:
  84.             list_talons.append({ticket[0] : [ticket[1]]})
  85.  
  86.     if list_talons:
  87.         countTicket = len(list_talons[0])
  88.     else: countTicket = len(list_talons)
  89.     return (date, countTicket, list_talons)
  90.  
  91. def generate_month(year: int, month: int, select_reception: str, user: id, positionId: id, doctorId: int = 0) -> tuple:
  92.  
  93.     """Первый день месяца"""
  94.     first_day_of_month = datetime(year, month, 1)
  95.  
  96.     """Последний день месяца"""
  97.     last_day_of_month = first_day_of_month.replace(day=calendar.monthrange(year, month)[1])
  98.  
  99.     """Сгенерированные календарные дни"""
  100.     range_date = rrule.rrule(rrule.DAILY, dtstart=first_day_of_month, until=last_day_of_month)
  101.  
  102.     """Последний день предыдущего месяца"""
  103.     last_day_of_last_month = first_day_of_month - timedelta(days=1)
  104.  
  105.     """Кол-во недель в месяце"""
  106.     max_week = len(calendar.monthcalendar(year, month))
  107.  
  108.     """Кол-во дней в недели"""
  109.     DAYS_WEEK = 7
  110.  
  111.     dict_days = defaultdict(lambda: [])
  112.     for i in range(DAYS_WEEK):
  113.         for day in range_date:
  114.             if day.weekday() == i:
  115.                 dict_days[i].append(day)
  116.  
  117.     """Получаем индекс элемента с первым и последним числом"""
  118.     first_day_of_week = 0
  119.  
  120.     for index, value in dict_days.items():
  121.         for date in value:
  122.             if first_day_of_month.day == date.day:
  123.                 first_day_of_week = index
  124.             if last_day_of_month.day == date.day:
  125.                 last_day_of_week = index
  126.  
  127.     month_list = []  # Список с неделями
  128.     """Заполнием пустую матрицу"""
  129.     for i in range(max_week):
  130.         week = [0 for i in range(DAYS_WEEK)]
  131.         month_list.append(week)
  132.  
  133.     index = 0
  134.     """Индекс последнего дня предыдущего месяца"""
  135.     pre_date = first_day_of_week
  136.     while pre_date:
  137.         pre_date -= 1
  138.         date = datetime.strftime(last_day_of_last_month-timedelta(days=pre_date), '%Y-%m-%d')
  139.         tikets = get_free_ticket(date, select_reception,user,positionId, doctorId)
  140.         month_list[0][index] = {
  141.             'date': tikets[0],
  142.             'count_ticket' : tikets[1] ,
  143.             'ticket' : tikets[2],
  144.             'is_weekend' : True if index in [5,6] else False
  145.         }
  146.         index += 1
  147.  
  148.     index = 0
  149.     """Первого дня следующего месяца"""
  150.     last_index = last_day_of_week
  151.     while last_index < DAYS_WEEK:
  152.         date = datetime.strftime(last_day_of_month + timedelta(days=index), '%Y-%m-%d')
  153.         tikets = get_free_ticket(date, select_reception,user,positionId, doctorId)
  154.         month_list[-1][last_index] = {
  155.             'date': tikets[0],
  156.             'count_ticket' : tikets[1],
  157.             'ticket' : tikets[2],
  158.             'is_weekend' : True if index in [5,6] else False
  159.         }
  160.  
  161.         last_index += 1
  162.         index += 1
  163.  
  164.  
  165.     """Формируем календарь с вложенными параметрами"""
  166.     for week_num, weeks in enumerate(month_list):
  167.         for index, value in enumerate(weeks):
  168.             if first_day_of_week <= index and week_num < len(dict_days[index]):
  169.                 date = datetime.strftime(dict_days[index][week_num], '%Y-%m-%d')
  170.                 tikets = get_free_ticket(date,  select_reception, user, positionId, doctorId)
  171.                 month_list[week_num][index] =  {
  172.                     'date': tikets[0],
  173.                     'count_ticket' : tikets[1] ,
  174.                     'ticket' : tikets[2],
  175.                     'is_weekend' : True if index in [5,6] else False
  176.                 }
  177.  
  178.             if index < first_day_of_week and len(dict_days[index]) > week_num >= 0:
  179.                 date = datetime.strftime(dict_days[index][week_num], '%Y-%m-%d')
  180.                 tikets = get_free_ticket(date, select_reception, user, positionId, doctorId)
  181.                 month_list[week_num + 1][index] = {
  182.                     'date': tikets[0],
  183.                     'count_ticket' : tikets[1] ,
  184.                     'ticket' : tikets[2],
  185.                     'is_weekend' : True if index in [5,6] else False
  186.                 }
  187.  
  188.  
  189.  
  190.     """Удаление прошедшей недели"""
  191.     if datetime.today().month == month:
  192.         for element in range(len(month_list)):
  193.             if element < len(month_list):
  194.                 for value in month_list[element]:
  195.                     if datetime.strftime(datetime.today(), '%Y-%m-%d')  == value['date']:
  196.                         _slice_previous_week(element, month_list)
  197.                         break
  198.     return (
  199.         (first_day_of_month.strftime('%b').title(), year),
  200.         month_list
  201.     )
  202.  
Add Comment
Please, Sign In to add comment