> ## Documentation Index
> Fetch the complete documentation index at: https://www.twicecommerce.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Hintataulukko

> Hinnoittelurakenne, joka määrittää, miten listaus hinnoitellaan — vuokrahinnat keston mukaan, myyntihinnat ja kestotilaussuunnitelmat — mahdollisine päivämääräväleineen ja varianttikohtaisine ohituksineen.

<Frame caption="Katalogi > Hintataulukot">
  <img src="https://mintcdn.com/twicecommerce/Ab7tx7ih94KQsi0k/images/catalog-price-tables.webp?fit=max&auto=format&n=Ab7tx7ih94KQsi0k&q=85&s=7318ed02c5760ce47bbcfb6342cd995b" alt="Hintataulukot Adminissa" width="1920" height="1080" data-path="images/catalog-price-tables.webp" />
</Frame>

## Määritelmä

<Snippet file="definitions/fi/price-table-definition.mdx" />

<Info>
  **Vertaus:** Hintataulukko on hinnasto. Se kokoaa yhden myyntitavan — varauksen, myynnin tai kestotilauksen — kaikki hinnat yhdeksi muokattavaksi objektiksi, joka voidaan liittää yhteen listaukseen tai jakaa monelle.
</Info>

<Tip>
  **Erityistä TWICEssä:** Listaus ei koskaan tallenna hintakenttää suoraan. Kaikki hinnoittelu on hintataulukoissa. Listauksella voi olla yksi oletushintataulukko sekä mikä tahansa määrä päivämäärään sidottuja taulukoita kampanjoita, kausia tai kampanjahinnoittelua varten. Taulukon `availabilityRange` määrittää, **milloin sen rivit ovat ehdolla** — se ei anna taulukolle etusijaa. Laskentahetkellä kaikkien varaukselle aktiivisten taulukoiden rivit käsitellään yhdessä (katso kohta Hinnan ratkaisu).
</Tip>

## Missä sitä käytetään?

* **Vuokrahinnastot** — määritä `1 päivä 40 €`, `3 päivää 100 €`, `1 viikko 180 €` ja niin edelleen
* **Myyntihinnoittelu** — aseta listauksen suoramyyntihinta, halutessasi vertailuhinnan kanssa
* **Kestotilaussuunnitelmat** — määritä sitoutumisjakso, maksujakso ja automaattisen uusimisen rytmi
* **Kampanja- ja kausihinnoittelu** — liitä lisäksi päivämäärään sidottu hintataulukko, jonka rivit ovat ehdolla sen aikaikkunan sisällä (**halvempi** kampanjarivi valitaan oletuksen sijaan — katso kohta Hinnan ratkaisu)
* **Varianttikohtaiset ohitukset** — säädä kutakin hintariviä `rateMultiplier`-kertoimella tietyille varianttiarvoille
* **Massahinnoittelu** — ylläpidä yhtä jaettua taulukkoa ja liitä se moneen saman kategorian listaukseen

## Hintataulukon malli

API:n palauttama jaettu oletushintataulukko näyttää tältä:

```json theme={null}
{
  "id": "a1b2c3d4-e5f6-4789-a012-3456789abcde",
  "catalogItemId": null,
  "label": "Standard bike rates",
  "availabilityRange": null,
  "isDefault": true,
  "bookingsEnabled": true,
  "salesEnabled": true,
  "subscriptionsEnabled": false,
  "bookingPricingRows": [],
  "salesPricingRows": [],
  "subscriptionPricingRows": [],
  "variants": [],
  "isShared": true,
  "linkedCatalogItemsCount": 12,
  "createdAt": "2026-01-15T09:30:00Z"
}
```

`catalogItemId` on `null` jaetuissa taulukoissa, joita ei ole sidottu yhteen listaukseen, ja `availabilityRange` on `null` aina voimassa olevassa oletustaulukossa.

Yksi hintataulukko sisältää kolme toisistaan riippumatonta rivijoukkoa — varaus-, myynti- ja kestotilausrivit — joita ohjaavat `bookingsEnabled`, `salesEnabled` ja `subscriptionsEnabled`. Poista käytöstä ne tavat, joita et myy, jotta muokkausnäkymä pysyy selkeänä.

## Jaettu vs. itsenäinen

| Kenttä              | Merkitys                                                                                                                                                                                                                                                                                                                         |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `isShared = true`   | Taulukko sijaitsee kohdassa **Katalogi > Hintataulukot**, ja siihen voi linkittää monta listausta. `catalogItemId` on null                                                                                                                                                                                                       |
| `isShared = false`  | Itsenäinen taulukko, joka on olemassa vain yhdellä listauksella. `catalogItemId` on asetettu                                                                                                                                                                                                                                     |
| `isDefault = true`  | Merkitsee aina voimassa olevan taulukon (ei `availabilityRange`-arvoa), joten sen rivit ovat aina ehdokasjoukossa. `isDefault` määrittää myös, mikä taulukko on valmiiksi valittuna editorissa — se **ei** tee taulukosta voittajaa laskentahetkellä. Vain jaetut taulukot ilman `availabilityRange`-arvoa voivat olla oletuksia |
| `availabilityRange` | Aikaikkuna, jonka aikana taulukon rivit ovat **ehdolla**. `null` tarkoittaa aina ehdolla (sallittu vain oletustaulukolle). Se ohjaa ehdokkuutta, ei etusijaa                                                                                                                                                                     |

Linkitystä hallitaan omilla päätepisteillään (`link-catalog-item`, `unlink-catalog-items`), jotta listauksella on selkeä tieto siitä, mitkä jaetut taulukot siihen pätevät.

## Hintarivityypit

Hintataulukko sisältää kolme rivityyppiä, joista kukin ohjaa eri ostotapaa.

### Varaushintarivit

Käytetään, kun tilaus on vuokravaraus.

| Kenttä                              | Tyyppi                         | Kuvaus                                                                                                                                                                                                                                                               |
| ----------------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `label`                             | Merkkijono                     | Asiakkaalle näkyvä nimike (`Day`, `Weekend`, `Week`)                                                                                                                                                                                                                 |
| `timeUnit`                          | Enum                           | `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, `years`                                                                                                                                                                                                    |
| `timeUnitAmount`                    | Int > 0                        | Yksiköiden määrä, jonka tämä rivi hinnoittelee                                                                                                                                                                                                                       |
| `timeUnitPrice`                     | Int                            | Koko lohkon hinta pienimpinä yksikköinä (sentteinä)                                                                                                                                                                                                                  |
| `timeCalculation`                   | `standard` \| `cap_to_closing` | Miten riviä sovelletaan päivämäärävälillä. `cap_to_closing` lopettaa laskutuksen sulkemisaikaan                                                                                                                                                                      |
| `timeBasis`                         | `rolling` \| `capped`          | Miten kestoa lasketaan. `rolling` (oletus): ”päivä” on 24 kulunutta tuntia noudosta. `capped`: jokainen varauksen koskettama kalenterijakso on yksi laskutettava yksikkö — katso kohta Aloitettuihin jaksoihin perustuva hinnoittelu                                 |
| `counterTimeUnitPrice`              | Int \| null                    | Tämän rivin lohkon varahinta, jota käytetään varauksen osuuksiin, joita minkään rivin viikonpäivä-, kellonaika- tai päivämäärärajoitukset eivät kata. Kun useampi rivi tarjoaa varahinnan, halvin soveltuva voittaa. `null` tarkoittaa, ettei rivi tarjoa varahintaa |
| `additionalTimeUnitPrice`           | Int \| null                    | Hinta määritetyn lohkon ylittävälle ajalle                                                                                                                                                                                                                           |
| `additionalTimeUnitCalculationType` | `add` \| `multiply`            | Miten lisähinta kertyy                                                                                                                                                                                                                                               |
| `weekdays`                          | Int\[] (1–7) \| null           | Rajaa rivin tiettyihin viikonpäiviin                                                                                                                                                                                                                                 |
| `timeOfDayRange`                    | `{ start, end }` \| null       | Rajaa vuorokauden sisäiseen aikaikkunaan                                                                                                                                                                                                                             |
| `availabilityRange`                 | `{ start, end }` \| null       | Rajaa päivämäärävälille                                                                                                                                                                                                                                              |
| `isDynamicPricing`                  | Totuusarvo                     | Merkitsee rivin dynaamisen hinnoittelun ohjaamaksi kiinteän hinnan sijaan                                                                                                                                                                                            |
| `isHidden`                          | Totuusarvo                     | Säilytä rivi taulukossa mutta piilota se tuotesivulta                                                                                                                                                                                                                |
| `isEnabled`                         | Totuusarvo                     | Rivin pehmeä päälle/pois-kytkin                                                                                                                                                                                                                                      |

Kertoimeen perustuvassa hinnoittelussa moottori valitsee rivit, jotka kattavat varauksen keston parhaiten (katso kohta Hinnan ratkaisu). Tunti-, päivä- ja viikkorivien avulla yksi hintataulukko kattaa minkä tahansa keston järkevällä hinnalla.

### Myyntihintarivit

Käytetään suorissa myyntitilauksissa.

| Kenttä              | Tyyppi                   | Kuvaus                                       |
| ------------------- | ------------------------ | -------------------------------------------- |
| `price`             | Int ≥ 0                  | Myyntihinta pienimpinä yksikköinä            |
| `compareAtPrice`    | Int \| null              | Yliviivattu ”ennen”-hinta kampanjoita varten |
| `availabilityRange` | `{ start, end }` \| null | Päivämääräväli, jolla rivi on voimassa       |
| `isEnabled`         | Totuusarvo               | Pehmeä päälle/pois                           |

### Kestotilaushintarivit

Käytetään kestotilaustyyppisissä tilauksissa. Katso koko laskutuksen elinkaari kohdasta [Kestotilaukset](/docs/fi/concepts/catalog/subscriptions).

| Kenttä                                                    | Tyyppi                                   | Kuvaus                                                                                                                                  |
| --------------------------------------------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `label`                                                   | Merkkijono                               | Asiakkaalle näkyvä suunnitelman nimi (esimerkiksi ”Kuukausittain”, ”Vuosittain”)                                                        |
| `price`                                                   | Int > 0                                  | Jaksokohtainen hinta pienimpinä yksikköinä                                                                                              |
| `paymentCycleUnit` / `paymentCycleAmount`                 | Enum / Int                               | Laskutusrytmi. Yksikkö on `days`, `weeks`, `months` tai `years`                                                                         |
| `commitmentCycles`                                        | Int > 0                                  | Maksujaksojen määrä, joihin asiakas sitoutuu (enintään 24)                                                                              |
| `initialChargeType`                                       | `order_creation` \| `subscription_start` | Milloin ensimmäinen lasku erääntyy                                                                                                      |
| `renewalType`                                             | `none` \| `auto_renew`                   | Toiminta sitoutumisen päätyttyä                                                                                                         |
| `renewalPrice`                                            | Int \| null                              | Jaksokohtainen hinta sitoutumisen jälkeen (vain automaattisessa uusimisessa). Null tarkoittaa uusimista alkuperäisellä `price`-hinnalla |
| `collectionMethod`                                        | `charge_automatically` \| `send_invoice` | Miten maksu peritään. Oletus: `charge_automatically`                                                                                    |
| `cancellationLeadTimeUnit` / `cancellationLeadTimeAmount` | Enum / Int                               | Kuinka paljon etukäteen peruutus on pyydettävä                                                                                          |
| `availabilityRange`                                       | `{ start, end }` \| null                 | Päivämääräväli                                                                                                                          |
| `isEnabled`                                               | Totuusarvo                               | Pehmeä päälle/pois                                                                                                                      |

## Varianttikohtainen hinnoittelu

Jos listauksella on variantteja, hintataulukossa voi olla vapaaehtoinen `variants`-taulukko `CatalogItemVariantPricingTable`-merkintöjä. Kukin merkintä sitoo `variantName`-arvon ja yhden tai useamman `values`-arvon `rateMultiplier`-kertoimeen sekä rivikohtaisiin kertoimiin varaus-, myynti- ja kestotilausriveille.

`CatalogItemVariantPricingTable`-merkinnässä on seuraavat kentät:

| Kenttä           | Tyyppi                      | Kuvaus                                               |
| ---------------- | --------------------------- | ---------------------------------------------------- |
| `id`             | UUID                        | Palvelimen luoma tunniste                            |
| `variantName`    | Merkkijono                  | Varianttiulottuvuus, johon ohitus kohdistuu          |
| `values`         | `CatalogItemVariantValue[]` | Varianttiarvot, joita ohitus koskee                  |
| `booking`        | Taulukko                    | Rivikohtaiset varauskertoimet                        |
| `sales`          | Taulukko                    | Rivikohtaiset myyntikertoimet                        |
| `subscription`   | Taulukko                    | Rivikohtaiset kestotilauskertoimet                   |
| `rateMultiplier` | Luku                        | Taulukkotason kerroin, jota sovelletaan yhdistelmään |
| `pricingTableId` | UUID                        | Hintataulukko, johon ohitus kuuluu                   |

Kukin rivikohtainen ohitus viittaa säätämäänsä perushintariviin (`basePricingRowId`) ja soveltaa `rateMultiplier`-kerrointa (ja vapaaehtoista `additionalRateMultiplier`-kerrointa) kyseisen perusrivin hinnan päälle. Kerroin `1.0` vastaa perustasoa; `1.2` lisää 20 %; `0.8` antaa 20 % alennuksen.

Admin merkitsee jokaisen yhdistelmän, jolla on `CatalogItemVariantPricingTable`-merkintä, tekstillä ”Variant pricing” tekstin ”Base” sijaan.

## Aloitettuihin jaksoihin perustuva hinnoittelu

Jokaisella varaushintarivillä on `timeBasis`-kenttä, joka määrittää, miten kestoa lasketaan laskutusta varten. Tapoja on kaksi:

| `timeBasis`        | Nimike       | Toiminta                                                                                                                                                                    |
| ------------------ | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rolling` (oletus) | Kulunut aika | ”1 päivä” -hinta kattaa 24 kulunutta tuntia noudosta. Varaus klo 23.00–01.00 on 2 tuntia — selvästi yhden päiväyksikön sisällä                                              |
| `capped`           | Starting at  | ”1 päivä” -hinta kattaa jokaisen **kalenteripäivän**, jota varaus koskettaa. Varaus klo 23.00–01.00 ulottuu kahdelle kalenteripäivälle ja laskuttaa **kaksi päiväyksikköä** |

### Miten ”Starting at” -laskutus toimii

Hinnoittelumoottori tunnistaa jokaisen kalenterijakson, jota varaus koskettaa rivin omalla ruudukolla. Päiväyksikkö on aina keskiyöstä keskiyöhön, tuntiyksikkö tasatunnista tasatuntiin ja viikkoyksikkö alkaa asiakkaan määrittämästä viikon ensimmäisestä päivästä.

Jokainen kosketettu jakso laskutetaan yhtenä yksikkönä — ellei hienojakoisempi hinta kata kyseisen jakson varattua osuutta halvemmalla. Moottori valitsee halvimman kelvollisen yhdistelmän rekursiivisesti.

**Esimerkki — päivä- ja viikkohinnat:**

10 päivän varaus, joka alkaa torstaina, päivähinta 50 € ja viikkohinta 250 €:

* Torstaista sunnuntaihin: 4 aloitettua päivää = 200 €
* Maanantaista seuraavaan sunnuntaihin: 1 aloitettu viikko = 250 €
* Yhteensä: **450 €**

Viikko on kalenteriin sidottu (ma–su, kun viikko alkaa maanantaista), ei noutohetkeen ankkuroitu.

**Esimerkki — päivä- ja tuntihinnat:**

Päivähinta 100 €, tuntihinta 20 €. Varaus maanantaista klo 9.00 tiistaihin klo 9.00:

* Maanantai: 1 aloitettu päivä = 100 €
* Tiistai: 1 aloitettu päivä = 100 €
* Yhteensä: **200 €** (2 kalenteripäivää)

Jos tuntihinta olisi 5 €, moottori laskuttaisi 24 aloitettua tuntia = 120 €, koska hienojakoisempi yhdistelmä on halvempi.

### ”Starting at” kiinteän keston paketeissa

Myös kiinteän keston varausrivit tukevat `timeBasis`-asetusta. Kalenteriin sidottu kiinteä paketti ankkuroi palautuspäivän kalenterijaksoon eikä tarkkaan noutoaikaan.

”2 päivää” -kiinteä paketti, joka noudetaan maanantaina klo 14.00:

* **Kulunut aika** (`rolling`): palautus keskiviikkona klo 14.00 — tasan 48 tuntia myöhemmin
* **Aloitetut jaksot** (`capped`): palautus **tiistaina** viimeisimpään mahdolliseen palautusaikaan mennessä — varaus koskettaa maanantaita ja tiistaita, joten kaksi kalenteripäivää tulee katetuksi

Jos palautuspäivä osuu päivälle, jolloin sijainti on suljettu, vaihtoehtoa ei tarjota kyseiselle noutopäivälle.

### Rajoitukset

* **Tuntia lyhyemmät yksiköt laskuttavat aina kuluneen ajan mukaan.** `timeBasis`-asetus ei vaikuta riveihin, jotka käyttävät yksikköjä `seconds` tai `minutes`. Ne voivat esiintyä vapaasti ”Starting at” -taulukossa.
* **Kaikki taulukon kertoimeen perustuvat rivit jakavat saman `timeBasis`-arvon.** Admin valvoo tätä yhdellä ”Starting at pricing” -valintaruudulla, joka koskee kaikkia kelvollisia kertoimeen perustuvia rivejä. Kiinteän keston riveillä on kullakin oma itsenäinen `timeBasis`-asetuksensa.
* **Viikkohinnat käyttävät asiakkaan viikon aloituspäivää.** Lauantai–sunnuntai-varaus lasketaan yhdeksi viikoksi, kun viikko alkaa maanantaista (molemmat päivät ovat samassa ma–su-viikossa), mutta kahdeksi viikoksi, kun viikko alkaa sunnuntaista.

<Frame caption="Kertoimeen perustuva varaushinnoittelu ja Starting at pricing -valintaruutu">
  <img src="https://mintcdn.com/twicecommerce/5ARkyCTk5wMAizBn/images/catalog-listing-pricing.webp?fit=max&auto=format&n=5ARkyCTk5wMAizBn&q=85&s=667528b54b992ad9f1997518ed63ec6e" alt="Varaushinnan osio, jossa näkyy Starting at pricing -valintaruutu" width="1920" height="1080" data-path="images/catalog-listing-pricing.webp" />
</Frame>

<Frame caption="Kiinteän hinnoittelurivin kestovaihtoehdot">
  <img src="https://mintcdn.com/twicecommerce/5ARkyCTk5wMAizBn/images/catalog-listing-pricing-duration-options.webp?fit=max&auto=format&n=5ARkyCTk5wMAizBn&q=85&s=8dbcb61d0428165a1ddad0fcb6c67e02" alt="Kiinteän rivin kestovaihtoehdot Started- ja Elapsed-muodoissa" width="1920" height="1080" data-path="images/catalog-listing-pricing-duration-options.webp" />
</Frame>

## Hinnan ratkaisu

`availabilityRange` määrittää, **mitkä taulukot ovat ehdolla** varaukseen — se **ei** anna taulukolle etusijaa. Taulukkokohtaista prioriteetti- tai ohituskenttää ei ole. Kun hinta lasketaan:

Kaikki hinnoittelulaskennat suoritetaan **sijainnin aikavyöhykkeellä**. Päivä- ja viikkorajat, `weekdays`-rajoitukset ja `timeOfDayRange`-ikkunat arvioidaan sijainnin paikallisen kellon mukaan — ei UTC:n eikä asiakkaan aikavyöhykkeen. Paikallisen keskiyön tuntumassa oleva varaus kohdistuu oikeaan paikalliseen päivään, ja kesäaikasiirtymät hoidetaan kalenterilaskennalla sijainnin aikavyöhykkeellä.

1. **Kerää aktiiviset taulukot.** Taulukko on aktiivinen, kun sillä ei ole `availabilityRange`-arvoa tai sen aikaväli menee päällekkäin varauspäivien kanssa. Oletustaulukko (ei aikaväliä) on siten aina aktiivinen *yhdessä* minkä tahansa päivämäärään sidotun taulukon kanssa, jonka ikkunaan varaus osuu.
2. **Kokoa rivit.** Kaikki aktiivisten taulukoiden käytössä olevat rivit kootaan yhteen ehdokasjoukkoon. Moottori **ei** valitse ensin yhtä ”voittavaa” taulukkoa — eri taulukoiden rivit kilpailevat suoraan.
3. **Valitse rivi tai rivit.**
   * **Kertoimeen perustuvat (dynaamiset) varaukset** — moottori rakentaa joukosta halvimman kelvollisen katteen varauksen kestolle. Kussakin osuudessa se suosii riviä, jolla on **pisin vielä mahtuva kesto**, ja tasatilanteessa **halvin hinta**, ja täyttää loput lyhyemmillä riveillä ja lisäaikasäännöillä (viikonpäivä-, kellonaika- ja `availabilityRange`-rajoitukset pätevät edelleen rivikohtaisesti). Kun rivit käyttävät aloitettuihin jaksoihin perustuvaa hinnoittelua (`timeBasis: capped`), moottori laskee kosketetut kalenterijaksot kuluneen ajan sijaan ja valitsee halvimman yhdistelmän eri tarkkuustasoilta.
   * **Kiinteähintaiset varaukset** — asiakas valitsee tietyn hintarivin (esimerkiksi `1 päivä 40 €`) ja kyseisen rivin hintaa käytetään sellaisenaan.
4. **Sovella varianttikertoimia.** Jos jokin `CatalogItemVariantPricingTable`-merkintä vastaa valittua varianttiarvojen yhdistelmää, kerro rivin osuus rivitason kertoimella (ja taulukkotason `rateMultiplier`-kertoimella).
5. **Palauta summat.** Päätepisteet `…/rate-based-price` ja `…/fixed-price` palauttavat `priceBreakdown`-erittelyn sekä `totalPrice`-summan, jossa kukin osuus on eritelty verkkokauppaa ja tilausyhteenvetoa varten.

<Warning>
  **Päivämäärään sidottu taulukko ei ohita oletusta päivämäärän perusteella — se kilpailee samassa joukossa.** Kertoimeen perustuvassa hinnoittelussa päivämäärään sidottua riviä käytetään vain, kun moottori valitsee sen (halvimman keston kattavan rivin). **Halvempi** kampanjarivi siis voittaa ikkunansa sisällä, mutta **korkeampaa** päivämääräkohtaista hintaa (esimerkiksi juhlapyhälisää) **ei** sovelleta, jos oletuksessa on edelleen yhtä pitkä tai pidempi rivi, joka kattaa saman keston halvemmalla.

  **Esimerkki.** Oletustaulukko: `1 päivä 100 €` (ei päivämääräväliä). Juhlapyhätaulukko: `1 päivä 150 €` (24.–31.12.). 24 tunnin vuokraus 25.12. hinnoitellaan **100 euroon** — molemmat rivit kattavat päivän yhtä lailla, joten halvempi voittaa. Jos haluat veloittaa 150 euron juhlapyhähinnan, poista tai kytke pois kilpaileva 100 euron rivi kyseiseltä ikkunalta (tai aseta sen `availabilityRange` sulkemaan juhlapyhäpäivät pois), jotta vain 150 euron rivi kattaa sen.
</Warning>

Hintataulukkomallissa ei tällä hetkellä ole asiakastunnistekohtaista hinnoittelua — asiakassegmenttien hinnoittelua ei voi määrittää hintataulukossa. Tietyille asiakkaille tarkoitetut edut hoidetaan [alennuskoodeilla](/docs/fi/concepts/catalog/discount-codes), ei hintataulukoilla.

## Taulukoiden soveltaminen listauksiin ja kokoelmiin

Jaettu hintataulukko liitetään listaukseen omilla päätepisteillään:

* `POST /pricing-tables/pricing-table/:pricingTableId/link-catalog-item` — liitä yksi listaus
* `DELETE /pricing-tables/pricing-table/:pricingTableId/unlink-catalog-items` — poista liitokset kerralla
* `POST /pricing-tables/add-pricing-table-to-catalog-item` — erotteleva unioni neljälle liitostavalle:
  * `mode = 'link'` — liitä olemassa olevaan jaettuun taulukkoon
  * `mode = 'create'` — luo uusi itsenäinen taulukko suoraan
  * `mode = 'sharedToShared'` — korvaa yksi jaettu liitos toisella
  * `mode = 'sharedToStandalone'` — haaroita jaettu taulukko itsenäiseksi listauksella
  * `mode = 'standaloneToShared'` / `'standaloneUpdate'` — vaihda omistajuutta tai nimeä paikallaan

Kokoelmia ei voi liittää suoraan hintataulukkoon. Kokoelman uudelleenhinnoittelu tehdään käymällä läpi sen `listCatalogItems` ja liittämällä taulukko kuhunkin listaukseen.

## Keskeiset ominaisuudet (hintataulukko)

| Ominaisuus                | Tyyppi                             | Kuvaus                                                                                                                                                                             |
| ------------------------- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                      | UUID                               | Palvelimen luoma                                                                                                                                                                   |
| `label`                   | Merkkijono                         | Ihmisluettava nimi Adminin välilehdillä ja valitsimissa                                                                                                                            |
| `catalogItemId`           | UUID \| null                       | Asetettu itsenäisissä taulukoissa, null jaetuissa                                                                                                                                  |
| `isShared`                | Totuusarvo                         | Erottaa jaetun ja itsenäisen taulukon                                                                                                                                              |
| `isDefault`               | Totuusarvo                         | Merkitsee aina voimassa olevan taulukon (ei `availabilityRange`-arvoa) ja määrittää, mikä taulukko on valmiiksi valittuna editorissa. Ei vaikuta rivien valintaan laskentahetkellä |
| `availabilityRange`       | `{ start, end }` \| null           | Taulukon voimassaoloikkuna                                                                                                                                                         |
| `bookingsEnabled`         | Totuusarvo                         | Arvioidaanko varausrivit                                                                                                                                                           |
| `salesEnabled`            | Totuusarvo                         | Arvioidaanko myyntirivit                                                                                                                                                           |
| `subscriptionsEnabled`    | Totuusarvo                         | Arvioidaanko kestotilausrivit                                                                                                                                                      |
| `bookingPricingRows`      | `BookingPricingRow[]`              | Vuokrahintarivit                                                                                                                                                                   |
| `salesPricingRows`        | `SalesPricingRow[]`                | Suoramyyntirivit                                                                                                                                                                   |
| `subscriptionPricingRows` | `SubscriptionPricingRow[]`         | Kestotilausrivit                                                                                                                                                                   |
| `variants`                | `CatalogItemVariantPricingTable[]` | Varianttikohtaiset ohitukset                                                                                                                                                       |
| `linkedCatalogItemsCount` | Luku                               | Kuinka moni listaus viittaa tähän taulukkoon                                                                                                                                       |

## Suhteet

<AccordionGroup>
  <Accordion title="Liitetty yhteen tai useampaan listaukseen">
    Jaettuun hintataulukkoon voi linkittää monta listausta. Itsenäinen hintataulukko on olemassa vain yhdellä listauksella.
  </Accordion>

  <Accordion title="Sisältää varaus-, myynti- ja kestotilausrivit">
    Jokainen taulukko on säiliö kolmelle toisistaan riippumattomalle hinnoittelutavalle. Kytke tavat päälle ja pois rakentamatta taulukkoa uudelleen.
  </Accordion>

  <Accordion title="Lisää varianttihinnoittelun listauksen varianttien päälle">
    Varianttikohtaiset hinnoittelumerkinnät viittaavat listauksen varianttiarvoihin — katso [Variantti-käsite](/docs/fi/concepts/catalog/variants).
  </Accordion>

  <Accordion title="Arvioidaan listauksen ostotapaa vasten kassalla">
    Verkkokauppa ja tilausten rakentaja valitsevat oikean rivin ostotavan mukaan (varaus / myynti / kestotilaus) ja kutsuvat päätepistettä `…/rate-based-price` tai `…/fixed-price` loppusumman laskemiseksi.
  </Accordion>
</AccordionGroup>

## Elinkaari

<Steps>
  <Step title="Luonti">
    `POST /pricing-tables/` kentällä `label` ja (jaetuissa taulukoissa) `isDefault: true`. Uudet taulukot alkavat tyhjillä rivitaulukoilla.

    <AccordionGroup>
      <Accordion title="Itsenäinen vai jaettu?">
        Käytä itsenäistä, kun hinnoittelu on yhdelle listaukselle ainutlaatuista. Käytä jaettua, kun haluat käyttää samaa hinnastoa useissa saman kategorian listauksissa.
      </Accordion>

      <Accordion title="Voinko tehdä päivämäärään sidotusta taulukosta oletuksen?">
        Et. Vain taulukot, joilla `availabilityRange = null`, voivat olla `isDefault = true` (Adminin käyttöliittymä valvoo tätä; malli sallii merkinnän, mutta liitoslogiikka ohittaa päivämäärään sidotut taulukot oletusta ratkaistessaan).
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Rivien lisäys">
    Lisää varaus-, myynti- ja kestotilausrivejä rivikohtaisilla päätepisteillä (`/pricing-table/:id/row`, `…/sales-row`, `…/subscription-row`). Lisää varianttikohtaisia ohituksia päätepisteellä `/pricing-table/:id/variant-pricing-table`.
  </Step>

  <Step title="Liittäminen listaukseen">
    Käytä päätepistettä `add-pricing-table-to-catalog-item` oikealla `mode`-arvolla. Listauksen Hinnoittelu-välilehti näyttää liitetyt taulukot sivupalkissa ja antaa luoda uusia suoraan.
  </Step>

  <Step title="Varianttikohtainen ohitus">
    Lisää `CatalogItemVariantPricingTable`-lohko niille varianttiarvoille, jotka tarvitsevat eri hinnoittelun.
  </Step>

  <Step title="Kampanjointi tai korvaaminen">
    Kun haluat ottaa hintamuutoksen käyttöön rikkomatta aktiivisia tilauksia, lisää uusi päivämäärään sidottu taulukko kyseiselle ikkunalle. Sen rivit kilpailevat ikkunan sisällä oletuksen kanssa samassa joukossa — **halvempi** rivi valitaan automaattisesti. **Korkeampi** hinta tulee voimaan vasta, kun poistat kilpailevan oletusrivin tai rajaat sen päivämäärillä pois (katso kohta Hinnan ratkaisu). Olemassa olevat tilaukset säilyttävät kassalla tallennetun hintansa.
  </Step>

  <Step title="Poisto">
    `DELETE /pricing-tables/delete-table/:pricingTableId`. Jaetun taulukon poistaminen irrottaa sen jokaisesta listauksesta.
  </Step>
</Steps>

## Usein kysytyt kysymykset

<AccordionGroup>
  <Accordion title="Voiko yhdellä listauksella olla useita hintataulukoita?">
    Kyllä. Voit liittää oletustaulukon sekä minkä tahansa määrän päivämäärään sidottuja taulukoita kampanjoita tai kausia varten. Tilaushetkellä kaikkien varaukselle aktiivisten taulukoiden rivit kootaan yhteen, ja moottori valitsee tästä joukosta — katso kohta Hinnan ratkaisu. `availabilityRange` päättää, mitkä taulukot ovat ehdolla, ei sitä, kumpi voittaa.
  </Accordion>

  <Accordion title="Mistä vuokra-ajan hinta tulee?">
    Siitä varaushintarivistä, joka sopii pyydettyyn kestoon parhaiten. Järjestelmä tarkastelee kunkin käytössä olevan rivin arvoa `timeUnit` × `timeUnitAmount`, valitsee lähimmän sopivan ja soveltaa loppuosaan lisäaikasääntöjä.
  </Accordion>

  <Accordion title="Miten toteutan 20 %:n viikonloppukampanjan?">
    Luo päivämäärään sidottu hintataulukko, jonka `availabilityRange` kattaa viikonlopun ja jonka rivit on hinnoiteltu 20 % oletusta **halvemmiksi**, ja liitä se kyseisiin listauksiin. Koska kampanjarivit ovat halvempia ja kattavat samat kestot, moottori valitsee ne ikkunan sisällä ja palaa sen jälkeen oletukseen. Tämä toimii nimenomaan siksi, että kampanja on **halvempi** — katso seuraavasta kysymyksestä korkeampi hinnoittelu.
  </Accordion>

  <Accordion title="Miksi korkeampi kausi- tai juhlapyhähintani ei mene läpi?">
    Koska moottori kokoaa kaikki aktiiviset taulukot yhteen ja valitsee **halvimman** keston kattavan rivin — se ei suosi päivämäärään sidottuja taulukoita. Korkeampaa päivämääräkohtaista hintaa ei valita, jos oletuksessa on edelleen yhtä pitkä tai pidempi rivi, joka kattaa saman keston halvemmalla. Lisän soveltamiseksi poista tai kytke pois kilpaileva oletusrivi kyseiseltä ikkunalta, tai aseta oletusrivin `availabilityRange` sulkemaan nuo päivät pois, jotta vain korkeampi rivi kattaa ne.
  </Accordion>

  <Accordion title="Mikä ero on rolling- ja Starting at -hinnoittelulla?">
    **Rolling** (oletus) laskee kulunutta aikaa noudosta. ”Päivä” on 24 tuntia. Varaus maanantaista klo 14.00 keskiviikkoon klo 14.00 laskuttaa tasan 2 päivää.

    **Starting at** (`capped`) laskee jokaisen varauksen koskettaman kalenterijakson. ”Päivä” on keskiyöstä keskiyöhön. Sama varaus maanantaista klo 14.00 keskiviikkoon klo 14.00 koskettaa maanantaita, tiistaita ja keskiviikkoa — 3 aloitettua päivää.

    Käytä ”Starting at” -tapaa, kun veloitat kalenteripäivittäin (kuten pysäköintihallit tai hotelliyöt). Käytä rolling-tapaa, kun veloitat tarkan kuluneen ajan mukaan (kuten tuntipohjaisessa laitevuokrauksessa).
  </Accordion>

  <Accordion title="Voivatko hinnat vaihdella asiakassegmentin mukaan?">
    Eivät hintataulukoiden kautta. Hintataulukkomallissa ei tällä hetkellä ole asiakassegmenttiulottuvuutta. Käytä asiakaskohtaiseen hinnoitteluun [alennuskoodeja](/docs/fi/concepts/catalog/discount-codes).
  </Accordion>

  <Accordion title="Mitä aikavyöhykettä hinnoittelumoottori käyttää?">
    Sijainnin aikavyöhykettä. Päivä- ja viikkorajat, viikonpäivärajoitukset ja kellonaikaikkunat ratkaistaan sijainnin paikallisen kellon mukaan. Jos sijainnin aikavyöhykettä ei ole asetettu, käytetään asiakastason aikavyöhykettä ja viimeisenä keinona UTC:tä. Aikavyöhyke ratkaistaan valitusta noutosijainnista (tai jos yhtä sijaintia ei ole valittu, listauksen ensisijaisesta liitetystä sijainnista).
  </Accordion>

  <Accordion title="Hinnoitellaanko olemassa olevat tilaukset uudelleen, kun muokkaan taulukkoa?">
    Ei. Tilaukset tallentavat hintaosuudet kassalla. Hintataulukon muokkaus vaikuttaa vain tulevien tilausten summiin.
  </Accordion>

  <Accordion title="Mikä ero on vastauksen kentillä `priceContribution` ja `totalPrice`?">
    `priceContribution` on se, mitä yksi rivi lisäsi summaan; `totalPrice` on kaikkien moottorin valitsemien rivien summa (perusrivi + lisäaikarivit + varianttikertoimet).
  </Accordion>
</AccordionGroup>

## Kehittäjän viite

Hintataulukot näkyvät API:ssa nimellä `pricing-tables`.

<Card title="API: Pricing Tables" icon="code" href="https://server.twicecommerce.com/api/internal">
  Avaa päätepiste API-referenssissä.
</Card>

## Aiheeseen liittyvää

<CardGroup cols={2}>
  <Card title="Listaukset" icon="list" href="/docs/fi/concepts/catalog/listings">
    Mihin hintataulukko liitetään
  </Card>

  <Card title="Variantit" icon="layer-group" href="/docs/fi/concepts/catalog/variants">
    Varianttikohtaiset hinnoitteluohitukset
  </Card>

  <Card title="Kokoelmat" icon="folder" href="/docs/fi/concepts/catalog/collections">
    Ryhmittele listaukset ennen jaetun taulukon massakäyttöönottoa
  </Card>

  <Card title="Tilauksen elinkaari" icon="shopping-cart" href="/docs/fi/concepts/orders/order-lifecycle">
    Missä hintataulukon summat tallennetaan kassalla
  </Card>
</CardGroup>
