use of org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode in project cu-kfs by CU-CommunityApps.
the class ContractsGrantsInvoiceDocumentServiceImpl method adjustObjectCodeAmountsIfChanged.
/**
* If any of the current expenditures for the cost categories on the Contracts & Grants Invoice Document have
* changed, recalculate the Object Code amounts.
*
* @param contractsGrantsInvoiceDocument document containing cost categories to review
* @return true if expenditure value changed, false otherwise
*/
protected boolean adjustObjectCodeAmountsIfChanged(ContractsGrantsInvoiceDocument contractsGrantsInvoiceDocument) {
boolean isExpenditureValueChanged = false;
// put the invoiceDetailAccountObjectCode into a map based on category
List<InvoiceDetailAccountObjectCode> invoiceDetailAccountObjectCodes = contractsGrantsInvoiceDocument.getInvoiceDetailAccountObjectCodes();
Map<String, List<InvoiceDetailAccountObjectCode>> invoiceDetailAccountObjectCodeMap = new HashMap<>();
for (InvoiceDetailAccountObjectCode invoiceDetailAccountObjectCode : invoiceDetailAccountObjectCodes) {
String categoryCode = invoiceDetailAccountObjectCode.getCategoryCode();
List<InvoiceDetailAccountObjectCode> invoiceDetailAccountObjectCodeList = invoiceDetailAccountObjectCodeMap.get(categoryCode);
// if new category, create new list to put into map
if (invoiceDetailAccountObjectCodeList == null) {
List<InvoiceDetailAccountObjectCode> newInvoiceDetailAccountObjectCodeList = new ArrayList<>();
newInvoiceDetailAccountObjectCodeList.add(invoiceDetailAccountObjectCode);
invoiceDetailAccountObjectCodeMap.put(categoryCode, newInvoiceDetailAccountObjectCodeList);
} else {
// else, if list is found, add it to existing list
invoiceDetailAccountObjectCodeMap.get(categoryCode).add(invoiceDetailAccountObjectCode);
}
}
// invoiceDetailObjectCode and update account details
for (ContractsGrantsInvoiceDetail invoiceDetail : contractsGrantsInvoiceDocument.getInvoiceDetails()) {
KualiDecimal total = getSumOfExpendituresOfCategory(invoiceDetailAccountObjectCodeMap.get(invoiceDetail.getCategoryCode()));
// To set expenditures to zero if its blank - to avoid exceptions.
if (ObjectUtils.isNull(invoiceDetail.getInvoiceAmount())) {
invoiceDetail.setInvoiceAmount(KualiDecimal.ZERO);
}
if (invoiceDetail.getInvoiceAmount().compareTo(total) != 0) {
recalculateObjectCodeByCategory(contractsGrantsInvoiceDocument, invoiceDetail, total, invoiceDetailAccountObjectCodeMap.get(invoiceDetail.getCategoryCode()));
isExpenditureValueChanged = true;
}
}
return isExpenditureValueChanged;
}
use of org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode 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.module.ar.businessobject.InvoiceDetailAccountObjectCode 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.module.ar.businessobject.InvoiceDetailAccountObjectCode in project cu-kfs by CU-CommunityApps.
the class ContractsGrantsInvoiceCreateDocumentServiceImpl method updateCategoryActualAmountsByBalance.
/**
* Updates the appropriate amounts for the InvoiceDetailAccountObjectCode matching the given balance
*
* @param document the CINV document we're generating
* @param balance the balance to update amounts by
* @param award the award on the CINV document we're generating
* @param invoiceDetailAccountObjectCodes the List of invoiceDetailObjectCodes to update one of
* @param firstFiscalPeriod whether we're generating the CINV document in the fiscal fiscal period
* or not
*/
protected void updateCategoryActualAmountsByBalance(ContractsGrantsInvoiceDocument document, Balance balance, ContractsAndGrantsBillingAward award, List<InvoiceDetailAccountObjectCode> invoiceDetailAccountObjectCodes, boolean firstFiscalPeriod) {
final CostCategory category = getCostCategoryService().getCostCategoryForObjectCode(balance.getUniversityFiscalYear(), balance.getChartOfAccountsCode(), balance.getObjectCode());
if (!ObjectUtils.isNull(category)) {
final InvoiceDetailAccountObjectCode invoiceDetailAccountObjectCode = getInvoiceDetailAccountObjectCodeByBalanceAndCategory(invoiceDetailAccountObjectCodes, balance, document.getDocumentNumber(), document.getInvoiceGeneralDetail().getProposalNumber(), category);
if (ArConstants.BillingFrequencyValues.isTimeBased(document.getInvoiceGeneralDetail())) {
if (firstFiscalPeriod) {
invoiceDetailAccountObjectCode.setCumulativeExpenditures(cleanAmount(invoiceDetailAccountObjectCode.getCumulativeExpenditures()).add(cleanAmount(balance.getContractsGrantsBeginningBalanceAmount())).add(cleanAmount(balance.getAccountLineAnnualBalanceAmount())));
if (!includePeriod13InPeriod01Calculations()) {
invoiceDetailAccountObjectCode.setCumulativeExpenditures(cleanAmount(invoiceDetailAccountObjectCode.getCumulativeExpenditures()).subtract(cleanAmount(balance.getMonth13Amount())));
}
} else {
invoiceDetailAccountObjectCode.setCumulativeExpenditures(cleanAmount(invoiceDetailAccountObjectCode.getCumulativeExpenditures()).add(calculateBalanceAmountWithoutLastBilledPeriod(document.getInvoiceGeneralDetail().getLastBilledDate(), balance)));
}
} else {
// For other billing frequencies
cleanAmount(balance.getContractsGrantsBeginningBalanceAmount()).add(cleanAmount(balance.getAccountLineAnnualBalanceAmount()));
invoiceDetailAccountObjectCode.setCumulativeExpenditures(cleanAmount(invoiceDetailAccountObjectCode.getCumulativeExpenditures()).add(cleanAmount(balance.getContractsGrantsBeginningBalanceAmount()).add(cleanAmount(balance.getAccountLineAnnualBalanceAmount()))));
}
}
}
use of org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode in project cu-kfs by CU-CommunityApps.
the class ContractsGrantsInvoiceCreateDocumentServiceImpl method generateValuesForCategories.
/**
* 1. This method is responsible to populate categories column for the ContractsGrantsInvoice Document. 2. The
* categories are retrieved from the Maintenance document as a collection and then a logic with conditions to
* handle ranges of Object Codes. 3. Once the object codes are retrieved and categories are set the
* performAccountingCalculations method of InvoiceDetail BO will do all the accounting calculations.
*
* @param documentNumber the number of the document we want to add invoice details to
* @param invoiceDetailAccountObjectCodes the List of InvoiceDetailAccountObjectCodes containing amounts to
* sum into our invoice details
* @param budgetAmountsByCostCategory the budget amounts, sorted by cost category
* @param awardAccountObjectCodeTotalBilleds the business objects containing what has been billed from the
* document's award accounts already
*/
public List<ContractsGrantsInvoiceDetail> generateValuesForCategories(String documentNumber, List<InvoiceDetailAccountObjectCode> invoiceDetailAccountObjectCodes, Map<String, KualiDecimal> budgetAmountsByCostCategory, List<AwardAccountObjectCodeTotalBilled> awardAccountObjectCodeTotalBilleds) {
Collection<CostCategory> costCategories = retrieveAllBillingCategories();
List<ContractsGrantsInvoiceDetail> invoiceDetails = new ArrayList<>();
Map<String, List<InvoiceDetailAccountObjectCode>> invoiceDetailAccountObjectCodesMap = mapInvoiceDetailAccountObjectCodesByCategoryCode(invoiceDetailAccountObjectCodes);
Map<String, List<AwardAccountObjectCodeTotalBilled>> billedsMap = mapAwardAccountObjectCodeTotalBilledsByCategoryCode(awardAccountObjectCodeTotalBilleds);
for (CostCategory category : costCategories) {
ContractsGrantsInvoiceDetail invDetail = new ContractsGrantsInvoiceDetail();
invDetail.setDocumentNumber(documentNumber);
invDetail.setCategoryCode(category.getCategoryCode());
invDetail.setCostCategory(category);
invDetail.setIndirectCostIndicator(category.isIndirectCostIndicator());
// calculate total billed first
invDetail.setCumulativeExpenditures(KualiDecimal.ZERO);
invDetail.setInvoiceAmount(KualiDecimal.ZERO);
invDetail.setTotalPreviouslyBilled(KualiDecimal.ZERO);
List<InvoiceDetailAccountObjectCode> invoiceDetailAccountObjectCodesForCategory = invoiceDetailAccountObjectCodesMap.get(category.getCategoryCode());
if (!CollectionUtils.isEmpty(invoiceDetailAccountObjectCodesForCategory)) {
for (InvoiceDetailAccountObjectCode invoiceDetailAccountObjectCode : invoiceDetailAccountObjectCodesForCategory) {
invDetail.setCumulativeExpenditures(invDetail.getCumulativeExpenditures().add(invoiceDetailAccountObjectCode.getCumulativeExpenditures()));
invDetail.setInvoiceAmount(invDetail.getInvoiceAmount().add(invoiceDetailAccountObjectCode.getCurrentExpenditures()));
}
}
List<AwardAccountObjectCodeTotalBilled> billedForCategory = billedsMap.get(category.getCategoryCode());
if (!CollectionUtils.isEmpty(billedForCategory)) {
for (AwardAccountObjectCodeTotalBilled accountObjectCodeTotalBilled : billedForCategory) {
// this adds up all the total billed based on object code into categories; sum for this category.
invDetail.setTotalPreviouslyBilled(invDetail.getTotalPreviouslyBilled().add(accountObjectCodeTotalBilled.getTotalBilled()));
}
}
// calculate the rest using billed to date
if (!ObjectUtils.isNull(budgetAmountsByCostCategory.get(category.getCategoryCode()))) {
invDetail.setTotalBudget(budgetAmountsByCostCategory.get(category.getCategoryCode()));
} else {
invDetail.setTotalBudget(KualiDecimal.ZERO);
}
invoiceDetails.add(invDetail);
}
return invoiceDetails;
}
Aggregations