| | 196 | |
| | 197 | == **ID 3** - Manage Trip |
| | 198 | The `/routes` endpoint allows transport organizers to manage their trips. It includes the ability to **view, add, edit, and delete trips** for their authorized routes. |
| | 199 | |
| | 200 | Here is an example of the flow to manage trips: |
| | 201 | - View routes: `/routes/company` |
| | 202 | - View trips for a specific route: `/routes/company/view-trips/{routeId}` |
| | 203 | - Add a new trip: `/routes/company/view-trips/{routeId}/add-trip` |
| | 204 | - Edit an existing trip: `/routes/company/view-trips/{routeId}/edit-trip/{tripId}` |
| | 205 | - Delete a trip: `/routes/company/view-trips/{routeId}/delete-trip/{tripId}` |
| | 206 | |
| | 207 | === |
| | 208 | {{{ |
| | 209 | @RequestMapping("/routes") |
| | 210 | public class CompanyRouteController { |
| | 211 | private final CompanyRouteService companyRouteService; |
| | 212 | |
| | 213 | public CompanyRouteController(CompanyRouteService companyRouteService) { |
| | 214 | this.companyRouteService = companyRouteService; |
| | 215 | } |
| | 216 | |
| | 217 | @GetMapping("/company") |
| | 218 | public String routes(Model model) { |
| | 219 | model.addAttribute("companyRoutes", companyRouteService.getAuthorizedRoutes()); |
| | 220 | model.addAttribute("display", "/company/company-route"); |
| | 221 | |
| | 222 | return "master"; |
| | 223 | } |
| | 224 | } |
| | 225 | }}} |
| | 226 | |
| | 227 | === |
| | 228 | {{{ |
| | 229 | @RequestMapping("/routes/company/view-trips/{routeId}") |
| | 230 | public class CompanyTripController { |
| | 231 | private final CompanyTripService companyTripService; |
| | 232 | private final RouteService routeService; |
| | 233 | private final LocationService locationService; |
| | 234 | |
| | 235 | public CompanyTripController(CompanyTripService companyTripService, RouteService routeService, LocationService locationService) { |
| | 236 | this.companyTripService = companyTripService; |
| | 237 | this.routeService = routeService; |
| | 238 | this.locationService = locationService; |
| | 239 | } |
| | 240 | |
| | 241 | @GetMapping |
| | 242 | public String routeTrips(@PathVariable Integer routeId, Model model) { |
| | 243 | Route route = routeService.findById(routeId); |
| | 244 | |
| | 245 | model.addAttribute("trips", companyTripService.getAuthorizedTripsByRoute(routeId)); |
| | 246 | model.addAttribute("routeId", routeId); |
| | 247 | model.addAttribute("locations", locationService.findAll()); |
| | 248 | model.addAttribute("routeSource", route.getSource()); |
| | 249 | model.addAttribute("routeDestination", route.getDestination()); |
| | 250 | model.addAttribute("display", "/company/company-view-trip"); |
| | 251 | |
| | 252 | return "master"; |
| | 253 | } |
| | 254 | |
| | 255 | @PostMapping("/add-trip") |
| | 256 | public String addNewTrip(@PathVariable Integer routeId, |
| | 257 | @RequestParam("date") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date, |
| | 258 | @RequestParam("freeSeats") int freeSeats, |
| | 259 | @RequestParam("locations") List<Integer> locationIds, |
| | 260 | @RequestParam("etas") @DateTimeFormat(pattern = "HH:mm") List<LocalTime> etas, |
| | 261 | RedirectAttributes redirectAttributes) { |
| | 262 | |
| | 263 | try { |
| | 264 | Route route = routeService.findById(routeId); |
| | 265 | companyTripService.createTrip(route, date, freeSeats, locationIds, etas); |
| | 266 | redirectAttributes.addFlashAttribute("message", "Trip created successfully!"); |
| | 267 | } catch (IllegalArgumentException | SecurityException e) { |
| | 268 | redirectAttributes.addFlashAttribute("error", e.getMessage()); |
| | 269 | } |
| | 270 | return "redirect:/routes/company/view-trips/" + routeId; |
| | 271 | } |
| | 272 | |
| | 273 | @PostMapping("/edit-trip/{tripId}") |
| | 274 | public String editTrip(@PathVariable Integer routeId, |
| | 275 | @PathVariable Integer tripId, |
| | 276 | @RequestParam("date") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date, |
| | 277 | @RequestParam("freeSeats") int freeSeats, |
| | 278 | @RequestParam("locations") List<Integer> locationIds, |
| | 279 | @RequestParam("etas") @DateTimeFormat(pattern = "HH:mm") List<LocalTime> etas, |
| | 280 | RedirectAttributes redirectAttributes) { |
| | 281 | try { |
| | 282 | Route route = routeService.findById(routeId); |
| | 283 | companyTripService.updateTrip(route, tripId, date, freeSeats, locationIds, etas); |
| | 284 | redirectAttributes.addFlashAttribute("message", "Trip updated successfully!"); |
| | 285 | } catch (IllegalArgumentException | SecurityException e) { |
| | 286 | redirectAttributes.addFlashAttribute("error", e.getMessage()); |
| | 287 | } |
| | 288 | return "redirect:/routes/company/view-trips/" + routeId; |
| | 289 | } |
| | 290 | |
| | 291 | @PostMapping("/delete-trip/{tripId}") |
| | 292 | public String deleteTrip(@PathVariable Integer routeId, @PathVariable Integer tripId) { |
| | 293 | return companyTripService.deleteTripIfAuthorized(tripId) |
| | 294 | ? "redirect:/routes/company/view-trips/" + routeId |
| | 295 | : "redirect:/"; |
| | 296 | } |
| | 297 | } |
| | 298 | }}} |
| | 299 | |
| | 300 | === |
| | 301 | ==== Controller Details for Routes: |
| | 302 | - **URL Mapping:** `/routes/company` |
| | 303 | - **Method:** `GET` |
| | 304 | - **Functionality:** Displays all **authorized routes** for the transport organizer. |
| | 305 | - **View:** Uses the `master` template and dynamically embeds `/company/company-route`. |
| | 306 | |
| | 307 | ==== Breakdown: |
| | 308 | - Displays a list of all routes that the transport organizer is authorized to manage. |
| | 309 | - Retrieves authorized routes from the `CompanyRouteService` and populates them into the `Model`. |
| | 310 | - The view is displayed using `/company/company-route`. |
| | 311 | |
| | 312 | |
| | 313 | === |
| | 314 | |
| | 315 | ==== Controller Details for Trips: |
| | 316 | - **URL Mapping:** `/routes/company/view-trips/{routeId}` |
| | 317 | - **Method:** `GET`, `POST` |
| | 318 | - **Functionality:** |
| | 319 | - **GET `/routes/company/view-trips/{routeId}`**: Displays **all trips** for the selected route. |
| | 320 | - **POST `/routes/company/view-trips/{routeId}/add-trip`**: Allows the transport organizer to **add a new trip**. |
| | 321 | - **POST `/routes/company/view-trips/{routeId}/edit-trip/{tripId}`**: Allows the transport organizer to **edit an existing trip**. |
| | 322 | - **POST `/routes/company/view-trips/{routeId}/delete-trip/{tripId}`**: Allows the transport organizer to **delete a trip**. |
| | 323 | - **View:** Uses the `master` template and dynamically embeds `/company/company-view-trip`. |
| | 324 | |
| | 325 | ==== Breakdown: |
| | 326 | - **Viewing trips**: When the transport organizer accesses `/routes/company/view-trips/{routeId}`, the controller retrieves all trips for the specified route using `companyTripService.getAuthorizedTripsByRoute(routeId)`. |
| | 327 | - **Adding a new trip**: A form allows the transport organizer to specify the date, free seats, locations, and ETAs for the trip. The controller calls `companyTripService.createTrip()` to create a new trip. |
| | 328 | - **Editing a trip**: The transport organizer can modify trip details. The controller calls `companyTripService.updateTrip()` to update the trip. |
| | 329 | - **Deleting a trip**: The transport organizer can delete a trip. The controller calls `companyTripService.deleteTripIfAuthorized()` to remove the trip if the organizer is authorized. |
| | 330 | - **Viewing trip stops trip** The transport organizer can view and modify trip stops. The controller calls companyTripService.updateTrip() to update whatever the authorized transport organizer wants. |
| | 331 | |
| | 332 | === |
| | 333 | |
| | 334 | ==== Edit Trip: |
| | 335 | ===== **Free seats modified:** |
| | 336 | [[Image(edit-trip.png, 100%)]] |
| | 337 | [[Image(edited-trip.png, 100%)]] |
| | 338 | |
| | 339 | ==== Delete Trip: |
| | 340 | [[Image(delete-trip.png, 100%)]] |
| | 341 | |
| | 342 | === |
| | 343 | === Trip Stops: |
| | 344 | [[Image(trip-stops.png, 100%)]] |
| | 345 | === |
| | 346 | |