/**
 * Axelor Business Solutions
 * <p>
 * Copyright (C) 2017 Axelor (<http://axelor.com>).
 * <p>
 * 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.
 * <p>
 * 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.
 * <p>
 * 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.account.service;

import com.axelor.apps.account.db.AccountManagement;
import com.axelor.apps.account.db.AccountingSituation;
import com.axelor.apps.account.db.PaymentMode;
import com.axelor.apps.account.db.repo.PaymentModeRepository;
import com.axelor.apps.account.service.payment.PaymentModeService;
import com.axelor.apps.base.db.BankDetails;
import com.axelor.apps.base.db.Company;
import com.axelor.apps.base.db.Partner;
import com.axelor.apps.base.service.BankDetailsServiceImpl;
import com.axelor.apps.base.service.administration.GeneralService;
import com.axelor.apps.tool.StringTool;
import com.axelor.inject.Beans;

import java.util.ArrayList;
import java.util.List;

public class BankDetailsServiceAccountImpl extends BankDetailsServiceImpl {

    /**
     * In this implementation, we use the O2M in payment mode.
     * @param company
     * @param paymentMode
     * @return
     */
    @Override
    public String createCompanyBankDetailsDomain(Company company,
                                                 PaymentMode paymentMode) {

        if (!Beans.get(GeneralService.class).getGeneral().getManageMultiBanks()) {
            return super.createCompanyBankDetailsDomain(company, paymentMode);
        } else {
            if (paymentMode == null) {
                return "self.id IN (0)";
            }
            List<AccountManagement> accountManagementList = paymentMode.getAccountManagementList();

            List<BankDetails> authorizedBankDetails = new ArrayList<>();

            for (AccountManagement accountManagement : accountManagementList) {
                if (accountManagement.getCompany() != null
                        && accountManagement.getCompany().equals(company)) {
                    authorizedBankDetails.add(accountManagement.getBankDetails());
                }
            }
            if (authorizedBankDetails.isEmpty()) {
                return "self.id IN (0)";
            } else {
                return "self.id IN ("
                        + StringTool.getIdFromCollection(authorizedBankDetails)
                        + ") AND self.active = true";
            }
        }
    }

	/**
	 * Find a default bank details.
	 * @param company
	 * @param paymentMode
	 * @param partner
	 * @return  the default bank details in accounting situation if it is active
	 *          and allowed by the payment mode, or an authorized bank details if
     *          he is the only one authorized.
	 */
    @Override
    public BankDetails getDefaultCompanyBankDetails(Company company,
                                                    PaymentMode paymentMode,
                                                    Partner partner) {

        if (paymentMode == null) {
            return null;
        }

        BankDetails candidateBankDetails = getDefaultCompanyBankDetailsFromPartner(company, paymentMode, partner);

        List<BankDetails>authorizedBankDetails = Beans.get(PaymentModeService.class).
                getCompatibleBankDetailsList(paymentMode, company);
        if (candidateBankDetails != null
                && authorizedBankDetails.contains(candidateBankDetails)
                && candidateBankDetails.getActive()) {
            return candidateBankDetails;
        }
        //we did not find a bank details in accounting situation
        else {
            if (authorizedBankDetails.size() == 1) {
                return authorizedBankDetails.get(0);
            } else {
                return null;
            }
        }
    }

    /**
     * Looks for the bank details in accounting situation.
     * @param company
     * @param paymentMode
     * @param partner
     * @return The bank details corresponding to the partner and the company
     *         with the right payment mode
     *         null if the partner is null or the accounting situation empty
     */
    protected BankDetails getDefaultCompanyBankDetailsFromPartner(Company company,
                                                                  PaymentMode paymentMode,
                                                                  Partner partner) {

        if (partner == null) {
            return null;
        }
        AccountingSituation accountingSituation = Beans
                .get(AccountingSituationService.class)
                .getAccountingSituation(partner, company);
        if (accountingSituation == null) {
            return null;
        }

        BankDetails candidateBankDetails = null;
        if (paymentMode.getInOutSelect() == PaymentModeRepository.IN) {
            candidateBankDetails = accountingSituation.getCompanyInBankDetails();
        } else if (paymentMode.getInOutSelect() == PaymentModeRepository.OUT) {
            candidateBankDetails = accountingSituation.getCompanyOutBankDetails();
        }
        return candidateBankDetails;
    }
}

@@ -3414,32 +3414,222 @@
 ner partner) %7B%0A%0A
+        if (!Beans.get(GeneralService.class).getGeneral().getManageMultiBanks()) %7B%0A            return super.getDefaultCompanyBankDetails(company, paymentMode, partner);%0A        %7D else %7B%0A    
         if (paym
@@ -3639,32 +3639,36 @@
 Mode == null) %7B%0A
+    
             retu
@@ -3676,35 +3676,43 @@
 n null;%0A        
-%7D%0A%0A
+    %7D%0A%0A    
         BankDeta
@@ -3811,32 +3811,36 @@
 tner);%0A%0A        
+   
+ 
 List%3CBankDetails
@@ -3840,16 +3840,17 @@
 Details%3E
+ 
 authoriz
@@ -3918,16 +3918,20 @@
         
+   
+ 
 getCompa
@@ -3978,24 +3978,28 @@
 y);%0A        
+   
+ 
 if (candidat
@@ -4011,32 +4011,36 @@
 Details != null%0A
+    
                 
@@ -4111,16 +4111,20 @@
         
+   
+ 
 && candi
@@ -4158,32 +4158,36 @@
 ) %7B%0A            
+    
 return candidate
@@ -4195,24 +4195,28 @@
 ankDetails;%0A
+    
         %7D%0A  
@@ -4221,16 +4221,20 @@
         
+    
 //we did
@@ -4282,16 +4282,20 @@
 tuation%0A
+    
         
@@ -4305,32 +4305,36 @@
 e %7B%0A            
+    
 if (authorizedBa
@@ -4370,24 +4370,28 @@
             
+    
 return autho
@@ -4419,32 +4419,36 @@
 0);%0A            
+ 
+   
 %7D else %7B%0A       
@@ -4432,32 +4432,36 @@
        %7D else %7B%0A
+    
                 
@@ -4465,32 +4465,50 @@
    return null;%0A
+                %7D%0A
             %7D%0A  

Fix default bankdetails with no multibanks