/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.coa.document;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.kuali.kfs.coa.businessobject.OrganizationReversion;
import org.kuali.kfs.coa.businessobject.OrganizationReversionCategory;
import org.kuali.kfs.coa.businessobject.OrganizationReversionDetail;
import org.kuali.kfs.coa.service.OrganizationReversionDetailTrickleDownInactivationService;
import org.kuali.kfs.coa.service.OrganizationReversionService;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.document.FinancialSystemMaintainable;
import org.kuali.rice.kns.document.MaintenanceDocument;
import org.kuali.rice.kns.maintenance.Maintainable;
import org.kuali.rice.kns.web.ui.Field;
import org.kuali.rice.kns.web.ui.Row;
import org.kuali.rice.kns.web.ui.Section;
import org.kuali.rice.krad.util.KRADConstants;
import org.kuali.rice.krad.util.ObjectUtils;
/**
* This class provides some specific functionality for the {@link OrganizationReversion} maintenance document inner class for doing
* comparisons on {@link OrganizationReversionCategory} populateBusinessObject setBusinessObject - pre-populate the static list of
* details with each category isRelationshipRefreshable - makes sure that {@code organizationReversionGlobalDetails} isn't wiped out
* accidentally
*/
public class OrganizationReversionMaintainableImpl extends FinancialSystemMaintainable {
private static transient OrganizationReversionService organizationReversionService;
private static transient OrganizationReversionDetailTrickleDownInactivationService trickleDownInactivationService;
/**
* This comparator is used internally for sorting the list of categories
*/
protected static class CategoryComparator implements Comparator<OrganizationReversionDetail> {
@Override
public int compare(OrganizationReversionDetail detail0, OrganizationReversionDetail detail1) {
OrganizationReversionCategory category0 = detail0.getOrganizationReversionCategory();
OrganizationReversionCategory category1 = detail1.getOrganizationReversionCategory();
String code0 = category0.getOrganizationReversionCategoryCode();
String code1 = category1.getOrganizationReversionCategoryCode();
return code0.compareTo(code1);
}
}
@Override
public void processAfterNew(MaintenanceDocument document, Map<String, String[]> requestParameters) {
super.processAfterNew(document, requestParameters);
OrganizationReversion organizationReversion = (OrganizationReversion) getBusinessObject();
List<OrganizationReversionDetail> details = organizationReversion.getOrganizationReversionDetail();
if (details == null) {
details = new ArrayList<OrganizationReversionDetail>();
organizationReversion.setOrganizationReversionDetail(details);
}
if (details.size() == 0) {
Collection<OrganizationReversionCategory> categories = getOrganizationReversionService().getCategoryList();
for (OrganizationReversionCategory category : categories) {
if (category.isActive()) {
OrganizationReversionDetail detail = new OrganizationReversionDetail();
detail.setOrganizationReversionCategoryCode(category.getOrganizationReversionCategoryCode());
detail.setOrganizationReversionCategory(category);
details.add(detail);
}
}
Collections.sort(details, new CategoryComparator());
}
}
/**
* A method that prevents lookups from refreshing the Organization Reversion Detail list (because, if it is refreshed before a
* save...it ends up destroying the list).
*
* @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#isRelationshipRefreshable(java.lang.Class, java.lang.String)
*/
@Override
protected boolean isRelationshipRefreshable(Class boClass, String relationshipName) {
if (relationshipName.equals("organizationReversionDetail")) {
return false;
} else {
return super.isRelationshipRefreshable(boClass, relationshipName);
}
}
/**
* Determines if this maint doc is inactivating an organization reversion
* @return true if the document is inactivating an active organization reversion, false otherwise
*/
protected boolean isInactivatingOrganizationReversion() {
// the account has to be closed on the new side when editing in order for it to be possible that we are closing the account
if (KRADConstants.MAINTENANCE_EDIT_ACTION.equals(getMaintenanceAction()) && !((OrganizationReversion) getBusinessObject()).isActive()) {
OrganizationReversion existingOrganizationReversionFromDB = retrieveExistingOrganizationReversion();
if (ObjectUtils.isNotNull(existingOrganizationReversionFromDB)) {
// now see if the original account was not closed, in which case, we are closing the account
if (existingOrganizationReversionFromDB.isActive()) {
return true;
}
}
}
return false;
}
/**
* Determines if this maint doc is activating an organization reversion
* @return true if the document is activating an inactive organization reversion, false otherwise
*/
protected boolean isActivatingOrganizationReversion() {
// the account has to be closed on the new side when editing in order for it to be possible that we are closing the account
if (KRADConstants.MAINTENANCE_EDIT_ACTION.equals(getMaintenanceAction()) && ((OrganizationReversion) getBusinessObject()).isActive()) {
OrganizationReversion existingOrganizationReversionFromDB = retrieveExistingOrganizationReversion();
if (ObjectUtils.isNotNull(existingOrganizationReversionFromDB)) {
// now see if the original account was not closed, in which case, we are closing the account
if (!existingOrganizationReversionFromDB.isActive()) {
return true;
}
}
}
return false;
}
/**
* Grabs the old version of this org reversion from the database
* @return the old version of this organization reversion
*/
protected OrganizationReversion retrieveExistingOrganizationReversion() {
OrganizationReversion orgRev = (OrganizationReversion)getBusinessObject();
OrganizationReversion oldOrgRev = getOrganizationReversionService().getByPrimaryId(orgRev.getUniversityFiscalYear(), orgRev.getChartOfAccountsCode(), orgRev.getOrganizationCode());
return oldOrgRev;
}
/**
* Overridden to trickle down inactivation or activation to details
* @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#saveBusinessObject()
*/
@Override
public void saveBusinessObject() {
super.saveBusinessObject();
if (isActivatingOrganizationReversion()) {
getTrickleDownInactivationService().trickleDownActiveOrganizationReversionDetails((OrganizationReversion)getBusinessObject(), getDocumentNumber());
} else if (isInactivatingOrganizationReversion()) {
getTrickleDownInactivationService().trickleDownInactiveOrganizationReversionDetails((OrganizationReversion)getBusinessObject(), getDocumentNumber());
}
}
/**
* @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#getSections(org.kuali.rice.kns.document.MaintenanceDocument, org.kuali.rice.kns.maintenance.Maintainable)
*
* KRAD Conversion: Inquirable performs conditional display/hiding of the fields/sections on the inquiry
* But all field/section definitions are in data dictionary for bo Organization.
*/
@Override
public List getSections(MaintenanceDocument document, Maintainable oldMaintainable) {
List<Section> sections = super.getSections(document, oldMaintainable);
for (Section section : sections) {
for (Row row : section.getRows()) {
List<Field> updatedFields = new ArrayList<Field>();
for (Field field : row.getFields()) {
if (shouldIncludeField(field)) {
updatedFields.add(field);
}
}
row.setFields(updatedFields);
}
}
return sections;
}
/**
* Determines if the given field should be included in the updated row, once we take out inactive categories
* @param field the field to check
* @return true if the field should be included (ie, it doesn't describe an organization reversion with an inactive category); false otherwise
*
* KRAD Conversion: Determines if fields should be included in the section.
* But all field/section definitions are in data dictionary.
*/
protected boolean shouldIncludeField(Field field) {
boolean includeField = true;
if (field.getContainerRows() != null) {
for (Row containerRow : field.getContainerRows()) {
for (Field containedField : containerRow.getFields()) {
if (containedField.getPropertyName().matches("organizationReversionDetail\\[\\d+\\]\\.organizationReversionCategory\\.organizationReversionCategoryName")) {
final String categoryValue = containedField.getPropertyValue();
includeField = getOrganizationReversionService().isCategoryActiveByName(categoryValue);
}
}
}
}
return includeField;
}
protected OrganizationReversionService getOrganizationReversionService() {
if ( organizationReversionService == null ) {
organizationReversionService = SpringContext.getBean(OrganizationReversionService.class);
}
return organizationReversionService;
}
protected static OrganizationReversionDetailTrickleDownInactivationService getTrickleDownInactivationService() {
if ( trickleDownInactivationService == null ) {
trickleDownInactivationService = SpringContext.getBean(OrganizationReversionDetailTrickleDownInactivationService.class);
}
return trickleDownInactivationService;
}
}