use of org.kuali.kfs.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class ContractsGrantsInvoiceDocumentServiceImpl method assignCurrentExpenditureToNonExistingAccountObjectCode.
protected void assignCurrentExpenditureToNonExistingAccountObjectCode(ContractsGrantsInvoiceDocument contractsGrantsInvoiceDocument, ContractsGrantsInvoiceDetail invoiceDetail) {
String categoryCode = invoiceDetail.getCategoryCode();
if (StringUtils.isBlank(categoryCode)) {
throw new IllegalArgumentException("Category Code can not be null during recalculation of account object code for Contracts & Grants Invoice Document.");
}
// get the category that matches this category code.
final CostCategory category = businessObjectService.findBySinglePrimaryKey(CostCategory.class, categoryCode);
// got the category now.
if (!ObjectUtils.isNull(category)) {
final KualiDecimal oneCent = new KualiDecimal(0.01);
int size = contractsGrantsInvoiceDocument.getAccountDetails().size();
KualiDecimal amount = new KualiDecimal(invoiceDetail.getInvoiceAmount().bigDecimalValue().divide(new BigDecimal(size), 2, RoundingMode.HALF_UP));
KualiDecimal remainder = invoiceDetail.getInvoiceAmount().subtract(amount.multiply(new KualiDecimal(size)));
for (InvoiceAccountDetail invoiceAccountDetail : contractsGrantsInvoiceDocument.getAccountDetails()) {
InvoiceDetailAccountObjectCode invoiceDetailAccountObjectCode = new InvoiceDetailAccountObjectCode();
invoiceDetailAccountObjectCode.setDocumentNumber(contractsGrantsInvoiceDocument.getDocumentNumber());
invoiceDetailAccountObjectCode.setProposalNumber(contractsGrantsInvoiceDocument.getInvoiceGeneralDetail().getProposalNumber());
invoiceDetailAccountObjectCode.setCategoryCode(categoryCode);
invoiceDetailAccountObjectCode.setAccountNumber(invoiceAccountDetail.getAccountNumber());
invoiceDetailAccountObjectCode.setChartOfAccountsCode(invoiceAccountDetail.getChartOfAccountsCode());
// it's 0.00 that's why we are in this section to begin with.
invoiceDetailAccountObjectCode.setCumulativeExpenditures(KualiDecimal.ZERO);
// this is also 0.00 because it has never been billed before
invoiceDetailAccountObjectCode.setTotalBilled(KualiDecimal.ZERO);
final ObjectCodeCurrent objectCode = getCostCategoryService().findObjectCodeForChartAndCategory(invoiceAccountDetail.getChartOfAccountsCode(), categoryCode);
if (!ObjectUtils.isNull(objectCode)) {
invoiceDetailAccountObjectCode.setFinancialObjectCode(objectCode.getFinancialObjectCode());
}
// tack on or remove one penny until the remainder is 0 - take a penny, leave a penny!
if (remainder.isGreaterThan(KualiDecimal.ZERO)) {
amount = amount.add(oneCent);
remainder = remainder.subtract(oneCent);
} else if (remainder.isLessThan(KualiDecimal.ZERO)) {
amount = amount.subtract(oneCent);
remainder = remainder.add(oneCent);
}
invoiceDetailAccountObjectCode.setCurrentExpenditures(amount);
List<InvoiceDetailAccountObjectCode> invoiceDetailAccountObjectCodes = contractsGrantsInvoiceDocument.getInvoiceDetailAccountObjectCodes();
if (invoiceDetailAccountObjectCodes.contains(invoiceDetailAccountObjectCode)) {
// update existing code
InvoiceDetailAccountObjectCode original = invoiceDetailAccountObjectCodes.get(invoiceDetailAccountObjectCodes.indexOf(invoiceDetailAccountObjectCode));
original.setCurrentExpenditures(amount);
original.setCategoryCode(categoryCode);
} else {
// add this single account object code item to the list in the Map
contractsGrantsInvoiceDocument.getInvoiceDetailAccountObjectCodes().add(invoiceDetailAccountObjectCode);
}
}
} else {
LOG.error("Category Code cannot be found from the category list during recalculation of account object " + "code for Contracts & Grants Invoice Document.");
}
}
use of org.kuali.kfs.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class ContractsGrantsInvoiceDocumentServiceImpl method getCategoryTotalBilledAmountsForInvoiceAccountDetail.
/**
* Totals the total billed amounts of any invoice detail account object codes on the document which have set
* categories by account numbers
*
* @param contractsGrantsInvoiceDocument the document holding invoice detail account object codes
* @return a Map where the key is the concatenation of chartOfAccountsCode-accountNumber and the value is the
* total billed amount on that account
*/
protected Map<String, KualiDecimal> getCategoryTotalBilledAmountsForInvoiceAccountDetail(ContractsGrantsInvoiceDocument contractsGrantsInvoiceDocument) {
Map<String, KualiDecimal> totalBilledAmounts = new HashMap<>();
for (InvoiceDetailAccountObjectCode invoiceDetailAccountObjectCode : contractsGrantsInvoiceDocument.getInvoiceDetailAccountObjectCodes()) {
final String accountKey = StringUtils.join(new String[] { invoiceDetailAccountObjectCode.getChartOfAccountsCode(), invoiceDetailAccountObjectCode.getAccountNumber() }, "-");
if (StringUtils.isNotBlank(invoiceDetailAccountObjectCode.getCategoryCode())) {
KualiDecimal total = totalBilledAmounts.get(accountKey);
if (ObjectUtils.isNull(total)) {
total = KualiDecimal.ZERO;
}
totalBilledAmounts.put(accountKey, total.add(invoiceDetailAccountObjectCode.getTotalBilled()));
}
}
return totalBilledAmounts;
}
use of org.kuali.kfs.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class ContractsGrantsInvoiceDocumentServiceImpl method prorateBill.
@Override
public void prorateBill(ContractsGrantsInvoiceDocument contractsGrantsInvoiceDocument) {
// Amount to be billed on this invoice
KualiDecimal totalCost = new KualiDecimal(0);
// must iterate through the invoice details because the user might have manually changed the value
for (ContractsGrantsInvoiceDetail invD : contractsGrantsInvoiceDocument.getInvoiceDetails()) {
totalCost = totalCost.add(invD.getInvoiceAmount());
}
// Total Billed so far
KualiDecimal billedTotalCost = contractsGrantsInvoiceDocument.getInvoiceGeneralDetail().getTotalPreviouslyBilled();
// AwardTotal
KualiDecimal accountAwardTotal = contractsGrantsInvoiceDocument.getInvoiceGeneralDetail().getAwardTotal();
if (accountAwardTotal.subtract(billedTotalCost).isGreaterEqual(new KualiDecimal(0))) {
KualiDecimal amountEligibleForBilling = accountAwardTotal.subtract(billedTotalCost);
if (totalCost.isGreaterThan(amountEligibleForBilling)) {
// use BigDecimal because percentage should not have only a scale of 2, we need more for accuracy
BigDecimal percentage = amountEligibleForBilling.bigDecimalValue().divide(totalCost.bigDecimalValue(), 10, RoundingMode.HALF_DOWN);
// use to check if rounding has left a few cents off
KualiDecimal amountToBill = new KualiDecimal(0);
ContractsGrantsInvoiceDetail largestCostCategory = null;
BigDecimal largestAmount = BigDecimal.ZERO;
for (ContractsGrantsInvoiceDetail invD : contractsGrantsInvoiceDocument.getInvoiceDetails()) {
BigDecimal newValue = invD.getInvoiceAmount().bigDecimalValue().multiply(percentage);
KualiDecimal newKualiDecimalValue = new KualiDecimal(newValue.setScale(2, RoundingMode.DOWN));
invD.setInvoiceAmount(newKualiDecimalValue);
amountToBill = amountToBill.add(newKualiDecimalValue);
if (newValue.compareTo(largestAmount) > 0) {
largestAmount = newKualiDecimalValue.bigDecimalValue();
largestCostCategory = invD;
}
}
if (!amountToBill.equals(amountEligibleForBilling)) {
KualiDecimal remaining = amountEligibleForBilling.subtract(amountToBill);
if (ObjectUtils.isNull(largestCostCategory) && CollectionUtils.isNotEmpty(contractsGrantsInvoiceDocument.getInvoiceDetails())) {
largestCostCategory = contractsGrantsInvoiceDocument.getInvoiceDetails().get(0);
}
if (ObjectUtils.isNotNull(largestCostCategory)) {
largestCostCategory.setInvoiceAmount(largestCostCategory.getInvoiceAmount().add(remaining));
}
}
recalculateTotalAmountBilledToDate(contractsGrantsInvoiceDocument);
}
}
}
use of org.kuali.kfs.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class ContractsGrantsInvoiceDocumentServiceImpl method createSourceAccountingLinesByAward.
/**
* Generates the source accounting lines for a Contracts & Grants Invoice from the award accounts associated with
* an award (in the form of the pre-generated invoice account details)
*
* @param contractsGrantsInvoiceDocument the Contracts & Grants Invoice to create invoice details for
* @return a List of generated accounting lines
*/
protected List<CustomerInvoiceDetail> createSourceAccountingLinesByAward(ContractsGrantsInvoiceDocument contractsGrantsInvoiceDocument) {
List<CustomerInvoiceDetail> awardAccountingLines = new ArrayList<>();
if (!CollectionUtils.isEmpty(contractsGrantsInvoiceDocument.getAccountDetails())) {
final Map<String, KualiDecimal> accountExpenditureAmounts = getCategoryExpenditureAmountsForInvoiceAccountDetail(contractsGrantsInvoiceDocument);
final Map<String, KualiDecimal> accountTotalBilledAmounts = getCategoryTotalBilledAmountsForInvoiceAccountDetail(contractsGrantsInvoiceDocument);
for (InvoiceAccountDetail invAcctD : contractsGrantsInvoiceDocument.getAccountDetails()) {
final String proposalNumber = invAcctD.getProposalNumber();
final String chartOfAccountsCode = invAcctD.getChartOfAccountsCode();
final String accountNumber = invAcctD.getAccountNumber();
if (invAcctD.getAccount() == null) {
invAcctD.refreshReferenceObject(KFSPropertyConstants.ACCOUNT);
}
final SubFundGroup subFundGroup = invAcctD.getAccount().getSubFundGroup();
final Integer sequenceNumber = contractsGrantsInvoiceDocument.getAccountDetails().indexOf(invAcctD) + 1;
final String accountKey = StringUtils.join(new String[] { chartOfAccountsCode, accountNumber }, "-");
KualiDecimal totalAmount = accountExpenditureAmounts.getOrDefault(accountKey, KualiDecimal.ZERO);
if (invAcctD.getTotalPreviouslyBilled().isZero()) {
KualiDecimal previouslyBilledAmount = getPredeterminedBillingBilledToDateAmount(proposalNumber, chartOfAccountsCode, accountNumber);
previouslyBilledAmount = previouslyBilledAmount.add(getMilestonesBilledToDateAmount(proposalNumber, chartOfAccountsCode, accountNumber));
KualiDecimal totalBilledAmount = accountTotalBilledAmounts.getOrDefault(accountKey, KualiDecimal.ZERO);
previouslyBilledAmount = previouslyBilledAmount.subtract(totalBilledAmount);
if (previouslyBilledAmount.isGreaterThan(KualiDecimal.ZERO)) {
totalAmount = totalAmount.subtract(previouslyBilledAmount);
}
}
CustomerInvoiceDetail cide = createSourceAccountingLine(contractsGrantsInvoiceDocument.getDocumentNumber(), chartOfAccountsCode, accountNumber, subFundGroup, totalAmount, sequenceNumber);
awardAccountingLines.add(cide);
}
}
return awardAccountingLines;
}
use of org.kuali.kfs.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class CustomerInvoiceDetailServiceImpl method recalculateCustomerInvoiceDetail.
@Override
public void recalculateCustomerInvoiceDetail(CustomerInvoiceDocument customerInvoiceDocument, CustomerInvoiceDetail customerInvoiceDetail) {
// make sure amounts are negative when they are supposed to be
if (!customerInvoiceDocument.isInvoiceReversal() && customerInvoiceDetail.isDiscountLine()) {
customerInvoiceDetail.setInvoiceItemUnitPriceToNegative();
} else if (customerInvoiceDocument.isInvoiceReversal() && !customerInvoiceDetail.isDiscountLine()) {
customerInvoiceDetail.setInvoiceItemUnitPriceToNegative();
}
KualiDecimal pretaxAmount = customerInvoiceDetail.getInvoiceItemPreTaxAmount();
KualiDecimal taxAmount = KualiDecimal.ZERO;
if (accountsReceivableTaxService.isCustomerInvoiceDetailTaxable(customerInvoiceDocument, customerInvoiceDetail)) {
String postalCode = accountsReceivableTaxService.getPostalCodeForTaxation(customerInvoiceDocument);
taxAmount = taxService.getTotalSalesTaxAmount(dateTimeService.getCurrentSqlDate(), postalCode, pretaxAmount);
}
customerInvoiceDetail.setInvoiceItemTaxAmount(taxAmount);
customerInvoiceDetail.setAmount(taxAmount.add(pretaxAmount));
}
Aggregations