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.sql.Date;
019    import java.text.ParseException;
020    import java.util.ArrayList;
021    import java.util.Collection;
022    import java.util.HashMap;
023    import java.util.List;
024    import java.util.Map;
025    
026    import org.apache.commons.lang.StringUtils;
027    import org.apache.log4j.Logger;
028    import org.kuali.kfs.module.endow.EndowConstants;
029    import org.kuali.kfs.module.endow.EndowPropertyConstants;
030    import org.kuali.kfs.module.endow.businessobject.Tickler;
031    import org.kuali.kfs.module.endow.businessobject.TicklerKEMID;
032    import org.kuali.kfs.module.endow.businessobject.TicklerRecipientGroup;
033    import org.kuali.kfs.module.endow.businessobject.TicklerRecipientPrincipal;
034    import org.kuali.kfs.module.endow.businessobject.TicklerSecurity;
035    import org.kuali.kfs.module.endow.businessobject.TypeCode;
036    import org.kuali.kfs.module.endow.businessobject.TypeFeeMethod;
037    import org.kuali.kfs.module.endow.businessobject.lookup.CalculateProcessDateUsingFrequencyCodeService;
038    import org.kuali.kfs.module.endow.document.service.FeeMethodService;
039    import org.kuali.kfs.module.endow.document.service.FrequencyCodeService;
040    import org.kuali.kfs.module.endow.document.service.KEMService;
041    import org.kuali.kfs.module.endow.document.validation.impl.TicklerRule;
042    import org.kuali.kfs.sys.KFSConstants;
043    import org.kuali.kfs.sys.context.SpringContext;
044    import org.kuali.rice.kns.bo.PersistableBusinessObject;
045    import org.kuali.rice.kns.document.MaintenanceDocument;
046    import org.kuali.rice.kns.maintenance.KualiMaintainableImpl;
047    import org.kuali.rice.kns.maintenance.Maintainable;
048    import org.kuali.rice.kns.service.BusinessObjectService;
049    import org.kuali.rice.kns.service.DateTimeService;
050    import org.kuali.rice.kns.service.SequenceAccessorService;
051    import org.kuali.rice.kns.util.KNSConstants;
052    import org.kuali.rice.kns.util.KualiDecimal;
053    import org.kuali.rice.kns.util.ObjectUtils;
054    import org.kuali.rice.kns.web.ui.Field;
055    import org.kuali.rice.kns.web.ui.Row;
056    import org.kuali.rice.kns.web.ui.Section;
057    
058    /**
059     * This class implements the hok on points associated with the Tickler.
060     * 
061     * @author Tapan S Mokha
062     * @version 1.0
063     */
064    public class TicklerMaintainableImpl extends KualiMaintainableImpl 
065    {
066    
067        private static Logger log = org.apache.log4j.Logger.getLogger(TicklerMaintainableImpl.class);
068        
069        private Tickler newTickler;
070        private Tickler oldTickler;
071        
072        private transient SequenceAccessorService sequenceAccessorService;
073        
074        /**
075         * Called when page is refreshed and does 
076         * 1. Updates frequency date when frequency code is selected.
077         * 
078         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#refresh(java.lang.String, java.util.Map,
079         *      org.kuali.rice.kns.document.MaintenanceDocument)
080         */
081        @Override
082        public void refresh(String refreshCaller, Map fieldValues, MaintenanceDocument document) 
083        {
084            super.refresh(refreshCaller, fieldValues, document);
085            
086            initializeAttributes(document);
087            
088            //Update Next Due date if frequency Code selected
089            updateNextDueDate(refreshCaller, fieldValues);
090        }
091    
092        /**
093         * Updates Next Due date if frequency Code selected.
094         *     
095         * @param refreshCaller
096         * @param fieldValues
097         */
098        private void updateNextDueDate(String refreshCaller, Map fieldValues) 
099        {
100            if (refreshCaller != null && refreshCaller.equalsIgnoreCase(EndowConstants.KUALI_FREQUENCY_LOOKUPABLE_IMPL) && fieldValues != null) 
101            {
102                String frequencyCode = newTickler.getFrequencyCode();
103                if (StringUtils.isNotEmpty(frequencyCode)) 
104                {
105                    FrequencyCodeService frequencyCodeService = (FrequencyCodeService) SpringContext.getBean(FrequencyCodeService.class);
106                    newTickler.setNextDueDate(frequencyCodeService.calculateProcessDate(frequencyCode));
107                }
108            }
109        }
110    
111        /**
112         * Called after a copy operation is performed and performs.
113         * 1. Clears all associated collections (kemids, security, principals & groups)
114         * 
115         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#processAfterCopy(org.kuali.rice.kns.document.MaintenanceDocument,
116         *      java.util.Map)
117         */
118        @Override
119        public void processAfterCopy(MaintenanceDocument arg0, Map<String, String[]> arg1) {
120            super.processAfterCopy(arg0, arg1);
121    
122            initializeAttributes(arg0);
123    
124            //Clears all associated collections (kemids, security, principals & groups)
125            clearAllCollections();
126            
127        }
128        
129        /**
130         * Clears all associated collections (kemids, security, principals & groups)
131         */
132        private void clearAllCollections()
133        {
134            getOldTickler().getKemIds().clear();
135            getOldTickler().getSecurities().clear();
136            getOldTickler().getRecipientPrincipals().clear();
137            getOldTickler().getRecipientGroups().clear();
138            
139            getNewTickler().getKemIds().clear();
140            getNewTickler().getSecurities().clear();
141            getNewTickler().getRecipientPrincipals().clear();
142            getNewTickler().getRecipientGroups().clear();
143        }
144    
145        /**
146         * Called before a Tickler is saved and performs.
147         * 1. Assign Tickler Number to Tickler in case of new or copy workflows.
148         * 2. If tickler marked as inactive, mark all associated collections: kemids, securities, principals and groups records as inactive. 
149         * 
150         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#prepareForSave()
151         */
152        @Override
153        public void prepareForSave() 
154        {
155            super.prepareForSave();
156            
157            Tickler tickler = (Tickler) getBusinessObject();
158            
159            //Assign Tickler Number to Tickler in case of new or copy workflows
160            assignTicklerNumber(tickler);
161            
162            //Rule 18: If tickler marked as inactive, mark all associated collections: kemids, securities, principals and groups records as inactive 
163            inactivateTicklerAssociations(tickler);
164            
165        }
166    
167        /**
168         * Assign Tickler Number to Tickler in case of new or copy workflows.
169         *      
170         * @param tickler
171         */
172        private void assignTicklerNumber(Tickler tickler) 
173        {
174            if( KNSConstants.MAINTENANCE_NEW_ACTION.equals(getMaintenanceAction()) || KNSConstants.MAINTENANCE_COPY_ACTION.equals(getMaintenanceAction()) )
175            {
176                //Only assign a Tickler number if not assigned already,may be assigned during a previous save operation.
177                if(tickler.getNumber() == null)
178                {
179                    String ticklerNumber = getSequenceAccessorService().getNextAvailableSequenceNumber(EndowConstants.Sequences.END_TICKLER_SEQ).toString();
180                    tickler.setNumber(ticklerNumber);
181                }
182            }
183        }
184    
185        /**
186         * If tickler marked as inactive, mark all associated collections: kemids, securities, principals and groups records as inactive.
187         * 
188         * @param tickler
189         */
190        private void inactivateTicklerAssociations(Tickler tickler)
191        {
192            if(!tickler.isActive())
193            {
194                //Inactivate Kemids
195                for(TicklerKEMID kemId: tickler.getKemIds())
196                {
197                    kemId.setActive(false);
198                }
199                
200                //Inactivate Securities 
201                for(TicklerSecurity security: tickler.getSecurities())
202                {
203                    security.setActive(false);
204                }
205                    
206                //Inactivate Principals
207                for(TicklerRecipientPrincipal principal : tickler.getRecipientPrincipals())
208                {
209                    principal.setActive(false);
210                }
211                
212                //Inactivate Groups
213                for(TicklerRecipientGroup group : tickler.getRecipientGroups())
214                {
215                    group.setActive(false);
216                }
217    
218            }
219        }
220    
221        /**
222         * Initializes newTickler and oldTickler.
223         * 
224         * @param document
225         */
226        private void initializeAttributes(MaintenanceDocument document) {
227            if (newTickler == null) {
228                newTickler = (Tickler) document.getNewMaintainableObject().getBusinessObject();
229            }
230            if (oldTickler == null) {
231                oldTickler = (Tickler) document.getOldMaintainableObject().getBusinessObject();
232            }
233        }
234    
235        /**
236         * Obtain SequenceAccessorService
237         * 
238         * @return
239         */
240        public SequenceAccessorService getSequenceAccessorService() 
241        {
242            if(sequenceAccessorService == null)
243            {
244                sequenceAccessorService = SpringContext.getBean(SequenceAccessorService.class);
245            }
246            return sequenceAccessorService;
247        }
248    
249        public void setSequenceAccessorService(SequenceAccessorService sequenceAccessorService) {
250            this.sequenceAccessorService = sequenceAccessorService;
251        }
252    
253        public Tickler getOldTickler() {
254            return oldTickler;
255        }
256    
257        public void setOldTickler(Tickler oldTickler) {
258            this.oldTickler = oldTickler;
259        }
260    
261        public Tickler getNewTickler() {
262            return newTickler;
263        }
264    
265        public void setNewTickler(Tickler newTickler) {
266            this.newTickler = newTickler;
267        }
268        
269    }