P7: advanced_triggers.sql

File advanced_triggers.sql, 6.2 KB (added by 193284, 8 days ago)
Line 
1CREATE OR REPLACE FUNCTION check_venue_booking_overlap()
2RETURNS TRIGGER AS $$
3BEGIN
4 IF NEW.end_time <= NEW.start_time THEN
5 RAISE EXCEPTION 'Invalid venue booking interval: end_time must be after start_time.';
6 END IF;
7
8 IF EXISTS (
9 SELECT 1
10 FROM venue_booking vb
11 WHERE vb.venue_id = NEW.venue_id
12 AND vb.status <> 'cancelled'
13 AND vb.booking_id <> COALESCE(NEW.booking_id, -1)
14 AND (
15 -- Case 1: new booking starts inside existing booking
16 ((NEW."date" + NEW.start_time) >= (vb."date" + vb.start_time)
17 AND (NEW."date" + NEW.start_time) < (vb."date" + vb.end_time))
18
19 OR
20
21 -- Case 2: new booking ends inside existing booking
22 ((NEW."date" + NEW.end_time) > (vb."date" + vb.start_time)
23 AND (NEW."date" + NEW.end_time) <= (vb."date" + vb.end_time))
24
25 OR
26
27 -- Case 3: new booking fully contains existing booking
28 ((NEW."date" + NEW.start_time) <= (vb."date" + vb.start_time)
29 AND (NEW."date" + NEW.end_time) >= (vb."date" + vb.end_time))
30
31 OR
32
33 -- Case 4: new booking is fully inside existing booking
34 ((NEW."date" + NEW.start_time) >= (vb."date" + vb.start_time)
35 AND (NEW."date" + NEW.end_time) <= (vb."date" + vb.end_time))
36 )
37 ) THEN
38 RAISE EXCEPTION 'Venue is already booked for this date and time interval.';
39 END IF;
40
41 RETURN NEW;
42END;
43$$ LANGUAGE plpgsql;
44
45DROP TRIGGER IF EXISTS trg_venue_booking_overlap ON venue_booking;
46
47CREATE TRIGGER trg_venue_booking_overlap
48BEFORE INSERT OR UPDATE ON venue_booking
49FOR EACH ROW
50EXECUTE FUNCTION check_venue_booking_overlap();
51
52
53CREATE OR REPLACE FUNCTION check_photographer_booking_overlap()
54RETURNS TRIGGER AS $$
55BEGIN
56 IF NEW.end_time <= NEW.start_time THEN
57 RAISE EXCEPTION 'Invalid photographer booking interval: end_time must be after start_time.';
58 END IF;
59
60 IF EXISTS (
61 SELECT 1
62 FROM photographer_booking pb
63 WHERE pb.photographer_id = NEW.photographer_id
64 AND pb.status <> 'cancelled'
65 AND pb.booking_id <> COALESCE(NEW.booking_id, -1)
66 AND (
67 -- Case 1: new booking starts inside existing booking
68 ((NEW."date" + NEW.start_time) >= (pb."date" + pb.start_time)
69 AND (NEW."date" + NEW.start_time) < (pb."date" + pb.end_time))
70
71 OR
72
73 -- Case 2: new booking ends inside existing booking
74 ((NEW."date" + NEW.end_time) > (pb."date" + pb.start_time)
75 AND (NEW."date" + NEW.end_time) <= (pb."date" + pb.end_time))
76
77 OR
78
79 -- Case 3: new booking fully contains existing booking
80 ((NEW."date" + NEW.start_time) <= (pb."date" + pb.start_time)
81 AND (NEW."date" + NEW.end_time) >= (pb."date" + pb.end_time))
82
83 OR
84
85 -- Case 4: new booking is fully inside existing booking
86 ((NEW."date" + NEW.start_time) >= (pb."date" + pb.start_time)
87 AND (NEW."date" + NEW.end_time) <= (pb."date" + pb.end_time))
88 )
89 ) THEN
90 RAISE EXCEPTION 'Photographer is already booked for this date and time interval.';
91 END IF;
92
93 RETURN NEW;
94END;
95$$ LANGUAGE plpgsql;
96
97DROP TRIGGER IF EXISTS trg_photographer_booking_overlap ON photographer_booking;
98
99CREATE TRIGGER trg_photographer_booking_overlap
100BEFORE INSERT OR UPDATE ON photographer_booking
101FOR EACH ROW
102EXECUTE FUNCTION check_photographer_booking_overlap();
103
104
105CREATE OR REPLACE FUNCTION check_band_booking_overlap()
106RETURNS TRIGGER AS $$
107BEGIN
108 IF NEW.end_time <= NEW.start_time THEN
109 RAISE EXCEPTION 'Invalid band booking interval: end_time must be after start_time.';
110 END IF;
111
112 IF EXISTS (
113 SELECT 1
114 FROM band_booking bb
115 WHERE bb.band_id = NEW.band_id
116 AND bb.status <> 'cancelled'
117 AND bb.booking_id <> COALESCE(NEW.booking_id, -1)
118 AND (
119 -- Case 1: new booking starts inside existing booking
120 ((NEW."date" + NEW.start_time) >= (bb."date" + bb.start_time)
121 AND (NEW."date" + NEW.start_time) < (bb."date" + bb.end_time))
122
123 OR
124
125 -- Case 2: new booking ends inside existing booking
126 ((NEW."date" + NEW.end_time) > (bb."date" + bb.start_time)
127 AND (NEW."date" + NEW.end_time) <= (bb."date" + bb.end_time))
128
129 OR
130
131 -- Case 3: new booking fully contains existing booking
132 ((NEW."date" + NEW.start_time) <= (bb."date" + bb.start_time)
133 AND (NEW."date" + NEW.end_time) >= (bb."date" + bb.end_time))
134
135 OR
136
137 -- Case 4: new booking is fully inside existing booking
138 ((NEW."date" + NEW.start_time) >= (bb."date" + bb.start_time)
139 AND (NEW."date" + NEW.end_time) <= (bb."date" + bb.end_time))
140 )
141 ) THEN
142 RAISE EXCEPTION 'Band is already booked for this date and time interval.';
143 END IF;
144
145 RETURN NEW;
146END;
147$$ LANGUAGE plpgsql;
148
149DROP TRIGGER IF EXISTS trg_band_booking_overlap ON band_booking;
150
151CREATE TRIGGER trg_band_booking_overlap
152BEFORE INSERT OR UPDATE ON band_booking
153FOR EACH ROW
154EXECUTE FUNCTION check_band_booking_overlap();
155
156
157CREATE OR REPLACE FUNCTION validate_attendance_consistency()
158RETURNS TRIGGER AS $$
159DECLARE
160 guest_rsvp VARCHAR(30);
161BEGIN
162 SELECT status
163 INTO guest_rsvp
164 FROM event_rsvp
165 WHERE guest_id = NEW.guest_id
166 AND event_id = NEW.event_id;
167
168 IF guest_rsvp = 'declined'
169 AND NEW.status = 'attending' THEN
170 RAISE EXCEPTION 'Declined guests cannot be marked as attending.';
171 END IF;
172
173 RETURN NEW;
174END;
175$$ LANGUAGE plpgsql;
176
177DROP TRIGGER IF EXISTS trg_attendance_consistency ON attendance;
178
179CREATE TRIGGER trg_attendance_consistency
180BEFORE INSERT OR UPDATE ON attendance
181FOR EACH ROW
182EXECUTE FUNCTION validate_attendance_consistency();