View Javadoc
1   /*
2    * Copyright 2008 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.sys.document;
17  
18  import java.util.Map;
19  import java.util.Set;
20  
21  import org.apache.log4j.Logger;
22  import org.kuali.ole.sys.OLEConstants;
23  import org.kuali.ole.sys.businessobject.FinancialSystemDocumentHeader;
24  import org.kuali.ole.sys.context.SpringContext;
25  import org.kuali.ole.sys.document.dataaccess.FinancialSystemDocumentHeaderDao;
26  import org.kuali.ole.sys.document.service.FinancialSystemDocumentService;
27  import org.kuali.ole.sys.service.impl.OleParameterConstants;
28  import org.kuali.rice.core.api.util.type.KualiDecimal;
29  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
30  import org.kuali.rice.kew.api.WorkflowRuntimeException;
31  import org.kuali.rice.kew.api.exception.WorkflowException;
32  import org.kuali.rice.kew.framework.postprocessor.DocumentRouteLevelChange;
33  import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
34  import org.kuali.rice.kns.service.DocumentHelperService;
35  import org.kuali.rice.krad.bo.DocumentHeader;
36  import org.kuali.rice.krad.document.TransactionalDocumentBase;
37  import org.kuali.rice.krad.service.BusinessObjectService;
38  import org.kuali.rice.krad.util.GlobalVariables;
39  
40  /**
41   * This class is a OLE specific TransactionalDocumentBase class
42   */
43  public class FinancialSystemTransactionalDocumentBase extends TransactionalDocumentBase implements FinancialSystemTransactionalDocument {
44      private static final Logger LOG = Logger.getLogger(FinancialSystemTransactionalDocumentBase.class);
45  
46      protected static final String UPDATE_TOTAL_AMOUNT_IN_POST_PROCESSING_PARAMETER_NAME = "UPDATE_TOTAL_AMOUNT_IN_POST_PROCESSING_IND";
47  
48      private static transient BusinessObjectService businessObjectService;
49      private static transient FinancialSystemDocumentService financialSystemDocumentService;
50      private static transient ParameterService parameterService;
51  
52      private transient Map<String,Boolean> canEditCache;
53  
54      /**
55       * Constructs a FinancialSystemTransactionalDocumentBase.java.
56       */
57      public FinancialSystemTransactionalDocumentBase() {
58          super();
59      }
60  
61      @Override
62      public FinancialSystemDocumentHeader getFinancialSystemDocumentHeader() {
63          return (FinancialSystemDocumentHeader) documentHeader;
64      }
65  
66      /**
67       * @see org.kuali.rice.krad.document.DocumentBase#setDocumentHeader(org.kuali.rice.krad.bo.DocumentHeader)
68       */
69      @Override
70      public void setDocumentHeader(DocumentHeader documentHeader) {
71          if ((documentHeader != null) && (!FinancialSystemDocumentHeader.class.isAssignableFrom(documentHeader.getClass()))) {
72              throw new IllegalArgumentException("document header of class '" + documentHeader.getClass() + "' is not assignable from financial document header class '" + FinancialSystemDocumentHeader.class + "'");
73          }
74          this.documentHeader = documentHeader;
75      }
76  
77      /**
78       * If the document has a total amount, call method on document to get the total and set in doc header.
79       *
80       * @see org.kuali.rice.krad.document.Document#prepareForSave()
81       */
82      @Override
83      public void prepareForSave() {
84          if (this instanceof AmountTotaling) {
85              getFinancialSystemDocumentHeader().setFinancialDocumentTotalAmount(((AmountTotaling) this).getTotalDollarAmount());
86          }
87          super.prepareForSave();
88      }
89  
90      /**
91       * This is the default implementation which ensures that document note attachment references are loaded.
92       *
93       * @see org.kuali.rice.krad.document.Document#processAfterRetrieve()
94       */
95      @Override
96      public void processAfterRetrieve() {
97          // set correctedByDocumentId manually, since OJB doesn't maintain that relationship
98          try {
99              DocumentHeader correctingDocumentHeader = SpringContext.getBean(FinancialSystemDocumentHeaderDao.class).getCorrectingDocumentHeader(getFinancialSystemDocumentHeader().getDocumentNumber());
100             if (correctingDocumentHeader != null) {
101                 getFinancialSystemDocumentHeader().setCorrectedByDocumentId(correctingDocumentHeader.getDocumentNumber());
102             }
103         } catch (Exception e) {
104             LOG.error("Received WorkflowException trying to get route header id from workflow document.", e);
105             throw new WorkflowRuntimeException(e);
106         }
107         // set the ad hoc route recipients too, since OJB doesn't maintain that relationship
108         // TODO - see KULNRVSYS-1054
109 
110         super.processAfterRetrieve();
111     }
112 
113     /**
114      * This is the default implementation which checks for a different workflow statuses, and updates the Kuali status accordingly.
115      *
116      * @see org.kuali.rice.krad.document.Document#doRouteStatusChange()
117      */
118     @Override
119     public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) {
120         if (getDocumentHeader().getWorkflowDocument().isCanceled()) {
121             getFinancialSystemDocumentHeader().setFinancialDocumentStatusCode(OLEConstants.DocumentStatusCodes.CANCELLED);
122         }
123         else if (getDocumentHeader().getWorkflowDocument().isEnroute()) {
124             getFinancialSystemDocumentHeader().setFinancialDocumentStatusCode(OLEConstants.DocumentStatusCodes.ENROUTE);
125         }
126         if (getDocumentHeader().getWorkflowDocument().isDisapproved()) {
127             getFinancialSystemDocumentHeader().setFinancialDocumentStatusCode(OLEConstants.DocumentStatusCodes.DISAPPROVED);
128         }
129         if (getDocumentHeader().getWorkflowDocument().isProcessed()) {
130             getFinancialSystemDocumentHeader().setFinancialDocumentStatusCode(OLEConstants.DocumentStatusCodes.APPROVED);
131         }
132         if ( LOG.isInfoEnabled() ) {
133             LOG.info("Document: " + statusChangeEvent.getDocumentId() + " -- Status is: " + getFinancialSystemDocumentHeader().getFinancialDocumentStatusCode());
134         }
135 
136         super.doRouteStatusChange(statusChangeEvent);
137     }
138 
139     /**
140      * This is the default implementation which, if parameter KFS-SYS / Document / UPDATE_TOTAL_AMOUNT_IN_POST_PROCESSING_IND is on, updates the document
141      * and resaves if needed
142      * @see org.kuali.rice.kns.document.DocumentBase#doRouteLevelChange(org.kuali.rice.kew.dto.DocumentRouteLevelChangeDTO)
143      */
144     @Override
145     public void doRouteLevelChange(DocumentRouteLevelChange levelChangeEvent) {
146         if (this instanceof AmountTotaling
147                 && getDocumentHeader() != null
148                 && getParameterService() != null
149                 && getBusinessObjectService() != null
150                 && getParameterService().parameterExists(OleParameterConstants.FINANCIAL_SYSTEM_DOCUMENT.class, UPDATE_TOTAL_AMOUNT_IN_POST_PROCESSING_PARAMETER_NAME)
151                 && getParameterService().getParameterValueAsBoolean(OleParameterConstants.FINANCIAL_SYSTEM_DOCUMENT.class, UPDATE_TOTAL_AMOUNT_IN_POST_PROCESSING_PARAMETER_NAME)) {
152             final KualiDecimal currentTotal = ((AmountTotaling)this).getTotalDollarAmount();
153             if (!currentTotal.equals(getFinancialSystemDocumentHeader().getFinancialDocumentTotalAmount())) {
154                 getFinancialSystemDocumentHeader().setFinancialDocumentTotalAmount(currentTotal);
155                 getBusinessObjectService().save(getFinancialSystemDocumentHeader());
156             }
157         }
158         super.doRouteLevelChange(levelChangeEvent);
159     }
160 
161     /**
162      * @see org.kuali.ole.sys.document.Correctable#toErrorCorrection()
163      */
164     public void toErrorCorrection() throws WorkflowException, IllegalStateException {
165         DocumentHelperService documentHelperService = SpringContext.getBean(DocumentHelperService.class);
166         final Set<String> documentActionsFromPresentationController = documentHelperService.getDocumentPresentationController(this).getDocumentActions(this);
167         final Set<String> documentActionsFromAuthorizer = documentHelperService.getDocumentAuthorizer(this).getDocumentActions(this, GlobalVariables.getUserSession().getPerson(), documentActionsFromPresentationController);
168         if (!documentActionsFromAuthorizer.contains(OLEConstants.KFS_ACTION_CAN_ERROR_CORRECT)) {
169             throw new IllegalStateException(this.getClass().getName() + " does not support document-level error correction");
170         }
171 
172         String sourceDocumentHeaderId = getDocumentNumber();
173         setNewDocumentHeader();
174         getFinancialSystemDocumentHeader().setFinancialDocumentInErrorNumber(sourceDocumentHeaderId);
175         addCopyErrorDocumentNote("error-correction for document " + sourceDocumentHeaderId);
176     }
177 
178     @Override
179     public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException {
180         throw new UnsupportedOperationException("No split node logic defined for split node "+nodeName+" on " + this.getClass().getSimpleName());
181     }
182 
183     /**
184      * @return the default implementation of the ParameterService
185      */
186     protected ParameterService getParameterService() {
187        if (parameterService == null) {
188            parameterService = SpringContext.getBean(ParameterService.class);
189        }
190        return parameterService;
191     }
192 
193     /**
194      * @return the default implementation of the BusinessObjectService
195      */
196     protected BusinessObjectService getBusinessObjectService() {
197         if (businessObjectService == null) {
198             businessObjectService = SpringContext.getBean(BusinessObjectService.class);
199         }
200         return businessObjectService;
201     }
202 
203     protected FinancialSystemDocumentService getFinancialSystemDocumentService() {
204         if (financialSystemDocumentService == null) {
205             financialSystemDocumentService = SpringContext.getBean(FinancialSystemDocumentService.class);
206         }
207         return financialSystemDocumentService;
208     }
209 
210     @Override
211     public void toCopy() throws WorkflowException, IllegalStateException {
212         FinancialSystemDocumentHeader oldDocumentHeader = getFinancialSystemDocumentHeader();
213         super.toCopy();
214 
215         getFinancialSystemDocumentService().prepareToCopy(oldDocumentHeader, this);
216     }
217 
218     /**
219      * Updates status of this document and saves the workflow data
220      *
221      * @param applicationDocumentStatus is the app doc status to save
222      * @throws WorkflowException
223      */
224     public void updateAndSaveAppDocStatus(String applicationDocumentStatus) throws WorkflowException {
225         getFinancialSystemDocumentHeader().updateAndSaveAppDocStatus(applicationDocumentStatus);
226     }
227 
228     /**
229      * Gets the applicationDocumentStatus attribute.
230      *
231      * @return Returns the applicationDocumentStatus
232      */
233 
234     public String getApplicationDocumentStatus() {
235         return getFinancialSystemDocumentHeader().getApplicationDocumentStatus();
236     }
237 
238     /**
239      * Sets the applicationDocumentStatus attribute.
240      *
241      * @param applicationDocumentStatus The applicationDocumentStatus to set.
242      */
243     public void setApplicationDocumentStatus(String applicationDocumentStatus) {
244         getFinancialSystemDocumentHeader().setApplicationDocumentStatus(applicationDocumentStatus);
245     }
246 }