from django.shortcuts import render, get_object_or_404, redirect

import uuid

import time
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,WorkOrderService, 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,Service,Chat
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.db.models import Case, When, Value, CharField, F
from django.db.models.functions import Concat, Lower,Trim
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 ,Max
from django.db.models import CharField, Value, Case, When , Exists, OuterRef
from django.db.models.functions import Concat
from reversion import revisions as reversion
import os
from itertools import zip_longest
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
from dateutil.relativedelta import relativedelta
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 urllib.parse import urlencode
from PyPDF2 import PdfMerger
from django.http import FileResponse
from django.core.files.storage import default_storage
from django.db.models.functions import TruncDate
from technician.technician_api.serializers import(
     ServiceRequestImageSerializer,
     ChatSerializer,
     OrderItemSerializer
    )
from collections import defaultdict
def send_service_customer_sign_email(request,job_id):
    print(job_id)
    job = Technician_Assigned_Order_Item.objects.get(id=job_id)
    # print(job_d)
    subject = f'EXCITECH Australia -Service Job Signature For Job Id: {job.id}'
    # message = f"Hi {job.order_item.order.invoice.customer},<br>"
    # message += "Please find link to make sign."
    token = base64.urlsafe_b64encode(str(job_id).encode()).decode()
    link = f'http://ea.stagingstorm.com:8000/job-signature/{token}/'
    # link='http://ea.stagingstorm.com:8000/job-signature/<int:job_id>/'
    template_data = {'job_id': job_id,'job':job,'link':link}
    message = render_to_string('pages/quotation/servicesignature_email.html', template_data)
    from_email = settings.FROM_EMAIL #job.technician.email # Replace with your email address
    recipient_email ='kiran@beedev.co.in' #job.order_item.order.invoice.customer.email  # Use the customer's email address
    email = EmailMessage(subject, message, from_email, [recipient_email])
    email.content_subtype = "html"
    email.send()
    job.sign_email_cust = 1
    job.sign_email_cust_by = request.user
    job.save()
    return redirect('quotation:technician_assigned_job_list')
    # return render(request,'pages/quotation/reminder_jobs.html',{'technician_assigned_job_lists':technician_assigned_job_lists,'technicians':technicians,'customers':customers,'products':products})   
    
def sendpushtest(request,jobid,type,reg_id):
    job = Technician_Assigned_Order_Item.objects.get(id=jobid)
    sendPush(
            f'EXCITECH Australia - Job #{jobid} Assigned for Service',
            f'Job #69 Assigned for Service',
            [f'{reg_id}'],
            # ['fdVbsugmBkn6neZWo4xM6H:APA91bEqJfSnFZuq-km89q4cJ_DhahKDMPoni2V5BciElU3iQ9LmK5dAT9oDb9htB3xBXJ6P4E0IE-r4laErnjodorTEEpnmMFWN-HvZdkH0P75KV5pog-E'],
            {"job_id": jobid,"type": type,"job_details":job}
        )
def sendReminderEmailForJob(request):
    today_date = date.today()
    five_months_ago = today_date - relativedelta(months=5)
    
    start = timezone.make_aware(
        datetime.combine(five_months_ago, datetime.min.time())
    )
    
    end = timezone.make_aware(
        datetime.combine(five_months_ago, datetime.max.time())
    )
    
    tech = Technician_Assigned_Order_Item.objects.filter(
        job_type=1,
        is_5_month_reminder_sent=False,
        job_complete_datetime__range=(start, end)
    )
    for t in tech:
        t.is_5_month_reminder_sent = True
        t.reminder_5_month_datetime = timezone.now()
        # ---------- MAIN TECHNICIAN ----------
        if t.technician:
            if not t.technician.is_active and t.technician.replacement_technician:
                t.replace_technician = t.technician.replacement_technician
    
        # ---------- SECONDARY TECHNICIAN ----------
        if t.secondary_technician:
            if not t.secondary_technician.is_active and t.secondary_technician.replacement_technician:
                t.replace_secondary_technician = t.secondary_technician.replacement_technician

        t.save()
        template_data = {'quotation': t}
        message = render_to_string('pages/quotation/email_reminder5Monthsand11Months.html', template_data)
        subject = f'EXCITECH Australia - EXCITECH Australia - Service Reminder - 5 months.'
        from_email = settings.FROM_EMAIL 
        recipient_email = 'hari@beedev.co.in'
        email = EmailMessage(subject, message, from_email, [recipient_email])
        email.content_subtype = 'html'
        email.send()
        
    eleven_months_ago = today_date - relativedelta(months=11)
    start = timezone.make_aware(
        datetime.combine(eleven_months_ago, datetime.min.time())
    )
    
    end = timezone.make_aware(
        datetime.combine(eleven_months_ago, datetime.max.time())
    )
    
    tech = Technician_Assigned_Order_Item.objects.filter(
        job_type=1,
        is_11_month_reminder_sent=False,
        job_complete_datetime__range=(start, end)
    )
    
    for t in tech:
    
        t.is_11_month_reminder_sent = True
        t.reminder_11_month_datetime = timezone.now()
        # ---------- MAIN TECHNICIAN ----------
        if t.technician:
            if not t.technician.is_active and t.technician.replacement_technician:
                t.replace_technician = t.technician.replacement_technician
    
        # ---------- SECONDARY TECHNICIAN ----------
        if t.secondary_technician:
            if not t.secondary_technician.is_active and t.secondary_technician.replacement_technician:
                t.replace_secondary_technician = t.secondary_technician.replacement_technician
    
        t.save()
    
        template_data = {'quotation': t}
    
        message = render_to_string(
            'pages/quotation/email_reminder5Monthsand11Months.html',
            template_data
        )
    
        subject = 'EXCITECH Australia - Service Reminder - 11 months.'
    
        from_email = settings.FROM_EMAIL
        recipient_email = 'hari@beedev.co.in'
    
        email = EmailMessage(subject, message, from_email, [recipient_email])
        email.content_subtype = 'html'
        email.send()    
    # for or1 in tech:
    #     template_data = {'quotation': or1}
    #     message = render_to_string('pages/quotation/email_reminder5Monthsand11Months.html', template_data)
    #     subject = f'EXCITECH Australia - Service Reminder - 5 months.'
    #     from_email = settings.FROM_EMAIL 
    #     recipient_email = 'hari@beedev.co.in'
    #     email = EmailMessage(subject, message, from_email, [recipient_email])
    #     email.content_subtype = 'html'
    #     email.send()
    # eleven_months_ago_date = (timezone.now() - relativedelta(months=11)).date()
    
    # tech = Technician_Assigned_Order_Item.objects.filter(
    #     job_type=1,
    #     job_complete_datetime__startswith=eleven_months_ago_date
    # )
    # print(eleven_months_ago_date)
    
    # # tech = Technician_Assigned_Order_Item.objects.filter(job_type=1,job_complete_datetime__date=five_months_ago_date)
    # print(tech)
    # for or1 in tech:
    #     template_data = {'quotation': or1}
    #     message = render_to_string('pages/quotation/email_reminder5Monthsand11Months.html', template_data)
    #     subject = f'EXCITECH Australia - EXCITECH Australia - Service Reminder - 11 months.'
    #     from_email = settings.FROM_EMAIL 
    #     recipient_email = 'hari@beedev.co.in'
    #     email = EmailMessage(subject, message, from_email, [recipient_email])
    #     email.content_subtype = 'html'
    #     email.send()
        
    return HttpResponse('here')

def get_all_reminder_job(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')
    reminder_period = request.GET.get('reminder_period')
    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)
).annotate(
    display_name=Trim(
        Concat(
            Coalesce('userinfo__first_name', Value('')),
            Value(' '),
            Coalesce('userinfo__last_name', Value(''))
        )
    )
).distinct().order_by(Lower('display_name'))
    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)
        ).annotate(
            display_name=Trim(
                Case(
                    When(
                        is_individual=True,
                        then=Concat(
                            Coalesce('first_name', Value('')),
                            Value(' '),
                            Coalesce('last_name', Value(''))
                        )
                    ),
                    default=Coalesce('company_name', Value('')),
                    output_field=CharField()
                )
            )
        ).distinct().order_by(Lower('display_name'))
    # dd(customers)
    products=Product.objects.filter(deleted_at__isnull=True ).order_by('product_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(
            is_renewal_active=True
    ).filter(
        Q(is_5_month_reminder_sent=True) |
        Q(is_11_month_reminder_sent=True)
    )
    if technician_id:
        technician_assigned_job_lists = technician_assigned_job_lists.filter(
            Q(technician__id=technician_id) |
            Q(replace_technician__id=technician_id) |
            Q(secondary_technician__id=technician_id) |
            Q(replace_secondary_technician__id=technician_id)
        )
        
    if customer_id:
        technician_assigned_job_lists = technician_assigned_job_lists.filter(order_item__order__invoice__customer__id=customer_id)
        
    if product_id:
        technician_assigned_job_lists = technician_assigned_job_lists.filter(order_item__product__id=product_id)
    
    if reminder_period == '5':
        technician_assigned_job_lists = technician_assigned_job_lists.filter(
            is_5_month_reminder_sent=True
        )

    elif reminder_period == '11':
        technician_assigned_job_lists = technician_assigned_job_lists.filter(
            is_11_month_reminder_sent=True
        )
    
        
    # if start_date:
    #     technician_assigned_job_lists = technician_assigned_job_lists.filter(booking_date__gte=start_date)
        
    # if end_date:
    #     technician_assigned_job_lists = technician_assigned_job_lists.filter(booking_date__lte=end_date)
   
    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)
    return render(request,'pages/quotation/reminder_jobs.html',{'technician_assigned_job_lists':technician_assigned_job_lists,'technicians':technicians,'customers':customers,'products':products})   
    

    return HttpResponse("Check terminal")

def create_service_request(request,id):
    # job_detail = Technician_Assigned_Order_Item.objects.get(id=id)
    job_detail = Technician_Assigned_Order_Item.objects.select_related(
        'order_item__order__invoice__customer',
        'technician',
        'replace_technician'
    ).get(id=id)
    
    customer = job_detail.order_item.order.invoice.customer
    technician = job_detail.replace_technician if job_detail.replace_technician else job_detail.technician
    print(technician.__dict__)
    return render(request,'pages/order/create_service_ticket.html',{'job_detail':job_detail,'findcustomer':customer,'selectedtechnician':technician})   


def save_service_request_web(request):
    if request.method == "POST":
        customer_id = request.POST.get('customer_id')
        technician_id = request.POST.get('technician_id')
        order_item_id = request.POST.get('order_item_id')
        job = request.POST.get('source')
        job_id = request.POST.get('order_id')
        order_item = get_object_or_404(Order_Item, id=order_item_id)
        assigned_order_item = Technician_Assigned_Order_Item.objects.filter(
            order_item=order_item
        ).first()
        is_selected_warranty = request.POST.get('is_selected_warranty')
        description = request.POST.get('description')

        service_request_images = request.FILES.getlist('service_request_images[]')
        service_request_videos = request.FILES.getlist('service_request_videos')
        # dd(service_request_images)
        service_request_date = datetime.now().date()
        service_request_time = datetime.now().time()
        
        MAX_IMAGES = 10
        MAX_VIDEOS = 2
        
        
        if len(service_request_images) > MAX_IMAGES:
            messages.error(request, "You can upload maximum 15 images.")
            return redirect(redirect_url)
        
        if len(service_request_videos) > MAX_VIDEOS:
            messages.error(request, "You can upload maximum 15 videos.")
            return redirect(
                f"{request.META.get('HTTP_REFERER')}?customer_id={customer_id}"
                f"&order_item_id={order_item_id}"
                f"&technician_id={technician_id}"
                f"&description={description}"
            )
        job_detail = None
        if job_id:
            job_detail = get_object_or_404(Technician_Assigned_Order_Item, id=job_id)
        params = {
            "customer_id": customer_id,
            "order_item_id": order_item_id,
            "technician_id": technician_id,
            "description": description
        }
        
        # add job_detail only if job_id exists
        if job_id:
            params["job_detail"] = job_detail
        
        redirect_url = f"{request.META.get('HTTP_REFERER')}?{urlencode(params)}"
        # -------- Validations --------
        if not is_selected_warranty:
            messages.error(request, "Please select warranty status.")
            return redirect(
                f"{request.META.get('HTTP_REFERER')}?customer_id={customer_id}"
                f"&order_item_id={order_item_id}"
                f"&technician_id={technician_id}"
                f"&description={description}"
            )

        if not description:
            messages.error(request, "No description provided.")
            return redirect(
                f"{request.META.get('HTTP_REFERER')}?customer_id={customer_id}"
                f"&order_item_id={order_item_id}"
                f"&technician_id={technician_id}"
                f"&description={description}"
            )

        # -------- Create Service --------
        service = Service.objects.create(
            order_item=order_item,
            description=description,
            is_selected_warranty=is_selected_warranty
        )

        order_item.status = 8
        order_item.service_type = 2
        order_item.save()
        if job:
            technician_id = request.POST.get('technician_id')
            main_technician = User.objects.get(id=technician_id)
            secondary_technician = None
        else:
            main_technician = assigned_order_item.replace_technician or assigned_order_item.technician
            secondary_technician = (
                assigned_order_item.replace_secondary_technician
                or assigned_order_item.secondary_technician
            )
            
        assignment = Technician_Assigned_Order_Item.objects.create(
            order_item=order_item,
            technician=main_technician,
            secondary_technician=secondary_technician,
            service_request_date=service_request_date,
            service_request_time=service_request_time,
            service=service,
            job_type=2
        )
        assignment.working_status = 4
        assignment.save()

        # -------- Save Files --------
        
            
        for image_data, video_data in zip_longest(
            service_request_images,
            service_request_videos,
            fillvalue=None
        ):
            serializer = ServiceRequestImageSerializer(data={
                'service_request_image': image_data,
                'service_request_video': video_data
            })
            if serializer.is_valid():
                print('save')
                print(image_data)
                serializer.save(service=service)
        # for image_data in service_request_images:
        #     serializer = ServiceRequestImageSerializer(data={
        #         'service_request_image': image_data
        #     })
        #     if serializer.is_valid():
        #         serializer.save(service=service)
        #     else:
        #         print(serializer.errors)
        
        # # Save videos
        # for video_data in service_request_videos:
        #     serializer = ServiceRequestImageSerializer(data={
        #         'service_request_video': video_data
        #     })
        #     if serializer.is_valid():
        #         serializer.save(service=service)
        #     else:
        #         print(serializer.errors)
        Technician_Assigned_Order_Item.objects.filter(id=job_id).update(is_renewal_active=False)
        add_service_work_order(request,Technician_Assigned_Order_Item.objects.filter(id=assignment.id).first())
        messages.success(request, "service request created successfully.")

        # -------- Email --------
        subject = f'EXCITECH Australia-Job Assigned Notification (Service)-{assignment.id}'
        template_data = {'assignment': assignment}
        message = render_to_string('pages/quotation/job_assigned_email_temp.html', template_data)
        email = EmailMessage(
            subject,
            message,
            settings.FROM_EMAIL,
            ['hari@beedev.co.in']
        )
        # assignment.technician.email
        email.content_subtype = 'html'
        email.send()

        # -------- Push Notification --------
        try:
            tokens = FCMDevice.objects.filter(
                user_id=assignment.technician.id,
                active=True
            )
            for i in tokens:
                sendPush(
                    f'EXCITECH Australia - Job #{assignment.id} Assigned for Service',
                    f'Job #{assignment.id} Assigned for Service',
                    [i.registration_id],{"job_id": assignment.id,"type": "job","tech_ids":assignment.technician.id,"customer_ids":'',"additional_cust_ids":[],"sec_tech_ids":[],"job_chat_allow":[]}
                )
        except:
            pass
        if job:
            return redirect('quotation:create_service_ticket') 
        else:
            return redirect('quotation:get_all_reminder_job') 

    # GET request (show form)
    
    technicians=User.objects.filter(role=3,deleted_at__isnull=True)
    allcustomers = Customer.objects.filter(deleted_by__isnull=True)
    if job:
        return render(request,'pages/order/create_service_ticket.html',{'technicians': technicians,'allcustomers':allcustomers})
    else:
        return render(request,'pages/quotation/create_service_request.html',{'job_detail': job_detail})


    
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 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
def generateTestWorkOrder(request):
    # print(request.POST)
    WO=WorkOrderService.objects.get(technician_assigend_order_item__id=107)
    order_item=WO.order_item
    tech_assign_order_item = get_object_or_404(Technician_Assigned_Order_Item,id=WO.technician_assigend_order_item.id)
    template = get_template('pages/workorder/service_workorder_pdf.html')
    context = {
        'technician':  User.objects.get(id=222),
        'installation_start_date': '13-03-2026',
        'Size': '2',
        'product': f'{order_item.product.product_name}-{order_item.product.sku}',
        'note_by_admin': WO.note_by_admin,
        'note_by_customer': WO.note_by_customer,
        'business_hours_from_time':WO.business_hours_from_time,
        'business_hours_to_time':WO.business_hours_to_time,
        'forklift_available' :WO.forklift_available,
        'order_item' : order_item,
        'address_type' : WO.address_type,
        'street':WO.street,
        'suburb':WO.suburb,
        'postcode':WO.postcode,
        'state':WO.state,
        'country':WO.country,
        'tech_assign_order_item':tech_assign_order_item
    }
    # dd(tech_assign_order_item.related_service_request_images)
    html_content = template.render(context)
    pdf_buffer = BytesIO()
    # pisa.CreatePDF(html_content, dest=pdf_buffer)
    pisa.CreatePDF(html_content, dest=pdf_buffer, link_callback=link_callback)
    pdf_buffer.seek(0)
    response = HttpResponse(pdf_buffer, content_type='application/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 reject_quotation(request, id):
    if request.method == "POST":
        reason = request.POST.get('reason')
        quotation = Quotation.objects.get(id=id)
        quotation.status = 4
        quotation.admin_response_mail=True
        quotation.reject_reason = reason
        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],{"job_id": assignment.id,"type": "job"
                            ,"tech_ids":assignment.technician.id,"customer_ids":'',"additional_cust_ids":[],"sec_tech_ids":[],"job_chat_allow":[]})
                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',
                payment_intent_data={
                    "description": description  # ✅ Set Stripe payment description
                },
                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')
    # description = session.get('description')
    currency = session.get('currency')
    payment_reference_id = session.get('payment_intent')
    stripe_id = session.get('id')
    payment_intent_id = session.payment_intent
    payment_intent = stripe.PaymentIntent.retrieve(payment_intent_id)
    description = payment_intent.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()
            Technician_Assigned_Order_Item.objects.filter(order_item=order_item,job_type=1).update(
                deleted_by=request.user,
                deleted_at=timezone.now(),
                
                comment_cancel_job=request.POST.get('cancel_reason')
            )
            messages.success(request, 'Job Cancelled Successfully.')
            return redirect('/order/tracking-order-status/')
    return HttpResponseBadRequest("Invalid request")   

def cancelservicejob(request):
    # print(request.POST)
    # dd(request.POST)
    storage = messages.get_messages(request)
    storage.used = True
    if request.method == 'POST':
        order_item_id = request.POST.get('order_item_id')
        job_id = request.POST.get('job_id')
        # status = request.POST.get('status')
        if  job_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(id=job_id).first().delete()
            Technician_Assigned_Order_Item.objects.filter(id=job_id).update(
                deleted_by=request.user,
                deleted_at=timezone.now(),
                comment_cancel_job=request.POST.get('cancel_reason')
            )
            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,
#                 'address_type' : request.POST.get('address_type'),
#                 'street':request.POST.get('street'),
#                 'suburb':request.POST.get('suburb'),
#                 'postcode':request.POST.get('postcode'),
#                 'state':request.POST.get('state'),
#                 'country':request.POST.get('country'),
#             }
#             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'],
#                 'address_type' : context['address_type'],
#                 'street':context['street'],
#                 'suburb':context['suburb'],
#                 'postcode':context['postcode'],
#                 'state':context['state'],
#                 'country':context['country'],
#             }
#             )
#             if order_item.serial_number:
#                 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 link_callback(uri, rel):
    if uri.startswith(settings.MEDIA_URL):
        path = os.path.join(settings.MEDIA_ROOT, uri.replace(settings.MEDIA_URL, ""))
        return path

    if uri.startswith(settings.STATIC_URL):
        path = os.path.join(settings.STATIC_ROOT, uri.replace(settings.STATIC_URL, ""))
        return path

    return uri
def add_service_work_order(request,service):
    order_item_id = service.order_item.id
    tech_assign_order_item_id = service.id
    # status = request.POST.get('status')
    tech_assign_order_item = get_object_or_404(Technician_Assigned_Order_Item, id=service.id)
       
        
    if  order_item_id:
        order_item = get_object_or_404(Order_Item, id=order_item_id)
        # tech_assign_order_item = get_object_or_404(Technician_Assigned_Order_Item, id=tech_assign_order_item_id)
        # order_item.status = 12
        order_item.updated_by = request.user
        tech_assign_order_item.updated_by = request.user
        
        template = get_template('pages/workorder/service_workorder_pdf.html')
        context = {
            'technician':  User.objects.get(id=service.technician.id),
            'installation_start_date': None,
            'Size': None,
            'product': f'{order_item.product.product_name}-{order_item.product.sku}',
            'note_by_admin': None,
            'note_by_customer': tech_assign_order_item.service.description, #request.POST.get('note_by_customer'),
            'business_hours_from_time': None, #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':None, #ddatetime.strptime(request.POST.get('business_hours_to_time'), "%H:%M").strftime("%-I %p"),
            'forklift_available' : 0,
            'order_item' : order_item,
            'address_type' : 'same',
            'street':order_item.order.invoice.customer.street,
            'suburb':order_item.order.invoice.customer.city,
            'postcode':order_item.order.invoice.customer.post_code,
            'state':order_item.order.invoice.customer.state,
            'country':order_item.order.invoice.customer.country,
            'tech_assign_order_item':tech_assign_order_item
        }
        # dd(context)
        html_content = template.render(context)
        pdf_buffer = BytesIO()
        # pisa.CreatePDF(html_content, dest=pdf_buffer)
        pisa.CreatePDF(html_content, dest=pdf_buffer, link_callback=link_callback)
        pdf_buffer.seek(0)
        pdf_data=pdf_buffer
        order_item.work_order_pdf.save(f'{order_item_id}_workorder.pdf', pdf_data)
        tech_assign_order_item.work_order_pdf.save(f'{tech_assign_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 = WorkOrderService.objects.update_or_create(
        order_item=order_item,
        technician_assigend_order_item=tech_assign_order_item,
        defaults={
            "technician": context['technician'],
            "installation_start_date": installation_start_date,
            "size": context['Size'],
            "note_by_admin": context['note_by_admin'],
            "note_by_customer": context['note_by_customer'],
            "business_hours_from_time": context['business_hours_from_time'],
            "business_hours_to_time": context['business_hours_to_time'],
            "forklift_available": context['forklift_available'],
            'address_type' : context['address_type'],
            'street':context['street'],
            'suburb':context['suburb'],
            'postcode':context['postcode'],
            'state':context['state'],
            'country':context['country'],
        }
        )
   
        # messages.success(request, 'Work Order Updated Successfully.')
        return redirect(request.META.get('HTTP_REFERER', '/'))
        # return redirect('/order/tracking-order-status/')

def update_service_work_order(request):
    if request.method == 'POST':
        print(request.POST)
        order_item_id = request.POST.get('order_item_id')
        tech_assign_order_item_id = request.POST.get('tech_assign_order_item_id')
        # status = request.POST.get('status')
        if  order_item_id:
            order_item_id = request.POST.get('order_item_id')
            
        else:
            tech_assign_order_item = get_object_or_404(Technician_Assigned_Order_Item, id=tech_assign_order_item_id)
            order_item_id = tech_assign_order_item.order_item.id
            
            
        if  order_item_id:
            order_item = get_object_or_404(Order_Item, id=order_item_id)
            tech_assign_order_item = get_object_or_404(Technician_Assigned_Order_Item, id=tech_assign_order_item_id)
            # order_item.status = 12
            # order_item.updated_by = request.user
            tech_assign_order_item.updated_by = request.user
            
            template = get_template('pages/workorder/service_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_by_admin': request.POST.get('note_by_admin'),
                'note_by_customer': request.POST.get('note_by_customer'), #tech_assign_order_item.service.description, 
                'business_hours_from_time': None, #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':None, #ddatetime.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,
                'address_type' : request.POST.get('address_type'),
                'street':request.POST.get('street'),
                'suburb':request.POST.get('suburb'),
                'postcode':request.POST.get('postcode'),
                'state':request.POST.get('state'),
                'country':request.POST.get('country'),
                'tech_assign_order_item':tech_assign_order_item
            }
            html_content = template.render(context)
            pdf_buffer = BytesIO()
            # pisa.CreatePDF(html_content, dest=pdf_buffer)
            pisa.CreatePDF(html_content, dest=pdf_buffer, link_callback=link_callback)
            pdf_buffer.seek(0)
            pdf_data=pdf_buffer
            # order_item.work_order_pdf.save(f'{order_item_id}_workorder.pdf', pdf_data)
            tech_assign_order_item.work_order_pdf.save(f'{tech_assign_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 = WorkOrderService.objects.filter(
                technician_assigend_order_item=tech_assign_order_item
            ).first()
            
            if work_order:
                # UPDATE
                work_order.technician = context['technician']
                work_order.installation_start_date = installation_start_date
                work_order.size = context['Size']
                work_order.note_by_admin = context['note_by_admin']
                work_order.note_by_customer = context['note_by_customer']
                work_order.business_hours_from_time = context['business_hours_from_time']
                work_order.business_hours_to_time = context['business_hours_to_time']
                work_order.forklift_available = context['forklift_available']
                work_order.address_type = context['address_type']
                work_order.street = context['street']
                work_order.suburb = context['suburb']
                work_order.postcode = context['postcode']
                work_order.state = context['state']
                work_order.country = context['country']
            
                work_order.updated_by = request.user
                work_order.save()
            
            else:
                # CREATE
                work_order = WorkOrderService.objects.create(
                    order_item=order_item,
                    technician_assigend_order_item=tech_assign_order_item,
                    technician=context['technician'],
                    installation_start_date=installation_start_date,
                    size=context['Size'],
                    note_by_admin=context['note_by_admin'],
                    note_by_customer=context['note_by_customer'],
                    business_hours_from_time=context['business_hours_from_time'],
                    business_hours_to_time=context['business_hours_to_time'],
                    forklift_available=context['forklift_available'],
                    address_type=context['address_type'],
                    street=context['street'],
                    suburb=context['suburb'],
                    postcode=context['postcode'],
                    state=context['state'],
                    country=context['country'],
                    created_by=request.user
                )
            # work_order, created = WorkOrderService.objects.update_or_create(
            # order_item=order_item,
            # technician_assigend_order_item=tech_assign_order_item,
            # defaults={
            #     "technician": context['technician'],
            #     "installation_start_date": installation_start_date,
            #     "size": context['Size'],
            #     "note_by_admin": context['note_by_admin'],
            #     "note_by_customer": context['note_by_customer'],
            #     "business_hours_from_time": context['business_hours_from_time'],
            #     "business_hours_to_time": context['business_hours_to_time'],
            #     "forklift_available": context['forklift_available'],
            #     'address_type' : context['address_type'],
            #     'street':context['street'],
            #     'suburb':context['suburb'],
            #     'postcode':context['postcode'],
            #     'state':context['state'],
            #     'country':context['country'],
            # }
            # )
       
            messages.success(request, 'Service work order updated successfully.')
            return redirect(request.META.get('HTTP_REFERER', '/'))
            # 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')
        order_item = get_object_or_404(Order_Item, id=order_item_id)
        tech_assign_order_item_id = request.POST.get('tech_assign_order_item_id')
        # status = request.POST.get('status')
        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
        if tech_assign_order_item_id:
            tech_assign_order_item_id = tech_assign_order_item_id
        else:
            tech_assign_order_item = Technician_Assigned_Order_Item.objects.update_or_create(
            order_item= order_item,
            job_type = 1,
            defaults={
                'technician_id':User.objects.get(id=request.POST.get('technician')),
                'installation_date': installation_start_date,
                'updated_by': request.user,
                'deleted_by': None,
                'deleted_at': None,
            }
        )
            tech_assign_order_item = Technician_Assigned_Order_Item.objects.filter(order_item__id = order_item_id, job_type = 1).first()
            # dd(order_item_id,tech_assign_order_item)
            tech_assign_order_item_id=tech_assign_order_item.id
        if  order_item_id:
            order_item = get_object_or_404(Order_Item, id=order_item_id)
            tech_assign_order_item = get_object_or_404(Technician_Assigned_Order_Item, id=tech_assign_order_item_id)
            if order_item.status == 12:
                order_item.status = 4
            # order_item.updated_by = request.user
            tech_assign_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,
                'address_type' : request.POST.get('address_type'),
                'street':request.POST.get('street'),
                'suburb':request.POST.get('suburb'),
                'postcode':request.POST.get('postcode'),
                'state':request.POST.get('state'),
                'country':request.POST.get('country'),
            }
            html_content = template.render(context)
            pdf_buffer = BytesIO()
            # pisa.CreatePDF(html_content, dest=pdf_buffer)
            pisa.CreatePDF(html_content, dest=pdf_buffer, link_callback=link_callback)
            pdf_buffer.seek(0)
            pdf_data=pdf_buffer
            order_item.work_order_pdf.save(f'{order_item_id}_workorder.pdf', pdf_data)
            tech_assign_order_item.work_order_pdf.save(f'{tech_assign_order_item_id}_workorder.pdf', pdf_data)
            order_item.save()
            work_order = WorkOrder.objects.filter(
                Q(order_item=order_item) |
                Q(technician_assigend_order_item=tech_assign_order_item)
            ).first()
            if work_order:
                work_order.technician = context['technician']
                work_order.installation_start_date = installation_start_date
                work_order.size = context['Size']
                work_order.note = context['note']
                work_order.business_hours_from_time = context['business_hours_from_time']
                work_order.business_hours_to_time = context['business_hours_to_time']
                work_order.forklift_available = context['forklift_available']
                work_order.address_type = context['address_type']
                work_order.street = context['street']
                work_order.suburb = context['suburb']
                work_order.postcode = context['postcode']
                work_order.state = context['state']
                work_order.country = context['country']
            
                work_order.updated_by = request.user
                work_order.save()
            else:
                # ===== CREATE =====
                work_order = WorkOrder.objects.create(
                    order_item=order_item,
                    technician_assigend_order_item=tech_assign_order_item,
                    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'],
                    address_type=context['address_type'],
                    street=context['street'],
                    suburb=context['suburb'],
                    postcode=context['postcode'],
                    state=context['state'],
                    country=context['country'],
                    created_by=request.user,
                    updated_by=request.user
                )
            # work_order, created = WorkOrder.objects.update_or_create(
            #     order_item=order_item,
            #     technician_assigend_order_item=tech_assign_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'],
            #         'address_type': context['address_type'],
            #         'street': context['street'],
            #         'suburb': context['suburb'],
            #         'postcode': context['postcode'],
            #         'state': context['state'],
            #         'country': context['country'],
            #     }
            # )
            
            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'):
            print(request.POST)
            order_item_id = request.POST.get('order_item_id')
            job_id = request.POST.get('job_id')
            if job_id:
                job_type=2
            else:
                job_type=1
            # order_identifier= request.POST.get('order_identifier')
            technician = request.POST.get('technician')
            secondary_technician = request.POST.get('secondary_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')
            if secondary_technician:
                secondary_technician = User.objects.get(id=secondary_technician)
            else:
                secondary_technician = None
            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 job_id:
                existing_assignment = None
                existing_assignment, created = Technician_Assigned_Order_Item.objects.update_or_create(
                    id = job_id,
                    order_item=order_item,
                    job_type = job_type,
                    defaults={
                        'technician': technician,
                        'secondary_technician': secondary_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}')
                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/')
            else:
                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,
                        job_type = job_type,
                        defaults={
                            'technician': technician,
                            'secondary_technician': secondary_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,
                        job_type = job_type,
                        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],{"job_id": assignment.id,"type": "job"
                            ,"tech_ids":assignment.technician.id,"customer_ids":'',"additional_cust_ids":[],"sec_tech_ids":[],"job_chat_allow":[]})
                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_assigned_job_lists = Technician_Assigned_Order_Item.objects.filter(
        deleted_at__isnull=True
    ).prefetch_related('technician_jobs_interval__technician__userinfo')
    for technician_assigned_job_list in technician_assigned_job_lists:
        raw_breakdown = technician_assigned_job_list.technician_jobs_interval.values(
            'technician'
        ).annotate(
            total_time=Sum('total_time_timer')
        )
    
        # Attach real user objects + full name
        technician_assigned_job_list.tech_breakdown = []
        for row in raw_breakdown:
            tech_id = row['technician']
        
            if not tech_id:
                continue  # skip NULL technician
            
            tech = User.objects.filter(id=tech_id).first()
            if not tech:
                continue  # skip deleted user
            td = row['total_time'] or timedelta(seconds=0)
            total_seconds = int(td.total_seconds())
    
            hours, remainder = divmod(total_seconds, 3600)
            minutes, seconds = divmod(remainder, 60)
    
            formatted_time = f"{hours:02d}:{minutes:02d}:{seconds:02d}"
            technician_assigned_job_list.tech_breakdown.append({
                'technician': tech,
                'full_name': tech.userinfo.get_full_name,
                'total_time': formatted_time,
            })

    technician_orderitem_history=Technician_Comment.objects.filter(technician_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})   
    
@login_required  
def machines_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)
    # )
    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)
).annotate(
    display_name=Trim(
        Concat(
            Coalesce('userinfo__first_name', Value('')),
            Value(' '),
            Coalesce('userinfo__last_name', Value(''))
        )
    )
).distinct().order_by(Lower('display_name'))
    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)
).annotate(
    display_name=Trim(
        Case(
            When(
                is_individual=True,
                then=Concat(
                    Coalesce('first_name', Value('')),
                    Value(' '),
                    Coalesce('last_name', Value(''))
                )
            ),
            default=Coalesce('company_name', Value('')),
            output_field=CharField()
        )
    )
).distinct().order_by(Lower('display_name'))
    serial_numbers = SerialNumber.objects.filter(serial_number__isnull = False).filter(
    ~Q(serial_number=''),
    ~Q(serial_number=' ')
    ).order_by('serial_number')
    products=Product.objects.filter(deleted_at__isnull=True ).order_by('product_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_assigned_job_lists = Technician_Assigned_Order_Item.objects.filter(
        deleted_at__isnull=True,
        working_status__in = [
            Technician_Assigned_Order_Item.COMPLETED_INSTALLATION,
            Technician_Assigned_Order_Item.COMPLETED_SERVICE
        ]
    ).prefetch_related('technician_jobs_interval__technician__userinfo')
    for technician_assigned_job_list in technician_assigned_job_lists:
        raw_breakdown = technician_assigned_job_list.technician_jobs_interval.values(
            'technician'
        ).annotate(
            total_time=Sum('total_time_timer')
        )
    
        # Attach real user objects + full name
        technician_assigned_job_list.tech_breakdown = []
        for row in raw_breakdown:
            tech_id = row['technician']
        
            if not tech_id:
                continue  # skip NULL technician
            
            tech = User.objects.filter(id=tech_id).first()
            if not tech:
                continue  # skip deleted user
            td = row['total_time'] or timedelta(seconds=0)
            total_seconds = int(td.total_seconds())
    
            hours, remainder = divmod(total_seconds, 3600)
            minutes, seconds = divmod(remainder, 60)
    
            formatted_time = f"{hours:02d}:{minutes:02d}:{seconds:02d}"
            technician_assigned_job_list.tech_breakdown.append({
                'technician': tech,
                'full_name': tech.userinfo.get_full_name,
                'total_time': formatted_time,
            })

    technician_orderitem_history=Technician_Comment.objects.filter(technician_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(order_item__warranty_end_date__gte=start_date)
        )

    if end_date:
        technician_assigned_job_lists = technician_assigned_job_lists.filter(
            Q(order_item__warranty_end_date__lte=end_date)
        )
    if job_type:
        technician_assigned_job_lists = technician_assigned_job_lists.filter(Q(job_type=job_type))
    technician_assigned_job_lists=technician_assigned_job_lists.order_by('order_item__warranty_end_date')
   
    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/machines.html',{'serial_numbers':serial_numbers,'technician_assigned_job_lists':technician_assigned_job_lists,'technicians':technicians,'customers':customers,'products':products})   



STATUS_LABELS = {
    0: "Ordered",
    10: "Installation Completed",
    8: "Service Requested",
    11: "Service Completed",
}

def machine_detail(request, machine_id):

    order_item = get_object_or_404(Order_Item, id=machine_id)

    statuses_needed = [0, 10, 8, 11]
    timeline = []

    # ---------- STATUS HISTORY ----------
    order_history = order_item.get_order_history.order_by("timestamp")

    statuses = []

    for st in statuses_needed:

        record = order_history.filter(
            new_data__0__fields__status=st
        ).first()

        if record:
            statuses.append({
                "type": "status",
                "label": STATUS_LABELS.get(st),
                "status_code": st,
                "date": record.timestamp
            })

    statuses.sort(key=lambda x: x["date"])

    # ---------- GET CHATS ----------
    chats = Chat.objects.filter(job__id=machine_id).order_by("timestamp")

    chat_serializer = ChatSerializer(chats, many=True)
    chats = chat_serializer.data

    chat_groups = defaultdict(list)

    for chat in chats:

        chat_time = datetime.fromisoformat(
            chat["timestamp"].replace("Z", "+00:00")
        )

        chat["chat_time"] = chat_time
        chat_groups["all"].append(chat)

    # ---------- BUILD TIMELINE ----------
    for i, status in enumerate(statuses):

        timeline.append({
            "type": "status",
            "label": status["label"],
            "date": status["date"].strftime("%d-%m-%Y %H:%M:%S")
        })

        start = status["date"]

        if i + 1 < len(statuses):
            end = statuses[i+1]["date"]

            group_chats = [
                c for c in chat_groups["all"]
                if start < c["chat_time"] < end
            ]
        else:
            group_chats = [
                c for c in chat_groups["all"]
                if c["chat_time"] > start
            ]

        if group_chats:

            for g in group_chats:
                g["date"] = g["chat_time"].strftime("%d %b %Y, %I:%M %p")

            timeline.append({
                "type": "chat_group",
                "count": len(group_chats),
                "chats": json.dumps(group_chats, default=str)
            })

    serializer = OrderItemSerializer(order_item)

    return render(
        request,
        "pages/order/machine_detail.html",
        {
            "order": serializer.data,
            "product_name": order_item.product,
            "serial_number": order_item.serial_number.serial_number,
            "sku": order_item.product.sku,
            "timeline": timeline,
            "logged_user": f"{request.user.userinfo.first_name} {request.user.userinfo.last_name}".strip()
        }
    )
# def machine_detail(request, machine_id):

#     order_item = get_object_or_404(Order_Item, id=machine_id)

#     statuses_needed = [0, 10, 8, 11]
#     timeline = []

#     # ---------- STATUS HISTORY ----------
#     order_history = order_item.get_order_history.order_by("timestamp")

#     for st in statuses_needed:

#         record = order_history.filter(
#             new_data__0__fields__status=st
#         ).first()

#         if record:
#             timeline.append({
#                 "type": "status",
#                 "label": STATUS_LABELS.get(st),
#                 "status_code": st,
#                 "date": record.timestamp
#             })

#     # ---------- CHAT ----------
#     chats = Chat.objects.filter(job__id=machine_id)
#     chat_serializer = ChatSerializer(chats, many=True)

#     for chat in chat_serializer.data:

#         chat_time = datetime.fromisoformat(
#             chat["timestamp"].replace("Z", "+00:00")
#         )

#         timeline.append({
#             "type": "chat",
#             "message": chat["content"],
#             "sender": chat["sender"],
#             "recipient": chat["recipient"],
#             "images": chat["chat_images"],
#             "is_visible": chat["is_visible"],
#             "date": chat_time,
#             "is_system": False
#         })

#     # ---------- SORT TIMELINE ----------
#     timeline.sort(key=lambda x: x["date"])

#     # convert date to string for template
#     for item in timeline:
#         item["date"] = item["date"].strftime("%d-%m-%Y %H:%M:%S")

#     serializer = OrderItemSerializer(order_item)

#     return render(
#         request,
#         "pages/order/machine_detail.html",
#         {
#             "order": serializer.data,
#             "product_name": order_item.product,
#             "sku": order_item.product.sku,
#             "timeline": timeline
#         }
#     )


def create_service_ticket(request):
    orders = Order.objects.filter(deleted_at__isnull=True).select_related('invoice__customer__user')
    technicians=User.objects.filter(role=3,deleted_at__isnull=True)
    orders = Order.objects.filter(
        invoice__customer=OuterRef('pk'),
        deleted_at__isnull=True
    )
    
    allcustomers = Customer.objects.filter(
        deleted_by__isnull=True,
        is_primary=True
    ).annotate(
        has_order=Exists(orders)
    ).filter(has_order=True)
    # allcustomers = Customer.objects.filter(deleted_by__isnull=True)
    return render(request,'pages/order/create_service_ticket.html',{'orders':orders,'technicians':technicians,'allcustomers':allcustomers})

def get_order_by_customer(request):
    try:
        customer_id = request.POST.get('customer_id')

        if not customer_id:
            return JsonResponse({
                'success': False,
                'orders': []
            })

        user = User.objects.get(id=customer_id)
        if user.isprimary == 1:
            queryset = Order.objects.filter(
                invoice__customer__user__id=customer_id,
                deleted_at__isnull=True
            )
        else:
            cust_info = Customer_Info.objects.filter(user__id=customer_id).first()
            if cust_info:
                queryset = Order.objects.filter(
                    invoice__customer__user__id=cust_info.customer.user.id,
                    deleted_at__isnull=True
                )
            else:
                queryset = Order.objects.none()
            
        queryset = queryset.prefetch_related(
            'orderset__product',
        )
        orders_data = [
                {
                    'id': order.id,
                    'items': [
                        {
                            'order_item_id': item.id,
                            'product': {
                                'id': item.product.id,
                                'product_name': item.product.product_name,
                                'sku': item.product.sku,
                            },
                            'installation_date': item.installation_date,
                            'installation_time': item.installation_time,
                            'view_by_technician': item.view_by_technician,
                            'installation_complete': item.installation_complete,
                            'warranty_end_date': item.warranty_end_date,
                            'get_status': item.get_status,
                            'installed_date': item.installed_date,
                            'serial_number': item.serial_number.serial_number if item.serial_number else None,
                        
                            
                        }
                        for item in order.orderset.all()
                        if Technician_Assigned_Order_Item.objects.filter(
                    order_item=item,job_type = 1 , job_completed = True ,deleted_at__isnull = True
                ).exists()
                    ]
                }
                for order in queryset
            ]

        return JsonResponse({
            'success': True,
            'orders': orders_data
        })

    except Exception as e:
        return JsonResponse({
            'success': False,
            'error': str(e)
        })

# def get_order_by_customer(request):
#     try:
#         get_logged_in_user = request.POST.get('customer_id')
#         user=User.objects.get(id=get_logged_in_user)
#         if  user.isprimary == 1:
#             queryset = Order.objects.filter(invoice__customer__user__id = get_logged_in_user ,deleted_at__isnull=True)
#         else:
#             # additional contact
#             cust_info=Customer_Info.objects.get(user__id = get_logged_in_user)
#             if cust_info:
#                 queryset = Order.objects.filter(invoice__customer__user__id = cust_info.customer.user.id,deleted_at__isnull=True)
#             else:
#                 queryset = Order.objects.none()
                
#         data = []
#         for item in items:
#             data.append({
#                 'id': item.id,
#                 'product': item.product.product_name,
#                 'serial_number': item.serial_number.serial_number if item.serial_number else None,
#                 'warranty_end_date': item.warranty_end_date.strftime('%d-%m-%Y') if item.warranty_end_date else None
#             })

#         return JsonResponse({
#             'success': True,
#             'items': data
#         })

#     except Exception as e:
#         return JsonResponse({
#             'success': False,
#             'error': str(e)
#         })


def get_order_items(request):
    try:
        order_id = request.POST.get('order_id')

        if not order_id:
            return JsonResponse({
                'success': False,
                'message': 'Order ID is required'
            })

        items = Order_Item.objects.filter(order=order_id)
        for item in items:
            print(item.id)
            print(item.product.product_name)
            print(item.warranty_end_date)
        data = []
        for item in items:
            data.append({
                'id': item.id,
                'product': item.product.product_name,
                'serial_number': item.serial_number.serial_number if item.serial_number else None,
                'warranty_end_date': item.warranty_end_date.strftime('%d-%m-%Y') if item.warranty_end_date else None
            })

        return JsonResponse({
            'success': True,
            'items': data
        })

    except Exception as e:
        return JsonResponse({
            'success': False,
            'error': str(e)
        })
  
def show_job_chat(request,job_id):
    from service.models import Chat,ChatImage
    
    # dd(chat)
    if request.method == 'POST':
        # dd(request.FILES.getlist("chat_images"))
        job = Technician_Assigned_Order_Item.objects.get(id=job_id)
        recipient = job.technician.userinfo.user.id
        recipient_user=User.objects.get(id=recipient)
        st_id=[]
        if job.secondary_technician:
            st=User.objects.get(id=job.secondary_technician.id)
            st_id=st.id
        cust=job.order_item.order.invoice.customer.user.id
        
        
        cust_info_ids= list(
                Customer_Info.objects.filter(customer__id=job.order_item.order.invoice.customer.id, user__app_access=1)
                .values_list("user_id", flat=True)
            )
        # user=cust_info.customer.user.id
            
        chat = Chat.objects.create(
            job=job,
            sender=request.user,
            recipient=recipient_user,
            content=request.POST.get('message'),
            is_visible=1,
            is_sent=0
        )
        files = request.FILES.getlist("chat_images")
        for f in files:
            ChatImage.objects.create(
                chat=chat,
                chat_image=f
            )
        messages.success(request, 'Message Send Successfully.')
        try:
            all_other= list(
                User.objects.filter(job_chat=1)
                .values_list("id", flat=True)
            )
            query = Q(user__job_chat=1)
            
            if recipient:
                query |= Q(user_id=recipient)
            # query =  Q(user_id=recipient)
            if cust:
                query |= Q(user_id=cust)
            if st_id:
                query |= Q(user_id=st_id)
            
            
            if cust_info_ids:
                query |= Q(user_id__in=cust_info_ids)
            print(query)
            print(cust_info_ids)
            registration_ids = list(
                FCMDevice.objects.filter(active=True)
                .filter(query)
                .exclude(user=request.user)
                .values_list("registration_id", flat=True)
                .distinct()
            )
            
            # print('registration_ids')
            # print(registration_ids)
            job_data = {
                'id':job.id,
            'customercompanyname':job.order_item.order.invoice.customer.company_name,
            'customerlastname':job.order_item.order.invoice.customer.last_name,
            'customerfirstname':job.order_item.order.invoice.customer.first_name,
            'is_individual':job.order_item.order.invoice.customer.is_individual
            }
            response =sendPush(
                f"EXCITECH Australia - Job #{job_id} Chat",
                f"New Chat For Job #{job_id}",
                list(registration_ids),{"job_id": job_id,"type": "chat","job_details": json.dumps(job_data),"tech_ids":recipient,"customer_ids":cust,"additional_cust_ids":cust_info_ids,"sec_tech_ids":st_id,"job_chat_allow":all_other}
            )
            
        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}")
       # dd(request.POST)
    # dd('GET')
    chat=Chat.objects.filter(job__id=job_id)
    chat_image= ChatImage.objects.filter(chat__job__id=job_id)
    return render(request,'pages/notification/job_chat.html',{'chat':chat,'chat_image':chat_image,'job_id':job_id})
def mark_job_chat_as_read(request,job_id):
    from service.models import Chat,ChatImage,ChatRead

    job = Technician_Assigned_Order_Item.objects.get(id=job_id)
    chats = Chat.objects.filter(job=job).exclude(sender=request.user)
    for chat in chats:
        ChatRead.objects.get_or_create(chat=chat, user=request.user)
    
    return JsonResponse({"status": "success","marked_count": chats.count()})
        
        
def is_read(chat, user):
    return chat.reads.filter(user=user).exists()
    
    
    
    
def job_signature(request,token): 
    
    if request.method == "POST":
        # job_id = request.POST.get("job_id")  # if you pass it
        job_id = base64.urlsafe_b64decode(token.encode()).decode()
        print(job_id)
        job = Technician_Assigned_Order_Item.objects.get(id=job_id)
        jobsignature=Service_Signature.objects.filter(signature = '',job=job).first()
        # jobsignature=Service_Signature.objects.filter(signature__isnull = False,job=job).first()
        if jobsignature:
            # dd(jobsignature)
            name = request.POST.get("name")
            signature_data = request.POST.get("signature")
            answers = []
            for key, value in request.POST.items():
                if key.startswith("q"):
                    if value == 'yes':
                        ansflag=1
                    if value == 'yes':
                        ansflag=0
                    question_id = key.replace("q", "")
                    ans = Answer.objects.filter(id=question_id, technician_assigned_job=job_id).first()
                    if not ans:
                        return HttpResponseBadRequest(f"Invalid question id {question_id}")
                    print(ans,question_id)
                    ans=Answer.objects.get(id=question_id,technician_assigned_job=job_id)
                    ans.answer=ansflag
                    ans.save()
                    # answers.append({
                    #     "question_id": int(question_id),
                    #     "answer": value
                    # })
                    if value != "yes":
                        return HttpResponseBadRequest("All answers must be YES")
            order_item=Order_Item.objects.get(id=job.order_item.id)
            technician_assigned_job = Technician_Assigned_Order_Item.objects.get(id=job_id,order_item=order_item)
            signature_data = request.POST.get("signature")
    
            if not name or not signature_data:
                return HttpResponseBadRequest("Missing data")
    
            format, imgstr = signature_data.split(';base64,')
            ext = format.split('/')[-1]
            file_name = f"{uuid.uuid4()}.{ext}"
            file = ContentFile(base64.b64decode(imgstr), name=file_name)
    
            jobsignature.signature_text=name
            jobsignature.signature=file
            jobsignature.job=job
            jobsignature.save()
            if job.job_type==1:
                job.working_status = 3  #Completed Installation
            if job.job_type==2:
                job.working_status = 7  #Completed Service 
            job.job_status=4
            job.job_complete_datetime=timezone.now()
            job.job_completed=True
            job.is_signature=True
            job.customer_signature_required=False
            job.save()
            if order_item.service_type == 1:
                order_item.installation_complete=True
                order_item.status=10
            elif order_item.service_type == 2:   
                order_item.installation_complete=True
                order_item.status=11
            order_item.save()
            # try:
            #     unique_registration_ids = set()
            #     get_registration_token = FCMDevice.objects.filter(user_id=get_logged_in_user, active=True) 
            #     for i in get_registration_token:
            #         if i.registration_id not in unique_registration_ids:
            #             sendPush(f'EXCITECH Australia - Job #{job.id} Completed','Signature Done By The Customer',[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=job.technician.id, active=True)
                for i in get_registration_token:
                    if i.registration_id not in unique_registration_ids:
                        sendPush(f'EXCITECH Australia - Job #{job.id} Completed',f'Signature Done By The Customer',[i.registration_id],{"job_id": job.id,"type": "job"
                            ,"tech_ids":job.technician.id,"customer_ids":'',"additional_cust_ids":[],"sec_tech_ids":[],"job_chat_allow":[]
                        })     
                        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}")
            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)
            if answer:
                pdf_data = generate_pdf_checklist(job, answer,signature,accepted_images)
                if pdf_data:
                    job.pdf_file.save(f'job_{job.id}.pdf', pdf_data, save=True)
                    
                    subject = f'EXCITECH Australia -Job Checklist Details For Job Id: {job.id}'
                    message = f"Hi {job.order_item.order.invoice.customer},<br>"
                    message += "Please find technician attached checklist."
                    from_email = settings.FROM_EMAIL #job.technician.email # Replace with your email address
                    recipient_email ='kiran@beedev.co.in' #job.order_item.order.invoice.customer.email  # Use the customer's email address
                    email = EmailMessage(subject, message, from_email, [recipient_email])
                    
                    
                    pdf_file_path = job.pdf_file.path 
                    email.attach_file(pdf_file_path, 'application/pdf')
                    email.content_subtype = 'html'
                    email.send()
                    
                    # ci = Customer_Info.objects.filter(customer__id = job.order_item.order.invoice.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()
            messages.success(request, 'Your Response is updated.')
        else:
            messages.success(request, 'Your Response is already updated.')

            #quotation_detail_url = reverse('quotation:view_quotation_detail', args=[quotation.id])
            #return redirect(quotation_detail_url)
        return redirect('thankyou')
    else:
        job_id = base64.urlsafe_b64decode(token.encode()).decode()
        print(job_id)
        technician_assigned_job = Technician_Assigned_Order_Item.objects.get(   id=job_id )
        print(technician_assigned_job)
        answers = Answer.objects.filter(
            Q(technician_assigned_job=technician_assigned_job),
            Q(is_parts=0),
            Q(question__checklist__type=3)
        )
        question_data = []
        for answer in answers:
            question_data.append({
                "job_id": answer.technician_assigned_job.id,
                "question_id": answer.id,
                "question": answer.question.question,
                "answer": answer.get_answer_display(),
            })
        # dd(question_data)
        if technician_assigned_job.order_item.product.is_product :
            return render(request,'pages/invoice/customer_sign_job.html',{'question_data':[],'job_id':job_id,'token':token,'technician_assigned_job':technician_assigned_job})  
        else:
            return render(request,'pages/invoice/customer_sign_job.html',{'question_data':question_data,'job_id':job_id,'token':token,'technician_assigned_job':technician_assigned_job})  
def generate_pdf_checklist(job, answer,signature,accepted_images):

    template = get_template('pages/check_list/checklist_pdf.html')
    context = {
        'job': job,
        'answer': answer,
        'signature':signature,
        'accepted_images':accepted_images,
    }
    html_content = template.render(context)

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

    if result.err:
       
        return None

    pdf_buffer.seek(0)
    return pdf_buffer

def job_chat_list(request):
    
    technicians=User.objects.filter(role=3,deleted_at__isnull=True,id__in=Technician_Assigned_Order_Item.objects.filter(
            deleted_by__isnull=True,deleted_at__isnull=True
        ).values_list("technician__id", flat=True))
   
    customers = Customer.objects.filter(
        id__in=Technician_Assigned_Order_Item.objects.filter(
            deleted_by__isnull=True,deleted_at__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')
    user = request.user
    if user:
        if user.job_chat == 1:
            technician_assigned_job_lists = (
                Technician_Assigned_Order_Item.objects
                .filter(
                    Q(job_completed=False),
                    Q(deleted_at__isnull=True)
                )
                .annotate(
                    last_msg_time=Max('chat_set__created_at')  # latest message for each job
                )
                .order_by('-last_msg_time')  # newest chat on top
            )
        else:
           messages.success(request, "Access Denied!")
           return redirect(request.META.get('HTTP_REFERER', '/'))
    else:
        messages.success(request, "Access Denied!")
        return redirect(request.META.get('HTTP_REFERER', '/'))
    # technician_assigned_job_lists =  Technician_Assigned_Order_Item.objects.filter(deleted_at__isnull=True)
   
    for job in technician_assigned_job_lists:
        job.unread_count = job.get_chat_unread_count(request.user)
   
    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)
    return render(request,'pages/notification/job_chat_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})   
    
# def job_chat_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))
#     # from django.db.models import Count

#     # 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)
#     # ).annotate(
#     #     chat_count=Count('chat', distinct=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()
    
#     user = request.user
#     if user:
#         if user.job_chat == 1:
#             # queryset = Technician_Assigned_Order_Item.objects.filter( Q(job_completed=False)  & Q(deleted_at__isnull=True)).order_by('installation_date')
#             technician_assigned_job_lists = (
#                 Technician_Assigned_Order_Item.objects
#                 .filter(
#                     Q(job_completed=False),
#                     Q(deleted_at__isnull=True)
#                 )
#                 .annotate(
#                     last_msg_time=Max('chat_set__created_at')  # latest message for each job
#                 )
#                 .order_by('-last_msg_time')  # newest chat on top
#             )
#         else:
#           messages.success(request, "Access Denied!")
#           return redirect(request.META.get('HTTP_REFERER', '/'))
#     else:
#         messages.success(request, "Access Denied!")
#         return redirect(request.META.get('HTTP_REFERER', '/'))
#     # technician_assigned_job_lists =  Technician_Assigned_Order_Item.objects.filter(deleted_at__isnull=True)
   
#     for job in technician_assigned_job_lists:
#         job.unread_count = job.get_chat_unread_count(request.user)
   
#     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)
#     return render(request,'pages/notification/job_chat_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
    sale_order_uid=customer_invoice.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:
            invoices = matching_payment["Invoices"]
            invoice_number= invoices[0]['Number']
            sale_order_uid=invoices[0]['UID']
            amount_appliyed=invoices[0]['AmountApplied']
            invoice=Invoice.objects.get(myob_inv_no=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"],
                        )
                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 customer_payment_check_cron(request):
    with open("/tmp/cron.log", "a") as f:
        f.write("CRON HITT\n")
    refresh_token(None)
    myobdata = MyobModel.objects.first()
    if not myobdata:
        return JsonResponse({"error": "MYOB access token not found"})

    open_invoices = Invoice.objects.filter(
        status=3,
        deleted_at__isnull=True
    )
    
    if not open_invoices.exists():
        return JsonResponse({"status": "No open invoices found"})

    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()
        for customer_invoice in open_invoices:
            sale_order_uid=customer_invoice.uid
            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)
            for matching_payment in matching_customer_payments:
                invoices = matching_payment["Invoices"]
                invoice_number= invoices[0]['Number']
                sale_order_uid=invoices[0]['UID']
                amount_appliyed=invoices[0]['AmountApplied']
                invoice=Invoice.objects.get(myob_inv_no=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"],
                            )
                    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()    

    return JsonResponse({
        "status": "MYOB Cron Completed",
    })


         
# 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": abs(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": abs(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')
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"
    api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Invoice/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,  
                    "BillQuantity": int(quantities[i]),
                    "ShipQuantity" : int(quantities[i]),
                    "UnitPrice": abs(float(cost_per_unit)),
                    "UnitCount" :abs(int(quantities[i])),
                    "DiscountPercent" :float(discount_percent_myob),
                    "Account": {
                        "UID": myob_income_account, # 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]
            # invoice.sale_uid = uid
            invoice.uid = uid
            invoice.save()
            # api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item/{uid}/?format=pdf&templatename=Excitech%20Invoice" 
            api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Invoice/Item/{uid}/?format=pdf&templatename=Excitech%20Invoice" 
            headersnew = {
                        'Authorization': f'Bearer {myobdata.access_token}',
                        'x-myobapi-key': settings.MYOB_CLIENT_ID,
                        'x-myobapi-version': 'v2',
                        'Accept': 'application/pdf',
                        'Accept-Encoding': 'gzip, deflate',
                        # optional: include company file credentials if required
                        # 'x-myobapi-cftoken': base64.b64encode(f"{username}:{password}".encode()).decode(),
                    }

            # response = requests.get(api_url, headers=headersnew,)
            for _ in range(5):
                responsepdf = requests.get(api_url, headers=headersnew)
                if responsepdf.status_code == 200:
                    break
                time.sleep(2)
            if responsepdf.status_code == 200:
                pdf_data=responsepdf.content
                content = ContentFile(pdf_data)
                invoice.myob_invoice_pdf.save(f'{invoice.id}_invoice.pdf', content)
                invoice.save()
                get_invoice_url = (
                    f"https://arl2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}"
                    f"/Sale/Invoice/Item/{uid}"
                )
                
                invoice_res = requests.get(get_invoice_url, headers=headers)
                invoice_data = invoice_res.json()
                invoice.myob_inv_no=invoice_data.get("Number")  # <-- This is DisplayID / invoice number
                invoice.save()
                print('**********************done***************************')
        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')        

def sync_myob_invoice_payment(request, invoice_id):
    refresh_token(request)
    myobdata = MyobModel.objects.first()

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

    invoice = Invoice.objects.get(id=invoice_id)

    if not invoice.sale_uid:
        messages.error(request, 'Invoice not synced with MYOB yet.')
        return redirect('quotation:list_invoice')

    api_url = f"https://ar2.api.myob.com/accountright/{settings.COMPANY_FILE_ID}/Sale/Order/Item/{invoice.sale_uid}"

    headers = {
        'Authorization': f'Bearer {myobdata.access_token}',
        'x-myobapi-key': settings.MYOB_CLIENT_ID,
        'x-myobapi-version': 'v2',
    }

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

    if response.status_code != 200:
        messages.error(request, 'Failed to fetch invoice from MYOB.')
        return redirect('quotation:list_invoice')

    data = response.json()

    total = Decimal(data.get("TotalAmount", 0))
    balance = Decimal(data.get("BalanceDueAmount", 0))
    last_payment_date = data.get("LastPaymentDate")
    status = data.get("Status")

    paid = total - balance

    invoice.total = total
    invoice.total_paid_amount = paid
    invoice.payable_amount = balance
    # invoice.last_payment_date = last_payment_date
    # invoice.payment_source = "MYOB"

    # if paid == 0:
    #     invoice.payment_status = "UNPAID"
    # elif balance == 0:
    #     invoice.payment_status = "PAID"
    #     invoice.is_paid = True
    # else:
    #     invoice.payment_status = "PARTIAL"
    #     invoice.is_paid = False

    invoice.save()

    messages.success(
        request,
        f"MYOB Sync Successful. Status: {invoice.payment_status}"
    )
    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" : abs(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()
                # dd(response)
                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": abs(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" : abs(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": abs(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": abs(float(cost_per_unit)),
                        "UnitCount" :abs(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 = "hari@beedev.co.in" #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" : abs(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": -qty_values[i] if product_obj.is_product == 1 else abs(qty_values[i]), #-int(qty_values[i]),
                "ShipQuantity" : -qty_values[i] if product_obj.is_product == 1 else abs(qty_values[i]),
                "UnitPrice": abs(float(cost_per_unit)),
                "UnitCount" :abs(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')
        # print(confirm)
        # print(reject)
        # dd(confirm)
        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 reject:
                quotation.status = 4
                quotation.save()
                subject = f'EXCITECH Australia - Quote Rejected for Quote ID {quotation.id}'
                filenamequote=f'{quotation.id}_Rejected_Quote.pdf'
                
            else:
                quotation.status = 2
                quotation.save()
                subject = f'EXCITECH Australia - Quote Signed & Approved for Quote ID {quotation.id}'
                filenamequote=f'{quotation.id}_Signed_Approved_Quote.pdf'
                

            quotationitems=QuotationItem.objects.filter(quotation=quotation)
            signature = Signature.objects.filter(quotation=quotation).last()
            
            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 reject:
                    quotation.status = 4
                    quotation.save()
                    subject = f'EXCITECH Australia - Quote Rejected for Quote ID {quotation.id}'
                    filenamequote=f'{quotation.id}_Rejected_Quote.pdf'
                else:
                    quotation.status = 2
                    quotation.save()
                    subject = f'EXCITECH Australia - Quote Signed & Approved for Quote ID {quotation.id}'
                    filenamequote=f'{quotation.id}_Signed_Approved_Quote.pdf'
                    
    
                quotationitems=QuotationItem.objects.filter(quotation=quotation)
                signature = Signature.objects.filter(quotation=quotation).last()
                
                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)
    return render(request, 'pages/quotation/customer_view_quotation.html',{'quotation': quotation,'quotationitems':quotationitems, 'contracts':contracts,'token': token})
    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')
    quote_id = request.GET.get('quote_id')
    
    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
    if quote_id:
        quotations = quotations.filter(id=quote_id)
    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" : abs(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" : abs(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
        else:
            if quotation.pdf_file:
                old_pdf_path = quotation.pdf_file.path
                if os.path.exists(old_pdf_path):
                    os.remove(old_pdf_path) 
        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()
                # leadid lead_id customer_id
                # Quotation.objects.filter(deleted_by__isnull=True,lead__id=leadid,customer__id__isnull=True)
                Quotation.objects.filter(deleted_by__isnull=True,lead_id=leadid,customer_id__isnull=True).update(customer_id=cust.id)
                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,
            'phone1': lead.mobile,
            '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],bcc=settings.BCC_EMAIL_BD)
        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.')
                    Quotation.objects.filter(deleted_by__isnull=True,lead_id=leadid,customer_id__isnull=True).update(customer_id=customers.id)
                    return customers.id
                else:
                    Quotation.objects.filter(deleted_by__isnull=True,lead_id=leadid,customer_id__isnull=True).update(customer_id=customers.id)
                    return customers.id
                    # messages.error(request, 'Location header not found in API response.')
            else:
                Quotation.objects.filter(deleted_by__isnull=True,lead_id=leadid,customer_id__isnull=True).update(customer_id=customers.id)
                return customers.id
                # messages.error(request, 'Failed To Added Customer.')
    
        except requests.exceptions.RequestException as e:
            Quotation.objects.filter(deleted_by__isnull=True,lead_id=leadid,customer_id__isnull=True).update(customer_id=customers.id)
            return customers.id
            # messages.error(request, f'An error occurred: {str(e)}')
def manually_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()
                # leadid lead_id customer_id
                # Quotation.objects.filter(deleted_by__isnull=True,lead__id=leadid,customer__id__isnull=True)
                Quotation.objects.filter(deleted_by__isnull=True,lead_id=leadid,customer_id__isnull=True).update(customer_id=cust.id)
                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,
            'phone1': lead.mobile,
            '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],bcc=settings.BCC_EMAIL_BD)
        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.')
                    Quotation.objects.filter(deleted_by__isnull=True,lead_id=leadid,customer_id__isnull=True).update(customer_id=customers.id)
                    return redirect('quotation:list_quotation')
                else:
                    Quotation.objects.filter(deleted_by__isnull=True,lead_id=leadid,customer_id__isnull=True).update(customer_id=customers.id)
                    return redirect('quotation:list_quotation')
                    # messages.error(request, 'Location header not found in API response.')
            else:
                Quotation.objects.filter(deleted_by__isnull=True,lead_id=leadid,customer_id__isnull=True).update(customer_id=customers.id)
                return redirect('quotation:list_quotation')
                # messages.error(request, 'Failed To Added Customer.')
    
        except requests.exceptions.RequestException as e:
            Quotation.objects.filter(deleted_by__isnull=True,lead_id=leadid,customer_id__isnull=True).update(customer_id=customers.id)
            return redirect('quotation:list_quotation')
            # messages.error(request, f'An error occurred: {str(e)}')
# def manually_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],bcc=settings.BCC_EMAIL_BD)
#         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 redirect('quotation:list_quotation')
#                 else:
#                     return redirect('quotation:list_quotation')
#                     # messages.error(request, 'Location header not found in API response.')
#             else:
#                 return redirect('quotation:list_quotation')
#                 # messages.error(request, 'Failed To Added Customer.')
    
#         except requests.exceptions.RequestException as e:
#             return redirect('quotation:list_quotation')
#             # messages.error(request, f'An error occurred: {str(e)}')    
# 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)}')
    
    