from django.contrib.auth import authenticate, login
from django.contrib.auth.decorators import login_required
import json
from django.shortcuts import redirect, render, HttpResponse

from django.views import View
from .forms import ProduitForm,ArticleFilterForm
from django.contrib import messages
import xmlrpc.client
from django.db.models import Sum
from collections import defaultdict
from .models import Category_user_set
url = 'https://bms.insidjam.com'  # Odoo URL
db = 'BMS_PROD'  # Database name
common = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/common')
uid = -1
password =''
models = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/object')
product_couvetutre = []
Stock_min = []
categories = []
Articles_PF = []
Articles_MP = []
Boms = []
Bom_Lines = []
# Define the object you want to interact with
cat_imporation = ""
cat_imporation_id = 0

current_company_id = -1

selected_id =[]
# Create your views here.
result_prd = []
pdp_items=[]
pdp_simulet_items=[]
stock_min_erp = []

lot_prd = []
prodcuts_semulatePF = []
prodcuts_pdp_semulateMP = []
username_erp =''
username = ''
def login_view(request):
    if request.user.is_authenticated:
        return redirect('produits:index')
    
    
    if request.method == 'POST':
        global password,username
        username = request.POST['username']
        
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)  # Connecter l'utilisateur
            global common
            global uid
            uid = common.authenticate(db, username, password, {})
            champs_CAT = ['id','name','parent_id']
            context1 = {'lang': 'en_US'}
            global models
            global categories
            categories = models.execute_kw(db, uid, password, 'product.category', 'search_read', [[]], {'fields': champs_CAT, 'context': context1})
            #print(categories)

            
            user = models.execute_kw(db, uid, password,
                             'res.users', 'read',
                             [uid], {'fields': ['company_id','name']})
            
            global current_company_id, username_erp
            current_company_id = user['company_id'][0]
            username_erp = user['name']


            
            #print(f"ID de la compagnie actuelle : {user['company_id'][0]}")


            global cat_imporation_id
            cat_imporation_id = get_cat_impo_id(uid)
            #print(cat_imporation_id)

            dom_SM = [('product_id.categ_id.parent_id.name', 'ilike', get_cat_pf(uid)),('product_id.sale_ok', '=', True),('product_min_qty', '>', 0)]
            champs_SM = ['product_min_qty','product_id']
            global Stock_min
            Stock_min = models.execute_kw(
                db, uid, password,
                'stock.rule', 'search_read',  # Odoo model name and method
                [dom_SM],  # Domain for filtering the records (empty list fetches all)
                {'fields': champs_SM}  # Fields you want to retrieve
            )

            #dom_PF = [('categ_id.parent_id.name', 'ilike', get_cat_pf(uid)),('sale_ok', '=', True),('bom_ids.id', '!=', False)]
            dom_PF = [('categ_id.parent_id.name', 'ilike', get_cat_pf(uid)),('sale_ok', '=', True),('bom_ids.id', '!=', False)]
            champs_PF = ['id','default_code','name','qty_available','virtual_available']
            global Articles_PF
            Articles_PF = models.execute_kw(
                db, uid, password,
                'product.product', 'search_read',  # Odoo model name and method
                [dom_PF],  # Domain for filtering the records (empty list fetches all)
                {'fields': champs_PF,  # Champs à récupérer
                 'context': {'lang': 'fr_FR'}}  # Fields you want to retrieve
            )

            dom_BM = [('product_id.categ_id.parent_id.name', 'ilike', get_cat_pf(uid))]
            champs_BM = [ 'id','code', 'product_qty', 'product_id','bom_line_ids','sequence','name']
            context1 = {'lang': 'en_US'}  # Example context
            global Boms
            Boms = models.execute_kw(db, uid, password, 'mrp.bom', 'search_read', [dom_BM], {'fields': champs_BM, 'context': context1})
            
            global Bom_Lines
           
            fields6 = ['product_id', 'product_qty']
            for bom in Boms:
                bom_lines = models.execute_kw(db, uid, password, 'mrp.bom.line', 'read', [bom['bom_line_ids']], {'fields': fields6})
                x={
                    'bom_id':bom['id'],
                    'bom_lines':bom_lines
                }
                Bom_Lines.append(x)

           
            article_mp_ids_tmp = []
            for bl in Bom_Lines:
                for art_id in bl['bom_lines']:
                    article_mp_ids_tmp.append(art_id['product_id'][0])            

            article_mp_ids = list(set(article_mp_ids_tmp))           

            dom_MP = [['id','in',article_mp_ids]]
            champs_MP = ['id','default_code','name','qty_available','virtual_available','categ_id','sale_ok','purchase_ok']
            global Articles_MP
            Articles_MP = models.execute_kw(
                db, uid, password,
                'product.product', 'search_read',  # Odoo model name and method
                [dom_MP],  # Domain for filtering the records (empty list fetches all)
                {'fields': champs_MP,  # Champs à récupérer
                 'context': {'lang': 'fr_FR'}}  # Fields you want to retrieve
            )
            

            """ #dom_MP = [['product_id.id','in',article_mp_ids],['qty_lot','>',0]]
            dom_MP = [['product_id.id','=',22859],['qty_lot','>',0]]
            champs_MP = ['id','name','product_id','qty_lot']
            global lot_prd
            lot_prd = models.execute_kw(
                db, uid, password,
                'stock.production.lot', 'search_read',  # Odoo model name and method
                [dom_MP],  # Domain for filtering the records (empty list fetches all)
                {'fields': champs_MP}  # Fields you want to retrieve
            )

            print(lot_prd) """

            return redirect('produits:index')
        else:
            messages.error(request, "Nom d'utilisateur ou mot de passe incorrect")

    return render(request, 'login.html')



def username_erp_name(request):
    global username_erp
    return HttpResponse(username_erp)
    


def refresh_data(request):
    global uid
    global password    
    champs_CAT = ['id','name','parent_id']
    context1 = {'lang': 'en_US'}
    global models
    global categories
    categories = models.execute_kw(db, uid, password, 'product.category', 'search_read', [], {'fields': champs_CAT, 'context': context1})
    #print(categories)
    
    global cat_imporation_id
    cat_imporation_id = get_cat_impo_id(uid)
    #print(cat_imporation_id)

    user = models.execute_kw(db, uid, password,
                             'res.users', 'read',
                             [uid], {'fields': ['company_id']})
            
    global current_company_id
    current_company_id = user['company_id'][0]

    dom_SM = [('product_id.categ_id.parent_id.name', 'ilike', get_cat_pf(uid)),('product_id.sale_ok', '=', True),('product_min_qty', '>', 0)]
    champs_SM = ['product_min_qty','product_id']
    global Stock_min
    Stock_min = models.execute_kw(
        db, uid, password,
        'stock.rule', 'search_read',  # Odoo model name and method
        [dom_SM],  # Domain for filtering the records (empty list fetches all)
        {'fields': champs_SM}  # Fields you want to retrieve
    )

    dom_PF = [('categ_id.parent_id.name', 'ilike', get_cat_pf(uid)),('sale_ok', '=', True),('bom_ids.id', '!=', False)]
    champs_PF = ['id','default_code','name','qty_available','virtual_available']
    global Articles_PF
    Articles_PF = models.execute_kw(
        db, uid, password,
        'product.product', 'search_read',  # Odoo model name and method
        [dom_PF],  # Domain for filtering the records (empty list fetches all)
        {'fields': champs_PF}  # Fields you want to retrieve
    )

    dom_BM = [('product_id.categ_id.parent_id.name', 'ilike', get_cat_pf(uid))]
    champs_BM = [ 'id','code', 'product_qty', 'product_id','bom_line_ids','sequence','name']
    context1 = {'lang': 'en_US'}  # Example context
    global Boms
    Boms = models.execute_kw(db, uid, password, 'mrp.bom', 'search_read', [dom_BM], {'fields': champs_BM, 'context': context1})
    
    
    global Bom_Lines
    
    fields6 = ['product_id', 'product_qty']
    for bom in Boms:
        bom_lines = models.execute_kw(db, uid, password, 'mrp.bom.line', 'read', [bom['bom_line_ids']], {'fields': fields6})
        x={
            'bom_id':bom['id'],
            'bom_lines':bom_lines
        }
        Bom_Lines.append(x)

    
    article_mp_ids_tmp = []
    for bl in Bom_Lines:
        for art_id in bl['bom_lines']:
            article_mp_ids_tmp.append(art_id['product_id'][0])

    

    article_mp_ids = list(set(article_mp_ids_tmp))
    

    dom_MP = [['id','in',article_mp_ids]]
    champs_MP = ['id','default_code','name','qty_available','virtual_available','categ_id','sale_ok','purchase_ok']
    global Articles_MP
    Articles_MP = models.execute_kw(
        db, uid, password,
        'product.product', 'search_read',  # Odoo model name and method
        [dom_MP],  # Domain for filtering the records (empty list fetches all)
        {'fields': champs_MP}  # Fields you want to retrieve
    )
    
    return redirect('produits:index')
    
    
    
result = []  
    

def index(request,*args,**kwargs):

    name_erp = username_erp_name(request)
    form = ArticleFilterForm(request.GET or None)
    global result
    result = []  
    
    for item1 in Stock_min:
        for item2 in Articles_PF:
            if item1['product_id'][0] == item2['id']:
                prd_id = item2['id']
                prd_code = item2['default_code']
                prd_name = item2['name']
                prd_avb_st = item2['qty_available']
                prd_vrt_st = item2['virtual_available']
                prd_min = item1['product_min_qty']
                prd_ecart = prd_vrt_st-prd_min
                prd_couvrt = 0
                    
                if prd_min==0:
                    prd_couvrt = 0
                if prd_vrt_st<=0:
                    prd_couvrt = 0
                else:
                    prd_couvrt = prd_vrt_st/prd_min*100 

                
                
                prd_can_prd_max = can_prd_global_IMP(prd_id)

                

                combined_item = {'id':prd_id,'default_code':prd_code,'name':prd_name,'qty_available':prd_avb_st,'virtual_available':prd_vrt_st,'product_min_qty':prd_min,'ecar':prd_ecart,'couvert':prd_couvrt,'prd_max':prd_can_prd_max}
                result.append(combined_item)
    global result_prd
    result_prd = result

    if form.is_valid():
        if form.cleaned_data['default_code']:            
            result = [art for art in result if form.cleaned_data['default_code'].lower() in art['default_code'].lower() or form.cleaned_data['default_code'].lower() in art['name'].lower()] 
        if form.cleaned_data['chiffre']:
            if form.cleaned_data['regle']:
                if form.cleaned_data['regle'] == 'egal': 
                    result = [art for art in result if art[form.cleaned_data['chiffre']] == form.cleaned_data['val']]
                elif form.cleaned_data['regle'] =='notegal': 
                    result = [art for art in result if art[form.cleaned_data['chiffre']] != form.cleaned_data['val']] 
                elif form.cleaned_data['regle'] =='sup': 
                    result = [art for art in result if art[form.cleaned_data['chiffre']] > form.cleaned_data['val']] 
                elif form.cleaned_data['regle'] =='inf': 
                    result = [art for art in result if art[form.cleaned_data['chiffre']] < form.cleaned_data['val']]
                elif form.cleaned_data['regle'] =='supegal': 
                    result = [art for art in result if art[form.cleaned_data['chiffre']] >= form.cleaned_data['val']] 
                else:
                    result = [art for art in result if art[form.cleaned_data['chiffre']] <= form.cleaned_data['val']]
                    
                    
               
    result = sorted(result,key=lambda art: art["default_code"])
    global product_couvetutre
    product_couvetutre = result
    prodcuts_pdp_semulateMP = Articles_MP

    for p in prodcuts_pdp_semulateMP:
        p['qty_restante'] = p['virtual_available']

    #print(result)
    context = {
        'produits' : result,
        'nom':'Produits de la boutique',
        'form': form,
        'name_erp':name_erp,
        'nbr_result':len(result),
        }
    
    return render(request,'index.html',context)


code_prd=""
code_bom=""
name_prd=""
name_bom=""
can_prd = 0
should_prd = 0
prd_pdp_detail_list = []
def prd_pdp_detail(request):
    
    if request.method == "POST":
        global code_prd
        global code_bom
        global should_prd
        code_prd = request.POST.get('code_prd','')
        code_bom = request.POST.get('code_bom','')
        print(code_prd,code_bom)
        global prd_pdp_deta
        print(prd_pdp_deta)
        prd_detail = [art for art in prd_pdp_deta if code_prd == art['default_code'] and code_bom == art['code']]
        global name_prd,name_bom
        global can_prd

        name_prd = prd_detail[0]['prd_name']
        name_bom = prd_detail[0]['bom_name']
        can_prd = prd_detail[0]['can_prd']
        should_prd = abs(prd_detail[0]['ecar'])
        #list_bom_prd_detail = [art['code'] for art in prd_pdp_deta if code_prd == art['default_code']]
        global Bom_Lines
        bomlines_prd = [bl['bom_lines'] for bl in Bom_Lines if prd_detail[0]['id'] == bl['bom_id']][0]
        global prd_pdp_detail_list
        prd_pdp_detail_list = []
        for bom_line_prd in bomlines_prd:
            cpt_id_prd = bom_line_prd['product_id'][0]
            cpt_qty_prd = get_product(cpt_id_prd)[0]['virtual_available']


            qty = cpt_qty_prd*prd_detail[0]['product_qty']/bom_line_prd['product_qty']
            x={
                'default_code':get_product(cpt_id_prd)[0]['default_code'],
                'name':get_product(cpt_id_prd)[0]['name'],
                'qty_available':get_product(cpt_id_prd)[0]['qty_available'],
                'virtual_available':get_product(cpt_id_prd)[0]['virtual_available'],
                'sale_ok':get_product(cpt_id_prd)[0]['sale_ok'],
                'purchase_ok':get_product(cpt_id_prd)[0]['purchase_ok'],
                'categ_id':get_product(cpt_id_prd)[0]['categ_id'],
                'qty':int(qty)

               }            
            prd_pdp_detail_list.append(x)
        #print(elem)
        
        #print(prd_pdp_detail_list)
    

    form = ArticleFilterForm(request.GET or None)
    game = 0
    loc_prd = 0
    prduc_prd = 0
    Stock_min_filtre1 = []
    if form.is_valid():
        global cat_imporation_id
        
        if form.cleaned_data['gamme']:
            game = 1
            Stock_min_filtre1 += [prd for prd in prd_pdp_detail_list if prd['categ_id'][0] == cat_imporation_id]
        if form.cleaned_data['loc_prd']:
            loc_prd = 1
            Stock_min_filtre1 += [prd for prd in prd_pdp_detail_list if prd['categ_id'][0] != cat_imporation_id and prd['purchase_ok']==True]
        if form.cleaned_data['prduc_prd']:
            prduc_prd = 1
            Stock_min_filtre1 += [prd for prd in prd_pdp_detail_list if prd['sale_ok']==False and prd['purchase_ok']==False]
        
    else:
         Stock_min_filtre1 = prd_pdp_detail_list
    
    Stock_min_filtre1.sort(key=lambda ap: ap['qty'])

    data = {
                'detail':Stock_min_filtre1,
                'article_pdp':code_prd,
                'name_prd':name_prd,
                'boms':name_bom,
                'can_prd':can_prd,
                'gamme':game,
                'loc_prd':loc_prd,
                'prduc_prd':prduc_prd,
                'should_prd':should_prd,
                
            }
   
    return render(request, 'prd_pdp_detail.html', data)

prd_pdp_deta = []

def can_prd_global(product_id):

    global Boms
    selected_boms = [bom for bom in Boms if bom['product_id'][0] ==product_id ]

    #print("selected bom ",selected_boms)
    list_prd_max = []
    if len(selected_boms)==0:
        return 0
    
    for bom in selected_boms:
        cp = can_product_global(bom['id'])
        
        list_prd_max.append(cp)
    
    if max(list_prd_max)<=0:
        return 0
    else:
        return max(list_prd_max)
    

def can_prd_global_IMP(product_id):

    global Boms,cat_imporation_id
    selected_boms = [bom for bom in Boms if bom['product_id'][0] ==product_id ]

    #print("selected bom ",selected_boms)
    list_prd_max = []
    if len(selected_boms)==0:
        return 0
    
    for bom in selected_boms:
        cp = can_product_IMP(bom['id'],cat_imporation_id)
        
        list_prd_max.append(cp)
    
    if max(list_prd_max)<=0:
        return 0
    else:
        return max(list_prd_max)


listeMP_Reserve = []

def GetArticleQtyReszervation(prd_id):
    global listeMP_Reserve
    #reservations = [rsvs for rsvs in listeMP_Reserve if  rsvs['id_mp'] == prd_id]

    total = sum(item['qty_reserve'] for item in listeMP_Reserve if item['id_mp']  == prd_id)
    #result = next((item for item in listeMP_Reserve if item['id_mp'] == prd_id), None)
    
    return total

def Addresevation(bom_id1,qtyG):
    #print('id bom',bom_id1,type(bom_id1))

    global Boms
    bom = [bm for bm in Boms if int(bom_id1) == bm['id']]
    #print('boms',bom)
    global Bom_Lines
    bomlines_prd = [bl['bom_lines'] for bl in Bom_Lines if int(bom_id1) == bl['bom_id']][0]
    for bom_line_prd in bomlines_prd:
        cpt_id_prd = bom_line_prd['product_id'][0]
        qty = bom_line_prd['product_qty']*float(qtyG)/bom[0]['product_qty']
        x = {'id_mp':cpt_id_prd,'qty_reserve':qty}
        listeMP_Reserve.append(x)

def can_product_global_resevation(bom_id):
    
    elem = []
    global Boms
    bom = [bm for bm in Boms if int(bom_id) == bm['id']]
    global Bom_Lines
    bomlines_prd = [bl['bom_lines'] for bl in Bom_Lines if int(bom_id) == bl['bom_id']][0]
    for bom_line_prd in bomlines_prd:
        cpt_id_prd = bom_line_prd['product_id'][0]
        cpt_qty_prd = get_product(cpt_id_prd)[0]['virtual_available']-GetArticleQtyReszervation(cpt_id_prd)
        qty = cpt_qty_prd*bom[0]['product_qty']/bom_line_prd['product_qty']
        elem.append(int(qty))
    
    float_list = [float(i) for i in elem]
    
    return min(float_list)


pdp_simulet_items = []



def pdp_semulat(request):
    
    global listeMP_Reserve
    listeMP_Reserve = []
    productPF_SEMUL = []
    
    if request.method == "POST":
        global pdp_simulet_items
        pdp_simulet_items = json.loads(request.POST.get('my_list'))
        #print('liste complet',pdp_simulet_items)

    

    """ prdpfline = {'id_prd':pdp_simulet_items[0]['id_prd'],'id_bom':pdp_simulet_items[0]['id_bom'],'qty':float(pdp_simulet_items[0]['qty'])}

    productPF_SEMUL.append(prdpfline)
    y = productPF_SEMUL[0]
    #print(y)
    Addresevation(y['id_bom'],y['qty']) """

    #print(listeMP_Reserve)
    #print(GetArticleQtyReszervation(22829))
    #print('premier element',productPF_SEMUL)

    for rpf in pdp_simulet_items:
        qty_simulation = can_product_global_resevation(rpf['id_bom'])
        qty_planifie = rpf['qty']
        qty_resulat = qty_planifie
        if qty_simulation < float(qty_planifie):
            qty_resulat = qty_simulation
        
        prdpfline = {
            'id_prd':rpf['id_prd'],
            'id_bom':rpf['id_bom'],
            'qty_planifie':float(qty_planifie),
            'qty_resulat':float(qty_resulat),
        }

        #prdpfline = {'id_prd':rpf['id_prd'],'id_bom':rpf['id_bom'],'qty':can_product_global_resevation(rpf['id_bom'])}
        productPF_SEMUL.append(prdpfline)
        Addresevation(prdpfline['id_bom'],prdpfline['qty_resulat'])
    

    
    
    global  product_couvetutre  
    
    productPF_SEMUL_PDP=[]
    #print('len',product_couvetutre)
    for prd_simul in productPF_SEMUL:
        for pc in product_couvetutre:
            if int(prd_simul['id_prd'])==pc['id']:
                bom = get_bom(int(prd_simul['id_bom']))
                global uid,current_company_id
                line = {
                    'id':pc['id'],
                    'default_code':pc['default_code'],
                    'prd_name':pc['name'],
                    'qty_available':pc['qty_available'],
                    'virtual_available':pc['virtual_available'],
                    'product_min_qty':pc['product_min_qty'],
                    'ecar':pc['ecar'],
                    'qty_planifie':prd_simul['qty_planifie'],
                    'qty_resulat':prd_simul['qty_resulat'],
                    'bom_id':bom['id'],
                    'bom_code':bom['code'],
                    'bom_name':bom['name'],
                    'opr_typr':get_opr_type(uid,current_company_id)

                }
                #print('line',line)
                
                productPF_SEMUL_PDP.append(line)
    """ for p in productPF_SEMUL_PDP:
        print('data',p) """ 

    #print(listeMP_Reserve)     
    productPF_SEMUL_PDP.sort(key=lambda ap:(ap['default_code'],ap['bom_code']))
    data = {
        'products':productPF_SEMUL_PDP,
        
    }
    return render(request, 'pdp_semulat.html', data)

def pdp(request):
    form = ArticleFilterForm(request.GET or None)
    selected_prds =[]
    selected_boms =[]
    
    if request.method == "POST":
        global selected_id
        selected_id = request.POST.get('articles')

    global  product_couvetutre  
    selected_prds = [art for art in product_couvetutre if str(art['id']) in selected_id] 
    global Boms
    selected_boms = [bom for bom in Boms if str(bom['product_id'][0]) in selected_id]

    gamme =0
    gamme_uniq =0
    list_boms = []
    global cat_imporation_id
    if form.is_valid():        
        if form.cleaned_data['gamme']:
            gamme = 1   
            for bom in selected_boms:

                combined_item = {**bom,}
                


                cp = can_product_IMP(bom['id'],cat_imporation_id)
                combined_item['can_prd']=cp
                
                list_boms.append(combined_item)
        else: 
            if form.cleaned_data['gamme_uniq']: 
                gamme_uniq = 1          
                for bom in selected_boms:
                    combined_item = {**bom,}
                    cp = can_product_IMP_Uniq(bom['id'],cat_imporation_id)
                    combined_item['can_prd']=cp
                    
                    list_boms.append(combined_item)
            else:
                for bom in selected_boms:
                    combined_item = {**bom,}
                    cp = can_product_global(bom['id'])
                    combined_item['can_prd']=cp
                    
                    
                    list_boms.append(combined_item)

        
    else:
       
        for bom in selected_boms:
            combined_item = {**bom,}
            cp = can_product_global(bom['id'])
            
            combined_item['can_prd']=cp
            
            list_boms.append(combined_item)
    
    can_prd =0
    cant_prd =0
    default_code =''
    pdp_list = []
    for sp in selected_prds:
        for bm in list_boms:
             if sp['id']==bm['product_id'][0]:
                combined_item = {**sp,**bm,}
                #print('car prd',bm['can_prd'],' ecar prd',sp['ecar'])
                combined_item['ecart_pdp']=bm['can_prd']-abs(sp['ecar'])
                combined_item['prd_id']=sp['id']
                combined_item['bom_name']=bm['name']
                combined_item['prd_name']=sp['name']
                global uid
                global current_company_id
                combined_item['opr_typr']=get_opr_type(uid,current_company_id)
                pdp_list.append(combined_item)

    #print('pdp list=',pdp_list)
    
    if form.is_valid():
        if form.cleaned_data['default_code']:
            default_code = form.cleaned_data['default_code']
            pdp_list = [art for art in pdp_list if form.cleaned_data['default_code'].lower() in art['default_code'].lower() or form.cleaned_data['default_code'].lower() in art['name'].lower()] 
        if form.cleaned_data['can_prd']:
            can_prd =1
            pdp_list = [art for art in pdp_list if art['can_prd']>0] 
        if form.cleaned_data['cant_prd']:
            cant_prd =1
            pdp_list = [art for art in pdp_list if art['can_prd']<=0] 
        
    pdp_list.sort(key=lambda ap:(ap['default_code'],ap['code']))
    global prd_pdp_deta
    prd_pdp_deta = pdp_list
    data = {
       'article_pdp':pdp_list,
       'boms':list_boms,
       'gamme':gamme,
       'gamme_uniq':gamme_uniq,
       'can_prd':can_prd,
       'cant_prd':cant_prd,
       'default_code':default_code,
       'nbr_result':len(pdp_list),
    }
   
    return render(request, 'pdp.html', data)

def can_product_global(bom_id):
    
    elem = []
    global Boms
    bom = [bm for bm in Boms if bom_id == bm['id']]
    global Bom_Lines
    bomlines_prd = [bl['bom_lines'] for bl in Bom_Lines if bom_id == bl['bom_id']][0]
    for bom_line_prd in bomlines_prd:
        cpt_id_prd = bom_line_prd['product_id'][0]
        cpt_qty_prd = get_product(cpt_id_prd)[0]['virtual_available']
        qty = cpt_qty_prd*bom[0]['product_qty']/bom_line_prd['product_qty']
        elem.append(int(qty))
    
    float_list = [float(i) for i in elem]
    
    return min(float_list)

def can_product_IMP(bom_id,cat_imp):
    
    elem = []
    global Boms
    bom = [bm for bm in Boms if bom_id == bm['id']]
    global Bom_Lines
    
    bomlines_prd = [bl['bom_lines'] for bl in Bom_Lines if bom_id == bl['bom_id']][0]

    
    for bom_line_prd in bomlines_prd:
        cpt_id_prd = bom_line_prd['product_id'][0]
        cpt_qty_prd = get_product(cpt_id_prd)[0]['virtual_available']
        qty = cpt_qty_prd*bom[0]['product_qty']/bom_line_prd['product_qty']
        cate_ids = get_product(cpt_id_prd)[0]['categ_id']
        
        if cate_ids[0]==cat_imp:
            elem.append(int(qty))

    
    float_list = [float(i) for i in elem]
    
    return min(float_list)

def can_product_IMP_Uniq(bom_id,cat_imp):
    
    elem = []
    global Boms
    bom = [bm for bm in Boms if bom_id == bm['id']]
    global Bom_Lines
    
    bomlines_prd = [bl['bom_lines'] for bl in Bom_Lines if bom_id == bl['bom_id']][0]
    

    bomlines_prd_diff = [bl['bom_lines'] for bl in Bom_Lines if bom_id != bl['bom_id']]
    
    article_prd_diff = []

    for bl in bomlines_prd_diff:
        #print('bom_lines',bl)
        for b in bl:
            #print('aticle',b['product_id'][0])
            article_prd_diff.append(b['product_id'][0])
    

    #article_prd_diff = list(set(article_prd_diff))
    #print(bomlines_prd_diff)
    
    for bom_line_prd in bomlines_prd:
        
        cpt_id_prd = bom_line_prd['product_id'][0]

        existe = [x for x in article_prd_diff if cpt_id_prd == x]
        
        cpt_qty_prd = get_product(cpt_id_prd)[0]['virtual_available']
        qty = cpt_qty_prd*bom[0]['product_qty']/bom_line_prd['product_qty']
        cate_ids = get_product(cpt_id_prd)[0]['categ_id']
        if len(existe)!=0:
            print('existe',get_product(cpt_id_prd)[0]['default_code'])
        else:
            print('not existe',get_product(cpt_id_prd)[0]['default_code'])

        if  len(existe)==0 and cate_ids == cat_imp:
            elem.append(int(qty))

    
    float_list = [float(i) for i in elem]
    if len(float_list) == 0:
        return 0
    return min(float_list)

def get_product(id_prd):
    global Articles_MP
    art = [art for art in Articles_MP if id_prd == art['id']]
    return art



def production(request):
    form = ArticleFilterForm(request.GET or None)
    prds_prd = []
    global result_prd
    gamme =0
    if form.is_valid():        
        if form.cleaned_data['gamme']:
            gamme = 1
            for art_prd in  result_prd:
                for bom_prd in Boms:
                    if art_prd['id']==bom_prd['product_id'][0]:
                        global cat_imporation_id
                        x= {'code':art_prd['default_code'],'name':art_prd['name'],'stock_v':art_prd['virtual_available'],'ecart':art_prd['virtual_available']-art_prd['product_min_qty'],'bom':bom_prd['code'],'qty':can_product_IMP(bom_prd['id'],cat_imporation_id)}    
                        prds_prd.append(x)
        else:
            for art_prd in  result_prd:
                for bom_prd in Boms:
                    if art_prd['id']==bom_prd['product_id'][0]:
                        x= {'code':art_prd['default_code'],'name':art_prd['name'],'stock_v':art_prd['virtual_available'],'ecart':art_prd['virtual_available']-art_prd['product_min_qty'],'bom':bom_prd['code'],'qty':can_product_global(bom_prd['id'])}    
                        prds_prd.append(x)
    else:
        
        for art_prd in  result_prd:
            for bom_prd in Boms:
                if art_prd['id']==bom_prd['product_id'][0]:
                    x= {'code':art_prd['default_code'],'name':art_prd['name'],'stock_v':art_prd['virtual_available'],'ecart':art_prd['virtual_available']-art_prd['product_min_qty'],'bom':bom_prd['code'],'qty':can_product_global(bom_prd['id'])}    
                    prds_prd.append(x)
    prd_shearch = ''

    if form.is_valid():        
        if form.cleaned_data['default_code']:
            prd_shearch = form.cleaned_data['default_code']
            prds_prd = [l for l in prds_prd if form.cleaned_data['default_code'].lower() in l['code'].lower() or  form.cleaned_data['default_code'].lower() in l['name'].lower()]

    prds_prd.sort(key=lambda ap: (ap['code'],ap['bom']))            
    
    data = {
        'products' : prds_prd,
        'prd_shearch' :prd_shearch,
        'gamme' :gamme,
        'nbr_result':len(prds_prd),
        } 
   
    return render(request, 'can_prd.html', data)

def get_cat_pf(user_id):
    cat = Category_user_set.objects.get(user=user_id)
    return cat.cat_parent_pf
def get_cat_mp(user_id):
    cat = Category_user_set.objects.get(user=user_id)
    return cat.cat_parent_mp
    


def get_user_cats(user_id):
    cat = Category_user_set.objects.get(user=user_id)
    return cat

def get_bom_lines(id_bom):
    fields6 = ['product_id', 'product_qty']
    bom_data = models.execute_kw(db, uid, password, 'mrp.bom', 'read', [id_bom], {'fields': ['bom_line_ids']})
    
    bom_line_ids = bom_data['bom_line_ids'] if bom_data else []
    bom_lines = models.execute_kw(db, uid, password, 'mrp.bom.line', 'read', [bom_line_ids], {'fields': fields6})
    return bom_lines

def get_bom(bom_id):

    result = [bm for bm in Boms if bm['id'] == bom_id]
    return result[0]

def get_bom_lines1(id_bom,gamme):
    fields6 = ['product_id', 'product_qty']
    bom_data = models.execute_kw(db, uid, password, 'mrp.bom', 'read', [id_bom], {'fields': ['bom_line_ids']})
    dom = [('product_id.categ_id', '=', gamme)]
    bom_line_ids = bom_data['bom_line_ids'] if bom_data else []
    dom99 = [bom_line_ids]
    bom_lines = models.execute_kw(db, uid, password, 'mrp.bom.line', 'read', [bom_line_ids], {'fields': fields6})
    return bom_lines

def get_bom_prd_qty(id_bom):
    global Boms

    result = [bm for bm in Boms if bm['id'] == id_bom]
    return result[0]['product_qty']

selected_id_cbn = []

def Stock_Min(request,*args,**kwargs):
    form = ArticleFilterForm(request.GET or None)
    


    if request.method == "POST":
        
        selected_id_json = request.POST.get('articles')
       

        
        #print(selected_id_cbn)
        global selected_id_cbn,nbr_mois_cbn
        selected_id_cbn = json.loads(selected_id_json)
        
        
        
    
    
    global result_prd_filtre
    #print(selected_id_cbn)

    global Bom_Lines
    #print(Bom_Lines)
   
        


    for rp in result_prd_filtre:
        for l in selected_id_cbn :
            if rp['default_code'] == l[0]:
                
                rp['product_min_qty1'] = float(l[1])
                rp['bom_id'] = float(l[2])
                
    stock_min = []
    Stock_mins = []
    for art_prd in  result_prd_filtre:
        boms_prd = [bom for bom in Boms if bom['id'] == art_prd['bom_id']]
        #print(boms_prd)
        boms_cpts = []
        for bom_prd in boms_prd:
            bomlines_prd = [bl['bom_lines'] for bl in Bom_Lines if bom_prd['id'] == bl['bom_id']][0]
            #bomlines_prd = get_bom_lines(bom_prd['id'])
            for bom_line_prd in bomlines_prd:
                item = {'id':bom_line_prd['product_id'][0],'qty':bom_line_prd['product_qty'],'bom_qty':bom_prd['product_qty']}
                boms_cpts.append(item)
       
        boms_cpts_clean = list({obj['id']: obj for obj in boms_cpts}.values())
        
        for cpt in boms_cpts_clean:
            qty_cpt = cpt['qty']*art_prd['product_min_qty1']/cpt['bom_qty']
            prd = get_product(cpt['id'])[0]
            
            composant = {'code':prd['default_code'],'name':prd['name'],'qty':qty_cpt,'sale_ok':prd['sale_ok'],'purchase_ok':prd['purchase_ok'],'categ_id':prd['categ_id'],'virtual_available':prd['virtual_available']}
            stock_min.append(composant)






    """ for p in stock_min:
        print(p) """
    cmp_data_sum = {}

    for component in stock_min:
        cmp_id = component['code']
        cmp_qty = component['qty']
        
        # Si le cmp_id existe déjà, ajouter à la quantité existante
        if cmp_id in cmp_data_sum:
            cmp_data_sum[cmp_id]['cmp_qty'] += cmp_qty
        else:
            # Sinon, initialiser les informations pour ce cmp_id
            cmp_data_sum[cmp_id] = {
                'code': component['code'],
                'name': component['name'],
                'sale_ok': component['sale_ok'],
                'purchase_ok': component['purchase_ok'],
                'categ_id': component['categ_id'],
                'virtual_available': component['virtual_available'],
                #'ecart':component['virtual_available']-cmp_qty,
                'cmp_qty': cmp_qty
            }

        # Convertir le dictionnaire en liste d'objets (dictionnaires)
        Stock_mins = list(cmp_data_sum.values())
    
    for p in Stock_mins:
        p['ecart'] = p['virtual_available']-p['cmp_qty']
    
    form = ArticleFilterForm(request.GET or None)
    game = 0
    loc_prd = 0
    prduc_prd = 0
    ecart_f = 0
    Stock_min_filtre = []
    if form.is_valid():
        
        global cat_imporation_id
        if form.cleaned_data['gamme']:
            game = 1
            Stock_min_filtre += [prd for prd in Stock_mins if prd['categ_id'][0] == cat_imporation_id]
        if form.cleaned_data['loc_prd']:
            loc_prd = 1
            Stock_min_filtre += [prd for prd in Stock_mins if prd['categ_id'][0] != cat_imporation_id and prd['purchase_ok']==True]
        if form.cleaned_data['prduc_prd']:
            prduc_prd = 1
            Stock_min_filtre += [prd for prd in Stock_mins if prd['sale_ok']==False and prd['purchase_ok']==False]
        if form.cleaned_data['ecart']:
            ecart_f = 1
            Stock_min_filtre += [prd for prd in Stock_mins if prd['ecart']<=0]
    else:
         Stock_min_filtre = Stock_mins
    
    Stock_min_filtre.sort(key=lambda ap: ap['code'])
    #print('kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk')
    context = {
        'products' : Stock_min_filtre,
        'gamme':game,
        'loc_prd':loc_prd,
        'prduc_prd':prduc_prd,
        'ecart':ecart_f,
        'nbr_result':len(Stock_min_filtre),
        }
    
    

    return render(request,'stock_min.html',context)

def Stock_Min1(request,*args,**kwargs):
    global result_prd
    stock_min = []
    Stock_mins = []
    for art_prd in  result_prd:
        boms_prd = [bom for bom in Boms if bom['product_id'][0] == art_prd['id']]
        boms_cpts = []
        for bom_prd in boms_prd:
            bomlines_prd = [bl['bom_lines'] for bl in Bom_Lines if bom_prd['id'] == bl['bom_id']][0]
            #bomlines_prd = get_bom_lines(bom_prd['id'])
            for bom_line_prd in bomlines_prd:
                item = {'id':bom_line_prd['product_id'][0],'qty':bom_line_prd['product_qty'],'bom_qty':bom_prd['product_qty']}
                boms_cpts.append(item)
       
        boms_cpts_clean = list({obj['id']: obj for obj in boms_cpts}.values())
        
        for cpt in boms_cpts_clean:
            qty_cpt = cpt['qty']*art_prd['product_min_qty']/cpt['bom_qty']
            prd = get_product(cpt['id'])[0]
            composant = {'code':prd['default_code'],'name':prd['name'],'qty':qty_cpt}
            stock_min.append(composant)

    cmp_data_sum = {}

    for component in stock_min:
        cmp_id = component['code']
        cmp_qty = component['qty']
        
        # Si le cmp_id existe déjà, ajouter à la quantité existante
        if cmp_id in cmp_data_sum:
            cmp_data_sum[cmp_id]['cmp_qty'] += cmp_qty
        else:
            # Sinon, initialiser les informations pour ce cmp_id
            cmp_data_sum[cmp_id] = {
                'code': component['code'],
                'name': component['name'],
                'cmp_qty': cmp_qty
            }

        # Convertir le dictionnaire en liste d'objets (dictionnaires)
        Stock_mins = list(cmp_data_sum.values())
    
   
    
    Stock_mins.sort(key=lambda ap: ap['code'])
    context = {
        'products' : Stock_mins,
        'nom':'Produits de la boutique',
        }
    
    

    return render(request,'stock_min.html',context)

result_prd_filtre = []

def Cbn(request,*args,**kwargs):

    global result_prd,result_prd_filtre,result
    #result_prd = result
    #print(result_prd[0]['default_code'],result_prd[0]['product_min_qty'])
    default_code =''
    form = ArticleFilterForm(request.GET or None)
    if form.is_valid():
        if form.cleaned_data['default_code']:
            default_code = form.cleaned_data['default_code']
            result_prd_filtre = [art  for art in result_prd if form.cleaned_data['default_code'].lower() in art['default_code'].lower() or form.cleaned_data['default_code'].lower() in art['name'].lower() ]
        else:
            result_prd_filtre = result_prd
    else:
        result_prd_filtre = result_prd

    result_prd_filtre.sort(key=lambda ap: ap['default_code'])
    global Boms
    #print(Boms)
    context = {
        'products' : result_prd_filtre,
        'nom':default_code,
        'boms':Boms,
        'nbr_result':len(result_prd_filtre),
        }
    
    
    return render(request,'cbn.html',context)

def get_category_pf(cat_name):
    catrgory = [cat for cat in categories if cat_name == cat['name']]
    return catrgory[0]['id']

def get_category_mp(cat_name):
    catrgory = [cat for cat in categories if cat_name == cat['name']]
    return catrgory[0]['id']



def get_cat_impo_id(user_id):
    cat = Category_user_set.objects.get(user=user_id)
    cat_name = cat.cat_imporation
    global categories
    catrgory = [cat for cat in categories if cat_name == cat['name']]
    return catrgory[0]['id']

def get_opr_type(user_id,company_id):
    
    cat = Category_user_set.objects.get(user=user_id)
    opr_typ = 0
    if company_id ==1:
        opr_typ = cat.type_oper1
    if company_id ==3:
        opr_typ = cat.type_oper2
    if company_id ==5:
        opr_typ = cat.type_oper3

    return opr_typ









    

def appros(request):
   
    appros_gl = []
    
    if request.method == "POST":
        global pdp_items
        pdp_items = json.loads(request.POST.get('my_list'))

        #print(pdp_items)
    for item in pdp_items:
        bom_qty= get_bom_prd_qty(int(item['id_bom']))
        for line in get_bom_lines(int(item['id_bom'])):            
            product_id = line['product_id'][0]  # Product name
            product_qty = line['product_qty']*float(item['qty'])/bom_qty


            x1 = {'product_id':product_id,'product_qty':product_qty}
            appros_gl.append(x1)

    cmp_data_sum = {}

    for component in appros_gl:
        cmp_id = component['product_id']
        cmp_qty = component['product_qty']
        # Si le cmp_id existe déjà, ajouter à la quantité existante
        if cmp_id in cmp_data_sum:
            cmp_data_sum[cmp_id]['cmp_qty'] += cmp_qty
        else:
            cmp_data_sum[cmp_id] = {
                'cmp_id': cmp_id,
                'cmp_qty': cmp_qty
            }

    # Convertir le dictionnaire en liste d'objets (dictionnaires)
    result_list_appro = list(cmp_data_sum.values())
    result_list_appros = []
    for rst in result_list_appro:
        app = {
                'code': get_product(rst['cmp_id'])[0]['default_code'],
                'name': get_product(rst['cmp_id'])[0]['name'],
                'qty_available': get_product(rst['cmp_id'])[0]['qty_available'],
                'virtual_available': get_product(rst['cmp_id'])[0]['virtual_available'],
                'cmp_qty':rst['cmp_qty'],
                'ecar':get_product(rst['cmp_id'])[0]['virtual_available']- rst['cmp_qty']
            
            }

        result_list_appros.append(app)
    
    result_list_appros.sort(key=lambda ap: ap['code'])
    
    data = {
      'appros':result_list_appros,
      'nbr_result':len(result_list_appros),
    }

    return render(request, 'appros.html', data)

