/* 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.payments.scheduled; import java.math.BigDecimal; import javax.servlet.http.HttpServletRequest; import nl.strohalm.cyclos.annotations.Inject; import nl.strohalm.cyclos.controls.ActionContext; import nl.strohalm.cyclos.controls.BaseFormAction; import nl.strohalm.cyclos.entities.accounts.AccountOwner; import nl.strohalm.cyclos.entities.accounts.AccountType; import nl.strohalm.cyclos.entities.accounts.MemberAccount; import nl.strohalm.cyclos.entities.accounts.transactions.Payment; import nl.strohalm.cyclos.entities.accounts.transactions.ScheduledPayment; import nl.strohalm.cyclos.entities.accounts.transactions.Transfer; import nl.strohalm.cyclos.entities.accounts.transactions.TransferType; import nl.strohalm.cyclos.entities.exceptions.UnexpectedEntityException; import nl.strohalm.cyclos.entities.members.Member; import nl.strohalm.cyclos.services.transactions.PaymentService; import nl.strohalm.cyclos.services.transactions.ScheduledPaymentService; import nl.strohalm.cyclos.services.transactions.exceptions.CreditsException; import nl.strohalm.cyclos.services.transfertypes.TransactionFeePreviewDTO; import nl.strohalm.cyclos.services.transfertypes.TransactionFeeService; import nl.strohalm.cyclos.services.transfertypes.TransferTypeService; import nl.strohalm.cyclos.utils.ActionHelper; import nl.strohalm.cyclos.utils.RelationshipHelper; import nl.strohalm.cyclos.utils.validation.RequiredError; import nl.strohalm.cyclos.utils.validation.ValidationException; import org.apache.commons.lang.StringUtils; import org.apache.struts.action.ActionForward; public class ConfirmScheduledPaymentAction extends BaseFormAction { private PaymentService paymentService; private ScheduledPaymentService scheduledPaymentService; private TransactionFeeService transactionFeeService; private TransferTypeService transferTypeService; @Inject public void setPaymentService(final PaymentService paymentService) { this.paymentService = paymentService; } @Inject public void setScheduledPaymentService(final ScheduledPaymentService scheduledPaymentService) { this.scheduledPaymentService = scheduledPaymentService; } @Inject public void setTransactionFeeService(final TransactionFeeService transactionFeeService) { this.transactionFeeService = transactionFeeService; } @Inject public void setTransferTypeService(final TransferTypeService transferTypeService) { this.transferTypeService = transferTypeService; } @Override protected ActionForward handleSubmit(final ActionContext context) throws Exception { Transfer transfer = resolveTransfer(context); // Validate the transaction password if needed if (shouldValidateTransactionPassword(context, transfer)) { final ScheduledPaymentForm form = context.getForm(); context.checkTransactionPassword(form.getTransactionPassword()); } // Perform the actual payment try { transfer = scheduledPaymentService.processTransfer(transfer); } catch (final CreditsException e) { return context.sendError(actionHelper.resolveErrorKey(e), actionHelper.resolveParameters(e)); } catch (final UnexpectedEntityException e) { return context.sendError("payment.error.invalidTransferType"); } return ActionHelper.redirectWithParam(context.getRequest(), context.getSuccessForward(), "paymentId", transfer.getScheduledPayment().getId()); } @Override protected void prepareForm(final ActionContext context) throws Exception { final Transfer transfer = resolveTransfer(context); // Check for transaction password final HttpServletRequest request = context.getRequest(); final boolean requestTransactionPassword = shouldValidateTransactionPassword(context, transfer); if (requestTransactionPassword) { context.validateTransactionPassword(); } request.setAttribute("requestTransactionPassword", requestTransactionPassword); request.setAttribute("wouldRequireAuthorization", paymentService.wouldRequireAuthorization(transfer)); // Transfer number and number of transfers final int transferNumber = getTransferNumber(transfer); final int numberOfTransfers = getNumberOfTransfer(transfer); request.setAttribute("transferNumber", transferNumber); request.setAttribute("numberOfTransfers", numberOfTransfers); // Fetch related data final AccountOwner from = transfer.getFromOwner(); final AccountOwner to = transfer.getToOwner(); final TransferType transferType = transferTypeService.load(transfer.getType().getId(), RelationshipHelper.nested(TransferType.Relationships.FROM, AccountType.Relationships.CURRENCY), TransferType.Relationships.TO); final BigDecimal amount = transfer.getAmount(); if (from instanceof Member) { request.setAttribute("fromMember", from); } if (to instanceof Member) { request.setAttribute("toMember", to); } transfer.setType(transferType); request.setAttribute("unitsPattern", transferType.getFrom().getCurrency().getPattern()); // Store the transaction fees final TransactionFeePreviewDTO preview = transactionFeeService.preview(from, to, transferType, amount); request.setAttribute("finalAmount", preview.getFinalAmount()); request.setAttribute("fees", preview.getFees()); request.setAttribute("transfer", transfer); } @Override protected void validateForm(final ActionContext context) { if (shouldValidateTransactionPassword(context, resolveTransfer(context))) { final ScheduledPaymentForm form = context.getForm(); if (StringUtils.isEmpty(form.getTransactionPassword())) { throw new ValidationException("_transactionPassword", "login.transactionPassword", new RequiredError()); } } } private int getNumberOfTransfer(final Transfer transfer) { final ScheduledPayment scheduledPayment = transfer.getScheduledPayment(); return scheduledPayment.getTransfers().size(); } private int getTransferNumber(final Transfer transfer) { final ScheduledPayment scheduledPayment = transfer.getScheduledPayment(); int transferNumber = 0; for (final Transfer currentTransfer : scheduledPayment.getTransfers()) { transferNumber++; if (currentTransfer.equals(transfer)) { break; } } return transferNumber; } private Transfer resolveTransfer(final ActionContext context) { final ScheduledPaymentForm form = context.getForm(); final Long transferId = form.getTransferId(); if (transferId <= 0L) { throw new ValidationException(); } return paymentService.load(transferId, RelationshipHelper.nested(Payment.Relationships.FROM, MemberAccount.Relationships.MEMBER), RelationshipHelper.nested(Payment.Relationships.TO, MemberAccount.Relationships.MEMBER), RelationshipHelper.nested(Transfer.Relationships.SCHEDULED_PAYMENT, ScheduledPayment.Relationships.TRANSFERS)); } private boolean shouldValidateTransactionPassword(final ActionContext context, final Transfer transfer) { final TransferType transferType = transferTypeService.load(transfer.getType().getId(), TransferType.Relationships.FROM); return context.isTransactionPasswordEnabled(transferType.getFrom()); } }