/** * Axelor Business Solutions * * Copyright (C) 2016 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.supplychain.service.invoice.generator; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.List; import com.axelor.apps.account.db.AnalyticDistributionLine; import com.axelor.apps.account.db.BudgetDistribution; import com.axelor.apps.account.db.Invoice; import com.axelor.apps.account.db.InvoiceLine; import com.axelor.apps.account.db.repo.AnalyticDistributionLineRepository; import com.axelor.apps.account.service.invoice.InvoiceLineService; import com.axelor.apps.account.service.invoice.InvoiceToolService; import com.axelor.apps.account.service.invoice.generator.InvoiceLineGenerator; import com.axelor.apps.base.db.Product; import com.axelor.apps.base.db.Unit; import com.axelor.apps.base.db.repo.ProductRepository; import com.axelor.apps.base.service.UnitConversionService; import com.axelor.apps.base.service.administration.GeneralService; import com.axelor.apps.purchase.db.PurchaseOrderLine; import com.axelor.apps.sale.db.SaleOrderLine; import com.axelor.apps.stock.db.StockMove; import com.axelor.apps.stock.db.StockMoveLine; import com.axelor.apps.supplychain.db.Subscription; import com.axelor.exception.AxelorException; import com.axelor.inject.Beans; import com.google.inject.Inject; /** * Classe de création de ligne de facture abstraite. * */ public abstract class InvoiceLineGeneratorSupplyChain extends InvoiceLineGenerator { @Inject protected InvoiceLineService invoiceLineService; @Inject protected UnitConversionService unitConversionService; protected SaleOrderLine saleOrderLine; protected PurchaseOrderLine purchaseOrderLine; protected StockMoveLine stockMoveLine; protected Subscription subscription; protected InvoiceLineGeneratorSupplyChain( Invoice invoice, Product product, String productName, String description, BigDecimal qty, Unit unit, int sequence, boolean isTaxInvoice, SaleOrderLine saleOrderLine, PurchaseOrderLine purchaseOrderLine, StockMoveLine stockMoveLine) throws AxelorException { super(invoice, product, productName, description, qty, unit, sequence, isTaxInvoice); this.saleOrderLine = saleOrderLine; this.purchaseOrderLine = purchaseOrderLine; this.stockMoveLine = stockMoveLine; if(saleOrderLine != null) { this.discountAmount = saleOrderLine.getDiscountAmount(); this.price = saleOrderLine.getPrice(); this.priceDiscounted = saleOrderLine.getPriceDiscounted(); this.taxLine = saleOrderLine.getTaxLine(); this.discountTypeSelect = saleOrderLine.getDiscountTypeSelect(); this.isTitleLine = saleOrderLine.getIsTitleLine(); } else if (purchaseOrderLine != null){ this.isTitleLine = purchaseOrderLine.getIsTitleLine(); this.purchaseOrderLine = purchaseOrderLine; this.discountAmount = purchaseOrderLine.getDiscountAmount(); this.price = purchaseOrderLine.getPrice(); this.priceDiscounted = purchaseOrderLine.getPriceDiscounted(); this.taxLine = purchaseOrderLine.getTaxLine(); this.discountTypeSelect = purchaseOrderLine.getDiscountTypeSelect(); } else if(stockMoveLine != null) { this.priceDiscounted = stockMoveLine.getUnitPriceUntaxed(); Unit saleOrPurchaseUnit = this.getSaleOrPurchaseUnit(); if(saleOrPurchaseUnit != null && this.unit != null && !this.unit.equals(saleOrPurchaseUnit)){ this.qty = Beans.get(UnitConversionService.class).convertWithProduct(this.unit, saleOrPurchaseUnit, qty, stockMoveLine.getProduct()); this.priceDiscounted = Beans.get(UnitConversionService.class).convertWithProduct(this.unit, saleOrPurchaseUnit, this.priceDiscounted, product); this.unit = saleOrPurchaseUnit; } } } protected InvoiceLineGeneratorSupplyChain( Invoice invoice, Product product, String productName, String description, BigDecimal qty, Unit unit, int sequence, boolean isTaxInvoice, SaleOrderLine saleOrderLine, PurchaseOrderLine purchaseOrderLine, StockMoveLine stockMoveLine, Subscription subscription) throws AxelorException { this(invoice, product, productName, description, qty, unit, sequence, isTaxInvoice, saleOrderLine, purchaseOrderLine, stockMoveLine); this.subscription = subscription; } /** * @return * @throws AxelorException */ @Override protected InvoiceLine createInvoiceLine() throws AxelorException { InvoiceLine invoiceLine = super.createInvoiceLine(); // Update for subscription SaleOrderLine if (saleOrderLine != null && product != null && ProductRepository.PRODUCT_TYPE_SUBSCRIPTABLE.equals(product.getProductTypeSelect()) && saleOrderLine.getSubscriptionList() != null && !saleOrderLine.getSubscriptionList().isEmpty()) { BigDecimal subscriptionListSize = new BigDecimal(saleOrderLine.getSubscriptionList().size()); this.exTaxTotal = this.exTaxTotal.divide(subscriptionListSize, 2, RoundingMode.HALF_EVEN); this.inTaxTotal = this.inTaxTotal.divide(subscriptionListSize, 2, RoundingMode.HALF_EVEN); } this.assignOriginElements(invoiceLine); if (saleOrderLine != null) { this.copyAnalyticDistributionLines(saleOrderLine.getAnalyticDistributionLineList(), invoiceLine); } else if (purchaseOrderLine != null) { this.copyAnalyticDistributionLines(purchaseOrderLine.getAnalyticDistributionLineList(), invoiceLine); this.copyBudgetDistributionList(purchaseOrderLine.getBudgetDistributionList(), invoiceLine); invoiceLine.setBudget(purchaseOrderLine.getBudget()); } else if(stockMoveLine != null) { this.price = invoiceLineService.getUnitPrice(invoice, invoiceLine, taxLine, InvoiceToolService.isPurchase(invoice)); this.price = Beans.get(UnitConversionService.class).convertWithProduct(stockMoveLine.getUnit(), this.unit, this.price, product); } return invoiceLine; } public void assignOriginElements(InvoiceLine invoiceLine) throws AxelorException { if (!Beans.get(GeneralService.class).getGeneral().getManageInvoicedAmountByLine()) { return; } StockMove stockMove = null; if(stockMoveLine != null) { stockMove = stockMoveLine.getStockMove(); } if(stockMove != null) { if(InvoiceToolService.isPurchase(invoice)) { invoiceLine.setIncomingStockMove(stockMove); } else { invoiceLine.setOutgoingStockMove(stockMove); } } if(saleOrderLine != null) { invoiceLine.setSaleOrderLine(saleOrderLine); } if(purchaseOrderLine != null) { invoiceLine.setPurchaseOrderLine(purchaseOrderLine); } } public void copyAnalyticDistributionLines(List<AnalyticDistributionLine> originalAnalyticDistributionLineList, InvoiceLine invoiceLine) { if(originalAnalyticDistributionLineList == null) { return; } for (AnalyticDistributionLine analyticDistributionLineIt : originalAnalyticDistributionLineList) { invoiceLine.addAnalyticDistributionLineListItem(Beans.get(AnalyticDistributionLineRepository.class).copy(analyticDistributionLineIt, false)); } } public void copyBudgetDistributionList(List<BudgetDistribution> originalBudgetDistributionList, InvoiceLine invoiceLine) { if(originalBudgetDistributionList == null) { return ; } for (BudgetDistribution budgetDistributionIt : originalBudgetDistributionList) { BudgetDistribution budgetDistribution = new BudgetDistribution(); budgetDistribution.setBudget(budgetDistributionIt.getBudget()); budgetDistribution.setAmount(budgetDistributionIt.getAmount()); invoiceLine.addBudgetDistributionListItem(budgetDistribution); } } public Unit getSaleOrPurchaseUnit() throws AxelorException { if(!InvoiceToolService.isPurchase(invoice)){ return product.getSalesUnit(); } else{ return product.getPurchasesUnit(); } } }