use of org.mifos.accounts.business.AccountFeesEntity in project head by mifos.
the class ImportClientsServiceFacadeWebTier method save.
@Override
public ParsedClientsDto save(ParsedClientsDto parsedClientsDto) {
MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserContext userContext = toUserContext(user);
OfficeBO userOffice = this.officeDao.findOfficeById(userContext.getBranchId());
userContext.setBranchGlobalNum(userOffice.getGlobalOfficeNum());
DateTimeService dateTimeService = new DateTimeService();
/* Construct ClientBO objects */
List<NewClientDto> newClients = new ArrayList<NewClientDto>();
for (ImportedClientDetail importedClient : parsedClientsDto.getSuccessfullyParsedRows()) {
String secondMiddleName = null;
ClientCreationDetail clientCreationDetail = importedClient.getClientCreationDetail();
PersonnelBO formedBy = null;
/* Client name details */
ClientNameDetailDto clientNameDetails = clientCreationDetail.getClientNameDetailDto();
ClientNameDetailEntity clientNameDetailEntity = new ClientNameDetailEntity(null, secondMiddleName, clientNameDetails);
ClientDetailEntity clientDetailEntity = new ClientDetailEntity();
clientDetailEntity.updateClientDetails(clientCreationDetail.getClientPersonalDetailDto());
String clientFirstName = clientNameDetails.getFirstName();
String clientLastName = clientNameDetails.getLastName();
String secondLastName = clientNameDetails.getSecondLastName();
/* Spouse/father name details */
ClientNameDetailEntity spouseFatherNameDetailEntity = null;
if (clientCreationDetail.getSpouseFatherName() != null) {
spouseFatherNameDetailEntity = new ClientNameDetailEntity(null, secondMiddleName, clientCreationDetail.getSpouseFatherName());
}
/* Data conversion */
DateTime dateOfBirth = new DateTime(clientCreationDetail.getDateOfBirth());
DateTime mfiJoiningDate = new DateTime(clientCreationDetail.getMfiJoiningDate());
DateTime trainedDateTime = null;
if (clientCreationDetail.getTrainedDate() != null) {
trainedDateTime = new DateTime(clientCreationDetail.getTrainedDate());
}
/* Status */
CustomerStatus clientStatus = CustomerStatus.fromInt(clientCreationDetail.getClientStatus());
CustomerStatus finalStatus = clientStatus;
if (clientStatus == CustomerStatus.CLIENT_ACTIVE && clientCreationDetail.getActivationDate() == null) {
clientStatus = CustomerStatus.CLIENT_PENDING;
}
/* Address */
Address address = null;
if (clientCreationDetail.getAddress() != null) {
AddressDto dto = clientCreationDetail.getAddress();
address = new Address(dto.getLine1(), dto.getLine2(), dto.getLine3(), dto.getCity(), dto.getState(), dto.getCountry(), dto.getZip(), dto.getPhoneNumber());
}
// empty list
List<ClientInitialSavingsOfferingEntity> associatedOfferings = new ArrayList<ClientInitialSavingsOfferingEntity>();
// client object
ClientBO client;
if (clientCreationDetail.getGroupFlag() == 1) {
CustomerBO group = customerDao.findCustomerBySystemId(clientCreationDetail.getParentGroupId());
if (clientCreationDetail.getFormedBy() != null) {
formedBy = this.personnelDao.findPersonnelById(clientCreationDetail.getFormedBy());
} else {
formedBy = group.getPersonnel();
}
client = ClientBO.createNewInGroupHierarchy(userContext, clientCreationDetail.getClientName(), clientStatus, mfiJoiningDate, group, formedBy, clientNameDetailEntity, dateOfBirth, clientCreationDetail.getGovernmentId(), clientCreationDetail.isTrained(), trainedDateTime, clientCreationDetail.getGroupFlag(), clientFirstName, clientLastName, secondLastName, spouseFatherNameDetailEntity, clientDetailEntity, associatedOfferings, clientCreationDetail.getExternalId(), address, clientCreationDetail.getActivationDate());
} else {
Short officeId = clientCreationDetail.getOfficeId();
Short officerId = clientCreationDetail.getLoanOfficerId();
PersonnelBO loanOfficer = personnelDao.findPersonnelById(officerId);
OfficeBO office = this.officeDao.findOfficeById(officeId);
if (clientCreationDetail.getFormedBy() != null) {
formedBy = this.personnelDao.findPersonnelById(clientCreationDetail.getFormedBy());
} else {
formedBy = loanOfficer;
}
int lastSearchIdCustomerValue = customerDao.retrieveLastSearchIdValueForNonParentCustomersInOffice(officeId);
/* meeting */
final MeetingDto meetingDto = importedClient.getMeeting();
MeetingBO clientMeeting = null;
if (meetingDto != null) {
clientMeeting = new MeetingFactory().create(meetingDto);
clientMeeting.setUserContext(userContext);
}
client = ClientBO.createNewOutOfGroupHierarchy(userContext, clientCreationDetail.getClientName(), clientStatus, mfiJoiningDate, office, loanOfficer, clientMeeting, formedBy, clientNameDetailEntity, dateOfBirth, clientCreationDetail.getGovernmentId(), clientCreationDetail.isTrained(), trainedDateTime, clientCreationDetail.getGroupFlag(), clientFirstName, clientLastName, secondLastName, spouseFatherNameDetailEntity, clientDetailEntity, associatedOfferings, clientCreationDetail.getExternalId(), address, lastSearchIdCustomerValue);
if (clientCreationDetail.getActivationDate() != null) {
client.setCustomerActivationDate(clientCreationDetail.getActivationDate().toDateMidnight().toDate());
}
}
// global id
if (importedClient.getClientGlobalNum() != null) {
client.setGlobalCustNum(importedClient.getClientGlobalNum());
}
NewClientDto newClient = new NewClientDto(client, finalStatus);
newClients.add(newClient);
}
/* Validate client data */
for (NewClientDto newClient : newClients) {
ClientBO client = newClient.getClientBO();
try {
client.validate();
customerDao.validateClientForDuplicateNameOrGovtId(client.getDisplayName(), client.getDateOfBirth(), client.getGovernmentId());
} catch (CustomerException ex) {
throw new MifosRuntimeException(ex);
}
}
/* Save clients */
// empty list
List<AccountFeesEntity> accountFees = new ArrayList<AccountFeesEntity>();
try {
hibernateTransactionHelper.startTransaction();
for (NewClientDto newClient : newClients) {
ClientBO client = newClient.getClientBO();
CustomerStatus finalStatus = newClient.getCustomerStatus();
// status to pending approval if active
MeetingBO meeting = client.getCustomerMeetingValue();
customerDao.save(client);
hibernateTransactionHelper.flushSession();
CalendarEvent applicableCalendarEvents = holidayDao.findCalendarEventsForThisYearAndNext(client.getOfficeId());
CustomerAccountBO customerAccount = customerAccountFactory.create(client, accountFees, meeting, applicableCalendarEvents);
client.addAccount(customerAccount);
customerDao.save(client);
hibernateTransactionHelper.flushSession();
if (client.getParentCustomer() != null) {
customerDao.save(client.getParentCustomer());
}
if (client.getGlobalCustNum() == null) {
client.generateGlobalCustomerNumber();
}
client.generateSearchId();
customerDao.save(client);
hibernateTransactionHelper.flushSession();
if (client.getParentCustomer() != null) {
customerDao.save(client.getParentCustomer());
}
/* activate client */
if (finalStatus == CustomerStatus.CLIENT_ACTIVE) {
hibernateTransactionHelper.flushSession();
hibernateTransactionHelper.beginAuditLoggingFor(client);
client.clearCustomerFlagsIfApplicable(client.getStatus(), finalStatus);
client.updateCustomerStatus(finalStatus);
// changeStatus(client, oldStatus, newStatus);
if (client.getParentCustomer() != null) {
CustomerHierarchyEntity hierarchy = new CustomerHierarchyEntity(client, client.getParentCustomer());
client.addCustomerHierarchy(hierarchy);
}
if (client.getCustomerActivationDate() != null) {
client.setCustomerActivationDate(client.getCustomerActivationDate());
} else {
client.setCustomerActivationDate(dateTimeService.getCurrentJavaDateTime());
}
customerAccount.createSchedulesAndFeeSchedulesForFirstTimeActiveCustomer(client, accountFees, meeting, applicableCalendarEvents, new DateTime(client.getCustomerActivationDate()));
customerDao.save(client);
}
}
hibernateTransactionHelper.commitTransaction();
} catch (Exception ex) {
hibernateTransactionHelper.rollbackTransaction();
throw new MifosRuntimeException(ex);
}
return parsedClientsDto;
}
use of org.mifos.accounts.business.AccountFeesEntity in project head by mifos.
the class IndividualLoanScheduleFactory method calculateTotalFeesAndInterestForLoanSchedules.
private Money calculateTotalFeesAndInterestForLoanSchedules(List<LoanScheduleEntity> unroundedLoanSchedules, MifosCurrency currencyInUse, List<AccountFeesEntity> accountFees) {
Money zero = new Money(currencyInUse);
Money interest = zero;
Money fees = zero;
for (LoanScheduleEntity unroundedLoanSchedule : unroundedLoanSchedules) {
interest = interest.add(unroundedLoanSchedule.getInterest());
fees = fees.add(unroundedLoanSchedule.getTotalFeesDueWithMiscFee());
}
Money feeDisbursementAmount = zero;
for (AccountFeesEntity accountFeesEntity : accountFees) {
if (accountFeesEntity.getFees().isTimeOfDisbursement()) {
feeDisbursementAmount = fees.add(accountFeesEntity.getAccountFeeAmount());
}
}
fees = fees.add(feeDisbursementAmount);
fees = MoneyUtils.currencyRound(fees);
interest = MoneyUtils.currencyRound(interest);
Money rawAmount = interest.add(fees);
return rawAmount;
}
use of org.mifos.accounts.business.AccountFeesEntity in project head by mifos.
the class LoanBOTestUtils method createLoanAccountWithDisbursement.
/**
* Like
* {@link #createLoanAccount(String, CustomerBO, AccountState, Date, LoanOfferingBO)}
* but differs in various ways.
*
* Note: the manipulation done in this method looks very suspicious and
* possibly wrong. Tests that use this method should be considered as
* suspect.
*/
public static LoanBO createLoanAccountWithDisbursement(final CustomerBO customer, final AccountState state, final Date startDate, final LoanOfferingBO loanOffering, final int disbursalType, final Short noOfInstallments) {
Calendar calendar = new GregorianCalendar();
calendar.setTime(startDate);
MeetingBO meeting = TestObjectFactory.createLoanMeeting(customer.getCustomerMeeting().getMeeting());
List<Date> meetingDates = TestObjectFactory.getMeetingDates(customer.getOfficeId(), meeting, 6);
MifosCurrency currency = TestUtils.RUPEE;
List<CreateAccountFeeDto> accountFees = new ArrayList<CreateAccountFeeDto>();
AmountFeeBO maintanenceFee = (AmountFeeBO) TestObjectFactory.createPeriodicAmountFee("Mainatnence Fee", FeeCategory.LOAN, "100", RecurrenceType.WEEKLY, Short.valueOf("1"));
IntegrationTestObjectMother.saveFee(maintanenceFee);
accountFees.add(new CreateAccountFeeDto(maintanenceFee.getFeeId().intValue(), maintanenceFee.getFeeAmount().toString()));
AccountFeesEntity accountDisbursementFee = null;
AmountFeeBO disbursementFee = null;
AccountFeesEntity accountDisbursementFee2 = null;
AmountFeeBO disbursementFee2 = null;
if (disbursalType == 1 || disbursalType == 2) {
disbursementFee = (AmountFeeBO) TestObjectFactory.createOneTimeAmountFee("Disbursement Fee 1", FeeCategory.LOAN, "10", FeePayment.TIME_OF_DISBURSEMENT);
IntegrationTestObjectMother.saveFee(disbursementFee);
accountFees.add(new CreateAccountFeeDto(disbursementFee.getFeeId().intValue(), disbursementFee.getFeeAmount().toString()));
disbursementFee2 = (AmountFeeBO) TestObjectFactory.createOneTimeAmountFee("Disbursement Fee 2", FeeCategory.LOAN, "20", FeePayment.TIME_OF_DISBURSEMENT);
IntegrationTestObjectMother.saveFee(disbursementFee2);
accountFees.add(new CreateAccountFeeDto(disbursementFee2.getFeeId().intValue(), disbursementFee2.getFeeAmount().toString()));
}
BigDecimal loanAmount = BigDecimal.valueOf(DEFAULT_LOAN_AMOUNT);
BigDecimal minAllowedLoanAmount = loanAmount;
BigDecimal maxAllowedLoanAmount = loanAmount;
Double interestRate = Double.valueOf("10.0");
LocalDate disbursementDate = new LocalDate(meetingDates.get(0));
int numberOfInstallments = noOfInstallments;
int minAllowedNumberOfInstallments = loanOffering.getEligibleInstallmentSameForAllLoan().getMaxNoOfInstall();
int maxAllowedNumberOfInstallments = loanOffering.getEligibleInstallmentSameForAllLoan().getMaxNoOfInstall();
int graceDuration = 0;
Integer sourceOfFundId = null;
Integer loanPurposeId = null;
Integer collateralTypeId = null;
String collateralNotes = null;
String externalId = null;
boolean repaymentScheduleIndependentOfCustomerMeeting = false;
RecurringSchedule recurringSchedule = null;
CreateLoanAccount createLoanAccount = new CreateLoanAccount(customer.getCustomerId(), loanOffering.getPrdOfferingId().intValue(), state.getValue().intValue(), loanAmount, minAllowedLoanAmount, maxAllowedLoanAmount, interestRate, disbursementDate, null, numberOfInstallments, minAllowedNumberOfInstallments, maxAllowedNumberOfInstallments, graceDuration, sourceOfFundId, loanPurposeId, collateralTypeId, collateralNotes, externalId, repaymentScheduleIndependentOfCustomerMeeting, recurringSchedule, accountFees, new ArrayList<CreateAccountPenaltyDto>());
SecurityContext securityContext = new SecurityContextImpl();
MifosUser principal = new MifosUserBuilder().nonLoanOfficer().withAdminRole().build();
Authentication authentication = new TestingAuthenticationToken(principal, principal);
securityContext.setAuthentication(authentication);
SecurityContextHolder.setContext(securityContext);
LoanBO loan = IntegrationTestObjectMother.createClientLoan(createLoanAccount);
loan.updateDetails(TestUtils.makeUser());
AccountFeesEntity accountPeriodicFee = new AccountFeesEntity(loan, maintanenceFee, new Double("10.0"));
AccountTestUtils.addAccountFees(accountPeriodicFee, loan);
if (disbursalType == 1 || disbursalType == 2) {
accountDisbursementFee = new AccountFeesEntity(loan, disbursementFee, new Double("10.0"));
AccountTestUtils.addAccountFees(accountDisbursementFee, loan);
accountDisbursementFee2 = new AccountFeesEntity(loan, disbursementFee2, new Double("20.0"));
AccountTestUtils.addAccountFees(accountDisbursementFee2, loan);
}
loan.setLoanMeeting(meeting);
if (// 2-Interest At Disbursement
disbursalType == 2) {
loan.setInterestDeductedAtDisbursement(true);
meetingDates = TestObjectFactory.getMeetingDates(customer.getOfficeId(), loan.getLoanMeeting(), 6);
short i = 0;
for (Date date : meetingDates) {
if (i == 0) {
i++;
loan.setDisbursementDate(date);
LoanScheduleEntity actionDate = (LoanScheduleEntity) loan.getAccountActionDate(i);
actionDate.setActionDate(new java.sql.Date(date.getTime()));
actionDate.setInterest(new Money(currency, "12.0"));
actionDate.setPaymentStatus(PaymentStatus.UNPAID);
AccountTestUtils.addAccountActionDate(actionDate, loan);
// periodic fee
AccountFeesActionDetailEntity accountFeesaction = new LoanFeeScheduleEntity(actionDate, maintanenceFee, accountPeriodicFee, new Money(currency, "10.0"));
setFeeAmountPaid(accountFeesaction, new Money(currency, "0.0"));
actionDate.addAccountFeesAction(accountFeesaction);
// dibursement fee one
AccountFeesActionDetailEntity accountFeesaction1 = new LoanFeeScheduleEntity(actionDate, disbursementFee, accountDisbursementFee, new Money(currency, "10.0"));
setFeeAmountPaid(accountFeesaction1, new Money(currency, "0.0"));
actionDate.addAccountFeesAction(accountFeesaction1);
// disbursementfee2
AccountFeesActionDetailEntity accountFeesaction2 = new LoanFeeScheduleEntity(actionDate, disbursementFee2, accountDisbursementFee2, new Money(currency, "20.0"));
setFeeAmountPaid(accountFeesaction2, new Money(currency, "0.0"));
actionDate.addAccountFeesAction(accountFeesaction2);
continue;
}
i++;
LoanScheduleEntity actionDate = (LoanScheduleEntity) loan.getAccountActionDate(i);
actionDate.setActionDate(new java.sql.Date(date.getTime()));
actionDate.setPrincipal(new Money(currency, "100.0"));
actionDate.setInterest(new Money(currency, "12.0"));
actionDate.setPaymentStatus(PaymentStatus.UNPAID);
AccountTestUtils.addAccountActionDate(actionDate, loan);
AccountFeesActionDetailEntity accountFeesaction = new LoanFeeScheduleEntity(actionDate, maintanenceFee, accountPeriodicFee, new Money(currency, "100.0"));
setFeeAmountPaid(accountFeesaction, new Money(currency, "0.0"));
actionDate.addAccountFeesAction(accountFeesaction);
}
} else if (disbursalType == 1 || disbursalType == 3) {
loan.setInterestDeductedAtDisbursement(false);
meetingDates = TestObjectFactory.getMeetingDates(customer.getOfficeId(), loan.getLoanMeeting(), 6);
short i = 0;
for (Date date : meetingDates) {
if (i == 0) {
i++;
loan.setDisbursementDate(date);
continue;
}
LoanScheduleEntity actionDate = (LoanScheduleEntity) loan.getAccountActionDate(i++);
actionDate.setActionDate(new java.sql.Date(date.getTime()));
actionDate.setPrincipal(new Money(currency, "100.0"));
actionDate.setInterest(new Money(currency, "12.0"));
actionDate.setPaymentStatus(PaymentStatus.UNPAID);
AccountTestUtils.addAccountActionDate(actionDate, loan);
AccountFeesActionDetailEntity accountFeesaction = new LoanFeeScheduleEntity(actionDate, maintanenceFee, accountPeriodicFee, new Money(currency, "100.0"));
setFeeAmountPaid(accountFeesaction, new Money(currency, "0.0"));
actionDate.addAccountFeesAction(accountFeesaction);
}
}
GracePeriodTypeEntity gracePeriodType = new GracePeriodTypeEntity(GraceType.NONE);
loan.setGracePeriodType(gracePeriodType);
loan.setCreatedBy(Short.valueOf("1"));
// Set collateral type to lookup id 109, which references the lookup
// value 'Type 1'
loan.setCollateralTypeId(Integer.valueOf("109"));
InterestTypesEntity interestTypes = new InterestTypesEntity(InterestType.FLAT);
loan.setInterestType(interestTypes);
loan.setInterestRate(10.0);
loan.setCreatedDate(new Date(System.currentTimeMillis()));
setLoanSummary(loan, currency);
return loan;
}
use of org.mifos.accounts.business.AccountFeesEntity in project head by mifos.
the class LoanAccountServiceFacadeWebTier method createLoanAccount.
private LoanCreationResultDto createLoanAccount(CreateLoanAccount loanAccountInfo, List<LoanPaymentDto> backdatedLoanPayments, List<QuestionGroupDetail> questionGroups, LoanAccountCashFlow loanAccountCashFlow, List<DateTime> loanScheduleInstallmentDates, List<Number> totalInstallmentAmounts, List<GroupMemberAccountDto> memberDetails, boolean isBackdatedLoan) {
DateTime creationDate = new DateTime();
// 0. verify member details for GLIM group accounts
for (GroupMemberAccountDto groupMemberAccount : memberDetails) {
ClientBO member = this.customerDao.findClientBySystemId(groupMemberAccount.getGlobalId());
if (creationDate.isBefore(new DateTime(member.getCreatedDate()))) {
throw new BusinessRuleException("errors.cannotCreateLoan.because.clientsAreCreatedInFuture");
}
}
// 1. assemble loan details
MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserContext userContext = toUserContext(user);
OfficeBO userOffice = this.officeDao.findOfficeById(user.getBranchId());
PersonnelBO createdBy = this.personnelDao.findPersonnelById(userContext.getId());
CustomerBO customer = this.customerDao.findCustomerById(loanAccountInfo.getCustomerId());
if (customer.isGroup()) {
customer = this.customerDao.findGroupBySystemId(customer.getGlobalCustNum());
}
// assemble
LoanAccountDetail loanAccountDetail = assembleLoanAccountDetail(loanAccountInfo);
List<AccountFeesEntity> accountFeeEntities = assembleAccountFees(loanAccountInfo.getAccountFees());
List<AccountPenaltiesEntity> accountPenaltyEntities = assembleAccountPenalties(loanAccountInfo.getAccountPenalties());
LoanProductOverridenDetail overridenDetail = new LoanProductOverridenDetail(loanAccountDetail.getLoanAmount(), loanAccountInfo.getDisbursementDate(), loanAccountInfo.getInterestRate(), loanAccountInfo.getNumberOfInstallments(), loanAccountInfo.getGraceDuration(), accountFeeEntities, accountPenaltyEntities);
Integer interestDays = Integer.valueOf(AccountingRules.getNumberOfInterestDays().intValue());
boolean loanScheduleIndependentOfCustomerMeetingEnabled = loanAccountInfo.isRepaymentScheduleIndependentOfCustomerMeeting();
LoanScheduleConfiguration configuration = new LoanScheduleConfiguration(loanScheduleIndependentOfCustomerMeetingEnabled, interestDays);
MeetingBO repaymentDayMeeting = null;
if (loanScheduleIndependentOfCustomerMeetingEnabled) {
repaymentDayMeeting = this.createNewMeetingForRepaymentDay(loanAccountInfo.getDisbursementDate(), loanAccountInfo, loanAccountDetail.getCustomer());
} else {
MeetingDto customerMeetingDto = customer.getCustomerMeetingValue().toDto();
repaymentDayMeeting = new MeetingFactory().create(customerMeetingDto);
Short recurAfter = loanAccountDetail.getLoanProduct().getLoanOfferingMeeting().getMeeting().getRecurAfter();
repaymentDayMeeting.getMeetingDetails().setRecurAfter(recurAfter);
}
List<DateTime> loanScheduleDates = new ArrayList<DateTime>(loanScheduleInstallmentDates);
LoanSchedule loanSchedule = assembleLoanSchedule(loanAccountDetail.getCustomer(), loanAccountDetail.getLoanProduct(), overridenDetail, configuration, repaymentDayMeeting, userOffice, loanScheduleDates, loanAccountInfo.getDisbursementDate(), totalInstallmentAmounts);
// 2. create loan
InstallmentRange installmentRange = new MaxMinNoOfInstall(loanAccountInfo.getMinAllowedNumberOfInstallments().shortValue(), loanAccountInfo.getMaxAllowedNumberOfInstallments().shortValue(), null);
AmountRange amountRange = new MaxMinLoanAmount(loanAccountInfo.getMaxAllowedLoanAmount().doubleValue(), loanAccountInfo.getMinAllowedLoanAmount().doubleValue(), null);
if (isBackdatedLoan) {
creationDate = loanAccountInfo.getDisbursementDate().toDateMidnight().toDateTime();
}
CreationDetail creationDetail = new CreationDetail(creationDate, Integer.valueOf(user.getUserId()));
LoanBO loan = LoanBO.openStandardLoanAccount(loanAccountDetail.getLoanProduct(), loanAccountDetail.getCustomer(), repaymentDayMeeting, loanSchedule, loanAccountDetail.getAccountState(), loanAccountDetail.getFund(), overridenDetail, configuration, installmentRange, amountRange, creationDetail, createdBy);
loan.setBusinessActivityId(loanAccountInfo.getLoanPurposeId());
loan.setExternalId(loanAccountInfo.getExternalId());
loan.setCollateralNote(loanAccountInfo.getCollateralNotes());
loan.setCollateralTypeId(loanAccountInfo.getCollateralTypeId());
if (isBackdatedLoan) {
loan.markAsCreatedWithBackdatedPayments();
}
//set up predefined loan account for importing loans
if (loanAccountInfo.getPredefinedAccountNumber() != null) {
loan.setGlobalAccountNum(loanAccountInfo.getPredefinedAccountNumber());
}
try {
personnelDao.checkAccessPermission(userContext, loan.getOfficeId(), loan.getCustomer().getLoanOfficerId());
} catch (AccountException e) {
throw new MifosRuntimeException("Access denied!", e);
}
try {
transactionHelper.startTransaction();
this.loanDao.save(loan);
transactionHelper.flushSession();
//no predefined account number, generate one instead
if (loanAccountInfo.getPredefinedAccountNumber() == null) {
try {
loan.setGlobalAccountNum(loan.generateId(userOffice.getGlobalOfficeNum()));
} catch (AccountException e) {
throw new BusinessRuleException(e.getMessage());
}
this.loanDao.save(loan);
transactionHelper.flushSession();
}
//set up status flag
AccountStateFlagEntity flagEntity = null;
if (loanAccountInfo.getFlagId() != null) {
try {
flagEntity = legacyMasterDao.getPersistentObject(AccountStateFlagEntity.class, loanAccountInfo.getFlagId());
loan.setUserContext(userContext);
loan.setFlag(flagEntity);
loan.setClosedDate(new DateTimeService().getCurrentJavaDateTime());
loan.setUserContext(userContext);
} catch (PersistenceException e) {
throw new BusinessRuleException(e.getMessage());
}
this.loanDao.save(loan);
transactionHelper.flushSession();
}
// for GLIM loans only
List<GroupMemberLoanDetail> individualMembersOfGroupLoan = new ArrayList<GroupMemberLoanDetail>();
List<BigDecimal> radio = new ArrayList<BigDecimal>(loan.getNoOfInstallments());
for (GroupMemberAccountDto groupMemberAccount : memberDetails) {
ClientBO member = this.customerDao.findClientBySystemId(groupMemberAccount.getGlobalId());
Money loanAmount = new Money(loanAccountDetail.getLoanProduct().getCurrency(), groupMemberAccount.getLoanAmount());
List<CreateAccountFeeDto> defaultAccountFees = new ArrayList<CreateAccountFeeDto>();
List<CreateAccountPenaltyDto> defaultAccountPenalties = new ArrayList<CreateAccountPenaltyDto>();
radio.add(loanAmount.divide(loan.getLoanAmount()));
for (CreateAccountFeeDto createAccountFeeDto : loanAccountInfo.getAccountFees()) {
Integer feeId = createAccountFeeDto.getFeeId();
String amount = createAccountFeeDto.getAmount();
FeeBO feeBO = this.feeDao.findById(feeId.shortValue());
if (feeBO instanceof AmountFeeBO) {
amount = String.valueOf(Double.valueOf(createAccountFeeDto.getAmount()) * (loanAmount.divide(loanAccountInfo.getLoanAmount()).getAmount().doubleValue()));
}
defaultAccountFees.add(new CreateAccountFeeDto(feeId, amount));
}
int memberCount = memberDetails.size();
for (CreateAccountPenaltyDto createAccountPenaltyDto : loanAccountInfo.getAccountPenalties()) {
Integer penaltyId = createAccountPenaltyDto.getPenaltyId();
String amount = createAccountPenaltyDto.getAmount();
PenaltyBO penaltyBO = this.penaltyDao.findPenaltyById(penaltyId.shortValue());
if (penaltyBO instanceof AmountPenaltyBO) {
amount = String.valueOf(Double.valueOf(createAccountPenaltyDto.getAmount()) / memberCount);
}
defaultAccountPenalties.add(new CreateAccountPenaltyDto(penaltyId, amount));
}
List<AccountFeesEntity> feeEntities = assembleAccountFees(defaultAccountFees);
List<AccountPenaltiesEntity> penaltyEntities = assembleAccountPenalties(defaultAccountPenalties);
LoanProductOverridenDetail memberOverridenDetail = new LoanProductOverridenDetail(loanAmount, feeEntities, overridenDetail, penaltyEntities);
LoanSchedule memberSchedule = assembleLoanSchedule(member, loanAccountDetail.getLoanProduct(), memberOverridenDetail, configuration, repaymentDayMeeting, userOffice, new ArrayList<DateTime>(), loanAccountInfo.getDisbursementDate(), new ArrayList<Number>());
GroupMemberLoanDetail groupMemberLoanDetail = new GroupMemberLoanDetail(member, memberOverridenDetail, memberSchedule, groupMemberAccount.getLoanPurposeId());
individualMembersOfGroupLoan.add(groupMemberLoanDetail);
}
checkScheduleForMembers(loanSchedule, loan, individualMembersOfGroupLoan, radio);
//for original schedule persisting
List<LoanBO> memberLoans = new ArrayList<LoanBO>();
for (GroupMemberLoanDetail groupMemberAccount : individualMembersOfGroupLoan) {
LoanBO memberLoan = LoanBO.openGroupMemberLoanAccount(loan, loanAccountDetail.getLoanProduct(), groupMemberAccount.getMember(), repaymentDayMeeting, groupMemberAccount.getMemberSchedule(), groupMemberAccount.getMemberOverridenDetail(), configuration, installmentRange, amountRange, creationDetail, createdBy);
if (groupMemberAccount.getLoanPurposeId() > 0) {
memberLoan.setBusinessActivityId(groupMemberAccount.getLoanPurposeId());
}
if (!backdatedLoanPayments.isEmpty()) {
memberLoan.markAsCreatedWithBackdatedPayments();
}
this.loanDao.save(memberLoan);
transactionHelper.flushSession();
try {
memberLoan.setGlobalAccountNum(memberLoan.generateId(userOffice.getGlobalOfficeNum()));
} catch (AccountException e) {
throw new BusinessRuleException(e.getMessage());
}
this.loanDao.save(memberLoan);
transactionHelper.flushSession();
memberLoans.add(memberLoan);
}
// save question groups
if (!questionGroups.isEmpty()) {
Integer eventSourceId = questionnaireServiceFacade.getEventSourceId("Create", "Loan");
QuestionGroupDetails questionGroupDetails = new QuestionGroupDetails(Integer.valueOf(user.getUserId()).shortValue(), loan.getAccountId(), eventSourceId, questionGroups);
questionnaireServiceFacade.saveResponses(questionGroupDetails);
transactionHelper.flushSession();
}
if (loanAccountCashFlow != null && !loanAccountCashFlow.getMonthlyCashFlow().isEmpty()) {
List<MonthlyCashFlowDetail> monthlyCashFlowDetails = new ArrayList<MonthlyCashFlowDetail>();
for (MonthlyCashFlowDto monthlyCashFlow : loanAccountCashFlow.getMonthlyCashFlow()) {
MonthlyCashFlowDetail monthlyCashFlowDetail = new MonthlyCashFlowDetail(monthlyCashFlow.getMonthDate(), monthlyCashFlow.getRevenue(), monthlyCashFlow.getExpenses(), monthlyCashFlow.getNotes());
monthlyCashFlowDetails.add(monthlyCashFlowDetail);
}
org.mifos.platform.cashflow.service.CashFlowDetail cashFlowDetail = new org.mifos.platform.cashflow.service.CashFlowDetail(monthlyCashFlowDetails);
cashFlowDetail.setTotalCapital(loanAccountCashFlow.getTotalCapital());
cashFlowDetail.setTotalLiability(loanAccountCashFlow.getTotalLiability());
cashFlowService.save(cashFlowDetail);
transactionHelper.flushSession();
}
if (isBackdatedLoan) {
// 3. auto approve loan
String comment = "Automatic Status Update (Redo Loan)";
LocalDate approvalDate = loanAccountInfo.getDisbursementDate();
loan.approve(createdBy, comment, approvalDate);
// 4. disburse loan
String receiptNumber = null;
Date receiptDate = null;
PaymentTypeEntity paymentType = new PaymentTypeEntity(PaymentTypes.CASH.getValue());
if (loanAccountInfo.getDisbursalPaymentTypeId() != null) {
paymentType = new PaymentTypeEntity(loanAccountInfo.getDisbursalPaymentTypeId());
}
Date paymentDate = loanAccountInfo.getDisbursementDate().toDateMidnight().toDate();
AccountPaymentEntity disbursalPayment = new AccountPaymentEntity(loan, loan.getLoanAmount(), receiptNumber, receiptDate, paymentType, paymentDate);
disbursalPayment.setCreatedByUser(createdBy);
this.loanBusinessService.persistOriginalSchedule(loan);
for (LoanBO memberLoan : memberLoans) {
this.loanBusinessService.persistOriginalSchedule(memberLoan);
}
// refactoring of loan disbursal
if (customer.isDisbursalPreventedDueToAnyExistingActiveLoansForTheSameProduct(loan.getLoanOffering())) {
throw new BusinessRuleException("errors.cannotDisburseLoan.because.otherLoansAreActive");
}
try {
loan.updateCustomer(customer);
new ProductMixValidator().checkIfProductsOfferingCanCoexist(loan);
} catch (ServiceException e1) {
throw new AccountException(e1.getMessage());
}
loan.disburse(createdBy, disbursalPayment);
customer.updatePerformanceHistoryOnDisbursement(loan, loan.getLoanAmount());
// end of refactoring of loan disbural
this.loanDao.save(loan);
transactionHelper.flushSession();
// 5. apply each payment
for (LoanPaymentDto loanPayment : backdatedLoanPayments) {
Money amountPaidToDate = new Money(loan.getCurrency(), loanPayment.getAmount());
PaymentData paymentData = new PaymentData(amountPaidToDate, createdBy, loanPayment.getPaymentTypeId(), loanPayment.getPaymentDate().toDateMidnight().toDate());
loan.applyPayment(paymentData);
this.loanDao.save(loan);
}
}
transactionHelper.commitTransaction();
return new LoanCreationResultDto(false, loan.getAccountId(), loan.getGlobalAccountNum());
} catch (BusinessRuleException e) {
this.transactionHelper.rollbackTransaction();
throw new BusinessRuleException(e.getMessageKey(), e);
} catch (Exception e) {
this.transactionHelper.rollbackTransaction();
throw new MifosRuntimeException(e);
} finally {
this.transactionHelper.closeSession();
}
}
use of org.mifos.accounts.business.AccountFeesEntity in project head by mifos.
the class LoanAccountServiceFacadeWebTier method applyLoanRepayment.
@Override
public void applyLoanRepayment(String globalAccountNumber, LocalDate paymentDate, BigDecimal repaymentAmount, String receiptId, LocalDate receiptDate, Short modeOfPayment) {
MifosUser user = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserContext userContext = toUserContext(user);
try {
this.transactionHelper.startTransaction();
LoanBO loan = loanDao.findByGlobalAccountNum(globalAccountNumber);
PersonnelBO personnel = personnelDao.findPersonnelById((short) user.getUserId());
Money outstandingOverpayment = loan.applyNewPaymentMechanism(paymentDate, repaymentAmount, personnel, receiptId, receiptDate, modeOfPayment);
// 3. pay off principal of next installment and recalculate interest if 'over paid'
if (outstandingOverpayment.isGreaterThanZero()) {
Money totalPrincipalDueNow = loan.getTotalPrincipalDue().subtract(outstandingOverpayment);
// assemble into domain entities
LoanOfferingBO loanProduct = this.loanProductDao.findById(loan.getLoanOffering().getPrdOfferingId().intValue());
CustomerBO customer = this.customerDao.findCustomerById(loan.getCustomer().getCustomerId());
List<AccountFeesEntity> accountFeeEntities = new ArrayList<AccountFeesEntity>();
Integer unpaidInstallments = loan.getDetailsOfUnpaidInstallmentsOn(paymentDate).size();
Integer gracePeriodDiff = loan.getNoOfInstallments().intValue() - loan.getGracePeriodDuration().intValue();
Integer gracePeriodsRemaining = Math.max(0, unpaidInstallments - gracePeriodDiff);
LocalDate disbursementDate = new LocalDate(loan.getDetailsOfUpcomigInstallment().getActionDate());
LoanProductOverridenDetail overridenDetail = new LoanProductOverridenDetail(totalPrincipalDueNow, disbursementDate, loan.getInterestRate(), unpaidInstallments, gracePeriodsRemaining, accountFeeEntities, new ArrayList<AccountPenaltiesEntity>());
Integer interestDays = Integer.valueOf(AccountingRules.getNumberOfInterestDays().intValue());
boolean loanScheduleIndependentOfCustomerMeetingEnabled = false;
MeetingBO loanMeeting = customer.getCustomerMeetingValue();
if (loanScheduleIndependentOfCustomerMeetingEnabled) {
RecurringSchedule createLoanSchedule = new MonthlyOnDayOfMonthSchedule(Integer.valueOf(1), Integer.valueOf(5));
loanMeeting = this.createNewMeetingForRepaymentDay(disbursementDate, createLoanSchedule, customer);
if (loanProduct.isVariableInstallmentsAllowed()) {
loanMeeting.setMeetingStartDate(disbursementDate.toDateMidnight().toDate());
}
}
LoanScheduleConfiguration configuration = new LoanScheduleConfiguration(loanScheduleIndependentOfCustomerMeetingEnabled, interestDays);
Short userBranchOfficeId = userContext.getBranchId();
LoanSchedule loanSchedule = this.loanScheduleService.generate(loanProduct, customer, loanMeeting, overridenDetail, configuration, userBranchOfficeId, accountFeeEntities, disbursementDate);
loan.rescheduleRemainingUnpaidInstallments(loanSchedule, paymentDate);
loan.recordOverpayment(outstandingOverpayment, paymentDate, personnel, receiptId, receiptDate, modeOfPayment);
}
this.loanDao.save(loan);
this.transactionHelper.commitTransaction();
} catch (BusinessRuleException e) {
this.transactionHelper.rollbackTransaction();
throw new BusinessRuleException(e.getMessageKey(), e);
} catch (AccountException e) {
this.transactionHelper.rollbackTransaction();
throw new BusinessRuleException(e.getKey(), e);
} finally {
this.transactionHelper.closeSession();
}
}
Aggregations