001/*
002 * Copyright 2007 The Kuali Foundation
003 * 
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 * http://www.opensource.org/licenses/ecl2.php
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.ole.module.cg.service.impl;
017
018import java.sql.Date;
019import java.text.MessageFormat;
020import java.util.Collection;
021
022import org.apache.commons.lang.StringUtils;
023import org.kuali.ole.module.cg.CGConstants;
024import org.kuali.ole.module.cg.CGKeyConstants;
025import org.kuali.ole.module.cg.businessobject.Award;
026import org.kuali.ole.module.cg.businessobject.Proposal;
027import org.kuali.ole.module.cg.dataaccess.AwardDao;
028import org.kuali.ole.module.cg.dataaccess.CloseDao;
029import org.kuali.ole.module.cg.dataaccess.ProposalDao;
030import org.kuali.ole.module.cg.document.ProposalAwardCloseDocument;
031import org.kuali.ole.module.cg.service.CloseService;
032import org.kuali.ole.sys.context.SpringContext;
033import org.kuali.rice.core.api.config.property.ConfigurationService;
034import org.kuali.rice.core.api.datetime.DateTimeService;
035import org.kuali.rice.kew.api.exception.WorkflowException;
036import org.kuali.rice.krad.service.BusinessObjectService;
037import org.kuali.rice.krad.service.DocumentService;
038import org.springframework.transaction.annotation.Transactional;
039
040@Transactional
041public class CloseServiceImpl implements CloseService {
042
043    private AwardDao awardDao;
044    private ProposalDao proposalDao;
045    private CloseDao closeDao;
046    private DateTimeService dateTimeService;
047    protected BusinessObjectService businessObjectService;
048    protected DocumentService documentService;
049
050    /**
051     * <ul>
052     * <li>Get the max proposal_close_number in cg_prpsl_close_t.</li>
053     * <li>Get the Close with that max_close_number.</li>got
054     * <li>If todays date is the same as the user_initiate_date on that Close, continue. Else, break.</li>
055     * <li>Get all proposals with a null closing_date and a submission_date <= the last_closed_date of the Close with the
056     * max_proposal_close number.</li>
057     * <li>Save the number of proposals that come back.</li>
058     * <li>Update each of these proposals setting the close_date to todays date.</li>
059     * <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
060     * a status_code not equal to 'U'.</li>
061     * <li>Save the number of awards that come back.</li>
062     * <li>Update each of these awards setting the close_date to todays date.</li>
063     * <li>Update the Close with that max_close_number setting the proposal_closed_count to the number of proposals brought back
064     * above and the award_closed_count to the number of awards brought back above.</li>
065     * <li>Save the Close.</li>
066     * </ul>
067     * 
068     * @see org.kuali.ole.module.cg.service.CloseService#close()
069     */
070    @Override
071    public boolean close() {
072
073        Date today = dateTimeService.getCurrentSqlDateMidnight();
074        ProposalAwardCloseDocument max = getMaxApprovedClose(today);
075
076        if (null == max) { // no closes at all. Gotta wait until we get an approved one.
077            return true;
078        }
079
080        boolean result = true;
081        String noteText = null;
082        if (max.getDocumentHeader().getWorkflowDocument().getCurrentRouteNodeInstances().contains( CGConstants.CGKimApiConstants.UNPROCESSED_ROUTING_NODE_NAME) ) {
083
084            ConfigurationService kualiConfigurationService = SpringContext.getBean(ConfigurationService.class);
085
086            try {
087
088                Collection<Proposal> proposals = proposalDao.getProposalsToClose(max);
089                Long proposalCloseCount = new Long(proposals.size());
090                for (Proposal p : proposals) {
091                    p.setProposalClosingDate(today);
092                    businessObjectService.save(p);
093                }
094
095                Collection<Award> awards = awardDao.getAwardsToClose(max);
096                Long awardCloseCount = new Long(awards.size());
097                for (Award a : awards) {
098                    a.setAwardClosingDate(today);
099                    businessObjectService.save(a);
100                }
101
102                max.setAwardClosedCount(awardCloseCount);
103                max.setProposalClosedCount(proposalCloseCount);
104
105                businessObjectService.save(max);
106                noteText = kualiConfigurationService.getPropertyValueAsString(CGKeyConstants.MESSAGE_CLOSE_JOB_SUCCEEDED);
107
108            }
109            catch (Exception e) {
110                String messageProperty = kualiConfigurationService.getPropertyValueAsString(CGKeyConstants.ERROR_CLOSE_JOB_FAILED);
111                noteText = MessageFormat.format(messageProperty, e.getMessage(), e.getCause().getMessage());
112            }
113            finally {
114                result = this.addDocumentNoteAfterClosing(max, noteText);
115            }
116        }
117        return result;
118    }
119
120    /**
121     * @see org.kuali.ole.module.cg.service.CloseService#getMostRecentClose()
122     */
123    @Override
124    public ProposalAwardCloseDocument getMostRecentClose() {
125        Date today = dateTimeService.getCurrentSqlDateMidnight();
126        String documentNumber = closeDao.getMostRecentClose(today);
127        if (StringUtils.isNotBlank(documentNumber)) {
128            try {
129                return (ProposalAwardCloseDocument) documentService.getByDocumentHeaderId(documentNumber);
130            }
131            catch (WorkflowException we) {
132                throw new RuntimeException(we);
133            }
134        }
135        else {
136            return null;
137        }
138
139    }
140
141    /**
142     * @see org.kuali.ole.module.cg.service.CloseService#addDocumentNoteAfterClosing(String)
143     */
144    protected boolean addDocumentNoteAfterClosing(ProposalAwardCloseDocument close, String noteText) {
145        DocumentService service = SpringContext.getBean(DocumentService.class);
146        try {
147            service.createNoteFromDocument(close, noteText);
148            service.approveDocument(close, noteText, null);
149        }
150        catch (WorkflowException we) {
151            we.printStackTrace();
152            return false;
153        }
154        return true;
155    }
156
157    /**
158     * @see org.kuali.ole.module.cg.service.CloseService#getMaxApprovedClose(java.sql.Date)
159     */
160    @Override
161    public ProposalAwardCloseDocument getMaxApprovedClose(Date today) {
162        String documentNumber = closeDao.getMaxApprovedClose(today);
163        if (StringUtils.isNotBlank(documentNumber)) {
164
165            try {
166                return (ProposalAwardCloseDocument) documentService.getByDocumentHeaderId(documentNumber);
167            }
168            catch (WorkflowException we) {
169                throw new RuntimeException(we);
170            }
171        }
172        else {
173            return null;
174        }
175    }
176
177    public void setAwardDao(AwardDao awardDao) {
178        this.awardDao = awardDao;
179    }
180
181    public void setDateTimeService(DateTimeService dateTimeService) {
182        this.dateTimeService = dateTimeService;
183    }
184
185    public void setCloseDao(CloseDao closeDao) {
186        this.closeDao = closeDao;
187    }
188
189    public void setProposalDao(ProposalDao proposalDao) {
190        this.proposalDao = proposalDao;
191    }
192
193    public void setBusinessObjectService(BusinessObjectService businessObjectService) {
194        this.businessObjectService = businessObjectService;
195    }
196
197    public void setDocumentService(DocumentService documentService) {
198        this.documentService = documentService;
199    }
200}