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.bc.document.web.struts; 017 018 import java.util.ArrayList; 019 import java.util.HashMap; 020 import java.util.HashSet; 021 import java.util.List; 022 import java.util.Set; 023 024 import javax.servlet.http.HttpServletRequest; 025 026 import org.kuali.kfs.coa.businessobject.Account; 027 import org.kuali.kfs.coa.businessobject.Organization; 028 import org.kuali.kfs.module.bc.BCConstants; 029 import org.kuali.kfs.module.bc.BCKeyConstants; 030 import org.kuali.kfs.module.bc.BCPropertyConstants; 031 import org.kuali.kfs.module.bc.BCConstants.LockStatus; 032 import org.kuali.kfs.module.bc.businessobject.BudgetConstructionLockStatus; 033 import org.kuali.kfs.module.bc.businessobject.BudgetConstructionPosition; 034 import org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding; 035 import org.kuali.kfs.module.bc.document.service.BudgetConstructionProcessorService; 036 import org.kuali.kfs.module.bc.document.service.BudgetDocumentService; 037 import org.kuali.kfs.module.bc.document.service.LockService; 038 import org.kuali.kfs.module.bc.document.service.SalarySettingService; 039 import org.kuali.kfs.module.bc.util.SalarySettingFieldsHolder; 040 import org.kuali.kfs.sys.KFSConstants; 041 import org.kuali.kfs.sys.KFSPropertyConstants; 042 import org.kuali.kfs.sys.ObjectUtil; 043 import org.kuali.kfs.sys.context.SpringContext; 044 import org.kuali.kfs.sys.identity.KfsKimAttributes; 045 import org.kuali.rice.kim.bo.types.dto.AttributeSet; 046 import org.kuali.rice.kim.service.PermissionService; 047 import org.kuali.rice.kim.service.RoleManagementService; 048 import org.kuali.rice.kns.service.BusinessObjectService; 049 import org.kuali.rice.kns.util.ErrorMap; 050 import org.kuali.rice.kns.util.MessageMap; 051 052 /** 053 * the base struts form for the detail salary setting: by position or by incumbent 054 */ 055 public abstract class DetailSalarySettingForm extends SalarySettingBaseForm { 056 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DetailSalarySettingForm.class); 057 058 private PendingBudgetConstructionAppointmentFunding newBCAFLine; 059 private boolean addLine; 060 061 private String positionNumber; 062 private String emplid; 063 private String name; 064 065 private SalarySettingService salarySettingService = SpringContext.getBean(SalarySettingService.class); 066 private BudgetDocumentService budgetDocumentService = SpringContext.getBean(BudgetDocumentService.class); 067 private PermissionService permissionService = SpringContext.getBean(PermissionService.class); 068 private LockService lockService = SpringContext.getBean(LockService.class); 069 private BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class); 070 071 private static final List<String> comparableFields = getComparableFields(); 072 073 /** 074 * Constructs a DetailSalarySettingForm.java. 075 */ 076 public DetailSalarySettingForm() { 077 super(); 078 079 this.setEditingMode(new HashMap<String, String>()); 080 this.setNewBCAFLine(new PendingBudgetConstructionAppointmentFunding()); 081 } 082 083 /** 084 * @see org.kuali.rice.kns.web.struts.form.KualiForm#populate(javax.servlet.http.HttpServletRequest) 085 */ 086 @Override 087 public void populate(HttpServletRequest request) { 088 super.populate(request); 089 090 this.setSingleAccountMode(this.resetSingleAccountModeFlag()); 091 092 this.populateBCAFLines(); 093 } 094 095 /** 096 * @see org.kuali.kfs.module.bc.document.web.struts.SalarySettingBaseForm#populateBCAFLines() 097 */ 098 @Override 099 public void populateBCAFLines() { 100 super.populateBCAFLines(); 101 102 this.refreshBCAFLine(this.getNewBCAFLine()); 103 } 104 105 /** 106 * @see org.kuali.kfs.module.bc.document.web.struts.SalarySettingBaseForm#refreshBCAFLine(org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding) 107 */ 108 @Override 109 public void refreshBCAFLine(PendingBudgetConstructionAppointmentFunding appointmentFunding) { 110 super.refreshBCAFLine(appointmentFunding); 111 112 appointmentFunding.refreshReferenceObject(BCPropertyConstants.BUDGET_CONSTRUCTION_INTENDED_INCUMBENT); 113 appointmentFunding.refreshReferenceObject(BCPropertyConstants.BUDGET_CONSTRUCTION_POSITION); 114 appointmentFunding.refreshReferenceObject(BCPropertyConstants.BUDGET_CONSTRUCTION_ADMINISTRATIVE_POST); 115 } 116 117 /** 118 * acquire position and funding locks for all appointment fundings 119 */ 120 public boolean acquirePositionAndFundingLocks(MessageMap errorMap) { 121 List<PendingBudgetConstructionAppointmentFunding> appointmentFundings = this.getAppointmentFundings(); 122 for (PendingBudgetConstructionAppointmentFunding appointmentFunding : appointmentFundings) { 123 boolean gotLocks = this.acquirePositionAndFundingLocks(appointmentFunding, errorMap); 124 125 if (!gotLocks) { 126 return false; 127 } 128 } 129 return true; 130 } 131 132 /** 133 * acquire position and funding locks for the given appointment funding 134 * 135 * @param appointmentFunding the given appointment funding 136 * @return true if the position and funding locks for the given appointment funding are acquired successfully, otherwise, false 137 */ 138 public boolean acquirePositionAndFundingLocks(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) { 139 LOG.info("acquirePositionAndFundingLocks() started"); 140 141 try { 142 // not to acquire any lock for the display-only and non-budgetable funding line 143 if (appointmentFunding.isDisplayOnlyMode() || !appointmentFunding.isBudgetable()) { 144 return true; 145 } 146 147 // acquire position lock for the current funding line 148 BudgetConstructionPosition position = appointmentFunding.getBudgetConstructionPosition(); 149 String positionNumber = position.getPositionNumber(); 150 Integer universityFiscalYear = position.getUniversityFiscalYear(); 151 String principalId = this.getPerson().getPrincipalId(); 152 Boolean positionWasAlreadyLocked = lockService.isPositionLockedByUser(positionNumber, universityFiscalYear, principalId); 153 if (!positionWasAlreadyLocked) { 154 BudgetConstructionLockStatus positionLockingStatus = lockService.lockPosition(position, this.getPerson()); 155 if (!LockStatus.SUCCESS.equals(positionLockingStatus.getLockStatus())) { 156 errorMap.putError(BCPropertyConstants.NEW_BCAF_LINE, BCKeyConstants.ERROR_FAIL_TO_LOCK_POSITION, position.toString()); 157 158 // gwp - added if test, unlock all others only when initially loading the screen 159 // not during the add line action 160 if (!appointmentFunding.isNewLineIndicator()) { 161 this.releasePositionAndFundingLocks(); 162 } 163 return false; 164 } 165 } 166 167 // acquire funding lock for the current funding line 168 BudgetConstructionLockStatus fundingLockingStatus = this.getLockStatusForBudgetByAccountMode(appointmentFunding); 169 if (fundingLockingStatus == null) { 170 fundingLockingStatus = lockService.lockFunding(appointmentFunding, this.getPerson()); 171 } 172 173 if (!LockStatus.SUCCESS.equals(fundingLockingStatus.getLockStatus())) { 174 errorMap.putError(BCPropertyConstants.NEW_BCAF_LINE, BCKeyConstants.ERROR_FAIL_TO_LOCK_FUNDING, appointmentFunding.getAppointmentFundingString()); 175 176 // gwp - added if test, unlock all others only when initially loading the screen 177 // not during the add line action 178 if (!appointmentFunding.isNewLineIndicator()) { 179 this.releasePositionAndFundingLocks(); 180 } 181 else { 182 // adding a new line, just release the earlier position lock 183 // if we just issued it above, not from other line 184 if (!positionWasAlreadyLocked) { 185 lockService.unlockPosition(positionNumber, universityFiscalYear, principalId); 186 } 187 } 188 return false; 189 } 190 } 191 catch (Exception e) { 192 this.releasePositionAndFundingLocks(); 193 194 String errorMessage = "Failed when acquiring position/funding lock for " + appointmentFunding; 195 LOG.error(errorMessage, e); 196 throw new RuntimeException(errorMessage, e); 197 } 198 199 return true; 200 } 201 202 /** 203 * update the access modes of all appointment fundings 204 */ 205 public boolean updateAccessMode(MessageMap errorMap) { 206 List<PendingBudgetConstructionAppointmentFunding> appointmentFundings = this.getAppointmentFundings(); 207 for (PendingBudgetConstructionAppointmentFunding appointmentFunding : appointmentFundings) { 208 boolean accessModeUpdated = this.updateAccessMode(appointmentFunding, errorMap); 209 210 if (!accessModeUpdated) { 211 return false; 212 } 213 } 214 return true; 215 } 216 217 /** 218 * update the access mode of the given appointment funding 219 * 220 * @param appointmentFunding the given appointment funding 221 * @return true if the access mode of the given appointment funding are updated successfully, otherwise, false 222 */ 223 public boolean updateAccessMode(PendingBudgetConstructionAppointmentFunding appointmentFunding, MessageMap errorMap) { 224 LOG.info("updateAccessMode() started"); 225 226 try { 227 SalarySettingFieldsHolder fieldsHolder = this.getSalarySettingFieldsHolder(); 228 229 // update the access flags of the current funding line 230 boolean updated = salarySettingService.updateAccessOfAppointmentFunding(appointmentFunding, fieldsHolder, this.isBudgetByAccountMode(), this.isEditAllowed(), this.getPerson()); 231 if (!updated) { 232 errorMap.putError(BCPropertyConstants.NEW_BCAF_LINE, BCKeyConstants.ERROR_FAIL_TO_UPDATE_FUNDING_ACCESS, appointmentFunding.getAppointmentFundingString()); 233 return false; 234 } 235 } 236 catch (Exception e) { 237 String errorMessage = "Failed to update the access mode of " + appointmentFunding + "."; 238 LOG.error(errorMessage, e); 239 throw new RuntimeException(errorMessage, e); 240 } 241 242 return true; 243 } 244 245 /** 246 * acquire transaction locks for the savable appointment fundings 247 * 248 * @return true if the transaction locks for all savable appointment fundings are acquired successfully, otherwise, false 249 */ 250 public boolean acquireTransactionLocks(MessageMap messageMap) { 251 LOG.info("acquireTransactionLocks() started"); 252 253 for (PendingBudgetConstructionAppointmentFunding appointmentFunding : this.getSavableAppointmentFundings()) { 254 try { 255 BudgetConstructionLockStatus transactionLockStatus = this.getLockStatusForBudgetByAccountMode(appointmentFunding); 256 if (transactionLockStatus == null) { 257 transactionLockStatus = lockService.lockTransaction(appointmentFunding, this.getPerson()); 258 } 259 260 if (!LockStatus.SUCCESS.equals(transactionLockStatus.getLockStatus())) { 261 messageMap.putError(BCPropertyConstants.NEW_BCAF_LINE, BCKeyConstants.ERROR_FAIL_TO_ACQUIRE_TRANSACTION_LOCK, appointmentFunding.getAppointmentFundingString()); 262 263 this.releaseTransactionLocks(); 264 return false; 265 } 266 } 267 catch (Exception e) { 268 this.releaseTransactionLocks(); 269 this.releasePositionAndFundingLocks(); 270 271 LOG.error("Failed when acquiring transaction lock for " + appointmentFunding, e); 272 throw new RuntimeException("Failed when acquiring transaction lock for " + appointmentFunding, e); 273 } 274 } 275 276 return true; 277 } 278 279 /** 280 * release all position and funding locks acquired in current action by the current user 281 */ 282 public void releasePositionAndFundingLocks() { 283 LOG.info("releasePositionAndFundingLocks() started"); 284 285 List<PendingBudgetConstructionAppointmentFunding> releasableAppointmentFundings = this.getReleasableAppointmentFundings(); 286 lockService.unlockFunding(releasableAppointmentFundings, this.getPerson()); 287 288 Set<BudgetConstructionPosition> lockedPositionSet = new HashSet<BudgetConstructionPosition>(); 289 for (PendingBudgetConstructionAppointmentFunding fundingLine : releasableAppointmentFundings) { 290 lockedPositionSet.add(fundingLine.getBudgetConstructionPosition()); 291 LOG.info("fundingLine: " + fundingLine); 292 } 293 294 LOG.info("releasePositionAndFundingLocks()" + lockedPositionSet); 295 List<BudgetConstructionPosition> lockedPositions = new ArrayList<BudgetConstructionPosition>(); 296 lockedPositions.addAll(lockedPositionSet); 297 lockService.unlockPostion(lockedPositions, this.getPerson()); 298 for (BudgetConstructionPosition position : lockedPositionSet) { 299 LOG.info("fundingLine: " + position.getPositionLockUserIdentifier()); 300 } 301 } 302 303 /** 304 * release all the transaction locks acquired in current action by the current user 305 */ 306 public void releaseTransactionLocks() { 307 LOG.info("releaseTransactionLocks() started"); 308 309 List<PendingBudgetConstructionAppointmentFunding> fundingsWithTransactionLocks = this.getReleasableAppointmentFundings(); 310 for (PendingBudgetConstructionAppointmentFunding appointmentFunding : fundingsWithTransactionLocks) { 311 lockService.unlockTransaction(appointmentFunding, this.getPerson()); 312 } 313 } 314 315 /** 316 * get the appointment fundings that can be saved 317 */ 318 public List<PendingBudgetConstructionAppointmentFunding> getSavableAppointmentFundings() { 319 LOG.info("getSavableAppointmentFundings() started"); 320 321 // get the funding lines that can be saved 322 List<PendingBudgetConstructionAppointmentFunding> savableAppointmentFundings = new ArrayList<PendingBudgetConstructionAppointmentFunding>(); 323 for (PendingBudgetConstructionAppointmentFunding fundingLine : this.getAppointmentFundings()) { 324 325 // save-able line is one that is edit-able 326 // rules should catch attempts to save active, !purged, !isBudgetable lines 327 if (!fundingLine.isDisplayOnlyMode()) { 328 savableAppointmentFundings.add(fundingLine); 329 } 330 } 331 return savableAppointmentFundings; 332 } 333 334 /** 335 * get the appointment fundings for which the position or funding locks can be released 336 */ 337 public List<PendingBudgetConstructionAppointmentFunding> getReleasableAppointmentFundings() { 338 LOG.info("getReleasableAppointmentFundings() started"); 339 340 List<PendingBudgetConstructionAppointmentFunding> savableAppointmentFundings = this.getSavableAppointmentFundings(); 341 List<PendingBudgetConstructionAppointmentFunding> releasableAppointmentFundings = new ArrayList<PendingBudgetConstructionAppointmentFunding>(); 342 releasableAppointmentFundings.addAll(savableAppointmentFundings); 343 344 return releasableAppointmentFundings; 345 } 346 347 /** 348 * determine whether there is any active funding line in the given savable appointment funding lines 349 */ 350 public List<PendingBudgetConstructionAppointmentFunding> getActiveFundingLines() { 351 LOG.info("getActiveFundingLines() started"); 352 353 List<PendingBudgetConstructionAppointmentFunding> activeFundingLines = new ArrayList<PendingBudgetConstructionAppointmentFunding>(); 354 for (PendingBudgetConstructionAppointmentFunding appointmentFunding : this.getSavableAppointmentFundings()) { 355 if (!appointmentFunding.isAppointmentFundingDeleteIndicator()) { 356 activeFundingLines.add(appointmentFunding); 357 } 358 } 359 return activeFundingLines; 360 } 361 362 /** 363 * sets the default fields not setable by the user for added lines and any other required initialization 364 * 365 * @param appointmentFunding the given appointment funding line 366 */ 367 public PendingBudgetConstructionAppointmentFunding createNewAppointmentFundingLine() { 368 PendingBudgetConstructionAppointmentFunding appointmentFunding = new PendingBudgetConstructionAppointmentFunding(); 369 370 if (this.isAddLine() || this.isSingleAccountMode()) { 371 appointmentFunding.setChartOfAccountsCode(this.getChartOfAccountsCode()); 372 appointmentFunding.setAccountNumber(this.getAccountNumber()); 373 374 // empty field implies dashes and is fixed in add action 375 if (this.getSubAccountNumber().equals(KFSConstants.getDashSubAccountNumber())) { 376 appointmentFunding.setSubAccountNumber(KFSConstants.EMPTY_STRING); 377 } 378 else { 379 appointmentFunding.setSubAccountNumber(this.getSubAccountNumber()); 380 } 381 appointmentFunding.setFinancialObjectCode(this.getFinancialObjectCode()); 382 383 // empty field implies dashes and is fixed in add action 384 if (this.getFinancialSubObjectCode().equals(KFSConstants.getDashFinancialSubObjectCode())) { 385 appointmentFunding.setFinancialSubObjectCode(KFSConstants.EMPTY_STRING); 386 } 387 else { 388 appointmentFunding.setFinancialSubObjectCode(this.getFinancialSubObjectCode()); 389 } 390 } 391 392 appointmentFunding.setUniversityFiscalYear(this.getUniversityFiscalYear()); 393 appointmentFunding.setAppointmentFundingDeleteIndicator(false); 394 appointmentFunding.setNewLineIndicator(true); 395 appointmentFunding.setAppointmentFundingDurationCode(BCConstants.AppointmentFundingDurationCodes.NONE.durationCode); 396 397 return appointmentFunding; 398 } 399 400 /** 401 * pick up the appointment fundings belonging to the specified account from a collection of fundings that are associated with a 402 * position/incumbent 403 */ 404 public void pickAppointmentFundingsForSingleAccount() { 405 LOG.info("pickAppointmentFundingsForSingleAccount() started"); 406 407 List<PendingBudgetConstructionAppointmentFunding> excludedFundings = new ArrayList<PendingBudgetConstructionAppointmentFunding>(); 408 for (PendingBudgetConstructionAppointmentFunding appointmentFunding : this.getAppointmentFundings()) { 409 if (!ObjectUtil.equals(appointmentFunding, this, comparableFields)) { 410 excludedFundings.add(appointmentFunding); 411 } 412 } 413 414 this.getAppointmentFundings().removeAll(excludedFundings); 415 } 416 417 /** 418 * Funding/transaction locks are not required for the lines associated with a document already open in budget by account mode 419 */ 420 private BudgetConstructionLockStatus getLockStatusForBudgetByAccountMode(PendingBudgetConstructionAppointmentFunding appointmentFunding) { 421 LOG.info("getLockStatusForBudgetByAccountMode() started"); 422 423 BudgetConstructionLockStatus transactionLockStatus = null; 424 425 if (this.isBudgetByAccountMode() && ObjectUtil.equals(appointmentFunding, this, comparableFields)) { 426 transactionLockStatus = new BudgetConstructionLockStatus(); 427 transactionLockStatus.setLockStatus(LockStatus.SUCCESS); 428 } 429 430 return transactionLockStatus; 431 } 432 433 /** 434 * get the names of comparable fields that are considered to determine a single account, that is, the fundings are considered 435 * being assocated with the given account if they have the same values of the fields as specified. 436 */ 437 public static List<String> getComparableFields() { 438 List<String> comparableFields = new ArrayList<String>(); 439 comparableFields.add(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE); 440 comparableFields.add(KFSPropertyConstants.ACCOUNT_NUMBER); 441 comparableFields.add(KFSPropertyConstants.SUB_ACCOUNT_NUMBER); 442 443 return comparableFields; 444 } 445 446 /** 447 * determine whether the editing mode for detail salary setting is in single account mode or not 448 */ 449 private boolean resetSingleAccountModeFlag() { 450 451 List<Organization> processorOrgs = SpringContext.getBean(BudgetConstructionProcessorService.class).getProcessorOrgs(this.getPerson()); 452 Boolean isOrgApprover = processorOrgs != null && !processorOrgs.isEmpty(); 453 454 if (this.isBudgetByAccountMode()) { 455 456 Account account = new Account(); 457 account.setAccountNumber(this.getAccountNumber()); 458 account.setChartOfAccountsCode(this.getChartOfAccountsCode()); 459 account = (Account) businessObjectService.retrieve(account); 460 461 RoleManagementService roleService = SpringContext.getBean(RoleManagementService.class); 462 AttributeSet qualification = new AttributeSet(); 463 qualification.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, getChartOfAccountsCode()); 464 qualification.put(KfsKimAttributes.ACCOUNT_NUMBER, getAccountNumber()); 465 qualification.put(KfsKimAttributes.DOCUMENT_TYPE_NAME, BCConstants.BUDGET_CONSTRUCTION_DOCUMENT_NAME); 466 467 List<String> roleId = new ArrayList<String>(); 468 roleId.add(roleService.getRoleIdByName(KFSConstants.ParameterNamespaces.KFS, KFSConstants.SysKimConstants.FISCAL_OFFICER_KIM_ROLE_NAME)); 469 470 Boolean isFiscalOfficerOrDelegate = roleService.principalHasRole(getPerson().getPrincipalId(), roleId, qualification); 471 472 return (isFiscalOfficerOrDelegate && !isOrgApprover); 473 } 474 475 // instruct the detail salary setting by multiple account mode if current user is an organization level approver 476 if (isOrgApprover) { 477 return false; 478 } 479 else { 480 throw new RuntimeException("Access denied: not authorized to do the detail salary setting"); 481 } 482 } 483 484 /** 485 * Gets the newBCAFLine attribute. 486 * 487 * @return Returns the newBCAFLine. 488 */ 489 public PendingBudgetConstructionAppointmentFunding getNewBCAFLine() { 490 return newBCAFLine; 491 } 492 493 /** 494 * Sets the newBCAFLine attribute value. 495 * 496 * @param newBCAFLine The newBCAFLine to set. 497 */ 498 public void setNewBCAFLine(PendingBudgetConstructionAppointmentFunding newBCAFLine) { 499 this.newBCAFLine = newBCAFLine; 500 } 501 502 /** 503 * Gets the emplid attribute. 504 * 505 * @return Returns the emplid. 506 */ 507 public String getEmplid() { 508 return emplid; 509 } 510 511 /** 512 * Sets the emplid attribute value. 513 * 514 * @param emplid The emplid to set. 515 */ 516 public void setEmplid(String emplid) { 517 this.emplid = emplid; 518 } 519 520 /** 521 * Gets the addLine attribute. 522 * 523 * @return Returns the addLine. 524 */ 525 public boolean isAddLine() { 526 return addLine; 527 } 528 529 /** 530 * Sets the addLine attribute value. 531 * 532 * @param addLine The addLine to set. 533 */ 534 public void setAddLine(boolean addLine) { 535 this.addLine = addLine; 536 } 537 538 /** 539 * Gets the positionNumber attribute. 540 * 541 * @return Returns the positionNumber. 542 */ 543 public String getPositionNumber() { 544 return positionNumber; 545 } 546 547 /** 548 * Sets the positionNumber attribute value. 549 * 550 * @param positionNumber The positionNumber to set. 551 */ 552 public void setPositionNumber(String positionNumber) { 553 this.positionNumber = positionNumber; 554 } 555 556 /** 557 * Gets the name attribute. 558 * 559 * @return Returns the name. 560 */ 561 public String name() { 562 return name; 563 } 564 565 /** 566 * Sets the name attribute value. 567 * 568 * @param name The name to set. 569 */ 570 public void setName(String name) { 571 this.name = name; 572 } 573 574 /** 575 * @see org.kuali.rice.kns.web.struts.form.KualiForm#shouldPropertyBePopulatedInForm(java.lang.String, 576 * javax.servlet.http.HttpServletRequest) 577 */ 578 @Override 579 public boolean shouldPropertyBePopulatedInForm(String requestParameterName, HttpServletRequest request) { 580 581 if (super.shouldPropertyBePopulatedInForm(requestParameterName, request)) { 582 return true; 583 } 584 else { 585 // make sure special disabled fields are allowed to be populated 586 if (requestParameterName.endsWith(BCPropertyConstants.APPOINTMENT_REQUESTED_CSF_AMOUNT) || requestParameterName.endsWith(BCPropertyConstants.APPOINTMENT_REQUESTED_CSF_TIME_PERCENT) || requestParameterName.endsWith(BCPropertyConstants.APPOINTMENT_FUNDING_REASON_AMOUNT)) { 587 return true; 588 } 589 else { 590 return false; 591 } 592 } 593 } 594 }