/*
 * Axelor Business Solutions
 *
 * Copyright (C) 2017 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;

import java.math.BigDecimal;
import java.util.Map;
import java.util.List;

import com.axelor.apps.account.db.Invoice;
import com.axelor.apps.account.db.InvoiceLine;
import com.axelor.apps.account.service.AnalyticMoveLineService;
import com.axelor.apps.account.service.app.AppAccountService;
import com.axelor.apps.account.service.invoice.InvoiceLineService;
import com.axelor.apps.base.db.IPriceListLine;
import com.axelor.apps.base.db.PriceList;
import com.axelor.apps.base.db.PriceListLine;
import com.axelor.apps.base.db.Product;
import com.axelor.apps.base.db.Unit;
import com.axelor.apps.base.db.repo.AppBaseRepository;
import com.axelor.apps.base.service.CurrencyService;
import com.axelor.apps.base.service.PriceListService;
import com.axelor.apps.base.service.tax.AccountManagementService;
import com.axelor.apps.purchase.service.PurchaseProductService;
import com.axelor.apps.base.service.ProductService;
import com.google.inject.Inject;
import com.axelor.apps.purchase.db.SupplierCatalog;
import com.axelor.apps.purchase.db.repo.SupplierCatalogRepository;
import com.axelor.apps.account.db.repo.InvoiceRepository;
import com.axelor.inject.Beans;


public class InvoiceLineSupplychainService extends InvoiceLineService  {
	
	protected PurchaseProductService purchaseProductService;

	@Inject
	public InvoiceLineSupplychainService(AccountManagementService accountManagementService, CurrencyService currencyService, PriceListService priceListService, 
			AppAccountService appAccountService, AnalyticMoveLineService analyticMoveLineService, ProductService productService)  {
		
		super(accountManagementService, currencyService, priceListService, appAccountService, analyticMoveLineService, productService);
		
	}
	
	@Override
	public Unit getUnit(Product product, boolean isPurchase){
		if(isPurchase){
			if(product.getPurchasesUnit() != null){
				return product.getPurchasesUnit();
			}
			else{
				return product.getUnit();
			}
		}
		else{
			if(product.getSalesUnit() != null){
				return product.getPurchasesUnit();
			}
			else{
				return product.getUnit();
			}
		}
	}
	
	@Override
	public Map<String,Object> getDiscount(Invoice invoice, InvoiceLine invoiceLine, BigDecimal price)  {
		
		PriceList priceList = invoice.getPriceList();
		BigDecimal discountAmount = BigDecimal.ZERO;
		Map<String, Object> discounts = null;
		
		int computeMethodDiscountSelect = appAccountService.getAppBase().getComputeMethodDiscountSelect();

		if(priceList != null)  {
			int discountTypeSelect = 0;
			
			PriceListLine priceListLine = this.getPriceListLine(invoiceLine, priceList);
			if(priceListLine!=null){
				discountTypeSelect = priceListLine.getTypeSelect();
			}

			discounts = priceListService.getDiscounts(priceList, priceListLine, price);
			discountAmount = (BigDecimal) discounts.get("discountAmount");
			
			if((computeMethodDiscountSelect == AppBaseRepository.INCLUDE_DISCOUNT_REPLACE_ONLY && discountTypeSelect == IPriceListLine.TYPE_REPLACE) 
					|| computeMethodDiscountSelect == AppBaseRepository.INCLUDE_DISCOUNT)  {
				discounts.put("price", priceListService.computeDiscount(price, (int) discounts.get("discountTypeSelect"), discountAmount));
			}
		}

		if (invoice.getOperationTypeSelect() < InvoiceRepository.OPERATION_TYPE_CLIENT_SALE && discountAmount.compareTo(BigDecimal.ZERO) == 0){
			List<SupplierCatalog> supplierCatalogList = invoiceLine.getProduct().getSupplierCatalogList();
			if(supplierCatalogList != null && !supplierCatalogList.isEmpty()){
				SupplierCatalog supplierCatalog = Beans.get(SupplierCatalogRepository.class).all().filter("self.product = ?1 AND self.minQty <= ?2 AND self.supplierPartner = ?3 ORDER BY self.minQty DESC",invoiceLine.getProduct(),invoiceLine.getQty(),invoice.getPartner()).fetchOne();
				if(supplierCatalog != null){
					
					discounts = purchaseProductService.getDiscountsFromCatalog(supplierCatalog,price);

					if(computeMethodDiscountSelect != AppBaseRepository.DISCOUNT_SEPARATE){
						discounts.put("price", priceListService.computeDiscount(price, (int) discounts.get("discountTypeSelect"), (BigDecimal) discounts.get("discountAmount")));
					}
				}
			}
		}
		return discounts;
	}
}

@@ -1127,17 +1127,16 @@
 base.db.
-I
 PriceLis
@@ -1140,100 +1140,8 @@
 List
-Line;%0Aimport com.axelor.apps.base.db.PriceList;%0Aimport com.axelor.apps.base.db.PriceListLine
 ;%0Aim
@@ -2950,51 +2950,8 @@
 RO;%0A
-%09%09Map%3CString, Object%3E discounts = null;%0A%09%09%0A
 %09%09in
@@ -3051,308 +3051,81 @@
 ();%0A
-%0A
 %09%09
-if(priceList != null)  %7B%0A%09%09%09int discountTypeSelect = 0;%0A%09%09%09%0A%09%09%09PriceListLine priceListLine = this.getPriceListLine(invoiceLine, priceList);%0A%09%09%09if(priceListLine!=null)%7B%0A%09%09%09%09discountTypeSelect = priceListLine.getTypeSelect();%0A%09%09%09%7D%0A%0A%09%09%09discounts = priceListService.getDiscounts(priceList, pr
+%0A%09%09Map%3CString, Object%3E discounts = super.getDiscount(invoice, invo
 iceLi
-stLi
 ne, 
@@ -3138,296 +3138,34 @@
 ;%0A%09%09
-%09discountAmount = (BigDecimal) discounts.get(%22discountAmount%22);%0A%09%09%09%0A%09%09%09if((computeMethodDiscountSelect == AppBaseRepository.INCLUDE_DISCOUNT_REPLACE_ONLY && discountTypeSelect == IPriceListLine.TYPE_REPLACE) %0A%09%09%09%09%09%7C%7C computeMethodDiscountSelect == AppBaseRepository.INCLUDE_DISCOUNT)  
+%0A%09%09if(priceList != null)
 %7B%0A
-%09
 %09%09%09d
@@ -3175,67 +3175,28 @@
 ount
-s.put(%22price%22, priceListService.computeDiscount(price, (int
+Amount = (BigDecimal
 ) di
@@ -3208,38 +3208,16 @@
 ts.get(%22
-discountTypeSelect%22), 
 discount
@@ -3226,21 +3226,18 @@
 ount
-)
+%22
 );%0A
-%09%09%09%7D%0A
 %09%09%7D%0A
+%09%09
 %0A%09%09i

fix in RM#8856