Java tutorial
/** * Axelor Business Solutions * * Copyright (C) 2015 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.cash.management.service; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.joda.time.LocalDate; import com.axelor.apps.ReportFactory; import com.axelor.apps.account.db.Invoice; import com.axelor.apps.account.db.repo.InvoiceRepository; import com.axelor.apps.base.service.CurrencyService; import com.axelor.apps.base.service.administration.GeneralService; import com.axelor.apps.cash.management.db.Forecast; import com.axelor.apps.cash.management.db.ForecastReason; import com.axelor.apps.cash.management.db.ForecastRecap; import com.axelor.apps.cash.management.db.ForecastRecapLine; import com.axelor.apps.cash.management.db.repo.ForecastRecapLineRepository; import com.axelor.apps.cash.management.db.repo.ForecastRecapRepository; import com.axelor.apps.cash.management.db.repo.ForecastRepository; import com.axelor.apps.cash.management.report.IReport; import com.axelor.apps.crm.db.Opportunity; import com.axelor.apps.crm.db.repo.OpportunityRepository; import com.axelor.apps.hr.db.Employee; import com.axelor.apps.hr.db.Expense; import com.axelor.apps.hr.db.repo.EmployeeRepository; import com.axelor.apps.hr.db.repo.ExpenseRepository; import com.axelor.apps.purchase.db.PurchaseOrder; import com.axelor.apps.purchase.db.repo.PurchaseOrderRepository; import com.axelor.apps.sale.db.SaleOrder; import com.axelor.apps.sale.db.repo.SaleOrderRepository; import com.axelor.apps.supplychain.db.Timetable; import com.axelor.apps.supplychain.db.repo.TimetableRepository; import com.axelor.apps.supplychain.service.TimetableService; import com.axelor.exception.AxelorException; import com.axelor.inject.Beans; import com.google.inject.Inject; import com.google.inject.persist.Transactional; import com.axelor.i18n.I18n; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ForecastRecapService { private final Logger logger = LoggerFactory.getLogger(getClass()); @Inject protected TimetableService timetableService; @Inject protected GeneralService generalService; @Inject protected ForecastRepository forecastRepo; @Inject protected ForecastRecapLineRepository forecastRecapLineRepo; @Inject protected CurrencyService currencyService; @Inject protected ReportFactory reportFactory; public void populate(ForecastRecap forecastRecap) throws AxelorException { List<ForecastRecapLine> forecastRecapLineList = forecastRecap.getForecastRecapLineList(); if (forecastRecapLineList != null && !forecastRecapLineList.isEmpty()) { for (ForecastRecapLine forecastRecapLine : forecastRecapLineList) { if (forecastRecapLine.getId() != null && forecastRecapLine.getId() > 0) { forecastRecapLineRepo.remove(forecastRecapLine); } } forecastRecapLineList.clear(); } forecastRecap.setCurrentBalance(forecastRecap.getStartingBalance()); if (forecastRecap.getOpportunitiesTypeSelect() != null && forecastRecap.getOpportunitiesTypeSelect() > ForecastRecapRepository.OPPORTUNITY_TYPE_NO) { this.populateWithOpportunities(forecastRecap); } this.populateWithInvoices(forecastRecap); this.populateWithSalaries(forecastRecap); this.populateWithTimetables(forecastRecap); this.populateWithForecasts(forecastRecap); this.populateWithExpenses(forecastRecap); forecastRecap.setEndingBalance(forecastRecap.getCurrentBalance()); } public void populateWithOpportunities(ForecastRecap forecastRecap) throws AxelorException { List<Opportunity> opportunityList = new ArrayList<Opportunity>(); if (forecastRecap.getBankDetails() != null) { opportunityList = Beans.get(OpportunityRepository.class).all().filter( "self.company = ?1 AND self.bankDetails = ?2 AND self.expectedCloseDate BETWEEN ?3 AND ?4 AND self.saleOrder = null", forecastRecap.getCompany(), forecastRecap.getBankDetails(), forecastRecap.getFromDate(), forecastRecap.getToDate()).fetch(); } else { opportunityList = Beans.get(OpportunityRepository.class).all().filter( "self.company = ?1 AND self.expectedCloseDate BETWEEN ?2 AND ?3 AND self.saleOrder = null", forecastRecap.getCompany(), forecastRecap.getFromDate(), forecastRecap.getToDate()).fetch(); } for (Opportunity opportunity : opportunityList) { BigDecimal amountCompanyCurr = BigDecimal.ZERO; if (forecastRecap.getOpportunitiesTypeSelect() == ForecastRecapRepository.OPPORTUNITY_TYPE_BASE) { amountCompanyCurr = currencyService.getAmountCurrencyConverted(opportunity.getCurrency(), opportunity.getCompany().getCurrency(), opportunity.getAmount().multiply(opportunity.getProbability()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP), generalService.getTodayDate()).setScale(2, RoundingMode.HALF_UP); forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().add(amountCompanyCurr)); forecastRecap.addForecastRecapLineListItem( this.createForecastRecapLine(opportunity.getExpectedCloseDate(), 1, null, amountCompanyCurr, forecastRecap.getCurrentBalance())); } else if (forecastRecap .getOpportunitiesTypeSelect() == ForecastRecapRepository.OPPORTUNITY_TYPE_BEST) { amountCompanyCurr = currencyService.getAmountCurrencyConverted(opportunity.getCurrency(), opportunity.getCompany().getCurrency(), new BigDecimal(opportunity.getBestCase()).multiply(opportunity.getProbability()).divide( new BigDecimal(100), 2, RoundingMode.HALF_UP), generalService.getTodayDate()).setScale(2, RoundingMode.HALF_UP); forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().add(amountCompanyCurr)); forecastRecap.addForecastRecapLineListItem( this.createForecastRecapLine(opportunity.getExpectedCloseDate(), 1, null, amountCompanyCurr, forecastRecap.getCurrentBalance())); } else { amountCompanyCurr = currencyService.getAmountCurrencyConverted(opportunity.getCurrency(), opportunity.getCompany().getCurrency(), new BigDecimal(opportunity.getWorstCase()).multiply(opportunity.getProbability()).divide( new BigDecimal(100), 2, RoundingMode.HALF_UP), generalService.getTodayDate()).setScale(2, RoundingMode.HALF_UP); forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().add(amountCompanyCurr)); forecastRecap.addForecastRecapLineListItem( this.createForecastRecapLine(opportunity.getExpectedCloseDate(), 1, null, amountCompanyCurr, forecastRecap.getCurrentBalance())); } } } public void getOpportunities(ForecastRecap forecastRecap, Map<LocalDate, BigDecimal> mapExpected, Map<LocalDate, BigDecimal> mapConfirmed) throws AxelorException { List<Opportunity> opportunityList = new ArrayList<Opportunity>(); if (forecastRecap.getBankDetails() != null) { opportunityList = Beans.get(OpportunityRepository.class).all().filter( "self.company = ?1 AND self.bankDetails = ?2 AND self.expectedCloseDate BETWEEN ?3 AND ?4 AND self.saleOrder = null", forecastRecap.getCompany(), forecastRecap.getBankDetails(), forecastRecap.getFromDate(), forecastRecap.getToDate()).fetch(); } else { opportunityList = Beans.get(OpportunityRepository.class).all().filter( "self.company = ?1 AND self.expectedCloseDate BETWEEN ?2 AND ?3 AND self.saleOrder = null", forecastRecap.getCompany(), forecastRecap.getFromDate(), forecastRecap.getToDate()).fetch(); } for (Opportunity opportunity : opportunityList) { BigDecimal amountCompanyCurr = BigDecimal.ZERO; if (forecastRecap.getOpportunitiesTypeSelect() == ForecastRecapRepository.OPPORTUNITY_TYPE_BASE) { amountCompanyCurr = currencyService.getAmountCurrencyConverted(opportunity.getCurrency(), opportunity.getCompany().getCurrency(), opportunity.getAmount().multiply(opportunity.getProbability()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP), generalService.getTodayDate()).setScale(2, RoundingMode.HALF_UP); } else if (forecastRecap .getOpportunitiesTypeSelect() == ForecastRecapRepository.OPPORTUNITY_TYPE_BEST) { amountCompanyCurr = currencyService.getAmountCurrencyConverted(opportunity.getCurrency(), opportunity.getCompany().getCurrency(), new BigDecimal(opportunity.getBestCase()).multiply(opportunity.getProbability()).divide( new BigDecimal(100), 2, RoundingMode.HALF_UP), generalService.getTodayDate()).setScale(2, RoundingMode.HALF_UP); } else { amountCompanyCurr = currencyService.getAmountCurrencyConverted(opportunity.getCurrency(), opportunity.getCompany().getCurrency(), new BigDecimal(opportunity.getWorstCase()).multiply(opportunity.getProbability()).divide( new BigDecimal(100), 2, RoundingMode.HALF_UP), generalService.getTodayDate()).setScale(2, RoundingMode.HALF_UP); } if (opportunity.getSalesStageSelect() == 9) { if (mapExpected.containsKey(opportunity.getExpectedCloseDate())) { mapExpected.put(opportunity.getExpectedCloseDate(), mapExpected.get(opportunity.getExpectedCloseDate()).add(amountCompanyCurr)); } else { mapExpected.put(opportunity.getExpectedCloseDate(), amountCompanyCurr); } } else { if (mapConfirmed.containsKey(opportunity.getExpectedCloseDate())) { mapConfirmed.put(opportunity.getExpectedCloseDate(), mapConfirmed.get(opportunity.getExpectedCloseDate()).add(amountCompanyCurr)); } else { mapConfirmed.put(opportunity.getExpectedCloseDate(), amountCompanyCurr); } } } } public void populateWithInvoices(ForecastRecap forecastRecap) { List<Invoice> invoiceList = new ArrayList<Invoice>(); if (forecastRecap.getBankDetails() != null) { invoiceList = Beans.get(InvoiceRepository.class).all().filter( "self.company = ?1 AND self.companyBankDetails = ?2 AND self.statusSelect = 3 AND self.estimatedPaymentDate BETWEEN ?3 AND ?4 AND self.companyInTaxTotalRemaining != 0", forecastRecap.getCompany(), forecastRecap.getBankDetails(), forecastRecap.getFromDate(), forecastRecap.getToDate()).fetch(); } else { invoiceList = Beans.get(InvoiceRepository.class).all().filter( "self.company = ?1 AND self.statusSelect = 3 AND self.estimatedPaymentDate BETWEEN ?2 AND ?3 AND self.companyInTaxTotalRemaining != 0", forecastRecap.getCompany(), forecastRecap.getFromDate(), forecastRecap.getToDate()).fetch(); } for (Invoice invoice : invoiceList) { BigDecimal amountPaidExTax = invoice.getAmountPaid().multiply(invoice.getCompanyExTaxTotal()) .divide(invoice.getCompanyInTaxTotal(), 2, RoundingMode.HALF_UP); BigDecimal amount = invoice.getCompanyExTaxTotal().subtract(amountPaidExTax); if (invoice.getOperationTypeSelect() == 2 || invoice.getOperationTypeSelect() == 3) { forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().add(amount)); forecastRecap.addForecastRecapLineListItem(this.createForecastRecapLine( invoice.getEstimatedPaymentDate(), 1, null, amount, forecastRecap.getCurrentBalance())); } if (invoice.getOperationTypeSelect() == 1 || invoice.getOperationTypeSelect() == 4) { forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().subtract(amount)); forecastRecap.addForecastRecapLineListItem(this.createForecastRecapLine( invoice.getEstimatedPaymentDate(), 2, null, amount, forecastRecap.getCurrentBalance())); } } } public void getInvoices(ForecastRecap forecastRecap, Map<LocalDate, BigDecimal> mapExpected, Map<LocalDate, BigDecimal> mapConfirmed) { List<Invoice> invoiceList = new ArrayList<Invoice>(); if (forecastRecap.getBankDetails() != null) { invoiceList = Beans.get(InvoiceRepository.class).all().filter( "self.company = ?1 AND self.companyBankDetails = ?2 AND self.statusSelect = 3 AND self.estimatedPaymentDate BETWEEN ?3 AND ?4 AND self.companyInTaxTotalRemaining != 0", forecastRecap.getCompany(), forecastRecap.getBankDetails(), forecastRecap.getFromDate(), forecastRecap.getToDate()).fetch(); } else { invoiceList = Beans.get(InvoiceRepository.class).all().filter( "self.company = ?1 AND self.statusSelect = 3 AND self.estimatedPaymentDate BETWEEN ?2 AND ?3 AND self.companyInTaxTotalRemaining != 0", forecastRecap.getCompany(), forecastRecap.getFromDate(), forecastRecap.getToDate()).fetch(); } for (Invoice invoice : invoiceList) { BigDecimal amountPaidExTax = invoice.getAmountPaid().multiply(invoice.getCompanyExTaxTotal()) .divide(invoice.getCompanyInTaxTotal(), 2, RoundingMode.HALF_UP); BigDecimal amount = invoice.getCompanyExTaxTotal().subtract(amountPaidExTax); if (invoice.getOperationTypeSelect() == 2 || invoice.getOperationTypeSelect() == 3) { if (mapConfirmed.containsKey(invoice.getEstimatedPaymentDate())) { mapConfirmed.put(invoice.getEstimatedPaymentDate(), mapConfirmed.get(invoice.getEstimatedPaymentDate()).add(amount)); } else { mapConfirmed.put(invoice.getEstimatedPaymentDate(), amount); } } } } public void populateWithSalaries(ForecastRecap forecastRecap) { List<Employee> employeeList = new ArrayList<Employee>(); if (forecastRecap.getBankDetails() != null) { employeeList = Beans.get(EmployeeRepository.class).all() .filter("self.user.activeCompany = ?1 AND self.bankDetails = ?2", forecastRecap.getCompany(), forecastRecap.getBankDetails()) .fetch(); } else { employeeList = Beans.get(EmployeeRepository.class).all() .filter("self.user.activeCompany = ?1", forecastRecap.getCompany()).fetch(); } LocalDate itDate = new LocalDate(forecastRecap.getFromDate()); while (!itDate.isAfter(forecastRecap.getToDate())) { if (itDate.isEqual(new LocalDate(itDate.getYear(), itDate.getMonthOfYear(), itDate.dayOfMonth().getMaximumValue()))) { for (Employee employee : employeeList) { forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().subtract(employee .getHourlyRate().multiply(employee.getWeeklyWorkHours().multiply(new BigDecimal(4))))); forecastRecap.addForecastRecapLineListItem(this.createForecastRecapLine(itDate, 2, null, employee.getHourlyRate() .multiply(employee.getWeeklyWorkHours().multiply(new BigDecimal(4))), forecastRecap.getCurrentBalance())); } itDate = itDate.plusMonths(1); } else { itDate = new LocalDate(itDate.getYear(), itDate.getMonthOfYear(), itDate.dayOfMonth().getMaximumValue()); } } } public void populateWithTimetables(ForecastRecap forecastRecap) throws AxelorException { List<Timetable> timetableSaleOrderList = new ArrayList<Timetable>(); List<Timetable> timetablePurchaseOrderList = new ArrayList<Timetable>(); if (forecastRecap.getBankDetails() != null) { timetableSaleOrderList = Beans.get(TimetableRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.saleOrder.company = ?3 AND" + " self.saleOrder.companyBankDetails = ?4 AND self.saleOrder.statusSelect = 3 AND self.amountToInvoice != 0", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany(), forecastRecap.getBankDetails()) .fetch(); timetablePurchaseOrderList = Beans.get(TimetableRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.purchaseOrder.company = ?3 AND" + " self.purchaseOrder.companyBankDetails = ?4 AND self.purchaseOrder.statusSelect = 3 AND self.amountToInvoice != 0", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany(), forecastRecap.getBankDetails()) .fetch(); } else { timetableSaleOrderList = Beans.get(TimetableRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.saleOrder.company = ?3 AND" + " self.saleOrder.statusSelect = 3 AND self.amountToInvoice != 0", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany()) .fetch(); timetablePurchaseOrderList = Beans.get(TimetableRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.purchaseOrder.company = ?3 AND" + " self.purchaseOrder.statusSelect = 3 AND self.amountToInvoice != 0", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany()) .fetch(); } for (Timetable timetable : timetableSaleOrderList) { timetableService.updateTimetable(timetable.getSaleOrder()); BigDecimal amountCompanyCurr = currencyService .getAmountCurrencyConverted(timetable.getSaleOrder().getCurrency(), timetable.getSaleOrder().getCompany().getCurrency(), timetable.getAmountToInvoice(), generalService.getTodayDate()) .setScale(2, RoundingMode.HALF_UP); forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().add(amountCompanyCurr)); forecastRecap.addForecastRecapLineListItem(this.createForecastRecapLine(timetable.getEstimatedDate(), 1, null, amountCompanyCurr, forecastRecap.getCurrentBalance())); } for (Timetable timetable : timetablePurchaseOrderList) { timetableService.updateTimetable(timetable.getPurchaseOrder()); BigDecimal amountCompanyCurr = currencyService .getAmountCurrencyConverted(timetable.getPurchaseOrder().getCurrency(), timetable.getPurchaseOrder().getCompany().getCurrency(), timetable.getAmountToInvoice(), generalService.getTodayDate()) .setScale(2, RoundingMode.HALF_UP); forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().subtract(amountCompanyCurr)); forecastRecap.addForecastRecapLineListItem(this.createForecastRecapLine(timetable.getEstimatedDate(), 2, null, amountCompanyCurr, forecastRecap.getCurrentBalance())); } } public void populateWithTimetablesOrOrders(ForecastRecap forecastRecap) throws AxelorException { List<Timetable> timetableSaleOrderList = new ArrayList<Timetable>(); List<SaleOrder> saleOrderList = new ArrayList<SaleOrder>(); List<Timetable> timetablePurchaseOrderList = new ArrayList<Timetable>(); List<PurchaseOrder> purchaseOrderList = new ArrayList<PurchaseOrder>(); if (forecastRecap.getBankDetails() != null) { timetableSaleOrderList = Beans.get(TimetableRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.saleOrder.company = ?3 AND" + " self.saleOrder.companyBankDetails = ?4 AND self.saleOrder.statusSelect = 3 AND self.amountToInvoice != 0", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany(), forecastRecap.getBankDetails()) .fetch(); timetablePurchaseOrderList = Beans.get(TimetableRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.purchaseOrder.company = ?3 AND" + " self.purchaseOrder.companyBankDetails = ?4 AND self.purchaseOrder.statusSelect = 3 AND self.amountToInvoice != 0", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany(), forecastRecap.getBankDetails()) .fetch(); } else { timetableSaleOrderList = Beans.get(TimetableRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.saleOrder.company = ?3 AND" + " self.saleOrder.statusSelect = 3 AND self.amountToInvoice != 0", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany()) .fetch(); timetablePurchaseOrderList = Beans.get(TimetableRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.purchaseOrder.company = ?3 AND" + " self.purchaseOrder.statusSelect = 3 AND self.amountToInvoice != 0", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany()) .fetch(); } for (Timetable timetable : timetableSaleOrderList) { saleOrderList.add(timetable.getSaleOrder()); timetableService.updateTimetable(timetable.getSaleOrder()); BigDecimal amountCompanyCurr = currencyService .getAmountCurrencyConverted(timetable.getSaleOrder().getCurrency(), timetable.getSaleOrder().getCompany().getCurrency(), timetable.getAmountToInvoice(), generalService.getTodayDate()) .setScale(2, RoundingMode.HALF_UP); forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().add(amountCompanyCurr)); forecastRecap.addForecastRecapLineListItem(this.createForecastRecapLine(timetable.getEstimatedDate(), 1, null, amountCompanyCurr, forecastRecap.getCurrentBalance())); } for (Timetable timetable : timetablePurchaseOrderList) { purchaseOrderList.add(timetable.getPurchaseOrder()); timetableService.updateTimetable(timetable.getPurchaseOrder()); BigDecimal amountCompanyCurr = currencyService .getAmountCurrencyConverted(timetable.getPurchaseOrder().getCurrency(), timetable.getPurchaseOrder().getCompany().getCurrency(), timetable.getAmountToInvoice(), generalService.getTodayDate()) .setScale(2, RoundingMode.HALF_UP); forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().subtract(amountCompanyCurr)); forecastRecap.addForecastRecapLineListItem(this.createForecastRecapLine(timetable.getEstimatedDate(), 2, null, amountCompanyCurr, forecastRecap.getCurrentBalance())); } List<SaleOrder> saleOrderNoTimeTableList = new ArrayList<SaleOrder>(); List<PurchaseOrder> purchaseOrderNoTimetableList = new ArrayList<PurchaseOrder>(); if (forecastRecap.getBankDetails() != null) { saleOrderNoTimeTableList = Beans.get(SaleOrderRepository.class).all() .filter("self.expectedRealisationDate BETWEEN ?1 AND ?2 AND self.company = ?3 AND" + " self.companyBankDetails = ?4 AND (self.statusSelect = 2 OR self.statusSelect = 3)", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany(), forecastRecap.getBankDetails()) .fetch(); purchaseOrderNoTimetableList = Beans.get(PurchaseOrderRepository.class).all() .filter("self.expectedRealisationDate BETWEEN ?1 AND ?2 AND self.company = ?3 AND" + " self.companyBankDetails = ?4 AND self.statusSelect = 3", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany(), forecastRecap.getBankDetails()) .fetch(); } else { saleOrderNoTimeTableList = Beans.get(SaleOrderRepository.class).all() .filter("self.expectedRealisationDate BETWEEN ?1 AND ?2 AND self.company = ?3 AND" + " (self.statusSelect = 2 OR self.statusSelect = 3)", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany()) .fetch(); purchaseOrderNoTimetableList = Beans.get(PurchaseOrderRepository.class).all() .filter("self.expectedRealisationDate BETWEEN ?1 AND ?2 AND self.company = ?3 AND" + " self.statusSelect = 3", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany()) .fetch(); } for (SaleOrder saleOrder : saleOrderNoTimeTableList) { if (!saleOrderList.contains(saleOrder)) { BigDecimal amountCompanyCurr = saleOrder.getCompanyExTaxTotal() .subtract(saleOrder.getAmountInvoiced()); if (amountCompanyCurr.compareTo(BigDecimal.ZERO) == 0) { forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().add(amountCompanyCurr)); forecastRecap.addForecastRecapLineListItem( this.createForecastRecapLine(saleOrder.getExpectedRealisationDate(), 1, null, amountCompanyCurr, forecastRecap.getCurrentBalance())); } } } for (PurchaseOrder purchaseOrder : purchaseOrderNoTimetableList) { if (!purchaseOrderList.contains(purchaseOrder)) { BigDecimal amountCompanyCurr = purchaseOrder.getCompanyExTaxTotal() .subtract(purchaseOrder.getAmountInvoiced()); if (amountCompanyCurr.compareTo(BigDecimal.ZERO) == 0) { forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().subtract(amountCompanyCurr)); forecastRecap.addForecastRecapLineListItem( this.createForecastRecapLine(purchaseOrder.getExpectedRealisationDate(), 2, null, amountCompanyCurr, forecastRecap.getCurrentBalance())); } } } } public void getTimetablesOrOrders(ForecastRecap forecastRecap, Map<LocalDate, BigDecimal> mapExpected, Map<LocalDate, BigDecimal> mapConfirmed) throws AxelorException { List<Timetable> timetableSaleOrderList = new ArrayList<Timetable>(); List<SaleOrder> saleOrderList = new ArrayList<SaleOrder>(); if (forecastRecap.getBankDetails() != null) { timetableSaleOrderList = Beans.get(TimetableRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.saleOrder.company = ?3 AND" + " self.saleOrder.companyBankDetails = ?4 AND (self.saleOrder.statusSelect = 2 OR self.saleOrder.statusSelect = 3) AND self.amountToInvoice != 0", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany(), forecastRecap.getBankDetails()) .fetch(); } else { timetableSaleOrderList = Beans.get(TimetableRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.saleOrder.company = ?3 AND" + " (self.saleOrder.statusSelect = 2 OR self.saleOrder.statusSelect = 3) AND self.amountToInvoice != 0", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany()) .fetch(); } for (Timetable timetable : timetableSaleOrderList) { saleOrderList.add(timetable.getSaleOrder()); timetableService.updateTimetable(timetable.getSaleOrder()); BigDecimal amountCompanyCurr = currencyService .getAmountCurrencyConverted(timetable.getSaleOrder().getCurrency(), timetable.getSaleOrder().getCompany().getCurrency(), timetable.getAmountToInvoice(), generalService.getTodayDate()) .setScale(2, RoundingMode.HALF_UP); if (timetable.getSaleOrder().getStatusSelect() == 2) { if (mapExpected.containsKey(timetable.getEstimatedDate())) { mapExpected.put(timetable.getEstimatedDate(), mapExpected.get(timetable.getEstimatedDate()).add(amountCompanyCurr)); } else { mapExpected.put(timetable.getEstimatedDate(), amountCompanyCurr); } } else { if (mapConfirmed.containsKey(timetable.getEstimatedDate())) { mapConfirmed.put(timetable.getEstimatedDate(), mapConfirmed.get(timetable.getEstimatedDate()).add(amountCompanyCurr)); } else { mapConfirmed.put(timetable.getEstimatedDate(), amountCompanyCurr); } } } List<SaleOrder> saleOrderNoTimeTableList = new ArrayList<SaleOrder>(); if (forecastRecap.getBankDetails() != null) { saleOrderNoTimeTableList = Beans.get(SaleOrderRepository.class).all() .filter("self.expectedRealisationDate BETWEEN ?1 AND ?2 AND self.company = ?3 AND" + " self.companyBankDetails = ?4 AND (self.statusSelect = 2 OR self.statusSelect = 3)", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany(), forecastRecap.getBankDetails()) .fetch(); } else { saleOrderNoTimeTableList = Beans.get(SaleOrderRepository.class).all() .filter("self.expectedRealisationDate BETWEEN ?1 AND ?2 AND self.company = ?3 AND" + " (self.statusSelect = 2 OR self.statusSelect = 3)", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany()) .fetch(); } for (SaleOrder saleOrder : saleOrderNoTimeTableList) { if (!saleOrderList.contains(saleOrder)) { BigDecimal amountCompanyCurr = saleOrder.getCompanyExTaxTotal() .subtract(saleOrder.getAmountInvoiced()); if (amountCompanyCurr.compareTo(BigDecimal.ZERO) == 0) { if (saleOrder.getStatusSelect() == 2) { if (mapExpected.containsKey(saleOrder.getExpectedRealisationDate())) { mapExpected.put(saleOrder.getExpectedRealisationDate(), mapExpected.get(saleOrder.getExpectedRealisationDate()).add(amountCompanyCurr)); } else { mapExpected.put(saleOrder.getExpectedRealisationDate(), amountCompanyCurr); } } else { if (mapConfirmed.containsKey(saleOrder.getExpectedRealisationDate())) { mapConfirmed.put(saleOrder.getExpectedRealisationDate(), mapConfirmed .get(saleOrder.getExpectedRealisationDate()).add(amountCompanyCurr)); } else { mapConfirmed.put(saleOrder.getExpectedRealisationDate(), amountCompanyCurr); } } } } } } @Transactional public void populateWithForecasts(ForecastRecap forecastRecap) { List<Forecast> forecastList = new ArrayList<Forecast>(); if (forecastRecap.getBankDetails() != null) { forecastList = Beans.get(ForecastRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.company = ?3 AND" + " self.bankDetails = ?4 AND (self.realizedSelect = 2 OR (self.realizedSelect = 3 AND self.estimatedDate <= ?5))", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany(), forecastRecap.getBankDetails(), generalService.getTodayDate()) .fetch(); } else { forecastList = Beans.get(ForecastRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.company = ?3 AND" + " (self.realizedSelect = 2 OR (self.realizedSelect = 3 AND self.estimatedDate <= ?4))", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany(), generalService.getTodayDate()) .fetch(); } for (Forecast forecast : forecastList) { if (forecast.getTypeSelect() == 1) { forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().add(forecast.getAmount())); } else { forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().subtract(forecast.getAmount())); } forecastRecap.addForecastRecapLineListItem( this.createForecastRecapLine(forecast.getEstimatedDate(), forecast.getTypeSelect(), forecast.getForecastReason(), forecast.getAmount(), forecastRecap.getCurrentBalance())); forecast.setRealizedSelect(ForecastRepository.REALISED_SELECT_YES); forecastRepo.save(forecast); } } public void populateWithForecastsNoSave(ForecastRecap forecastRecap) { List<Forecast> forecastList = new ArrayList<Forecast>(); if (forecastRecap.getBankDetails() != null) { forecastList = Beans.get(ForecastRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.company = ?3 AND" + " self.bankDetails = ?4 AND (self.realizedSelect = 2 OR (self.realizedSelect = 3 AND self.estimatedDate <= ?5))", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany(), forecastRecap.getBankDetails(), generalService.getTodayDate()) .fetch(); } else { forecastList = Beans.get(ForecastRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.company = ?3 AND" + " (self.realizedSelect = 2 OR (self.realizedSelect = 3 AND self.estimatedDate <= ?4))", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany(), generalService.getTodayDate()) .fetch(); } for (Forecast forecast : forecastList) { if (forecast.getTypeSelect() == 1) { forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().add(forecast.getAmount())); } else { forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().subtract(forecast.getAmount())); } forecastRecap.addForecastRecapLineListItem( this.createForecastRecapLine(forecast.getEstimatedDate(), forecast.getTypeSelect(), forecast.getForecastReason(), forecast.getAmount(), forecastRecap.getCurrentBalance())); } } public void getForecasts(ForecastRecap forecastRecap, Map<LocalDate, BigDecimal> mapExpected, Map<LocalDate, BigDecimal> mapConfirmed) { List<Forecast> forecastList = new ArrayList<Forecast>(); if (forecastRecap.getBankDetails() != null) { forecastList = Beans.get(ForecastRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.company = ?3 AND" + " self.bankDetails = ?4 AND (self.realizedSelect = 2 OR self.realizedSelect = 3)", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany(), forecastRecap.getBankDetails()) .fetch(); } else { forecastList = Beans.get(ForecastRepository.class).all() .filter("self.estimatedDate BETWEEN ?1 AND ?2 AND self.company = ?3 AND" + " (self.realizedSelect = 2 OR self.realizedSelect = 3)", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany()) .fetch(); } for (Forecast forecast : forecastList) { if (forecast.getTypeSelect() == 1) { if (forecast.getRealizedSelect() == 2) { if (mapExpected.containsKey(forecast.getEstimatedDate())) { mapExpected.put(forecast.getEstimatedDate(), mapExpected.get(forecast.getEstimatedDate()).add(forecast.getAmount())); } else { mapExpected.put(forecast.getEstimatedDate(), forecast.getAmount()); } } else { if (mapConfirmed.containsKey(forecast.getEstimatedDate())) { mapConfirmed.put(forecast.getEstimatedDate(), mapConfirmed.get(forecast.getEstimatedDate()).add(forecast.getAmount())); } else { mapConfirmed.put(forecast.getEstimatedDate(), forecast.getAmount()); } } } } } public void populateWithExpenses(ForecastRecap forecastRecap) { List<Expense> expenseList = new ArrayList<Expense>(); if (forecastRecap.getBankDetails() != null) { expenseList = Beans.get(ExpenseRepository.class).all() .filter("self.validationDate BETWEEN ?1 AND ?2 AND self.company = ?3 AND" + " self.bankDetails = ?4 AND self.statusSelect = 3", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany(), forecastRecap.getBankDetails()) .fetch(); } else { expenseList = Beans.get(ExpenseRepository.class).all() .filter("self.validationDate BETWEEN ?1 AND ?2 AND self.company = ?3 AND" + " self.statusSelect = 3", forecastRecap.getFromDate(), forecastRecap.getToDate(), forecastRecap.getCompany()) .fetch(); } for (Expense expense : expenseList) { forecastRecap.setCurrentBalance(forecastRecap.getCurrentBalance().subtract(expense.getExTaxTotal())); forecastRecap.addForecastRecapLineListItem(this.createForecastRecapLine(expense.getValidationDate(), 2, null, expense.getExTaxTotal(), forecastRecap.getCurrentBalance())); } } public ForecastRecapLine createForecastRecapLine(LocalDate date, int type, ForecastReason reason, BigDecimal amount, BigDecimal balance) { ForecastRecapLine forecastRecapLine = new ForecastRecapLine(); forecastRecapLine.setEstimatedDate(date); forecastRecapLine.setTypeSelect(type); forecastRecapLine.setForecastReason(reason); forecastRecapLine.setAmount(amount); forecastRecapLine.setBalance(balance); return forecastRecapLine; } public String getURLForecastRecapPDF(ForecastRecap forecastRecap) throws AxelorException { String language = ""; try { language = forecastRecap.getCompany().getPrintingSettings().getLanguageSelect() != null ? forecastRecap.getCompany().getPrintingSettings().getLanguageSelect() : "en"; } catch (NullPointerException e) { language = "en"; } language = language.equals("") ? "en" : language; String title = I18n.get("ForecastRecap"); title += forecastRecap.getId(); return reportFactory.createReport(IReport.FORECAST_RECAP, title + "-${date}") .addParam("ForecastRecapId", forecastRecap.getId().toString()).addParam("Locale", language) .generate().getFileLink(); } }