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 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.PersonBean; import com.sfs.whichdoctor.beans.SearchBean; import com.sfs.whichdoctor.beans.SearchResultsBean; import java.sql.Date; import java.sql.ResultSet; import java.sql.Timestamp; import java.sql.SQLException; import java.util.ArrayList; import java.util.Calendar; import java.util.TreeMap; 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; /** * The Class CreditDAOImpl. */ public class CreditDAOImpl extends WhichDoctorFinancialObjectDAOImpl implements CreditDAO { /** The data logger. */ private static Logger dataLogger = Logger.getLogger(CreditDAOImpl.class); /** * Used to load a CreditBean with a specific creditId. * * @param creditId the credit id * * @return the credit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final CreditBean load(final int creditId) throws WhichDoctorDaoException { return load(creditId, new BuilderBean(), false); } /** * Used to load a CreditBean with a specific creditId and supplied load * options. * * @param creditId the credit id * @param loadDetails the load details * * @return the credit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final CreditBean load(final int creditId, final BuilderBean loadDetails) throws WhichDoctorDaoException { return load(creditId, loadDetails, false); } /** * Used to load a CreditBean with a specific name and supplied load options. * A boolean parameter identifies whether to use the default reader * connection or optional writer connection datasource. * * @param creditId the credit id * @param loadDetails the load details * @param useWriter the use writer * * @return the credit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ private CreditBean load(final int creditId, final BuilderBean loadDetails, final boolean useWriter) throws WhichDoctorDaoException { CreditBean credit = null; dataLogger.info("Credit Id: " + creditId + " requested"); final String loadSQL = getSQL().getValue("credit/load") + " AND credit.CreditId = ?"; JdbcTemplate jdbcTemplate = this.getJdbcTemplateReader(); if (useWriter) { jdbcTemplate = this.getJdbcTemplateWriter(); } try { credit = (CreditBean) jdbcTemplate.queryForObject(loadSQL, new Object[] { creditId }, new RowMapper() { public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException { return loadCredit(rs, loadDetails); } }); } catch (IncorrectResultSizeDataAccessException ie) { dataLogger.debug("No results found for this search:" + ie.getMessage()); } return credit; } /** * Used to load a CreditBean with a specific name. * * @param strCredit the str credit * * @return the credit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final CreditBean load(final String strCredit) throws WhichDoctorDaoException { return load(strCredit, new BuilderBean()); } /** * Used to load a CreditBean with a specific name and supplied load options. * * @param strCredit the str credit * @param loadDetails the load details * * @return the credit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final CreditBean load(final String strCredit, final BuilderBean loadDetails) throws WhichDoctorDaoException { dataLogger.info("Credit Name: " + strCredit + " requested"); int creditGUID = 0; final String loadSQL = getSQL().getValue("credit/loadName"); try { creditGUID = this.getJdbcTemplateReader().queryForInt(loadSQL, new Object[] { strCredit }); } catch (IncorrectResultSizeDataAccessException ie) { dataLogger.debug("No results found for this search:" + ie.getMessage()); } if (creditGUID > 0) { return loadGUID(creditGUID, loadDetails); } else { throw new WhichDoctorDaoException("Sorry no credit matching those " + "details could be identified"); } } /** * Used to load a CreditBean with a specific GUID. * * @param guid the guid * * @return the credit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final CreditBean loadGUID(final int guid) throws WhichDoctorDaoException { return loadGUID(guid, new BuilderBean()); } /** * Used to load a CreditBean with a specific GUID and supplied load options. * * @param guid the guid * @param loadDetails the load details * * @return the credit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final CreditBean loadGUID(final int guid, final BuilderBean loadDetails) throws WhichDoctorDaoException { dataLogger.info("Credit GUID: " + guid + " requested"); CreditBean credit = null; final String loadSQL = getSQL().getValue("credit/load") + " AND credit.GUID = ? AND credit.Active = true"; try { credit = (CreditBean) this.getJdbcTemplateReader().queryForObject(loadSQL, new Object[] { guid }, new RowMapper() { public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException { return loadCredit(rs, loadDetails); } }); } catch (IncorrectResultSizeDataAccessException ie) { dataLogger.debug("No results found for this search:" + ie.getMessage()); } return credit; } /** * Creates the CreditBean. * * @param credit the credit * @param checkUser the check user * @param privileges the privileges * * @return the credit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final CreditBean create(final CreditBean credit, final UserBean checkUser, final PrivilegesBean privileges) throws WhichDoctorDaoException { credit.setActive(true); int creditId = save(credit, checkUser, privileges, "create"); return load(creditId, new BuilderBean(), true); } /** * Modify the CreditBean. * * @param credit the credit * @param checkUser the check user * @param privileges the privileges * * @return the credit bean * * @throws WhichDoctorDaoException the which doctor dao exception */ public final CreditBean modify(final CreditBean credit, final UserBean checkUser, final PrivilegesBean privileges) throws WhichDoctorDaoException { credit.setActive(true); int creditId = save(credit, checkUser, privileges, "modify"); return load(creditId, new BuilderBean(), true); } /** * Deletes the CreditBean. * * @param credit the credit * @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 CreditBean credit, final UserBean checkUser, final PrivilegesBean privileges) throws WhichDoctorDaoException { boolean success = false; if (privileges.getPrivilege(checkUser, "credits", "delete")) { // Before deleting the credit remove its child objects final BuilderBean loadDetails = new BuilderBean(); loadDetails.setParameter("LOAD_ALL", true); try { final CreditBean deleteObj = this.loadGUID(credit.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()); } } credit.setActive(false); int creditDeleted = save(credit, checkUser, privileges, "delete"); if (creditDeleted > 0) { success = true; } return success; } /** * Save the updated credit bean. * * @param credit the credit * @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 CreditBean credit, final UserBean checkUser, final PrivilegesBean privileges, final String action) throws WhichDoctorDaoException { // Create credit requires all the essential information to be supplied if (credit.getDescription() == null) { throw new WhichDoctorDaoException("Credit description field " + "cannot be null"); } if (StringUtils.isBlank(credit.getDescription())) { throw new WhichDoctorDaoException("Credit description field cannot " + "be an empty string"); } if (credit.getTypeName() == null) { throw new WhichDoctorDaoException("Credit requires a credit type"); } if (StringUtils.isBlank(credit.getTypeName())) { throw new WhichDoctorDaoException("Credit requires a credit type"); } if (StringUtils.equals(credit.getTypeName(), "Null")) { throw new WhichDoctorDaoException("Credit requires a credit type"); } if (credit.getValue() == 0) { throw new WhichDoctorDaoException("The credit requires a value"); } if (credit.getPersonId() == 0 && credit.getOrganisationId() == 0) { throw new WhichDoctorDaoException("Credit must be attributed to " + "a person or organisation"); } if (!privileges.getPrivilege(checkUser, "credits", action)) { throw new WhichDoctorDaoException("Insufficient user credentials to " + action + " credit"); } int typeId = 0; try { FinancialTypeBean financialObject = financialTypeDAO.load("Credit", credit.getTypeName(), credit.getClassName()); typeId = financialObject.getFinancialTypeId(); } catch (Exception e) { dataLogger.error("Error loading financial type for credit: " + e.getMessage()); throw new WhichDoctorDaoException("Credit requires a valid type"); } int existingDebitGUID = 0; // Load the existing credit (if GUID > 0) to check if the // associated debit has changed. if (credit.getGUID() > 0) { try { final BuilderBean existingDetails = new BuilderBean(); existingDetails.setParameter("DEBITS_FULL", true); final CreditBean existingCredit = this.loadGUID(credit.getGUID(), existingDetails); if (existingCredit.getDebit() != null) { existingDebitGUID = existingCredit.getDebit().getGUID(); } } catch (WhichDoctorDaoException wde) { dataLogger.error("Error loading existing credit: " + wde.getMessage()); } } /* Check if the credit number exists, if not create one */ credit.setNumber(this.checkNumber("credit", credit.getNumber(), credit.getIssued())); int creditId = 0; /* Does a credit number need to be generated */ Date issued = new Date(Calendar.getInstance().getTimeInMillis()); if (credit.getIssued() != null) { issued = new Date(credit.getIssued().getTime()); } DebitBean debit = credit.getDebit(); if (debit == null) { debit = new DebitBean(); } Timestamp sqlTimeStamp = new Timestamp(Calendar.getInstance().getTimeInMillis()); ArrayList<Object> parameters = new ArrayList<Object>(); parameters.add(credit.getDescription()); parameters.add(credit.getNumber()); parameters.add(credit.getCancelled()); parameters.add(credit.getGSTRate()); parameters.add(credit.getValue()); parameters.add(credit.getNetValue()); parameters.add(credit.getPersonId()); parameters.add(credit.getOrganisationId()); parameters.add(issued); parameters.add(typeId); parameters.add(debit.getGUID()); parameters.add(credit.getActive()); parameters.add(sqlTimeStamp); parameters.add(checkUser.getDN()); parameters.add(credit.getLogMessage(action)); try { Integer[] result = this.performUpdate("credit", credit.getGUID(), parameters, "Credit", checkUser, action); /* Set the returned guid and id values */ credit.setGUID(result[0]); creditId = result[1]; } catch (Exception e) { dataLogger.error("Error processing credit record: " + e.getMessage()); throw new WhichDoctorDaoException("Error processing credit record: " + e.getMessage()); } if (creditId > 0) { dataLogger.info(checkUser.getDN() + " created creditId: " + String.valueOf(creditId)); // Update the financial summary updateFinancialSummary(action, credit, typeId, issued); // Update the related debit's calculated values if (existingDebitGUID > 0) { // Update the previous debit GUID this.getDebitDAO().refreshDebitValues(existingDebitGUID); } if (debit.getGUID() > 0 && debit.getGUID() != existingDebitGUID) { this.getDebitDAO().refreshDebitValues(debit.getGUID()); } // Update the search index if (credit.getOrganisationId() > 0) { this.getSearchIndexDAO().updateCurrentBalanceIndex(credit.getOrganisationId(), "organisation"); } else { this.getSearchIndexDAO().updateCurrentBalanceIndex(credit.getPersonId(), "person"); } } return creditId; } /** * Update the financial summary. * * @param action the action * @param credit the credit * @param typeId the type id * @param issued the issued * * @throws WhichDoctorDaoException the which doctor dao exception */ private void updateFinancialSummary(final String action, final CreditBean credit, final int typeId, final Date issued) throws WhichDoctorDaoException { try { if (StringUtils.equals(action, "delete")) { this.getJdbcTemplateWriter().update(this.getSQL().getValue("credit/deleteSummary"), new Object[] { credit.getGUID() }); } else { /* Create or modify the financial summarty */ this.getJdbcTemplateWriter().update(this.getSQL().getValue("credit/editSummary"), new Object[] { credit.getGUID(), typeId, credit.getNumber(), credit.getDescription(), credit.getValue(), credit.getNetValue(), credit.getCancelled(), issued, credit.getPersonId(), credit.getOrganisationId(), typeId, credit.getNumber(), credit.getDescription(), credit.getValue(), credit.getNetValue(), credit.getCancelled(), issued, credit.getPersonId(), credit.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 CreditBean. * * @param deleteObjects the delete objects * @param checkUser the check user * @param privileges the privileges */ private void deleteAssociatedObjects(final CreditBean deleteObjects, final UserBean checkUser, final PrivilegesBean privileges) { deleteMemos(deleteObjects, checkUser, privileges); deleteGroups(deleteObjects, checkUser, privileges); } /** * Load credit. * * @param rs the rs * @param loadDetails the load details * * @return the credit bean * * @throws SQLException the SQL exception */ private CreditBean loadCredit(final ResultSet rs, final BuilderBean loadDetails) throws SQLException { CreditBean credit = new CreditBean(); // Create resource bean and fill with dataset info. credit.setId(rs.getInt("CreditId")); credit.setGUID(rs.getInt("GUID")); credit.setAbbreviation(rs.getString("Abbreviation")); credit.setTypeName(rs.getString("Type")); credit.setClassName(rs.getString("CreditType")); credit.setNumber(rs.getString("CreditNo")); credit.setDescription(rs.getString("Description")); credit.setPersonId(rs.getInt("PersonId")); if (credit.getPersonId() > 0) { credit.setPerson(loadPerson(rs, credit.getPersonId(), loadDetails)); } credit.setOrganisationId(rs.getInt("OrganisationId")); if (credit.getOrganisationId() > 0) { credit.setOrganisation(loadOrganisation(rs, credit.getOrganisationId(), loadDetails)); } credit.setValue(rs.getDouble("Value")); credit.setNetValue(rs.getDouble("NetValue")); try { credit.setIssued(rs.getDate("Issued")); } catch (SQLException e) { credit.setIssued(null); } credit.setCancelled(rs.getBoolean("Cancelled")); credit.setGSTRate(rs.getDouble("GSTRate")); if (loadDetails.getBoolean("DEBITS_FULL")) { int debitGUID = rs.getInt("InvoiceId"); if (debitGUID > 0) { DebitBean debit = new DebitBean(); try { debit = this.getDebitDAO().loadGUID(debitGUID); } catch (Exception e) { dataLogger.error("Error loading debit for credit: " + e.getMessage()); } if (debit.getId() > 0) { credit.setDebit(debit); } } } credit.setSecurity(rs.getString("Security")); credit.setActive(rs.getBoolean("Active")); if (loadDetails.getBoolean("HISTORY")) { try { credit.setCreatedDate(rs.getTimestamp("CreatedDate")); } catch (SQLException sqe) { dataLogger.debug("Error reading CreatedDate: " + sqe.getMessage()); } credit.setCreatedBy(rs.getString("CreatedBy")); try { credit.setModifiedDate(rs.getTimestamp("ModifiedDate")); } catch (SQLException sqe) { dataLogger.debug("Error reading ModifiedDate: " + sqe.getMessage()); } credit.setModifiedBy(rs.getString("ModifiedBy")); try { credit.setExportedDate(rs.getTimestamp("ExportedDate")); } catch (SQLException sqe) { dataLogger.debug("Error reading ExportedDate: " + sqe.getMessage()); } credit.setExportedBy(rs.getString("ExportedBy")); } if (loadDetails.getBoolean("TAGS")) { try { credit.setTags(this.getTagDAO().load(credit.getGUID(), loadDetails.getString("USERDN"), true)); } catch (Exception e) { dataLogger.error("Error loading tags for credit: " + e.getMessage()); } } if (loadDetails.getBoolean("MEMO")) { try { credit.setMemo(this.getMemoDAO().load(credit.getGUID(), loadDetails.getBoolean("MEMO_FULL"))); } catch (Exception e) { dataLogger.error("Error loading memos for credit: " + e.getMessage()); } } if (loadDetails.getBoolean("GROUPS")) { credit.setGroups(loadGroups(credit.getGUID())); } if (loadDetails.getBoolean("CREATED")) { UserBean user = new UserBean(); user.setDN(rs.getString("CreatedBy")); user.setPreferredName(rs.getString("CreatedFirstName")); user.setLastName(rs.getString("CreatedLastName")); credit.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")); credit.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")); credit.setExportedUser(user); } return credit; } /** * 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.setGUID(personId); person.setPersonIdentifier(rs.getInt("PersonIdentifier")); person.setPreferredName(rs.getString("PreferredName")); person.setFirstName(rs.getString("FirstName")); person.setLastName(rs.getString("LastName")); 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")); 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 Credit and default values SearchResultsBean results = new SearchResultsBean(); SearchBean groupSearch = this.getSearchDAO().initiate("group", null); groupSearch.setLimit(0); GroupBean searchCriteria = (GroupBean) groupSearch.getSearchCriteria(); searchCriteria.setObjectType("Credits"); ItemBean item = new ItemBean(); item.setObject2GUID(guid); TreeMap<String, ItemBean> items = new TreeMap<String, ItemBean>(); items.put("Credit", 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 credit: " + e.getMessage()); } ArrayList<GroupBean> groups = new ArrayList<GroupBean>(); for (Object group : results.getSearchResults()) { groups.add((GroupBean) group); } return groups; } }