/* * 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 static org.kuali.kfs.module.cam.CamsKeyConstants.ERROR_INVALID_ASSET_WARRANTY_NO; import static org.kuali.kfs.module.cam.CamsKeyConstants.PreTag.ERROR_PRE_TAG_INVALID_REPRESENTATIVE_ID; import static org.kuali.kfs.module.cam.CamsPropertyConstants.Asset.ASSET_REPRESENTATIVE; import static org.kuali.kfs.module.cam.CamsPropertyConstants.Asset.ASSET_WARRANTY_WARRANTY_NUMBER; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.coa.businessobject.Account; import org.kuali.kfs.integration.cam.CapitalAssetManagementModuleService; import org.kuali.kfs.module.cam.CamsConstants; 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.AssetComponent; import org.kuali.kfs.module.cam.businessobject.AssetFabrication; import org.kuali.kfs.module.cam.businessobject.AssetLocation; import org.kuali.kfs.module.cam.businessobject.AssetRepairHistory; import org.kuali.kfs.module.cam.businessobject.AssetWarranty; import org.kuali.kfs.module.cam.businessobject.defaultvalue.NextAssetNumberFinder; import org.kuali.kfs.module.cam.document.service.AssetComponentService; import org.kuali.kfs.module.cam.document.service.AssetDateService; 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.AssetService; import org.kuali.kfs.module.cam.document.service.EquipmentLoanOrReturnService; import org.kuali.kfs.module.cam.document.service.PaymentSummaryService; import org.kuali.kfs.module.cam.document.service.RetirementInfoService; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.service.UniversityDateService; import org.kuali.kfs.sys.util.KfsDateUtils; import org.kuali.rice.core.api.datetime.DateTimeService; import org.kuali.rice.core.api.parameter.ParameterEvaluatorService; import org.kuali.rice.core.api.util.type.KualiDecimal; import org.kuali.rice.coreservice.framework.parameter.ParameterService; import org.kuali.rice.kew.api.WorkflowDocument; import org.kuali.rice.kim.api.identity.Person; import org.kuali.rice.kim.api.identity.PersonService; import org.kuali.rice.kns.document.MaintenanceDocument; import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase; import org.kuali.rice.krad.bo.PersistableBusinessObject; import org.kuali.rice.krad.util.ErrorMessage; import org.kuali.rice.krad.util.GlobalVariables; import org.kuali.rice.krad.util.ObjectUtils; import org.springframework.util.AutoPopulatingList; /** * AssetRule for Asset edit. */ public class AssetRule extends MaintenanceDocumentRuleBase { protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AssetRule.class); protected static final Map<LocationField, String> LOCATION_FIELD_MAP = new HashMap<LocationField, String>(); static { LOCATION_FIELD_MAP.put(LocationField.CAMPUS_CODE, CamsPropertyConstants.Asset.CAMPUS_CODE); LOCATION_FIELD_MAP.put(LocationField.BUILDING_CODE, CamsPropertyConstants.Asset.BUILDING_CODE); LOCATION_FIELD_MAP.put(LocationField.ROOM_NUMBER, CamsPropertyConstants.Asset.BUILDING_ROOM_NUMBER); LOCATION_FIELD_MAP.put(LocationField.SUB_ROOM_NUMBER, CamsPropertyConstants.Asset.BUILDING_SUB_ROOM_NUMBER); LOCATION_FIELD_MAP.put(LocationField.CONTACT_NAME, CamsPropertyConstants.Asset.AssetLocation.CONTACT_NAME); LOCATION_FIELD_MAP.put(LocationField.STREET_ADDRESS, CamsPropertyConstants.Asset.AssetLocation.STREET_ADDRESS); LOCATION_FIELD_MAP.put(LocationField.CITY_NAME, CamsPropertyConstants.Asset.AssetLocation.CITY_NAME); LOCATION_FIELD_MAP.put(LocationField.STATE_CODE, CamsPropertyConstants.Asset.AssetLocation.STATE_CODE); LOCATION_FIELD_MAP.put(LocationField.ZIP_CODE, CamsPropertyConstants.Asset.AssetLocation.ZIP_CODE); LOCATION_FIELD_MAP.put(LocationField.COUNTRY_CODE, CamsPropertyConstants.Asset.AssetLocation.COUNTRY_CODE); } // protected AgencyService agencyService = SpringContext.getBean(AgencyService.class); protected AssetService assetService = SpringContext.getBean(AssetService.class); protected ParameterService parameterService = SpringContext.getBean(ParameterService.class); protected PaymentSummaryService paymentSummaryService = SpringContext.getBean(PaymentSummaryService.class); protected RetirementInfoService retirementInfoService = SpringContext.getBean(RetirementInfoService.class); protected EquipmentLoanOrReturnService equipmentLoanOrReturnService = SpringContext.getBean(EquipmentLoanOrReturnService.class); protected AssetDateService assetDateService = SpringContext.getBean(AssetDateService.class); protected AssetComponentService assetComponentService = SpringContext.getBean(AssetComponentService.class); protected UniversityDateService universityDateService = SpringContext.getBean(UniversityDateService.class); protected AssetLocationService assetLocationService = SpringContext.getBean(AssetLocationService.class); protected DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class); protected Asset newAsset; protected Asset oldAsset; protected boolean isFabrication; /** * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument) */ @Override protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) { initializeAttributes(document); boolean valid = true; if (SpringContext.getBean(AssetService.class).isAssetFabrication(document)) { this.isFabrication = true; valid &= validateAccount(); valid &= validateLocation(); valid &= validateFabricationDetails(); } else { setAssetComponentNumbers(newAsset); paymentSummaryService.calculateAndSetPaymentSummary(oldAsset); paymentSummaryService.calculateAndSetPaymentSummary(newAsset); assetService.setSeparateHistory(oldAsset); assetService.setSeparateHistory(newAsset); retirementInfoService.setRetirementInfo(oldAsset); retirementInfoService.setRetirementInfo(newAsset); equipmentLoanOrReturnService.setEquipmentLoanInfo(oldAsset); equipmentLoanOrReturnService.setEquipmentLoanInfo(newAsset); valid &= processAssetValidation(document); valid &= validateWarrantyInformation(newAsset); valid &= validateDepreciationData(newAsset); valid &= checkAssetDepreciationMethodChange(); valid &= super.processCustomSaveDocumentBusinessRules(document); if (valid) { assetDateService.checkAndUpdateLastInventoryDate(oldAsset, newAsset); assetDateService.checkAndUpdateDepreciationDate(oldAsset, newAsset); assetDateService.checkAndUpdateFiscalYearAndPeriod(oldAsset, newAsset); } valid &= checkAssetLocked(document); } valid &= validateManufacturer(newAsset); return valid; } /** * Check if asset is locked by other document. * * @param document * @param valid * @return */ protected boolean checkAssetLocked(MaintenanceDocument document) { Asset asset = (Asset) document.getNewMaintainableObject().getBusinessObject(); return !getCapitalAssetManagementModuleService().isAssetLocked(retrieveAssetNumberForLocking(asset), CamsConstants.DocumentTypeName.ASSET_EDIT, document.getDocumentNumber()); } /** * Retrieve asset numbers need to be locked. * * @return */ protected List<Long> retrieveAssetNumberForLocking(Asset asset) { List<Long> capitalAssetNumbers = new ArrayList<Long>(); if (asset.getCapitalAssetNumber() != null) { capitalAssetNumbers.add(asset.getCapitalAssetNumber()); } return capitalAssetNumbers; } /** * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomAddCollectionLineBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument, * java.lang.String, org.kuali.rice.krad.bo.PersistableBusinessObject) */ @Override public boolean processCustomAddCollectionLineBusinessRules(MaintenanceDocument documentCopy, String collectionName, PersistableBusinessObject bo) { boolean success = true; // get all incidentDates from AssetRepairHistory collection and check for duplicate dates. if (collectionName.equals(CamsConstants.Asset.COLLECTION_ID_ASSET_REPAIR_HISTORY)) { Asset asset = (Asset) documentCopy.getNewMaintainableObject().getBusinessObject(); Set<Date> incidentDateSet = new HashSet<Date>(); for (AssetRepairHistory assetRepairHistory : asset.getAssetRepairHistory()) { if (assetRepairHistory.getIncidentDate() != null) { incidentDateSet.add(assetRepairHistory.getIncidentDate()); } } AssetRepairHistory assetRepairHistoryDetails = (AssetRepairHistory) bo; success &= checkDuplicateIncidentDate(assetRepairHistoryDetails, incidentDateSet); return success & super.processCustomAddCollectionLineBusinessRules(documentCopy, collectionName, bo); } return success; } /** * Check for duplicate incident dates within the Repair History section * * @param assetRepairHistory * @param incidentDateSet * @return boolean */ protected boolean checkDuplicateIncidentDate(AssetRepairHistory assetRepairHistory, Set<Date> incidentDateSet) { boolean success = true; if (!incidentDateSet.add(assetRepairHistory.getIncidentDate())) { GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetRepairHistory.INCIDENT_DATE, CamsKeyConstants.AssetRepairHistory.ERROR_DUPLICATE_INCIDENT_DATE); success &= false; } return success; } /** * Validate fabrication details * * @return boolean */ protected boolean validateFabricationDetails() { /** * Please don't remove this validation, forcing required fields from DD file is not possible and will break asset edit * screen, so please leave this validation here. */ boolean valid = true; if (newAsset.getFabricationEstimatedTotalAmount() != null && newAsset.getFabricationEstimatedTotalAmount().isNegative()) { putFieldError(CamsPropertyConstants.Asset.FABRICATION_ESTIMATED_TOTAL_AMOUNT, CamsKeyConstants.ERROR_FABRICATION_ESTIMATED_TOTAL_AMOUNT_NEGATIVE); valid &= false; } if (newAsset.getEstimatedFabricationCompletionDate() != null && newAsset.getEstimatedFabricationCompletionDate().before(KfsDateUtils.clearTimeFields(dateTimeService.getCurrentDate()))) { putFieldError(CamsPropertyConstants.Asset.ESTIMATED_FABRICATION_COMPLETION_DATE, CamsKeyConstants.ERROR_ESTIMATED_FABRICATION_COMPLETION_DATE_PAST); valid &= false; } if (newAsset.getFabricationEstimatedRetentionYears() != null && newAsset.getFabricationEstimatedRetentionYears().intValue() < 0) { putFieldError(CamsPropertyConstants.Asset.FABRICATION_ESTIMATED_RETENTION_YEARS, CamsKeyConstants.ERROR_ESTIMATED_FABRICATION_LIFE_LIMIT_NEGATIVE); valid &= false; } return valid; } /** * Validate account * * @return boolean */ protected boolean validateAccount() { boolean valid = true; Account currentOwnerAccount = newAsset.getOrganizationOwnerAccount(); Account previoudOwnerAccount = oldAsset.getOrganizationOwnerAccount(); // Account is valid? if (ObjectUtils.isNull(currentOwnerAccount) && StringUtils.isNotBlank(newAsset.getOrganizationOwnerAccountNumber())) { putFieldError(CamsPropertyConstants.Asset.ORGANIZATION_OWNER_ACCOUNT_NUMBER, CamsKeyConstants.ORGANIZATION_OWNER_ACCOUNT_INVALID); valid &= false; } // check if values changed, if not return if (ObjectUtils.isNotNull(previoudOwnerAccount) && ObjectUtils.isNotNull(currentOwnerAccount) && previoudOwnerAccount.getChartOfAccountsCode().equals(currentOwnerAccount.getChartOfAccountsCode()) && previoudOwnerAccount.getAccountNumber().equals(currentOwnerAccount.getAccountNumber())) { return valid; } else if (ObjectUtils.isNotNull(currentOwnerAccount) && (currentOwnerAccount.isExpired() || !currentOwnerAccount.isActive())) { // Account is not active putFieldError(CamsPropertyConstants.Asset.ORGANIZATION_OWNER_ACCOUNT_NUMBER, CamsKeyConstants.ORGANIZATION_OWNER_ACCOUNT_INACTIVE); valid &= false; } return valid; } /** * * Validate asset representative * @return boolean */ protected boolean validateAssetRepresentative() { boolean valid = true; Person assetRepresentative = SpringContext.getBean(PersonService.class).getPersonByPrincipalName(newAsset.getAssetRepresentative().getPrincipalName()); if(ObjectUtils.isNull(assetRepresentative)) { putFieldError(ASSET_REPRESENTATIVE, ERROR_PRE_TAG_INVALID_REPRESENTATIVE_ID); valid = false; } return valid; } /** * Set asset component numbers * * @param asset */ protected void setAssetComponentNumbers(Asset asset) { List<AssetComponent> assetComponents = asset.getAssetComponents(); Integer maxNo = null; for (AssetComponent assetComponent : assetComponents) { assetComponent.setCapitalAssetNumber(asset.getCapitalAssetNumber()); if (maxNo == null) { maxNo = assetComponentService.getMaxSequenceNumber(assetComponent); } if (assetComponent.getComponentNumber() == null) { assetComponent.setComponentNumber(++maxNo); } } } /** * Validates Asset document. * * @param document MaintenanceDocument instance * @return boolean false or true */ protected boolean processAssetValidation(MaintenanceDocument document) { boolean valid = true; // validate Inventory Status Code. if (!StringUtils.equalsIgnoreCase(oldAsset.getInventoryStatusCode(), newAsset.getInventoryStatusCode())) { valid &= validateInventoryStatusCode(oldAsset.getInventoryStatusCode(), newAsset.getInventoryStatusCode()); } // validate Organization Owner Account Number if (!StringUtils.equalsIgnoreCase(oldAsset.getOrganizationOwnerAccountNumber(), newAsset.getOrganizationOwnerAccountNumber())) { valid &= validateAccount(); } // validate asset representative name if (!StringUtils.equalsIgnoreCase(oldAsset.getAssetRepresentative().getPrincipalName(), newAsset.getAssetRepresentative().getPrincipalName())) { valid &= validateAssetRepresentative(); } // validate Vendor Name. if (!StringUtils.equalsIgnoreCase(oldAsset.getVendorName(), newAsset.getVendorName())) { valid &= validateVendorName(); } // validate Tag Number. if (!StringUtils.equalsIgnoreCase(oldAsset.getCampusTagNumber(), newAsset.getCampusTagNumber())) { valid &= validateTagNumber(); } // validate location. valid &= validateLocation(); // validate In-service Date if (assetService.isInServiceDateChanged(oldAsset, newAsset)) { valid &= validateInServiceDate(); } return valid; } /** * Check if the new In-service Date is a valid University Date * * @return */ protected boolean validateInServiceDate() { boolean valid = true; // if asset already starts depreciation, the user can't blank in-service date. if (ObjectUtils.isNull(newAsset.getCapitalAssetInServiceDate()) && assetService.isAssetDepreciationStarted(oldAsset)) { putFieldError(CamsPropertyConstants.Asset.ASSET_DATE_OF_SERVICE, CamsKeyConstants.ERROR_BLANK_IN_SERVICE_DATE_DISALLOWED); valid = false; } else if (ObjectUtils.isNotNull(newAsset.getCapitalAssetInServiceDate()) && universityDateService.getFiscalYear(newAsset.getCapitalAssetInServiceDate()) == null) { putFieldError(CamsPropertyConstants.Asset.ASSET_DATE_OF_SERVICE, CamsKeyConstants.ERROR_INVALID_IN_SERVICE_DATE); valid = false; } return valid; } /** * Check if off campus fields has changed. * * @return */ protected boolean isOffCampusLocationChanged() { boolean changed = false; AssetLocation oldLocation = oldAsset.getOffCampusLocation(); AssetLocation newLocation = newAsset.getOffCampusLocation(); if (!StringUtils.equalsIgnoreCase(newLocation.getAssetLocationContactName(), oldLocation.getAssetLocationContactName()) || !StringUtils.equalsIgnoreCase(newLocation.getAssetLocationStreetAddress(), oldLocation.getAssetLocationStreetAddress()) || !StringUtils.equalsIgnoreCase(newLocation.getAssetLocationCityName(), oldLocation.getAssetLocationCityName()) || !StringUtils.equalsIgnoreCase(newLocation.getAssetLocationStateCode(), oldLocation.getAssetLocationStateCode()) || !StringUtils.equalsIgnoreCase(newLocation.getAssetLocationZipCode(), oldLocation.getAssetLocationZipCode()) || !StringUtils.equalsIgnoreCase(newLocation.getAssetLocationCountryCode(), oldLocation.getAssetLocationCountryCode())) { changed = true; } return changed; } /** * Validate Inventory Status Code Change */ protected boolean validateInventoryStatusCode(String oldInventoryStatusCode, String newInventoryStatusCode) { boolean valid = true; if (assetService.isCapitalAsset(oldAsset) && assetService.isAssetRetired(newAsset)) { // disallow retire capital asset. putFieldError(CamsPropertyConstants.Asset.ASSET_INVENTORY_STATUS, CamsKeyConstants.ERROR_ASSET_RETIRED_CAPITAL); valid = false; } else { // validate inventory status change per system parameter. GlobalVariables.getMessageMap().addToErrorPath(MAINTAINABLE_ERROR_PATH); valid &= /*REFACTORME*/SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(Asset.class, CamsConstants.Parameters.VALID_INVENTROY_STATUS_CODE_CHANGE, CamsConstants.Parameters.INVALID_INVENTROY_STATUS_CODE_CHANGE, oldAsset.getInventoryStatusCode(), newAsset.getInventoryStatusCode()).evaluateAndAddError(newAsset.getClass(), CamsPropertyConstants.Asset.ASSET_INVENTORY_STATUS); GlobalVariables.getMessageMap().removeFromErrorPath(MAINTAINABLE_ERROR_PATH); } return valid; } protected void initializeAttributes(MaintenanceDocument document) { if (newAsset == null) { newAsset = (Asset) document.getNewMaintainableObject().getBusinessObject(); } if (oldAsset == null) { oldAsset = (Asset) document.getOldMaintainableObject().getBusinessObject(); } // for fabrication if (oldAsset == null) { oldAsset = newAsset; } } /** * If the tag number has not been assigned, the departmental user will be able to update the tag number. The Tag Number shall be * verified that the tag number does not exist on another asset. * * @param asset * @return */ protected boolean validateTagNumber() { boolean valid = true; boolean anyFound = false; if (!assetService.isTagNumberCheckExclude(newAsset)) { Map<String, Object> fieldValues = new HashMap<String, Object>(); if (ObjectUtils.isNotNull(newAsset.getCampusTagNumber())) { fieldValues.put(CamsPropertyConstants.Asset.CAMPUS_TAG_NUMBER, newAsset.getCampusTagNumber().toUpperCase()); Collection<Asset> results = getBoService().findMatching(Asset.class, fieldValues); for (Asset asset : results) { if (!asset.getCapitalAssetNumber().equals(newAsset.getCapitalAssetNumber())) { // KFSMI-6149 - do not invalidate if the asset from the database is retired if (StringUtils.isBlank(asset.getRetirementReasonCode())) { putFieldError(CamsPropertyConstants.Asset.CAMPUS_TAG_NUMBER, CamsKeyConstants.AssetLocationGlobal.ERROR_DUPLICATE_TAG_NUMBER_FOUND, new String[] { newAsset.getCampusTagNumber(), asset.getCapitalAssetNumber().toString(), newAsset.getCapitalAssetNumber().toString() }); valid &= false; LOG.info("The asset tag number [" + newAsset.getCampusTagNumber().toUpperCase() + "] is a duplicate of asset number [" + asset.getCapitalAssetNumber().toString() + "]'s tag number"); } else { LOG.info("Although the asset tag number [" + newAsset.getCampusTagNumber().toUpperCase() + "] is a duplicate of asset number [" + asset.getCapitalAssetNumber().toString() + "]'s tag number, the old asset has already been retired"); } } } } } return valid; } /** * The Vendor Name is required for capital equipment and not required for non-capital assets. * * @param asset * @return */ protected boolean validateVendorName() { boolean valid = true; if (assetService.isCapitalAsset(newAsset) && StringUtils.isBlank(newAsset.getVendorName())) { putFieldError(CamsPropertyConstants.Asset.VENDOR_NAME, CamsKeyConstants.ERROR_CAPITAL_ASSET_VENDOR_NAME_REQUIRED); valid &= false; } return valid; } /** * Validate Asset Location fields * * @param asset * @return */ protected boolean validateLocation() { GlobalVariables.getMessageMap().addToErrorPath("document.newMaintainableObject"); boolean isCapitalAsset = assetService.isCapitalAsset(newAsset); boolean valid = assetLocationService.validateLocation(LOCATION_FIELD_MAP, newAsset, isCapitalAsset, newAsset.getCapitalAssetType()); GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject"); if (valid && (this.isFabrication || isOffCampusLocationChanged())) { assetLocationService.updateOffCampusLocation(newAsset); } return valid; } /** * Validate warranty information if user enters value * * @param asset Asset * @return validation result */ protected boolean validateWarrantyInformation(Asset asset) { AssetWarranty warranty = asset.getAssetWarranty(); if (warranty != null) { if (!StringUtils.isEmpty(warranty.getWarrantyContactName()) || !StringUtils.isEmpty(warranty.getWarrantyPhoneNumber()) || !StringUtils.isEmpty(warranty.getWarrantyText()) || warranty.getWarrantyBeginningDate() != null || warranty.getWarrantyEndingDate() != null) { if (StringUtils.isEmpty(warranty.getWarrantyNumber())) { // warranty number is mandatory when any other related info is known putFieldError(ASSET_WARRANTY_WARRANTY_NUMBER, ERROR_INVALID_ASSET_WARRANTY_NO); return false; } } } return true; } /** * validates depreciation data * * @param asset * @return boolean */ protected boolean validateDepreciationData(Asset asset) { //do not run the validation if the total cost amount is negative. //see KFSMI-9266 for details. if (ObjectUtils.isNotNull(asset.getTotalCostAmount()) && asset.getTotalCostAmount().compareTo(KualiDecimal.ZERO) < 0) { return true; } if (asset.getSalvageAmount() == null) { asset.setSalvageAmount(KualiDecimal.ZERO); } if (asset.getBaseAmount() == null) { asset.setBaseAmount(KualiDecimal.ZERO); } // If the salvage amount is greater than the base amount, then data is invalid if (asset.getSalvageAmount().compareTo(asset.getBaseAmount()) > 0) { GlobalVariables.getMessageMap().putWarning(MAINTAINABLE_ERROR_PREFIX + CamsPropertyConstants.Asset.SALVAGE_AMOUNT, CamsKeyConstants.Asset.ERROR_INVALID_SALVAGE_AMOUNT); } // If book value is negative then depreciation data is invalid. if (asset.getBookValue().compareTo(KualiDecimal.ZERO) < 0) { putFieldError(CamsPropertyConstants.Asset.BOOK_VALUE, CamsKeyConstants.Asset.ERROR_INVALID_BOOKVALUE_AMOUNT); return false; } return true; } @Override protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) { boolean valid = super.processCustomRouteDocumentBusinessRules(document); initializeAttributes(document); if (SpringContext.getBean(AssetService.class).isAssetFabrication(document) && newAsset.getCapitalAssetNumber() == null) { newAsset.setCapitalAssetNumber(NextAssetNumberFinder.getLongValue()); oldAsset.setCapitalAssetNumber(newAsset.getCapitalAssetNumber()); newAsset.setLastInventoryDate(new Timestamp(SpringContext.getBean(DateTimeService.class).getCurrentSqlDate().getTime())); oldAsset.setLastInventoryDate(new Timestamp(SpringContext.getBean(DateTimeService.class).getCurrentSqlDate().getTime())); } // check for change valid &= checkAcquisitionTypeCodeChange(); valid &= checkConditionCodeChange(); valid &= checkAssetStatusCodeChange(); valid &= checkAssetTypeCodeChange(); valid &= checkFinancialObjectSubtypeCodeChange(); valid &= validateAccount(); WorkflowDocument workflowDoc = document.getDocumentHeader().getWorkflowDocument(); // adding asset locks for asset edit only if (newAsset instanceof Asset && !(newAsset instanceof AssetFabrication) && !GlobalVariables.getMessageMap().hasErrors() && (workflowDoc.isInitiated() || workflowDoc.isSaved())) { valid &= setAssetLock(document); } return valid; } /** * Locking asset number * * @param document * @return */ protected boolean setAssetLock(MaintenanceDocument document) { Asset asset = (Asset) document.getNewMaintainableObject().getBusinessObject(); return this.getCapitalAssetManagementModuleService().storeAssetLocks(retrieveAssetNumberForLocking(asset), document.getDocumentNumber(), CamsConstants.DocumentTypeName.ASSET_EDIT, null); } protected CapitalAssetManagementModuleService getCapitalAssetManagementModuleService() { return SpringContext.getBean(CapitalAssetManagementModuleService.class); } /** * Convenience method to append the path prefix */ public AutoPopulatingList<ErrorMessage> putError(String propertyName, String errorKey, String... errorParameters) { return GlobalVariables.getMessageMap().putError(CamsConstants.DOCUMENT_PATH + "." + propertyName, errorKey, errorParameters); } /** * Check if the Acquisition Type Code is valid or is inactive. * * @param oldAcquisitionTypeCode * @param newAcquisitionTypeCode * @return boolean */ protected boolean checkAcquisitionTypeCodeChange() { if (ObjectUtils.isNull(newAsset.getAcquisitionType())) { putFieldError(CamsPropertyConstants.Asset.ACQUISITION_TYPE_CODE, CamsKeyConstants.Asset.ERROR_ACQUISITION_TYPE_CODE_INVALID); return false; } else if (!StringUtils.equalsIgnoreCase(newAsset.getAcquisitionTypeCode(), oldAsset.getAcquisitionTypeCode())) { newAsset.refreshReferenceObject(CamsPropertyConstants.Asset.REF_ACQUISITION_TYPE); if (ObjectUtils.isNotNull(newAsset.getAcquisitionType())) { if (!newAsset.getAcquisitionType().isActive()) { putFieldError(CamsPropertyConstants.Asset.ACQUISITION_TYPE_CODE, CamsKeyConstants.Asset.ERROR_ACQUISITION_TYPE_CODE_INACTIVE); return false; } } } return true; } /** * Check if the Asset Condition is valid or is inactive. * * @param oldConditionCode * @param newConditionCode * @return boolean */ protected boolean checkConditionCodeChange() { if (ObjectUtils.isNull(newAsset.getCondition())) { putFieldError(CamsPropertyConstants.Asset.CONDITION_CODE, CamsKeyConstants.Asset.ERROR_ASSET_CONDITION_INVALID); return false; } else if (!StringUtils.equalsIgnoreCase(newAsset.getConditionCode(), oldAsset.getConditionCode())) { newAsset.refreshReferenceObject(CamsPropertyConstants.Asset.REF_ASSET_CONDITION); if (ObjectUtils.isNotNull(newAsset.getCondition())) { if (!newAsset.getCondition().isActive()) { putFieldError(CamsPropertyConstants.Asset.CONDITION_CODE, CamsKeyConstants.Asset.ERROR_ASSET_CONDITION_INACTIVE); return false; } } } return true; } /** * Check if the Asset Depreciation Method is valid or is inactive. * * @param oldAssetDepreciationMethod * @param newAssetDepreciationMethod * @return boolean */ protected boolean checkAssetDepreciationMethodChange() { if (ObjectUtils.isNull(newAsset.getAssetPrimaryDepreciationMethod())) { putFieldError(CamsPropertyConstants.Asset.PRIMARY_DEPRECIATION_METHOD, CamsKeyConstants.Asset.ERROR_DEPRECATION_METHOD_CODE_INVALID); return false; } else if (!StringUtils.equalsIgnoreCase(newAsset.getPrimaryDepreciationMethodCode(), oldAsset.getPrimaryDepreciationMethodCode())) { newAsset.refreshReferenceObject(CamsPropertyConstants.Asset.REF_ASSET_DEPRECATION_METHOD); if (ObjectUtils.isNotNull(newAsset.getAssetPrimaryDepreciationMethod())) { if (!newAsset.getAssetPrimaryDepreciationMethod().isActive()) { putFieldError(CamsPropertyConstants.Asset.PRIMARY_DEPRECIATION_METHOD, CamsKeyConstants.Asset.ERROR_DEPRECATION_METHOD_CODE_INACTIVE); return false; } } } return true; } /** * Check if the Asset Status Code is valid or is inactive. * * @param oldAssetStatus * @param newAssetStatus * @return boolean */ protected boolean checkAssetStatusCodeChange() { if (ObjectUtils.isNull(newAsset.getInventoryStatus())) { putFieldError(CamsPropertyConstants.Asset.ASSET_INVENTORY_STATUS, CamsKeyConstants.Asset.ERROR_ASSET_STATUS_INVALID); return false; } else if (!StringUtils.equalsIgnoreCase(newAsset.getInventoryStatusCode(), oldAsset.getInventoryStatusCode())) { newAsset.refreshReferenceObject(CamsPropertyConstants.Asset.REF_ASSET_STATUS); if (ObjectUtils.isNotNull(newAsset.getInventoryStatus())) { if (!newAsset.getInventoryStatus().isActive()) { putFieldError(CamsPropertyConstants.Asset.ASSET_INVENTORY_STATUS, CamsKeyConstants.Asset.ERROR_ASSET_STATUS_INACTIVE); return false; } } } return true; } /** * Check if the Asset Type Code is valid or is inactive. * * @param oldAssetType * @param newAssetType * @return boolean */ protected boolean checkAssetTypeCodeChange() { if (ObjectUtils.isNull(newAsset.getCapitalAssetType())) { putFieldError(CamsPropertyConstants.Asset.CAPITAL_ASSET_TYPE_CODE, CamsKeyConstants.Asset.ERROR_TYPE_CODE_INVALID); return false; } else if (!StringUtils.equalsIgnoreCase(newAsset.getCapitalAssetTypeCode(), oldAsset.getCapitalAssetTypeCode())) { newAsset.refreshReferenceObject(CamsPropertyConstants.Asset.REF_ASSET_TYPE); if (ObjectUtils.isNotNull(newAsset.getCapitalAssetType())) { if (!newAsset.getCapitalAssetType().isActive()) { putFieldError(CamsPropertyConstants.AssetType.CAPITAL_ASSET_TYPE_CODE, CamsKeyConstants.Asset.ERROR_TYPE_CODE_INACTIVE); return false; } } } return true; } /** * Check if the Financial Object Sub-Type Code is valid or is inactive. * * @param oldObjectSubType * @param newObjectSubType * @return boolean */ protected boolean checkFinancialObjectSubtypeCodeChange() { if (ObjectUtils.isNotNull(newAsset.getFinancialObjectSubType()) || StringUtils.isNotBlank(newAsset.getFinancialObjectSubTypeCode())) { newAsset.refreshReferenceObject(CamsPropertyConstants.Asset.REF_OBJECT_SUB_TYPE); if (ObjectUtils.isNull(newAsset.getFinancialObjectSubType())) { putFieldError(CamsPropertyConstants.Asset.FINANCIAL_OBJECT_SUB_TYP_CODE, CamsKeyConstants.Asset.ERROR_FINANCIAL_OBJECT_SUBTYPE_CODE_INVALID); return false; } else if (!newAsset.getFinancialObjectSubType().isActive()) { putFieldError(CamsPropertyConstants.Asset.FINANCIAL_OBJECT_SUB_TYP_CODE, CamsKeyConstants.Asset.ERROR_FINANCIAL_OBJECT_SUBTYPE_CODE_INACTIVE); return false; } } return true; } protected boolean validateManufacturer(Asset asset) { boolean valid = true; if (assetService.isCapitalAsset(asset)) { if (parameterService.getParameterValueAsBoolean(CamsConstants.CAM_MODULE_CODE, "Asset", CamsConstants.Parameters.MANUFACTURER_REQUIRED_FOR_NON_MOVEABLE_ASSET_IND) && StringUtils.isEmpty(asset.getManufacturerName())){ putFieldError(CamsPropertyConstants.Asset.MANUFACTURER_NAME, CamsKeyConstants.AssetGlobal.ERROR_MFR_NAME_REQUIRED); valid = false; } } return valid; } }