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.coa.document.validation.impl;
017    
018    import java.util.Iterator;
019    
020    import org.apache.commons.lang.StringUtils;
021    import org.kuali.kfs.coa.businessobject.ObjectCode;
022    import org.kuali.kfs.coa.businessobject.OrganizationReversionGlobal;
023    import org.kuali.kfs.coa.businessobject.OrganizationReversionGlobalDetail;
024    import org.kuali.kfs.coa.businessobject.OrganizationReversionGlobalOrganization;
025    import org.kuali.kfs.coa.businessobject.options.OrganizationReversionCodeValuesFinder;
026    import org.kuali.kfs.coa.document.OrganizationReversionGlobalMaintainableImpl;
027    import org.kuali.kfs.coa.service.ObjectCodeService;
028    import org.kuali.kfs.coa.service.OrganizationReversionService;
029    import org.kuali.kfs.sys.KFSConstants;
030    import org.kuali.kfs.sys.KFSKeyConstants;
031    import org.kuali.kfs.sys.context.SpringContext;
032    import org.kuali.rice.kns.bo.PersistableBusinessObject;
033    import org.kuali.rice.kns.document.MaintenanceDocument;
034    import org.kuali.rice.kns.util.GlobalVariables;
035    import org.kuali.rice.kns.util.ObjectUtils;
036    import org.kuali.rice.core.util.KeyLabelPair;
037    
038    /**
039     * 
040     * This class implements the business rules for {@link OrganizationReversionGlobal}
041     */
042    public class OrganizationReversionGlobalRule extends GlobalDocumentRuleBase {
043        protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OrganizationReversionGlobalRule.class);
044        protected OrganizationReversionGlobal globalOrganizationReversion;
045        protected OrganizationReversionService organizationReversionService;
046        protected ObjectCodeService objectCodeService;
047    
048        /**
049         * 
050         * Constructs a OrganizationReversionGlobalRule
051         * Pseudo-injects services 
052         */
053        public OrganizationReversionGlobalRule() {
054            super();
055            setOrganizationReversionService(SpringContext.getBean(OrganizationReversionService.class));
056            setObjectCodeService(SpringContext.getBean(ObjectCodeService.class));
057        }
058    
059        /**
060         * This method sets the convenience objects like newAccount and oldAccount, so you have short and easy handles to the new and
061         * old objects contained in the maintenance document. It also calls the BusinessObjectBase.refresh(), which will attempt to load
062         * all sub-objects from the DB by their primary keys, if available.
063         * 
064         * @param document - the maintenanceDocument being evaluated
065         * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#setupConvenienceObjects()
066         */
067        @Override
068        public void setupConvenienceObjects() {
069            this.globalOrganizationReversion = (OrganizationReversionGlobal) super.getNewBo();
070            for (OrganizationReversionGlobalDetail detail : this.globalOrganizationReversion.getOrganizationReversionGlobalDetails()) {
071                detail.refreshNonUpdateableReferences();
072            }
073            for (OrganizationReversionGlobalOrganization org : this.globalOrganizationReversion.getOrganizationReversionGlobalOrganizations()) {
074                org.refreshNonUpdateableReferences();
075            }
076        }
077    
078        /**
079         * Calls the basic rules check on document save:
080         * <ul>
081         * <li>{@link OrganizationReversionGlobalRule#checkSimpleRules(OrganizationReversionGlobal)}</li>
082         * </ul>
083         * Does not fail on rules failure
084         * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument)
085         */
086        @Override
087        protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) {
088            checkSimpleRules(getGlobalOrganizationReversion());
089            return true; // always return true on save
090        }
091    
092        /**
093         * Calls the basic rules check on document approval:
094         * <ul>
095         * <li>{@link OrganizationReversionGlobalRule#checkSimpleRules(OrganizationReversionGlobal)}</li>
096         * </ul>
097         * Fails on rules failure
098         * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomApproveDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument)
099         */
100        @Override
101        protected boolean processCustomApproveDocumentBusinessRules(MaintenanceDocument document) {
102            return checkSimpleRules(getGlobalOrganizationReversion());
103        }
104    
105        /**
106         * Calls the basic rules check on document routing:
107         * <ul>
108         * <li>{@link OrganizationReversionGlobalRule#checkSimpleRules(OrganizationReversionGlobal)}</li>
109         * </ul>
110         * Fails on rules failure
111         * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument)
112         */
113        @Override
114        protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
115            return checkSimpleRules(getGlobalOrganizationReversion());
116        }
117    
118        /**
119         * This performs rules checks whenever a new {@link OrganizationReversionGlobalDetail} or {@link OrganizationReversionGlobalOrganization} is added
120         * <p>
121         * This includes:
122         * <ul>
123         * <li>{@link OrganizationReversionGlobalRule#checkDetailObjectCodeValidity(OrganizationReversionGlobal, OrganizationReversionGlobalDetail)}</li>
124         * <li>{@link OrganizationReversionGlobalRule#checkDetailObjectReversionCodeValidity(OrganizationReversionGlobalDetail)}</li>
125         * <li>ensure that the chart of accounts code and organization codes for {@link OrganizationReversionGlobalOrganization} are not empty values</li>
126         * <li>{@link OrganizationReversionGlobalRule#checkAllObjectCodesForValidity(OrganizationReversionGlobal, OrganizationReversionGlobalOrganization)}</li>
127         * <li>{@link OrganizationReversionGlobalRule#checkOrganizationChartValidity(OrganizationReversionGlobalOrganization)</li>
128         * <li>{@link OrganizationReversionGlobalRule#checkOrganizationValidity(OrganizationReversionGlobalOrganization)</li>
129         * <li>{@link OrganizationReversionGlobalRule#checkOrganizationReversionForOrganizationExists(OrganizationReversionGlobal, OrganizationReversionGlobalOrganization)</li>
130         * <li>{@link OrganizationReversionGlobalRule#checkOrganizationIsNotAmongOrgRevOrganizations(OrganizationReversionGlobal, OrganizationReversionGlobalOrganization)</li>
131         * </ul>
132         * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomAddCollectionLineBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument,
133         *      java.lang.String, org.kuali.rice.kns.bo.PersistableBusinessObject)
134         */
135        @Override
136        public boolean processCustomAddCollectionLineBusinessRules(MaintenanceDocument document, String collectionName, PersistableBusinessObject line) {
137            boolean success = true;
138            OrganizationReversionGlobal globalOrgRev = (OrganizationReversionGlobal) ((OrganizationReversionGlobalMaintainableImpl) document.getNewMaintainableObject()).getBusinessObject();
139            if (line instanceof OrganizationReversionGlobalDetail) {
140                OrganizationReversionGlobalDetail detail = (OrganizationReversionGlobalDetail) line;
141                success &= checkDetailObjectCodeValidity(globalOrgRev, detail);
142                success &= checkDetailObjectReversionCodeValidity(detail);
143            }
144            else if (line instanceof OrganizationReversionGlobalOrganization) {
145                OrganizationReversionGlobalOrganization org = (OrganizationReversionGlobalOrganization) line;
146                if (!checkEmptyValue(org.getChartOfAccountsCode())) {
147                    GlobalVariables.getMessageMap().putError("chartOfAccountsCode", KFSKeyConstants.ERROR_REQUIRED, "Chart of Accounts Code");
148                }
149                if (!checkEmptyValue(org.getOrganizationCode())) {
150                    GlobalVariables.getMessageMap().putError("organizationCode", KFSKeyConstants.ERROR_REQUIRED, "Organization Code");
151                }
152                if (success) {
153                    success &= checkAllObjectCodesForValidity(globalOrgRev, org);
154                    success &= checkOrganizationChartValidity(org);
155                    success &= checkOrganizationValidity(org);
156                    success &= checkOrganizationReversionForOrganizationExists(globalOrgRev, org);
157                    success &= checkOrganizationIsNotAmongOrgRevOrganizations(globalOrgRev, org);
158                }
159            }
160            return success;
161        }
162    
163        /**
164         * Convenient convenience method to test all the simple rules in one go. Including:
165         * <ul>
166         * <li>{@link OrganizationReversionGlobalRule#checkBudgetReversionAccountPair(OrganizationReversionGlobal)}</li>
167         * <li>{@link OrganizationReversionGlobalRule#checkCashReversionAccountPair(OrganizationReversionGlobal)}</li>
168         * <li>{@link OrganizationReversionGlobalRule#areAllDetailsValid(OrganizationReversionGlobal)}</li>
169         * <li>{@link OrganizationReversionGlobalRule#areAllOrganizationsValid(OrganizationReversionGlobal)</li>
170         * </ul>
171         * @param globalOrgRev the global organization reversion to check
172         * @return true if the new global organization reversion passes all tests, false if it deviates even a tiny little bit
173         */
174        public boolean checkSimpleRules(OrganizationReversionGlobal globalOrgRev) {
175            boolean success = true;
176    
177            success &= checkBudgetReversionAccountPair(globalOrgRev);
178            success &= checkCashReversionAccountPair(globalOrgRev);
179    
180            success &= areAllDetailsValid(globalOrgRev);
181            success &= areAllOrganizationsValid(globalOrgRev);
182    
183            return success;
184        }
185    
186        /**
187         * This method makes sure that if one part of the Budget Reversion Chart/Account pair is specified, both are specified, or an
188         * error is thrown.
189         * 
190         * @param globalOrgRev the Global Organization Reversion to check
191         * @return true if budget reversion chart/account pair is specified correctly, false if otherwise
192         */
193        public boolean checkBudgetReversionAccountPair(OrganizationReversionGlobal globalOrgRev) {
194            boolean success = true;
195            if ((!StringUtils.isBlank(globalOrgRev.getBudgetReversionChartOfAccountsCode()) && StringUtils.isBlank(globalOrgRev.getBudgetReversionAccountNumber())) || (StringUtils.isBlank(globalOrgRev.getBudgetReversionChartOfAccountsCode()) && !StringUtils.isBlank(globalOrgRev.getBudgetReversionAccountNumber()))) {
196                success = false;
197                GlobalVariables.getMessageMap().putError(MAINTAINABLE_ERROR_PREFIX + "budgetReversionChartOfAccountsCode", KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ORG_REVERSION_BUDGET_REVERSION_INCOMPLETE, new String[] {});
198            }
199            return success;
200        }
201    
202        /**
203         * This method makes sure that if one part of the Cash Reversion Chart/Account pair is specified, both are specified, or an
204         * error is thrown.
205         * 
206         * @param globalOrgRev the Global Organization Reversion to check
207         * @return true if cash reversion chart/account pair is specified correctly, false if otherwise
208         */
209        public boolean checkCashReversionAccountPair(OrganizationReversionGlobal globalOrgRev) {
210            boolean success = true;
211            if ((!StringUtils.isBlank(globalOrgRev.getCashReversionFinancialChartOfAccountsCode()) && StringUtils.isBlank(globalOrgRev.getCashReversionAccountNumber())) || (StringUtils.isBlank(globalOrgRev.getCashReversionFinancialChartOfAccountsCode()) && !StringUtils.isBlank(globalOrgRev.getCashReversionAccountNumber()))) {
212                success = false;
213                GlobalVariables.getMessageMap().putError(MAINTAINABLE_ERROR_PREFIX + "cashReversionFinancialChartOfAccountsCode", KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ORG_REVERSION_CASH_REVERSION_INCOMPLETE, new String[] {});
214            }
215            return success;
216        }
217    
218        /**
219         * Tests if all of the {@link OrganizationReversionGlobalDetail} objects associated with the given global organization reversion are
220         * valid.
221         * 
222         * @param globalOrgRev the global organization reversion to check
223         * @return true if valid, false otherwise
224         */
225        public boolean areAllDetailsValid(OrganizationReversionGlobal globalOrgRev) {
226            boolean success = true;
227            for (int i = 0; i < globalOrgRev.getOrganizationReversionGlobalDetails().size(); i++) {
228                OrganizationReversionGlobalDetail detail = globalOrgRev.getOrganizationReversionGlobalDetails().get(i);
229                
230                String errorPath = MAINTAINABLE_ERROR_PREFIX + "organizationReversionGlobalDetails[" + i + "]";
231                GlobalVariables.getMessageMap().addToErrorPath(errorPath);
232    
233                if (!StringUtils.isBlank(detail.getOrganizationReversionObjectCode()) && !StringUtils.isBlank(detail.getOrganizationReversionCode())) {
234                    success &= this.checkDetailOrgReversionCategoryValidity(detail);
235                    success &= this.checkDetailObjectCodeValidity(globalOrgRev, detail);
236                    success &= this.checkDetailObjectReversionCodeValidity(detail);
237                }
238                GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
239            }
240            return success;
241        }
242    
243        /**
244         * Tests if the Organization Reversion Category existed in the database and was active.
245         * 
246         * @param detail OrganizationReversionGlobalDetail to check
247         * @return true if the category is valid, false if otherwise
248         */
249        public boolean checkDetailOrgReversionCategoryValidity(OrganizationReversionGlobalDetail detail) {
250            boolean success = true;
251            if (StringUtils.isBlank(detail.getOrganizationReversionCategoryCode())) {
252                success = false;
253                GlobalVariables.getMessageMap().putError("organizationReversionCategoryCode", KFSKeyConstants.ERROR_REQUIRED, new String[] {});
254            }
255            else {
256                detail.refreshReferenceObject("organizationReversionCategory");
257                if (detail.getOrganizationReversionCategory() == null || !detail.getOrganizationReversionCategory().isActive()) {
258                    success = false;
259                    GlobalVariables.getMessageMap().putError("organizationReversionCategoryCode", KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ORG_REVERSION_INVALID_ORG_REVERSION_CATEGORY, new String[] { detail.getOrganizationReversionCategoryCode() });
260                }
261            }
262            return success;
263        }
264    
265        /**
266         * For each organization, tests if the object code in the detail exists in the system and is active
267         * 
268         * @param detail the OrganizationReversionGlobalDetail to check
269         * @return true if it is valid, false if otherwise
270         */
271        public boolean checkDetailObjectCodeValidity(OrganizationReversionGlobal globalOrgRev, OrganizationReversionGlobalDetail detail) {
272            boolean success = true;
273            for (OrganizationReversionGlobalOrganization org : globalOrgRev.getOrganizationReversionGlobalOrganizations()) {
274                if (!validObjectCode(globalOrgRev.getUniversityFiscalYear(), org.getChartOfAccountsCode(), detail.getOrganizationReversionObjectCode())) {
275                    success = false;
276                    GlobalVariables.getMessageMap().putError("organizationReversionObjectCode", KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ORG_REVERSION_OBJECT_CODE_INVALID, new String[] { globalOrgRev.getUniversityFiscalYear().toString(), org.getChartOfAccountsCode(), detail.getOrganizationReversionObjectCode(), org.getChartOfAccountsCode(), org.getOrganizationCode() });
277                }
278            }
279            return success;
280        }
281    
282        /**
283         * This method loops through each of the OrganizationReversionGlobalDetail objects, checking that the entered object codes for
284         * each of them are compatible with the OrganizationReversionGlobalOrganization specified.
285         * 
286         * @param globalOrgRev the global organization reversion to check
287         * @param org the OrganizationReversionGlobalOrganization with a new chart to check against all of the object codes
288         * @return true if there are no conflicts, false if otherwise
289         */
290        public boolean checkAllObjectCodesForValidity(OrganizationReversionGlobal globalOrgRev, OrganizationReversionGlobalOrganization org) {
291            boolean success = true;
292            for (OrganizationReversionGlobalDetail detail : globalOrgRev.getOrganizationReversionGlobalDetails()) {
293                if (!validObjectCode(globalOrgRev.getUniversityFiscalYear(), org.getChartOfAccountsCode(), detail.getOrganizationReversionObjectCode())) {
294                    success = false;
295                    GlobalVariables.getMessageMap().putError("organizationCode", KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ORG_REVERSION_OBJECT_CODE_INVALID, new String[] { globalOrgRev.getUniversityFiscalYear().toString(), org.getChartOfAccountsCode(), detail.getOrganizationReversionObjectCode(), org.getChartOfAccountsCode(), org.getOrganizationCode() });
296                }
297            }
298            return success;
299        }
300    
301        /**
302         * This method checks if an object code with the given primary key fields exists in the database.
303         * 
304         * @param universityFiscalYear the university fiscal year of the object code
305         * @param chartOfAccountsCode the chart of accounts code of the object code
306         * @param objectCode the object code itself
307         * @return true if it exists (or was not filled in to begin with), false if otherwise
308         */
309        public boolean validObjectCode(Integer universityFiscalYear, String chartOfAccountsCode, String objectCode) {
310            if (!StringUtils.isBlank(objectCode) && universityFiscalYear != null && !StringUtils.isBlank(chartOfAccountsCode)) {
311                ObjectCode objCode = objectCodeService.getByPrimaryId(universityFiscalYear, chartOfAccountsCode, objectCode);
312                return (ObjectUtils.isNotNull(objCode));
313            }
314            else {
315                return true; // blank object code? well, it's not required...and thus, it's a valid choice
316            }
317        }
318    
319        /**
320         * Tests if the object reversion code is a valid code.
321         * 
322         * @param detail the OrganizationReversionGlobalDetail to check
323         * @return true if it the detail is valid, false if otherwise
324         */
325        public boolean checkDetailObjectReversionCodeValidity(OrganizationReversionGlobalDetail detail) {
326            boolean success = true;
327            if (!StringUtils.isBlank(detail.getOrganizationReversionCode())) {
328                boolean foundInList = false;
329                // TODO Dude!! The *only* place that the org reversion code values are defined
330                // is in the lookup class, so I've got to use a web-based class to actually
331                // search through the values. Is that right good & healthy?
332                for (Object kvPairObj : new OrganizationReversionCodeValuesFinder().getKeyValues()) {
333                    KeyLabelPair kvPair = (KeyLabelPair) kvPairObj;
334                    if (kvPair.getKey().toString().equals(detail.getOrganizationReversionCode())) {
335                        foundInList = true;
336                        break;
337                    }
338                }
339                if (!foundInList) {
340                    success = false; // we've failed to find the code in the list...FAILED!
341                    GlobalVariables.getMessageMap().putError("organizationReversionCode", KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ORG_REVERSION_INVALID_ORG_REVERSION_CODE, new String[] { detail.getOrganizationReversionCode() });
342                }
343            }
344            return success;
345        }
346    
347        /**
348         * This method tests if all the OrganizationReversionGlobalOrganization objects associated with the given global organization
349         * reversion pass all of their tests.
350         * 
351         * @param globalOrgRev the global organization reversion to check
352         * @return true if valid, false otherwise
353         */
354        public boolean areAllOrganizationsValid(OrganizationReversionGlobal globalOrgRev) {
355            boolean success = true;
356            if (globalOrgRev.getOrganizationReversionGlobalOrganizations().size() == 0) {
357                putFieldError(KFSConstants.MAINTENANCE_ADD_PREFIX + "organizationReversionGlobalOrganizations.organizationCode", KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ORG_REVERSION_NO_ORGANIZATIONS);
358            }
359            else {
360                for (int i = 0; i < globalOrgRev.getOrganizationReversionGlobalOrganizations().size(); i++) {
361                    OrganizationReversionGlobalOrganization org = globalOrgRev.getOrganizationReversionGlobalOrganizations().get(i);
362                    String errorPath = MAINTAINABLE_ERROR_PREFIX + "organizationReversionGlobalOrganizations[" + i + "]";
363                    GlobalVariables.getMessageMap().addToErrorPath(errorPath);
364                    success &= checkAllObjectCodesForValidity(globalOrgRev, org);
365                    success &= checkOrganizationValidity(org);
366                    success &= checkOrganizationChartValidity(org);
367                    success &= checkOrganizationReversionForOrganizationExists(globalOrgRev, org);
368                    GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
369                }
370            }
371            return success;
372        }
373    
374        /**
375         * Tests if the the organization of the given OrganizationReversionGlobalOrganization is within the chart of the global
376         * organization reversion as a whole.
377         * 
378         * @param globalOrgRev the global organization reversion that is currently being validated.
379         * @param org the OrganizationReversionGlobalOrganization to check
380         * @return true if valid, false otherwise
381         */
382        public boolean checkOrganizationChartValidity(OrganizationReversionGlobalOrganization org) {
383            boolean success = true;
384            if (StringUtils.isBlank(org.getChartOfAccountsCode())) {
385                if (!StringUtils.isBlank(org.getOrganizationCode())) {
386                    success = false;
387                    GlobalVariables.getMessageMap().putError("chartOfAccountsCode", KFSKeyConstants.ERROR_REQUIRED, new String[] {});
388                }
389            }
390            else {
391                org.setChartOfAccountsCode(org.getChartOfAccountsCode().toUpperCase());
392                org.refreshReferenceObject("chartOfAccounts");
393                if (org.getChartOfAccounts() == null) {
394                    success = false;
395                    GlobalVariables.getMessageMap().putError("chartOfAccountsCode", KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ORG_REVERSION_INVALID_CHART, new String[] { org.getChartOfAccountsCode() });
396                }
397            }
398            return success;
399        }
400    
401        /**
402         * Tests if the given OrganizationReversionGlobalOrganization's Organization is active and within the system.
403         * 
404         * @param org the OrganizationReversionGlobalOrganization to check
405         * @return true if valid, false otherwise
406         */
407        public boolean checkOrganizationValidity(OrganizationReversionGlobalOrganization org) {
408            boolean success = true;
409            if (StringUtils.isBlank(org.getOrganizationCode())) {
410                if (!StringUtils.isBlank(org.getChartOfAccountsCode())) {
411                    success = false;
412                    GlobalVariables.getMessageMap().putError("organizationCode", KFSKeyConstants.ERROR_REQUIRED, new String[] {});
413                }
414            }
415            else if (!StringUtils.isBlank(org.getChartOfAccountsCode())) {
416                org.refreshReferenceObject("organization");
417                if (org.getOrganization() == null) {
418                    success = false;
419                    GlobalVariables.getMessageMap().putError("organizationCode", KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ORG_REVERSION_INVALID_ORGANIZATION, new String[] { org.getChartOfAccountsCode(), org.getOrganizationCode() });
420                }
421            }
422            return success;
423        }
424    
425        /**
426         * Checks that an organization reversion for the given organization reversion change and organization reversion change
427         * organization exist.
428         * 
429         * @param globalOrgRev global Organization Reversion to check
430         * @param org organization within that Global Organization Reversion to check specifically
431         * @return true if organization reversion for organization exists, false if otherwise
432         */
433        public boolean checkOrganizationReversionForOrganizationExists(OrganizationReversionGlobal globalOrgRev, OrganizationReversionGlobalOrganization org) {
434            boolean success = true;
435            if (globalOrgRev.getUniversityFiscalYear() != null) {
436                if (organizationReversionService.getByPrimaryId(globalOrgRev.getUniversityFiscalYear(), org.getChartOfAccountsCode(), org.getOrganizationCode()) == null) {
437                    success = false;
438                    GlobalVariables.getMessageMap().putError("organizationCode", KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ORG_REVERSION_NO_ORG_REVERSION, new String[] { globalOrgRev.getUniversityFiscalYear().toString(), org.getChartOfAccountsCode(), org.getOrganizationCode() });
439                }
440            }
441            return success;
442        }
443    
444        /**
445         * This method checks if a newly added organization is already among the organizations already listed. WARNING: only use on add
446         * line rules; there's no good way to use this method when testing the entire document.
447         * 
448         * @param globalOrgRev the global Organization Reversion to check
449         * @param orgRevOrg the newly adding organization reversion change organization
450         * @return true if organization should be added as it is not currently in the collection, false if otherwise
451         */
452        public boolean checkOrganizationIsNotAmongOrgRevOrganizations(OrganizationReversionGlobal globalOrgRev, OrganizationReversionGlobalOrganization orgRevOrg) {
453            boolean success = true;
454            Iterator<OrganizationReversionGlobalOrganization> iter = globalOrgRev.getOrganizationReversionGlobalOrganizations().iterator();
455            while (iter.hasNext() && success) {
456                OrganizationReversionGlobalOrganization currOrg = iter.next();
457                if (areContainingSameOrganizations(currOrg, orgRevOrg)) {
458                    success = false;
459                    GlobalVariables.getMessageMap().putError("organizationCode", KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ORG_REVERSION_DUPLICATE_ORGS, new String[] { orgRevOrg.getChartOfAccountsCode(), orgRevOrg.getOrganizationCode() });
460                }
461            }
462            return success;
463        }
464    
465        /**
466         * This method tests if two OrganizationReversionGlobalOrganization objects are holding the same underlying Organization.
467         * 
468         * @param orgRevOrgA the first OrganizationReversionGlobalOrganization to check
469         * @param orgRevOrgB the second OrganizationReversionGlobalOrganization to check
470         * @return true if they share the organization, false if otherwise
471         */
472        public static boolean areContainingSameOrganizations(OrganizationReversionGlobalOrganization orgRevOrgA, OrganizationReversionGlobalOrganization orgRevOrgB) {
473            boolean containingSame = false;
474            if (orgRevOrgA.getChartOfAccountsCode() != null && orgRevOrgB.getChartOfAccountsCode() != null && orgRevOrgA.getOrganizationCode() != null && orgRevOrgB.getOrganizationCode() != null) {
475                containingSame = (orgRevOrgA.getChartOfAccountsCode().equals(orgRevOrgB.getChartOfAccountsCode()) && orgRevOrgA.getOrganizationCode().equals(orgRevOrgB.getOrganizationCode()));
476            }
477            return containingSame;
478        }
479    
480        public void setOrganizationReversionService(OrganizationReversionService organizationReversionService) {
481            this.organizationReversionService = organizationReversionService;
482        }
483    
484        public void setObjectCodeService(ObjectCodeService objectCodeService) {
485            this.objectCodeService = objectCodeService;
486        }
487    
488        protected OrganizationReversionGlobal getGlobalOrganizationReversion() {
489            return this.globalOrganizationReversion;
490        }
491    }