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.ar.document; 017 018 import java.sql.Date; 019 import java.util.ArrayList; 020 import java.util.List; 021 022 import org.apache.commons.lang.StringUtils; 023 import org.kuali.kfs.coa.businessobject.Account; 024 import org.kuali.kfs.coa.businessobject.Chart; 025 import org.kuali.kfs.coa.businessobject.ObjectCode; 026 import org.kuali.kfs.coa.businessobject.ProjectCode; 027 import org.kuali.kfs.coa.businessobject.SubAccount; 028 import org.kuali.kfs.coa.businessobject.SubObjectCode; 029 import org.kuali.kfs.module.ar.ArConstants; 030 import org.kuali.kfs.module.ar.businessobject.AccountsReceivableDocumentHeader; 031 import org.kuali.kfs.module.ar.businessobject.CustomerInvoiceDetail; 032 import org.kuali.kfs.module.ar.businessobject.ReceivableCustomerInvoiceDetail; 033 import org.kuali.kfs.module.ar.businessobject.SalesTaxCustomerInvoiceDetail; 034 import org.kuali.kfs.module.ar.businessobject.WriteoffCustomerInvoiceDetail; 035 import org.kuali.kfs.module.ar.businessobject.WriteoffTaxCustomerInvoiceDetail; 036 import org.kuali.kfs.module.ar.document.service.AccountsReceivableTaxService; 037 import org.kuali.kfs.module.ar.document.service.CustomerInvoiceGLPEService; 038 import org.kuali.kfs.module.ar.document.service.CustomerInvoiceWriteoffDocumentService; 039 import org.kuali.kfs.sys.KFSConstants; 040 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper; 041 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail; 042 import org.kuali.kfs.sys.businessobject.TaxDetail; 043 import org.kuali.kfs.sys.context.SpringContext; 044 import org.kuali.kfs.sys.document.AmountTotaling; 045 import org.kuali.kfs.sys.document.GeneralLedgerPendingEntrySource; 046 import org.kuali.kfs.sys.document.GeneralLedgerPostingDocumentBase; 047 import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService; 048 import org.kuali.kfs.sys.service.TaxService; 049 import org.kuali.rice.kew.dto.DocumentRouteStatusChangeDTO; 050 import org.kuali.rice.kns.bo.Note; 051 import org.kuali.rice.kns.exception.ValidationException; 052 import org.kuali.rice.kns.rule.event.KualiDocumentEvent; 053 import org.kuali.rice.kns.service.ParameterService; 054 import org.kuali.rice.kns.util.KualiDecimal; 055 import org.kuali.rice.kns.util.ObjectUtils; 056 import org.kuali.rice.kns.util.TypedArrayList; 057 058 public class CustomerInvoiceWriteoffDocument extends GeneralLedgerPostingDocumentBase implements GeneralLedgerPendingEntrySource, AmountTotaling { 059 060 protected static final String REQUIRES_APPROVAL_NODE = "RequiresApproval"; 061 protected String chartOfAccountsCode; 062 protected String accountNumber; 063 protected String subAccountNumber; 064 protected String financialObjectCode; 065 protected String financialSubObjectCode; 066 protected String projectCode; 067 protected String organizationReferenceIdentifier; 068 protected String financialDocumentReferenceInvoiceNumber; 069 protected String statusCode; 070 071 protected String customerNote; 072 073 protected Account account; 074 protected Chart chartOfAccounts; 075 protected SubAccount subAccount; 076 protected ObjectCode financialObject; 077 protected SubObjectCode financialSubObject; 078 protected ProjectCode project; 079 protected CustomerInvoiceDocument customerInvoiceDocument; 080 protected AccountsReceivableDocumentHeader accountsReceivableDocumentHeader; 081 protected KualiDecimal invoiceWriteoffAmount; 082 083 public AccountsReceivableDocumentHeader getAccountsReceivableDocumentHeader() { 084 return accountsReceivableDocumentHeader; 085 } 086 087 public void setAccountsReceivableDocumentHeader(AccountsReceivableDocumentHeader accountsReceivableDocumentHeader) { 088 this.accountsReceivableDocumentHeader = accountsReceivableDocumentHeader; 089 } 090 091 public String getChartOfAccountsCode() { 092 return chartOfAccountsCode; 093 } 094 095 public void setChartOfAccountsCode(String chartOfAccountsCode) { 096 this.chartOfAccountsCode = chartOfAccountsCode; 097 } 098 099 public String getAccountNumber() { 100 return accountNumber; 101 } 102 103 public void setAccountNumber(String accountNumber) { 104 this.accountNumber = accountNumber; 105 } 106 107 public String getSubAccountNumber() { 108 return subAccountNumber; 109 } 110 111 public void setSubAccountNumber(String subAccountNumber) { 112 this.subAccountNumber = subAccountNumber; 113 } 114 115 public String getFinancialObjectCode() { 116 return financialObjectCode; 117 } 118 119 public void setFinancialObjectCode(String financialObjectCode) { 120 this.financialObjectCode = financialObjectCode; 121 } 122 123 public String getFinancialSubObjectCode() { 124 return financialSubObjectCode; 125 } 126 127 public void setFinancialSubObjectCode(String financialSubObjectCode) { 128 this.financialSubObjectCode = financialSubObjectCode; 129 } 130 131 public String getProjectCode() { 132 return projectCode; 133 } 134 135 public void setProjectCode(String projectCode) { 136 this.projectCode = projectCode; 137 } 138 139 public String getOrganizationReferenceIdentifier() { 140 return organizationReferenceIdentifier; 141 } 142 143 public void setOrganizationReferenceIdentifier(String organizationReferenceIdentifier) { 144 this.organizationReferenceIdentifier = organizationReferenceIdentifier; 145 } 146 147 public String getFinancialDocumentReferenceInvoiceNumber() { 148 return financialDocumentReferenceInvoiceNumber; 149 } 150 151 public void setFinancialDocumentReferenceInvoiceNumber(String financialDocumentReferenceInvoiceNumber) { 152 this.financialDocumentReferenceInvoiceNumber = financialDocumentReferenceInvoiceNumber; 153 } 154 155 public Account getAccount() { 156 return account; 157 } 158 159 public void setAccount(Account account) { 160 this.account = account; 161 } 162 163 public Chart getChartOfAccounts() { 164 return chartOfAccounts; 165 } 166 167 public void setChartOfAccounts(Chart chartOfAccounts) { 168 this.chartOfAccounts = chartOfAccounts; 169 } 170 171 public SubAccount getSubAccount() { 172 return subAccount; 173 } 174 175 public void setSubAccount(SubAccount subAccount) { 176 this.subAccount = subAccount; 177 } 178 179 public ObjectCode getFinancialObject() { 180 return financialObject; 181 } 182 183 public void setFinancialObject(ObjectCode financialObject) { 184 this.financialObject = financialObject; 185 } 186 187 public SubObjectCode getFinancialSubObject() { 188 return financialSubObject; 189 } 190 191 public void setFinancialSubObject(SubObjectCode financialSubObject) { 192 this.financialSubObject = financialSubObject; 193 } 194 195 public ProjectCode getProject() { 196 return project; 197 } 198 199 public void setProject(ProjectCode project) { 200 this.project = project; 201 } 202 203 public CustomerInvoiceDocument getCustomerInvoiceDocument() { 204 if (ObjectUtils.isNull(customerInvoiceDocument) && StringUtils.isNotEmpty(financialDocumentReferenceInvoiceNumber)) { 205 refreshReferenceObject("customerInvoiceDocument"); 206 } 207 208 return customerInvoiceDocument; 209 } 210 211 public void setCustomerInvoiceDocument(CustomerInvoiceDocument customerInvoiceDocument) { 212 this.customerInvoiceDocument = customerInvoiceDocument; 213 } 214 215 /** 216 * This method returns all the applicable invoice details for writeoff. This method also sets the writeoff document number on 217 * each of the invoice details for making retrieval of the actual writeoff amount easier. 218 * 219 * @return 220 */ 221 public List<CustomerInvoiceDetail> getCustomerInvoiceDetailsForWriteoff() { 222 List<CustomerInvoiceDetail> customerInvoiceDetailsForWriteoff = new TypedArrayList(CustomerInvoiceDetail.class); 223 for (CustomerInvoiceDetail customerInvoiceDetail : getCustomerInvoiceDocument().getCustomerInvoiceDetailsWithoutDiscounts()) { 224 customerInvoiceDetail.setCustomerInvoiceWriteoffDocumentNumber(this.documentNumber); 225 customerInvoiceDetailsForWriteoff.add(customerInvoiceDetail); 226 } 227 228 return customerInvoiceDetailsForWriteoff; 229 } 230 231 /** 232 * This method returns the total amount to be written off 233 * 234 * @return 235 */ 236 public KualiDecimal getInvoiceWriteoffAmount() { 237 // only pull the invoice open amount as the invoice writeoff amount while the doc 238 // is in play. once its been approved, rely on the amount stored in the db. 239 if (!KFSConstants.DocumentStatusCodes.APPROVED.equals(getDocumentHeader().getFinancialDocumentStatusCode())) { 240 invoiceWriteoffAmount = customerInvoiceDocument.getOpenAmount(); 241 } 242 return invoiceWriteoffAmount; 243 } 244 245 public void setInvoiceWriteoffAmount(KualiDecimal invoiceWriteoffAmount) { 246 this.invoiceWriteoffAmount = invoiceWriteoffAmount; 247 } 248 249 public String getStatusCode() { 250 return statusCode; 251 } 252 253 public void setStatusCode(String statusCode) { 254 this.statusCode = statusCode; 255 } 256 257 /** 258 * Initializes the values for a new document. 259 */ 260 public void initiateDocument() { 261 setStatusCode(ArConstants.CustomerInvoiceWriteoffStatuses.INITIATE); 262 } 263 264 /** 265 * Clear out the initially populated fields. 266 */ 267 public void clearInitFields() { 268 setFinancialDocumentReferenceInvoiceNumber(null); 269 } 270 271 @Override 272 public List<Long> getWorkflowEngineDocumentIdsToLock() { 273 if (StringUtils.isNotBlank(getFinancialDocumentReferenceInvoiceNumber())) { 274 List<Long> documentIds = new ArrayList<Long>(); 275 documentIds.add(new Long(getFinancialDocumentReferenceInvoiceNumber())); 276 return documentIds; 277 } 278 return null; 279 280 } 281 282 /** 283 * When document is processed do the following: 1) Apply amounts to writeoff invoice 2) Mark off invoice indiciator 284 * 285 * @see org.kuali.kfs.sys.document.GeneralLedgerPostingDocumentBase#doRouteStatusChange() 286 */ 287 @Override 288 public void doRouteStatusChange(DocumentRouteStatusChangeDTO statusChangeEvent) { 289 super.doRouteStatusChange(statusChangeEvent); 290 if (getDocumentHeader().getWorkflowDocument().stateIsProcessed()) { 291 CustomerInvoiceWriteoffDocumentService writeoffService = SpringContext.getBean(CustomerInvoiceWriteoffDocumentService.class); 292 writeoffService.completeWriteoffProcess(this); 293 } 294 } 295 296 /** 297 * do all the calculations before the document gets saved gets called for 'Submit', 'Save', and 'Blanket Approved' 298 * 299 * @see org.kuali.rice.kns.document.Document#prepareForSave(org.kuali.rice.kns.rule.event.KualiDocumentEvent) 300 */ 301 public void prepareForSave(KualiDocumentEvent event) { 302 // generate GLPEs 303 if (!SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(this)) { 304 logErrors(); 305 throw new ValidationException("general ledger GLPE generation failed"); 306 } 307 super.prepareForSave(event); 308 } 309 310 public boolean generateDocumentGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySequenceHelper sequenceHelper) { 311 return true; 312 } 313 314 protected KualiDecimal getCustomerInvoiceDetailOpenPretaxAmount(CustomerInvoiceDetail customerInvoiceDetail) { 315 String postalCode = SpringContext.getBean(AccountsReceivableTaxService.class).getPostalCodeForTaxation(getCustomerInvoiceDocument()); 316 Date dateOfTransaction = getCustomerInvoiceDocument().getBillingDate(); 317 KualiDecimal pretaxAmount = SpringContext.getBean(TaxService.class).getPretaxAmount(dateOfTransaction, postalCode, customerInvoiceDetail.getAmountOpen()); 318 319 return pretaxAmount; 320 } 321 322 /** 323 * This method creates the following GLPE's for the customer invoice writeoff 1. C Receivable object code with remaining amount 324 * 2. D Writeoff object code (or Writeoff FAU) with remaining amount 3. C Receivable object code for tax on state tax account 4. 325 * D Sales Tax object code for tax on the state tax account 5. C Receivable object code for tax on district tax account 6. D 326 * District tax object code for $1.00 on the district tax account 327 * 328 * @see org.kuali.kfs.service.impl.GenericGeneralLedgerPendingEntryGenerationProcessImpl#processGenerateGeneralLedgerPendingEntries(org.kuali.kfs.sys.document.GeneralLedgerPendingEntrySource, 329 * org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail, 330 * org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper) 331 */ 332 333 public boolean generateGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) { 334 CustomerInvoiceDetail customerInvoiceDetail = (CustomerInvoiceDetail) glpeSourceDetail; 335 336 // if invoice item open amount <= 0 -> do not generate GLPEs for this glpeSourceDetail 337 if (!customerInvoiceDetail.getAmountOpen().isPositive()) 338 return true; 339 340 KualiDecimal amount; 341 342 String receivableOffsetOption = SpringContext.getBean(ParameterService.class).getParameterValue(CustomerInvoiceDocument.class, ArConstants.GLPE_RECEIVABLE_OFFSET_GENERATION_METHOD); 343 boolean hasReceivableClaimOnCashOffset = ArConstants.GLPE_RECEIVABLE_OFFSET_GENERATION_METHOD_FAU.equals(receivableOffsetOption); 344 345 String writeoffOffsetOption = SpringContext.getBean(ParameterService.class).getParameterValue(CustomerInvoiceWriteoffDocument.class, ArConstants.GLPE_WRITEOFF_GENERATION_METHOD); 346 boolean hasWriteoffClaimOnCashOffset = ArConstants.GLPE_WRITEOFF_GENERATION_METHOD_ORG_ACCT_DEFAULT.equals(writeoffOffsetOption); 347 348 String writeoffTaxGenerationOption = SpringContext.getBean(ParameterService.class).getParameterValue(CustomerInvoiceWriteoffDocument.class, ArConstants.ALLOW_SALES_TAX_LIABILITY_ADJUSTMENT_IND); 349 boolean hasWriteoffTaxClaimOnCashOffset = ArConstants.ALLOW_SALES_TAX_LIABILITY_ADJUSTMENT_IND_NO.equals( writeoffTaxGenerationOption ); 350 351 boolean hasClaimOnCashOffset = hasReceivableClaimOnCashOffset || hasWriteoffClaimOnCashOffset; 352 353 // if sales tax is enabled generate tax GLPEs 354 if (SpringContext.getBean(AccountsReceivableTaxService.class).isCustomerInvoiceDetailTaxable(getCustomerInvoiceDocument(), customerInvoiceDetail)) { 355 amount = getCustomerInvoiceDetailOpenPretaxAmount(customerInvoiceDetail); 356 addReceivableGLPEs(sequenceHelper, glpeSourceDetail, hasClaimOnCashOffset, amount); 357 sequenceHelper.increment(); 358 addWriteoffGLPEs(sequenceHelper, glpeSourceDetail, hasClaimOnCashOffset, amount); 359 addSalesTaxGLPEs( sequenceHelper, glpeSourceDetail, hasWriteoffTaxClaimOnCashOffset, amount); 360 } 361 else { 362 amount = customerInvoiceDetail.getAmountOpen(); 363 addReceivableGLPEs(sequenceHelper, glpeSourceDetail, hasClaimOnCashOffset, amount); 364 sequenceHelper.increment(); 365 addWriteoffGLPEs(sequenceHelper, glpeSourceDetail, hasClaimOnCashOffset, amount); 366 } 367 return true; 368 } 369 370 /** 371 * This method creates the receivable GLPEs for customer invoice details using the remaining amount 372 * 373 * @param poster 374 * @param sequenceHelper 375 * @param postable 376 * @param explicitEntry 377 */ 378 protected void addReceivableGLPEs(GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, boolean hasClaimOnCashOffset, KualiDecimal amount) { 379 380 CustomerInvoiceDetail customerInvoiceDetail = (CustomerInvoiceDetail) glpeSourceDetail; 381 ReceivableCustomerInvoiceDetail receivableCustomerInvoiceDetail = new ReceivableCustomerInvoiceDetail(customerInvoiceDetail, getCustomerInvoiceDocument()); 382 boolean isDebit = false; 383 384 CustomerInvoiceGLPEService service = SpringContext.getBean(CustomerInvoiceGLPEService.class); 385 service.createAndAddGenericInvoiceRelatedGLPEs(this, receivableCustomerInvoiceDetail, sequenceHelper, isDebit, hasClaimOnCashOffset, amount); 386 } 387 388 /** 389 * This method adds writeoff GLPE's for the customer invoice details using the remaining amount. 390 * 391 * @param poster 392 * @param sequenceHelper 393 * @param postable 394 * @param explicitEntry 395 */ 396 protected void addWriteoffGLPEs(GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, boolean hasClaimOnCashOffset, KualiDecimal amount) { 397 398 CustomerInvoiceDetail customerInvoiceDetail = (CustomerInvoiceDetail) glpeSourceDetail; 399 WriteoffCustomerInvoiceDetail writeoffCustomerInvoiceDetail = new WriteoffCustomerInvoiceDetail(customerInvoiceDetail, this); 400 boolean isDebit = true; 401 402 CustomerInvoiceGLPEService service = SpringContext.getBean(CustomerInvoiceGLPEService.class); 403 service.createAndAddGenericInvoiceRelatedGLPEs(this, writeoffCustomerInvoiceDetail, sequenceHelper, isDebit, hasClaimOnCashOffset, amount); 404 } 405 406 protected void addSalesTaxGLPEs(GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, boolean hasWriteoffTaxClaimOnCashOffset, KualiDecimal amount){ 407 CustomerInvoiceDetail customerInvoiceDetail = (CustomerInvoiceDetail) glpeSourceDetail; 408 WriteoffCustomerInvoiceDetail writeoffCustomerInvoiceDetail = new WriteoffCustomerInvoiceDetail(customerInvoiceDetail, this); 409 410 boolean isDebit = true; 411 412 String postalCode = SpringContext.getBean(AccountsReceivableTaxService.class).getPostalCodeForTaxation(getCustomerInvoiceDocument()); 413 Date dateOfTransaction = getCustomerInvoiceDocument().getBillingDate(); 414 415 List<TaxDetail> salesTaxDetails = SpringContext.getBean(TaxService.class).getSalesTaxDetails(dateOfTransaction, postalCode, amount); 416 417 CustomerInvoiceGLPEService service = SpringContext.getBean(CustomerInvoiceGLPEService.class); 418 SalesTaxCustomerInvoiceDetail salesTaxCustomerInvoiceDetail; 419 ReceivableCustomerInvoiceDetail receivableCustomerInvoiceDetail; 420 WriteoffTaxCustomerInvoiceDetail writeoffTaxCustomerInvoiceDetail; 421 for (TaxDetail salesTaxDetail : salesTaxDetails) { 422 423 salesTaxCustomerInvoiceDetail = new SalesTaxCustomerInvoiceDetail(salesTaxDetail, customerInvoiceDetail); 424 receivableCustomerInvoiceDetail = new ReceivableCustomerInvoiceDetail(salesTaxCustomerInvoiceDetail, getCustomerInvoiceDocument()); 425 writeoffTaxCustomerInvoiceDetail = new WriteoffTaxCustomerInvoiceDetail(salesTaxCustomerInvoiceDetail, this); 426 427 sequenceHelper.increment(); 428 service.createAndAddGenericInvoiceRelatedGLPEs(this, receivableCustomerInvoiceDetail, sequenceHelper, !isDebit, hasWriteoffTaxClaimOnCashOffset, salesTaxDetail.getTaxAmount()); 429 430 sequenceHelper.increment(); 431 service.createAndAddGenericInvoiceRelatedGLPEs(this, writeoffTaxCustomerInvoiceDetail, sequenceHelper, isDebit, hasWriteoffTaxClaimOnCashOffset, salesTaxDetail.getTaxAmount()); 432 } 433 } 434 435 public KualiDecimal getGeneralLedgerPendingEntryAmountForDetail(GeneralLedgerPendingEntrySourceDetail glpeSourceDetail) { 436 // TODO Auto-generated method stub 437 return null; 438 } 439 440 public List<GeneralLedgerPendingEntrySourceDetail> getGeneralLedgerPendingEntrySourceDetails() { 441 List<GeneralLedgerPendingEntrySourceDetail> generalLedgerPendingEntrySourceDetails = new ArrayList<GeneralLedgerPendingEntrySourceDetail>(); 442 generalLedgerPendingEntrySourceDetails.addAll(getCustomerInvoiceDocument().getCustomerInvoiceDetailsWithoutDiscounts()); 443 return generalLedgerPendingEntrySourceDetails; 444 445 } 446 447 public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) { 448 // TODO Auto-generated method stub 449 return false; 450 } 451 452 public KualiDecimal getTotalDollarAmount() { 453 return getInvoiceWriteoffAmount(); 454 } 455 456 /** 457 * Gets the customerNote attribute. 458 * 459 * @return Returns the customerNote. 460 */ 461 public String getCustomerNote() { 462 /* 463 * ArrayList boNotes = (ArrayList) this.getCustomerInvoiceDocument().getCustomer().getBoNotes(); if (boNotes.size() > 0) 464 * customerNote = boNotes.toString(); else customerNote = ""; 465 */ 466 return customerNote; 467 } 468 469 /** 470 * Sets the customerNote attribute value. 471 * 472 * @param customerNote The customerNote to set. 473 */ 474 public void setCustomerNote(String customerNote) { 475 this.customerNote = customerNote; 476 } 477 478 public void populateCustomerNote() { 479 customerNote = ""; 480 ArrayList boNotes = (ArrayList) this.getCustomerInvoiceDocument().getCustomer().getBoNotes(); 481 if (boNotes.size() > 0) { 482 for (int i = 0; i < boNotes.size(); i++) 483 customerNote += ((Note) boNotes.get(i)).getNoteText() + " "; 484 customerNote.trim(); 485 } 486 } 487 488 /** 489 * Answers true when invoice write off amount is greater than default approved amount ($50???) 490 * 491 * @see org.kuali.kfs.sys.document.FinancialSystemTransactionalDocumentBase#answerSplitNodeQuestion(java.lang.String) 492 */ 493 @Override 494 public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException { 495 if (REQUIRES_APPROVAL_NODE.equals(nodeName)) { 496 497 // grab the approval threshold from the param service 498 ParameterService paramService = SpringContext.getBean(ParameterService.class); 499 KualiDecimal approvalThreshold = new KualiDecimal(paramService.getParameterValue(CustomerInvoiceWriteoffDocument.class, ArConstants.WRITEOFF_APPROVAL_THRESHOLD)); 500 501 return (approvalThreshold.isLessThan(getInvoiceWriteoffAmount())); 502 } 503 throw new UnsupportedOperationException("answerSplitNode('" + nodeName + "') called but no handler for this nodeName present."); 504 } 505 506 507 }