from django.shortcuts import render, get_object_or_404, redirect
from django.core import signing
from django.urls import reverse
from quotation.models import Quotation,ContractOfSale,QuotationItem,Signature
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,WorkOrder
from leads.models import Lead
from product.models import ProductCategory
from service.models import Service_Request_image,Answer,Service_Signature,Accepted_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
myob_customer_freightaxcode = os.environ.get('MYOB_Customer_FreightTaxCode')
myob_customer_taxcode = os.environ.get('MYOB_Customer_TaxCode')
import random
import string
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,date
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, Case, When
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
from django.http import HttpResponseForbidden

from PyPDF2 import PdfMerger
from django.http import FileResponse
from django.core.files.storage import default_storage
def testapi(request):
    refresh_token(request)
    myobdata = MyobModel.objects.first()
    if not myobdata:
        messages.error(request,'Please First create Access Code')
        return redirect('/myob/initiate-connection')
    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'
    }
    url=f"https://arl2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/GeneralLedger/TaxCode"
    response = requests.get(url, headers=headers)

    if response.status_code == 200:
        data = response.json()
        print(data)
        print(myob_tax_code)
# 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 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"'
    job = Technician_Assigned_Order_Item.objects.get(id=54)
    answer = Answer.objects.filter(technician_assigned_job=job,answer__isnull = False) 
    signature=Service_Signature.objects.get(job=job)
    accepted_images = Accepted_Image.objects.filter(service_signature=signature)
    template = get_template('pages/check_list/checklistStatic_pdf.html')
    context = {
        'job': job,
        'answer': answer,
        'signature':signature,
        'accepted_images':accepted_images,
    }
    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="workorder.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,deleted_at__isnull=True ).order_by('category__category_name')
        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,deleted_at__isnull=True ).order_by('category__category_name')
    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()
    user=User.objects.filter(role=2,id=quotation.quote_by_id)
    if user.exists():  # check if QuerySet has any object
        confirm=False
        template_data = {'quotation': quotation,'confirm':confirm}
        message = render_to_string('pages/quotation/quote_email_temp.html', template_data)
        subject = f'EXCITECH Australia - Quote ID {quotation.id} Approved By Admin'
        from_email = settings.FROM_EMAIL 
        recipient_email = user[0].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()
        # print(user[0].email)
    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.filter(deleted_at__isnull=True ).order_by('category__category_name')
    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:
        unique_registration_ids = set()
        get_registration_token = FCMDevice.objects.filter(user_id=assignment.technician.id,active=True)
        for i in get_registration_token:
            if i.registration_id not in unique_registration_ids:
                # sendPush('Job Parts Received Notification',f'EXCITECH Australia - Job Parts Received Notification-{assignment.id}',[i.registration_id])
                sendPush(f'EXCITECH Australia - Job Parts Received',f'Job #{assignment.id} Parts Received',[i.registration_id])
                unique_registration_ids.add(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:
    #     unique_registration_ids = set()
    #     get_registration_token =  FCMDevice.objects.filter(user_id=assignment.order_item.order.invoice.customer.user.id, active=True)
    #     for i in get_registration_token:
    #         if i.registration_id not in unique_registration_ids:
    #             sendPush(f'EXCITECH Australia - Job Parts Received',f'Job #{assignment.id} Parts Received',[i.registration_id])
    #             unique_registration_ids.add(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": customer_invoice.comment,
                "CustomerPurchaseOrderNumber":customer_invoice.id,
                "ShippingMethod": None,
                "PromisedDate": None,
                "JournalMemo": "Custom comment here",
                "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)
    storage = messages.get_messages(request)
    storage.used = True
    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):
    storage = messages.get_messages(request)
    storage.used = True
    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):
    storage = messages.get_messages(request)
    storage.used = True
    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):
    storage = messages.get_messages(request)
    storage.used = True
    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 canceljob(request):
    # print(request.POST)
    # dd('here')
    storage = messages.get_messages(request)
    storage.used = True
    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)
            serial_number_id=order_item.serial_number.id
            order_item.status = 0
            order_item.work_order_pdf= None
            order_item.serial_number_id= None
            order_item.updated_by = request.user
            order_item.save()
            serial_number = SerialNumber.objects.filter(id=serial_number_id).first()
            # dd(serial_number)
            serial_number.tracking_status = 3
            serial_number.status = 1
            serial_number.invoice_id = None
            serial_number.customer_id = None
            # if status == '3' :
            #     serial_number.arrived_date = datetime.today()
            serial_number.save()
            Technician_Assigned_Order_Item.objects.filter(order_item=order_item).first().delete()
            messages.success(request, 'Job Cancelled Successfully.')
            return redirect('/order/tracking-order-status/')
    return HttpResponseBadRequest("Invalid request")   
    
def update_work_order(request):
    if request.method == 'POST':
        print(request.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 = 12
            order_item.updated_by = request.user
            
            template = get_template('pages/workorder/workorder_pdf.html')
            context = {
                'technician':  User.objects.get(id=request.POST.get('technician')),
                'installation_start_date': request.POST.get('installation_start_date'),
                'Size': request.POST.get('Size'),
                'product': f'{order_item.product.product_name}-{order_item.product.sku}',
                'note': request.POST.get('note'),
                'business_hours_from_time':datetime.strptime(request.POST.get('business_hours_from_time'), "%H:%M").strftime("%-I %p"),# request.POST.get('business_hours_from_time'),
                'business_hours_to_time':datetime.strptime(request.POST.get('business_hours_to_time'), "%H:%M").strftime("%-I %p"),
                'forklift_available' : int(request.POST.get('forklift_available', 0)),
                'order_item' : order_item,
            }
            html_content = template.render(context)
            pdf_buffer = BytesIO()
            pisa.CreatePDF(html_content, dest=pdf_buffer)
            pdf_buffer.seek(0)
            pdf_data=pdf_buffer
            order_item.work_order_pdf.save(f'{order_item_id}_workorder.pdf', pdf_data)
            order_item.save()
            raw_date = request.POST.get("installation_start_date")  # e.g. "08-09-2025"

            if raw_date:
                installation_start_date = datetime.strptime(raw_date, "%d-%m-%Y").date()
            else:
                installation_start_date = None
            work_order, created = WorkOrder.objects.update_or_create(
            order_item=order_item,
            defaults={
                "technician": context['technician'],
                "installation_start_date": installation_start_date,
                "size": context['Size'],
                "note": context['note'],
                "business_hours_from_time": context['business_hours_from_time'],
                "business_hours_to_time": context['business_hours_to_time'],
                "forklift_available": context['forklift_available'],
            }
            )
            serial_number = SerialNumber.objects.filter(id=order_item.serial_number.id).first()
            # dd(serial_number)
            serial_number.tracking_status = 6
    #         if status == '3' :
    #             serial_number.arrived_date = datetime.today()
            serial_number.save()
            messages.success(request, 'Work Order Updated Successfully.')
            return redirect(request.META.get('HTTP_REFERER', '/'))
            # return redirect('/order/tracking-order-status/')
    return HttpResponseBadRequest("Invalid request")   

def update_bill_status(request):
    storage = messages.get_messages(request)
    storage.used = True
    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_job(request,jobid):
    storage = messages.get_messages(request)
    storage.used = True
    if request.method == 'POST':
        installation_date_str = request.POST.get('installation_start_date')
        installation_end_date_str = request.POST.get('installation_end_date')
        comment = request.POST.get('comment')
        installation_time_str = request.POST.get('installation_time')
        
        # Parse dates (assuming your form sends 'YYYY-MM-DD')
        installation_date = datetime.strptime(installation_date_str, '%Y-%m-%d').date()
        installation_end_date = datetime.strptime(installation_end_date_str, '%Y-%m-%d').date()
        
        # Parse time
        installation_time = datetime.strptime(installation_time_str, '%H:%M').time()

        existing_assignment, created = Technician_Assigned_Order_Item.objects.update_or_create(
            id=jobid,
            defaults={
                # 'technician': technician,
                'installation_date': installation_date,
                'installation_end_date': installation_end_date,# Ensure it's a date object
                'installation_time': installation_time,
                'updated_by': request.user,
                'deleted_by': None,
                'comment':comment,
                'deleted_at': None,
            }
        )
        print('deepak',f'ddd-{existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name}')
        # try:
        #     unique_registration_ids = set()
        #     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:
        #         if i.registration_id not in unique_registration_ids:
        #             sendPush(f'EXCITECH Australia - Technician Assigned',f'Technician {existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name} Assigned for JOB #{existing_assignment.id}',[i.registration_id])
        #             unique_registration_ids.add(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, 'Job Rescheduled Successfully.')
        else:
            messages.success(request, 'Job Rescheduled Successfully.')

        # Send email to technician
        send_technician_email(existing_assignment)
        existing_assignment.last_mail_sent_at = timezone.now()
        existing_assignment.save(update_fields=['last_mail_sent_at'])
        return redirect('/technician/assigned/job/list/')
            
@csrf_exempt
def update_tttechnician(request):
    storage = messages.get_messages(request)
    storage.used = True
    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_start_date')
            installation_end_date_str = request.POST.get('installation_end_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_end_date=datetime.strptime(installation_end_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 order_item.order.invoice.total < 0:
                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,
                        'installation_end_date': installation_end_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:
                #     unique_registration_ids = set()
                #     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:
                #         if i.registration_id not in unique_registration_ids:
                #             sendPush(f'EXCITECH Australia - Technician Assigned',f'Technician {existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name} Assigned for JOB #{existing_assignment.id}',[i.registration_id])
                #             unique_registration_ids.add(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)
                existing_assignment.last_mail_sent_at = timezone.now()
                existing_assignment.save(update_fields=['last_mail_sent_at'])
                return redirect('/order/tracking-order-status/')
            if testpayment or total_paid_amount > 0:
                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,
                        'installation_end_date': installation_end_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:
                #     unique_registration_ids = set()
                #     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:
                #         if i.registration_id not in unique_registration_ids:
                #             sendPush(f'EXCITECH Australia - Technician Assigned',f'Technician {existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name} Assigned for JOB #{existing_assignment.id}',[i.registration_id])
                #             unique_registration_ids.add(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)
                existing_assignment.last_mail_sent_at = timezone.now()
                existing_assignment.save(update_fields=['last_mail_sent_at'])
                return redirect('/order/tracking-order-status/')
            # 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,
            #             'installation_end_date': installation_end_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:
            #         unique_registration_ids = set()
            #         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:
            #             if i.registration_id not in unique_registration_ids:
            #                 sendPush(f'EXCITECH Australia - Technician Assigned',f'Technician {existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name} Assigned for JOB #{existing_assignment.id}',[i.registration_id])
            #                 unique_registration_ids.add(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_end_date': installation_end_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:
            #             unique_registration_ids = set()
            #             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:
            #                 if i.registration_id not in unique_registration_ids:
            #                     sendPush(f'EXCITECH Australia - Technician Assigned',f'Technician {existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name} Assigned for JOB #{existing_assignment.id}',[i.registration_id])
            #                     # sendPush('Technician Assigned Notification',f'EXCITECH Australia - Technician Assigned - Job Id: {existing_assignment.id} {existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name}',[i.registration_id])
            #                     unique_registration_ids.add(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_end_date': installation_end_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:
            #                 unique_registration_ids = set()
            #                 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:
            #                     if i.registration_id not in unique_registration_ids:
            #                         # sendPush('Technician Assigned Notification',f'EXCITECH Australia - Technician Assigned - Job Id: {existing_assignment.id} {existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name}',[i.registration_id])
            #                         sendPush(f'EXCITECH Australia - Technician Assigned',f'Technician {existing_assignment.technician.userinfo.first_name} {existing_assignment.technician.userinfo.last_name} Assigned for JOB #{existing_assignment.id}',[i.registration_id])
            #                         unique_registration_ids.add(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
                print(testpaymentcheck)
                print(total)
                print(total_paid_amount)
                if order_item.order.invoice.total < 0:
                     return JsonResponse({'status': 1,'here':'here','total_paid_amount': 0,'payable_amount' : 0,'total':total})
                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):
    current_time = timezone.now()
    time_difference = timedelta(hours=6)

    # Jobs that have never had an email sent & are older than 6 hours
    never_sent_jobs = Technician_Assigned_Order_Item.objects.filter(
        view_by_technician=False,
        last_mail_sent_at__isnull=True,
        created_at__lt=current_time - time_difference
    )

    # Jobs that had an email before but need another after 6 hours
    repeat_jobs = Technician_Assigned_Order_Item.objects.filter(
        view_by_technician=False,
        last_mail_sent_at__lt=current_time - time_difference
    )

    jobs_to_send = list(never_sent_jobs) + list(repeat_jobs)

    for assignment in jobs_to_send:
        send_technician_email(assignment)
        assignment.last_mail_sent_at = current_time
        assignment.save(update_fields=['last_mail_sent_at'])
    # 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_end_date = assignment.installation_end_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,'formatted_end_date':formatted_end_date}
    message = render_to_string('pages/quotation/job_assigned_email_temp.html', template_data)
    try:
        unique_registration_ids = set()
        get_registration_token = FCMDevice.objects.filter(user_id=assignment.technician.id,active=True)
        for i in get_registration_token:
            if i.registration_id not in unique_registration_ids:
                # sendPush('Job Assigned Notification (Installation)',f'EXCITECH Australia - Job Assigned Notification (Installation)- Job Id: {assignment.id}',[i.registration_id])
                sendPush(f'EXCITECH Australia - Installation',f'Job #{assignment.id} Scheduled for Installation',[i.registration_id])
                unique_registration_ids.add(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.filter(deleted_at__isnull=True ).order_by('category__category_name')
        # 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):
    storage = messages.get_messages(request)
    storage.used = True
    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)
    technicians=User.objects.filter(role=3,deleted_at__isnull=True,id__in=Technician_Assigned_Order_Item.objects.filter(
            deleted_by__isnull=True
        ).values_list("technician__id", flat=True))
    # customers = Customer.objects.all()
    customers = Customer.objects.filter(
        id__in=Technician_Assigned_Order_Item.objects.filter(
            deleted_by__isnull=True
        ).values_list("order_item__order__invoice__customer__id", flat=True)
    )
    serial_numbers = SerialNumber.objects.filter(serial_number__isnull = False).filter(
    ~Q(serial_number=''),
    ~Q(serial_number=' ')
    )
    products=Product.objects.filter(deleted_at__isnull=True ).order_by('category__category_name')
    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.filter(deleted_at__isnull=True)
    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.filter(deleted_at__isnull=True ).order_by('category__category_name')
    
    
    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()
    customers = Customer.objects.filter(
            id__in=Order.objects.filter(
                deleted_by__isnull=True
            ).values_list("invoice__customer_id", flat=True)
        )
    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.filter(deleted_at__isnull=True ).order_by('category__category_name')
    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.filter(deleted_at__isnull=True ).order_by('category__category_name')
    #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": customer_invoice.comment,
                        "CustomerPurchaseOrderNumber":customer_invoice.po_number,
                        "ShippingMethod": None,
                        "PromisedDate": None,
                        "JournalMemo": "Custom comment here",
                        "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 convert_to_order(request,id):
    invoice=Invoice.objects.get(id=id)
    existing_order = Order.objects.filter(invoice=invoice).first()
    if not existing_order:
        order = Order.objects.create(invoice=invoice, created_by=request.user)
        order_identifier = 1 
        invoice.status = 4
        invoice.save()
        for item in invoice.invoice_items.all():
            for j in range(item.qty):
                if item.is_trade_product == 1:
                    order_item = Order_Item.objects.create(
                        order=order,
                        order_identifier=order_identifier, 
                        product=item.product,
                        cost_per_unit=item.cost_per_unit,
                        qty=1, 
                        status=4,
                        created_by=request.user,
                        subtotal=item.subtotal,
                        is_trade=1,
                        # latitude=location.latitude,
                        # longitude=location.longitude
                        latitude=37.4219983,
                        longitude=-122.084
                    )
                    order_identifier += 1
                    invoice=order.invoice
                    customer=order.invoice.customer
                    # allocate_serial_number(order_item, invoice, customer)
                else:
                    order_item = Order_Item.objects.create(
                        order=order,
                        order_identifier=order_identifier, 
                        product=item.product,
                        cost_per_unit=item.cost_per_unit,
                        qty=1,  
                        is_trade=0,
                        created_by=request.user,
                        subtotal=item.subtotal,
                        # latitude=location.latitude,
                        # longitude=location.longitude
                        latitude=37.4219983,
                        longitude=-122.084
                    )
                    order_identifier += 1
                    invoice=order.invoice
                    customer=order.invoice.customer
                    # allocate_serial_number(order_item, invoice, customer)
        messages.success(request, 'Order Created Successfully.')
        return redirect('quotation:list_invoice')
    return redirect('quotation:list_invoice')
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": customer_invoice.comment,
                        "CustomerPurchaseOrderNumber":customer_invoice.po_number,
                        "ShippingMethod": None,
                        "PromisedDate": None,
                        "JournalMemo": "Custom comment here",
                        "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)
            if invoice_item.is_trade_product == 1:
                quantities.append(-invoice_item.qty)
            else:
                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" :abs(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": invoice.comment,
                    "ShippingMethod": None,
                    "PromisedDate": None,
                    "JournalMemo": "Custom comment here",
                    "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):
    # dd('here')
    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)
        if invoice_item.is_trade_product == 1:
            quantities.append(-invoice_item.qty)
        else:
            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" :abs(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": invoice.comment,
                "CustomerPurchaseOrderNumber":f"Quote ID: {invoice.po_number}",
                "ShippingMethod": None,
                "PromisedDate": None,
                "JournalMemo": "Custom comment here",
                "BillDeliveryStatus": "Print",
                "AppliedToDate": 0,
                "BalanceDueAmount": 0,
                "Status": "Open",
                "LastPaymentDate": None,
                "Order": None,
                "ForeignCurrency":None
            }
    print(details)
    # dd('here')
    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(response.status_code)
    print(response.text)
    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')
        comment = request.POST.get('comment')
        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,
            comment=comment,
            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.comment = comment
                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}'
        if invoice.quotation:
            subject = f'EXCITECH Australia - Invoice #{invoice.id} for {invoice.quotation.id}'
        else:
            subject = f'EXCITECH Australia - Invoice #{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(deleted_at__isnull=True,is_active=True,is_product=0 ).order_by('category__category_name')
        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)
        if invoice_item.is_trade_product == 1:
            quantities.append(-invoice_item.qty)
        else:
            quantities.append(invoice_item.qty)
        # 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" :abs(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')
        comment = request.POST.get('comment')
        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.comment = comment
        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}'
        if invoice.quotation:
            subject = f'EXCITECH Australia - Invoice #{invoice.id} for {invoice.quotation.id}'
        else:
            subject = f'EXCITECH Australia - Invoice #{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
                if trade_product_name[i] == '':
                    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",
                        },
                        
                    }
                else:
                    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": invoice.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)
            # print(invoice_data)
            # dd('jj')
            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(deleted_at__isnull=True,is_active=True,is_product=0 ).order_by('category__category_name')
        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}'
        if invoice.quotation:
            subject = f'EXCITECH Australia - Invoice #{invoice.id} for {invoice.quotation.id}'
        else:
            subject = f'EXCITECH Australia - Invoice #{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')
        comment = request.POST.get('comment')
        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,
            comment=comment,
            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=discount/grandsubtotal*100
            # discount_percent_myob= Decimal(descpercent.replace(",", "")) #Decimal(invoice.discount/invoice.grandsubtotal*100) 
            discount_percent_myob= Decimal(descpercent)
        else:
            discount_percent_myob= Decimal(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": invoice.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}'
                    if invoice.quotation:
                        subject = f'EXCITECH Australia - Invoice #{invoice.id} for {invoice.quotation.id}'
                    else:
                        subject = f'EXCITECH Australia - Invoice #{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,deleted_at__isnull=True ).order_by('category__category_name')
        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, token):
    signer = signing.TimestampSigner()
    try:
        id = signer.unsign(token, max_age=30*24*60*60)  # 30 days expiry
    except signing.SignatureExpired:
        return HttpResponseForbidden("Link expired.")
    except signing.BadSignature:
        return HttpResponseForbidden("Invalid link.")

    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":
        # dd('here')
        signature_text = request.POST.get('signature_text')
        signature_image_data = request.POST.get('signature')
        confirm = request.POST.get('confirm')
        reject = request.POST.get('reject')
        terms1_accepted = request.POST.get('terms1_accepted')
        if quotation.customer is not None: 
            customer = Customer.objects.get(id=quotation.customer.id)
        else:
            lead= Lead.objects.get(id=quotation.lead.id)
        if signature_image_data:
            image_binary = base64.b64decode(signature_image_data)
            image = Image.open(io.BytesIO(image_binary))
            temp_image_path = "temp_signature.png"
            image.save(temp_image_path)
            
            if quotation.customer is not None: 
                signature = Signature.objects.create(
                    quotation=quotation,
                    customer=customer,
                    lead=None,
                    email=quotation.customer.user.email,
                    signature_text=signature_text,
                    terms1_accepted=terms1_accepted,
                )
            else:
                signature = Signature.objects.create(
                    quotation=quotation,
                    customer=None,
                    lead=lead,
                    email=quotation.lead.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()
            filenamequote=f'{quotation.id}_Signed_Approved_Quote.pdf'
            pdf_data = confirm_generate_pdf(quotation, quotationitems,signature,filenamequote)

          
            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 
            if quotation.customer is not None: 
                recipient_email = customer.user.email  #
            else:
                recipient_email = lead.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()  
            if quotation.customer is not None:
                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() 
            admin_users=User.objects.filter(role=1)
            for admin_user in admin_users:
                print(admin_user)
                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()
            # 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:
                if quotation.customer is not None: 
                    messages.success(request, 'Thank You For Accepting The Quote.')
                else:
                    customer_id = lead_convert_to_customer(request, quotation.lead.id)
                    quotation.customer_id = customer_id
                    quotation.save()
            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:
            if signature_text:
                if quotation.customer is not None: 
                    signature = Signature.objects.create(
                        quotation=quotation,
                        customer=customer,
                        lead=None,
                        email=quotation.customer.user.email,
                        signature_text=signature_text,
                        terms1_accepted=terms1_accepted,
                    )
                else:
                    signature = Signature.objects.create(
                        quotation=quotation,
                        customer=None,
                        lead=lead,
                        email=quotation.lead.email,
                        signature_text=signature_text,
                        terms1_accepted=terms1_accepted,
                    )
                signature.save()
                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()
                filenamequote=f'{quotation.id}_Signed_Approved_Quote.pdf'
                pdf_data = confirm_generate_pdf(quotation, quotationitems,signature,filenamequote)
    
              
                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 
                if quotation.customer is not None: 
                    recipient_email = customer.user.email  #
                else:
                    recipient_email = lead.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()  
                if quotation.customer is not None:
                    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])
                admin_users=User.objects.filter(role=1)
                for admin_user in admin_users:
                    print(admin_user)
                    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()
                if quotation.status == 2:
                    if quotation.customer is not None: 
                        messages.success(request, 'Thank You For Accepting The Quote.')
                    else:
                        customer_id = lead_convert_to_customer(request, quotation.lead.id)
                        quotation.customer_id = customer_id
                        quotation.save()
                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,'token': token})
        
    elif quotation.status == 4 :
        messages.success(request,'Admin Quote Rejected. Thank You.')
        return redirect('thankyou')    
  
    

    




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()
                user=User.objects.filter(role=2,id=quotation.quote_by_id)
                if user.exists():  # check if QuerySet has any object
                    confirm=False
                    template_data = {'quotation': quotation,'confirm':confirm}
                    message = render_to_string('pages/quotation/quote_email_temp.html', template_data)
                    subject = f'EXCITECH Australia - Quote ID {quotation.id} Approved By Admin'
                    from_email = settings.FROM_EMAIL 
                    recipient_email = user[0].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()
                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')
    value = request.GET.get("customer_id")  # e.g. "lead-1151" or "customer-1151"
    lead_id = None
    customer_id = None
    customer = None
    lead = None
    if value:
        if value.startswith("lead-"):
            lead_id = int(value.replace("lead-", ""))
            lead=Lead.objects.get(id=lead_id)
        elif value.startswith("customer-"):
            customer_id = int(value.replace("customer-", ""))
            customer = Customer.objects.get(id=customer_id)
    start_date = request.GET.get('start_date')
    end_date = request.GET.get('end_date')
    status = request.GET.get('status')
    userid =  request.GET.get('userid')
    # status = request.GET.get('status')
    if is_admin(request.user) and is_sales(request.user):
        if request.GET.get("lead") == '1':
            quotations = Quotation.objects.filter(deleted_by__isnull=True,customer_id__isnull=True).order_by( '-created_at')
        else:
            quotations = Quotation.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()
        # dd(start_date)
        
        # Apply additional filters based on user input
        if value:
            if customer_id is not None:
                quotations = Quotation.objects.filter(customer__id=customer_id,deleted_by__isnull=True).order_by( '-created_at')
            else:
                quotations = Quotation.objects.filter(lead__id=lead_id,deleted_by__isnull=True).order_by( '-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)
        if request.GET.get("lead") == '1':
            quotations = Quotation.objects.filter(quote_by=quote_by,deleted_by__isnull=True,customer_id__isnull=True).order_by( '-created_at')
        else:
            quotations = Quotation.objects.filter(quote_by=quote_by,deleted_by__isnull=True).order_by( '-created_at')
        # 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 value:
            if customer_id is not None:
                quotations = Quotation.objects.filter(customer__id=customer_id,quote_by=quote_by,deleted_by__isnull=True).order_by( '-created_at')
            else:
                quotations = Quotation.objects.filter(lead__id=lead_id,quote_by=quote_by,deleted_by__isnull=True).order_by( '-created_at')
                # quotations = Quotation.objects.filter(lead__id=lead_id,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')
        if request.GET.get("lead") == '1':
            quotations = Quotation.objects.filter(deleted_by__isnull=True,customer_id__isnull=True).order_by( '-created_at')
        else:
            quotations = Quotation.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()
        # dd(start_date)
        
        # Apply additional filters based on user input
        if value:
            if customer_id is not None:
                quotations = Quotation.objects.filter(customer__id=customer_id,deleted_by__isnull=True).order_by('status', '-created_at')
            else:
                quotations = Quotation.objects.filter(lead__id=lead_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)

    
    
    if status:
        quotations = quotations.filter(status=status)
    if userid:
        salesuser=User.objects.get(id=userid)
        quotations = quotations.filter(quote_by=salesuser)  # adjust field name accordingly
    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)
    customersold = Customer.objects.all()
    customers = Customer.objects.filter(
            is_active=True, deleted_at__isnull=True
        ).annotate(
            display_name=Case(
                When(
                    is_individual=1,
                    then=Concat('first_name', Value(' '), 'last_name',
                                Value(' (Customer)'), output_field=CharField())
                ),
                default=Concat('company_name', Value(' (Customer)'), output_field=CharField()),
                output_field=CharField()
            ),
            option_value=Concat(Value('customer-'), 'id', output_field=CharField())
        ).values('option_value', 'display_name')
    leads = Lead.objects.filter(customer_id__isnull=True).annotate(
            display_name=Case(
                When(
                    ~Q(company_name=None) & ~Q(company_name=""),
                    then=Concat('company_name', Value(' (Lead)'), output_field=CharField())
                ),
                default=Concat('first_name', Value(' '), 'last_name',
                               Value(' (Lead)'), output_field=CharField()),
                output_field=CharField()
            ),
            option_value=Concat(Value('lead-'), 'id', output_field=CharField())
        ).values('option_value', 'display_name')
    if request.GET.get("lead") == '1':
        lead=1
        combined = leads
    else:
        lead=0
        combined = customers.union(leads).order_by('display_name')
    # statuses = [choice[0] for choice in Quotation.STATUS_CHOICES] 
    statuses = Quotation.STATUS_CHOICES
    users = User.objects.filter( deleted_at__isnull=True, is_superuser=0, role__id=2 ).distinct()
    return render(request, 'pages/quotation/list.html',{'users':users,'quotations':quotations,'customers':customersold,'custold':Customer.objects.filter(deleted_at__isnull=True),'cust':combined,'customer_id':value,'lead':lead,'statuses':statuses})
    
    
  
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
            if p.category.category_name.upper() ==  'OTHER':
                other = True
                
              
            else:
                
                other = 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,'other':other})

    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':
        # sent_mail = request.POST.get("sent_mail")  # will be 'on' or None
        # sent_mail_financial_broker= request.POST.get('sent_mail_financial_broker')
        # sent_mail_admin = request.POST.get('sent_mail_admin')
        # print(sent_mail)
        # print(sent_mail_admin)
        # print(sent_mail_financial_broker)
        # print( request.POST)
        # dd('here')
        # customer_id = request.POST.get('customer') 
        value = request.POST.get("customer")  # e.g. "lead-1151" or "customer-1151"
        lead_id = None
        customer_id = None
        customer = None
        lead = None
        if value.startswith("lead-"):
            lead_id = int(value.replace("lead-", ""))
            lead=Lead.objects.get(id=lead_id)
        elif value.startswith("customer-"):
            customer_id = int(value.replace("customer-", ""))
            customer = Customer.objects.get(id=customer_id)
        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

        
        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,
            lead=lead,
            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
        )
        if lead is not None:
            lead = Lead.objects.filter(id=lead.id).first()
            lead.status = 6
            lead.save()
        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)
                # if product_obj.category.category_name == 'OTHER' or product_obj.category.category_name == 'STORAGE SYSTEMS':
                if product_obj.category.category_name == 'STORAGE SYSTEMS':
                    is_madatory=1
                    # is_required_send_to_admin=1
                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)
        filenamequote=f'QuoteID_{quotation.id}_1.pdf'
        pdf_data = generate_pdf(quotation, quotationitems,filenamequote)
        # # 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 is not None:

            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 is not None :
            
            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 is not None:
            signer = signing.TimestampSigner()
            token = signer.sign(quotation.id)
            quotation_detail_url = request.build_absolute_uri(reverse('quotation:view_quotation_detail', args=[token]))
            # 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
            if customer is not None:
                recipient_email = customer.user.email  # Use the customer's email address
            else:
                recipient_email = lead.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()
            if customer is not None:
                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=True
            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,deleted_at__isnull=True ).order_by('category__category_name')
        customersold = Customer.objects.filter(is_active=True,deleted_at__isnull=True).order_by('first_name')
        quote_bys=User.objects.filter(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)
        customers = Customer.objects.filter(
            is_active=True, deleted_at__isnull=True
        ).annotate(
            display_name=Case(
                When(
                    is_individual=1,
                    then=Concat('first_name', Value(' '), 'last_name',
                                Value(' (Customer)'), output_field=CharField())
                ),
                default=Concat('company_name', Value(' (Customer)'), output_field=CharField()),
                output_field=CharField()
            ),
            option_value=Concat(Value('customer-'), 'id', output_field=CharField())
        ).values('option_value', 'display_name')
        # leads = Lead.objects.annotate(
        #     display_name=Case(
        #         When(
        #             ~Q(company_name=None) & ~Q(company_name=""),
        #             then=Concat('company_name', Value(' (Lead)'), output_field=CharField())
        #         ),
        #         default=Concat('first_name', Value(' '), 'last_name',
        #                       Value(' (Lead)'), output_field=CharField()),
        #         output_field=CharField()
        #     ),
        #     option_value=Concat(Value('lead-'), 'id', output_field=CharField())
        # ).values('option_value', 'display_name')
        leads = Lead.objects.filter(customer_id__isnull=True).annotate(
            display_name=Case(
                When(
                    ~Q(company_name=None) & ~Q(company_name=""),
                    then=Concat('company_name', Value(' (Lead)'), output_field=CharField())
                ),
                default=Concat('first_name', Value(' '), 'last_name',
                               Value(' (Lead)'), output_field=CharField()),
                output_field=CharField()
            ),
            option_value=Concat(Value('lead-'), 'id', output_field=CharField())
        ).values('option_value', 'display_name')
        combined = customers.union(leads).order_by('display_name')
        return render(request, 'pages/quotation/create.html', {'products': products,'pcategory':pcategory, 'combined':combined,'customers': customersold,'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)
    quotationitems = QuotationItem.objects.filter(quotation=quotation)
    signer = signing.TimestampSigner()
    token = signer.sign(quotation.id)
    quotation_detail_url = request.build_absolute_uri(reverse('quotation:view_quotation_detail', args=[token]))
    # 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
    if quotation.customer is not None:
        customer = Customer.objects.get(id=quotation.customer.id)
        recipient_email = customer.user.email 
    else:
        recipient_email = quotation.lead.email 
   
    email = EmailMessage(subject, message, from_email, [recipient_email])
    
    if email:
        quotation.quote_send_date = date.today()
        
        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
        filenamequote=f'QuoteID_{quotation.id}_{version_old}.pdf'
        pdf_data = generate_pdf(quotation, quotationitems,filenamequote)
        quotation.save()
        
        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()
        if quotation.customer is not None:
           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') 
        value = request.POST.get("customer")  # e.g. "lead-1151" or "customer-1151"

        lead_id = None
        customer_id = None
        customer = None
        lead = None
        if value.startswith("lead-"):
            lead_id = int(value.replace("lead-", ""))
            lead=Lead.objects.get(id=lead_id)
        elif value.startswith("customer-"):
            customer_id = int(value.replace("customer-", ""))
            customer = Customer.objects.get(id=customer_id)
        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)
                # if product_obj.category.category_name == 'OTHER' or product_obj.category.category_name == 'STORAGE SYSTEMS':
                if product_obj.category.category_name == 'STORAGE SYSTEMS':
                    is_madatory=1
                    is_required_send_to_admin=1
                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:
                print(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:
                    print('exist')
                    print(request.POST)
                    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
                    print(product_id,qty,cost_per_unit_str,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
                    print(product)
                    # dd(product_obj)
                    
                    quotationitem = QuotationItem(
                            quotation= quotation,  
                            # product=product_obj,
                            trade_product=product,
                            description=description,
                            cost_per_unit=cost_per_unit,
                            is_trade_product=1,
                            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_obj
                        quotationitemsexist.cost_per_unit=cost_per_unit
                        quotationitemsexist.qty=qty
                        quotationitemsexist.subtotal=subtotal
                        quotationitemsexist.is_trade_product=1
                        quotationitemsexist.trade_product=product
                        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,
                lead=quotation.lead,
                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
            quotation.version_number=version_old
            quotation.status=Quotation.CREATED
        email_to_financial_broker_status = quotation.email_to_financial_broker      
        quotation.customer = customer
        quotation.lead = lead
        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)
        filenamequote=f'QuoteID_{quotation.id}_{version_old}.pdf'
        pdf_data = generate_pdf(quotation, quotationitems,filenamequote)
        # # 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 is not None:

            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 is not None :
            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 is not None:
            signer = signing.TimestampSigner()
            token = signer.sign(quotation.id)
            quotation_detail_url = request.build_absolute_uri(reverse('quotation:view_quotation_detail', args=[token]))
            # 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
            if quotation.customer is not None:
                recipient_email = customer.user.email  # Use the customer's email address
            else:
                recipient_email = lead.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()
            if quotation.customer is not None:
                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= True 
            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,deleted_at__isnull=True ).order_by('category__category_name')
        discounts = Discount.objects.all()
        customersold = 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)
        if quotation.customer is not None:
            customer_value = f"customer-{quotation.customer.id}"
        elif quotation.lead is not None:
            customer_value = f"lead-{quotation.lead.id}"
        customers = Customer.objects.filter(
            is_active=True, deleted_at__isnull=True
        ).annotate(
            display_name=Case(
                When(
                    is_individual=1,
                    then=Concat('first_name', Value(' '), 'last_name',
                                Value(' (Customer)'), output_field=CharField())
                ),
                default=Concat('company_name', Value(' (Customer)'), output_field=CharField()),
                output_field=CharField()
            ),
            option_value=Concat(Value('customer-'), 'id', output_field=CharField())
        ).values('option_value', 'display_name')
        leads = Lead.objects.filter(customer_id__isnull=True).annotate(
            display_name=Case(
                When(
                    ~Q(company_name=None) & ~Q(company_name=""),
                    then=Concat('company_name', Value(' (Lead)'), output_field=CharField())
                ),
                default=Concat('first_name', Value(' '), 'last_name',
                               Value(' (Lead)'), output_field=CharField()),
                output_field=CharField()
            ),
            option_value=Concat(Value('lead-'), 'id', output_field=CharField())
        ).values('option_value', 'display_name')
        combined = customers.union(leads).order_by('display_name')
        return render(request, 'pages/quotation/edit.html', {'quotation': quotation, 'customer_value':customer_value,'quotationitems': quotationitems, 'products': products,'pcategory':pcategory, 'customers': customersold,'combined':combined,'quote_bys': quote_bys,'gsts': gsts, 'discounts': discounts})

def generate_pdfTest(request):
    quotation = Quotation.objects.get(id=33)
    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")
    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
def confirm_generate_pdfTestOld(quotation,quotationitems,signature,filenamequote):
        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 confirm_generate_pdfTest(request):
    quotation = Quotation.objects.get(id=32)
    quotationitems = QuotationItem.objects.filter(quotation=quotation)
    signature = Signature.objects.filter(quotation=quotation).last()
    filenamequote=filenamequote=f'32_quote.pdf'
    timestamp = timezone.now().strftime("%Y%m%d_%H%M%S")
    contracts = ContractOfSale.objects.first()
    # print(contracts)
    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")
    skus = [
        item.product.sku
        for item in quotationitems
            if item.product and item.product.sku  # ensures product exists and sku not empty
    ]
   
    sku_string = ", ".join(skus)
    context = {
        'quotation': quotation,
        'quotationitems': quotationitems,
        'signature':signature,
        'skus':sku_string,
        '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
    }
    firstpage = get_template('pages/quotation/quotepdf_first_page.html')
    first_html_content = firstpage.render(context)
    first_pdf_buffer = BytesIO()
    pisa.CreatePDF(first_html_content, dest=first_pdf_buffer)
    first_pdf_buffer.seek(0)
    quotation.first_page_pdf.save(f'QuoteFirstPage_{quotation.id}_{timestamp}.pdf', first_pdf_buffer)
    # return pdf_buffer
    
    secondpage = get_template('pages/quotation/quotepdf_product_table_page.html')
    second_html_content = secondpage.render(context)
    second_pdf_buffer = BytesIO()
    pisa.CreatePDF(second_html_content, dest=second_pdf_buffer)
    second_pdf_buffer.seek(0)
    quotation.producttable_page_pdf.save(f'QuoteSecondPage_{quotation.id}_{timestamp}.pdf', second_pdf_buffer)
    
    
    thirdpage = get_template('pages/quotation/quotepdf_contract_page.html')
    third_html_content = thirdpage.render(context)
    third_pdf_buffer = BytesIO()
    pisa.CreatePDF(third_html_content, dest=third_pdf_buffer)
    third_pdf_buffer.seek(0)
    quotation.contract_page_pdf.save(f'QuoteThirdPage_{quotation.id}_{timestamp}.pdf', third_pdf_buffer)
    
    # pdfs = [
    #     os.path.join(settings.MEDIA_ROOT, "manual_quote_pdfs", f'QuoteFirstPage_{quotation.id}_{timestamp}.pdf'),
    #     os.path.join(settings.MEDIA_ROOT, "manual_quote_pdfs", f'QuoteSecondPage_{quotation.id}_{timestamp}.pdf'),
    #     os.path.join(settings.MEDIA_ROOT, "manual_quote_pdfs", f'QuoteThirdPage_{quotation.id}_{timestamp}.pdf'),
    # ]
    
    pdfs = []

    # 1️⃣ Always include first page
    pdfs.append(
        os.path.join(
            settings.MEDIA_ROOT,
            "manual_quote_pdfs",
            f"QuoteFirstPage_{quotation.id}_{timestamp}.pdf"
        )
    )

    # 2️⃣ Add product detail PDFs from quotation items
    quotationitems = QuotationItem.objects.filter(quotation=quotation)
    for item in quotationitems:
        if item.product and item.product.product_details_pdf:  # not null
            pdfs.append(item.product.product_details_pdf.path)  
            # use .url if needed for web access instead of filesystem

    # 3️⃣ Always include second and third page
    pdfs.extend([
        os.path.join(
            settings.MEDIA_ROOT,
            "manual_quote_pdfs",
            f"QuoteSecondPage_{quotation.id}_{timestamp}.pdf"
        ),
        os.path.join(
            settings.MEDIA_ROOT,
            "manual_quote_pdfs",
            f"QuoteThirdPage_{quotation.id}_{timestamp}.pdf"
        ),
    ])
    pdfs = list(dict.fromkeys(pdfs))
    # print(pdfs)
    merger = PdfMerger()
    for pdf in pdfs:
        merger.append(pdf)

    # Save merged into memory first
    output_stream = BytesIO()
    merger.write(output_stream)
    merger.close()
    output_stream.seek(0)

    # Save into Django storage (MEDIA_ROOT / cloud storage)
    merged_filename = "attachments/merged.pdf"
    quotation.pdf_file.save(filenamequote, ContentFile(output_stream.read()))

    # Rewind for response
    # output_stream.seek(0)  
    return  output_stream
def confirm_generate_pdf(quotation,quotationitems,signature,filenamequote):
    # quotation = Quotation.objects.get(id=33)
    # quotationitems = QuotationItem.objects.filter(quotation=quotation)
    # signature = Signature.objects.filter(quotation=quotation).last()
    timestamp = timezone.now().strftime("%Y%m%d_%H%M%S")
    contracts = ContractOfSale.objects.first()
    # print(contracts)
    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")
    skus = [
        item.product.sku
        for item in quotationitems
            if item.product and item.product.sku  # ensures product exists and sku not empty
    ]
   
    sku_string = ", ".join(skus)
    context = {
        'quotation': quotation,
        'quotationitems': quotationitems,
        'signature':signature,
        'skus':sku_string,
        '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
    }
    firstpage = get_template('pages/quotation/quotepdf_first_page.html')
    first_html_content = firstpage.render(context)
    first_pdf_buffer = BytesIO()
    pisa.CreatePDF(first_html_content, dest=first_pdf_buffer)
    first_pdf_buffer.seek(0)
    quotation.first_page_pdf.save(f'QuoteFirstPage_{quotation.id}_{timestamp}.pdf', first_pdf_buffer)
    # return pdf_buffer
    
    secondpage = get_template('pages/quotation/quotepdf_product_table_page.html')
    second_html_content = secondpage.render(context)
    second_pdf_buffer = BytesIO()
    pisa.CreatePDF(second_html_content, dest=second_pdf_buffer)
    second_pdf_buffer.seek(0)
    quotation.producttable_page_pdf.save(f'QuoteSecondPage_{quotation.id}_{timestamp}.pdf', second_pdf_buffer)
    
    
    thirdpage = get_template('pages/quotation/quotepdf_contract_page.html')
    third_html_content = thirdpage.render(context)
    third_pdf_buffer = BytesIO()
    pisa.CreatePDF(third_html_content, dest=third_pdf_buffer)
    third_pdf_buffer.seek(0)
    quotation.contract_page_pdf.save(f'QuoteThirdPage_{quotation.id}_{timestamp}.pdf', third_pdf_buffer)
    
    # pdfs = [
    #     os.path.join(settings.MEDIA_ROOT, "manual_quote_pdfs", f'QuoteFirstPage_{quotation.id}_{timestamp}.pdf'),
    #     os.path.join(settings.MEDIA_ROOT, "manual_quote_pdfs", f'QuoteSecondPage_{quotation.id}_{timestamp}.pdf'),
    #     os.path.join(settings.MEDIA_ROOT, "manual_quote_pdfs", f'QuoteThirdPage_{quotation.id}_{timestamp}.pdf'),
    # ]
    
    pdfs = []

    # 1️⃣ Always include first page
    pdfs.append(
        os.path.join(
            settings.MEDIA_ROOT,
            "manual_quote_pdfs",
            f"QuoteFirstPage_{quotation.id}_{timestamp}.pdf"
        )
    )

    # 2️⃣ Add product detail PDFs from quotation items
    quotationitems = QuotationItem.objects.filter(quotation=quotation)
    for item in quotationitems:
        if item.product and item.product.product_details_pdf:  # not null
            pdfs.append(item.product.product_details_pdf.path)  
            # use .url if needed for web access instead of filesystem

    # 3️⃣ Always include second and third page
    pdfs.extend([
        os.path.join(
            settings.MEDIA_ROOT,
            "manual_quote_pdfs",
            f"QuoteSecondPage_{quotation.id}_{timestamp}.pdf"
        ),
        os.path.join(
            settings.MEDIA_ROOT,
            "manual_quote_pdfs",
            f"QuoteThirdPage_{quotation.id}_{timestamp}.pdf"
        ),
    ])
    pdfs = list(dict.fromkeys(pdfs))
    # print(pdfs)
    merger = PdfMerger()
    for pdf in pdfs:
        merger.append(pdf)

    # Save merged into memory first
    output_stream = BytesIO()
    merger.write(output_stream)
    merger.close()
    output_stream.seek(0)

    # Save into Django storage (MEDIA_ROOT / cloud storage)
    merged_filename = "attachments/merged.pdf"
    quotation.pdf_file.save(filenamequote, ContentFile(output_stream.read()))

    # Rewind for response
    # output_stream.seek(0)  
    return  output_stream
def generate_pdf(quotation,quotationitems,filenamequote):
    # quotation = Quotation.objects.get(id=33)
    # quotationitems = QuotationItem.objects.filter(quotation=quotation)
    timestamp = timezone.now().strftime("%Y%m%d_%H%M%S")
    contracts = ContractOfSale.objects.first()
    # print(contracts)
    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")
    skus = [
        item.product.sku
        for item in quotationitems
            if item.product and item.product.sku  # ensures product exists and sku not empty
    ]
   
    sku_string = ", ".join(skus)
    context = {
        'quotation': quotation,
        'quotationitems': quotationitems,
        'skus':sku_string,
        '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
    }
    firstpage = get_template('pages/quotation/quotepdf_first_page.html')
    first_html_content = firstpage.render(context)
    first_pdf_buffer = BytesIO()
    pisa.CreatePDF(first_html_content, dest=first_pdf_buffer)
    first_pdf_buffer.seek(0)
    quotation.first_page_pdf.save(f'QuoteFirstPage_{quotation.id}_{timestamp}.pdf', first_pdf_buffer)
    # return pdf_buffer
    
    secondpage = get_template('pages/quotation/quotepdf_product_table_page.html')
    second_html_content = secondpage.render(context)
    second_pdf_buffer = BytesIO()
    pisa.CreatePDF(second_html_content, dest=second_pdf_buffer)
    second_pdf_buffer.seek(0)
    quotation.producttable_page_pdf.save(f'QuoteSecondPage_{quotation.id}_{timestamp}.pdf', second_pdf_buffer)
    
    
    thirdpage = get_template('pages/quotation/quotepdf_contract_page.html')
    third_html_content = thirdpage.render(context)
    third_pdf_buffer = BytesIO()
    pisa.CreatePDF(third_html_content, dest=third_pdf_buffer)
    third_pdf_buffer.seek(0)
    quotation.contract_page_pdf.save(f'QuoteThirdPage_{quotation.id}_{timestamp}.pdf', third_pdf_buffer)
    
    # pdfs = [
    #     os.path.join(settings.MEDIA_ROOT, "manual_quote_pdfs", f'QuoteFirstPage_{quotation.id}_{timestamp}.pdf'),
    #     os.path.join(settings.MEDIA_ROOT, "manual_quote_pdfs", f'QuoteSecondPage_{quotation.id}_{timestamp}.pdf'),
    #     os.path.join(settings.MEDIA_ROOT, "manual_quote_pdfs", f'QuoteThirdPage_{quotation.id}_{timestamp}.pdf'),
    # ]
    
    pdfs = []

    # 1️⃣ Always include first page
    pdfs.append(
        os.path.join(
            settings.MEDIA_ROOT,
            "manual_quote_pdfs",
            f"QuoteFirstPage_{quotation.id}_{timestamp}.pdf"
        )
    )

    # 2️⃣ Add product detail PDFs from quotation items
    quotationitems = QuotationItem.objects.filter(quotation=quotation)
    for item in quotationitems:
        if item.product and item.product.product_details_pdf:  # not null
            pdfs.append(item.product.product_details_pdf.path)  
            # use .url if needed for web access instead of filesystem

    # 3️⃣ Always include second and third page
    pdfs.extend([
        os.path.join(
            settings.MEDIA_ROOT,
            "manual_quote_pdfs",
            f"QuoteSecondPage_{quotation.id}_{timestamp}.pdf"
        ),
        os.path.join(
            settings.MEDIA_ROOT,
            "manual_quote_pdfs",
            f"QuoteThirdPage_{quotation.id}_{timestamp}.pdf"
        ),
    ])
    pdfs = list(dict.fromkeys(pdfs))
    print(pdfs)
    merger = PdfMerger()
    for pdf in pdfs:
        merger.append(pdf)

    # Save merged into memory first
    output_stream = BytesIO()
    merger.write(output_stream)
    merger.close()
    output_stream.seek(0)

    # Save into Django storage (MEDIA_ROOT / cloud storage)
    merged_filename = "attachments/merged.pdf"
    quotation.pdf_file.save(filenamequote, ContentFile(output_stream.read()))

    # Rewind for response
    # output_stream.seek(0)
    return  output_stream
@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 add_quote(request,customer_id):
    products = Product.objects.filter(is_active=True,is_product=0,deleted_at__isnull=True ).order_by('category__category_name')
    customersold = 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)
    customers = Customer.objects.filter(
        is_active=True, deleted_at__isnull=True,id=customer_id
    ).annotate(
        display_name=Case(
            When(
                is_individual=1,
                then=Concat('first_name', Value(' '), 'last_name',
                            Value(' (Customer)'), output_field=CharField())
            ),
            default=Concat('company_name', Value(' (Customer)'), output_field=CharField()),
            output_field=CharField()
        ),
        option_value=Concat(Value('customer-'), 'id', output_field=CharField())
    ).values('option_value', 'display_name')
    
    leads = Lead.objects.filter(
        is_active=True, deleted_at__isnull=True,id=customer_id
    ).annotate(
        display_name=Case(
            When(
                ~Q(company_name=None) & ~Q(company_name=""),
                then=Concat('company_name', Value(' (Lead)'), output_field=CharField())
            ),
            default=Concat('first_name', Value(' '), 'last_name',
                          Value(' (Lead)'), output_field=CharField()),
            output_field=CharField()
        ),
        option_value=Concat(Value('lead-'), 'id', output_field=CharField())
    ).values('option_value', 'display_name')
    
    # combined = customers.union(leads).order_by('display_name')
    if request.GET.get("lead") == '1':
        lead=1
        combined=leads
    else:
        combined=customers
        lead=0
    print(combined)
    return render(request, 'pages/quotation/create.html', {'products': products,'pcategory':pcategory, 'combined':combined,'customers': customersold,'quote_bys':quote_bys,'quotations': quotations,'gsts':gsts,'discounts':discounts,'lead':lead})


def quote_list_by_customer(request,customer_id):
    # customer_id = request.GET.get('customer_id')
    exist_cusomer_id=customer_id
    value = request.GET.get("customer_id")  # e.g. "lead-1151" or "customer-1151"
    lead_id = None
    customer_id = None
    customer = None
    lead = None
    if value:
        if value.startswith("lead-"):
            lead_id = int(value.replace("lead-", ""))
            lead=Lead.objects.get(id=lead_id)
        elif value.startswith("customer-"):
            customer_id = int(value.replace("customer-", ""))
            customer = Customer.objects.get(id=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):
        if request.GET.get("lead") == '1':
            quotations = Quotation.objects.filter(deleted_by__isnull=True,lead__id=exist_cusomer_id).order_by('status', 'created_at')
        else:
            quotations = Quotation.objects.filter(deleted_by__isnull=True,customer__id=exist_cusomer_id).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 value:
            if customer_id is not None:
                quotations = Quotation.objects.filter(customer__id=customer_id,deleted_by__isnull=True).order_by('status', 'created_at')
            else:
                quotations = Quotation.objects.filter(lead__id=lead_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)
        if request.GET.get("lead") == '1':
            quotations = Quotation.objects.filter(quote_by=quote_by, deleted_by__isnull=True,lead__id=exist_cusomer_id).order_by('status', 'created_at')
        else:
            quotations = Quotation.objects.filter(quote_by=quote_by, deleted_by__isnull=True,customer__id=exist_cusomer_id).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 value:
            if customer_id is not None:
                quotations = Quotation.objects.filter(customer__id=customer_id,quote_by=quote_by,deleted_by__isnull=True).order_by('status', 'created_at')
            else:
                quotations = Quotation.objects.filter(lead__id=lead_id,quote_by=quote_by,deleted_by__isnull=True).order_by('status', 'created_at')
                # quotations = Quotation.objects.filter(lead__id=lead_id,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:
        if request.GET.get("lead") == '1':
            quotations = Quotation.objects.filter(deleted_by__isnull=True,lead__id=exist_cusomer_id).order_by('status', 'created_at')
        else:
            quotations = Quotation.objects.filter(deleted_by__isnull=True,customer__id=exist_cusomer_id).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 value:
            if customer_id is not None:
                quotations = Quotation.objects.filter(customer__id=customer_id,deleted_by__isnull=True).order_by('status', 'created_at')
            else:
                quotations = Quotation.objects.filter(lead__id=lead_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)
    customersold = Customer.objects.all()
    customers = Customer.objects.filter(
            is_active=True, deleted_at__isnull=True,id=exist_cusomer_id
        ).annotate(
            display_name=Case(
                When(
                    is_individual=1,
                    then=Concat('first_name', Value(' '), 'last_name',
                                Value(''), output_field=CharField())
                ),
                default=Concat('company_name', Value(''), output_field=CharField()),
                output_field=CharField()
            ),
            option_value=Concat(Value('customer-'), 'id', output_field=CharField())
        ).values('option_value', 'display_name')
    leadold = Lead.objects.all()
    leads = Lead.objects.filter(
            is_active=True, deleted_at__isnull=True,id=exist_cusomer_id
        ).annotate(
            display_name=Case(
                When(
                    is_individual=1,
                    then=Concat('first_name', Value(' '), 'last_name',
                                Value(''), output_field=CharField())
                ),
                default=Concat('company_name', Value(''), output_field=CharField()),
                output_field=CharField()
            ),
            option_value=Concat(Value('lead-'), 'id', output_field=CharField())
        ).values('option_value', 'display_name')
    if request.GET.get("lead") == '1':
        combined = leads
        lead=1
    else:
        combined = customers
        lead=0
    return render(request, 'pages/quotation/list.html',{'quotations':quotations,'customers':customersold,'custold':Customer.objects.filter(deleted_at__isnull=True),'cust':combined,'customer_id':value,'lead':lead})

def lead_convert_to_customer(request,leadid):    
    refresh_token(request)
    myobdata = MyobModel.objects.first()
    lead=Lead.objects.get(id=leadid)
    if lead.customer_id is not None:
        return lead.customer_id
    else:
        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 lead.company_name is not None:
            customer_type= 0
        else:
            customer_type= 1
        first_names = lead.first_name
        last_names = lead.last_name
        positions = None
        emails = lead.email
        app_access = 1
        is_sent_creadentials=0
        is_communication=1
        primary_email = emails
        phone_numbers = lead.work_phone
        is_active = True                    
        
        is_sent_creadentials1=0
        is_communication1=0
       
        user=User.objects.filter(username=primary_email,deleted_at__isnull = True).exists()
        if user:
            cust=Customer.objects.filter(email=primary_email,deleted_at__isnull = True).exists()
            if cust:
                cust=Customer.objects.get(email=primary_email,deleted_at__isnull = True)
                cust.lead=lead
                cust.save()
                return cust.id
        print(user)
        if user:
            user=User.objects.get(email=primary_email,deleted_at__isnull = True)
            # 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': lead.street,
            'city': lead.city,
            'state': lead.state,
            'post_code': lead.post_code,
            'country': lead.country,
    
            'phone2': lead.work_phone,
            'phone3': lead.mobile,
            'fax': None,
    
            'website': None,
            'contact_name': lead.first_name,
            'salutation': None,
            'abn': lead.abn,
    
            }
        if customer_type == 1:
            customer = Customer(
                user=user,
                is_individual=int(customer_type),
                first_name=first_names,
                last_name=last_names,
                phone1=phone_numbers,
                email=emails,
                is_primary=1,
                **customer_data,
                # created_by=request.user,
            )
            customer.lead_id=leadid or None
            customer.primary_mail=primary_email
            customer.save()
            lead.customer_id=customer.id
            lead.status=7
            lead.save()
        else:
            company_name = lead.company_name
            customer = Customer(
                user=user,
                is_individual=int(customer_type),
                company_name=company_name,
                first_name=first_names,
                last_name=last_names,
                phone1=phone_numbers,
                email=emails,
                is_primary=1,
                **customer_data,
                # created_by=request.user,
                # updated_by=request.user,
            )
            customer.lead_id=leadid or None
            customer.primary_mail=primary_email
            customer.save()
        
            lead.customer_id=customer.id
            lead.status=7
            lead.save()            
                  
        customers=Customer.objects.filter(lead_id=leadid).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)
        subject = f'EXCITECH Australia - Your Account Credentials'
        username= primary_email  #user.email
        password="Excitech@123"
        template_data = {'password': password,'username':username}
        message = render_to_string('pages/customer/cust_email_temp.html', template_data)
        # message += "Please find attached Quote."
        from_email = settings.FROM_EMAIL
        recipient_email =primary_email #user.email 
        email = EmailMessage(subject, message, from_email, [recipient_email])
        email.content_subtype = 'html'
        email.send()
        print(email)
        done=1
        if done:
            user.is_sent_creadentials= 1
            user.reset_password=1
            user.save()
        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 customers.id
                else:
                    return customers.id
                    # messages.error(request, 'Location header not found in API response.')
            else:
                return customers.id
                # messages.error(request, 'Failed To Added Customer.')
    
        except requests.exceptions.RequestException as e:
            return customers.id
            # messages.error(request, f'An error occurred: {str(e)}')
    
    