Java tutorial
/** * Axelor Business Solutions * * Copyright (C) 2014 Axelor (<http://axelor.com>). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.axelor.apps.organisation.service; import java.math.BigDecimal; import java.util.List; import java.util.Map; import javax.persistence.Query; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import com.axelor.apps.account.service.invoice.InvoiceService; import com.axelor.apps.base.db.Product; import com.axelor.apps.base.db.SpentTime; import com.axelor.apps.base.db.Unit; import com.axelor.apps.base.db.repo.UnitRepository; import com.axelor.apps.base.service.UnitConversionService; import com.axelor.apps.base.service.administration.GeneralService; import com.axelor.apps.organisation.db.Employee; import com.axelor.apps.organisation.db.ITask; import com.axelor.apps.organisation.db.ITaskUpdateLine; import com.axelor.apps.organisation.db.PlanningLine; import com.axelor.apps.organisation.db.Project; import com.axelor.apps.organisation.db.Task; import com.axelor.apps.organisation.db.repo.TaskRepository; import com.axelor.apps.organisation.exceptions.IExceptionMessage; import com.axelor.apps.tool.date.DurationTool; import com.axelor.db.JPA; import com.axelor.exception.AxelorException; import com.axelor.exception.db.IException; import com.axelor.i18n.I18n; import com.google.inject.Inject; import com.google.inject.persist.Transactional; public class TaskService extends TaskRepository { @Inject private UnitConversionService unitConversionService; private LocalDateTime todayTime; @Inject private UnitRepository unitRepo; @Inject public TaskService() { todayTime = GeneralService.getTodayDateTime().toLocalDateTime(); } public void updateFinancialInformation(Task task) throws AxelorException { // Les montants sont figs ds le commencement de la tache if (task.getStatusSelect() < ITask.STATUS_STARTED && task.getRealEstimatedMethodSelect() != ITask.REAL_ESTIMATED_METHOD_NONE) { this.updateInitialEstimatedAmount(task); } this.updateRealEstimedAmount(task); this.updateRealInvoicedAmount(task); } public void checkTaskProject(Task task) throws AxelorException { if (task.getProject() == null) { throw new AxelorException(I18n.get(IExceptionMessage.TASK_1), IException.CONFIGURATION_ERROR); } } public void checkProjectUnit(Project project) throws AxelorException { if (project.getUnit() == null) { throw new AxelorException(IExceptionMessage.TASK_2, IException.CONFIGURATION_ERROR); } } public void checkPlanningLineUnit(PlanningLine planningLine) throws AxelorException { if (planningLine.getUnit() == null) { throw new AxelorException(IExceptionMessage.TASK_3, IException.CONFIGURATION_ERROR); } } public void checkSpentTimeUnit(SpentTime spentTime) throws AxelorException { if (spentTime.getUnit() == null) { throw new AxelorException(IExceptionMessage.TASK_4, IException.CONFIGURATION_ERROR); } } public BigDecimal getSpentTime(Task task) throws AxelorException { if (task.getSpentTimeList() != null && !task.getSpentTimeList().isEmpty()) { this.checkTaskProject(task); this.checkProjectUnit(task.getProject()); return this.getSpentTime(task.getSpentTimeList(), task.getProject().getUnit()); } else { return BigDecimal.ZERO; } } public BigDecimal getPlannedTime(Task task) throws AxelorException { BigDecimal plannedTime = BigDecimal.ZERO; if (task.getPlanningLineList() != null) { this.checkTaskProject(task); this.checkProjectUnit(task.getProject()); return this.getPlannedTime(task.getPlanningLineList(), task.getProject().getUnit()); } return plannedTime; } public BigDecimal getPlannedTime(List<PlanningLine> planningLineList, Unit unit) throws AxelorException { BigDecimal plannedTime = BigDecimal.ZERO; for (PlanningLine planningLine : planningLineList) { this.checkPlanningLineUnit(planningLine); plannedTime = plannedTime .add(unitConversionService.convert(planningLine.getUnit(), unit, planningLine.getDuration())); } return plannedTime; } public BigDecimal getSpentTime(List<SpentTime> spentTimeList, Unit unit) throws AxelorException { BigDecimal spentTimesDuration = BigDecimal.ZERO; for (SpentTime spentTime : spentTimeList) { this.checkSpentTimeUnit(spentTime); spentTimesDuration = spentTimesDuration .add(unitConversionService.convert(spentTime.getUnit(), unit, spentTime.getDuration())); } return spentTimesDuration; } public void updateInitialEstimatedAmount(Task task) throws AxelorException { /** REVENUE **/ Query q = JPA.em().createQuery( "select SUM(sol.companyExTaxTotal) FROM SaleOrderLine as sol WHERE sol.task = ?1 AND sol.saleOrder.statusSelect = 3"); q.setParameter(1, task); BigDecimal saleOrderTurnover = (BigDecimal) q.getSingleResult(); BigDecimal financialInformationUpdateTurnover = this.getFinancialInformationUpdateAmount(task, ITaskUpdateLine.TYPE_REVENUE, ITaskUpdateLine.APPLICATION_INITIAL_ESTIMATED); BigDecimal turnover = BigDecimal.ZERO; if (saleOrderTurnover != null) { turnover = turnover.add(saleOrderTurnover); } if (financialInformationUpdateTurnover != null) { turnover = turnover.add(financialInformationUpdateTurnover); } /** COST **/ q = JPA.em().createQuery( "select SUM(pol.companyExTaxTotal) FROM PurchaseOrderLine as pol WHERE pol.task = ?1 AND pol.purchaseOrder.statusSelect = 3"); q.setParameter(1, task); BigDecimal purchaseOrderCost = (BigDecimal) q.getSingleResult(); BigDecimal saleOrderCost = this.getSaleOrderInitialEstimatedCost(task); BigDecimal financialInformationUpdateCost = this.getFinancialInformationUpdateAmount(task, ITaskUpdateLine.TYPE_COST, ITaskUpdateLine.APPLICATION_INITIAL_ESTIMATED); BigDecimal cost = BigDecimal.ZERO; if (purchaseOrderCost != null) { cost = cost.add(purchaseOrderCost); } if (saleOrderCost != null) { cost = cost.add(saleOrderCost); } if (financialInformationUpdateCost != null) { cost = cost.add(financialInformationUpdateCost); } /** MARGIN **/ BigDecimal margin = BigDecimal.ZERO; if (turnover != null) { margin = margin.add(turnover); } if (cost != null) { margin = margin.subtract(cost); } task.setInitialEstimatedTurnover(turnover); task.setInitialEstimatedCost(cost); task.setInitialEstimatedMargin(margin); } public void updateRealEstimedAmount(Task task) throws AxelorException { /** REVENUE **/ BigDecimal progressTurnover = this.getTaskProgressTurnover(task); BigDecimal financialInformationUpdateTurnover = this.getFinancialInformationUpdateAmount(task, ITaskUpdateLine.TYPE_REVENUE, ITaskUpdateLine.APPLICATION_REAL_ESTIMATED); BigDecimal turnover = BigDecimal.ZERO; if (progressTurnover != null) { turnover = turnover.add(progressTurnover); } if (financialInformationUpdateTurnover != null) { turnover = turnover.add(financialInformationUpdateTurnover); } /** COST **/ Query q = JPA.em().createQuery( "select SUM(pol.companyExTaxTotal) FROM PurchaseOrderLine as pol WHERE pol.task = ?1 AND pol.purchaseOrder.statusSelect = 3 AND pol.product.applicationTypeSelect = 1"); q.setParameter(1, task); BigDecimal purchaseOrderCost = (BigDecimal) q.getSingleResult(); q = JPA.em().createQuery( "select SUM(tl.timesheet.user.employee.dailySalaryCost * tl.duration) FROM TimesheetLine as tl WHERE tl.task = ?1 and tl.timesheet.statusSelect = 3"); q.setParameter(1, task); BigDecimal timesheetLineCost = (BigDecimal) q.getSingleResult(); q = JPA.em().createQuery( "select SUM(el.companyTotal) FROM ExpenseLine as el WHERE el.task = ?1 and el.expense.statusSelect = 4"); q.setParameter(1, task); BigDecimal expenseLineCost = (BigDecimal) q.getSingleResult(); // plannification pas encore chue q = JPA.em().createQuery( "select MAX(tl.date) FROM TimesheetLine as tl WHERE tl.task = ?1 and tl.timesheet.statusSelect = 3"); q.setParameter(1, task); LocalDate timesheetLineMaxDate = (LocalDate) q.getSingleResult(); BigDecimal planningLineCost = this.getPlanningLinesAmount(task, timesheetLineMaxDate); BigDecimal financialInformationUpdateCost = this.getFinancialInformationUpdateAmount(task, ITaskUpdateLine.TYPE_COST, ITaskUpdateLine.APPLICATION_REAL_ESTIMATED); BigDecimal cost = BigDecimal.ZERO; if (purchaseOrderCost != null) { cost = cost.add(purchaseOrderCost); } if (timesheetLineCost != null) { cost = cost.add(timesheetLineCost); } if (expenseLineCost != null) { cost = cost.add(expenseLineCost); } if (planningLineCost != null) { cost = cost.add(planningLineCost); } if (financialInformationUpdateCost != null) { cost = cost.add(financialInformationUpdateCost); } /** MARGIN **/ BigDecimal margin = BigDecimal.ZERO; if (turnover != null) { margin = margin.add(turnover); } if (cost != null) { margin = margin.subtract(cost); } task.setRealEstimatedTurnover(turnover); task.setRealEstimatedCost(cost); task.setRealEstimatedMargin(margin); } public void updateRealInvoicedAmount(Task task) { /** REVENUE **/ Query q = JPA.em().createQuery("select SUM(il.companyExTaxTotal) FROM InvoiceLine as il WHERE il.task = ?1 " + "AND (il.invoice.statusSelect = ?2 OR il.invoice.statusSelect = ?3) AND (il.invoice.operationTypeSelect = ?4 OR il.invoice.operationTypeSelect = ?5)"); q.setParameter(1, task); q.setParameter(2, InvoiceService.STATUS_VALIDATED); q.setParameter(3, InvoiceService.STATUS_VENTILATED); q.setParameter(4, InvoiceService.OPERATION_TYPE_CLIENT_REFUND); q.setParameter(5, InvoiceService.OPERATION_TYPE_CLIENT_SALE); BigDecimal invoiceLineTurnover = (BigDecimal) q.getSingleResult(); BigDecimal financialInformationUpdateTurnover = this.getFinancialInformationUpdateAmount(task, ITaskUpdateLine.TYPE_REVENUE, ITaskUpdateLine.APPLICATION_REAL_INVOICED); BigDecimal turnover = BigDecimal.ZERO; if (invoiceLineTurnover != null) { turnover = turnover.add(invoiceLineTurnover); } if (financialInformationUpdateTurnover != null) { turnover = turnover.add(financialInformationUpdateTurnover); } /** COST **/ q = JPA.em().createQuery("select SUM(il.companyExTaxTotal) FROM InvoiceLine as il WHERE il.task = ?1 " + "AND (il.invoice.statusSelect = ?2 OR il.invoice.statusSelect = ?3) AND (il.invoice.operationTypeSelect = ?4 OR il.invoice.operationTypeSelect = ?5)"); q.setParameter(1, task); q.setParameter(2, InvoiceService.STATUS_VALIDATED); q.setParameter(3, InvoiceService.STATUS_VENTILATED); q.setParameter(4, InvoiceService.OPERATION_TYPE_SUPPLIER_PURCHASE); q.setParameter(5, InvoiceService.OPERATION_TYPE_SUPPLIER_REFUND); BigDecimal supplierInvoiceLineCost = (BigDecimal) q.getSingleResult(); // q = JPA.em().createQuery("select SUM(il.companyCostPrice * il.qty) FROM InvoiceLine as il WHERE il.task = ?1 AND il.invoice.status.code = 'val' AND (il.invoice.operationTypeSelect = 3 OR il.invoice.operationTypeSelect = 4)"); // q.setParameter(1, task); // // BigDecimal customerInvoiceLineCost = (BigDecimal) q.getSingleResult(); q = JPA.em().createQuery( "select SUM(tl.timesheet.user.employee.dailySalaryCost * tl.duration) FROM TimesheetLine as tl WHERE tl.task = ?1 and tl.timesheet.statusSelect = 3"); q.setParameter(1, task); BigDecimal timesheetLineCost = (BigDecimal) q.getSingleResult(); q = JPA.em().createQuery( "select SUM(el.companyTotal) FROM ExpenseLine as el WHERE el.task = ?1 and el.expense.statusSelect = 4"); q.setParameter(1, task); BigDecimal expenseLineCost = (BigDecimal) q.getSingleResult(); BigDecimal financialInformationUpdateCost = this.getFinancialInformationUpdateAmount(task, ITaskUpdateLine.TYPE_COST, ITaskUpdateLine.APPLICATION_REAL_INVOICED); BigDecimal cost = BigDecimal.ZERO; if (supplierInvoiceLineCost != null) { cost = cost.add(supplierInvoiceLineCost); } // if(customerInvoiceLineCost != null) { // cost = cost.add(customerInvoiceLineCost); // } if (timesheetLineCost != null) { cost = cost.add(timesheetLineCost); } if (expenseLineCost != null) { cost = cost.add(expenseLineCost); } if (financialInformationUpdateCost != null) { cost = cost.add(financialInformationUpdateCost); } /** MARGIN **/ BigDecimal margin = BigDecimal.ZERO; if (turnover != null) { margin = margin.add(turnover); } if (cost != null) { margin = margin.subtract(cost); } task.setRealInvoicedTurnover(turnover); task.setRealInvoicedCost(cost); task.setRealInvoicedMargin(margin); } public BigDecimal getSaleOrderInitialEstimatedCost(Task task) throws AxelorException { BigDecimal saleOrderEstimatedCost = BigDecimal.ZERO; if (task.getPlanningLineList() != null && !task.getPlanningLineList().isEmpty()) { saleOrderEstimatedCost = this.getPlanningLinesAmount(task, null); Query q = JPA.em().createQuery( "select SUM(sol.companyCostPrice * sol.qty) FROM SaleOrderLine as sol WHERE sol.task = ?1 AND sol.saleOrder.statusSelect = 3 AND sol.product.applicationTypeSelect = 1"); q.setParameter(1, task); saleOrderEstimatedCost = (BigDecimal) q.getSingleResult(); } else { Query q = JPA.em().createQuery( "select SUM(sol.companyCostPrice * sol.qty) FROM SaleOrderLine as sol WHERE sol.task = ?1 AND sol.saleOrder.statusSelect = 3"); q.setParameter(1, task); saleOrderEstimatedCost = (BigDecimal) q.getSingleResult(); } return saleOrderEstimatedCost; } public BigDecimal getFinancialInformationUpdateAmount(Task task, int typeSelect, int applicationSelect) { Query q = JPA.em().createQuery( "select SUM(fiu.amount) FROM FinancialInformationUpdate as fiu WHERE fiu.task = ?1 AND fiu.typeSelect = ?2 AND fiu.applicationSelect = ?3"); q.setParameter(1, task); q.setParameter(2, typeSelect); q.setParameter(3, applicationSelect); return (BigDecimal) q.getSingleResult(); } public BigDecimal getPlanningLinesAmountNotAccounted(List<Task> taskList) throws AxelorException { BigDecimal planningLineAmount = BigDecimal.ZERO; if (taskList != null) { for (Task task : taskList) { planningLineAmount = planningLineAmount.add(this.getPlanningLinesAmountNotAccounted(task)); } } return planningLineAmount; } public BigDecimal getPlanningLinesAmountNotAccounted(Task task) throws AxelorException { Query q = JPA.em().createQuery( "select MAX(tl.date) FROM TimesheetLine as tl WHERE tl.task = ?1 and tl.timesheet.statusSelect = 3"); q.setParameter(1, task); LocalDate timesheetLineMaxDate = (LocalDate) q.getSingleResult(); return this.getPlanningLinesAmount(task, timesheetLineMaxDate); } public BigDecimal getPlanningLinesAmount(Task task, LocalDate startDate) throws AxelorException { BigDecimal planningLinesAmount = BigDecimal.ZERO; if (task.getPlanningLineList() == null) return planningLinesAmount; for (PlanningLine planningLine : task.getPlanningLineList()) { if (startDate == null || planningLine.getFromDateTime().isAfter(startDate)) { Employee employee = planningLine.getEmployee(); Product profil = planningLine.getProduct(); if (employee != null) { planningLinesAmount = planningLinesAmount.add(employee.getDailySalaryCost() .multiply(unitConversionService.convert(planningLine.getUnit(), unitRepo.findByCode("JR"), planningLine.getDuration()))); } else if (profil != null) { planningLinesAmount = planningLinesAmount.add( profil.getCostPrice().multiply(unitConversionService.convert(planningLine.getUnit(), profil.getUnit(), planningLine.getDuration()))); } } } return planningLinesAmount; } public BigDecimal getTaskProgressTurnover(List<Task> taskList) { BigDecimal taskProgressTurnover = BigDecimal.ZERO; if (taskList != null) { for (Task task : taskList) { taskProgressTurnover = taskProgressTurnover.add(this.getTaskProgressTurnover(task)); } } return taskProgressTurnover; } public BigDecimal getTaskProgressTurnover(Task task) { return new BigDecimal(task.getTaskProgress() / 100).multiply(task.getEstimatedAmount()); } public void updateTaskProgress(List<Task> taskList) { if (taskList != null) { for (Task task : taskList) { this.updateTaskProgress(task); } } } @Transactional(rollbackOn = { AxelorException.class, Exception.class }) public void updateTaskProgress(Task task) { switch (task.getRealEstimatedMethodSelect()) { case ITask.REAL_ESTIMATED_METHOD_NONE: break; case ITask.REAL_ESTIMATED_METHOD_PROGRESS: task.setTaskProgress(this.computeTaskProgressMethodProgress(task)); break; case ITask.REAL_ESTIMATED_METHOD_SUBSCRIPTION: task.setTaskProgress(this.computeTaskProgressMethodSubscription(task)); break; default: break; } if (task.getTaskProgress() == 100) { task.setStatusSelect(ITask.STATUS_COMPLETED); } save(task); } public int computeTaskProgressMethodProgress(Task task) { BigDecimal taskProgress = BigDecimal.ZERO; BigDecimal totalTime = task.getTotalTime(); if (totalTime.compareTo(BigDecimal.ZERO) == 1) { taskProgress = task.getSpentTime().multiply(new BigDecimal(100)).divide(totalTime, 2, BigDecimal.ROUND_UP); } return taskProgress.intValue(); } public int computeTaskProgressMethodSubscription(Task task) { LocalDateTime startDateTime = task.getStartDateT(); LocalDateTime endDateTime = task.getEndDateT(); if (startDateTime != null && endDateTime != null && this.todayTime.isAfter(startDateTime)) { if (this.todayTime.isAfter(endDateTime)) { return 100; } int total = DurationTool.getMinutesDuration(DurationTool.computeDuration(startDateTime, endDateTime)); if (total == 0) { return 0; } int realized = DurationTool .getMinutesDuration(DurationTool.computeDuration(startDateTime, this.todayTime)); return 100 * realized / total; } return 0; } /** * Mthode permettant de calculer la somme des dures de la liste de planning et * d'assigner la quantit, l'unit, et la date de fin la tche courante. * @param planningLineList La liste des lignes de planning * @param task La tche courante * @throws AxelorException Les units demands ne se trouvent pas dans la liste de conversion */ public LocalDateTime getTaskEndDate(Task task) throws AxelorException { LocalDateTime laterDate = task.getEndDateT(); if (task.getPlanningLineList() != null) { for (PlanningLine planningLine : task.getPlanningLineList()) { if (laterDate == null || laterDate.compareTo(planningLine.getToDateTime()) < 0) { laterDate = planningLine.getToDateTime(); } } } return laterDate; } public Task importTask(Object bean, Map values) { try { Task task = (Task) bean; task.setSpentTime(getSpentTime(task)); task.setPlannedTime(getPlannedTime(task)); updateFinancialInformation(task); return task; } catch (Exception e) { e.printStackTrace(); } return null; } }