| | 248 | Останати рефакторирани процедури |
| | 249 | {{{ |
| | 250 | create or replace procedure make_request( |
| | 251 | out request_id int4, |
| | 252 | in customer_id int4, |
| | 253 | in start_position geometry, |
| | 254 | in end_position geometry, |
| | 255 | in number_of_adult_passengers int4 default 1, |
| | 256 | in number_of_children int4 default 0, |
| | 257 | in female_driver boolean default false, |
| | 258 | in luggage boolean default false, |
| | 259 | in luggage_count int4 default 0, |
| | 260 | in baby_seat_count int4 default 0 |
| | 261 | ) |
| | 262 | language plpgsql as |
| | 263 | $$ |
| | 264 | begin |
| | 265 | if not exists(select user_id |
| | 266 | from customer c |
| | 267 | where c.user_id = customer_id) |
| | 268 | then |
| | 269 | raise exception 'Customer with id % does not exist', customer_id; |
| | 270 | end if; |
| | 271 | |
| | 272 | if number_of_adult_passengers < 0 then |
| | 273 | raise exception 'Number of adult passengers cannot be negative'; |
| | 274 | end if; |
| | 275 | |
| | 276 | if number_of_children < 0 then |
| | 277 | raise exception 'Number of children cannot be negative'; |
| | 278 | end if; |
| | 279 | |
| | 280 | if number_of_adult_passengers + number_of_children < 0 then |
| | 281 | raise exception 'There must be at least 1 passenger'; |
| | 282 | end if; |
| | 283 | |
| | 284 | if baby_seat_count < 0 then |
| | 285 | raise exception 'Baby seat count cannot be negative'; |
| | 286 | end if; |
| | 287 | |
| | 288 | if luggage = false and luggage_count > 0 then |
| | 289 | raise exception 'Luggage count cannot be greater than zero if the luggage flag is set to false.'; |
| | 290 | end if; |
| | 291 | |
| | 292 | if luggage = true and luggage_count <= 0 then |
| | 293 | raise exception 'Invalid luggage count parameters'; |
| | 294 | end if; |
| | 295 | |
| | 296 | if start_position = end_position then |
| | 297 | raise exception 'Start and destination location cannot be the same'; |
| | 298 | end if; |
| | 299 | |
| | 300 | insert into request(customer_user_id, start_latitude, start_longitude, end_latitude, end_longitude, timestamp, |
| | 301 | number_of_adult_passengers, number_of_children, status, female_driver, luggage, luggage_count, |
| | 302 | baby_seat_count, start_location, |
| | 303 | end_location) |
| | 304 | values (customer_id, |
| | 305 | ST_Y(start_position::geometry), |
| | 306 | ST_X(start_position::geometry), |
| | 307 | ST_Y(end_position::geometry), |
| | 308 | ST_X(end_position::geometry), |
| | 309 | now(), |
| | 310 | make_request.number_of_adult_passengers, |
| | 311 | make_request.number_of_children, |
| | 312 | 'pending', |
| | 313 | make_request.female_driver, |
| | 314 | make_request.luggage, |
| | 315 | make_request.luggage_count, |
| | 316 | make_request.baby_seat_count, |
| | 317 | make_request.start_position, |
| | 318 | make_request.end_position) |
| | 319 | returning id into request_id; |
| | 320 | commit; |
| | 321 | end; |
| | 322 | $$; |
| | 323 | |
| | 324 | create or replace procedure start_ride( |
| | 325 | in v_offer_id int4 |
| | 326 | ) |
| | 327 | language plpgsql as |
| | 328 | $$ |
| | 329 | declare |
| | 330 | v_request_id int4; |
| | 331 | v_driver_id int4; |
| | 332 | v_vehicle_vin varchar(17); |
| | 333 | begin |
| | 334 | if not exists(select id from offer where id = v_offer_id) then |
| | 335 | raise exception 'Offer with id % does not exist', v_offer_id; |
| | 336 | end if; |
| | 337 | |
| | 338 | if not exists (select 1 |
| | 339 | from offer |
| | 340 | where id = v_offer_id |
| | 341 | and status = 'pending') then |
| | 342 | raise exception 'Offer % is not pending', v_offer_id; |
| | 343 | end if; |
| | 344 | |
| | 345 | v_request_id := (select o.request_id |
| | 346 | from offer o |
| | 347 | where o.id = v_offer_id); |
| | 348 | |
| | 349 | v_driver_id := (select driver_user_id from offer where id = v_offer_id); |
| | 350 | |
| | 351 | if v_driver_id is null then |
| | 352 | raise exception 'No active drivers available'; |
| | 353 | end if; |
| | 354 | |
| | 355 | v_vehicle_vin := (select vin_vehicle |
| | 356 | from driver_vehicle |
| | 357 | where id_driver = v_driver_id |
| | 358 | and (time_to is null or time_to > now()) |
| | 359 | limit 1); |
| | 360 | |
| | 361 | if v_vehicle_vin is null then |
| | 362 | raise exception 'No active vehicle for driver %', v_driver_id; |
| | 363 | end if; |
| | 364 | |
| | 365 | insert into ride(start_time, |
| | 366 | end_time, |
| | 367 | distance_traveled, |
| | 368 | vehicle_vin, |
| | 369 | driver_user_id, |
| | 370 | request_id, |
| | 371 | status, |
| | 372 | offer_id) |
| | 373 | values (now(), |
| | 374 | null, |
| | 375 | 0, |
| | 376 | v_vehicle_vin, |
| | 377 | v_driver_id, |
| | 378 | v_request_id, |
| | 379 | 'in_progress', |
| | 380 | v_offer_id); |
| | 381 | |
| | 382 | update offer |
| | 383 | set status='accepted' |
| | 384 | where id = v_offer_id; |
| | 385 | |
| | 386 | update request |
| | 387 | set status='accepted' |
| | 388 | where id = v_request_id; |
| | 389 | |
| | 390 | commit; |
| | 391 | end; |
| | 392 | $$; |
| | 393 | |
| | 394 | create or replace procedure add_waypoint( |
| | 395 | in v_request_id int4, |
| | 396 | in v_location geometry |
| | 397 | ) |
| | 398 | language plpgsql as |
| | 399 | $$ |
| | 400 | declare |
| | 401 | v_prev_seqno int4; |
| | 402 | begin |
| | 403 | if not exists(select id from request where id = v_request_id) then |
| | 404 | raise exception 'Request with id % does not exist', v_request_id; |
| | 405 | end if; |
| | 406 | |
| | 407 | if exists(select id |
| | 408 | from waypoints w |
| | 409 | where w.request_id = v_request_id |
| | 410 | and ST_DWithin(w.location, v_location, 0.000001)) then |
| | 411 | raise exception 'Waypoint already added'; |
| | 412 | end if; |
| | 413 | |
| | 414 | v_prev_seqno := (select count(*) |
| | 415 | from waypoints w |
| | 416 | where w.request_id = v_request_id); |
| | 417 | |
| | 418 | insert into waypoints(latitude, longitude, seqno, request_id, location) |
| | 419 | values (st_y(v_location), st_x(v_location), v_prev_seqno + 1, v_request_id, v_location); |
| | 420 | commit; |
| | 421 | end; |
| | 422 | $$; |
| | 423 | |
| | 424 | create or replace procedure write_report( |
| | 425 | id_ride int, |
| | 426 | user_id int, |
| | 427 | new_message text, |
| | 428 | new_title text, |
| | 429 | incident_location geometry, |
| | 430 | new_reason text |
| | 431 | ) |
| | 432 | language plpgsql |
| | 433 | as $$ |
| | 434 | begin |
| | 435 | if not exists ( |
| | 436 | select 1 |
| | 437 | from Ride r |
| | 438 | join Request req on r.request_id = req.id |
| | 439 | where r.id = id_ride and req.customer_user_id = user_id |
| | 440 | ) then |
| | 441 | raise exception 'Invalid report: Customer % was not part of Ride %', user_id, id_ride; |
| | 442 | end if; |
| | 443 | |
| | 444 | if exists ( |
| | 445 | select 1 |
| | 446 | from Report |
| | 447 | where ride_id = id_ride and customer_user_id = user_id |
| | 448 | ) then |
| | 449 | raise exception 'Duplicate report: Customer % has already reported Ride %', user_id, id_ride; |
| | 450 | end if; |
| | 451 | |
| | 452 | if trim(new_message) = '' or trim(new_title) = '' or trim(new_reason) = '' then |
| | 453 | raise exception 'Validation error: Title, message, and reason cannot be empty strings.'; |
| | 454 | end if; |
| | 455 | |
| | 456 | insert into report(ride_id, customer_user_id, message, title, location, latitude, longitude, reason) |
| | 457 | values ( |
| | 458 | id_ride, |
| | 459 | user_id, |
| | 460 | new_message, |
| | 461 | new_title, |
| | 462 | st_setsrid(incident_location, 4326), |
| | 463 | ST_Y(incident_location), |
| | 464 | ST_X(incident_location), |
| | 465 | new_reason |
| | 466 | ); |
| | 467 | |
| | 468 | commit; |
| | 469 | end; |
| | 470 | $$; |
| | 471 | }}} |
| | 472 | |