/*
* 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.module.cam.document.validation.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.coa.businessobject.Account;
import org.kuali.kfs.coa.businessobject.ObjectCode;
import org.kuali.kfs.coa.service.ObjectCodeService;
import org.kuali.kfs.integration.cam.CapitalAssetManagementModuleService;
import org.kuali.kfs.module.cam.CamsConstants;
import org.kuali.kfs.module.cam.CamsConstants.DocumentTypeName;
import org.kuali.kfs.module.cam.CamsKeyConstants;
import org.kuali.kfs.module.cam.CamsPropertyConstants;
import org.kuali.kfs.module.cam.businessobject.Asset;
import org.kuali.kfs.module.cam.businessobject.AssetGlobal;
import org.kuali.kfs.module.cam.businessobject.AssetGlobalDetail;
import org.kuali.kfs.module.cam.businessobject.AssetPaymentDetail;
import org.kuali.kfs.module.cam.businessobject.AssetType;
import org.kuali.kfs.module.cam.document.gl.AssetGlobalGeneralLedgerPendingEntrySource;
import org.kuali.kfs.module.cam.document.service.AssetAcquisitionTypeService;
import org.kuali.kfs.module.cam.document.service.AssetGlobalService;
import org.kuali.kfs.module.cam.document.service.AssetLocationService;
import org.kuali.kfs.module.cam.document.service.AssetLocationService.LocationField;
import org.kuali.kfs.module.cam.document.service.AssetPaymentService;
import org.kuali.kfs.module.cam.document.service.AssetService;
import org.kuali.kfs.module.cam.document.service.PaymentSummaryService;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.kfs.sys.businessobject.Building;
import org.kuali.kfs.sys.businessobject.FinancialSystemDocumentHeader;
import org.kuali.kfs.sys.businessobject.Room;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.document.authorization.FinancialSystemMaintenanceDocumentAuthorizerBase;
import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService;
import org.kuali.rice.core.api.datetime.DateTimeService;
import org.kuali.rice.core.api.parameter.ParameterEvaluator;
import org.kuali.rice.core.api.parameter.ParameterEvaluatorService;
import org.kuali.rice.core.api.util.RiceKeyConstants;
import org.kuali.rice.core.api.util.type.KualiDecimal;
import org.kuali.rice.core.web.format.CurrencyFormatter;
import org.kuali.rice.coreservice.framework.parameter.ParameterService;
import org.kuali.rice.kns.document.MaintenanceDocument;
import org.kuali.rice.kns.maintenance.Maintainable;
import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
import org.kuali.rice.kns.service.DataDictionaryService;
import org.kuali.rice.kns.service.KNSServiceLocator;
import org.kuali.rice.krad.bo.DocumentHeader;
import org.kuali.rice.krad.bo.PersistableBusinessObject;
import org.kuali.rice.krad.datadictionary.ReferenceDefinition;
import org.kuali.rice.krad.document.Document;
import org.kuali.rice.krad.exception.ValidationException;
import org.kuali.rice.krad.service.BusinessObjectService;
import org.kuali.rice.krad.service.DocumentDictionaryService;
import org.kuali.rice.krad.util.GlobalVariables;
import org.kuali.rice.krad.util.KRADPropertyConstants;
import org.kuali.rice.krad.util.ObjectUtils;
import org.kuali.rice.location.api.campus.Campus;
import org.kuali.rice.location.api.campus.CampusService;
/**
* Rule implementation for Asset Global document.
*/
public class AssetGlobalRule extends MaintenanceDocumentRuleBase {
private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AssetGlobalRule.class);
protected static final Map<LocationField, String> LOCATION_FIELD_MAP = new HashMap<LocationField, String>();
static {
LOCATION_FIELD_MAP.put(LocationField.CAMPUS_CODE, CamsPropertyConstants.AssetGlobalDetail.CAMPUS_CODE);
LOCATION_FIELD_MAP.put(LocationField.BUILDING_CODE, CamsPropertyConstants.AssetGlobalDetail.BUILDING_CODE);
LOCATION_FIELD_MAP.put(LocationField.ROOM_NUMBER, CamsPropertyConstants.AssetGlobalDetail.BUILDING_ROOM_NUMBER);
LOCATION_FIELD_MAP.put(LocationField.SUB_ROOM_NUMBER, CamsPropertyConstants.AssetGlobalDetail.BUILDING_SUB_ROOM_NUMBER);
LOCATION_FIELD_MAP.put(LocationField.CONTACT_NAME, CamsPropertyConstants.AssetGlobalDetail.OFF_CAMPUS_NAME);
LOCATION_FIELD_MAP.put(LocationField.STREET_ADDRESS, CamsPropertyConstants.AssetGlobalDetail.OFF_CAMPUS_ADDRESS);
LOCATION_FIELD_MAP.put(LocationField.CITY_NAME, CamsPropertyConstants.AssetGlobalDetail.OFF_CAMPUS_CITY_NAME);
LOCATION_FIELD_MAP.put(LocationField.STATE_CODE, CamsPropertyConstants.AssetGlobalDetail.OFF_CAMPUS_STATE_CODE);
LOCATION_FIELD_MAP.put(LocationField.ZIP_CODE, CamsPropertyConstants.AssetGlobalDetail.OFF_CAMPUS_ZIP_CODE);
LOCATION_FIELD_MAP.put(LocationField.COUNTRY_CODE, CamsPropertyConstants.AssetGlobalDetail.OFF_CAMPUS_COUNTRY_CODE);
}
/**
* This method checks reference fields when adding new payment into collection.
*
* @param assetGlobal
* @param assetPaymentDetail
* @return
*/
protected boolean checkReferenceExists(AssetGlobal assetGlobal, AssetPaymentDetail assetPaymentDetail) {
boolean valid = true;
// validate required field for object code. Skip the error message because the maintenance DD 'defaultExistenceChecks' can
// generate the same error message. We won't duplicate it.
if (StringUtils.isBlank(assetPaymentDetail.getFinancialObjectCode())) {
valid = false;
}
// Validate Financial Posted date
if (assetPaymentDetail.getExpenditureFinancialDocumentPostedDate() != null) {
valid &= validatePostedDate(assetPaymentDetail);
}
if (valid) {
// Check for ObjectCode
if (StringUtils.isNotBlank(assetPaymentDetail.getFinancialObjectCode())) {
assetPaymentDetail.refreshReferenceObject(KFSPropertyConstants.OBJECT_CODE);
if (ObjectUtils.isNull(assetPaymentDetail.getObjectCode())) {
String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.AssetPaymentDetail.FINANCIAL_OBJECT_CODE).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.FINANCIAL_OBJECT_CODE, RiceKeyConstants.ERROR_EXISTENCE, label);
valid &= false;
}
}
}
if (StringUtils.isBlank(assetGlobal.getAcquisitionTypeCode()) || ObjectUtils.isNull(assetGlobal.getAcquisitionType())) {
putFieldError(CamsPropertyConstants.AssetGlobal.ACQUISITION_TYPE_CODE, CamsKeyConstants.AssetGlobal.ERROR_ACQUISITION_TYPE_CODE_REQUIRED);
valid &= false;
}
if (StringUtils.isBlank(assetGlobal.getInventoryStatusCode())) {
putFieldError(CamsPropertyConstants.AssetGlobal.INVENTORY_STATUS_CODE, CamsKeyConstants.AssetGlobal.ERROR_INVENTORY_STATUS_REQUIRED_FOR_PAYMENT);
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.SEQUENCE_NUMBER, CamsKeyConstants.AssetGlobal.ERROR_ASSET_PAYMENT_DEPENDENCY);
valid &= false;
}
if (StringUtils.isBlank(assetGlobal.getCapitalAssetTypeCode())) {
putFieldError(CamsPropertyConstants.AssetGlobal.CAPITAL_ASSET_TYPE_CODE, CamsKeyConstants.AssetGlobal.ERROR_ASSET_TYPE_REQUIRED);
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.SEQUENCE_NUMBER, CamsKeyConstants.AssetGlobal.ERROR_ASSET_PAYMENT_DEPENDENCY);
valid &= false;
}
// check for existence and active when not separating. This can't be done in the DD because we have a condition on it.
// Note: Even though on separate the payment lines can't be edited we still can't force the rules because data may have
// gone inactive since then.
if (!getAssetGlobalService().isAssetSeparate(assetGlobal)) {
assetPaymentDetail.refreshReferenceObject(CamsPropertyConstants.AssetPaymentDetail.ACCOUNT);
if (StringUtils.isBlank(assetPaymentDetail.getAccountNumber()) || isAccountInvalid(assetPaymentDetail.getAccount())) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.ACCOUNT_NUMBER, CamsKeyConstants.AssetGlobal.ERROR_PAYMENT_ACCT_NOT_VALID, new String[] { assetPaymentDetail.getChartOfAccountsCode(), assetPaymentDetail.getAccountNumber() });
valid &= false;
}
else if (!StringUtils.isBlank(assetPaymentDetail.getAccountNumber()) && !assetPaymentDetail.getAccount().isActive()) {
String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.AssetPaymentDetail.ACCOUNT_NUMBER).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.ACCOUNT_NUMBER, RiceKeyConstants.ERROR_INACTIVE, label);
valid &= false;
}
assetPaymentDetail.refreshReferenceObject(KFSPropertyConstants.SUB_ACCOUNT);
if (!StringUtils.isBlank(assetPaymentDetail.getSubAccountNumber()) && ObjectUtils.isNull(assetPaymentDetail.getSubAccount())) {
String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.AssetPaymentDetail.SUB_ACCOUNT_NUMBER).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.SUB_ACCOUNT_NUMBER, RiceKeyConstants.ERROR_EXISTENCE, label);
valid &= false;
}
else if (!StringUtils.isBlank(assetPaymentDetail.getSubAccountNumber()) && !assetPaymentDetail.getSubAccount().isActive()) {
String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.AssetPaymentDetail.SUB_ACCOUNT_NUMBER).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.SUB_ACCOUNT_NUMBER, RiceKeyConstants.ERROR_INACTIVE, label);
valid &= false;
}
assetPaymentDetail.refreshReferenceObject(KFSPropertyConstants.OBJECT_CODE);
if (!StringUtils.isBlank(assetPaymentDetail.getFinancialObjectCode()) && ObjectUtils.isNull(assetPaymentDetail.getObjectCode())) {
String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.AssetPaymentDetail.FINANCIAL_OBJECT_CODE).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.FINANCIAL_OBJECT_CODE, RiceKeyConstants.ERROR_EXISTENCE, label);
valid &= false;
}
else if (!StringUtils.isBlank(assetPaymentDetail.getFinancialObjectCode()) && !assetPaymentDetail.getObjectCode().isActive()) {
String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.AssetPaymentDetail.FINANCIAL_OBJECT_CODE).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.FINANCIAL_OBJECT_CODE, RiceKeyConstants.ERROR_INACTIVE, label);
valid &= false;
}
assetPaymentDetail.refreshReferenceObject(KFSPropertyConstants.SUB_OBJECT_CODE);
if (!StringUtils.isBlank(assetPaymentDetail.getFinancialSubObjectCode()) && ObjectUtils.isNull(assetPaymentDetail.getSubObjectCode())) {
String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.AssetPaymentDetail.SUB_OBJECT_CODE).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.SUB_OBJECT_CODE, RiceKeyConstants.ERROR_EXISTENCE, label);
valid &= false;
}
else if (!StringUtils.isBlank(assetPaymentDetail.getFinancialSubObjectCode()) && !assetPaymentDetail.getSubObjectCode().isActive()) {
String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.AssetPaymentDetail.SUB_OBJECT_CODE).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.SUB_OBJECT_CODE, RiceKeyConstants.ERROR_INACTIVE, label);
valid &= false;
}
assetPaymentDetail.refreshReferenceObject(KFSPropertyConstants.PROJECT);
if (!StringUtils.isBlank(assetPaymentDetail.getProjectCode()) && ObjectUtils.isNull(assetPaymentDetail.getProject())) {
String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.AssetPaymentDetail.PROJECT_CODE).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.PROJECT_CODE, RiceKeyConstants.ERROR_EXISTENCE, label);
valid &= false;
}
else if (!StringUtils.isBlank(assetPaymentDetail.getProjectCode()) && !assetPaymentDetail.getProject().isActive()) {
String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.AssetPaymentDetail.PROJECT_CODE).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.PROJECT_CODE, RiceKeyConstants.ERROR_INACTIVE, label);
valid &= false;
}
assetPaymentDetail.refreshReferenceObject(CamsPropertyConstants.AssetPaymentDetail.ORIGINATION);
if (!StringUtils.isBlank(assetPaymentDetail.getExpenditureFinancialSystemOriginationCode()) && ObjectUtils.isNull(assetPaymentDetail.getExpenditureFinancialSystemOrigination())) {
String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.AssetPaymentDetail.ORIGINATION_CODE).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.ORIGINATION_CODE, RiceKeyConstants.ERROR_EXISTENCE, label);
valid &= false;
}
else if (!StringUtils.isBlank(assetPaymentDetail.getExpenditureFinancialSystemOriginationCode()) && !assetPaymentDetail.getExpenditureFinancialSystemOrigination().isActive()) {
String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.AssetPaymentDetail.ORIGINATION_CODE).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.ORIGINATION_CODE, RiceKeyConstants.ERROR_INACTIVE, label);
valid &= false;
}
if (!StringUtils.isBlank(assetPaymentDetail.getExpenditureFinancialDocumentTypeCode()) && ObjectUtils.isNull(assetPaymentDetail.getExpenditureFinancialSystemDocumentTypeCode())) {
String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.AssetPaymentDetail.DOCUMENT_TYPE_CODE).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.DOCUMENT_TYPE_CODE, RiceKeyConstants.ERROR_EXISTENCE, label);
valid &= false;
return valid;
}
if (!StringUtils.isBlank(assetPaymentDetail.getExpenditureFinancialDocumentTypeCode()) && !assetPaymentDetail.getExpenditureFinancialSystemDocumentTypeCode().isActive()) {
String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.AssetPaymentDetail.DOCUMENT_TYPE_CODE).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.DOCUMENT_TYPE_CODE, RiceKeyConstants.ERROR_INACTIVE, label);
valid &= false;
}
}
return valid;
}
/**
* This method checks reference fields when adding one shared location information into collection.
*
* @param assetGlobalDetail
* @return
*/
protected boolean checkReferenceExists(AssetGlobalDetail assetGlobalDetail) {
boolean valid = true;
if (StringUtils.isNotBlank(assetGlobalDetail.getCampusCode())) {
Campus campus = SpringContext.getBean(CampusService.class).getCampus(assetGlobalDetail.getCampusCode());
if (ObjectUtils.isNull(campus)) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.CAMPUS_CODE, CamsKeyConstants.AssetLocation.ERROR_INVALID_CAMPUS_CODE, assetGlobalDetail.getCampusCode());
valid &= false;
}
else if (!campus.isActive()) {
String label = getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(Campus.class.getName()).getAttributeDefinition(KFSPropertyConstants.CAMPUS_CODE).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.CAMPUS_CODE, RiceKeyConstants.ERROR_INACTIVE, label);
valid &= false;
}
}
if (StringUtils.isNotBlank(assetGlobalDetail.getBuildingCode())) {
Map<String, String> objectKeys = new HashMap<String, String>();
objectKeys.put(CamsPropertyConstants.AssetGlobalDetail.CAMPUS_CODE, assetGlobalDetail.getCampusCode());
objectKeys.put(CamsPropertyConstants.AssetGlobalDetail.BUILDING_CODE, assetGlobalDetail.getBuildingCode());
Building building = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(Building.class, objectKeys);
if (ObjectUtils.isNull(building)) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.BUILDING_CODE, CamsKeyConstants.AssetLocation.ERROR_INVALID_BUILDING_CODE, assetGlobalDetail.getBuildingCode(), assetGlobalDetail.getCampusCode());
valid &= false;
}
else if (!building.isActive()) {
String label = getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(Building.class.getName()).getAttributeDefinition(KFSPropertyConstants.BUILDING_CODE).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.BUILDING_CODE, RiceKeyConstants.ERROR_INACTIVE, label);
valid &= false;
}
}
if (StringUtils.isNotBlank(assetGlobalDetail.getBuildingRoomNumber())) {
Map<String, String> objectKeys = new HashMap<String, String>();
objectKeys.put(CamsPropertyConstants.AssetGlobalDetail.CAMPUS_CODE, assetGlobalDetail.getCampusCode());
objectKeys.put(CamsPropertyConstants.AssetGlobalDetail.BUILDING_CODE, assetGlobalDetail.getBuildingCode());
objectKeys.put(CamsPropertyConstants.AssetGlobalDetail.BUILDING_ROOM_NUMBER, assetGlobalDetail.getBuildingRoomNumber());
Room room = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(Room.class, objectKeys);
if (ObjectUtils.isNull(room)) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.BUILDING_ROOM_NUMBER, CamsKeyConstants.AssetLocation.ERROR_INVALID_ROOM_NUMBER, assetGlobalDetail.getBuildingCode(), assetGlobalDetail.getBuildingRoomNumber(), assetGlobalDetail.getCampusCode());
valid &= false;
}
else if (!room.isActive()) {
String label = getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(Room.class.getName()).getAttributeDefinition(KFSPropertyConstants.BUILDING_ROOM_NUMBER).getLabel();
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.BUILDING_ROOM_NUMBER, RiceKeyConstants.ERROR_INACTIVE, label);
valid &= false;
}
}
return valid;
}
protected boolean isCapitalStatus(AssetGlobal assetGlobal) {
return getParameterService().getParameterValuesAsString(Asset.class, CamsConstants.Parameters.CAPITAL_ASSET_STATUS_CODES).contains(assetGlobal.getInventoryStatusCode());
}
protected boolean isStatusCodeRetired(String statusCode) {
return getParameterService().getParameterValuesAsString(Asset.class, CamsConstants.Parameters.RETIRED_STATUS_CODES).contains(statusCode);
}
@Override
public boolean processCustomAddCollectionLineBusinessRules(MaintenanceDocument document, String collectionName, PersistableBusinessObject line) {
boolean success = super.processCustomAddCollectionLineBusinessRules(document, collectionName, line);
if (GlobalVariables.getMessageMap().hasErrors()) {
return false;
}
AssetGlobal assetGlobal = (AssetGlobal) document.getNewMaintainableObject().getBusinessObject();
List<AssetGlobalDetail> assetSharedDetails = assetGlobal.getAssetSharedDetails();
if (CamsPropertyConstants.AssetGlobal.ASSET_SHARED_DETAILS.equals(collectionName)) {
// handle location information
AssetGlobalDetail assetGlobalDetail = (AssetGlobalDetail) line;
success &= checkReferenceExists(assetGlobalDetail);
success &= validateLocation(assetGlobal, assetGlobalDetail);
// qty. of assets (unique) to be created
success &= validateLocationQuantity(line);
}
else if (StringUtils.isNotBlank(collectionName) && collectionName.contains(CamsPropertyConstants.AssetGlobalDetail.ASSET_UNIQUE_DETAILS)) {
// handle unique information
AssetGlobalDetail assetUniqueDetail = (AssetGlobalDetail) line;
String campusTagNumber = assetUniqueDetail.getCampusTagNumber();
if (StringUtils.isNotBlank(campusTagNumber)) {
success &= validateTagDuplication(assetSharedDetails, campusTagNumber);
}
}
else if (CamsPropertyConstants.AssetGlobal.ASSET_PAYMENT_DETAILS.equals(collectionName)) {
AssetPaymentDetail assetPaymentDetail = (AssetPaymentDetail) line;
if (success &= checkReferenceExists(assetGlobal, assetPaymentDetail)) {
success &= validatePaymentLine(document, assetGlobal, assetPaymentDetail);
success &= checkNegativeOrZeroPayment(document, assetPaymentDetail);
}
}
// only for "Asset Separate" document
if (getAssetGlobalService().isAssetSeparate(assetGlobal)) {
// total cost must be > 0
success &= validateTotalCostAmount(assetGlobal);
}
return success;
}
/**
* Validated the location quantity
*
* @param line
* @return boolean
*/
protected boolean validateLocationQuantity(PersistableBusinessObject line) {
boolean success = true;
AssetGlobalDetail assetGlobalDetail = (AssetGlobalDetail) line;
if (assetGlobalDetail.getLocationQuantity() <= 0) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.LOCATION_QUANTITY, CamsKeyConstants.AssetSeparate.ERROR_ZERO_OR_NEGATIVE_LOCATION_QUANTITY, assetGlobalDetail.getLocationQuantity().toString());
success &= false;
}
return success;
}
protected boolean validateTagDuplication(List<AssetGlobalDetail> assetSharedDetails, String campusTagNumber) {
boolean success = true;
if (!campusTagNumber.equalsIgnoreCase(CamsConstants.Asset.NON_TAGGABLE_ASSET)) {
for (AssetGlobalDetail assetSharedDetail : assetSharedDetails) {
List<AssetGlobalDetail> assetGlobalUniqueDetails = assetSharedDetail.getAssetGlobalUniqueDetails();
for (AssetGlobalDetail assetSharedUniqueDetail : assetGlobalUniqueDetails) {
if (campusTagNumber.equalsIgnoreCase(assetSharedUniqueDetail.getCampusTagNumber())) {
success &= false;
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.CAMPUS_TAG_NUMBER, CamsKeyConstants.AssetGlobal.ERROR_CAMPUS_TAG_NUMBER_DUPLICATE, campusTagNumber);
}
}
}
if (success) {
List<Asset> tagMatches = getAssetService().findActiveAssetsMatchingTagNumber(campusTagNumber);
if (!tagMatches.isEmpty()) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.CAMPUS_TAG_NUMBER, CamsKeyConstants.AssetGlobal.ERROR_CAMPUS_TAG_NUMBER_DUPLICATE, campusTagNumber);
success &= false;
}
}
}
return success;
}
protected boolean validateTagDuplication(List<AssetGlobalDetail> assetSharedDetails) {
HashSet<String> assetTags = new HashSet<String>();
boolean success = true;
int parentIndex = -1;
int childIndex = -1;
for (AssetGlobalDetail assetSharedDetail : assetSharedDetails) {
parentIndex++;
List<AssetGlobalDetail> assetGlobalUniqueDetails = assetSharedDetail.getAssetGlobalUniqueDetails();
for (AssetGlobalDetail assetSharedUniqueDetail : assetGlobalUniqueDetails) {
childIndex++;
String campusTagNumber = assetSharedUniqueDetail.getCampusTagNumber();
if (StringUtils.isNotBlank(campusTagNumber) && !assetTags.add(campusTagNumber) && !campusTagNumber.equalsIgnoreCase(CamsConstants.Asset.NON_TAGGABLE_ASSET)) {
success &= false;
String errorPath = MAINTAINABLE_ERROR_PREFIX + CamsPropertyConstants.AssetGlobal.ASSET_SHARED_DETAILS + "[" + parentIndex + "]." + CamsPropertyConstants.AssetGlobalDetail.ASSET_UNIQUE_DETAILS + "[" + childIndex + "]";
GlobalVariables.getMessageMap().addToErrorPath(errorPath);
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.CAMPUS_TAG_NUMBER, CamsKeyConstants.AssetGlobal.ERROR_CAMPUS_TAG_NUMBER_DUPLICATE, campusTagNumber);
GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
}
}
childIndex = -1;
for (AssetGlobalDetail assetSharedUniqueDetail : assetGlobalUniqueDetails) {
childIndex++;
String campusTagNumber = assetSharedUniqueDetail.getCampusTagNumber();
if (StringUtils.isNotBlank(campusTagNumber) && !campusTagNumber.equalsIgnoreCase(CamsConstants.Asset.NON_TAGGABLE_ASSET)) {
List<Asset> tagMatches = getAssetService().findActiveAssetsMatchingTagNumber(campusTagNumber);
if (!tagMatches.isEmpty()) {
success &= false;
String errorPath = MAINTAINABLE_ERROR_PREFIX + CamsPropertyConstants.AssetGlobal.ASSET_SHARED_DETAILS + "[" + parentIndex + "]." + CamsPropertyConstants.AssetGlobalDetail.ASSET_UNIQUE_DETAILS + "[" + childIndex + "]";
GlobalVariables.getMessageMap().addToErrorPath(errorPath);
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.CAMPUS_TAG_NUMBER, CamsKeyConstants.AssetGlobal.ERROR_CAMPUS_TAG_NUMBER_DUPLICATE, campusTagNumber);
GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
}
}
}
}
return success;
}
protected boolean validatePaymentLine(MaintenanceDocument maintenanceDocument, AssetGlobal assetGlobal, AssetPaymentDetail assetPaymentDetail) {
boolean success = true;
// If Acquisition type is "New" or "non-capital", check required fields including Document number, Document type code,
// Posted date.
if (getAssetGlobalService().existsInGroup(getAssetGlobalService().getNewAcquisitionTypeCode(), assetGlobal.getAcquisitionTypeCode()) || !getAssetGlobalService().existsInGroup(getAssetGlobalService().getCapitalObjectAcquisitionCodeGroup(), assetGlobal.getAcquisitionTypeCode())) {
success &= checkRequiredFieldsForNewOrNonCapital(assetPaymentDetail);
}
else {
// Validate Financial Document Type Code
success &= validateDocumentTypeForNonNew(assetGlobal.getAcquisitionTypeCode(), assetPaymentDetail);
}
assetPaymentDetail.refreshReferenceObject(KFSPropertyConstants.OBJECT_CODE);
success &= validateObjectCode(assetPaymentDetail.getObjectCode(), assetGlobal);
return success;
}
/**
* "Add Negative Payment" permission check.
*
* @param maintenanceDocument
* @param assetPaymentDetail
* @return
*/
protected boolean checkNegativeOrZeroPayment(MaintenanceDocument maintenanceDocument, AssetPaymentDetail assetPaymentDetail) {
boolean success = true;
FinancialSystemMaintenanceDocumentAuthorizerBase documentAuthorizer = (FinancialSystemMaintenanceDocumentAuthorizerBase) SpringContext.getBean(DocumentDictionaryService.class).getDocumentAuthorizer(maintenanceDocument);
boolean isAuthorized = documentAuthorizer.isAuthorized(maintenanceDocument, CamsConstants.CAM_MODULE_CODE, CamsConstants.PermissionNames.ADD_NEGATIVE_PAYMENTS, GlobalVariables.getUserSession().getPerson().getPrincipalId());
if (!isAuthorized && assetPaymentDetail.getAmount() != null && assetPaymentDetail.getAmount().isNegative()) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.AMOUNT, CamsKeyConstants.AssetGlobal.ERROR_INVALID_PAYMENT_AMOUNT);
success = false;
}
// amount can not be zero for any user
if (assetPaymentDetail.getAmount().isZero()) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.AMOUNT, CamsKeyConstants.AssetGlobal.ERROR_INVALID_PAYMENT_AMOUNT);
success = false;
}
return success;
}
/**
* This method check the required fields for acquisition type New .
*
* @param assetPaymentDetail
* @return
*/
protected boolean checkRequiredFieldsForNewOrNonCapital(AssetPaymentDetail assetPaymentDetail) {
boolean valid = true;
if (StringUtils.isBlank(assetPaymentDetail.getExpenditureFinancialDocumentNumber())) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.DOCUMENT_NUMBER, CamsKeyConstants.AssetGlobal.ERROR_EXPENDITURE_FINANCIAL_DOCUMENT_NUMBER_REQUIRED);
valid &= false;
}
if (assetPaymentDetail.getExpenditureFinancialDocumentPostedDate() == null) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.DOCUMENT_POSTING_DATE, CamsKeyConstants.AssetGlobal.ERROR_DOCUMENT_POSTING_DATE_REQUIRED);
valid &= false;
}
if (StringUtils.isBlank(assetPaymentDetail.getExpenditureFinancialDocumentTypeCode())) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.DOCUMENT_TYPE_CODE, CamsKeyConstants.AssetGlobal.ERROR_EXPENDITURE_FINANCIAL_DOCUMENT_TYPE_CODE_REQUIRED);
valid &= false;
}
return valid;
}
/**
* Validates the posted date payment posted date can't be a future date
*
* @param assetPaymentDetail
* @return boolean
*/
protected boolean validatePostedDate(AssetPaymentDetail assetPaymentDetail) {
boolean valid = true;
Date currentDate = SpringContext.getBean(DateTimeService.class).getCurrentDate();
if (!getAssetPaymentService().extractPostedDatePeriod(assetPaymentDetail)) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.DOCUMENT_POSTING_FISCAL_YEAR, CamsKeyConstants.AssetGlobal.ERROR_UNIVERSITY_NOT_DEFINED_FOR_DATE, new String[] { assetPaymentDetail.getExpenditureFinancialDocumentPostedDate().toString() });
valid &= false;
}
else if (assetPaymentDetail.getExpenditureFinancialDocumentPostedDate().compareTo(currentDate) > 0) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.DOCUMENT_POSTING_DATE, CamsKeyConstants.Payment.ERROR_INVALID_DOC_POST_DATE);
valid = false;
}
return valid;
}
/**
* When acquisition type code is Capital (Gifts, Transfer-in, State excess, and Found), payment document type code will be
* assigned to AA for Add Asset Document.
*
* @param documentTypeCode
* @return
*/
protected boolean validateDocumentTypeForNonNew(String acquisitionTypeCode, AssetPaymentDetail assetPaymentDetail) {
String documentTypeCode = assetPaymentDetail.getExpenditureFinancialDocumentTypeCode();
boolean valid = true;
if (StringUtils.isNotBlank(acquisitionTypeCode) && getAssetGlobalService().existsInGroup(getAssetGlobalService().getNonNewAcquisitionCodeGroup(), acquisitionTypeCode)) {
if (StringUtils.isNotBlank(documentTypeCode) && !CamsConstants.DocumentTypeName.ASSET_ADD_GLOBAL.equalsIgnoreCase(documentTypeCode)) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetPaymentDetail.DOCUMENT_TYPE_CODE, CamsKeyConstants.AssetGlobal.ERROR_DOCUMENT_TYPE_CODE_NOT_ALLOWED, documentTypeCode);
valid = false;
}
else {
// system set document type code as 'AA'
assetPaymentDetail.setExpenditureFinancialDocumentTypeCode(CamsConstants.DocumentTypeName.ASSET_ADD_GLOBAL);
}
}
return valid;
}
/**
* Check object code is set to capital only when the status is capital.
*
* @param assetGlobal
* @param assetPaymentDetail
* @return valid
*/
protected boolean validateObjectCode(ObjectCode objectCode, AssetGlobal assetGlobal) {
boolean valid = true;
// The acquisition type code of (F, G, N, S, T) requires a capital object code.
ParameterService parameterService = SpringContext.getBean(ParameterService.class);
ParameterEvaluator parameterEvaluator = /*REFACTORME*/SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(AssetGlobal.class, CamsConstants.Parameters.VALID_OBJECT_SUB_TYPES_BY_ACQUISITION_TYPE, CamsConstants.Parameters.INVALID_OBJECT_SUB_TYPES_BY_ACQUISITION_TYPE, assetGlobal.getAcquisitionTypeCode(), objectCode.getFinancialObjectSubTypeCode());
valid &= parameterEvaluator.evaluateAndAddError(ObjectCode.class, CamsPropertyConstants.Asset.FINANCIAL_OBJECT_SUB_TYP_CODE, CamsPropertyConstants.AssetPaymentDetail.FINANCIAL_OBJECT_CODE);
return valid;
}
protected boolean isAccountInvalid(Account account) {
return ObjectUtils.isNull(account) || account.isExpired();
}
@Override
protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
AssetGlobal assetGlobal = (AssetGlobal) document.getNewMaintainableObject().getBusinessObject();
List<AssetGlobalDetail> assetSharedDetails = assetGlobal.getAssetSharedDetails();
boolean success = super.processCustomRouteDocumentBusinessRules(document);
if (GlobalVariables.getMessageMap().hasErrors()) {
return false;
}
// need at least one asset location
if (assetSharedDetails.isEmpty() || assetSharedDetails.get(0).getAssetGlobalUniqueDetails().isEmpty()) {
putFieldError(CamsPropertyConstants.AssetGlobal.ASSET_SHARED_DETAILS, CamsKeyConstants.AssetGlobal.MIN_ONE_ASSET_REQUIRED);
success &= false;
}
// Capital Asset must have payment zone.
if (isCapitalStatus(assetGlobal) && assetGlobal.getAssetPaymentDetails().isEmpty()) {
putFieldError(CamsPropertyConstants.AssetGlobal.ASSET_PAYMENT_DETAILS, CamsKeyConstants.AssetGlobal.MIN_ONE_PAYMENT_REQUIRED);
success &= false;
}
// check total amount for Asset Create
if (!getAssetGlobalService().isAssetSeparate(assetGlobal)) {
success &= validateAssetTotalAmount(document);
}
else {
// only for "Asset Separate" document
if (getAssetPaymentService().getAssetPaymentDetailQuantity(assetGlobal) >= 10) {
/*
* @TODO KULCAP-828 putFieldError(CamsPropertyConstants.AssetGlobal.ASSET_SHARED_DETAILS,
* CamsKeyConstants.AssetSeparate.ERROR_ASSET_SPLIT_MAX_LIMIT); success &= false;
*/
}
// new source payments must be greater than the capital asset cost amount
KualiDecimal totalSeparateSourceAmount = getAssetGlobalService().getUniqueAssetsTotalAmount(assetGlobal);
if (totalSeparateSourceAmount.isGreaterThan(assetGlobal.getTotalCostAmount())) {
putFieldError(CamsPropertyConstants.AssetGlobal.ASSET_SHARED_DETAILS, CamsKeyConstants.AssetSeparate.ERROR_INVALID_TOTAL_SEPARATE_SOURCE_AMOUNT, new String[] { assetGlobal.getSeparateSourceCapitalAssetNumber().toString() });
success &= false;
}
// only active capital assets can be separated
assetGlobal.refreshReferenceObject(CamsPropertyConstants.AssetGlobal.SEPARATE_SOURCE_CAPITAL_ASSET);
if (ObjectUtils.isNotNull(assetGlobal.getSeparateSourceCapitalAsset())) {
if (!getAssetService().isCapitalAsset(assetGlobal.getSeparateSourceCapitalAsset())) {
if (StringUtils.isNotBlank(assetGlobal.getAcquisitionTypeCode())) {
putFieldError(CamsPropertyConstants.AssetGlobal.ACQUISITION_TYPE_CODE, CamsKeyConstants.AssetSeparate.ERROR_NON_CAPITAL_ASSET_SEPARATE_REQUIRED);
success &= false;
}
}
}
// validate required fields within "Asset Unique Information" tab
int sharedIndex = 0;
for (AssetGlobalDetail addLocationDetail : assetSharedDetails) {
int uniqueIndex = 0;
for (AssetGlobalDetail assetGlobalUniqueDetail : addLocationDetail.getAssetGlobalUniqueDetails()) {
String errorPath = MAINTAINABLE_ERROR_PREFIX + CamsPropertyConstants.AssetGlobal.ASSET_SHARED_DETAILS + "[" + sharedIndex + "]." + CamsPropertyConstants.AssetGlobalDetail.ASSET_GLOBAL_UNIQUE_DETAILS + "[" + uniqueIndex + "]";
GlobalVariables.getMessageMap().addToErrorPath(errorPath);
success &= validateCapitalAssetTypeCode(assetGlobalUniqueDetail);
success &= validateAssetType(assetGlobalUniqueDetail, sharedIndex, uniqueIndex);
success &= validateAssetDescription(assetGlobalUniqueDetail);
success &= validateManufacturer(assetGlobalUniqueDetail);
success &= validateSeparateSourceAmount(assetGlobalUniqueDetail, document);
GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
uniqueIndex++;
}
sharedIndex++;
}
// total cost must be > 0
success &= validateTotalCostAmount(assetGlobal);
success &= validateAssetTotalCostMatchesPaymentTotalCost(assetGlobal);
if (getAssetGlobalService().isAssetSeparateByPayment(assetGlobal)) {
AssetGlobalRule.validateAssetAlreadySeparated(assetGlobal.getSeparateSourceCapitalAssetNumber());
}
} // end ASEP
success &= validateLocationCollection(assetGlobal, assetSharedDetails);
success &= validateTagDuplication(assetSharedDetails);
return success;
}
/**
* Validate all separate source amount is above the capital asset threshold amount.
*
* @param document
* @return
*/
protected boolean validateSeparateSourceAmountAboveThreshold(MaintenanceDocument document, AssetGlobalDetail assetGlobalUniqueDetail) {
boolean success = true;
String capitalizationThresholdAmount = this.getCapitalizationThresholdAmount();
KualiDecimal separateAmount = assetGlobalUniqueDetail.getSeparateSourceAmount();
// check for the minimal amount only among all separate source amount. if it's above the threshold, safe...
if (separateAmount != null && !getAssetService().isDocumentEnrouting(document) && !validateCapitalAssetAmountAboveThreshhold(document, separateAmount, capitalizationThresholdAmount)) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.SEPARATE_SOURCE_AMOUNT, CamsKeyConstants.AssetSeparate.ERROR_SEPARATE_ASSET_BELOW_THRESHOLD, new String[] { assetGlobalUniqueDetail.getCapitalAssetNumber().toString(), capitalizationThresholdAmount });
success = false;
}
return success;
}
/**
* check if amount is above threshold for capital assets for normal user. minTotalPaymentByAsset and maxTotalPaymentByAsset are
* used to check against threshold. Due to the decimal rounding, the asset total amount could have 1 cent difference with each
* other. We need to pick up the right value for different threshold check.
*
* @param document
* @return
*/
protected boolean validateAssetTotalAmount(MaintenanceDocument document) {
boolean success = true;
AssetGlobal assetGlobal = (AssetGlobal) document.getNewMaintainableObject().getBusinessObject();
KualiDecimal minTotalPaymentByAsset = getAssetGlobalService().totalPaymentByAsset(assetGlobal, false);
KualiDecimal maxTotalPaymentByAsset = getAssetGlobalService().totalPaymentByAsset(assetGlobal, true);
if (minTotalPaymentByAsset.isGreaterThan(maxTotalPaymentByAsset)) {
// swap min and max
KualiDecimal totalPayment = minTotalPaymentByAsset;
minTotalPaymentByAsset = maxTotalPaymentByAsset;
maxTotalPaymentByAsset = totalPayment;
}
// Disallow FO change asset total amount during routing. Asset total amount is derived from asset payments total and the
// quantity of assets
if (getAssetService().isDocumentEnrouting(document) && (!minTotalPaymentByAsset.equals(assetGlobal.getMinAssetTotalAmount()) || !maxTotalPaymentByAsset.equals(assetGlobal.getMaxAssetTotalAmount()))) {
putFieldError(CamsPropertyConstants.AssetGlobal.ASSET_PAYMENT_DETAILS, CamsKeyConstants.AssetGlobal.ERROR_CHANGE_ASSET_TOTAL_AMOUNT_DISALLOW, !minTotalPaymentByAsset.equals(assetGlobal.getMinAssetTotalAmount()) ? new String[] { (String) new CurrencyFormatter().format(assetGlobal.getMinAssetTotalAmount()), (String) new CurrencyFormatter().format(minTotalPaymentByAsset) } : new String[] { (String) new CurrencyFormatter().format(assetGlobal.getMaxAssetTotalAmount()), (String) new CurrencyFormatter().format(maxTotalPaymentByAsset) });
success = false;
}
// run threshold checking before routing
if (!getAssetService().isDocumentEnrouting(document)) {
String capitalizationThresholdAmount = getCapitalizationThresholdAmount();
if (isCapitalStatus(assetGlobal)) {
// check if amount is above threshold for capital asset.
if (!validateCapitalAssetAmountAboveThreshhold(document, minTotalPaymentByAsset, capitalizationThresholdAmount)) {
putFieldError(CamsPropertyConstants.AssetGlobal.INVENTORY_STATUS_CODE, CamsKeyConstants.AssetGlobal.ERROR_CAPITAL_ASSET_PAYMENT_AMOUNT_MIN, capitalizationThresholdAmount);
success = false;
}
}
else {
// check if amount is less than threshold for non-capital assets for all users
success &= validateNonCapitalAssetAmountBelowThreshold(maxTotalPaymentByAsset, capitalizationThresholdAmount);
}
}
return success;
}
/**
* Get the capitalization threshold amount from the system parameter setting.
*
* @return
*/
protected String getCapitalizationThresholdAmount() {
return getParameterService().getParameterValueAsString(AssetGlobal.class, CamsConstants.Parameters.CAPITALIZATION_LIMIT_AMOUNT);
}
/**
* Validate Capital Asset Amount above the threshold or below the amount for authorized user only.
*
* @param document
* @param assetAmount
* @param capitalizationThresholdAmount
* @return
*/
protected boolean validateCapitalAssetAmountAboveThreshhold(MaintenanceDocument document, KualiDecimal assetAmount, String capitalizationThresholdAmount) {
boolean success = true;
FinancialSystemMaintenanceDocumentAuthorizerBase documentAuthorizer = (FinancialSystemMaintenanceDocumentAuthorizerBase) SpringContext.getBean(DocumentDictionaryService.class).getDocumentAuthorizer(document);
boolean isOverrideAuthorized = documentAuthorizer.isAuthorized(document, CamsConstants.CAM_MODULE_CODE, CamsConstants.PermissionNames.OVERRIDE_CAPITALIZATION_LIMIT_AMOUNT, GlobalVariables.getUserSession().getPerson().getPrincipalId());
if (assetAmount.isLessThan(new KualiDecimal(capitalizationThresholdAmount)) && !isOverrideAuthorized) {
success = false;
}
return success;
}
/**
* Validate non-capital asset amount below the threshold.
*
* @param assetAmount
* @param capitalizationThresholdAmount
* @return
*/
protected boolean validateNonCapitalAssetAmountBelowThreshold(KualiDecimal assetAmount, String capitalizationThresholdAmount) {
boolean success = true;
if (assetAmount.isGreaterEqual(new KualiDecimal(capitalizationThresholdAmount))) {
putFieldError(CamsPropertyConstants.AssetGlobal.INVENTORY_STATUS_CODE, CamsKeyConstants.AssetGlobal.ERROR_NON_CAPITAL_ASSET_PAYMENT_AMOUNT_MAX, capitalizationThresholdAmount);
success &= false;
}
return success;
}
/**
* Validate that the total cost of the source asset is not zero or a negative amount.
*
* @param assetGlobal
* @return boolean
*/
protected boolean validateTotalCostAmount(AssetGlobal assetGlobal) {
boolean success = true;
if (!assetGlobal.getTotalCostAmount().isGreaterThan(KualiDecimal.ZERO)) {
GlobalVariables.getMessageMap().putErrorForSectionId(CamsConstants.AssetGlobal.SECTION_ID_ASSET_INFORMATION, CamsKeyConstants.AssetSeparate.ERROR_ZERO_OR_NEGATIVE_DOLLAR_AMOUNT);
success &= false;
}
return success;
}
/**
* Validates the capital asset type code. This only checks for the existence of some contents, not whether the contents are valid.
*
* @param uniqueLocationDetails
* @return boolean
*/
protected boolean validateCapitalAssetTypeCode(AssetGlobalDetail uniqueLocationDetails) {
boolean success = true;
if (StringUtils.isEmpty(uniqueLocationDetails.getCapitalAssetTypeCode())) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.CAPITAL_ASSET_TYPE_CODE, CamsKeyConstants.AssetSeparate.ERROR_CAPITAL_ASSET_TYPE_CODE_REQUIRED, uniqueLocationDetails.getCapitalAssetTypeCode());
success &= false;
}
return success;
}
/**
* Validates the asset description.
*
* @param uniqueLocationDetails
* @return boolean
*/
protected boolean validateAssetDescription(AssetGlobalDetail uniqueLocationDetails) {
boolean success = true;
if (StringUtils.isEmpty(uniqueLocationDetails.getCapitalAssetDescription())) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.CAPITAL_ASSET_DESCRIPTION, CamsKeyConstants.AssetSeparate.ERROR_ASSET_DESCRIPTION_REQUIRED, uniqueLocationDetails.getCapitalAssetTypeCode());
success &= false;
}
return success;
}
/**
* Validates the manufacturer.
*
* @param uniqueLocationDetails
* @return boolean
*/
protected boolean validateManufacturer(AssetGlobalDetail uniqueLocationDetails) {
boolean success = true;
if (StringUtils.isEmpty(uniqueLocationDetails.getManufacturerName())) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.MANUFACTURER_NAME, CamsKeyConstants.AssetSeparate.ERROR_MANUFACTURER_REQUIRED, uniqueLocationDetails.getCapitalAssetTypeCode());
success &= false;
}
return success;
}
/**
* Validates the separate source amount.
*
* @param uniqueLocationDetails
* @return boolean
*/
protected boolean validateSeparateSourceAmount(AssetGlobalDetail uniqueLocationDetail, MaintenanceDocument document) {
boolean success = true;
KualiDecimal separateSourceAmount = uniqueLocationDetail.getSeparateSourceAmount();
if (separateSourceAmount == null || separateSourceAmount.isLessEqual(KualiDecimal.ZERO)) {
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.SEPARATE_SOURCE_AMOUNT, CamsKeyConstants.AssetSeparate.ERROR_TOTAL_SEPARATE_SOURCE_AMOUNT_REQUIRED);
success &= false;
}
else {
// for capital asset separate, validate the minimal separate source amount above the threshold
success &= validateSeparateSourceAmountAboveThreshold(document, uniqueLocationDetail);
}
return success;
}
protected boolean validateLocationCollection(AssetGlobal assetGlobal, List<AssetGlobalDetail> assetSharedDetails) {
boolean success = true;
// for each shared location info, validate
boolean isCapitalAsset = isCapitalStatus(assetGlobal);
int index = 0;
for (AssetGlobalDetail assetLocationDetail : assetSharedDetails) {
String errorPath = MAINTAINABLE_ERROR_PREFIX + CamsPropertyConstants.AssetGlobal.ASSET_SHARED_DETAILS + "[" + index + "]";
GlobalVariables.getMessageMap().addToErrorPath(errorPath);
success &= SpringContext.getBean(AssetLocationService.class).validateLocation(LOCATION_FIELD_MAP, assetLocationDetail, isCapitalAsset, assetGlobal.getCapitalAssetType());
GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
index++;
}
return success;
}
@Override
protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) {
AssetGlobal assetGlobal = (AssetGlobal) document.getNewMaintainableObject().getBusinessObject();
boolean success = true;
success &= super.processCustomSaveDocumentBusinessRules(document);
if (GlobalVariables.getMessageMap().hasErrors()) {
return false;
}
String acquisitionTypeCode = assetGlobal.getAcquisitionTypeCode();
String statusCode = assetGlobal.getInventoryStatusCode();
// no need to validate specific fields if document is "Asset Separate"
if (!getAssetGlobalService().isAssetSeparate(assetGlobal)) {
success &= validateAccount(assetGlobal);
if (StringUtils.isNotBlank(acquisitionTypeCode) && StringUtils.isNotBlank(statusCode)) {
// check if status code and acquisition type code combination is valid
success &= /*REFACTORME*/SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(AssetGlobal.class, CamsConstants.Parameters.VALID_ASSET_STATUSES_BY_ACQUISITION_TYPE, CamsConstants.Parameters.INVALID_ASSET_STATUSES_BY_ACQUISITION_TYPE, acquisitionTypeCode, statusCode).evaluateAndAddError(AssetGlobal.class, CamsPropertyConstants.AssetGlobal.INVENTORY_STATUS_CODE, MAINTAINABLE_ERROR_PREFIX + CamsPropertyConstants.AssetGlobal.INVENTORY_STATUS_CODE);
}
success &= validateAssetType(assetGlobal);
if (isCapitalStatus(assetGlobal)) {
success &= validateVendorAndManufacturer(assetGlobal);
}
success &= validatePaymentCollection(document, assetGlobal);
}
else {
// append doc type to existing doc header description
if (!document.getDocumentHeader().getDocumentDescription().toLowerCase().contains(CamsConstants.AssetSeparate.SEPARATE_AN_ASSET_DESCRIPTION.toLowerCase())) {
Integer maxDocumentDescription = ddService.getAttributeMaxLength(DocumentHeader.class, KRADPropertyConstants.DOCUMENT_DESCRIPTION);
String documentDescription = CamsConstants.AssetSeparate.SEPARATE_AN_ASSET_DESCRIPTION + " " + document.getDocumentHeader().getDocumentDescription();
documentDescription = StringUtils.left(documentDescription, maxDocumentDescription);
document.getDocumentHeader().setDocumentDescription(documentDescription);
}
}
// System shall only generate GL entries if we have an incomeAssetObjectCode for this acquisitionTypeCode and the statusCode
// is for capital assets
// GLs should not be generated while separating assets too
if ((success && !getAssetGlobalService().isAssetSeparate(assetGlobal) && super.processCustomSaveDocumentBusinessRules(document)) && getAssetAcquisitionTypeService().hasIncomeAssetObjectCode(acquisitionTypeCode) && this.isCapitalStatus(assetGlobal)) {
if (success &= validateAcquisitionIncomeObjectCode(assetGlobal)) {
// create poster
AssetGlobalGeneralLedgerPendingEntrySource assetGlobalGlPoster = new AssetGlobalGeneralLedgerPendingEntrySource((FinancialSystemDocumentHeader) document.getDocumentHeader());
// create postables
getAssetGlobalService().createGLPostables(assetGlobal, assetGlobalGlPoster);
if (SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(assetGlobalGlPoster)) {
assetGlobal.setGeneralLedgerPendingEntries(assetGlobalGlPoster.getPendingEntries());
}
else {
assetGlobalGlPoster.getPendingEntries().clear();
}
}
}
return success;
}
/**
* Locking on separate source asset number
*
* @param document
* @param assetGlobal
* @return
*/
protected boolean setAssetLock(MaintenanceDocument document, AssetGlobal assetGlobal) {
List<Long> capitalAssetNumbers = new ArrayList<Long>();
if (assetGlobal.getSeparateSourceCapitalAssetNumber() != null) {
capitalAssetNumbers.add(assetGlobal.getSeparateSourceCapitalAssetNumber());
}
return SpringContext.getBean(CapitalAssetManagementModuleService.class).storeAssetLocks(capitalAssetNumbers, document.getDocumentNumber(), DocumentTypeName.ASSET_SEPARATE, null);
}
/**
* Validate offset object code
*
* @param assetGlobal
* @return
*/
protected boolean validateAcquisitionIncomeObjectCode(AssetGlobal assetGlobal) {
boolean valid = true;
for (AssetPaymentDetail assetPaymentDetail : assetGlobal.getAssetPaymentDetails()) {
// check offset object code existence
ObjectCode objectCode = SpringContext.getBean(ObjectCodeService.class).getByPrimaryId(assetPaymentDetail.getPostingYear(), assetPaymentDetail.getChartOfAccountsCode(), assetGlobal.getAcquisitionType().getIncomeAssetObjectCode());
if (ObjectUtils.isNull(objectCode)) {
putFieldError(CamsPropertyConstants.AssetGlobal.ACQUISITION_TYPE_CODE, CamsKeyConstants.AssetGlobal.ERROR_INVALID_ACQUISITION_INCOME_OBJECT_CODE, new String[] { assetGlobal.getAcquisitionType().getIncomeAssetObjectCode(), assetPaymentDetail.getPostingYear().toString(), assetPaymentDetail.getChartOfAccountsCode() });
valid = false;
}
// check Object Code active
else if (!objectCode.isActive()) {
putFieldError(CamsPropertyConstants.AssetGlobal.ACQUISITION_TYPE_CODE, CamsKeyConstants.GLPosting.ERROR_OBJECT_CODE_FROM_ASSET_OBJECT_CODE_INACTIVE, new String[] { CamsConstants.GLPostingObjectCodeType.INCOME, assetGlobal.getAcquisitionType().getIncomeAssetObjectCode(), assetPaymentDetail.getChartOfAccountsCode() });
valid = false;
}
}
return valid;
}
protected boolean validatePaymentCollection(MaintenanceDocument maintenanceDocument, AssetGlobal assetGlobal) {
boolean success = true;
int index = 0;
for (AssetPaymentDetail assetPaymentDetail : assetGlobal.getAssetPaymentDetails()) {
String errorPath = MAINTAINABLE_ERROR_PREFIX + CamsPropertyConstants.AssetGlobal.ASSET_PAYMENT_DETAILS + "[" + index + "]";
GlobalVariables.getMessageMap().addToErrorPath(errorPath);
success &= validatePaymentLine(maintenanceDocument, assetGlobal, assetPaymentDetail);
GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
index++;
}
return success;
}
protected boolean validateVendorAndManufacturer(AssetGlobal assetGlobal) {
boolean success = true;
if (StringUtils.isBlank(assetGlobal.getVendorName())) {
putFieldError(CamsPropertyConstants.AssetGlobal.VENDOR_NAME, CamsKeyConstants.AssetGlobal.ERROR_VENDOR_NAME_REQUIRED);
success &= false;
}
if (StringUtils.isBlank(assetGlobal.getManufacturerName())) {
putFieldError(CamsPropertyConstants.AssetGlobal.MFR_NAME, CamsKeyConstants.AssetGlobal.ERROR_MFR_NAME_REQUIRED);
success &= false;
}
return success;
}
@Override
public boolean processSaveDocument(Document document) {
boolean valid = true;
MaintenanceDocument maintenanceDocument = (MaintenanceDocument) document;
AssetGlobal assetGlobal = (AssetGlobal) maintenanceDocument.getNewMaintainableObject().getBusinessObject();
List<AssetGlobalDetail> assetSharedDetails = assetGlobal.getAssetSharedDetails();
int index = 0;
for (AssetGlobalDetail assetLocationDetail : assetSharedDetails) {
String errorPath = MAINTAINABLE_ERROR_PREFIX + CamsPropertyConstants.AssetGlobal.ASSET_SHARED_DETAILS + "[" + index + "]";
GlobalVariables.getMessageMap().addToErrorPath(errorPath);
valid &= checkReferenceExists(assetLocationDetail);
GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
// checks that all of the asset types entered in the collection of Unique Details actually exist in persistent storage
int indexUniqueDetails = 0;
for (AssetGlobalDetail assetGlobalUniqueDetails : assetLocationDetail.getAssetGlobalUniqueDetails()) {
valid &= validateAssetType(assetGlobalUniqueDetails, index, indexUniqueDetails);
indexUniqueDetails++;
}
index++;
}
// Creates locking representation for this global document. The locking is only applicable for assets that are being split.
// The assets that are being created do not need to be locked since they don't exist yet.
if (valid && getAssetGlobalService().isAssetSeparate(assetGlobal)) {
valid &= setAssetLock(maintenanceDocument, assetGlobal);
}
return valid && super.processSaveDocument(document);
}
protected boolean validateAccount(AssetGlobal assetGlobal) {
boolean success = true;
assetGlobal.refreshReferenceObject(CamsPropertyConstants.AssetGlobal.ORGANIZATION_OWNER_ACCOUNT);
Account organizationOwnerAccount = assetGlobal.getOrganizationOwnerAccount();
boolean skipAccountAvailiablityCheck;
if (StringUtils.isBlank(assetGlobal.getOrganizationOwnerChartOfAccountsCode()) || StringUtils.isBlank(assetGlobal.getOrganizationOwnerAccountNumber())) {
skipAccountAvailiablityCheck = true;
}
else {
skipAccountAvailiablityCheck = isOrgOwnerAccountFromCab(assetGlobal);
}
// when check if organizationOwnerAccount is existing, use ObjectUtils rather than comparing with 'null' since OJB proxy
// object is used here.
if (!skipAccountAvailiablityCheck && (ObjectUtils.isNull(organizationOwnerAccount) || !organizationOwnerAccount.isActive() || organizationOwnerAccount.isExpired())) {
putFieldError(CamsPropertyConstants.AssetGlobal.ORGANIZATION_OWNER_ACCOUNT_NUMBER, CamsKeyConstants.AssetGlobal.ERROR_OWNER_ACCT_NOT_ACTIVE, new String[] { assetGlobal.getOrganizationOwnerChartOfAccountsCode(), assetGlobal.getOrganizationOwnerAccountNumber() });
success &= false;
}
return success;
}
/**
* Check if organization owner account is set from CAB. We honor all accounting lines from CAB are valid payments even thougth
* they are expired.
*
* @param assetGlobal
* @return
*/
protected boolean isOrgOwnerAccountFromCab(AssetGlobal assetGlobal) {
String orgOwnerChartCode = assetGlobal.getOrganizationOwnerChartOfAccountsCode();
String orgOwnerAccountNbr = assetGlobal.getOrganizationOwnerAccountNumber();
if (StringUtils.isBlank(assetGlobal.getOrganizationOwnerChartOfAccountsCode()) || StringUtils.isBlank(assetGlobal.getOrganizationOwnerAccountNumber())) {
return true;
}
if (assetGlobal.isCapitalAssetBuilderOriginIndicator()) {
// If CAB submits, allow use of inactive accounting line from the payments
for (AssetPaymentDetail assetPaymentDetail : assetGlobal.getAssetPaymentDetails()) {
if (orgOwnerChartCode.equalsIgnoreCase(assetPaymentDetail.getChartOfAccountsCode()) && orgOwnerAccountNbr.equalsIgnoreCase(assetPaymentDetail.getAccountNumber())) {
return true;
}
}
}
return false;
}
/**
* Validate location
*
* @param assetGlobal
* @return boolean
*/
protected boolean validateLocation(AssetGlobal assetGlobal, AssetGlobalDetail assetGlobalDetail) {
boolean success = true;
if (StringUtils.isBlank(assetGlobal.getInventoryStatusCode())) {
putFieldError(CamsPropertyConstants.AssetGlobal.INVENTORY_STATUS_CODE, CamsKeyConstants.AssetGlobal.ERROR_INVENTORY_STATUS_REQUIRED);
success &= false;
}
success = validateAssetType(assetGlobal);
if (success) {
boolean isCapitalAsset = isCapitalStatus(assetGlobal);
success &= SpringContext.getBean(AssetLocationService.class).validateLocation(LOCATION_FIELD_MAP, assetGlobalDetail, isCapitalAsset, assetGlobal.getCapitalAssetType());
}
else {
putFieldError(CamsPropertyConstants.AssetGlobal.CAPITAL_ASSET_TYPE_CODE, CamsKeyConstants.AssetGlobal.ERROR_ASSET_LOCATION_DEPENDENCY);
}
return success;
}
/**
* Validate asset type at the AssetGlobal level. Only checks that there are contents in the object.
*
* @param assetGlobal
* @return boolean
*/
protected boolean validateAssetType(AssetGlobal assetGlobal) {
boolean success = true;
assetGlobal.refreshReferenceObject(CamsPropertyConstants.AssetGlobal.CAPITAL_ASSET_TYPE);
if (ObjectUtils.isNull(assetGlobal.getCapitalAssetType())) {
putFieldError(CamsPropertyConstants.AssetGlobalDetail.ASSET_UNIQUE_DETAILS, CamsKeyConstants.AssetGlobal.ERROR_ASSET_TYPE_REQUIRED);
success &= false;
}
return success;
}
/**
* Validate asset type in the AssetGlobalUniqueDetails level, and ensures the value is in the list of valid types.
* The incoming indices are for creation of the errorPath for the global variable message map, which will determine
* what text field to mark as having a problem. This was written to be called within a loop.
*
* @param assetGlobalUniqueDetails
* @param sharedIndex the index of the shared details within the AssetGlobal
* @param uniqueIndex the index of the unique details within the shared details
* @return boolean
*/
protected boolean validateAssetType(AssetGlobalDetail assetGlobalUniqueDetails, Integer sharedIndex, Integer uniqueIndex) {
boolean success = true;
int sharedInd = 0;
int uniqueInd = 0;
// In hindsite, maybe this should have been written to perform the loop-within-loop fully contained within this
// method, and not used within the typical double loop structure of processSaveDocument() and
// processCustomRouteDecumentBusinessRules.
// don't change the value of the incoming param!
if (sharedIndex != null) {
sharedInd = sharedIndex;
}
if (uniqueIndex != null) {
uniqueInd = uniqueIndex;
}
if (ObjectUtils.isNull(assetGlobalUniqueDetails)) {
putFieldError(CamsPropertyConstants.AssetGlobalDetail.ASSET_UNIQUE_DETAILS, CamsKeyConstants.AssetGlobal.ERROR_ASSET_LOCATION_DEPENDENCY);
success &= false;
}
// validate asset type
if (StringUtils.isNotBlank(assetGlobalUniqueDetails.getCapitalAssetTypeCode())) {
AssetType assetType = SpringContext.getBean(BusinessObjectService.class).findBySinglePrimaryKey(AssetType.class, assetGlobalUniqueDetails.getCapitalAssetTypeCode());
if (assetType == null || StringUtils.isBlank(assetType.getCapitalAssetTypeCode())) {
String errorPath = MAINTAINABLE_ERROR_PREFIX + CamsPropertyConstants.AssetGlobal.ASSET_SHARED_DETAILS + "[" + sharedInd + "]." + CamsPropertyConstants.AssetGlobalDetail.ASSET_UNIQUE_DETAILS + "[" + uniqueInd + "]";
GlobalVariables.getMessageMap().addToErrorPath(errorPath);
GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetGlobalDetail.CAPITAL_ASSET_TYPE_CODE, CamsKeyConstants.AssetSeparate.ERROR_CAPITAL_ASSET_TYPE_CODE_INVALID, assetGlobalUniqueDetails.getCapitalAssetTypeCode());
GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
success &= false;
}
}
return success;
}
/**
* Give an error if this asset can't be separated due to mismatching amount on asset and AssetPayment records
*
* @param assetGlobal
* @return validation success of failure
*/
public static boolean validateAssetTotalCostMatchesPaymentTotalCost(AssetGlobal assetGlobal) {
PaymentSummaryService paymentSummaryService = SpringContext.getBean(PaymentSummaryService.class);
assetGlobal.refreshReferenceObject(CamsPropertyConstants.AssetGlobal.SEPARATE_SOURCE_CAPITAL_ASSET);
KualiDecimal assetTotalCost = ObjectUtils.isNull(assetGlobal.getSeparateSourceCapitalAsset().getTotalCostAmount()) ? new KualiDecimal(0) : assetGlobal.getSeparateSourceCapitalAsset().getTotalCostAmount();
KualiDecimal paymentTotalCost = paymentSummaryService.calculatePaymentTotalCost(assetGlobal.getSeparateSourceCapitalAsset());
if (!paymentTotalCost.equals(assetTotalCost)) {
GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(MAINTAINABLE_ERROR_PREFIX + CamsPropertyConstants.AssetGlobal.SEPARATE_SOURCE_CAPITAL_ASSET_NUMBER, CamsKeyConstants.AssetGlobal.ERROR_SEPARATE_ASSET_TOTAL_COST_NOT_MATCH_PAYMENT_TOTAL_COST);
return false;
}
return true;
}
/**
* Give an error if this asset has already been separated
*
* @param assetGlobal
* @return validation success of failure
*/
public static boolean validateAssetAlreadySeparated(Long separateSourceCapitalAssetNumber) {
AssetService assetService = SpringContext.getBean(AssetService.class);
List<String> documentNumbers = assetService.getDocumentNumbersThatSeparatedThisAsset(separateSourceCapitalAssetNumber);
if (!documentNumbers.isEmpty()) {
GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(MAINTAINABLE_ERROR_PREFIX + CamsPropertyConstants.AssetGlobal.SEPARATE_SOURCE_CAPITAL_ASSET_NUMBER, CamsKeyConstants.AssetGlobal.ERROR_SEPARATE_ASSET_ALREADY_SEPARATED, new String[] { documentNumbers.toString() });
return false;
}
return true;
}
/**
*
* @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#dataDictionaryValidate(org.kuali.rice.kns.document.MaintenanceDocument)
* Override this method to only validate reference exists for asset separate , otherwise do default Existence Checks.
* KFSMI-6584
*/
@Override
protected boolean dataDictionaryValidate(MaintenanceDocument document) {
AssetGlobal assetGlobal = (AssetGlobal) document.getNewMaintainableObject().getBusinessObject();
LOG.debug("MaintenanceDocument validation beginning");
// explicitly put the errorPath that the dictionaryValidationService requires
GlobalVariables.getMessageMap().addToErrorPath("document.newMaintainableObject");
// document must have a newMaintainable object
Maintainable newMaintainable = document.getNewMaintainableObject();
if (newMaintainable == null) {
GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject");
throw new ValidationException("Maintainable object from Maintenance Document '" + document.getDocumentTitle() + "' is null, unable to proceed.");
}
// document's newMaintainable must contain an object (ie, not null)
PersistableBusinessObject businessObject = newMaintainable.getBusinessObject();
if (businessObject == null) {
GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject.");
throw new ValidationException("Maintainable's component business object is null.");
}
// run required check from maintenance data dictionary
maintDocDictionaryService.validateMaintenanceRequiredFields(document);
//check for duplicate entries in collections if necessary
maintDocDictionaryService.validateMaintainableCollectionsForDuplicateEntries(document);
// run the DD DictionaryValidation (non-recursive)
dictionaryValidationService.validateBusinessObjectOnMaintenanceDocument(businessObject,
document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName());
// do default (ie, mandatory) existence checks
if (!getAssetGlobalService().isAssetSeparate(assetGlobal)) {
dictionaryValidationService.validateDefaultExistenceChecks(businessObject);
}
else {
Collection references = KNSServiceLocator.getMaintenanceDocumentDictionaryService().getDefaultExistenceChecks(businessObject.getClass());
// walk through the references, doing the tests on each
for (Iterator iter = references.iterator(); iter.hasNext();) {
ReferenceDefinition reference = (ReferenceDefinition) iter.next();
// do the existence and validation testing
dictionaryValidationService.validateReferenceExists(assetGlobal,reference );
}
}
// explicitly remove the errorPath we've added
GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject");
LOG.debug("MaintenanceDocument validation ending");
return true;
}
protected ParameterService getParameterService() {
return SpringContext.getBean(ParameterService.class);
}
protected AssetService getAssetService() {
return SpringContext.getBean(AssetService.class);
}
protected AssetPaymentService getAssetPaymentService() {
return SpringContext.getBean(AssetPaymentService.class);
}
protected AssetAcquisitionTypeService getAssetAcquisitionTypeService() {
return SpringContext.getBean(AssetAcquisitionTypeService.class);
}
protected AssetGlobalService getAssetGlobalService() {
return SpringContext.getBean(AssetGlobalService.class);
}
}