use of org.kuali.kfs.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class CuUserFavoriteAccountServiceImplTest method validateAccount.
private void validateAccount(String accountType, Class accountClass) {
final FavoriteAccount favoriteAccount = FavoriteAccountFixture.FAVORITE_ACCOUNT_1.createFavoriteAccount();
final GeneralLedgerPendingEntrySourceDetail acct = userFavoriteAccountService.getPopulatedNewAccount(favoriteAccount, accountClass);
Assert.assertNotNull("Account should be populated", acct);
Assert.assertTrue("Account should be " + accountType + " Account", accountClass.isInstance(acct));
Assert.assertEquals("Account Number should be populated", favoriteAccount.getAccountNumber(), acct.getAccountNumber());
Assert.assertEquals("Object Code should be populated", favoriteAccount.getFinancialObjectCode(), acct.getFinancialObjectCode());
if (acct instanceof IWantAccount) {
final KualiDecimal accountLinePercent = ((IWantAccount) acct).getAmountOrPercent();
Assert.assertEquals("Incorrect percentage (comparison against 100% should have been zero)", 0, accountLinePercent.compareTo(new KualiDecimal(100)));
Assert.assertEquals("Amount-or-Percent indicator should be Percent", CUPurapConstants.PERCENT, ((IWantAccount) acct).getUseAmountOrPercent());
} else {
final BigDecimal accountLinePercent = ((PurApAccountingLineBase) acct).getAccountLinePercent();
Assert.assertEquals("Incorrect percentage (comparison against 100% should have been zero)", 0, accountLinePercent.compareTo(new BigDecimal(100)));
}
}
use of org.kuali.kfs.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class CuLaborPendingEntryGenerator method generateBenefitClearingPendingEntries.
public static List<LaborLedgerPendingEntry> generateBenefitClearingPendingEntries(LaborLedgerPostingDocument document, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, String accountNumber, String chartOfAccountsCode) {
List<LaborLedgerPendingEntry> benefitClearingPendingEntries = new ArrayList<LaborLedgerPendingEntry>();
Map<String, Map<String, KualiDecimal>> sourceLineBenefitAmountSumByObjectCode = new HashMap<String, Map<String, KualiDecimal>>();
List<ExpenseTransferSourceAccountingLine> sourceAccountingLines = document.getSourceAccountingLines();
for (ExpenseTransferSourceAccountingLine accountingLine : sourceAccountingLines) {
updateBenefitAmountSumObject(sourceLineBenefitAmountSumByObjectCode, accountingLine);
}
Map<String, Map<String, KualiDecimal>> targetLineBenefitAmountSumByObjectCode = new HashMap<String, Map<String, KualiDecimal>>();
List<ExpenseTransferTargetAccountingLine> targetAccountingLines = document.getTargetAccountingLines();
for (ExpenseTransferTargetAccountingLine accountingLine : targetAccountingLines) {
updateBenefitAmountSumObject(targetLineBenefitAmountSumByObjectCode, accountingLine);
}
Set<String> benefitTypeCodes = new HashSet<String>();
for (String key : targetLineBenefitAmountSumByObjectCode.keySet()) {
benefitTypeCodes.add(key);
}
for (String key : sourceLineBenefitAmountSumByObjectCode.keySet()) {
benefitTypeCodes.add(key);
}
for (String benefitTypeCode : benefitTypeCodes) {
KualiDecimal targetAmount = KualiDecimal.ZERO;
Map<String, KualiDecimal> targetBenefitSumsByObjectCode = new HashMap<String, KualiDecimal>();
if (targetLineBenefitAmountSumByObjectCode.containsKey(benefitTypeCode)) {
targetBenefitSumsByObjectCode = targetLineBenefitAmountSumByObjectCode.get(benefitTypeCode);
for (String objCode : targetBenefitSumsByObjectCode.keySet()) {
if (targetBenefitSumsByObjectCode.containsKey(objCode)) {
targetAmount = targetAmount.add(targetBenefitSumsByObjectCode.get(objCode));
}
}
}
KualiDecimal sourceAmount = KualiDecimal.ZERO;
Map<String, KualiDecimal> sourceBenefitSumsByObjectCode = new HashMap<String, KualiDecimal>();
if (sourceLineBenefitAmountSumByObjectCode.containsKey(benefitTypeCode)) {
sourceBenefitSumsByObjectCode = sourceLineBenefitAmountSumByObjectCode.get(benefitTypeCode);
for (String objCode : sourceBenefitSumsByObjectCode.keySet()) {
if (sourceBenefitSumsByObjectCode.containsKey(objCode)) {
sourceAmount = sourceAmount.add(sourceBenefitSumsByObjectCode.get(objCode));
}
}
}
KualiDecimal clearingAmount = sourceAmount.subtract(targetAmount);
KualiDecimal amountForObjectCode = KualiDecimal.ZERO;
if (clearingAmount.isNonZero() && ObjectUtils.isNotNull(benefitTypeCode)) {
for (String objCode : sourceBenefitSumsByObjectCode.keySet()) {
amountForObjectCode = sourceBenefitSumsByObjectCode.get(objCode);
benefitClearingPendingEntries.add(((CuLaborPendingEntryConverterServiceImpl) SpringContext.getBean(LaborPendingEntryConverterService.class)).getBenefitClearingPendingEntry(document, sequenceHelper, accountNumber, chartOfAccountsCode, benefitTypeCode, amountForObjectCode, objCode));
}
for (String objCode : targetBenefitSumsByObjectCode.keySet()) {
amountForObjectCode = targetBenefitSumsByObjectCode.get(objCode);
benefitClearingPendingEntries.add(((CuLaborPendingEntryConverterServiceImpl) SpringContext.getBean(LaborPendingEntryConverterService.class)).getBenefitClearingPendingEntry(document, sequenceHelper, accountNumber, chartOfAccountsCode, benefitTypeCode, amountForObjectCode.negated(), objCode));
}
}
}
// refresh nonupdateable references for financial object...
LaborPendingEntryGenerator.refreshObjectCodeNonUpdateableReferences(benefitClearingPendingEntries);
return benefitClearingPendingEntries;
}
use of org.kuali.kfs.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class CuLaborPendingEntryGenerator method updateBenefitAmountSumObject.
protected static void updateBenefitAmountSumObject(Map<String, Map<String, KualiDecimal>> benefitAmountSumByBenefitType, ExpenseTransferAccountingLine accountingLine) {
accountingLine.refreshReferenceObject(KFSPropertyConstants.LABOR_OBJECT);
if (ObjectUtils.isNull(accountingLine.getLaborObject())) {
return;
}
String fringeOrSalaryCode = accountingLine.getLaborObject().getFinancialObjectFringeOrSalaryCode();
if (!LaborConstants.SalaryExpenseTransfer.LABOR_LEDGER_SALARY_CODE.equals(fringeOrSalaryCode)) {
return;
}
Integer payrollFiscalyear = accountingLine.getPayrollEndDateFiscalYear();
String chartOfAccountsCode = accountingLine.getChartOfAccountsCode();
String objectCode = accountingLine.getFinancialObjectCode();
String fringeBenefitObjectCode = retrieveFringeBenefitObjectCode(accountingLine, chartOfAccountsCode);
Collection<PositionObjectBenefit> positionObjectBenefits = SpringContext.getBean(LaborPositionObjectBenefitService.class).getPositionObjectBenefits(payrollFiscalyear, chartOfAccountsCode, objectCode);
for (PositionObjectBenefit positionObjectBenefit : positionObjectBenefits) {
String tmpLaborBenefitRateCategoryCode = accountingLine.getAccount().getLaborBenefitRateCategoryCode();
positionObjectBenefit.setLaborBenefitRateCategoryCode(tmpLaborBenefitRateCategoryCode);
String benefitTypeCode = positionObjectBenefit.getBenefitsCalculation().getPositionBenefitTypeCode();
Map<String, KualiDecimal> benefitSumsByObjectCode = new HashMap<String, KualiDecimal>();
KualiDecimal benefitAmount = SpringContext.getBean(LaborBenefitsCalculationService.class).calculateFringeBenefit(positionObjectBenefit, accountingLine.getAmount(), accountingLine.getAccountNumber(), accountingLine.getSubAccountNumber());
if (benefitAmountSumByBenefitType.containsKey(benefitTypeCode)) {
benefitSumsByObjectCode = benefitAmountSumByBenefitType.get(benefitTypeCode);
if (benefitSumsByObjectCode.containsKey(fringeBenefitObjectCode)) {
benefitAmount = benefitAmount.add(benefitSumsByObjectCode.get(fringeBenefitObjectCode));
}
benefitSumsByObjectCode.put(fringeBenefitObjectCode, benefitAmount);
} else {
benefitSumsByObjectCode.put(fringeBenefitObjectCode, benefitAmount);
benefitAmountSumByBenefitType.put(benefitTypeCode, benefitSumsByObjectCode);
}
benefitAmountSumByBenefitType.put(benefitTypeCode, benefitSumsByObjectCode);
}
}
use of org.kuali.kfs.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class CuLaborPendingEntryGenerator method generateBenefitPendingEntries.
public static List<LaborLedgerPendingEntry> generateBenefitPendingEntries(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
accountingLine.refreshReferenceObject(KFSPropertyConstants.LABOR_OBJECT);
if (ObjectUtils.isNull(accountingLine.getLaborObject())) {
return null;
}
String FringeOrSalaryCode = accountingLine.getLaborObject().getFinancialObjectFringeOrSalaryCode();
if (!LaborConstants.SalaryExpenseTransfer.LABOR_LEDGER_SALARY_CODE.equals(FringeOrSalaryCode)) {
return null;
}
Integer payrollFiscalyear = accountingLine.getPayrollEndDateFiscalYear();
String chartOfAccountsCode = accountingLine.getChartOfAccountsCode();
String objectCode = accountingLine.getFinancialObjectCode();
Collection<PositionObjectBenefit> positionObjectBenefits = SpringContext.getBean(LaborPositionObjectBenefitService.class).getActivePositionObjectBenefits(payrollFiscalyear, chartOfAccountsCode, objectCode);
List<LaborLedgerPendingEntry> benefitPendingEntries = new ArrayList<LaborLedgerPendingEntry>();
for (PositionObjectBenefit positionObjectBenefit : positionObjectBenefits) {
positionObjectBenefit.setLaborBenefitRateCategoryCode(accountingLine.getAccount().getLaborBenefitRateCategoryCode());
String fringeBenefitObjectCode = retrieveFringeBenefitObjectCode(accountingLine, chartOfAccountsCode);
KualiDecimal benefitAmount = SpringContext.getBean(LaborBenefitsCalculationService.class).calculateFringeBenefit(positionObjectBenefit, accountingLine.getAmount(), accountingLine.getAccountNumber(), accountingLine.getSubAccountNumber());
if (benefitAmount.isNonZero() && positionObjectBenefit.getBenefitsCalculation().isActive()) {
ParameterService parameterService = SpringContext.getBean(ParameterService.class);
Boolean enableFringeBenefitCalculationByBenefitRate = parameterService.getParameterValueAsBoolean(KfsParameterConstants.FINANCIAL_SYSTEM_ALL.class, LaborConstants.BenefitCalculation.ENABLE_FRINGE_BENEFIT_CALC_BY_BENEFIT_RATE_CATEGORY_PARAMETER);
// If fringeBenefitObjectCode is empty and its enable to use calculation by benefit rate
if (StringUtils.isEmpty(fringeBenefitObjectCode) && enableFringeBenefitCalculationByBenefitRate) {
String laborBenefitRateCategoryCode = positionObjectBenefit.getLaborBenefitRateCategoryCode();
// Use parameter default if labor benefit rate category code is blank
if (StringUtils.isBlank(laborBenefitRateCategoryCode)) {
laborBenefitRateCategoryCode = parameterService.getParameterValueAsString(Account.class, LaborConstants.BenefitCalculation.DEFAULT_BENEFIT_RATE_CATEGORY_CODE_PARAMETER);
}
// create a map for the search criteria to lookup the fringe benefit percentage
Map<String, Object> fieldValues = new HashMap<String, Object>();
fieldValues.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, positionObjectBenefit.getUniversityFiscalYear());
fieldValues.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, positionObjectBenefit.getChartOfAccountsCode());
fieldValues.put(LaborPropertyConstants.POSITION_BENEFIT_TYPE_CODE, positionObjectBenefit.getFinancialObjectBenefitsTypeCode());
fieldValues.put(LaborPropertyConstants.LABOR_BENEFIT_RATE_CATEGORY_CODE, laborBenefitRateCategoryCode);
BenefitsCalculation bc = (BenefitsCalculation) SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(BenefitsCalculation.class, fieldValues);
fringeBenefitObjectCode = bc.getPositionFringeBenefitObjectCode();
}
List<LaborLedgerPendingEntry> pendingEntries = LaborPendingEntryGenerator.generateBenefitPendingEntries(document, accountingLine, sequenceHelper, benefitAmount, fringeBenefitObjectCode);
benefitPendingEntries.addAll(pendingEntries);
}
}
return benefitPendingEntries;
}
use of org.kuali.kfs.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.
the class CuFileEnterpriseFeederHelperServiceImpl method feedOnFile.
@Override
public void feedOnFile(File doneFile, File dataFile, File reconFile, PrintStream enterpriseFeedPs, String feederProcessName, String reconciliationTableId, EnterpriseFeederStatusAndErrorMessagesWrapper statusAndErrors, LedgerSummaryReport ledgerSummaryReport, ReportWriterService errorStatisticsReport, EnterpriseFeederReportData feederReportData) {
LOG.info("Processing done file: " + doneFile.getAbsolutePath());
List<Message> errorMessages = statusAndErrors.getErrorMessages();
BufferedReader dataFileReader = null;
ReconciliationBlock reconciliationBlock = null;
Reader reconReader = null;
try {
reconReader = new FileReader(reconFile, StandardCharsets.UTF_8);
reconciliationBlock = reconciliationParserService.parseReconciliationBlock(reconReader, reconciliationTableId);
} catch (IOException e) {
LOG.error("IO Error occured trying to read the recon file.", e);
errorMessages.add(new Message("IO Error occured trying to read the recon file.", Message.TYPE_FATAL));
reconciliationBlock = null;
statusAndErrors.setStatus(new FileReconBadLoadAbortedStatus());
throw new RuntimeException(e);
} catch (RuntimeException e) {
LOG.error("Error occured trying to parse the recon file.", e);
errorMessages.add(new Message("Error occured trying to parse the recon file.", Message.TYPE_FATAL));
reconciliationBlock = null;
statusAndErrors.setStatus(new FileReconBadLoadAbortedStatus());
throw e;
} finally {
if (reconReader != null) {
try {
reconReader.close();
} catch (IOException e) {
LOG.error("Error occured trying to close recon file: " + reconFile.getAbsolutePath(), e);
}
}
}
try {
if (reconciliationBlock == null) {
errorMessages.add(new Message("Unable to parse reconciliation file.", Message.TYPE_FATAL));
} else {
dataFileReader = new BufferedReader(new FileReader(dataFile, StandardCharsets.UTF_8));
Iterator<LaborOriginEntry> fileIterator = new LaborOriginEntryFileIterator(dataFileReader, false);
reconciliationService.reconcile(fileIterator, reconciliationBlock, errorMessages);
fileIterator = null;
dataFileReader.close();
dataFileReader = null;
}
if (reconciliationProcessSucceeded(errorMessages)) {
dataFileReader = new BufferedReader(new FileReader(dataFile, StandardCharsets.UTF_8));
String line;
int count = 0;
Collection<String> offsetDocTypes = parameterService.getParameterValuesAsString(LaborEnterpriseFeedStep.class, LaborParameterConstants.LABOR_BENEFIT_OFFSET_DOCTYPE);
offsetDocTypes = offsetDocTypes.stream().map(offsetDocType -> offsetDocType.toUpperCase(Locale.US)).collect(Collectors.toList());
while ((line = dataFileReader.readLine()) != null) {
try {
LaborOriginEntry tempEntry = new LaborOriginEntry();
tempEntry.setFromTextFileForBatch(line, count);
feederReportData.incrementNumberOfRecordsRead();
feederReportData.addToTotalAmountRead(tempEntry.getTransactionLedgerEntryAmount());
enterpriseFeedPs.printf("%s\n", line);
ledgerSummaryReport.summarizeEntry(tempEntry);
feederReportData.incrementNumberOfRecordsWritten();
feederReportData.addToTotalAmountWritten(tempEntry.getTransactionLedgerEntryAmount());
List<LaborOriginEntry> benefitEntries = generateBenefits(tempEntry, errorStatisticsReport, feederReportData);
KualiDecimal benefitTotal = new KualiDecimal(0);
KualiDecimal offsetTotal = new KualiDecimal(0);
for (LaborOriginEntry benefitEntry : benefitEntries) {
benefitEntry.setTransactionLedgerEntryDescription("FRINGE EXPENSE");
enterpriseFeedPs.printf("%s\n", benefitEntry.getLine());
feederReportData.incrementNumberOfRecordsWritten();
feederReportData.addToTotalAmountWritten(benefitEntry.getTransactionLedgerEntryAmount());
if (benefitEntry.getTransactionLedgerEntryAmount().isZero())
continue;
benefitTotal = benefitTotal.add(benefitEntry.getTransactionLedgerEntryAmount());
}
if (tempEntry.getFinancialBalanceTypeCode() == null || tempEntry.getFinancialBalanceTypeCode().equalsIgnoreCase("IE"))
continue;
List<LaborOriginEntry> offsetEntries = generateOffsets(tempEntry, offsetDocTypes);
for (LaborOriginEntry offsetEntry : offsetEntries) {
if (offsetEntry.getTransactionLedgerEntryAmount().isZero())
continue;
enterpriseFeedPs.printf("%s\n", offsetEntry.getLine());
offsetTotal = offsetTotal.add(offsetEntry.getTransactionLedgerEntryAmount());
}
if (!benefitTotal.equals(offsetTotal)) {
LOG.info("** count:offsetTotal: benefitTotal=" + count + ":" + offsetTotal + "" + benefitTotal);
}
} catch (NullPointerException npe) {
LOG.error("NPE encountered");
throw new RuntimeException(npe.toString());
} catch (Exception e) {
throw new IOException(e.toString());
}
count++;
LOG.info("Processed Entry # " + count);
}
dataFileReader.close();
dataFileReader = null;
// LOG.info("TotalBenifits : " + totalBenefitValue);
statusAndErrors.setStatus(new FileReconOkLoadOkStatus());
} else {
statusAndErrors.setStatus(new FileReconBadLoadAbortedStatus());
}
} catch (Exception e) {
LOG.error("Caught exception when reconciling/loading done file: " + doneFile, e);
statusAndErrors.setStatus(new ExceptionCaughtStatus());
errorMessages.add(new Message("Caught exception attempting to reconcile/load done file: " + doneFile + ". File contents are NOT loaded", Message.TYPE_FATAL));
// re-throw the exception rather than returning a value so that Spring will auto-rollback
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else {
// Spring only rolls back when throwing a runtime exception (by default), so we throw a new exception
throw new RuntimeException(e);
}
} finally {
if (dataFileReader != null) {
try {
dataFileReader.close();
} catch (IOException e) {
LOG.error("IO Exception occured trying to close connection to the data file", e);
errorMessages.add(new Message("IO Exception occured trying to close connection to the data file", Message.TYPE_FATAL));
}
}
}
}
Aggregations