/*
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.rates;
import java.math.BigDecimal;
import java.util.Calendar;
import nl.strohalm.cyclos.entities.accounts.Account;
import nl.strohalm.cyclos.entities.accounts.fees.transaction.SimpleTransactionFee.ARateRelation;
import nl.strohalm.cyclos.entities.accounts.fees.transaction.TransactionFee;
import nl.strohalm.cyclos.entities.accounts.transactions.Transfer;
import nl.strohalm.cyclos.services.transactions.GrantLoanDTO;
import nl.strohalm.cyclos.services.transactions.TransferDTO;
import nl.strohalm.cyclos.utils.validation.Validator;
/**
* Local interface. It must be used only from other services.
*/
public interface RateServiceLocal extends RateService {
/**
* does the validation for fields when configuring an A-rated fee.
*/
Validator applyARateFieldsValidation(Validator validator, ARatedFeeDTO dto, ARateRelation arateRelation);
/**
* applies the rates for a newly created loan
*/
RatesResultDTO applyLoan(TransferDTO transferDto, GrantLoanDTO params);
/**
* applies the needed rate changes which result from the transfer to the account. These changes mean:
* <ul>
* <li>rate of the transfer is calculated
* <li>if needed, the from-account's rateBalanceCorrection is saved to the RateSaver object, ready for future persisting.
* <li>this transfer rate is merged with the to-account's rate.
* <li>the result is saved to the resulting RateSaver object, ready for future persisting.
* </ul>
* NO changes are made to the transfer itself, nor to the accounts. <br>
* Note that this method requires that all accounts (both from and to) are locked. The calling method should take care of that.
* @param transfer
* @return RateSaver object with the transfer's rate, and with a que of AccountRates entities to be persisted. These can be persisted as soon as
* the tranfer itself is persisted. If the specific rate is null, it's corresponding field on the result will be null. If no rates enabled, it
* will have all fields set to null.
*/
RatesToSave applyTransfer(Transfer transfer);
/**
* performs correcting of the rates in a chargeback transaction. This is to be called after all other actions are done, that is: after the
* original transfer is marked as chargedback.
* <p>
* Chargebacks are treated as transactions which are returned/undone. This leads to the following strategy:
* <ul>
* <li>the chargeback transfer is a transfer in the same direction as the original transfer, but with a negated transfer amount. Rates are not
* applied as usual in such a case, but treated in an exceptional way (see next point). Just applying rates with a negated transfer amount would
* lead to deviations in case the accounts have been used in the meantime.
* <li>both involved accounts get their rates recalculated from the date of the original chargedback transfer.
* <li>no deeper levels correction; only correction on the primary involved accounts. This means that any other accounts than the original
* transfer's from and to account will not be updated for any rates that might have been changed due to the chargeback. So there are no side
* effects for other accounts, even if such an other account was involved in a transfer from or to the original from and to accounts, that took
* place between an original transfer and it's chargeback.
* <li>Other transfers are NOT affected by the chargeback. A Transfer is considered an agreement under the then valid circumstances. This means
* that a transfer's rates are fixed from the moment the tranfer is processed, and that these rates are NOT changed as a result of earlier
* chargebacks, even if the account from which the transfer was paid had it's rates changed as a result of a chargeback.
* </ul>
* @param original The transfer to be chargedback
* @param chargeback the transfer that was chargedback
*/
void chargeback(Transfer original, Transfer chargeback);
/**
* converts the rate from raw Calendar rates to BigDecimal Rates
* @param ratesDTO a RatesDTO which needs to have either emissionDate, expirationDate or both set. It must also have a date set, and in case of
* D-rate, a Currency
* @return sets the calculated BigDecimal rates to a new RatesResultDTO object. If a particular rate in the input is null, the corresponding field
* in the output will be null too.
*/
RatesResultDTO dateToRate(RatesDTO ratesDTO);
/**
* gets the precentage of the fee with chargeType A_RATED or MIXED_A_D_RATES.
* @param fee
* @param rawARate a Calendar being the raw A-rate to be used. May NOT be null.
* @param rawDRate a Calendar being the raw D-rate to be used. May be null in case of A_RATED; in that case the param is not used.
* @param date the processdate
* @return the percentage of the fee charge.
*/
BigDecimal getARatedFeePercentage(TransactionFee fee, Calendar rawARate, Calendar rawDRate, Calendar date);
/**
* calculates the conversion result according to the D-rate.
* @param setOfUnits a RatesDTO. Needs to have set:
* <ul>
* <li>the currency
* <li>the amount to be converted
* <li>the expiration date.
* <li>the date
* </ul>
* @return null if D-rate is not enabled. Otherwise, the sum the member gets from converting the original amount.
*/
BigDecimal getDRateConversionResult(RatesDTO setOfUnits);
/**
* gets a validator for the currency's RateParameters.
*/
Validator getRateParametersValidator(Validator validator, WhatRate whatRate);
/**
* gets all the rates, plus the virtualRatedBalance at the given date. If the date in the param is null, it gets the present rates.
* <ul>
* <li>if no rates are enabled on the requested date, it returns a RatesResultDTO with all rate fields set to null.
* <li>If some rate (A, D, I) is not enabled on the requested date, it's corresponding field on the returned result will be null.
* <li>rates are updated with transfers which happened between the last available AccountRatesEntity and the requested date.
* <li>If a null rate is encountered while the rate is enabled, that rate is initialized. This also counts for rateBalanceCorrection/VRB. An
* exception is the I-rate, as this cannot be initialized. In this case an alert is fired
* <li>If the account is an unlimited type, the virtualRatedBalance is set to zero. See next item for consequences.
* <li>If the virtualRatedBalance is zero, rates are set to their creation value.
* </ul>
*
* @param a RatesDTO with the following set:
* <ul>
* <li>date - may be null, in which case the present rates are retrieved, and the history is not looped
* <li>account
* <li>amount (balance)
* </ul>
* @return a RatesResultDTO containing enabled rates and VRB. Rates are included as raw rates and as BigDecimals.
*/
RatesResultDTO getRates(RatesDTO dto);
/**
* gets all the Rates for a transfer from the from-account. Does this by checking if the account has sufficient balance. If not, it creates extra
* units by going negative. Created units get a rate as specifically defined for newly created units. Note that the method does NOT check if the
* lower account limit is violated; this is a task to be done by the calling method. It either doesn't set a new ratebalancecorrection on the from
* account if it finds out new units have to be created.
*
* @param from the from Account
* @param amount the amount to be taken from the from account
* @param date the date of the (supposed) transfer; if null, this is now.
*
* @return a RatesResultDTO containing the raw rates as well as their BigDecimal numerical equivalents to be used for this transfer. If new units
* had to be created because of this account going negative, then the DTO also contains the new value for rateBalanceCorrection. Calling methods
* should check on this, and save this if appropriate. Returns null if the rate is not enabled on the currency.
* @throws IllegalArgumentException in case of payments in past, that is, if transfers exist for this account after or ON the requested date. NOTE
* that the method also raises the exception in case of an already existing, processed transfer with the exact same date/time.
*/
RatesResultDTO getRatesForTransferFrom(Account from, BigDecimal amount, Calendar date);
/**
* checks if any of the rates is enabled on the given date.
* @param account
* @param date
* @return true if any rate enabled
*/
boolean isAnyRateEnabled(final Account account, final Calendar date);
/**
* persists the rates in the argument.
* @param rates
*/
void persist(RatesToSave rates);
/**
* converts the rate from BigDecimals to raw Calendar dates. As I-rate doesn't have a raw calendar date, i-rate is ignored.
* @param ratesResultDTO a RatesResultDTO which needs to have either emissionDate, expirationDate or both set. It also needs to have a date set.
* @return sets the calculated Calendar raw rates to a new RatesResultDTO object. If a particular rate in the input is null, the corresponding
* field in the output will be null too.
*/
RatesResultDTO rateToDate(final RatesResultDTO params);
}