feat: checklists, minibar and deposit modules

- DB migrations 057-059: checklist_templates/items/completions, minibar_items/consumptions, hotel_deposit_settings, booking_deposits
- Backend routes: checklists (templates CRUD + task completions), minibar (items + consumptions), deposit (settings, cash/yookassa hold, release/capture)
- YooKassa service for hold/capture/cancel payments
- Frontend: ChecklistSettingsPage, MinibarSettingsPage, DepositSettingsPage
- HousekeepingPage: task cards now show checklist + minibar panel with checkboxes and quantity buttons
- BookingModal: minibar charges summary + deposit management (cash/YooKassa/release) for existing bookings
- Sidebar + App.tsx: new routes /settings/checklists, /settings/minibar, /settings/deposit

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-02 19:24:53 +03:00
parent ed2dfd4c7f
commit 3c1a6ccebf
17 changed files with 2569 additions and 9 deletions

View File

@@ -0,0 +1,27 @@
-- Шаблоны чек-листов
CREATE TABLE checklist_templates (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
hotel_id UUID NOT NULL REFERENCES hotels(id) ON DELETE CASCADE,
name TEXT NOT NULL,
task_type TEXT, -- 'checkout', 'daily', 'deep', NULL = all types
is_active BOOLEAN NOT NULL DEFAULT true,
sort_order INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE checklist_items (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
template_id UUID NOT NULL REFERENCES checklist_templates(id) ON DELETE CASCADE,
text TEXT NOT NULL,
sort_order INTEGER NOT NULL DEFAULT 0
);
-- Отметки выполнения пункта (привязаны к задаче уборки)
CREATE TABLE checklist_completions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
task_id UUID NOT NULL REFERENCES housekeeping_tasks(id) ON DELETE CASCADE,
item_id UUID NOT NULL REFERENCES checklist_items(id) ON DELETE CASCADE,
completed_by UUID REFERENCES users(id),
completed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(task_id, item_id)
);

View File

@@ -0,0 +1,22 @@
CREATE TABLE minibar_items (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
hotel_id UUID NOT NULL REFERENCES hotels(id) ON DELETE CASCADE,
name TEXT NOT NULL,
price NUMERIC(10,2) NOT NULL DEFAULT 0,
category TEXT,
is_active BOOLEAN NOT NULL DEFAULT true,
sort_order INTEGER NOT NULL DEFAULT 0
);
CREATE TABLE minibar_consumptions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
hotel_id UUID NOT NULL REFERENCES hotels(id),
room_id UUID NOT NULL REFERENCES rooms(id),
booking_id UUID REFERENCES bookings(id),
task_id UUID REFERENCES housekeeping_tasks(id),
item_id UUID NOT NULL REFERENCES minibar_items(id),
quantity INTEGER NOT NULL DEFAULT 1,
price_per_unit NUMERIC(10,2) NOT NULL,
recorded_by UUID REFERENCES users(id),
recorded_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

View File

@@ -0,0 +1,34 @@
CREATE TABLE hotel_deposit_settings (
hotel_id UUID PRIMARY KEY REFERENCES hotels(id) ON DELETE CASCADE,
is_enabled BOOLEAN NOT NULL DEFAULT false,
amount NUMERIC(10,2) NOT NULL DEFAULT 5000,
yookassa_shop_id TEXT,
yookassa_secret_key TEXT,
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE booking_deposits (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
hotel_id UUID NOT NULL REFERENCES hotels(id),
booking_id UUID NOT NULL REFERENCES bookings(id),
amount NUMERIC(10,2) NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
-- pending = ожидает оплаты
-- paid_cash = оплачен наличными
-- hold_created = холд создан в ЮКасса
-- hold_confirmed = холд подтверждён (webhook)
-- captured = частично/полностью списано
-- refunded = возвращён полностью
-- cancelled = отменён
payment_method TEXT, -- 'cash', 'yookassa_hold'
yookassa_payment_id TEXT,
yookassa_confirmation_url TEXT,
captured_amount NUMERIC(10,2),
retention_reason TEXT,
guest_email_sent BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
paid_at TIMESTAMPTZ,
released_at TIMESTAMPTZ
);
CREATE INDEX ON booking_deposits(booking_id);