-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #241 from AreaFiftyLAN/feature-consumption_tracker
Consumption Tracking
- Loading branch information
Showing
10 changed files
with
806 additions
and
0 deletions.
There are no files selected for viewing
74 changes: 74 additions & 0 deletions
74
src/main/java/ch/wisv/areafiftylan/controller/ConsumptionController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package ch.wisv.areafiftylan.controller; | ||
|
||
import ch.wisv.areafiftylan.exception.AlreadyConsumedException; | ||
import ch.wisv.areafiftylan.exception.ConsumptionNotFoundException; | ||
import ch.wisv.areafiftylan.model.util.Consumption; | ||
import ch.wisv.areafiftylan.service.ConsumptionService; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.access.prepost.PreAuthorize; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
|
||
import static ch.wisv.areafiftylan.util.ResponseEntityBuilder.createResponseEntity; | ||
|
||
/** | ||
* Created by beer on 16-5-16. | ||
*/ | ||
@RestController | ||
@PreAuthorize("hasRole('ADMIN')") | ||
@RequestMapping(value = "/consumptions") | ||
public class ConsumptionController { | ||
@Autowired | ||
private ConsumptionService consumptionService; | ||
|
||
@RequestMapping(value = "/{ticketId}", method = RequestMethod.GET) | ||
public Collection<Consumption> consumptionsMade(@PathVariable Long ticketId){ | ||
return consumptionService.getByTicketIdIfValid(ticketId).getConsumptionsMade(); | ||
} | ||
|
||
@RequestMapping(method = RequestMethod.GET) | ||
public Collection<Consumption> getAllPossibleConsumptions(){ | ||
return consumptionService.getPossibleConsumptions(); | ||
} | ||
|
||
@RequestMapping(method = RequestMethod.POST) | ||
public ResponseEntity<?> addAvailableConsumption(@RequestBody String consumptionName){ | ||
consumptionService.addPossibleConsumption(consumptionName); | ||
|
||
return createResponseEntity(HttpStatus.OK, "Successfully added " + consumptionName + " as a supported consumption."); | ||
} | ||
|
||
@RequestMapping(method = RequestMethod.DELETE) | ||
public ResponseEntity<?> removeAvailableConsumption(@RequestBody Long consumptionId){ | ||
Consumption c = consumptionService.removePossibleConsumption(consumptionId); | ||
|
||
return createResponseEntity(HttpStatus.OK, "Successfully removed " + c.getName() + " as a supported consumption."); | ||
} | ||
|
||
@RequestMapping(value = "/{ticketId}/consume", method = RequestMethod.POST) | ||
public ResponseEntity<?> consume(@PathVariable Long ticketId, @RequestBody Long consumptionId){ | ||
consumptionService.consume(ticketId, consumptionId); | ||
return createResponseEntity(HttpStatus.OK, "Successfully consumed consumption"); | ||
} | ||
|
||
@RequestMapping(value = "/{ticketId}/reset", method = RequestMethod.POST) | ||
public ResponseEntity<?> reset(@PathVariable Long ticketId, @RequestBody Long consumptionId){ | ||
consumptionService.reset(ticketId, consumptionId); | ||
return createResponseEntity(HttpStatus.OK, "Successfully reset consumption"); | ||
} | ||
|
||
@ExceptionHandler(value = AlreadyConsumedException.class) | ||
public ResponseEntity<?> handleAlreadyConsumed(AlreadyConsumedException e){ | ||
return createResponseEntity(HttpStatus.CONFLICT, e.getMessage()); | ||
} | ||
|
||
@ExceptionHandler(value = ConsumptionNotFoundException.class) | ||
public ResponseEntity<?> handleConsumptionNotSupported(ConsumptionNotFoundException e){ | ||
return createResponseEntity(HttpStatus.NOT_FOUND, e.getMessage()); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/ch/wisv/areafiftylan/exception/AlreadyConsumedException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package ch.wisv.areafiftylan.exception; | ||
|
||
import ch.wisv.areafiftylan.model.util.Consumption; | ||
|
||
/** | ||
* Created by beer on 16-5-16. | ||
*/ | ||
public class AlreadyConsumedException extends RuntimeException { | ||
public AlreadyConsumedException(Consumption consumption) { | ||
super("Consumption " + consumption.getName() + " has already been consumed."); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/ch/wisv/areafiftylan/exception/ConsumptionNotFoundException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package ch.wisv.areafiftylan.exception; | ||
|
||
import ch.wisv.areafiftylan.model.util.Consumption; | ||
|
||
/** | ||
* Created by beer on 8-5-16. | ||
*/ | ||
public class ConsumptionNotFoundException extends RuntimeException { | ||
public ConsumptionNotFoundException(Long consumptionId) { | ||
super("Can't find a consumption with id: \"" + consumptionId + "\" is unsupported."); | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
src/main/java/ch/wisv/areafiftylan/model/ConsumptionMap.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package ch.wisv.areafiftylan.model; | ||
|
||
import ch.wisv.areafiftylan.exception.AlreadyConsumedException; | ||
import ch.wisv.areafiftylan.model.util.Consumption; | ||
import lombok.Getter; | ||
import lombok.NonNull; | ||
|
||
import javax.persistence.*; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
|
||
/** | ||
* Created by beer on 8-5-16. | ||
*/ | ||
@Entity | ||
public class ConsumptionMap { | ||
@Id | ||
@GeneratedValue | ||
Long id; | ||
|
||
@NonNull | ||
@ElementCollection(fetch = FetchType.EAGER) | ||
private Collection<Consumption> consumptionsMade; | ||
|
||
@OneToOne(targetEntity = Ticket.class, cascade = CascadeType.MERGE) | ||
@NonNull | ||
@Getter | ||
private Ticket ticket; | ||
|
||
public ConsumptionMap() { | ||
// JPA Only | ||
} | ||
|
||
public ConsumptionMap(Ticket t) { | ||
this.consumptionsMade = new ArrayList<>(); | ||
this.ticket = t; | ||
} | ||
|
||
public boolean isConsumed(Consumption consumption){ | ||
return consumptionsMade.contains(consumption); | ||
} | ||
|
||
public void consume(Consumption consumption){ | ||
if(isConsumed(consumption)){ | ||
throw new AlreadyConsumedException(consumption); | ||
} | ||
|
||
consumptionsMade.add(consumption); | ||
} | ||
|
||
public void reset(Consumption consumption){ | ||
if(isConsumed(consumption)){ | ||
consumptionsMade.remove(consumption); | ||
} | ||
} | ||
|
||
public Collection<Consumption> getConsumptionsMade(){ | ||
return consumptionsMade; | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
src/main/java/ch/wisv/areafiftylan/model/util/Consumption.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package ch.wisv.areafiftylan.model.util; | ||
|
||
import lombok.Getter; | ||
|
||
import javax.persistence.GeneratedValue; | ||
import javax.persistence.Id; | ||
|
||
import javax.persistence.Entity; | ||
|
||
/** | ||
* Created by beer on 20-5-16. | ||
*/ | ||
@Entity | ||
public class Consumption { | ||
@GeneratedValue | ||
@Getter | ||
@Id | ||
Long id; | ||
|
||
@Getter | ||
String name; | ||
|
||
public Consumption() { | ||
// JPA Only | ||
} | ||
|
||
public Consumption(String name) { | ||
this.name = name; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (!(o instanceof Consumption)) return false; | ||
|
||
Consumption that = (Consumption) o; | ||
|
||
if (id != that.id) return false; | ||
return name.equals(that.getName()); | ||
|
||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/main/java/ch/wisv/areafiftylan/service/ConsumptionService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package ch.wisv.areafiftylan.service; | ||
|
||
import ch.wisv.areafiftylan.model.ConsumptionMap; | ||
import ch.wisv.areafiftylan.model.util.Consumption; | ||
|
||
import java.util.Collection; | ||
|
||
/** | ||
* Created by beer on 16-5-16. | ||
*/ | ||
public interface ConsumptionService { | ||
ConsumptionMap getByTicketIdIfValid(Long ticketId); | ||
|
||
boolean isConsumed(Long ticketId, Long consumptionId); | ||
|
||
void consume(Long ticketId, Long consumptionId); | ||
|
||
void reset(Long ticketId, Long consumptionId); | ||
|
||
Consumption getByConsumptionId(Long consumptionId); | ||
|
||
Collection<Consumption> getPossibleConsumptions(); | ||
|
||
Consumption removePossibleConsumption(Long consumptionId); | ||
|
||
Consumption addPossibleConsumption(String consumptionName); | ||
} |
115 changes: 115 additions & 0 deletions
115
src/main/java/ch/wisv/areafiftylan/service/ConsumptionServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package ch.wisv.areafiftylan.service; | ||
|
||
import ch.wisv.areafiftylan.exception.ConsumptionNotFoundException; | ||
import ch.wisv.areafiftylan.exception.InvalidTicketException; | ||
import ch.wisv.areafiftylan.model.ConsumptionMap; | ||
import ch.wisv.areafiftylan.model.Ticket; | ||
import ch.wisv.areafiftylan.model.util.Consumption; | ||
import ch.wisv.areafiftylan.service.repository.ConsumptionMapsRepository; | ||
import ch.wisv.areafiftylan.service.repository.PossibleConsumptionsRepository; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.dao.DuplicateKeyException; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.Collection; | ||
import java.util.Optional; | ||
import java.util.stream.Collectors; | ||
|
||
/** | ||
* Created by beer on 16-5-16. | ||
*/ | ||
@Service | ||
public class ConsumptionServiceImpl implements ConsumptionService { | ||
ConsumptionMapsRepository consumptionMapsRepository; | ||
PossibleConsumptionsRepository possibleConsumptionsRepository; | ||
TicketService ticketService; | ||
|
||
@Autowired | ||
public ConsumptionServiceImpl(ConsumptionMapsRepository consumptionMapsRepository, | ||
PossibleConsumptionsRepository possibleConsumptionsRepository, | ||
TicketService ticketService) { | ||
this.consumptionMapsRepository = consumptionMapsRepository; | ||
this.possibleConsumptionsRepository = possibleConsumptionsRepository; | ||
this.ticketService = ticketService; | ||
} | ||
|
||
@Override | ||
public ConsumptionMap getByTicketIdIfValid(Long ticketId) { | ||
if(!ticketService.getTicketById(ticketId).isValid()){ | ||
throw new InvalidTicketException("Ticket is invalid; It can not be used for consumptions."); | ||
} | ||
|
||
Optional<ConsumptionMap> mapOptional = consumptionMapsRepository.findByTicketId(ticketId); | ||
|
||
if(mapOptional.isPresent()){ | ||
return mapOptional.get(); | ||
}else{ | ||
return initializeConsumptionMap(ticketId); | ||
} | ||
} | ||
|
||
@Override | ||
public boolean isConsumed(Long ticketId, Long consumptionId) { | ||
Consumption c = getByConsumptionId(consumptionId); | ||
return getByTicketIdIfValid(ticketId).isConsumed(c); | ||
} | ||
|
||
private ConsumptionMap initializeConsumptionMap(Long ticketId){ | ||
Ticket t = ticketService.getTicketById(ticketId); | ||
return consumptionMapsRepository.saveAndFlush(new ConsumptionMap(t)); | ||
} | ||
|
||
@Override | ||
public void consume(Long ticketId, Long consumptionId) { | ||
ConsumptionMap consumptions = getByTicketIdIfValid(ticketId); | ||
Consumption consumption = getByConsumptionId(consumptionId); | ||
consumptions.consume(consumption); | ||
consumptionMapsRepository.saveAndFlush(consumptions); | ||
} | ||
|
||
@Override | ||
public void reset(Long ticketId, Long consumptionId) { | ||
ConsumptionMap consumptions = getByTicketIdIfValid(ticketId); | ||
Consumption consumption = getByConsumptionId(consumptionId); | ||
consumptions.reset(consumption); | ||
consumptionMapsRepository.saveAndFlush(consumptions); | ||
} | ||
|
||
@Override | ||
public Consumption getByConsumptionId(Long consumptionId) { | ||
return possibleConsumptionsRepository.findById(consumptionId) | ||
.orElseThrow(() -> new ConsumptionNotFoundException(consumptionId)); | ||
} | ||
|
||
@Override | ||
public Collection<Consumption> getPossibleConsumptions() { | ||
return possibleConsumptionsRepository.findAll(); | ||
} | ||
|
||
@Override | ||
public Consumption removePossibleConsumption(Long consumptionId) { | ||
Consumption consumption = getByConsumptionId(consumptionId); | ||
|
||
resetConsumptionEverywhere(consumption); | ||
|
||
possibleConsumptionsRepository.delete(consumption); | ||
return consumption; | ||
} | ||
|
||
@Override | ||
public Consumption addPossibleConsumption(String consumptionName) { | ||
if(possibleConsumptionsRepository.findByName(consumptionName).isPresent()){ | ||
throw new DuplicateKeyException("Consumption " + consumptionName + " is already supported"); | ||
} | ||
|
||
Consumption consumption = new Consumption(consumptionName); | ||
return possibleConsumptionsRepository.saveAndFlush(consumption); | ||
} | ||
|
||
private void resetConsumptionEverywhere(Consumption consumption){ | ||
Collection<Ticket> allValidTickets = ticketService.getAllTickets().stream() | ||
.filter(t -> t.isValid()).collect(Collectors.toList()); | ||
|
||
allValidTickets.forEach(t -> reset(t.getId(), consumption.getId())); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/ch/wisv/areafiftylan/service/repository/ConsumptionMapsRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package ch.wisv.areafiftylan.service.repository; | ||
|
||
import ch.wisv.areafiftylan.model.ConsumptionMap; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
import java.util.Optional; | ||
|
||
/** | ||
* Created by beer on 16-5-16. | ||
*/ | ||
@Repository | ||
public interface ConsumptionMapsRepository extends JpaRepository<ConsumptionMap, Long> { | ||
Optional<ConsumptionMap> findByTicketId(Long ticketId); | ||
} |
17 changes: 17 additions & 0 deletions
17
src/main/java/ch/wisv/areafiftylan/service/repository/PossibleConsumptionsRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package ch.wisv.areafiftylan.service.repository; | ||
|
||
import ch.wisv.areafiftylan.model.util.Consumption; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
import java.util.Optional; | ||
|
||
/** | ||
* Created by beer on 20-5-16. | ||
*/ | ||
@Repository | ||
public interface PossibleConsumptionsRepository extends JpaRepository<Consumption, String> { | ||
Optional<Consumption> findByName(String name); | ||
|
||
Optional<Consumption> findById(Long consumptionId); | ||
} |
Oops, something went wrong.