use of com.axelor.apps.hr.db.KilometricAllowanceRate in project axelor-open-suite by axelor.
the class KilometricService method computeKilometricExpense.
public BigDecimal computeKilometricExpense(ExpenseLine expenseLine, Employee employee) throws AxelorException {
BigDecimal distance = expenseLine.getDistance();
EmploymentContract mainEmploymentContract = employee.getMainEmploymentContract();
if (mainEmploymentContract == null || mainEmploymentContract.getPayCompany() == null) {
throw new AxelorException(TraceBackRepository.CATEGORY_CONFIGURATION_ERROR, I18n.get(IExceptionMessage.EMPLOYEE_CONTRACT_OF_EMPLOYMENT), employee.getName());
}
Company company = mainEmploymentContract.getPayCompany();
KilometricLog log = getKilometricLog(employee, expenseLine.getExpenseDate());
BigDecimal previousDistance = log == null ? BigDecimal.ZERO : log.getDistanceTravelled();
KilometricAllowanceRate allowance = expenseLine.getKilometricAllowParam() != null ? Beans.get(KilometricAllowanceRateRepository.class).all().filter("self.kilometricAllowParam.id = :_kilometricAllowParamId " + "and self.hrConfig.id = :_hrConfigId").bind("_kilometricAllowParamId", expenseLine.getKilometricAllowParam().getId()).bind("_hrConfigId", Beans.get(HRConfigService.class).getHRConfig(company).getId()).fetchOne() : null;
if (allowance == null) {
throw new AxelorException(TraceBackRepository.CATEGORY_CONFIGURATION_ERROR, I18n.get(IExceptionMessage.KILOMETRIC_ALLOWANCE_RATE_MISSING), expenseLine.getKilometricAllowParam() != null ? expenseLine.getKilometricAllowParam().getName() : "", company.getName());
}
List<KilometricAllowanceRule> ruleList = new ArrayList<>();
List<KilometricAllowanceRule> allowanceRuleList = allowance.getKilometricAllowanceRuleList();
if (ObjectUtils.notEmpty(allowanceRuleList)) {
for (KilometricAllowanceRule rule : allowanceRuleList) {
if (rule.getMinimumCondition().compareTo(previousDistance.add(distance)) <= 0 && rule.getMaximumCondition().compareTo(previousDistance) >= 0) {
ruleList.add(rule);
}
}
}
if (ruleList.isEmpty()) {
throw new AxelorException(TraceBackRepository.CATEGORY_CONFIGURATION_ERROR, I18n.get(IExceptionMessage.KILOMETRIC_ALLOWANCE_NO_RULE), allowance.getKilometricAllowParam().getName());
}
BigDecimal price = BigDecimal.ZERO;
if (ruleList.size() == 1) {
price = distance.multiply(ruleList.get(0).getRate());
} else {
Collections.sort(ruleList, (object1, object2) -> object1.getMinimumCondition().compareTo(object2.getMinimumCondition()));
for (KilometricAllowanceRule rule : ruleList) {
BigDecimal min = rule.getMinimumCondition().max(previousDistance);
BigDecimal max = rule.getMaximumCondition().min(previousDistance.add(distance));
price = price.add(max.subtract(min).multiply(rule.getRate()));
}
}
return price.setScale(2, RoundingMode.HALF_UP);
}
Aggregations