Changes between Version 2 and Version 3 of DatabaseProgramming


Ignore:
Timestamp:
05/06/26 13:27:13 (3 weeks ago)
Author:
231035
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • DatabaseProgramming

    v2 v3  
    6868    execute function trg_review_only_completed_booking();
    6969}}}
    70 == Only an available room can be booked
    71 {{{
    72 
    73 create or replace function trg_room_is_available_for_booking()
    74 returns trigger
    75 as $$
    76     begin
    77     if new.check_in_date > new.check_out_date then
    78         raise exception 'Booking start date cannot be after end date';
    79     end if;
    80 
    81 
    82     if not exists(
    83         select 1
     70== Check if a room is available
     71{{{
     72create or replace function fn_is_room_available(p_room_id bigint,p_check_in_date date, p_check_out_date date)
     73returns boolean
     74language plpgsql
     75as $$
     76    begin
     77        if p_check_in_date >= p_check_out_date then
     78            return false;
     79        end if;
     80
     81        if not exists(
     82            select 1
     83            from rooms r
     84            where r.room_id = p_room_id
     85            and r.status = 'ACTIVE'
     86        )then
     87            return false;
     88        end if;
     89
     90        if exists(
     91            select 1
     92            from bookings b
     93            where b.room_id = p_room_id
     94            and b.booking_status in ('PENDING','CONFIRMED')
     95            and daterange(b.check_in_date,b.check_out_date,'[)')
     96            && daterange(p_check_in_date,p_check_out_date,'[)')
     97        )then
     98            return false;
     99        end if;
     100        return true;
     101    end;
     102    $$;
     103}}}
     104== Calculate the number of nights stayed
     105{{{
     106create or replace function fn_calculate_nights(p_check_in_date date, p_check_out_date date)
     107returns int
     108language plpgsql
     109as $$
     110    begin
     111        if p_check_in_date >= p_check_out_date then
     112            raise exception 'Check out must be after check in';
     113        end if;
     114        return p_check_out_date - p_check_in_date;
     115    end;
     116    $$;
     117}}}
     118== Calculate the total price of a booking
     119{{{
     120create or replace function fn_calculate_booking_price(p_room_id bigint, p_check_in_date date,p_check_out_date date,
     121p_guest_count int)
     122returns numeric
     123language plpgsql
     124as $$
     125    declare
     126        v_price_per_night numeric;
     127        v_capacity int;
     128        v_extra_capacity int;
     129        v_extra_guest_price numeric;
     130
     131        v_nights int;
     132        v_room_total numeric;
     133        v_amenities_total numeric;
     134        v_extra_guests int;
     135        v_extra_guest_total numeric;
     136        v_total numeric;
     137    begin
     138        select
     139            r.price_per_night,
     140            r.capacity,
     141            coalesce(r.extra_capacity,0),
     142            coalesce(r.extra_guest_price,0)
     143        into
     144        v_price_per_night,
     145            v_capacity,
     146            v_extra_capacity,
     147            v_extra_guest_price
    84148        from rooms r
    85         where r.room_id = new.room_id
    86         and r.status = 'ACTIVE'
    87     )then
    88         raise exception 'Room is not active';
    89     end if;
    90 
    91     if exists(
    92         select 1
    93         from bookings b
    94         where b.room_id = new.room_id
    95         and b.booking_status in ('PENDING','CONFIRMED')
    96         and b.booking_id <> new.booking_id
    97         and (
    98             (new.check_in_date,new.check_out_date)
    99             overlaps
    100             (b.check_in_date,b.check_out_date)
    101             )
    102     )then
    103         raise exception 'Room is already booked';
    104     end if;
    105 
    106     return new;
    107 
    108     end;
    109     $$ language plpgsql;
    110 create or replace trigger book_only_available_room
    111     before insert or update on bookings for each row
    112     execute function trg_room_is_available_for_booking();
    113 }}}
     149        where r.room_id = p_room_id;
     150
     151        if p_check_in_date>=p_check_out_date then
     152            raise exception 'Check out must be after check in';
     153        end if;
     154        v_nights := p_check_in_date - p_check_out_date;
     155        if p_guest_count > v_capacity + v_extra_capacity then
     156            raise exception 'Guest count exceeds';
     157        end if;
     158        v_room_total := v_price_per_night * v_nights;
     159
     160        select coalesce(sum(a.price),0)
     161        into v_amenities_total
     162        from room_amenities ra
     163        join amenities a on a.amenity_id = ra.amenity_id
     164        where ra.room_id = p_room_id
     165        and a.is_included = false;
     166
     167        v_extra_guests := greatest(p_guest_count-v_capacity,0);
     168        v_extra_guest_total := v_extra_guests*v_extra_guest_price*v_nights;
     169
     170        v_total := v_room_total + v_extra_guest_total +v_amenities_total;
     171        return v_total;
     172
     173    end;
     174    $$;
     175}}}
     176== Cancel a booking
     177{{{
     178create or replace procedure sp_cancel_booking(p_booking_id bigint)
     179language plpgsql
     180as $$
     181    declare
     182        v_status varchar;
     183    begin
     184        select b.booking_status
     185        into v_status
     186            from bookings b
     187        where booking_id = p_booking_id;
     188
     189        if v_status is null then
     190            raise exception 'Booking does not exsists';
     191        end if;
     192
     193        if v_status = 'COMPLETED' then
     194            raise exception 'Completed booking cannot be canceled';
     195        end if;
     196        if v_status = 'CANCELLED' then
     197            raise exception 'The booking is already cancelled';
     198        end if;
     199
     200        update bookings
     201        set booking_status = 'CANCELLED'
     202        where booking_id = p_booking_id;
     203
     204    end;
     205    $$;
     206}}}
     207== Complete old bookings
     208{{{
     209create or replace procedure  sp_complete_finished_bookings()
     210language plpgsql
     211as $$
     212    begin
     213        update bookings
     214        set booking_status = 'COMPLETED'
     215        where booking_status = 'CONFIRMED'
     216        and check_out_date < current_date;
     217    end;
     218    $$;
     219}}}