---
# System prepended metadata

title: RC+ czyli CrossSellopodobne dodatki do rezerwacji (zwane roboczo dalej CrossSellPlus)

---

- Transakcyjność D2D: 3MD
- 



# RC+ czyli CrossSellopodobne dodatki do rezerwacji (zwane roboczo dalej CrossSellPlus)

## Co to ma być?

R+ - dodatek (w stylu upselli) do rezerwacji D2D (tylko do takiej rezerwacji. Krzysiu popraw mnie jeśli się mylę).


## TODOs

RC+
- modele i relacje
    - ReservableExtra + STI
    - ^ - obsługa obrazków
    - ReservationReservableExtra
    - menu do ReservationReservableExtras
    - tagi do menu / Menuable :-) 
    - Rule
- serwisy
    - Wyliczanie możliwości dodania RC+'a' z Ruli (RC+ Rule Resolver czy coś)
    - Rekalkulacja kwoty rezerwacji z uwzględnieniem RC+
- końcówki (klient)
    - Q: getReservationPossibilities(reservationID!, date!, approxStartHour!, numPeople!, definitiveStartHour, reservationExtras: [{id: 1, quantity: 5}])
           ReservationAttempt {
           reservationPossible: bool     (definitiveStartHour?)
           hours : [{ hour: "HH:MM", available: bool }]
           availableReservationExtras: [
               - id
               - pic_url
               - title
               - desc: text
               - price: decimal
           ]

    - Q: reservableExtras(+filtry) (użyte do litingu doświadczeń)
    - Q: reservableExtra (szczegóły RC+ z menu)
    - M: createReservation oraz updateReservation(z RC+ami)
- końcówki (admin)
    - CRUD R+ (typ, menus+tagi, opis,temat,zdjęcia,...) na poziomie restauracji
    - CRUD Ruli do R+
    - dodanie RRE do typu rezerwacji
## Dostępność dodatków

Jego dostępność może być ograniczona kalendarzem (jeśli nie ma żadnych ruli to jest dostępny we wszystkich stolikach, jeśli ma swoje rule to są ważniejsze), posiada minimalna długość slotu która "rozpycha" rezerwację D2D - o ile jest miejsce w kalendarzu D2D.


1) ograniczona rulesami
2) lub jeśli nie ma ruli - nieograniczona (poprawcie jeśli się mylę))
3) plany śledzenia stanu magazynowego zarzucono (poprawcie jeśli się mylę)

> :cherries: Minimalna długość slotu nie jest cechą RC+ rula, ale samego RC+. Oznacza spodziewaną prędkość przeżuwania :-) Nazwijmy to tymczasowo `eating_duration` (w minutach, żeby pasowało do slotów). :cherries: no chyba, że ustalimy, że eating_duration jest cechą dania i ~~jest wyliczane z dań jakie znajdą się w RC+ie~~, ale to by pewnie komplikowało rezerwacje i "wydłużanie slotu", bo trzeba by to gdzieś keszować, bo zestaw dań w określonym RC+ie może zmieniać się w czasie.
> **nic nie wyliczamy, duration jest jeden na poziomie RC+ i tyle**
> [name=Janek][color=green]


### rozpychanie czasu rezerwacji RC+ :cherries::cherries::cherries::cherries:

załóżmy że ktoś rezerwuje D2D na 90 min

i dodaję RC+ o nazwie "Tuzin Burgerów (Sharing)". Tak się składa, że jest wyceniony na 120 min.

System powinien rozszerzyć rezerwację o różnicę 120-90 min, czyli o 30 min (90 + 30)

> :cherries: Na start w wersji v0 możemy przyjąć że każdy R+ będzie się mieścił w defaultowym slocie. Przygotować się na to na przyszłość.
> [name=Paweł][color=red]  

## Oczekiwane typy "dodatków":

- degustacja - zbudowana z dań, ma jedno menu (X dań w ramach menu) :cherries: Od tego zaczniemy. Reszta ma niższe prio.
- danie flagowe - raczej jedno danie (może więcej?), opis, cena
- shareing - na ile to jest osób, cena, dla ilu osób (+ od ilu osób go pokazujemy - żarłoki)
- menu lunchowe

> :cherries: Jak dla mnie z tego wynika że potrzebujemy dodać encję `Dish`, Danie, czy cokolwiek.
> Degustacja has many Dania i DanieFlagowe has_one Danie :-)
> Sharing być może też has_one Danie
> i Menu Lunchowe pewnie has_many Dania
> [name=Janek][color=green]

> Zdaje się że dania muszą należeć do restauracji - każda ma inne... 
> [name=Krzysiek][color=green] 

dania muszą posiadać tagi składników (ryba, mięso, krewetki)
Dochodzi cały moduł transakcyjności w D2D / anulacji i zwrotów (do ustalenia na jakich warunkach)
 
> :cherries: Jak dla mnie z tego wynika że potrzebujemy STI
> [name=Janek][color=green] 

> :cherries: Zastanawiam się czy czyściej / wygodniej nie było by tagować całego R+ a nie dań. To ma służyć do szukania R+ które zawierają dane skłądniki w całym zestawie. Nie widzę w tej chwili zysku nad tagowaniem poszczególnych dań - a tylko utrudnienie w dodawaniu nowy R+ gdzie przy 7-daniowym R+ trzeba będzie otagować aż 7 dań - gdzie składniki mogą się powtarzać
> [name=Paweł][color=red]  


```ruby
CrossSellPlus
    self.abstract_class = true
    
    has_many :cross_sell_plus_rules
    has_many :dishes # lub has_one :dish
    belongs_to :reservation # must be Daily
    has_many :dish_tags, through: :dishes, source :tag
end
```

```plantuml
@startuml

skinparam stereotypeCBackgroundColor<<Done>> Green

class ReservableExtra <<Done>>{
    + name
    + pictureUrls
    + type: string // STI sub class
    + restaurant <----
    + eating_duration: int // minutes
    + rules[]
    + price: decimal
    + show_as_upsell: bool //TBC urżnąć
}

class Reservation {}

note top of ReservationCrossSellPlus #0F0: zakodzone 
class ReservationCrossSellPlus {
    + reservation_id
    + cross_sell_plus_id
}

class Dish <<Done>> {
    + name
    + description
    + tags[]
}


note top of Dish #0F0: zakodzone 

class DishTag {
    + name
}
class ReservableExtraRule {
    + reservable_extra
}


note top of ReservableExtra : STI Ober-Class

Dish ||--|{ DishTag
Restaurant <|-- ReservableExtra




ReservableExtra ||--|{ ReservableExtraRule : RC+ has many rules

ReservableExtra }|--|{ Dish : HABTM

Reservation }|--|| ReservationCrossSellPlus
ReservableExtra }|--|| ReservationCrossSellPlus

package ReservableExtras <<Node>> {
    .ReservableExtra <|-- Degustation
    .ReservableExtra <|-- FlagshipDish
    .ReservableExtra <|-- ShareableDish : STI subclasses
    .ReservableExtra <|-- LunchMenu
}


@enduml
```




### Jak mogłaby wyglądać Rula, żeby nie było wielu zagnieżdżonych modeli Rule->WeekDay->HourRange (która to cecha mnie szczególnie wk...)


```plantuml
@startuml

class ReservableExtraRule {
    + cross_sell_plus -> FK
    + dows:char[7]
    + active:bool
    + starts_at:int
    + ends_at:int
    + date_from:date_with_zone
    + date_to:date_with_zone
}

@enduml
```

- char(7) na oznaczenie dni tygodnia np. '1110111' (wszystko oprócz czwartków), albo nawet to samo jako char(1) konwertowany na array bitów (mniej czytelne potem co prawda

- date_from i date_to mogłyby być nullable i wtedy rozumiemy, że rule trwa w nieskończoność (jeśli enabled)

A najlepiej wywalić daty w cholerę dopóki biznes tego nie zażąda. (niech operują enabled/disabled). Taniej będzie się to liczyło.
 
> :cherries: No nie wiem. Ogarniczenia R+ mają być tez po to żeby go np ogarniczyć w trakcie trwania festiwalu. Wynika z tego że daty by się "przydały" bo inaczej musisz wyłączyć ograniczyć R+ i potem pamiętać zeby to cofnąć
> [name=Paweł][color=red]  
 
## Brudnopis #ignore
#### O typach binarnych które pomogą z dows
https://www.postgresql.org/docs/9.0/datatype-binary.html
PG::TextDecoder::Bytea
PG::Connection.unescape_bytea(raw)

escape_bytea 

https://apidock.com/rails/v5.0.0.1/ActiveRecord/ConnectionAdapters/PostgreSQL/OID/Bytea/deserialize

https://stackoverflow.com/questions/53808048/postgres-sql-read-binary-value-from-string-field

ReservationExtras
postgres bit mask






## Końcówki

dodać obrazek do RC+


- listing doświadczeń (RC+) per region
                            globalny
                            per restauracja
czyli jeden endpoint
        filtrowanie:
            region
            restauracja
            typ
            paginacja  (zwracać connection)
            
            
Mutacja: dodaj doświadczenie do Rezerwacji

ReservationAttempt
    - reservation
    - permitted ReservationReservableExtras (RC+'s)
    
query: rc+ details
query: getReservationPossibilities(
            date!,
            approxStartHour!,
            numPeople!,
            definitiveStartHour,
            reservationExtrasIds)

    returns: ReservationAttempt:
               reservationPossible: bool     (definitiveStartHour?)
               hours : [{ hour: "HH:MM", available: bool }]
               availableReservationExtras: [
                   - id
                   - pic_url
                   - title
                   - desc: text
                   - price: decimal
               ]
               

## Spotkanie 10 lutego - ustalenia

- tagujemy R+y, nie Dania
- rezygnujemy na razie z "rozpychania" slotów
- rezygnujemy z Dish i modelujemy to jak Menu Festivalowe

1 R+ ma jedno menu, i to menu ma swoje tagi. A R+ sam z siebie nie ma tagów
  MenusTags

Muszą być rule - dać ilość sztuk/miejsc