/*
 * Axelor Business Solutions
 *
 * Copyright (C) 2019 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.suppliermanagement.web;

import com.axelor.apps.base.db.Company;
import com.axelor.apps.base.db.repo.BlockingRepository;
import com.axelor.apps.base.service.BlockingService;
import com.axelor.apps.purchase.db.PurchaseOrder;
import com.axelor.apps.purchase.db.PurchaseOrderLine;
import com.axelor.apps.purchase.db.repo.PurchaseOrderLineRepository;
import com.axelor.apps.purchase.service.app.AppPurchaseService;
import com.axelor.apps.suppliermanagement.db.PurchaseOrderSupplierLine;
import com.axelor.apps.suppliermanagement.db.repo.PurchaseOrderSupplierLineRepository;
import com.axelor.apps.suppliermanagement.service.PurchaseOrderSupplierLineService;
import com.axelor.apps.purchase.service.PurchaseOrderService;
import com.axelor.exception.service.TraceBackService;
import com.axelor.inject.Beans;
import com.axelor.rpc.ActionRequest;
import com.axelor.rpc.ActionResponse;
import com.google.common.base.Strings;
import com.google.inject.Singleton;
import java.util.stream.Collectors;
import com.axelor.meta.schema.actions.ActionView;


@Singleton
public class PurchaseOrderSupplierLineController {

  public void showPurchaseOrder(ActionRequest request, ActionResponse response) {
    PurchaseOrderSupplierLine purchaseOrderSupplierLine = Beans.get(PurchaseOrderSupplierLineRepository.class)
        .find(request.getContext().asType(PurchaseOrderSupplierLine.class).getId());
    PurchaseOrder purchaseOrder = purchaseOrderSupplierLine.getPurchaseOrderLine().getPurchaseOrder();
    response.setView(
        ActionView.define("Devis fournisseur")
            .model(PurchaseOrder.class.getName())
            .add("form", "purchase-order-form")
            .param("show-toolbar", "false")
            .param("show-confirm", "false")
            .param("popup-save", "false")
            .param("popup", "true")
            .context("_showRecord", String.valueOf(purchaseOrder.getId()))
            .map());
  }

  public void accept(ActionRequest request, ActionResponse response) {

    PurchaseOrderSupplierLine purchaseOrderSupplierLine =
        Beans.get(PurchaseOrderSupplierLineRepository.class)
            .find(request.getContext().asType(PurchaseOrderSupplierLine.class).getId());

    if (purchaseOrderSupplierLine.getPurchaseOrderLine() == null
        && request.getContext().getParent() != null) {
      purchaseOrderSupplierLine.setPurchaseOrderLine(
          Beans.get(PurchaseOrderLineRepository.class)
              .find(request.getContext().getParent().asType(PurchaseOrderLine.class).getId()));
    }

     // sophal refresh purchase order price
     PurchaseOrder order = purchaseOrderSupplierLine.getPurchaseOrderLine().getPurchaseOrder();

    try {
      Beans.get(PurchaseOrderSupplierLineService.class).accept(purchaseOrderSupplierLine);
       // sophal refresh purchase order price
       Beans.get(PurchaseOrderService.class).computePurchaseOrder(order);
       Beans.get(PurchaseOrderService.class).updateCostPrice(order);
      // response.setReload(true);
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void refuse(ActionRequest request, ActionResponse response) {
    
    PurchaseOrderSupplierLine purchaseOrderSupplierLine =
        Beans.get(PurchaseOrderSupplierLineRepository.class)
            .find(request.getContext().asType(PurchaseOrderSupplierLine.class).getId());
    try {
      Beans.get(PurchaseOrderSupplierLineService.class).refuse(purchaseOrderSupplierLine);
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }
  
  /**
   * Called on supplier partner select. Set the domain for the field supplierPartner
   *
   * @param request
   * @param response
   */
  public void supplierPartnerDomain(ActionRequest request, ActionResponse response) {
    PurchaseOrderSupplierLine purchaseOrderSupplierLine =
        request.getContext().asType(PurchaseOrderSupplierLine.class);

    PurchaseOrderLine purchaseOrderLine = purchaseOrderSupplierLine.getPurchaseOrderLine();
    if (purchaseOrderLine == null) {
      purchaseOrderLine = request.getContext().getParent().asType(PurchaseOrderLine.class);
    }

    PurchaseOrder purchaseOrder = purchaseOrderLine.getPurchaseOrder();
    if (purchaseOrder == null) {
      purchaseOrder = request.getContext().getParent().getParent().asType(PurchaseOrder.class);
    }
    Company company = purchaseOrder.getCompany();

    String domain = "";
    if (Beans.get(AppPurchaseService.class).getAppPurchase().getManageSupplierCatalog()
        && purchaseOrderLine.getProduct() != null
        && !purchaseOrderLine.getProduct().getSupplierCatalogList().isEmpty()) {
      domain +=
          "self.id != "
              + company.getPartner().getId()
              + " AND self.id IN "
              + purchaseOrderLine
                  .getProduct()
                  .getSupplierCatalogList()
                  .stream()
                  .map(s -> s.getSupplierPartner().getId())
                  .collect(Collectors.toList())
                  .toString()
                  .replace('[', '(')
                  .replace(']', ')');

      String blockedPartnerQuery =
          Beans.get(BlockingService.class)
              .listOfBlockedPartner(company, BlockingRepository.PURCHASE_BLOCKING);

      if (!Strings.isNullOrEmpty(blockedPartnerQuery)) {
        domain += String.format(" AND self.id NOT in (%s)", blockedPartnerQuery);
      }
    } else {
      domain += "self.id = 0";
    }

    domain += " AND " + company.getId() + " in (SELECT id FROM self.companySet)";

    response.setAttr("supplierPartner", "domain", domain);
  }
}
