001 /* 002 * Copyright 2011 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.kfs.module.cam.document.validation.impl; 017 018 import static org.kuali.kfs.module.cam.CamsKeyConstants.ERROR_INVALID_ASSET_WARRANTY_NO; 019 import static org.kuali.kfs.module.cam.CamsPropertyConstants.Asset.ASSET_WARRANTY_WARRANTY_NUMBER; 020 021 import java.sql.Timestamp; 022 import java.util.ArrayList; 023 import java.util.Collection; 024 import java.util.Date; 025 import java.util.HashMap; 026 import java.util.HashSet; 027 import java.util.List; 028 import java.util.Map; 029 import java.util.Set; 030 031 import org.apache.commons.lang.StringUtils; 032 import org.kuali.kfs.coa.businessobject.Account; 033 import org.kuali.kfs.integration.cam.CapitalAssetManagementModuleService; 034 import org.kuali.kfs.module.cam.CamsConstants; 035 import org.kuali.kfs.module.cam.CamsKeyConstants; 036 import org.kuali.kfs.module.cam.CamsPropertyConstants; 037 import org.kuali.kfs.module.cam.businessobject.Asset; 038 import org.kuali.kfs.module.cam.businessobject.AssetComponent; 039 import org.kuali.kfs.module.cam.businessobject.AssetFabrication; 040 import org.kuali.kfs.module.cam.businessobject.AssetLocation; 041 import org.kuali.kfs.module.cam.businessobject.AssetRepairHistory; 042 import org.kuali.kfs.module.cam.businessobject.AssetWarranty; 043 import org.kuali.kfs.module.cam.businessobject.defaultvalue.NextAssetNumberFinder; 044 import org.kuali.kfs.module.cam.document.service.AssetComponentService; 045 import org.kuali.kfs.module.cam.document.service.AssetDateService; 046 import org.kuali.kfs.module.cam.document.service.AssetLocationService; 047 import org.kuali.kfs.module.cam.document.service.AssetLocationService.LocationField; 048 import org.kuali.kfs.module.cam.document.service.AssetService; 049 import org.kuali.kfs.module.cam.document.service.EquipmentLoanOrReturnService; 050 import org.kuali.kfs.module.cam.document.service.PaymentSummaryService; 051 import org.kuali.kfs.module.cam.document.service.RetirementInfoService; 052 import org.kuali.kfs.sys.context.SpringContext; 053 import org.kuali.kfs.sys.service.UniversityDateService; 054 import org.kuali.rice.kns.bo.PersistableBusinessObject; 055 import org.kuali.rice.kns.document.MaintenanceDocument; 056 import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase; 057 import org.kuali.rice.kns.service.DateTimeService; 058 import org.kuali.rice.kns.service.ParameterService; 059 import org.kuali.rice.kns.util.DateUtils; 060 import org.kuali.rice.kns.util.GlobalVariables; 061 import org.kuali.rice.kns.util.KualiDecimal; 062 import org.kuali.rice.kns.util.ObjectUtils; 063 import org.kuali.rice.kns.util.TypedArrayList; 064 import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument; 065 066 /** 067 * AssetRule for Asset edit. 068 */ 069 public class AssetRule extends MaintenanceDocumentRuleBase { 070 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AssetRule.class); 071 protected static final Map<LocationField, String> LOCATION_FIELD_MAP = new HashMap<LocationField, String>(); 072 static { 073 LOCATION_FIELD_MAP.put(LocationField.CAMPUS_CODE, CamsPropertyConstants.Asset.CAMPUS_CODE); 074 LOCATION_FIELD_MAP.put(LocationField.BUILDING_CODE, CamsPropertyConstants.Asset.BUILDING_CODE); 075 LOCATION_FIELD_MAP.put(LocationField.ROOM_NUMBER, CamsPropertyConstants.Asset.BUILDING_ROOM_NUMBER); 076 LOCATION_FIELD_MAP.put(LocationField.SUB_ROOM_NUMBER, CamsPropertyConstants.Asset.BUILDING_SUB_ROOM_NUMBER); 077 LOCATION_FIELD_MAP.put(LocationField.CONTACT_NAME, CamsPropertyConstants.Asset.AssetLocation.CONTACT_NAME); 078 LOCATION_FIELD_MAP.put(LocationField.STREET_ADDRESS, CamsPropertyConstants.Asset.AssetLocation.STREET_ADDRESS); 079 LOCATION_FIELD_MAP.put(LocationField.CITY_NAME, CamsPropertyConstants.Asset.AssetLocation.CITY_NAME); 080 LOCATION_FIELD_MAP.put(LocationField.STATE_CODE, CamsPropertyConstants.Asset.AssetLocation.STATE_CODE); 081 LOCATION_FIELD_MAP.put(LocationField.ZIP_CODE, CamsPropertyConstants.Asset.AssetLocation.ZIP_CODE); 082 LOCATION_FIELD_MAP.put(LocationField.COUNTRY_CODE, CamsPropertyConstants.Asset.AssetLocation.COUNTRY_CODE); 083 } 084 085 // protected AgencyService agencyService = SpringContext.getBean(AgencyService.class); 086 protected AssetService assetService = SpringContext.getBean(AssetService.class); 087 protected ParameterService parameterService = SpringContext.getBean(ParameterService.class); 088 protected PaymentSummaryService paymentSummaryService = SpringContext.getBean(PaymentSummaryService.class); 089 protected RetirementInfoService retirementInfoService = SpringContext.getBean(RetirementInfoService.class); 090 protected EquipmentLoanOrReturnService equipmentLoanOrReturnService = SpringContext.getBean(EquipmentLoanOrReturnService.class); 091 protected AssetDateService assetDateService = SpringContext.getBean(AssetDateService.class); 092 protected AssetComponentService assetComponentService = SpringContext.getBean(AssetComponentService.class); 093 protected UniversityDateService universityDateService = SpringContext.getBean(UniversityDateService.class); 094 protected AssetLocationService assetLocationService = SpringContext.getBean(AssetLocationService.class); 095 protected DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class); 096 097 protected Asset newAsset; 098 protected Asset oldAsset; 099 protected boolean isFabrication; 100 101 102 /** 103 * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument) 104 */ 105 @Override 106 protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) { 107 initializeAttributes(document); 108 boolean valid = true; 109 if (SpringContext.getBean(AssetService.class).isAssetFabrication(document)) { 110 this.isFabrication = true; 111 valid &= validateAccount(); 112 valid &= validateLocation(); 113 valid &= validateFabricationDetails(); 114 } 115 else { 116 setAssetComponentNumbers(newAsset); 117 paymentSummaryService.calculateAndSetPaymentSummary(oldAsset); 118 paymentSummaryService.calculateAndSetPaymentSummary(newAsset); 119 120 assetService.setSeparateHistory(oldAsset); 121 assetService.setSeparateHistory(newAsset); 122 123 retirementInfoService.setRetirementInfo(oldAsset); 124 retirementInfoService.setRetirementInfo(newAsset); 125 126 equipmentLoanOrReturnService.setEquipmentLoanInfo(oldAsset); 127 equipmentLoanOrReturnService.setEquipmentLoanInfo(newAsset); 128 129 valid &= processAssetValidation(document); 130 valid &= validateWarrantyInformation(newAsset); 131 valid &= validateDepreciationData(newAsset); 132 133 valid &= super.processCustomSaveDocumentBusinessRules(document); 134 if (valid) { 135 assetDateService.checkAndUpdateLastInventoryDate(oldAsset, newAsset); 136 assetDateService.checkAndUpdateDepreciationDate(oldAsset, newAsset); 137 assetDateService.checkAndUpdateFiscalYearAndPeriod(oldAsset, newAsset); 138 } 139 140 valid &= checkAssetLocked(document); 141 } 142 return valid; 143 } 144 145 /** 146 * Check if asset is locked by other document. 147 * 148 * @param document 149 * @param valid 150 * @return 151 */ 152 protected boolean checkAssetLocked(MaintenanceDocument document) { 153 Asset asset = (Asset) document.getNewMaintainableObject().getBusinessObject(); 154 return !getCapitalAssetManagementModuleService().isAssetLocked(retrieveAssetNumberForLocking(asset), CamsConstants.DocumentTypeName.ASSET_EDIT, document.getDocumentNumber()); 155 } 156 157 /** 158 * Retrieve asset numbers need to be locked. 159 * 160 * @return 161 */ 162 protected List<Long> retrieveAssetNumberForLocking(Asset asset) { 163 List<Long> capitalAssetNumbers = new ArrayList<Long>(); 164 if (asset.getCapitalAssetNumber() != null) { 165 capitalAssetNumbers.add(asset.getCapitalAssetNumber()); 166 } 167 return capitalAssetNumbers; 168 } 169 170 /** 171 * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomAddCollectionLineBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument, 172 * java.lang.String, org.kuali.rice.kns.bo.PersistableBusinessObject) 173 */ 174 @Override 175 public boolean processCustomAddCollectionLineBusinessRules(MaintenanceDocument documentCopy, String collectionName, PersistableBusinessObject bo) { 176 boolean success = true; 177 178 // get all incidentDates from AssetRepairHistory collection and check for duplicate dates. 179 if (collectionName.equals(CamsConstants.Asset.COLLECTION_ID_ASSET_REPAIR_HISTORY)) { 180 181 Asset asset = (Asset) documentCopy.getNewMaintainableObject().getBusinessObject(); 182 Set<Date> incidentDateSet = new HashSet<Date>(); 183 184 for (AssetRepairHistory assetRepairHistory : asset.getAssetRepairHistory()) { 185 if (assetRepairHistory.getIncidentDate() != null) { 186 incidentDateSet.add(assetRepairHistory.getIncidentDate()); 187 } 188 } 189 190 AssetRepairHistory assetRepairHistoryDetails = (AssetRepairHistory) bo; 191 192 success &= checkDuplicateIncidentDate(assetRepairHistoryDetails, incidentDateSet); 193 194 return success & super.processCustomAddCollectionLineBusinessRules(documentCopy, collectionName, bo); 195 } 196 197 return success; 198 } 199 200 /** 201 * Check for duplicate incident dates within the Repair History section 202 * 203 * @param assetRepairHistory 204 * @param incidentDateSet 205 * @return boolean 206 */ 207 protected boolean checkDuplicateIncidentDate(AssetRepairHistory assetRepairHistory, Set<Date> incidentDateSet) { 208 boolean success = true; 209 210 if (!incidentDateSet.add(assetRepairHistory.getIncidentDate())) { 211 GlobalVariables.getMessageMap().putError(CamsPropertyConstants.AssetRepairHistory.INCIDENT_DATE, CamsKeyConstants.AssetRepairHistory.ERROR_DUPLICATE_INCIDENT_DATE); 212 success &= false; 213 } 214 215 return success; 216 } 217 218 /** 219 * Validate fabrication details 220 * 221 * @return boolean 222 */ 223 protected boolean validateFabricationDetails() { 224 /** 225 * Please don't remove this validation, forcing required fields from DD file is not possible and will break asset edit 226 * screen, so please leave this validation here. 227 */ 228 boolean valid = true; 229 if (newAsset.getFabricationEstimatedTotalAmount() != null && newAsset.getFabricationEstimatedTotalAmount().isNegative()) { 230 putFieldError(CamsPropertyConstants.Asset.FABRICATION_ESTIMATED_TOTAL_AMOUNT, CamsKeyConstants.ERROR_FABRICATION_ESTIMATED_TOTAL_AMOUNT_NEGATIVE); 231 valid &= false; 232 } 233 if (newAsset.getEstimatedFabricationCompletionDate() != null && newAsset.getEstimatedFabricationCompletionDate().before(DateUtils.clearTimeFields(dateTimeService.getCurrentDate()))) { 234 putFieldError(CamsPropertyConstants.Asset.ESTIMATED_FABRICATION_COMPLETION_DATE, CamsKeyConstants.ERROR_ESTIMATED_FABRICATION_COMPLETION_DATE_PAST); 235 valid &= false; 236 } 237 if (newAsset.getFabricationEstimatedRetentionYears() != null && newAsset.getFabricationEstimatedRetentionYears().intValue() < 0) { 238 putFieldError(CamsPropertyConstants.Asset.FABRICATION_ESTIMATED_RETENTION_YEARS, CamsKeyConstants.ERROR_ESTIMATED_FABRICATION_LIFE_LIMIT_NEGATIVE); 239 valid &= false; 240 } 241 return valid; 242 } 243 244 /** 245 * Validate account 246 * 247 * @return boolean 248 */ 249 protected boolean validateAccount() { 250 boolean valid = true; 251 Account currentOwnerAccount = newAsset.getOrganizationOwnerAccount(); 252 Account previoudOwnerAccount = oldAsset.getOrganizationOwnerAccount(); 253 254 // Account is valid? 255 if (ObjectUtils.isNull(currentOwnerAccount) && StringUtils.isNotBlank(newAsset.getOrganizationOwnerAccountNumber())) { 256 putFieldError(CamsPropertyConstants.Asset.ORGANIZATION_OWNER_ACCOUNT_NUMBER, CamsKeyConstants.ORGANIZATION_OWNER_ACCOUNT_INVALID); 257 valid &= false; 258 } 259 260 // check if values changed, if not return 261 if (ObjectUtils.isNotNull(previoudOwnerAccount) && ObjectUtils.isNotNull(currentOwnerAccount) && previoudOwnerAccount.getChartOfAccountsCode().equals(currentOwnerAccount.getChartOfAccountsCode()) && previoudOwnerAccount.getAccountNumber().equals(currentOwnerAccount.getAccountNumber())) { 262 return valid; 263 264 } 265 else if (ObjectUtils.isNotNull(currentOwnerAccount) && (currentOwnerAccount.isExpired() || !currentOwnerAccount.isActive())) { 266 // Account is not active 267 putFieldError(CamsPropertyConstants.Asset.ORGANIZATION_OWNER_ACCOUNT_NUMBER, CamsKeyConstants.ORGANIZATION_OWNER_ACCOUNT_INACTIVE); 268 valid &= false; 269 } 270 return valid; 271 } 272 273 /** 274 * Set asset component numbers 275 * 276 * @param asset 277 */ 278 protected void setAssetComponentNumbers(Asset asset) { 279 List<AssetComponent> assetComponents = asset.getAssetComponents(); 280 Integer maxNo = null; 281 for (AssetComponent assetComponent : assetComponents) { 282 assetComponent.setCapitalAssetNumber(asset.getCapitalAssetNumber()); 283 if (maxNo == null) { 284 maxNo = assetComponentService.getMaxSequenceNumber(assetComponent); 285 } 286 if (assetComponent.getComponentNumber() == null) { 287 assetComponent.setComponentNumber(++maxNo); 288 } 289 } 290 } 291 292 /** 293 * Validates Asset document. 294 * 295 * @param document MaintenanceDocument instance 296 * @return boolean false or true 297 */ 298 protected boolean processAssetValidation(MaintenanceDocument document) { 299 boolean valid = true; 300 301 // validate Inventory Status Code. 302 if (!StringUtils.equalsIgnoreCase(oldAsset.getInventoryStatusCode(), newAsset.getInventoryStatusCode())) { 303 valid &= validateInventoryStatusCode(oldAsset.getInventoryStatusCode(), newAsset.getInventoryStatusCode()); 304 } 305 306 // validate Organization Owner Account Number 307 if (!StringUtils.equalsIgnoreCase(oldAsset.getOrganizationOwnerAccountNumber(), newAsset.getOrganizationOwnerAccountNumber())) { 308 valid &= validateAccount(); 309 } 310 311 // validate Vendor Name. 312 if (!StringUtils.equalsIgnoreCase(oldAsset.getVendorName(), newAsset.getVendorName())) { 313 valid &= validateVendorName(); 314 } 315 316 // validate Tag Number. 317 if (!StringUtils.equalsIgnoreCase(oldAsset.getCampusTagNumber(), newAsset.getCampusTagNumber())) { 318 valid &= validateTagNumber(); 319 } 320 321 // validate location. 322 valid &= validateLocation(); 323 324 // validate In-service Date 325 if (assetService.isInServiceDateChanged(oldAsset, newAsset)) { 326 valid &= validateInServiceDate(); 327 } 328 return valid; 329 } 330 331 332 /** 333 * Check if the new In-service Date is a valid University Date 334 * 335 * @return 336 */ 337 protected boolean validateInServiceDate() { 338 boolean valid = true; 339 // if asset already starts depreciation, the user can't blank in-service date. 340 if (ObjectUtils.isNull(newAsset.getCapitalAssetInServiceDate()) && assetService.isAssetDepreciationStarted(oldAsset)) { 341 putFieldError(CamsPropertyConstants.Asset.ASSET_DATE_OF_SERVICE, CamsKeyConstants.ERROR_BLANK_IN_SERVICE_DATE_DISALLOWED); 342 valid = false; 343 } 344 345 else if (ObjectUtils.isNotNull(newAsset.getCapitalAssetInServiceDate()) && universityDateService.getFiscalYear(newAsset.getCapitalAssetInServiceDate()) == null) { 346 putFieldError(CamsPropertyConstants.Asset.ASSET_DATE_OF_SERVICE, CamsKeyConstants.ERROR_INVALID_IN_SERVICE_DATE); 347 valid = false; 348 } 349 return valid; 350 } 351 352 353 /** 354 * Check if off campus fields has changed. 355 * 356 * @return 357 */ 358 protected boolean isOffCampusLocationChanged() { 359 boolean changed = false; 360 AssetLocation oldLocation = oldAsset.getOffCampusLocation(); 361 AssetLocation newLocation = newAsset.getOffCampusLocation(); 362 363 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())) { 364 changed = true; 365 } 366 return changed; 367 } 368 369 /** 370 * Validate Inventory Status Code Change 371 */ 372 protected boolean validateInventoryStatusCode(String oldInventoryStatusCode, String newInventoryStatusCode) { 373 boolean valid = true; 374 if (assetService.isCapitalAsset(oldAsset) && assetService.isAssetRetired(newAsset)) { 375 // disallow retire capital asset. 376 putFieldError(CamsPropertyConstants.Asset.ASSET_INVENTORY_STATUS, CamsKeyConstants.ERROR_ASSET_RETIRED_CAPITAL); 377 valid = false; 378 } 379 else { 380 // validate inventory status change per system parameter. 381 GlobalVariables.getMessageMap().addToErrorPath(MAINTAINABLE_ERROR_PATH); 382 valid &= parameterService.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); 383 GlobalVariables.getMessageMap().removeFromErrorPath(MAINTAINABLE_ERROR_PATH); 384 } 385 return valid; 386 } 387 388 protected void initializeAttributes(MaintenanceDocument document) { 389 if (newAsset == null) { 390 newAsset = (Asset) document.getNewMaintainableObject().getBusinessObject(); 391 } 392 if (oldAsset == null) { 393 oldAsset = (Asset) document.getOldMaintainableObject().getBusinessObject(); 394 } 395 // for fabrication 396 if (oldAsset == null) { 397 oldAsset = newAsset; 398 } 399 } 400 401 /** 402 * If the tag number has not been assigned, the departmental user will be able to update the tag number. The Tag Number shall be 403 * verified that the tag number does not exist on another asset. 404 * 405 * @param asset 406 * @return 407 */ 408 protected boolean validateTagNumber() { 409 boolean valid = true; 410 boolean anyFound = false; 411 412 if (!assetService.isTagNumberCheckExclude(newAsset)) { 413 414 Map<String, Object> fieldValues = new HashMap<String, Object>(); 415 fieldValues.put(CamsPropertyConstants.Asset.CAMPUS_TAG_NUMBER, newAsset.getCampusTagNumber().toUpperCase()); 416 417 Collection<Asset> results = getBoService().findMatching(Asset.class, fieldValues); 418 419 for (Asset asset : results) { 420 if (!asset.getCapitalAssetNumber().equals(newAsset.getCapitalAssetNumber())) { 421 // KFSMI-6149 - do not invalidate if the asset from the database is retired 422 if (StringUtils.isBlank(asset.getRetirementReasonCode())) { 423 putFieldError(CamsPropertyConstants.Asset.CAMPUS_TAG_NUMBER, CamsKeyConstants.AssetLocationGlobal.ERROR_DUPLICATE_TAG_NUMBER_FOUND, new String[] { newAsset.getCampusTagNumber(), asset.getCapitalAssetNumber().toString(), newAsset.getCapitalAssetNumber().toString() }); 424 valid &= false; 425 LOG.info("The asset tag number [" + newAsset.getCampusTagNumber().toUpperCase() + "] is a duplicate of asset number [" + asset.getCapitalAssetNumber().toString() + "]'s tag number"); 426 } else { 427 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"); 428 } 429 } 430 } 431 } 432 433 return valid; 434 } 435 436 /** 437 * The Vendor Name is required for capital equipment and not required for non-capital assets. 438 * 439 * @param asset 440 * @return 441 */ 442 protected boolean validateVendorName() { 443 boolean valid = true; 444 445 if (assetService.isCapitalAsset(newAsset) && StringUtils.isBlank(newAsset.getVendorName())) { 446 putFieldError(CamsPropertyConstants.Asset.VENDOR_NAME, CamsKeyConstants.ERROR_CAPITAL_ASSET_VENDOR_NAME_REQUIRED); 447 valid &= false; 448 449 } 450 return valid; 451 } 452 453 454 /** 455 * Validate Asset Location fields 456 * 457 * @param asset 458 * @return 459 */ 460 protected boolean validateLocation() { 461 GlobalVariables.getMessageMap().addToErrorPath("document.newMaintainableObject"); 462 boolean isCapitalAsset = assetService.isCapitalAsset(newAsset); 463 boolean valid = assetLocationService.validateLocation(LOCATION_FIELD_MAP, newAsset, isCapitalAsset, newAsset.getCapitalAssetType()); 464 GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject"); 465 466 if (valid && (this.isFabrication || isOffCampusLocationChanged())) { 467 assetLocationService.updateOffCampusLocation(newAsset); 468 } 469 return valid; 470 } 471 472 /** 473 * Validate warranty information if user enters value 474 * 475 * @param asset Asset 476 * @return validation result 477 */ 478 protected boolean validateWarrantyInformation(Asset asset) { 479 AssetWarranty warranty = asset.getAssetWarranty(); 480 if (warranty != null) { 481 if (!StringUtils.isEmpty(warranty.getWarrantyContactName()) || !StringUtils.isEmpty(warranty.getWarrantyPhoneNumber()) || !StringUtils.isEmpty(warranty.getWarrantyText()) || warranty.getWarrantyBeginningDate() != null || warranty.getWarrantyEndingDate() != null) { 482 if (StringUtils.isEmpty(warranty.getWarrantyNumber())) { 483 // warranty number is mandatory when any other related info is known 484 putFieldError(ASSET_WARRANTY_WARRANTY_NUMBER, ERROR_INVALID_ASSET_WARRANTY_NO); 485 return false; 486 } 487 } 488 } 489 return true; 490 } 491 492 /** 493 * validates depreciation data 494 * 495 * @param asset 496 * @return boolean 497 */ 498 protected boolean validateDepreciationData(Asset asset) { 499 if (asset.getSalvageAmount() == null) { 500 asset.setSalvageAmount(KualiDecimal.ZERO); 501 } 502 503 if (asset.getBaseAmount() == null) { 504 asset.setBaseAmount(KualiDecimal.ZERO); 505 } 506 507 // If the salvage amount is greater than the base amount, then data is invalid 508 if (asset.getSalvageAmount().compareTo(asset.getBaseAmount()) > 0) { 509 putFieldError(CamsPropertyConstants.Asset.SALVAGE_AMOUNT, CamsKeyConstants.Asset.ERROR_INVALID_SALVAGE_AMOUNT); 510 return false; 511 } 512 else { 513 return true; 514 } 515 } 516 517 @Override 518 protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) { 519 boolean valid = super.processCustomRouteDocumentBusinessRules(document); 520 initializeAttributes(document); 521 if (SpringContext.getBean(AssetService.class).isAssetFabrication(document) && newAsset.getCapitalAssetNumber() == null) { 522 newAsset.setCapitalAssetNumber(NextAssetNumberFinder.getLongValue()); 523 oldAsset.setCapitalAssetNumber(newAsset.getCapitalAssetNumber()); 524 newAsset.setLastInventoryDate(new Timestamp(SpringContext.getBean(DateTimeService.class).getCurrentSqlDate().getTime())); 525 oldAsset.setLastInventoryDate(new Timestamp(SpringContext.getBean(DateTimeService.class).getCurrentSqlDate().getTime())); 526 } 527 528 // check for change 529 valid &= checkAcquisitionTypeCodeChange(); 530 valid &= checkConditionCodeChange(); 531 valid &= checkAssetDepreciationMethodChange(); 532 valid &= checkAssetStatusCodeChange(); 533 valid &= checkAssetTypeCodeChange(); 534 valid &= checkFinancialObjectSubtypeCodeChange(); 535 valid &= validateAccount(); 536 537 KualiWorkflowDocument workflowDoc = document.getDocumentHeader().getWorkflowDocument(); 538 // adding asset locks for asset edit only 539 if (newAsset instanceof Asset && !(newAsset instanceof AssetFabrication) && !GlobalVariables.getMessageMap().hasErrors() && (workflowDoc.stateIsInitiated() || workflowDoc.stateIsSaved())) { 540 valid &= setAssetLock(document); 541 } 542 return valid; 543 } 544 545 /** 546 * Locking asset number 547 * 548 * @param document 549 * @return 550 */ 551 protected boolean setAssetLock(MaintenanceDocument document) { 552 Asset asset = (Asset) document.getNewMaintainableObject().getBusinessObject(); 553 return this.getCapitalAssetManagementModuleService().storeAssetLocks(retrieveAssetNumberForLocking(asset), document.getDocumentNumber(), CamsConstants.DocumentTypeName.ASSET_EDIT, null); 554 } 555 556 protected CapitalAssetManagementModuleService getCapitalAssetManagementModuleService() { 557 return SpringContext.getBean(CapitalAssetManagementModuleService.class); 558 } 559 560 /** 561 * Convenience method to append the path prefix 562 */ 563 public TypedArrayList putError(String propertyName, String errorKey, String... errorParameters) { 564 return GlobalVariables.getMessageMap().putError(CamsConstants.DOCUMENT_PATH + "." + propertyName, errorKey, errorParameters); 565 } 566 567 /** 568 * Check if the Acquisition Type Code is valid or is inactive. 569 * 570 * @param oldAcquisitionTypeCode 571 * @param newAcquisitionTypeCode 572 * @return boolean 573 */ 574 protected boolean checkAcquisitionTypeCodeChange() { 575 if (ObjectUtils.isNull(newAsset.getAcquisitionType())) { 576 putFieldError(CamsPropertyConstants.Asset.ACQUISITION_TYPE_CODE, CamsKeyConstants.Asset.ERROR_ACQUISITION_TYPE_CODE_INVALID); 577 return false; 578 } 579 else if (!StringUtils.equalsIgnoreCase(newAsset.getAcquisitionTypeCode(), oldAsset.getAcquisitionTypeCode())) { 580 newAsset.refreshReferenceObject(CamsPropertyConstants.Asset.REF_ACQUISITION_TYPE); 581 if (ObjectUtils.isNotNull(newAsset.getAcquisitionType())) { 582 if (!newAsset.getAcquisitionType().isActive()) { 583 putFieldError(CamsPropertyConstants.Asset.ACQUISITION_TYPE_CODE, CamsKeyConstants.Asset.ERROR_ACQUISITION_TYPE_CODE_INACTIVE); 584 return false; 585 } 586 } 587 } 588 return true; 589 } 590 591 /** 592 * Check if the Asset Condition is valid or is inactive. 593 * 594 * @param oldConditionCode 595 * @param newConditionCode 596 * @return boolean 597 */ 598 protected boolean checkConditionCodeChange() { 599 if (ObjectUtils.isNull(newAsset.getCondition())) { 600 putFieldError(CamsPropertyConstants.Asset.CONDITION_CODE, CamsKeyConstants.Asset.ERROR_ASSET_CONDITION_INVALID); 601 return false; 602 } 603 else if (!StringUtils.equalsIgnoreCase(newAsset.getConditionCode(), oldAsset.getConditionCode())) { 604 newAsset.refreshReferenceObject(CamsPropertyConstants.Asset.REF_ASSET_CONDITION); 605 if (ObjectUtils.isNotNull(newAsset.getCondition())) { 606 if (!newAsset.getCondition().isActive()) { 607 putFieldError(CamsPropertyConstants.Asset.CONDITION_CODE, CamsKeyConstants.Asset.ERROR_ASSET_CONDITION_INACTIVE); 608 return false; 609 } 610 } 611 } 612 return true; 613 } 614 615 /** 616 * Check if the Asset Depreciation Method is valid or is inactive. 617 * 618 * @param oldAssetDepreciationMethod 619 * @param newAssetDepreciationMethod 620 * @return boolean 621 */ 622 protected boolean checkAssetDepreciationMethodChange() { 623 if (ObjectUtils.isNull(newAsset.getAssetPrimaryDepreciationMethod())) { 624 putFieldError(CamsPropertyConstants.Asset.PRIMARY_DEPRECIATION_METHOD, CamsKeyConstants.Asset.ERROR_DEPRECATION_METHOD_CODE_INVALID); 625 return false; 626 } 627 else if (!StringUtils.equalsIgnoreCase(newAsset.getPrimaryDepreciationMethodCode(), oldAsset.getPrimaryDepreciationMethodCode())) { 628 newAsset.refreshReferenceObject(CamsPropertyConstants.Asset.REF_ASSET_DEPRECATION_METHOD); 629 if (ObjectUtils.isNotNull(newAsset.getAssetPrimaryDepreciationMethod())) { 630 if (!newAsset.getAssetPrimaryDepreciationMethod().isActive()) { 631 putFieldError(CamsPropertyConstants.Asset.PRIMARY_DEPRECIATION_METHOD, CamsKeyConstants.Asset.ERROR_DEPRECATION_METHOD_CODE_INACTIVE); 632 return false; 633 } 634 } 635 } 636 return true; 637 } 638 639 /** 640 * Check if the Asset Status Code is valid or is inactive. 641 * 642 * @param oldAssetStatus 643 * @param newAssetStatus 644 * @return boolean 645 */ 646 protected boolean checkAssetStatusCodeChange() { 647 if (ObjectUtils.isNull(newAsset.getInventoryStatus())) { 648 putFieldError(CamsPropertyConstants.Asset.ASSET_INVENTORY_STATUS, CamsKeyConstants.Asset.ERROR_ASSET_STATUS_INVALID); 649 return false; 650 } 651 else if (!StringUtils.equalsIgnoreCase(newAsset.getInventoryStatusCode(), oldAsset.getInventoryStatusCode())) { 652 newAsset.refreshReferenceObject(CamsPropertyConstants.Asset.REF_ASSET_STATUS); 653 if (ObjectUtils.isNotNull(newAsset.getInventoryStatus())) { 654 if (!newAsset.getInventoryStatus().isActive()) { 655 putFieldError(CamsPropertyConstants.Asset.ASSET_INVENTORY_STATUS, CamsKeyConstants.Asset.ERROR_ASSET_STATUS_INACTIVE); 656 return false; 657 } 658 } 659 } 660 return true; 661 } 662 663 /** 664 * Check if the Asset Type Code is valid or is inactive. 665 * 666 * @param oldAssetType 667 * @param newAssetType 668 * @return boolean 669 */ 670 protected boolean checkAssetTypeCodeChange() { 671 if (ObjectUtils.isNull(newAsset.getCapitalAssetType())) { 672 putFieldError(CamsPropertyConstants.Asset.CAPITAL_ASSET_TYPE_CODE, CamsKeyConstants.Asset.ERROR_TYPE_CODE_INVALID); 673 return false; 674 } 675 else if (!StringUtils.equalsIgnoreCase(newAsset.getCapitalAssetTypeCode(), oldAsset.getCapitalAssetTypeCode())) { 676 newAsset.refreshReferenceObject(CamsPropertyConstants.Asset.REF_ASSET_TYPE); 677 if (ObjectUtils.isNotNull(newAsset.getCapitalAssetType())) { 678 if (!newAsset.getCapitalAssetType().isActive()) { 679 putFieldError(CamsPropertyConstants.AssetType.CAPITAL_ASSET_TYPE_CODE, CamsKeyConstants.Asset.ERROR_TYPE_CODE_INACTIVE); 680 return false; 681 } 682 } 683 } 684 return true; 685 } 686 687 /** 688 * Check if the Financial Object Sub-Type Code is valid or is inactive. 689 * 690 * @param oldObjectSubType 691 * @param newObjectSubType 692 * @return boolean 693 */ 694 protected boolean checkFinancialObjectSubtypeCodeChange() { 695 if (ObjectUtils.isNotNull(newAsset.getFinancialObjectSubType()) || StringUtils.isNotBlank(newAsset.getFinancialObjectSubTypeCode())) { 696 newAsset.refreshReferenceObject(CamsPropertyConstants.Asset.REF_OBJECT_SUB_TYPE); 697 if (ObjectUtils.isNull(newAsset.getFinancialObjectSubType())) { 698 putFieldError(CamsPropertyConstants.Asset.FINANCIAL_OBJECT_SUB_TYP_CODE, CamsKeyConstants.Asset.ERROR_FINANCIAL_OBJECT_SUBTYPE_CODE_INVALID); 699 return false; 700 } 701 else if (!newAsset.getFinancialObjectSubType().isActive()) { 702 putFieldError(CamsPropertyConstants.Asset.FINANCIAL_OBJECT_SUB_TYP_CODE, CamsKeyConstants.Asset.ERROR_FINANCIAL_OBJECT_SUBTYPE_CODE_INACTIVE); 703 return false; 704 } 705 } 706 return true; 707 } 708 }