use of org.kuali.rice.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class CuPurapGeneralLedgerServiceImpl method reencumberEncumbrance.
@Override
protected List<SourceAccountingLine> reencumberEncumbrance(PaymentRequestDocument preq) {
LOG.debug("reencumberEncumbrance() started");
PurchaseOrderDocument po = purchaseOrderService.getCurrentPurchaseOrder(preq.getPurchaseOrderIdentifier());
Map encumbranceAccountMap = new HashMap();
// Get each item one by one
for (Iterator items = preq.getItems().iterator(); items.hasNext(); ) {
PaymentRequestItem payRequestItem = (PaymentRequestItem) items.next();
PurchaseOrderItem poItem = getPoItem(po, payRequestItem.getItemLineNumber(), payRequestItem.getItemType());
// Amount to reencumber for this item
KualiDecimal itemReEncumber = null;
String logItmNbr = "Item # " + payRequestItem.getItemLineNumber();
if (LOG.isDebugEnabled()) {
LOG.debug("reencumberEncumbrance() " + logItmNbr);
}
// If there isn't a PO item or the total amount is 0, we don't need encumbrances
final KualiDecimal preqItemTotalAmount = (payRequestItem.getTotalAmount() == null) ? KualiDecimal.ZERO : payRequestItem.getTotalAmount();
if ((poItem == null) || (preqItemTotalAmount.doubleValue() == 0)) {
if (poItem != null) {
// KFSUPGRADE-893 recumber $0 item too
if (poItem.getItemType().isQuantityBasedGeneralLedgerIndicator()) {
if (LOG.isDebugEnabled()) {
LOG.debug("reencumberEncumbrance() " + logItmNbr + " Calculate encumbrance based on quantity");
}
// Do disencumbrance calculations based on quantity
KualiDecimal preqQuantity = payRequestItem.getItemQuantity() == null ? ZERO : payRequestItem.getItemQuantity();
KualiDecimal outstandingEncumberedQuantity = poItem.getItemOutstandingEncumberedQuantity() == null ? ZERO : poItem.getItemOutstandingEncumberedQuantity();
KualiDecimal invoicedTotal = poItem.getItemInvoicedTotalQuantity() == null ? ZERO : poItem.getItemInvoicedTotalQuantity();
poItem.setItemInvoicedTotalQuantity(invoicedTotal.subtract(preqQuantity));
poItem.setItemOutstandingEncumberedQuantity(outstandingEncumberedQuantity.add(preqQuantity));
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("reencumberEncumbrance() " + logItmNbr + " No encumbrances required");
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("reencumberEncumbrance() " + logItmNbr + " Calculate encumbrance GL entries");
}
// Do we calculate the encumbrance amount based on quantity or amount?
if (poItem.getItemType().isQuantityBasedGeneralLedgerIndicator()) {
if (LOG.isDebugEnabled()) {
LOG.debug("reencumberEncumbrance() " + logItmNbr + " Calculate encumbrance based on quantity");
}
// Do disencumbrance calculations based on quantity
KualiDecimal preqQuantity = payRequestItem.getItemQuantity() == null ? ZERO : payRequestItem.getItemQuantity();
KualiDecimal outstandingEncumberedQuantity = poItem.getItemOutstandingEncumberedQuantity() == null ? ZERO : poItem.getItemOutstandingEncumberedQuantity();
KualiDecimal invoicedTotal = poItem.getItemInvoicedTotalQuantity() == null ? ZERO : poItem.getItemInvoicedTotalQuantity();
poItem.setItemInvoicedTotalQuantity(invoicedTotal.subtract(preqQuantity));
poItem.setItemOutstandingEncumberedQuantity(outstandingEncumberedQuantity.add(preqQuantity));
// do math as big decimal as doing it as a KualiDecimal will cause the item price to round to 2 digits
itemReEncumber = new KualiDecimal(preqQuantity.bigDecimalValue().multiply(poItem.getItemUnitPrice()));
// add tax for encumbrance
KualiDecimal itemTaxAmount = poItem.getItemTaxAmount() == null ? ZERO : poItem.getItemTaxAmount();
KualiDecimal encumbranceTaxAmount = preqQuantity.divide(poItem.getItemQuantity()).multiply(itemTaxAmount);
itemReEncumber = itemReEncumber.add(encumbranceTaxAmount);
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("reencumberEncumbrance() " + logItmNbr + " Calculate encumbrance based on amount");
}
itemReEncumber = preqItemTotalAmount;
// this prevents negative encumbrance
if ((poItem.getTotalAmount() != null) && (poItem.getTotalAmount().bigDecimalValue().signum() < 0)) {
// po item extended cost is negative
if ((poItem.getTotalAmount().compareTo(itemReEncumber)) > 0) {
itemReEncumber = poItem.getTotalAmount();
}
} else if ((poItem.getTotalAmount() != null) && (poItem.getTotalAmount().bigDecimalValue().signum() >= 0)) {
// po item extended cost is positive
if ((poItem.getTotalAmount().compareTo(itemReEncumber)) < 0) {
itemReEncumber = poItem.getTotalAmount();
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("reencumberEncumbrance() " + logItmNbr + " Amount to reencumber: " + itemReEncumber);
}
KualiDecimal outstandingEncumberedAmount = poItem.getItemOutstandingEncumberedAmount() == null ? ZERO : poItem.getItemOutstandingEncumberedAmount();
if (LOG.isDebugEnabled()) {
LOG.debug("reencumberEncumbrance() " + logItmNbr + " PO Item Outstanding Encumbrance Amount set to: " + outstandingEncumberedAmount);
}
KualiDecimal newOutstandingEncumberedAmount = outstandingEncumberedAmount.add(itemReEncumber);
if (LOG.isDebugEnabled()) {
LOG.debug("reencumberEncumbrance() " + logItmNbr + " New PO Item Outstanding Encumbrance Amount to set: " + newOutstandingEncumberedAmount);
}
poItem.setItemOutstandingEncumberedAmount(newOutstandingEncumberedAmount);
KualiDecimal invoicedTotalAmount = poItem.getItemInvoicedTotalAmount() == null ? ZERO : poItem.getItemInvoicedTotalAmount();
if (LOG.isDebugEnabled()) {
LOG.debug("reencumberEncumbrance() " + logItmNbr + " PO Item Invoiced Total Amount set to: " + invoicedTotalAmount);
}
KualiDecimal newInvoicedTotalAmount = invoicedTotalAmount.subtract(preqItemTotalAmount);
if (LOG.isDebugEnabled()) {
LOG.debug("reencumberEncumbrance() " + logItmNbr + " New PO Item Invoiced Total Amount to set: " + newInvoicedTotalAmount);
}
poItem.setItemInvoicedTotalAmount(newInvoicedTotalAmount);
// make the list of accounts for the reencumbrance entry
PurchaseOrderAccount lastAccount = null;
KualiDecimal accountTotal = ZERO;
// Sort accounts
Collections.sort((List) poItem.getSourceAccountingLines());
for (Iterator accountIter = poItem.getSourceAccountingLines().iterator(); accountIter.hasNext(); ) {
PurchaseOrderAccount account = (PurchaseOrderAccount) accountIter.next();
if (!account.isEmpty()) {
SourceAccountingLine acctString = account.generateSourceAccountingLine();
// amount = item reencumber * account percent / 100
KualiDecimal reencumbranceAmount = itemReEncumber.multiply(new KualiDecimal(account.getAccountLinePercent().toString())).divide(HUNDRED);
account.setItemAccountOutstandingEncumbranceAmount(account.getItemAccountOutstandingEncumbranceAmount().add(reencumbranceAmount));
// For rounding check at the end
accountTotal = accountTotal.add(reencumbranceAmount);
lastAccount = account;
if (LOG.isDebugEnabled()) {
LOG.debug("reencumberEncumbrance() " + logItmNbr + " " + acctString + " = " + reencumbranceAmount);
}
if (encumbranceAccountMap.containsKey(acctString)) {
KualiDecimal currentAmount = (KualiDecimal) encumbranceAccountMap.get(acctString);
encumbranceAccountMap.put(acctString, reencumbranceAmount.add(currentAmount));
} else {
encumbranceAccountMap.put(acctString, reencumbranceAmount);
}
}
}
// account for rounding by adjusting last account as needed
if (lastAccount != null) {
KualiDecimal difference = itemReEncumber.subtract(accountTotal);
if (LOG.isDebugEnabled()) {
LOG.debug("reencumberEncumbrance() difference: " + logItmNbr + " " + difference);
}
SourceAccountingLine acctString = lastAccount.generateSourceAccountingLine();
KualiDecimal amount = (KualiDecimal) encumbranceAccountMap.get(acctString);
if (amount == null) {
encumbranceAccountMap.put(acctString, difference);
} else {
encumbranceAccountMap.put(acctString, amount.add(difference));
}
lastAccount.setItemAccountOutstandingEncumbranceAmount(lastAccount.getItemAccountOutstandingEncumbranceAmount().add(difference));
}
}
}
SpringContext.getBean(BusinessObjectService.class).save(po);
List<SourceAccountingLine> encumbranceAccounts = new ArrayList<SourceAccountingLine>();
for (Iterator<SourceAccountingLine> iter = encumbranceAccountMap.keySet().iterator(); iter.hasNext(); ) {
SourceAccountingLine acctString = iter.next();
KualiDecimal amount = (KualiDecimal) encumbranceAccountMap.get(acctString);
if (amount.doubleValue() != 0) {
acctString.setAmount(amount);
encumbranceAccounts.add(acctString);
}
}
return encumbranceAccounts;
}
use of org.kuali.rice.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class CuPurapGeneralLedgerServiceImpl method generateEntriesPaymentRequest.
protected boolean generateEntriesPaymentRequest(PaymentRequestDocument preq, List encumbrances, List summaryAccounts, String processType) {
LOG.debug("generateEntriesPaymentRequest() started");
boolean success = true;
preq.setGeneralLedgerPendingEntries(new ArrayList());
/*
* Can't let generalLedgerPendingEntryService just create all the entries because we need the sequenceHelper to carry over
* from the encumbrances to the actuals and also because we need to tell the PaymentRequestDocumentRule customize entry
* method how to customize differently based on if creating an encumbrance or actual.
*/
GeneralLedgerPendingEntrySequenceHelper sequenceHelper = new GeneralLedgerPendingEntrySequenceHelper(getNextAvailableSequence(preq.getDocumentNumber()));
// when cancelling a PREQ, do not book encumbrances if PO is CLOSED
if (encumbrances != null && !(CANCEL_PAYMENT_REQUEST.equals(processType) && PurapConstants.PurchaseOrderStatuses.APPDOC_CLOSED.equals(preq.getPurchaseOrderDocument().getApplicationDocumentStatus()))) {
LOG.debug("generateEntriesPaymentRequest() generate encumbrance entries");
if (CREATE_PAYMENT_REQUEST.equals(processType)) {
// on create, use CREDIT code for encumbrances
preq.setDebitCreditCodeForGLEntries(GL_CREDIT_CODE);
} else if (CANCEL_PAYMENT_REQUEST.equals(processType)) {
// on cancel, use DEBIT code
preq.setDebitCreditCodeForGLEntries(GL_DEBIT_CODE);
} else if (MODIFY_PAYMENT_REQUEST.equals(processType)) {
// no encumbrances for modify
}
preq.setGenerateEncumbranceEntries(true);
for (Iterator iter = encumbrances.iterator(); iter.hasNext(); ) {
AccountingLine accountingLine = (AccountingLine) iter.next();
preq.generateGeneralLedgerPendingEntries(accountingLine, sequenceHelper);
// increment for the next line
sequenceHelper.increment();
}
}
if (ObjectUtils.isNotNull(summaryAccounts) && !summaryAccounts.isEmpty()) {
LOG.debug("generateEntriesPaymentRequest() now book the actuals");
preq.setGenerateEncumbranceEntries(false);
if (CREATE_PAYMENT_REQUEST.equals(processType) || MODIFY_PAYMENT_REQUEST.equals(processType)) {
// on create and modify, use DEBIT code
preq.setDebitCreditCodeForGLEntries(GL_DEBIT_CODE);
} else if (CANCEL_PAYMENT_REQUEST.equals(processType)) {
// on cancel, use CREDIT code
preq.setDebitCreditCodeForGLEntries(GL_CREDIT_CODE);
}
for (Iterator iter = summaryAccounts.iterator(); iter.hasNext(); ) {
SummaryAccount summaryAccount = (SummaryAccount) iter.next();
preq.generateGeneralLedgerPendingEntries(summaryAccount.getAccount(), sequenceHelper);
// increment for the next line
sequenceHelper.increment();
}
// generate offset accounts for use tax if it exists (useTaxContainers will be empty if not a use tax document)
List<UseTaxContainer> useTaxContainers = SpringContext.getBean(PurapAccountingService.class).generateUseTaxAccount(preq);
for (UseTaxContainer useTaxContainer : useTaxContainers) {
PurApItemUseTax offset = useTaxContainer.getUseTax();
List<SourceAccountingLine> accounts = useTaxContainer.getAccounts();
for (SourceAccountingLine sourceAccountingLine : accounts) {
preq.generateGeneralLedgerPendingEntries(sourceAccountingLine, sequenceHelper, useTaxContainer.getUseTax());
// increment for the next line
sequenceHelper.increment();
}
}
// Manually save preq summary accounts
if (MODIFY_PAYMENT_REQUEST.equals(processType)) {
// for modify, regenerate the summary from the doc
List<SummaryAccount> summaryAccountsForModify = SpringContext.getBean(PurapAccountingService.class).generateSummaryAccountsWithNoZeroTotalsNoUseTax(preq);
saveAccountsPayableSummaryAccounts(summaryAccountsForModify, preq.getPurapDocumentIdentifier(), PurapDocTypeCodes.PAYMENT_REQUEST_DOCUMENT);
} else {
// for create and cancel, use the summary accounts
saveAccountsPayableSummaryAccounts(summaryAccounts, preq.getPurapDocumentIdentifier(), PurapDocTypeCodes.PAYMENT_REQUEST_DOCUMENT);
}
// manually save cm account change tables (CAMS needs this)
if (CREATE_PAYMENT_REQUEST.equals(processType) || MODIFY_PAYMENT_REQUEST.equals(processType)) {
SpringContext.getBean(PurapAccountRevisionService.class).savePaymentRequestAccountRevisions(preq.getItems(), preq.getPostingYearFromPendingGLEntries(), preq.getPostingPeriodCodeFromPendingGLEntries());
} else if (CANCEL_PAYMENT_REQUEST.equals(processType)) {
SpringContext.getBean(PurapAccountRevisionService.class).cancelPaymentRequestAccountRevisions(preq.getItems(), preq.getPostingYearFromPendingGLEntries(), preq.getPostingPeriodCodeFromPendingGLEntries());
}
// we would only want to do this when booking the actuals (not the encumbrances)
if (preq.getGeneralLedgerPendingEntries() == null || preq.getGeneralLedgerPendingEntries().size() < 2) {
LOG.warn("No gl entries for accounting lines.");
} else {
// upon create, build the entries normally
if (CREATE_PAYMENT_REQUEST.equals(processType)) {
getPaymentMethodGeneralLedgerPendingEntryService().generatePaymentMethodSpecificDocumentGeneralLedgerPendingEntries(preq, ((CuPaymentRequestDocument) preq).getPaymentMethodCode(), preq.getBankCode(), KRADConstants.DOCUMENT_PROPERTY_NAME + "." + "bankCode", preq.getGeneralLedgerPendingEntry(0), false, false, sequenceHelper);
} else if (MODIFY_PAYMENT_REQUEST.equals(processType)) {
// upon modify, we need to calculate the deltas here and pass them in so the appropriate adjustments are created
KualiDecimal bankOffsetAmount = KualiDecimal.ZERO;
Map<String, KualiDecimal> changesByChart = new HashMap<String, KualiDecimal>();
if (ObjectUtils.isNotNull(summaryAccounts) && !summaryAccounts.isEmpty()) {
for (SummaryAccount a : (List<SummaryAccount>) summaryAccounts) {
bankOffsetAmount = bankOffsetAmount.add(a.getAccount().getAmount());
if (changesByChart.get(a.getAccount().getChartOfAccountsCode()) == null) {
changesByChart.put(a.getAccount().getChartOfAccountsCode(), a.getAccount().getAmount());
} else {
changesByChart.put(a.getAccount().getChartOfAccountsCode(), changesByChart.get(a.getAccount().getChartOfAccountsCode()).add(a.getAccount().getAmount()));
}
}
}
getPaymentMethodGeneralLedgerPendingEntryService().generatePaymentMethodSpecificDocumentGeneralLedgerPendingEntries(preq, ((CuPaymentRequestDocument) preq).getPaymentMethodCode(), preq.getBankCode(), KRADConstants.DOCUMENT_PROPERTY_NAME + "." + "bankCode", preq.getGeneralLedgerPendingEntry(0), true, false, sequenceHelper, bankOffsetAmount, changesByChart);
}
}
preq.generateDocumentGeneralLedgerPendingEntries(sequenceHelper);
// END MOD
}
// Manually save GL entries for Payment Request and encumbrances
saveGLEntries(preq.getGeneralLedgerPendingEntries());
return success;
}
use of org.kuali.rice.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class BalanceInquiryLookupAction method getSelectedObjectIds.
/**
* put all enties into select object map. This implmentation only deals with the money amount objects.
*
* @param multipleValueLookupForm the given struts form
* @param resultTable the given result table that holds all data being presented
* @return the map containing all entries available for selection
* <p>
* KRAD Conversion: Performs customization of the results. Prepares
* <p>
* There is no use of data dictionary for fields.
*/
private Map<String, String> getSelectedObjectIds(MultipleValueLookupForm multipleValueLookupForm, List<ResultRow> resultTable) {
String businessObjectClassName = multipleValueLookupForm.getBusinessObjectClassName();
SegmentedBusinessObject segmentedBusinessObject;
try {
segmentedBusinessObject = (SegmentedBusinessObject) Class.forName(multipleValueLookupForm.getBusinessObjectClassName()).newInstance();
} catch (Exception e) {
throw new RuntimeException("Fail to create an object of " + businessObjectClassName + e);
}
Map<String, String> selectedObjectIds = new HashMap<String, String>();
Collection<String> segmentedPropertyNames = segmentedBusinessObject.getSegmentedPropertyNames();
for (ResultRow row : resultTable) {
for (Column column : row.getColumns()) {
String propertyName = column.getPropertyName();
if (segmentedPropertyNames.contains(propertyName)) {
String propertyValue = StringUtils.replace(column.getPropertyValue(), ",", "");
// If there is a negative value, we need to convert it from (##.##) to -##.##
if (StringUtils.contains(propertyValue, "(")) {
propertyValue = StringUtils.replace(propertyValue, "(", "-");
propertyValue = StringUtils.replace(propertyValue, ")", "");
}
KualiDecimal amount = new KualiDecimal(propertyValue);
if (amount.isNonZero()) {
String objectId = row.getObjectId() + "." + propertyName + "." + KRADUtils.convertDecimalIntoInteger(amount);
selectedObjectIds.put(objectId, objectId);
}
}
}
}
return selectedObjectIds;
}
use of org.kuali.rice.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class GlLineServiceImpl method createNewCapitalAsset.
/**
* helper method to add accounting details for this new capital asset record
*
* @param capitalAccountingLines
* @param currentCapitalAssetInformation
* @param documentNumber
* @param actionType
* @param nextCapitalAssetLineNumnber
*/
protected void createNewCapitalAsset(List<CapitalAccountingLines> capitalAccountingLines, String documentNumber, String actionType, Integer nextCapitalAssetLineNumber) {
CapitalAssetInformation capitalAsset = new CapitalAssetInformation();
capitalAsset.setCapitalAssetLineAmount(KualiDecimal.ZERO);
capitalAsset.setDocumentNumber(documentNumber);
capitalAsset.setCapitalAssetLineNumber(nextCapitalAssetLineNumber);
capitalAsset.setCapitalAssetActionIndicator(actionType);
capitalAsset.setCapitalAssetProcessedIndicator(false);
KualiDecimal capitalAssetLineAmount = KualiDecimal.ZERO;
// now setup the account line information associated with this capital asset
for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) {
capitalAsset.setDistributionAmountCode(capitalAccountingLine.getDistributionAmountCode());
createCapitalAssetAccountingLinesDetails(capitalAccountingLine, capitalAsset);
capitalAssetLineAmount = capitalAssetLineAmount.add(capitalAccountingLine.getAmount());
}
capitalAsset.setCapitalAssetLineAmount(capitalAssetLineAmount);
businessObjectService.save(capitalAsset);
}
use of org.kuali.rice.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class GlLineServiceImpl method getAccountingLineAmountForPaymentDetail.
/**
* @param entry GL entry
* @param accountingLine accounting line in the capital asset
* @return accountingLineAmount
*/
protected KualiDecimal getAccountingLineAmountForPaymentDetail(GeneralLedgerEntry entry, CapitalAssetAccountsGroupDetails accountingLine) {
KualiDecimal accountLineAmount = accountingLine.getAmount();
List<String> expenseObjectTypes = objectTypeService.getExpenseAndTransferObjectTypesForPayments();
List<String> incomeObjectTypes = objectTypeService.getIncomeAndTransferObjectTypesForPayments();
// KFSUPGRADE-931 : contribution code
if (isDocumentAnErrorCorrection(entry) || StringUtils.equals(KFSConstants.FinancialDocumentTypeCodes.GENERAL_ERROR_CORRECTION, entry.getFinancialDocumentTypeCode())) {
if (KFSConstants.SOURCE_ACCT_LINE_TYPE_CODE.equals(accountingLine.getFinancialDocumentLineTypeCode())) {
return accountLineAmount.negated();
}
return accountLineAmount;
}
if (expenseObjectTypes.contains(entry.getFinancialObjectTypeCode()) && KFSConstants.SOURCE_ACCT_LINE_TYPE_CODE.equals(accountingLine.getFinancialDocumentLineTypeCode()) && KFSConstants.GL_CREDIT_CODE.equals(entry.getTransactionDebitCreditCode()) && accountLineAmount.compareTo(KualiDecimal.ZERO) > 0) {
return accountLineAmount.negated();
}
if (incomeObjectTypes.contains(entry.getFinancialObjectTypeCode()) && accountLineAmount.compareTo(KualiDecimal.ZERO) > 0) {
return accountLineAmount.negated();
}
return accountLineAmount;
}
Aggregations