| 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 | |