001/*
002 * Copyright 2007 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 */
016package org.kuali.ole.coa.document.validation.impl;
017
018import java.util.Iterator;
019
020import org.apache.commons.lang.StringUtils;
021import org.kuali.ole.coa.businessobject.ObjectCode;
022import org.kuali.ole.coa.businessobject.OrganizationReversionGlobal;
023import org.kuali.ole.coa.businessobject.OrganizationReversionGlobalDetail;
024import org.kuali.ole.coa.businessobject.OrganizationReversionGlobalOrganization;
025import org.kuali.ole.coa.businessobject.options.OrganizationReversionCodeValuesFinder;
026import org.kuali.ole.coa.document.OrganizationReversionGlobalMaintainableImpl;
027import org.kuali.ole.coa.service.ObjectCodeService;
028import org.kuali.ole.coa.service.OrganizationReversionService;
029import org.kuali.ole.sys.OLEConstants;
030import org.kuali.ole.sys.OLEKeyConstants;
031import org.kuali.ole.sys.context.SpringContext;
032import org.kuali.rice.core.api.util.KeyValue;
033import org.kuali.rice.kns.document.MaintenanceDocument;
034import org.kuali.rice.krad.bo.PersistableBusinessObject;
035import org.kuali.rice.krad.util.GlobalVariables;
036import org.kuali.rice.krad.util.ObjectUtils;
037
038/**
039 * 
040 * This class implements the business rules for {@link OrganizationReversionGlobal}
041 */
042public 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.krad.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", OLEKeyConstants.ERROR_REQUIRED, "Chart of Accounts Code");
148            }
149            if (!checkEmptyValue(org.getOrganizationCode())) {
150                GlobalVariables.getMessageMap().putError("organizationCode", OLEKeyConstants.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", OLEKeyConstants.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", OLEKeyConstants.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", OLEKeyConstants.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", OLEKeyConstants.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", OLEKeyConstants.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", OLEKeyConstants.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                KeyValue kvPair = (KeyValue) 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", OLEKeyConstants.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(OLEConstants.MAINTENANCE_ADD_PREFIX + "organizationReversionGlobalOrganizations.organizationCode", OLEKeyConstants.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", OLEKeyConstants.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", OLEKeyConstants.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", OLEKeyConstants.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", OLEKeyConstants.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", OLEKeyConstants.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", OLEKeyConstants.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}