/* This file is part of Cyclos (www.cyclos.org). A project of the Social Trade Organisation (www.socialtrade.org). Cyclos is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Cyclos is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Cyclos; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package nl.strohalm.cyclos.controls.members.references; import java.util.Calendar; import java.util.Collection; import java.util.Map; import javax.servlet.http.HttpServletRequest; import nl.strohalm.cyclos.annotations.Inject; import nl.strohalm.cyclos.controls.ActionContext; import nl.strohalm.cyclos.controls.BaseQueryAction; import nl.strohalm.cyclos.entities.accounts.AccountType; import nl.strohalm.cyclos.entities.accounts.transactions.Payment; import nl.strohalm.cyclos.entities.accounts.transactions.TransferType; import nl.strohalm.cyclos.entities.members.Element; import nl.strohalm.cyclos.entities.members.Member; import nl.strohalm.cyclos.entities.members.Reference; import nl.strohalm.cyclos.entities.members.Reference.Level; import nl.strohalm.cyclos.entities.members.Reference.Nature; import nl.strohalm.cyclos.entities.members.ReferenceQuery; import nl.strohalm.cyclos.entities.members.TransactionFeedback; import nl.strohalm.cyclos.entities.settings.LocalSettings; import nl.strohalm.cyclos.services.elements.ReferenceService; import nl.strohalm.cyclos.utils.Period; import nl.strohalm.cyclos.utils.RelationshipHelper; import nl.strohalm.cyclos.utils.RequestHelper; import nl.strohalm.cyclos.utils.TimePeriod; import nl.strohalm.cyclos.utils.binding.BeanBinder; import nl.strohalm.cyclos.utils.binding.DataBinder; import nl.strohalm.cyclos.utils.binding.DataBinderHelper; import nl.strohalm.cyclos.utils.conversion.CoercionHelper; import nl.strohalm.cyclos.utils.query.QueryParameters; import nl.strohalm.cyclos.utils.validation.ValidationException; /** * Action used to view a member's references and edit the reference to that member * @author luis */ public class MemberReferencesAction extends BaseQueryAction { /** * Represents the direction we're searching * @author luis */ public static enum Direction { RECEIVED, GIVEN } private DataBinder<ReferenceQuery> dataBinder; private ReferenceService referenceService; @Inject public void setReferenceService(final ReferenceService referenceService) { this.referenceService = referenceService; } @SuppressWarnings("unchecked") @Override protected void executeQuery(final ActionContext context, final QueryParameters queryParameters) { final HttpServletRequest request = context.getRequest(); final MemberReferencesForm form = context.getForm(); final Direction direction = CoercionHelper.coerce(Direction.class, form.getDirection()); final Member member = (Member) request.getAttribute("member"); final ReferenceQuery query = (ReferenceQuery) queryParameters; if (member != null) { form.setMemberId(member.getId()); } // Retrieve both summaries for all time and last 30 days final Map<Level, Integer> allTime = referenceService.countReferencesByLevel(query.getNature(), member, direction == Direction.RECEIVED); request.setAttribute("summaryAllTime", allTime); final Period period30 = new TimePeriod(30, TimePeriod.Field.DAYS).periodEndingAt(Calendar.getInstance()); final Map<Level, Integer> last30Days = referenceService.countReferencesHistoryByLevel(query.getNature(), member, period30, direction == Direction.RECEIVED); request.setAttribute("summaryLast30Days", last30Days); // Calculate the score int totalAllTime = 0; int total30Days = 0; int scoreAllTime = 0; int score30Days = 0; final Collection<Level> levels = (Collection<Level>) request.getAttribute("levels"); int nonNeutralCountAllTime = 0; int positiveCountAllTime = 0; int nonNeutralCount30Days = 0; int positiveCount30Days = 0; for (final Level level : levels) { final int value = level.getValue(); final int allTimeCount = CoercionHelper.coerce(Integer.TYPE, allTime.get(level)); final int last30DaysCount = CoercionHelper.coerce(Integer.TYPE, last30Days.get(level)); // Calculate the total totalAllTime += allTimeCount; total30Days += last30DaysCount; // Calculate the score (sum of count * value) scoreAllTime += allTimeCount * value; score30Days += last30DaysCount * value; // Calculate the data for positive percentage if (value != 0) { nonNeutralCountAllTime += allTimeCount; nonNeutralCount30Days += last30DaysCount; if (value > 0) { positiveCountAllTime += allTimeCount; positiveCount30Days += last30DaysCount; } } } // Calculate the positive percentage final int percentAllTime = nonNeutralCountAllTime == 0 ? 0 : Math.round((float) positiveCountAllTime / nonNeutralCountAllTime * 100F); final int percentLast30Days = nonNeutralCount30Days == 0 ? 0 : Math.round((float) positiveCount30Days / nonNeutralCount30Days * 100F); // Store calculated data on request request.setAttribute("totalAllTime", totalAllTime); request.setAttribute("total30Days", total30Days); request.setAttribute("scoreAllTime", scoreAllTime); request.setAttribute("score30Days", score30Days); request.setAttribute("percentAllTime", percentAllTime); request.setAttribute("percent30Days", percentLast30Days); // Get the references list request.setAttribute("references", referenceService.search(query)); } @Override protected QueryParameters prepareForm(final ActionContext context) { final MemberReferencesForm form = context.getForm(); final HttpServletRequest request = context.getRequest(); final ReferenceQuery query = getDataBinder().readFromString(form.getQuery()); query.setNature(CoercionHelper.coerce(Nature.class, form.getNature())); if (query.getNature() == null) { query.setNature(Nature.GENERAL); } // Find out the member Member member; try { member = (Member) (form.getMemberId() <= 0L ? context.getAccountOwner() : elementService.load(form.getMemberId(), Element.Relationships.GROUP)); } catch (final Exception e) { throw new ValidationException(); } final boolean myReferences = member.equals(context.getAccountOwner()); // Retrieve the direction we're looking at Direction direction = CoercionHelper.coerce(Direction.class, form.getDirection()); if (direction == null) { direction = Direction.RECEIVED; form.setDirection(direction.name()); } final boolean isGiven = direction == Direction.GIVEN; if (isGiven) { query.setFrom(member); } else { query.setTo(member); } final boolean isGeneral = query.getNature() == Reference.Nature.GENERAL; if (!isGeneral) { query.fetch(RelationshipHelper.nested(TransactionFeedback.Relationships.TRANSFER, Payment.Relationships.TYPE, TransferType.Relationships.FROM, AccountType.Relationships.CURRENCY)); } // When it's a member (or operator) viewing of other member's received general references, he can set his own too final boolean canSetReference = isGeneral && referenceService.canGiveGeneralReference(member); // Check whether the logged user can manage references on the list final boolean canManage = isGeneral && (myReferences && isGiven || !myReferences) && referenceService.canManageGeneralReference(member); // Bind the form and store the request attributes final LocalSettings localSettings = settingsService.getLocalSettings(); getDataBinder().writeAsString(form.getQuery(), query); request.setAttribute("member", member); request.setAttribute("canManage", canManage); request.setAttribute("myReferences", myReferences); request.setAttribute("isGiven", isGiven); request.setAttribute("isGeneral", isGeneral); request.setAttribute("levels", localSettings.getReferenceLevelList()); request.setAttribute("canSetReference", canSetReference); RequestHelper.storeEnum(request, Direction.class, "directions"); if (!isGeneral) { final boolean showAmount = context.isAdmin() || context.getAccountOwner().equals(member); request.setAttribute("showAmount", showAmount); } return query; } @Override protected boolean willExecuteQuery(final ActionContext context, final QueryParameters queryParameters) throws Exception { return true; } private DataBinder<ReferenceQuery> getDataBinder() { if (dataBinder == null) { final BeanBinder<ReferenceQuery> binder = BeanBinder.instance(ReferenceQuery.class); binder.registerBinder("pageParameters", DataBinderHelper.pageBinder()); dataBinder = binder; } return dataBinder; } }