/* 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.entities.accounts.transactions; import java.io.Serializable; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.List; import nl.strohalm.cyclos.entities.Entity; import nl.strohalm.cyclos.entities.Relationship; import nl.strohalm.cyclos.entities.access.Channel; import nl.strohalm.cyclos.entities.accounts.AccountType; import nl.strohalm.cyclos.entities.accounts.Currency; import nl.strohalm.cyclos.entities.accounts.fees.account.AccountFee; import nl.strohalm.cyclos.entities.accounts.fees.transaction.TransactionFee; import nl.strohalm.cyclos.entities.accounts.fees.transaction.TransactionFee.ChargeType; import nl.strohalm.cyclos.entities.accounts.loans.LoanParameters; import nl.strohalm.cyclos.entities.customization.fields.PaymentCustomField; import nl.strohalm.cyclos.entities.groups.Group; import nl.strohalm.cyclos.entities.members.Member; import nl.strohalm.cyclos.entities.members.Reference.Level; import nl.strohalm.cyclos.utils.StringValuedEnum; import nl.strohalm.cyclos.utils.TimePeriod; import org.apache.commons.collections.CollectionUtils; /** * Every transfer has a type, which may contain fees and other relevant data * @author luis */ public class TransferType extends Entity { /** * A transfer type context represents where it can be performed * @author luis */ public static class Context implements Serializable { private static final long serialVersionUID = -7966654322680432255L; public static Context payment() { final Context context = new Context(); context.setPayment(true); return context; } public static Context self() { final Context context = new Context(); context.setSelfPayment(true); return context; } private boolean payment = false; private boolean selfPayment = false; public Context() { } public boolean isPayment() { return payment; } public boolean isSelfPayment() { return selfPayment; } public void setPayment(final boolean payment) { this.payment = payment; } public void setSelfPayment(final boolean selfPayment) { this.selfPayment = selfPayment; } } public static enum Direction { FROM, TO, BOTH } public static enum Relationships implements Relationship { FROM("from"), GROUPS("groups"), GROUPS_AS_MEMBER("groupsAsMember"), TO("to"), TRANSACTION_FEES("transactionFees"), GENERATED_BY_TRANSACTION_FEES("generatedByTransactionFees"), GENERATED_BY_ACCOUNT_FEES("generatedByAccountFees"), PAYMENT_FILTERS("paymentFilters"), AUTHORIZATION_LEVELS("authorizationLevels"), CUSTOM_FIELDS("customFields"), LINKED_CUSTOM_FIELDS("linkedCustomFields"), CHANNELS("channels"); private final String name; private Relationships(final String name) { this.name = name; } @Override public String getName() { return name; } } public static enum TransactionHierarchyVisibility implements StringValuedEnum { ADMIN("A"), BROKER("B"), MEMBER("M"); private final String value; private TransactionHierarchyVisibility(final String value) { this.value = value; } @Override public String getValue() { return value; } public boolean isVisibleTo(final Group.Nature groupNature) { switch (groupNature) { case ADMIN: return true; case BROKER: return this != TransactionHierarchyVisibility.ADMIN; case MEMBER: case OPERATOR: return this == TransactionHierarchyVisibility.MEMBER; } return false; } } private static final long serialVersionUID = -6248433842449336187L; private String name; private String description; private String confirmationMessage; private Context context = new Context(); private boolean priority; private boolean conciliable; private AccountType from; private AccountType to; private BigDecimal maxAmountPerDay; private BigDecimal minAmount; private LoanParameters loan; private Collection<? extends TransactionFee> transactionFees; private Collection<? extends TransactionFee> generatedByTransactionFees; private Collection<? extends AccountFee> generatedByAccountFees; private Collection<? extends Group> groups; private Collection<? extends Group> groupsAsMember; private Collection<PaymentFilter> paymentFilters; private boolean requiresAuthorization; private Collection<AuthorizationLevel> authorizationLevels; private boolean allowsScheduledPayments; private boolean requiresFeedback; private boolean reserveTotalAmountOnScheduling; private boolean allowCancelScheduledPayments; private boolean allowBlockScheduledPayments; private boolean showScheduledPaymentsToDestination; private boolean allowSmsNotification; private Calendar feedbackEnabledSince; private TimePeriod feedbackExpirationTime; private TimePeriod feedbackReplyExpirationTime; private String defaultFeedbackComments; private Level defaultFeedbackLevel; private Collection<Channel> channels; private Member fixedDestinationMember; private Collection<PaymentCustomField> customFields; private Collection<PaymentCustomField> linkedCustomFields; private String transferListenerClass; private TransactionHierarchyVisibility transactionHierarchyVisibility = TransactionHierarchyVisibility.MEMBER; /** * gets all the transaction fees based on a-rate, being the fees with ChargeType A_RATE or MIXED_A_D_RATES * @return a Collection with A-rated TransactionFees * @see #getRatedFees() */ public Collection<? extends TransactionFee> getARatedFees() { final List<TransactionFee> result = new ArrayList<TransactionFee>(transactionFees.size()); for (final TransactionFee fee : transactionFees) { if (fee.getChargeType() == ChargeType.A_RATE || fee.getChargeType() == ChargeType.MIXED_A_D_RATES) { result.add(fee); } } return result; } public Collection<AuthorizationLevel> getAuthorizationLevels() { return authorizationLevels; } public Collection<Channel> getChannels() { return channels; } public String getConfirmationMessage() { return confirmationMessage; } public Context getContext() { return context; } public Currency getCurrency() { try { return from.getCurrency(); } catch (final Exception e) { return null; } } public Collection<PaymentCustomField> getCustomFields() { return customFields; } public String getDefaultFeedbackComments() { return defaultFeedbackComments; } public Level getDefaultFeedbackLevel() { return defaultFeedbackLevel; } public String getDescription() { return description; } /** * gets all the transaction fees based on d-rate, that is: having ChargeType = D_RATE * @return a Collection with TransactionFees * @see #getRatedFees() */ public Collection<? extends TransactionFee> getDRatedFees() { final List<TransactionFee> result = new ArrayList<TransactionFee>(transactionFees.size()); for (final TransactionFee fee : transactionFees) { if (fee.getChargeType() == ChargeType.D_RATE || fee.getChargeType() == ChargeType.MIXED_A_D_RATES) { result.add(fee); } } return result; } public Calendar getFeedbackEnabledSince() { return feedbackEnabledSince; } public TimePeriod getFeedbackExpirationTime() { return feedbackExpirationTime; } public TimePeriod getFeedbackReplyExpirationTime() { return feedbackReplyExpirationTime; } public Member getFixedDestinationMember() { return fixedDestinationMember; } public AccountType getFrom() { return from; } public Collection<? extends AccountFee> getGeneratedByAccountFees() { return generatedByAccountFees; } public Collection<? extends TransactionFee> getGeneratedByTransactionFees() { return generatedByTransactionFees; } public Collection<? extends Group> getGroups() { return groups; } public Collection<? extends Group> getGroupsAsMember() { return groupsAsMember; } public Collection<PaymentCustomField> getLinkedCustomFields() { return linkedCustomFields; } public LoanParameters getLoan() { return loan; } public BigDecimal getMaxAmountPerDay() { return maxAmountPerDay; } public BigDecimal getMinAmount() { return minAmount; } @Override public String getName() { return name; } public Collection<PaymentFilter> getPaymentFilters() { return paymentFilters; } /** * gets all the transaction fees which do use a-rate or d-rate * @return a Collection with TransactionFees using a-rate or d-rate * @see #getRatedFees() */ public Collection<? extends TransactionFee> getRatedFees() { final List<TransactionFee> result = new ArrayList<TransactionFee>(transactionFees.size()); for (final TransactionFee fee : transactionFees) { if (fee.getChargeType() == ChargeType.A_RATE || fee.getChargeType() == ChargeType.D_RATE || fee.getChargeType() == ChargeType.MIXED_A_D_RATES) { result.add(fee); } } return result; } public AccountType getTo() { return to; } public Collection<? extends TransactionFee> getTransactionFees() { return transactionFees; } public TransactionHierarchyVisibility getTransactionHierarchyVisibility() { return transactionHierarchyVisibility; } public String getTransferListenerClass() { return transferListenerClass; } /** * @return true if there are any TransactionFees on this TT. */ public boolean hasTransactionFees() { return !CollectionUtils.isEmpty(transactionFees); } public boolean isAllowBlockScheduledPayments() { return allowBlockScheduledPayments; } public boolean isAllowCancelScheduledPayments() { return allowCancelScheduledPayments; } public boolean isAllowSmsNotification() { return allowSmsNotification; } public boolean isAllowsScheduledPayments() { return allowsScheduledPayments; } public boolean isConciliable() { return conciliable; } public boolean isFromMember() { return !isFromSystem(); } public boolean isFromSystem() { return from.getNature() == AccountType.Nature.SYSTEM; } /** * returns true if the TransferType has TransactionFees based on a-rate. */ public boolean isHavingAratedFees() { if (getARatedFees().size() == 0) { return false; } return true; } /** * returns true if the TransferType has TransactionFees based on d-rate. */ public boolean isHavingDratedFees() { if (getDRatedFees().size() == 0) { return false; } return true; } /** * returns true if the TransferType has TransactionFees based on a-rate or d-rate. */ public boolean isHavingRatedFees() { if (getRatedFees().size() == 0) { return false; } return true; } public boolean isLoanType() { return loan != null && loan.getType() != null; } public boolean isPriority() { return priority; } public boolean isRequiresAuthorization() { return requiresAuthorization; } public boolean isRequiresFeedback() { return requiresFeedback; } public boolean isReserveTotalAmountOnScheduling() { return reserveTotalAmountOnScheduling; } public boolean isShowScheduledPaymentsToDestination() { return showScheduledPaymentsToDestination; } public boolean isToMember() { return !isToSystem(); } public boolean isToSystem() { return to.getNature() == AccountType.Nature.SYSTEM; } public void setAllowBlockScheduledPayments(final boolean allowBlockScheduledPayments) { this.allowBlockScheduledPayments = allowBlockScheduledPayments; } public void setAllowCancelScheduledPayments(final boolean allowCancelScheduledPayments) { this.allowCancelScheduledPayments = allowCancelScheduledPayments; } public void setAllowSmsNotification(final boolean allowSmsNotification) { this.allowSmsNotification = allowSmsNotification; } public void setAllowsScheduledPayments(final boolean allowsScheduledPayments) { this.allowsScheduledPayments = allowsScheduledPayments; } public void setAuthorizationLevels(final Collection<AuthorizationLevel> authorizationLevels) { this.authorizationLevels = authorizationLevels; } public void setChannels(final Collection<Channel> channels) { this.channels = channels; } public void setConciliable(final boolean conciliable) { this.conciliable = conciliable; } public void setConfirmationMessage(final String confirmationMessage) { this.confirmationMessage = confirmationMessage; } public void setContext(final Context context) { this.context = context; } public void setCustomFields(final Collection<PaymentCustomField> customFields) { this.customFields = customFields; } public void setDefaultFeedbackComments(final String defaultFeedbackComments) { this.defaultFeedbackComments = defaultFeedbackComments; } public void setDefaultFeedbackLevel(final Level defaultFeedbackLevel) { this.defaultFeedbackLevel = defaultFeedbackLevel; } public void setDescription(final String description) { this.description = description; } public void setFeedbackEnabledSince(final Calendar feedbackEnabledSince) { this.feedbackEnabledSince = feedbackEnabledSince; } public void setFeedbackExpirationTime(final TimePeriod feedbackExpirationTime) { this.feedbackExpirationTime = feedbackExpirationTime; } public void setFeedbackReplyExpirationTime(final TimePeriod feedbackReplyExpirationTime) { this.feedbackReplyExpirationTime = feedbackReplyExpirationTime; } public void setFixedDestinationMember(final Member fixedDestinationMember) { this.fixedDestinationMember = fixedDestinationMember; } public void setFrom(final AccountType from) { this.from = from; } public void setGeneratedByAccountFees(final Collection<? extends AccountFee> generatedByAccountFees) { this.generatedByAccountFees = generatedByAccountFees; } public void setGeneratedByTransactionFees(final Collection<? extends TransactionFee> generatedByTransactionFees) { this.generatedByTransactionFees = generatedByTransactionFees; } public void setGroups(final Collection<? extends Group> groups) { this.groups = groups; } public void setGroupsAsMember(final Collection<? extends Group> groupsAsMember) { this.groupsAsMember = groupsAsMember; } public void setLinkedCustomFields(final Collection<PaymentCustomField> linkedCustomFields) { this.linkedCustomFields = linkedCustomFields; } public void setLoan(final LoanParameters loan) { this.loan = loan; if (loan != null) { loan.setOriginalTransferType(this); } } public void setMaxAmountPerDay(final BigDecimal maxAmountPerDay) { this.maxAmountPerDay = maxAmountPerDay; } public void setMinAmount(final BigDecimal minAmount) { this.minAmount = minAmount; } public void setName(final String name) { this.name = name; } public void setPaymentFilters(final Collection<PaymentFilter> paymentFilters) { this.paymentFilters = paymentFilters; } public void setPriority(final boolean priority) { this.priority = priority; } public void setRequiresAuthorization(final boolean requiresAuthorization) { this.requiresAuthorization = requiresAuthorization; } public void setRequiresFeedback(final boolean requiresFeedback) { this.requiresFeedback = requiresFeedback; } public void setReserveTotalAmountOnScheduling(final boolean reserveTotalAmountOnScheduling) { this.reserveTotalAmountOnScheduling = reserveTotalAmountOnScheduling; } public void setShowScheduledPaymentsToDestination(final boolean showScheduledPaymentsToDestination) { this.showScheduledPaymentsToDestination = showScheduledPaymentsToDestination; } public void setTo(final AccountType to) { this.to = to; } public void setTransactionFees(final Collection<? extends TransactionFee> transactionFees) { this.transactionFees = transactionFees; } public void setTransactionHierarchyVisibility(final TransactionHierarchyVisibility transactionHierarchyVisibility) { this.transactionHierarchyVisibility = transactionHierarchyVisibility; } public void setTransferListenerClass(final String transferListenerClass) { this.transferListenerClass = transferListenerClass; } @Override public String toString() { return getId() + " - " + name; } }