package com.plannaplan.services; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import com.plannaplan.entities.Assignment; import com.plannaplan.entities.Commision; import com.plannaplan.entities.Exchange; import com.plannaplan.entities.Groups; import com.plannaplan.entities.User; import com.plannaplan.models.EmailExchangesData; import com.plannaplan.models.MatchData; import com.plannaplan.repositories.ExchangeRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * Service to manage Exchanges */ @Service public class ExchangeService { @Autowired private ExchangeRepository repo; @Autowired private AssignmentService assignmentService; @Autowired private UserService userService; @Autowired private EmailService emailService; /** * @param exchange Instance to save in database * @return Exchange Instance contains database id */ public Exchange save(Exchange exchange) { return this.repo.save(exchange); } /** * @param id Id of exchange in database * @return Optional Exchange if found */ public Optional getById(Long id) { return this.repo.findById(id); } /** * @return list of all exchanges in database */ public List getAllExchanges() { return this.repo.findAll(); } /** * @param id Id of user * @return List of exchanges that belong to user */ public List getByUserId(Long id) { return this.repo.getByUserId(id); } /** * @param entity Exchange entity which we would like to delete */ public void deleteExchange(Exchange entity) { this.repo.delete(entity); } /** * @param assignment Assignment to trade for * @param group Desired group * @return Optional with Exchange if exist */ public Optional checkForExchange(Assignment assignment, Groups group) { return this.repo.checkForExchange(assignment, group); } /** * method to perform Exchange algorythm. It search for matches and swap * assignments between latests user commisions if it can be performed. After * swap we block users matches that contains switched groups. After algorythm * email is being sent to all users with information about performed exchanges */ public void performExchange() { final List matchData = this.getMatches(); final List performedAssignmentExchanges = new ArrayList<>(); final EmailExchangesData emailData = new EmailExchangesData(); final List exchangesToDelete = new ArrayList<>(); matchData.forEach(m -> { final Assignment assignmentOne = m.getAssignmentOne(); final Assignment assignmentTwo = m.getAssignmentTwo(); final Exchange exchange1 = m.getExchangeOne(); final Exchange exchange2 = m.getExchangeTwo(); if (!(performedAssignmentExchanges.contains(assignmentOne.getId()) || performedAssignmentExchanges.contains(assignmentTwo.getId()))) { final Commision commisionOne = assignmentOne.getCommision(); final User userOne = commisionOne.getCommisionOwner(); final Commision commisionTwo = assignmentTwo.getCommision(); final User userTwo = commisionTwo.getCommisionOwner(); assignmentOne.setCommision(commisionTwo); assignmentTwo.setCommision(commisionOne); userOne.removeGroup(assignmentOne.getGroup().getId()); userTwo.removeGroup(assignmentTwo.getGroup().getId()); userOne.claimGroup(assignmentTwo.getGroup()); userTwo.claimGroup(assignmentOne.getGroup()); this.assignmentService.save(assignmentOne); this.assignmentService.save(assignmentTwo); this.userService.save(userOne); this.userService.save(userTwo); performedAssignmentExchanges.add(assignmentOne.getId()); performedAssignmentExchanges.add(assignmentTwo.getId()); emailData.addExchange(exchange1.getOwnedAssignment().getCommision().getCommisionOwner(), exchange1); emailData.addExchange(exchange2.getOwnedAssignment().getCommision().getCommisionOwner(), exchange2); } exchangesToDelete.add(exchange1); exchangesToDelete.add(exchange2); }); this.emailService.sendExchangesResults(emailData); this.repo.deleteAll(exchangesToDelete); } /** * @return list of matches found in database */ public List getMatches() { final List matches = this.repo.getMatches().stream().map(m -> { final Exchange exchangeOne = (Exchange) m[0]; final Exchange exchangeTwo = (Exchange) m[1]; return new MatchData(exchangeOne, exchangeTwo); }).collect(Collectors.toList()); final Set uniqData = new HashSet<>(matches); final List matchDataListSorted = uniqData.stream().sorted((m1, m2) -> -1 * m1.compare(m2)) .collect(Collectors.toList()); return matchDataListSorted; } }