-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsupabase_rentals_table.sql
More file actions
168 lines (150 loc) · 4.03 KB
/
supabase_rentals_table.sql
File metadata and controls
168 lines (150 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
-- Create rentals/bookings table
create table public.rentals (
id uuid primary key default gen_random_uuid(),
user_id uuid references auth.users(id) on delete cascade not null,
bike_id uuid references public.bikes(id) on delete cascade not null,
start_time timestamptz not null default now(),
end_time timestamptz,
duration_minutes integer not null,
planned_end_time timestamptz not null,
price_per_hour numeric(10, 2) not null default 5.00,
total_cost numeric(10, 2),
status text not null default 'active' check (status in ('active', 'completed', 'cancelled')),
start_station_id uuid references public.stations(id),
end_station_id uuid references public.stations(id),
created_at timestamptz default now(),
updated_at timestamptz default now()
);
-- Create indexes for better performance
create index idx_rentals_user_id on public.rentals(user_id);
create index idx_rentals_bike_id on public.rentals(bike_id);
create index idx_rentals_status on public.rentals(status);
create index idx_rentals_start_time on public.rentals(start_time);
-- Create trigger for updated_at
create trigger on_rentals_updated
before update on public.rentals
for each row
execute function public.handle_updated_at();
-- Enable Row Level Security
alter table public.rentals enable row level security;
-- Create policies for rentals
create policy "Users can view their own rentals"
on public.rentals for select
using (auth.uid() = user_id);
create policy "Users can create their own rentals"
on public.rentals for insert
with check (auth.uid() = user_id);
create policy "Users can update their own rentals"
on public.rentals for update
using (auth.uid() = user_id);
-- Function to calculate rental cost
create or replace function public.calculate_rental_cost(
p_rental_id uuid
)
returns numeric
language plpgsql
as $$
declare
v_duration_minutes integer;
v_price_per_hour numeric;
v_total_cost numeric;
begin
select
duration_minutes,
price_per_hour
into
v_duration_minutes,
v_price_per_hour
from public.rentals
where id = p_rental_id;
-- Calculate cost: (duration in minutes / 60) * price per hour
v_total_cost := (v_duration_minutes::numeric / 60) * v_price_per_hour;
return v_total_cost;
end;
$$;
-- Function to complete rental
create or replace function public.complete_rental(
p_rental_id uuid
)
returns void
language plpgsql
security definer
as $$
declare
v_bike_id uuid;
v_total_cost numeric;
v_user_id uuid;
begin
-- Get rental details
select bike_id, user_id
into v_bike_id, v_user_id
from public.rentals
where id = p_rental_id;
-- Calculate total cost
v_total_cost := public.calculate_rental_cost(p_rental_id);
-- Update rental
update public.rentals
set
end_time = now(),
total_cost = v_total_cost,
status = 'completed',
updated_at = now()
where id = p_rental_id;
-- Update bike status back to available
update public.bikes
set
status = 'available',
updated_at = now()
where id = v_bike_id;
-- Update user's total rentals
update public.profiles
set
total_rentals = total_rentals + 1,
balance = balance - v_total_cost
where id = v_user_id;
end;
$$;
-- Function to start rental
create or replace function public.start_rental(
p_user_id uuid,
p_bike_id uuid,
p_duration_minutes integer,
p_price_per_hour numeric default 5.00
)
returns uuid
language plpgsql
security definer
as $$
declare
v_rental_id uuid;
v_planned_end_time timestamptz;
begin
-- Calculate planned end time
v_planned_end_time := now() + (p_duration_minutes || ' minutes')::interval;
-- Create rental
insert into public.rentals (
user_id,
bike_id,
duration_minutes,
planned_end_time,
price_per_hour,
status
)
values (
p_user_id,
p_bike_id,
p_duration_minutes,
v_planned_end_time,
p_price_per_hour,
'active'
)
returning id into v_rental_id;
-- Update bike status to rented
update public.bikes
set
status = 'rented',
updated_at = now()
where id = p_bike_id;
return v_rental_id;
end;
$$;