################################################################### Suggested workflows and examples for automated self-service devices ################################################################### ************************* Basic supported workflow: ************************* Checkin: ======== 1. Find correct reservation 2. Select proper room 3. Display price 4. Collect information from guest 5. Optionally charge guest in advance 6. Checkin guest Checkout: ========= 1. Check and display account ballance 2. If needed, charge guest for non-zero account ballance 3. Checkout guest **************** Request examples **************** Reservations ============ To find and display reservation information, use :: { gsetReservation(reservation_number: 8866) { id name total_price total_prepayments accommodation_currency { code } prepayments { receipt_items { price } } reservation_rows { id check_in_date check_out_date guests { id checked_in room_id room { code } } } } } Currently you can filter only by **reservation-number**, if needed, filter by other unique parameters can be added. **Total_price** is price for whole reservation - all rooms. **Total_prepayments** is summ already prepayed (you can check individual prepayments in **"prepayments"** section. **Accommodation_currency** is currency used for those total summs. In **reservation_rows** you will find detailed information about checkin/checkout dates, room-types, room and guest-counts etc. You will find guest-cards and assign room-numbers in **"guests"** list. You can create new prepayment like this:: mutation { createUpdateReservation(reservation: { id: 8866, prepayments: [ { note: "any note", receipt_items: [ { price: "20.00", payment_method_id: 1, currency_id: 1, raster_id: 32, vat: "21.0", vat_price: "4.00", default_currency_price: "20.00" }] }] }) { ok reservation { total_prepayments } } } Such payment will be written to cass-office in HORES. You need to specify correct prepayment **raster_id**, **payment_method_id**, **vat** and **vat_price** yourself now, it will not be calculated or selected automatically. It's up to HOTEL which payment_method and raster they want to use, there may be multiple prepayment rasters and credit-card payment methods in some cases. You need to use proper **raster_id** - it must be one of the rasters with **Raster.variant = 2** (prepayment) and corresponding **vat** (Raster.vat). **default_currency_price** is price converted to default currency (CZK in case of Dalimil) **vat_price** is VAT computed from default_currency_price and vat. Check-in ======== Initial checkin (when no room from reservation is checked-in yet) is done with **checkIn()** mutation:: mutation { checkIn(reservation_number: 8866, current_rooms: [ { room_id: 114 current_guests: [ { reservation_id: 10420 reservation_guests_id: 20905 profile: { last_name: "Novák" } }, { reservation_id: 10420 reservation_guests_id: 20906 profile: { last_name: "Nováková" } } ] } ]) { ok } } Here you need to specify **reservation number** and list of **current_rooms**, where each represents one room to check in. For each **current_room** you need to specify **room_id** (ID of physical room to use) and list of **current_guests**. Note that there is no direct link between **current_room** and reservation - link is between reservation and **current_guests**. For that reason you need to specify correct **reservation_id** (ID of reservation_row) for each checked-in current_guest. If guest is from pre-filled reservation informations, you need to properly specify **reservation_guest_id** which links to **reservation_guest.id** from reservation. This link specify which reservation-guest corresponds to which current_guest and also mark proper **reservation_guest.checked_in** flag as true. Detailed information about each guest is specified inside **"profile"** fields. If you want to use existing profile, do not forget to include **profile.id**. If anything goes wrong, you can undo checkin of given room with **cancelCheckIn()**:: mutation { cancelCheckIn(current_room_id: 5566) { ok } } This mutation should not be used as part of regular workflow, only to handle possible error/inconsistant states if you cannot finish checkin process for some reason but you already called checkIn() mutation. Only room with no payed accounts can be canceled. Cancelation must happen same day as checkin. When canceled, all unpayed account items are also deleted. Cancel cannot be undone, all related database records for given current-room, current-guests, current-account and current-guest-group (in case of all rooms from group are canceled) are deleted. Room-mate checkin ================= When reservation is already (partially) checked-in and you need to add guest to existing room, you cannot use **checkIn()** mutation, you need to use **createUpdateCurrentRooms()** instead:: mutation { createUpdateCurrentRooms(current_rooms: { id: 21815 current_guests: [ { id: 40915 profile: { id: 73678 last_name: "Kozhevnikova/Egor Aleksin" first_name: "Alisa x" } }, { reservation_id: 26937 group_id: 17968 check_out_date: "2019-09-28" profile: { last_name: "Test Two" } } ] }) { ok } } posibilities: **CurrentGuestInput.id** is set: = modify existing checked-in guest else: create (checkin) new guest to room **ProfileInput.id** is set: = modify existing guest record else: = create new guest record **CurrentGuestInput.reservation_id** is set: = created checked-in guest will be linked to that reservation and subtracted from reserved guest-count **CurrentGuestInput.reservation_guest_id** is set and **.reservation_id** is set: = created checked-in guest will be linked to specific guest from reservation prepared guests-list Note that when creating new current_guest, you need to specify **group_id** = link to existing CurrentGuestGroup record, see bellow. To check if reservation is already (partially) checked-in and what rooms/guests, use **listCurrentRooms()** with reservation_id filter:: { listCurrentRooms(reservation_id: 6253, room_id: 32) { items { id room_id current_guests { reservation_id master } } } } You can get **CurrentRoom** for reservation and room_id if exists (is already checked-in). Note that **reservation_id** is **Reservation.ReservationRow.id**, not reservation number. **room_id** is internal Room.id, not room-number. second method for convenience is standard getCurrentRoom(id=xy) to get info about particular CurrentRoom record (you will find for example CurrentGuest.current_room_id for which this method would be usefull, because there is no direct link to query CurrentGuest.CurrentRoom to avoid circular queries. To get CurrentGuestGroup for given reservation (if already checked-in), use **getCurrentGuestGroup()** with reservation_number filter:: { getCurrentGuestGroup(reservation_number: 5688) { id name } } If no group for that reservation-number is found, reservation is not checked-in Check-out ========= Use **listAccountItems()** to list items on given guest/group account. Default filter lists only valid unpayed items:: { listAccountItems(current_account_id: 6933) { id price currency { id } } } If there are any, you can create new bill with **createAccountPayment()** method:: mutation { createAccountPayment(account: { current_account_id: 6933 }, account_items: [ {id: 109847}, {id: 109846}, {id: 109842}, {id: 109841} ], account_payments: [ { payment_method_id: 1 price: "980.00" currency_id: 1 } ]) { ok account { number } } } You need to specify **current_account_id**, list of **account_items** to put on this receipt and **account_payment**. Currently there is no option to specify different than current exchange-rate (see **listCurrencies**), so if your payment currency and account-items currencies does not match, you need to convert values via this exchange rate to calculate right ammount for guest to pay. When ready, you can checkout room with **checkOutRoom()** mutation (there is single current_room_id parameter):: mutation { checkOutRoom(current_room_id: 5455) { ok } }