001    /*
002     * Copyright 2011 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     */
016    package org.kuali.kfs.sys.document;
017    
018    import org.apache.log4j.Logger;
019    import org.kuali.kfs.sys.KFSConstants;
020    import org.kuali.kfs.sys.businessobject.FinancialSystemDocumentHeader;
021    import org.kuali.kfs.sys.context.SpringContext;
022    import org.kuali.kfs.sys.document.dataaccess.FinancialSystemDocumentHeaderDao;
023    import org.kuali.rice.kew.dto.DocumentRouteStatusChangeDTO;
024    import org.kuali.rice.kew.exception.WorkflowException;
025    import org.kuali.rice.kew.exception.WorkflowRuntimeException;
026    import org.kuali.rice.kim.bo.Person;
027    import org.kuali.rice.kim.service.PersonService;
028    import org.kuali.rice.kns.bo.DocumentHeader;
029    import org.kuali.rice.kns.document.MaintenanceDocumentBase;
030    import org.kuali.rice.kns.service.DateTimeService;
031    
032    /**
033     * This class is used by the system to use financial specific objects and data for maintenance documents
034     */
035    public class FinancialSystemMaintenanceDocument extends MaintenanceDocumentBase {
036        protected static final Logger LOG = Logger.getLogger(FinancialSystemMaintenanceDocument.class);
037    
038        protected FinancialSystemDocumentHeader documentHeader;
039    
040        /**
041         * Constructs a FinancialSystemMaintenanceDocument.java.
042         */
043        public FinancialSystemMaintenanceDocument() {
044            super();
045        }
046    
047        /**
048         * Constructs a FinancialSystemMaintenanceDocument.java.
049         * @param documentTypeName
050         */
051        public FinancialSystemMaintenanceDocument(String documentTypeName) {
052            super(documentTypeName);
053        }
054    
055        /**
056         * @see org.kuali.rice.kns.document.DocumentBase#getDocumentHeader()
057         */
058        @Override
059        public FinancialSystemDocumentHeader getDocumentHeader() {
060            return documentHeader;
061        }
062    
063        /**
064         * @see org.kuali.rice.kns.document.DocumentBase#setDocumentHeader(org.kuali.rice.kns.bo.DocumentHeader)
065         */
066        @Override
067        public void setDocumentHeader(DocumentHeader documentHeader) {
068            if ((documentHeader != null) && (!FinancialSystemDocumentHeader.class.isAssignableFrom(documentHeader.getClass()))) {
069                throw new IllegalArgumentException("document header of class '" + documentHeader.getClass() + "' is not assignable from financial document header class '" + FinancialSystemDocumentHeader.class + "'");
070            }
071            this.documentHeader = (FinancialSystemDocumentHeader) documentHeader;
072        }
073    
074        /**
075         * If the document has a total amount, call method on document to get the total and set in doc header.
076         * 
077         * @see org.kuali.rice.kns.document.Document#prepareForSave()
078         */
079    //    @Override
080    //    public void prepareForSave() {
081    //        if (this instanceof AmountTotaling) {
082    //            getDocumentHeader().setFinancialDocumentTotalAmount(((AmountTotaling) this).getTotalDollarAmount());
083    //        }
084    //    }
085    
086        /**
087         * This is the default implementation which ensures that document note attachment references are loaded.
088         * 
089         * @see org.kuali.rice.kns.document.Document#processAfterRetrieve()
090         */
091        @Override
092        public void processAfterRetrieve() {
093            // set correctedByDocumentId manually, since OJB doesn't maintain that relationship
094            try {
095                DocumentHeader correctingDocumentHeader = SpringContext.getBean(FinancialSystemDocumentHeaderDao.class).getCorrectingDocumentHeader(getDocumentHeader().getWorkflowDocument().getRouteHeaderId().toString());
096                if (correctingDocumentHeader != null) {
097                    getDocumentHeader().setCorrectedByDocumentId(correctingDocumentHeader.getDocumentNumber());
098                }
099            } catch (WorkflowException e) {
100                LOG.error("Received WorkflowException trying to get route header id from workflow document");
101                throw new WorkflowRuntimeException(e);
102            }
103            // set the ad hoc route recipients too, since OJB doesn't maintain that relationship
104            // TODO - see KULNRVSYS-1054
105    
106            super.processAfterRetrieve();
107        }
108    
109        /**
110         * This is the default implementation which checks for a different workflow statuses, and updates the Kuali status accordingly.
111         * 
112         * @see org.kuali.rice.kns.document.Document#doRouteStatusChange()
113         */
114        @Override
115        public void doRouteStatusChange(DocumentRouteStatusChangeDTO statusChangeEvent) {
116            if (getDocumentHeader().getWorkflowDocument().stateIsCanceled()) {
117                getDocumentHeader().setFinancialDocumentStatusCode(KFSConstants.DocumentStatusCodes.CANCELLED);
118            }
119            else if (getDocumentHeader().getWorkflowDocument().stateIsEnroute()) {
120                getDocumentHeader().setFinancialDocumentStatusCode(KFSConstants.DocumentStatusCodes.ENROUTE);
121            }
122            if (getDocumentHeader().getWorkflowDocument().stateIsDisapproved()) {
123                getDocumentHeader().setFinancialDocumentStatusCode(KFSConstants.DocumentStatusCodes.DISAPPROVED);
124            }
125            if (getDocumentHeader().getWorkflowDocument().stateIsProcessed()) {
126                getDocumentHeader().setFinancialDocumentStatusCode(KFSConstants.DocumentStatusCodes.APPROVED);
127            }
128            LOG.info("Status is: " + getDocumentHeader().getFinancialDocumentStatusCode());
129            
130            super.doRouteStatusChange(statusChangeEvent);
131        }
132        
133        public boolean answerSplitNodeQuestion(String nodeName) {
134            if (getNewMaintainableObject() instanceof FinancialSystemMaintainable) {
135                FinancialSystemMaintainable fsMaintainable = (FinancialSystemMaintainable)getNewMaintainableObject();
136    
137                if (fsMaintainable == null) {
138                    throw new UnsupportedOperationException("Cannot access Maintainable class to answer split node question");
139                }
140                return fsMaintainable.answerSplitNodeQuestion(nodeName);
141            } else if (getNewMaintainableObject() instanceof FinancialSystemGlobalMaintainable) {
142                FinancialSystemGlobalMaintainable fsMaintainable = (FinancialSystemGlobalMaintainable)getNewMaintainableObject();
143    
144                if (fsMaintainable == null) {
145                    throw new UnsupportedOperationException("Cannot access Maintainable class to answer split node question");
146                }
147                return fsMaintainable.answerSplitNodeQuestion(nodeName);
148            } else {
149                throw new UnsupportedOperationException("Maintainable for "+getNewMaintainableObject().getBoClass().getName()+" does not extend org.kuali.kfs.sys.document.FinancialSystemMaintainable nor org.kuali.kfs.sys.document.FinancialSystemGlobalMaintainable and therefore cannot answer split node question");
150            }
151        }
152        
153        /**
154         * This method is used for routing and simply returns the initiator's Chart code.
155         * @return The Chart code of the document initiator
156         */
157        public String getInitiatorChartOfAccountsCode() {
158            String[] chartOrg = getInitiatorPrimaryDepartmentCode();
159            return chartOrg[0];
160        }
161        
162        /**
163         * This method is used for routing and simply returns the initiator's Organization code.
164         * @return The Organization code of the document initiator
165         */
166        public String getInitiatorOrganizationCode() {
167            String[] chartOrg = getInitiatorPrimaryDepartmentCode();
168            return chartOrg[1];
169        }
170        
171        /**
172         * 
173         * This method is a utility method that returns a String array containing the document initiator's
174         * ChartCode in the first index and the OrganizationCode in the second.
175         * @return a String array.
176         */
177        protected String[] getInitiatorPrimaryDepartmentCode() {
178            PersonService personService = SpringContext.getBean(PersonService.class);
179            
180            String netID = documentHeader.getWorkflowDocument().getInitiatorNetworkId();
181            Person person =  personService.getPersonByPrincipalName(netID);
182           
183            String deptCode = person.getPrimaryDepartmentCode();
184            String[] chartOrg = deptCode.split("-");
185            return chartOrg;
186            
187        }
188        
189    }
190