From 2b9870913f421d2294e4821e449686b866d94a2f Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Fri, 3 Apr 2026 10:20:34 +0200 Subject: [PATCH 01/13] Initial code TicketController --- .../alfs/controllers/TicketController.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/main/java/org/example/alfs/controllers/TicketController.java diff --git a/src/main/java/org/example/alfs/controllers/TicketController.java b/src/main/java/org/example/alfs/controllers/TicketController.java new file mode 100644 index 0000000..8793e1a --- /dev/null +++ b/src/main/java/org/example/alfs/controllers/TicketController.java @@ -0,0 +1,54 @@ +package org.example.alfs.controllers; + +import jakarta.validation.Valid; +import org.example.alfs.dto.ticket.TicketCreateDTO; +import org.example.alfs.entities.Ticket; +import org.example.alfs.services.TicketService; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping +public class TicketController { + + TicketService ticketService; + + + public TicketController(TicketService ticketService) { + this.ticketService = ticketService(); + + } + + //create ticket + + @GetMapping("/create") + public String createNewTicketForm(Model model) { + model.addAttribute("ticket", new TicketCreateDTO()); + return "create"; + } + + //TODO REDIRECT, WHERE?? + @PostMapping("/create") + public String createNewTicket(@ModelAttribute @Valid TicketCreateDTO ticketCreateDTO, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + return "create"; + } + + ticketService.createNewTicket(ticketCreateDTO); + + return "redirect:/home"; + + } + + //view ticket + //assign ticket + //update status + //create comment + //View comment + //upload attachment +} From 6d6894fb872db8075ea219bf9d0dcd04547a6a83 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Sat, 4 Apr 2026 10:56:12 +0200 Subject: [PATCH 02/13] fix: correct TicketService injection in TicketController --- .../java/org/example/alfs/controllers/TicketController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/example/alfs/controllers/TicketController.java b/src/main/java/org/example/alfs/controllers/TicketController.java index 8793e1a..f561123 100644 --- a/src/main/java/org/example/alfs/controllers/TicketController.java +++ b/src/main/java/org/example/alfs/controllers/TicketController.java @@ -20,7 +20,7 @@ public class TicketController { public TicketController(TicketService ticketService) { - this.ticketService = ticketService(); + this.ticketService = ticketService; } From c91e4350231d284963991c767b5109c034bd30e7 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Sat, 4 Apr 2026 10:57:32 +0200 Subject: [PATCH 03/13] Create TicketService and initial code --- .../example/alfs/services/TicketService.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/main/java/org/example/alfs/services/TicketService.java diff --git a/src/main/java/org/example/alfs/services/TicketService.java b/src/main/java/org/example/alfs/services/TicketService.java new file mode 100644 index 0000000..ff07c80 --- /dev/null +++ b/src/main/java/org/example/alfs/services/TicketService.java @@ -0,0 +1,28 @@ +package org.example.alfs.services; + +import org.example.alfs.dto.ticket.TicketCreateDTO; +import org.example.alfs.dto.ticket.TicketViewDTO; +import org.example.alfs.entities.Ticket; +import org.example.alfs.repositories.TicketRepository; +import org.springframework.stereotype.Service; + +@Service +public class TicketService { + + + private final TicketRepository ticketRepository; + + public TicketService(TicketRepository ticketRepository) { + this.ticketRepository = ticketRepository; + } + + //createNewTicket + public TicketViewDTO createNewTicket(TicketCreateDTO ticketCreateDTO) { + + Ticket ticket = new Ticket(); + + Ticket save = ticketRepository.save(ticket); + + return ticketCreateDTO; + } +} From 92b40f0b78d1eb7055254709e44bad81ef15af11 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Sat, 4 Apr 2026 11:02:48 +0200 Subject: [PATCH 04/13] feat: implement createTicket mapping in TicketService --- .../java/org/example/alfs/services/TicketService.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/example/alfs/services/TicketService.java b/src/main/java/org/example/alfs/services/TicketService.java index ff07c80..4d7d3c4 100644 --- a/src/main/java/org/example/alfs/services/TicketService.java +++ b/src/main/java/org/example/alfs/services/TicketService.java @@ -3,6 +3,7 @@ import org.example.alfs.dto.ticket.TicketCreateDTO; import org.example.alfs.dto.ticket.TicketViewDTO; import org.example.alfs.entities.Ticket; +import org.example.alfs.mapper.TicketMapper; import org.example.alfs.repositories.TicketRepository; import org.springframework.stereotype.Service; @@ -11,9 +12,11 @@ public class TicketService { private final TicketRepository ticketRepository; + private final TicketMapper ticketMapper; - public TicketService(TicketRepository ticketRepository) { + public TicketService(TicketRepository ticketRepository, TicketMapper ticketMapper) { this.ticketRepository = ticketRepository; + this.ticketMapper = ticketMapper; } //createNewTicket @@ -21,8 +24,11 @@ public TicketViewDTO createNewTicket(TicketCreateDTO ticketCreateDTO) { Ticket ticket = new Ticket(); + ticket.setTitle(ticketCreateDTO.getTitle()); + ticket.setDescription(ticketCreateDTO.getDescription()); + Ticket save = ticketRepository.save(ticket); - return ticketCreateDTO; + return ticketMapper.entityToViewDTO(save); } } From 343ea3ca9d98fc81dfe530ff84620891a1e06edd Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Sat, 4 Apr 2026 11:04:24 +0200 Subject: [PATCH 05/13] Create TicketMapper, add entityToViewDTO --- .../org/example/alfs/mapper/TicketMapper.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/main/java/org/example/alfs/mapper/TicketMapper.java diff --git a/src/main/java/org/example/alfs/mapper/TicketMapper.java b/src/main/java/org/example/alfs/mapper/TicketMapper.java new file mode 100644 index 0000000..7af8139 --- /dev/null +++ b/src/main/java/org/example/alfs/mapper/TicketMapper.java @@ -0,0 +1,28 @@ +package org.example.alfs.mapper; + +import org.example.alfs.dto.ticket.TicketViewDTO; +import org.example.alfs.entities.Ticket; +import org.springframework.stereotype.Component; + +@Component +public class TicketMapper { + + public TicketViewDTO entityToViewDTO(Ticket ticket){ + + TicketViewDTO ticketViewDTO = new TicketViewDTO(); + + ticketViewDTO.setId(ticket.getId()); + ticketViewDTO.setTitle(ticket.getTitle()); + ticketViewDTO.setDescription(ticket.getDescription()); + ticketViewDTO.setStatus(ticket.getStatus()); + ticketViewDTO.setCreatedAt(ticket.getCreatedAt()); + + if (ticket.getInvestigator() != null) { + ticketViewDTO.setAssignedInvestigatorId(ticket.getInvestigator().getId()); + } + + return ticketViewDTO; + } + + +} From d27fb3fb048759589481fc6e56101839face27e5 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Sat, 4 Apr 2026 16:26:03 +0200 Subject: [PATCH 06/13] add viewTicketByToken --- .../alfs/controllers/TicketController.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/example/alfs/controllers/TicketController.java b/src/main/java/org/example/alfs/controllers/TicketController.java index f561123..8a0c8ff 100644 --- a/src/main/java/org/example/alfs/controllers/TicketController.java +++ b/src/main/java/org/example/alfs/controllers/TicketController.java @@ -2,15 +2,13 @@ import jakarta.validation.Valid; import org.example.alfs.dto.ticket.TicketCreateDTO; +import org.example.alfs.dto.ticket.TicketViewDTO; import org.example.alfs.entities.Ticket; import org.example.alfs.services.TicketService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.*; @Controller @RequestMapping @@ -45,7 +43,16 @@ public String createNewTicket(@ModelAttribute @Valid TicketCreateDTO ticketCreat } - //view ticket + //view ticket by token + + @GetMapping("/view/{token}") + public String viewTicketByToken(@PathVariable String token, Model model) { + + TicketViewDTO ticket = ticketService.getTicketByToken(token); + model.addAttribute("ticket", ticket); + + return "view"; + } //assign ticket //update status //create comment From 6e8715df38407a5af8459c32d68dc0052e7dd517 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Sat, 4 Apr 2026 16:27:59 +0200 Subject: [PATCH 07/13] add getTicketByToken --- .../example/alfs/services/TicketService.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/org/example/alfs/services/TicketService.java b/src/main/java/org/example/alfs/services/TicketService.java index 4d7d3c4..475ecd9 100644 --- a/src/main/java/org/example/alfs/services/TicketService.java +++ b/src/main/java/org/example/alfs/services/TicketService.java @@ -7,6 +7,8 @@ import org.example.alfs.repositories.TicketRepository; import org.springframework.stereotype.Service; +import java.util.Optional; + @Service public class TicketService { @@ -31,4 +33,22 @@ public TicketViewDTO createNewTicket(TicketCreateDTO ticketCreateDTO) { return ticketMapper.entityToViewDTO(save); } + + // View by token + public TicketViewDTO getTicketByToken(String token) { + + Ticket ticket = ticketRepository.findByReporterToken(token). + orElseThrow(() -> new RuntimeException("Ticket not found")); + return ticketMapper.entityToViewDTO(ticket); + } + + //findByReporterId + + //findByInvestigatorId + + //findByStatus + + //findByStatusAndInvestigatorId + + //findAll (pageable) } From 3bac7a67efedf09ccb56db541940e0e32c399bce Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Sun, 5 Apr 2026 15:14:04 +0200 Subject: [PATCH 08/13] add getTicketById --- .../java/org/example/alfs/services/TicketService.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/org/example/alfs/services/TicketService.java b/src/main/java/org/example/alfs/services/TicketService.java index 475ecd9..1517bd7 100644 --- a/src/main/java/org/example/alfs/services/TicketService.java +++ b/src/main/java/org/example/alfs/services/TicketService.java @@ -42,6 +42,15 @@ public TicketViewDTO getTicketByToken(String token) { return ticketMapper.entityToViewDTO(ticket); } + //findById + public TicketViewDTO getTicketById(Long id) { + + Ticket ticket = ticketRepository.findById(id). + orElseThrow(() -> new RuntimeException("Ticket not found")); + return ticketMapper.entityToViewDTO(ticket); + + } + //findByReporterId //findByInvestigatorId From 2a67db572cf8ed5837376230c4cfd590ede0dc18 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Sun, 5 Apr 2026 15:15:26 +0200 Subject: [PATCH 09/13] add getTicketById --- .../alfs/controllers/TicketController.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/example/alfs/controllers/TicketController.java b/src/main/java/org/example/alfs/controllers/TicketController.java index 8a0c8ff..cb5690d 100644 --- a/src/main/java/org/example/alfs/controllers/TicketController.java +++ b/src/main/java/org/example/alfs/controllers/TicketController.java @@ -10,6 +10,8 @@ import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; +//TODO: Decide final routes and redirects + @Controller @RequestMapping public class TicketController { @@ -45,7 +47,7 @@ public String createNewTicket(@ModelAttribute @Valid TicketCreateDTO ticketCreat //view ticket by token - @GetMapping("/view/{token}") + @GetMapping("/view/token/{token}") public String viewTicketByToken(@PathVariable String token, Model model) { TicketViewDTO ticket = ticketService.getTicketByToken(token); @@ -53,6 +55,17 @@ public String viewTicketByToken(@PathVariable String token, Model model) { return "view"; } + + //view ticket by id + @GetMapping("/view/id/{id}") + public String viewTicketById(@PathVariable Long id, Model model) { + + TicketViewDTO ticket = ticketService.getTicketById(id); + model.addAttribute("ticket", ticket); + + return "view"; + } + //assign ticket //update status //create comment From ce231905d14b5900dbb3152df3da5058916abff4 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Thu, 9 Apr 2026 10:53:50 +0200 Subject: [PATCH 10/13] add findBy methods --- .../example/alfs/services/TicketService.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/main/java/org/example/alfs/services/TicketService.java b/src/main/java/org/example/alfs/services/TicketService.java index 1517bd7..6b40d75 100644 --- a/src/main/java/org/example/alfs/services/TicketService.java +++ b/src/main/java/org/example/alfs/services/TicketService.java @@ -3,10 +3,12 @@ import org.example.alfs.dto.ticket.TicketCreateDTO; import org.example.alfs.dto.ticket.TicketViewDTO; import org.example.alfs.entities.Ticket; +import org.example.alfs.enums.TicketStatus; import org.example.alfs.mapper.TicketMapper; import org.example.alfs.repositories.TicketRepository; import org.springframework.stereotype.Service; +import java.util.List; import java.util.Optional; @Service @@ -52,12 +54,40 @@ public TicketViewDTO getTicketById(Long id) { } //findByReporterId + public List getTicketsByReporterId(Long reporterId) { + return ticketRepository.findByReporterId(reporterId) + .stream() + .map(ticketMapper::entityToViewDTO) + .toList(); + } //findByInvestigatorId + public List getTicketsByInvestigatorId(Long investigatorId){ + return ticketRepository.findByInvestigatorId(investigatorId) + .stream() + .map(ticketMapper::entityToViewDTO) + .toList(); + } //findByStatus + public List getTicketsByStatus(TicketStatus status) { + return ticketRepository.findByStatus(status) + .stream() + .map(ticketMapper::entityToViewDTO) + .toList(); + } //findByStatusAndInvestigatorId + public List getTicketsByStatusAndInvestigator( + TicketStatus status, + Long investigatorId) { + + return ticketRepository + .findByStatusAndInvestigatorId(status, investigatorId) + .stream() + .map(ticketMapper::entityToViewDTO) + .toList(); + } //findAll (pageable) } From f5c7e2df33c65cd8630ab03a9c49a364d7199c00 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Thu, 9 Apr 2026 10:58:49 +0200 Subject: [PATCH 11/13] add assignTicket , updateStatus --- .../example/alfs/controllers/TicketController.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/example/alfs/controllers/TicketController.java b/src/main/java/org/example/alfs/controllers/TicketController.java index cb5690d..96d0d82 100644 --- a/src/main/java/org/example/alfs/controllers/TicketController.java +++ b/src/main/java/org/example/alfs/controllers/TicketController.java @@ -67,8 +67,20 @@ public String viewTicketById(@PathVariable Long id, Model model) { } //assign ticket + // TODO implement DTO + service + @PostMapping("/{id}/assign") + public String assignTicket(@PathVariable Long id) { + return "redirect:/tickets/" + id; + } + //update status - //create comment + // TODO implement DTO + service + @PostMapping("/{id}/status") + public String updateStatus(@PathVariable Long id) { + return "redirect:/tickets/" + id; + } + + //create comment //View comment //upload attachment } From 6977168e09320449084f30ff187fc04563e094b0 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Thu, 9 Apr 2026 15:01:33 +0200 Subject: [PATCH 12/13] fix: modelAttribute missmatch --- .../java/org/example/alfs/controllers/TicketController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/example/alfs/controllers/TicketController.java b/src/main/java/org/example/alfs/controllers/TicketController.java index 96d0d82..23ade1d 100644 --- a/src/main/java/org/example/alfs/controllers/TicketController.java +++ b/src/main/java/org/example/alfs/controllers/TicketController.java @@ -34,7 +34,7 @@ public String createNewTicketForm(Model model) { //TODO REDIRECT, WHERE?? @PostMapping("/create") - public String createNewTicket(@ModelAttribute @Valid TicketCreateDTO ticketCreateDTO, BindingResult bindingResult) { + public String createNewTicket(@ModelAttribute("ticket") @Valid TicketCreateDTO ticketCreateDTO, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return "create"; } From 43862d90baa5977aadc2427e3281de9bbf92c988 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Thu, 9 Apr 2026 15:09:37 +0200 Subject: [PATCH 13/13] refactor: replace RuntimeException with ResponseStatusException --- src/main/java/org/example/alfs/services/TicketService.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/example/alfs/services/TicketService.java b/src/main/java/org/example/alfs/services/TicketService.java index 6b40d75..4bfb1eb 100644 --- a/src/main/java/org/example/alfs/services/TicketService.java +++ b/src/main/java/org/example/alfs/services/TicketService.java @@ -6,7 +6,9 @@ import org.example.alfs.enums.TicketStatus; import org.example.alfs.mapper.TicketMapper; import org.example.alfs.repositories.TicketRepository; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; import java.util.List; import java.util.Optional; @@ -40,7 +42,7 @@ public TicketViewDTO createNewTicket(TicketCreateDTO ticketCreateDTO) { public TicketViewDTO getTicketByToken(String token) { Ticket ticket = ticketRepository.findByReporterToken(token). - orElseThrow(() -> new RuntimeException("Ticket not found")); + orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Ticket not found")); return ticketMapper.entityToViewDTO(ticket); } @@ -48,7 +50,7 @@ public TicketViewDTO getTicketByToken(String token) { public TicketViewDTO getTicketById(Long id) { Ticket ticket = ticketRepository.findById(id). - orElseThrow(() -> new RuntimeException("Ticket not found")); + orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Ticket not found")); return ticketMapper.entityToViewDTO(ticket); }