---
# System prepended metadata

title: Constrained Product availability for appointments

---

# Constrained Product availability for appointments

[TOC]

## Business Requirements:

### R1. SPs in certain time periods should be excluded from Housecall routine and be committed to stationary Service Center duties. In such case all services that this SP is able to provide are available.

### R2. In certain cases (Vaccination) service entries should be limited to only some products (subset of those SP is able to provide). This is likely not to be a very frequent case.

### R3. Booking acts as a container (and time frame) for Appointments.

### R4. Booking can be assigned to multiple ServiceProviders. We assume that if 3 SPs are on a booking, they are blocked for entire duration of the booking.

### R5. SlotCalculator should be able to produce timeslots (Appointments) from either of the two:
- ServiceCenterRules (as it is now)
- Bookings (used as a rule, you pass[time period, people_count, product, slot_duration, slot_interval])

### R6. Some functionalities of Vaccinations current implementation should be transplanted to Appointments, to make Appointment engine default solution. 
In particular, checkboxes should be dependant on the product


## Solution proposals:

### for R1:
We'd add a `service_center_id` column to `calendar_entries`
if is NULL <- calendar_entry is for housecalls
if not null <- calendar_entry is for stationary services (clinics)
we can ditch current relation ServiceCenters <> ServiceProviders. Outdated

### for R2:
We'd add a relation CalendarEntry many-to-many V2::Product
CalendarEntry has_many ProductCalEntryAssignments
CalendarEntry has_many V2::Products, throu**gh: ProductCalEntryAssignments
if **calendar_entry.products.count.zero?**
    in this CEntry all products that SP is able to
provide are available.else (calendar_entry.products.count.positive?)
    in this CEntry only those products are avaliable.
    
### for R3: 
- Booking has_many Appointments (hyphotesis). Appointment belongs_to Booking, optional: true

there's actually a pretty clear separation of concerns between the two models:

Bookings <- are important in terms of SP availability planning, business consequences to orders and sales, but do NOT answer to a question how (if a booking is for 4h and 100 ppl) to process all these patients

Appointments <- Have no direct impact or meaning to the Orders, LineItems, sales and what-not. They just answer the question, how to break down booking time and patients efficiently, so that 1 or several SPs tending them, could effectively provide services. Hence need of time slots.

### for R4:
Booking HABTM ServiceProviders (join table)

**we need some safeguards to make sure that the supply is guaranteed for every booking** [TDP]

R5. SlotCalculator should be able to produce timeslots (Appointments) from either of the two

### for R5:
SlotCalculator should either accept mode param and (booking | regular_params)
or maybe better: we should have a tiny abstraction layer on top of that :-) 

### for R6:
We create a new relation eg. CheckboxQuestion HABTM (many-to-many) with V2::Product. That way we'll define the checkbox questions on per-product basis. no more hardcoding stuff.


### Matching strategy 2.0 (Concept)

there are 2 modes of querying for Availability
- housecalls
- clinics

**if(mode=housecalls)**
    - we only pick calendar_entries.where(service_center_id: nil)
    - we ignore service_center_rules
    - we check against ongoing/booked appointments and bookings in the given scope
    - we apply coverage_maps/proximity/distance logic


**if(mode=clinics)**
    - we ignore coverage_maps/proximity logic
    - we apply service_center_rules
    - we check against ongoing/booked appointments and bookings in the given scope
    - we check for CalendarEntry<>ServiceCenterId assoc
    - we abandon V2::Product <> ServiceCenter assoc

**common for both modes:**
    - we first create a booking
    - then we create one or more underlying Appointment
    - we deduce product availability from CalendarEntries->ServiceProviders->V2::Products
    - we check for product list overrides in CalendarEntries<>V2::Product assoc.
    
## Big questions and doubts?

### Q1. On which levels to enforce/guard doctors availability? on Booking level or on Appointment level

#### arguments for booking level: easier
because it's how it is now.

#### arguments for appointment level: future-proof-ity? 
If, at some point we'd like to have to have time-ranged bookings, it's nice to have a booking of 3hrs, that'll really manifest itself as a 30min-long Appointment assigned for a booking, appointment which you can safely move around within that 3hrs range. Then, for ex. 1h prior it taking place you can move it (still within 3hrs), or reassign to some other SP (provided he's available)