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.module.endow.document;
017    
018    import java.math.BigDecimal;
019    import java.sql.Date;
020    import java.util.Map;
021    
022    import org.apache.commons.lang.ObjectUtils;
023    import org.kuali.kfs.module.endow.EndowConstants;
024    import org.kuali.kfs.module.endow.businessobject.Security;
025    import org.kuali.kfs.module.endow.document.service.KEMService;
026    import org.kuali.kfs.module.endow.util.KEMCalculationRoundingHelper;
027    import org.kuali.kfs.sys.KFSConstants;
028    import org.kuali.kfs.sys.context.SpringContext;
029    import org.kuali.kfs.sys.document.FinancialSystemMaintenanceDocument;
030    import org.kuali.rice.kew.exception.WorkflowException;
031    import org.kuali.rice.kim.bo.Person;
032    import org.kuali.rice.kns.bo.DocumentHeader;
033    import org.kuali.rice.kns.document.MaintenanceDocument;
034    import org.kuali.rice.kns.maintenance.KualiMaintainableImpl;
035    import org.kuali.rice.kns.service.DocumentService;
036    import org.kuali.rice.kns.util.GlobalVariables;
037    import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument;
038    import org.springframework.util.StringUtils;
039    
040    public class SecurityMaintainableImpl extends KualiMaintainableImpl {
041    
042        private Security oldSecurity;
043        private Security newSecurity;
044    
045        /**
046         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#doRouteStatusChange(org.kuali.rice.kns.bo.DocumentHeader)
047         */
048        @Override
049        public void doRouteStatusChange(DocumentHeader documentHeader) {
050            super.doRouteStatusChange(documentHeader);
051    
052            KualiWorkflowDocument workflowDoc = documentHeader.getWorkflowDocument();
053            DocumentService documentService = SpringContext.getBean(DocumentService.class);
054            FinancialSystemMaintenanceDocument maintDoc = null;
055    
056            try {
057                maintDoc = (FinancialSystemMaintenanceDocument) documentService.getByDocumentHeaderId(this.documentNumber);
058            }
059            catch (WorkflowException e) {
060                throw new RuntimeException(e);
061            }
062    
063            initializeAttributes(maintDoc);
064    
065            // This code is only executed when the final approval occurs
066            if (workflowDoc.stateIsProcessed()) {
067    
068                // if user changed unit price, copy old unit price in previous unit value
069                if (!ObjectUtils.equals(newSecurity.getUnitValue(), oldSecurity.getUnitValue())) {
070    
071                    newSecurity.setPreviousUnitValue(oldSecurity.getUnitValue());
072    
073                    // the unit value source is populated with the name of the individual that initiated the change
074                    Person currentUser = GlobalVariables.getUserSession().getPerson();
075                    newSecurity.setUnitValueSource(currentUser.getName());
076                }
077    
078                // if unit value date is changed copy old unit value in previous unit value
079                if (!ObjectUtils.equals(newSecurity.getValuationDate(), oldSecurity.getValuationDate())) {
080    
081                    newSecurity.setPreviousUnitValueDate(oldSecurity.getValuationDate());
082                }
083    
084                // when dividend amount is changed take the new value times 4 and apply to income rate
085                if (!ObjectUtils.equals(newSecurity.getDividendAmount(), oldSecurity.getDividendAmount())) {
086                    if (newSecurity.getDividendAmount() == null) {
087                        newSecurity.setIncomeRate(null);
088                    }
089                    else {
090                        // ensure calculation rounding rules
091                        BigDecimal newIncomeRate = KEMCalculationRoundingHelper.multiply(newSecurity.getDividendAmount(), new BigDecimal(4), EndowConstants.Scale.SECURITY_INCOME_RATE);
092                        newSecurity.setIncomeRate(newIncomeRate);
093                    }
094                    // set the last income change date to the current process date
095                    KEMService kemService = SpringContext.getBean(KEMService.class);
096                    Date currentDate = kemService.getCurrentDate();
097                    newSecurity.setIncomeChangeDate(currentDate);
098    
099                }
100                
101                //KFSMI-6674
102                //If SEC_INC_PAY_FREQ entered then the SEC_INC_NEXT_PAY_DT is 
103                //automatically calculated.
104                //if class code type is stocks and SEC_DIV_PAY_DT is entered then 
105                //copy the date value to SEC_INC_NEXT_PAY_DT. 
106                //We do not want to overwrite the date if it already exists.
107                if (EndowConstants.ClassCodeTypes.STOCKS.equalsIgnoreCase(newSecurity.getClassCode().getClassCodeType())) {
108                    if (newSecurity.getDividendPayDate() != null) {
109                        newSecurity.setIncomeNextPayDate(newSecurity.getDividendPayDate());
110                    }
111                }
112            }
113        }
114    
115        /**
116         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#processAfterCopy(org.kuali.rice.kns.document.MaintenanceDocument,
117         *      java.util.Map)
118         */
119        @Override
120        public void processAfterCopy(MaintenanceDocument arg0, Map<String, String[]> arg1) {
121            super.processAfterCopy(arg0, arg1);
122    
123            initializeAttributes(arg0);
124    
125            // set old userEnteredSecurityIDprefix to the whole security ID so that all 9 digits are displayed on the copy screen
126            oldSecurity.setUserEnteredSecurityIDprefix(oldSecurity.getId());
127    
128            newSecurity.refreshNonUpdateableReferences();
129    
130            // clear fields for copy as we want only certain fields to be copied over
131            newSecurity.setDescription(KFSConstants.EMPTY_STRING);
132            newSecurity.setTickerSymbol(KFSConstants.EMPTY_STRING);
133            newSecurity.setUnitValue(null);
134            newSecurity.setUnitsHeld(null);
135            newSecurity.setValuationDate(null);
136            newSecurity.setUnitValueSource(KFSConstants.EMPTY_STRING);
137            newSecurity.setPreviousUnitValue(null);
138            newSecurity.setPreviousUnitValueDate(null);
139            newSecurity.setCarryValue(null);
140            newSecurity.setMarketValue(null);
141            newSecurity.setSecurityValueByMarket(null);
142            newSecurity.setLastTransactionDate(null);
143            newSecurity.setIncomeNextPayDate(null);
144            // newSecurity.setIncomeRate(null);
145            newSecurity.setIncomeChangeDate(null);
146            newSecurity.setDividendRecordDate(null);
147            newSecurity.setExDividendDate(null);
148            newSecurity.setDividendPayDate(null);
149            newSecurity.setDividendAmount(null);
150            newSecurity.setNextFiscalYearDistributionAmount(null);
151        }
152    
153        /**
154         * Initializes newSecurity and oldSecurity.
155         * 
156         * @param document
157         */
158        private void initializeAttributes(MaintenanceDocument document) {
159            if (newSecurity == null) {
160                newSecurity = (Security) document.getNewMaintainableObject().getBusinessObject();
161            }
162            if (oldSecurity == null) {
163                oldSecurity = (Security) document.getOldMaintainableObject().getBusinessObject();
164            }
165        }
166    
167    }