| 1 | package mk.finki.roomreservation.service;
|
|---|
| 2 |
|
|---|
| 3 | import mk.finki.roomreservation.model.ApprovalRequest;
|
|---|
| 4 | import mk.finki.roomreservation.model.ApprovalResult;
|
|---|
| 5 | import mk.finki.roomreservation.model.PendingReservation;
|
|---|
| 6 | import org.springframework.jdbc.core.JdbcTemplate;
|
|---|
| 7 | import org.springframework.stereotype.Service;
|
|---|
| 8 |
|
|---|
| 9 | import java.util.List;
|
|---|
| 10 |
|
|---|
| 11 | @Service
|
|---|
| 12 | public class ApprovalService {
|
|---|
| 13 |
|
|---|
| 14 | private final JdbcTemplate jdbcTemplate;
|
|---|
| 15 |
|
|---|
| 16 | public ApprovalService(JdbcTemplate jdbcTemplate) {
|
|---|
| 17 | this.jdbcTemplate = jdbcTemplate;
|
|---|
| 18 | }
|
|---|
| 19 |
|
|---|
| 20 | public List<PendingReservation> findPendingReservations() {
|
|---|
| 21 | String sql = """
|
|---|
| 22 | SELECT
|
|---|
| 23 | reservation_id,
|
|---|
| 24 | requester_name,
|
|---|
| 25 | reservation_date::text AS reservation_date,
|
|---|
| 26 | start_time::text AS start_time,
|
|---|
| 27 | end_time::text AS end_time,
|
|---|
| 28 | COALESCE(room_code, 'No room') AS room_code,
|
|---|
| 29 | COALESCE(building_name, 'No building') AS building_name,
|
|---|
| 30 | status,
|
|---|
| 31 | COALESCE(requested_equipment, 'No equipment') AS requested_equipment
|
|---|
| 32 | FROM project.v_pending_reservation_details
|
|---|
| 33 | ORDER BY reservation_date, start_time, reservation_id
|
|---|
| 34 | """;
|
|---|
| 35 |
|
|---|
| 36 | return jdbcTemplate.query(sql, (rs, rowNum) ->
|
|---|
| 37 | new PendingReservation(
|
|---|
| 38 | rs.getInt("reservation_id"),
|
|---|
| 39 | rs.getString("requester_name"),
|
|---|
| 40 | rs.getString("reservation_date"),
|
|---|
| 41 | rs.getString("start_time"),
|
|---|
| 42 | rs.getString("end_time"),
|
|---|
| 43 | rs.getString("room_code"),
|
|---|
| 44 | rs.getString("building_name"),
|
|---|
| 45 | rs.getString("status"),
|
|---|
| 46 | rs.getString("requested_equipment")
|
|---|
| 47 | )
|
|---|
| 48 | );
|
|---|
| 49 | }
|
|---|
| 50 |
|
|---|
| 51 | public ApprovalResult approveOrReject(ApprovalRequest request) {
|
|---|
| 52 | validateApprovalRequest(request);
|
|---|
| 53 |
|
|---|
| 54 | String sql = """
|
|---|
| 55 | SELECT *
|
|---|
| 56 | FROM project.fn_approve_or_reject_reservation(
|
|---|
| 57 | ?,
|
|---|
| 58 | ?,
|
|---|
| 59 | CAST(? AS project.approval_decision_domain),
|
|---|
| 60 | ?
|
|---|
| 61 | )
|
|---|
| 62 | """;
|
|---|
| 63 |
|
|---|
| 64 | ApprovalResult result = jdbcTemplate.queryForObject(
|
|---|
| 65 | sql,
|
|---|
| 66 | (rs, rowNum) -> new ApprovalResult(
|
|---|
| 67 | rs.getInt("out_approval_id"),
|
|---|
| 68 | rs.getInt("out_reservation_id"),
|
|---|
| 69 | rs.getString("out_status"),
|
|---|
| 70 | rs.getString("out_decision"),
|
|---|
| 71 | rs.getString("out_decision_time")
|
|---|
| 72 | ),
|
|---|
| 73 | request.reservationId(),
|
|---|
| 74 | request.approverId(),
|
|---|
| 75 | request.decision(),
|
|---|
| 76 | request.note()
|
|---|
| 77 | );
|
|---|
| 78 |
|
|---|
| 79 | if (result == null) {
|
|---|
| 80 | throw new RuntimeException("Approval operation failed.");
|
|---|
| 81 | }
|
|---|
| 82 |
|
|---|
| 83 | return result;
|
|---|
| 84 | }
|
|---|
| 85 |
|
|---|
| 86 | private void validateApprovalRequest(ApprovalRequest request) {
|
|---|
| 87 | if (request.reservationId() <= 0) {
|
|---|
| 88 | throw new IllegalArgumentException("Reservation ID is required.");
|
|---|
| 89 | }
|
|---|
| 90 |
|
|---|
| 91 | if (request.approverId() <= 0) {
|
|---|
| 92 | throw new IllegalArgumentException("Approver ID is required.");
|
|---|
| 93 | }
|
|---|
| 94 |
|
|---|
| 95 | if (request.decision() == null || request.decision().isBlank()) {
|
|---|
| 96 | throw new IllegalArgumentException("Decision is required.");
|
|---|
| 97 | }
|
|---|
| 98 |
|
|---|
| 99 | if (!request.decision().equals("approved") && !request.decision().equals("rejected")) {
|
|---|
| 100 | throw new IllegalArgumentException("Decision must be approved or rejected.");
|
|---|
| 101 | }
|
|---|
| 102 | }
|
|---|
| 103 | } |
|---|