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.kuali.kfs.module.endow.EndowPropertyConstants;
028    import org.kuali.kfs.module.endow.businessobject.KEMID;
029    import org.kuali.kfs.module.endow.businessobject.KemidAgreement;
030    import org.kuali.kfs.module.endow.businessobject.KemidCombineDonorStatement;
031    import org.kuali.kfs.module.endow.businessobject.KemidCurrentCash;
032    import org.kuali.kfs.module.endow.businessobject.KemidFee;
033    import org.kuali.kfs.module.endow.businessobject.TypeCode;
034    import org.kuali.kfs.module.endow.businessobject.TypeFeeMethod;
035    import org.kuali.kfs.module.endow.document.service.FeeMethodService;
036    import org.kuali.kfs.module.endow.document.service.KEMService;
037    import org.kuali.kfs.sys.KFSConstants;
038    import org.kuali.kfs.sys.context.SpringContext;
039    import org.kuali.kfs.sys.document.FinancialSystemMaintenanceDocument;
040    import org.kuali.rice.kew.exception.WorkflowException;
041    import org.kuali.rice.kns.bo.DocumentHeader;
042    import org.kuali.rice.kns.bo.PersistableBusinessObject;
043    import org.kuali.rice.kns.document.MaintenanceDocument;
044    import org.kuali.rice.kns.maintenance.KualiMaintainableImpl;
045    import org.kuali.rice.kns.maintenance.Maintainable;
046    import org.kuali.rice.kns.service.BusinessObjectService;
047    import org.kuali.rice.kns.service.DateTimeService;
048    import org.kuali.rice.kns.service.DocumentService;
049    import org.kuali.rice.kns.util.KNSConstants;
050    import org.kuali.rice.kns.util.KualiDecimal;
051    import org.kuali.rice.kns.util.ObjectUtils;
052    import org.kuali.rice.kns.web.ui.Field;
053    import org.kuali.rice.kns.web.ui.Row;
054    import org.kuali.rice.kns.web.ui.Section;
055    import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument;
056    
057    /**
058     * This class...
059     */
060    public class KEMIDMaintainableImpl extends KualiMaintainableImpl {
061    
062        private KEMID oldKemid;
063        private KEMID newKemid;
064    
065        /**
066         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#doRouteStatusChange(org.kuali.rice.kns.bo.DocumentHeader)
067         */
068        @Override
069        public void doRouteStatusChange(DocumentHeader documentHeader) {
070    
071            super.doRouteStatusChange(documentHeader);
072    
073            KualiWorkflowDocument workflowDoc = documentHeader.getWorkflowDocument();
074            DocumentService documentService = SpringContext.getBean(DocumentService.class);
075            FinancialSystemMaintenanceDocument maintDoc = null;
076    
077            try {
078                maintDoc = (FinancialSystemMaintenanceDocument) documentService.getByDocumentHeaderId(this.documentNumber);
079            }
080            catch (WorkflowException e) {
081                throw new RuntimeException(e);
082            }
083    
084            initializeAttributes(maintDoc);
085    
086            // This code is only executed if the maintenance action was NEW or COPY and when the final approval occurs
087            if ((KNSConstants.MAINTENANCE_NEW_ACTION.equals(maintDoc.getNewMaintainableObject().getMaintenanceAction()) || KNSConstants.MAINTENANCE_COPY_ACTION.equals(maintDoc.getNewMaintainableObject().getMaintenanceAction())) && workflowDoc.stateIsFinal()) {
088    
089                KemidCurrentCash newCurrentCashEntry = new KemidCurrentCash();
090                newCurrentCashEntry.setKemid(newKemid.getKemid());
091                newCurrentCashEntry.setCurrentIncomeCash(KualiDecimal.ZERO);
092                newCurrentCashEntry.setCurrentPrincipalCash(KualiDecimal.ZERO);
093    
094                // save new current cash entry
095                SpringContext.getBean(BusinessObjectService.class).save(newCurrentCashEntry);
096            }
097        }
098    
099    
100        /**
101         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#refresh(java.lang.String, java.util.Map,
102         *      org.kuali.rice.kns.document.MaintenanceDocument)
103         */
104        @Override
105        public void refresh(String refreshCaller, Map fieldValues, MaintenanceDocument document) {
106    
107            super.refresh(refreshCaller, fieldValues, document);
108    
109            // update fees and ACI, cash sweep models when type code is changed
110            if (refreshCaller != null && refreshCaller.equalsIgnoreCase(KFSConstants.KUALI_LOOKUPABLE_IMPL) && fieldValues != null && fieldValues.containsKey(KFSConstants.MAINTENANCE_NEW_MAINTAINABLE + EndowPropertyConstants.KEMID_TYPE_CODE)) {
111                initializeAttributes(document);
112    
113                if (ObjectUtils.isNotNull(oldKemid) && ObjectUtils.isNotNull(newKemid) && StringUtils.isNotBlank(newKemid.getTypeCode())) {
114                    BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);
115                    Map<String, String> pkMap = new HashMap<String, String>();
116                    pkMap.put(EndowPropertyConstants.ENDOWCODEBASE_CODE, newKemid.getTypeCode());
117                    TypeCode typeCode = (TypeCode) businessObjectService.findByPrimaryKey(TypeCode.class, pkMap);
118    
119                    if (ObjectUtils.isNotNull(typeCode)) {
120                        newKemid.setCashSweepModelId(typeCode.getCashSweepModelId());
121                        newKemid.setIncomeACIModelId(typeCode.getIncomeACIModelId());
122                        newKemid.setPrincipalACIModelId(typeCode.getPrincipalACIModelId());
123                    }
124    
125                    if (KNSConstants.MAINTENANCE_NEW_ACTION.equals(document.getNewMaintainableObject().getMaintenanceAction())) {
126                        updateKemidFees(document);
127                    }
128                }
129            }
130    
131            // when the user looks up a fee method in the add kemid fee method tab the add fee method start date is updated to the
132            // returned fee method next process date
133            if (refreshCaller != null && refreshCaller.equalsIgnoreCase(KFSConstants.KUALI_LOOKUPABLE_IMPL) && fieldValues != null && fieldValues.containsKey(KFSConstants.MAINTENANCE_NEW_MAINTAINABLE + KFSConstants.ADD_PREFIX + "." + EndowPropertyConstants.KEMID_FEES_TAB + "." + EndowPropertyConstants.KEMID_FEE_MTHD_CD)) {
134    
135                KemidFee addKemidFee = (KemidFee) document.getNewMaintainableObject().getNewCollectionLine(EndowPropertyConstants.KEMID_FEES_TAB);
136                String feeMethodCode = addKemidFee.getFeeMethodCode();
137    
138                if (StringUtils.isNotBlank(addKemidFee.getFeeMethodCode())) {
139                    FeeMethodService feeMethodService = SpringContext.getBean(FeeMethodService.class);
140                    addKemidFee.setFeeStartDate(feeMethodService.getFeeMethodNextProcessDate(feeMethodCode));
141                }
142    
143    
144            }
145    
146    
147        }
148    
149        /**
150         * Add the default kemid fees based on the kemid type.
151         * 
152         * @param document
153         */
154        private void updateKemidFees(MaintenanceDocument document) {
155            BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);
156            Map<String, String> typeFeeMethodFieldValues = new HashMap<String, String>();
157            List<KemidFee> kemidFees = new ArrayList<KemidFee>();
158            List<TypeFeeMethod> typeFeeMethodList = new ArrayList<TypeFeeMethod>();
159            KEMID kemid = (KEMID) getBusinessObject();
160    
161            typeFeeMethodFieldValues.put(EndowPropertyConstants.ENDOWCODEBASE_CODE, newKemid.getTypeCode());
162            typeFeeMethodList = (List<TypeFeeMethod>) businessObjectService.findMatching(TypeFeeMethod.class, typeFeeMethodFieldValues);
163    
164            // remove the old kemid fees
165            kemid.getKemidFees().clear();
166    
167            for (TypeFeeMethod feeMethod : typeFeeMethodList) {
168                kemid.getKemidFees().add(createNewKemidFee(feeMethod));
169            }
170    
171            // refresh non-updatable references
172            kemid.refreshNonUpdateableReferences();
173            refreshNonUpdateableReferences(kemid.getKemidFees());
174        }
175    
176        /**
177         * @param collection
178         */
179        private static void refreshNonUpdateableReferences(Collection<? extends PersistableBusinessObject> collection) {
180            for (PersistableBusinessObject item : collection) {
181                item.refreshNonUpdateableReferences();
182            }
183        }
184    
185        /**
186         * Creates a new kemid fee based on a fee method.
187         * 
188         * @param feeMethod
189         * @return the new kemid fee
190         */
191        private KemidFee createNewKemidFee(TypeFeeMethod typeFeeMethod) {
192    
193            KemidFee kemidFee = new KemidFee();
194            kemidFee.setChargeFeeToKemid(newKemid.getKemid());
195            kemidFee.setFeeMethodCode(typeFeeMethod.getFeeMethodCode());
196            kemidFee.setPercentOfFeeChargedToIncome(new KualiDecimal(1));
197            kemidFee.setPercentOfFeeChargedToPrincipal(KualiDecimal.ZERO);
198            kemidFee.setTotalAccruedFees(KualiDecimal.ZERO);
199            kemidFee.setWaiveFees(false);
200            kemidFee.setAccrueFees(false);
201            kemidFee.setTotalWaivedFeesThisFiscalYear(KualiDecimal.ZERO);
202            kemidFee.setTotalWaivedFees(KualiDecimal.ZERO);
203    
204            typeFeeMethod.refreshReferenceObject(EndowPropertyConstants.FEE_METHOD);
205    
206            Date feeStartDate = ObjectUtils.isNotNull(typeFeeMethod.getFeeMethod()) ? typeFeeMethod.getFeeMethod().getFeeNextProcessDate() : null;
207            kemidFee.setFeeStartDate(feeStartDate);
208            kemidFee.setNewCollectionRecord(true);
209    
210            return kemidFee;
211        }
212    
213        /**
214         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#getSections(org.kuali.rice.kns.document.MaintenanceDocument,
215         *      org.kuali.rice.kns.maintenance.Maintainable)
216         */
217        @Override
218        public List getSections(MaintenanceDocument document, Maintainable oldMaintainable) {
219    
220            List<Section> sections = super.getSections(document, oldMaintainable);
221    
222            if (sections != null) {
223                initializeAttributes(document);
224    
225                for (Section section : sections) {
226                    String sectionId = section.getSectionId();
227    
228                    if (sectionId.equalsIgnoreCase(EndowPropertyConstants.KEMID_PAY_INSTRUCTIONS_SECTION)) {
229                        preparePayoutInstructionsTab(document, section);
230                    }
231    
232                    if (sectionId.equalsIgnoreCase(EndowPropertyConstants.KEMID_SPECIAL_INSTRUCTIONS_SECTION)) {
233                        prepareSpecialInstructionsTab(document, section);
234                    }
235    
236                    if (sectionId.equalsIgnoreCase(EndowPropertyConstants.KEMID_REPORT_GROUP_SECTION)) {
237                        prepareReportGroupsTab(document, section);
238                    }
239    
240                    if (sectionId.equalsIgnoreCase(EndowPropertyConstants.KEMID_DONOR_STATEMENTS_SECTION)) {
241                        prepareDonorStatementsTab(document, section);
242                    }
243    
244                    if (sectionId.equalsIgnoreCase(EndowPropertyConstants.KEMID_COMBINE_DONOR_STATEMENTS_SECTION)) {
245                        prepareCombineDonorStatementsTab(document, section);
246                    }
247    
248                    if (sectionId.equalsIgnoreCase(EndowPropertyConstants.KEMID_FEES_SECTION)) {
249                        // section.setDefaultOpen(true);
250                        prepareFeesTab(document, section);
251    
252                    }
253    
254                }
255            }
256            return sections;
257        }
258    
259    
260        /**
261         * Prepares the payout instructions tab for display.
262         * 
263         * @param document
264         * @param section
265         * @param field
266         */
267        private void preparePayoutInstructionsTab(MaintenanceDocument document, Section section) {
268    
269            KEMService kemService = SpringContext.getBean(KEMService.class);
270            DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
271    
272            for (Row row : section.getRows()) {
273                for (Field field : row.getFields()) {
274    
275                    if (field.getCONTAINER().equalsIgnoreCase(field.getFieldType())) {
276    
277                        for (Row containerRow : field.getContainerRows()) {
278                            for (Field containerRowfield : containerRow.getFields()) {
279    
280                                // the payout start date is no longer editable if the payout start date is less than the
281                                // current process
282                                // or
283                                // system date
284    
285                                String indexedPropertyNamePrefix = EndowPropertyConstants.KEMID_PAY_INSTRUCTIONS_TAB + "\\[\\d+\\]\\" + ".";
286                                String indexedStartDate = indexedPropertyNamePrefix + EndowPropertyConstants.KEMID_PAY_INC_START_DATE;
287                                if (containerRowfield.getPropertyName().matches(indexedStartDate)) {
288                                    String payoutStartDateString = containerRowfield.getPropertyValue();
289                                    if (payoutStartDateString != null && !KFSConstants.EMPTY_STRING.equalsIgnoreCase(payoutStartDateString)) {
290                                        String currentProcessDateString = kemService.getCurrentSystemProcessDate();
291    
292                                        try {
293                                            Date currentProcessDate = dateTimeService.convertToSqlDate(currentProcessDateString);
294                                            Date payoutStartDate = dateTimeService.convertToSqlDate(payoutStartDateString);
295    
296                                            if (payoutStartDate.compareTo(currentProcessDate) < 0) {
297                                                containerRowfield.setReadOnly(true);
298                                            }
299                                        }
300                                        catch (ParseException ex) {
301                                            // do nothing
302                                        }
303                                    }
304                                }
305    
306    
307                                // a record is no longer editable if the payout termination date is less than the current
308                                // process or
309                                // system
310                                // date
311                                String indexedEndDate = indexedPropertyNamePrefix + EndowPropertyConstants.KEMID_PAY_INC_END_DATE;
312                                if (containerRowfield.getPropertyName().matches(indexedEndDate)) {
313                                    String payoutEndDateString = containerRowfield.getPropertyValue();
314                                    if (payoutEndDateString != null && !KFSConstants.EMPTY_STRING.equalsIgnoreCase(payoutEndDateString)) {
315    
316                                        String currentProcessDateString = kemService.getCurrentSystemProcessDate();
317    
318                                        try {
319                                            Date currentProcessDate = dateTimeService.convertToSqlDate(currentProcessDateString);
320                                            Date payoutEndDate = dateTimeService.convertToSqlDate(payoutEndDateString);
321    
322                                            if (payoutEndDate.compareTo(currentProcessDate) < 0) {
323                                                containerRow.setHidden(true);
324                                            }
325                                        }
326                                        catch (ParseException ex) {
327                                            // do nothing
328                                        }
329                                    }
330                                }
331                            }
332                        }
333                    }
334    
335    
336                }
337            }
338        }
339    
340    
341        /**
342         * Prepares the special instructions tab.
343         * 
344         * @param document
345         * @param section
346         * @param field
347         */
348        private void prepareSpecialInstructionsTab(MaintenanceDocument document, Section section) {
349            KEMService kemService = SpringContext.getBean(KEMService.class);
350            DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
351    
352            for (Row row : section.getRows()) {
353                for (Field field : row.getFields()) {
354    
355                    if (field.getCONTAINER().equalsIgnoreCase(field.getFieldType())) {
356    
357                        for (Row containerRow : field.getContainerRows()) {
358                            for (Field containerRowfield : containerRow.getFields()) {
359    
360    
361                                // a record is no longer editable if the instruction end date is less than the current
362                                // process or
363                                // system
364                                // date
365                                String specialInstructionEndDateField = KFSConstants.ADD_PREFIX + "." + EndowPropertyConstants.KEMID_SPECIAL_INSTRUCTIONS_TAB + "." + EndowPropertyConstants.KEMID_SPEC_INSTR_END_DATE;
366                                if (specialInstructionEndDateField.equalsIgnoreCase(specialInstructionEndDateField)) {
367                                    String instructionEndDateString = containerRowfield.getPropertyValue();
368                                    if (instructionEndDateString != null && !KFSConstants.EMPTY_STRING.equalsIgnoreCase(instructionEndDateString)) {
369    
370                                        String currentProcessDateString = kemService.getCurrentSystemProcessDate();
371    
372                                        try {
373                                            Date currentProcessDate = dateTimeService.convertToSqlDate(currentProcessDateString);
374                                            Date specialInstructionEndDate = dateTimeService.convertToSqlDate(instructionEndDateString);
375    
376                                            if (specialInstructionEndDate.compareTo(currentProcessDate) < 0) {
377                                                for (Field rowfield : row.getFields()) {
378                                                    rowfield.setReadOnly(true);
379    
380                                                }
381                                            }
382                                        }
383                                        catch (ParseException ex) {
384                                            // do nothing
385                                        }
386                                    }
387                                }
388                            }
389                        }
390                    }
391    
392                }
393            }
394        }
395    
396        /**
397         * Prepares the fees tab.
398         * 
399         * @param document
400         * @param section
401         * @param field
402         */
403        private void prepareFeesTab(MaintenanceDocument document, Section section) {
404            KEMService kemService = SpringContext.getBean(KEMService.class);
405            DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
406    
407            // fees tab
408            for (Row row : section.getRows()) {
409                for (Field field : row.getFields()) {
410    
411                    if (field.getCONTAINER().equalsIgnoreCase(field.getFieldType())) {
412    
413                        for (Row containerRow : field.getContainerRows()) {
414                            for (Field containerRowfield : containerRow.getFields()) {
415                                if (KNSConstants.MAINTENANCE_NEW_ACTION.equals(document.getNewMaintainableObject().getMaintenanceAction()) || KNSConstants.MAINTENANCE_COPY_ACTION.equals(document.getNewMaintainableObject().getMaintenanceAction())) {
416                                    String totalAccruedFeespropertyName = KFSConstants.ADD_PREFIX + "." + EndowPropertyConstants.KEMID_FEES_TAB + "." + EndowPropertyConstants.KEMID_FEE_TOTAL_ACCRUED_FEES;
417                                    String indexedTotalAccruedFeesPropertyName = EndowPropertyConstants.KEMID_FEES_TAB + "\\[\\d+\\]\\" + "." + EndowPropertyConstants.KEMID_FEE_TOTAL_ACCRUED_FEES;
418                                    if (totalAccruedFeespropertyName.equalsIgnoreCase(containerRowfield.getPropertyName()) || containerRowfield.getPropertyName().matches(indexedTotalAccruedFeesPropertyName)) {
419                                        containerRowfield.setReadOnly(true);
420                                    }
421                                }
422                                if (KNSConstants.MAINTENANCE_EDIT_ACTION.equals(document.getNewMaintainableObject().getMaintenanceAction())) {
423    
424                                    String indexedFeeStartDatePropertyName = EndowPropertyConstants.KEMID_FEES_TAB + "\\[\\d+\\]\\" + "." + EndowPropertyConstants.KEMID_FEE_START_DATE;
425                                    if (containerRowfield.getPropertyName().matches(indexedFeeStartDatePropertyName)) {
426                                        containerRowfield.setReadOnly(true);
427                                    }
428                                }
429    
430                                String feeEndDateField = KFSConstants.ADD_PREFIX + "." + EndowPropertyConstants.KEMID_FEES_TAB + "." + EndowPropertyConstants.KEMID_FEE_END_DATE;
431                                if (feeEndDateField.equalsIgnoreCase(feeEndDateField)) {
432                                    String feeEndDateString = containerRowfield.getPropertyValue();
433                                    if (feeEndDateString != null && !KFSConstants.EMPTY_STRING.equalsIgnoreCase(feeEndDateString)) {
434    
435                                        String currentProcessDateString = kemService.getCurrentSystemProcessDate();
436    
437                                        try {
438                                            Date currentProcessDate = dateTimeService.convertToSqlDate(currentProcessDateString);
439                                            Date specialInstructionEndDate = dateTimeService.convertToSqlDate(feeEndDateString);
440    
441                                            if (specialInstructionEndDate.compareTo(currentProcessDate) < 0) {
442                                                for (Field rowfield : row.getFields()) {
443                                                    rowfield.setReadOnly(true);
444    
445                                                }
446                                            }
447                                        }
448                                        catch (ParseException ex) {
449                                            // do nothing
450                                        }
451                                    }
452                                }
453                            }
454                        }
455    
456                    }
457                }
458            }
459        }
460    
461        /**
462         * Prepares the Report Groups tab.
463         * 
464         * @param document
465         * @param section
466         * @param field
467         */
468        private void prepareReportGroupsTab(MaintenanceDocument document, Section section) {
469            KEMService kemService = SpringContext.getBean(KEMService.class);
470            DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
471    
472            for (Row row : section.getRows()) {
473                for (Field field : row.getFields()) {
474    
475                    if (field.getCONTAINER().equalsIgnoreCase(field.getFieldType())) {
476    
477                        for (Row containerRow : field.getContainerRows()) {
478                            for (Field containerRowfield : containerRow.getFields()) {
479    
480    
481                                // a record is no longer editable if the instruction end date is less than the current process or system
482                                // date
483    
484                                String indexedDonorStatementTermDateField = EndowPropertyConstants.KEMID_REPORT_GROUP_TAB + "\\[\\d+\\]\\" + "." + EndowPropertyConstants.KEMID_REPORT_GRP_DATE_TERMINATED;
485                                if (containerRowfield.getPropertyName().matches(indexedDonorStatementTermDateField)) {
486                                    String reportTerminatedDateString = containerRowfield.getPropertyValue();
487                                    if (reportTerminatedDateString != null && !KFSConstants.EMPTY_STRING.equalsIgnoreCase(reportTerminatedDateString)) {
488    
489                                        String currentProcessDateString = kemService.getCurrentSystemProcessDate();
490    
491                                        try {
492                                            Date currentProcessDate = dateTimeService.convertToSqlDate(currentProcessDateString);
493                                            Date reportTerminatedDate = dateTimeService.convertToSqlDate(reportTerminatedDateString);
494    
495                                            if (reportTerminatedDate.compareTo(currentProcessDate) < 0) {
496    
497                                                for (Field rowfield : row.getFields()) {
498                                                    if (rowfield.getCONTAINER().equalsIgnoreCase(rowfield.getFieldType())) {
499    
500                                                        for (Row fieldContainerRow : rowfield.getContainerRows()) {
501                                                            for (Field fieldContainerRowField : fieldContainerRow.getFields()) {
502                                                                fieldContainerRowField.setReadOnly(true);
503                                                            }
504                                                        }
505                                                    }
506    
507                                                }
508                                            }
509                                        }
510                                        catch (ParseException ex) {
511                                            // do nothing
512                                        }
513                                    }
514                                }
515                            }
516                        }
517                    }
518                }
519            }
520        }
521    
522        /**
523         * Prepares the Donor Statements tab.
524         * 
525         * @param document
526         * @param section
527         * @param row
528         * @param field
529         */
530        private void prepareDonorStatementsTab(MaintenanceDocument document, Section section) {
531            KEMService kemService = SpringContext.getBean(KEMService.class);
532            DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
533            for (Row row : section.getRows()) {
534                for (Field field : row.getFields()) {
535                    if (field.getCONTAINER().equalsIgnoreCase(field.getFieldType())) {
536    
537                        for (Row containerRow : field.getContainerRows()) {
538                            for (Field containerRowfield : containerRow.getFields()) {
539    
540    
541                                // a record is no longer editable if the donor statement termination date is less than the current
542                                // process or system date
543    
544                                String indexedDonorStatementTermDateField = EndowPropertyConstants.KEMID_DONOR_STATEMENTS_TAB + "\\[\\d+\\]\\" + "." + EndowPropertyConstants.KEMID_DONOR_STATEMENT_TERMINATION_DATE;
545    
546                                if (containerRowfield.getPropertyName().matches(indexedDonorStatementTermDateField)) {
547                                    String donorStatementTermDateString = containerRowfield.getPropertyValue();
548                                    if (donorStatementTermDateString != null && !KFSConstants.EMPTY_STRING.equalsIgnoreCase(donorStatementTermDateString)) {
549    
550                                        String currentProcessDateString = kemService.getCurrentSystemProcessDate();
551    
552                                        try {
553                                            Date currentProcessDate = dateTimeService.convertToSqlDate(currentProcessDateString);
554                                            Date donorStatementTermDate = dateTimeService.convertToSqlDate(donorStatementTermDateString);
555    
556                                            if (donorStatementTermDate.compareTo(currentProcessDate) < 0) {
557                                                for (Field rowfield : row.getFields()) {
558                                                    if (rowfield.getCONTAINER().equalsIgnoreCase(rowfield.getFieldType())) {
559    
560                                                        for (Row fieldContainerRow : rowfield.getContainerRows()) {
561                                                            for (Field fieldContainerRowField : fieldContainerRow.getFields()) {
562                                                                fieldContainerRowField.setReadOnly(true);
563                                                            }
564                                                        }
565                                                    }
566    
567                                                }
568                                            }
569                                        }
570                                        catch (ParseException ex) {
571                                            // do nothing
572                                        }
573                                    }
574                                }
575                            }
576                        }
577                    }
578                }
579            }
580        }
581    
582        /**
583         * Prepares the Combine Donor statements tab.
584         * 
585         * @param document
586         * @param section
587         * @param row
588         * @param field
589         */
590        private void prepareCombineDonorStatementsTab(MaintenanceDocument document, Section section) {
591            KEMService kemService = SpringContext.getBean(KEMService.class);
592            DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
593    
594            for (Row row : section.getRows()) {
595                for (Field field : row.getFields()) {
596                    if (field.getCONTAINER().equalsIgnoreCase(field.getFieldType())) {
597    
598                        for (Row containerRow : field.getContainerRows()) {
599                            for (Field containerRowfield : containerRow.getFields()) {
600    
601    
602                                // a record is no longer editable if the combine donor statement termination date is less than the
603                                // current
604                                // process or system date
605    
606                                String indexedCombineDonorStatementTermDateField = EndowPropertyConstants.KEMID_COMBINE_DONOR_STATEMENTS_TAB + "\\[\\d+\\]\\" + "." + EndowPropertyConstants.KEMID_COMBINE_DONOR_STATEMENT_TERMINATION_DATE;
607    
608                                if (containerRowfield.getPropertyName().matches(indexedCombineDonorStatementTermDateField)) {
609                                    String combineDonorStatementTermDateString = containerRowfield.getPropertyValue();
610                                    if (combineDonorStatementTermDateString != null && !KFSConstants.EMPTY_STRING.equalsIgnoreCase(combineDonorStatementTermDateString)) {
611    
612                                        String currentProcessDateString = kemService.getCurrentSystemProcessDate();
613    
614                                        try {
615                                            Date currentProcessDate = dateTimeService.convertToSqlDate(currentProcessDateString);
616                                            Date combineDonorStatementTermDate = dateTimeService.convertToSqlDate(combineDonorStatementTermDateString);
617    
618                                            if (combineDonorStatementTermDate.compareTo(currentProcessDate) < 0) {
619                                                for (Field rowfield : row.getFields()) {
620                                                    if (rowfield.getCONTAINER().equalsIgnoreCase(rowfield.getFieldType())) {
621    
622                                                        for (Row fieldContainerRow : rowfield.getContainerRows()) {
623                                                            for (Field fieldContainerRowField : fieldContainerRow.getFields()) {
624                                                                fieldContainerRowField.setReadOnly(true);
625                                                            }
626                                                        }
627                                                    }
628    
629                                                }
630                                            }
631                                        }
632                                        catch (ParseException ex) {
633                                            // do nothing
634                                        }
635                                    }
636                                }
637                            }
638                        }
639                    }
640                }
641            }
642    
643        }
644    
645        /**
646         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#processAfterCopy(org.kuali.rice.kns.document.MaintenanceDocument,
647         *      java.util.Map)
648         */
649        @Override
650        public void processAfterCopy(MaintenanceDocument arg0, Map<String, String[]> arg1) {
651            super.processAfterCopy(arg0, arg1);
652    
653            initializeAttributes(arg0);
654    
655            newKemid.refreshNonUpdateableReferences();
656            newKemid.getKemidAgreements().clear();
657            oldKemid.getKemidAgreements().clear();
658            newKemid.getKemidSourcesOfFunds().clear();
659            oldKemid.getKemidSourcesOfFunds().clear();
660            newKemid.getKemidBenefittingOrganizations().clear();
661            oldKemid.getKemidBenefittingOrganizations().clear();
662            newKemid.getKemidGeneralLedgerAccounts().clear();
663            oldKemid.getKemidGeneralLedgerAccounts().clear();
664            newKemid.getKemidPayoutInstructions().clear();
665            oldKemid.getKemidPayoutInstructions().clear();
666            newKemid.getKemidUseCriteria().clear();
667            oldKemid.getKemidUseCriteria().clear();
668            newKemid.getKemidFees().clear();
669            oldKemid.getKemidFees().clear();
670            newKemid.getKemidReportGroups().clear();
671            oldKemid.getKemidReportGroups().clear();
672            newKemid.getKemidSpecialInstructions().clear();
673            oldKemid.getKemidSpecialInstructions().clear();
674            newKemid.getKemidDonorStatements().clear();
675            oldKemid.getKemidDonorStatements().clear();
676            newKemid.getKemidCombineDonorStatements().clear();
677            oldKemid.getKemidCombineDonorStatements().clear();
678            newKemid.getKemidAuthorizations().clear();
679            oldKemid.getKemidAuthorizations().clear();
680        }
681    
682        /**
683         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#prepareForSave()
684         */
685        @Override
686        public void prepareForSave() {
687            KEMID kemid = (KEMID) getBusinessObject();
688    
689            // set the KEMID transaction restriction code
690            for (KemidAgreement kemidAgreement : kemid.getKemidAgreements()) {
691                if (kemidAgreement.isUseTransactionRestrictionFromAgreement()) {
692                    kemidAgreement.refreshReferenceObject(EndowPropertyConstants.KEMID_AGRMNT_STATUS);
693                    if (ObjectUtils.isNotNull(kemidAgreement.getAgreementStatus())) {
694                        kemid.setTransactionRestrictionCode(kemidAgreement.getAgreementStatus().getDefaultTransactionRestrictionCode());
695                    }
696                }
697            }
698            super.prepareForSave();
699        }
700    
701        /**
702         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#addNewLineToCollection(java.lang.String)
703         */
704        @Override
705        public void addNewLineToCollection(String collectionName) {
706            if (collectionName.equalsIgnoreCase(EndowPropertyConstants.KEMID_COMBINE_DONOR_STATEMENTS_TAB)) {
707                KemidCombineDonorStatement addLine = (KemidCombineDonorStatement) newCollectionLines.get(collectionName);
708                KEMService kemService = SpringContext.getBean(KEMService.class);
709                DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
710                try {
711                    addLine.setCombineDate(dateTimeService.convertToSqlDate(kemService.getCurrentSystemProcessDate()));
712                }
713                catch (ParseException ex) {
714                    // do nothing?
715                }
716            }
717            super.addNewLineToCollection(collectionName);
718        }
719    
720        /**
721         * Initializes newKemid and oldKemid.
722         * 
723         * @param document
724         */
725        private void initializeAttributes(MaintenanceDocument document) {
726            if (newKemid == null) {
727                newKemid = (KEMID) document.getNewMaintainableObject().getBusinessObject();
728            }
729            if (oldKemid == null) {
730                oldKemid = (KEMID) document.getOldMaintainableObject().getBusinessObject();
731            }
732        }
733    
734    }