Kitworks Event Suite — повний гід з налаштування

Від чистої бази до проданого квитка та розрахунку з гідом. На прикладі екскурсійної компанії «Цікавий Київ» (Odoo 19).

Odoo 19.0 34 модулі Каталог → події Квитки & знижки Бюджет-матриця Розрахунки з гідом REST API

Цей гід проходить весь шлях з нуля на чистій базі event19 з demo-даними. Усі скриншоти — реальні екрани локального стека Odoo 19.

0. Що це за система і кому вона потрібна

Kitworks Event Suite — це надбудова над модулем Events ядра Odoo, заточена під компанії, що регулярно проводять платні заходи з виїзним персоналом: екскурсійні бюро, тури, майстер-класи, виїзні лекції. Ключові відмінності від «голого» Odoo Events:

Каталог замість ручного створення
Один шаблон екскурсії → з нього штампуються десятки конкретних подій (регулярних або індивідуальних) однією дією.
Квитки зі знижками-пресетами
Повний / пільговий / дитячий квиток з автоматичним розрахунком ціни від базової, з вікнами продажу.
Бюджет-матриця події
Планований / підтверджений / оплачений дохід і витрати в одній таблиці, що перераховується автоматично.
Гід як підрядник
Ставка гіда (за годину / за подію / за групу / % прибутку), гаманець гіда та взаєморозрахунок після турів.
Види витрат
Транспорт, харчування, вхідні квитки — з формулою «фікс + на людину + мінімалка» і одержувачем оплати.
REST API
Створення подій, реєстрацій та продаж квитків із зовнішнього сайту (WordPress/WooCommerce).
Логіка під капотом. Уся система обертається навколо ланцюга:
Каталог (шаблон) Подія Квитки Реєстрації Продаж (SO) Бюджет Розрахунок з гідом
Налаштування (розділи 1–5) готують довідники цього ланцюга. Робота (розділи 6–10) — це сам ланцюг.

1. Які модулі встановити для якого функціоналу

Suite складається з ~34 опційних модулів kw_event_*. Встановлюйте не «усе підряд», а під потрібний функціонал — залежності підтягнуться автоматично. Нижче — групи за призначенням.

1.1 База (встановити завжди)

МодульЩо дає
kw_event_catalogКаталог екскурсій — шаблони подій, місця збору (start places), тривалість, тип.
kw_event_saleКвитки як товари: типи квитків, пресети, знижки, вікна продажу, продаж через Sale Order.
kw_event_type_uiПеремикачі вкладок на типі події (Питання / Спілкування / Мульти-слоти).
kw_event_configЗагальні налаштування suite (меню «Конфігурація»).

1.2 Ціни та квитки

МодульЩо дає
kw_event_catalog_ticket_presetБазова ціна квитка на каталозі + перевизначення ціни/знижки на рівні каталогу (kw.event.catalog.ticket).
kw_event_catalog_priceПрайс-логіка для каталогу.
kw_event_registration_paymentОплата реєстрації, статуси «оплачено», звʼязок з платежами.
kw_event_invoice_preset / kw_invoice_presetПресети рахунків для швидкого виставлення.

1.3 Бюджет та аналітика

МодульЩо дає
kw_event_sale_accountДвигун бюджету події — матриця Планований/Підтверджений/Оплачений; event._kw_recompute_budget.
kw_event_state_analytic_matrix + kw_matrix_widgetВіджет-матриця станів аналітики на вкладці «Бюджет».
kw_event_accountПривʼязка події до аналітичного рахунку, проводки.
kw_purchase_analyticАналітика на закупівлях (витрати події).

1.4 Гіди / виконавці та витрати

МодульЩо дає
kw_event_performerГід/виконавець як партнер; гаманець гіда (каса гіда).
kw_event_performer_feeСтавка гіда: за годину / за подію / за групу / % прибутку.
kw_event_performer_fee_invoiceРахунки підряднику (гіду) за його ставкою.
kw_event_performer_settlementВзаєморозрахунок з гідом: вкладка розрахунків, майстер по кількох турах, кольори списку.
kw_event_expenseВиди витрат: фікс + на людину + мінімалка, групові тарифи, одержувач оплати.
kw_event_catalog_expenseВитрати на рівні каталогу (автододаються в подію).
kw_event_catalog_performerГіди за замовчуванням на каталозі.

1.5 Логістика, формати, додаткове

МодульЩо дає
kw_event_truckage (+ kw_truckage*)Транспорт/логістика: автобуси, водії, тип ТЗ під розмір групи.
kw_event_onlineОнлайн-події (без локації).
kw_event_parentСкладені події: батьківська подія з під-подіями (багатоденний тур).
kw_event_seats_planПланована кількість місць (seats_plan) для бюджету.
kw_event_language / kw_event_catalog_languageМови екскурсій.
kw_event_timezoneЧасовий пояс за замовчуванням на типі події.
kw_event_utmUTM-мітки (звідки прийшов учасник), вкладка «Маркетинг».
kw_event_client_modeРежим «є клієнт» (B2B-захід на замовлення) + прапор «учасники впливають на бюджет».
kw_event_customerКлієнт події (замовник).
kw_event_registration_participant / kw_event_registration_extraДодаткові поля учасника (паспорт, дата народження тощо).
kw_event_attendee_opsМасові операції над учасниками.
kw_event_access / kw_event_catalog_accessПрава доступу до подій і каталогу.
kw_events_apiREST API /kw_api/* (потребує kw_api).
Рекомендований мінімум для екскурсійної компанії: kw_event_catalog, kw_event_sale, kw_event_catalog_ticket_preset, kw_event_sale_account, kw_event_state_analytic_matrix, kw_event_expense, kw_event_catalog_expense, kw_event_performer, kw_event_performer_fee, kw_event_performer_settlement, kw_event_seats_plan, kw_event_type_ui, kw_event_registration_payment. Решта — за потребою (онлайн, транспорт, API, UTM).

2. Які довідники заповнити і в якому порядку

Порядок важливий: кожен наступний довідник посилається на попередній. Не можна зробити каталог без типу події, а тип події без продукту-квитка не дасть продавати.

1Компанія, валюта, журнали

  • Компанія — назва, реквізити, лого («Цікавий Київ»).
  • Валюта — UAH як основна.
  • Журнали обліку: Каса (Cash), Банк (Bank), Продажі, Закупівлі. Для кожного гіда згодом створюється окрема каса-гаманець.

2Податки та продукти-послуги

  • Налаштувати ставки ПДВ / без ПДВ під ваш режим оподаткування.
  • Базові продукти-послуги для витрат (вони створюються автоматично з видів витрат, але можна й вручну).

3Мови екскурсій (kw.event.language)

Українська, англійська тощо. Прапор «Іноземна» відрізняє внутрішні мови від іноземних.

4Місця збору (kw.event.start.place)

Точки старту екскурсій («Майдан Незалежності», «Золоті ворота») з адресою та координатами. Перевикористовуються в каталозі.

5Типи квитків та пресети

  • Типи квитків додаються в окремому довіднику (меню «Типи квитків»). Атрибут товару створювати не треба — системний атрибут «Тип квитка» підвʼязується автоматично до кожного нового запису.
  • Створіть значення: Повний, Пільговий, Дитячий — кожне зі знижкою (kw_price_discount + тип знижки %/грн) та вікнами продажу (днів до події).
  • Зберіть їх у пресет (kw.event.ticket.preset), напр. «Стандартні квитки екскурсії».

6Види витрат (kw.event.expense)

Транспорт, харчування, вхідні квитки — з формулою та одержувачем оплати. Деталі — розділ 3.

7Гіди та їхні ставки

  • Контакт гіда (партнер) з позначкою «Виконавець» (kw_event_is_performer).
  • Каса-гаманець гіда створювати не треба — журнал «Готівка в <ім'я>» створюється автоматично, щойно партнера позначено виконавцем.
  • Ставки у вкладці «Performance fee»: за годину / за подію / за групу / %. Деталі — розділ 4.

8Типи подій (event.type)

«Регулярна екскурсія», «Індивідуальна екскурсія», «Онлайн-лекція» — з усіма перемикачами (пресети квитків, вкладки, бюджет). Деталі — розділ 5.

9Каталог екскурсій (kw.event.catalog)

Фінальний крок налаштування: шаблон конкретної екскурсії, що звʼязує все вище. Деталі — розділ 6.

Коротко про залежності: Мови + Місця збору + Пресети квитків + Види витрат + Гіди → потрібні для Каталогу. Каталог + Тип події → потрібні для Події. Тому послідовність 3→9 строга.

3. Види витрат

Вид витрат (kw.event.expense) — це багаторазова категорія собівартості події: оренда автобуса, обід, вхідні квитки до музею. Кожен вид описує формулу вартості, продукт для обліку і одержувача оплати.

3.1 Поля виду витрат

ПолеПризначення
Назва«Оренда автобуса», «Обід», «Вхідні квитки».
Продукт (product_id)Товар/послуга для рахунка постачальнику (створюється автоматично, якщо немає).
Фіксована вартість (fixed_cost)Базова сума незалежно від кількості людей.
Вартість на людину (person_cost)Додається за кожного учасника.
Мінімальна вартість (minimal_cost)Підлога: підсумок не може бути нижчим.
Одержувач оплати (cash_recipient)performer — гіду · manager — менеджеру події · partner — компанії-постачальнику.
Журнал (journal_id)Журнал оплати (для грошового потоку).
Групові тарифи (group_expense_ids)Різна ціна для діапазонів кількості (1–15, 16–30, 31+).

3.2 Формула вартості

підсумок = fixed_cost + (person_cost × К-сть_учасників) + груповий_тариф + коригування
фінал    = max(підсумок, minimal_cost)
Приклад «Обід». Фікс 20 грн (оренда столу) + 8 грн/особа + мінімалка 20 грн.
  • Група 10 осіб: 20 + 8×10 = 100 грн
  • Група 25 осіб: 20 + 8×25 = 220 грн

3.3 Три суми кожної витрати в події

Коли вид витрат потрапляє в подію (рядок kw.event.expense.line), система рахує три величини — вони ж видно у вкладці «Бюджет»:

СумаВід чого рахуєтьсяДе видно
Планована (planned)За планованою к-стю місць (kw_seats_plan)Колонка «Планований»
Підтверджена / «До сплати» (confirmed)За фактичними реєстраціями (стан open/done)«Підтверджений» + вкладка розрахунків
Оплачена (paid)Сума проведених рахунків постачальника«Оплачений» + розрахунок з гідом
Ручне перевизначення. Поле custom_amount замінює розраховану «Підтверджену» суму. Напр. вид витрат рахує 500 грн, але ви домовилися на 400 — вписуєте 400, і саме 400 піде в бюджет, у рахунок та в розрахунок з гідом.

3.4 Витрати на каталозі

У каталозі (kw.event.catalog.expense) перелічуються види витрат, які автоматично клонуються в кожну подію, створену з цього каталогу. Так ви один раз описуєте собівартість екскурсії, а далі вона зʼявляється в кожному виїзді.

4. Принципи розрахунку ставки гіда

Ставка гіда — це сума, яку компанія платить гіду за проведену екскурсію. Suite підтримує чотири способи розрахунку. Спосіб задається у вкладці «Performance fee» на контакті гіда (kw.event.performance.type.fee), а сума фіксується на події у вкладці «Виконавці» (kw.event.performance).

За годину (per_hour)
ставка × тривалість події.
25 грн/год × 3 год = 75 грн
За подію (per_event)
Фіксована сума за виїзд, незалежно від людей і годин.
напр. 100 грн / екскурсію
За групу (per_group)
Різна сума для діапазонів розміру групи.
1–5 → 50 · 6–10 → 75 · 11+ → 100
% від прибутку (percent)
Відсоток від чистого прибутку події (дохід − усі витрати). Рахується при завершенні події.
15% × max(0, прибуток)

4.1 Як це працює на події

У вкладці «Виконавці» додаєте рядок: гід + тип виступу (Екскурсовод) + спосіб розрахунку. Система:

  1. Бере ставку гіда з його довідника ставок.
  2. Для фіксованих типів: сума = ставка × кількість (1 для per_event, години для per_hour).
  3. Для %: відкладається до завершення події (бо потрібен підсумковий прибуток).
  4. confirmed_amount («До сплати») = custom_amount (якщо вписали вручну) або розрахована сума.

4.2 Особливість «% від прибутку»

Гід-відсоток не може бути порахований одразу: прибуток = дохід − витрати, а його ставка сама є витратою. Тому система рахує спочатку всі не-відсоткові витрати, визначає прибуток, і лише тоді: гонорар = % × max(0, прибуток). Клемп на нулі — при збитку гонорар не стає відʼємним. Остаточний нарахунок і рахунок підряднику створюються коли подія переходить у стан «Завершено».

5. Тип події — за що відповідає кожне налаштування

Тип події (event.type) — це «профіль поведінки» події. Більшість налаштувань — це перемикачі-фічі: вмикаєш — зʼявляється вкладка/поле/логіка, вимикаєш — приховується (і відповідні записи не створюються).

Форма типу події з перемикачами
Тип події «Регулярна екскурсія»: ліворуч — «Показ на події» (вкладки, квитки, терміни продажу), праворуч — «Правила розрахунку» (Онлайн, Складена, Має клієнта, Учасники впливають на бюджет, Набори квитків).

5.1 Видимість вкладок (UI)

ПолеЗа замовч.Що робить
Показати вкладку «Питання»
kw_show_question_page
ТакВкладка з кастомними питаннями реєстрації. Вимкнено → вкладки немає.
Показати вкладку «Спілкування»
kw_show_communication_page
ТакЗаплановані листи учасникам (підтвердження, нагадування). Вимкнено → вкладка зникає і заплановані листи видаляються.
Показати мульти-слоти
kw_show_multi_slots
ТакРеєстрація на кілька слотів однієї події.
Показати сторінку «Маркетинг»
kw_show_marketing_page
ТакUTM-мітки (джерело/канал/кампанія) для відстеження звідки прийшов учасник.

5.2 Формат і структура події

ПолеЗа замовч.Що робить
Онлайн kw_is_onlineНіПодія онлайн-лише: локація не обовʼязкова, інші шаблони листів.
Складена kw_is_compoundНіБатьківська подія з під-подіями (багатоденний тур). Один рівень вкладеності.
Потребує перевезення kw_is_truckageНіВмикає панель логістики/транспорту (автобуси, водії).

5.3 Квитки та ціни

ПолеЗа замовч.Що робить
Має квиток kw_has_ticketТакРеєстрація вимагає вибору типу квитка з ціною. Вимкнено → проста реєстрація імʼя/email без цін.
Інтервал дат квитків kw_use_ticket_date_intervalТакВікна продажу рахуються як зсув у днях від дати події (відкрити за 30 днів, закрити за 5). Вимкнено → дати вручну.
Авто-підтвердження реєстрацій auto_confirmТакУчасник підтверджується одразу. Вимкнено → реєстрація в чернетці, потрібне ручне підтвердження.
Набори квитків preset_idsПресети, з яких автоматично генеруються квитки при створенні події (якщо каталог не перевизначає).
Продукт продажу kw_sale_product_idЗапасний товар для SO, якщо немає товару-квитка.

5.4 Клієнт і бюджет

ПолеЗа замовч.Що робить
Має клієнта kw_event_has_clientНіB2B-режим: подія на замовлення зовнішнього клієнта, якому виставляють рахунок.
Учасники впливають на бюджет kw_is_attendee_affect_budgetТакУвімкнено → витрати/дохід на місце множаться на к-сть учасників. Вимкнено → фіксований бюджет незалежно від відвідуваності (flat-fee).
Часовий пояс default_timezoneТЗ за замовчуванням для подій цього типу (Europe/Kyiv).
Принцип «вимкнув → не створюється». Коли вкладка вимкнена, це не просто приховування: відповідні записи (листи спілкування, питання) не створюються взагалі. Це важливо для чистоти даних.

6. Створюємо екскурсію в каталозі

Практична частина. Створюємо каталог «Оглядова екскурсія Старим Києвом» — шаблон, з якого далі штампуватимемо конкретні виїзди.

1Відкрийте «Події → Каталог» і натисніть «Новий»

Заповніть шапку каталогу:

  • Каталожна назва — «Оглядова екскурсія Старим Києвом».
  • Тривалість 2,5 · Тип інтервалу — годин (екскурсія триває 2,5 год).
  • Типи подій — обидва: «Регулярна екскурсія» і «Індивідуальна екскурсія» (каталог годиться для обох форматів).
  • Місце початку — «Майдан Незалежності», «Золоті ворота».
  • Мова — Українська, Англійська.
  • Базова ціна квитка — 400 грн (від неї рахуються знижки пресету).
  • Набір квитків — «Стандартні квитки екскурсії» (Повний/Пільговий/Дитячий).
  • Запланована кількість людей 20 · Мінімум місць 10 (нижче — тур скасовується).
  • Метод розрахунку витрат за замовчуванням — «За подію» (так рахується гонорар гіда).

2Вкладка «Витрати» — собівартість туру

Додайте види витрат, що автоматично потраплятимуть у кожну подію з цього каталогу: «Оренда автобуса» (фікс 2000, отримувач — Партнер) та «Вхідні квитки до музею» (60 грн/особа, отримувач — Гід, бо гід купує квитки на місці готівкою).

3Вкладка «Хто може проводити»

Закріпіть гіда за каталогом: «Олександр Екскурсовод», тип виступу «Екскурсовод», розрахунок «За подію». Цей гід підставлятиметься в нові події за замовчуванням.

Форма каталогу екскурсії
Готовий каталог «Оглядова екскурсія Старим Києвом»: шапка з усіма параметрами + вкладка «Витрати» з видами витрат і отримувачами оплати.

7. Регулярна подія з каталогу

З каталогу створюємо регулярний виїзд на конкретну дату з авто-згенерованими квитками.

1На каталозі натисніть «Створити подію»

Відкривається майстер, попередньо заповнений із каталогу: каталог, Категорія = «Регулярна екскурсія», мова, набір квитків, запланована/мінімальна к-сть, гід. Лишається задати дату/час і місце початку.

Майстер створення події з каталогу
Майстер «Створити подію»: усе підтягнулось із каталогу; гід «Олександр Екскурсовод» з типом розрахунку «За подію» вже в списку виконавців.

2Подію створено — квитки згенерувались автоматично

Натисніть «Створити подію». Система створює event.event і з пресету каталогу сама генерує квитки з розрахованими цінами та вікнами продажу. Зверху — лічильники (Учасники, Оплати, Витрати), статуси «Новий → Зарезервовано → Оголошено → Закінчений», вкладки suite (Квитки, Зв'язок, Витрати, Запитання, Гонорари, Розрахунки з гідом, Маркетинг, Бюджет).

Форма створеної регулярної події
Готова регулярна подія: дата 30 черв. 13:00→15:30, шаблон «Регулярна екскурсія», місце «Золоті ворота», план 20 / мінімум 10.

3Вкладка «Квитки»

Три типи квитків з пресету, ціни розраховані від базової 400 ₴: Повний 400 ₴, Пільговий 200 ₴ (−50%), Дитячий 0 ₴ (−100%). Вікна продажу: відкрито за 30 днів, закрито за 1 день до події.

Згенеровані квитки з цінами
Авто-згенеровані квитки: знижки пресету застосовані до базової ціни, дата кінця продажу = за день до екскурсії.

8. Індивідуальна подія

Той самий каталог, але індивідуальний захід на замовлення (режим «є клієнт»).

1Створення з тим самим каталогом, але іншою категорією

У майстрі «Створити подію» змініть Категорію на «Індивідуальна екскурсія». Каталог один і той самий — змінюється лише тип події, а з ним і поведінка.

Майстер з категорією Індивідуальна
Той самий каталог, обрана категорія «Індивідуальна екскурсія».

2Різниця: зʼявляється поле «Клієнт»

Оскільки тип «Індивідуальна екскурсія» має увімкнений прапор «Має клієнта», на події зʼявляється поле Клієнт — замовник заходу, якому виставлятимуть рахунок за весь тур (а не продаватимуть окремі квитки відвідувачам). Вкладка «Зв'язок» одразу містить автоматичні листи (підтвердження, нагадування за 1 год і за 3 дні) — це фіча «Показати вкладку Спілкування».

Форма індивідуальної події з полем Клієнт
Індивідуальна подія: поле «Клієнт» (замовник) + автоматичні комунікації. Це і є практична різниця між регулярним (продаж квитків людям) та індивідуальним (продаж туру клієнту) форматами.
Один каталог — два формати. Каталог описує зміст екскурсії (маршрут, тривалість, собівартість, гід). Тип події вирішує як її продавати: регулярна — роздрібно по квитках; індивідуальна — оптом одному клієнту.

9. Як записувати людей і продавати квитки

Реєстрація учасників + продаж квитків + прийом оплати — все в одному майстрі «Запис/Квитки».

1Кнопка «Запис/Квитки» на події

Відкриває майстер продажу. Заповніть:

  • Партнер — покупець (хто оплачує; для роздрібу можна загального).
  • Прайс-лист — обовʼязковий.
  • Кількості по типах квитків (напр. Повний ×3, Пільговий ×2).
  • Тип оплати «Оплата гіду» + Куди сплачуютькаса гіда, якщо гроші збирає гід на місці готівкою. Саме так надходження потрапляють у гаманець гіда для подальшого розрахунку.
Майстер продажу квитків
Продаж: 3×Повний + 2×Пільговий = 5 квитків на 1 600 ₴, оплата в «Касу гіда — Олександр».

2«Купити квитки» — що відбувається

Одна дія робить одразу все:

  • створює 5 реєстрацій (учасників) у стані «open»;
  • створює замовлення на продаж (SO) з рядками-квитками;
  • реєструє платіж 1 600 ₴ у касу гіда (статус «оплачено»).

Кнопка «Запис без оплати» — лише реєструє людей без прийому грошей (оплата пізніше).

3Бюджет одразу оновлюється

Вкладка «Бюджет» показує матрицю в трьох станах. Числа круглі, бо компанія без ПДВ:

  • Заплановано (на 20 місць): дохід 8 000, витрати 3 700 (автобус 2 000 + вхідні 60×20 + гонорар 500), баланс +4 300.
  • Записано (5 фактичних): дохід 1 600, витрати 2 800 (вхідні 60×5=300), баланс −1 200.
  • Оплачено: 1 600 надійшло, баланс +1 600.
Матриця бюджету події
Бюджет-матриця: дохід (Вхідні) / витрати (Вихідні) / Баланс × Заплановано / Записано / Оплачено. Перераховується автоматично при кожному продажу.

4Прийняти оплату пізніше — масово зі списку учасників

Якщо людей записали через «Запис без оплати», гроші можна прийняти згодом одразу від кількох учасників, не відкриваючи кожного окремо.

  • Відкрийте список учасників події → відмітьте галочками потрібних → у шапці списку зʼявиться кнопка «Прийняти оплату».
  • У майстрі поле «Журнал» за замовчуванням підтягує касу основного гіда події (можна змінити). Нижче — рядок на кожного вибраного учасника з полем «Сума» (за замовчуванням несплачений залишок), суму можна редагувати.
  • «Зареєструвати» реєструє платіж по кожному рядку → учасники переходять у стан «Оплачено», а стовпець «Оплачено» у Бюджеті оновлюється.
  • Обмеження: усі вибрані учасники мають належати одній події; якщо серед них є вже повністю оплачений або без замовлення на продаж — майстер зупиниться з попередженням.

5Статуси учасника у списку

У списку учасників (та у статус-барі картки) стан кожної реєстрації позначено кольоровим тегом:

Непідтверджено Підтверджено Оплачено Відвідав Скасовано
  • Непідтверджено — реєстрація в чернетці, оплату/підтвердження ще не отримано.
  • Підтверджено — учасника підтверджено (раніше називалося «Зареєстровано»). Нова назва діє скрізь: у списку, у статус-барі картки та у фільтрах.
  • Оплачено — оплату прийнято повністю.
  • Відвідав — учасник прийшов на подію.
  • Скасовано — реєстрацію скасовано (мʼяке видалення).
Кнопки в рядку списку: «Сплатити» прихована для Скасовано реєстрацій (платити нема за що). Кнопка «Позначити як Прийшов» залишається доступною навіть для Оплачено учасників — оплата не закриває можливість відмітити прихід.

10. Концепція оплати гіду та взаєморозрахунок

Це найтонша частина. Ідея: гід має власний «гаманець» (каса), у який падають готівкові оплати з його екскурсій, і з якого оплачуються його витрати й гонорар. Після туру рахується, хто кому винен, і робиться один підсумковий переказ.

10.1 Гаманець гіда

Кожному гіду автоматично заводиться окрема каса («Готівка в <ім'я>») — щойно партнера позначено «Виконавець». Окремо її створювати не треба. Баланс каси = скільки готівки «на руках» у гіда. Позитивний — гід має нашу готівку; відʼємний — компанія винна гіду.

10.2 Вкладка «Розрахунки з гідом» (одна екскурсія)

На події вкладка показує чотири блоки:

БлокЩо це
Надходження (Receipts)Готівка, що впала в гаманець гіда з продажів цієї події.
Витрати й гонорари (Owed)Скільки винні гіду: його витрати (cash_recipient = performer) + його ставка.
Сплачено (Paid)Скільки вже виплачено по рахунках підрядника.
До сплати = max(Owed − Paid, 0)Залишок. Якщо > 0 — зʼявляється кнопка «Сплатити».

Підсумок події:

net = Надходження − Винні_гіду − Раніше_переказано
Гід винен компанії = max(net, 0)
Компанія винна гіду = max(−net, 0)
Розраховано?        = усі «До сплати» = 0  І  net = 0
Вкладка Розрахунки з гідом
Реальна вкладка «Розрахунки з гідом» нашої екскурсії: надходження від квитків 1 600 ₴, винні гіду 800 ₴ (вхідні 300 + гонорар 500), підсумок «Борг компанії: 800 ₴» + кнопка «Перевести компанії».
Розбір цього прикладу (з екрана вище).
Гід зібрав готівкою в свій гаманець: 1 600 ₴ (5 квитків).
Компанія винна гіду: гонорар 500 ₴ + вхідні квитки, що він купив за свої 300 ₴ = 800 ₴.
net = 1 600 − 800 = 800 ₴гід винен компанії 800 ₴.
Кнопки «Оплатити» гасять гонорар і витрати гіда (стовпчик «Оплачено»), а «Перевести компанії» переказує підсумкові 800 ₴ з гаманця гіда в касу компанії — після чого подія стає зеленою (розраховано).

10.3 Взаєморозрахунок по кількох екскурсіях

Кнопка «Розрахувати» у списку подій відкриває майстер (kw.event.guide.multi.settlement.wizard), що зводить гіда одразу по кількох турах, пулячи його гаманець:

  1. Обираєте гіда (зі списку гідів з касою).
  2. Підтягуються всі нерозраховані тури цього гіда.
  3. Кожен тур показує «гід винен компанії» або «компанія винна гіду»; галочкою обираєте, які звести.
  4. Майстер рахує net по всіх обраних — прибуткова екскурсія перекриває збиткову.
  5. По кожній події гасяться рахунки з гаманця, фіксується kw_settlement_transferred, і робиться один підсумковий переказ пулового net.
Приклад двох екскурсій.
Тур А: гід винен компанії 1200 грн. Тур Б: компанія винна гіду 300 грн (виїзд був збитковим/гід доплатив за вхідні).
Пуловий net = 1200 − 300 = 900 грн → один переказ: гід здає 900 грн. Замість двох окремих рухів — один.

10.4 Кольори списку турів

КолірУмоваЗначення
🔴 Червонийkw_under_min_seatsНе набрано мінімум місць.
🔵 Синійє активність, не розрахованоЄ нерозраховані витрати/гонорари — треба звести.
🟢 Зеленийє активність, розрахованоПовністю зведено (усе сплачено, net = 0).
⚪ Без кольорунемає активностіНічого робити.

11. REST API

Модуль kw_events_api дає REST-ендпоінти /kw_api/* для інтеграції із зовнішнім сайтом (WordPress/WooCommerce): створення подій, реєстрація учасників, продаж і оплата квитків. Автентифікація — токенна.

11.1 Автентифікація

Спершу отримуєте токен, далі передаєте його у заголовку Authorization: Bearer <token> (або access_token). Токен живе 24 год (налаштовується).

POST /kw_api/event_auth

// запит
{ "db": "event19", "login": "admin", "password": "admin" }

// відповідь
{ "status":"200", "result":"OK",
  "data": { "uid":2, "access_token":"abc123…", "expires_in":"2026-07-01 12:30:45" } }

11.2 Створення події

POST /kw_api/create_event  (потрібен токен)

Створює подію з каталогу. Ідемпотентно за ключем слоту (catalog_id, date_begin, date_end) — повторний виклик не плодить дублі.

ПараметрОбовʼязк.Опис
event_nameтакНазва події.
start_datetime / end_datetimeтакISO 8601, у ТЗ користувача.
catalog_idніКаталог-шаблон (місця, мова, гіди, ціни).
event_type_idніТип події.
seats_max / seats_planніМакс. і планована к-сть місць.
base_ticket_priceніБазова ціна для пресетів квитків.
disc_priceніЦіна пільгового квитка (перевизначає формулу пресета).
preset_id, guide_id, language_idніПресет квитків, гід, мова.
utm_source/medium/campaignніUTM-мітки.
curl -X POST https://HOST/kw_api/create_event \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "event_name": "Оглядова Старим Києвом — 15.08",
    "start_datetime": "2026-08-15T11:00:00",
    "end_datetime":   "2026-08-15T13:30:00",
    "catalog_id": 5,
    "seats_max": 25,
    "base_ticket_price": 400
  }'
// → { "data": { "event_id": 42 } }

11.3 Реєстрація / продаж квитків

POST /kw_api/create_registration

Створює один або кілька квитків-реєстрацій. Ідемпотентно за order (advisory-lock проти подвійного спрацювання). Кожен квиток — у власному savepoint.

ПараметрОбовʼязк.Опис
event_idтакID події.
tickets[]такМасив: ticket_id (значення атрибута типу квитка), price, опц. coupon_code, certificate_number.
orderніЗовнішній № замовлення (WP) — вмикає ідемпотентність.
name, email, phoneніДані учасника.
is_paid, journal_idніПозначити оплаченим + журнал для реєстрації платежу.
payment_statusні0=чернетка · 1=відкрито · 2=оплачено.
curl -X POST https://HOST/kw_api/create_registration \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "event_id": 42,
    "order": "WP-2026-08-001",
    "tickets": [ { "ticket_id": 1, "price": 400 } ],
    "name": "Олена Коваль", "email": "olena@example.com",
    "phone": "+380501234567", "is_paid": true, "journal_id": 6, "payment_status": 2
  }'
// → { "data": { "event_id":42, "registrations":[123], "order":"WP-2026-08-001" } }

11.4 Інші ендпоінти

МетодШляхПризначення
PUT/kw_api/change_registrationЗамінити всі квитки замовлення (видаляє старі, створює нові). Заборонено для оплачених.
PUT/kw_api/update_registrationОновити лише статус оплати (payment_status) без перестворення квитків.
DELETE/kw_api/delete_registrationСкасувати реєстрації замовлення (state = cancel, мʼяке видалення).

11.5 Формат відповіді

{
  "status":  "200",          // код HTTP рядком
  "result":  "OK",           // OK | error
  "error":   "",             // код помилки: auth_error | parameters_missing | validation_error
  "message": "",             // повідомлення для користувача
  "data":    { ... },        // корисне навантаження
  "count":   1               // к-сть полів у data
}

11.6 Повний приклад (Python)

import requests
BASE = "https://HOST"

# 1. токен
tok = requests.post(f"{BASE}/kw_api/event_auth",
    json={"db":"event19","login":"admin","password":"admin"}
).json()["data"]["access_token"]
H = {"Authorization": f"Bearer {tok}"}

# 2. подія
ev = requests.post(f"{BASE}/kw_api/create_event", headers=H, json={
    "event_name":"Оглядова Старим Києвом — 15.08",
    "start_datetime":"2026-08-15T11:00:00",
    "end_datetime":"2026-08-15T13:30:00",
    "catalog_id":5, "seats_max":25, "base_ticket_price":400
}).json()["data"]["event_id"]

# 3. продаж квитка + оплата
requests.post(f"{BASE}/kw_api/create_registration", headers=H, json={
    "event_id":ev, "order":"WP-2026-08-001",
    "tickets":[{"ticket_id":1,"price":400}],
    "name":"Олена Коваль","email":"olena@example.com",
    "is_paid":True,"journal_id":6,"payment_status":2
})