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 java.util.ArrayList; 019 import java.util.HashMap; 020 import java.util.List; 021 import java.util.Map; 022 023 import org.apache.commons.lang.StringUtils; 024 import org.kuali.kfs.coa.businessobject.Account; 025 import org.kuali.kfs.coa.businessobject.ObjectCode; 026 import org.kuali.kfs.coa.businessobject.OffsetDefinition; 027 import org.kuali.kfs.coa.businessobject.Organization; 028 import org.kuali.kfs.coa.service.ObjectCodeService; 029 import org.kuali.kfs.coa.service.OffsetDefinitionService; 030 import org.kuali.kfs.fp.document.TransferOfFundsDocument; 031 import org.kuali.kfs.module.cam.CamsConstants; 032 import org.kuali.kfs.module.cam.CamsKeyConstants; 033 import org.kuali.kfs.module.cam.CamsPropertyConstants; 034 import org.kuali.kfs.module.cam.businessobject.Asset; 035 import org.kuali.kfs.module.cam.businessobject.AssetGlobal; 036 import org.kuali.kfs.module.cam.businessobject.AssetObjectCode; 037 import org.kuali.kfs.module.cam.businessobject.AssetPayment; 038 import org.kuali.kfs.module.cam.document.AssetTransferDocument; 039 import org.kuali.kfs.module.cam.document.service.AssetLocationService; 040 import org.kuali.kfs.module.cam.document.service.AssetObjectCodeService; 041 import org.kuali.kfs.module.cam.document.service.AssetPaymentService; 042 import org.kuali.kfs.module.cam.document.service.AssetService; 043 import org.kuali.kfs.module.cam.document.service.AssetTransferService; 044 import org.kuali.kfs.module.cam.document.service.AssetLocationService.LocationField; 045 import org.kuali.kfs.module.cam.service.AssetLockService; 046 import org.kuali.kfs.sys.KFSConstants; 047 import org.kuali.kfs.sys.context.SpringContext; 048 import org.kuali.kfs.sys.document.authorization.FinancialSystemTransactionalDocumentAuthorizerBase; 049 import org.kuali.kfs.sys.document.validation.impl.GeneralLedgerPostingDocumentRuleBase; 050 import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService; 051 import org.kuali.kfs.sys.service.UniversityDateService; 052 import org.kuali.rice.kim.bo.Person; 053 import org.kuali.rice.kim.service.PersonService; 054 import org.kuali.rice.kns.document.Document; 055 import org.kuali.rice.kns.exception.ValidationException; 056 import org.kuali.rice.kns.service.DocumentHelperService; 057 import org.kuali.rice.kns.service.ParameterService; 058 import org.kuali.rice.kns.util.GlobalVariables; 059 import org.kuali.rice.kns.util.ObjectUtils; 060 import org.kuali.rice.kns.util.TypedArrayList; 061 062 public class AssetTransferDocumentRule extends GeneralLedgerPostingDocumentRuleBase { 063 protected static final Map<LocationField, String> LOCATION_FIELD_MAP = new HashMap<LocationField, String>(); 064 static { 065 LOCATION_FIELD_MAP.put(LocationField.CAMPUS_CODE, CamsPropertyConstants.AssetTransferDocument.CAMPUS_CODE); 066 LOCATION_FIELD_MAP.put(LocationField.BUILDING_CODE, CamsPropertyConstants.AssetTransferDocument.BUILDING_CODE); 067 LOCATION_FIELD_MAP.put(LocationField.ROOM_NUMBER, CamsPropertyConstants.AssetTransferDocument.BUILDING_ROOM_NUMBER); 068 LOCATION_FIELD_MAP.put(LocationField.SUB_ROOM_NUMBER, CamsPropertyConstants.AssetTransferDocument.BUILDING_SUB_ROOM_NUMBER); 069 LOCATION_FIELD_MAP.put(LocationField.STREET_ADDRESS, CamsPropertyConstants.AssetTransferDocument.OFF_CAMPUS_ADDRESS); 070 LOCATION_FIELD_MAP.put(LocationField.CITY_NAME, CamsPropertyConstants.AssetTransferDocument.OFF_CAMPUS_CITY); 071 LOCATION_FIELD_MAP.put(LocationField.STATE_CODE, CamsPropertyConstants.AssetTransferDocument.OFF_CAMPUS_STATE_CODE); 072 LOCATION_FIELD_MAP.put(LocationField.ZIP_CODE, CamsPropertyConstants.AssetTransferDocument.OFF_CAMPUS_ZIP); 073 LOCATION_FIELD_MAP.put(LocationField.COUNTRY_CODE, CamsPropertyConstants.AssetGlobalDetail.OFF_CAMPUS_COUNTRY_CODE); 074 LOCATION_FIELD_MAP.put(LocationField.CONTACT_NAME, CamsPropertyConstants.AssetTransferDocument.OFF_CAMPUS_CONTACT_NAME); 075 } 076 077 protected UniversityDateService universityDateService; 078 protected AssetPaymentService assetPaymentService; 079 protected AssetService assetService; 080 protected ObjectCodeService objectCodeService; 081 protected AssetLockService assetLockService; 082 083 /** 084 * @see org.kuali.rice.kns.rules.DocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.rice.kns.document.Document) 085 */ 086 @Override 087 protected boolean processCustomSaveDocumentBusinessRules(Document document) { 088 AssetTransferDocument assetTransferDocument = (AssetTransferDocument) document; 089 Asset asset = assetTransferDocument.getAsset(); 090 boolean valid = checkReferencesExist(assetTransferDocument); 091 assetTransferDocument.clearGlPostables(); 092 if (valid && (valid &= validateAssetObjectCodeDefn(assetTransferDocument, asset))) { 093 SpringContext.getBean(AssetTransferService.class).createGLPostables(assetTransferDocument); 094 if (!SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(assetTransferDocument)) { 095 throw new ValidationException("General Ledger GLPE generation failed"); 096 } 097 } 098 099 return valid; 100 } 101 102 /** 103 * Retrieve asset number need to be locked. 104 * 105 * @param document 106 * @return 107 */ 108 protected List<Long> retrieveAssetNumberForLocking(Document document) { 109 AssetTransferDocument assetTransferDocument = (AssetTransferDocument) document; 110 List<Long> assetNumbers = new ArrayList<Long>(); 111 if (assetTransferDocument.getAsset().getCapitalAssetNumber() != null) { 112 assetNumbers.add(assetTransferDocument.getAsset().getCapitalAssetNumber()); 113 } 114 return assetNumbers; 115 } 116 117 protected boolean validateAssetObjectCodeDefn(AssetTransferDocument assetTransferDocument, Asset asset) { 118 119 if ( !isNonCapitalAsset(asset) && StringUtils.isNotBlank(assetTransferDocument.getOrganizationOwnerChartOfAccountsCode()) && StringUtils.isNotBlank(assetTransferDocument.getOrganizationOwnerAccountNumber())) { 120 boolean valid = true; 121 List<AssetPayment> assetPayments = asset.getAssetPayments(); 122 ObjectCodeService objectCodeService = (ObjectCodeService) SpringContext.getBean(ObjectCodeService.class); 123 for (AssetPayment assetPayment : assetPayments) { 124 if (SpringContext.getBean(AssetPaymentService.class).isPaymentEligibleForGLPosting(assetPayment) && !assetPayment.getAccountChargeAmount().isZero()) { 125 // validate for transfer source 126 127 ObjectCode objectCode = objectCodeService.getByPrimaryIdForCurrentYear(assetPayment.getChartOfAccountsCode(), assetPayment.getFinancialObjectCode()); 128 129 AssetObjectCode originAssetObjectCode = SpringContext.getBean(AssetObjectCodeService.class).findAssetObjectCode(asset.getOrganizationOwnerChartOfAccountsCode(), objectCode.getFinancialObjectSubTypeCode()); 130 if (valid &= validateAssetObjectCode(originAssetObjectCode, asset.getOrganizationOwnerChartOfAccountsCode(), objectCode.getFinancialObjectSubTypeCode())) { 131 // validate object codes used to generate Capitalization/Accumulated Depreciation/Offset GL Postings. 132 valid &= validateFinancialObjectCodes(asset, assetPayment, originAssetObjectCode); 133 } 134 // validate for transfer target 135 AssetObjectCode targetAssetObjectCode = SpringContext.getBean(AssetObjectCodeService.class).findAssetObjectCode(assetTransferDocument.getOrganizationOwnerChartOfAccountsCode(), objectCode.getFinancialObjectSubTypeCode()); 136 if (valid &= validateAssetObjectCode(targetAssetObjectCode, assetTransferDocument.getOrganizationOwnerChartOfAccountsCode(), objectCode.getFinancialObjectSubTypeCode())) { 137 // validate object codes used to generate Capitalization/Accumulated Depreciation/Offset GL Postings. 138 valid &= validateFinancialObjectCodes(asset, assetPayment, targetAssetObjectCode); 139 } 140 } 141 } 142 return valid; 143 } 144 else { 145 return true; 146 } 147 148 } 149 150 /** 151 * Asset Object Code must exist as an active status. 152 * 153 * @param asset 154 * @param assetPayment 155 * @return 156 */ 157 protected boolean validateAssetObjectCode(AssetObjectCode assetObjectCode, String chartOfAccountsCode, String finObjectSubTypeCode) { 158 boolean valid = true; 159 if (ObjectUtils.isNull(assetObjectCode)) { 160 putError(CamsConstants.DOCUMENT_NUMBER_PATH, CamsKeyConstants.GLPosting.ERROR_ASSET_OBJECT_CODE_NOT_FOUND, new String[] { chartOfAccountsCode, finObjectSubTypeCode }); 161 valid &= false; 162 }// check Asset Object Code active 163 else if (!assetObjectCode.isActive()) { 164 putError(CamsConstants.DOCUMENT_NUMBER_PATH, CamsKeyConstants.GLPosting.ERROR_ASSET_OBJECT_CODE_INACTIVE, new String[] { chartOfAccountsCode, finObjectSubTypeCode }); 165 valid = false; 166 } 167 168 return valid; 169 } 170 171 /** 172 * Check Financial Object Code for GLPE. 173 * 174 * @param asset 175 * @param assetPayment 176 * @return 177 */ 178 protected boolean validateFinancialObjectCodes(Asset asset, AssetPayment assetPayment, AssetObjectCode assetObjectCode) { 179 AssetPaymentService assetPaymentService = getAssetPaymentService(); 180 boolean valid = true; 181 182 if (assetPaymentService.isPaymentEligibleForCapitalizationGLPosting(assetPayment)) { 183 // check for capitalization financial object code existing. 184 assetObjectCode.refreshReferenceObject(CamsPropertyConstants.AssetObjectCode.CAPITALIZATION_FINANCIAL_OBJECT); 185 valid &= validateFinObjectCodeForGLPosting(asset.getOrganizationOwnerChartOfAccountsCode(), assetObjectCode.getCapitalizationFinancialObjectCode(), assetObjectCode.getCapitalizationFinancialObject(), CamsConstants.GLPostingObjectCodeType.CAPITALIZATION); 186 } 187 if (assetPaymentService.isPaymentEligibleForAccumDeprGLPosting(assetPayment)) { 188 // check for accumulate depreciation financial Object Code existing 189 assetObjectCode.refreshReferenceObject(CamsPropertyConstants.AssetObjectCode.ACCUMULATED_DEPRECIATION_FINANCIAL_OBJECT); 190 valid &= validateFinObjectCodeForGLPosting(asset.getOrganizationOwnerChartOfAccountsCode(), assetObjectCode.getAccumulatedDepreciationFinancialObjectCode(), assetObjectCode.getAccumulatedDepreciationFinancialObject(), CamsConstants.GLPostingObjectCodeType.ACCUMMULATE_DEPRECIATION); 191 } 192 if (assetPaymentService.isPaymentEligibleForOffsetGLPosting(assetPayment)) { 193 // check for offset financial object code existing. 194 OffsetDefinition offsetDefinition = SpringContext.getBean(OffsetDefinitionService.class).getByPrimaryId(getUniversityDateService().getCurrentFiscalYear(), assetObjectCode.getChartOfAccountsCode(), CamsConstants.AssetTransfer.DOCUMENT_TYPE_CODE, CamsConstants.Postable.GL_BALANCE_TYPE_CODE_AC); 195 valid &= validateFinObjectCodeForGLPosting(asset.getOrganizationOwnerChartOfAccountsCode(), offsetDefinition.getFinancialObjectCode(), offsetDefinition.getFinancialObject(), CamsConstants.GLPostingObjectCodeType.OFFSET_AMOUNT); 196 } 197 return valid; 198 } 199 200 /** 201 * check existence and active status for given financial Object Code BO. 202 * 203 * @param chartCode 204 * @param finObjectCode 205 * @param finObject 206 * @return 207 */ 208 protected boolean validateFinObjectCodeForGLPosting(String chartOfAccountsCode, String finObjectCode, ObjectCode finObject, String glPostingType) { 209 boolean valid = true; 210 // not defined in Asset Object Code table 211 if (StringUtils.isBlank(finObjectCode)) { 212 putError(CamsConstants.DOCUMENT_NUMBER_PATH, CamsKeyConstants.GLPosting.ERROR_OBJECT_CODE_FROM_ASSET_OBJECT_CODE_NOT_FOUND, new String[] { glPostingType, chartOfAccountsCode }); 213 valid = false; 214 } 215 // check Object Code existing 216 else if (ObjectUtils.isNull(finObject)) { 217 putError(CamsConstants.DOCUMENT_NUMBER_PATH, CamsKeyConstants.GLPosting.ERROR_OBJECT_CODE_FROM_ASSET_OBJECT_CODE_INVALID, new String[] { glPostingType, finObjectCode, chartOfAccountsCode }); 218 valid = false; 219 } 220 // check Object Code active 221 else if (!finObject.isActive()) { 222 putError(CamsConstants.DOCUMENT_NUMBER_PATH, CamsKeyConstants.GLPosting.ERROR_OBJECT_CODE_FROM_ASSET_OBJECT_CODE_INACTIVE, new String[] { glPostingType, finObjectCode, chartOfAccountsCode }); 223 valid = false; 224 } 225 return valid; 226 } 227 228 /** 229 * @see org.kuali.rice.kns.rules.DocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.kns.document.Document) 230 */ 231 @Override 232 protected boolean processCustomRouteDocumentBusinessRules(Document document) { 233 if (!super.processCustomRouteDocumentBusinessRules(document) || GlobalVariables.getMessageMap().hasErrors()) 234 return false; 235 236 Asset asset = ((AssetTransferDocument)document).getAsset(); 237 boolean valid = true; 238 if (SpringContext.getBean(AssetService.class).isAssetRetired(asset)) { 239 valid &= false; 240 GlobalVariables.getMessageMap().putError(CamsConstants.DOC_HEADER_PATH, CamsKeyConstants.Transfer.ERROR_ASSET_RETIRED_NOTRANSFER, asset.getCapitalAssetNumber().toString(), asset.getRetirementReason().getRetirementReasonName()); 241 } 242 243 if (valid) { 244 valid &= applyRules(document); 245 } 246 247 // only generate error message if asset is locked by other document without stop saving 248 valid &= !this.getAssetLockService().isAssetLocked(retrieveAssetNumberForLocking(document), CamsConstants.DocumentTypeName.ASSET_TRANSFER, document.getDocumentNumber()); 249 250 return valid; 251 } 252 253 /** 254 * This method applies business rules 255 * 256 * @param document Transfer Document 257 * @return true if all rules are pass 258 */ 259 protected boolean applyRules(Document document) { 260 boolean valid = true; 261 // check if selected account has plant fund accounts 262 AssetTransferDocument assetTransferDocument = (AssetTransferDocument) document; 263 264 // validate if asset status = N or D 265 String inventoryStatusCode = assetTransferDocument.getAsset().getInventoryStatus().getInventoryStatusCode(); 266 if (inventoryStatusCode != null && !(StringUtils.equalsIgnoreCase(inventoryStatusCode, CamsConstants.InventoryStatusCode.NON_CAPITAL_ASSET_ACTIVE) || StringUtils.equalsIgnoreCase(inventoryStatusCode, CamsConstants.InventoryStatusCode.NON_CAPITAL_ASSET_ACTIVE_2003))) { 267 valid &= validateOwnerAccount(assetTransferDocument); 268 } 269 270 // validate if location info is available, campus or off-campus 271 valid &= validateLocation(assetTransferDocument); 272 if (assetTransferDocument.isInterdepartmentalSalesIndicator()) { 273 if (StringUtils.isBlank(assetTransferDocument.getTransferOfFundsFinancialDocumentNumber())) { 274 putError(CamsPropertyConstants.AssetTransferDocument.TRANSFER_FUND_FINANCIAL_DOC_NUM, CamsKeyConstants.Transfer.ERROR_TRFR_FDOC_REQUIRED); 275 valid &= false; 276 } 277 } 278 279 valid &= validatePaymentObjectCodes(assetTransferDocument); 280 281 return valid; 282 } 283 284 285 /** 286 * This method validates location information provided by the user 287 * 288 * @param assetTransferDocument Transfer Document 289 * @return true is location information is valid for the asset type 290 */ 291 protected boolean validateLocation(AssetTransferDocument assetTransferDocument) { 292 GlobalVariables.getMessageMap().addToErrorPath(CamsConstants.DOCUMENT_PATH); 293 Asset asset = assetTransferDocument.getAsset(); 294 asset.refreshReferenceObject(CamsPropertyConstants.Asset.CAPITAL_ASSET_TYPE); 295 boolean isCapitalAsset = this.getAssetService().isCapitalAsset(asset); 296 boolean valid = SpringContext.getBean(AssetLocationService.class).validateLocation(LOCATION_FIELD_MAP, assetTransferDocument, isCapitalAsset, asset.getCapitalAssetType()); 297 GlobalVariables.getMessageMap().removeFromErrorPath(CamsConstants.DOCUMENT_PATH); 298 return valid; 299 } 300 301 302 /** 303 * This method checks if reference objects exist in the database or not 304 * 305 * @param assetTransferDocument Transfer document 306 * @return true if all objects exists in db 307 */ 308 protected boolean checkReferencesExist(AssetTransferDocument assetTransferDocument) { 309 boolean valid = true; 310 311 assetTransferDocument.refreshReferenceObject(CamsPropertyConstants.AssetTransferDocument.ASSET); 312 // If asset is loaned, ask a confirmation question 313 if (this.getAssetService().isAssetLoaned(assetTransferDocument.getAsset())) { 314 putError(CamsPropertyConstants.AssetTransferDocument.ASSET + "." + CamsPropertyConstants.AssetTransferDocument.CAPITAL_ASSET_NUMBER, CamsKeyConstants.Transfer.ERROR_TRFR_LOANED); 315 valid &= false; 316 } 317 318 if (StringUtils.isNotBlank(assetTransferDocument.getOrganizationOwnerChartOfAccountsCode())) { 319 assetTransferDocument.refreshReferenceObject(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_CHART_OF_ACCOUNTS); 320 if (ObjectUtils.isNull(assetTransferDocument.getOrganizationOwnerChartOfAccounts())) { 321 putError(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_CHART_OF_ACCOUNTS_CODE, CamsKeyConstants.Transfer.ERROR_OWNER_CHART_CODE_INVALID, assetTransferDocument.getOrganizationOwnerChartOfAccountsCode()); 322 valid &= false; 323 } 324 } 325 326 if (StringUtils.isNotBlank(assetTransferDocument.getOrganizationOwnerAccountNumber())) { 327 assetTransferDocument.refreshReferenceObject(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_ACCOUNT); 328 if (ObjectUtils.isNull(assetTransferDocument.getOrganizationOwnerAccount())) { 329 putError(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_ACCOUNT_NUMBER, CamsKeyConstants.Transfer.ERROR_OWNER_ACCT_INVALID, assetTransferDocument.getOrganizationOwnerAccountNumber(), assetTransferDocument.getOrganizationOwnerChartOfAccountsCode()); 330 valid &= false; 331 } 332 } 333 if (StringUtils.isNotBlank(assetTransferDocument.getTransferOfFundsFinancialDocumentNumber())) { 334 TransferOfFundsDocument transferOfFundsFinancialDocument = assetTransferDocument.getTransferOfFundsFinancialDocument(); 335 if (ObjectUtils.isNull(transferOfFundsFinancialDocument) || !KFSConstants.DocumentStatusCodes.APPROVED.equals(transferOfFundsFinancialDocument.getDocumentHeader().getFinancialDocumentStatusCode())) { 336 putError(CamsPropertyConstants.AssetTransferDocument.TRANSFER_FUND_FINANCIAL_DOC_NUM, CamsKeyConstants.Transfer.ERROR_TRFR_FDOC_INVALID); 337 valid &= false; 338 } 339 } 340 if (StringUtils.isNotBlank(assetTransferDocument.getCampusCode())) { 341 // assetTransferDocument.refreshReferenceObject(CamsPropertyConstants.AssetTransferDocument.CAMPUS); 342 if (ObjectUtils.isNull(assetTransferDocument.getCampus())) { 343 putError(CamsPropertyConstants.AssetTransferDocument.CAMPUS_CODE, CamsKeyConstants.AssetLocation.ERROR_INVALID_CAMPUS_CODE, assetTransferDocument.getCampusCode()); 344 valid &= false; 345 } 346 } 347 if (StringUtils.isNotBlank(assetTransferDocument.getBuildingCode())) { 348 assetTransferDocument.refreshReferenceObject(CamsPropertyConstants.AssetTransferDocument.BUILDING); 349 if (ObjectUtils.isNull(assetTransferDocument.getBuilding())) { 350 putError(CamsPropertyConstants.AssetTransferDocument.BUILDING_CODE, CamsKeyConstants.AssetLocation.ERROR_INVALID_BUILDING_CODE, assetTransferDocument.getBuildingCode(), assetTransferDocument.getCampusCode()); 351 valid &= false; 352 } 353 } 354 if (StringUtils.isNotBlank(assetTransferDocument.getBuildingRoomNumber())) { 355 assetTransferDocument.refreshReferenceObject(CamsPropertyConstants.AssetTransferDocument.BUILDING_ROOM); 356 if (ObjectUtils.isNull(assetTransferDocument.getBuildingRoom())) { 357 putError(CamsPropertyConstants.AssetTransferDocument.BUILDING_ROOM_NUMBER, CamsKeyConstants.AssetLocation.ERROR_INVALID_ROOM_NUMBER, assetTransferDocument.getBuildingCode(), assetTransferDocument.getBuildingRoomNumber(), assetTransferDocument.getCampusCode()); 358 valid &= false; 359 } 360 } 361 if (StringUtils.isNotBlank(assetTransferDocument.getAssetRepresentative().getPrincipalName())) { 362 PersonService personService = SpringContext.getBean(org.kuali.rice.kim.service.PersonService.class); 363 Person person = personService.getPersonByPrincipalName(assetTransferDocument.getAssetRepresentative().getPrincipalName()); 364 if (person != null) { 365 assetTransferDocument.setAssetRepresentative(person); 366 assetTransferDocument.setRepresentativeUniversalIdentifier(person.getPrincipalId()); 367 } 368 else { 369 putError(CamsPropertyConstants.AssetTransferDocument.REP_USER_AUTH_ID, CamsKeyConstants.Transfer.ERROR_INVALID_USER_AUTH_ID, assetTransferDocument.getAssetRepresentative().getPrincipalName()); 370 valid &= false; 371 } 372 } 373 return valid; 374 } 375 376 377 /** 378 * This method validates the new owner organization and account provided 379 * 380 * @param assetTransferDocument 381 * @return 382 */ 383 protected boolean validateOwnerAccount(AssetTransferDocument assetTransferDocument) { 384 boolean valid = true; 385 386 Asset asset = assetTransferDocument.getAsset(); 387 String finObjectSubTypeCode = asset.getFinancialObjectSubTypeCode(); 388 if (ObjectUtils.isNotNull(asset.getAssetPayments()) && !asset.getAssetPayments().isEmpty()) { 389 AssetPayment firstAssetPayment = asset.getAssetPayments().get(0); 390 firstAssetPayment.refreshReferenceObject(CamsPropertyConstants.AssetPayment.FINANCIAL_OBJECT); 391 ObjectCodeService objectCodeService = (ObjectCodeService) SpringContext.getBean(ObjectCodeService.class); 392 393 ObjectCode objectCode = objectCodeService.getByPrimaryIdForCurrentYear(firstAssetPayment.getChartOfAccountsCode(),firstAssetPayment.getFinancialObjectCode()); 394 finObjectSubTypeCode = objectCode.getFinancialObjectSubTypeCode(); 395 } 396 boolean assetMovable = getAssetService().isAssetMovableCheckByPayment(finObjectSubTypeCode); 397 398 FinancialSystemTransactionalDocumentAuthorizerBase documentAuthorizer = (FinancialSystemTransactionalDocumentAuthorizerBase) SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(assetTransferDocument); 399 boolean isAuthorizedTransferMovable = documentAuthorizer.isAuthorized(assetTransferDocument, CamsConstants.CAM_MODULE_CODE, CamsConstants.PermissionNames.TRANSFER_NON_MOVABLE_ASSETS, GlobalVariables.getUserSession().getPerson().getPrincipalId()); 400 401 // KFSMI-6169 - Not check permission for Transfer Non-Movable Assets when user approve the doc. 402 if (!assetTransferDocument.getDocumentHeader().getWorkflowDocument().getRouteHeader().isApproveRequested()){ 403 if (!assetMovable && !isAuthorizedTransferMovable) { 404 GlobalVariables.getMessageMap().putErrorForSectionId(CamsPropertyConstants.COMMON_ERROR_SECTION_ID, CamsKeyConstants.Transfer.ERROR_INVALID_USER_GROUP_FOR_TRANSFER_NONMOVABLE_ASSET, asset.getCapitalAssetNumber().toString()); 405 valid &= false; 406 } 407 } 408 409 // check if account is valid 410 Account organizationOwnerAccount = assetTransferDocument.getOrganizationOwnerAccount(); 411 if (ObjectUtils.isNotNull(organizationOwnerAccount) && (organizationOwnerAccount.isExpired())) { 412 putError(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_ACCOUNT_NUMBER, CamsKeyConstants.Transfer.ERROR_OWNER_ACCT_INVALID, assetTransferDocument.getOrganizationOwnerChartOfAccountsCode(), assetTransferDocument.getOrganizationOwnerAccountNumber()); 413 valid &= false; 414 } 415 else if (getAssetService().isCapitalAsset(asset) && !asset.getAssetPayments().isEmpty()) { 416 // for a capital asset, check if plant account is defined 417 Organization ownerOrg = organizationOwnerAccount.getOrganization(); 418 Account campusPlantAccount = ownerOrg.getCampusPlantAccount(); 419 Account organizationPlantAccount = ownerOrg.getOrganizationPlantAccount(); 420 421 if (assetMovable && ObjectUtils.isNull(organizationPlantAccount)) { 422 putError(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_ACCOUNT_NUMBER, CamsKeyConstants.Transfer.ERROR_ORG_PLANT_FUND_UNKNOWN); 423 valid &= false; 424 } 425 if (!assetMovable && ObjectUtils.isNull(campusPlantAccount)) { 426 putError(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_ACCOUNT_NUMBER, CamsKeyConstants.Transfer.ERROR_CAMPUS_PLANT_FUND_UNKNOWN); 427 valid &= false; 428 } 429 } 430 return valid; 431 } 432 433 /** 434 * checks that all the asset payments to be transfer has a valid object code in the new Chart of account code and current fiscal 435 * year 436 * 437 * @param assetTransferDocument 438 * @return 439 */ 440 protected boolean validatePaymentObjectCodes(AssetTransferDocument assetTransferDocument) { 441 boolean valid = true; 442 List<AssetPayment> assetPayments = assetTransferDocument.getAsset().getAssetPayments(); 443 444 String chartOfAccountsCode = assetTransferDocument.getOrganizationOwnerChartOfAccountsCode(); 445 Integer fiscalYear = getUniversityDateService().getCurrentUniversityDate().getUniversityFiscalYear(); 446 447 for (AssetPayment assetPayment : assetPayments) { 448 if (!CamsConstants.AssetPayment.TRANSFER_PAYMENT_CODE_Y.equals(assetPayment.getTransferPaymentCode())) { 449 if (this.getObjectCodeService().getByPrimaryId(fiscalYear, chartOfAccountsCode, assetPayment.getFinancialObjectCode()) == null) { 450 putError(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_CHART_OF_ACCOUNTS_CODE, CamsKeyConstants.Transfer.ERROR_PAYMENT_OBJECT_CODE_NOT_FOUND, new String[] { assetPayment.getFinancialObjectCode(), fiscalYear.toString() }); 451 valid = false; 452 } 453 } 454 } 455 return valid; 456 } 457 458 /** 459 * Convenience method to append the path prefix 460 */ 461 public TypedArrayList putError(String propertyName, String errorKey, String... errorParameters) { 462 return GlobalVariables.getMessageMap().putError(CamsConstants.DOCUMENT_PATH + "." + propertyName, errorKey, errorParameters); 463 } 464 465 private boolean isNonCapitalAsset(Asset asset) { 466 boolean isNonCapitalAsset = false; 467 468 List<String> capitalAssetAquisitionTypeCodes = new ArrayList<String>(); 469 470 capitalAssetAquisitionTypeCodes.addAll(SpringContext.getBean(ParameterService.class).getParameterValues(AssetGlobal.class, CamsConstants.AssetGlobal.CAPITAL_OBJECT_ACQUISITION_CODE_PARAM)); 471 capitalAssetAquisitionTypeCodes.addAll(SpringContext.getBean(ParameterService.class).getParameterValues(AssetGlobal.class, CamsConstants.AssetGlobal.NON_NEW_ACQUISITION_GROUP_PARAM)); 472 capitalAssetAquisitionTypeCodes.addAll(SpringContext.getBean(ParameterService.class).getParameterValues(AssetGlobal.class, CamsConstants.AssetGlobal.NEW_ACQUISITION_CODE_PARAM)); 473 capitalAssetAquisitionTypeCodes.addAll(SpringContext.getBean(ParameterService.class).getParameterValues(Asset.class, CamsConstants.AssetGlobal.FABRICATED_ACQUISITION_CODE)); 474 capitalAssetAquisitionTypeCodes.addAll(SpringContext.getBean(ParameterService.class).getParameterValues(AssetGlobal.class, CamsConstants.AssetGlobal.PRE_TAGGING_ACQUISITION_CODE)); 475 476 if( ObjectUtils.isNotNull(asset.getAcquisitionTypeCode()) && 477 capitalAssetAquisitionTypeCodes.contains(asset.getAcquisitionTypeCode()) ) isNonCapitalAsset = false; 478 else isNonCapitalAsset = true; 479 480 return isNonCapitalAsset; 481 } 482 483 public UniversityDateService getUniversityDateService() { 484 if (this.universityDateService == null) { 485 this.universityDateService = SpringContext.getBean(UniversityDateService.class); 486 } 487 return universityDateService; 488 } 489 490 public void setUniversityDateService(UniversityDateService universityDateService) { 491 this.universityDateService = universityDateService; 492 } 493 494 public AssetPaymentService getAssetPaymentService() { 495 if (this.assetPaymentService == null) { 496 this.assetPaymentService = SpringContext.getBean(AssetPaymentService.class); 497 498 } 499 return assetPaymentService; 500 } 501 502 public void setAssetPaymentService(AssetPaymentService assetPaymentService) { 503 this.assetPaymentService = assetPaymentService; 504 } 505 506 public AssetService getAssetService() { 507 if (this.assetService == null) { 508 this.assetService = SpringContext.getBean(AssetService.class); 509 } 510 return assetService; 511 } 512 513 public AssetLockService getAssetLockService() { 514 if (this.assetLockService == null) { 515 this.assetLockService = SpringContext.getBean(AssetLockService.class); 516 } 517 return assetLockService; 518 } 519 520 521 public void setAssetService(AssetService assetService) { 522 this.assetService = assetService; 523 } 524 525 public ObjectCodeService getObjectCodeService() { 526 if (this.objectCodeService == null) { 527 this.objectCodeService = SpringContext.getBean(ObjectCodeService.class); 528 } 529 return objectCodeService; 530 } 531 532 public void setObjectCodeService(ObjectCodeService objectCodeService) { 533 this.objectCodeService = objectCodeService; 534 } 535 }