package com.ufund.api.ufundapi.service; import java.io.IOException; import java.util.Arrays; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import com.ufund.api.ufundapi.DuplicateKeyException; import com.ufund.api.ufundapi.model.Need; import com.ufund.api.ufundapi.persistence.CupboardDAO; @Component public class CupboardService { private final CupboardDAO cupboardDAO; final AuthService authService; public CupboardService(@Lazy AuthService authService, CupboardDAO cupboardDAO) { this.authService = authService; this.cupboardDAO = cupboardDAO; } /** * Creates a new Need * * @param name The name of the need to create * @param image The image representation of the need to create * @param location The location of the new need * @param maxGoal The max goal of the new need * @param goalType The goal type of the new need * @param urgent The urgency of the new need * @param description The description of the new need * @return The need that was created * @throws IOException Thrown if there was any issue saving the data * @throws DuplicateKeyException If there already exists a need with the same name */ public Need createNeed(String name, String image, String location, double maxGoal, Need.GoalType goalType, boolean urgent, String description) throws IOException, DuplicateKeyException { if (maxGoal <= 0) { throw new IllegalArgumentException("Max Goal must be greater than zero"); } else if (goalType.equals(Need.GoalType.PHYSICAL) && maxGoal % 1 != 0) { throw new IllegalArgumentException("Cannot have non whole number value for physical goal"); } else if (name == null || name.isEmpty()) { throw new IllegalArgumentException("Required fields cannot be blank"); } for (Need searchNeed : cupboardDAO.getNeeds()) { if (searchNeed.getName().equalsIgnoreCase(name)) { throw new DuplicateKeyException("Duplicate names are not allowed"); } } Need need = new Need(name, image, location, maxGoal, goalType, urgent, description); return cupboardDAO.addNeed(need); } /** * Get all the needs in the cupboard * * @return An array containing all needs * @throws IOException Thrown if there was any issue saving the data */ public Need[] getNeeds() throws IOException { return cupboardDAO.getNeeds(); } /** * Returns an array of needs filtered by a search * * @param search The search substring * @return The requested array * @throws IOException Thrown if there was any issue saving the data */ public Need[] searchNeeds(String search) throws IOException { return Arrays.stream(cupboardDAO.getNeeds()) .filter(i -> i.getName().toLowerCase().contains(search.toLowerCase())) .toArray(Need[]::new); } /** * Gets a need with the specified ID * * @param id the ID of the need * @return The resulting Need or null if the need was not found */ public Need getNeed(int id) throws IOException { return cupboardDAO.getNeed(id); } /** * Updates a need * * @param id The ID of the need to update * @param need The need object to set (note: the ID is ignored) * @return The updated need object * @throws IOException Thrown if there was an issue saving the changes */ public Need updateNeed(Need need, int id) throws IOException { if (need.getId() != id) { throw new IllegalArgumentException("ID in URL and body must match"); } if (need.getMaxGoal() <= 0) { throw new IllegalArgumentException("Goal must be greater than 0"); } else if (need.getType().equals(Need.GoalType.PHYSICAL) && need.getMaxGoal() % 1 != 0) { throw new IllegalArgumentException("Cannot have non whole number value for physical goal"); } else if (need.getName() == null || need.getName().isEmpty()) { throw new IllegalArgumentException("Required fields cannot be blank"); } return cupboardDAO.updateNeed(need); } /** * Checks out a need with the desired amount * * @param id The ID of the need to update * @param checkoutAmount The amount to update the need by * @throws IOException If there is an error reading the file * @throws IllegalAccessException If the user has insufficient permission */ public void checkoutNeed(int id, double checkoutAmount, String key) throws IOException, IllegalAccessException { if (checkoutAmount <= 0) { throw new IllegalArgumentException("Amount must be greater than 0"); } if ((checkoutAmount % 1 != 0) && (cupboardDAO.getNeed(id).getType() == Need.GoalType.PHYSICAL)) { throw new IllegalArgumentException("Physical amounts must be whole numbers"); } authService.keyIsValid(key); Need need = cupboardDAO.getNeed(id); need.incrementCurrent(checkoutAmount); } /** * Delete a need from the cupboard * * @param id the ID of the need * @return True if the need was deleted * @throws IOException Thrown on any problem removing the need */ public boolean deleteNeed(int id) throws IOException { return cupboardDAO.deleteNeed(id); } }