from django.views.generic import TemplateView
from django.http import HttpResponse
from django.conf import settings
from django.urls import resolve
from _keenthemes.__init__ import KTLayout
from _keenthemes.libs.theme import KTTheme
from pprint import pprint
from django.template.loader import render_to_string
from django.shortcuts import render,HttpResponse,redirect
from django.contrib.auth.decorators import login_required
from django.http import FileResponse
from django.core.mail import EmailMessage
from authentication.models import User
from myobconnect.models import MyobModel
from supplier.models import Supplier,Supplier_Bill,Supplier_Bill_Item,Supplier_Bill_Item,Supplier_Payment
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
import base64
from django.contrib import messages
import requests
import json
from myobconnect.views import refresh_token
from datetime import datetime
from decimal import Decimal
import re
from product.models import Product
from quotation.models import GST,Discount,ContractOfSale
from django.db.models import Sum
from customer.views import sync_myob_customer
from product.views import sync_myob_product_row
from django.db.models import Q
from django.db.models import CharField, Value
from django.db.models.functions import Concat
from django.contrib.auth.decorators import login_required
from django.contrib.auth.decorators import user_passes_test
from authentication.models import ActivityLog
from authentication.decorators import is_admin, is_sales, is_technician, is_customer,is_superuser
from django.shortcuts import get_object_or_404
from io import BytesIO
from xhtml2pdf import pisa
from PIL import Image
import io
from django.template.loader import get_template

import os
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())

myob_supplier_bill_taxcode = os.environ.get('MYOB_Supplier_Bill_TaxCode')
myob_supplier_freightaxcode = os.environ.get('MYOB_Supplier_FreightTaxCode')
myob_supplier_account = os.environ.get('MYOB_Supplier_Account')
myob_supplier_taxcode = os.environ.get('MYOB_Supplier_TaxCode')

def history(row):
    if not row.model_name == 'SerialNumber' :
        if not row.model_name == 'Order_Item':
            result = []
            old = []
            newarr = []
            
            activity={}
            if row.model_name != Supplier_Payment:
                activity['model_name']=row.model_name
                activity['timestamp']=row.timestamp
              
                activity['activity_by'] = str(row.user.userinfo.get_name) if row.user and row.user.userinfo is not None else 'Admin'
                
                if row.action == 'Updated':
                    a = json.dumps(row.new_data[0]['fields'])
                    b = json.dumps( row.old_data[0]['fields'])
                    a = json.loads(a)
                    b = json.loads(b)
                    for key in a:
                       
                        activity['action']='Updated'
                        
                        if key not in b:
                            result.append(f'{dict({key: a[key]})} -> {"key deleted"}')
                            # activity['log_activity']=f'{dict({key: a[key]})} -> {"key deleted"}'
                            # activity['log_activity']=f'Updated <b>{dict({key: b[key]})} </b> <b>{" Added"} </b>'
                            
                            
                        if key in a and key in b and a[key] != b[key] and a[key] != None and  b[key] != None and a[key] != '' and b[key] != '':
                            result.append(f'{dict({key: a[key]})} -> {dict({key: b[key]})}')
                           
                            if not ( key == 'updated_at' or key == 'updated_at' or key == 'updated_by' or key == 'deleted_at'):
                                old.append(f'Updated {key} From {a[key]} to {b[key]}')
                                
                              
                                
                                activity['log_activity']=f'<b>{key} </b> From   <b>{b[key]} </b> To  <b>{a[key]} </b>'
                                if key == 'status':
                                    if a[key]==0:
                                         a[key]='Created'
                                    if a[key]==1:
                                         a[key]='Open'  
                                    if a[key]==2:
                                         a[key]='Close'
                                        
                                    if b[key]==0:
                                         b[key]='Created'
                                    if b[key]==1:
                                         b[key]='Open'  
                                    if b[key]==2:
                                         b[key]='Close' 
                                    activity['log_activity']=f' <b>{key} </b> From   <b>{b[key]} </b> To  <b>{a[key]} </b>'
                                    
                             
                                    
                                if key == 'tracking_status':
                                    a[key]=int(a[key])
                                    b[key]=int(b[key])
                                    if a[key]==0:
                                         a[key]='Ordered'
                                    if a[key]==1:
                                         a[key]='Shipped'
                                    if a[key]==2:
                                         a[key]='Watered' 
                                    if a[key]==3:
                                         a[key]='Arrived'  
                                    if a[key]==4:
                                         a[key]='Book For Install'
                                    if a[key]==5:
                                         a[key]='Installed'
                                        
                                    if b[key]==0:
                                         b[key]='Ordered'
                                    if b[key]==1:
                                         b[key]='Shipped'
                                    if b[key]==2:
                                         b[key]='Watered' 
                                    if b[key]==3:
                                         b[key]='Arrived'  
                                    if b[key]==4:
                                         b[key]='Book For Install'
                                    if b[key]==5:
                                         b[key]='Installed'
                                    
                                    activity['log_activity']=f'<b>{key} </b> From   <b>{b[key]} </b> To  <b>{a[key]} </b>'
                                if row.model_name == 'Serial_Number':
                                    if key == 'status':
                                        if a[key]==0:
                                             a[key]='Created'
                                        if a[key]==1:
                                             a[key]='Email Sent'
                                        if a[key]==2:
                                             a[key]='Accepted' 
                                        if a[key]==3:
                                             a[key]='Open'  
                                        if a[key]==4:
                                             a[key]='Close'
                                            
                                        if b[key]==0:
                                             b[key]='Created'
                                        if b[key]==1:
                                            b[key]='Email Sent'
                                        if b[key]==2:
                                            b[key]='Accepted' 
                                        if b[key]==3:
                                             b[key]='Open'  
                                        if b[key]==4:
                                             b[key]='Close' 
                                        activity['log_activity']=f' <b>{key} </b> From   <b>{b[key]} </b> To  <b>{a[key]} </b>'
                           
                                
                            # if row.model_name == 'Customer_Payment':
                            #     formatted_a_key = '{:.2f}'.format(a[key])
                            #     formatted_b_key = '{:.2f}'.format(b[key])
                            
                            #     if formatted_a_key != formatted_b_key:
                            #         activity['log_activity'] = f'<b>{key}</b> From <b>{formatted_b_key}</b> To <b>{formatted_a_key}</b>'
                                
                                
                        
                        
                        
                        
                        
                    # else:
                        # old.append(f'Updated {key} From {a[key]} to {b[key]}')
                        # old.append(f'Updated {key} From {a[key]} to {b[key]}')
                        
                if row.action == 'Deleted':
                    result.append(f'Deleted')
                    activity['log_activity']='Deleted'
                    activity['action']='Deleted'
                if row.action == 'Created':
                    result.append(f'Created')
                    activity['log_activity']='Created'
                    activity['action']='Created'
                # dd(old)
                # result='\n'.join(t for t in result)
                # result='\n'.join(t for tkey,tvalue in activity)
                # result1='\n'.join(t for t in result1)
                # dd({'result':result,'result1':result1})
                # result_activity=[activity]
                # dd(activity)
                return activity
            
@user_passes_test(lambda u: is_admin(u) or is_superuser(u))
@login_required
def activity_supplier_bill(request, id):
    supplier_bill = get_object_or_404(Supplier_Bill, pk=id)
    supplier_bill_item = Supplier_Bill_Item.objects.filter(supplier_bill=supplier_bill)
    context={'supplier_bills': supplier_bill}
    # dd(invoice.get_history)
    
    t1=[]
    if supplier_bill.get_history is not None:
      
        for s_bill in supplier_bill.get_history:
            t=history(s_bill)
            t1.append(t)
    counter = 1

    for supplier_bill in t1:
        if 'log_activity' in supplier_bill and supplier_bill['log_activity'] is not None and supplier_bill['log_activity'] != ''  :
            supplier_bill['row_number'] = counter
            counter += 1

    return render(request, 'pages/supplier_bill/activity.html', {'t1':t1})
    
@user_passes_test(lambda u: is_admin(u) or is_superuser(u))
@login_required     
def send_supplier_mail(request, id): 
    bill = get_object_or_404(Supplier_Bill, pk=id)
    subject = f'EXCITECH Australia - Bill PO request for Bill ID {bill.id}'
    template_data = {'bill': bill}
    message = render_to_string('pages/supplier_bill/supplier_email_temp.html', template_data)
    from_email =settings.FROM_EMAIL # Replace with your email address
    recipient_email = bill.supplier.user.email  # Use the customer's email address
    cc_emails=settings.ADMIN_EMAIL_CC_PO
    email = EmailMessage(subject, message, from_email, [recipient_email],cc=cc_emails)
    pdf_file_path = bill.pdf_file.path 
    email.attach_file(pdf_file_path, 'application/pdf')
    email.content_subtype = 'html'
    email.send()
    # get_registration_token = get_object_or_404(FCMDevice,user_id=customer.user.id)
    # sendPush('Invoice Details Notification',f'EXCITECH Australia - Invoice Details for Invoice ID {invoice.id}',[get_registration_token.registration_id])
    bill.mailstatus=1
    bill.save()
    return redirect('supplier:bill_list')
    # dd('her')
@user_passes_test(lambda u: is_admin(u) or is_superuser(u))
@login_required
def activity_supplier(request, id):
    supplier = get_object_or_404(Supplier, pk=id)
   
    context={'suppliers': supplier}
    # dd(invoice.get_history)
    
    
    t1=[]
    if supplier.get_history_supplier is not None:
        for supplier in supplier.get_history_supplier:
            t=history(supplier)
            if t is not None:
               t1.append(t)
            
    counter = 1       
    for supplier in t1:
        if 'log_activity' in supplier and supplier['log_activity'] is not None and supplier['log_activity'] != ''  :
            supplier['row_number'] = counter
            counter += 1
   
    return render(request, 'pages/supplier/activity.html', {'t1':t1})
                
                
 
@login_required
def sync_myob_bill(request,id):
    refresh_token(request)

    myobdata = MyobModel.objects.first()
    if not myobdata:
        messages.error(request,'Please First create Access Code')
        return redirect('/myob/initiate-connection')
    api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Purchase/Bill/Item"
    supplier_bill=Supplier_Bill.objects.get(id=id)
    bill_items=Supplier_Bill_Item.objects.filter(supplier_bill=supplier_bill)

    product_ids = []
   
    quantities = []
    subtotals = []
    costs_per_unit = []
    if supplier_bill.supplier.myob_uid == None:
        sync_myob_supplier(request,supplier_bill.customer.id)
    for bill_item in bill_items:
        product_ids.append(bill_item.product.id)
        if bill_item.product.uid == None:
            sync_myob_product_row(request,bill_item.product.id)
        quantities.append(bill_item.qty)
        subtotals.append(bill_item.subtotal)
        print(subtotals)
        costs_per_unit.append(bill_item.cost_per_unit)
        if(supplier_bill.discount_type =='$'): 
            discount_percent_myob=Decimal(supplier_bill.discount/supplier_bill.grandsubtotal*100)
            discount_percent_myob=Decimal(supplier_bill.discount_percent)
            
        details = []
        discount_percent_myob = 0 
        for i in range(len(product_ids)):
            product_id = product_ids[i]
            product_obj = Product.objects.get(id=product_id)
            product_names = product_obj.product_name
            subtotal_str = subtotals[i]
            subtotal = Decimal(subtotal_str)
            cost_per_unit_str = costs_per_unit[i]
            cost_per_unit = Decimal(cost_per_unit_str)
            detail ={
                    "Type": "Transaction",
                    "Description":product_names + f"({product_obj.sku})",  
                    "BillQuantity": int(quantities[i]),
                    "ReceivedQuantity" : int(quantities[i]),
                    "UnitPrice": float(cost_per_unit),
                    # "UnitCount" :int(qty_values[i]),
                    "DiscountPercent" :float(discount_percent_myob),
                    # "Account": {
                    #     "UID": "d6343c99-8ae8-4f21-8723-87e6b540c9ca",
                    # },
                    "TaxCode": {
                         "UID":myob_supplier_bill_taxcode
                        # "UID": "6f5fce5d-604f-49db-9a56-8573e7d2a5ec",
                        
                    },
                    "Item": {
                        "UID": product_obj.uid,
                    },
                }
            details.append(detail)

            bill_data={
                "Number": supplier_bill.id,
                "Date":supplier_bill.bill_date.strftime('%Y-%m-%dT%H:%M:%S'),
                "SupplierInvoiceNumber": supplier_bill.invoice_number,
                "Supplier": {
                    "UID": supplier_bill.supplier.myob_uid,
                },
                "ShipToAddress": supplier_bill.supplier.city,
                "Terms": { 
                    "PaymentIsDue": "DayOfMonthAfterEOM",
                    "DiscountDate": 1,
                    "BalanceDueDate": 30,
                    "DiscountForEarlyPayment": 0,
                    "MonthlyChargeForLatePayment": 0,
                    "DiscountExpiryDate": None,
                    "Discount":float(supplier_bill.discount),
                    "DueDate": supplier_bill.due_date.strftime('%Y-%m-%dT%H:%M:%S'),
                },
                "IsTaxInclusive": False,
                "IsReportable": False,
                "Lines":details,
                "Subtotal": float(supplier_bill.subtotal),
                "Freight": 0,
                "FreightTaxCode":  {
                        "UID": myob_supplier_freightaxcode
                    },
                "TotalTax": float(supplier_bill.gst),
                "TotalAmount": float(supplier_bill.total),
                "Category": None,
                "Comment": "",
                "ShippingMethod": None,
                "PromisedDate": None,
                "JournalMemo": "Purchase; 786",
                "BillDeliveryStatus": "Print",
                "AppliedToDate": 0,
                "BalanceDueAmount": 0,
                "Status": "Open",
                "LastPaymentDate": None,
                "Order": None,
                "ForeignCurrency":None
            }

        post_json = json.dumps(bill_data)
        
        headers = {
            'Authorization': f'Bearer {myobdata.access_token}',
            'x-myobapi-key': settings.MYOB_CLIENT_ID,
            'x-myobapi-version': 'v2',
            'Content-Type': 'application/json',
           
        }
        response = requests.post(api_url, data=post_json, headers=headers)
        data=response.headers

        if response.status_code == 201:
            
            location = data['Location']
        
            if location:
                parts = location.split('/')
                uid = parts[-1]

                
                supplier_bill.uid = uid
                supplier_bill.updated_by=request.user
                supplier_bill.save()

                api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Purchase/Bill/Item/{uid}/Attachment"
                
                file_content = supplier_bill.attachment.read()
                file_base64 = base64.b64encode(file_content).decode('utf-8')
                attachment_data = {
                "Attachments" : [
                                {
                                "OriginalFileName" : f"{uid}-item.pdf",
                                "FileBase64Content" : file_base64
                                }
                ]
                    }
                response = requests.post(api_url, json=attachment_data, headers=headers)

                if response.status_code == 200:
                    supplier_bill = Supplier_Bill.objects.get(uid=uid)
                    supplier_bill.updated_by=request.user
                    supplier_bill.attachment.save(f'{uid}-item.pdf', supplier_bill.attachment)
                    messages.success(request, 'Supplier Bill Sync With Myob Successfully.')
                    return redirect('supplier:bill_list')
            else:
                messages.error(request, 'Failed To Sync With Myob.')
                return redirect('supplier:bill_list')


def supplier_payment_check(request,id):

    refresh_token(request)
    
    myobdata = MyobModel.objects.first()
    if not myobdata:
        messages.error(request,'Please First create Access Code')
        return redirect('/myob/initiate-connection')
    supplier_bill=Supplier_Bill.objects.get(id=id)
    supplier_bill_uid=supplier_bill.uid
  
    api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Purchase/SupplierPayment"

   
    
    headers = {
        'Authorization': f'Bearer {myobdata.access_token}',
        'x-myobapi-key': settings.MYOB_CLIENT_ID,
        'x-myobapi-version': 'v2',
        'Content-Type': 'application/json',
        'Accept-Encoding': 'gzip,deflate'
    }
    
    response = requests.get(api_url,headers=headers)

    if response.status_code == 200:
        myob_data=response.json()

        

        matching_supplier_payments = []
        for supplier_payment in myob_data["Items"]:
          

            lines = supplier_payment["Lines"]
          
            for line in lines:
      
                if line["Purchase"]["UID"] == supplier_bill_uid:
                    
                    matching_supplier_payments.append(supplier_payment)

        for matching_payment in  matching_supplier_payments:
            print("Matching Supplier Payment:",matching_payment["UID"])

            supplier_payments=Supplier_Payment.objects.filter(uid=matching_payment["UID"])
            if not  supplier_payments.exists():
                
                supplier_payment=Supplier_Payment(

                    uid=matching_payment["UID"],
                    paid_amount= matching_payment["AmountPaid"],
                    pay_date=matching_payment["Date"],
                    supplier_bill=supplier_bill,
                    due_amount=abs(float(supplier_bill.payable_amount)- matching_payment["AmountPaid"]),
                    payable_amount=abs(float(supplier_bill.payable_amount)- matching_payment["AmountPaid"]),
                    total_amount=supplier_bill.total
                    
                )

                supplier_payment.save()
                supplier_bill.payable_amount=abs(float(supplier_bill.payable_amount)- matching_payment["AmountPaid"])
                total_paid_amount = supplier_bill.supplier_bill_payment.aggregate(Sum('paid_amount'))['paid_amount__sum'] or 0
                
                if supplier_bill.total > total_paid_amount:
                   supplier_bill.status = 1
                elif supplier_bill.total <= total_paid_amount:
                    supplier_bill.status = 2

                supplier_bill.total_paid_amount=total_paid_amount
                supplier_bill.updated_by=request.user
                supplier_bill.save()


@login_required
def supplier_payment(request,id):

    if request.method =='POST':


        refresh_token(request)
    
        myobdata = MyobModel.objects.first()
        if not myobdata:
            messages.error(request,'Please First create Access Code')
            return redirect('/myob/initiate-connection')

        api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Purchase/SupplierPayment"

        supplier_bill=Supplier_Bill.objects.get(id=id)

        paid_amount=float(request.POST.get('paid_amount'))
       
        description=request.POST.get('description')
        
        payable_amount=float(supplier_bill.payable_amount)-paid_amount
  

        supplier_payment=Supplier_Payment(
            supplier_bill= supplier_bill,
         
            payable_amount=abs(payable_amount),
            paid_amount=abs(paid_amount),
            due_amount=abs(payable_amount),
            description=description,
            total_amount=supplier_bill.total,
        )
        supplier_payment.updated_by=request.user
        supplier_payment.save()

        supplier_bill.payable_amount=payable_amount

        total_paid_amount = supplier_bill.supplier_bill_payment.aggregate(Sum('paid_amount'))['paid_amount__sum'] or 0
       
        if supplier_bill.total > total_paid_amount :
           supplier_bill.status = 1
        elif supplier_bill.total <= total_paid_amount :
             supplier_bill.status = 2

        supplier_bill.total_paid_amount=total_paid_amount
        supplier_bill.save()


        headers = {
            'Authorization': f'Bearer {myobdata.access_token}',
            'x-myobapi-key': settings.MYOB_CLIENT_ID,
            'x-myobapi-version': 'v2',
            'Content-Type': 'application/json',
            'Accept-Encoding': 'gzip,deflate'
        }

        supplier_payment=Supplier_Payment.objects.latest('id')


        supplierpayment=    {
            "PayFrom": "Account",
              "Account": {
                "UID": myob_supplier_account
            },
            "Supplier": {
                "UID": supplier_bill.supplier.myob_uid
            },
            "PayeeAddress": None,
            "StatementParticulars": "",
            "PaymentNumber": "1",
            "Date": supplier_payment.pay_date.strftime('%Y-%m-%dT%H:%M:%S'),
            "AmountPaid":float(supplier_payment.paid_amount),
            "Memo": supplier_payment.description,
            "Lines": [
                {
                    "Type": "Bill",
                    "Purchase": {
                        "UID": supplier_bill.uid
                    },
                    "AmountApplied": float(supplier_payment.paid_amount),
                }
            ],
            "DeliveryStatus": "Print",
            "ForeignCurrency": None
        }

        response = requests.post(api_url,json=supplierpayment, headers=headers)
        data=response.headers

        if response.status_code == 201:

            location = data['Location']
        
            if location:
                parts = location.split('/')
                uid = parts[-1]

                supplier_payment.uid=uid
                supplier_payment.updated_by=request.user
                supplier_payment.save()
            messages.success(request, 'Bill Payment Done Successfully.')
            return redirect('supplier:supplier_payment_list',supplier_bill.id)
        else:

            messages.success(request, 'Failed To Bill Payment.')
            return redirect('supplier:supplier_payment_list',supplier_bill.id)

@login_required
def supplier_payment_list(request,id):
    supplier_bill=Supplier_Bill.objects.get(id=id)
    supplier_payment_check(request,id)

    payment_lists = Supplier_Payment.objects.filter(supplier_bill=supplier_bill)
    payment=Supplier_Payment.objects.filter(supplier_bill=supplier_bill).last()
    
    if payment:
        payable_amount=payment.due_amount
    else:
        payable_amount=supplier_bill.total
 
    return render(request,'pages/supplier_bill/payment_list.html',{'supplier_bill':supplier_bill,'payment_lists':payment_lists,'payable_amount':payable_amount})


@login_required
def supplier_bill_list(request,id):

    supplier=Supplier.objects.get(id=id)
    supplier_bills=Supplier_Bill.objects.filter(supplier=supplier)

    supplier_name = request.GET.get('supplier_name')
    start_date = request.GET.get('start_date')
    end_date = request.GET.get('end_date')
    status = request.GET.get('status')

    if start_date:
        start_date = datetime.strptime(start_date, '%d-%m-%Y').date()
    if end_date:
        end_date = datetime.strptime(end_date, '%d-%m-%Y').date()
    
    
    print(supplier_name)
    # Apply additional filters based on user input
    if supplier_name:
        supplier_bills = supplier_bills.filter(
            Q(supplier__first_name__icontains=supplier_name) or
            Q(supplier__last_name__icontains=supplier_name) or
            Q(supplier__company_name__icontains=supplier_name) or
            Q(bill_date__gte=start_date) and Q(bill_date__lte=end_date) or
            Q(status=status)

        )

    if start_date:
        supplier_bills = supplier_bills.filter(bill_date__gte=start_date)
    if end_date:
        supplier_bills = supplier_bills.filter(bill_date__lte=end_date)

    if status:
        supplier_bills = supplier_bills.filter(status=status)
    
    return render(request,'pages/supplier_bill/list_supplier_bills.html',{'supplier_bills':supplier_bills,'supplier':supplier})


@login_required
def list_supplier_bill(request):
    supplier_name = request.GET.get('supplier_name')
    start_date = request.GET.get('start_date')
    end_date = request.GET.get('end_date')
    status = request.GET.get('status')
   
    supplier_bills = Supplier_Bill.objects.filter(deleted_at__isnull=True)
    suppliers=Supplier.objects.filter(deleted_at__isnull=True)
  
    # Convert string dates to datetime objects if provided
    if start_date:
        start_date = datetime.strptime(start_date, '%d-%m-%Y').date()
    if end_date:
        end_date = datetime.strptime(end_date, '%d-%m-%Y').date()

    if supplier_name:
        supplier_bills = supplier_bills.filter(supplier__id=supplier_name).order_by('supplier','-created_at')  

    if start_date:
        supplier_bills = supplier_bills.filter(bill_date__gte=start_date)
    if end_date:
        supplier_bills = supplier_bills.filter(bill_date__lte=end_date)

    if status:
        supplier_bills = supplier_bills.filter(status=status)
        
        
    total_records = supplier_bills.count()
    show_pagination = total_records > settings.PAGE_RECORDS


    if show_pagination: 

        page = request.GET.get('page', 1)
        paginator = Paginator(supplier_bills, settings.PAGE_RECORDS)  # Show 10 bills per page
        try:
            supplier_bills = paginator.page(page)
        except PageNotAnInteger:
            supplier_bills = paginator.page(1)
        except EmptyPage:
            supplier_bills = paginator.page(paginator.num_pages)

    
    return render(request,'pages/supplier_bill/list_supplier_bill.html',{'supplier_bills':supplier_bills,'suppliers':suppliers})

@login_required
def add_specific_supplier_bill(request,id):
    supplier=Supplier.objects.get(id=id)
    suppliers=Supplier.objects.filter(deleted_at__isnull=True)
    products = Product.objects.filter(is_active=True,is_product=0)
    discounts = Discount.objects.all()
    gsts = GST.objects.all()
    return render(request,'pages/supplier_bill/add_supplier_bill.html',{'supplierexist':supplier,'suppliers':suppliers,'products':products,'discounts':discounts,'gsts':gsts})


@login_required
def add_supplier_bill(request):
    suppliers=Supplier.objects.filter(deleted_at__isnull=True,is_active=True)
    products = Product.objects.filter(is_active=True,is_product=0)
    discounts = Discount.objects.all()
    gsts = GST.objects.all()
    if request.method == "POST":
        refresh_token(request)
        myobdata = MyobModel.objects.first()
        if not myobdata:
            messages.error(request,'Please First create Access Code')
            return redirect('/myob/initiate-connection')
       
        supplier_id=request.POST.get('supplier')
        invoice_number=request.POST.get('invoice_number')
        bill_date =  request.POST.get('bill_date')
        attachment = request.FILES.get('attachment')
        due_date =  request.POST.get('due_date')
        product_ids = request.POST.getlist('product[]', [])
        qty_values = request.POST.getlist('qty[]', [])
        # serial_numbers= request.POST.getlist('serialnumber[]', [])

        cost_per_unit_values =  request.POST.getlist('cost_per_unit[]', [])
        subtotal_values = request.POST.getlist('subtotal[]', [])
        grandsubtotal = float(request.POST.get('grandsubtotal'))
        gst_percent =int( request.POST.get('gst'))
        total = request.POST.get('total')
        sent_mail = request.POST.get('sent_mail')
        status = request.POST.get('status')
       
        if(request.POST.get('discount_type')=='dollar'):
            discount_type="$"
            discount_percent= 0
            discount = int(int(re.findall('\d+', request.POST.get('dollar_type'))[0]) ) 
            discount_percent_myob=Decimal(discount/grandsubtotal*100)
        else:
            discount_type="%"
            discount_percent= int(request.POST.get('discount'))
            discount = grandsubtotal * ( discount_percent / 100)  
            discount_percent_myob=Decimal(discount_percent)
        grand_subtotal= grandsubtotal-discount
        gst = grand_subtotal * ( gst_percent / 100) 
        gst = "{:.2f}".format(gst)
        start_date_obj = datetime.strptime(bill_date, '%d-%m-%Y').date()
       
        due_date_obj = datetime.strptime(due_date, '%d-%m-%Y').date()

        if status:
            status = status
        else:
            status = 0

        is_active = request.POST.get('is_active')


        if is_active:
            is_active = is_active
        else:
            is_active = True
    
        supplier = Supplier.objects.get(id=supplier_id)
        print("ddddd")
        print(supplier)
        
        supplier_bill = Supplier_Bill.objects.create(
            supplier=supplier,
            invoice_number=invoice_number,
            bill_date=start_date_obj,
            due_date=due_date_obj,
            subtotal= grandsubtotal,
            discount_percent=discount_percent,
            discount=discount,
            discount_type=discount_type,
            total=total,
            payable_amount=total,

            gst_percent=gst_percent,
            gst=gst,
            status=status,
            is_active=is_active,
            created_by=request.user
        )
        if  attachment:
            supplier_bill.attachment.save(f'{supplier_bill.id}-attachment.pdf', attachment)
        billitems = []

        for i in range(len(product_ids)):
            product_id = product_ids[i]
            qty = int(qty_values[i]) 
            cost_per_unit_str = cost_per_unit_values[i]
            cost_per_unit_str = cost_per_unit_str.replace('$', '') 
            cost_per_unit = Decimal(cost_per_unit_str)
            subtotal_str = subtotal_values[i]
            subtotal_str = subtotal_str.replace('$', '')  
            subtotal = Decimal(subtotal_str)

            product_obj = Product.objects.get(id=product_id)

            billitem = Supplier_Bill_Item(
                supplier_bill= supplier_bill,  
                product=product_obj,
                cost_per_unit=cost_per_unit,
                qty=qty,
                subtotal=subtotal,

            )
            billitem.created_by=request.user
            billitem.save()

            billitems.append(billitem)


            api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Purchase/Bill/Item"
        bill=supplier_bill
        pdf_data = generate_pdfs(bill, billitems)
        bill.pdf_file.save(f'{bill.id}_bill.pdf', pdf_data)
        
        subject = f'EXCITECH Australia - Bill PO request for Bill ID {bill.id}'
        template_data = {'bill': bill}
        message = render_to_string('pages/supplier_bill/supplier_email_temp.html', template_data)
        from_email =settings.FROM_EMAIL # Replace with your email address
        recipient_email = bill.supplier.user.email  # Use the customer's email address
        cc_emails=settings.ADMIN_EMAIL_CC_PO
        email = EmailMessage(subject, message, from_email, [recipient_email],cc=cc_emails)
        if sent_mail == '1':
            pdf_file_path = bill.pdf_file.path 
            email.attach_file(pdf_file_path, 'application/pdf')
            email.content_subtype = 'html'
            email.send()
            # get_registration_token = get_object_or_404(FCMDevice,user_id=customer.user.id)
            # sendPush('Invoice Details Notification',f'EXCITECH Australia - Invoice Details for Invoice ID {invoice.id}',[get_registration_token.registration_id])
            bill.mailstatus=1
            bill.save()
            
        details = []
        
        for i in range(len(product_ids)):
            product_id = product_ids[i]
            product_obj = Product.objects.get(id=product_id)
            product_names = product_obj.product_name
            subtotal_str = subtotal_values[i]
            subtotal_str=subtotal_str.replace('$', '')
            subtotal = Decimal(subtotal_str)

            cost_per_unit_str = cost_per_unit_values[i]
            cost_per_unit_str = cost_per_unit_str.replace('$', '')
            cost_per_unit = Decimal(cost_per_unit_str)
            detail ={
                    "Type": "Transaction",
                    "Description":product_names + f"({product_obj.sku})" ,   # + ",".join(serial_numbers_list),  
                    "BillQuantity": int(qty_values[i]),
                    "ReceivedQuantity" : int(qty_values[i]),
                    "UnitPrice": float(cost_per_unit),
                    # "UnitCount" :int(qty_values[i]),
                    "DiscountPercent" :float(discount_percent_myob),
                    # "Account": {
                    #     "UID": "d6343c99-8ae8-4f21-8723-87e6b540c9ca",
                    # },
                    "TaxCode": {
                         "UID":myob_supplier_bill_taxcode
                        # "UID": "6f5fce5d-604f-49db-9a56-8573e7d2a5ec",
                        
                    },
                    "Item": {
                        "UID": product_obj.uid,
                    },
                }

            details.append(detail)

            bill_data={
                "Number": supplier_bill.id,
                "Date":supplier_bill.bill_date.strftime('%Y-%m-%dT%H:%M:%S'),
                "SupplierInvoiceNumber": supplier_bill.invoice_number,
                "Supplier": {
                    "UID": supplier.myob_uid,
                },
                "ShipToAddress": supplier.city,
                "Terms": { 
                    "PaymentIsDue": "DayOfMonthAfterEOM",
                    "DiscountDate": 1,
                    "BalanceDueDate": 30,
                    "DiscountForEarlyPayment": 0,
                    "MonthlyChargeForLatePayment": 0,
                    "DiscountExpiryDate": None,
                    "Discount":float(supplier_bill.discount),
                    "DueDate": supplier_bill.due_date.strftime('%Y-%m-%dT%H:%M:%S'),
                },
                "IsTaxInclusive": False,
                "IsReportable": False,
                "Lines":details,
                "Subtotal": float(supplier_bill.subtotal),
                "Freight": 0,
                "FreightTaxCode":  {
                        "UID": myob_supplier_freightaxcode
                    },
                "TotalTax": float(supplier_bill.gst),
                "TotalAmount": float(supplier_bill.total),
                "Category": None,
                "Comment": "",
                "ShippingMethod": None,
                "PromisedDate": None,
                "JournalMemo": "Purchase; 786",
                "BillDeliveryStatus": "Print",
                "AppliedToDate": 0,
                "BalanceDueAmount": 0,
                "Status": "Open",
                "LastPaymentDate": None,
                "Order": None,
                "ForeignCurrency":None
            }

        post_json = json.dumps(bill_data)
        
        headers = {
            'Authorization': f'Bearer {myobdata.access_token}',
            'x-myobapi-key': settings.MYOB_CLIENT_ID,
            'x-myobapi-version': 'v2',
            'Content-Type': 'application/json',
           
        }

        response = requests.post(api_url, data=post_json, headers=headers)
        data=response.headers

        if response.status_code == 201:
            
            location = data['Location']
        
            if location:
                parts = location.split('/')
                uid = parts[-1]

                
                supplier_bill.uid = uid
                supplier_bill.created_by=request.user
                supplier_bill.save()

                api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Purchase/Bill/Item/{uid}/Attachment"
                if  attachment:
                    file_content = attachment.read()
                    file_base64 = base64.b64encode(file_content).decode('utf-8')
                    attachment_data = {
                    "Attachments" : [
                                    {
                                    "OriginalFileName" : f"{uid}-item.pdf",
                                    "FileBase64Content" : file_base64
                                    }
                    ]
                        }
    
    
                    response = requests.post(api_url, json=attachment_data, headers=headers)

                messages.success(request, 'Supplier  Bill Created Successfully.')
                return redirect('supplier:bill_list')
        
        else:
            messages.error(request, 'Failed To Create Bill.')
            return redirect('supplier:bill_list')

    return render(request,'pages/supplier_bill/add_supplier_bill.html',{'suppliers':suppliers,'products':products,'discounts':discounts,'gsts':gsts})
@login_required
def popdfdownload(request,id):
    supplier_bill=Supplier_Bill.objects.get(id=id)
    if supplier_bill.pdf_file:
        file_path = supplier_bill.pdf_file.url
        # dd(file_path)
        file_path = os.path.join(settings.MEDIA_ROOT, 'bill_pdfs', f'{supplier_bill.id}_bill.pdf')
        return FileResponse(open(file_path, 'rb'), content_type='application/pdf', as_attachment=True, filename=f'{supplier_bill.id}_bill.pdf')
    else:
        messages.error(request, 'Failed To Download File.')
        return redirect('supplier:bill_list')
@login_required
def edit_supplier_bill(request,id):
    supplier_bill=Supplier_Bill.objects.get(id=id)
    suppliers=Supplier.objects.filter(is_active=True)
    invoiceitems = Supplier_Bill_Item.objects.filter(supplier_bill=supplier_bill)
    products = Product.objects.filter(is_active=True,is_product=0)
    # invoices=Invoice.objects.all()
    if request.method == 'POST':
       
        refresh_token(request)
   
        myobdata = MyobModel.objects.first()
        if not myobdata:
            messages.error(request,'Please First create Access Code')
            return redirect('/myob/initiate-connection')
        
        UID=supplier_bill.uid
        api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Purchase/Bill/Item/{UID}"

        supplier_id = request.POST.get('supplier')
        print(supplier_id)
        bill_date = request.POST.get('bill_date') 
        due_date = request.POST.get('due_date') 
        invoice_number=request.POST.get('invoice_number') 
        attachment = request.FILES.get('attachment')
        product_ids = request.POST.getlist('product[]', [])
        qty_values = request.POST.getlist('qty[]', [])
        # serial_numbers= request.POST.getlist('serialnumber[]', [])
        cost_per_unit_values =  request.POST.getlist('cost_per_unit[]', [])
        subtotal_values = request.POST.getlist('subtotal[]', [])
        grandsubtotal = float(request.POST.get('grandsubtotal'))   
        gst_percent =int( request.POST.get('gst'))
        total = request.POST.get('total')
        delete_list = request.POST.getlist('deleted[]')
        
        print(total)

        sent_mail = request.POST.get('sent_mail')
        status = request.POST.get('status')
       
        if(request.POST.get('discount_type')=='dollar'):
            discount_type="$"
            discount_percent= 0
            discount = int(int(re.findall('\d+', request.POST.get('dollar_type'))[0]) ) 
            discount_percent_myob=Decimal(discount/grandsubtotal*100)
            discount="{:.2f}".format(discount)
        else:
            discount_type="%"
            discount_percent= int(request.POST.get('discount'))
            discount = grandsubtotal * ( discount_percent / 100)  
            discount_percent_myob=Decimal(discount_percent)
            discount="{:.2f}".format(discount)
        grand_subtotal= grandsubtotal-float(discount)
        gst = grand_subtotal * ( gst_percent / 100) 
        gst = "{:.2f}".format(gst)
        print("dddd",gst)
        
        start_date_obj = datetime.strptime(bill_date, '%d-%m-%Y').date()
        due_date_obj = datetime.strptime(due_date, '%d-%m-%Y').date()

        is_active = request.POST.get('is_active')

        if is_active:
            is_active = is_active
        else:
            is_active = True

        supplier = Supplier.objects.get(id=supplier_id)
        print(supplier)
        supplier_bill.supplier = supplier
        supplier_bill.bill_date = start_date_obj
        supplier_bill.due_date = due_date_obj
        supplier_bill.invoice_number = invoice_number
        supplier_bill.subtotal = "{:.2f}".format(grand_subtotal)
        supplier_bill.discount_percent=discount_percent
        supplier_bill.discount = discount
        supplier_bill.discount_type = discount_type
        supplier_bill.total = total
        supplier_bill.payable_amount=total
           
        supplier_bill.gst_percent=gst_percent
        supplier_bill.gst=gst
    
        supplier_bill.is_active = is_active

        total_paid_amount = supplier_bill.supplier_bill_payment.aggregate(Sum('paid_amount'))['paid_amount__sum'] or 0
        
       
        if total_paid_amount > 0:
        
            if float(supplier_bill.total) > float(total_paid_amount):
                supplier_bill.status = 1
            elif float(supplier_bill.total) <= float(total_paid_amount):
                supplier_bill.status = 2
        else:
            supplier_bill.status = 0
        if attachment:
           supplier_bill.attachment.save('{}-attachment.pdf'.format(supplier_bill.id), attachment)
        
        supplier_bill.updated_by=request.user
        supplier_bill.save()

        bill_items = []
        
        
        if  delete_list:
            for i in range(len(delete_list)):
                
               
                deleted_value = delete_list[i]
             
                if deleted_value == '0':
                    pass
                else:
                    billitem = Supplier_Bill_Item.objects.filter(id=deleted_value).delete()
        
            # invoiceitems = InvoiceItem.objects.filter(invoice=invoice).delete()
        for i in range(len(product_ids)):
            product_id = product_ids[i]
          
            qty = int(qty_values[i])
            cost_per_unit_str = cost_per_unit_values[i]
            cost_per_unit_str = cost_per_unit_str.replace("$", "").replace(",", "")
            cost_per_unit = Decimal(cost_per_unit_str)
            subtotal_str = subtotal_values[i]
            subtotal_str = subtotal_str.replace("$", "").replace(",", "")
            subtotal = Decimal(subtotal_str)

            product_obj = Product.objects.get(id=product_id)
       
            billitemexist = Supplier_Bill_Item.objects.filter(supplier_bill=supplier_bill,product=product_obj)
            if not billitemexist:
                billitem = Supplier_Bill_Item(
                    supplier_bill= supplier_bill,  
                    product=product_obj,
                   
                    cost_per_unit=cost_per_unit,
                    qty=qty,
                    subtotal=subtotal,
                )
                billitem.save()
            else:
                billitemexist = Supplier_Bill_Item.objects.get(supplier_bill=supplier_bill,product=product_obj)
                billitemexist.product=product_obj
                billitemexist.cost_per_unit=cost_per_unit
                billitemexist.qty=qty
                billitemexist.subtotal=subtotal
                billitemexist.save()
                billitem = Supplier_Bill_Item(
                    supplier_bill= supplier_bill,  
                    product=product_obj,
                   
                    cost_per_unit=cost_per_unit,
                    qty=qty,
                    subtotal=subtotal,
                )
                bill_items.append(billitem)
                  
            
            headers = {
            'Authorization': f'Bearer {myobdata.access_token}',
            'x-myobapi-key': settings.MYOB_CLIENT_ID,
            'x-myobapi-version': 'v2',
            'Content-Type': 'application/json',
            'Accept-Encoding': 'gzip,deflate'
        }

        UID = supplier_bill.uid
        if UID:
            response = requests.get(api_url, headers=headers)

            print(response.content)
            response_json = response.json()
            print(response_json)
            current_row_version = response_json.get('RowVersion')
            data= response_json 

            lines = []  # Initialize the list to store line items

            for i in range(len(product_ids)):
                product_id = product_ids[i]
                product_obj = Product.objects.get(id=product_id)
                product_names = product_obj.product_name
                # serial_numbers_obj = SerialNumber.objects.filter(order=invoice.id,product=product_obj )
                # serial_numbers_list =[serial_number.serial_number for serial_number in serial_numbers_obj]
              
                print(discount_percent)
                
                subtotal_str = subtotal_values[i]
                subtotal_str=subtotal_str.replace('$', '')
                subtotal = Decimal(subtotal_str)

                cost_per_unit_str = cost_per_unit_values[i]
                cost_per_unit_str = cost_per_unit_str.replace('$', '')
                cost_per_unit = Decimal(cost_per_unit_str)

                # Create a line item for the current product
                line_item = {
                    "Item": {
                        "UID": product_obj.uid,
                    },
                    
                    "Type": "Transaction",
                    "Description":product_names + f"({product_obj.sku})", # + ",".join(serial_numbers_list),  
                    "BillQuantity": int(qty_values[i]),
                    "ShipQuantity" : int(qty_values[i]),
                    "UnitPrice": float(cost_per_unit),
                    "UnitCount" :int(qty_values[i]),
                    "DiscountPercent" :float(discount_percent_myob),
                    # "Account": {
                    #     "UID": "d6343c99-8ae8-4f21-8723-87e6b540c9ca",
                    # },
                    "TaxCode": {
                        "UID":myob_supplier_bill_taxcode
                        # "UID": "6f5fce5d-604f-49db-9a56-8573e7d2a5ec",
                    },
        
                }

                lines.append(line_item) 
          
                supplier_bill = Supplier_Bill.objects.filter(id=supplier_bill.id).first()
    
                bill_data={
                    "UID": supplier_bill.uid,
                    "Number": supplier_bill.id,
                    "Date":supplier_bill.bill_date.strftime('%Y-%m-%dT%H:%M:%S'),
                    "SupplierInvoiceNumber": supplier_bill.invoice_number,
                    "Supplier": {
                        "UID": supplier.myob_uid,
                    },
                    "ShipToAddress": supplier.city,
                    "Terms": { 
                        "PaymentIsDue": "DayOfMonthAfterEOM",
                        "DiscountDate": 1,
                        "BalanceDueDate": 30,
                        "DiscountForEarlyPayment": 0,
                        "MonthlyChargeForLatePayment": 0,
                        "DiscountExpiryDate": None,
                        "Discount":float(supplier_bill.discount),
                        "DueDate": supplier_bill.due_date.strftime('%Y-%m-%dT%H:%M:%S'),
                    },
                    "IsTaxInclusive": False,
                    "IsReportable": False,
                    "Lines":lines,
                    "Subtotal": float(supplier_bill.subtotal),
                    "Freight": 0,
                    "FreightTaxCode": {
                            "UID": myob_supplier_freightaxcode
                        },
                    "TotalTax": float(supplier_bill.gst),
                    "TotalAmount": float(supplier_bill.total),
                    "Category": None,
                    "Comment": "",
                    "ShippingMethod": None,
                    "PromisedDate": None,
                    "JournalMemo": "Purchase; 786",
                    "BillDeliveryStatus": "Print",
                    "AppliedToDate": 0,
                    "BalanceDueAmount": 0,
                    "Status": "Open",
                    "LastPaymentDate": None,
                    "Order": None,
                    "ForeignCurrency":None,
                    "RowVersion":current_row_version, 
                }

            post_json = json.dumps(bill_data)
            
            headers = {
                'Authorization': f'Bearer {myobdata.access_token}',
                'x-myobapi-key': settings.MYOB_CLIENT_ID,
                'x-myobapi-version': 'v2',
                'Content-Type': 'application/json',
            }

            response = requests.put(api_url, data=post_json, headers=headers)
            data=response.headers
            print(response.status_code);
            if response.status_code == 200:
                location = data['Location']
            
                if location:
                    parts = location.split('/')
                    uid = parts[-1]    
                    api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Invoice/Item/{uid}"
                    print(api_url)

                    supplier_bill.uid = uid
                    # invoice.myob_invoice_pdf.save(f'{invoice.id}_invoice.pdf', content)
                    supplier_bill.updated_by=request.user
                    supplier_bill.save()

                    if  attachment :
                    
                        api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Purchase/Bill/Item/{uid}/Attachment"                
                        file_content = attachment.read()
                        file_base64 = base64.b64encode(file_content).decode('utf-8')
                        attachment_data = {
                                "Attachments" : [
                                                {
                                                "OriginalFileName" : f"{uid}-item.pdf",
                                                "FileBase64Content" : file_base64
                                                }
                                ]
                            }
                        response = requests.post(api_url, json=attachment_data, headers=headers)
                    bill=supplier_bill
                    billitems=Supplier_Bill_Item.objects.filter(supplier_bill=supplier_bill)
                    pdf_data = generate_pdfs(bill, billitems)
                    bill.pdf_file.save(f'{bill.id}_bill.pdf', pdf_data)
                    
                    subject = f'EXCITECH Australia - Bill PO request for Bill ID {bill.id}'
                    template_data = {'bill': bill}
                    message = render_to_string('pages/supplier_bill/supplier_email_temp.html', template_data)
                    from_email =settings.FROM_EMAIL # Replace with your email address
                    recipient_email = bill.supplier.user.email  # Use the customer's email address
                    cc_emails=settings.ADMIN_EMAIL_CC_PO
                    email = EmailMessage(subject, message, from_email, [recipient_email],cc=cc_emails)
                    if sent_mail == '1':
                        pdf_file_path = bill.pdf_file.path 
                        email.attach_file(pdf_file_path, 'application/pdf')
                        email.content_subtype = 'html'
                        email.send()
                        # get_registration_token = get_object_or_404(FCMDevice,user_id=customer.user.id)
                        # sendPush('Invoice Details Notification',f'EXCITECH Australia - Invoice Details for Invoice ID {invoice.id}',[get_registration_token.registration_id])
                        bill.mailstatus=1
                        bill.save()
                    messages.success(request, 'Bill Updated Successfully.')
                    return redirect('supplier:bill_list')
            
                else:
                    messages.success(request, 'Supplier Bill Updated Successfully.')
                    return redirect('supplier:bill_list')
            else:
                messages.error(request, 'Failed To Update Bill.')
                return redirect('supplier:bill_list')
        else:
            # create to myob
            messages.error(request, 'Failed to update to myob.')
            return redirect('supplier:bill_list')
    else:
      
        discounts = Discount.objects.all()

        gsts = GST.objects.all()
        return render(request,'pages/supplier_bill/edit_supplier_bill.html',{'supplier_bill':supplier_bill,'invoiceitems':invoiceitems,'suppliers':suppliers,'products':products,'discounts':discounts,'gsts':gsts})

def generate_pdfs(bill,billitems):
    template = get_template('pages/supplier_bill/po_pdf.html')
    contracts = ContractOfSale.objects.first()
    context = {
        'bill': bill,
        'billitems': billitems,
        'contracts':contracts
    }
    html_content = template.render(context)

    pdf_buffer = BytesIO()
    pisa.CreatePDF(html_content, dest=pdf_buffer)

    pdf_buffer.seek(0)
    return pdf_buffer
    
@login_required
def delete_supplier_bill(request,id):
    supplier_bill=Supplier_Bill.objects.get(id=id)
    supplier_bill.deleted_by=request.user
    supplier_bill.delete()
   
    messages.success(request, 'Supplier Invoice Deleted Successfully.')
    return redirect('supplier:bill_list')




@login_required
def list_supplier(request):
    supplier=Supplier.objects.filter(deleted_at__isnull=True )
    supplier_name = request.GET.get('supplier_name')
    email = request.GET.get('email')
    phone = request.GET.get('phone')
    status = request.GET.get('status')

    
    if supplier_name:
        supplier = supplier.filter(id=supplier_name)  
        
    if email:
        email = request.GET.get('email').strip()
        supplier = supplier.filter(email__icontains=email)

    if phone:
        phone = request.GET.get('phone').strip()
        supplier = supplier.filter(phone1__icontains=phone)
        
    if status:
        supplier = supplier.filter(is_active=status)

    total_records = supplier.count()
    show_pagination = total_records > settings.PAGE_RECORDS


    if show_pagination: 

        page = request.GET.get('page', 1)
        paginator = Paginator(supplier, settings.PAGE_RECORDS)  # Show 10 suppliers per page
        try:
            supplier= paginator.page(page)
        except PageNotAnInteger:
            supplier = paginator.page(1)
        except EmptyPage:
            supplier = paginator.page(paginator.num_pages)

    return render(request,'pages/supplier/list.html',{'suppliers':supplier})
    
@login_required
def create_supplier(request):
    refresh_token(request)
    context={}
    myobdata = MyobModel.objects.first()
    if not myobdata:
        messages.error(request,'Please First create Access Code')
        return redirect('/myob/initiate-connection')
    
    api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Contact/Supplier"
    if myobdata.access_token:

        if request.method == 'POST':
            form = request.POST
            email = request.POST.get('email')
            if User.objects.filter(email=email):
                messages.error(request,f'User With Email {email} Is Already Exists.')

                context['form'] = form
                return render(request,'pages/supplier/create.html',context)
            
            is_active=request.POST.get('is_active')
        
            if is_active is None:
               is_active = False
            else:
                is_active = True

            user = User.objects.create(
                is_active=is_active,
                username=email,
                email=email,
              
            )

            user.role.set('5')

            user.set_password('Excitech@123')
            user.save()
            
            supplier_type = request.POST.get('supplier_type')
            
            is_active= request.POST.get('is_active')
        
        
            if is_active is None:
               is_active = False
            else:
                is_active = True
            

            country=request.POST.get('country')
            other=0
            if country == 'Other':
                country=request.POST.get('other_country')
                state=request.POST.get('other_state')
                other=1
            else:
                country=country
                state=request.POST.get('state')
                
            supplier_code = request.POST.get('supplier_code')
            existing_suppliers = Supplier.objects.filter(supplier_code=supplier_code)
            
            if existing_suppliers.exists():
                messages.error(request, "Supplier Code Must Be Unique.")    
                context['form'] = form
                return render(request,'pages/supplier/create.html',context)
                
            supplier_data = {
            

                'is_active':is_active,
                'street': request.POST.get('street'),
                'city': request.POST.get('city'),
                'state': state,
                'post_code': request.POST.get('post_code'),
                'country':country,
                'supplier_code':supplier_code,
                'otherCountry':other,
                'phone1': request.POST.get('phone1'),
                'phone2': request.POST.get('phone2'),
                'phone3': request.POST.get('phone3'),
                'fax': request.POST.get('fax'),
                'email': request.POST.get('email'),
                'website': request.POST.get('website'),
                'contact_name': request.POST.get('contact_name'),
                'salutation': request.POST.get('salutation'),
                'abn': request.POST.get('abn'),
                }


            if supplier_type=='1':

                first_name = request.POST.get('first_name')
                last_name = request.POST.get('last_name')
                individual = Supplier(
                    user=user,
                    is_individual=int(supplier_type),
                    first_name=first_name,
                    last_name=last_name,
                    **supplier_data,
                    created_by=request.user,
                )
                individual.save()
            else:
                company_name = request.POST.get('company_name')
                company = Supplier(
                    user=user,
                    is_individual=int(supplier_type),
                    company_name=company_name,
                    **supplier_data,
                    created_by=request.user,
                    updated_by=request.user,
                )
                company.save()

            suppliers=Supplier.objects.filter(created_by=request.user).last()

            supplier_data={
                "LastName" :suppliers.last_name,
                "FirstName" : suppliers.first_name,
                "Addresses" : [
                    {
                    "Location" : 1,
                    "Street" : suppliers.street,
                    "City" : suppliers.city,
                    "State" : suppliers.state,
                    "PostCode" : suppliers.post_code,
                    "Country" : suppliers.country,
                    "Phone1" : suppliers.phone1,
                    "Phone2" : suppliers.phone2,
                    "Phone3" : suppliers.phone3,
                    "Fax" : suppliers.fax,
                    "Email" : suppliers.email,
                    "Website" : suppliers.website,
                    "ContactName" : suppliers.contact_name,
                    "Salutation" : suppliers.salutation,
                    }
                ],
                "IsIndividual" : suppliers.is_individual,
                "IsActive" : suppliers.is_active  ,
                "ABN":suppliers.abn,
                "BuyingDetails" : {
                
                "TaxCode" : {
                    "UID": myob_supplier_taxcode,
                 
                            
                            },
                    "FreightTaxCode" : {
                            "UID": myob_supplier_freightaxcode,
                            
                            },
                    }

                    

            }
            if not suppliers.is_individual:
                supplier_data["CompanyName"] = suppliers.company_name
            
            headers = {
                'Authorization': f'Bearer {myobdata.access_token}',
                'x-myobapi-key': settings.MYOB_CLIENT_ID,
                'x-myobapi-version': 'v2',
                'Content-Type': 'application/json',
                'Accept-Encoding': 'gzip,deflate'
            }

            supplier_json = json.dumps(supplier_data)
            try:
                response = requests.post(api_url, data=supplier_json, headers=headers)
                data=response.headers

                if response.status_code == 201:
                    location = data['Location']
                    if location:
                        parts = location.split('/')
                        uid = parts[-1]
                        suppliers.myob_location = location
                        suppliers.myob_uid = uid
                        suppliers.created_by=request.user
                        suppliers.save()
                        messages.success(request, ' Supplier Added Successfully.')
                        return redirect('supplier:list')
                    else:
                        messages.error(request, 'Location Header Not Found In API Response.')
                        context['form'] = form
                        return render(request,'pages/supplier/create.html',context)
                else:
                    messages.error(request, 'Failed To Add Supplier.')
                    context['form'] = {}
                    return render(request,'pages/supplier/create.html',context)

            except requests.exceptions.RequestException as e:
                messages.error(request, f'An error occurred: {str(e)}')
    context['form'] = {}
    return render(request,'pages/supplier/create.html',context)

    


@login_required    
def edit_supplier(request,id):
    refresh_token(request)
    myobdata = MyobModel.objects.first()
    if not myobdata:
        messages.error(request,'Please First create Access Code')
        return redirect('/myob/initiate-connection')
    
    supplier = Supplier.objects.get(id=id)
    UID=supplier.myob_uid
    api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Contact/Supplier/{UID}"
    
    if request.method == 'POST':
        supplier_type = request.POST.get('supplier_type')
        
        is_active=request.POST.get('is_active')
        
        if is_active is None:
           is_active = False
        else:
            is_active = True

        email=request.POST.get('email')
        if User.objects.filter(email=email).exclude(id=supplier.user.id).exists():
            messages.error(request,  f'User With Email {email} Is Already Exists.')
            return redirect('supplier:edit' ,id )
            
        supplier_code= request.POST.get('supplier_code')
        existing_suppliers = Supplier.objects.filter(supplier_code=supplier_code).exclude(pk=id)
        
        if existing_suppliers.exists():
            messages.error(request, "Supplier Code Must Be Unique.")    
            return redirect('supplier:edit' ,id )
            

        user=User.objects.get(id=supplier.user.id)
        user.is_active=is_active
        user.email=email 
        user.username=email
        user.save()   
        country=request.POST.get('country')
        other = 0
        if country == 'Other':
            country=request.POST.get('other_country')
            state = request.POST.get('other_state')
            other = 1
            
        else:
            country=country
            state = request.POST.get('state')
        print(supplier_type)

        
        if supplier_type=="1":
            supplier.first_name = request.POST.get('first_name')
            supplier.last_name = request.POST.get('last_name')
            supplier.company_name==""
            
        else:
            supplier.company_name = request.POST.get('company_name')
            supplier.first_name =""
            supplier.last_name=""
            
        supplier.is_individual=int(supplier_type) 

        supplier.user=user
        supplier.is_active=is_active
        supplier.street = request.POST.get('street')
        supplier.city = request.POST.get('city')
        supplier.state = state
        supplier.post_code = request.POST.get('post_code')
        supplier.supplier_code = supplier_code
        supplier.country = country
        supplier.otherCountry = other

        supplier.phone1 = request.POST.get('phone1')
        supplier.phone2 = request.POST.get('phone2')
        supplier.phone3 = request.POST.get('phone3')
        supplier.fax = request.POST.get('fax')
        supplier.email = request.POST.get('email')
        supplier.website = request.POST.get('website')
        supplier.contact_name = request.POST.get('contact_name')
        supplier.salutation = request.POST.get('salutation')
        supplier.abn = request.POST.get('abn')
        supplier.updated_by = request.user
        supplier.save()

        headers = {
            'Authorization': f'Bearer {myobdata.access_token}',
            'x-myobapi-key': settings.MYOB_CLIENT_ID,
            'x-myobapi-version': 'v2',
            'Content-Type': 'application/json',
            'Accept-Encoding': 'gzip,deflate'
        }

        if UID:
            response = requests.get(api_url, headers=headers)
            response_json = response.json()
            current_row_version = response_json.get('RowVersion')

            supplier_data={
                "RowVersion": current_row_version,
                "UID":supplier.myob_uid,
                "LastName" :supplier.last_name,
                "FirstName" : supplier.first_name,
                "Addresses" : [
                    {
                    "Location" : 1,
                    "Street" : supplier.street,
                    "City" : supplier.city,
                    "State" : supplier.state,
                    "PostCode" : supplier.post_code,
                    "Country" : supplier.country,
                    "Phone1" : supplier.phone1,
                    "Phone2" : supplier.phone2,
                    "Phone3" : supplier.phone3,
                    "Fax" : supplier.fax,
                    "Email" : supplier.email,
                    "Website" : supplier.website,
                    "ContactName" : supplier.contact_name,
                    "Salutation" : supplier.salutation,
                    }
                ],
                "IsIndividual" : supplier.is_individual,
                "IsActive" : supplier.is_active  ,
                "ABN":supplier.abn,
                "BuyingDetails" : {

            "TaxCode" : {
                "UID": myob_supplier_taxcode,
                        },
                "FreightTaxCode" : {
                        "UID": myob_supplier_freightaxcode,
                        },
                }
            }
            if not supplier.is_individual:
                supplier_data["CompanyName"] = supplier.company_name
            supplier_json = json.dumps(supplier_data)
            response = requests.put(api_url, data=supplier_json, headers=headers)

            data=response.headers
            if response.status_code == 200:
                location = data['Location']
                if location:
                    parts = location.split('/')
                    uid = parts[-1]
                    supplier.myob_location = location
                    supplier.current_row_version=current_row_version
                    supplier.myob_uid = uid
                    supplier.updated_by = request.user
                    supplier.save()
                messages.success(request, 'Supplier Updated Successfully.')
                return redirect('supplier:list')
            else:
                messages.error(request, 'Failed To Update Supplier.')

                return redirect('supplier:edit',id)

        else:
            messages.success(request, 'Supplier Updated Successfully.')
            return redirect('supplier:list')

    return render(request,'pages/supplier/edit.html',{'supplier': supplier})
    

@login_required
def sync_myob_supplier(request,id):

    refresh_token(request)
    myobdata = MyobModel.objects.first()
    if not myobdata:
        messages.error(request,'Please First create Access Code')
        return redirect('/myob/initiate-connection')
    supplier = Supplier.objects.get(id=id)
    api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Contact/supplier/"

    headers = {
        'Authorization': f'Bearer {myobdata.access_token}',
        'x-myobapi-key': settings.MYOB_CLIENT_ID,
        'x-myobapi-version': 'v2',
        'Content-Type': 'application/json',
        'Accept-Encoding': 'gzip,deflate'
    }

    supplier_data={

        "LastName" :supplier.last_name,
        "FirstName" : supplier.first_name,
        "Addresses" : [
                    {
                    "Location" : 1,
                    "Street" : supplier.street,
                    "City" : supplier.city,
                    "State" : supplier.state,
                    "PostCode" : supplier.post_code,
                    "Country" : supplier.country,
                    "Phone1" : supplier.phone1,
                    "Phone2" : supplier.phone2,
                    "Phone3" : supplier.phone3,
                    "Fax" : supplier.fax,
                    "Email" : supplier.email,
                    "Website" : supplier.website,
                    "ContactName" : supplier.contact_name,
                    "Salutation" : supplier.salutation,
                    }
                ],
        "IsIndividual" : supplier.is_individual,
        "IsActive" : supplier.is_active  ,
        "ABN":supplier.abn,
        "BuyingDetails" : {
        "TaxCode" : {
            "UID": myob_supplier_taxcode,
                    },
            "FreightTaxCode" : {
                    "UID": myob_supplier_freightaxcode,
                    },
            }           
        }
    if not supplier.is_individual:
        supplier_data["CompanyName"] = supplier.company_name
    supplier_json = json.dumps(supplier_data)
    response = requests.post(api_url, data=supplier_json, headers=headers)

    data=response.headers
    if response.status_code == 201:
        location = data['Location']
        if location:
            parts = location.split('/')
            uid = parts[-1]
            supplier.myob_location = location
            supplier.myob_uid = uid
            supplier.updated_by=request.user
            supplier.save()
        messages.success(request, 'Supplier Successfully Sync With Myob.')
        return redirect('supplier:list')
    else:
        messages.error(request, 'Failed To Sync With Myob.')
        return redirect('supplier:list')

@login_required 
def delete_supplier(request, id):
    supplier = Supplier.objects.get(id=id)
    supplier.deleted_by = request.user  
    supplier.soft_delete()
    messages.success(request, 'Supplier Deleted Successfully.')
    return redirect('supplier:list')


def myob_bill_payment_synch(request,id):
    refresh_token(request)

    myobdata = MyobModel.objects.first()
    if not myobdata:
        messages.error(request,'Please First create Access Code')
        return redirect('/myob/initiate-connection')
    api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Purchase/SupplierPayment"
    supplier_bill=Supplier_Bill.objects.get(id=id)

    headers = {
        'Authorization': f'Bearer {myobdata.access_token}',
        'x-myobapi-key': settings.MYOB_CLIENT_ID,
        'x-myobapi-version': 'v2',
        'Content-Type': 'application/json',
        'Accept-Encoding': 'gzip,deflate'
    }

    supplier_payment=Supplier_Payment.objects.filter(supplier_bill=supplier_bill).last()

    supplierpayment=    {
        "PayFrom": "Account",
            "Account": {
            "UID": myob_supplier_account
        },
        "Supplier": {
            "UID": supplier_bill.supplier.myob_uid
        },
        "PayeeAddress": None,
        "StatementParticulars": "",
        "PaymentNumber": "1",
        "Date": supplier_payment.pay_date.strftime('%Y-%m-%dT%H:%M:%S'),
        "AmountPaid":float(supplier_payment.paid_amount),
        "Memo": supplier_payment.description,
        "Lines": [
            {
                "Type": "Bill",
                "Purchase": {
                    "UID": supplier_bill.uid
                },
                "AmountApplied": float(supplier_payment.paid_amount),
            }
        ],
        "DeliveryStatus": "Print",
        "ForeignCurrency": None
    }

    response = requests.post(api_url,json=supplierpayment, headers=headers)
    data=response.headers
    if response.status_code == 201:
        location = data['Location']
        if location:
            parts = location.split('/')
            uid = parts[-1]

            supplier_payment.uid=uid
            supplier_payment.updated_by=request.user
            supplier_payment.save()
        messages.success(request, 'Bill Payment Done Successfully.')
        return redirect('supplier:supplier_payment_list',supplier_bill.id)
    else:

        messages.success(request, 'Failed To Bill Payment.')
        return redirect('supplier:supplier_payment_list',supplier_bill.id)


