/* * 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.tem.document.service.impl; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.kuali.kfs.module.tem.TemPropertyConstants; import org.kuali.kfs.module.tem.businessobject.AccountingDocumentRelationship; import org.kuali.kfs.module.tem.dataaccess.AccountingDocumentRelationshipDao; import org.kuali.kfs.module.tem.document.service.AccountingDocumentRelationshipService; import org.kuali.kfs.sys.KFSConstants; import org.kuali.rice.kim.api.identity.IdentityService; import org.kuali.rice.kim.api.identity.principal.Principal; import org.kuali.rice.krad.service.BusinessObjectService; import org.springframework.transaction.annotation.Transactional; @Transactional public class AccountingDocumentRelationshipServiceImpl implements AccountingDocumentRelationshipService { protected AccountingDocumentRelationshipDao accountingDocumentRelationshipDao; protected BusinessObjectService businessObjectService; protected IdentityService identityService; private static final Logger LOG = Logger.getLogger(AccountingDocumentRelationshipServiceImpl.class); /** * @see org.kuali.kfs.module.tem.document.service.AccountingDocumentRelationshipService#getRelatedDocumentNumbers(java.lang.String) */ @Override public Set<String> getRelatedDocumentNumbers(String documentNumber) { List<AccountingDocumentRelationship> adrList = accountingDocumentRelationshipDao.findAccountingDocumentRelationshipByDocumentNumber(documentNumber); Set<String> allRelatedDocumentNumbers = new HashSet<String>(); if (adrList != null) { for (AccountingDocumentRelationship adr : adrList) { addRelationship(adr, allRelatedDocumentNumbers, documentNumber); } } return allRelatedDocumentNumbers; } /** * Adds the relationship to a Set of document numbers, skipping the given document number * @param adr the relationship with document numbers to add * @param relatedDocumentNumbers the Set of Document numbers to add the relationship to * @param documentNumber the document number to add the other side of the relationship to */ protected void addRelationship(AccountingDocumentRelationship adr, Set<String> relatedDocumentNumbers, String documentNumber) { if (adr.getDocumentNumber().equals(documentNumber)) { // child docs relatedDocumentNumbers.add(adr.getRelDocumentNumber()); } else { // parent docs relatedDocumentNumbers.add(adr.getDocumentNumber()); } } /** * @see org.kuali.kfs.module.tem.document.service.AccountingDocumentRelationshipService#getAllRelatedDocumentNumbers(java.lang.String) */ @Override public Set<String> getAllRelatedDocumentNumbers(String documentNumber) { Set<String> allRelatedDocumentNumbers = new HashSet<String>(); // get root document number String rootDocumentNumber = getRootDocumentNumber(documentNumber); rootDocumentNumber = rootDocumentNumber != null ? rootDocumentNumber : documentNumber; if (rootDocumentNumber != null) { allRelatedDocumentNumbers.add(rootDocumentNumber); // get all children document numbers allRelatedDocumentNumbers = getAllRelatedChildrenDocumentNumbers(allRelatedDocumentNumbers); // add the root document number if the initial lookup document number != root document number if (!rootDocumentNumber.equals(documentNumber)) { allRelatedDocumentNumbers.add(rootDocumentNumber); } // remove the document number used for initial lookup. allRelatedDocumentNumbers.remove(documentNumber); return allRelatedDocumentNumbers; } return allRelatedDocumentNumbers; } /** * @see org.kuali.kfs.module.tem.document.service.AccountingDocumentRelationshipService#getRootDocumentNumber(java.lang.String) */ @Override public String getRootDocumentNumber(String documentNumber) { List<AccountingDocumentRelationship> adrList = accountingDocumentRelationshipDao.findAccountingDocumentRelationship(new AccountingDocumentRelationship(null, documentNumber)); if (!adrList.isEmpty() && adrList.size() > 1) { LOG.warn("Document has 2 parents. This should not happen."); } return adrList.isEmpty() ? documentNumber : getRootDocumentNumber(adrList.get(0).getDocumentNumber()); } /** * This method finds all related children document numbers * * @param documentNumbers * @return */ private Set<String> getAllRelatedChildrenDocumentNumbers(Set<String> documentNumbers) { Set<String> allRelatedDocumentNumbers = new HashSet<String>(); for (String documentNumber : documentNumbers) { List<AccountingDocumentRelationship> adrList = accountingDocumentRelationshipDao.findAccountingDocumentRelationship(new AccountingDocumentRelationship(documentNumber, null)); for (AccountingDocumentRelationship adr : adrList) { allRelatedDocumentNumbers.add(adr.getRelDocumentNumber()); } allRelatedDocumentNumbers.addAll(getAllRelatedChildrenDocumentNumbers(allRelatedDocumentNumbers)); } return allRelatedDocumentNumbers.isEmpty() ? documentNumbers : allRelatedDocumentNumbers; } /** * @see org.kuali.kfs.module.tem.document.service.AccountingDocumentRelationshipService#save(java.util.List) */ @Override public void save(List<AccountingDocumentRelationship> accountingDocumentRelationships) { for (AccountingDocumentRelationship adr : accountingDocumentRelationships) { save(adr); } } /** * @see org.kuali.kfs.module.tem.document.service.AccountingDocumentRelationshipService#save(org.kuali.kfs.module.tem.businessobject.AccountingDocumentRelationship) * If the principalId is not set, it will be defaulted to KualiUser.SYSTEM_USER's principalId. */ @Override public void save(AccountingDocumentRelationship accountingDocumentRelationship) { if (accountingDocumentRelationship.getPrincipalId() == null) { Principal person = identityService.getPrincipalByPrincipalName(KFSConstants.SYSTEM_USER); accountingDocumentRelationship.setPrincipalId(person.getPrincipalId()); } accountingDocumentRelationshipDao.save(accountingDocumentRelationship); } /** * @see org.kuali.kfs.module.tem.document.service.AccountingDocumentRelationshipService#delete(java.util.List) */ @Override public void delete(List<AccountingDocumentRelationship> accountingDocumentRelationships) { for (AccountingDocumentRelationship adr : accountingDocumentRelationships) { delete(adr); } } /** * @see org.kuali.kfs.module.tem.document.service.AccountingDocumentRelationshipService#huntForRelatedDocumentNumbersWithADocumentType(java.lang.String, java.lang.String) */ @Override public Set<String> huntForRelatedDocumentNumbersWithDocumentType(String documentNumber, String documentType) { List<AccountingDocumentRelationship> adrList = accountingDocumentRelationshipDao.findAccountingDocumentRelationshipByDocumentNumber(documentNumber); Set<String> docNumbers = new HashSet<String>(); if (adrList != null && adrList != null) { for (AccountingDocumentRelationship adr: adrList) { if (!StringUtils.isBlank(adr.getDescription()) && adr.getDescription().matches(".*"+documentType+".*")) { addRelationship(adr, docNumbers, documentNumber); } } } return docNumbers; } /** * @see org.kuali.kfs.module.tem.document.service.AccountingDocumentRelationshipService#delete(org.kuali.kfs.module.tem.businessobject.AccountingDocumentRelationship) */ @Override public void delete(AccountingDocumentRelationship accountingDocumentRelationship) { accountingDocumentRelationshipDao.delete(accountingDocumentRelationship); } /** * Counts the number of accounting document relationships where the given document number is the related document number; returns true * if that count is greater than 0 * @see org.kuali.kfs.module.tem.document.service.AccountingDocumentRelationshipService#isDocumentSomebodysChild(java.lang.String) */ @Override public boolean isDocumentSomebodysChild(String documentNumber) { Map<String, String> fieldValues = new HashMap<String, String>(); fieldValues.put(TemPropertyConstants.TRVL_RELATED_DOCUMENT_NUM, documentNumber); final int count = getBusinessObjectService().countMatching(AccountingDocumentRelationship.class, fieldValues); return count > 0; } @Override public List<AccountingDocumentRelationship> find(AccountingDocumentRelationship adr) { return accountingDocumentRelationshipDao.findAccountingDocumentRelationship(adr); } public AccountingDocumentRelationshipDao getAccountingDocumentRelationshipDao() { return accountingDocumentRelationshipDao; } public void setAccountingDocumentRelationshipDao(AccountingDocumentRelationshipDao accountingDocumentRelationshipDao) { this.accountingDocumentRelationshipDao = accountingDocumentRelationshipDao; } public BusinessObjectService getBusinessObjectService() { return businessObjectService; } public void setBusinessObjectService(BusinessObjectService businessObjectService) { this.businessObjectService = businessObjectService; } public IdentityService getIdentityService() { return identityService; } public void setIdentityService(IdentityService identityService) { this.identityService = identityService; } }