from django.shortcuts import render, get_object_or_404, redirect
from django.urls import reverse
from quotation.models import Quotation,ContractOfSale,QuotationItem,Signature,notifymodal
from product.models import Product,SerialNumber
# from customer.models import Customer
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseBadRequest
from django.contrib import messages
from django.http import JsonResponse
from decimal import Decimal
from django.template.loader import render_to_string
from django.utils.html import strip_tags
from django.core.mail import EmailMessage
from .models import GST,Discount,Quotation, QuotationItem,QuotationVersion, Customer,Supplier, Product,Invoice,InvoiceItem,SerialNumber,InvoicePdf,Customer_Payment,Order,Order_Item,User,Technician_Assigned_Order_Item,Technician_Comment,Supplier_Bill
from product.models import ProductCategory
from service.models import Service_Request_image
from customer.models import Customer,Customer_Info
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from user.models import UserInfo
from authentication.models import ActivityLog
from reversion.models import Version
from django.template.loader import get_template
from django.http import HttpResponse
#from warnings import PendingDeprecationWarning
from docx import Document
from io import BytesIO
from xhtml2pdf import pisa
from PIL import Image
import base64
import io

import os
from django.core.files import File 
from django.core.serializers import serialize
import json
from myobconnect.models import MyobModel
from myobconnect.views import refresh_token
from customer.views import sync_myob_customer
from product.views import sync_myob_product_row
from django.conf import settings
import requests
from datetime import datetime
from django.core.files.base import ContentFile
from html.parser import HTMLParser
from htmldocx import HtmlToDocx 
from authentication.models import ActivityLog
from authentication.decorators import is_admin, is_sales, is_technician, is_customer,is_superuser
from django.contrib.auth.decorators import user_passes_test
from django.db.models import Sum
from service.models import Parts_Request
from django.db.models import Count
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import get_object_or_404
from .models import Order
from django.db.models import Q
from django.db.models import CharField, Value
from django.db.models.functions import Concat
from reversion import revisions as reversion
import os

from celery import shared_task
from django.utils import timezone
from datetime import timedelta

from django.http import HttpResponseServerError
import stripe
from technician.models import CallDetail
from technician.firebaseManager import sendPush
from fcm_django.models import FCMDevice
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())

myob_quotation_freightaxcode = os.environ.get('MYOB_Quotation_FreightTaxCode')
myob_quotation_account = os.environ.get('MYOB_Quotation_Account')
myob_quotation_taxcode = os.environ.get('MYOB_Quotation_TaxCode')
stripe.api_key =  os.environ.get('STRIPE_SECRET_KEY')
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
from django.db.models.functions import Coalesce
from django.db.models import Count

myob_expense_account = os.environ.get('MYOB_ExpenseAccount')
myob_cost_of_sales_account = os.environ.get('MYOB_CostOfSalesAccount')
myob_income_account = os.environ.get('MYOB_IncomeAccount')
myob_asset_account = os.environ.get('MYOB_AssetAccount')
myob_tax_code = os.environ.get('MYOB_TaxCode')



from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from google.auth.transport.requests import Request
import os
import pickle


# def testapi(request):
#     try:
#         import googleapiclient
#         print('google-api-python-client is installed')
#     except ImportError:
#         print('google-api-python-client is not installed')

#     try:
#         import google.auth.httplib2
#         print('google-auth-httplib2 is installed')
#     except ImportError:
#         print('google-auth-httplib2 is not installed')

#     try:
#         import google_auth_oauthlib
#         print('google-auth-oauthlib is installed')
#     except ImportError:
#         print('google-auth-oauthlib is not installed')
def checknotification(request):
    try:
        notifyset = notifymodal.objects.get(id=1)
    except notifymodal.DoesNotExist:
        notifyset = None
    return notifyset
def product_list_to_bill_count(request):
    order_items= Order_Item.objects.filter(serial_number__isnull=True,is_trade = 0).values('product__id','product__product_name','product__sku').annotate(qty=Count('product__id'))
    order_item=[]
    for or1 in order_items:
        sr=SerialNumber.objects.filter(product__id=or1['product__id'],customer=None).count()
        if or1['qty']-sr == 0:
            pass
        else:
            or1['reuiredbilledqty']=or1['qty']-sr
            order_item.append(or1)
    if len(order_item) > 0:
        return {'unread_count': len(order_item)}
    else:
        return {'unread_count': 0 }


def generate_testpdfs(request):
    template = get_template('pages/check_list/checklistStatic_pdf.html')
    context = {
        # 'invoice': invoice,
        # 'invoiceitems': invoiceitems,
    }
    html_content = template.render(context)

    pdf_buffer = BytesIO()

   
    pisa.CreatePDF(html_content, dest=pdf_buffer)

    pdf_buffer.seek(0)
    response = HttpResponse(pdf_buffer, content_type='application/pdf')
    response['Content-Disposition'] = f'attachment; filename="checklist.pdf"'
    
    return response
@login_required
def create_bill(request):
    if request.method == 'POST':
        product_id=request.POST.getlist('product_id[]')
        # dd(product_id)
        suppliers=Supplier.objects.filter(is_active=True)
        products = Product.objects.filter(is_active=True)
        discounts = Discount.objects.all()
        gsts = GST.objects.all()
        order_item= Order_Item.objects.filter(serial_number__isnull=True,product__id__in=product_id,is_trade=0)
        order_items= order_item.values('product__id','product__product_name', 'product__sku','serial_number').annotate(qty=Count('id')).distinct()
        for or1 in order_items:
            sr=SerialNumber.objects.filter(product__id=or1['product__id'],customer=None).count()
            or1['serial_number_qty']=sr
            or1['reuiredbilledqty']=or1['qty']-sr
        return render(request,'pages/notification/create_bill.html',{'order_items':order_items,'products':products,'suppliers':suppliers,'discounts':discounts,'gsts':gsts})
    else:
        return redirect('/notification/request-product-bill/')

@login_required
def product_list_to_bill(request):
    product_id = request.GET.get('product_id')
    if product_id:
        order_items= Order_Item.objects.filter(serial_number__isnull=True,product=product_id).values('product__id','product__product_name','product__sku').annotate(qty=Count('product__id'))
    else:
        order_items= Order_Item.objects.filter(serial_number__isnull=True,is_trade=0).values('product__id','product__product_name','product__sku').annotate(qty=Count('product__id'))
    order_item=[]
    for or1 in order_items:
        sr=SerialNumber.objects.filter(product__id=or1['product__id'],customer=None).count()
        if or1['qty']-sr == 0:
            pass
        else:
            or1['reuiredbilledqty']=or1['qty']-sr
            order_item.append(or1)
    products=Product.objects.filter(is_product=0)
    total_records = len(order_item)
    show_pagination = total_records >settings.PAGE_RECORDS
    if show_pagination: 
        page = request.GET.get('page', 1)
        paginator = Paginator(order_item, settings.PAGE_RECORDS)  # Show 10 orders per page
        try:
            order_item = paginator.page(page)
        except PageNotAnInteger:
            order_item = paginator.page(1)
        except EmptyPage:
            order_item = paginator.page(paginator.num_pages)
    return render(request,'pages/notification/product_list_need_to_bill.html',{'products':products,'order_items':order_item})


def reject_quotation(request,id):
    quotation = get_object_or_404(Quotation, id=id)
    quotation.status = 4
    quotation.admin_response_mail=True
    quotation.save()
    messages.success(request, 'Quote Reject Successfully.')
    return redirect('quotation:list_quotation')


def approval_quotation(request,id):

    quotation = Quotation.objects.get(id=id)
    quotation.status = 5
    quotation.admin_response_mail=True
    quotation.save()
    messages.success(request, 'Quote Approved Successfully.')
    return redirect('quotation:list_quotation')

def testsss(request):
    return render(request,'pages/quotation/test.html')   
 
def technician_part_needed_job_list(request):

    customers = Customer.objects.all()
    products=Product.objects.all()
    technicians=User.objects.filter(role=3,deleted_at__isnull=True)
    # technician_name = request.GET.get('technician_name')  
    # customer_name = request.GET.get('customer_name')
    start_date = request.GET.get('start_date')
    end_date = request.GET.get('end_date')
    # status = request.GET.get('status')

    customer_id = request.GET.get('customer_id')
    technician_id = request.GET.get('technician_id')
    product_id = request.GET.get('product_id')
    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()
  
    technician_part_needed_job_lists =  Parts_Request.objects.filter(technician_assigned_job__job_status=2)

    if technician_id:
        technician_part_needed_job_lists = Parts_Request.objects.filter(Q(technician_assigned_job__technician__id=technician_id,technician_assigned_job__job_status=2 ) )
    

    if customer_id:
        technician_part_needed_job_lists = Parts_Request.objects.filter(Q(technician_assigned_job__order_item__order__invoice__customer__id=customer_id,technician_assigned_job__job_status=2) )
    
    if product_id:
        technician_part_needed_job_lists = Parts_Request.objects.filter(Q(technician_assigned_job__order_item__product__id=product_id,technician_assigned_job__job_status=2) )

    if start_date:
        technician_part_needed_job_lists = technician_part_needed_job_lists.filter(technician_assigned_job__booking_date__gte=start_date,technician_assigned_job__job_status=2 )
    if end_date:
        technician_part_needed_job_lists = technician_part_needed_job_lists.filter(technician_assigned_job__booking_date__lte=end_date,technician_assigned_job__job_status=2 )
   
   
    total_records = technician_part_needed_job_lists.count()
    show_pagination = total_records > settings.PAGE_RECORDS


    if show_pagination: 

        page = request.GET.get('page', 1)
        paginator = Paginator(technician_part_needed_job_lists, settings.PAGE_RECORDS)  # Show 10 orders per page
        try:
            technician_part_needed_job_lists = paginator.page(page)
        except PageNotAnInteger:
            technician_part_needed_job_lists = paginator.page(1)
        except EmptyPage:
            technician_part_needed_job_lists = paginator.page(paginator.num_pages)
    
    # dd(technician_part_needed_job_lists)
    return render(request,'pages/order/part_needed_job_list.html',{'technician_part_needed_job_lists':technician_part_needed_job_lists,'technicians':technicians,'customers':customers,'products':products})   
    
    
    
def technician_part_needed_job_list_received(request,id):
    technician_part_needed_job_lists =  Parts_Request.objects.get(id = id)
    technician_part_needed_job_lists.status=3
    technician_part_needed_job_lists.save()
    technician_part_needed_job_lists1 =  Parts_Request.objects.filter(technician_assigned_job = technician_part_needed_job_lists.technician_assigned_job,status = 2)
    if not technician_part_needed_job_lists1:
        t=Technician_Assigned_Order_Item.objects.get(id=technician_part_needed_job_lists.technician_assigned_job.id)
      
        t.job_status=3
        
        t.working_status=9
        t.save()
       
        o_i=Order_Item.objects.get(id=t.order_item.id)
        o_i.status=3
        o_i.save()
        # try:
        #     get_registration_token = get_object_or_404(FCMDevice,user_id=t.technician.id,active=True)
        #     sendPush('Job Parts Received Notification',f'EXCITECH Australia - Job Parts Received Notification-{t.id}',[get_registration_token.registration_id])
        # except FCMDevice.DoesNotExist:
        #     print("FCMDevice not found for the specified conditions. Push notification not sent.")
        # except Exception as e:
        #     print(f"Error sending push notification: {e}")
        send_technician_email_notification(t)
    return redirect('/technician/part-needed/job/list/')

def send_technician_email_notification(assignment):
    subject = f'EXCITECH Australia - Job Parts Received Notification-{assignment.id}'
    formatted_date = assignment.installation_date.strftime('%d-%m-%Y')
    formatted_time = assignment.installation_time.strftime('%I:%M %p') 
    template_data = {'assignment': assignment,'formatted_date':formatted_date,'formatted_time':formatted_time}
    message = render_to_string('pages/quotation/job_assigned_email_temp.html', template_data)

    try:
        get_registration_token = FCMDevice.objects.filter(user_id=assignment.technician.id,active=True)
        for i in get_registration_token:
            sendPush('Job Parts Received Notification',f'EXCITECH Australia - Job Parts Received Notification-{assignment.id}',[i.registration_id])
    except FCMDevice.DoesNotExist:
        print("FCMDevice not found for the specified conditions. Push notification not sent.")
    except Exception as e:
        print(f"Error sending push notification: {e}")
        
    
    try:
        get_registration_token =  FCMDevice.objects.filter(user_id=assignment.order_item.order.invoice.customer.user.id, active=True)
        for i in get_registration_token:
            sendPush('Job Parts Received Notification',f'EXCITECH Australia - Job Parts Received Notification-{assignment.id}',[i.registration_id])
    except FCMDevice.DoesNotExist:
        print("FCMDevice not found for the specified conditions. Push notification not sent.")
    except Exception as e:
        print(f"Error sending push notification: {e}")

    from_email = settings.FROM_EMAIL # Replace with your email 
    recipient_email = assignment.technician.email
    email = EmailMessage(subject, message, from_email, [recipient_email])
    email.content_subtype = 'html'
    email.send()
    

def create_checkout_session(request,id):
    try:

        if request.method == 'POST':
            invoiceNumber = request.POST.get('invoiceNumber')
            invoice=Invoice.objects.get(id=id)
            invoiceTotal = request.POST.get('invoiceTotal')
            payableAmount = request.POST.get('payableAmount')
            payAmount = float(request.POST.get('payAmount')) 
            description=request.POST.get('description')# Added the missing closing parenthesis
            line_items = [
                {
                    'price_data': {
                        'currency': 'aud',
                        'product_data': {
                            'name': f"Invoice Number {invoiceNumber} Total Amount {invoiceTotal} Payable Amount {payableAmount}",
                            'description': description,
                        },
                        'unit_amount': int(payAmount * 100),  # Amount in cents
                    },
                    'quantity': 1,
                }
            ]

            session = stripe.checkout.Session.create(
                payment_method_types=['card'],
                customer_email=invoice.customer.user.email,
                line_items=line_items,
                mode='payment',
                success_url=request.build_absolute_uri(reverse("quotation:success"))+ f"?session_id={{CHECKOUT_SESSION_ID}}&invoice_id={invoice.id}",
                # success_url= request.build_absolute_uri(reverse('quotation:success', args=[CHECKOUT_SESSION_ID])),
                
                cancel_url=request.build_absolute_uri(reverse('quotation:cancel')),
     
            )
     
            return redirect(session.url)

    except stripe.error.StripeError as e:
        # Handle Stripe errors
        return HttpResponseServerError(f'Error: {e.error.message}')

    except Invoice.DoesNotExist:
        # Handle the case where the invoice with the provided ID does not exist
        return HttpResponseServerError('Invoice does not exist.')

    except Exception as e:
        # Handle other exceptions
        return HttpResponseServerError(f'Unexpected error: {str(e)}')
        
def success(request):
    print('in success')
    print(request.GET.get('session_id'))
    print(request)
    session_id=request.GET.get('session_id')
    invoice_id=request.GET.get('invoice_id')
    print(invoice_id)
    
    session = stripe.checkout.Session.retrieve(session_id)
    order_id = session.get('client_reference_id')
    print('ddkdkdkd',order_id)
    payment_status = session.get('payment_status')
    amount_paid = session.get('amount_total')
    currency = session.get('currency')
    payment_reference_id = session.get('payment_intent')
    stripe_id = session.get('id')
    description = session.get('description')
    print(session)
    print(payment_status)
    print(amount_paid)
    print(payment_reference_id)   
    
    payAmount= amount_paid / 100
    refresh_token(request)

    myobdata = MyobModel.objects.first()
    if not myobdata:
        messages.error(request,'Please First create Access Code')
        return redirect('/myob/initiate-connection')
        
    customer_invoice=Invoice.objects.get(id=invoice_id)
    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}/Sale/CustomerPayment"

    
    sale_order_uid=customer_invoice.sale_uid
    
    payable_amount=float(customer_invoice.payable_amount)-payAmount
    customer_payment=Customer_Payment(
        invoice=customer_invoice,
        payable_amount=abs(payable_amount),
        paid_amount=abs(payAmount),
        description=description,
        due_amount=abs(payable_amount),
        stripe_id=stripe_id,
        payment_reference_id=payment_reference_id
    )

    # customer_payment.created_by=request.user
    customer_payment.save()
    customer_invoice.payable_amount=payable_amount
    total_paid_amount = customer_invoice.invoice_payment.aggregate(Sum('paid_amount'))['paid_amount__sum'] or 0
    
    if customer_invoice.total > total_paid_amount:
        customer_invoice.status = 3
    elif customer_invoice.total <= total_paid_amount:
        customer_invoice.status = 4
    


    customer_invoice.total_paid_amount=total_paid_amount
    customer_invoice.stripe_id=stripe_id
    customer_invoice.payment_reference_id=payment_reference_id
    customer_invoice.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'
    }


    customer_payment=Customer_Payment.objects.latest('id')

    customerpayment={
        "PayFrom": "Account",
        "Account": {
            "UID": "bbcdb17b-8526-4fe1-9fbd-2e23c6c6b18e"
        },
        "Customer": {
            "UID": customer_invoice.customer.myob_uid
        },
        "PayeeAddress": None,
        "StatementParticulars": "",
        "PaymentNumber": customer_invoice.po_number,
        "Date": customer_payment.paydate.strftime('%Y-%m-%dT%H:%M:%S'),
        "AmountPaid": float(customer_payment.paid_amount),
        "Memo": customer_payment.description,
        "Invoices": [{
            "UID": customer_invoice.sale_uid,
            "AmountApplied": float(customer_payment.paid_amount),
            "Type": "Order"
        }],
        "DeliveryStatus": "Print",
        "ForeignCurrency": None
    }

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

    if response.status_code == 201:

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

            customer_payment.uid=uid
            customer_payment.save()
            
            
            api_urls = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item/{sale_order_uid}"
                   
            headers = {
                'Authorization': f'Bearer {myobdata.access_token}',
                'x-myobapi-key': settings.MYOB_CLIENT_ID,
                'x-myobapi-version': 'v2',
                'Accept-Encoding':'gzip,deflate',
                'Accept':'Application/PDF',
            }

            response = requests.get(api_urls, headers=headers,)
            pdf_data=response.content
            content = ContentFile(pdf_data)

          
            customer_invoice.myob_invoice_pdf.save(f'{customer_invoice.id}_invoice.pdf', content)
            customer_invoice.save()
            
            print(customer_invoice.due_amount())
            
            due_amount =  customer_invoice.due_amount()
            if due_amount == '$0.00':
                headerss = {
                    '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'
                }
                
                sales_order_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item/{sale_order_uid}"
                response = requests.get(sales_order_url, headers=headerss)
                sales_order_data = response.json()
                
               
                lines = sales_order_data['Lines']
                
                current_row_version = sales_order_data.get('RowVersion')
                invoice_data = {
                'Customer': sales_order_data['Customer'],
                'Number': customer_invoice.id,
                "Date":customer_invoice.invoice_date.strftime('%Y-%m-%dT%H:%M:%S'),
                "SupplierInvoiceNumber": None,

                "ShipToAddress": f'{customer_invoice.customer.street} {customer_invoice.customer.city} {customer_invoice.customer.state} {customer_invoice.customer.post_code} {customer_invoice.customer.country}',

                "Terms": { 
                    "PaymentIsDue": "DayOfMonthAfterEOM",
                    "DiscountDate": 1,
                    "BalanceDueDate": 30,
                    "DiscountForEarlyPayment": 0,
                    "MonthlyChargeForLatePayment": 0,
                    "DiscountExpiryDate": None,
                    "Discount":float(customer_invoice.discount),
                    "DueDate": customer_invoice.due_date.strftime('%Y-%m-%dT%H:%M:%S'),
                },
                "IsTaxInclusive": False,
                "Lines": [],
                "IsReportable": False,
               
                "Subtotal": float(customer_invoice.subtotal),
                "Freight": 0,
                "FreightTaxCode":  {
                        "UID": myob_quotation_freightaxcode
                    },
                "TotalTax": float(customer_invoice.gst),
                "TotalAmount": float(customer_invoice.total),
                "Category": None,
                "Comment": "",
                "CustomerPurchaseOrderNumber":customer_invoice.id,
                "ShippingMethod": None,
                "PromisedDate": None,
                "JournalMemo": "Purchase; 786",
                "BillDeliveryStatus": "Print",
                "AppliedToDate": 0,
                "BalanceDueAmount": 0,
                # "Status": 'ConvertedToInvoice',
                "Status":'Open',
                "LastPaymentDate": None,
                "Order":{
                        "UID": customer_invoice.sale_uid,
                    },
                "ForeignCurrency":None,
            

                }
                for line in lines:
                    print("dfgh")
                    line_type= line['Type']
                    line_description = line['Description']
                    line_total = line['Total'] 
                    line_shipqty= line['ShipQuantity']
                    line_unitprice= line['UnitPrice']
                    line_item= line['Item']['UID'] 
                    line_text=line['TaxCode']['UID']
                    invoice_data["Lines"].append({
                        "Type": "Transaction",
                        "Description": line_description,
                        "Total": line_total,
                        "ShipQuantity": line_shipqty,
                        "UnitPrice": line_unitprice,
                        
                        "Item":{
                            'UID':line_item
                        },
                        "TaxCode":{
                            
                            'UID':line_text
                        },
                        "Account": {
                        "UID": myob_quotation_account,
                    },
                     
                    })
                headeres = {
                    'Authorization': f'Bearer {myobdata.access_token}',
                    'x-myobapi-key': settings.MYOB_CLIENT_ID,
                    'x-myobapi-version': 'v2',
                    'Content-Type': 'application/json',

                }
                post_json = json.dumps(invoice_data)

                invoice_url=f'https://api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Invoice/Item'
                
                response = requests.post(invoice_url, data=post_json, headers=headeres)
                data=response.headers

                if response.status_code == 201:
                    pdf_data=response.content
                    print(pdf_data)
                    content = ContentFile(pdf_data)
                    print(content)
                    
                    location = data['Location']
                
                    if location:
                        parts = location.split('/')
                        uid = parts[-1]
        
                        invoice_api_url = f"https://api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Invoice/Item/{uid}"
                        print(api_url)
        
                        headerss = {
                            'Authorization': f'Bearer {myobdata.access_token}',
                            'x-myobapi-key': settings.MYOB_CLIENT_ID,
                            'x-myobapi-version': 'v2',
                            'Accept-Encoding':'gzip,deflate',
                            'Accept':'Application/PDF',
                        }

                        response = requests.get(invoice_api_url, headers=headerss,)
                        pdf_data=response.content
                        content = ContentFile(pdf_data)
        
                        customer_invoice.uid = uid
                        customer_invoice.myob_invoice_pdf.save(f'{customer_invoice.id}_invoice.pdf', content)
                        customer_invoice.save()
                          


        response = requests.get(api_url,headers=headers)
        myob_data=response.json()
        matching_customer_payments = []
        
        for customer_payments in myob_data["Items"]:
    

            invoices = customer_payments["Invoices"]
            for invoice in invoices:
                if invoice["UID"] == sale_order_uid:
                
                    matching_customer_payments.append(customer_payments)

        
        # for matching_payment in matching_customer_payments:
        #     customer_payment.bill_number=matching_payment["ReceiptNumber"]
        #     customer_payment.save()
    
    return render(request, 'pages/payment_gateway/success.html')
   

def cancel(request):
    return render(request, 'pages/payment_gateway/cancel.html')


def checkout(request,id):
    invoice = Invoice.objects.get(id=id)
 
    invoice_item = InvoiceItem.objects.filter(invoice=invoice)
    products_with_sku = [{'name': item.product.product_name, 'sku': item.product.sku} for item in invoice_item]
        
    return render(request, 'pages/payment_gateway/checkout.html',{'invoice':invoice})


@csrf_exempt
def update_serial_number_status(request):
    print(request.method)
    if request.method == 'GET':
        print('get method')
        return HttpResponseBadRequest("Invalid request")
    if request.method == 'POST':
        order_item_id = request.POST.get('order_item_id')
        print(order_item_id)
        print(request.POST)
        bill_item_id = request.POST.get('bill_item_id')
        serial_number_id = request.POST.get('serial_number_id')
        status = request.POST.get('status')
        typeorder = request.POST.get('type')
        # if typeorder == 'order item':
        
        if order_item_id and bill_item_id:
            print("bill_item_id")
            if bill_item_id:
                bill = get_object_or_404(Supplier_Bill, id=bill_item_id)
                bill_item = get_object_or_404(SerialNumber, bill=bill.id, id=serial_number_id)
            else:
                bill_item = get_object_or_404(SerialNumber,id=serial_number_id)
            print(bill_item)
            if status != '4':
                bill_item.tracking_status = status
                bill_item.updated_by = request.user
            if status == '3' :
                bill_item.arrived_date = datetime.today()
                # order_item = get_object_or_404(Order_Item, serial_number__id=serial_number_id)
                # if order_item:
                #     order_item.status = status
                #     order_item.save()
            bill_item.save()
            messages.success(request, 'Bill Product Status Updated Successfully.')
            return HttpResponse('Bill Product Status Updated Successfully.')
        elif bill_item_id or serial_number_id:
            print("bill_item_id")
            print(bill_item_id)
            # if status != '4':
            if bill_item_id:
                # bill = get_object_or_404(Supplier_Bill, id=bill_item_id)
                bill_item = get_object_or_404(SerialNumber, id=serial_number_id)
            else:
                bill_item = get_object_or_404(SerialNumber,id=serial_number_id)
            print(bill_item)
            if status != '4':
                bill_item.tracking_status = status
                bill_item.updated_by = request.user
            if status == '3' :
                bill_item.arrived_date = datetime.today()
                # order_item = get_object_or_404(Order_Item, serial_number__id=serial_number_id)
                # if order_item:
                #     order_item.status = status
                #     order_item.save()
            bill_item.save()
            print('done')
            messages.success(request, 'Bill Product Status Updated Successfully.')
            return HttpResponse('Bill Product Status Updated Successfully.')
        else:
            messages.success(request, 'No record found.')
            return HttpResponse('No record found.')
    return HttpResponseBadRequest("Invalid request")


@csrf_exempt
def update_status(request):
    if request.method == 'POST':
        order_item_id = request.POST.get('order_item_id')
        bill_item_id = request.POST.get('bill_item_id')
        serial_number_id = request.POST.get('serial_number_id')
        status = request.POST.get('status')
        if  order_item_id:
            order_item = get_object_or_404(Order_Item, id=order_item_id)
            order_item.status = status
            order_item.updated_by = request.user
            order_item.save()
            if(order_item.serial_number):
                if(order_item.serial_number.bill):
                    bill = get_object_or_404(Supplier_Bill, id=order_item.serial_number.bill.id)
                    bill_item = get_object_or_404(SerialNumber, bill=order_item.serial_number.bill.id, id=order_item.serial_number.id)
                else:
                    bill_item = get_object_or_404(SerialNumber, id=order_item.serial_number.id)
                bill_item.tracking_status = status
                bill_item.updated_by = request.user
                bill_item.save()
            if status == '3' :
                bill_item.arrived_date = datetime.today()
                bill_item.save()
            if status == '0' or status == '1' or status == '2':
                bill_item.arrived_date = None
                # bill_item.Arrival_ETA_date = None
                bill_item.save()
            # push_notification(order_item)
            messages.success(request, 'Order Bill Product Status Updated Successfully.')
            return redirect('/order/tracking-order-status/')
    return HttpResponseBadRequest("Invalid request")
    
@csrf_exempt
def update_SN_status(request):
    if request.method == 'POST':
        order_item_id = request.POST.get('order_item_id')
        status = request.POST.get('status')
        if  order_item_id:
            order_item = get_object_or_404(SerialNumber, id=order_item_id)
            order_item.tracking_status = status
            order_item.updated_by = request.user
            order_item.save()
            
            if status == '3' :
                order_item.arrived_date = datetime.today()
                order_item.save()
            if status == '0' or status == '1' or status == '2':
                order_item.arrived_date = None
                # bill_item.Arrival_ETA_date = None
                order_item.save()
            # push_notification(order_item)
            messages.success(request, 'Bill Product Status Updated Successfully.')
            return redirect('/order/tracking-order-status/')
    return HttpResponseBadRequest("Invalid request")
    


def update_order_status(request):
    if request.method == 'POST':
        order_item_id = request.POST.get('order_item_id')
        status = request.POST.get('status')
        if  order_item_id:
            order_item = get_object_or_404(Order_Item, id=order_item_id)
            order_item.status = status
            order_item.updated_by = request.user
            order_item.save()
            serial_number = SerialNumber.objects.filter(id=order_item.serial_number.id).first()
            # dd(serial_number)
            serial_number.tracking_status = status
            if status == '3' :
                serial_number.arrived_date = datetime.today()
            serial_number.save()
            messages.success(request, 'Order Product Status Updated Successfully.')
            return redirect('/order/tracking-order-status/')
    return HttpResponseBadRequest("Invalid request")   

def update_bill_status(request):
    if request.method == 'POST':
        order_item_id = request.POST.get('order_item_id')
        order_type = request.POST.get('order_type')
        arrival_eta_datestr = request.POST.get('arrival_eta_date')
        arrival_eta_date=datetime.strptime(arrival_eta_datestr, '%d-%m-%Y').date()
        # datetime.strptime(arrival_eta_datestr, '%Y-%m-%d')
        print(order_item_id)
        print(order_type)
        print(arrival_eta_date)
        print('here')
        status = 1
        if order_type == '1':
            order_item = Order_Item.objects.filter(id=order_item_id).first()
            if order_item:
                # dd(order_item)
                order_item.status = status
                order_item.updated_by = request.user
                order_item.save()
            
            serial_number = SerialNumber.objects.filter(id=order_item.serial_number.id).first()
            print(serial_number.id)
            serial_number.tracking_status = status
            serial_number.Arrival_ETA_date = arrival_eta_date
            serial_number.save()
            print(serial_number)
        else:
            serial_number = SerialNumber.objects.filter(id=order_item_id).first()
            serial_number.tracking_status = status
            serial_number.Arrival_ETA_date = arrival_eta_date
            serial_number.save()
        if order_type == '1' or order_type == '2':
            messages.success(request, 'Order Product Status Updated Successfully.')
            return redirect('/order/tracking-order-status/')
        else:
            messages.success(request, 'Record Updated Successfully.')
            return redirect('/dashboard')
    return HttpResponseBadRequest("Invalid request")  
    
    
 
@csrf_exempt
def update_tttechnician(request):
    if request.method == 'POST':
        if request.POST.get('technician'):
            order_item_id = request.POST.get('order_item_id')
          

            # order_identifier= request.POST.get('order_identifier')
            technician = request.POST.get('technician')
            installation_date_str = request.POST.get('installation_date')
            # dd(installation_date)
            installation_time_str = request.POST.get('installation_time')
            technician = User.objects.get(id=technician)
            order_item = Order_Item.objects.get(id=order_item_id)
            # installation_date = datetime.strptime(installation_date_str, '%Y-%m-%d')
            installation_date=datetime.strptime(installation_date_str, '%d-%m-%Y').date()
            installation_time = datetime.strptime(installation_time_str, '%H:%M')
            
            
            
            testpayment= Technician_Assigned_Order_Item.objects.filter(order_item=order_item)
            total_paid_amount=order_item.order.invoice.total_paid_amount
            payable_amount=order_item.order.invoice.payable_amount
            # Initialize existing_assignment
            if testpayment or payable_amount == 0:
                # dd('216')
                order_item.service_type=1
                order_item.save()
                existing_assignment = None
                existing_assignment, created = Technician_Assigned_Order_Item.objects.update_or_create(
                    order_item=order_item,
                    defaults={
                        'technician': technician,
                        'installation_date': installation_date,  # Ensure it's a date object
                        'installation_time': installation_time,
                        'updated_by': request.user if existing_assignment else None,
                        'deleted_by': None,
                        'deleted_at': None,
                    }
                )
                print('deepak',f'ddd-{existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name}')
                try:
                    get_registration_token = FCMDevice.objects.filter(user_id=existing_assignment.order_item.order.invoice.customer.user.id,active=True)
                    for i in get_registration_token:
                    
                        sendPush('Technician Assigned Notification',f'EXCITECH Australia - Technician Assigned-{existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name}',[i.registration_id])
                except FCMDevice.DoesNotExist:
                  print("FCMDevice not found for the specified conditions. Push notification not sent.")
                except Exception as e:
                    print(f"Error sending push notification: {e}")
                
                if not created:
                    messages.success(request, 'Technician Assigned Successfully.')
                else:
                    messages.success(request, 'Technician Assigned Successfully.')

                # Send email to technician
                send_technician_email(existing_assignment)
                return redirect('/order/tracking-order-status/')      
            else:
                # dd('237')
                #  check partially done payment
                order_item.service_type=1
                order_item.save()
                testpaymentcheck= Technician_Assigned_Order_Item.objects.filter(order_item__order=order_item.order)
                gst_percent=order_item.order.invoice.gst_percent
                cost_per_unit=order_item.cost_per_unit
                total=cost_per_unit
                if gst_percent != 0:
                    total=((cost_per_unit/100)*gst_percent)+cost_per_unit
                if not testpaymentcheck and total <= total_paid_amount:
                    # dd('246')
                    
                   
                    existing_assignment = None
                    existing_assignment, created = Technician_Assigned_Order_Item.objects.update_or_create(
                        order_item=order_item,
                        defaults={
                            'technician': technician,
                            'installation_date': installation_date,  # Ensure it's a date object
                            'installation_time': installation_time,
                            'updated_by': request.user if existing_assignment else None,
                            'deleted_by': None,
                            'deleted_at': None,
                        }
                    )
                    
                    print('deepak',f'ddd-{existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name}')
                    try:
                        get_registration_token = FCMDevice.objects.filter(user_id=existing_assignment.order_item.order.invoice.customer.user.id,active=True)
                        for i in get_registration_token:
                            sendPush('Technician Assigned Notification',f'EXCITECH Australia - Technician Assigned-{existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name}',[i.registration_id])
                    except FCMDevice.DoesNotExist:
                        print("FCMDevice not found for the specified conditions. Push notification not sent.")
                    except Exception as e:
                        print(f"Error sending push notification: {e}")
                    if not created:

                        messages.success(request, 'Technician Assigned Successfully.')
                    else:
                        messages.success(request, 'Technician Assigned Successfully.')

                    # Send email to technician
                    send_technician_email(existing_assignment)
                    return redirect('/order/tracking-order-status/') 
                else:
                  
                    totalall=0
                    for o_i in testpaymentcheck:
                        gst_percent=o_i.order_item.order.invoice.gst_percent
                        cost_per_unit=o_i.order_item.cost_per_unit
                        total1=cost_per_unit
                        if gst_percent != 0:
                            total1=((cost_per_unit/100)*gst_percent)+cost_per_unit
                        totalall= totalall+total1
                    total=total+totalall
                    if total <= total_paid_amount:
                        # dd(277)
                        existing_assignment = None
                        existing_assignment, created = Technician_Assigned_Order_Item.objects.update_or_create(
                            order_item=order_item,
                            defaults={
                                'technician': technician,
                                'installation_date': installation_date,  # Ensure it's a date object
                                'installation_time': installation_time,
                                'updated_by': request.user if existing_assignment else None,
                                'deleted_by': None,
                                'deleted_at': None,
                            }
                        )
                        print('deepak',f'ddd-{existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name}')
                        try:
                            get_registration_token = FCMDevice.objects.filter(user_id=existing_assignment.order_item.order.invoice.customer.user.id,active=True)
                            for i in get_registration_token:
                                sendPush('Technician Assigned Notification',f'EXCITECH Australia - Technician Assigned -{existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name}',[i.registration_id])
                        except FCMDevice.DoesNotExist:
                            print("FCMDevice not found for the specified conditions. Push notification not sent.")
                        except Exception as e:
                            print(f"Error sending push notification: {e}")
                        if not created:
                            messages.success(request, 'Technician Assigned Successfully.')
                        else:
                            messages.success(request, 'Technician Assigned Successfully.')

                        # Send email to technician
                        send_technician_email(existing_assignment)
                        return redirect('/order/tracking-order-status/') 
                    else:
                        # dd('298')
                        messages.success(request, 'Not Paid Amount To Proceed.')
                        return redirect('/order/tracking-order-status/')
                
@csrf_exempt            
def checkpaymentstatus(request):
    if request.method == 'POST':
        if request.POST.get('order_item_id'):
            order_item_id = request.POST.get('order_item_id')
            print(order_item_id)
            order_item = Order_Item.objects.get(id=order_item_id)
            testpayment= Technician_Assigned_Order_Item.objects.filter(order_item=order_item)
            total_paid_amount=order_item.order.invoice.total_paid_amount
            payable_amount=order_item.order.invoice.payable_amount
            # Initialize existing_assignment
            if testpayment or payable_amount == 0:
                return JsonResponse({'status': 1,'total_paid_amount': total_paid_amount,'payable_amount' : payable_amount}) 
            else:
                # dd('237')
                #  check partially done payment
                testpaymentcheck= Technician_Assigned_Order_Item.objects.filter(order_item__order=order_item.order)
                gst_percent=order_item.order.invoice.gst_percent
                cost_per_unit=order_item.cost_per_unit
                total=cost_per_unit
                if gst_percent != 0:
                    total=((cost_per_unit/100)*gst_percent)+cost_per_unit
                if not testpaymentcheck and total <= total_paid_amount:
                    return JsonResponse({'status': 1,'here':'here','total_paid_amount': total_paid_amount,'payable_amount' : payable_amount,'total':total}) 
                else:
                    totalall=0
                    for o_i in testpaymentcheck:
                        gst_percent=o_i.order_item.order.invoice.gst_percent
                        cost_per_unit=o_i.order_item.cost_per_unit
                        total1=cost_per_unit
                        if gst_percent != 0:
                            total1=((cost_per_unit/100)*gst_percent)+cost_per_unit
                        totalall= totalall+total1
                    total=total+totalall
                    if total <= total_paid_amount:
                        return JsonResponse({'status': 1,'total_paid_amount': total_paid_amount,'payable_amount' : payable_amount,'total':total}) 
                    else:
                        return JsonResponse({'status': 0,'total_paid_amount': total_paid_amount,'payable_amount' : payable_amount,'total':total}) 



def check_technician_jobs(request):
    time_difference = timedelta(hours=6)
    current_time = timezone.now()
    unviewed_jobs = Technician_Assigned_Order_Item.objects.filter(view_by_technician=False, created_at__lt=current_time - time_difference)
    print("real_time",unviewed_jobs)
    for assignment in unviewed_jobs:
        print(assignment)
        send_technician_email(assignment)
    return HttpResponse('mail sent function call')  
    
    
def send_technician_email(assignment):
    subject = f'EXCITECH Australia - Job Assigned Notification (Installation)- Job Id: {assignment.id}'
    formatted_date = assignment.installation_date.strftime('%d-%m-%Y')
    formatted_time = assignment.installation_time.strftime('%I:%M %p') 
    
    
    template_data = {'assignment': assignment,'formatted_date':formatted_date,'formatted_time':formatted_time}
    message = render_to_string('pages/quotation/job_assigned_email_temp.html', template_data)
    try:
        get_registration_token = FCMDevice.objects.filter(user_id=assignment.technician.id,active=True)
        for i in get_registration_token:
            sendPush('Job Assigned Notification (Installation)',f'EXCITECH Australia - Job Assigned Notification (Installation)- Job Id: {assignment.id}',[i.registration_id])
    except FCMDevice.DoesNotExist:
        print("FCMDevice not found for the specified conditions. Push notification not sent.")
    except Exception as e:
        print(f"Error sending push notification: {e}")
    from_email = settings.FROM_EMAIL # Replace with your email
    recipient_email = assignment.technician.email
    email = EmailMessage(subject, message, from_email, [recipient_email])
    email.content_subtype = 'html'
    email.send()
        
@login_required
def getOrderDetails(request):
    if request.method == 'POST':
        # order_id=request.POST.get('order_id')
        # order_identifier=request.POST.get('order_identifier')
        # technicians=User.objects.filter(role=3,deleted_at__isnull=True)
        # o_item=Order_Item.objects.filter( order__id=order_id , order_identifier=order_identifier)
        # return render(request,'pages/order/order_modal.html',{'order':o_item,'technicians':technicians})
       
        order_item_id=request.POST.get('order_item_id')
        status=request.POST.get('status')
        billItemId=request.POST.get('billItemId')
        ordertype=request.POST.get('ordertype')
        order_items = ()
        if(ordertype=='order'):
            order_items = Order_Item.objects.filter(id=order_item_id)
        else:
            order_items = SerialNumber.objects.filter(id=order_item_id)
        technicians=User.objects.filter(role=3,deleted_at__isnull=True)
        customer = Customer.objects.all()
        suppliers = Supplier.objects.all()
        products=Product.objects.all()
        # dd(order_items)
        return render(request,'pages/order/order_modal.html',{'order_items':order_items,'technicians':technicians,'customers':customer,'suppliers':suppliers,'products':products})

@login_required
def technician_update_installation_date(request,id):
    order_item=Order_Item.objects.get(id=id)
    assigned_orderitem =Technician_Assigned_Order_Item.objects.get(order_item=order_item)
    if request.method =="POST":
        assigned_orderitem.installation_date=request.POST.get('installation_date')
        assigned_orderitem.comment = request.POST.get('comment')
        
        
        assigned_orderitem.installation_time= request.POST.get('installation_time')
        assigned_orderitem.save()
        messages.success(request,'Installation Date Updated Successfully.')
        return redirect('quotation:technician_assigned_product',id=assigned_orderitem.order_item.order.id)


@login_required
def technician_assigned_product(request,id):
    order= Order.objects.get(id=id)
    
    assigned_products=Technician_Assigned_Order_Item.objects.filter(order_item__order=order,technician = request.user)
    

    technicians=User.objects.filter(role=3,deleted_at__isnull=True)
    
    

    return render(request,'pages/technician/assigend_product.html',{'order':order,'assigned_products':assigned_products,'technicians':technicians})

@login_required  
def technician_assigned_orders(request):
    assigned_orders = Technician_Assigned_Order_Item.objects.filter(technician=request.user)

    return render(request,'pages/technician/assigend_orders_list.html',{'assigned_orders':assigned_orders})
from geopy.geocoders import Nominatim




@login_required  
def technician_assigned_item_list(request,id):
    technician_assigned_item_lists=Technician_Assigned_Order_Item.objects.filter(order_item__order__id=id)

    technician_orderitem_history=Technician_Comment.objects.filter(technician_assigend_order_item__in=technician_assigned_item_lists)
    
 
    
    return render(request,'pages/order/technician_assigned_item_list.html',{'technician_assigned_item_lists':technician_assigned_item_lists,'technician_orderitem_history':technician_orderitem_history})
 
    
@login_required
def job_activity(request, job_id):
    print("deepawertytrek")
    technician_assigned_item=Technician_Assigned_Order_Item.objects.get(id=job_id)

    technician_orderitem_history=Technician_Comment.objects.filter(technician_assigend_order_item__in=technician_assigned_item)
    return redirect('quotation:technician_assigned_job_list')   
     
 

@login_required  
def technician_assigned_job_list(request):
    customer_id = request.GET.get('customer_id')
    technician_id = request.GET.get('technician_id')
    product_id = request.GET.get('product_id')
    start_date = request.GET.get('start_date')
    end_date = request.GET.get('end_date')
    job_type = request.GET.get('job_type')
    serial_number=request.GET.get('serial_number')
    technicians=User.objects.filter(role=3,deleted_at__isnull=True)
    customers = Customer.objects.all()
    serial_numbers = SerialNumber.objects.filter(serial_number__isnull = False).filter(
    ~Q(serial_number=''),
    ~Q(serial_number=' ')
)
    products=Product.objects.all() 
    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()
  
    technician_assigned_job_lists =  Technician_Assigned_Order_Item.objects.all()
    technician_orderitem_history=Technician_Comment.objects.filter(technician_assigend_order_item__in=technician_assigned_job_lists)
    # job_call_details=CallDetail.objects.filter(assigend_order_item__in=technician_assigned_job_lists)
    
    if technician_id:
        technician_assigned_job_lists = Technician_Assigned_Order_Item.objects.filter(Q(technician__id=technician_id ) )
    

    if customer_id:
        technician_assigned_job_lists = Technician_Assigned_Order_Item.objects.filter(Q(order_item__order__invoice__customer__id=customer_id) )
    
    if product_id:
        technician_assigned_job_lists = Technician_Assigned_Order_Item.objects.filter(Q(order_item__product__id=product_id) )
    if serial_number:
        technician_assigned_job_lists = Technician_Assigned_Order_Item.objects.filter(Q(order_item__serial_number__serial_number=serial_number) )
    if start_date:
        technician_assigned_job_lists = technician_assigned_job_lists.filter(Q(booking_date__gte=start_date))
    if end_date:
        technician_assigned_job_lists = technician_assigned_job_lists.filter(Q(booking_date__lte=end_date))
    if job_type:
        technician_assigned_job_lists = technician_assigned_job_lists.filter(Q(job_type=job_type))
   
   
    total_records = technician_assigned_job_lists.count()
    show_pagination = total_records > settings.PAGE_RECORDS

 
    if show_pagination: 

        page = request.GET.get('page', 1)
        paginator = Paginator(technician_assigned_job_lists, settings.PAGE_RECORDS)  # Show 10 orders per page
        try:
            technician_assigned_job_lists = paginator.page(page)
        except PageNotAnInteger:
            technician_assigned_job_lists = paginator.page(1)
        except EmptyPage:
            technician_assigned_job_lists = paginator.page(paginator.num_pages)
    # dd(serial_numbers)
    return render(request,'pages/order/technician_assigned_job_list.html',{'serial_numbers':serial_numbers,'technician_assigned_job_lists':technician_assigned_job_lists,'technicians':technicians,'customers':customers,'products':products,'technician_assigned_job_lists':technician_assigned_job_lists})   
    


   
@login_required  
def technician_assigned_order_list(request,id):

    
    technician_assigned_order_lists = (
        Technician_Assigned_Order_Item.objects
        .filter(technician__id=id)
        .values('technician','booking_date','order_item__order__id','order_item__order__invoice__customer__first_name','order_item__order__invoice__customer__last_name' ,'order_item__order__invoice__customer__company_name')  # Assuming 'product_name' is a field in Order
        .annotate(order_item=Count('order_item__id', distinct=True))       
    )


    return render(request,'pages/order/technician_assigned_order_list.html',{'technician_assigned_order_lists':technician_assigned_order_lists})

@login_required  
def technician_list(request):
    technician_id = request.GET.get('technician_id')
    email = request.GET.get('email')
    phone = request.GET.get('phone')
    # status = request.GET.get('status')
    technician_lists=User.objects.filter(role=3,deleted_at__isnull=True)
   
   
   
    technicians=User.objects.filter(role=3,deleted_at__isnull=True)
   
    if technician_id:
            technician_lists = User.objects.filter(Q(id=technician_id ) )
    
    
    # if user_name:
    #     technician_lists = User.objects.annotate(name=Concat('userinfo__first_name', 
    #       Value(''), 'userinfo__last_name', output_field=CharField())).filter(Q(name__icontains=user_name ,role=3 , deleted_at__isnull=True) )
        

    # if user_name:
    #     user_name1=user_name.replace(' ','').strip()
    #     technician_lists = User.objects.annotate(name=Concat('userinfo__first_name', Value(''), 'userinfo__last_name', output_field=CharField())).filter(name__icontains=user_name1, role=3 , deleted_at__isnull=True)
        
 
    if email:
        email=email.strip()
        technician_lists = technician_lists.filter(email__icontains=email)

    if phone:
        phone=phone.strip()
        technician_lists = technician_lists.filter(userinfo__phone1__icontains=phone)

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


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

        
    return render(request,'pages/order/technician_list.html',{'technician_lists':technician_lists,'technicians':technicians})




@login_required
def order_item_history(request,id):

    order = Order.objects.get(id=id)
  
    # order_item=Order_Item.objects.filter(order=order)
    order_history = ActivityLog.objects.filter(new_data__contains={'fields': {'order': id}}).order_by('-timestamp')
    status_values = []  # To store status values for each entry
    for entry in order_history:
        if entry.new_data and entry.new_data[0] and 'fields' in entry.new_data[0]:
            fields_data = entry.new_data[0]['fields']
            status_values.append(fields_data.get('status'))
  
    return render(request,'pages/order/order_item_history.html',{'order_history':order_history,'status_values':status_values,'order':order})
    
    
    
from django.http import HttpResponse 
def cron_order_item_serial_number_allocate(request):
    order_items = Order_Item.objects.filter(serial_number__isnull=True,is_trade=0)
    unassigned_serial_numbers = SerialNumber.objects.filter(status=SerialNumber.UNALLOCATED)
    # dd(order_items)
    if order_items and unassigned_serial_numbers:
        for order_item in order_items:
            serial_number = SerialNumber.objects.filter(status=SerialNumber.UNALLOCATED,product=order_item.product).order_by('created_at').first()
            if serial_number:
                order_item.serial_number = serial_number
                order_item.status=serial_number.tracking_status
                order_item.save()
                serial_number.status = SerialNumber.ALLOCATED
                serial_number.invoice = order_item.order.invoice
                serial_number.customer = order_item.order.invoice.customer
                serial_number.save()
                # dd('here')
                # messages.success(request, 'Order Item  Serial Number Allocate Successfully.')
                # return HttpResponse("Done")
            # else:
            #      return HttpResponse("No more Unallocate Serial Numbers Available")
        return HttpResponse('done')
    else:
        return HttpResponse('No record found')
        
from django.http import HttpResponse        
def arrived_bill_product_ETAwise(request):
    serial_numbers=SerialNumber.objects.filter(Arrival_ETA_date=datetime.today(),arrived_date__isnull = True,bill__isnull = False)
    # serial_numbers.update(
    #     arrived_date=datetime.today(),
    #     tracking_status=3,
    # )
    # dd(serial_numbers)
    # Order_Item.objects.filter(serial_number__in=serial_numbers).update(status=3)
    if serial_numbers:
        for snrow in serial_numbers:
            snrow.arrived_date = datetime.today()
            snrow.save()
            Order_Item.objects.filter(serial_number_id=snrow.id).update(status=3)
        return HttpResponse('done')
    else:
        return HttpResponse('No record found')
    return HttpResponse('done')
    
@login_required
def order_item_serial_number_allocate(request, id):
    if request.method == 'POST':
        serial_number_id =request.POST.get('serial_number')
        order_item = Order_Item.objects.get(id=id)
        serial_number=SerialNumber.objects.get(id=serial_number_id)
        order_item.serial_number=serial_number
        order_item.updated_by=request.user
        order_item.status=serial_number.tracking_status
        order_item.save()
        serial_number.status = SerialNumber.ALLOCATED
        serial_number.invoice=order_item.order.invoice
        serial_number.customer=order_item.order.invoice.customer
        serial_number.updated_by=request.user
        serial_number.save()
    messages.success(request,'Order Item  Serial Number Allocate Successfully.')
    return redirect('/notification/order-item/serialnumber/unallocate-list/')
    # return redirect('quotation:customer_invoice_order_item_list',id=order_item.order.id)
    
    
@login_required
def order_item_serial_number_unallocate_list(request):
    customer_id = request.GET.get('customer_id')
    order_no = request.GET.get('order_no')
    product_id = request.GET.get('product_id')
    
    # order_items=Order_Item.objects.filter(serial_number__isnull=True)
    serial_numbers=SerialNumber.objects.filter(
        status=SerialNumber.UNALLOCATED
    ).all()
    
    snor_condition = Q()
  
    snor_condition.add(Q(**{'serial_number__isnull':True}), Q.AND)
    snor_condition.add(Q(**{'is_trade':0}), Q.AND)
    
    
    if customer_id:
        snor_condition.add(Q(**{'order__invoice__customer__id': int(customer_id)}), Q.AND)
    
        
    if product_id:
        snor_condition.add(Q(**{'product__id': int(product_id)}), Q.AND)
        # or_condition.add(Q(**{'product__id': product_id}), Q.OR)
    if order_no:
        snor_condition.add(Q(**{'order__id': int(order_no)}), Q.AND)
    
    snor_condition.add(snor_condition, Q.AND)
    # dd(snand_condition)
    order_items=Order_Item.objects.filter(snor_condition)
    # if customer_id:
    #      order_items=Order_Item.objects.filter(serial_number__isnull=True)
    customers = Customer.objects.all()
    products=Product.objects.all()
    
    
    total_records = order_items.count()
    show_pagination = total_records > settings.PAGE_RECORDS


    if show_pagination: 

        page = request.GET.get('page', 1)
        paginator = Paginator(order_items, settings.PAGE_RECORDS)  # Show 10 orders per page
        try:
            order_items = paginator.page(page)
        except PageNotAnInteger:
            order_items = paginator.page(1)
        except EmptyPage:
            order_items = paginator.page(paginator.num_pages)
    
    return render(request,'pages/order/oi_unallocate_list.html',{'order_items':order_items,'serial_numbers':serial_numbers,'customers':customers,'products':products})

    
        
    

@login_required
def order_item_list(request, id):
    order = Order.objects.get(id=id)
    
    order_items=Order_Item.objects.filter(order=order)
    serial_numbers=SerialNumber.objects.filter(
     
        status=SerialNumber.OPEN
    ).all()
    
    technicians=User.objects.filter(role=3,deleted_at__isnull=True)
    return render(request,'pages/order/order_details.html',{'order':order,'order_items':order_items,'technicians':technicians,'serial_numbers':serial_numbers})

def update_order_statuss(request,id):
    order_item = Order_Item.objects.get(id=id)
    
    if request.method == 'POST':
        status = int(request.POST.get('status'))
        technician = request.POST.get('technician')
        installation_date=request.POST.get('installation_date')
       
        technician=User.objects.get(id=technician)
        order_item.status = status
        # order_item.technician=technician
        # if installation_date:
        #    order_item.installation_date=installation_date

        order_item.save()
        print("Deepaksdfgh")
        print(order_item.status)
        if order_item.status == 4:
           Technician_Assigned_Order_Item.objects.create(
               order_item=order_item,
               technician=technician,
               installation_date=installation_date

           )
   
    messages.success(request,'Order Product Status Updated Successfully.')
    return redirect('quotation:customer_invoice_order_item_list',id=order_item.order.id)
    
@user_passes_test(lambda u: is_customer(u) or is_admin(u) or is_superuser(u) or is_sales(u))
@login_required
def order_list(request):

    customer_id = request.GET.get('customer_id')
    start_date = request.GET.get('start_date')
    end_date = request.GET.get('end_date')
    # status = request.GET.get('status')
    


    orders = Order.objects.all()
 

    customers = Customer.objects.all()
  
    if '2' in request.user.get_role and '1' in request.user.get_role:
        orders = Order.objects.filter(deleted_by__isnull=True).order_by('created_at')
        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 start_date:
            orders = orders.filter(order_date__gte=start_date)
        if end_date:
            orders = orders.filter(order_date__lte=end_date)
    
    
    elif   '2' in request.user.get_role and '3' in request.user.get_role or '2' in request.user.get_role:
        quote_by = User.objects.get(id=request.user.id)
        orders = Order.objects.filter(invoice__quotation__quote_by=quote_by, deleted_by__isnull=True).order_by('created_at')
      
        if customer_id:
            orders = Order.objects.filter(invoice__customer__id=customer_id,invoice__quotation__quote_by=quote_by, deleted_by__isnull=True)
        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 start_date:
            orders = orders.filter(order_date__gte=start_date)
        if end_date:
            orders = orders.filter(order_date__lte=end_date)
            
            
    else:
        orders = Order.objects.filter(deleted_by__isnull=True).order_by('created_at')
        
        
        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 start_date:
            orders = orders.filter(order_date__gte=start_date)
        if end_date:
            orders = orders.filter(order_date__lte=end_date)
   
   
    total_records = orders.count()
    show_pagination = total_records > settings.PAGE_RECORDS


    if show_pagination: 

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

    return render(request,'pages/order/order_list.html',{'orders':orders,'customers':customers})









def test(request):
    # order_items=Order_Item.objects.all()
    order_items=[]
    order_items1=Order_Item.objects.filter('technician__id'== 2)
    # dd(order_items1);
    for i in order_items1:
        # dd(i['order'])
        # o_i=False
        # if i['order_identifier'] == 1:
        #     o_i=True
        result = Order_Item.objects.filter( order__id = i['order'] , order_identifier = i['order_identifier'])[0]
        order_items.append(result)     
        
    # dd(order_items)

    technicians=User.objects.filter(role=3,deleted_at__isnull=True)
    return render(request,'pages/order/tracking_status.html',{'order_items':order_items,'technicians':technicians})

def tracking_order_status_search(request):
    customer_id = request.GET.get('customer_id')
    product_id = request.GET.get('product_id')
    supplier_id = request.GET.get('supplier_id')
    orderno = request.GET.get('orderno')
    billno = request.GET.get('billno')

    order_items = ()
    if orderno or customer_id or product_id or supplier_id:
        if supplier_id:
            snor_condition = Q()
            snand_condition = Q(customer__isnull=True)
            snor_condition.add(Q(**{'invoice__isnull': True}), Q.AND)
        or_condition = Q()
        and_condition = Q(serial_number__isnull=False)
        if orderno:
            if orderno and customer_id and product_id:
                or_condition.add(Q(**{'order__id': orderno}), Q.AND)
                or_condition.add(Q(**{'order__invoice__customer__id': customer_id}), Q.AND)
                or_condition.add(Q(**{'product__id': product_id}), Q.AND)
            elif  orderno and customer_id:
                or_condition.add(Q(**{'order__invoice__customer__id': customer_id}), Q.AND)
                or_condition.add(Q(**{'order__id': orderno}), Q.AND)
            elif orderno and product_id:
                or_condition.add(Q(**{'product__id': product_id}), Q.AND)
                or_condition.add(Q(**{'order__id': orderno}), Q.AND)
            else:
                or_condition.add(Q(**{'order__id': orderno}), Q.AND)
        elif customer_id:
            if customer_id  and product_id:
                or_condition.add(Q(**{'product__id': product_id}), Q.AND)
                or_condition.add(Q(**{'order__invoice__customer__id': customer_id}), Q.AND)
            else :
                or_condition.add(Q(**{'order__invoice__customer__id': customer_id}), Q.AND)
        else:
            or_condition.add(Q(**{'product__id': product_id}), Q.AND)
        if orderno or customer_id or product_id:    
            and_condition.add(or_condition, Q.AND)
        order_items = Order_Item.objects.filter(and_condition)
        order_items = Order_Item.objects.filter(and_condition)
        order_items = list(order_items)
         
    if orderno or supplier_id or product_id:
        if not supplier_id:
            snor_condition = Q()
            snand_condition = Q(customer__isnull=True)
            snor_condition.add(Q(**{'invoice__isnull': True}), Q.AND)
        if orderno:
            if orderno and supplier_id and product_id:
                snor_condition.add(Q(**{'bill__id': orderno}), Q.AND)
                snor_condition.add(Q(**{'bill__supplier__id': supplier_id}), Q.AND)
                or_condition.add(Q(**{'serial_number__bill__supplier__id': supplier_id}), Q.AND)
                snor_condition.add(Q(**{'product__id': product_id}), Q.AND)
            elif  orderno and supplier_id:
                snor_condition.add(Q(**{'bill__supplier__id': supplier_id}), Q.AND)
                or_condition.add(Q(**{'serial_number__bill__supplier__id': supplier_id}), Q.AND)
                snor_condition.add(Q(**{'bill__id': orderno}), Q.AND)
            elif orderno and product_id:
                snor_condition.add(Q(**{'product__id': product_id}), Q.AND)
                snor_condition.add(Q(**{'bill__id': orderno}), Q.AND)
            else:
                snor_condition.add(Q(**{'bill__id': orderno}), Q.AND)
        elif supplier_id:
            if supplier_id  and product_id:
                snor_condition.add(Q(**{'product__id': product_id}), Q.AND)
                snor_condition.add(Q(**{'bill__supplier__id': supplier_id}), Q.AND)
                or_condition.add(Q(**{'serial_number__bill__supplier__id': supplier_id}), Q.AND)
            else :
                snor_condition.add(Q(**{'bill__supplier__id': supplier_id}), Q.AND)
                or_condition.add(Q(**{'serial_number__bill__supplier__id': supplier_id}), Q.AND)
        else:
            snor_condition.add(Q(**{'product__id': product_id}), Q.AND)
        snand_condition.add(snor_condition, Q.AND)
        # dd(snand_condition)
        serial_numbers = SerialNumber.objects.filter(snand_condition)
        order_items = list(order_items) + list(serial_numbers)

    technicians=User.objects.filter(role=3,deleted_at__isnull=True)
    customer = Customer.objects.all()
    suppliers = Supplier.objects.all()
    products=Product.objects.all()
    return render(request,'pages/order/tracking_status.html',{'order_items':order_items,'technicians':technicians,'customers':customer,'suppliers':suppliers,'products':products})

def tracking_order_status(request):
    order_items = Order_Item.objects.filter(serial_number__isnull=False)
    serial_numbers = SerialNumber.objects.filter(customer__isnull=True, invoice__isnull=True)
    order_items = list(order_items) + list(serial_numbers)
    technicians=User.objects.filter(role=3,deleted_at__isnull=True)
    customer = Customer.objects.all()
    suppliers = Supplier.objects.all()
    products=Product.objects.all()
    #dd(order_items)
    return render(request,'pages/order/tracking_status.html',{'order_items':order_items,'technicians':technicians,'customers':customer,'suppliers':suppliers,'products':products})


def customer_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')
    
    customer_invoice=Invoice.objects.get(id=id)
    sale_order_uid=customer_invoice.sale_uid
    api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/CustomerPayment"

    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_customer_payments = []


        for customer_payment in myob_data["Items"]:

            invoices = customer_payment["Invoices"]
            for invoice in invoices:
                if invoice["UID"] == sale_order_uid:
                    
                    matching_customer_payments.append(customer_payment)

        # dd(matching_customer_payments)
        for matching_payment in matching_customer_payments:
            print("Matching Customer Payment:",matching_payment["UID"])
            print("Receipt Number:", matching_payment["ReceiptNumber"])
            
            print("Date:", matching_payment["Date"])
            print("Amount Received:", matching_payment["AmountReceived"])
            invoices = matching_payment["Invoices"]
            invoice_number= invoices[0]['Number']
            sale_order_uid=invoices[0]['UID']
            amount_appliyed=invoices[0]['AmountApplied']

            print(invoice_number)
            print(sale_order_uid) 
            print(amount_appliyed)
        
            invoice=Invoice.objects.get(id=invoice_number)
            
            payments=Customer_Payment.objects.filter(uid=matching_payment["UID"])

            if not  payments.exists():
                customer_payment=Customer_Payment(
                            uid=matching_payment["UID"],
                            paid_amount= matching_payment["AmountReceived"],
                            paydate=matching_payment["Date"],
                            invoice=invoice,
                            due_amount=float(invoice.payable_amount)- matching_payment["AmountReceived"],
                            payable_amount=float(invoice.payable_amount)- matching_payment["AmountReceived"],
                            # bill_number=matching_payment["ReceiptNumber"]
                        )
                customer_payment.save()
                invoice.payable_amount=abs(float(invoice.payable_amount)- matching_payment["AmountReceived"])
                total_paid_amount = invoice.invoice_payment.aggregate(Sum('paid_amount'))['paid_amount__sum'] or 0

                if invoice.total > total_paid_amount:
                    invoice.status = 3
                elif invoice.total <= total_paid_amount:
                    invoice.status = 4
       
                invoice.total_paid_amount = total_paid_amount
                invoice.save()
                

         
# def myob_payment_synch(request,id,payment_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}/Sale/CustomerPayment"

#         customer_invoice=Invoice.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'
#         }


#         customer_payment=Customer_Payment.objects.get(invoice=customer_invoice,id=payment_id)

#         customerpayment={
#             "PayFrom": "Account",
#             "Account": {
#                 "UID": "bbcdb17b-8526-4fe1-9fbd-2e23c6c6b18e"
#             },
            
#             "Customer": {
#                 "UID": customer_invoice.customer.myob_uid
#             },
#             "PayeeAddress": None,
#             "StatementParticulars": "",
#             "PaymentNumber": customer_invoice.id,
#             "Date": customer_payment.paydate.strftime('%Y-%m-%dT%H:%M:%S'),
#             "AmountPaid": float(customer_payment.paid_amount),
#             "Memo": customer_payment.description,
#             "Invoices": [{
#                 "UID": customer_invoice.sale_uid,
#                 "AmountApplied": float(customer_payment.paid_amount),
#                 "Type": "Order"
#             }],
#             "DeliveryStatus": "Print",
#             "ForeignCurrency": None
#         }
     
        
#         response = requests.post(api_url, json=customerpayment, headers=headers)
      
#         data=response.headers

#         print(data)
#         print(response.content)
#         print("-------------------dk--------------------")
#         print("Response:", response.status_code, response.content)
#         print(response)
#         print('2222')
#         print(request.headers)
#         print("--------------------")
    

#         if response.status_code == 201:

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

#                 customer_payment.uid=uid
#                 customer_payment.save()
                
#                 invoice_api_url = f"https://api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Invoice/Item/{uid}"
                            

#                 headerss = {
#                     'Authorization': f'Bearer {myobdata.access_token}',
#                     'x-myobapi-key': settings.MYOB_CLIENT_ID,
#                     'x-myobapi-version': 'v2',
#                     'Accept-Encoding':'gzip,deflate',
#                     'Accept':'Application/PDF',
#                 }

#                 response = requests.get(invoice_api_url, headers=headerss,)
#                 pdf_data=response.content
#                 content = ContentFile(pdf_data)

#                 customer_invoice.uid = uid
#                 customer_invoice.myob_invoice_pdf.save(f'{customer_invoice.id}_invoice.pdf', content)
#                 customer_invoice.save()
                
    
#             response = requests.get(api_url,headers=headers)
#             myob_data=response.json()
#             # matching_customer_payments = []


#             # for customer_payments in myob_data["Items"]:
        

#                 # invoices = customer_payments["Invoices"]
#                 # for invoice in invoices:
#                 #     if invoice["UID"] ==  customer_invoice.uid:
                      
#                         # matching_customer_payments.append(customer_payments)

            
#             # for matching_payment in matching_customer_payments:
#             #     customer_payment.bill_number=matching_payment["ReceiptNumber"]
#             #     customer_payment.save()
       
          
#             messages.success(request, 'Customer payment created to MYOB.')
#             return redirect('quotation:customer_payment_list' ,customer_invoice.id)
#         else:
#           messages.error(request, 'Failed to update payment in MYOB.')
#           return redirect('quotation:customer_payment_list' ,customer_invoice.id)

def myob_payment_synch(request,id,payment_id):
    # try:
        customer_invoice=Invoice.objects.get(id=id)
        if request.method =="GET":
            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}/Sale/CustomerPayment"
            sale_order_uid=customer_invoice.sale_uid
            customer_payment=Customer_Payment.objects.get(id=payment_id)
            paid_amount=customer_payment.paid_amount
            description=customer_payment.description
            payable_amount=customer_payment.payable_amount
            print(payable_amount)
            # customer_payment=Customer_Payment(
            #     invoice=customer_invoice,
            #     payable_amount= Decimal(payable_amount.replace(",", "")), #Decimal(payable_amount),
            #     paid_amount=Decimal(paid_amount.replace(",", "")), #Decimal(paid_amount),
            #     description=description,
            #     created_by=request.user,
            #     due_amount=payable_amount, #Decimal(payable_amount),
            # )
            # customer_payment.created_by=request.user
            # customer_payment.save()
            customer_invoice.payable_amount=Customer_Payment.objects.filter(invoice=customer_invoice).last().payable_amount
            total_paid_amount = customer_invoice.invoice_payment.aggregate(Sum('paid_amount'))['paid_amount__sum'] or 0
            if customer_invoice.total > total_paid_amount:
                customer_invoice.status = 3
            elif customer_invoice.total <= total_paid_amount:
                customer_invoice.status = 4
            customer_invoice.total_paid_amount=total_paid_amount
            customer_invoice.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'
            }
            # customer_payment=Customer_Payment.objects.latest('id')
            customerpayment={
                "PayFrom": "Account",
                "Account": {
                    "UID": "bbcdb17b-8526-4fe1-9fbd-2e23c6c6b18e"
                },
                "Customer": {
                    "UID": customer_invoice.customer.myob_uid
                },
                "PayeeAddress": None,
                "StatementParticulars": "",
                "PaymentNumber": customer_invoice.id,
                "Date": customer_payment.paydate.strftime('%Y-%m-%dT%H:%M:%S'),
                "AmountPaid": float(customer_payment.paid_amount),
                "Memo": description,
                "Invoices": [{
                    "UID": customer_invoice.sale_uid,
                    "AmountApplied": float(customer_payment.paid_amount),
                    "Type": "Order"
                }],
                "DeliveryStatus": "Print",
                "ForeignCurrency": None
            }
            response = requests.post(api_url, json=customerpayment, headers=headers)
            data=response.headers
            print(data)
            print(response.content)
            print("-------------------dk--------------------")
            print("Response:", response.status_code, response.content)
            print(response)
            print('2222')
            print(request.headers)
            print("--------------------")
            
            if response.status_code == 201:
                pdf_data=response.content
                content = ContentFile(pdf_data)
                location = data['Location']
                if location:
                    parts = location.split('/')
                    uid = parts[-1]
                    customer_payment.uid=uid
                    customer_payment.save()
                    api_urls = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item/{sale_order_uid}"
                    headers = {
                        'Authorization': f'Bearer {myobdata.access_token}',
                        'x-myobapi-key': settings.MYOB_CLIENT_ID,
                        'x-myobapi-version': 'v2',
                        'Accept-Encoding':'gzip,deflate',
                        'Accept':'Application/PDF',
                    }
                    response = requests.get(api_urls, headers=headers,)
                    pdf_data=response.content
                    content = ContentFile(pdf_data)
                    customer_invoice.myob_invoice_pdf.save(f'{customer_invoice.id}_invoice.pdf', content)
                    customer_invoice.save()
                    print(customer_invoice.due_amount())
                    due_amount =  customer_invoice.due_amount()
                    if due_amount == '$0.00':
                        headerss = {
                            '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'
                        }
                        sales_order_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item/{sale_order_uid}"
                        response = requests.get(sales_order_url, headers=headerss)
                        sales_order_data = response.json()
                        lines = sales_order_data['Lines']
                        current_row_version = sales_order_data.get('RowVersion')
                        invoice_data = {
                        'Customer': sales_order_data['Customer'],
                        'Number': customer_invoice.id,
                        "Date":customer_invoice.invoice_date.strftime('%Y-%m-%dT%H:%M:%S'),
                        "SupplierInvoiceNumber": None,
                        "ShipToAddress": f'{customer_invoice.customer.street} {customer_invoice.customer.city} {customer_invoice.customer.state} {customer_invoice.customer.post_code}{customer_invoice.customer.country}',

                        "Terms": { 
                            "PaymentIsDue": "DayOfMonthAfterEOM",
                            "DiscountDate": 1,
                            "BalanceDueDate": 30,
                            "DiscountForEarlyPayment": 0,
                            "MonthlyChargeForLatePayment": 0,
                            "DiscountExpiryDate": None,
                            "Discount":float(customer_invoice.discount),
                            "DueDate": customer_invoice.due_date.strftime('%Y-%m-%dT%H:%M:%S'),
                        },
                        "IsTaxInclusive": False,
                        "Lines": [],
                        "IsReportable": False,
                       
                        "Subtotal": float(customer_invoice.subtotal),
                        "Freight": 0,
                        "FreightTaxCode":  {
                                "UID": myob_quotation_freightaxcode
                            },
                        "TotalTax": float(customer_invoice.gst),
                        "TotalAmount": float(customer_invoice.total),
                        "Category": None,
                        "Comment": "",
                        "CustomerPurchaseOrderNumber":customer_invoice.po_number,
                        "ShippingMethod": None,
                        "PromisedDate": None,
                        "JournalMemo": "Purchase; 786",
                        "BillDeliveryStatus": "Print",
                        "AppliedToDate": 0,
                        "BalanceDueAmount": 0,
                        # "Status": 'ConvertedToInvoice',
                        "Status":'Open',
                        "LastPaymentDate": None,
                        "Order":{
                                "UID": customer_invoice.sale_uid,
                            },
                        "ForeignCurrency":None,
                    
    
                        }
                        for line in lines:
                            print("dfgh")
                            line_type= line['Type']
                            line_description = line['Description']
                            line_total = line['Total'] 
                            line_shipqty= line['ShipQuantity']
                            line_unitprice= line['UnitPrice']
                            line_item= line['Item']['UID'] 
                            line_text=line['TaxCode']['UID']
                            invoice_data["Lines"].append({
                                "Type": "Transaction",
                                "Description": line_description,
                                "Total": line_total,
                                "ShipQuantity": line_shipqty,
                                "UnitPrice": line_unitprice,
                                "Item":{
                                    'UID':line_item
                                },
                                "TaxCode":{
                                    
                                    'UID':line_text
                                },
                                "Account": {
                                "UID": myob_quotation_account,
                            },
                            })
                        headeres = {
                            'Authorization': f'Bearer {myobdata.access_token}',
                            'x-myobapi-key': settings.MYOB_CLIENT_ID,
                            'x-myobapi-version': 'v2',
                            'Content-Type': 'application/json',
                        }
                        post_json = json.dumps(invoice_data)
                        # response = requests.put(sales_order_url, data=post_json, headers=headerss)
                        # data=response.headers
                        # print(data)
                        # print(response.content)
                        # print("-------------------rahul--------------------")
                        # print("Response:", response.status_code, response.content)
                        # print(response)
                        # print('2222')
                        # print(request.headers)
                        # print("--------------------")
                        invoice_url=f'https://api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Invoice/Item'
                        response = requests.post(invoice_url, data=post_json, headers=headeres)
                        data=response.headers
                        print(data)
                        print(response.content)
                        print("-------------------dgggggk--------------------")
                        print("Response:", response.status_code, response.content)
                        print(response)
                        print('2222')
                        print(request.headers)
                        print("--------------------")
                        if response.status_code == 201:
                            pdf_data=response.content
                            print(pdf_data)
                            content = ContentFile(pdf_data)
                            print(content)
                            location = data['Location']
                            if location:
                                parts = location.split('/')
                                uid = parts[-1]
                                invoice_api_url = f"https://api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Invoice/Item/{uid}"
                                print(api_url)
                                headerss = {
                                    'Authorization': f'Bearer {myobdata.access_token}',
                                    'x-myobapi-key': settings.MYOB_CLIENT_ID,
                                    'x-myobapi-version': 'v2',
                                    'Accept-Encoding':'gzip,deflate',
                                    'Accept':'Application/PDF',
                                }

                                response = requests.get(invoice_api_url, headers=headerss,)
                                pdf_data=response.content
                                content = ContentFile(pdf_data)
                
                                customer_invoice.uid = uid
                                customer_invoice.myob_invoice_pdf.save(f'{customer_invoice.id}_invoice.pdf', content)
                                customer_invoice.save()
                                  
                
                response = requests.get(api_url,headers=headers)
               
                myob_data=response.json()
               
                matching_customer_payments = []
    
    
                for customer_payments in myob_data["Items"]:
                    invoices = customer_payments["Invoices"]
                    for invoice in invoices:
                        if invoice["UID"] == sale_order_uid:
                            matching_customer_payments.append(customer_payments)
            # for matching_payment in matching_customer_payments:
            #     customer_payment.bill_number=matching_payment['ReceiptNumber']
            #     customer_payment.save()
                messages.success(request, 'Invoice Payment Done Successfully.')
                return redirect('quotation:customer_payment_list' ,customer_invoice.id)
            else:
                messages.error(request, 'Failed To Invoice Payment.')
                return redirect('quotation:customer_payment_list' ,customer_invoice.id)
        else:
            return HttpResponse("Invalid request method.")
   
def customer_payment(request,id):
    # try:
        customer_invoice=Invoice.objects.get(id=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}/Sale/CustomerPayment"
            sale_order_uid=customer_invoice.sale_uid
            paid_amount=float(request.POST.get('paid_amount'))
            description=request.POST.get('description')
            payable_amount=float(customer_invoice.payable_amount)-paid_amount
            paid_amount="{:.2f}".format(paid_amount) 
            print("dddd",paid_amount)
            payable_amount="{:.2f}".format(payable_amount) 
            print(payable_amount)
            customer_payment=Customer_Payment(
                invoice=customer_invoice,
                payable_amount= Decimal(payable_amount.replace(",", "")), #Decimal(payable_amount),
                paid_amount=Decimal(paid_amount.replace(",", "")), #Decimal(paid_amount),
                description=description,
                created_by=request.user,
                due_amount=Decimal(payable_amount.replace(",", "")), #Decimal(payable_amount),
            )
            customer_payment.created_by=request.user
            customer_payment.save()
            customer_invoice.payable_amount=payable_amount
            total_paid_amount = customer_invoice.invoice_payment.aggregate(Sum('paid_amount'))['paid_amount__sum'] or 0
            if customer_invoice.total > total_paid_amount:
                customer_invoice.status = 3
            elif customer_invoice.total <= total_paid_amount:
                customer_invoice.status = 4
            customer_invoice.total_paid_amount=total_paid_amount
            customer_invoice.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'
            }
            customer_payment=Customer_Payment.objects.latest('id')
            customerpayment={
                "PayFrom": "Account",
                "Account": {
                    "UID": "bbcdb17b-8526-4fe1-9fbd-2e23c6c6b18e"
                },
                "Customer": {
                    "UID": customer_invoice.customer.myob_uid
                },
                "PayeeAddress": None,
                "StatementParticulars": "",
                "PaymentNumber": customer_invoice.id,
                "Date": customer_payment.paydate.strftime('%Y-%m-%dT%H:%M:%S'),
                "AmountPaid": float(customer_payment.paid_amount),
                "Memo": description,
                "Invoices": [{
                    "UID": customer_invoice.sale_uid,
                    "AmountApplied": float(customer_payment.paid_amount),
                    "Type": "Order"
                }],
                "DeliveryStatus": "Print",
                "ForeignCurrency": None
            }
            response = requests.post(api_url, json=customerpayment, headers=headers)
            data=response.headers
            print(data)
            print(response.content)
            print("-------------------dk--------------------")
            print("Response:", response.status_code, response.content)
            print(response)
            print('2222')
            print(request.headers)
            print("--------------------")
            
            if response.status_code == 201:
                pdf_data=response.content
                content = ContentFile(pdf_data)
                location = data['Location']
                if location:
                    parts = location.split('/')
                    uid = parts[-1]
                    customer_payment.uid=uid
                    customer_payment.save()
                    api_urls = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item/{sale_order_uid}"
                    headers = {
                        'Authorization': f'Bearer {myobdata.access_token}',
                        'x-myobapi-key': settings.MYOB_CLIENT_ID,
                        'x-myobapi-version': 'v2',
                        'Accept-Encoding':'gzip,deflate',
                        'Accept':'Application/PDF',
                    }
                    response = requests.get(api_urls, headers=headers,)
                    pdf_data=response.content
                    content = ContentFile(pdf_data)
                    customer_invoice.myob_invoice_pdf.save(f'{customer_invoice.id}_invoice.pdf', content)
                    customer_invoice.save()
                    print(customer_invoice.due_amount())
                    due_amount =  customer_invoice.due_amount()
                    if due_amount == '$0.00':
                        headerss = {
                            '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'
                        }
                        sales_order_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item/{sale_order_uid}"
                        response = requests.get(sales_order_url, headers=headerss)
                        sales_order_data = response.json()
                        lines = sales_order_data['Lines']
                        current_row_version = sales_order_data.get('RowVersion')
                        invoice_data = {
                        'Customer': sales_order_data['Customer'],
                        'Number': customer_invoice.id,
                        "Date":customer_invoice.invoice_date.strftime('%Y-%m-%dT%H:%M:%S'),
                        "SupplierInvoiceNumber": None,
                        "ShipToAddress": f'{customer_invoice.customer.street} {customer_invoice.customer.city} {customer_invoice.customer.state} {customer_invoice.customer.post_code}{customer_invoice.customer.country}',

                        "Terms": { 
                            "PaymentIsDue": "DayOfMonthAfterEOM",
                            "DiscountDate": 1,
                            "BalanceDueDate": 30,
                            "DiscountForEarlyPayment": 0,
                            "MonthlyChargeForLatePayment": 0,
                            "DiscountExpiryDate": None,
                            "Discount":float(customer_invoice.discount),
                            "DueDate": customer_invoice.due_date.strftime('%Y-%m-%dT%H:%M:%S'),
                        },
                        "IsTaxInclusive": False,
                        "Lines": [],
                        "IsReportable": False,
                       
                        "Subtotal": float(customer_invoice.subtotal),
                        "Freight": 0,
                        "FreightTaxCode":  {
                                "UID": myob_quotation_freightaxcode
                            },
                        "TotalTax": float(customer_invoice.gst),
                        "TotalAmount": float(customer_invoice.total),
                        "Category": None,
                        "Comment": "",
                        "CustomerPurchaseOrderNumber":customer_invoice.po_number,
                        "ShippingMethod": None,
                        "PromisedDate": None,
                        "JournalMemo": "Purchase; 786",
                        "BillDeliveryStatus": "Print",
                        "AppliedToDate": 0,
                        "BalanceDueAmount": 0,
                        # "Status": 'ConvertedToInvoice',
                        "Status":'Open',
                        "LastPaymentDate": None,
                        "Order":{
                                "UID": customer_invoice.sale_uid,
                            },
                        "ForeignCurrency":None,
                    
    
                        }
                        for line in lines:
                            print("dfgh")
                            line_type= line['Type']
                            line_description = line['Description']
                            line_total = line['Total'] 
                            line_shipqty= line['ShipQuantity']
                            line_unitprice= line['UnitPrice']
                            line_item= line['Item']['UID'] 
                            line_text=line['TaxCode']['UID']
                            invoice_data["Lines"].append({
                                "Type": "Transaction",
                                "Description": line_description,
                                "Total": line_total,
                                "ShipQuantity": line_shipqty,
                                "UnitPrice": line_unitprice,
                                "Item":{
                                    'UID':line_item
                                },
                                "TaxCode":{
                                    
                                    'UID':line_text
                                },
                                "Account": {
                                "UID": myob_quotation_account,
                            },
                            })
                        headeres = {
                            'Authorization': f'Bearer {myobdata.access_token}',
                            'x-myobapi-key': settings.MYOB_CLIENT_ID,
                            'x-myobapi-version': 'v2',
                            'Content-Type': 'application/json',
                        }
                        post_json = json.dumps(invoice_data)
                        # response = requests.put(sales_order_url, data=post_json, headers=headerss)
                        # data=response.headers
                        # print(data)
                        # print(response.content)
                        # print("-------------------rahul--------------------")
                        # print("Response:", response.status_code, response.content)
                        # print(response)
                        # print('2222')
                        # print(request.headers)
                        # print("--------------------")
                        invoice_url=f'https://api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Invoice/Item'
                        response = requests.post(invoice_url, data=post_json, headers=headeres)
                        data=response.headers
                        print(data)
                        print(response.content)
                        print("-------------------dgggggk--------------------")
                        print("Response:", response.status_code, response.content)
                        print(response)
                        print('2222')
                        print(request.headers)
                        print("--------------------")
                        if response.status_code == 201:
                            pdf_data=response.content
                            print(pdf_data)
                            content = ContentFile(pdf_data)
                            print(content)
                            location = data['Location']
                            if location:
                                parts = location.split('/')
                                uid = parts[-1]
                                invoice_api_url = f"https://api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Invoice/Item/{uid}"
                                print(api_url)
                                headerss = {
                                    'Authorization': f'Bearer {myobdata.access_token}',
                                    'x-myobapi-key': settings.MYOB_CLIENT_ID,
                                    'x-myobapi-version': 'v2',
                                    'Accept-Encoding':'gzip,deflate',
                                    'Accept':'Application/PDF',
                                }

                                response = requests.get(invoice_api_url, headers=headerss,)
                                pdf_data=response.content
                                content = ContentFile(pdf_data)
                
                                customer_invoice.uid = uid
                                customer_invoice.myob_invoice_pdf.save(f'{customer_invoice.id}_invoice.pdf', content)
                                customer_invoice.save()
                                  
                
                response = requests.get(api_url,headers=headers)
               
                myob_data=response.json()
               
                matching_customer_payments = []
    
    
                for customer_payments in myob_data["Items"]:
                    invoices = customer_payments["Invoices"]
                    for invoice in invoices:
                        if invoice["UID"] == sale_order_uid:
                            matching_customer_payments.append(customer_payments)
            # for matching_payment in matching_customer_payments:
            #     customer_payment.bill_number=matching_payment['ReceiptNumber']
            #     customer_payment.save()
                messages.success(request, 'Invoice Payment Done Successfully.')
                return redirect('quotation:customer_payment_list' ,customer_invoice.id)
            else:
                messages.error(request, 'Failed To Invoice Payment.')
                return redirect('quotation:customer_payment_list' ,customer_invoice.id)
        else:
            return HttpResponse("Invalid request method.")
   
def customer_payment_list(request,id):
    invoice=Invoice.objects.get(id=id)
    if id:
       customer_payment_check(request,id)
    payment_lists = Customer_Payment.objects.filter(invoice=invoice)
    payment = Customer_Payment.objects.filter(invoice=invoice).last()
    if payment:
        # payable_amount="${:,.2f}".format(payment.payable_amount)
        payable_amount=payment.payable_amount
    else:
        payable_amount=invoice.total
    return render(request,'pages/invoice/payment_list.html',{'invoice':invoice,'payment_lists':payment_lists,'payable_amount':payable_amount})
def manual_upload_document(request,id):
    
    quotation = get_object_or_404(Quotation, id=id)

    if request.method =="POST":
        quotation.manual_quote_pdf=request.FILES['manual_quote_pdf']
        # quotation.manual_quote_doc = request.FILES['manual_quote_doc']
        quotation.save()
        messages.success(request, 'Document Uploded Successfully.')
        return redirect('quotation:list_quotation')
       
    return render(request,'pages/quotation/manual_upload_document.html',{'quotation':quotation})


def order_word(request,id):
    quotation = get_object_or_404(Quotation, id=id)
    contracts = ContractOfSale.objects.first()
    quotationitems = QuotationItem.objects.filter(quotation=quotation)
    return render(request,'pages/quotation/quote_doc.html',{'quotation':quotation,'quotationitems':quotationitems,'contracts':contracts})


def myob_invoice_pdf(request,id):
    invoice = get_object_or_404(Invoice, pk=id)
    # invoiceitems = InvoiceItem.objects.filter(invoice=invoice)
  
    refresh_token(request)
   
    myobdata = MyobModel.objects.first()
    if not myobdata:
        messages.error(request,'Please First create Access Code')
        return redirect('/myob/initiate-connection')
    type = 'Item'
    UID=invoice.uid
    print(UID)
  
   
    api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item/{UID}"
    print(api_url)

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

    response = requests.get(api_url, headers=headers)

    if response.status_code == 200:
       pdf_data=response.content
       print(pdf_data)
       invoicepdf= InvoicePdf()
       
       content = ContentFile(pdf_data)
       print(content)
  
       invoicepdf.pdf.save(f'{invoice.id}_invoice.pdf', content)

       messages.success(request, 'pdf successfully .')
       return HttpResponse('done')
    else:
        messages.error(request, 'Product Already to Sync With Myob.')
        return HttpResponse(' Not Done')
      

  
    

def get_serial_numbers(request):
    selected_product_id = request.GET.get('product_id')
    if selected_product_id:
        p=Product.objects.filter(id=selected_product_id).first()
        serial_numbers=SerialNumber.objects.filter(product=p,customer=None)
        serialized_data = serialize("json", serial_numbers)
        serialized_data = json.loads(serialized_data)
        return JsonResponse({'data':serialized_data})
    else:
        return JsonResponse({'error': 'No product selected.'})
def get_inv(request):
    selected_product_id = request.GET.get('product_id')
    if selected_product_id:
        p=Product.objects.filter(id=selected_product_id).first()
        serial_numbers=Invoice.objects.filter(invoice_items__product=p)
        serialized_data = serialize("json", serial_numbers)
        serialized_data = json.loads(serialized_data)
        return JsonResponse({'data':serialized_data})
    else:
        return JsonResponse({'error': 'No product selected.'})
        
        


# def convert_quotation_to_invoice(request, id):
#     quotation = get_object_or_404(Quotation, id=id)
#     quotationitem = QuotationItem.objects.get(quotation=quotation)
#     invoice = Invoice.objects.create(
#         customer=quotation.customer,
#         subtotal=quotation.subtotal,
#         discount=quotation.discount,
#         gst=quotation.gst,
#         total=quotation.total,
#         quotation=quotation,
#         status = Invoice.CREATED,
#         is_active=quotation.is_active,
#         created_by=request.user       
#     )

@user_passes_test(lambda u: is_admin(u) or is_superuser(u)  or is_sales(u))
@login_required
def sync_myob_invoice_all(request):
    
    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}/Sale/Order/Item"
    invoices=Invoice.objects.filter(uid=None)
    for invoice in invoices:        
        invoiceitems=InvoiceItem.objects.filter(invoice=invoice)
        product_ids = []
    
        quantities = []
        subtotals = []
        costs_per_unit = []
        if invoice.customer.myob_uid == None:
            sync_myob_customer(request,invoice.customer.id)
        for invoice_item in invoiceitems:
            product_ids.append(invoice_item.product.id)
            if invoice_item.product.uid == None:
                sync_myob_product_row(request,invoice_item.product.id)
            quantities.append(invoice_item.qty)
            subtotals.append(invoice_item.subtotal)
            print(subtotals)
            costs_per_unit.append(invoice_item.cost_per_unit)
            if(invoice.discount_type =='$'): 
                disc=invoice.discount/invoice.grandsubtotal*100
                discount_percent_myob= Decimal(disc.replace(",", "")) #Decimal(invoice.discount/invoice.grandsubtotal*100)
            else:
                discount_percent_myob= Decimal(invoice.discount_percent)
            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
                serial_numbers_obj = SerialNumber.objects.filter(product=product_obj,order=invoice.id)
                serial_numbers_list = [serial_number.serial_number for serial_number in serial_numbers_obj]

                subtotal_str = subtotals[i]
                subtotal =  Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)

                cost_per_unit_str = costs_per_unit[i]
                cost_per_unit = Decimal(cost_per_unit_str.replace(",", "")) #Decimal(cost_per_unit_str)
                detail ={
                        "Type": "Transaction",
                        "Description":product_names + f"({product_obj.sku})" + ",".join(serial_numbers_list),  
                        "BillQuantity": int(quantities[i]),
                        "ShipQuantity" : int(quantities[i]),
                        "UnitPrice": float(cost_per_unit),
                        "UnitCount" :int(quantities[i]),
                        "DiscountPercent" :float(discount_percent_myob),
                        "Account": {
                            "UID": myob_quotation_account,
                        },
                        "TaxCode": {
                            "UID":myob_quotation_taxcode
                            # "UID": "6f5fce5d-604f-49db-9a56-8573e7d2a5ec",
                        },
                        "Item": {
                            "UID": product_obj.uid,
                        },
                    }
                details.append(detail)            
                invoice_data={
                    "Number": invoice.id,
                    "Date":invoice.invoice_date.strftime('%Y-%m-%dT%H:%M:%S'),
                    "SupplierInvoiceNumber": None,
                    "Customer": {
                        "UID": invoice.customer.myob_uid,
                    },

                    "ShipToAddress": f'{invoice.customer.street} {invoice.customer.city} {invoice.customer.state} {invoice.customer.post_code} {invoice.customer.country}',
            

                    "Terms": { 
                        "PaymentIsDue": "DayOfMonthAfterEOM",
                        "DiscountDate": 1,
                        "BalanceDueDate": 30,
                        "DiscountForEarlyPayment": 0,
                        "MonthlyChargeForLatePayment": 0,
                        "DiscountExpiryDate": None,
                        "Discount":float(invoice.discount),
                        "DueDate": invoice.due_date.strftime('%Y-%m-%dT%H:%M:%S'),
                    },
                    "IsTaxInclusive": False,
                    "IsReportable": False,
                    "Lines":details,
                    "Subtotal": float(invoice.subtotal),
                    "Freight": 0,
                    "FreightTaxCode":  {
                            "UID": myob_quotation_freightaxcode
                        },
                    "TotalTax": float(invoice.gst),
                    "TotalAmount": float(invoice.total),
                    "Category": None,
                    "CustomerPurchaseOrderNumber":f"Quote ID: {invoice.po_number}",
                    "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(invoice_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]
                parts = location.split('/')
                uid = parts[-1]
                api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item/{uid}"     

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

                response = requests.get(api_url, headers=headers,)
                pdf_data=response.content
                content = ContentFile(pdf_data)

                invoice.uid = uid
                invoice.myob_invoice_pdf.save(f'{invoice.id}_invoice.pdf', content)
                invoice.save()

            messages.success(request, 'Invoice Sync With Myob Successfully.')
            # return redirect('quotation:list_invoice')
        else:
            messages.error(request, 'Failed To Sync With Myob.')
            # return redirect('quotation:list_invoice')


@user_passes_test(lambda u: is_admin(u) or is_superuser(u)  or is_sales(u))
@login_required
def sync_myob_invoice(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}/Sale/Order/Item"
    invoice=Invoice.objects.get(id=id)
    invoiceitems=InvoiceItem.objects.filter(invoice=invoice)
    product_ids = []
    quantities = []
    subtotals = []
    costs_per_unit = []
    if invoice.customer.myob_uid == None:
        sync_myob_customer(request,invoice.customer.id)
    for invoice_item in invoiceitems:
        product_ids.append(invoice_item.product.id)
        if invoice_item.product.uid == None:
            sync_myob_product_row(request,invoice_item.product.id)
        quantities.append(invoice_item.qty)
        subtotals.append(invoice_item.subtotal)
        print(subtotals)
        costs_per_unit.append(invoice_item.cost_per_unit)
        if(invoice.discount_type =='$'): 
            discpers=invoice.discount/invoice.grandsubtotal*100
            discount_percent_myob=Decimal(discpers.replace(",", "")) #Decimal(invoice.discount/invoice.grandsubtotal*100)
        else:
            discount_percent_myob= Decimal(invoice.discount_percent)
        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
            serial_numbers_obj = SerialNumber.objects.filter(product=product_obj,invoice=invoice.id)
            serial_numbers_list = [serial_number.serial_number for serial_number in serial_numbers_obj]
            subtotal_str = subtotals[i]
            subtotal = Decimal(subtotal_str) # Decimal(subtotal_str.replace(",", "")) #
            cost_per_unit_str = costs_per_unit[i]
            cost_per_unit = Decimal(cost_per_unit_str) # Decimal(cost_per_unit_str.replace(",", "")) #
            detail ={
                    "Type": "Transaction",
                    "Description":product_names + f"({product_obj.sku})" + ",".join(serial_numbers_list),  
                    "BillQuantity": int(quantities[i]),
                    "ShipQuantity" : int(quantities[i]),
                    "UnitPrice": float(cost_per_unit),
                    "UnitCount" :int(quantities[i]),
                    "DiscountPercent" :float(discount_percent_myob),
                    "Account": {
                        "UID": myob_quotation_account,
                    },
                    "TaxCode": {
                        "UID":myob_quotation_taxcode
                        # "UID": "6f5fce5d-604f-49db-9a56-8573e7d2a5ec",
                    },
                    "Item": {
                        "UID": product_obj.uid,
                    },
                }
            details.append(detail)
            invoice_data={
                "Number": invoice.id,
                "Date":invoice.invoice_date.strftime('%Y-%m-%dT%H:%M:%S'),
                "SupplierInvoiceNumber": None,
                "Customer": {
                    "UID": invoice.customer.myob_uid,
                },
                "ShipToAddress": f'{invoice.customer.street} {invoice.customer.city} {invoice.customer.state} {invoice.customer.post_code} {invoice.customer.country}',

                "Terms": { 
                    "PaymentIsDue": "DayOfMonthAfterEOM",
                    "DiscountDate": 1,
                    "BalanceDueDate": 30,
                    "DiscountForEarlyPayment": 0,
                    "MonthlyChargeForLatePayment": 0,
                    "DiscountExpiryDate": None,
                    "Discount":float(invoice.discount),
                    "DueDate": invoice.due_date.strftime('%Y-%m-%dT%H:%M:%S'),
                },
                "IsTaxInclusive": False,
                "IsReportable": False,
                "Lines":details,
                "Subtotal": float(invoice.subtotal),
                "Freight": 0,
                "FreightTaxCode":  {
                        "UID": myob_quotation_freightaxcode
                    },
                "TotalTax": float(invoice.gst),
                "TotalAmount": float(invoice.total),
                "Category": None,
                "Comment": "",
                "CustomerPurchaseOrderNumber":f"Quote ID: {invoice.po_number}",
                "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(invoice_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]
            parts = location.split('/')
            uid = parts[-1]
            api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item/{uid}"     

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

            response = requests.get(api_url, headers=headers,)
            pdf_data=response.content
            content = ContentFile(pdf_data)

            invoice.sale_uid = uid
            invoice.myob_invoice_pdf.save(f'{invoice.id}_invoice.pdf', content)
            invoice.save()

        messages.success(request, 'Invoice Sync With Myob Successfully.')
        return redirect('quotation:list_invoice')
    else:
        messages.error(request, 'Failed To Sync With Myob.')
        return redirect('quotation:list_invoice')
        
        

@user_passes_test(lambda u: is_admin(u) or is_superuser(u))
@login_required
def create_invoice(request):
    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')
        
        customer_id = request.POST.get('customer') 
       
        invoice_date =  request.POST.get('invoice_date')
    
        due_date =  request.POST.get('due_date')
        po_number =  request.POST.get('po_number')

        product_ids = request.POST.getlist('product[]', [])
       


        print(product_ids)
       


        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')
        descriptions = request.POST.getlist('description[]', [])
        sent_mail = request.POST.get('sent_mail')
        trade_product_name = request.POST.getlist('tradeproduct[]',[])
        trade_pcategory = request.POST.getlist('pcategory[]',[])
        trade_product_description = request.POST.getlist('descriptiontrade[]',[])
        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]) ) 
            disc=discount/grandsubtotal*100
            discount_percent_myob= Decimal(disc.replace(",", "")) #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) #Decimal(discount_percent.replace(",", ""))
        grand_subtotal= grandsubtotal-discount
        gst = grand_subtotal * ( gst_percent / 100) 
        start_date_obj = datetime.strptime(invoice_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 None:
        #     is_active = False
        if is_active:
            is_active = is_active
        else:
            is_active = True
    
        customer = Customer.objects.get(id=customer_id)
       
        invoice = Invoice.objects.create(
            customer=customer,
            
            invoice_date=start_date_obj,
            due_date=due_date_obj,
            po_number=po_number,
               

            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
        )
        print(product_ids)
        invoiceitems = []
        for i in range(len(trade_product_name)):
            if trade_product_name[i] == '':
                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.replace(",", "")) #Decimal(cost_per_unit_str)
                subtotal_str = subtotal_values[i]
                subtotal_str = subtotal_str.replace("$", "").replace(",", "")
                subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)
                is_trade_product=0
                if i < len(descriptions):
                    description = descriptions[i]    
                    if  descriptions[i] != '':
                        is_madatory=1
                        is_required_send_to_admin=1
                else:
                    description = None
                product_obj = Product.objects.get(id=product_id)
                invoiceitem = InvoiceItem(
                    invoice= invoice,  
                    product=product_obj,
                    cost_per_unit=cost_per_unit,
                    qty=qty,
                    description=description,
                    subtotal=subtotal,
                    is_trade_product=is_trade_product,
                    created_by=request.user
                )
                invoiceitem.save()
                invoiceitems.append( invoiceitem)
            else:
                t_product_name = trade_product_name[i]
                t_product_discription = trade_product_description[i]
                t_category=trade_pcategory[i]
                t_product_cost_per_unit=cost_per_unit_values[i]
                t_product_cost_per_unit = t_product_cost_per_unit.replace('$', '').replace(",", "") 
                t_product_cost_per_unit =  Decimal(t_product_cost_per_unit.replace(",", "")) # Decimal(t_product_cost_per_unit)
                categorie = ProductCategory.objects.get(category_name="TRADE PRODUCT")
                product = Product.objects.create(
                    category_id= t_category, #categorie.id,
                    product_type='used',
                    product_name=t_product_name,
                    product_description= t_product_discription ,
                    product_price=t_product_cost_per_unit,
                    is_active=True,
                    is_product=1,
                    created_by=request.user
                )
                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}/Inventory/Item/"
                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'
                }
                product = Product.objects.latest('id')
                product_data=   {
                        "Number":product.id,
                        "Name": f'{product.product_name}',
                        "IsActive": True,
                        "IsBought" : True,
                        "IsSold" : True,
                        "IsInventoried" : False,
                        "ExpenseAccount" :  { "UID": myob_expense_account },
                        "Description": product.product_description[:255],
                        "CostOfSalesAccount" : { "UID" : myob_cost_of_sales_account,  },
                        "IncomeAccount": { "UID":  myob_income_account, },
                        "AssetAccount" : { "UID" : myob_asset_account, },
                        "BuyingDetails": {
                            "BaseSellingPrice" :float(product.product_price),
                            "ItemsPerBuyingUnit" : 1,
                            "TaxCode": {  "UID": myob_tax_code, }
                        },
                        "SellingDetails": {
                            "BaseSellingPrice" : float(product.product_price),
                            "ItemsPerBuyingUnit" : 1,
                            "TaxCode": { "UID": myob_tax_code, }
                        }
                    }
                product_json = json.dumps(product_data)
                response = requests.post(api_url, data=product_json, headers=headers)
                data=response.headers
                if response.status_code == 201:
                    location = data['Location']
                    if location:
                        parts = location.split('/')
                        uid = parts[-1]
                        product.uid = uid
                        product.save()
                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.replace(",", "")) #Decimal(cost_per_unit_str)
                subtotal_str = subtotal_values[i]
                subtotal_str = subtotal_str.replace("$", "").replace(",", "")
                subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)
                product_obj = Product.objects.get(id=product_id)
                is_trade_product=1
                trade_product_id = Product.objects.get(id=product_id)
                cost_per_unit=cost_per_unit
                invoiceitem = InvoiceItem(
                    invoice= invoice,    
                    product=product,
                    cost_per_unit=cost_per_unit,
                    qty=qty,
                    subtotal=subtotal,
                    trade_product_id = trade_product_id.id,
                    is_trade_product=is_trade_product,
                    created_by=request.user
                )
                invoiceitem.save()
                invoiceitems.append( invoiceitem)
                invoice = Invoice.objects.latest('id')
                invoice.is_trade=1
                invoice.save()

        invoice = Invoice.objects.latest('id')
        invoiceitems = InvoiceItem.objects.filter(invoice=invoice)
        pdf_data = generate_pdfs(invoice, invoiceitems)
        invoice.pdf_file.save(f'{invoice.id}_invoice.pdf', pdf_data)
        invoice_detail_url = request.build_absolute_uri(reverse('quotation:view_invoice_detail', args=[invoice.id]))
        subject = f'EXCITECH Australia - Invoice Details for Invoice ID {invoice.id}'
        invoice_payment_url = request.build_absolute_uri(reverse('quotation:checkout', args=[invoice.id]))
        template_data = {'invoice': invoice,'invoice_payment_url':invoice_payment_url}
        message = render_to_string('pages/invoice/invoice_email_temp.html', template_data)
        from_email =settings.FROM_EMAIL # Replace with your email address
        recipient_email = customer.user.email  # Use the customer's email address
        email = EmailMessage(subject, message, from_email, [recipient_email])
        data=sync_myob_invoice(request,invoice.id)
        # api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item"
        # 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
        #     # serial_numbers_obj = SerialNumber.objects.filter(product=product_obj,order=invoice.id)
        #     # serial_numbers_list = [serial_number.serial_number for serial_number in serial_numbers_obj]

        #     subtotal_str = subtotal_values[i]
        #     subtotal_str=subtotal_str.replace("$", "").replace(",", "")

        #     subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)

        #     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.replace(",", "")) #Decimal(cost_per_unit_str)
        #     detail ={
        #             "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": myob_quotation_account,
        #             },
        #             "TaxCode": {
        #                  "UID":myob_quotation_taxcode
        #                 # "UID": "6f5fce5d-604f-49db-9a56-8573e7d2a5ec",
                        
        #             },
        #             "Item": {
        #                 "UID": product_obj.uid,
        #             },
        #         }

        #     details.append(detail)
        #     invoice_data={
        #         "Number": invoice.id,
        #         "Date":invoice.invoice_date.strftime('%Y-%m-%dT%H:%M:%S'),
        #         "SupplierInvoiceNumber": None,
        #         "Customer": {
        #             "UID": customer.myob_uid,
        #         },
        #         "ShipToAddress": f'{customer.street} {customer.city} {customer.state} {customer.post_code} {customer.country}',

        #         "Terms": { 
        #             "PaymentIsDue": "DayOfMonthAfterEOM",
        #             "DiscountDate": 1,
        #             "BalanceDueDate": 30,
        #             "DiscountForEarlyPayment": 0,
        #             "MonthlyChargeForLatePayment": 0,
        #             "DiscountExpiryDate": None,
        #             "Discount":float(invoice.discount),
        #             "DueDate": invoice.due_date.strftime('%Y-%m-%dT%H:%M:%S'),
        #         },
        #         "IsTaxInclusive": False,
        #         "IsReportable": False,
        #         "Lines":details,
        #         "Subtotal": float(invoice.subtotal),
        #         "Freight": 0,
        #         "FreightTaxCode":  {
        #                 "UID": myob_quotation_freightaxcode
        #             },
        #         "TotalTax": float(invoice.gst),
        #         "TotalAmount": float(invoice.total),
        #         "Category": None,
        #         "Comment": "",
        #         "CustomerPurchaseOrderNumber":po_number,
        #         "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(invoice_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

      

        # print("-------------------dk--------------------")
        # print("Response:", response.status_code, response.content)
        # print(response)
        # print('2222')
        # print(request.headers)
        # print("--------------------")
        # print(data)
       
        # if response.status_code == 201:
        #     pdf_data=response.content
        #     print(pdf_data)
        #     content = ContentFile(pdf_data)
        #     print(content)
            
        #     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/Order/Item/{uid}"
        #         print(api_url)

        #         headers = {
        #             'Authorization': f'Bearer {myobdata.access_token}',
        #             'x-myobapi-key': settings.MYOB_CLIENT_ID,
        #             'x-myobapi-version': 'v2',
        #             'Accept-Encoding':'gzip,deflate',
        #             'Accept':'Application/PDF',
        #         }

        #         response = requests.get(api_url, headers=headers,)
        #         pdf_data=response.content
        #         content = ContentFile(pdf_data)

        #         invoice.sale_uid = uid
        #         invoice.myob_invoice_pdf.save(f'{invoice.id}_invoice.pdf', content)
        #         invoice.flag=0
        #         invoice.save()
        invoice = Invoice.objects.get(id=invoice.id)
        if sent_mail == '1':
            pdf_file_path = invoice.myob_invoice_pdf.path 
            email.attach_file(pdf_file_path, 'application/pdf')
            email.content_subtype = 'html'
            email.send()
            ci = Customer_Info.objects.filter(customer__id = customer.id,user__is_communication = 1)
            if ci:
                for additional_email in  ci:
                    email = EmailMessage(subject, message, from_email, [additional_email.user.email])
                    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])
            status = 1
            invoice.status=status
            invoice.mailstatus=1

            invoice.save()
            messages.success(request, 'Invoice Created Successfully.')
            return redirect('quotation:list_invoice')
        
        #     else:
        #         messages.success(request, 'Invoice Created Successfully.')
        #         return redirect('quotation:list_invoice')
        # else:
        #     messages.error(request, 'Failed To Create Invoice.')
        #     return redirect('quotation:list_invoice')
        messages.success(request, 'Invoice Created Successfully.')
        return redirect('quotation:list_invoice')
    else:
        products = Product.objects.filter(is_active=True,is_product=0)
        customers = Customer.objects.filter(is_active=True,deleted_at__isnull=True)
     
        serialnumbers=SerialNumber.objects.filter(is_active=True, customer=None)
        quotations = Quotation.objects.all()

        discounts = Discount.objects.all()
        gsts = GST.objects.all()
        pcategory= ProductCategory.objects.filter(is_active=True)
        return render(request, 'pages/invoice/create.html', {'products': products,'pcategory':pcategory, 'customers': customers, 'quotations': quotations,'gsts':gsts,'discounts':discounts,'serialnumbers':serialnumbers})        
        
def line_iitems(request,id): 
    product_ids = []
    quantities = []
    subtotals = []
    costs_per_unit = []
    invoice=Invoice.objects.get(id=id)
    invoiceitems=InvoiceItem.objects.filter(invoice=invoice)
    for invoice_item in invoiceitems:
        product_ids.append(invoice_item.product.id)
        if invoice_item.product.uid == None:
            sync_myob_product_row(request,invoice_item.product.id)
        quantities.append(invoice_item.qty)
        subtotals.append(invoice_item.subtotal)
        print(subtotals)
        costs_per_unit.append(invoice_item.cost_per_unit)
        if(invoice.discount_type =='$'): 
            discpers=invoice.discount/invoice.grandsubtotal*100
            discount_percent_myob=Decimal(discpers.replace(",", "")) #Decimal(invoice.discount/invoice.grandsubtotal*100)
        else:
            discount_percent_myob= Decimal(invoice.discount_percent)
        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
            serial_numbers_obj = SerialNumber.objects.filter(product=product_obj,invoice=invoice.id)
            serial_numbers_list = [serial_number.serial_number for serial_number in serial_numbers_obj]
            subtotal_str = subtotals[i]
            subtotal = Decimal(subtotal_str) # Decimal(subtotal_str.replace(",", "")) #
            cost_per_unit_str = costs_per_unit[i]
            cost_per_unit = Decimal(cost_per_unit_str) # Decimal(cost_per_unit_str.replace(",", "")) #
            detail ={
                    "Type": "Transaction",
                    "Description":product_names + f"({product_obj.sku})" + ",".join(serial_numbers_list),  
                    "BillQuantity": int(quantities[i]),
                    "ShipQuantity" : int(quantities[i]),
                    "UnitPrice": float(cost_per_unit),
                    "UnitCount" :int(quantities[i]),
                    "DiscountPercent" :float(discount_percent_myob),
                    "Account": {
                        "UID": myob_quotation_account,
                    },
                    "TaxCode": {
                        "UID":myob_quotation_taxcode
                        # "UID": "6f5fce5d-604f-49db-9a56-8573e7d2a5ec",
                    },
                    "Item": {
                        "UID": product_obj.uid,
                    },
                }
            details.append(detail)     
        return details;


def find_diff(a, b):
    result = []
    old = []
    newarr = []
    a = json.loads(a)
    b = json.loads(b)
    for key in a:
        # dd(a)
        if key not in b:
            result.append(f'{dict({key: a[key]})} -> {"key deleted"}')
        if a[key] != 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]}')
            # else:
                # old.append(f'Updated {key} From {a[key]} to {b[key]}')
                # old.append(f'Updated {key} From {a[key]} to {b[key]}')
    dd(old)
    result='\n'.join(t for t in result)
    # result1='\n'.join(t for t in result1)
    # dd({'result':result,'result1':result1})
    return result
# @user_passes_test(lambda u: is_admin(u) or is_superuser(u))
# @login_required
# def activity_invoice(request, id):
#     invoice = get_object_or_404(Invoice, pk=id)
#     invoiceitems = InvoiceItem.objects.filter(invoice=invoice)
#     context={'invoices': invoice}
#     # dd(invoice.get_history)
#     t1=[]
#     for inv in invoice.get_history:
#         if inv.action == 'Updated':
#             s1 = json.dumps(inv.new_data[0]['fields'])
#             s2 = json.dumps( inv.old_data[0]['fields'])
#             t=find_diff(s1, s2)
#             t1.append(t)
#     for t in t1:
#         dd(t)
#     return render(request, 'pages/invoice/activity.html', {'invoices':t1})


def history(row):  
    result = []
    old = []
    newarr = []
    activity={}
    if row.model_name != 'Customer_Payment' and row.model_name != 'Order':
        activity['model_name']=row.model_name
        activity['timestamp']=row.timestamp
        activity['log_activity']=''
        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' or key == 'created_at' ):
                        
                        old.append(f'Updated {key} From {a[key]} to {b[key]}')
                        
                        # CREATED = 0
                        # SENTED = 1
                        # ACCEPTED = 2
                        # OPEN=3
                        # CLOSE=4
                        
                        activity['log_activity']= f"{activity['log_activity']}<b>{key} </b> From   <b>{b[key]} </b> To  <b>{a[key]} </b><br>"
                        # dd( activity['log_activity'])
                        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>'
                            
                            
                        ORDERED = 0
                        SHIPPED = 1
                        WATERED = 2
                        ARRIVED = 3
                        BOOKED_FOR_INSTALL= 4
                        INSTALLED=5    
                            
                            
                        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 key == 'tracking_status':
                                    a[key]=int(a[key])
                                    b[key]=int(b[key])
                                    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':
            if row.model_name == 'QuotationItem'  or  row.model_name == 'InvoiceItem':
                a = json.dumps(row.new_data[0]['fields'])
                a = json.loads(a)
                pname=''
                qty=0
                for key in a:
                    if key == 'product':
                        product= Product.objects.get(id=a[key])
                        pname=product.product_name
                        sku=product.sku
                    if key == 'qty':
                        qty=a[key]
                
                activity['log_activity']=f"{ activity['log_activity']} Product <b>{pname}({sku}) </b> With Qty   <b>{qty} </b>"
                activity['action']='Created'
            else:
                result.append(f'Created')
                activity['log_activity']='Created'
                activity['action']='Created'
    
        elif  row.action == 'Updated':
            
            if row.model_name == 'QuotationItem' or  row.model_name == 'InvoiceItem'  :
                if key in a and key in b and a[key] != b[key]:
                    a = json.dumps(row.new_data[0]['fields'])
                    a = json.loads(a)
                    pname=''
                    qty=0
    
                    
                    for key in a:
                        if key == 'product':
                            product= Product.objects.get(id=a[key])
                            pname=product.product_name
                            sku=product.sku
                        if key == 'qty':
                            qty=a[key]
    
                    
                    
                    activity['log_activity']= f"{ activity['log_activity']} Product <b>{pname}({sku}) </b> With Qty   <b>{qty} </b><br>"
                    activity['action']='Updated'
            # elif row.model_name == 'Customer_Payment':
            #     if key in a and key in b and a[key] != b[key]:
            #         a = json.dumps(row.new_data[0]['fields'])
            #         a = json.loads(a)
    
            #         for key in a:
            #             if key == 'payable_amount':
    
    
    
            #         activity['log_activity']= f"{ activity['log_activity']} Product <b>{pname}({sku}) </b> With Qty   <b>{qty} </b><br>"
            #         activity['action']='Updated'
    
    
    
    
        
        return activity

    

def oder_history(row):
    result = []
    old = []
    newarr = []
    
    activity={}
   
    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]:
                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]='Ordered'
                        if a[key]==1:
                            a[key]='Shipped'
                        if a[key]==3  :
                             a[key]='Arrived' 
                        if a[key]==4:
                             a[key]='Booked For Install'  
                        if a[key]==5:
                             a[key]='Not Started'
                        if a[key]==6:
                             a[key]='In Progress'
                        if a[key]==7:
                             a[key]='Installed'
                        if a[key]==8:
                             a[key]='Service Requested' 
                        if a[key]==9:
                             a[key]='Parts Requested'  
                        if a[key]==10:
                             a[key]='Installation Completed'
                        if a[key]==11:
                             a[key]='Service Completed'  
                           
                            
                        if b[key]==0:
                            b[key]='Ordered'
                        if b[key]==1:
                            b[key]='Shipped'
                        if b[key]==3:
                             b[key]='Arrived' 
                        if b[key]==4:
                             b[key]='Booked For Install'  
                        if b[key]==5:
                             b[key]='Not Started'
                        if b[key]==6:
                            b[key]='In Progress'
                        if b[key]==7:
                             b[key]='Installed'
                        if b[key]==8:
                             b[key]='Service Requested' 
                        if b[key]==9:
                             b[key]='Parts Requested'  
                        if b[key]==10:
                             b[key]='Installation Completed'
                        if b[key]==11:
                             b[key]='Service Completed'  
                           
                        activity['log_activity']=f' <b>{key} </b> From   <b>{b[key]} </b> To  <b>{a[key]} </b>'
                        
                        
                
                        
                    if key == 'service_type':
                        a[key]=int(a[key])
                        b[key]=int(b[key])
                        if a[key]==1:
                             a[key]='Installation'
                        if a[key]==2:
                             a[key]='Service'
                        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]==1:
                             b[key]='Installation'
                        if b[key]==2:
                             b[key]='Service' 
                       
                        
                        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 key == 'tracking_status':
                                a[key]=int(a[key])
                                b[key]=int(b[key])
                                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) or is_sales(u))
@login_required
def activity_invoice(request, id):
    invoice = get_object_or_404(Invoice, pk=id)
    invoiceitems = InvoiceItem.objects.filter(invoice=invoice)
    context={'invoices': invoice}
    # dd(invoice.get_history)
    t1=[]
    counter=1

   
        
        
    for inv in invoice.get_history:
        if inv is not None:
            t=history(inv)
            t1.append(t)

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

    return render(request, 'pages/invoice/activity.html', {'t1':t1,'counter':counter})

    
    
    
    
    
    
@user_passes_test(lambda u: is_admin(u) or is_superuser(u) or is_sales(u))
@login_required
def activity_quote(request, id):
    quotation = get_object_or_404(Quotation, pk=id)

    context={'quotations': quotation}
    # dd(invoice.get_history)
    t1=[]

   
    for quote in quotation.get_history:
        if quote is not None:
            t=history(quote)
            t1.append(t)

    
    counter = 1

    for quote in t1:
        if 'log_activity' in quote and quote['log_activity'] is not None and quote['log_activity'] != '':
            quote['row_number'] = counter
            counter += 1
    
    return render(request, 'pages/quotation/activity.html', {'t1':t1,'counter':counter})

    
    
    
@user_passes_test(lambda u: is_admin(u) or is_superuser(u) or is_sales(u))
@login_required
def activity_order(request, id):
    order = get_object_or_404(Order, pk=id)
    orderitems = Order_Item.objects.filter(order=order)
    context={'orders': order}
    # dd(invoice.get_history)
    t1=[]

    counter=1

    if order.get_history is not None:
        for o_r in order.get_history:
            if  o_r.old_data:
                t=oder_history(o_r)
                t1.append(t)

    for order in t1:
        if 'log_activity' in order and order['log_activity'] is not None and order['log_activity'] != '':
            order['row_number'] = counter
            counter += 1
    
    return render(request, 'pages/order/activity.html', {'t1':t1,'counter':counter})
        

        
@user_passes_test(lambda u: is_admin(u) or is_superuser(u) or is_sales(u))
@login_required
def edit_invoice(request, id):
    invoice = get_object_or_404(Invoice, pk=id)
    invoiceitems = InvoiceItem.objects.filter(invoice=invoice)
    refresh_token(request)
    myobdata = MyobModel.objects.first()
    if not myobdata:
        messages.error(request,'Please First create Access Code')
        return redirect('/myob/initiate-connection')
    
    
    if request.method == 'POST':
        # dd(request.POST)
        customer_id = request.POST.get('customer') 
        invoice_date = request.POST.get('invoice_date') 
        due_date = request.POST.get('due_date') 
        po_number=request.POST.get('po_number') 
        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')) 
        descriptions = request.POST.getlist('description[]', [])
        gst_percent =int( request.POST.get('gst'))
        total = request.POST.get('total')
        sent_mail = request.POST.get('sent_mail')
        status = request.POST.get('status')
        trade_product_name = request.POST.getlist('tradeproduct[]',[])
        trade_pcategory = request.POST.getlist('pcategory[]',[])
        trade_product_description = request.POST.getlist('descriptiontrade[]',[])
        trade_ids = request.POST.getlist('trade_id[]',[])
        
        delete_list = request.POST.getlist('deleted[]')
        if(request.POST.get('discount_type')=='dollar'):
            discount_type="$"
            discount_percent= 0
            discount = int(int(re.findall('\d+', request.POST.get('dollar_type'))[0]) ) 
            percmyob=discount/grandsubtotal*100
            discount_percent_myob= Decimal(percmyob.replace(",", "")) #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) #Decimal(discount_percent)
        grand_subtotal= grandsubtotal-discount
        gst = grand_subtotal * ( gst_percent / 100) 
        discount="{:.2f}".format(discount) 
        gst="{:.2f}".format(gst) 
        grand_subtotal ="{:.2f}".format(grand_subtotal)
        start_date_obj = datetime.strptime(invoice_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

        customer = Customer.objects.get(id=customer_id)
        if invoice.total_paid_amount:
          total_paid_amount=invoice.total_paid_amount
        else:
            total_paid_amount=0
            
        invoice.customer = customer
        invoice.invoice_date = start_date_obj
        invoice.due_date = due_date_obj
        invoice.po_number = po_number
        invoice.subtotal = grand_subtotal
        invoice.discount_percent=discount_percent
        invoice.discount = discount
        invoice.discount_type = discount_type
        invoice.total = total
        invoice.payable_amount=Decimal(total.replace(",", ""))-total_paid_amount
        invoice.gst_percent=gst_percent
        invoice.gst=gst
        invoice.status = status
        invoice.is_active = is_active
        invoice.updated_by=request.user
        invoice.save()
        customer_payments = Customer_Payment.objects.filter(invoice=invoice)

        # Check if any Customer_Payment object exists for the given invoice
        if customer_payments.exists():
            # If at least one Customer_Payment object exists, you can access it using .first()
            customer_payment = customer_payments.first()
       
            customer_payment=Customer_Payment.objects.get(invoice=invoice)
            customer_payment.payable_amount=Decimal(total.replace(",", ""))-invoice.total_paid_amount
            customer_payment.due_amount=Decimal(total.replace(",", ""))-customer_payment.paid_amount
            customer_payment.save()

        

        invoice_items = []
        # if deleted[]:
        #     if  deleted=0 then dont do anything
        #     else delete
            
        #     # invoiceitems = InvoiceItem.objects.filter(invoice=invoice).delete()
        

        # if  delete_list:
        #     for i in range(len(delete_list)):
        #         deleted_value = delete_list[i]
        #         if deleted_value == '0':
        #             pass
        #         else:
        #             invoiceitems = InvoiceItem.objects.filter(id=deleted_value).delete()
        
        if  delete_list:
            for i in range(len(delete_list)):
                deleted_value = delete_list[i]
                if deleted_value == '0':
                    pass
                else:
                    if InvoiceItem.objects.filter(id=deleted_value,is_trade_product = 0):
                        invoiceitems = InvoiceItem.objects.filter(id=deleted_value).delete()
                    else:
                        invi=InvoiceItem.objects.filter(id=deleted_value,is_trade_product = 1)
                        if invi:
                            p=Product.objects.filter(id=invi[0].product.id)
                            if p:
                                Product.objects.filter(id=invi[0].product.id).delete()
                                InvoiceItem.objects.filter(id=deleted_value).delete()
        pnew=[]
        # dd(request.POST)
        for i in range(len(product_ids)):
            if trade_product_name[i] == '' or trade_ids[i] == ''  or trade_ids[i] == ' ':
                product_id = product_ids[i]
                pnew.append(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.replace(",", "")) #Decimal(cost_per_unit_str)
                subtotal_str = subtotal_values[i]
                subtotal_str = subtotal_str.replace("$", "").replace(",", "")
                subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)
                product_obj = Product.objects.get(id=product_id)
                invoiceitemsexist = InvoiceItem.objects.filter(invoice=invoice,product=product_obj)
                if i < len(descriptions):
                    description = descriptions[i]    
                    if  descriptions[i] != '':
                        is_madatory=1
                        is_required_send_to_admin=1
                else:
                    description = None
                is_trade_product=0
                if not invoiceitemsexist:
                    invoiceitem = InvoiceItem(
                        invoice= invoice,  
                        product=product_obj,
                        description=description,
                        cost_per_unit=cost_per_unit,
                        is_trade_product=is_trade_product,
                        qty=qty,
                        subtotal=subtotal,
                    )
                    invoiceitem.updated_by=request.user
                    invoiceitem.save()
                else:
                    # if(product_obj.trade_product == None):
                    #     invoiceitemsexist = InvoiceItem.objects.get(invoice=invoice,trade_product=product_obj,product__is_trade=1)
                    # else:
                    invoiceitemsexist = InvoiceItem.objects.get(invoice=invoice,product=product_obj)
                    invoiceitemsexist.product=product_obj
                    invoiceitemsexist.cost_per_unit=cost_per_unit
                    invoiceitemsexist.qty=qty
                    invoiceitemsexist.is_trade_product=is_trade_product
                    invoiceitemsexist.description=description
                    invoiceitemsexist.subtotal=subtotal
                    invoiceitemsexist.updated_by=request.user
                    invoiceitemsexist.save()
                    invoiceitem = InvoiceItem(
                        invoice= invoice,  
                        product=product_obj,
                        cost_per_unit=cost_per_unit,
                        is_trade_product=is_trade_product,
                        description=description,
                        qty=qty,
                        subtotal=subtotal,
                        updated_by=request.user
                    )
                invoice_items.append(invoiceitem)
            else:
                trade_id=trade_ids[i]
                if trade_id == 'new' :
                    product_id = product_ids[i]
                    qty = int(qty_values[i])
                    t_product_name = trade_product_name[i]
                    t_product_discription = trade_product_description[i]
                    t_category=trade_pcategory[i]
                    t_product_cost_per_unit=cost_per_unit_values[i]
                    t_product_cost_per_unit = t_product_cost_per_unit.replace('$', '').replace(",", "") 
                    t_product_cost_per_unit = Decimal(t_product_cost_per_unit.replace(",", "")) #Decimal(t_product_cost_per_unit)
                    categorie = ProductCategory.objects.get(category_name="TRADE PRODUCT")
                    product = Product.objects.create(
                        category_id= t_category, #categorie.id,
                        product_name=t_product_name,
                        product_type='used',
                        product_description= t_product_discription ,
                        product_price=t_product_cost_per_unit,
                        is_active=True,
                        is_product=1,
                        created_by=request.user
                    )
                    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}/Inventory/Item/"
                    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'
                    }
                    product = Product.objects.latest('id')
                    product_data=   {
                            "Number":product.id,
                            "Name": f'{product.product_name}',
                            "IsActive": True,
                            "IsBought" : True,
                            "IsSold" : True,
                            "IsInventoried" : False,
                            "ExpenseAccount" :  { "UID": myob_expense_account },
                            "Description": product.product_description[:255],
                            "CostOfSalesAccount" : { "UID" : myob_cost_of_sales_account,  },
                            "IncomeAccount": { "UID":  myob_income_account, },
                            "AssetAccount" : { "UID" : myob_asset_account, },
                            "BuyingDetails": {
                                "BaseSellingPrice" :float(product.product_price),
                                "ItemsPerBuyingUnit" : 1,
                                "TaxCode": {  "UID": myob_tax_code, }
                            },
                            "SellingDetails": {
                                "BaseSellingPrice" : float(product.product_price),
                                "ItemsPerBuyingUnit" : 1,
                                "TaxCode": { "UID": myob_tax_code, }
                            }
                        }
                    print(product_data)
                    product_json = json.dumps(product_data)
                    response = requests.post(api_url, data=product_json, headers=headers)
                    data=response.headers
                    if response.status_code == 201:
                        location = data['Location']
                        if location:
                            parts = location.split('/')
                            uid = parts[-1]
                            # product.myob_location = location
                            product.uid = uid
                            product.save()
                    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.replace(",", "")) # Decimal(cost_per_unit_str)
                    
                    subtotal_str = subtotal_values[i]
                    subtotal_str = subtotal_str.replace("$", "").replace(",", "")
                    subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)
                    # product_obj = Product.objects.get(id=product_id)
                    is_trade_product=1
                    trade_product_id = Product.objects.get(id=product_id)
                    cost_per_unit=cost_per_unit
                    
                    if i < len(descriptions):
                        description = descriptions[i]    
                        if  descriptions[i] != '':
                            is_madatory=1
                            is_required_send_to_admin=1
                    else:
                        description = None
                    is_trade_product=1
                    invoiceitem = InvoiceItem(
                        invoice= invoice,   
                        product= product,
                        cost_per_unit=cost_per_unit,
                        description=description,
                        qty=qty,
                        subtotal=subtotal,
                        trade_product_id = trade_product_id.id,
                        is_trade_product=is_trade_product,
                        created_by=request.user
                    )
                    pnew.append(product.id)
                    
                    invoiceitem.save()
                    invoice_items.append(invoiceitem)
                    invoice = Invoice.objects.latest('id')
                    invoice.is_trade=1
                    invoice.save()
                else:
                    product_id = product_ids[i]
                    trade_id=trade_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.replace(",", "")) #Decimal(cost_per_unit_str)
                    subtotal_str = subtotal_values[i]
                    subtotal_str = subtotal_str.replace('$', '').replace(",", "")
                    subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)
                    if i < len(descriptions):
                        description = descriptions[i]
                        is_madatory=1
                    else:
                        description = None
                    # dd(trade_id)
                    product_obj = Product.objects.get(id=trade_id)
                    product_obj.product_price=cost_per_unit
                    product_obj.product_description=trade_product_description[i]
                    product_obj.category_id=trade_pcategory[i]
                    product_obj.product_name=trade_product_name[i]
                    product_obj.save()
                    product= Product.objects.get(id=product_id)
                    # update product to myob
                    
                    # invoiceitem = InvoiceItem(
                    #         invoice= invoice,  
                    #         product=product_obj,
                    #         description=description,
                    #         cost_per_unit=cost_per_unit,
                    #         is_trade_product=1,
                    #         trade_product=product,
                    #         qty=qty,
                    #         subtotal=subtotal,
                    #     )
                    if(product_obj.trade_product == None):
                        invoiceitemsexist = InvoiceItem.objects.get(invoice=invoice,trade_product=product_obj,product__is_trade=1)
                    else:
                        invoiceitemsexist = InvoiceItem.objects.get(invoice=invoice,product=product_obj)
                    invoiceitemsexist.product=product_obj
                    invoiceitemsexist.cost_per_unit=cost_per_unit
                    invoiceitemsexist.qty=qty
                    invoiceitemsexist.subtotal=subtotal
                    invoiceitemsexist.description=description
                    invoiceitemsexist.is_trade_product=1
                    invoiceitemsexist.trade_product=product
                    invoiceitemsexist.updated_by=request.user
                    invoiceitemsexist.save()
                    pnew.append(product_obj.id)
                    
                # invoice_items.append(invoiceitem)
                  
        invoice = Invoice.objects.get(id=invoice.id)
        # dd(invoice)
        invoiceitems = InvoiceItem.objects.filter(invoice=invoice)
        
        if invoice.pdf_file:
            old_pdf_path = invoice.pdf_file.path
            if os.path.exists(old_pdf_path):
                os.remove(old_pdf_path)

        

        pdf_data = generate_pdfs(invoice, invoiceitems)
        invoice.pdf_file.save(f'{invoice.id}_invoice.pdf', pdf_data)

        # doc_data = generate_docs(invoice, invoiceitems)
        # invoice.doc_file.save(f'{invoice.id}_invoice.docx', doc_data)
        
        # invoice_detail_url = request.build_absolute_uri(reverse('quotation:view_invoice_detail', args=[invoice.id]))

        subject = f'EXCITECH Australia - Invoice Details for Invoice ID {invoice.id}'
        invoice_payment_url = request.build_absolute_uri(reverse('quotation:checkout', args=[invoice.id]))
        template_data = {'invoice': invoice,'invoice_payment_url':invoice_payment_url}
        message = render_to_string('pages/invoice/invoice_email_temp.html', template_data)
        # message += "Please find attached Invoice."
        from_email =settings.FROM_EMAIL # Replace with your email address
        recipient_email = customer.user.email  # Use the customer's email address
        email = EmailMessage(subject, message, from_email, [recipient_email])
        

        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=invoice.sale_uid
        api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item/{UID}"
        # dd(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 
            # row_id = data['Lines'][0]['RowID']
            # row_version = data['Lines'][0]['RowVersion']
            # balance_due_amount = data['BalanceDueAmount']
            lines = []  # Initialize the list to store line items

            for i in range(len(product_ids)):
                if trade_product_name[i] == '':
                    product_id = product_ids[i]
                else:
                    product_id = pnew[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("$", "").replace(",", "")
                subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)

                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.replace(",", "")) #Decimal(cost_per_unit_str)

                # Create a line item for the current product
                line_item = {
                    "Item": {
                        "UID": product_obj.uid,
                    },
                    # "Customer": {
                    #     "UID": customer.myob_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": myob_quotation_account,
                    },
                    "TaxCode": {
                        "UID":myob_quotation_taxcode
                        # "UID": "6f5fce5d-604f-49db-9a56-8573e7d2a5ec",
                    },
                    
                }

                lines.append(line_item) 
            
                # lines=line_iitems(request,invoice.id)
                

                invoice_data={
                    "UID": invoice.sale_uid,
                    "Number": invoice.id,
                    "Date":invoice.invoice_date.strftime('%Y-%m-%dT%H:%M:%S'),
                    "SupplierInvoiceNumber": None,
                    "Customer": {
                        "UID": invoice.customer.myob_uid,
                    },

                    "ShipToAddress": f'{customer.street} {customer.city} {customer.state} {customer.post_code} {customer.country}',

                    "Terms": { 
                        "PaymentIsDue": "DayOfMonthAfterEOM",
                        "DiscountDate": 1,
                        "BalanceDueDate": 30,
                        "DiscountForEarlyPayment": 0,
                        "MonthlyChargeForLatePayment": 0,
                        "DiscountExpiryDate": None,
                        "Discount":float(invoice.discount),
                        "DueDate": invoice.due_date.strftime('%Y-%m-%dT%H:%M:%S'),
                    },
                    "IsTaxInclusive": False,
                    "IsReportable": False,
                    "Lines":lines,
                    "Subtotal": float(invoice.subtotal),
                    "Freight": 0,
                    "FreightTaxCode": {
                            "UID": myob_quotation_freightaxcode
                        },
                    "TotalTax": float(invoice.gst),
                    "TotalAmount": float(invoice.total),
                    "Category": None,
                    "Comment": "",
                    "CustomerPurchaseOrderNumber":po_number,
                    "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(invoice_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)
            
           
            print("-------------------dk--------------------")
            print("Response:", response.status_code, response.content)
            print(response)
            
            print('2222')
            print(request.headers)
            print("--------------------")
            data=response.headers
            print(data)
            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/Order/Item/{uid}"
                    print(api_url)
                    
                    headers = {
                        'Authorization': f'Bearer {myobdata.access_token}',
                        'x-myobapi-key': settings.MYOB_CLIENT_ID,
                        'x-myobapi-version': 'v2',
                        'Accept-Encoding':'gzip,deflate',
                        'Accept':'Application/PDF',
                    }
    
                    response = requests.get(api_url, headers=headers,)
                    pdf_data=response.content
                    content = ContentFile(pdf_data)
                    if invoice.myob_invoice_pdf:
                        old_myob_invoice_pdf_path = invoice.myob_invoice_pdf.path
                        if os.path.exists(old_myob_invoice_pdf_path):
                            os.remove(old_myob_invoice_pdf_path)
                            # dd(old_myob_invoice_pdf_path);
                            
                    invoice.sale_uid = uid
                    invoice.myob_invoice_pdf.save(f'{invoice.id}_invoice.pdf', content)
                    # invoice.myob_invoice_pdf=invoice.myob_invoice_pdf
                    invoice.flag=0
                    invoice.save()
                # dd(sent_mail)
                if sent_mail == '1' or sent_mail == 1:
                    pdf_file_path = invoice.myob_invoice_pdf.path 
                    email.attach_file(pdf_file_path, 'application/pdf')
                    email.content_subtype = 'html'
                    email.send()
                    ci = Customer_Info.objects.filter(customer__id = customer.id,user__is_communication = 1)
                    if ci:
                        for additional_email in  ci:
                            email = EmailMessage(subject, message, from_email, [additional_email.user.email])
                            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])
                    if invoice.status == 0:
                        invoice.status=1
                    invoice.mailstatus=1
                    invoice.save()
                    messages.success(request, 'Invoice Updated Successfully.')
                    return redirect('quotation:list_invoice')
            
                else:
                    messages.success(request, 'Invoice Updated Successfully.')
                    return redirect('quotation:list_invoice')
            else:
                messages.error(request, 'Failed To Update Invoice.')
                return redirect('quotation:list_invoice')
        else:
            # return redirect('quotation:myob_synch',invoice.id)
            data=sync_myob_invoice(request,invoice.id)
            invoice=Invoice.objects.get(id=invoice.id)
            if sent_mail == '1' or sent_mail == 1:
                if invoice.myob_invoice_pdf:
                    pdf_file_path = invoice.myob_invoice_pdf.path 
                    email.attach_file(pdf_file_path, 'application/pdf')
                    email.content_subtype = 'html'
                    email.send()
                    ci = Customer_Info.objects.filter(customer__id = customer.id,user__is_communication = 1)
                    if ci:
                        for additional_email in  ci:
                            email = EmailMessage(subject, message, from_email, [additional_email.user.email])
                            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])
                    if invoice.status == 0:
                        invoice.status=1
                    invoice.mailstatus=1
                    invoice.save()
                    messages.success(request, 'Invoice Updated Successfully.')
                    return redirect('quotation:list_invoice')
            messages.success(request, 'Invoice Updated Successfully.')
            return redirect('quotation:list_invoice')

    else:
        
        serialnumbers=SerialNumber.objects.filter(is_active=True)
        print(serialnumbers)
        products = Product.objects.filter(is_active=True,is_product=0)
        customers = Customer.objects.filter(is_active=True,deleted_at__isnull=True)
      
        discounts = Discount.objects.all()
        
        gsts = GST.objects.all()
        pcategory= ProductCategory.objects.filter(is_active=True)
        return render(request, 'pages/invoice/edit.html', {'invoice': invoice, 'invoiceitems': invoiceitems, 'products': products,'pcategory':pcategory, 'customers': customers, 'gsts': gsts, 'discounts': discounts,'serialnumbers':serialnumbers})



@user_passes_test(lambda u: is_admin(u) or is_superuser(u) or is_sales(u))
@login_required
def sent_invoice_mail(request,id):
    invoice = get_object_or_404(Invoice, id=id)
    if(invoice.myob_invoice_pdf):
        customer = Customer.objects.get(id=invoice.customer.id)
        invoice_detail_url = request.build_absolute_uri(reverse('quotation:view_invoice_detail', args=[invoice.id]))
        invoice_payment_url = request.build_absolute_uri(reverse('quotation:checkout', args=[invoice.id]))
        subject = f'EXCITECH Australia - Invoice Details for Invoice ID {invoice.id}'
        template_data = {'invoice': invoice,'invoice_payment_url':invoice_payment_url}
        message = render_to_string('pages/invoice/invoice_email_temp.html', template_data)
        from_email =settings.FROM_EMAIL # Replace with your email address
        recipient_email = customer.user.email  # Use the customer's email address
        email = EmailMessage(subject, message, from_email, [recipient_email])
        
        if email:
           pdf_file_path = invoice.myob_invoice_pdf.path 
           email.attach_file(pdf_file_path, 'application/pdf')
           email.content_subtype = 'html'
           email.send()
           ci = Customer_Info.objects.filter(customer__id = customer.id,user__is_communication = 1)
           if ci:
               for additional_email in  ci:
                   email = EmailMessage(subject, message, from_email, [additional_email.user.email])
                   email.attach_file(pdf_file_path, 'application/pdf')
                   email.content_subtype = 'html'
                   email.send()
           invoice.mailstatus=1
           if invoice.status !=4 :
              invoice.status=Invoice.SENTED
           invoice.save()
           messages.success(request, 'Email Sent Successfully.')
           return redirect(request.META.get('HTTP_REFERER', '/'))
        else:
            messages.error(request, 'Fail To Send Mail.')
            return redirect('quotation:list_invoice')
    else:
        messages.error(request, 'Synch invoice with myob and try again.')
        return redirect('quotation:list_invoice')
        

@user_passes_test(lambda u: is_admin(u) or is_superuser(u) or is_sales(u))
@login_required
def send_payment_invoice_mail(request,id):
    invoice = get_object_or_404(Invoice, id=id)
    if(invoice.myob_invoice_pdf):
        customer = Customer.objects.get(id=invoice.customer.id)
        invoice_detail_url = request.build_absolute_uri(reverse('quotation:view_invoice_detail', args=[invoice.id]))
        invoice_payment_url = request.build_absolute_uri(reverse('quotation:checkout', args=[invoice.id]))
        subject = f'EXCITECH Australia - Invoice Payment Link For Invoice ID {invoice.id}'
        template_data = {'invoice': invoice,'invoice_payment_url':invoice_payment_url}
        # message = render_to_string('pages/invoice/invoice_email_temp.html', template_data)
        message = render_to_string('pages/invoice/invoice_payment_email.html', template_data)
        from_email =settings.FROM_EMAIL # Replace with your email address
        recipient_email = customer.user.email  # Use the customer's email address
        email = EmailMessage(subject, message, from_email, [recipient_email])
        
        if email:
            pdf_file_path = invoice.myob_invoice_pdf.path 
            email.attach_file(pdf_file_path, 'application/pdf')
            email.content_subtype = 'html'
            email.send()
            ci = Customer_Info.objects.filter(customer__id = customer.id,user__is_communication = 1) 
            if ci: 
                for additional_email in  ci:
                    email = EmailMessage(subject, message, from_email, [additional_email.user.email])
                    email.attach_file(pdf_file_path, 'application/pdf')
                    email.content_subtype = 'html'
                    email.send()
        #   invoice.mailstatus=1
        #   if invoice.status !=4 :
        #       invoice.status=Invoice.SENTED
        #   invoice.save()
            messages.success(request, 'Payment Link Sent Successfully.')
            return redirect(request.META.get('HTTP_REFERER', '/'))
        else:
            messages.error(request, 'Fail To Send Payment Link.')
            return redirect('quotation:list_invoice')
    else:
        messages.error(request, 'Synch invoice with myob and try again.')
        return redirect('quotation:list_invoice')
        
@user_passes_test(lambda u: is_admin(u) or is_superuser(u) or is_sales(u))
@login_required
def convert_quotation_to_invoice(request, id):
    quotation = get_object_or_404(Quotation, pk=id)
    quotationitems = QuotationItem.objects.filter(quotation=quotation)
    refresh_token(request)
    myobdata = MyobModel.objects.first()
    if not myobdata:
        messages.error(request,'Please First create Access Code')
        return redirect('/myob/initiate-connection')
    if request.method == 'POST':
        customer_id = request.POST.get('customer') 
        invoice_date = request.POST.get('invoice_date') 
        due_date =  request.POST.get('due_date')
        po_number =  request.POST.get('po_number')
        descriptions = request.POST.getlist('description[]', [])
        product_ids = request.POST.getlist('product[]', [])
        qty_values = request.POST.getlist('qty[]', [])
        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')
        trade_product_name = request.POST.getlist('tradeproduct[]',[])
        trade_pcategory = request.POST.getlist('pcategory[]',[])
        trade_product_description = request.POST.getlist('descriptiontrade[]',[])
        trade_ids = request.POST.getlist('trade_id[]',[])
        if(request.POST.get('discount_type')=='dollar'):
            discount_type="$"
            discount_percent= 0
            discount = int(int(re.findall('\d+', request.POST.get('dollar_type'))[0]) ) 
        else:
            discount_type="%"
            discount_percent= int(request.POST.get('discount'))
            discount = grandsubtotal * ( discount_percent / 100)  
        grand_subtotal= grandsubtotal-discount
        gst = grand_subtotal * ( gst_percent / 100) 
        start_date_obj = datetime.strptime(invoice_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
    
        customer = Customer.objects.get(id=customer_id)
        
        invoice = Invoice.objects.create(
            customer=customer,
            quotation=quotation,
            invoice_date=start_date_obj,
            due_date=due_date_obj,
            po_number=po_number,
            subtotal= grandsubtotal,
            discount_percent=discount_percent,
            discount=discount,
            discount_type=discount_type,
            total=total,
            payable_amount=total,
            gst_percent=gst_percent,
            gst=gst,
            is_trade=quotation.is_trade,
            status=status,
            is_active=is_active,
            created_by=request.user
        )
    
       

        invoiceitems = []

        for i in range(len(trade_product_name)):
            if trade_product_name[i] == '':
                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.replace(",", "")) #Decimal(cost_per_unit_str)
                subtotal_str = subtotal_values[i]
                subtotal_str = subtotal_str.replace('$', '')  
                print(subtotal_str)
                subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)
                if i < len(descriptions):
                    description = descriptions[i]
                    if description != '':
                       is_madatory=1
                else:
                    description = None
                product_obj = Product.objects.get(id=product_id)
              
                is_trade_product=0
                invoiceitem = InvoiceItem(
                    invoice=invoice,  
                    product=product_obj,
                    is_trade_product=is_trade_product,
                    description=description,
                    cost_per_unit=cost_per_unit,
                    qty=qty,
                    subtotal=subtotal,
                )
                created_by=request.user
                invoiceitem.save()
                invoiceitems.append(invoiceitem)
            else:
                trade_id=trade_ids[i]
                if trade_id == 'new' or trade_id == '':
                    t_product_name = trade_product_name[i]
                    t_product_discription = trade_product_description[i]
                    t_category=trade_pcategory[i]
                    t_product_cost_per_unit=cost_per_unit_values[i]
                    t_product_cost_per_unit = t_product_cost_per_unit.replace('$', '').replace(",", "") 
                    t_product_cost_per_unit = Decimal(t_product_cost_per_unit.replace(",", "")) # Decimal(t_product_cost_per_unit)
                    categorie = ProductCategory.objects.get(category_name="TRADE PRODUCT")
                    product = Product.objects.create(
                        category_id= t_category, #categorie.id,
                        product_name=t_product_name,
                        product_type='used',
                        product_description= t_product_discription ,
                        product_price=t_product_cost_per_unit,
                        is_active=True,
                        is_product=1,
                        created_by=request.user
                    )
                    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}/Inventory/Item/"
                    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'
                    }
                    product = Product.objects.latest('id')
                    product_data=   {
                            "Number":product.id,
                            "Name": f'{product.product_name}',
                            "IsActive": True,
                            "IsBought" : True,
                            "IsSold" : True,
                            "IsInventoried" : False,
                            "ExpenseAccount" :  { "UID": myob_expense_account },
                            "Description": product.product_description[:255],
                            "CostOfSalesAccount" : { "UID" : myob_cost_of_sales_account,  },
                            "IncomeAccount": { "UID":  myob_income_account, },
                            "AssetAccount" : { "UID" : myob_asset_account, },
                            "BuyingDetails": {
                                "BaseSellingPrice" :float(product.product_price),
                                "ItemsPerBuyingUnit" : 1,
                                "TaxCode": {  "UID": myob_tax_code, }
                            },
                            "SellingDetails": {
                                "BaseSellingPrice" : float(product.product_price),
                                "ItemsPerBuyingUnit" : 1,
                                "TaxCode": { "UID": myob_tax_code, }
                            }
                        }
                    print(product_data)
                    product_json = json.dumps(product_data)
                    response = requests.post(api_url, data=product_json, headers=headers)
                    data=response.headers
                    if response.status_code == 201:
                        location = data['Location']
                        if location:
                            parts = location.split('/')
                            uid = parts[-1]
                            # product.myob_location = location
                            product.uid = uid
                            product.save()
                    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.replace(",", ""))#Decimal(cost_per_unit_str)
                    subtotal_str = subtotal_values[i]
                    subtotal_str = subtotal_str.replace('$', '')  
                    subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)
                    product_obj = Product.objects.get(id=product.id)
                    # product_obj = Product.objects.get(id=trade_id)
                    product_obj.product_price=cost_per_unit
                    product_obj.product_description=trade_product_description[i]
                    product_obj.category_id=trade_pcategory[i]
                    product_obj.product_name=trade_product_name[i]
                    product_obj.save()
                    if i < len(descriptions):
                        description = descriptions[i] 
                        if description != '': 
                            is_madatory=1
                    else:
                        description = None
                    product= Product.objects.get(id=product_id)
                    invoiceitem = InvoiceItem(
                        invoice=invoice,  
                        product=product,
                        is_trade_product=1,
                        description=description,
                        cost_per_unit=cost_per_unit,
                        qty=qty,
                        trade_product=product_obj,
                        subtotal=subtotal,
                    )
                    created_by=request.user
                    invoiceitem.save()
                    invoiceitems.append(invoiceitem)
                else:
                    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.replace(",", "")) # Decimal(cost_per_unit_str)
                    subtotal_str = subtotal_values[i]
                    subtotal_str = subtotal_str.replace('$', '')  
                    subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)
                    product_obj = Product.objects.get(id=product_id)
                    product_obj = Product.objects.get(id=trade_id)
                    product_obj.product_price=cost_per_unit
                    product_obj.product_description=trade_product_description[i]
                    product_obj.category_id=trade_pcategory[i]
                    product_obj.product_name=trade_product_name[i]
                    product_obj.save()
                    if i < len(descriptions):
                        description = descriptions[i]
                        if description != '':
                            is_madatory=1
                    else:
                        description = None
                    product= Product.objects.get(id=product_id)
                    invoiceitem = InvoiceItem(
                        invoice=invoice,  
                        is_trade_product=1,
                        cost_per_unit=cost_per_unit,
                        qty=qty,
                        description=description,
                        product=product_obj,
                        trade_product=product,
                        subtotal=subtotal,
                    )
                    created_by=request.user
                    invoiceitem.save()
                    invoiceitems.append(invoiceitem)

        # for serial_number_value in serial_numbers:
        #     # SerialNumber_obj = SerialNumber.objects.get(id=serial_number_value)
        #     # product_obj = Product.objects.get(id=SerialNumber_obj.product.id)
        #     SerialNumber.objects.filter(id=serial_number_value).update(
        #         # product=product_obj,
        #         customer=customer,
        #         order=invoice.id
        #     )

        quotation.status = 3
        quotation.save()
        print('here')

        invoice =Invoice.objects.latest('id')
    
        invoiceitems = InvoiceItem.objects.filter(invoice=invoice)
        pdf_data = generate_pdfs(invoice, invoiceitems)
        invoice.pdf_file.save(f'{invoice.id}_invoice.pdf', pdf_data)

        # doc_data = generate_docs(invoice, invoiceitems)
        # invoice.doc_file.save(f'{invoice.id}_invoice.docx', doc_data)
        if(invoice.discount_type =='$'): 
            descpercent=invoice.discount/invoice.grandsubtotal*100
            discount_percent_myob= Decimal(descpercent.replace(",", "")) #Decimal(invoice.discount/invoice.grandsubtotal*100) 
        else:
            discount_percent_myob= Decimal(invoice.discount_percent)
        invoice_detail_url = request.build_absolute_uri(reverse('quotation:view_invoice_detail', args=[invoice.id]))
        

        
        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
            # 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.replace(",", "")) #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.replace(",", "")) #Decimal(cost_per_unit_str)
            detail = {
                "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": myob_quotation_account, 
                      },
                "TaxCode":{
                # "UID": "6f5fce5d-604f-49db-9a56-8573e7d2a5ec"
                "UID":myob_quotation_taxcode
                       },
               
                "Item": {
                    "UID": product_obj.uid,
                }

            }
            details.append(detail)


            invoice_data={
                "Number": invoice.id,
                "Date":invoice.invoice_date.strftime('%Y-%m-%dT%H:%M:%S'),
                "SupplierInvoiceNumber": None,
                "Customer": {
                    "UID": customer.myob_uid,
                },

                "ShipToAddress": f'{customer.street} {customer.city} {customer.state} {customer.post_code} {customer.country}',

                "Terms": { 
                    "PaymentIsDue": "DayOfMonthAfterEOM",
                    "DiscountDate": 1,
                    "BalanceDueDate": 30,
                    "DiscountForEarlyPayment": 0,
                    "MonthlyChargeForLatePayment": 0,
                    "DiscountExpiryDate": None,
                    "Discount":float(invoice.discount),
                    "DueDate": invoice.due_date.strftime('%Y-%m-%dT%H:%M:%S'),
                },
                "IsTaxInclusive": False,
                "IsReportable": False,
                "Lines":details,
                "Subtotal": float(invoice.subtotal),
                "Freight": 0,
                "FreightTaxCode": {
                        "UID": myob_quotation_freightaxcode
                    },
                "TotalTax": float(invoice.gst),
                "TotalAmount": float(invoice.total),
                "Category": None,
                "Comment": "",
                "CustomerPurchaseOrderNumber":po_number,
                "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(invoice_data)
        api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item"

        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]
                    
                    api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item/{uid}"
                    print(api_url)

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

                    response = requests.get(api_url, headers=headers,)
                    pdf_data=response.content
                    content = ContentFile(pdf_data)

                    invoice.sale_uid = uid
                    invoice.myob_invoice_pdf.save(f'{invoice.id}_invoice.pdf', content)
                    invoice.flag=0
                    invoice.save()
                 

                if sent_mail == '1':
                    
                    subject = f'EXCITECH Australia - Invoice Details for Invoice ID {invoice.id}'
                    
                    invoice_payment_url = request.build_absolute_uri(reverse('quotation:checkout', args=[invoice.id]))
                    template_data = {'invoice': invoice,'invoice_payment_url':invoice_payment_url}
                    message = render_to_string('pages/invoice/invoice_email_temp.html', template_data)
                    
                    # message += "Please find attached Invoice."
                    # from_email = 'deepakchandrawanshi5050@gmail.com' 
                    from_email = settings.FROM_EMAIL 
                    recipient_email = customer.user.email  
                    email = EmailMessage(subject, message, from_email, [recipient_email])
                    pdf_file_path = invoice.myob_invoice_pdf.path 
                    email.attach_file(pdf_file_path, 'application/pdf')
                    email.content_subtype = 'html'
                    email.send()
                    ci = Customer_Info.objects.filter(customer__id = customer.id,user__is_communication = 1)
                    if ci:
                        for additional_email in  ci:
                            email = EmailMessage(subject, message, from_email, [additional_email.user.email])
                            email.attach_file(pdf_file_path, 'application/pdf')
                            email.content_subtype = 'html'
                            email.send()
                    status = 1
                    invoice.status=status
                    invoice.mailstatus=1

                    invoice.save()
                    messages.success(request, 'Invoice Created Successfully.')
                    return redirect('quotation:list_invoice')
        
                else:
                    messages.success(request, 'Invoice Created Successfully.')
                    return redirect('quotation:list_invoice')
        else:
            messages.error(request, 'Failed To Create Invoice.')
            return redirect('quotation:list_invoice')


    else:
        products = Product.objects.filter(is_active=True)
        customers = Customer.objects.filter(is_active=True,deleted_at__isnull=True)
      
        discounts = Discount.objects.all()
      
        gsts = GST.objects.all()
        pcategory= ProductCategory.objects.filter(is_active=True)
        return render(request, 'pages/invoice/convert_invoice.html', {'quotation': quotation, 'quotationitems': quotationitems, 'products': products,'customers': customers, 'gsts': gsts, 'discounts': discounts,'pcategory':pcategory})

@user_passes_test(lambda u:  is_admin(u) or is_superuser(u))
@login_required
def delete_invoice(request,id):

    invoice = get_object_or_404(Invoice, id=id)
    invoice.deleted_by = request.user
    invoice.soft_delete()
    messages.success(request, 'Invoice Deleted Successfully.')
    return redirect('quotation:list_invoice')

        
  
def generate_pdfs(invoice,invoiceitems):
    template = get_template('pages/invoice/invoice_pdf.html')
    context = {
        'invoice': invoice,
        'invoiceitems': invoiceitems,
    }
    html_content = template.render(context)

    pdf_buffer = BytesIO()

   
    pisa.CreatePDF(html_content, dest=pdf_buffer)

    pdf_buffer.seek(0)
    return pdf_buffer

# def generate_docs(invoice,invoiceitems):
#     doc = Document()
#     doc.add_heading('Invoice Details', level=1)
#     if invoice.customer.first_name and invoice.customer.last_name:
#         customer_name = f'Customer: {invoice.customer.first_name} {invoice.customer.last_name}'
#     else:
#         customer_name = f'Customer: {invoice.customer.company_name}'


#     doc.add_paragraph(customer_name)
#     for invoiceitem in invoiceitems:  
#         doc.add_paragraph(f'Product: {invoiceitem.product.product_name}')
#         doc.add_paragraph(f'Quantity: {invoiceitem.qty}')
#         doc.add_paragraph(f'Unit Price: {invoiceitem.cost_per_unit}')
#     doc.add_paragraph(f'Subtotal: {invoice.subtotal}')
#     doc.add_paragraph(f'Discount: {invoice.discount}')
#     doc.add_paragraph(f'GST: {invoice.gst}')
#     doc.add_paragraph(f'Total: { invoice.total}')
 
    
#     doc_buffer = BytesIO()
#     doc.save(doc_buffer)
#     doc_buffer.seek(0)
#     return doc_buffer
    

    
def customer_view_invoice(request, id):
    invoice = get_object_or_404(Invoice, id=id)
    invoiceitems = InvoiceItem.objects.filter(invoice=invoice)
    return render(request, 'customer_view_invoice.html', {'invoice': invoice,'invoiceitems':invoiceitems})


@user_passes_test(lambda u: is_customer(u) or is_admin(u) or is_superuser(u) or is_sales(u))
@login_required
def list_invoice(request):
    customer_id = request.GET.get('customer_id')
    start_date = request.GET.get('start_date')
    end_date = request.GET.get('end_date')
    status = request.GET.get('status')
   
  
    # if is_customer(request.user):
    #     customer = Customer.objects.get(customer=request.user.id)
    #     invoices = Invoice.objects.filter(customer=customer.id, deleted_at__isnull=False)
    
    if is_admin(request.user) and is_sales(request.user):
        invoices = Invoice.objects.filter(deleted_by__isnull=True).order_by('-created_at')
      
        # 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()
        
        
        # Apply additional filters based on user input
        if customer_id:
            invoices = Invoice.objects.filter(customer__id=customer_id, deleted_by__isnull=True).order_by('-created_at')
            # customer_name1=customer_name.replace(' ','')
            # invoices = Invoice.objects.annotate(name=Concat('customer__first_name', 
            #   Value(''), 'customer__last_name', output_field=CharField())).filter(Q(name__icontains=customer_name1) | Q(customer__company_name__icontains=customer_name) )
        if start_date:
            invoices = invoices.filter(invoice_date__gte=start_date)
        if end_date:
            invoices = invoices.filter(invoice_date__lte=end_date)
        
        if status:
            st=int(status)
            invoices = invoices.filter(status=st)
    
        
    elif   '2' in request.user.get_role and '3' in request.user.get_role or '2' in request.user.get_role:
        quote_by = User.objects.get(id=request.user.id)
     
        invoices = Invoice.objects.filter(quotation__quote_by=quote_by, deleted_by__isnull=True).order_by('-created_at')
        
        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()
        
        
        # Apply additional filters based on user input
        if customer_id:
            invoices = Invoice.objects.filter(customer__id=customer_id,quotation__quote_by=quote_by, deleted_by__isnull=True).order_by('-created_at')
            # customer_name1=customer_name.replace(' ','')
            # invoices = Invoice.objects.annotate(name=Concat('customer__first_name', 
            #   Value(''), 'customer__last_name', output_field=CharField())).filter(Q(name__icontains=customer_name1) | Q(customer__company_name__icontains=customer_name) )
        if start_date:
            invoices = invoices.filter(invoice_date__gte=start_date)
        if end_date:
            invoices = invoices.filter(invoice_date__lte=end_date)
        
        if status:
            st=int(status)
            invoices = invoices.filter(status=st)
        
        
        
       
    else:
        invoices = Invoice.objects.filter(deleted_by__isnull=True).order_by('-created_at')
      
        # 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()
        
        
        # Apply additional filters based on user input
        if customer_id:
            invoices = Invoice.objects.filter(customer__id=customer_id, deleted_by__isnull=True).order_by('-created_at')
            # customer_name1=customer_name.replace(' ','')
            # invoices = Invoice.objects.annotate(name=Concat('customer__first_name', 
            #   Value(''), 'customer__last_name', output_field=CharField())).filter(Q(name__icontains=customer_name1) | Q(customer__company_name__icontains=customer_name) )
        if start_date:
            invoices = invoices.filter(invoice_date__gte=start_date)
        if end_date:
            invoices = invoices.filter(invoice_date__lte=end_date)
        
        if status:
            st=int(status)
            invoices = invoices.filter(status=st)
            
            
    
    
      
    total_records = invoices.count()
    show_pagination = total_records > settings.PAGE_RECORDS


    if show_pagination: 
        page = request.GET.get('page', 1)
        paginator = Paginator(invoices, settings.PAGE_RECORDS)  # Show 10 invoices per page
        try:
            invoices = paginator.page(page)
        except PageNotAnInteger:
            invoices = paginator.page(1)
        except EmptyPage:
            invoices = paginator.page(paginator.num_pages)
    customers = Customer.objects.all()
    return render(request, 'pages/invoice/list.html',{'invoices':invoices,'customers':customers,'cust':Customer.objects.filter(deleted_at__isnull=True)})


def customer_view_quotation(request, id):
    contracts = ContractOfSale.objects.first()
    quotation = get_object_or_404(Quotation, id=id)

      
    if quotation.status == 2  or quotation.status == 4:
        messages.success(request,'Your Response Already Submitted. Thank You.')
        return redirect('thankyou')
    if request.method == "POST":
        signature_text = request.POST.get('signature_text')
        signature_image_data = request.POST.get('signature')
        confirm = request.POST.get('confirm')
        reject = request.POST.get('reject')
       
        if signature_image_data:
           
            image_binary = base64.b64decode(signature_image_data)
            image = Image.open(io.BytesIO(image_binary))

            terms1_accepted = request.POST.get('terms1_accepted')
           
            customer = Customer.objects.get(id=quotation.customer.id)
          
           
            temp_image_path = "temp_signature.png"
            image.save(temp_image_path)
            
           
            signature = Signature.objects.create(
                quotation=quotation,
                customer=customer,
                email=quotation.customer.user.email,
                signature_text=signature_text,
                terms1_accepted=terms1_accepted,
               
            )
            
            signature.signature_image.save('signature.png', File(open(temp_image_path, 'rb')))
            os.remove(temp_image_path)
            print(reject)
            print("deepak")
           
            print(confirm)
            if confirm:
                quotation.status = 2
                quotation.save()
                subject = f'EXCITECH Australia - Quote Signed & Approved for Quote ID {quotation.id}'
            else:
                quotation.status = 4
                quotation.save()
                subject = f'EXCITECH Australia - Quote Signed & Rejected for Quote ID {quotation.id}'

            quotationitems=QuotationItem.objects.filter(quotation=quotation)
            signature = Signature.objects.filter(quotation=quotation).last()

            pdf_data = confirm_generate_pdf(quotation, quotationitems,signature)

          
            quotation_detail_url = request.build_absolute_uri(reverse('quotation:view_quotation_detail', args=[quotation.id]))

            quotation.pdf_file.save(f'{quotation.id}_quote.pdf', pdf_data)

            # doc_data = generate_doc(quotation, quotationitems,signature)
            # quotation.doc_file.save(f'{quotation.id}_doc.docx', doc_data)

           
            confirm=False
            template_data = {'quotation': quotation,'quotation_detail_url':quotation_detail_url,'confirm':confirm}
            message = render_to_string('pages/quotation/quote_email_temp.html', template_data)
            # message += "Please find attached Quote."
            from_email = settings.FROM_EMAIL 
            recipient_email = customer.user.email  #
            email = EmailMessage(subject, message, from_email, [recipient_email])
       
            pdf_file_path = quotation.pdf_file.path 
            email.attach_file(pdf_file_path, 'application/pdf')
            email.content_subtype = 'html'
            email.send()  
            ci = Customer_Info.objects.filter(customer__id = customer.id,user__is_communication = 1)
            if ci:
                for additional_email in  ci:
                    email = EmailMessage(subject, message, from_email, [additional_email.user.email])
                    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('Quote Signed & Approved Notification',f'EXCITECH Australia - Quote Signed & Approved for Quote ID {quotation.id}',[get_registration_token.registration_id])

            if quotation.status == 2:
                messages.success(request, 'Thank You For Accepting The Quote.')
            else:
                messages.success(request, 'Your Response Updated Successfully.')

            #quotation_detail_url = reverse('quotation:view_quotation_detail', args=[quotation.id])
            #return redirect(quotation_detail_url)
            return redirect('thankyou')
        else:
            messages.error(request, 'Signature Is Required.')






    quotationitems = QuotationItem.objects.filter(quotation=quotation)
    if(quotation.status<2):
        return render(request, 'pages/quotation/customer_view_quotation.html',{'quotation': quotation,'quotationitems':quotationitems, 'contracts':contracts})
        
    elif quotation.status == 4 :
        messages.success(request,'Admin Quote Rejected. Thank You.')
        return redirect('thankyou')    
  
    
def confirm_generate_pdf(quotation,quotationitems,signature):
        template = get_template('pages/quotation/quotation_pdf.html')
        context = {
            'quotation': quotation,
            'quotationitems': quotationitems,
            'signature':signature,
        }
        html_content = template.render(context)

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

        pdf_buffer.seek(0)
        return pdf_buffer   
    




def admin_approved_quotation(request, id):
    quotation = get_object_or_404(Quotation, id=id)
    print(quotation.admin_response_mail)
    if quotation.admin_response_mail == 0 : 
        if  quotation.status != 4 :
            if  quotation.status != 5:
                quotation.status = 5
                quotation.admin_response_mail=True
                quotation.save()
                messages.success(request, 'Your Response Updated Successfully.')
                
                return redirect('thankyou')
            elif quotation.status == 5:
                messages.success(request,'You Already Approved  Quote. Thank You.')
                return redirect('thankyou')
        else:
            messages.success(request,'You Already Rejected  Quote. Thank You.')
            return redirect('thankyou')
    else:
        messages.success(request,'You Already Response  Quote. Thank You.')
        return redirect('thankyou')  

  

def admin_rejected_quotation(request, id):
    quotation = get_object_or_404(Quotation, id=id)
    
    if quotation.admin_response_mail == 0 : 
        if  quotation.status != 5:
            if  quotation.status != 4 :
                quotation.status = 4
                quotation.admin_response_mail=True
                quotation.save()
                messages.success(request, 'Your Response Updated Successfully.')
                
                return redirect('thankyou')
            elif quotation.status == 4:
                messages.success(request,'You Already Rejected  Quote. Thank You.')
                return redirect('thankyou')
        else:
            messages.success(request,'You Already Approved  Quote. Thank You.')
            return redirect('thankyou')
    else:
        messages.success(request,'You Already Response  Quote. Thank You.')
        return redirect('thankyou')  




@login_required
def test_pdf(request):
    html_content = render_to_string('quotationtest.html')
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = f'inline; filename="quotation_test.pdf"'
    pisa.CreatePDF(html_content, dest=response)

    return response

@user_passes_test(lambda u: is_customer(u) or is_admin(u) or is_superuser(u) or is_sales(u))
@login_required
def list_quotation(request):


    customer_id = request.GET.get('customer_id')
    start_date = request.GET.get('start_date')
    end_date = request.GET.get('end_date')
    # status = request.GET.get('status')
    if is_admin(request.user) and is_sales(request.user):
        quotations = Quotation.objects.filter(deleted_by__isnull=True).order_by('status', 'created_at')
      
        # 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()
        # dd(start_date)
        
        # Apply additional filters based on user input
        if customer_id:
            quotations = Quotation.objects.filter(customer__id=customer_id,deleted_by__isnull=True).order_by('status', 'created_at')
            # customer_name1=customer_name.replace(' ','')
            # quotations = Quotation.objects.annotate(name=Concat('customer__first_name', 
            #   Value(''), 'customer__last_name', output_field=CharField())).filter(Q(name__icontains=customer_name1) | Q(customer__company_name__icontains=customer_name) )
        if start_date:
            quotations = quotations.filter(quote_date__gte=start_date)
        if end_date:
            quotations = quotations.filter(quote_date__lte=end_date)
        

    elif   '2' in request.user.get_role and '3' in request.user.get_role or '2' in request.user.get_role:
        quote_by = User.objects.get(id=request.user.id)
        quotations = Quotation.objects.filter(quote_by=quote_by, deleted_by__isnull=True).order_by('status', 'created_at')
        
        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()
        # dd(start_date)
        
        # Apply additional filters based on user input
        if customer_id:
            quotations = Quotation.objects.filter(customer__id=customer_id,quote_by=quote_by,deleted_by__isnull=True).order_by('status', 'created_at')
           
        if start_date:
            quotations = quotations.filter(quote_date__gte=start_date)
        if end_date:
            quotations = quotations.filter(quote_date__lte=end_date)

        
    else:
        quotations = Quotation.objects.filter(deleted_by__isnull=True).order_by('status', 'created_at')
      
        # 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()
        # dd(start_date)
        
        # Apply additional filters based on user input
        if customer_id:
            quotations = Quotation.objects.filter(customer__id=customer_id,deleted_by__isnull=True).order_by('status', 'created_at')
            # customer_name1=customer_name.replace(' ','')
            # quotations = Quotation.objects.annotate(name=Concat('customer__first_name', 
            #   Value(''), 'customer__last_name', output_field=CharField())).filter(Q(name__icontains=customer_name1) | Q(customer__company_name__icontains=customer_name) )
        if start_date:
            quotations = quotations.filter(quote_date__gte=start_date)
        if end_date:
            quotations = quotations.filter(quote_date__lte=end_date)

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


    if show_pagination: 
    
        page = request.GET.get('page', 1)
        paginator = Paginator(quotations, settings.PAGE_RECORDS)  # Show 10 quotations per page
        try:
            quotations = paginator.page(page)
        except PageNotAnInteger:
            quotations = paginator.page(1)
        except EmptyPage:
            quotations = paginator.page(paginator.num_pages)
    customers = Customer.objects.all()
    return render(request, 'pages/quotation/list.html',{'quotations':quotations,'customers':customers,'cust':Customer.objects.filter(deleted_at__isnull=True)})
    
    
  
import json    
@login_required
def list_quotation_version(request,id):

    quotation = Quotation.objects.get(id=id)
    quotation_versions=QuotationVersion.objects.filter(original_quote=quotation.id)
   

    return render(request, 'pages/quotation/quote_version_list.html',{'quotation_versions':quotation_versions,'quotation_id':id})
    
    
 


def get_product_id(request):
    selected_product_id = request.GET.get('product_id')
    discount = request.GET.get('discount')
   
    if selected_product_id:
        product= Product.objects.filter(id=selected_product_id)
        price=0
        

        for p in product:
            price=p.product_price
            allow_price_edit=p.category.allow_price_edit
         
            print("pooja",p.category)
            print("pooja", p.category.category_name)
            if p.category.category_name.upper() == 'STORAGE SYSTEMS':
                storage_systems = True
                
              
            else:
                
                storage_systems = False
            print(p.category.category_name.upper())
            if p.category.category_name.upper() == 'TRADE PRODUCT':
                trade_product = True
                print("deepkkkk")
            else:
                trade_product = False
              
              
  
        return JsonResponse({'price': price,'allow_price_edit':allow_price_edit,'storage_systems':storage_systems,'trade_product':trade_product})

    else:
        return JsonResponse({'error': 'No product selected.'})



import re


@user_passes_test(lambda u: is_admin(u) or is_superuser(u) or is_sales(u))
@login_required
def create_quotation(request):
    if request.method == 'POST':
        customer_id = request.POST.get('customer') 
        quote_by_id = request.POST.get('quote_by') 
        quote_date=request.POST.get('quote_date') 
        product_ids = request.POST.getlist('product[]', [])
        qty_values = request.POST.getlist('qty[]', [])
        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')
        quote_title = request.POST.get('quote_title')
        descriptions = request.POST.getlist('description[]', [])
        sent_mail = request.POST.get('sent_mail')
        sent_mail_financial_broker= request.POST.get('sent_mail_financial_broker')
        sent_mail_admin = request.POST.get('sent_mail_admin')
        trade_product_name = request.POST.getlist('tradeproduct[]',[])
        trade_pcategory = request.POST.getlist('pcategory[]',[])
        trade_product_description = request.POST.getlist('descriptiontrade[]',[])
        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="{:.2f}".format(discount)
        else:
            discount_type="%"
            discount_percent= int(request.POST.get('discount'))
            discount = grandsubtotal * ( discount_percent / 100) 
            discount="{:.2f}".format(discount)
        grand_subtotal= grandsubtotal-float(discount)
        gst = grand_subtotal * ( gst_percent / 100)
        gst = "{:.2f}".format(gst)
        quote_date_obj = datetime.strptime(quote_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

        customer = Customer.objects.get(id=customer_id)
        if quote_by_id:
            quote_by_id = quote_by_id
        else:
            quote_by_id = request.user.id   
        quote_by=User.objects.get(id=quote_by_id)

        quotation = Quotation.objects.create(
            customer=customer,
            quote_by=quote_by,
            quote_date=quote_date_obj,
            subtotal= "{:.2f}".format(grandsubtotal),
            discount_percent=discount_percent,
            discount=discount,
            total=total,
            quote_title=quote_title,
            gst_percent=gst_percent,
            gst=gst,
            discount_type=discount_type,
            status=status,
            is_active=is_active,

            created_by=request.user
        )
        is_madatory=0
        quotationitems = []
        for i in range(len(trade_product_name)):
            if trade_product_name[i] == '':
                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.replace(",", "")) #Decimal(cost_per_unit_str)
                print(descriptions)
                if i < len(descriptions):
                    description = descriptions[i]
                    if description != '':
                       is_madatory=1
                else:
                    description = None
                subtotal_str = subtotal_values[i]
                subtotal_str = subtotal_str.replace('$', '').replace(",", "")  
                subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)
                
                
                
                product_obj = Product.objects.get(id=product_id)
                product_obj = Product.objects.get(id=product_id)
                is_trade_product=0
                quotationitem = QuotationItem(
                    quotation=quotation,  
                    product=product_obj,
                    cost_per_unit=cost_per_unit,
                    description=description,
                    qty=qty,
                    subtotal=subtotal,
                    is_trade_product=is_trade_product,
                    created_by=request.user
                )
                quotationitem.save()
                quotationitems.append(quotationitem)
            else:
                t_product_name = trade_product_name[i]
                t_product_discription = trade_product_description[i]
                t_category=trade_pcategory[i]
                t_product_cost_per_unit=cost_per_unit_values[i]
                t_product_cost_per_unit = t_product_cost_per_unit.replace('$', '').replace(",", "") 
                t_product_cost_per_unit = Decimal(t_product_cost_per_unit.replace(",", "")) #Decimal(t_product_cost_per_unit)
                categorie = ProductCategory.objects.get(category_name="TRADE PRODUCT")
                product = Product.objects.create(
                    category_id= t_category, #categorie.id,
                    product_type='used',
                    product_name=t_product_name,
                    product_description= t_product_discription ,
                    product_price=t_product_cost_per_unit,
                    is_active=True,
                    is_product=1,
                    created_by=request.user
                )
                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}/Inventory/Item/"
                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'
                }
                product = Product.objects.latest('id')
                product_data=   {
                        "Number":product.id,
                        "Name": f'{product.product_name}',
                        "IsActive": True,
                        "IsBought" : True,
                        "IsSold" : True,
                        "IsInventoried" : False,
                        "ExpenseAccount" :  { "UID": myob_expense_account },
                        "Description": product.product_description[:255],
                        "CostOfSalesAccount" : { "UID" : myob_cost_of_sales_account,  },
                        "IncomeAccount": { "UID":  myob_income_account, },
                        "AssetAccount" : { "UID" : myob_asset_account, },
                        "BuyingDetails": {
                            "BaseSellingPrice" :float(product.product_price),
                            "ItemsPerBuyingUnit" : 1,
                            "TaxCode": {  "UID": myob_tax_code, }
                        },
                        "SellingDetails": {
                            "BaseSellingPrice" : float(product.product_price),
                            "ItemsPerBuyingUnit" : 1,
                            "TaxCode": { "UID": myob_tax_code, }
                        }
                    }
                print(product_data)
                product_json = json.dumps(product_data)
                response = requests.post(api_url, data=product_json, headers=headers)
                print("-------------------dk--------------------")
                print("Response:", response.status_code, response.content)
                print(response)
                print('2222')
                print(request.headers)
                print("--------------------")
    
                data=response.headers
                if response.status_code == 201:
                    location = data['Location']
                    if location:
                        parts = location.split('/')
                        uid = parts[-1]
                        # product.myob_location = location
                        product.uid = uid
                        product.save()
                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.replace(",", "")) #Decimal(cost_per_unit_str)
                print(descriptions)
                is_madatory=1
                if i < len(descriptions):
                    description = descriptions[i]
                    if description != '':
                       is_madatory=1
                else:
                    description = None
                subtotal_str = subtotal_values[i]
                subtotal_str = subtotal_str.replace('$', '').replace(",", "")  
                subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)
                is_trade_product=1
                trade_product_id = Product.objects.get(id=product_id)
                cost_per_unit=cost_per_unit
                quotationitem = QuotationItem(
                    quotation=quotation,  
                    product=product,
                    cost_per_unit=cost_per_unit,
                    description=description,
                    qty=qty,
                    subtotal=subtotal,
                    trade_product_id = trade_product_id.id,
                    is_trade_product=is_trade_product,
                    created_by=request.user
                )
                quotationitem.save()
                quotationitems.append(quotationitem)
                quotation = Quotation.objects.latest('id')
                quotation.is_trade=1
                quotation.save()

        quotation = Quotation.objects.latest('id')
        quotation.required_send_to_admin=is_madatory
        quotation.save()
        quotationitems = QuotationItem.objects.filter(quotation=quotation)
        pdf_data = generate_pdf(quotation, quotationitems)
        # quotation.pdf_file.save(f'version_old.pdf', pdf_data)
        quotation.pdf_file.save(f'QuoteID_{quotation.id}_1.pdf', pdf_data)
        # doc_data = generate_doc(quotation, quotationitems)
        # quotation.doc_file.save(f'{quotation.id}_quote.docx', doc_data)
        
   
        if sent_mail_admin == '1':

            approved_quotation_details_url = request.build_absolute_uri(reverse('quotation:admin_approved_quotation', args=[quotation.id]))
            rejected_quotation_details_url = request.build_absolute_uri(reverse('quotation:admin_rejected_quotation', args=[quotation.id]))
            subject = f'EXCITECH Australia - Quote Approval Required for Quote ID {quotation.id}'
            confirm=True
            template_data = {'quotation': quotation,'approved_quotation_details_url':approved_quotation_details_url,'confirm':confirm,'rejected_quotation_details_url':rejected_quotation_details_url}
            message = render_to_string('pages/quotation/sent_admin_quote_email_temp.html', template_data)
            # message += "Please find attached Quote."
            from_email = settings.FROM_EMAIL

            admin_users=User.objects.filter(role=1)
            for admin_user in admin_users:
                recipient_email = admin_user.email
                email = EmailMessage(subject, message, from_email, [recipient_email])
                pdf_file_path = quotation.pdf_file.path 
                email.attach_file(pdf_file_path, 'application/pdf')
                email.content_subtype = 'html'
                email.send()
        

            quotation.sent_mail_admin=True
            quotation.save()
     


        if sent_mail_financial_broker == '1':
            
            subject = f'EXCITECH Australia - Finance Required for Quote ID {quotation.id}'
            financial_name=settings.FINANCIAL_BROKER_NAME
            
            template_data = {'quotation': quotation,'financial_name':financial_name}
            message = render_to_string('pages/quotation/finance_need_email_temp.html', template_data)

            # message += "Please find attached Quote."
            from_email = settings.FROM_EMAIL 
            recipient_email = settings.FINANCIAL_BROKER_EMAIL  
            email = EmailMessage(subject, message, from_email, [recipient_email])

            pdf_file_path = quotation.pdf_file.path 
            email.attach_file(pdf_file_path, 'application/pdf')
            email.content_subtype = 'html'
            email.send()
            quotation.email_to_financial_broker=True

            quotation.save()


        if sent_mail == '1':

            quotation_detail_url = request.build_absolute_uri(reverse('quotation:view_quotation_detail', args=[quotation.id]))
            subject = f'EXCITECH Australia - Quote Confirmation Required for Quote ID {quotation.id}'
            confirm=True
            template_data = {'quotation': quotation,'quotation_detail_url':quotation_detail_url,'confirm':confirm}
            message = render_to_string('pages/quotation/quote_email_temp.html', template_data)
            # message += "Please find attached Quote."
            from_email = settings.FROM_EMAIL
            
            recipient_email = customer.user.email  # Use the customer's email address
            email = EmailMessage(subject, message, from_email, [recipient_email])

            pdf_file_path = quotation.pdf_file.path 
            email.attach_file(pdf_file_path, 'application/pdf')
            email.content_subtype = 'html'
            email.send()
            ci = Customer_Info.objects.filter(customer__id = customer.id,user__is_communication = 1)
            if ci:
                for additional_email in  ci:
                    email = EmailMessage(subject, message, from_email, [additional_email.user.email])
                    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('Quote Confirmation Notification',f'EXCITECH Australia - Quote Confirmation Required for Quote ID {quotation.id}',[get_registration_token.registration_id])
            
            quotation.status=Quotation.SENTED
            quotation.sent_mail_customer=sent_mail
            quotation.save()
            
            messages.success(request, 'Quote Added Successfully.')
            return redirect('quotation:list_quotation')
        

        else:
            messages.success(request, 'Quote Added Successfully.')
            return redirect('quotation:list_quotation')
    else:
        products = Product.objects.filter(is_active=True,is_product=0)
        customers = Customer.objects.filter(is_active=True,deleted_at__isnull=True).order_by('first_name')
        quote_bys=User.objects.filter((Q(role=1) | Q(role=2) ) & Q(deleted_at__isnull=True)).distinct()
        quotations = Quotation.objects.all()
        discounts = Discount.objects.all()

        gsts = GST.objects.all()
        pcategory= ProductCategory.objects.filter(is_active=True)
        return render(request, 'pages/quotation/create.html', {'products': products,'pcategory':pcategory, 'customers': customers,'quote_bys':quote_bys,'quotations': quotations,'gsts':gsts,'discounts':discounts})


@user_passes_test(lambda u: is_admin(u) or is_superuser(u) or is_sales(u))
@login_required
def sent_quotation_mail_customer(request,id,):
    quotation = get_object_or_404(Quotation, id=id)
    # quotationitem = QuotationItem.objects.filter(quotation=quotation)
    customer = Customer.objects.get(id=quotation.customer.id)
    quotation_detail_url = request.build_absolute_uri(reverse('quotation:view_quotation_detail', args=[quotation.id]))
    subject = f'EXCITECH Australia - Quote Confirmation Required for Quote ID {quotation.id}'
    confirm=True
    template_data = {'quotation': quotation,'quotation_detail_url':quotation_detail_url,'confirm':confirm}
    message = render_to_string('pages/quotation/quote_email_temp.html', template_data)

    # message += "Please find attached Quote."
    
    from_email = settings.FROM_EMAIL
 
    recipient_email = customer.user.email 
   
    email = EmailMessage(subject, message, from_email, [recipient_email])
    
    if email:
       pdf_file_path = quotation.pdf_file.path
       if quotation.manual_quote_pdf:
           manual_quote_pdf_path = quotation.manual_quote_pdf.path
           email.attach_file(manual_quote_pdf_path, 'application/pdf')
       else:
           email.attach_file(pdf_file_path, 'application/pdf')
       email.content_subtype = 'html'
       email.send()
       ci = Customer_Info.objects.filter(customer__id = customer.id,user__is_communication = 1)
       if ci:
           for additional_email in  ci:
               email = EmailMessage(subject, message, from_email, [additional_email.user.email])
               pdf_file_path = quotation.pdf_file.path
               if quotation.manual_quote_pdf:
                   manual_quote_pdf_path = quotation.manual_quote_pdf.path
                   email.attach_file(manual_quote_pdf_path, 'application/pdf')
               else:
                   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('Quote Confirmation Notification',f'EXCITECH Australia - Quote Confirmation Required for Quote ID {quotation.id}',[get_registration_token.registration_id])
       quotation.status=Quotation.SENTED
       quotation.sent_mail_customer=True
       quotation.save()
       
       print("------------------")
       print("send mail",email)
       messages.success(request, 'Mail Sent Successfully.')
       return redirect(request.META.get('HTTP_REFERER', '/'))
    else:
        messages.error(request, 'Failed To Send Mail.')
        return redirect('quotation:list_quotation')
        
@user_passes_test(lambda u: is_admin(u) or is_superuser(u) or is_sales(u))
@login_required
def sent_quotation_mail_admin(request,id,):
    quotation = get_object_or_404(Quotation, id=id)
    # quotationitem = QuotationItem.objects.filter(quotation=quotation)
    customer = Customer.objects.get(id=quotation.customer.id)
    approved_quotation_details_url = request.build_absolute_uri(reverse('quotation:admin_approved_quotation', args=[quotation.id]))
    rejected_quotation_details_url = request.build_absolute_uri(reverse('quotation:admin_rejected_quotation', args=[quotation.id]))
    subject = f'EXCITECH Australia - Quote Confirmation Required for Quote ID {quotation.id}'
    confirm=True
    template_data = {'quotation': quotation,'approved_quotation_details_url':approved_quotation_details_url,'confirm':confirm,'rejected_quotation_details_url':rejected_quotation_details_url}
    message = render_to_string('pages/quotation/sent_admin_quote_email_temp.html', template_data)

    # message += "Please find attached Quote."
    
    from_email = settings.FROM_EMAIL

    admin_users=User.objects.filter(role=1)
    for admin_user in admin_users:
        recipient_email = admin_user.email
        email = EmailMessage(subject, message, from_email, [recipient_email])
        if email:
           pdf_file_path = quotation.pdf_file.path
          
           if quotation.manual_quote_pdf:
               manual_quote_pdf_path = quotation.manual_quote_pdf.path
               email.attach_file(manual_quote_pdf_path, 'application/pdf')
           else:
               email.attach_file(pdf_file_path, 'application/pdf')
           email.content_subtype = 'html'
           email.send()
  
    quotation.status=Quotation.SENTED
    quotation.sent_mail_admin=True
    quotation.save()
    messages.success(request, 'Mail Sent Successfully.')
    return redirect(request.META.get('HTTP_REFERER', '/'))
    # else:
    #     messages.error(request, 'Failed To Send Mail.')
    #     return redirect('quotation:list_quotation')


@user_passes_test(lambda u: is_admin(u) or is_superuser(u) or is_sales(u))
@login_required
def edit_quotation(request,id):
    quotation = Quotation.objects.get(id=id)
    quotationitems = QuotationItem.objects.filter(quotation=quotation)

    if request.method == 'POST':
        # dd(request.POST)
        is_required_send_to_admin=0
        create_version=False
        customer_id = request.POST.get('customer') 
        quote_by_id = request.POST.get('quote_by') 
        quote_date = request.POST.get('quote_date') 
        product_ids = request.POST.getlist('product[]', [])
        product_quote_id = request.POST.getlist('product_quote_id[]', [])
        qty_values = request.POST.getlist('qty[]', [])
        cost_per_unit_values =  request.POST.getlist('cost_per_unit[]', [])
        subtotal_values = request.POST.getlist('subtotal[]', [])
        grandsubtotal = float(request.POST.get('grandsubtotal'))
        quote_title = request.POST.get('quote_title')
        gst_percent =int( request.POST.get('gst'))
        total = request.POST.get('total')
        sent_mail = request.POST.get('sent_mail')
        sent_mail_financial_broker = request.POST.get('sent_mail_financial_broker')
        convert_invoice =  request.POST.get('convert_invoice')
        status = request.POST.get('status')
        delete_list = request.POST.getlist('deleted[]')
        descriptions = request.POST.getlist('description[]', [])
        sent_mail_admin = request.POST.get('sent_mail_admin') 

        trade_product_name = request.POST.getlist('tradeproduct[]',[])
        trade_pcategory = request.POST.getlist('pcategory[]',[])
        trade_product_description = request.POST.getlist('descriptiontrade[]',[])
        trade_ids = request.POST.getlist('trade_id[]',[])
        
        if quotation.pdf_file:
            old_pdf_path = quotation.pdf_file.path
            if os.path.exists(old_pdf_path):
                os.remove(old_pdf_path)
        
        # if sent_mail_admin:
        #     sent_mail_admin=sent_mail_admin
        #     admin_response_mail=0
        # else:
        #   quotation.sent_mail_admin=False
        #   quotation.save()
        # dd(quotation)
        if(request.POST.get('discount_type')=='dollar'):
            discount_type="$"
            discount_percent= 0

            discount = int(re.findall('\d+', request.POST.get('dollar_type'))[0]) 
        else:
            discount_type="%"
            discount_percent= int(request.POST.get('discount'))
            discount = grandsubtotal * ( discount_percent / 100) 
            
        grand_subtotal= grandsubtotal-discount
        discount= "{:.2f}".format(discount)
        gst = "{:.2f}".format(grand_subtotal * ( gst_percent / 100)) 
       
        grand_subtotal="{:.2f}".format(grand_subtotal)
        quote_date_obj = datetime.strptime(quote_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

        if quote_by_id:
            quote_by_id = quote_by_id
        else:
            quote_by_id = request.user.id

        customer = Customer.objects.get(id=customer_id)
        quote_by=User.objects.get(id=quote_by_id)
        if quotation.pdf_file:
            old_pdf_path = quotation.pdf_file.path
            if os.path.exists(old_pdf_path):
                os.remove(old_pdf_path)

        if  delete_list:
            for i in range(len(delete_list)):
                deleted_value = delete_list[i]
                if deleted_value == '0':
                    pass
                else:
                    if QuotationItem.objects.filter(id=deleted_value,is_trade_product = 0):
                        quotationitem = QuotationItem.objects.filter(id=deleted_value).delete()
                    else:
                        qi=QuotationItem.objects.filter(id=deleted_value,is_trade_product = 1)
                        if qi:
                            p=Product.objects.filter(id=qi[0].product.id)
                            if p:
                                Product.objects.filter(id=qi[0].product.id).delete()
                                QuotationItem.objects.filter(id=deleted_value).delete()
        
        quotation_items = []
        is_madatory=0
        for i in range(len(product_ids)):
            if trade_product_name[i] == '':
                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.replace(",", "")) #Decimal(cost_per_unit_str)
                subtotal_str = subtotal_values[i]
                subtotal_str = subtotal_str.replace('$', '').replace(",", "")
                subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)
                if i < len(descriptions):
                    description = descriptions[i]    
                    if  descriptions[i] != '':
                        is_madatory=1
                        is_required_send_to_admin=1
                else:
                    description = None
                product_obj = Product.objects.get(id=product_id)
                is_trade_product=0
                quotationitem = QuotationItem(
                        quotation= quotation,  
                        product=product_obj,
                        description=description,
                        cost_per_unit=cost_per_unit,
                        is_trade_product=is_trade_product,
                        qty=qty,
                        subtotal=subtotal,
                    )
                if product_quote_id[i] != '':
                    quotationitemsexist = QuotationItem.objects.get(quotation=quotation,id=int(product_quote_id[i]))#product=product_obj)
                    if (quotationitemsexist.product.id != int(product_id)) or (int(quotationitemsexist.qty) != int(qty)) or (int(quotationitemsexist.cost_per_unit) != int(cost_per_unit)):
                        create_version=True
                        # print(i)
                    # quotationitemsexist = QuotationItem.objects.get(quotation=quotation,product=product_obj)
                    quotationitemsexist.product=product_obj
                    quotationitemsexist.cost_per_unit=cost_per_unit
                    quotationitemsexist.qty=qty
                    quotationitemsexist.subtotal=subtotal
                    quotationitemsexist.description=description
                    quotationitemsexist.updated_by=request.user
                    quotationitemsexist.is_trade_product=is_trade_product
                    quotationitemsexist.trade_product=None
                    quotationitemsexist.save()
                     
                else:
                    create_version=True
                    # print('else')
                    quotationitem.updated_by=request.user
                    quotationitem.save()
                quotation_items.append(quotationitem)
            else:
                # dd(request.POST)
                trade_id=trade_ids[i]
                if trade_id == 'new':
                    # dd('new')
                    is_required_send_to_admin=1
                    t_product_name = trade_product_name[i]
                    t_product_discription = trade_product_description[i]
                    t_category=trade_pcategory[i]
                    t_product_cost_per_unit=cost_per_unit_values[i]
                    t_product_cost_per_unit = t_product_cost_per_unit.replace('$', '').replace(",", "") 
                    t_product_cost_per_unit = Decimal(t_product_cost_per_unit.replace(",", "")) #Decimal(t_product_cost_per_unit)
                    categorie = ProductCategory.objects.get(category_name="TRADE PRODUCT")
                    product = Product.objects.create(
                        category_id= t_category, #categorie.id,
                        product_type='used',
                        product_name=t_product_name,
                        product_description= t_product_discription ,
                        product_price=t_product_cost_per_unit,
                        is_active=True,
                        is_product=1,
                        created_by=request.user
                    )
                    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}/Inventory/Item/"
                    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'
                    }
                    product = Product.objects.latest('id')
                    product_data=   {
                            "Number":product.id,
                            "Name": f'{product.product_name}',
                            "IsActive": True,
                            "IsBought" : True,
                            "IsSold" : True,
                            "IsInventoried" : False,
                            "ExpenseAccount" :  { "UID": myob_expense_account },
                            "Description": product.product_description[:255],
                            "CostOfSalesAccount" : { "UID" : myob_cost_of_sales_account,  },
                            "IncomeAccount": { "UID":  myob_income_account, },
                            "AssetAccount" : { "UID" : myob_asset_account, },
                            "BuyingDetails": {
                                "BaseSellingPrice" :float(product.product_price),
                                "ItemsPerBuyingUnit" : 1,
                                "TaxCode": {  "UID": myob_tax_code, }
                            },
                            "SellingDetails": {
                                "BaseSellingPrice" : float(product.product_price),
                                "ItemsPerBuyingUnit" : 1,
                                "TaxCode": { "UID": myob_tax_code, }
                            }
                        }
                    print(product_data)
                    product_json = json.dumps(product_data)
                    response = requests.post(api_url, data=product_json, headers=headers)
                    print("-------------------dk--------------------")
                    print("Response:", response.status_code, response.content)
                    print(response)
                    print('2222')
                    print(request.headers)
                    print("--------------------")
        
                    data=response.headers
                    if response.status_code == 201:
                        location = data['Location']
                        if location:
                            parts = location.split('/')
                            uid = parts[-1]
                            # product.myob_location = location
                            product.uid = uid
                            product.save()
                    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.replace(",", "")) #Decimal(cost_per_unit_str)
                    print(descriptions)
                    is_madatory=1
                    if i < len(descriptions):
                        description = descriptions[i]
                        if description != '':
                           is_madatory=1
                    else:
                        description = None
                    subtotal_str = subtotal_values[i]
                    subtotal_str = subtotal_str.replace('$', '').replace(",", "")  
                    subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)
                    is_trade_product=1
                    trade_product_id = Product.objects.get(id=product_id)
                    cost_per_unit=cost_per_unit
                    quotationitem = QuotationItem(
                        quotation=quotation,  
                        product= product,
                        cost_per_unit=cost_per_unit,
                        description=description,
                        qty=qty,
                        subtotal=subtotal,
                        trade_product_id = trade_product_id.id,
                        is_trade_product=is_trade_product,
                        created_by=request.user
                    )
                    quotationitem.save()
                    quotation_items.append(quotationitem)
                    quotation = Quotation.objects.latest('id')
                    quotation.is_trade=1
                    quotation.save()
                else:
                    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.replace(",", "")) #Decimal(cost_per_unit_str)
                    subtotal_str = subtotal_values[i]
                    subtotal_str = subtotal_str.replace('$', '').replace(",", "")
                    subtotal = Decimal(subtotal_str.replace(",", "")) #Decimal(subtotal_str)
                    if i < len(descriptions):
                        description = descriptions[i]
                        is_madatory=1
                        quotation.required_send_to_admin=1
                    else:
                        description = None
                    product_obj = Product.objects.get(id=trade_id)
                    product_obj.product_price=cost_per_unit
                    product_obj.product_description=trade_product_description[i]
                    product_obj.category_id=trade_pcategory[i]
                    product_obj.product_name=trade_product_name[i]
                    product_obj.save()
                    product= Product.objects.get(id=product_id)
                    # update product to myob
                    
                    # dd(product_obj)
                    
                    quotationitem = QuotationItem(
                            quotation= quotation,  
                            product=product,
                            description=description,
                            cost_per_unit=cost_per_unit,
                            is_trade_product=1,
                            trade_product=product_obj,
                            qty=qty,
                            subtotal=subtotal,
                        )
                    if product_quote_id[i] != '':
                        quotationitemsexist = QuotationItem.objects.get(quotation=quotation,id=int(product_quote_id[i]))#product=product_obj)
                        if (quotationitemsexist.product.id != int(product_id)) or (int(quotationitemsexist.qty) != int(qty)) or (int(quotationitemsexist.cost_per_unit) != int(cost_per_unit)):
                            create_version=True
                            # print(i)
                        # quotationitemsexist = QuotationItem.objects.get(quotation=quotation,product=product_obj)
                        quotationitemsexist.product=product
                        quotationitemsexist.cost_per_unit=cost_per_unit
                        quotationitemsexist.qty=qty
                        quotationitemsexist.subtotal=subtotal
                        quotationitemsexist.is_trade_product=1
                        quotationitemsexist.trade_product=product_obj
                        quotationitemsexist.description=description
                        quotationitemsexist.updated_by=request.user
                        quotationitemsexist.save()
                         
                    else:
                        create_version=True
                        # print('else')
                        quotationitem.updated_by=request.user
                        quotationitem.save()
                    quotation_items.append(quotationitem)
                    
        if quotation.pdf_file:
            old_pdf_path = quotation.pdf_file.path
            if os.path.exists(old_pdf_path):
                os.remove(old_pdf_path)          

        # dd('here')
        # if (Decimal(quotation.total) != Decimal(total)) and ( quotation.status == 1):
        latest_version = QuotationVersion.objects.filter(original_quote=quotation).order_by('-version_number').first() 
        version_old = 1 if latest_version is None else latest_version.version_number + 1
        if create_version == True and ( quotation.status == 1):
            version_old=int(version_old)+1
            latest_version = QuotationVersion.objects.filter(original_quote=quotation).order_by('-version_number').first()  
            new_version_number = 1 if latest_version is None else latest_version.version_number + 1
            quotation_version = QuotationVersion.objects.create(
                original_quote=quotation,
                customer=quotation.customer,
                quote_by=quotation.quote_by, 
                quote_date=quotation.quote_date,
                subtotal=quotation.subtotal, 
                discount_percent=quotation.discount_percent,
                discount=quotation.discount,
                discount_type=quotation.discount_type,
                total=quotation.total, 
                gst_percent=quotation.gst_percent,
                pdf_file=quotation.pdf_file,
                gst=quotation.gst,
                status=quotation.status,
                is_active=quotation.is_active,
                quote_title=quotation.quote_title,
             
                version_number=new_version_number)
            quotation.status = status
            quotation.sent_mail_admin=0
            quotation.admin_response_mail=0
            quotation.sent_mail_customer=0
        email_to_financial_broker_status = quotation.email_to_financial_broker      
        quotation.customer = customer
        quotation.quote_by = quote_by
        quotation.quote_date = quote_date_obj 
        quotation.subtotal = grand_subtotal
        quotation.discount_percent=discount_percent
        quotation.discount = discount
        quotation.discount_type=discount_type
        quotation.total = total
        quotation.gst_percent=gst_percent
        quotation.gst=gst
        quotationitemstradecount = QuotationItem.objects.filter(quotation=quotation,is_trade_product=1).count()
        if quotationitemstradecount > 0:
            quotation.is_trade = 1
            
        else:
            quotation.is_trade = 0
            quotation.sent_mail_admin=0
            quotation.admin_response_mail=0
        quotation.is_active = is_active
        quotation.quote_title=quote_title
        quotation.updated_by=request.user
        quotation.status=Quotation.CREATED
        quotation.save()
        
        
        # Quotation.objects.filter(status__in=statuses)
        quotation = Quotation.objects.get(id=quotation.id)
        # dd(is_required_send_to_admin)
        quotation.required_send_to_admin=is_required_send_to_admin
        quotation.save()
        if quotation.pdf_file:
            old_pdf_path = quotation.pdf_file.path
            if os.path.exists(old_pdf_path):
                os.remove(old_pdf_path) 
        
        quotationitems = QuotationItem.objects.filter(quotation=quotation)
        pdf_data = generate_pdf(quotation, quotationitems)
        # quotation.pdf_file.save(f'quote_{quotation.id}_version_{quotation.version_number}.pdf', pdf_data)

        quotation.pdf_file.save(f'QuoteID_{quotation.id}_{version_old}.pdf', pdf_data)
        # doc_data = generate_doc(quotation, quotationitems)
        # quotation.doc_file.save(f'{quotation.id}_quote.docx', doc_data)
        
        print('done5570');
        
        # if quotation.pdf_file:
        #     old_pdf_path = quotation.pdf_file.path
        #     if os.path.exists(old_pdf_path):
        #         os.remove(old_pdf_path) 
        print('done5576');     
        # if sent_mail_financial_broker == '1' or (create_version == True and email_to_financial_broker_status == True):
        if sent_mail_financial_broker == '1':

            subject = f'EXCITECH Australia - Finance Required for Quote ID {quotation.id}'
            financial_name=settings.FINANCIAL_BROKER_NAME
            
            template_data = {'quotation': quotation,'financial_name':financial_name}
            message = render_to_string('pages/quotation/finance_need_email_temp.html', template_data)
            # message += "Please find attached Quote."
            from_email = settings.FROM_EMAIL 
            recipient_email = settings.FINANCIAL_BROKER_EMAIL  
            email = EmailMessage(subject, message, from_email, [recipient_email])

            

            pdf_file_path = quotation.pdf_file.path 
            email.attach_file(pdf_file_path, 'application/pdf')
            email.content_subtype = 'html'
            email.send()
            quotation.email_to_financial_broker=True

            quotation.save()
            
        print('done5600');   
        print(sent_mail_admin);
            
        if sent_mail_admin == '1':
            print('5604');

            approved_quotation_details_url = request.build_absolute_uri(reverse('quotation:admin_approved_quotation', args=[quotation.id]))
            rejected_quotation_details_url = request.build_absolute_uri(reverse('quotation:admin_rejected_quotation', args=[quotation.id]))
            subject = f'EXCITECH Australia - Quote Approval Required for Quote ID {quotation.id}'
            confirm=True
            template_data = {'quotation': quotation,'approved_quotation_details_url':approved_quotation_details_url,'confirm':confirm,'rejected_quotation_details_url':rejected_quotation_details_url}
            message = render_to_string('pages/quotation/sent_admin_quote_email_temp.html', template_data)
            # message += "Please find attached Quote."
            from_email = settings.FROM_EMAIL

            admin_users=User.objects.filter(role=1)
            for admin_user in admin_users:
                recipient_email = admin_user.email
                email = EmailMessage(subject, message, from_email, [recipient_email])
    
                pdf_file_path = quotation.pdf_file.path 
                email.attach_file(pdf_file_path, 'application/pdf')
                email.content_subtype = 'html'
                email.send()

            quotation.sent_mail_admin=True
            # quotation.sent_mail_admin=0
            quotation.admin_response_mail=0
            quotation.sent_mail_customer=0
            quotation.save()
         
           
        print('done5627');
        if sent_mail == '1':

            quotation_detail_url = request.build_absolute_uri(reverse('quotation:view_quotation_detail', args=[quotation.id]))
            subject = f'EXCITECH Australia - Quote Confirmation Required for Quote ID {quotation.id}'
            confirm=True
            template_data = {'quotation': quotation,'quotation_detail_url':quotation_detail_url,'confirm':confirm}
            message = render_to_string('pages/quotation/quote_email_temp.html', template_data)
            # message += "Please find attached Quote."
            from_email = settings.FROM_EMAIL
            
            recipient_email = customer.user.email  # Use the customer's email address
            email = EmailMessage(subject, message, from_email, [recipient_email])
            pdf_file_path = quotation.pdf_file.path 
            email.attach_file(pdf_file_path, 'application/pdf')
            email.content_subtype = 'html'
            email.send()
            ci = Customer_Info.objects.filter(customer__id = customer.id,user__is_communication = 1)
            if ci:
                for additional_email in  ci:
                    email = EmailMessage(subject, message, from_email, [additional_email.user.email])
                    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.id)
            # sendPush('Quote Confirmation Notification',f'EXCITECH Australia - Quote Confirmation Required for Quote ID {quotation.id}',[get_registration_token.registration_id])
            
            
            quotation.status=Quotation.SENTED
            quotation.sent_mail_customer=sent_mail
            quotation.save()
            print('done5658');
            messages.success(request, 'Quote Updated Successfully.')
            return redirect('quotation:list_quotation')
        

        else:
            print('done5664');
            messages.success(request, 'Quote Updated Successfully.')
            return redirect('quotation:list_quotation')

    else:
        
        products = Product.objects.filter(is_active=True,is_product=0)
        discounts = Discount.objects.all()
        customers = Customer.objects.filter(is_active=True,deleted_at__isnull=True).order_by('first_name')
        quote_bys=User.objects.filter((Q(role=1) | Q(role=2) ) & Q(deleted_at__isnull=True)).distinct()
        gsts = GST.objects.all()
        pcategory= ProductCategory.objects.filter(is_active=True)
        return render(request, 'pages/quotation/edit.html', {'quotation': quotation, 'quotationitems': quotationitems, 'products': products,'pcategory':pcategory, 'customers': customers,'quote_bys': quote_bys,'gsts': gsts, 'discounts': discounts})

def generate_pdf(quotation,quotationitems):
    template = get_template('pages/quotation/quotation_pdf.html')
    contracts = ContractOfSale.objects.first()
    context = {
        'quotation': quotation,
        'quotationitems': quotationitems,
        'contracts':contracts
    }
    html_content = template.render(context)

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

    pdf_buffer.seek(0)
    return pdf_buffer
    
def generate_pdfTest(request):
    quotation = Quotation.objects.latest('id')
    quotationitems = QuotationItem.objects.filter(quotation=quotation)
    template = get_template('pages/quotation/quotation_pdf.html')
    contracts = ContractOfSale.objects.first()
    Nexa_Heavy = os.path.join(settings.BASE_DIR, "assets/css/Nexa-Font-Family/TTF/Nexa-Heavy.ttf")
    Nexa_Bold = os.path.join(settings.BASE_DIR, "assets/css/Nexa-Font-Family/TTF/Nexa-Bold.ttf")
    Nexa_Book = os.path.join(settings.BASE_DIR, "assets/css/Nexa-Font-Family/TTF/Nexa-Book.ttf")
    Nexa_Regular = os.path.join(settings.BASE_DIR, "assets/css/Nexa-Font-Family/TTF/Nexa-Regular.ttf")
    Nexa_Black = os.path.join(settings.BASE_DIR, "assets/css/Nexa-Font-Family/TTF/Nexa-Black.ttf")
    Nexa_Light = os.path.join(settings.BASE_DIR, "assets/css/Nexa-Font-Family/TTF/Nexa-Light.ttf")
    
    # dd(Nexa_Heavy)
    context = {
        'quotation': quotation,
        'quotationitems': quotationitems,
        'contracts':contracts,
        'Nexa_Heavy' : Nexa_Heavy,
        'Nexa_Bold' : Nexa_Bold,
        'Nexa_Book' : Nexa_Book,
        'Nexa_Regular' : Nexa_Regular,
        'Nexa_Black' : Nexa_Black,
        'Nexa_Light' : Nexa_Light
    }
    html_content = template.render(context)

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

    # pdf_buffer.seek(0)
    # return pdf_buffer
    pisa_status = pisa.CreatePDF(html_content, dest=pdf_buffer)

    if pisa_status.err:
        return HttpResponse("Error generating PDF", status=500)

    response = HttpResponse(pdf_buffer.getvalue(), content_type='application/pdf')
    # To display inline in browser:
    response['Content-Disposition'] = 'inline; filename="quotation.pdf"'
    # If you want to force download instead, use:
    # response['Content-Disposition'] = 'attachment; filename="quotation.pdf"'

    return response

@login_required
def sent_quotation_mail_financial_broker(request,id):
    quotation = get_object_or_404(Quotation, id=id)
    # quotationitem = QuotationItem.objects.filter(quotation=quotation)
    customer = Customer.objects.get(id=quotation.customer.id)
    quotation_detail_url = request.build_absolute_uri(reverse('quotation:view_quotation_detail', args=[quotation.id]))
    subject = f'EXCITECH Australia - Finance Required for Quote ID {quotation.id}'
    financial_name=settings.FINANCIAL_BROKER_NAME
    
    template_data = {'quotation': quotation,'financial_name':financial_name}
    message = render_to_string('pages/quotation/finance_need_email_temp.html', template_data)
    # message += "Please find attached Quote."
    
  
    from_email = settings.FROM_EMAIL 
    recipient_email = settings.FINANCIAL_BROKER_EMAIL
    email = EmailMessage(subject, message, from_email, [recipient_email])

    if email:
       
       pdf_file_path = quotation.pdf_file.path
      
       if quotation.manual_quote_pdf:
           manual_quote_pdf_path = quotation.manual_quote_pdf.path
           email.attach_file(manual_quote_pdf_path, 'application/pdf')
       else:
           email.attach_file(pdf_file_path, 'application/pdf')
       email.content_subtype = 'html'
       email.send()
       quotation.email_to_financial_broker=True
       quotation.save()
       messages.success(request, 'Mail Sent Successfully.')
       return redirect(request.META.get('HTTP_REFERER', '/'))
    else:
        messages.error(request, 'Failed To Send Mail.')
        return redirect('quotation:list_quotation')


@user_passes_test(lambda u: is_admin(u) or is_superuser(u) )
@login_required
def delete_quotation(request,id):

    quotation = get_object_or_404(Quotation, id=id)
    quotation.deleted_by = request.user
    quotation.soft_delete()
    messages.success(request, 'Quote Deleted Successfully.')
    return redirect('quotation:list_quotation')

def edit_contract(request,id):
    contract = get_object_or_404(ContractOfSale, id=id)
    if request.method == 'POST':
        content = request.POST.get('content')
        is_active=request.POST.get('is_active')
        contract.is_active=is_active
        contract.content = content
        contract.updated_by = request.user
        contract.save()

        messages.success(request, 'Contract For Sale Updated Successfully.')

        return redirect('quotation:view_contract')
    return render(request,'pages/contract_of_sale/edit.html',{'contract':contract})

def view_contract(request):
    contracts = ContractOfSale.objects.first()

    return render(request,'pages/contract_of_sale/view.html',{'contracts':contracts})
    
def youtube_authenticate():
    creds = None
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', settings.SCOPES)
            creds = flow.run_local_server(port=0)
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)
    return build('youtube', 'v3', credentials=creds)

def upload_video_to_youtube(title, description, video_file_path):
    youtube = youtube_authenticate()
    body = {
        'snippet': {
            'title': title,
            'description': description,
            'tags': ['tag1', 'tag2'],
            'categoryId': '22'
        },
        'status': {
            'privacyStatus': 'public'
        }
    }

    media_body = MediaFileUpload(video_file_path, chunksize=-1, resumable=True)
    request = youtube.videos().insert(
        part='snippet,status',
        body=body,
        media_body=media_body
    )
    response = request.execute()
    return response['id']

def upload_video(request):
    if request.method == 'POST':
        video_file = request.FILES['video_file']
        video_file_path = os.path.join(settings.MEDIA_ROOT, video_file.name)
        with open(video_file_path, 'wb+') as destination:
            for chunk in video_file.chunks():
                destination.write(chunk)
    
        video_id = upload_video_to_youtube('test', 'description', video_file_path)
        youtube_url = f'https://www.youtube.com/watch?v={video_id}'
    
        Service_Request_image = Service_Request_image(service_request_video=youtube_url,service_id=8)
        Service_Request_image.save()
        return HttpResponse('done')
    else:
        return render(request,'pages/notification/testvideoupload.html')

def lead_convert_to_customer(request):    
    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}/Contact/Customer"
    if request.method == 'POST':
        customer_type=form.customer_type = request.POST.get('customer_type')
        first_names = request.POST.getlist('first_name')
        last_names = request.POST.getlist('last_name')
        positions = request.POST.getlist('position')
        emails = request.POST.getlist('email')
        app_access = request.POST.getlist('app_access[]')
        is_sent_creadentials=request.POST.getlist('send_credentials[]')
        is_communication=request.POST.getlist('receive_emails[]')
        primary_email = emails[0]
        phone_numbers = request.POST.getlist('phone1')
        is_active = True                    
        app_accesss=0
        is_sent_creadentials1=0
        is_communication1=0
        app_accesss=1
        user=User.objects.filter(email=primary_email,deleted_at__isnull = False).exists()
        if user:
            user=User.objects.get(email=primary_email,deleted_at__isnull = False)
            # user.is_active=1 if is_active else 0
            user.is_active=is_active
            user.username=primary_email
            user.app_access=1
            user.isprimary=1
            # customer=customer
            user.deleted_at=None
            user.is_communication=1
            user.reset_password=0
            user.email=primary_email
            user.deleted_at=None
            user.save()
        else:
            user = User.objects.create(
                is_active=is_active,
                username=primary_email,
                app_access=1,
                isprimary=1,
                # customer=customer,
                is_communication=1,
                reset_password=0,
                email=primary_email,
            )
        user.role.set('4')
        new_password = ''.join(random.choices(string.ascii_letters + string.digits, k=12))
        user.set_password('Excitech@123')
        user.save()
     

        customer_data = {
            'customer':user,
            'is_active':is_active,
            'street': request.POST.get('street'),
            'city': request.POST.get('city'),
            'state': request.POST.get('state'),
            'post_code': request.POST.get('post_code'),
            'country': request.POST.get('country'),

            'phone2': request.POST.get('phone2'),
            'phone3': request.POST.get('phone3'),
            'fax': request.POST.get('fax'),

            'website': request.POST.get('website'),
            'contact_name': request.POST.get('contact_name'),
            'salutation': request.POST.get('salutation'),
            'abn': request.POST.get('abn'),

            }
        if customer_type == '1':
            customer = Customer(
                user=user,
                is_individual=int(customer_type),
                first_name=first_names[0],
                last_name=last_names[0],
                phone1=phone_numbers[0],
                email=emails[0],
                is_primary=1,
                **customer_data,
                created_by=request.user,
            )
            customer.lead_id=request.POST.get('lead_id') or None
            customer.primary_mail=primary_email
            customer.save()
            if request.POST.get('lead_id'):
                lead = Lead.objects.get(id=request.POST.get('lead_id'))
                lead.customer_id=customer.id
                lead.save()
        else:
            company_name = request.POST.get('company_name')
            customer = Customer(
                user=user,
                is_individual=int(customer_type),
                company_name=company_name,
                first_name=first_names[0],
                last_name=last_names[0],
                phone1=phone_numbers[0],
                email=emails[0],
                is_primary=1,
                **customer_data,
                created_by=request.user,
                updated_by=request.user,
            )
            customer.lead_id=request.POST.get('lead_id') or None
            customer.primary_mail=primary_email
            customer.save()
            if request.POST.get('lead_id'):
                lead = Lead.objects.get(id=request.POST.get('lead_id'))
                lead.customer_id=customer.id
                lead.save()            
        customer_info = []           
        customers=Customer.objects.filter(created_by=request.user).last()
        if customers.abn  and len(customers.abn ) == 11:
            abnres = f"{customers.abn[:2]} {customers.abn[2:5]} {customers.abn[5:8]} {customers.abn[8:]}"
        else:
            abnres=customers.abn
    
        customer_data={
            "LastName" :customers.last_name,
            "FirstName" : customers.first_name,
           "Addresses" : [
                {
                 "Location" : 1,
            "Street" : customers.street,
            "City" : customers.city,
            "State" : customers.state,
            "PostCode" : customers.post_code,
            "Country" : customers.country,
            "Phone1" : customers.phone1,
            "Phone2" : customers.phone2,
            "Phone3" : customers.phone3,
            "Fax" : customers.fax,
            "Email" : customers.email,
            "Website" : customers.website,
            "ContactName" : customers.contact_name,
            "Salutation" : customers.salutation
                }
            ],
            "IsIndividual" : customers.is_individual,
            "IsActive" : customers.is_active  ,            
            "SellingDetails" : {
            "SaleLayout" : "NoDefault",
            "InvoiceDelivery" : "Print",
            "TaxCode" : {
                "UID": myob_customer_taxcode,
                    "Code" : "GST",
                    "URI": "https://arl2.api.myob.com/accountright/ed1538a2-94c4-4188-81c6-c21ee5bff73c/GeneralLedger/Account/ba60da97-26df-4700-9435-3752f65c2826"  
                    },
            "FreightTaxCode" : {
                    "UID": myob_customer_freightaxcode,
                    "Code" : "GST",
                    "URI": "https://arl2.api.myob.com/accountright/ed1538a2-94c4-4188-81c6-c21ee5bff73c/GeneralLedger/Account/ba60da97-26df-4700-9435-3752f65c2826"       
                    },
            "ABN":abnres,
            }
        }

        if not customers.is_individual:
            customer_data["CompanyName"] = customers.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'
        }
        customer_json = json.dumps(customer_data)
        try:
            response = requests.post(api_url, data=customer_json, headers=headers)
            data=response.headers

            if response.status_code == 201:
                location = data['Location']
                if location:
                    parts = location.split('/')
                    uid = parts[-1]
                    customers.myob_location = location
                    customers.myob_uid = uid
                    customers.save()
                    messages.success(request, 'Customer Added Successfully.')
                    return redirect('customer:list')
                else:
                    messages.error(request, 'Location header not found in API response.')
            else:
                messages.error(request, 'Failed To Added Customer.')

        except requests.exceptions.RequestException as e:
            messages.error(request, f'An error occurred: {str(e)}')
     