/* * Copyright (c) 2005-2011 Grameen Foundation USA * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * See also http://www.apache.org/licenses/LICENSE-2.0.html for an * explanation of the license and how it is applied. */ package org.mifos.application.servicefacade; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import org.joda.time.LocalDate; /** * Holds data to save a collection sheet */ public class SaveCollectionSheetDto { /* * The "Contract" is that the first customer must be the "top customer" (usually Center) but other customers can be * any or all of the groups and clients underneath the top customer in any order. * * It would be normal to have them in order thought e.g center, group 1, client 1, client 2, group 2... */ private List<SaveCollectionSheetCustomerDto> saveCollectionSheetCustomers; private Short paymentType; private LocalDate transactionDate; private String receiptId; private LocalDate receiptDate; private Short userId; public SaveCollectionSheetDto(List<SaveCollectionSheetCustomerDto> saveCollectionSheetCustomers, Short paymentType, LocalDate transactionDate, String receiptId, LocalDate receiptDate, Short userId) throws SaveCollectionSheetException { validateInput(saveCollectionSheetCustomers, paymentType, transactionDate, userId); if (validationErrors.size() > 0) { throw new SaveCollectionSheetException(validationErrors); } this.saveCollectionSheetCustomers = saveCollectionSheetCustomers; this.paymentType = paymentType; this.transactionDate = transactionDate; this.receiptId = receiptId; this.receiptDate = receiptDate; this.userId = userId; analyze(); } public List<SaveCollectionSheetCustomerDto> getSaveCollectionSheetCustomers() { return this.saveCollectionSheetCustomers; } public Short getPaymentType() { return this.paymentType; } public LocalDate getTransactionDate() { return this.transactionDate; } public String getReceiptId() { return this.receiptId; } public LocalDate getReceiptDate() { return this.receiptDate; } public Short getUserId() { return this.userId; } /* * The Dto really ends here: All the fields and methods below are only 'helpers' derived because of: * * a) self-validation (any error is a programming problem) Some may think this should not be part of this class * and/or errors should just throw a runtime exception. I (JPW) thought it might be useful for a programmer to have * the errors nicely put in an array with a method to print them for debugging purposes. We'll see how it goes. * * * b) analysing the save collection sheet input. Again some may think this should not be in this class. However, * even this simplified structure takes quite a bit of set up and I thought it would be good to have methods that * told the programmer how the collection sheet was made up. Some of the fields are used to determine if it is worth * pre-fetching (into the Hibernate session cache) collection sheet data for performance reasons. */ private List<InvalidSaveCollectionSheetReason> validationErrors = new ArrayList<InvalidSaveCollectionSheetReason>(); /* * summary fields */ private Integer countOneLevelUnder = 0; private Integer countTwoLevelsUnder = 0; private Integer countCustomerAccounts = 0; private Integer countLoanDisbursements = 0; private Integer countLoanRepayments = 0; private Integer countSavingsWithdrawals = 0; private Integer countSavingsDeposits = 0; private Integer countIndividualSavingsWithdrawals = 0; private Integer countIndividualSavingsDeposits = 0; public Integer countOneLevelUnder() { return this.countOneLevelUnder; } public Integer countTwoLevelsUnder() { return this.countTwoLevelsUnder; } public Integer countCustomerAccounts() { return this.countCustomerAccounts; } public Integer countLoanDisbursements() { return this.countLoanDisbursements; } public Integer countLoanRepayments() { return this.countLoanRepayments; } public Integer countSavingsWithdrawals() { return this.countSavingsWithdrawals; } public Integer countSavingsDeposits() { return this.countSavingsDeposits; } public Integer countIndividualSavingsWithdrawals() { return this.countIndividualSavingsWithdrawals; } public Integer countIndividualSavingsDeposits() { return this.countIndividualSavingsDeposits; } private void validateInput(List<SaveCollectionSheetCustomerDto> saveCollectionSheetCustomers, Short paymentType, LocalDate transactionDate, Short userId) { if (saveCollectionSheetCustomers == null || saveCollectionSheetCustomers.size() < 1) { validationErrors.add(InvalidSaveCollectionSheetReason.NO_TOP_CUSTOMER_PROVIDED); } if (paymentType == null) { validationErrors.add(InvalidSaveCollectionSheetReason.PAYMENT_TYPE_NULL); } else { if (!validPaymentType(paymentType)) { validationErrors.add(InvalidSaveCollectionSheetReason.UNSUPPORTED_PAYMENT_TYPE); } } if (transactionDate == null) { validationErrors.add(InvalidSaveCollectionSheetReason.TRANSACTION_DATE_NULL); } if (userId == null) { validationErrors.add(InvalidSaveCollectionSheetReason.USERID_NULL); } if (!uniqueCustomers(saveCollectionSheetCustomers)) { validationErrors.add(InvalidSaveCollectionSheetReason.CUSTOMER_LISTED_MORE_THAN_ONCE); } } private boolean uniqueCustomers(List<SaveCollectionSheetCustomerDto> saveCollectionSheetCustomers) { if (saveCollectionSheetCustomers != null && saveCollectionSheetCustomers.size() > 0) { for (Integer i = 0; i < saveCollectionSheetCustomers.size() - 1; i++) { for (Integer j = i + 1; j < saveCollectionSheetCustomers.size(); j++) { if (saveCollectionSheetCustomers.get(i).getCustomerId().compareTo( saveCollectionSheetCustomers.get(j).getCustomerId()) == 0) { return false; } } } } return true; } private boolean validPaymentType(Short paymentType) { // allow any valid (positive id number) payment type for now (MIFOS-4486) if (paymentType < 1) { return false; } return true; } private void analyze() { for (SaveCollectionSheetCustomerDto saveCollectionSheetCustomer : this.getSaveCollectionSheetCustomers()) { if (saveCollectionSheetCustomer.getParentCustomerId() != null) { if (saveCollectionSheetCustomer.getParentCustomerId().equals( this.getSaveCollectionSheetCustomers().get(0).getCustomerId())) { countOneLevelUnder += 1; } else { countTwoLevelsUnder += 1; } } SaveCollectionSheetCustomerAccountDto saveCollectionSheetCustomerAccount = saveCollectionSheetCustomer .getSaveCollectionSheetCustomerAccount(); if (null != saveCollectionSheetCustomerAccount) { if (saveCollectionSheetCustomerAccount.getTotalCustomerAccountCollectionFee() .compareTo(BigDecimal.ZERO) > 0) { countCustomerAccounts += 1; } } List<SaveCollectionSheetCustomerLoanDto> saveCollectionSheetCustomerLoans = saveCollectionSheetCustomer .getSaveCollectionSheetCustomerLoans(); if (null != saveCollectionSheetCustomerLoans && saveCollectionSheetCustomerLoans.size() > 0) { for (SaveCollectionSheetCustomerLoanDto saveCollectionSheetCustomerLoan : saveCollectionSheetCustomerLoans) { if (saveCollectionSheetCustomerLoan.getTotalDisbursement().compareTo(BigDecimal.ZERO) > 0) { countLoanDisbursements += 1; } if (saveCollectionSheetCustomerLoan.getTotalLoanPayment().compareTo(BigDecimal.ZERO) > 0) { countLoanRepayments += 1; } } } List<SaveCollectionSheetCustomerSavingDto> saveCollectionSheetCustomerSavings = saveCollectionSheetCustomer .getSaveCollectionSheetCustomerSavings(); if (null != saveCollectionSheetCustomerSavings && saveCollectionSheetCustomerSavings.size() > 0) { for (SaveCollectionSheetCustomerSavingDto saveCollectionSheetCustomerSaving : saveCollectionSheetCustomerSavings) { if (saveCollectionSheetCustomerSaving.getTotalWithdrawal().compareTo(BigDecimal.ZERO) > 0) { countSavingsWithdrawals += 1; } if (saveCollectionSheetCustomerSaving.getTotalDeposit().compareTo(BigDecimal.ZERO) > 0) { countSavingsDeposits += 1; } } } List<SaveCollectionSheetCustomerSavingDto> saveCollectionSheetCustomerSavingsIndividual = saveCollectionSheetCustomer .getSaveCollectionSheetCustomerIndividualSavings(); if (null != saveCollectionSheetCustomerSavingsIndividual && saveCollectionSheetCustomerSavingsIndividual.size() > 0) { for (SaveCollectionSheetCustomerSavingDto saveCollectionSheetCustomerSavingIndividual : saveCollectionSheetCustomerSavingsIndividual) { if (saveCollectionSheetCustomerSavingIndividual.getTotalWithdrawal().compareTo(BigDecimal.ZERO) > 0) { countIndividualSavingsWithdrawals += 1; } if (saveCollectionSheetCustomerSavingIndividual.getTotalDeposit().compareTo(BigDecimal.ZERO) > 0) { countIndividualSavingsDeposits += 1; } } } } } public void print() { doLog(""); doLog(""); doLog(">>>>>Printing SaveCollectionSheetDto "); doLog("Payment Type: " + this.getPaymentType()); doLog("Receipt Id: " + this.getReceiptId()); doLog("Receipt Date: " + this.getReceiptDate()); doLog("Transaction Date: " + this.getTransactionDate()); doLog("User Id: " + this.getUserId()); doLog("Listing Customers..."); for (SaveCollectionSheetCustomerDto saveCollectionSheetCustomer : this.getSaveCollectionSheetCustomers()) { doLog("Customer: Id: " + saveCollectionSheetCustomer.getCustomerId() + " Parent Id: " + saveCollectionSheetCustomer.getParentCustomerId() + " Attendance Id: " + saveCollectionSheetCustomer.getAttendanceId()); SaveCollectionSheetCustomerAccountDto saveCollectionSheetCustomerAccount = saveCollectionSheetCustomer .getSaveCollectionSheetCustomerAccount(); if (null != saveCollectionSheetCustomerAccount) { doLog(" : A/C Collections"); doLog(" : Account Id: " + saveCollectionSheetCustomerAccount.getAccountId() + " Currency Id: " + saveCollectionSheetCustomerAccount.getCurrencyId() + " A/C Collections: " + saveCollectionSheetCustomerAccount.getTotalCustomerAccountCollectionFee()); } else { doLog(" : No A/C Collections"); } List<SaveCollectionSheetCustomerLoanDto> saveCollectionSheetCustomerLoans = saveCollectionSheetCustomer .getSaveCollectionSheetCustomerLoans(); if (null != saveCollectionSheetCustomerLoans && saveCollectionSheetCustomerLoans.size() > 0) { doLog(" : Loans"); for (SaveCollectionSheetCustomerLoanDto saveCollectionSheetCustomerLoan : saveCollectionSheetCustomerLoans) { doLog(" : Account Id: " + saveCollectionSheetCustomerLoan.getAccountId() + " Currency Id: " + saveCollectionSheetCustomerLoan.getCurrencyId() + " Payment: " + saveCollectionSheetCustomerLoan.getTotalLoanPayment() + " Disbursement: " + saveCollectionSheetCustomerLoan.getTotalDisbursement()); } } else { doLog(" : No Loans"); } List<SaveCollectionSheetCustomerSavingDto> saveCollectionSheetCustomerSavings = saveCollectionSheetCustomer .getSaveCollectionSheetCustomerSavings(); if (null != saveCollectionSheetCustomerSavings && saveCollectionSheetCustomerSavings.size() > 0) { doLog(" : Normal Saving Accounts"); for (SaveCollectionSheetCustomerSavingDto saveCollectionSheetCustomerSaving : saveCollectionSheetCustomerSavings) { doLog(" : Account Id: " + saveCollectionSheetCustomerSaving.getAccountId() + " Currency Id: " + saveCollectionSheetCustomerSaving.getCurrencyId() + " Deposit: " + saveCollectionSheetCustomerSaving.getTotalDeposit() + " Withdrawal: " + saveCollectionSheetCustomerSaving.getTotalWithdrawal()); } } else { doLog(" : No Normal Saving Accounts"); } saveCollectionSheetCustomerSavings = saveCollectionSheetCustomer .getSaveCollectionSheetCustomerIndividualSavings(); if (null != saveCollectionSheetCustomerSavings && saveCollectionSheetCustomerSavings.size() > 0) { doLog(" : Individual Saving Accounts"); for (SaveCollectionSheetCustomerSavingDto saveCollectionSheetCustomerSaving : saveCollectionSheetCustomerSavings) { doLog(" : Account Id: " + saveCollectionSheetCustomerSaving.getAccountId() + " Currency Id: " + saveCollectionSheetCustomerSaving.getCurrencyId() + " Deposit: " + saveCollectionSheetCustomerSaving.getTotalDeposit() + " Withdrawal: " + saveCollectionSheetCustomerSaving.getTotalWithdrawal()); } } else { doLog(" : No Individual Saving Accounts"); } } doLog(""); doLog("================= Summary (only items > 0.00 are processed)==================="); doLog("No. of Customers One level Under Top Customer : " + countOneLevelUnder); doLog("No. of Customers Two levels Under Top Customer: " + countTwoLevelsUnder); doLog(""); doLog("Total No. of Customer Accounts to be Processed: " + countCustomerAccounts); doLog("Total No. of Repayments to be Processed: " + countLoanRepayments); doLog("Total No. of Disbursals to be Processed: " + countLoanDisbursements); doLog("Total No. of Normal Savings Account Deposits to be Processed: " + countSavingsDeposits); doLog("Total No. of Normal Savings Account Withdrawals to be Processed: " + countSavingsWithdrawals); doLog("Total No. of Individual Savings Account Deposits to be Processed: " + countIndividualSavingsDeposits); doLog("Total No. of Individual Savings Account Withdrawals to be Processed: " + countIndividualSavingsWithdrawals); doLog("=============================================================================="); } public String printSummary() { final StringBuilder builder = new StringBuilder(); final String comma = ", "; builder.append("Collection Sheet Summary:"); builder.append(comma); builder.append(this.getSaveCollectionSheetCustomers().get(0).getCustomerId()); builder.append(comma); builder.append(countOneLevelUnder); builder.append(comma); builder.append(countTwoLevelsUnder); builder.append(comma); builder.append(countCustomerAccounts); builder.append(comma); builder.append(countLoanRepayments); builder.append(comma); builder.append(countLoanDisbursements); builder.append(comma); builder.append(countSavingsDeposits); builder.append(comma); builder.append(countSavingsWithdrawals); builder.append(comma); builder.append(countIndividualSavingsDeposits); builder.append(comma); builder.append(countIndividualSavingsWithdrawals); return builder.toString(); } private void doLog(String str) { System.out.println(str); } }