package com.axelor.apps.supplychain.service;

import com.axelor.apps.account.db.Account;
import com.axelor.apps.account.db.Invoice;
import com.axelor.apps.account.db.InvoiceLine;
import com.axelor.apps.account.db.InvoiceTemplate;
import com.axelor.apps.account.db.TaxLine;
import com.axelor.apps.account.db.repo.AccountRepository;
import com.axelor.apps.account.db.repo.InvoiceLineRepository;
import com.axelor.apps.account.db.repo.InvoiceRepository;
import com.axelor.apps.account.db.repo.TaxLineRepository;
import com.axelor.apps.account.service.InvoiceTemplateService;
import com.axelor.apps.account.service.invoice.generator.InvoiceLineGenerator;
import com.axelor.apps.base.db.Product;
import com.axelor.apps.base.db.repo.ProductRepository;
import com.axelor.apps.purchase.db.ImportationFolder;
import com.axelor.apps.purchase.db.repo.ImportationFolderRepository;
import com.axelor.apps.stock.db.ImportationFolderCostPrice;
import com.axelor.apps.stock.db.StockLocation;
import com.axelor.apps.stock.db.StockMove;
import com.axelor.apps.stock.db.StockMoveLine;
import com.axelor.apps.stock.db.repo.ImportationFolderCostPriceRepository;
import com.axelor.apps.stock.db.repo.StockMoveLineRepository;
import com.axelor.apps.supplychain.service.invoice.generator.InvoiceLineGeneratorSupplyChain;
import com.axelor.auth.AuthUtils;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.repo.TraceBackRepository;
import com.axelor.i18n.I18n;
import com.axelor.inject.Beans;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import java.lang.invoke.MethodHandles;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.MalformedURLException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import wslite.json.JSONException;

public class ImportationFolderServiceImpl {

  @Inject protected ImportationFolderRepository importationFolderRepository;
  private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

  @Transactional
  public List<Long> calculateAvgPriceAndGenerateInvoice(
      List<StockMoveLine> stockMoveLines, ImportationFolder importationFolder)
      throws MalformedURLException, JSONException, AxelorException {

    Set<StockMove> stockMovesSet = new HashSet<>();
    HashMap<String, List<StockMove>> stockMovesMap = new HashMap<>();

    for (StockMoveLine stockMoveLine : stockMoveLines) {
      stockMovesSet.add(stockMoveLine.getStockMove());
    }

    List<Long> invoiceIds = new ArrayList<>();

    for (StockMove stockMove : stockMovesSet) {
      // Use the 'ref' as the key, and add the object to the corresponding list
      stockMovesMap
          .computeIfAbsent(stockMove.getSupplierShipmentRef(), k -> new ArrayList<>())
          .add(stockMove);
    }

    stockMovesMap.forEach(
        (ref, stockMoveList) -> {
          // List<StockMove> stockMoveList = new ArrayList<>(stockMovesSet);
          if (stockMoveList.size() > 0) {

            Optional<Invoice> invoiceOpt;
            try {
              invoiceOpt =
                  Beans.get(StockMoveMultiInvoiceService.class)
                      .createInvoiceFromMultiIncomingStockMove(stockMoveList);

              Invoice invoice = invoiceOpt.get();
              Product product = Beans.get(ProductRepository.class).find(8931L);
              //  BigDecimal freightPrice = importationFolder.getFreight();

              BigDecimal freightPrice =
                  stockMoveLines
                      .stream()
                      .filter(line -> line.getStockMove() == stockMovesMap.get(ref).get(0))
                      .findFirst()
                      .get()
                      .getFreight()
                      .setScale(2);
              StockLocation stockLocation =
                  importationFolder
                      .getStockMoveLineList()
                      .get(0)
                      .getStockMove()
                      .getToStockLocation();
              TaxLine taxLine = null;
              if (stockLocation.getId() == 86) {
              // if (stockLocation.getId() == 61 || stockLocation.getId() == 60) {
                taxLine = Beans.get(TaxLineRepository.class).find(27L);
              } else {
                if (importationFolder.getStockMoveLineList().get(0).getPurchaseOrderLine()
                    == null) {
                  throw new AxelorException(
                      importationFolder,
                      TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
                      "Purchase order missing",
                      I18n.get(com.axelor.apps.base.exceptions.IExceptionMessage.EXCEPTION));
                }

                taxLine =
                    importationFolder
                        .getStockMoveLineList()
                        .get(0)
                        .getPurchaseOrderLine()
                        .getTaxLine();
              }

              InvoiceLineGenerator invoiceLineGenerator =
                  new InvoiceLineGeneratorSupplyChain(
                      invoice,
                      product,
                      product.getName(),
                      freightPrice,
                      freightPrice,
                      freightPrice,
                      "",
                      BigDecimal.ONE,
                      product.getUnit(),
                      taxLine,
                      100,
                      BigDecimal.ZERO,
                      0,
                      freightPrice,
                      freightPrice,
                      false,
                      null,
                      null,
                      null,
                      false,
                      null) {
                    @Override
                    public List<InvoiceLine> creates() throws AxelorException {

                      InvoiceLine invoiceLine = this.createInvoiceLine();
                      invoiceLine.setPrice(freightPrice);
                      invoiceLine.setPriceDiscounted(freightPrice);
                      Long categoryId =
                          importationFolder
                              .getStockMoveLineList()
                              .get(0)
                              .getProduct()
                              .getFamilleProduit()
                              .getId();
                      Account account = null;
                      switch (categoryId.intValue()) {
                        case 67:
                          account = Beans.get(AccountRepository.class).find(1430L);
                          break;
                        case 68:
                          account = Beans.get(AccountRepository.class).find(1430L);
                          break;
                        case 59:
                          account = Beans.get(AccountRepository.class).find(1431L);
                          break;
                        default:
                          account = Beans.get(AccountRepository.class).find(1431L);
                          break;
                      }
                      invoiceLine.setAccount(account);
                      List<InvoiceLine> invoiceLines = new ArrayList<InvoiceLine>();
                      invoiceLines.add(invoiceLine);

                      return invoiceLines;
                    }
                  };

              List<InvoiceLine> invoiceLines = invoiceLineGenerator.creates();
              invoice.addInvoiceLineListItem(invoiceLines.get(0));

              logger.debug(
                  "invoice.getInvoiceLineList() ********** ", invoice.getInvoiceLineList());

              BigDecimal inTaxTotal = BigDecimal.ZERO;
              BigDecimal exTaxTotal = BigDecimal.ZERO;
              BigDecimal taxTotal = BigDecimal.ZERO;

              for (InvoiceLine invoiceLine : invoice.getInvoiceLineList()) {
                BigDecimal currencyRate = BigDecimal.ZERO;
                // if(invoiceLine.getProduct().getId() == product.getId()){
                currencyRate = importationFolder.getStockMoveLineList().get(0).getCurrencyRate();
                // }else{
                //   currencyRate = invoiceLine.getStockMoveLine().getCurrencyRate();
                // }

                inTaxTotal =
                    inTaxTotal.add(
                        invoiceLine
                            .getInTaxTotal()
                            .multiply(currencyRate)
                            .setScale(2, RoundingMode.HALF_UP));
                exTaxTotal =
                    exTaxTotal.add(
                        invoiceLine
                            .getExTaxTotal()
                            .multiply(currencyRate)
                            .setScale(2, RoundingMode.HALF_UP));
                taxTotal = taxTotal.add(inTaxTotal.subtract(exTaxTotal));

                BigDecimal price =
                    (invoiceLine.getPrice().multiply(currencyRate))
                        .setScale(2, RoundingMode.HALF_UP);

                invoiceLine.setPrice(price);
                invoiceLine.setPriceDiscounted(
                    invoiceLine
                        .getPriceDiscounted()
                        .multiply(currencyRate)
                        .setScale(2, RoundingMode.HALF_UP));
                invoiceLine.setInTaxTotal(
                    invoiceLine
                        .getInTaxTotal()
                        .multiply(currencyRate)
                        .setScale(2, RoundingMode.HALF_UP));
                invoiceLine.setExTaxTotal(
                    invoiceLine
                        .getExTaxTotal()
                        .multiply(currencyRate)
                        .setScale(2, RoundingMode.HALF_UP));
                invoiceLine.setInTaxPrice(
                    invoiceLine
                        .getInTaxPrice()
                        .multiply(currencyRate)
                        .setScale(2, RoundingMode.HALF_UP));
                invoiceLine.setCompanyExTaxTotal(
                    invoiceLine
                        .getCompanyExTaxTotal()
                        .multiply(currencyRate)
                        .setScale(2, RoundingMode.HALF_UP));
                invoiceLine.setCompanyInTaxTotal(
                    invoiceLine
                        .getCompanyInTaxTotal()
                        .multiply(currencyRate)
                        .setScale(2, RoundingMode.HALF_UP));

                Beans.get(InvoiceLineRepository.class).save(invoiceLine);

                logger.debug("currencyRate****** {}", currencyRate);
                logger.debug("Invoice line in importation folder {}", invoiceLine.toString());
              }

              invoice.setInTaxTotal(inTaxTotal);
              invoice.setExTaxTotal(exTaxTotal);
              invoice.setCompanyExTaxTotal(exTaxTotal);
              invoice.setCompanyInTaxTotal(inTaxTotal);
              invoice.setAmountRemaining(inTaxTotal);
              invoice.setCurrency(invoice.getCompany().getCurrency());
              invoice.setTaxTotal(taxTotal);
              invoice.setImportationFolder(importationFolder);
              invoice.setIsImportationPartnerInvoice(true);

              importationFolder.setInvoicedFolder(true);

              Invoice generatedInvoice = Beans.get(InvoiceRepository.class).save(invoice);
              invoiceIds.add(generatedInvoice.getId());
            } catch (AxelorException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
            }
          }
        });
    return invoiceIds;
  }

  public String computeCostPrice(ImportationFolder importationFolder) {

    List<StockMoveLine> stockMoveLines = importationFolder.getStockMoveLineList();
    String message = "";
    BigDecimal costPrice = BigDecimal.ZERO;
    Set<Product> productSet = new HashSet<>();
    // int scale = Beans.get(AppBaseService.class).getNbDecimalDigitForUnitPrice();
    int scale = 20;

    for (StockMoveLine line : stockMoveLines) {
      productSet.add(line.getProduct());
    }

    this.resetCostPriceList(importationFolder);

    if (productSet.size() > 1) {
      List<Invoice> supplierInvoices =
          importationFolder
              .getInvoices()
              .stream()
              .filter(t -> t.getIsImportationPartnerInvoice())
              .collect(Collectors.toList());
      // BigDecimal totalQty =
      // stockMoveLines.stream().map(StockMoveLine::getRealQty).reduce(BigDecimal.ZERO,
      // BigDecimal::add);
      BigDecimal totalNetMass =
          stockMoveLines
              .stream()
              .map(StockMoveLine::getNetMass)
              .reduce(BigDecimal.ZERO, BigDecimal::add);
      BigDecimal totalVolume =
          stockMoveLines
              .stream()
              .map(StockMoveLine::getVolume)
              .reduce(BigDecimal.ZERO, BigDecimal::add);

      BigDecimal freight = BigDecimal.ZERO;

      Set<StockMove> stockMovesSet = new HashSet<>();
      HashMap<String, List<StockMove>> stockMovesMap = new HashMap<>();

      for (StockMoveLine stockMoveLine : stockMoveLines) {
        stockMovesSet.add(stockMoveLine.getStockMove());
      }

      for (StockMove stockMove : stockMovesSet) {
        stockMovesMap
            .computeIfAbsent(stockMove.getSupplierShipmentRef(), k -> new ArrayList<>())
            .add(stockMove);
      }

      freight =
          new BigDecimal(
              stockMovesMap
                  .values()
                  .stream()
                  .filter(t -> 
                      t.get(0)
                          .getStockMoveLineList()
                          .stream()
                          .filter(line -> line.getRealQty() != null && line.getRealQty().compareTo(BigDecimal.ZERO) > 0)
                          .findFirst()
                          .isPresent())
                  .mapToDouble(t -> 
                      t.get(0)
                          .getStockMoveLineList()
                          .stream()
                          .filter(line -> line.getRealQty() != null && line.getRealQty().compareTo(BigDecimal.ZERO) > 0)
                          .findFirst()
                          .map(line -> line.getFreight()
                              .multiply(stockMoveLines.get(0).getCurrencyRate())
                              .setScale(2, RoundingMode.HALF_EVEN)
                              .doubleValue())
                          .orElse(0.0)) // In case no valid line found, fallback to 0.0
                  .sum());


      System.out.println("*****************freight**************************************");
      System.out.println(freight);
      System.out.println("*******************************************************");

      Map<Product, Double> splitting = new HashMap<>();
      Map<Product, Double> splittingQty = new HashMap<>();
      List<InvoiceLine> invoiceLines = new ArrayList<>();
      BigDecimal totalInvoiceWithoutFreight = BigDecimal.ZERO;
      BigDecimal totalQty = BigDecimal.ZERO;

      for (Invoice supplierInvoice : supplierInvoices) {
        BigDecimal freightInvoice = BigDecimal.ZERO;
        Optional<InvoiceLine> invoiceLine =
            supplierInvoice
                .getInvoiceLineList()
                .stream()
                .filter(t -> t.getProduct().getId() == 8931L)
                .findAny();
        if (invoiceLine.isPresent()) {
          freightInvoice = invoiceLine.get().getInTaxTotal();
        }
        BigDecimal invoiceWithoutFreight =
            supplierInvoice
                .getInTaxTotal()
                .subtract(freightInvoice)
                .setScale(2, RoundingMode.HALF_EVEN);
        totalInvoiceWithoutFreight = totalInvoiceWithoutFreight.add(invoiceWithoutFreight);
        invoiceLines.addAll(supplierInvoice.getInvoiceLineList());
        // total qty without freight qty = 1
      }

      totalQty =
          invoiceLines
              .stream()
              .filter(t -> t.getProduct().getId() != 8931L)
              .map(InvoiceLine::getQty)
              .reduce(BigDecimal.ZERO, BigDecimal::add);
      splittingQty =
          invoiceLines
              .stream()
              .collect(
                  Collectors.groupingBy(
                      t -> t.getProduct(),
                      Collectors.summingDouble(o -> o.getQty().doubleValue())));

      if (importationFolder.getValorisation() == 1) {
        splitting =
            invoiceLines
                .stream()
                .collect(
                    Collectors.groupingBy(
                        t -> t.getProduct(),
                        Collectors.summingDouble(o -> o.getInTaxTotal().doubleValue())));
      } else if (importationFolder.getValorisation() == 2) {
        splitting =
            invoiceLines
                .stream()
                .collect(
                    Collectors.groupingBy(
                        t -> t.getProduct(),
                        Collectors.summingDouble(o -> o.getQty().doubleValue())));
      } else if (importationFolder.getValorisation() == 3) {
        splitting =
            stockMoveLines
                .stream()
                .collect(
                    Collectors.groupingBy(
                        t -> t.getProduct(),
                        Collectors.summingDouble(o -> o.getNetMass().doubleValue())));

      } else if (importationFolder.getValorisation() == 4) {
        splitting =
            stockMoveLines
                .stream()
                .collect(
                    Collectors.groupingBy(
                        t -> t.getProduct(),
                        Collectors.summingDouble(o -> o.getVolume().doubleValue())));
      }

      List<Invoice> invoices =
          importationFolder
              .getInvoices()
              .stream()
              .filter(t -> !t.getIsImportationPartnerInvoice())
              .collect(Collectors.toList());
      BigDecimal totalApproachs =
          invoices.stream().map(Invoice::getInTaxTotal).reduce(BigDecimal.ZERO, BigDecimal::add);

      for (Product product : productSet) {
        Stream<InvoiceLine> invoiceLineStream =
            invoiceLines.stream().filter(t -> t.getProduct() == product);

        BigDecimal productQty = new BigDecimal(splitting.get(product));
        BigDecimal productQty2 = new BigDecimal(splittingQty.get(product));
        BigDecimal freightSplit = BigDecimal.ZERO;
        // BigDecimal freightPerInvoiceForProduct=
        // invoiceLineStream.findFirst().get().getInvoice().getInvoiceLineList().stream().filter(t
        // -> t.getProduct().getId() == 8931L).findFirst().get().getInTaxTotal();

        // total per product
        BigDecimal totalInvoiceProduct =
            invoiceLineStream
                .map(InvoiceLine::getInTaxTotal)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        BigDecimal percent = BigDecimal.ZERO;

        if (totalInvoiceWithoutFreight.compareTo(BigDecimal.ZERO) == 0) {
          percent = productQty.divide(totalQty, scale, RoundingMode.HALF_EVEN);
        } else {
          switch (importationFolder.getValorisation()) {
            case 1:
              percent =
                  totalInvoiceProduct.divide(
                      totalInvoiceWithoutFreight, scale, RoundingMode.HALF_EVEN);
              break;
            case 2:
              percent = productQty.divide(totalQty, scale, RoundingMode.HALF_EVEN);
              break;
            case 3:
              percent = productQty.divide(totalNetMass, scale, RoundingMode.HALF_EVEN);
              break;
            case 4:
              percent = productQty.divide(totalVolume, scale, RoundingMode.HALF_EVEN);
              break;
            default:
              break;
          }
        }

        freightSplit = freight.multiply(percent).setScale(scale, RoundingMode.HALF_EVEN);

        BigDecimal totalApproachsPerProduct =
            totalApproachs.multiply(percent).setScale(scale, RoundingMode.HALF_EVEN);

        BigDecimal allPerProduct =
            totalApproachsPerProduct.add(totalInvoiceProduct).add(freightSplit);

        costPrice = allPerProduct.divide(productQty2, scale, RoundingMode.HALF_EVEN);

        message += "Cost price of " + product.getName() + " is " + costPrice + " || ";

        List<StockMoveLine> lines =
            stockMoveLines
                .stream()
                .filter(t -> t.getProduct() == product)
                .collect(Collectors.toList());
        for (StockMoveLine line : lines) {
          this.computeCostPriceAndPersist(
              importationFolder,
              line,
              freightSplit,
              percent,
              totalApproachsPerProduct,
              totalInvoiceProduct,
              costPrice);
        }
      }
    } else {

      List<Invoice> invoices = importationFolder.getInvoices();
      BigDecimal percent = BigDecimal.ZERO;
      BigDecimal inTaxTotal =
          invoices
              .stream()
              .map(Invoice::getInTaxTotal)
              .reduce(BigDecimal.ZERO, BigDecimal::add)
              .setScale(scale, RoundingMode.HALF_UP);
      BigDecimal totalQty =
          stockMoveLines
              .stream()
              .map(StockMoveLine::getRealQty)
              .reduce(BigDecimal.ZERO, BigDecimal::add);

      costPrice = inTaxTotal.divide(totalQty, scale, RoundingMode.HALF_UP);

      // this.resetCostPriceList(importationFolder);

      for (StockMoveLine stockMoveLine : stockMoveLines) {
        this.computeCostPriceAndPersist(
            importationFolder,
            stockMoveLine,
            BigDecimal.ZERO,
            BigDecimal.ONE,
            BigDecimal.ZERO,
            BigDecimal.ZERO,
            costPrice);
      }

      message = "CostPrice is : " + costPrice.toString();
    }

    return message;
  }

  @Transactional
  public void setStockMoveLineCurrenyRate(
      List<StockMoveLine> stockMoveLineList, BigDecimal currencyRate) {
    for (StockMoveLine stockMoveLine : stockMoveLineList) {
      stockMoveLine.setCurrencyRate(currencyRate);
      Beans.get(StockMoveLineRepository.class).save(stockMoveLine);
    }
  }

  @Transactional
  public void setStockMoveLineFreight(List<StockMoveLine> stockMoveLineList, BigDecimal freight) {
    for (StockMoveLine stockMoveLine : stockMoveLineList) {
      stockMoveLine.setFreight(freight);
      Beans.get(StockMoveLineRepository.class).save(stockMoveLine);
    }
  }

  @Transactional
  public void resetCostPriceList(ImportationFolder importationFolder) {
    importationFolder.getImportationFolderCostPriceList().clear();
  }

  @Transactional
  public void computeCostPriceAndPersist(
      ImportationFolder importationFolder,
      StockMoveLine stockMoveLine,
      BigDecimal freightSplit,
      BigDecimal precent,
      BigDecimal totalApproachsPerProduct,
      BigDecimal totalInvoiceProduct,
      BigDecimal costPrice) {

    ImportationFolderCostPrice importationFolderCostPrice = new ImportationFolderCostPrice();
    importationFolderCostPrice.setImportationFolder(importationFolder);
    importationFolderCostPrice.setStockMoveLine(stockMoveLine);
    importationFolderCostPrice.setCostPrice(costPrice.setScale(4, RoundingMode.HALF_EVEN));
    importationFolderCostPrice.setValorisation(importationFolder.getValorisation());
    importationFolderCostPrice.setPercent(
        precent.multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_EVEN));
    importationFolderCostPrice.setFreightSplit(freightSplit.setScale(2, RoundingMode.HALF_EVEN));
    importationFolderCostPrice.setTotalApproach(
        totalApproachsPerProduct.setScale(2, RoundingMode.HALF_EVEN));
    importationFolderCostPrice.setTotalInvoice(
        totalInvoiceProduct.setScale(2, RoundingMode.HALF_EVEN));
    importationFolderCostPrice.setProduct(stockMoveLine.getProduct());
    importationFolder.addImportationFolderCostPriceListItem(importationFolderCostPrice);
    importationFolderRepository.save(importationFolder);
  }

  // public void valisateCostPrice(ActionRequest request, ActionResponse response) {
  @Transactional
  public void validateCostPrice(ImportationFolderCostPrice importationFolderCostPrice) {

    ImportationFolderCostPriceRepository importationFolderCostPriceRepository =
        Beans.get(ImportationFolderCostPriceRepository.class);

    StockMove stockMove = importationFolderCostPrice.getStockMoveLine().getStockMove();
    Long productId = importationFolderCostPrice.getProduct().getId();
    Long stockMoveId = stockMove.getId();
    LocalDate toDate = LocalDate.now();
    BigDecimal costPrice = importationFolderCostPrice.getCostPrice();

    try {
      Beans.get(StockMoveLineServiceSupplychainImpl.class)
          .resetValorization(productId, stockMoveId, toDate, false);
      Beans.get(StockMoveLineServiceSupplychainImpl.class)
          .fillStockMoveLines(productId, toDate, stockMoveId, false);
      Beans.get(StockMoveLineServiceSupplychainImpl.class)
          .valorize(productId, stockMoveId, toDate, costPrice, false, false);
      importationFolderCostPrice.setStatusSelect(2);
      importationFolderCostPrice.setValidationDate(LocalDate.now());
      importationFolderCostPriceRepository.save(importationFolderCostPrice);
      // response.setReload(true);
    } catch (Exception e) {
      logger.debug(e.toString());
    }
  }

  @Transactional
  public void setStockMoveLineNetMass(List<StockMoveLine> stockMoveLineList, BigDecimal netMass) {
    for (StockMoveLine stockMoveLine : stockMoveLineList) {
      stockMoveLine.setNetMass(netMass);
      Beans.get(StockMoveLineRepository.class).save(stockMoveLine);
    }
  }

  @Transactional
  public void setStockMoveLineVolume(List<StockMoveLine> stockMoveLineList, BigDecimal volume) {
    for (StockMoveLine stockMoveLine : stockMoveLineList) {
      stockMoveLine.setVolume(volume);
      Beans.get(StockMoveLineRepository.class).save(stockMoveLine);
    }
  }

  @Transactional
  public void rejectImportationFolder(ImportationFolder importationFolder, String rejectionRaison) {

    importationFolder.setStatusSelect(ImportationFolderRepository.STATUS_REJECTED);
    importationFolder.setRejectionRaison(rejectionRaison);
    importationFolder.setRejectedDate(LocalDate.now());
    importationFolder.setRejectedByUser(AuthUtils.getUser());
    importationFolder.setRejectedInstanceSelect(1);
    importationFolderRepository.save(importationFolder);
  }

  @Transactional
  public Invoice generateFromModel(
      ImportationFolder importationFolder, InvoiceTemplate invoiceTemplate) throws AxelorException {
    Invoice invoice =
        Beans.get(InvoiceTemplateService.class).generateInvoiceFromTemplate(invoiceTemplate);
    invoice.setImportationFolder(importationFolder);
    invoice.setIsInvoiceApproach(true);
    return Beans.get(InvoiceRepository.class).save(invoice);
  }
}
