private CollectionSheetEntryGridDto getSuccessfulBulkEntry() throws Exception { MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING)); Date startDate = new Date(System.currentTimeMillis()); center = TestObjectFactory.createWeeklyFeeCenter("Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter( "Group", CustomerStatus.GROUP_ACTIVE, center); client = TestObjectFactory.createClient("Client", CustomerStatus.CLIENT_ACTIVE, group); LoanOfferingBO loanOffering1 = TestObjectFactory.createLoanOffering(startDate, meeting); LoanOfferingBO loanOffering2 = TestObjectFactory.createLoanOffering( "Loan2345", "313f", ApplicableTo.CLIENTS, startDate, PrdStatus.LOAN_ACTIVE, 300.0, 1.2, 3, InterestType.FLAT, meeting); groupAccount = TestObjectFactory.createLoanAccount( "42423142341", group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, startDate, loanOffering1); clientAccount = getLoanAccount(AccountState.LOAN_APPROVED, startDate, 1, loanOffering2); Date currentDate = new Date(System.currentTimeMillis()); // 2010-01-18: JohnW - This use of TestObjectFactory.createSavingsProduct used to break a number // of // business rules. // E.g all the savings products were set up as applicable for Groups and "per individual" which // is wrong for // centers and clients. In the case of the client being wrongly set up as "Per Individual" it // now triggers save // collection sheet validation (which checks that the account associated with the client marked // "per individual" // matches its parent group or center) // Also, when creating the center savings accounts (which is effectively "per individual") and // the group savings // account which is "per individual" the saving_schedule entries for the client are not written // (they are in the // production code). // // Considered using/updating the savingsProductBuilder functionality but that doesn't deal with // the // "per individual" aspect either (update: it does, but still problem with builder creating // installments). // Decided not to try and fix it up (good deal of effort involved) but rather change the // TestObjectFactory.createSavingsProduct to accept a RecommendedAmountUnit parameter. // Unfortunately it wouldn't allow a null parameter (which is valid for centers and clients) // through so, where // necessary, I picked a value that worked for the test but was wrong in a business rule sense // (just as its // always been). // So the savings product test data doesn't adhere to business rules but all tests pass here and // in others // tests. SavingsOfferingBO savingsOffering1 = TestObjectFactory.createSavingsProduct( "SavingPrd1", "ased", currentDate, RecommendedAmountUnit.COMPLETE_GROUP); SavingsOfferingBO savingsOffering2 = TestObjectFactory.createSavingsProduct( "SavingPrd2", "cvdf", currentDate, RecommendedAmountUnit.COMPLETE_GROUP); SavingsOfferingBO savingsOffering3 = TestObjectFactory.createSavingsProduct( "SavingPrd3", "zxsd", currentDate, RecommendedAmountUnit.COMPLETE_GROUP); centerSavingsAccount = TestObjectFactory.createSavingsAccount( "43244334", center, Short.valueOf("16"), startDate, savingsOffering1); groupSavingsAccount = TestObjectFactory.createSavingsAccount( "43234434", group, Short.valueOf("16"), startDate, savingsOffering2); clientSavingsAccount = TestObjectFactory.createSavingsAccount( "43245434", client, Short.valueOf("16"), startDate, savingsOffering3); CollectionSheetEntryView bulkEntryParent = new CollectionSheetEntryView(getCusomerView(center), null); SavingsAccountView centerSavingsAccountView = getSavingsAccountView(centerSavingsAccount); centerSavingsAccountView.setDepositAmountEntered("100"); centerSavingsAccountView.setWithDrawalAmountEntered("10"); bulkEntryParent.addSavingsAccountDetail(centerSavingsAccountView); bulkEntryParent.setCustomerAccountDetails(getCustomerAccountView(center)); CollectionSheetEntryView bulkEntryChild = new CollectionSheetEntryView(getCusomerView(group), null); LoanAccountView groupLoanAccountView = getLoanAccountView(groupAccount); SavingsAccountView groupSavingsAccountView = getSavingsAccountView(groupSavingsAccount); groupSavingsAccountView.setDepositAmountEntered("100"); groupSavingsAccountView.setWithDrawalAmountEntered("10"); bulkEntryChild.addLoanAccountDetails(groupLoanAccountView); bulkEntryChild.addSavingsAccountDetail(groupSavingsAccountView); bulkEntryChild.setCustomerAccountDetails(getCustomerAccountView(group)); CollectionSheetEntryView bulkEntrySubChild = new CollectionSheetEntryView(getCusomerView(client), null); LoanAccountView clientLoanAccountView = getLoanAccountView(clientAccount); clientLoanAccountView.setAmountPaidAtDisbursement(0.0); SavingsAccountView clientSavingsAccountView = getSavingsAccountView(clientSavingsAccount); clientSavingsAccountView.setDepositAmountEntered("100"); clientSavingsAccountView.setWithDrawalAmountEntered("10"); bulkEntrySubChild.addLoanAccountDetails(clientLoanAccountView); bulkEntrySubChild.setAttendence(new Short("2")); bulkEntrySubChild.addSavingsAccountDetail(clientSavingsAccountView); bulkEntrySubChild.setCustomerAccountDetails(getCustomerAccountView(client)); bulkEntryChild.addChildNode(bulkEntrySubChild); bulkEntryParent.addChildNode(bulkEntryChild); LoanAccountsProductView childView = bulkEntryChild.getLoanAccountDetails().get(0); childView.setPrdOfferingId(groupLoanAccountView.getPrdOfferingId()); childView.setEnteredAmount("100.0"); LoanAccountsProductView subchildView = bulkEntrySubChild.getLoanAccountDetails().get(0); subchildView.setDisBursementAmountEntered(clientAccount.getLoanAmount().toString()); subchildView.setPrdOfferingId(clientLoanAccountView.getPrdOfferingId()); ProductDto loanOfferingDto = new ProductDto(loanOffering1.getPrdOfferingId(), loanOffering1.getPrdOfferingShortName()); ProductDto loanOfferingDto2 = new ProductDto(loanOffering2.getPrdOfferingId(), loanOffering2.getPrdOfferingShortName()); List<ProductDto> loanProducts = Arrays.asList(loanOfferingDto, loanOfferingDto2); ProductDto savingsOfferingDto = new ProductDto( savingsOffering1.getPrdOfferingId(), savingsOffering1.getPrdOfferingShortName()); ProductDto savingsOfferingDto2 = new ProductDto( savingsOffering2.getPrdOfferingId(), savingsOffering2.getPrdOfferingShortName()); ProductDto savingsOfferingDto3 = new ProductDto( savingsOffering3.getPrdOfferingId(), savingsOffering3.getPrdOfferingShortName()); List<ProductDto> savingsProducts = Arrays.asList(savingsOfferingDto, savingsOfferingDto2, savingsOfferingDto3); final PersonnelView loanOfficer = getPersonnelView(center.getPersonnel()); final OfficeView officeView = null; final List<CustomValueListElement> attendanceTypesList = new ArrayList<CustomValueListElement>(); bulkEntryParent.setCountOfCustomers(3); final CollectionSheetEntryGridDto bulkEntry = new CollectionSheetEntryGridDto( bulkEntryParent, loanOfficer, officeView, getPaymentTypeView(), startDate, "324343242", startDate, loanProducts, savingsProducts, attendanceTypesList); return bulkEntry; }
@TransactionDemarcate(validateAndResetToken = true) @CloseSession public ActionForward update( final ActionMapping mapping, final ActionForm form, final HttpServletRequest request, @SuppressWarnings("unused") final HttpServletResponse response) throws Exception { LoanDisbursementActionForm actionForm = (LoanDisbursementActionForm) form; UserContext uc = getUserContext(request); Date trxnDate = getDateFromString(actionForm.getTransactionDate(), uc.getPreferredLocale()); trxnDate = DateUtils.getDateWithoutTimeStamp(trxnDate.getTime()); Date receiptDate = getDateFromString(actionForm.getReceiptDate(), uc.getPreferredLocale()); Integer loanAccountId = Integer.valueOf(actionForm.getAccountId()); AccountBO accountBO = new AccountBusinessService().getAccount(loanAccountId); createGroupQuestionnaire.saveResponses(request, actionForm, loanAccountId); try { String paymentTypeIdStringForDisbursement = actionForm.getPaymentTypeId(); Short paymentTypeIdForDisbursement = StringUtils.isEmpty(paymentTypeIdStringForDisbursement) ? PaymentTypes.CASH.getValue() : Short.valueOf(paymentTypeIdStringForDisbursement); Short paymentTypeId = Short.valueOf(paymentTypeIdForDisbursement); final String comment = ""; final BigDecimal disbursalAmount = new BigDecimal(actionForm.getLoanAmount()); CustomerDto customerDto = null; PaymentTypeDto paymentType = null; AccountPaymentParametersDto loanDisbursement = new AccountPaymentParametersDto( new UserReferenceDto(uc.getId()), new AccountReferenceDto(loanAccountId), disbursalAmount, new LocalDate(trxnDate), paymentType, comment, new LocalDate(receiptDate), actionForm.getReceiptId(), customerDto); monthClosingServiceFacade.validateTransactionDate(trxnDate); // GLIM List<LoanBO> individualLoans = this.loanDao.findIndividualLoans(loanAccountId); for (LoanBO individual : individualLoans) { if (!loanAccountServiceFacade.isTrxnDateValid( Integer.valueOf(individual.getAccountId()), trxnDate)) { throw new BusinessRuleException("errors.invalidTxndateOfDisbursal"); } } this.loanAccountServiceFacade.disburseLoan(loanDisbursement, paymentTypeId); for (LoanBO individual : individualLoans) { loanDisbursement = new AccountPaymentParametersDto( new UserReferenceDto(uc.getId()), new AccountReferenceDto(individual.getAccountId()), individual.getLoanAmount().getAmount(), new LocalDate(trxnDate), paymentType, comment, new LocalDate(receiptDate), actionForm.getReceiptId(), customerDto); this.loanAccountServiceFacade.disburseLoan(loanDisbursement, paymentTypeId); } } catch (BusinessRuleException e) { throw new AccountException(e.getMessage()); } catch (MifosRuntimeException e) { if (e.getCause() != null && e.getCause() instanceof AccountException) { throw new AccountException(e.getCause().getMessage()); } String msg = "errors.cannotDisburseLoan.because.disburseFailed"; logger.error(msg, e); throw new AccountException(msg); } catch (Exception e) { String msg = "errors.cannotDisburseLoan.because.disburseFailed"; logger.error(msg, e); throw new AccountException(msg); } return mapping.findForward(Constants.UPDATE_SUCCESS); }
@Override public void applyCharge(Integer accountId, Short feeId, Double chargeAmount) { MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = toUserContext(user); try { AccountBO account = new AccountBusinessService().getAccount(accountId); if (account instanceof LoanBO) { List<LoanBO> individualLoans = this.loanDao.findIndividualLoans(account.getAccountId()); if (individualLoans != null && individualLoans.size() > 0) { for (LoanBO individual : individualLoans) { individual.updateDetails(userContext); FeeBO fee = this.feeDao.findById(feeId); if (fee instanceof RateFeeBO) { individual.applyCharge(feeId, chargeAmount); } else { Double radio = individual.getLoanAmount().getAmount().doubleValue() / ((LoanBO) account).getLoanAmount().getAmount().doubleValue(); individual.applyCharge(feeId, chargeAmount * radio); } } } } account.updateDetails(userContext); CustomerLevel customerLevel = null; if (account.isCustomerAccount()) { customerLevel = account.getCustomer().getLevel(); } if (account.getPersonnel() != null) { checkPermissionForApplyCharges( account.getType(), customerLevel, userContext, account.getOffice().getOfficeId(), account.getPersonnel().getPersonnelId()); } else { checkPermissionForApplyCharges( account.getType(), customerLevel, userContext, account.getOffice().getOfficeId(), userContext.getId()); } this.transactionHelper.startTransaction(); account.applyCharge(feeId, chargeAmount); this.transactionHelper.commitTransaction(); } catch (ServiceException e) { this.transactionHelper.rollbackTransaction(); throw new MifosRuntimeException(e); } catch (ApplicationException e) { this.transactionHelper.rollbackTransaction(); throw new BusinessRuleException(e.getKey(), e); } }