Piecu nomas veidu rezervāciju sistēma, kas dzīvo vienā kopējā krājumā
No "cik laivu mums ir brīvas šodien?" līdz parakstītam līgumam, rēķinam un apmaksai — bez vienas rindas Excel. Viens pielāgots WordPress spraudnis pārvalda laivošanu, pirti un kublu, nakšņošanu, SUP nomu un pakas no vienas un tās pašas inventāra tabulas.
Projektēts, uzbūvēts un uzturēts Westtro.
Logotipu un vizuālo identitātiarī izstrādāja Westtro
Ģimenes bizness uz Ventas krasta
Upes Viesi ir Sanitas un Arta Veinbergu ģimenes tūrisma saimniecība Nīgrandes pagastā, Saldus novadā — uz Ventas, Latvijas garākās upes, kas tek pilnībā valsts teritorijā. Pamatdarbība ir laivošana — vadīti un pašapkalpošanās kanoe/kajaku maršruti — ko papildina mobilā pirts un kubls ar piegādi, nakšņošana teltsvietās un apartamentos, SUP dēļu un caurspīdīgo laivu stundu noma, un pakas, kas sasaista vairākus pakalpojumus vienā cenā. Pakalpojums izveidots ar ES lauku attīstības projekta atbalstu.
Ventas garums — Latvijas garākā upe tek pilnībā valsts robežās.
no tiem laivojami Latvijas teritorijā.
ģimene vada visu — sistēma būvēta viņu, nevis IT nodaļas, lietošanai.
Viens krājums, pieci nomas veidi, nulle gatavu spraudņu
Standarta WordPress rezervāciju spraudņi pieņem, ka tiek nomāta viena lieta vienā kategorijā. Upes Viesi vienlaicīgi nomā laivas pēc dienām, pirti/kublu ar piegādes un atgriešanas laiku, teltsvietas pēc naktīm, SUP dēļus pa pusstundām un pakas, kas apvieno visu iepriekšējo — no viena un tā paša inventāra, reāllaikā, bez dubultrezervācijas riska.
Klāt nāk Latvijai specifiskas prasības, ko vispārīgs spraudnis nerisina gatavā veidā: pašnodarbinātas personas PVN atbrīvojuma formulējums rēķinā, GDPR datu glabāšanas un anonimizācijas termiņi, juridiski saistošs nomas līgums ar maināmu drošības punktu sarakstu, un trīs atšķirīgas maksājumu plūsmas — kartei, pārskaitījumam un samaksai klātienē. Un tam visam vajadzēja darboties uz mazas sezonālas saimniecības budžeta, bez maksas kartogrāfijas API un dārgiem SaaS rezervāciju rīkiem.
Rezervāciju sistēma zem WordPress, nevis WordPress spraudnis virs rezervācijām
"Upes Viesi Booking" ir pasūtījuma spraudnis, kas pats apstrādā datu modeli, pieejamības loģiku, cenas, juridiskos dokumentus un GDPR — WooCommerce tajā ir tikai maksājumu cauruļvads, bez neviena produkta katalogā. Visi četri klienta vedņi beidzas vienā un tajā pašā iesniegšanas vārtejā.
Visi četri klienta vedņi iesniedz datus vienā un tajā pašā uv_submit_booking apdarinātājā, kas serverī pārbauda pieejamību otrreiz (pret sacensību starp paralēliem pirkumiem), izveido WooCommerce pasūtījumu ar vienu maksas pozīciju un atkarībā no izvēlētā maksājuma veida zaro uz trīs ceļiem. Apmaksas statusa izmaiņa ir vienīgais signāls, kas automātiski ģenerē līgumu, rēķinu un e-pastu — admin kalendārs lasa to pašu datubāzi, tāpēc manuāla bloķēšana un reāla rezervācija nekad nesaskaras.
Četri rezervācijas ceļi, viena datubāze
Katram pakalpojuma veidam savs solis-pa-solim vednis ar savu soļu skaitu — bet visi raksta tajās pašās tabulās, tāpēc laiva, pirts un teltsvieta nekad nesakrīt vienā datumā, ja koplieto inventāru.
Galvenais vednis
- 1. Maršruts no karuseļa vai "Izveido pats"
- 2. Kajaks / kanoe + cilvēku skaits
- 3. Datumi — dzīva pieejamība
- 4. Piegādes vieta (pašu ceļam)
- 5. Laivas ar DFS ieteikumu
- 6. Papildu inventārs
- 7. Kontakti, līgums, GDPR
- 8. Apmaksa
Vienīgais vednis ar laivu piešķires algoritmu.
Relax vednis
- 1. Pirts vai kubls
- 2. Datumi + piegādes logs
- 3. Piegādes adrese, dzīva cena
- 4. Kontakti, līgums, GDPR
- 5. Apmaksa
route_id=0 nosaka dienu skaitīšanu rēķinā.
Vienkāršākais vednis
- 1. Teltsvieta vai apartaments
- 2. Datumi (naktis)
- 3. Kontakti, līgums, GDPR
- 4. Apmaksa
Nav piegādes soļa — tikai 4 no 8 soļiem.
Stundu vednis
- 1. Inventāra izvēle
- 2. Datums + laiks (30 min sloti, 1-6h)
- 3. Kontakti, līgums, GDPR
- 4. Apmaksa
Vienīgais ar savu AJAX slotu endpointu.
Septiņas sistēmas, kas padara vienu rezervāciju par uzticamu
Katra no šīm daļām risina vienu konkrētu, neuzkrītošu problēmu — kopā tās nozīmē, ka saimniecības īpašniecei nekad manuāli nav jāseko, vai kaut kas ir dubultrezervēts, neapmaksāts vai juridiski nenodrošināts.
Laivu piešķires algoritms, kas pats saskaita vietas
Katrai pieprasītai dienu/stundu kombinācijai sistēma skaita pārklāšanos pret wp_uv_booking_items ar pusatvērtu intervālu loģiku (A < D UN B > C), ieskaitot 30 minūšu "soft hold" nesen izveidotām, bet vēl neapmaksātām rezervācijām — lai divi cilvēki, kas vienlaicīgi noklikšķina "Apmaksāt", nesaņemtu vienu un to pašu laivu.
Kad klients ievada cilvēku skaitu, uv_suggest_boats() ar DFS algoritmu meklē laivu kombināciju ar minimālo brīvo vietu pārpalikumu — vispirms precīzu sakritību, tad vismazāko "overshoot". Rezultāts nāk kā gatavs latviešu teikums klientam.
"Iesakām: 2× Kanoe + 1× Kajaks. 1 brīva vieta — kompaktākas laivas nav pieejamas."
Ko šis dzinējs dara papildus
- 120 dienu kalendāra priekšrēķins — vienā DB vaicājumā aprēķina, kuras dienas nespēj uzņemt norādīto cilvēku skaitu, un kalendārā tās pelēkas.
- Alternatīvu datumu meklēšana — ja izvēlētie datumi neder, sistēma piedāvā līdz 5 tuvākajiem logiem, kur viss pieprasītais ir pieejams.
- Pakas atrisina pašas sevī — pakai nav sava krājuma; tā ir bloķēta tajā dienā, kad kāda tās sastāvdaļa ir bloķēta.
- Stundu sloti ir atsevišķa matemātika — SUP/caurspīdīgo laivu pārbauda pret laika logu, nevis datumu diapazonu, tāpēc tās nekad nekonfliktē ar dienu rezervācijām.
WooCommerce kā maksājumu cauruļvads, nevis veikals
Šajā sistēmā nav ne viena WooCommerce produkta. Katra rezervācija kļūst par vienu dinamiski izveidotu maksas pozīciju ("Laivošanas rezervācija — Abava maršruts, 12.–13. jūlijs, 4 cilv.") uz pasūtījuma, kas tiek pilnībā pārveidots pēc Upes Viesi vizuālā stila — pašas WooCommerce e-pasta un noklusējuma izskats ir izslēgti.
Trīs maksājumu ceļi, trīs atšķirīgi noteikumi: karte (Stripe) apstiprinās tūlīt, bankas pārskaitījumam (BACS) ir 48 stundu logs pirms automātiskas atcelšanas, un samaksa klātienē ir atļauta tikai tad, ja brauciens sākas vismaz 14 dienas uz priekšu — pārbaudīts gan ekrānā, gan serverī, lai noteikumu nevarētu apiet.
Trīs noteikumi, viens avots
- 30 minūtes — soft hold jaunai, neapmaksātai kartes rezervācijai, pirms tā automātiski atbrīvo inventāru.
- 48 stundas — pārskaitījuma logs; pēc tam pasūtījums un rezervācija tiek atceltas automātiski ar cron darbu.
- 14 dienas — minimālais attālums līdz braucienam, lai atļautu samaksu klātienē; tajā pašā termiņā sūta atgādinājuma e-pastu.
- Pašrocīga atcelšana pirms apmaksas lapas — vienīgais brīdis, kad klientam vēl nav sūtīta "mana rezervācija" saite, tāpēc atcelšanas poga ir tieši apmaksas lapā.
Pakāpeniska atmaksa, ko klients var pieprasīt pats
Admin iestatījumos konfigurējama atmaksas tabula (noklusējumā 50% ≥14 dienas, 25% 7–13 dienas, 0% zem 7 dienām) tiek piemērota automātiski, kad klients ar savu personīgo piekļuves saiti ("mana rezervācija") pieprasa atcelšanu — bez zvana saimniecības īpašniecei.
Samaksātas, bet klātienē veiktas rezervācijas, kas tomēr nav apmaksātas (on_site_paid = 0), automātiski saņem 0% atmaksu — likmē nav ko atmaksāt. Kartes maksājumiem pēc apmaksas pašapkalpošanās atcelšanas poga vispār netiek rādīta, jo naudas plūsma jau ir reāla un to risina caur maksājumu apstrādātāju.
Aizsardzība pret ļaunprātīgu izmantošanu
- Tokena, nevis ID piekļuve — rezervāciju nevar "pārmeklēt", uzminot ciparus.
- 5 mēģinājumi/h uz IP — ātruma ierobežojums pašapkalpošanās atcelšanas endpointam.
- Brauciens jau sākās? — atcelšana vairs netiek piedāvāta.
- Admin "Atmaksas priekšskatījums" — rāda summu pirms klikšķa, lai darbinieks zinātu, ko solīt pa telefonu.
Juridiski saistošs līgums, kas pārrakstās katrai rezervācijai
Katrai apmaksātai rezervācijai sistēma tajā pašā brīdī izveido pielāgotu nomas līgumu — tas pieskaita tikai tās drošības klauzulas, kas attiecas uz faktiski nomāto (laivas glābšanas vestes punkts pazūd, ja nomāta tikai pirts), un sadala piegādes maksu pēc trim atšķirīgām formulām atkarībā no pasūtījuma veida.
Publiski pieejamā līguma priekšskatījumā (pirms apmaksas) īpašnieces personas kods, adrese un IBAN ir aizstāti ar placeholderu — pilnie dati parādās tikai serverī ģenerētajā, parakstītajā versijā. Rēķinu numerācija (UV-2026-0047) izmanto atomāru MySQL skaitītāju uz gadu, lai divi vienlaicīgi pirkumi nekad nesaņemtu vienu numuru.
Latvijai specifiskas detaļas
- PVN atbrīvojuma formulējums — rēķinā automātiski, jo pakalpojuma sniedzēja ir pašnodarbināta persona.
- 5 gadu glabāšanas termiņš — atbilst Grāmatvedības likuma prasībām; pēc tā beigām ikmēneša cron anonimizē klienta datus, saglabājot finanšu rindas.
- 6 juridiskās lapas auto-izveidotas aktivizācijā: privātuma politika, atcelšanas un rezervācijas noteikumi, 3 drošības instrukcijas (laivošana, pirts, kubls).
- Pilns piekrišanas audits — līguma versija, IP adrese un laikspiedols katrai rezervācijai, redzams admin detaļu skatā.
Pielāgots kalendārs, kas nejauc "paturēts" ar "pārdots"
Admin kalendārs ir uzrakstīts no nulles (nav FullCalendar vai citas bibliotēkas) — vairāku dienu rezervācijas rāda kā krāsainas joslas ar jostu piešķiri, lai tās nepārklātos, un ieņēmumu summa mēnesim tiek skaitīta reāllaikā, atstājot ārā neapmaksātās un pamestās sesijas, kas saimniecības īpašniecei iepriekš radīja maldīgu iespaidu, ka klients jau ir maksājis.
Pielāgota lietotāja loma uv_manager ar savu manage_uv_bookings tiesību ļauj pieņemt darbā personālu, kas pārvalda rezervācijas, bet nekad neredz spraudņus, lietotājus vai produktu katalogu.
Manuālā kontrole, kad tā nepieciešama
- "Bloķēt inventāru" — divi klikšķi kalendārā rezervē laivu tehniskai apkopei vai personīgai lietošanai, izmantojot to pašu tabulu, ko lasa pieejamības dzinējs.
- "Atzīmēt kā apmaksātu" BACS rindai iet caur īsto WooCommerce
payment_complete()ceļu — nekad tieši DB — lai pasūtījums un rezervācija nekad nesaskanētu nepareizi. - Leaflet karte detaļu skatā — sākuma, beigu un piegādes punkti uzreiz redzami uz kartes.
- Viens klikšķis nokopēt klienta "mana rezervācija" saiti, lai nodotu pa telefonu.
12 e-pasta veidnes, sava karšu dzirnavas un WhatsApp burbulis
Septiņi notikumi (apstiprināts, gaida pārskaitījumu, gaida samaksu klātienē, atgādinājums, čeks, atcelts, pamesta sesija) sadalās 12 veidnēs — klientam un adminam atsevišķi — ar vienotu vizuālo valodu: tumša galvene, "norauktas biļetes" caurumu atdalītājs, un maršruta karte, kas ielikta pašā e-pastā.
Tā karte nav no Google Maps API — tā ir pašrakstīts Web Merkatora projekcijas kods, kas salīmē CARTO flīzes pelēktoņos un virsū uzzīmē divus krāsainus punktus. Lēmums ietaupīt maksas kartogrāfijas API rēķinu mazai sezonālai saimniecībai.
Pilns kanālu klāsts
- Tokenizēta "Mana rezervācija" lapa — lejupielādē līgumu/rēķinu un pieprasa atcelšanu, bez pieteikšanās sistēmā.
- WhatsApp burbulis katrā lapā — pats pielāgojas, lai nepārklātos ar promo baneri.
- E-pasta QA konsole adminā — katru no 12 veidnēm var priekšskatīt un nosūtīt testa e-pastu, redzot patieso trigeri un pielikumus.
- 30 dienu attēlu kešs kartes momentuzņēmumiem — ģenerē vienreiz, pēc tam atkārtoti izsniedz no faila.
Maršruta karte, ko iezīmē ar klikšķi, nevis koordinātu kopēšanu
Maršrutu, inventāra un paku dati tiek pārvaldīti ar ACF laukiem — bet sākuma/beigu punktu ievadei admin redaktorā ir savs Leaflet kartes rīks: darbiniece uzklikšķina kartē (vai ielīmē Google Maps saiti), un sistēma pati izvelk lat,lng koordinātas, kuras tālāk lasa pieejamības, e-pasta kartes un rēķina loģika.
Trīs shortcode (maršrutu karuselis, paku promo kartiņas, relaksācijas kartiņas) un pielāgota sākumlapas/bloga sistēma veido pārējo publisko lapu, koplietojot vienu Google Fonts ielādi un vienu navigācijas/kājenes komponentu visās pielāgotajās veidnēs.
Mazas, bet jutīgas detaļas
- Promo baneris apspiests automātiski WooCommerce kasē un grozā, lai nekonfliktētu ar maksājuma plūsmu.
- SVG ikonas admin laukos iet caur
wp_kses()sanitizāciju — redaktora brīvība bez XSS riska. - GTranslate pielāgots valodas slēdzis — pārveidots no noklusējuma dropdown uz zīmola stila paneli.
- Viena fontu ielāde visai vietnei — koda komentārs fiksē, ka iepriekš 8 faili reģistrēja to pašu fontu neatkarīgi.
Četri cron darbi, kas strādā, kamēr saimniece guļ
Neviena no šīm darbībām nav manuāla. Katra pārbauda tieši vienu nosacījumu un rīkojas tikai tad, kad tas ir patiess.
uv_check_abandoned_sessions
Atrod pamestas vedņa sesijas pēc 30+ min neaktivitātes, nosūta adminam kopsavilkumu.
uv_cleanup_abandoned
Atceļ rezervācijas, kas iestrēgušas pending_payment — 30 min kartei, 48h pārskaitījumam — un atbrīvo inventāru.
uv_onsite_payment_reminder
14 dienas pirms brauciena sūta atgādinājumu par nesamaksātu, klātienē veicamu rezervāciju.
uv_anonymize_bookings
Anonimizē klienta datus rezervācijām, vecākām par glabāšanas termiņu; finanšu rindas paliek grāmatvedībai.
Paveiktais, skaitliski
Nekas no šī nav demo dati — šie ir faili un ieraksti, kas atrodas reālajā produkcijas vietnē.
28 funkcionalitātes klases spraudnī.
Rezervācijas, pozīcijas, pamestās sesijas.
Maršruti, inventārs, pakas, dokumenti.
Pilnībā atšķirīgi, viena kopīga kodola loģika.
Karte, pārskaitījums, klātiene — atšķirīgi noteikumi.
7 notikumu tipos, viena vizuālā sistēma.
Auto-izveidotas un auto-atjaunotas aktivizācijā.
No pamestu sesiju atklāšanas līdz GDPR anonimizācijai.
Citas transformācijas
| Darbs | Nozare | Saite |
|---|
Sāksim darbu. Sāksim ar sarunu.
Padomi un jaunumi par mājaslapu izstrādi. Pieraksties jaunumiem.
Pieteikums saņemts. Paldies!upesviesi.lv — dzīvs. Case study sagatavots, izpētot "Upes Viesi Booking" spraudņa pirmkodu un vietnes struktūru.
