FunctionsProceduresTriggers: 02_procedures.sql

File 02_procedures.sql, 6.4 KB (added by 231184, 5 days ago)

02_procedures

Line 
1-- =====================================================
2-- 1. Book appointment
3-- Inserts appointment and marks selected slot as unavailable
4-- =====================================================
5
6CREATE OR REPLACE PROCEDURE book_appointment(
7 p_customer_id INT,
8 p_employee_id INT,
9 p_business_id INT,
10 p_service_id INT,
11 p_slot_id INT
12)
13 LANGUAGE plpgsql
14AS $$
15BEGIN
16 IF NOT EXISTS (
17 SELECT 1
18 FROM time_slot
19 WHERE slot_id = p_slot_id
20 AND is_available = TRUE
21 ) THEN
22 RAISE EXCEPTION 'Slot % is not available', p_slot_id;
23 END IF;
24
25 INSERT INTO appointment (
26 customer_id,
27 employee_id,
28 business_id,
29 service_id,
30 slot_id,
31 status,
32 created_at
33 )
34 VALUES (
35 p_customer_id,
36 p_employee_id,
37 p_business_id,
38 p_service_id,
39 p_slot_id,
40 'confirmed',
41 CURRENT_TIMESTAMP
42 );
43
44 UPDATE time_slot
45 SET is_available = FALSE
46 WHERE slot_id = p_slot_id;
47END;
48$$;
49
50
51
52-- =====================================================
53-- 2. Cancel appointment
54-- Updates appointment status, frees slot and inserts cancellation
55-- =====================================================
56
57CREATE OR REPLACE PROCEDURE cancel_appointment(
58 p_appointment_id INT,
59 p_cancelled_by TEXT,
60 p_reason TEXT,
61 p_employee_id INT DEFAULT NULL
62)
63 LANGUAGE plpgsql
64AS $$
65DECLARE
66 v_slot_id INT;
67BEGIN
68 SELECT slot_id
69 INTO v_slot_id
70 FROM appointment
71 WHERE appointment_id = p_appointment_id;
72
73 IF v_slot_id IS NULL THEN
74 RAISE EXCEPTION 'Appointment % does not exist', p_appointment_id;
75 END IF;
76
77 UPDATE appointment
78 SET status = 'cancelled'
79 WHERE appointment_id = p_appointment_id;
80
81 UPDATE time_slot
82 SET is_available = TRUE
83 WHERE slot_id = v_slot_id;
84
85 INSERT INTO cancellation (
86 appointment_id,
87 cancelled_by,
88 reason,
89 refund_amount,
90 created_at,
91 employee_id
92 )
93 VALUES (
94 p_appointment_id,
95 p_cancelled_by,
96 p_reason,
97 0,
98 CURRENT_TIMESTAMP,
99 p_employee_id
100 );
101END;
102$$;
103
104
105
106-- =====================================================
107-- 3. Create review for appointment
108-- =====================================================
109
110CREATE OR REPLACE PROCEDURE create_review_for_appointment(
111 p_appointment_id INT,
112 p_customer_id INT,
113 p_employee_id INT,
114 p_manager_id INT,
115 p_business_id INT,
116 p_rating INT,
117 p_comment TEXT
118)
119 LANGUAGE plpgsql
120AS $$
121BEGIN
122 IF p_rating < 1 OR p_rating > 5 THEN
123 RAISE EXCEPTION 'Rating must be between 1 and 5';
124 END IF;
125
126 IF NOT EXISTS (
127 SELECT 1
128 FROM appointment
129 WHERE appointment_id = p_appointment_id
130 ) THEN
131 RAISE EXCEPTION 'Appointment % does not exist', p_appointment_id;
132 END IF;
133
134 INSERT INTO review (
135 appointment_id,
136 customer_id,
137 employee_id,
138 manager_id,
139 business_id,
140 rating,
141 comment,
142 created_at
143 )
144 VALUES (
145 p_appointment_id,
146 p_customer_id,
147 p_employee_id,
148 p_manager_id,
149 p_business_id,
150 p_rating,
151 p_comment,
152 CURRENT_TIMESTAMP
153 );
154END;
155$$;
156
157
158
159-- =====================================================
160-- 5. Approve reschedule request
161-- Updates appointment slot and request status
162-- =====================================================
163
164CREATE OR REPLACE PROCEDURE approve_reschedule_request(
165 p_request_id INT
166)
167 LANGUAGE plpgsql
168AS $$
169DECLARE
170 v_appointment_id INT;
171 v_old_slot_id INT;
172 v_new_slot_id INT;
173BEGIN
174 SELECT appointment_id, old_slot_id, new_slot_id
175 INTO v_appointment_id, v_old_slot_id, v_new_slot_id
176 FROM reschedule_request
177 WHERE request_id = p_request_id
178 AND status = 'pending';
179
180 IF v_appointment_id IS NULL THEN
181 RAISE EXCEPTION 'Pending reschedule request % does not exist', p_request_id;
182 END IF;
183
184 IF NOT EXISTS (
185 SELECT 1
186 FROM time_slot
187 WHERE slot_id = v_new_slot_id
188 AND is_available = TRUE
189 ) THEN
190 RAISE EXCEPTION 'New slot % is not available', v_new_slot_id;
191 END IF;
192
193 UPDATE appointment
194 SET slot_id = v_new_slot_id
195 WHERE appointment_id = v_appointment_id;
196
197 UPDATE time_slot
198 SET is_available = TRUE
199 WHERE slot_id = v_old_slot_id;
200
201 UPDATE time_slot
202 SET is_available = FALSE
203 WHERE slot_id = v_new_slot_id;
204
205 UPDATE reschedule_request
206 SET status = 'approved'
207 WHERE request_id = p_request_id;
208END;
209$$;
210
211
212
213CREATE OR REPLACE PROCEDURE make_employee_slots_unavailable(
214 p_employee_id INT,
215 p_date_from DATE,
216 p_date_to DATE,
217 p_reason TEXT DEFAULT 'Employee unavailable',
218 p_business_id INT DEFAULT NULL
219)
220 LANGUAGE plpgsql
221AS $$
222DECLARE
223 v_booked_count INT;
224 v_updated_count INT;
225BEGIN
226 IF p_date_from > p_date_to THEN
227 RAISE EXCEPTION 'date_from cannot be after date_to';
228 END IF;
229
230 SELECT COUNT(*)
231 INTO v_booked_count
232 FROM time_slot ts
233 JOIN appointment a ON a.slot_id = ts.slot_id
234 WHERE ts.employee_id = p_employee_id
235 AND ts.date BETWEEN p_date_from AND p_date_to
236 AND a.status <> 'cancelled'
237 AND (
238 p_business_id IS NULL
239 OR ts.business_id = p_business_id
240 );
241
242 IF v_booked_count > 0 THEN
243 RAISE EXCEPTION
244 'Cannot make slots unavailable. Employee % has % booked slots between % and %.',
245 p_employee_id, v_booked_count, p_date_from, p_date_to;
246 END IF;
247
248 UPDATE time_slot
249 SET is_available = FALSE
250 WHERE employee_id = p_employee_id
251 AND date BETWEEN p_date_from AND p_date_to
252 AND (
253 p_business_id IS NULL
254 OR business_id = p_business_id
255 );
256
257 GET DIAGNOSTICS v_updated_count = ROW_COUNT;
258
259 RAISE NOTICE
260 'Marked % slots as unavailable for employee % between % and %. Reason: %',
261 v_updated_count, p_employee_id, p_date_from, p_date_to, p_reason;
262END;
263$$;