/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.module.purap.service.impl; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import org.kuali.kfs.module.purap.businessobject.AccountsPayableItemBase; import org.kuali.kfs.module.purap.businessobject.CreditMemoAccountRevision; import org.kuali.kfs.module.purap.businessobject.CreditMemoItem; import org.kuali.kfs.module.purap.businessobject.PaymentRequestAccount; import org.kuali.kfs.module.purap.businessobject.PaymentRequestAccountRevision; import org.kuali.kfs.module.purap.businessobject.PaymentRequestItem; import org.kuali.kfs.module.purap.businessobject.PurApAccountingLine; import org.kuali.kfs.module.purap.businessobject.PurApAccountingLineBase; import org.kuali.kfs.module.purap.service.PurapAccountRevisionService; import org.kuali.rice.core.api.datetime.DateTimeService; import org.kuali.rice.krad.service.BusinessObjectService; public class PurapAccountRevisionServiceImpl implements PurapAccountRevisionService { private BusinessObjectService businessObjectService; private DateTimeService dateTimeService; /** * @see org.kuali.kfs.module.purap.service.PurapAccountHistoryService#savePaymentRequestAccountHistories(java.util.List, * java.lang.Integer, java.lang.String) */ public void savePaymentRequestAccountRevisions(List<PaymentRequestItem> paymentRequestItems, Integer postingYear, String postingPeriodCode) { List<PaymentRequestAccountRevision> accountHistories = new ArrayList<PaymentRequestAccountRevision>(); for (PaymentRequestItem item : paymentRequestItems) { Map<PurapAccountRevisionGroup, PurapAccountRevisionGroup> currentAcctLineGroups = buildAccountLineGroups(item, postingYear, postingPeriodCode); Map<PurapAccountRevisionGroup, PurapAccountRevisionGroup> historyAcctLineGroups = buildAccountHistoryGroups(item, postingYear, postingPeriodCode, PaymentRequestAccountRevision.class); HashSet<PurapAccountRevisionGroup> existList = new HashSet<PurapAccountRevisionGroup>(); // handle existing account line changes for (PurapAccountRevisionGroup histGroup : historyAcctLineGroups.keySet()) { PurapAccountRevisionGroup currGroup = currentAcctLineGroups.get(histGroup); if (currGroup != null) { // adjust the amount value histGroup.setChangeAmount(currGroup.getAmount().subtract(histGroup.getAmount())); } else { // negate the amount if acct line is deleted histGroup.setChangeAmount(histGroup.getAmount().negated()); } // build history record and save PaymentRequestAccountRevision history = (PaymentRequestAccountRevision) histGroup.buildRevisionRecord(PaymentRequestAccountRevision.class); history.setAccountRevisionTimestamp(dateTimeService.getCurrentTimestamp()); accountHistories.add(history); existList.add(histGroup); } // handle new accounting lines for (PurapAccountRevisionGroup group : currentAcctLineGroups.keySet()) { if (!existList.contains(group)) { // set change amount same as new amount group.setChangeAmount(group.getAmount()); PaymentRequestAccountRevision history = (PaymentRequestAccountRevision) group.buildRevisionRecord(PaymentRequestAccountRevision.class); history.setAccountRevisionTimestamp(dateTimeService.getCurrentTimestamp()); accountHistories.add(history); } } } businessObjectService.save(accountHistories); } public void cancelPaymentRequestAccountRevisions(List<PaymentRequestItem> paymentRequestItems, Integer postingYear, String postingPeriodCode) { List<PaymentRequestAccountRevision> accountHistories = new ArrayList<PaymentRequestAccountRevision>(); for (PaymentRequestItem item : paymentRequestItems) { Map<PurapAccountRevisionGroup, PurapAccountRevisionGroup> historyAcctLineGroups = buildAccountHistoryGroups(item, postingYear, postingPeriodCode, PaymentRequestAccountRevision.class); // handle existing account line changes for (PurapAccountRevisionGroup histGroup : historyAcctLineGroups.keySet()) { // negate the amount histGroup.setChangeAmount(histGroup.getAmount().negated()); // build history record and save PaymentRequestAccountRevision history = (PaymentRequestAccountRevision) histGroup.buildRevisionRecord(PaymentRequestAccountRevision.class); history.setAccountRevisionTimestamp(dateTimeService.getCurrentTimestamp()); accountHistories.add(history); } } businessObjectService.save(accountHistories); } /** * @see org.kuali.kfs.module.purap.service.PurapAccountHistoryService#saveCreditMemoAccountHistories(java.util.List, * java.lang.Integer, java.lang.String) */ public void saveCreditMemoAccountRevisions(List<CreditMemoItem> creditMemoItems, Integer postingYear, String postingPeriodCode) { List<CreditMemoAccountRevision> accountHistories = new ArrayList<CreditMemoAccountRevision>(); for (CreditMemoItem item : creditMemoItems) { Map<PurapAccountRevisionGroup, PurapAccountRevisionGroup> currentAcctLineGroups = buildAccountLineGroups(item, postingYear, postingPeriodCode); Map<PurapAccountRevisionGroup, PurapAccountRevisionGroup> historyAcctLineGroups = buildAccountHistoryGroups(item, postingYear, postingPeriodCode, CreditMemoAccountRevision.class); HashSet<PurapAccountRevisionGroup> existList = new HashSet<PurapAccountRevisionGroup>(); // first handle existing account line changes for (PurapAccountRevisionGroup histGroup : historyAcctLineGroups.keySet()) { PurapAccountRevisionGroup currGroup = currentAcctLineGroups.get(histGroup); if (currGroup != null) { // adjust the amount histGroup.setChangeAmount(currGroup.getAmount().subtract(histGroup.getAmount())); } else { // negate the amount if line is deleted histGroup.setChangeAmount(histGroup.getAmount().negated()); } // build history record and save CreditMemoAccountRevision history = (CreditMemoAccountRevision) histGroup.buildRevisionRecord(CreditMemoAccountRevision.class); history.setAccountRevisionTimestamp(dateTimeService.getCurrentTimestamp()); accountHistories.add(history); existList.add(histGroup); } // handle new account lines added for (PurapAccountRevisionGroup group : currentAcctLineGroups.keySet()) { if (!existList.contains(group)) { // set same change amount same as new amount group.setChangeAmount(group.getAmount()); CreditMemoAccountRevision history = (CreditMemoAccountRevision) group.buildRevisionRecord(CreditMemoAccountRevision.class); history.setAccountRevisionTimestamp(dateTimeService.getCurrentTimestamp()); accountHistories.add(history); } } } businessObjectService.save(accountHistories); } public void cancelCreditMemoAccountRevisions(List<CreditMemoItem> creditMemoItems, Integer postingYear, String postingPeriodCode) { List<CreditMemoAccountRevision> accountHistories = new ArrayList<CreditMemoAccountRevision>(); for (CreditMemoItem item : creditMemoItems) { Map<PurapAccountRevisionGroup, PurapAccountRevisionGroup> historyAcctLineGroups = buildAccountHistoryGroups(item, postingYear, postingPeriodCode, CreditMemoAccountRevision.class); // first handle existing account line changes for (PurapAccountRevisionGroup histGroup : historyAcctLineGroups.keySet()) { // negate the amount histGroup.setChangeAmount(histGroup.getAmount().negated()); // build history record and save CreditMemoAccountRevision history = (CreditMemoAccountRevision) histGroup.buildRevisionRecord(CreditMemoAccountRevision.class); history.setAccountRevisionTimestamp(dateTimeService.getCurrentTimestamp()); accountHistories.add(history); } } businessObjectService.save(accountHistories); } /** * Builds account history grouping data based on given list of purap account lines * * @param item PurAp Item * @param postingYear Posting year * @param postingPeriodCode Posting period * @return */ protected Map<PurapAccountRevisionGroup, PurapAccountRevisionGroup> buildAccountLineGroups(AccountsPayableItemBase item, Integer postingYear, String postingPeriodCode) { Map<PurapAccountRevisionGroup, PurapAccountRevisionGroup> accountLineGroups = new HashMap<PurapAccountRevisionGroup, PurapAccountRevisionGroup>(); for (PurApAccountingLine account : item.getSourceAccountingLines()) { PurapAccountRevisionGroup lineGroup = new PurapAccountRevisionGroup((PurApAccountingLineBase) account); lineGroup.setPostingYear(postingYear); lineGroup.setPostingPeriodCode(postingPeriodCode); if ((accountLineGroups.get(lineGroup)) == null) { accountLineGroups.put(lineGroup, lineGroup); } else { accountLineGroups.get(lineGroup).combineEntry((PurApAccountingLineBase) account); } } return accountLineGroups; } /** * Builds account history group based on existing account history lines * * @param item PurAp item * @param postingYear Posting year * @param postingPeriodCode Posting period code * @param clazz History class * @return Map of account history groups */ protected Map<PurapAccountRevisionGroup, PurapAccountRevisionGroup> buildAccountHistoryGroups(AccountsPayableItemBase item, Integer postingYear, String postingPeriodCode, Class<? extends PurApAccountingLineBase> clazz) { Map<PurapAccountRevisionGroup, PurapAccountRevisionGroup> historyGroups = new HashMap<PurapAccountRevisionGroup, PurapAccountRevisionGroup>(); // find the current sum value from history table and adjusts the amount Map<String, Object> fieldValues = new HashMap<String, Object>(); fieldValues.put("itemIdentifier", item.getItemIdentifier()); Collection<PurApAccountingLineBase> existingAccounts = (Collection<PurApAccountingLineBase>) businessObjectService.findMatching(clazz, fieldValues); if (existingAccounts != null && !existingAccounts.isEmpty()) { for (PurApAccountingLineBase existAcct : existingAccounts) { PurapAccountRevisionGroup historyGroup = new PurapAccountRevisionGroup(existAcct); historyGroup.setPostingYear(postingYear); historyGroup.setPostingPeriodCode(postingPeriodCode); if ((historyGroups.get(historyGroup)) == null) { historyGroups.put(historyGroup, historyGroup); } else { historyGroups.get(historyGroup).combineEntry((PaymentRequestAccount) existAcct); } } } return historyGroups; } /** * Gets the businessObjectService attribute. * * @return Returns the businessObjectService. */ public BusinessObjectService getBusinessObjectService() { return businessObjectService; } /** * Sets the businessObjectService attribute value. * * @param businessObjectService The businessObjectService to set. */ public void setBusinessObjectService(BusinessObjectService businessObjectService) { this.businessObjectService = businessObjectService; } /** * Gets the dateTimeService attribute. * * @return Returns the dateTimeService. */ public DateTimeService getDateTimeService() { return dateTimeService; } /** * Sets the dateTimeService attribute value. * * @param dateTimeService The dateTimeService to set. */ public void setDateTimeService(DateTimeService dateTimeService) { this.dateTimeService = dateTimeService; } }