# Pricing engine

The **pricing engine** is what turns the inputs you set — base rates, meal plans, markups, contracts, promotions, restrictions, currency rules, audience rules — into the final number a traveller sees and a partner receives. Same inputs, same output, every time. That predictability is the whole point.

## How calculation works

The pricing engine follows the same calculation path for the same inputs:

1. **The rate is reproducible.** Re-running the calculation with the same inputs returns the same number. No randomness, no time-dependent quirks beyond the date you are pricing.
2. **The rate is explainable.** For any quoted price, the engine can show *which* base rate, *which* meal plan adjustment, *which* markup, *which* promotion, *which* discount produced it.

When a partner or finance team asks "*how did we arrive at this rate*", the calculation chain shows the answer.

## The derivation chain

For a single cell — *property X, room Y, rate plan Z, date D, occupancy O* — the engine evaluates:

<figure><img src="/files/6X3W7Ord3QlHSxTe5AWZ" alt="Inputs flow through the derivation chain to produce the final rate"><figcaption><p>You set the inputs at each step; the engine combines them deterministically.</p></figcaption></figure>

You set inputs at each step; the engine combines them. Change any input — a new contract markup, a new promotion, a new minimum selling price — and the final rate at every affected cell updates.

For derived rate plans (children of another rate plan), Step 1 reads the parent's base and applies the relation offset (percentage or fixed amount). Derivation chains can be **up to 5 levels deep**. See [Rate plans → Derived rate plans](/console/pricing-and-availability/rate-plans.md).

## MSP (Minimum Selling Price)

Some contracts and partner agreements come with an **MSP** (Minimum Selling Price) — a floor below which the rate cannot drop. If your computed final rate falls below it, the engine clamps up to the floor; the booking lands and your contract is not violated. Common reasons:

* **Supplier contract** — the supplier mandates that their inventory cannot surface below a certain price (rate parity, brand protection).
* **Parity rule** — the operator's own commitment that public retail will not undercut a specific channel.
* **Manual override** — a finance or pricing-team decision for a specific period.

When the engine computes a final rate that falls below the MSP, it does not reject the booking — it **clamps the rate up to the floor**. The booking lands; the traveller sees the floor price; the pricing view shows that the floor was applied and where it came from.

### Where MSP applies

MSP is set at two levels:

* **On the rate plan** — the default floor for every booking against that rate plan.
* **On a per-channel exposure** — a tighter floor for a specific outbound channel (a B2B partner may require a higher floor than retail, for example).

When both apply, the higher of the two wins. The pricing explanation shows which value was used and why.

### When MSP affects a booking

The flow:

1. The engine computes the final rate through promotions, markup, and audience adjustments.
2. If the result is below the applicable MSP, the rate is clamped up to the floor.
3. The cell history records: the original computed rate, the floor that applied, the source of the floor, the clamped result.
4. The traveller sees the clamped rate; the booking proceeds normally.

This is what makes B2B distribution under supplier-mandated price floors operationally clean — the engine handles the floor automatically; you do not have to maintain parallel rate plans for "above MSP" and "would have been below MSP" cases.

## Net rate vs. commission

Two pricing models coexist depending on the contract type:

* **Net rate + markup.** The contract gives you a net rate; you add your markup; the traveller pays gross. Common with bedbank suppliers and some direct properties.
* **Commission on gross.** The contract publishes a gross rate; you take a commission off the top. Common with hotel-direct contracts and some channel agreements.

The engine reads the contract type and applies the correct model automatically. You do not pick per-booking; the contract does.

## Multi-currency

Three currency contexts coexist on a single booking:

* **Display** — what the operator sees in the console.
* **Contract** — the currency the supplier contract is in.
* **Settlement** — the currency a payment is settled in.

The engine handles conversions at each step, using a configurable rate source. Each conversion is recorded so the chain stays explainable — *EUR 180 base, contract in USD, FX rate from source X applied on date D*.

## The same rate everywhere

Adrasis's pricing engine is the source of truth, and it gives the same answer regardless of where the calculation surfaces — the operator console, an outbound feed, an inbound matching path. The number a traveller sees on a metasearch result is the same number you see on the rate calendar.

## What the engine does not do

The engine deliberately does *not*:

* **Decide what to show.** That is a distribution concern (per-channel exposure).
* **Hold business state.** It reads from canonical state; it does not modify it.
* **Route bookings.** Booking creation is a separate domain; the engine produces the rate, the booking flow uses it.
* **Manage availability.** Inventory checks are part of the same composite "can we sell this" question, but the inventory math is not the engine's job.

The engine is narrow on purpose. It calculates prices; policy is configured around it.

## Reviewing a derived rate

For every cell on the rate calendar you can:

* Open the **rate explanation** — the full chain that produced the displayed number.
* See **which contract version** was active for the date.
* See **which promotion(s)** layered on, in what order.
* See **the FX rates** used (if currency conversion was applied).
* Trace back **the operator action** that last touched any input.

This is how a "*why is this number what it is*" question becomes a quick product answer instead of a manual investigation.

## How Adragent uses the engine

When you ask Adragent to quote a rate or apply a promotion:

1. The agent reads the same canonical inputs the engine reads.
2. The preview shows you the derived rate alongside the inputs that produce it.
3. On confirmation, the change to inputs (the new promotion, the new markup) goes through the engine's normal path.

You never get a quoted rate that the engine did not produce. Adragent does not have its own pricing logic.

## Where to next

* **The rate plans the engine reads from** → [Rate plans](/console/pricing-and-availability/rate-plans.md)
* **The promotions the engine layers** → [Promotions & discounts](/console/pricing-and-availability/promotions-and-discounts.md)
* **The restrictions the engine respects** → [Stop-sale & restrictions](/console/pricing-and-availability/stop-sale-restrictions.md)
* **The per-cell history that records every input change** → [Cell history](/console/pricing-and-availability/cell-history.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://adrasis.gitbook.io/console/pricing-and-availability/pricing-engine.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
