Пример #1
0
def create_slots(request):
    data = data_parse(
        request.body, {
            'slots': list,
            'sources': list,
            'duration': int,
            'date': str,
            'resource': int
        })
    slots: List[str] = data[0]
    sources: List[str] = data[1]
    duration: int = data[2]
    date: str = data[3]
    resource: int = data[4]
    date_start = f"{date} 00:00:00"
    date_end = f"{date} 23:59:59"

    has_rights = can_edit_resource(request, resource)
    if not has_rights:
        return status_response(False, 'У вас недостаточно прав')

    date_slots = get_date_slots(date_start, date_end, resource)
    remove_element = []
    for s in slots:
        start_end = s.split(" — ")
        a1 = try_strptime(f"{date} {start_end[0]}",
                          formats=('%Y-%m-%d %H:%M', ))
        a2 = try_strptime(f"{date} {start_end[1]}",
                          formats=('%Y-%m-%d %H:%M', ))
        for ds in date_slots:
            b1 = try_strptime(f"{date} {ds.start_slot}",
                              formats=('%Y-%m-%d %H:%M', ))
            b2 = try_strptime(f"{date} {ds.end_slot}",
                              formats=('%Y-%m-%d %H:%M', ))
            # проерка на не пересечение
            if not (a1 >= b2 or a2 <= b1):
                remove_element.append(s)
    for r in remove_element:
        slots.remove(r)

    with transaction.atomic():
        for s in slots:
            time = s.split(' ')[0]
            datetime_str = f"{date} {time}"
            dt = try_strptime(datetime_str, formats=('%Y-%m-%d %H:%M', ))
            end_date = dt + relativedelta(minutes=duration)
            SlotPlan.objects.create(
                resource_id=resource,
                datetime=dt,
                datetime_end=end_date,
                duration_minutes=duration,
                available_systems=sources,
            )

    return status_response(True)
Пример #2
0
def get_available_slots_of_dates(research_pk,
                                 date_start,
                                 date_end,
                                 allow_cito=False):
    d1 = try_strptime(f"{date_start}", formats=('%Y-%m-%d', ))
    d2 = try_strptime(f"{date_end}", formats=('%Y-%m-%d', ))
    current_date = try_strptime(current_time().strftime("%Y-%m-%d"),
                                formats=('%Y-%m-%d', ))
    start_date = datetime.datetime.combine(d1, datetime.time.min)
    end_date = datetime.datetime.combine(d2, datetime.time.max)

    if end_date < datetime.datetime.combine(current_date, datetime.time.max):
        return {}

    if start_date < datetime.datetime.combine(current_date, datetime.time.min):
        start_date = datetime.datetime.combine(
            current_date, datetime.time.min) + datetime.timedelta(days=1)

    if allow_cito:
        data = {}
        date_i = start_date - datetime.timedelta(
            days=1)  # ЦИТО можно записать на сегодня
        while date_i < end_date:
            date_s = date_i.strftime("%Y-%m-%d")
            data[date_s] = True
            date_i += datetime.timedelta(days=1)
        return data

    resource_hosp = get_hospital_resource_by_research(research_pk)
    structure_resource = {
        rh.scheduleresource_id: rh.resource_title
        for rh in resource_hosp
    }

    resource_tuple = tuple(structure_resource.keys())
    slot_plans = get_date_slots_for_many_resource(start_date, end_date,
                                                  resource_tuple)
    slot_plan_pks = tuple([slplan.slot_id for slplan in slot_plans])
    slot_plan_busy_slot_fact = get_slot_fact(slot_plan_pks)
    slot_plan_busy_slot_fact = [i.plan_id for i in slot_plan_busy_slot_fact]
    data = {}

    for slotplan in slot_plans:
        if slotplan.slot_id in slot_plan_busy_slot_fact or slotplan.date_char in data:
            continue
        data[slotplan.date_char] = True

    return data
Пример #3
0
def check_available_hospital_slot_before_save(research_pk, resource_id, date):
    if not research_pk or not date:
        return False
    d = try_strptime(f"{date}", formats=('%Y-%m-%d', ))
    start_date = datetime.datetime.combine(d, datetime.time.min)
    end_date = datetime.datetime.combine(d, datetime.time.max)
    if resource_id is None:
        resource_id = tuple(
            ScheduleResource.objects.filter(
                service__in=[research_pk]).values_list('pk', flat=True))
    elif isinstance(resource_id, tuple):
        resource_id = resource_id
    elif isinstance(resource_id, list):
        resource_id = tuple(resource_id)
    else:
        resource_id = tuple([resource_id])

    if not resource_id:
        return False

    result_slot = get_slot_plan_by_hosp_resource(start_date, end_date,
                                                 resource_id)
    date_slots = [i.hhmm_char for i in result_slot]
    current_plan_count = PlanHospitalization.objects.filter(
        exec_at__range=(start_date, end_date),
        work_status=0,
        action=0,
        research_id=research_pk).order_by("exec_at").count()
    return len(date_slots) > current_plan_count
Пример #4
0
def save(request):
    data = data_parse(
        request.body,
        {
            'id': int,
            'cardId': int,
            'status': str,
            'planId': int,
            'serviceId': int,
            'date': str,
            'resource': str
        },
        {
            'planId': None,
            'cardId': None,
            'serviceId': None,
            'status': 'reserved',
            'date': None,
            'resource': None
        },
    )
    pk: int = data[0]
    card_pk: int = data[1]
    status: str = data[2]
    plan_id: int = data[3]
    service_id: int = data[4]
    date: str = data[5]
    resource: int = data[6]

    if not card_pk:
        return status_response(False, 'Пациен не выбран')

    is_cito = False

    if has_group(
            request.user,
            'Цито-запись в расписании') and pk == -10 and date and resource:
        d = try_strptime(f"{date}", formats=('%Y-%m-%d', ))
        start_date = datetime.datetime.combine(d, datetime.time.min)
        end_date = datetime.datetime.combine(d, datetime.time.max)
        slots = SlotPlan.objects.filter(datetime__range=(start_date, end_date))
        free_slot: SlotPlan = slots.filter(
            slotfact__isnull=True).order_by('datetime').first()
        if not free_slot:
            last_any_slot: SlotPlan = slots.order_by('-datetime').first()
            if last_any_slot:
                next_time = last_any_slot.datetime + datetime.timedelta(
                    minutes=last_any_slot.duration_minutes)
                duration = last_any_slot.duration_minutes
            else:
                next_time = try_strptime(f"{date} 08:00",
                                         formats=('%Y-%m-%d %H:%M', ))
                duration = 3
            end_time = next_time + datetime.timedelta(minutes=duration)
            new_slot_plan = SlotPlan.objects.create(
                resource_id=resource,
                datetime=next_time,
                datetime_end=end_time,
                duration_minutes=duration,
                available_systems=[SlotPlan.LOCAL],
                disabled=False,
                is_cito=True,
            )
            pk = new_slot_plan.pk
        else:
            pk = free_slot.pk
        is_cito = True

    s: SlotPlan = SlotPlan.objects.filter(pk=pk).first()

    if s:
        status = {
            'reserved': 0,
            'cancelled': 1,
            'success': 2,
        }.get(status, 0)
        slot_fact: SlotFact = SlotFact.objects.filter(
            plan=s).order_by('-pk').first()

        if not slot_fact:
            slot_fact = SlotFact.objects.create(plan=s, status=status)

        slot_fact.patient_id = card_pk
        slot_fact.status = status
        slot_fact.service_id = service_id
        slot_fact.is_cito = is_cito
        slot_fact.save()
        if plan_id:
            ph: PlanHospitalization = PlanHospitalization.objects.get(
                pk=plan_id)
            ph.slot_fact = slot_fact
            ph.work_status = 3
            ph.exec_at = s.datetime
            ph.save()
        return status_response(True)

    return status_response(False, 'Слот не найден')
Пример #5
0
def get_available_hospital_plans(research_pk,
                                 resource_id=None,
                                 date_start=None,
                                 date_end=None):
    if date_start and date_end:
        d1 = try_strptime(f"{date_start}", formats=('%Y-%m-%d', ))
        d2 = try_strptime(f"{date_end}", formats=('%Y-%m-%d', ))
    else:
        d1 = current_time(only_date=True) + relativedelta(days=1)
        d2 = d1 + relativedelta(days=FORWARD_DAYS_SCHEDULE)

    if resource_id is None:
        resource_id = tuple(
            ScheduleResource.objects.filter(
                service__in=[research_pk]).values_list('pk', flat=True))
    elif isinstance(resource_id, tuple):
        resource_id = resource_id
    elif isinstance(resource_id, list):
        resource_id = tuple(resource_id)
    else:
        resource_id = tuple([resource_id])

    if not resource_id:
        return {}, {}

    counts = {}

    start_date = datetime.datetime.combine(d1, datetime.time.min)
    end_date = datetime.datetime.combine(d2, datetime.time.max)
    result_slot = get_slot_plan_by_hosp_resource(start_date, end_date,
                                                 resource_id)
    date_slots = {}
    for rslots in result_slot:
        if not date_slots.get(rslots.date_char, None):
            date_slots[rslots.date_char] = [rslots.datetime]
        else:
            temp_date_slots = date_slots.get(rslots.date_char, None)
            temp_date_slots.append(rslots.datetime)
            date_slots[rslots.date_char] = temp_date_slots.copy()
    date_available_status = {}

    date_i = start_date - datetime.timedelta(
        days=1)  # ЦИТО можно записать на сегодня
    while date_i < end_date:
        date_s = date_i.strftime("%Y-%m-%d")
        date_available_status[date_s] = False
        date_i += datetime.timedelta(days=1)

    for current_date, slots_in_date in date_slots.items():
        d1 = try_strptime(current_date, formats=('%Y-%m-%d', ))
        start_date = datetime.datetime.combine(d1, datetime.time.min)
        end_date = datetime.datetime.combine(d1, datetime.time.max)
        current_plan_count = (PlanHospitalization.objects.filter(
            exec_at__range=(start_date, end_date),
            work_status__in=[0, 1, 3],
            action=0,
            research_id=research_pk).order_by("exec_at").count())
        counts[current_date] = {
            "available": len(slots_in_date),
            "used": current_plan_count,
        }
        date_available_status[current_date] = counts[current_date][
            "available"] > counts[current_date]["used"]

    return date_available_status, counts
Пример #6
0
def get_available_hospital_resource_slot(research_pk,
                                         date_start,
                                         date_end,
                                         allow_cito=False):
    d1 = try_strptime(f"{date_start}", formats=('%Y-%m-%d', ))
    d2 = try_strptime(f"{date_end}", formats=('%Y-%m-%d', ))
    start_date = datetime.datetime.combine(d1, datetime.time.min)
    end_date = datetime.datetime.combine(d2, datetime.time.max)
    result = {"dates": {}}

    if end_date < datetime.datetime.combine(
            try_strptime(current_time().strftime("%Y-%m-%d"),
                         formats=('%Y-%m-%d', )), datetime.time.max):
        return result

    resource_hosp = get_hospital_resource_by_research(research_pk)
    structure_resource = {
        rh.scheduleresource_id: rh.resource_title
        for rh in resource_hosp
    }

    resource_tuple = tuple(structure_resource.keys())
    slot_plans = get_date_slots_for_many_resource(start_date, end_date,
                                                  resource_tuple)
    slot_plan_pks = tuple([slplan.slot_id for slplan in slot_plans])
    slot_plan_busy_slot_fact = get_slot_fact(slot_plan_pks)
    slot_plan_busy_slot_fact = [i.plan_id for i in slot_plan_busy_slot_fact]
    data = result["dates"]
    dates = set([slotplan.date_char for slotplan in slot_plans])
    for d in dates:
        data[d] = []

    temp_data_slot_resource = {}
    for slotplan in slot_plans:
        if slotplan.slot_id in slot_plan_busy_slot_fact:
            continue
        if not temp_data_slot_resource.get(slotplan.resource_id):
            temp_data_slot_resource[slotplan.resource_id] = {
                slotplan.date_char: [{
                    "pk":
                    slotplan.slot_id,
                    "title":
                    f"{slotplan.start_slot} - {slotplan.end_slot}"
                }]
            }
        else:
            temp_slot_resource_date = temp_data_slot_resource.get(
                slotplan.resource_id, None)
            if not temp_slot_resource_date.get(slotplan.date_char):
                temp_slot_resource_date[slotplan.date_char] = [{
                    "pk":
                    slotplan.slot_id,
                    "title":
                    f"{slotplan.start_slot} - {slotplan.end_slot}"
                }]
            else:
                temp_slot_resource_data = temp_slot_resource_date.get(
                    slotplan.date_char)
                temp_slot_resource_data.append({
                    "pk":
                    slotplan.slot_id,
                    "title":
                    f"{slotplan.start_slot} - {slotplan.end_slot}"
                })
                temp_slot_resource_date[
                    slotplan.date_char] = temp_slot_resource_data.copy()
            temp_data_slot_resource[
                slotplan.resource_id] = temp_slot_resource_date.copy()

    for k, v in temp_data_slot_resource.items():
        for date, slots in v.items():
            temp_data = data.get(date)
            temp_data.append({
                "resourcePk": k,
                "resourceTitle": structure_resource.get(k, ""),
                "slots": slots
            })
            data[date] = temp_data.copy()

    if allow_cito:
        dates = []
        date_i = start_date
        while date_i < end_date:
            date = date_i.strftime("%Y-%m-%d")
            if date not in data:
                data[date] = []
            has_resources = {x['resourcePk']: x for x in data[date]}
            for rpk in resource_tuple:
                if rpk in has_resources:
                    has_resources[rpk]['slots'].append({
                        "pk": -10,
                        "title": "CITO"
                    })
                    continue
                temp_data = {
                    "resourcePk": rpk,
                    "resourceTitle": structure_resource.get(rpk, ""),
                    "slots": [{
                        "pk": -10,
                        "title": "CITO"
                    }]
                }
                data[date].append(temp_data)

            date_i += datetime.timedelta(days=1)
    return result