/* * 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.cg.service.impl; import java.sql.Date; import java.text.MessageFormat; import java.util.Collection; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.module.cg.CGConstants; import org.kuali.kfs.module.cg.CGKeyConstants; import org.kuali.kfs.module.cg.businessobject.Award; import org.kuali.kfs.module.cg.businessobject.Proposal; import org.kuali.kfs.module.cg.dataaccess.CloseDao; import org.kuali.kfs.module.cg.document.ProposalAwardCloseDocument; import org.kuali.kfs.module.cg.service.CloseService; import org.kuali.rice.core.api.config.property.ConfigurationService; import org.kuali.rice.core.api.datetime.DateTimeService; import org.kuali.rice.kew.api.exception.WorkflowException; import org.kuali.rice.krad.service.BusinessObjectService; import org.kuali.rice.krad.service.DocumentService; import org.springframework.transaction.annotation.Transactional; @Transactional public class CloseServiceImpl implements CloseService { protected CloseDao closeDao; protected DateTimeService dateTimeService; protected BusinessObjectService businessObjectService; protected DocumentService documentService; protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CloseServiceImpl.class); protected ConfigurationService configService; /** * <ul> * <li>Get the max proposal_close_number in cg_prpsl_close_t.</li> * <li>Get the Close with that max_close_number.</li>got * <li>If todays date is the same as the user_initiate_date on that Close, continue. Else, break.</li> * <li>Get all proposals with a null closing_date and a submission_date <= the last_closed_date of the Close with the * max_proposal_close number.</li> * <li>Save the number of proposals that come back.</li> * <li>Update each of these proposals setting the close_date to todays date.</li> * <li>Get all awards with a null closing_date, an entry_date <= the last_closed_date of the Close with the max_close number and * a status_code not equal to 'U'.</li> * <li>Save the number of awards that come back.</li> * <li>Update each of these awards setting the close_date to todays date.</li> * <li>Update the Close with that max_close_number setting the proposal_closed_count to the number of proposals brought back * above and the award_closed_count to the number of awards brought back above.</li> * <li>Save the Close.</li> * </ul> * * @see org.kuali.kfs.module.cg.service.CloseService#close() */ @Override public boolean close() { Date today = dateTimeService.getCurrentSqlDateMidnight(); ProposalAwardCloseDocument max = getMaxApprovedClose(today); if (null == max) { // no closes at all. Gotta wait until we get an approved one. return true; } boolean result = true; String noteText = null; if (max.getDocumentHeader().getWorkflowDocument().getCurrentNodeNames().contains( CGConstants.CGKimApiConstants.UNPROCESSED_ROUTING_NODE_NAME) ) { try { Collection<Proposal> proposals = closeDao.getProposalsToClose(max); Long proposalCloseCount = new Long(proposals.size()); for (Proposal p : proposals) { p.setProposalClosingDate(today); businessObjectService.save(p); } Collection<Award> awards = closeDao.getAwardsToClose(max); Long awardCloseCount = new Long(awards.size()); for (Award a : awards) { a.setAwardClosingDate(today); businessObjectService.save(a); } max.setAwardClosedCount(awardCloseCount); max.setProposalClosedCount(proposalCloseCount); businessObjectService.save(max); noteText = configService.getPropertyValueAsString(CGKeyConstants.MESSAGE_CLOSE_JOB_SUCCEEDED); } catch (Exception e) { String messageProperty = configService.getPropertyValueAsString(CGKeyConstants.ERROR_CLOSE_JOB_FAILED); noteText = MessageFormat.format(messageProperty, e.getMessage(), e.getCause().getMessage()); } finally { result = this.addDocumentNoteAfterClosing(max, noteText); } } return result; } /** * @see org.kuali.kfs.module.cg.service.CloseService#getMostRecentClose() */ @Override public ProposalAwardCloseDocument getMostRecentClose() { Date today = dateTimeService.getCurrentSqlDateMidnight(); String documentNumber = closeDao.getMostRecentClose(today); if (StringUtils.isNotBlank(documentNumber)) { try { return (ProposalAwardCloseDocument) documentService.getByDocumentHeaderId(documentNumber); } catch (WorkflowException we) { throw new RuntimeException(we); } } else { return null; } } /** * @see org.kuali.kfs.module.cg.service.CloseService#addDocumentNoteAfterClosing(String) */ protected boolean addDocumentNoteAfterClosing(ProposalAwardCloseDocument close, String noteText) { try { documentService.createNoteFromDocument(close, noteText); documentService.approveDocument(close, noteText, null); } catch (WorkflowException we) { LOG.error("problem during CloseServiceImpl.addDocumentNoteAfterClosing()", we); return false; } return true; } /** * @see org.kuali.kfs.module.cg.service.CloseService#getMaxApprovedClose(java.sql.Date) */ @Override public ProposalAwardCloseDocument getMaxApprovedClose(Date today) { String documentNumber = closeDao.getMaxApprovedClose(today); if (StringUtils.isNotBlank(documentNumber)) { try { return (ProposalAwardCloseDocument) documentService.getByDocumentHeaderId(documentNumber); } catch (WorkflowException we) { throw new RuntimeException(we); } } else { return null; } } public void setDateTimeService(DateTimeService dateTimeService) { this.dateTimeService = dateTimeService; } public void setCloseDao(CloseDao closeDao) { this.closeDao = closeDao; } public void setBusinessObjectService(BusinessObjectService businessObjectService) { this.businessObjectService = businessObjectService; } public void setDocumentService(DocumentService documentService) { this.documentService = documentService; } public void setConfigService(ConfigurationService configService) { this.configService = configService; } }