source: backend/src/main/java/mk/finki/roomreservation/service/ReportService.java

Last change on this file was 09e02d7, checked in by Nikola Sarafimov <sarafimov.nikola12345@…>, 4 days ago

Final room reservation system implementation

  • Property mode set to 100644
File size: 6.7 KB
Line 
1package mk.finki.roomreservation.service;
2
3import mk.finki.roomreservation.model.EquipmentDemandReport;
4import mk.finki.roomreservation.model.RoomUtilizationReport;
5import org.springframework.jdbc.core.JdbcTemplate;
6import org.springframework.stereotype.Service;
7
8import java.util.List;
9
10@Service
11public class ReportService {
12
13 private final JdbcTemplate jdbcTemplate;
14
15 public ReportService(JdbcTemplate jdbcTemplate) {
16 this.jdbcTemplate = jdbcTemplate;
17 }
18
19 public List<RoomUtilizationReport> roomUtilizationReport() {
20 String sql = """
21 SELECT
22 quarter_start::text AS quarter_start,
23 building_name,
24 room_code,
25 type,
26 capacity,
27 total_room_reservations,
28 approved_reservations,
29 rejected_reservations,
30 cancelled_reservations,
31 pending_reservations,
32 requested_hours,
33 approved_hours,
34 approved_hours_share_percent,
35 utilization_rank,
36 utilization_level
37 FROM project.v_quarterly_room_utilization
38 ORDER BY quarter_start, utilization_rank, building_name, room_code
39 """;
40
41 return jdbcTemplate.query(sql, (rs, rowNum) ->
42 new RoomUtilizationReport(
43 rs.getString("quarter_start"),
44 rs.getString("building_name"),
45 rs.getString("room_code"),
46 rs.getString("type"),
47 rs.getInt("capacity"),
48 rs.getLong("total_room_reservations"),
49 rs.getLong("approved_reservations"),
50 rs.getLong("rejected_reservations"),
51 rs.getLong("cancelled_reservations"),
52 rs.getLong("pending_reservations"),
53 rs.getDouble("requested_hours"),
54 rs.getDouble("approved_hours"),
55 rs.getDouble("approved_hours_share_percent"),
56 rs.getInt("utilization_rank"),
57 rs.getString("utilization_level")
58 )
59 );
60 }
61
62 public List<EquipmentDemandReport> equipmentDemandReport() {
63 String sql = """
64 WITH room_stock AS (
65 SELECT
66 re.equipment_id,
67 SUM(re.quantity) AS assigned_room_quantity
68 FROM project.room_equipment re
69 GROUP BY re.equipment_id
70 ),
71 equipment_demand AS (
72 SELECT
73 date_trunc('quarter', res.reservation_date)::date AS quarter_start,
74 e.equipment_id,
75 e.name AS equipment_name,
76 e.stock_quantity,
77 COALESCE(rs.assigned_room_quantity, 0) AS assigned_room_quantity,
78 e.stock_quantity + COALESCE(rs.assigned_room_quantity, 0) AS total_registered_quantity,
79 COUNT(DISTINCT req.reservation_id) AS reservations_with_equipment,
80 SUM(req.requested_quantity) AS total_requested_quantity,
81 COALESCE(SUM(req.requested_quantity) FILTER (WHERE res.status = 'approved'), 0) AS approved_requested_quantity,
82 COALESCE(SUM(req.requested_quantity) FILTER (WHERE res.status = 'pending'), 0) AS pending_requested_quantity,
83 COALESCE(SUM(req.requested_quantity) FILTER (WHERE res.status = 'rejected'), 0) AS rejected_requested_quantity
84 FROM project.reservation_equipment req
85 JOIN project.reservations res
86 ON req.reservation_id = res.reservation_id
87 JOIN project.equipment e
88 ON req.equipment_id = e.equipment_id
89 LEFT JOIN room_stock rs
90 ON e.equipment_id = rs.equipment_id
91 GROUP BY
92 date_trunc('quarter', res.reservation_date)::date,
93 e.equipment_id,
94 e.name,
95 e.stock_quantity,
96 rs.assigned_room_quantity
97 )
98 SELECT
99 quarter_start::text AS quarter_start,
100 equipment_name,
101 stock_quantity,
102 assigned_room_quantity,
103 total_registered_quantity,
104 reservations_with_equipment,
105 total_requested_quantity,
106 approved_requested_quantity,
107 pending_requested_quantity,
108 rejected_requested_quantity,
109 ROUND(
110 total_requested_quantity::numeric / NULLIF(total_registered_quantity, 0) * 100,
111 2
112 ) AS demand_to_registered_percent,
113 DENSE_RANK() OVER (
114 PARTITION BY quarter_start
115 ORDER BY total_requested_quantity DESC, reservations_with_equipment DESC, equipment_name
116 ) AS demand_rank,
117 CASE
118 WHEN total_requested_quantity > total_registered_quantity THEN 'stock_risk'
119 WHEN total_requested_quantity >= total_registered_quantity * 0.75 THEN 'high_demand'
120 WHEN total_requested_quantity > 0 THEN 'normal_demand'
121 ELSE 'no_demand'
122 END AS demand_level
123 FROM equipment_demand
124 ORDER BY quarter_start, demand_rank, equipment_name
125 """;
126
127 return jdbcTemplate.query(sql, (rs, rowNum) ->
128 new EquipmentDemandReport(
129 rs.getString("quarter_start"),
130 rs.getString("equipment_name"),
131 rs.getInt("stock_quantity"),
132 rs.getInt("assigned_room_quantity"),
133 rs.getInt("total_registered_quantity"),
134 rs.getLong("reservations_with_equipment"),
135 rs.getInt("total_requested_quantity"),
136 rs.getInt("approved_requested_quantity"),
137 rs.getInt("pending_requested_quantity"),
138 rs.getInt("rejected_requested_quantity"),
139 rs.getDouble("demand_to_registered_percent"),
140 rs.getInt("demand_rank"),
141 rs.getString("demand_level")
142 )
143 );
144 }
145}
Note: See TracBrowser for help on using the repository browser.