/* 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.services.accounts.pos; import java.util.Calendar; import java.util.List; import nl.strohalm.cyclos.access.AdminMemberPermission; import nl.strohalm.cyclos.access.BrokerPermission; import nl.strohalm.cyclos.dao.accounts.pos.MemberPosDAO; import nl.strohalm.cyclos.dao.accounts.pos.PosDAO; import nl.strohalm.cyclos.dao.accounts.pos.PosLogDAO; import nl.strohalm.cyclos.entities.Relationship; import nl.strohalm.cyclos.entities.accounts.pos.MemberPos; import nl.strohalm.cyclos.entities.accounts.pos.Pos; import nl.strohalm.cyclos.entities.accounts.pos.PosLog; import nl.strohalm.cyclos.entities.accounts.pos.PosQuery; import nl.strohalm.cyclos.entities.alerts.MemberAlert; import nl.strohalm.cyclos.entities.exceptions.EntityNotFoundException; import nl.strohalm.cyclos.entities.groups.MemberGroupSettings; import nl.strohalm.cyclos.entities.members.Member; import nl.strohalm.cyclos.services.accounts.AccountServiceLocal; import nl.strohalm.cyclos.services.alerts.AlertServiceLocal; import nl.strohalm.cyclos.services.permissions.PermissionServiceLocal; import nl.strohalm.cyclos.utils.RelationshipHelper; import nl.strohalm.cyclos.utils.access.LoggedUser; import nl.strohalm.cyclos.utils.validation.ValidationException; import nl.strohalm.cyclos.utils.validation.Validator; import nl.strohalm.cyclos.utils.validation.Validator.Property; /** * POS Service Implementation * @author rodrigo */ public class PosServiceImpl implements PosServiceLocal { private PosDAO posDao; private PosLogDAO posLogDao; private MemberPosDAO memberPosDao; private PermissionServiceLocal permissionService; private AlertServiceLocal alertService; private AccountServiceLocal accountService; @Override public Pos assignPos(final Member member, final Long posId) { if (!accountService.hasAccounts(member)) { throw new ValidationException("memberPos.assign.memberWithoutAccount"); } final MemberPos memberPos = new MemberPos(); final Pos pos = load(posId, RelationshipHelper.nested(Pos.Relationships.MEMBER_POS, MemberPos.Relationships.MEMBER)); memberPos.setMember(member); memberPos.setStatus(MemberPos.Status.PENDING); memberPos.setDate(Calendar.getInstance()); // Copy properties from member group settings final MemberGroupSettings mgs = new MemberGroupSettings(); memberPos.setAllowMakePayment(mgs.isAllowMakePayment()); memberPos.setMaxSchedulingPayments(mgs.getMaxSchedulingPayments()); memberPos.setNumberOfCopies(mgs.getNumberOfCopies()); memberPos.setResultPageSize(mgs.getResultPageSize()); // Associate pos to member pos and save the memberPos memberPos.setPos(pos); memberPosDao.insert(memberPos); // Inverse. Associates memberPos to pos and save the pos pos.setMemberPos(memberPos); pos.setStatus(Pos.Status.ASSIGNED); posDao.update(pos); // Generate log generateLog(pos); return pos; } @Override public void deletePos(final Long... ids) { posDao.delete(ids); } @Override public Pos discardPos(final Long posId) { final Pos pos = load(posId, Pos.Relationships.MEMBER_POS); pos.setStatus(Pos.Status.DISCARDED); long memberPosId = 0; if (pos.getMemberPos() != null && pos.getMemberPos().getId() != null) { memberPosId = pos.getMemberPos().getId(); } pos.setMemberPos(null); posDao.update(pos); if (memberPosId > 0L) { memberPosDao.delete(memberPosId); } generateLog(pos); return pos; } @Override public void generateLog(final Pos pos) { final PosLog posLog = new PosLog(); if (LoggedUser.hasUser()) { posLog.setBy(LoggedUser.element()); } posLog.setPos(pos); posLog.setDate(Calendar.getInstance()); posLog.setPosStatus(pos.getStatus()); if (pos.getMemberPos() != null) { posLog.setAssignedTo(pos.getMemberPos().getMember()); posLog.setMemberPosStatus(pos.getMemberPos().getStatus()); } posLogDao.insert(posLog); } @Override public Pos load(final Long id, final Relationship... fetch) { return posDao.load(id, fetch); } @Override public Pos loadByPosId(final String posId, final Relationship... fetch) { return posDao.loadByPosId(posId, fetch); } @Override public void notifyBlockedPosUsed(final Pos pos, final String remoteAddress) { alertService.create(pos.getMemberPos().getMember(), MemberAlert.Alerts.BLOCKED_POS_USED, pos.getPosId(), remoteAddress); } @Override public Pos save(Pos pos) { validate(pos); if (pos.isTransient()) { pos.setStatus(Pos.Status.UNASSIGNED); pos = posDao.insert(pos, true); } else { pos = posDao.update(pos, true); } return pos; } @Override public List<Pos> search(final PosQuery query) { return posDao.search(query); } public void setAccountServiceLocal(final AccountServiceLocal accountService) { this.accountService = accountService; } public void setAlertServiceLocal(final AlertServiceLocal alertService) { this.alertService = alertService; } public void setMemberPosDao(final MemberPosDAO memberPosDao) { this.memberPosDao = memberPosDao; } public void setPermissionServiceLocal(final PermissionServiceLocal permissionService) { this.permissionService = permissionService; } public void setPosDao(final PosDAO posDao) { this.posDao = posDao; } public void setPosLogDao(final PosLogDAO posLogDao) { this.posLogDao = posLogDao; } @Override public void unassignAllMemberPos(final Member member) { final List<Pos> userPos = posDao.getAllMemberPos(member); for (final Pos pos : userPos) { unassignPos(pos.getId()); } } @Override public Pos unassignPos(final Long posId) { final Pos pos = load(posId, Pos.Relationships.MEMBER_POS); pos.setStatus(Pos.Status.UNASSIGNED); final long memberPosId = pos.getMemberPos().getId(); pos.setMemberPos(null); posDao.update(pos); memberPosDao.delete(memberPosId); generateLog(pos); return pos; } @Override public void validate(final Pos pos) { getValidator(pos).validate(pos); } private Validator getValidator(final Pos pos) { final Validator validator = new Validator("pos"); final Property posId = validator.property("posId"); posId.required().maxLength(64); if (pos.isTransient()) { if (pos.getPosId() != null) { try { posDao.loadByPosId(pos.getPosId()); // If this point was reached, it means that there is a pos with the given posId throw new ValidationException("pos.error.posIdExists", ""); } catch (final EntityNotFoundException e) { // Ok, no pos with the given posId } } } if (pos.getMemberPos() != null && pos.getMemberPos().getId() != null) { if ((LoggedUser.isBroker() && permissionService.hasPermission(BrokerPermission.POS_CHANGE_PARAMETERS)) || (LoggedUser.isAdministrator() && permissionService.hasPermission(AdminMemberPermission.POS_CHANGE_PARAMETERS)) || (!LoggedUser.isBroker() && LoggedUser.isMember())) { validator.property("memberPos.allowMakePayment").key("memberPos.allowMakePayment").required(); validator.property("memberPos.maxSchedulingPayments").key("memberPos.maxSchedulingPayments").required(); validator.property("memberPos.numberOfCopies").key("memberPos.numberOfCopies").required(); validator.property("memberPos.resultPageSize").key("memberPos.resultPageSize").required(); } } return validator; } }