Author: bleny Date: 2013-04-16 19:37:40 +0200 (Tue, 16 Apr 2013) New Revision: 99 Url: http://forge.codelutin.com/projects/franciaflex-magalie/repository/revisions... Log: add affectation management Added: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/RequestedArticles.java trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/RequestedLists.java trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/DeliveredRequestedListDao.java trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/jpa/DeliveredRequestedListJpaDao.java trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/entity/DeliveredRequestedList.java trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/entity/DeliveredRequestedListStatus.java Removed: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/RequestedArticles.java Modified: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/Entities.java trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/JpaMagaliePersistenceContext.java trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/MagaliePersistenceContext.java trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/RequestedArticleDao.java trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/jpa/RequestedArticleJpaDao.java trunk/magalie-services/src/main/java/com/franciaflex/magalie/services/service/ArticleStorageService.java trunk/magalie-services/src/main/java/com/franciaflex/magalie/services/service/FindOrderToExecuteResult.java trunk/magalie-services/src/main/java/com/franciaflex/magalie/services/service/RequestedArticleService.java trunk/magalie-services/src/main/resources/fixtures.yaml trunk/magalie-services/src/test/java/com/franciaflex/magalie/services/service/RequestedArticleServiceTest.java trunk/magalie-web/src/main/java/com/franciaflex/magalie/web/MagalieSession.java trunk/magalie-web/src/main/java/com/franciaflex/magalie/web/action/DeliverRequestedArticleAction.java trunk/magalie-web/src/main/resources/log4j.properties Modified: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/Entities.java =================================================================== --- trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/Entities.java 2013-04-15 16:18:12 UTC (rev 98) +++ trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/Entities.java 2013-04-16 17:37:40 UTC (rev 99) @@ -4,7 +4,10 @@ import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import org.apache.commons.lang3.ObjectUtils; +import java.util.Comparator; + public class Entities { private Entities() {} @@ -17,6 +20,15 @@ } } + protected static class ArbitraryComparator<E extends AbstractEntity> implements Comparator<E> { + + @Override + public int compare(E x, E y) { + return ObjectUtils.compare(x.getId(), y.getId()); + } + + } + public static Function<AbstractEntity, String> getIdFunction() { return new GetIdFunction(); } @@ -25,4 +37,7 @@ return Predicates.compose(Predicates.equalTo(id), getIdFunction()); } + public static <E extends AbstractEntity> Comparator<E> arbitraryComparator() { + return new ArbitraryComparator(); + } } Modified: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/JpaMagaliePersistenceContext.java =================================================================== --- trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/JpaMagaliePersistenceContext.java 2013-04-15 16:18:12 UTC (rev 98) +++ trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/JpaMagaliePersistenceContext.java 2013-04-16 17:37:40 UTC (rev 99) @@ -3,6 +3,7 @@ import com.franciaflex.magalie.persistence.dao.ArticleDao; import com.franciaflex.magalie.persistence.dao.BuildingDao; import com.franciaflex.magalie.persistence.dao.DeliveredRequestedArticleDao; +import com.franciaflex.magalie.persistence.dao.DeliveredRequestedListDao; import com.franciaflex.magalie.persistence.dao.MagalieUserDao; import com.franciaflex.magalie.persistence.dao.RequestedArticleDao; import com.franciaflex.magalie.persistence.dao.LocationDao; @@ -15,6 +16,7 @@ import com.franciaflex.magalie.persistence.dao.jpa.ArticleJpaDao; import com.franciaflex.magalie.persistence.dao.jpa.BuildingJpaDao; import com.franciaflex.magalie.persistence.dao.jpa.DeliveredRequestedArticleJpaDao; +import com.franciaflex.magalie.persistence.dao.jpa.DeliveredRequestedListJpaDao; import com.franciaflex.magalie.persistence.dao.jpa.LocationErrorJpaDao; import com.franciaflex.magalie.persistence.dao.jpa.LocationJpaDao; import com.franciaflex.magalie.persistence.dao.jpa.MagalieUserJpaDao; @@ -123,4 +125,8 @@ return new RequestedListJpaDao(entityManager); } + @Override + public DeliveredRequestedListDao getDeliveredRequestedListDao() { + return new DeliveredRequestedListJpaDao(entityManager); + } } Modified: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/MagaliePersistenceContext.java =================================================================== --- trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/MagaliePersistenceContext.java 2013-04-15 16:18:12 UTC (rev 98) +++ trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/MagaliePersistenceContext.java 2013-04-16 17:37:40 UTC (rev 99) @@ -3,6 +3,7 @@ import com.franciaflex.magalie.persistence.dao.ArticleDao; import com.franciaflex.magalie.persistence.dao.BuildingDao; import com.franciaflex.magalie.persistence.dao.DeliveredRequestedArticleDao; +import com.franciaflex.magalie.persistence.dao.DeliveredRequestedListDao; import com.franciaflex.magalie.persistence.dao.LocationDao; import com.franciaflex.magalie.persistence.dao.LocationErrorDao; import com.franciaflex.magalie.persistence.dao.MagalieUserDao; @@ -48,4 +49,6 @@ RequestedListDao getRequestedListDao(); + DeliveredRequestedListDao getDeliveredRequestedListDao(); + } Deleted: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/RequestedArticles.java =================================================================== --- trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/RequestedArticles.java 2013-04-15 16:18:12 UTC (rev 98) +++ trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/RequestedArticles.java 2013-04-16 17:37:40 UTC (rev 99) @@ -1,98 +0,0 @@ -package com.franciaflex.magalie.persistence; - -import com.franciaflex.magalie.persistence.entity.RequestedArticle; -import com.franciaflex.magalie.persistence.entity.RequestedList; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableListMultimap; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimaps; -import org.apache.commons.collections.comparators.BooleanComparator; - -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.Map; - -public class RequestedArticles { - - protected static class UrgentFirstComparator implements Comparator<RequestedArticle> { - - @Override - public int compare(RequestedArticle x, RequestedArticle y) { - return BooleanComparator.getTrueFirstComparator().compare(x.getRequestedList().isUrgent(), y.getRequestedList().isUrgent()); - } - - } - - protected static class RequestDateFistComparator implements Comparator<RequestedArticle> { - - @Override - public int compare(RequestedArticle x, RequestedArticle y) { - return x.getRequestedList().getRequestDate().compareTo(y.getRequestedList().getRequestDate()); - } - - } - - protected static class FinishEarlyFirstComparator implements Comparator<RequestedArticle> { - - protected Map<RequestedList, Integer> requestListToArticleRemainingCount; - - public FinishEarlyFirstComparator(Map<RequestedList, Integer> requestListToArticleRemainingCount) { - this.requestListToArticleRemainingCount = requestListToArticleRemainingCount; - } - - protected int getRemainingCount(RequestedArticle requestedArticle) { - Integer remainingCount = requestListToArticleRemainingCount.get(requestedArticle.getRequestedList()); - return remainingCount; - } - - @Override - public int compare(RequestedArticle x, RequestedArticle y) { - int xRemainingCount = getRemainingCount(x); - int yRemainingCount = getRemainingCount(y); - return xRemainingCount - yRemainingCount; - } - - } - - protected static class GetRequestList implements Function<RequestedArticle, RequestedList> { - - @Override - public RequestedList apply(RequestedArticle requestedArticle) { - return requestedArticle.getRequestedList(); - } - } - - public static Comparator<RequestedArticle> urgentFirstComparator() { - return new UrgentFirstComparator(); - } - - public static Comparator<RequestedArticle> requestDateFirstComparator() { - return new RequestDateFistComparator(); - } - - public static Comparator<RequestedArticle> finishEarlyFirstComparator(List<RequestedArticle> requests) { - - ImmutableListMultimap<RequestedList, RequestedArticle> index = - Multimaps.index(requests, RequestedArticles.getRequestList()); - - Map<RequestedList, Integer> requestListToArticleRemainingCount = Maps.newHashMap(); - - for (Map.Entry<RequestedList, Collection<RequestedArticle>> requestedListCollectionEntry : index.asMap().entrySet()) { - - RequestedList requestedList = requestedListCollectionEntry.getKey(); - - int remainingCount = requestedListCollectionEntry.getValue().size(); - - requestListToArticleRemainingCount.put(requestedList, remainingCount); - - } - - return new FinishEarlyFirstComparator(requestListToArticleRemainingCount); - - } - - public static Function<RequestedArticle, RequestedList> getRequestList() { - return new GetRequestList(); - } -} Added: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/RequestedArticles.java =================================================================== --- trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/RequestedArticles.java (rev 0) +++ trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/RequestedArticles.java 2013-04-16 17:37:40 UTC (rev 99) @@ -0,0 +1,53 @@ +package com.franciaflex.magalie.persistence; + +import com.franciaflex.magalie.persistence.entity.RequestedArticle; +import com.franciaflex.magalie.persistence.entity.RequestedList; +import com.google.common.base.Function; +import com.google.common.collect.Lists; +import com.google.common.collect.Ordering; + +import java.util.Comparator; +import java.util.List; + +public class RequestedArticles { + + protected static class RequestedListComparator implements Comparator<RequestedArticle> { + + public RequestedListComparator(Comparator<RequestedList> requestedListComparator) { + this.requestedListComparator = requestedListComparator; + } + + protected Comparator<RequestedList> requestedListComparator; + + @Override + public int compare(RequestedArticle x, RequestedArticle y) { + return requestedListComparator.compare(x.getRequestedList(), y.getRequestedList()); + } + } + + public static Comparator<RequestedArticle> comparator(List<RequestedArticle> requests, RequestedList affectedRequestedList) { + Comparator<RequestedArticle> comparator = + Ordering.compound( + Lists.newArrayList( + + new RequestedListComparator(RequestedLists.comparator(requests, affectedRequestedList)), + + // we can still have ambiguous or priorities, so to be deterministic, use arbitrary order + Entities.<RequestedArticle>arbitraryComparator() + ) + ); + return comparator; + } + + protected static class GetRequestList implements Function<RequestedArticle, RequestedList> { + + @Override + public RequestedList apply(RequestedArticle requestedArticle) { + return requestedArticle.getRequestedList(); + } + } + + public static Function<RequestedArticle, RequestedList> getRequestList() { + return new GetRequestList(); + } +} Copied: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/RequestedLists.java (from rev 98, trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/RequestedArticles.java) =================================================================== --- trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/RequestedLists.java (rev 0) +++ trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/RequestedLists.java 2013-04-16 17:37:40 UTC (rev 99) @@ -0,0 +1,134 @@ +package com.franciaflex.magalie.persistence; + +import com.franciaflex.magalie.persistence.entity.RequestedArticle; +import com.franciaflex.magalie.persistence.entity.RequestedList; +import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimaps; +import com.google.common.collect.Ordering; +import org.apache.commons.collections.comparators.BooleanComparator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +public class RequestedLists { + + private static final Log log = LogFactory.getLog(RequestedLists.class); + + protected static class GivenRequestListFirst implements Comparator<RequestedList> { + + protected RequestedList requestedList; + + public GivenRequestListFirst(RequestedList requestedList) { + this.requestedList = requestedList; + } + + @Override + public int compare(RequestedList x, RequestedList y) { + return BooleanComparator.getTrueFirstComparator().compare(x.equals(requestedList), y.equals(requestedList)); + } + } + + protected static class UrgentFirstComparator implements Comparator<RequestedList> { + + @Override + public int compare(RequestedList x, RequestedList y) { + int compare = BooleanComparator.getTrueFirstComparator().compare(x.isUrgent(), y.isUrgent()); + return compare; + } + + } + + protected static class RequestDateFistComparator implements Comparator<RequestedList> { + + @Override + public int compare(RequestedList x, RequestedList y) { + int compare = x.getRequestDate().compareTo(y.getRequestDate()); + return compare; + } + + } + + protected static class FinishEarlyFirstComparator implements Comparator<RequestedList> { + + protected Map<RequestedList, Integer> requestListToArticleRemainingCount; + + public FinishEarlyFirstComparator(Map<RequestedList, Integer> requestListToArticleRemainingCount) { + this.requestListToArticleRemainingCount = requestListToArticleRemainingCount; + } + + protected int getRemainingCount(RequestedList requestedList) { + Integer remainingCount = requestListToArticleRemainingCount.get(requestedList); + return remainingCount; + } + + @Override + public int compare(RequestedList x, RequestedList y) { + int xRemainingCount = getRemainingCount(x); + int yRemainingCount = getRemainingCount(y); + int compare = xRemainingCount - yRemainingCount; + if (log.isTraceEnabled()) { + if (compare < 0) log.trace(x.getId() + " is before " + y.getId()); + if (compare == 0) log.trace(x.getId() + " is same position as " + y.getId()); + if (compare > 0) log.trace(y.getId() + " is before " + x.getId()); + } + return compare; + } + + } + + public static Comparator<RequestedList> urgentFirstComparator() { + return new UrgentFirstComparator(); + } + + public static Comparator<RequestedList> requestDateFirstComparator() { + return new RequestDateFistComparator(); + } + + public static Comparator<RequestedList> finishEarlyFirstComparator(List<RequestedArticle> requests) { + + ImmutableListMultimap<RequestedList, RequestedArticle> index = + Multimaps.index(requests, RequestedArticles.getRequestList()); + + Map<RequestedList, Integer> requestListToArticleRemainingCount = Maps.newHashMap(); + + for (Map.Entry<RequestedList, Collection<RequestedArticle>> requestedListCollectionEntry : index.asMap().entrySet()) { + + RequestedList requestedList = requestedListCollectionEntry.getKey(); + + int remainingCount = requestedListCollectionEntry.getValue().size(); + + requestListToArticleRemainingCount.put(requestedList, remainingCount); + + } + + if (log.isDebugEnabled()) { + log.debug("number of remaining articles per list: " + requestListToArticleRemainingCount); + } + + return new FinishEarlyFirstComparator(requestListToArticleRemainingCount); + + } + + public static Comparator<RequestedList> givenRequestListFirst(RequestedList requestedList) { + return new GivenRequestListFirst(requestedList); + } + + public static Comparator<RequestedList> comparator(List<RequestedArticle> requests, RequestedList affectedRequestedList) { + Ordering<RequestedList> comparator = + Ordering.compound( + Lists.newArrayList( + givenRequestListFirst(affectedRequestedList), + finishEarlyFirstComparator(requests), + urgentFirstComparator(), + requestDateFirstComparator() + ) + ); + return comparator; + } +} Added: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/DeliveredRequestedListDao.java =================================================================== --- trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/DeliveredRequestedListDao.java (rev 0) +++ trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/DeliveredRequestedListDao.java 2013-04-16 17:37:40 UTC (rev 99) @@ -0,0 +1,16 @@ +package com.franciaflex.magalie.persistence.dao; + +import com.franciaflex.magalie.persistence.entity.DeliveredRequestedList; +import com.franciaflex.magalie.persistence.entity.MagalieUser; +import com.franciaflex.magalie.persistence.entity.RequestedList; + +/** + * @author bleny + */ +public interface DeliveredRequestedListDao extends Dao<DeliveredRequestedList> { + + DeliveredRequestedList findByAffectedTo(MagalieUser affectedTo); + + DeliveredRequestedList findByRequestedList(RequestedList requestedList); + +} Modified: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/RequestedArticleDao.java =================================================================== --- trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/RequestedArticleDao.java 2013-04-15 16:18:12 UTC (rev 98) +++ trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/RequestedArticleDao.java 2013-04-16 17:37:40 UTC (rev 99) @@ -1,6 +1,7 @@ package com.franciaflex.magalie.persistence.dao; import com.franciaflex.magalie.persistence.entity.Building; +import com.franciaflex.magalie.persistence.entity.MagalieUser; import com.franciaflex.magalie.persistence.entity.RequestedArticle; import java.util.List; @@ -10,6 +11,6 @@ */ public interface RequestedArticleDao extends Dao<RequestedArticle> { - List<RequestedArticle> findAllUndelivered(Building building); + List<RequestedArticle> findAllUndelivered(Building building, MagalieUser affectedTo); } Added: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/jpa/DeliveredRequestedListJpaDao.java =================================================================== --- trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/jpa/DeliveredRequestedListJpaDao.java (rev 0) +++ trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/jpa/DeliveredRequestedListJpaDao.java 2013-04-16 17:37:40 UTC (rev 99) @@ -0,0 +1,62 @@ +package com.franciaflex.magalie.persistence.dao.jpa; + +import com.franciaflex.magalie.persistence.dao.DeliveredRequestedListDao; +import com.franciaflex.magalie.persistence.entity.DeliveredRequestedList; +import com.franciaflex.magalie.persistence.entity.DeliveredRequestedListStatus; +import com.franciaflex.magalie.persistence.entity.MagalieUser; +import com.franciaflex.magalie.persistence.entity.RequestedList; +import com.google.common.collect.Iterables; + +import javax.persistence.EntityManager; +import javax.persistence.TypedQuery; +import java.util.List; + +public class DeliveredRequestedListJpaDao extends AbstractJpaDao<DeliveredRequestedList> implements DeliveredRequestedListDao { + + public DeliveredRequestedListJpaDao(EntityManager entityManager) { + super(entityManager); + } + + @Override + protected Class<DeliveredRequestedList> getEntityClass() { + return DeliveredRequestedList.class; + } + + @Override + public DeliveredRequestedList findByAffectedTo(MagalieUser affectedTo) { + + TypedQuery<DeliveredRequestedList> query = + entityManager.createQuery( + "from DeliveredRequestedList drl where drl.status = :affected and drl.affectedTo = :affectedTo", + getEntityClass()); + + query.setParameter("affectedTo", affectedTo); + + query.setParameter("affected", DeliveredRequestedListStatus.AFFECTED); + + List<DeliveredRequestedList> resultList = query.getResultList(); + + DeliveredRequestedList onlyElement = Iterables.getOnlyElement(resultList, null); + + return onlyElement; + + } + + @Override + public DeliveredRequestedList findByRequestedList(RequestedList requestedList) { + + TypedQuery<DeliveredRequestedList> query = + entityManager.createQuery( + "from DeliveredRequestedList drl where drl.requestedList = :requestedList", + getEntityClass()); + + query.setParameter("requestedList", requestedList); + + List<DeliveredRequestedList> resultList = query.getResultList(); + + DeliveredRequestedList onlyElement = Iterables.getOnlyElement(resultList, null); + + return onlyElement; + + } +} Modified: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/jpa/RequestedArticleJpaDao.java =================================================================== --- trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/jpa/RequestedArticleJpaDao.java 2013-04-15 16:18:12 UTC (rev 98) +++ trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/dao/jpa/RequestedArticleJpaDao.java 2013-04-16 17:37:40 UTC (rev 99) @@ -2,6 +2,8 @@ import com.franciaflex.magalie.persistence.dao.RequestedArticleDao; import com.franciaflex.magalie.persistence.entity.Building; +import com.franciaflex.magalie.persistence.entity.DeliveredRequestedListStatus; +import com.franciaflex.magalie.persistence.entity.MagalieUser; import com.franciaflex.magalie.persistence.entity.RequestedArticle; import javax.persistence.EntityManager; @@ -20,13 +22,19 @@ } @Override - public List<RequestedArticle> findAllUndelivered(Building building) { + public List<RequestedArticle> findAllUndelivered(Building building, MagalieUser affectedTo) { TypedQuery<RequestedArticle> query = entityManager.createQuery( - "from RequestedArticle ra where ra not in (select dra.requestedArticle from DeliveredRequestedArticle dra) and ra.requestedList.building = :building", + "from RequestedArticle ra where " + + " ra not in (select dra.requestedArticle from DeliveredRequestedArticle dra) " + + " and ra.requestedList.building = :building " + + " and ra.requestedList not in (select drl.requestedList from DeliveredRequestedList drl where drl.status = :complete or drl.status = :affected and drl.affectedTo != :affectedTo)", getEntityClass() ); query.setParameter("building", building); + query.setParameter("complete", DeliveredRequestedListStatus.COMPLETE); + query.setParameter("affected", DeliveredRequestedListStatus.AFFECTED); + query.setParameter("affectedTo", affectedTo); return query.getResultList(); } Added: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/entity/DeliveredRequestedList.java =================================================================== --- trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/entity/DeliveredRequestedList.java (rev 0) +++ trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/entity/DeliveredRequestedList.java 2013-04-16 17:37:40 UTC (rev 99) @@ -0,0 +1,56 @@ +package com.franciaflex.magalie.persistence.entity; + + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.OneToOne; + +@Entity +public class DeliveredRequestedList extends AbstractEntity { + + @Id + @GeneratedValue + protected String id; + + @OneToOne + protected RequestedList requestedList; + + @OneToOne + protected MagalieUser affectedTo; + + protected DeliveredRequestedListStatus status; + + @Override + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public RequestedList getRequestedList() { + return requestedList; + } + + public void setRequestedList(RequestedList requestedList) { + this.requestedList = requestedList; + } + + public MagalieUser getAffectedTo() { + return affectedTo; + } + + public void setAffectedTo(MagalieUser affectedTo) { + this.affectedTo = affectedTo; + } + + public DeliveredRequestedListStatus getStatus() { + return status; + } + + public void setStatus(DeliveredRequestedListStatus status) { + this.status = status; + } +} Added: trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/entity/DeliveredRequestedListStatus.java =================================================================== --- trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/entity/DeliveredRequestedListStatus.java (rev 0) +++ trunk/magalie-persistence/src/main/java/com/franciaflex/magalie/persistence/entity/DeliveredRequestedListStatus.java 2013-04-16 17:37:40 UTC (rev 99) @@ -0,0 +1,9 @@ +package com.franciaflex.magalie.persistence.entity; + +public enum DeliveredRequestedListStatus { + + PENDING, + AFFECTED, + COMPLETE + +} Modified: trunk/magalie-services/src/main/java/com/franciaflex/magalie/services/service/ArticleStorageService.java =================================================================== --- trunk/magalie-services/src/main/java/com/franciaflex/magalie/services/service/ArticleStorageService.java 2013-04-15 16:18:12 UTC (rev 98) +++ trunk/magalie-services/src/main/java/com/franciaflex/magalie/services/service/ArticleStorageService.java 2013-04-16 17:37:40 UTC (rev 99) @@ -174,20 +174,27 @@ protected Queue<StoredArticle> sortStoredArticlesByPriority(List<StoredArticle> storedArticles) { - Ordering<StoredArticle> orderingByPriority = Ordering.compound( - Lists.newArrayList( - StoredArticles.fixedLocationForArticleComparator(), - StoredArticles.locationWithLowestQuantityFirstComparator(), - StoredArticles.articleStoredInLocationsRequiringDriverLicenseFirstComparator() - ) - ); + Queue<StoredArticle> storedArticlesByPriority = Lists.newLinkedList(); - Queue<StoredArticle> storedArticlesByPriority = - new PriorityQueue<StoredArticle>( - storedArticles.size(), - orderingByPriority - ); + if ( ! storedArticles.isEmpty()) { + Ordering<StoredArticle> orderingByPriority = + Ordering.compound( + Lists.newArrayList( + StoredArticles.fixedLocationForArticleComparator(), + StoredArticles.locationWithLowestQuantityFirstComparator(), + StoredArticles.articleStoredInLocationsRequiringDriverLicenseFirstComparator() + ) + ); + + storedArticlesByPriority = + new PriorityQueue<StoredArticle>( + storedArticles.size(), + orderingByPriority + ); + + } + storedArticlesByPriority.addAll(storedArticles); return storedArticlesByPriority; Modified: trunk/magalie-services/src/main/java/com/franciaflex/magalie/services/service/FindOrderToExecuteResult.java =================================================================== --- trunk/magalie-services/src/main/java/com/franciaflex/magalie/services/service/FindOrderToExecuteResult.java 2013-04-15 16:18:12 UTC (rev 98) +++ trunk/magalie-services/src/main/java/com/franciaflex/magalie/services/service/FindOrderToExecuteResult.java 2013-04-16 17:37:40 UTC (rev 99) @@ -1,5 +1,6 @@ package com.franciaflex.magalie.services.service; +import com.franciaflex.magalie.persistence.entity.DeliveredRequestedList; import com.franciaflex.magalie.persistence.entity.StorageMovementOrder; public class FindOrderToExecuteResult { @@ -10,6 +11,12 @@ protected boolean driverLicenseRequired; + protected boolean everythingUnavailable; + + protected DeliveredRequestedList oldAffectation; + + protected DeliveredRequestedList newAffectation; + public boolean isSuccess() { return storageMovementOrder != null; } @@ -38,7 +45,27 @@ return driverLicenseRequired; } + public void setEverythingUnavailable(boolean everythingUnavailable) { + this.everythingUnavailable = everythingUnavailable; + } + public boolean isEverythingUnavailable() { - return ! driverLicenseRequired && ! nothingToDo; + return everythingUnavailable; } + + public void setOldAffectation(DeliveredRequestedList oldAffectation) { + this.oldAffectation = oldAffectation; + } + + public DeliveredRequestedList getOldAffectation() { + return oldAffectation; + } + + public void setNewAffectation(DeliveredRequestedList newAffectation) { + this.newAffectation = newAffectation; + } + + public DeliveredRequestedList getNewAffectation() { + return newAffectation; + } } Modified: trunk/magalie-services/src/main/java/com/franciaflex/magalie/services/service/RequestedArticleService.java =================================================================== --- trunk/magalie-services/src/main/java/com/franciaflex/magalie/services/service/RequestedArticleService.java 2013-04-15 16:18:12 UTC (rev 98) +++ trunk/magalie-services/src/main/java/com/franciaflex/magalie/services/service/RequestedArticleService.java 2013-04-16 17:37:40 UTC (rev 99) @@ -26,19 +26,21 @@ import com.franciaflex.magalie.persistence.MagaliePersistenceContext; import com.franciaflex.magalie.persistence.RequestedArticles; import com.franciaflex.magalie.persistence.dao.DeliveredRequestedArticleDao; +import com.franciaflex.magalie.persistence.dao.DeliveredRequestedListDao; import com.franciaflex.magalie.persistence.dao.RequestedArticleDao; import com.franciaflex.magalie.persistence.entity.Article; import com.franciaflex.magalie.persistence.entity.Building; import com.franciaflex.magalie.persistence.entity.DeliveredRequestedArticle; +import com.franciaflex.magalie.persistence.entity.DeliveredRequestedList; +import com.franciaflex.magalie.persistence.entity.DeliveredRequestedListStatus; import com.franciaflex.magalie.persistence.entity.Location; import com.franciaflex.magalie.persistence.entity.MagalieUser; import com.franciaflex.magalie.persistence.entity.RequestedArticle; +import com.franciaflex.magalie.persistence.entity.RequestedList; import com.franciaflex.magalie.persistence.entity.StorageMovementOrder; import com.franciaflex.magalie.services.MagalieService; import com.franciaflex.magalie.services.MagalieServiceContext; import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import com.google.common.collect.Ordering; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -58,15 +60,12 @@ this.serviceContext = serviceContext; } - public FindOrderToExecuteResult getStorageMovementOrder( - MagalieUser magalieUser, - Building building) { + public FindOrderToExecuteResult findOrderToExecute(MagalieUser magalieUser, Building building) { - List<RequestedArticle> requestedArticles = getRequestedArticles(building); + List<RequestedArticle> requestedArticles = getRequestedArticles(building, magalieUser); - Queue<RequestedArticle> requestedArticlesByPriority = getRequestedArticlesByPriority(requestedArticles); + Queue<RequestedArticle> requestedArticlesByPriority = getRequestedArticlesByPriority(requestedArticles, magalieUser); - FindOrderToExecuteResult findOrderToExecuteResult = findOrderToExecute( requestedArticlesByPriority, @@ -77,11 +76,11 @@ } - protected List<RequestedArticle> getRequestedArticles(Building building) { + protected List<RequestedArticle> getRequestedArticles(Building building, MagalieUser magalieUser) { RequestedArticleDao requestedArticleDao = serviceContext.getPersistenceContext().getRequestedArticleDao(); - List<RequestedArticle> allRequestedArticles = requestedArticleDao.findAllUndelivered(building); + List<RequestedArticle> allRequestedArticles = requestedArticleDao.findAllUndelivered(building, magalieUser); if (log.isInfoEnabled()) { log.info(allRequestedArticles.size() + " articles requested in building " + building.getCode()); @@ -106,6 +105,8 @@ boolean driverLicenseRequired = false; + boolean somethingIsAvailable = false; + while ( ! success && requestedArticleIterator.hasNext()) { requestedArticle = requestedArticleIterator.next(); @@ -122,6 +123,8 @@ driverLicenseRequired |= bookArticleResult.isArticleInaccessible() && ! bookArticleResult.isArticleUnavailable(); + somethingIsAvailable |= ! bookArticleResult.isArticleUnavailable(); + success = bookArticleResult.isSuccess(); } @@ -130,6 +133,10 @@ if (success) { + if (log.isInfoEnabled()) { + log.info("order to execute found: " + requestedArticle); + } + Preconditions.checkState(requestedArticle != null); MagaliePersistenceContext persistenceContext = serviceContext.getPersistenceContext(); @@ -146,22 +153,114 @@ dao.persist(newDeliveredRequestedArticle); - persistenceContext.commit(); + findOrderToExecuteResult.setStorageMovementOrder(storageMovementOrder); - findOrderToExecuteResult = new FindOrderToExecuteResult(); + // deal with affectations + DeliveredRequestedListDao deliveredRequestedListDao = + persistenceContext.getDeliveredRequestedListDao(); - findOrderToExecuteResult.setStorageMovementOrder(storageMovementOrder); + DeliveredRequestedList oldAffectation = + deliveredRequestedListDao.findByAffectedTo(magalieUser); + RequestedList requestedList = requestedArticle.getRequestedList(); + + DeliveredRequestedList newAffectation = + deliveredRequestedListDao.findByRequestedList(requestedList); + + if (newAffectation == null) { + + newAffectation = new DeliveredRequestedList(); + + deliveredRequestedListDao.persist(newAffectation); + + } + + newAffectation.setAffectedTo(magalieUser); + + newAffectation.setRequestedList(requestedList); + + newAffectation.setStatus(DeliveredRequestedListStatus.AFFECTED); + + deliveredRequestedListDao.merge(newAffectation); + + if (oldAffectation == null) { + + if (log.isInfoEnabled()) { + log.info("user has no previous affectation"); + } + + findOrderToExecuteResult.setNewAffectation(newAffectation); + + } else { + + if (log.isInfoEnabled()) { + log.info("user is affected to " + oldAffectation.getRequestedList().getCode()); + } + + boolean affectationChanged = ! oldAffectation.getRequestedList().equals(requestedList); + + if (affectationChanged) { + + if (log.isInfoEnabled()) { + log.info("user changed affectation from " + + oldAffectation.getRequestedList().getCode() + + " to " + requestedList.getCode()); + } + + boolean isFinished = false; // TODO brendan 16/04/13 really ? + + if (isFinished) { + + if (log.isInfoEnabled()) { + log.info("request list " + oldAffectation.getRequestedList() + + " is complete, save status"); + } + + oldAffectation.setStatus(DeliveredRequestedListStatus.COMPLETE); + + } else { + + if (log.isInfoEnabled()) { + log.info("request list " + oldAffectation.getRequestedList() + + " is not complete, putting it back to pending"); + } + + oldAffectation.setStatus(DeliveredRequestedListStatus.PENDING); + + oldAffectation.setAffectedTo(null); + + } + + findOrderToExecuteResult.setOldAffectation(oldAffectation); + + findOrderToExecuteResult.setNewAffectation(newAffectation); + + } + + } + + persistenceContext.commit(); + } else { if (requestedArticlesByPriority.isEmpty()) { + if (log.isInfoEnabled()) { + log.info("no order to execute found: nothing to do"); + } + findOrderToExecuteResult.setNothingToDo(true); } else { + if (log.isInfoEnabled()) { + log.info("no order to execute found: there is something to do but driver license is required"); + } + findOrderToExecuteResult.setDriverLicenseRequired(driverLicenseRequired); + findOrderToExecuteResult.setEverythingUnavailable( ! somethingIsAvailable); + } } @@ -170,20 +269,29 @@ } - protected Queue<RequestedArticle> getRequestedArticlesByPriority(List<RequestedArticle> requests) { + protected Queue<RequestedArticle> getRequestedArticlesByPriority(List<RequestedArticle> requests, MagalieUser magalieUser) { PriorityQueue<RequestedArticle> requestedArticles = new PriorityQueue<RequestedArticle>(); if ( ! requests.isEmpty()) { + MagaliePersistenceContext persistenceContext = serviceContext.getPersistenceContext(); + + DeliveredRequestedListDao deliveredRequestedListDao = persistenceContext.getDeliveredRequestedListDao(); + + DeliveredRequestedList affectedDeliveredRequestedList = + deliveredRequestedListDao.findByAffectedTo(magalieUser); + + RequestedList affectedRequestedList = null; + + if (affectedDeliveredRequestedList != null) { + + affectedRequestedList = affectedDeliveredRequestedList.getRequestedList(); + + } + Comparator<RequestedArticle> priorityComparator = - Ordering.compound( - Lists.newArrayList( - RequestedArticles.finishEarlyFirstComparator(requests), - RequestedArticles.urgentFirstComparator(), - RequestedArticles.requestDateFirstComparator() - ) - ); + RequestedArticles.comparator(requests, affectedRequestedList); requestedArticles = new PriorityQueue<RequestedArticle>( Modified: trunk/magalie-services/src/main/resources/fixtures.yaml =================================================================== --- trunk/magalie-services/src/main/resources/fixtures.yaml 2013-04-15 16:18:12 UTC (rev 98) +++ trunk/magalie-services/src/main/resources/fixtures.yaml 2013-04-16 17:37:40 UTC (rev 99) @@ -417,7 +417,7 @@ requestedList2: &requestedList2 !requested-list id: requestedList2 - code: 123456789 + code: 987654321 requestDate: 2013-04-08 12:00:00 urgent: false building: *B1 Modified: trunk/magalie-services/src/test/java/com/franciaflex/magalie/services/service/RequestedArticleServiceTest.java =================================================================== --- trunk/magalie-services/src/test/java/com/franciaflex/magalie/services/service/RequestedArticleServiceTest.java 2013-04-15 16:18:12 UTC (rev 98) +++ trunk/magalie-services/src/test/java/com/franciaflex/magalie/services/service/RequestedArticleServiceTest.java 2013-04-16 17:37:40 UTC (rev 99) @@ -22,6 +22,10 @@ protected RequestedArticleService service; + protected MagalieUser magalieUser; + + protected Building building; + @Before public void setUp() throws ParseException { @@ -31,15 +35,16 @@ serviceContext.setDate(new Date(1363948427576l)); + magalieUser = fixture("bruno"); + + building = fixture("B1"); } @Test public void testGetRequestedArticles() { - Building building = fixture("B1"); + List<RequestedArticle> requestedArticles = service.getRequestedArticles(building, magalieUser); - List<RequestedArticle> requestedArticles = service.getRequestedArticles(building); - for (RequestedArticle requestedArticle : requestedArticles) { Assert.assertEquals(building, requestedArticle.getRequestedList().getBuilding()); @@ -54,19 +59,22 @@ List<RequestedArticle> requestedArticles = fixture("requestedArticles"); Queue<RequestedArticle> requestedArticlesByPriority = - service.getRequestedArticlesByPriority(requestedArticles); + service.getRequestedArticlesByPriority(requestedArticles, magalieUser); Assert.assertEquals(requestedArticles.size(), requestedArticlesByPriority.size()); + Assert.assertEquals("requestedArticle5", requestedArticlesByPriority.poll().getId()); + Assert.assertEquals("requestedArticle6", requestedArticlesByPriority.poll().getId()); + Assert.assertEquals("requestedArticle1", requestedArticlesByPriority.poll().getId()); + Assert.assertEquals("requestedArticle2", requestedArticlesByPriority.poll().getId()); + Assert.assertEquals("requestedArticle3", requestedArticlesByPriority.poll().getId()); + Assert.assertEquals("requestedArticle4", requestedArticlesByPriority.poll().getId()); + } @Test public void testFindOrderWhenNoRequestedArticles() { - MagalieUser magalieUser = fixture("bruno"); - - Building building = fixture("B1"); - Queue<RequestedArticle> emptyQueue = Lists.newLinkedList(); FindOrderToExecuteResult orderToExecute = service.findOrderToExecute(emptyQueue, magalieUser, building); @@ -78,4 +86,19 @@ } + @Test + public void testFindOrderRequestedArticles() { + + FindOrderToExecuteResult orderToExecute = service.findOrderToExecute(magalieUser, building); + + Assert.assertFalse(orderToExecute.isNothingToDo()); + Assert.assertFalse(orderToExecute.isEverythingUnavailable()); + Assert.assertFalse(orderToExecute.isDriverLicenseRequired()); + Assert.assertTrue(orderToExecute.isSuccess()); + + Assert.assertNull(orderToExecute.getOldAffectation()); + Assert.assertNotNull(orderToExecute.getNewAffectation()); + + } + } Modified: trunk/magalie-web/src/main/java/com/franciaflex/magalie/web/MagalieSession.java =================================================================== --- trunk/magalie-web/src/main/java/com/franciaflex/magalie/web/MagalieSession.java 2013-04-15 16:18:12 UTC (rev 98) +++ trunk/magalie-web/src/main/java/com/franciaflex/magalie/web/MagalieSession.java 2013-04-16 17:37:40 UTC (rev 99) @@ -3,8 +3,10 @@ import com.franciaflex.magalie.persistence.entity.Building; import com.franciaflex.magalie.persistence.entity.MagalieUser; import com.franciaflex.magalie.persistence.entity.Warehouse; +import com.google.common.collect.Lists; import java.io.Serializable; +import java.util.Collection; /** * The single object every user will have in its session. @@ -21,8 +23,11 @@ protected MagalieUser magalieUser; protected Building building; - private Warehouse lastUsedDestinationWarehouseForKanbans; + protected Warehouse lastUsedDestinationWarehouseForKanbans; + + protected Collection<String> messages; + public MagalieUser getMagalieUser() { return magalieUser; } @@ -46,4 +51,16 @@ public void setLastUsedDestinationWarehouseForKanbans(Warehouse lastUsedDestinationWarehouseForKanbans) { this.lastUsedDestinationWarehouseForKanbans = lastUsedDestinationWarehouseForKanbans; } + + public Collection<String> getMessages() { + if (messages == null) { + messages = Lists.newLinkedList(); + } + return messages; + } + + public void addMessage(String message) { + getMessages().add(message); + } + } Modified: trunk/magalie-web/src/main/java/com/franciaflex/magalie/web/action/DeliverRequestedArticleAction.java =================================================================== --- trunk/magalie-web/src/main/java/com/franciaflex/magalie/web/action/DeliverRequestedArticleAction.java 2013-04-15 16:18:12 UTC (rev 98) +++ trunk/magalie-web/src/main/java/com/franciaflex/magalie/web/action/DeliverRequestedArticleAction.java 2013-04-16 17:37:40 UTC (rev 99) @@ -1,6 +1,7 @@ package com.franciaflex.magalie.web.action; import com.franciaflex.magalie.persistence.entity.Building; +import com.franciaflex.magalie.persistence.entity.DeliveredRequestedList; import com.franciaflex.magalie.persistence.entity.MagalieUser; import com.franciaflex.magalie.persistence.entity.StorageMovementOrder; import com.franciaflex.magalie.services.service.FindOrderToExecuteResult; @@ -41,35 +42,59 @@ Building building = session.getBuilding(); FindOrderToExecuteResult findOrderToExecuteResult = - service.getStorageMovementOrder(magalieUser, building); + service.findOrderToExecute(magalieUser, building); + String result; + + addActionMessage("test"); + if (findOrderToExecuteResult.isSuccess()) { + DeliveredRequestedList oldAffectation = findOrderToExecuteResult.getOldAffectation(); + + if (oldAffectation != null) { + + session.addMessage("Vous n'êtes plus affecté à la liste " + oldAffectation.getRequestedList().getCode()); + + } + + DeliveredRequestedList newAffectation = findOrderToExecuteResult.getNewAffectation(); + + if (newAffectation != null) { + + session.addMessage("Vous venez d'être affecté à la liste " + newAffectation.getRequestedList().getCode()); + + } + storageMovementOrder = findOrderToExecuteResult.getStorageMovementOrder(); - return SUCCESS; + result = SUCCESS; - } + } else { - if (findOrderToExecuteResult.isNothingToDo()) { + if (findOrderToExecuteResult.isNothingToDo()) { - addActionMessage("Il n'y a aucune demande. Vous n'avez rien à faire"); + addActionMessage("Il n'y a aucune demande. Vous n'avez rien à faire"); - } + } - if (findOrderToExecuteResult.isDriverLicenseRequired()) { + if (findOrderToExecuteResult.isDriverLicenseRequired()) { - addActionMessage("Il y a des demandes en cours, mais un permis est requis"); + addActionMessage("Il y a des demandes en cours, mais un permis est requis"); - } + } - if (findOrderToExecuteResult.isEverythingUnavailable()) { + if (findOrderToExecuteResult.isEverythingUnavailable()) { - addActionMessage("Toutes les demandes en cours concernent des articles indisponibles"); + addActionMessage("Toutes les demandes en cours concernent des articles indisponibles"); + } + + result = INPUT; + } - return INPUT; + return result; } Modified: trunk/magalie-web/src/main/resources/log4j.properties =================================================================== --- trunk/magalie-web/src/main/resources/log4j.properties 2013-04-15 16:18:12 UTC (rev 98) +++ trunk/magalie-web/src/main/resources/log4j.properties 2013-04-16 17:37:40 UTC (rev 99) @@ -34,6 +34,9 @@ log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy/MM/dd hh:mm:ss} %5p (%F:%L) %m%n -log4j.logger.com.franciaflex.magalie=TRACE -log4j.logger.org.nuiton.web.filter.JpaTransactionFilter=TRACE +# log4j.logger.org.nuiton.web.filter.JpaTransactionFilter=TRACE +# log4j.logger.com.franciaflex.magalie=TRACE + +log4j.logger.com.franciaflex.magalie.services.service.RequestedArticleService=TRACE +log4j.logger.com.franciaflex.magalie.services.service.ArticleStorageService=TRACE