Java tutorial
/******************************************************************************* * Copyright (c) 2009 David Harrison. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl-3.0.html * * Contributors: * David Harrison - initial API and implementation ******************************************************************************/ package com.sfs.whichdoctor.dao; import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.TreeMap; import javax.annotation.Resource; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.springframework.dao.DataAccessException; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import com.sfs.beans.BuilderBean; import com.sfs.beans.FinancialTypeBean; import com.sfs.beans.PrivilegesBean; import com.sfs.beans.UserBean; import com.sfs.whichdoctor.beans.CreditBean; import com.sfs.whichdoctor.beans.DebitBean; import com.sfs.whichdoctor.beans.GroupBean; import com.sfs.whichdoctor.beans.ItemBean; import com.sfs.whichdoctor.beans.OrganisationBean; import com.sfs.whichdoctor.beans.PaymentBean; import com.sfs.whichdoctor.beans.PersonBean; import com.sfs.whichdoctor.beans.ReceiptBean; import com.sfs.whichdoctor.beans.SearchBean; import com.sfs.whichdoctor.beans.SearchResultsBean; import com.sfs.whichdoctor.search.WhichDoctorSearchDaoException; /** * The Class DebitDAOImpl. */ public class DebitDAOImpl extends WhichDoctorFinancialObjectDAOImpl implements DebitDAO { /** The data logger. */ private static Logger dataLogger = Logger.getLogger(DebitDAOImpl.class); /** The payment dao. */ @Resource private PaymentDAO paymentDAO; /** * Used to get a DebitBean for a specified debitId. * * @param debitId the debit id * * @return the debit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final DebitBean load(final int debitId) throws WhichDoctorDaoException { return load(debitId, new BuilderBean(), false); } /** * Used to get a DebitBean for a specified debitId & supplied load options. * * @param debitId the debit id * @param loadDetails the load details * * @return the debit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final DebitBean load(final int debitId, final BuilderBean loadDetails) throws WhichDoctorDaoException { return load(debitId, loadDetails, false); } /** * Used to get a DebitBean for a specified debitId and supplied load * options. A boolean parameter identifies whether to use the default reader * connection or optional writer connection datasource. * * @param debitId the debit id * @param loadDetails the load details * @param useWriterConn the use writer conn * * @return the debit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ private DebitBean load(final int debitId, final BuilderBean loadDetails, final boolean useWriterConn) throws WhichDoctorDaoException { DebitBean debit = null; dataLogger.info("DebitId: " + debitId + " requested"); JdbcTemplate jdbcTemplate = this.getJdbcTemplateReader(); if (useWriterConn) { jdbcTemplate = this.getJdbcTemplateWriter(); } final String loadSQL = getSQL().getValue("debit/load") + " AND invoice.InvoiceId = ?"; try { debit = (DebitBean) jdbcTemplate.queryForObject(loadSQL, new Object[] { debitId }, new RowMapper() { public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException { return loadDebit(rs, loadDetails); } }); } catch (IncorrectResultSizeDataAccessException ie) { dataLogger.debug("No results found for search: " + ie.getMessage()); } return debit; } /** * Load a DebitBean for a specified debit name. * * @param strDebit the str debit * * @return the debit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final DebitBean load(final String strDebit) throws WhichDoctorDaoException { return load(strDebit, new BuilderBean()); } /** * Load a DebitBean for a specified debit name and supplied load options. * * @param strDebit the str debit * @param loadDetails the load details * * @return the debit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final DebitBean load(final String strDebit, final BuilderBean loadDetails) throws WhichDoctorDaoException { dataLogger.info("Debit Name: " + strDebit + " requested"); int debitGUID = 0; final String loadSQL = getSQL().getValue("debit/loadName"); try { debitGUID = this.getJdbcTemplateReader().queryForInt(loadSQL, new Object[] { strDebit }); } catch (IncorrectResultSizeDataAccessException ie) { dataLogger.debug("No results found for search: " + ie.getMessage()); } if (debitGUID > 0) { return loadGUID(debitGUID, loadDetails); } else { throw new WhichDoctorDaoException("Sorry no debit matching " + "those details could be identified"); } } /** * Load a DebitBean for a specified GUID. * * @param guid the guid * * @return the debit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final DebitBean loadGUID(final int guid) throws WhichDoctorDaoException { return loadGUID(guid, new BuilderBean()); } /** * Load a DebitBean for a specified GUID and supplied load options. * * @param guid the guid * @param loadDetails the load details * * @return the debit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final DebitBean loadGUID(final int guid, final BuilderBean loadDetails) throws WhichDoctorDaoException { dataLogger.info("Debit GUID: " + guid + " requested"); DebitBean debit = null; final String loadSQL = getSQL().getValue("debit/load") + " AND invoice.Active = true AND invoice.GUID = ?"; try { debit = (DebitBean) this.getJdbcTemplateReader().queryForObject(loadSQL, new Object[] { guid }, new RowMapper() { public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException { return loadDebit(rs, loadDetails); } }); } catch (IncorrectResultSizeDataAccessException ie) { dataLogger.debug("No results found for search: " + ie.getMessage()); } return debit; } /** * Refresh the calculated debit values (credit/outstanding) for the supplied * debit GUID value. * * @param guid the guid */ public final void refreshDebitValues(final int guid) { try { final DebitBean debit = this.loadGUID(guid); if (debit != null) { refreshDebitValues(debit); } } catch (WhichDoctorDaoException wde) { dataLogger.error("Failed to load debit " + guid + " to refresh its values: " + wde.getMessage()); } } /** * Refresh the calculated values (credit/outstanding) for all debits stored * in the system. */ public final void refreshAllDebitValues() { // Perform a search for all debits, for each entry refresh and // update the creditValue and outstandingValues. Collection<DebitBean> debits = new ArrayList<DebitBean>(); SearchBean search = this.getSearchDAO().initiate("debit", null); search.setLimit(0); try { SearchResultsBean results = this.getSearchDAO().search(search); if (results.getSearchResults() != null) { for (Object objDebit : results.getSearchResults()) { DebitBean debit = (DebitBean) objDebit; debits.add(debit); } } } catch (WhichDoctorSearchDaoException wse) { dataLogger.error("Error performing debit search: " + wse.getMessage()); } for (DebitBean debit : debits) { refreshDebitValues(debit); dataLogger.error("Refreshed the calculated values for: " + debit.getGUID()); } } /** * A private function that refreshes the calculated debit values * (credit/outstanding) for the supplied debit object. * * @param debit the debit */ private void refreshDebitValues(final DebitBean debit) { try { Double[] calculatedValues = getCalculatedValues(debit); final double creditValue = calculatedValues[0]; final double outstandingValue = calculatedValues[1]; /* Modify the financial summary */ this.getJdbcTemplateWriter().update(this.getSQL().getValue("debit/updateValues"), new Object[] { creditValue, outstandingValue, debit.getGUID() }); } catch (DataAccessException dae) { dataLogger.error( "Failed to update calculated values for GUID " + debit.getGUID() + ": " + dae.getMessage()); } } /** * Creates the DebitBean. * * @param debit the debit * @param checkUser the check user * @param privileges the privileges * * @return the debit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final DebitBean create(final DebitBean debit, final UserBean checkUser, final PrivilegesBean privileges) throws WhichDoctorDaoException { debit.setActive(true); int debitId = save(debit, checkUser, privileges, "create"); return load(debitId, new BuilderBean(), true); } /** * Modify the DebitBean. * * @param debit the debit * @param checkUser the check user * @param privileges the privileges * * @return the debit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final DebitBean modify(final DebitBean debit, final UserBean checkUser, final PrivilegesBean privileges) throws WhichDoctorDaoException { debit.setActive(true); int debitId = save(debit, checkUser, privileges, "modify"); return load(debitId, new BuilderBean(), true); } /** * Delete the DebitBean. * * @param debit the debit * @param checkUser the check user * @param privileges the privileges * * @return true, if successful * * @throws WhichDoctorDaoException the which doctor dao exception */ public final boolean delete(final DebitBean debit, final UserBean checkUser, final PrivilegesBean privileges) throws WhichDoctorDaoException { boolean success = false; if (privileges.getPrivilege(checkUser, "invoices", "delete")) { // Before deleting the debit remove its child objects final BuilderBean loadDetails = new BuilderBean(); loadDetails.setParameter("LOAD_ALL", true); try { final DebitBean deleteObj = this.loadGUID(debit.getGUID(), loadDetails); deleteAssociatedObjects(deleteObj, checkUser, privileges); } catch (WhichDoctorDaoException wde) { dataLogger.error("Error deleting children: " + wde.getMessage(), wde); throw new WhichDoctorDaoException("Error deleting children objects: " + wde.getMessage()); } } debit.setActive(false); int debitDeleted = save(debit, checkUser, privileges, "delete"); if (debitDeleted > 0) { success = true; } return success; } /** * Save the updated DebitBean. * * @param debit the debit * @param checkUser the check user * @param privileges the privileges * @param action the action * * @return the int * * @throws WhichDoctorDaoException the which doctor dao exception */ private int save(final DebitBean debit, final UserBean checkUser, final PrivilegesBean privileges, final String action) throws WhichDoctorDaoException { /* Create invoice requires all the essential invoice information */ if (debit.getDescription() == null) { throw new NullPointerException("Debit description field cannot be null"); } if (StringUtils.isBlank(debit.getDescription())) { throw new WhichDoctorDaoException("Debit description field cannot " + "be an empty string"); } if (debit.getTypeName() == null) { throw new WhichDoctorDaoException("Debit requires a debit type"); } if (StringUtils.isBlank(debit.getTypeName())) { throw new WhichDoctorDaoException("Debit requires a debit type"); } if (StringUtils.equals(debit.getTypeName(), "Null")) { throw new WhichDoctorDaoException("Debit requires a debit type"); } if (debit.getPersonId() == 0 && debit.getOrganisationId() == 0) { throw new WhichDoctorDaoException("Debit must be attributed to " + "a person or organisation"); } if (!privileges.getPrivilege(checkUser, "invoices", action)) { throw new WhichDoctorDaoException("Insufficient user credentials to " + action + " debit"); } int typeId = 0; try { FinancialTypeBean financialObject = this.financialTypeDAO.load("Debit", debit.getTypeName(), debit.getClassName()); typeId = financialObject.getFinancialTypeId(); } catch (Exception e) { dataLogger.error("Error loading financial type for debit: " + e.getMessage()); throw new WhichDoctorDaoException("Debit requires a valid type"); } Double[] calculatedValues = getCalculatedValues(debit); final double creditValue = calculatedValues[0]; final double outstandingValue = calculatedValues[1]; // Load the existing debit (if one exists) to see if the GST rate has changed double existingGSTRate = debit.getGSTRate(); if (debit.getGUID() > 0) { try { final DebitBean existingDebit = this.loadGUID(debit.getGUID()); existingGSTRate = existingDebit.getGSTRate(); } catch (WhichDoctorDaoException wde) { dataLogger.error("Error loading existing debit: " + wde.getMessage()); } } /* Check if the debit number exists, if not create one */ debit.setNumber(this.checkNumber("debit", debit.getNumber(), debit.getIssued())); int debitId = 0; /* Does a credit number need to be generated */ Date issued = new Date(Calendar.getInstance().getTimeInMillis()); if (debit.getIssued() != null) { issued = new Date(debit.getIssued().getTime()); } Timestamp sqlTimeStamp = new Timestamp(Calendar.getInstance().getTimeInMillis()); ArrayList<Object> parameters = new ArrayList<Object>(); parameters.add(debit.getDescription()); parameters.add(debit.getNumber()); parameters.add(debit.getGSTRate()); parameters.add(debit.getCancelled()); parameters.add(debit.getValue()); parameters.add(debit.getNetValue()); parameters.add(creditValue); parameters.add(outstandingValue); parameters.add(typeId); parameters.add(debit.getPersonId()); parameters.add(debit.getOrganisationId()); parameters.add(issued); parameters.add(debit.getPaymentDue()); parameters.add(debit.getLatePaymentFee()); parameters.add(debit.getLatePaymentDate()); parameters.add(debit.getRecommendedDonation()); parameters.add(debit.getActive()); parameters.add(sqlTimeStamp); parameters.add(checkUser.getDN()); parameters.add(debit.getLogMessage(action)); try { Integer[] result = this.performUpdate("debit", debit.getGUID(), parameters, "Debit", checkUser, action); /* Set the returned guid and id values */ debit.setGUID(result[0]); debitId = result[1]; } catch (Exception e) { dataLogger.error("Error processing debit record: " + e.getMessage()); throw new WhichDoctorDaoException("Error processing debit record: " + e.getMessage()); } if (debitId > 0) { dataLogger.info(checkUser.getDN() + " created debitId: " + String.valueOf(debitId)); // Update the financial summary updateFinancialSummary(action, debit, typeId, issued); /* If the existing GST rate is different to the new rate update payments */ if (debit.getGUID() > 0 && existingGSTRate != debit.getGSTRate()) { updateReceiptGst(debit.getGUID(), debit.getGSTRate(), checkUser, privileges); } /* Update the search index */ if (debit.getOrganisationId() > 0) { this.getSearchIndexDAO().updateCurrentBalanceIndex(debit.getOrganisationId(), "organisation"); } else { this.getSearchIndexDAO().updateCurrentBalanceIndex(debit.getPersonId(), "person"); } } return debitId; } /** * Update the financial summary. * * @param action the action * @param debit the debit * @param typeId the type id * @param issued the issued * * @throws WhichDoctorDaoException the which doctor dao exception */ private void updateFinancialSummary(final String action, final DebitBean debit, final int typeId, final Date issued) throws WhichDoctorDaoException { try { if (StringUtils.equals(action, "delete")) { this.getJdbcTemplateWriter().update(this.getSQL().getValue("debit/deleteSummary"), new Object[] { debit.getGUID() }); } else { /* Create or modify the financial summary */ this.getJdbcTemplateWriter().update(this.getSQL().getValue("debit/editSummary"), new Object[] { debit.getGUID(), typeId, debit.getNumber(), debit.getDescription(), debit.getValue(), debit.getNetValue(), debit.getCancelled(), issued, debit.getPersonId(), debit.getOrganisationId(), typeId, debit.getNumber(), debit.getDescription(), debit.getValue(), debit.getNetValue(), debit.getCancelled(), issued, debit.getPersonId(), debit.getOrganisationId() }); } } catch (DataAccessException dae) { dataLogger.error("Failed to modify the financial summary: " + dae.getMessage()); throw new WhichDoctorDaoException("Failed to modify the financial summary: " + dae.getMessage()); } } /** * Delete the objects associated with the supplied DebitBean. * * @param deleteObjects the delete objects * @param checkUser the check user * @param privileges the privileges */ private void deleteAssociatedObjects(final DebitBean deleteObjects, final UserBean checkUser, final PrivilegesBean privileges) { deleteMemos(deleteObjects, checkUser, privileges); deleteGroups(deleteObjects, checkUser, privileges); } /** * Update the associated receipt GST values. * * @param guid the guid * @param gst the gst * @param checkUser the check user * @param privileges the privileges */ private void updateReceiptGst(final int guid, final double gst, final UserBean checkUser, final PrivilegesBean privileges) { final Collection<ReceiptBean> receipts = this.loadReceipts(guid); for (ReceiptBean receipt : receipts) { if (receipt.getPayments() != null) { for (PaymentBean payment : receipt.getPayments()) { payment.setGSTRate(gst); // Reset the value amount to recalculate payment.setValue(0); try { this.paymentDAO.modify(payment, receipt, checkUser, privileges); } catch (WhichDoctorDaoException wde) { dataLogger.error("Error updating payment GST value: " + wde.getMessage()); } } } } } /** * Load debit. * * @param rs the rs * @param loadDetails the load details * * @return the debit bean * * @throws SQLException the SQL exception */ private DebitBean loadDebit(final ResultSet rs, final BuilderBean loadDetails) throws SQLException { DebitBean debit = new DebitBean(); // Create resource bean and fill with dataset info. debit.setId(rs.getInt("InvoiceId")); debit.setGUID(rs.getInt("GUID")); debit.setAbbreviation(rs.getString("Abbreviation")); debit.setNumber(rs.getString("InvoiceNo")); debit.setDescription(rs.getString("Description")); debit.setPersonId(rs.getInt("PersonId")); if (debit.getPersonId() > 0) { debit.setPerson(loadPerson(rs, debit.getPersonId(), loadDetails)); } debit.setOrganisationId(rs.getInt("OrganisationId")); if (debit.getOrganisationId() > 0) { debit.setOrganisation(loadOrganisation(rs, debit.getOrganisationId(), loadDetails)); } debit.setValue(rs.getDouble("Value")); debit.setNetValue(rs.getDouble("NetValue")); debit.setCreditValue(rs.getDouble("CreditValue")); debit.setOutstandingValue(rs.getDouble("OutstandingValue")); debit.setGSTRate(rs.getDouble("GSTRate")); try { debit.setIssued(rs.getDate("Issued")); } catch (SQLException e) { debit.setIssued(null); } try { debit.setPaymentDue(rs.getDate("PaymentDue")); } catch (SQLException e) { dataLogger.debug("Error reading PaymentDue"); } debit.setLatePaymentFee(rs.getDouble("LatePaymentFee")); try { debit.setLatePaymentDate(rs.getDate("LatePaymentDate")); } catch (SQLException e) { dataLogger.debug("Error reading LatePaymentDate"); } debit.setRecommendedDonation(rs.getDouble("RecommendedDonation")); debit.setCancelled(rs.getBoolean("Cancelled")); debit.setTypeName(rs.getString("Type")); debit.setClassName(rs.getString("InvoiceType")); if (loadDetails.getBoolean("CREDITS")) { // Perform a search for credits associated with this debit Collection<CreditBean> loadedCredits = loadAllCredits(debit.getGUID()); debit.setCredits(getCredits(loadedCredits)); debit.setRefunds(getRefunds(loadedCredits)); } if (loadDetails.getBoolean("RECEIPTS")) { // Perform a search for receipts associated with this debit debit.setReceipts(loadReceipts(debit.getGUID())); } debit.setSecurity(rs.getString("Security")); debit.setActive(rs.getBoolean("Active")); if (loadDetails.getBoolean("HISTORY")) { try { debit.setCreatedDate(rs.getTimestamp("CreatedDate")); } catch (SQLException e) { dataLogger.debug("Error reading CreatedDate"); } debit.setCreatedBy(rs.getString("CreatedBy")); try { debit.setModifiedDate(rs.getTimestamp("ModifiedDate")); } catch (SQLException e) { dataLogger.debug("Error reading ModifiedDate"); } debit.setModifiedBy(rs.getString("ModifiedBy")); try { debit.setExportedDate(rs.getTimestamp("ExportedDate")); } catch (SQLException e) { dataLogger.debug("Error reading ExportedDate"); } debit.setExportedBy(rs.getString("ExportedBy")); } if (loadDetails.getBoolean("TAGS")) { try { debit.setTags(this.getTagDAO().load(debit.getGUID(), loadDetails.getString("USERDN"), true)); } catch (Exception e) { dataLogger.error("Error loading tags for debit: " + e.getMessage()); } } if (loadDetails.getBoolean("MEMO")) { try { debit.setMemo(this.getMemoDAO().load(debit.getGUID(), loadDetails.getBoolean("MEMO_FULL"))); } catch (Exception e) { dataLogger.error("Error loading memos for debit: " + e.getMessage()); } } if (loadDetails.getBoolean("GROUPS")) { debit.setGroups(loadGroups(debit.getGUID())); } if (loadDetails.getBoolean("CREATED")) { UserBean user = new UserBean(); user.setDN(rs.getString("CreatedBy")); user.setPreferredName(rs.getString("CreatedFirstName")); user.setLastName(rs.getString("CreatedLastName")); debit.setCreatedUser(user); } if (loadDetails.getBoolean("MODIFIED")) { UserBean user = new UserBean(); user.setDN(rs.getString("ModifiedBy")); user.setPreferredName(rs.getString("ModifiedFirstName")); user.setLastName(rs.getString("ModifiedLastName")); debit.setModifiedUser(user); } if (loadDetails.getBoolean("EXPORTED")) { UserBean user = new UserBean(); user.setDN(rs.getString("ExportedBy")); user.setPreferredName(rs.getString("ExportedFirstName")); user.setLastName(rs.getString("ExportedLastName")); debit.setExportedUser(user); } return debit; } /** * Load credits related to the supplied credit GUID. * * @param guid the guid * * @return the collection< credit bean> */ private Collection<CreditBean> loadAllCredits(final int guid) { Collection<CreditBean> credits = new ArrayList<CreditBean>(); try { SearchBean search = this.getSearchDAO().initiate("credit", null); search.setLimit(0); CreditBean criteria = (CreditBean) search.getSearchCriteria(); final DebitBean debit = new DebitBean(); debit.setGUID(guid); criteria.setDebit(debit); search.setSearchCriteria(criteria); SearchResultsBean results = this.getSearchDAO().search(search); if (results != null) { for (Object objCredit : results.getSearchResults()) { CreditBean credit = (CreditBean) objCredit; credits.add(credit); } } } catch (WhichDoctorSearchDaoException wse) { dataLogger.error("Error performing search for related credits: " + wse.getMessage()); } return credits; } /** * Gets the credits. * * @param creditArray the credit array * @return the credits */ private Collection<CreditBean> getCredits(final Collection<CreditBean> creditArray) { Collection<CreditBean> credits = new ArrayList<CreditBean>(); if (creditArray != null) { for (CreditBean credit : creditArray) { if (StringUtils.equalsIgnoreCase(credit.getClassName(), "Credit")) { credits.add(credit); } } } return credits; } /** * Gets the refunds. * * @param creditArray the credit array * @return the refunds */ private Collection<CreditBean> getRefunds(final Collection<CreditBean> creditArray) { Collection<CreditBean> refunds = new ArrayList<CreditBean>(); if (creditArray != null) { for (CreditBean credit : creditArray) { if (!StringUtils.equalsIgnoreCase(credit.getClassName(), "Credit")) { refunds.add(credit); } } } return refunds; } /** * Load receipts related to the supplied debit GUID. * * @param guid the guid * * @return the collection< receipt bean> */ private Collection<ReceiptBean> loadReceipts(final int guid) { Collection<ReceiptBean> receipts = new ArrayList<ReceiptBean>(); try { SearchBean search = this.getSearchDAO().initiate("receipt", null); search.setLimit(0); ReceiptBean criteria = (ReceiptBean) search.getSearchCriteria(); final PaymentBean payment = new PaymentBean(); final DebitBean debit = new DebitBean(); debit.setGUID(guid); payment.setDebit(debit); Collection<PaymentBean> payments = new ArrayList<PaymentBean>(); payments.add(payment); criteria.setPayments(payments); search.setSearchCriteria(criteria); BuilderBean details = new BuilderBean(); details.setParameter("PAYMENT", true); SearchResultsBean results = this.getSearchDAO().search(search, details); if (results != null) { for (Object objReceipt : results.getSearchResults()) { ReceiptBean receipt = (ReceiptBean) objReceipt; receipts.add(receipt); } } } catch (WhichDoctorSearchDaoException wse) { dataLogger.error("Error performing search for related receipts: " + wse.getMessage()); } return receipts; } /** * Gets the calculated values. * * @param debit the debit * * @return the calculated values */ private Double[] getCalculatedValues(final DebitBean debit) { double debitValue = 0; double creditValue = 0; double receiptValue = 0; double outstandingValue = 0; if (debit != null && !debit.getCancelled()) { debitValue = debit.getNetValue(); } if (debit != null && debit.getGUID() > 0) { Collection<CreditBean> credits = loadAllCredits(debit.getGUID()); Collection<ReceiptBean> receipts = loadReceipts(debit.getGUID()); if (receipts != null) { for (ReceiptBean receipt : receipts) { if (!receipt.getCancelled() && receipt.getPayments() != null) { for (PaymentBean payment : receipt.getPayments()) { if (payment.getDebit() != null) { final int debitGUID = payment.getDebit().getGUID(); if (debitGUID == debit.getGUID()) { receiptValue += payment.getNetValue(); } } } } } } if (credits != null) { for (CreditBean credit : credits) { if (!credit.getCancelled()) { if (!StringUtils.equalsIgnoreCase(credit.getClassName(), "Credit")) { // Cash credit, subtract from receipt value receiptValue -= credit.getNetValue(); } else { creditValue += credit.getNetValue(); } } } } } outstandingValue = debitValue - creditValue - receiptValue; if (dataLogger.isDebugEnabled()) { dataLogger.debug("Debit value: " + debitValue); dataLogger.debug("Credit value: " + creditValue); dataLogger.debug("Receipt value: " + receiptValue); dataLogger.debug("Outstanding value: " + outstandingValue); } return new Double[] { creditValue, outstandingValue }; } /** * Load person. * * @param rs the rs * @param personId the person id * @param loadDetails the load details * * @return the person bean * * @throws SQLException the SQL exception */ private PersonBean loadPerson(final ResultSet rs, final int personId, final BuilderBean loadDetails) throws SQLException { PersonBean person = new PersonBean(); person.setPersonIdentifier(rs.getInt("PersonIdentifier")); person.setPreferredName(rs.getString("PreferredName")); person.setFirstName(rs.getString("FirstName")); person.setLastName(rs.getString("LastName")); person.setGUID(personId); person.setTitle(rs.getString("Title")); person.setGender(rs.getString("Gender")); // Load address if (loadDetails.getBoolean("ADDRESS")) { try { person.setAddress(this.getAddressDAO().load(person.getGUID(), false, loadDetails.getString("ADDRESS_CLASS"), loadDetails.getString("ADDRESS_TYPE"))); } catch (Exception e) { dataLogger.error("Error loading address for credit: " + e.getMessage()); } } return person; } /** * Load organisation. * * @param rs the rs * @param organisationId the organisation id * @param loadDetails the load details * * @return the organisation bean * * @throws SQLException the SQL exception */ private OrganisationBean loadOrganisation(final ResultSet rs, final int organisationId, final BuilderBean loadDetails) throws SQLException { OrganisationBean organisation = new OrganisationBean(); organisation.setGUID(organisationId); organisation.setName(rs.getString("OrganisationName")); /* Load address */ if (loadDetails.getBoolean("ADDRESS")) { try { organisation.setAddress(this.getAddressDAO().load(organisation.getGUID(), false, loadDetails.getString("ADDRESS_CLASS"), loadDetails.getString("ADDRESS_TYPE"))); } catch (Exception e) { dataLogger.error("Error loading address for credit: " + e.getMessage()); } } return organisation; } /** * Load groups. * * @param guid the guid * * @return the array list< group bean> */ private ArrayList<GroupBean> loadGroups(final int guid) { // Create new SearchBean of type Debit and default values SearchResultsBean results = new SearchResultsBean(); SearchBean groupSearch = this.getSearchDAO().initiate("group", null); groupSearch.setLimit(0); GroupBean searchCriteria = (GroupBean) groupSearch.getSearchCriteria(); searchCriteria.setObjectType("Debits"); ItemBean item = new ItemBean(); item.setObject2GUID(guid); TreeMap<String, ItemBean> items = new TreeMap<String, ItemBean>(); items.put("Debit", item); searchCriteria.setItems(items); groupSearch.setSearchCriteria(searchCriteria); try { BuilderBean loadGroup = new BuilderBean(); loadGroup.setParameter("ITEMS", true); loadGroup.setParameter("REFERENCEID", String.valueOf(guid)); results = this.getSearchDAO().search(groupSearch, loadGroup); } catch (Exception e) { dataLogger.error("Error loading groups for debit: " + e.getMessage()); } ArrayList<GroupBean> groups = new ArrayList<GroupBean>(); for (Object group : results.getSearchResults()) { groups.add((GroupBean) group); } return groups; } }