use of org.mifos.accounts.loan.business.LoanBO in project head by mifos.
the class StandardAccountService method handleParentGroupLoanPayment.
/**
* Handles parent NOT-GLIM group loan payment.
*/
private void handleParentGroupLoanPayment(AccountBO account, AccountPaymentParametersDto parentPaymentParametersDto, Integer savingsPaymentId, AccountPaymentEntity paymentEntity) throws PersistenceException, AccountException {
if (account instanceof LoanBO && account.isParentGroupLoanAccount()) {
if (parentPaymentParametersDto.getMemberInfo() == null || parentPaymentParametersDto.getMemberInfo().isEmpty()) {
createMembersLoanPaymentsData(parentPaymentParametersDto);
}
for (Map.Entry<Integer, String> member : parentPaymentParametersDto.getMemberInfo().entrySet()) {
AccountBO memberAcc = this.legacyAccountDao.getAccount(member.getKey());
if (null == parentPaymentParametersDto.getMemberAccountIdToRepay() || (null != parentPaymentParametersDto.getMemberAccountIdToRepay() && !parentPaymentParametersDto.getMemberAccountIdToRepay().equals(memberAcc.getAccountId()))) {
AccountPaymentParametersDto memberAccountPaymentParametersDto = new AccountPaymentParametersDto(parentPaymentParametersDto.getUserMakingPayment(), new AccountReferenceDto(memberAcc.getAccountId()), new BigDecimal(member.getValue()), parentPaymentParametersDto.getPaymentDate(), parentPaymentParametersDto.getPaymentType(), parentPaymentParametersDto.getComment(), parentPaymentParametersDto.getReceiptDate(), parentPaymentParametersDto.getReceiptId(), memberAcc.getCustomer().toCustomerDto());
if (parentPaymentParametersDto.getPaymentOptions().contains(AccountPaymentParametersDto.PaymentOptions.ALLOW_OVERPAYMENTS)) {
memberAccountPaymentParametersDto.addPaymentOption(AccountPaymentParametersDto.PaymentOptions.ALLOW_OVERPAYMENTS);
}
makePaymentNoCommit(memberAccountPaymentParametersDto, savingsPaymentId, paymentEntity);
} else {
AccountPaymentDto paymentDto = new AccountPaymentDto(Double.valueOf(member.getValue()), parentPaymentParametersDto.getPaymentDate().toDateMidnight().toDate(), parentPaymentParametersDto.getReceiptId(), reciptDateNullValidation(parentPaymentParametersDto.getReceiptDate()), parentPaymentParametersDto.getPaymentType().getValue());
((LoanBO) memberAcc).makeEarlyRepayment(paymentDto, parentPaymentParametersDto.getUserMakingPayment().getUserId(), parentPaymentParametersDto.getRepayLoanInfoDto().isWaiveInterest(), new Money(account.getCurrency(), parentPaymentParametersDto.getInterestDueForCurrentInstalmanet()));
}
}
}
}
use of org.mifos.accounts.loan.business.LoanBO in project head by mifos.
the class StandardAccountService method validateLoanDisbursement.
/**
* Note that, since we don't store or otherwise utilize the amount disbursed (passed in
* AccountPaymentParametersDto.paymentAmount) we <em>do not</em> validate that digits after decimal for the amount
* disbursed fit in an allowed range. We <em>do</em> check that the amount disbursed matches the full amount of the
* loan.
*/
@Override
public List<InvalidPaymentReason> validateLoanDisbursement(AccountPaymentParametersDto payment) throws Exception {
List<InvalidPaymentReason> errors = new ArrayList<InvalidPaymentReason>();
LoanBO loanAccount = this.legacyLoanDao.getAccount(payment.getAccountId());
if ((loanAccount.getState() != AccountState.LOAN_APPROVED) && (loanAccount.getState() != AccountState.LOAN_DISBURSED_TO_LOAN_OFFICER)) {
errors.add(InvalidPaymentReason.INVALID_LOAN_STATE);
}
BigDecimal paymentAmount = payment.getPaymentAmount();
if ("MPESA".equals(payment.getPaymentType().getName())) {
paymentAmount = computeWithdrawnForMPESA(paymentAmount, loanAccount);
}
disbursalAmountMatchesFullLoanAmount(paymentAmount, errors, loanAccount);
Date meetingDate = new CustomerPersistence().getLastMeetingDateForCustomer(loanAccount.getCustomer().getCustomerId());
boolean repaymentIndependentOfMeetingEnabled = new ConfigurationPersistence().isRepaymentIndepOfMeetingEnabled();
if (!loanAccount.isTrxnDateValid(payment.getPaymentDate().toDateMidnight().toDate(), meetingDate, repaymentIndependentOfMeetingEnabled)) {
errors.add(InvalidPaymentReason.INVALID_DATE);
}
if (!getLoanDisbursementTypes().contains(payment.getPaymentType())) {
errors.add(InvalidPaymentReason.UNSUPPORTED_PAYMENT_TYPE);
}
if (!loanAccount.paymentAmountIsValid(new Money(loanAccount.getCurrency(), payment.getPaymentAmount()), payment.getPaymentOptions())) {
errors.add(InvalidPaymentReason.INVALID_PAYMENT_AMOUNT);
}
if (loanAccount.getCustomer().isDisbursalPreventedDueToAnyExistingActiveLoansForTheSameProduct(loanAccount.getLoanOffering())) {
errors.add(InvalidPaymentReason.OTHER_ACTIVE_LOANS_FOR_THE_SAME_PRODUCT);
}
return errors;
}
use of org.mifos.accounts.loan.business.LoanBO in project head by mifos.
the class StandardAccountService method makePaymentNoCommit.
public void makePaymentNoCommit(AccountPaymentParametersDto accountPaymentParametersDto, Integer savingsPaymentId, AccountPaymentEntity parentPayment) throws PersistenceException, AccountException {
final int accountId = accountPaymentParametersDto.getAccountId();
final AccountBO account = this.legacyAccountDao.getAccount(accountId);
MifosUser mifosUser = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserContext userContext = new UserContextFactory().create(mifosUser);
try {
personnelDao.checkAccessPermission(userContext, account.getOfficeId(), account.getCustomer().getLoanOfficerId());
} catch (AccountException e) {
throw new MifosRuntimeException(SecurityConstants.KEY_ACTIVITY_NOT_ALLOWED, e);
}
monthClosingServiceFacade.validateTransactionDate(accountPaymentParametersDto.getPaymentDate().toDateMidnight().toDate());
/**
* Handle member payment if parent payment data not provided.
* Situation may occur when payment is executed directly on group member account (e.g. from transaction import).
* Loan Group Member payments should be posted after parent payment.
*/
if (account.isGroupLoanAccountMember() && parentPayment == null) {
AccountPaymentParametersDto parentPaymentParametersDto = this.createParentLoanPaymentData(account, accountPaymentParametersDto);
makePaymentNoCommit(parentPaymentParametersDto, savingsPaymentId, null);
return;
}
PersonnelBO loggedInUser = ApplicationContextProvider.getBean(LegacyPersonnelDao.class).findPersonnelById(accountPaymentParametersDto.getUserMakingPayment().getUserId());
List<InvalidPaymentReason> validationErrors = validatePayment(accountPaymentParametersDto);
if (!(account instanceof CustomerAccountBO) && validationErrors.contains(InvalidPaymentReason.INVALID_DATE)) {
throw new AccountException("errors.invalidTxndate");
}
Money overpaymentAmount = null;
Money amount = new Money(account.getCurrency(), accountPaymentParametersDto.getPaymentAmount());
if (account instanceof LoanBO && accountPaymentParametersDto.getPaymentOptions().contains(AccountPaymentParametersDto.PaymentOptions.ALLOW_OVERPAYMENTS) && amount.isGreaterThan(((LoanBO) account).getTotalRepayableAmount())) {
overpaymentAmount = amount.subtract(((LoanBO) account).getTotalRepayableAmount());
amount = ((LoanBO) account).getTotalRepayableAmount();
}
Date receiptDate = null;
if (accountPaymentParametersDto.getReceiptDate() != null) {
receiptDate = accountPaymentParametersDto.getReceiptDate().toDateMidnight().toDate();
}
PaymentData paymentData = account.createPaymentData(amount, accountPaymentParametersDto.getPaymentDate().toDateMidnight().toDate(), accountPaymentParametersDto.getReceiptId(), receiptDate, accountPaymentParametersDto.getPaymentType().getValue(), loggedInUser);
if (savingsPaymentId != null) {
AccountPaymentEntity withdrawal = legacyAccountDao.findPaymentById(savingsPaymentId);
paymentData.setOtherTransferPayment(withdrawal);
}
if (accountPaymentParametersDto.getCustomer() != null) {
paymentData.setCustomer(customerDao.findCustomerById(accountPaymentParametersDto.getCustomer().getCustomerId()));
}
paymentData.setComment(accountPaymentParametersDto.getComment());
paymentData.setOverpaymentAmount(overpaymentAmount);
if (account instanceof LoanBO && account.isGroupLoanAccountMember() && parentPayment != null) {
paymentData.setParentPayment(parentPayment);
}
AccountPaymentEntity paymentEntity = account.applyPayment(paymentData);
handleParentGroupLoanPayment(account, accountPaymentParametersDto, savingsPaymentId, paymentEntity);
this.legacyAccountDao.createOrUpdate(account);
}
use of org.mifos.accounts.loan.business.LoanBO in project head by mifos.
the class StandardAccountService method disburseLoans.
@Override
public void disburseLoans(List<AccountPaymentParametersDto> accountPaymentParametersDtoList, Locale locale, Short paymentTypeIdForFees, Integer accountForTransferId) throws Exception {
StaticHibernateUtil.startTransaction();
for (AccountPaymentParametersDto accountPaymentParametersDto : accountPaymentParametersDtoList) {
LoanBO loan = this.legacyLoanDao.getAccount(accountPaymentParametersDto.getAccountId());
PersonnelBO personnelBO = personnelDao.findPersonnelById(accountPaymentParametersDto.getUserMakingPayment().getUserId());
BigDecimal paymentAmount = accountPaymentParametersDto.getPaymentAmount();
handleLoanDisbursal(locale, loan, personnelBO, paymentAmount, accountPaymentParametersDto.getPaymentType(), accountPaymentParametersDto.getReceiptDate(), accountPaymentParametersDto.getPaymentDate(), accountPaymentParametersDto.getReceiptId(), paymentTypeIdForFees, accountForTransferId);
}
StaticHibernateUtil.commitTransaction();
}
use of org.mifos.accounts.loan.business.LoanBO in project head by mifos.
the class ClientStatusChangeIntegrationTest method givenClientHasActiveAccountsShouldNotPassValidationWhenTryingToTranistionClientToClosed.
@Test
public void givenClientHasActiveAccountsShouldNotPassValidationWhenTryingToTranistionClientToClosed() throws Exception {
// setup
CenterBO existingCenter = new CenterBuilder().with(existingMeeting).withName("Center-IntegrationTest").with(existingOffice).withLoanOfficer(existingLoanOfficer).withUserContext().build();
IntegrationTestObjectMother.createCenter(existingCenter, existingMeeting);
GroupBO existingActiveGroup = new GroupBuilder().withName("newGroup").withStatus(CustomerStatus.GROUP_ACTIVE).withParentCustomer(existingCenter).formedBy(existingUser).build();
IntegrationTestObjectMother.createGroup(existingActiveGroup, existingMeeting);
ClientBO existingActiveClient = new ClientBuilder().withStatus(CustomerStatus.CLIENT_ACTIVE).withParentCustomer(existingActiveGroup).buildForIntegrationTests();
IntegrationTestObjectMother.createClient(existingActiveClient, existingMeeting);
StaticHibernateUtil.flushAndClearSession();
DateTime startDate = new DateTime().minusDays(14);
LoanOfferingBO clientLoanProduct = new LoanProductBuilder().appliesToClientsOnly().withGlobalProductNumber("XXX-00002").active().withMeeting(existingMeeting).withName("Loan-client").withShortName("dsvd").withStartDate(startDate).withDefaultInterest(1.2).buildForIntegrationTests();
IntegrationTestObjectMother.createProduct(clientLoanProduct);
LoanBO clientLoan = new LoanAccountBuilder().withLoanProduct(clientLoanProduct).withCustomer(existingActiveClient).withOriginalLoanAmount(600.0).build();
IntegrationTestObjectMother.saveLoanAccount(clientLoan);
existingActiveGroup = this.customerDao.findGroupBySystemId(existingActiveGroup.getGlobalCustNum());
existingActiveClient = this.customerDao.findClientBySystemId(existingActiveClient.getGlobalCustNum());
existingActiveClient.setUserContext(TestUtils.makeUser());
CustomerStatusFlag customerStatusFlag = null;
CustomerNoteEntity customerNote = new CustomerNoteEntity("go active", new Date(), existingActiveClient.getPersonnel(), existingActiveClient);
// exercise test
try {
customerService.updateClientStatus(existingActiveClient, existingActiveClient.getStatus(), CustomerStatus.CLIENT_CLOSED, customerStatusFlag, customerNote);
fail("should fail validation");
} catch (CustomerException expected) {
assertThat(expected.getKey(), is(CustomerConstants.CUSTOMER_HAS_ACTIVE_ACCOUNTS_EXCEPTION));
assertThat(existingActiveClient.getStatus(), is(CustomerStatus.CLIENT_ACTIVE));
}
}
Aggregations