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.service.KRADServiceLocatorWeb;
39  import org.kuali.rice.krad.util.GlobalVariables;
40  
41  /**
42   * This class is a OLE specific TransactionalDocumentBase class
43   */
44  public class FinancialSystemTransactionalDocumentBase extends TransactionalDocumentBase implements FinancialSystemTransactionalDocument {
45      private static final Logger LOG = Logger.getLogger(FinancialSystemTransactionalDocumentBase.class);
46  
47      protected static final String UPDATE_TOTAL_AMOUNT_IN_POST_PROCESSING_PARAMETER_NAME = "UPDATE_TOTAL_AMOUNT_IN_POST_PROCESSING_IND";
48  
49      private static transient BusinessObjectService businessObjectService;
50      private static transient FinancialSystemDocumentService financialSystemDocumentService;
51      private static transient ParameterService parameterService;
52      private FinancialSystemDocumentHeader financialSystemDocumentHeader = new FinancialSystemDocumentHeader();
53  
54      private transient Map<String,Boolean> canEditCache;
55  
56      /**
57       * Constructs a FinancialSystemTransactionalDocumentBase.java.
58       */
59      public FinancialSystemTransactionalDocumentBase() {
60          super();
61      }
62  
63      @Override
64      public FinancialSystemDocumentHeader getFinancialSystemDocumentHeader() {
65  /*        if (financialSystemDocumentHeader == null) {
66              financialSystemDocumentHeader = SpringContext.getBean(FinancialSystemDocumentHeader.class);
67          }*/
68          return this.financialSystemDocumentHeader;
69      }
70  
71      public void setFinancialSystemDocumentHeader(FinancialSystemDocumentHeader financialSystemDocumentHeader) {
72  
73          this.financialSystemDocumentHeader = financialSystemDocumentHeader;
74  
75      }
76  /**
77       * @see org.kuali.rice.krad.document.DocumentBase#setDocumentHeader(org.kuali.rice.krad.bo.DocumentHeader)
78       */
79      @Override
80      public void setDocumentHeader(DocumentHeader documentHeader) {
81          super.setDocumentHeader(documentHeader);
82          getFinancialSystemDocumentHeader().setDocumentNumber(documentHeader.getDocumentNumber());
83      }
84  /*    public void setDocumentHeader(FinancialSystemDocumentHeader documentHeader) {
85          if ((documentHeader != null) && (!FinancialSystemDocumentHeader.class.isAssignableFrom(documentHeader.getClass()))) {
86              throw new IllegalArgumentException("document header of class '" + documentHeader.getClass() + "' is not assignable from financial document header class '" + FinancialSystemDocumentHeader.class + "'");
87          }
88          //this.documentHeader = documentHeader;
89      }*/
90      /**
91       * If the document has a total amount, call method on document to get the total and set in doc header.
92       *
93       * @see org.kuali.rice.krad.document.Document#prepareForSave()
94       */
95      @Override
96      public void prepareForSave() {
97          if (this instanceof AmountTotaling) {
98              getFinancialSystemDocumentHeader().setFinancialDocumentTotalAmount(((AmountTotaling) this).getTotalDollarAmount());
99          }
100         super.prepareForSave();
101     }
102 
103     /**
104      * This is the default implementation which ensures that document note attachment references are loaded.
105      *
106      * @see org.kuali.rice.krad.document.Document#processAfterRetrieve()
107      */
108     @Override
109     public void processAfterRetrieve() {
110         // set correctedByDocumentId manually, since OJB doesn't maintain that relationship
111         try {
112             DocumentHeader correctingDocumentHeader = KRADServiceLocatorWeb.getDocumentHeaderService().getDocumentHeaderById(getDocumentHeader().getWorkflowDocument().getDocumentId());
113             //DocumentHeader correctingDocumentHeader = SpringContext.getBean(FinancialSystemDocumentHeaderDao.class).getCorrectingDocumentHeader(getFinancialSystemDocumentHeader().getDocumentNumber());
114             if (correctingDocumentHeader != null) {
115                 getFinancialSystemDocumentHeader().setCorrectedByDocumentId(correctingDocumentHeader.getDocumentNumber());
116             }
117         } catch (Exception e) {
118             LOG.error("Received WorkflowException trying to get route header id from workflow document.", e);
119             throw new WorkflowRuntimeException(e);
120         }
121         // set the ad hoc route recipients too, since OJB doesn't maintain that relationship
122         // TODO - see KULNRVSYS-1054
123 
124         super.processAfterRetrieve();
125     }
126 
127     /**
128      * This is the default implementation which checks for a different workflow statuses, and updates the Kuali status accordingly.
129      *
130      * @see org.kuali.rice.krad.document.Document# doRouteStatusChange()
131      */
132     @Override
133     public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) {
134         if (getDocumentHeader().getWorkflowDocument().isCanceled()) {
135             getFinancialSystemDocumentHeader().setFinancialDocumentStatusCode(OLEConstants.DocumentStatusCodes.CANCELLED);
136         }
137         else if (getDocumentHeader().getWorkflowDocument().isEnroute()) {
138             getFinancialSystemDocumentHeader().setFinancialDocumentStatusCode(OLEConstants.DocumentStatusCodes.ENROUTE);
139         }
140         if (getDocumentHeader().getWorkflowDocument().isDisapproved()) {
141             getFinancialSystemDocumentHeader().setFinancialDocumentStatusCode(OLEConstants.DocumentStatusCodes.DISAPPROVED);
142         }
143         if (getDocumentHeader().getWorkflowDocument().isProcessed()) {
144             getFinancialSystemDocumentHeader().setFinancialDocumentStatusCode(OLEConstants.DocumentStatusCodes.APPROVED);
145         }
146         if ( LOG.isInfoEnabled() ) {
147             LOG.info("Document: " + statusChangeEvent.getDocumentId() + " -- Status is: " + getFinancialSystemDocumentHeader().getFinancialDocumentStatusCode());
148         }
149 
150         super.doRouteStatusChange(statusChangeEvent);
151     }
152 
153     /**
154      * This is the default implementation which, if parameter KFS-SYS / Document / UPDATE_TOTAL_AMOUNT_IN_POST_PROCESSING_IND is on, updates the document
155      * and resaves if needed
156      * @see org.kuali.rice.kns.document.DocumentBase#doRouteLevelChange(org.kuali.rice.kew.dto.DocumentRouteLevelChangeDTO)
157      */
158     @Override
159     public void doRouteLevelChange(DocumentRouteLevelChange levelChangeEvent) {
160         if (this instanceof AmountTotaling
161                 && getDocumentHeader() != null
162                 && getParameterService() != null
163                 && getBusinessObjectService() != null
164                 && getParameterService().parameterExists(OleParameterConstants.FINANCIAL_SYSTEM_DOCUMENT.class, UPDATE_TOTAL_AMOUNT_IN_POST_PROCESSING_PARAMETER_NAME)
165                 && getParameterService().getParameterValueAsBoolean(OleParameterConstants.FINANCIAL_SYSTEM_DOCUMENT.class, UPDATE_TOTAL_AMOUNT_IN_POST_PROCESSING_PARAMETER_NAME)) {
166             final KualiDecimal currentTotal = ((AmountTotaling)this).getTotalDollarAmount();
167             if (!currentTotal.equals(getFinancialSystemDocumentHeader().getFinancialDocumentTotalAmount())) {
168                 getFinancialSystemDocumentHeader().setFinancialDocumentTotalAmount(currentTotal);
169                 KRADServiceLocatorWeb.getLegacyDataAdapter().save(getFinancialSystemDocumentHeader());
170             }
171         }
172         super.doRouteLevelChange(levelChangeEvent);
173     }
174 
175     /**
176      * @see org.kuali.ole.sys.document.Correctable#toErrorCorrection()
177      */
178     public void toErrorCorrection() throws WorkflowException, IllegalStateException {
179         DocumentHelperService documentHelperService = SpringContext.getBean(DocumentHelperService.class);
180         final Set<String> documentActionsFromPresentationController = documentHelperService.getDocumentPresentationController(this).getDocumentActions(this);
181         final Set<String> documentActionsFromAuthorizer = documentHelperService.getDocumentAuthorizer(this).getDocumentActions(this, GlobalVariables.getUserSession().getPerson(), documentActionsFromPresentationController);
182         if (!documentActionsFromAuthorizer.contains(OLEConstants.KFS_ACTION_CAN_ERROR_CORRECT)) {
183             throw new IllegalStateException(this.getClass().getName() + " does not support document-level error correction");
184         }
185 
186         String sourceDocumentHeaderId = getDocumentNumber();
187         setNewDocumentHeader();
188         getFinancialSystemDocumentHeader().setFinancialDocumentInErrorNumber(sourceDocumentHeaderId);
189         addCopyErrorDocumentNote("error-correction for document " + sourceDocumentHeaderId);
190     }
191 
192     @Override
193     public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException {
194         throw new UnsupportedOperationException("No split node logic defined for split node "+nodeName+" on " + this.getClass().getSimpleName());
195     }
196 
197     /**
198      * @return the default implementation of the ParameterService
199      */
200     protected ParameterService getParameterService() {
201        if (parameterService == null) {
202            parameterService = SpringContext.getBean(ParameterService.class);
203        }
204        return parameterService;
205     }
206 
207     /**
208      * @return the default implementation of the BusinessObjectService
209      */
210     protected BusinessObjectService getBusinessObjectService() {
211         if (businessObjectService == null) {
212             businessObjectService = SpringContext.getBean(BusinessObjectService.class);
213         }
214         return businessObjectService;
215     }
216 
217     protected FinancialSystemDocumentService getFinancialSystemDocumentService() {
218         if (financialSystemDocumentService == null) {
219             financialSystemDocumentService = SpringContext.getBean(FinancialSystemDocumentService.class);
220         }
221         return financialSystemDocumentService;
222     }
223 
224     @Override
225     public void toCopy() throws WorkflowException, IllegalStateException {
226         FinancialSystemDocumentHeader oldDocumentHeader = getFinancialSystemDocumentHeader();
227         super.toCopy();
228 
229         getFinancialSystemDocumentService().prepareToCopy(oldDocumentHeader, this);
230     }
231 
232     /**
233      * Updates status of this document and saves the workflow data
234      *
235      * @param applicationDocumentStatus is the app doc status to save
236      * @throws WorkflowException
237      */
238     public void updateAndSaveAppDocStatus(String applicationDocumentStatus) throws WorkflowException {
239         getFinancialSystemDocumentHeader().updateAndSaveAppDocStatus(applicationDocumentStatus);
240     }
241 
242     /**
243      * Gets the applicationDocumentStatus attribute.
244      *
245      * @return Returns the applicationDocumentStatus
246      */
247 
248     public String getApplicationDocumentStatus() {
249         return getFinancialSystemDocumentHeader().getApplicationDocumentStatus();
250     }
251 
252     /**
253      * Sets the applicationDocumentStatus attribute.
254      *
255      * @param applicationDocumentStatus The applicationDocumentStatus to set.
256      */
257     /**
258      *
259      * @param applicationDocumentStatus
260      */
261     public void setApplicationDocumentStatus(String applicationDocumentStatus) {
262         getFinancialSystemDocumentHeader().setApplicationDocumentStatus(applicationDocumentStatus);
263     }
264 }