@Override protected void addRoleQualification(Object businessObject, Map<String, String> attributes) { super.addRoleQualification(businessObject, attributes); CustomerInvoiceWriteoffDocument writeoffDoc = (CustomerInvoiceWriteoffDocument) businessObject; String invoiceDocNumber = writeoffDoc.getFinancialDocumentReferenceInvoiceNumber(); if (StringUtils.isBlank(invoiceDocNumber)) { return; } CustomerInvoiceDocumentService invoiceService = SpringContext.getBean(CustomerInvoiceDocumentService.class); Collection<CustomerInvoiceDetail> invoiceDetails = invoiceService.getCustomerInvoiceDetailsForCustomerInvoiceDocument(invoiceDocNumber); // adds the chart/account for each account used on the original invoice that will be credited // by this for (CustomerInvoiceDetail invoiceDetail : invoiceDetails) { if (StringUtils.isNotBlank(invoiceDetail.getChartOfAccountsCode()) && StringUtils.isNotBlank(invoiceDetail.getAccountNumber())) { attributes.put( KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, invoiceDetail.getChartOfAccountsCode()); attributes.put(KfsKimAttributes.ACCOUNT_NUMBER, invoiceDetail.getAccountNumber()); } } }
// PAYAPP public KualiDecimal getAmountDiscounted() { KualiDecimal a = getAmount(); CustomerInvoiceDetail discount = getDiscountCustomerInvoiceDetail(); if (ObjectUtils.isNotNull(discount)) { KualiDecimal d = discount.getAmount(); a = a.add(d); } return a; }
/** * @param customerInvoiceDetail * @param paymentApplicationDocument * @return */ public static boolean validateAmountAppliedToCustomerInvoiceDetailByPaymentApplicationDocument( CustomerInvoiceDetail customerInvoiceDetail, PaymentApplicationDocument paymentApplicationDocument, KualiDecimal totalFromControl) throws WorkflowException { boolean isValid = true; // This let's us highlight a specific invoice detail line String propertyName = MessageFormat.format( ArPropertyConstants.PaymentApplicationDocumentFields.AMOUNT_TO_BE_APPLIED_LINE_N, customerInvoiceDetail.getSequenceNumber().toString()); KualiDecimal amountAppliedByAllOtherDocuments = customerInvoiceDetail.getAmountAppliedExcludingAnyAmountAppliedBy( paymentApplicationDocument.getDocumentNumber()); KualiDecimal amountAppliedByThisDocument = customerInvoiceDetail.getAmountAppliedBy(paymentApplicationDocument.getDocumentNumber()); KualiDecimal totalAppliedAmount = amountAppliedByAllOtherDocuments.add(amountAppliedByThisDocument); // Can't apply more than the total amount of the detail if (!totalAppliedAmount.isLessEqual(totalFromControl)) { isValid = false; GlobalVariables.getMessageMap() .putError( propertyName, ArKeyConstants.PaymentApplicationDocumentErrors .AMOUNT_TO_BE_APPLIED_EXCEEDS_AMOUNT_OUTSTANDING); } // Can't apply a negative amount. if (KualiDecimal.ZERO.isGreaterThan(amountAppliedByThisDocument)) { isValid = false; GlobalVariables.getMessageMap() .putError( propertyName, ArKeyConstants.PaymentApplicationDocumentErrors .AMOUNT_TO_BE_APPLIED_MUST_BE_GREATER_THAN_ZERO); } // Can't apply more than the total amount outstanding on the cash control document. CashControlDocument cashControlDocument = paymentApplicationDocument.getCashControlDocument(); if (ObjectUtils.isNotNull(cashControlDocument)) { if (cashControlDocument.getCashControlTotalAmount().isLessThan(amountAppliedByThisDocument)) { isValid = false; GlobalVariables.getMessageMap() .putError( propertyName, ArKeyConstants.PaymentApplicationDocumentErrors .CANNOT_APPLY_MORE_THAN_BALANCE_TO_BE_APPLIED); } } return isValid; }
@Override public String getChartOfAccountsCode() { if (isUsingOrgAcctDefaultWriteoffFAU) { return poster.getChartOfAccountsCode(); } else { return postable.getChartOfAccountsCode(); } }
@Override public String getAccountNumber() { if (isUsingOrgAcctDefaultWriteoffFAU) { return poster.getAccountNumber(); } else { return postable.getAccountNumber(); } }
@Override public String getProjectCode() { if (isUsingOrgAcctDefaultWriteoffFAU) { return poster.getProjectCode(); } else { return postable.getProjectCode(); } }
/** * @see * org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getOpenAmountForCustomerInvoiceDocument(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument) */ @Override public KualiDecimal getOpenAmountForCustomerInvoiceDocument( CustomerInvoiceDocument customerInvoiceDocument) { KualiDecimal total = new KualiDecimal(0); if (customerInvoiceDocument.isOpenInvoiceIndicator()) { Collection<CustomerInvoiceDetail> customerInvoiceDetails = customerInvoiceDocument.getCustomerInvoiceDetailsWithoutDiscounts(); for (CustomerInvoiceDetail detail : customerInvoiceDetails) { // note that we're now dealing with conditionally applying discounts // depending on whether the doc is saved or approved one level down, // in the CustomerInvoiceDetail.getAmountOpen() detail.setCustomerInvoiceDocument(customerInvoiceDocument); total = total.add(detail.getAmountOpen()); } } return total; }
/** * If the detail is a discount customer invoice detail, return the parent customer invoice * detail's sequence number instead * * @see org.kuali.kfs.module.ar.businessobject.AppliedPayment#getInvoiceItemNumber() */ @Override public Integer getInvoiceItemNumber() { if (isDiscountLine()) { return parentDiscountCustomerInvoiceDetail.getSequenceNumber(); } else { return this.getSequenceNumber(); } }
@Override public String getOrganizationReferenceId() { if (isUsingOrgAcctDefaultWriteoffFAU) { return poster.getOrganizationReferenceIdentifier(); } else { return postable.getOrganizationReferenceId(); } }
public KualiDecimal getAmountOpen() { // if the parent isnt saved, or if its saved but not approved, we // need to include the discounts. If its both saved AND approved, // we do not include the discounts. boolean includeDiscounts = !(isParentSaved() && isParentApproved()); KualiDecimal amount = getAmount(); KualiDecimal applied = getAmountApplied(); KualiDecimal a = amount.subtract(applied); if (includeDiscounts) { CustomerInvoiceDetail discount = getDiscountCustomerInvoiceDetail(); if (ObjectUtils.isNotNull(discount)) { a = a.add(discount.getAmount()); } } return a; }
@Override protected void addRoleQualification(Object businessObject, Map<String, String> attributes) { super.addRoleQualification(businessObject, attributes); CustomerInvoiceDocument document = (CustomerInvoiceDocument) businessObject; CustomerInvoiceDocumentService invoiceDocService = SpringContext.getBean(CustomerInvoiceDocumentService.class); Collection<CustomerInvoiceDetail> invoiceDetails = invoiceDocService.getCustomerInvoiceDetailsForCustomerInvoiceDocumentWithCaching(document); for (CustomerInvoiceDetail invoiceDetail : invoiceDetails) { if (StringUtils.isNotBlank(invoiceDetail.getChartOfAccountsCode()) && StringUtils.isNotBlank(invoiceDetail.getAccountNumber())) { attributes.put( KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, invoiceDetail.getChartOfAccountsCode()); attributes.put(KfsKimAttributes.ACCOUNT_NUMBER, invoiceDetail.getAccountNumber()); } } // add profile principal id - hopefully someday, TEM can simply do this for us if it is turned // on final String currentUserPrincipalId = GlobalVariables.getUserSession().getPrincipalId(); attributes.put(KfsKimAttributes.PROFILE_PRINCIPAL_ID, currentUserPrincipalId); }
/** * @see * org.kuali.kfs.module.ar.document.service.AccountsReceivableTaxService#isCustomerInvoiceDetailTaxable(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument, * org.kuali.kfs.module.ar.businessobject.CustomerInvoiceDetail) */ @Override public boolean isCustomerInvoiceDetailTaxable( CustomerInvoiceDocument customerInvoiceDocument, CustomerInvoiceDetail customerInvoiceDetail) { // check if sales tax is enabled if (!parameterService.getParameterValueAsBoolean( KfsParameterConstants.ACCOUNTS_RECEIVABLE_DOCUMENT.class, ArConstants.ENABLE_SALES_TAX_IND)) { return false; } // check if customer is tax exempt if (ObjectUtils.isNotNull(customerInvoiceDocument.getCustomer())) { if (customerInvoiceDocument.getCustomer().isCustomerTaxExemptIndicator()) { return false; } } // check item if the taxable indicator is checked if (!customerInvoiceDetail.isTaxableIndicator()) { return false; } // check item if item is taxable /* if( StringUtils.isNotEmpty(customerInvoiceDetail.getInvoiceItemCode()) ){ Map<String, String> criteria = new HashMap<String, String>(); criteria.put("invoiceItemCode", customerInvoiceDetail.getInvoiceItemCode()); criteria.put("chartOfAccountsCode", customerInvoiceDocument.getAccountsReceivableDocumentHeader().getProcessingChartOfAccountCode()); criteria.put("organizationCode", customerInvoiceDocument.getAccountsReceivableDocumentHeader().getProcessingOrganizationCode()); CustomerInvoiceItemCode customerInvoiceItemCode = (CustomerInvoiceItemCode) businessObjectService.findByPrimaryKey(CustomerInvoiceItemCode.class, criteria); if (ObjectUtils.isNotNull(customerInvoiceItemCode) && !customerInvoiceItemCode.isTaxableIndicator()){ return false; } } */ // if address of billing org's postal code isn't the same as shipping address, return false??? return true; }
/** * @see * org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#convertDiscountsToPaidApplieds(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument) */ @Override public void convertDiscountsToPaidApplieds(CustomerInvoiceDocument invoice) { // this needs a little explanation. we have to calculate manually // whether we've written off the whole thing, because the regular // code uses the invoice paid applieds to discount, but since those // are added but not committed in this transaction, they're also not // visible in this transaction, so we do it manually. KualiDecimal openAmount = invoice.getOpenAmount(); String invoiceNumber = invoice.getDocumentNumber(); List<CustomerInvoiceDetail> discounts = invoice.getDiscounts(); // retrieve the number of current paid applieds, so we dont have item number overlap Integer paidAppliedItemNumber = 0; for (CustomerInvoiceDetail discount : discounts) { // if credit amount is zero, do nothing if (KualiDecimal.ZERO.equals(discount.getAmount())) { continue; } if (paidAppliedItemNumber == 0) { paidAppliedItemNumber = invoicePaidAppliedService.getNumberOfInvoicePaidAppliedsForInvoiceDetail( invoiceNumber, discount.getInvoiceItemNumber()); } // create and save the paidApplied InvoicePaidApplied invoicePaidApplied = new InvoicePaidApplied(); invoicePaidApplied.setDocumentNumber(invoiceNumber); invoicePaidApplied.setPaidAppliedItemNumber(paidAppliedItemNumber++); invoicePaidApplied.setFinancialDocumentReferenceInvoiceNumber(invoiceNumber); invoicePaidApplied.setInvoiceItemNumber(discount.getInvoiceItemNumber()); invoicePaidApplied.setUniversityFiscalYear(universityDateService.getCurrentFiscalYear()); invoicePaidApplied.setUniversityFiscalPeriodCode( universityDateService.getCurrentUniversityDate().getUniversityFiscalAccountingPeriod()); invoicePaidApplied.setInvoiceItemAppliedAmount(discount.getAmount().abs()); openAmount = openAmount.subtract(discount.getAmount().abs()); businessObjectService.save(invoicePaidApplied); } // if its open, but now with a zero openamount, then close it if (KualiDecimal.ZERO.equals(openAmount)) { invoice.setOpenInvoiceIndicator(false); invoice.setClosedDate(dateTimeService.getCurrentSqlDate()); documentService.updateDocument(invoice); } }
@Override public String getFinancialDocumentLineDescription() { return postable.getFinancialDocumentLineDescription(); }
@Override public KualiDecimal getAmount() { return postable.getAmountOpen(); }
@Override public String getDocumentNumber() { return postable.getDocumentNumber(); }
@Override public void completeCustomerCreditMemo(CustomerCreditMemoDocument creditMemo) { // retrieve the document and make sure its not already closed, crash if so String invoiceNumber = creditMemo.getFinancialDocumentReferenceInvoiceNumber(); CustomerInvoiceDocument invoice; try { invoice = (CustomerInvoiceDocument) documentService.getByDocumentHeaderId(invoiceNumber); } catch (WorkflowException e) { throw new RuntimeException( "A WorkflowException was generated when trying to load Customer Invoice #" + invoiceNumber + ".", e); } if (!invoice.isOpenInvoiceIndicator()) { throw new UnsupportedOperationException( "The CreditMemo Document #" + creditMemo.getDocumentNumber() + " attempted to credit " + "an Invoice [#" + invoiceNumber + "] that was already closed. This is not supported."); } // this needs a little explanation. we have to calculate manually // whether we've written off the whole thing, because the regular // code uses the invoice paid applieds to discount, but since those // are added but not committed in this transaction, they're also not // visible in this transaction, so we do it manually. KualiDecimal openAmount = invoice.getOpenAmount(); Integer paidAppliedItemNumber = 0; // retrieve the customer invoice details, and generate paid applieds for each List<CustomerCreditMemoDetail> details = creditMemo.getCreditMemoDetails(); for (CustomerCreditMemoDetail detail : details) { CustomerInvoiceDetail invoiceDetail = detail.getCustomerInvoiceDetail(); // if credit amount is zero, do nothing if (detail.getCreditMemoLineTotalAmount().isZero()) { continue; } // if credit amount is greater than the open amount, crash and complain if (detail .getCreditMemoLineTotalAmount() .abs() .isGreaterThan(invoiceDetail.getAmountOpen())) { throw new UnsupportedOperationException( "The credit detail for CreditMemo Document #" + creditMemo.getDocumentNumber() + " attempted " + "to credit more than the Open Amount on the Invoice Detail. This is not supported."); } // retrieve the number of current paid applieds, so we dont have item number overlap if (paidAppliedItemNumber == 0) { paidAppliedItemNumber = paidAppliedService.getNumberOfInvoicePaidAppliedsForInvoiceDetail( invoiceNumber, invoiceDetail.getInvoiceItemNumber()); } // create and save the paidApplied InvoicePaidApplied invoicePaidApplied = new InvoicePaidApplied(); invoicePaidApplied.setDocumentNumber(creditMemo.getDocumentNumber()); invoicePaidApplied.setPaidAppliedItemNumber(paidAppliedItemNumber++); invoicePaidApplied.setFinancialDocumentReferenceInvoiceNumber(invoiceNumber); invoicePaidApplied.setInvoiceItemNumber(invoiceDetail.getInvoiceItemNumber()); invoicePaidApplied.setUniversityFiscalYear(universityDateService.getCurrentFiscalYear()); invoicePaidApplied.setUniversityFiscalPeriodCode( universityDateService.getCurrentUniversityDate().getUniversityFiscalAccountingPeriod()); invoicePaidApplied.setInvoiceItemAppliedAmount(detail.getCreditMemoLineTotalAmount().abs()); openAmount = openAmount.subtract(detail.getCreditMemoLineTotalAmount().abs()); businessObjectService.save(invoicePaidApplied); } // if its open, but now with a zero openamount, then close it if (invoice.isOpenInvoiceIndicator() && KualiDecimal.ZERO.equals(openAmount)) { customerInvoiceDocumentService.addCloseNote( invoice, creditMemo.getDocumentHeader().getWorkflowDocument()); invoice.setOpenInvoiceIndicator(false); invoice.setClosedDate(dateTimeService.getCurrentSqlDate()); documentService.updateDocument(invoice); } }