feat: tariff selector in BookingModal

- Migration 050: add tariff_id FK to bookings table
- Backend: accept tariff_id in POST/PATCH bookings
- Frontend: load active tariffs in BookingModal, show tariff dropdown
- Price calculation applies tariff modifier (percent or fixed) before discount
- tariffId forwarded through CalendarPage → api.bookings.create/update

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-31 21:02:56 +03:00
parent 249492cf3a
commit 948744e077
6 changed files with 60 additions and 10 deletions

View File

@@ -61,7 +61,7 @@ const bookings: FastifyPluginAsync = async (fastify) => {
fastify.post<SlugParam & { Body: {
room_id: string; guest_name: string; guest_email?: string; guest_phone?: string
check_in: string; check_out: string; adults?: number; children?: number
status?: string; source?: string; total_amount?: number; paid_amount?: number; notes?: string
status?: string; source?: string; total_amount?: number; paid_amount?: number; notes?: string; tariff_id?: string
} }>(
'/api/hotels/:slug/bookings',
{ onRequest: [fastify.authenticate] },
@@ -79,7 +79,7 @@ const bookings: FastifyPluginAsync = async (fastify) => {
const {
room_id, guest_name, guest_email, guest_phone,
check_in, check_out, adults = 1, children = 0,
status = 'confirmed', source = 'direct', total_amount, paid_amount = 0, notes,
status = 'confirmed', source = 'direct', total_amount, paid_amount = 0, notes, tariff_id,
} = request.body
// Check for conflicts (checked_out = early departure, doesn't block new booking)
@@ -97,11 +97,11 @@ const bookings: FastifyPluginAsync = async (fastify) => {
const { rows } = await db.query(
`INSERT INTO bookings
(hotel_id, room_id, guest_name, guest_email, guest_phone, check_in, check_out,
adults, children, status, source, total_amount, paid_amount, notes)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14) RETURNING *`,
adults, children, status, source, total_amount, paid_amount, notes, tariff_id)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) RETURNING *`,
[hotelId, room_id, guest_name, guest_email ?? null, guest_phone ?? null,
check_in, check_out, adults, children, status, source,
total_amount ?? 0, paid_amount, notes ?? null],
total_amount ?? 0, paid_amount, notes ?? null, tariff_id ?? null],
)
return reply.code(201).send(rows[0])
},
@@ -147,7 +147,7 @@ const bookings: FastifyPluginAsync = async (fastify) => {
if (!hotelId) return reply.code(404).send({ error: 'Hotel not found' })
const allowed = ['room_id','guest_name','guest_email','guest_phone','check_in','check_out',
'adults','children','status','source','total_amount','paid_amount','notes']
'adults','children','status','source','total_amount','paid_amount','notes','tariff_id']
const updates: string[] = []
const values: unknown[] = []
let idx = 1