RATE & CALENDAR API

Update Calendar Max Stay API

Technical documentation for the method that updates maximum stay values for room rate plans by date.

Description

This endpoint updates the maxStay value in the calendar for a specific room and rate plan. It receives roomId and ratePlanId as request parameters and a list of MaxStayData objects in the request body.

For every date received, the method checks whether RoomAvailability already exists. If it exists, it updates or creates the related RateRoomAvailability entry for the selected rate plan. If it does not exist, it creates both RoomAvailability and RateRoomAvailability records.

At the end, all changed entities are saved and the derived price recalculation logic is triggered for the selected rate plan.

Endpoint

POST /updateCalendarMaxStay

Parameters

Name Type Required Description
roomId Long Yes The ID of the room whose availability calendar must be updated.
ratePlanId Long Yes The ID of the rate plan that belongs to the room and whose maxStay must be updated.

Request

Request parameters: roomId and ratePlanId. Content-Type: application/json

Authorization: Bearer <token>

Field Type Description
roomId Long Room identifier
ratePlanId Long Rate plan identifier
date Date Date to update
maxStay Integer Maximum-stay value for that date
propertyName String Property name supplied in the payload
Request Body Example
POST /updateCalendarMaxStay?roomId=12&ratePlanId=4
[
{"date": "2026-03-10T00:00:00.000+00:00", "maxStay": 5, "propertyName": "Hotel Example"},
{"date": "2026-03-11T00:00:00.000+00:00", "maxStay": 7, "propertyName": "Hotel Example"}

Process

  • The method first checks whether maxStayDataList is null or empty.
  • If the list is empty, it sends an email about the Channel Manager problem and returns an error message.
  • It loads the room from the database using roomId.
  • If the room is not found, it sends a notification email and returns a room-not-found message.
  • It searches inside room.getRatePlans() for the rate plan with the given ratePlanId.
  • If the rate plan is not found, it returns a rate-plan-not-found message.
  • It converts all received dates into LocalDate values.
  • It loads existing RoomAvailability records for the room and those dates, including related rate data.
  • It builds a map by date so each calendar day can be processed efficiently.
  • For each MaxStayData entry, it updates the existing RateRoomAvailability maxStay value or creates a new RateRoomAvailability if missing.
  • If no RoomAvailability exists for that date, it creates a new RoomAvailability with default values and links a new RateRoomAvailability to it.
  • It saves all changed RoomAvailability records.
  • It saves all changed or newly created RateRoomAvailability records.
  • It triggers derivedPriceService.processRatePlanChange(ratePlanId, false).
  • It returns a success message when the operation completes.

Responses Returned

The method returns a plain String response. Depending on the situation, one of the following messages is returned:

Condition Returned Response
maxStayDataList is null or empty maxStay is received as empty list {roomId}
Room not found in database Room with ID: {roomId} not exist in db, check room id {roomId} in allbookers
Rate plan not found for the room Rate plan with ID: {ratePlanId} not found for room ID: {roomId}
Update completed successfully maxStay is successfully updated

Notes

  • The method is annotated with @Transactional, so all database changes are committed together.
  • The date conversion uses ZoneId.systemDefault(), which means results depend on the server time zone.
  • When a new RateRoomAvailability is created, price is initialized to 0.0.
  • When a new RoomAvailability is created, totalRooms and occupiedRooms are initialized to 0 and closed is set to false.
  • The derived price logic is triggered even though the main update here is maxStay, not direct price.