from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.contrib import messages
from django.http import HttpResponse
from django.db.models import Q
from django.http import JsonResponse, HttpResponse

import json
from django.db.models import Sum, F
from django.db.models.functions import Lower

from rest_framework.decorators import api_view
from rest_framework.response import Response

from django.views.decorators.csrf import csrf_exempt
from django.utils.dateparse import parse_datetime

from django.utils import timezone
from django.db.models.deletion import ProtectedError

from datetime import date, datetime, timedelta

from .models import *
from .serializers import *
from .emails import *
# import datetime
import re
import xlrd
from pos.settings import BASE_DIR

def dateTime():
    current_time = datetime.now()
    newTime = str(current_time).split('.')[0]
    return newTime

# Updating Database
def update_customer(request):
    Customer.objects.filter(is_deleted=False).delete()
    workbook = xlrd.open_workbook((BASE_DIR / 'static/xls/ENTIDAD.xls'))
    sheet = workbook.sheet_by_index(0)

    for row_index in range(1, sheet.nrows): # start from row 1 to skip header row
        row_data = sheet.row_values(row_index)
        Customer.objects.create(
            id = row_data[0],
            first_name = row_data[3],
            contact = row_data[4],
            street = row_data[5],
            address = row_data[6],
            phone_no = row_data[7],
            fax_no = row_data[10],
            email = row_data[11],
        )
    return HttpResponse('Cutomer Added Successfully!')#

def update_product(request):
    Product.objects.all().delete()
    workbook = xlrd.open_workbook((BASE_DIR / 'static/xls/PRODUCT.xls'))
    sheet = workbook.sheet_by_index(0)

    for row_index in range(1, sheet.nrows): # start from row 1 to skip header row
        row_data = sheet.row_values(row_index)
        category = Product_Category.objects.get(id=row_data[1])
        if row_data[16] == '':
            row_data[16] = None
        Product.objects.create(
            id = row_data[0],
            name = row_data[2],
            price = row_data[6],
            qty = row_data[7],
            percent_imp = row_data[10],
            code_id = row_data[12],
            temp_unit_id = row_data[16],
            category = category,
        )

    return HttpResponse('Product Added Successfully!')

def update_salerep(request):
    Sale_Rep.objects.all().delete()
    workbook = xlrd.open_workbook((BASE_DIR / 'static/xls/SaleRepT.xls'))
    sheet = workbook.sheet_by_index(0)

    for row_index in range(1, sheet.nrows): # start from row 1 to skip header row
        row_data = sheet.row_values(row_index)
        Sale_Rep.objects.create(
            id=row_data[0],
            name = row_data[1],
        )

    return HttpResponse('Sale Rep Added Successfully!')

def update_address(request):
    Shipping_Address.objects.all().delete()
    Work_Site.objects.filter(is_deleted=False).delete()
    workbook = xlrd.open_workbook((BASE_DIR / 'static/xls/DIRECCION.xls'))
    sheet = workbook.sheet_by_index(0)

    for row_index in range(1, sheet.nrows): # start from row 1 to skip header row
        row_data = sheet.row_values(row_index)
        customer = Customer.objects.get(id=row_data[1])
        Work_Site.objects.create(
            id = row_data[0],
            customer = customer,
            contact = row_data[2],
            street = row_data[3],
            address = row_data[4],
        )

    return HttpResponse('Addresses Added Successfully!')

from django.utils.dateparse import parse_datetime
def update_invoice(request):
    Invoice.objects.all().delete()
    workbook = xlrd.open_workbook((BASE_DIR / 'static/xls/FACTURA.xls'))
    sheet = workbook.sheet_by_index(0)

    for row_index in range(1, sheet.nrows): # start from row 1 to skip header row
        row_data = sheet.row_values(row_index)
        
        customer = Customer.objects.get(id=row_data[1])
        try: datetime = parse_datetime(row_data[5])
        except: datetime = None
        try: shipdatetime = parse_datetime(row_data[16])
        except: shipdatetime = None
        tax = 0.0
        total = 0.0
        paid = 0.0
        sub = 0.0
        if row_data[9] is None or row_data[9] is '': pass
        else: tax = float(row_data[9])*100
        if row_data[3] is None or row_data[3] is '': pass
        else: total = row_data[3]
        if row_data[4] is None or row_data[4] is '': pass
        else: paid = row_data[4]
        if row_data[10] is None or row_data[10] is '': pass
        else: sub = row_data[10]
        balance = round((float(total) - float(paid)),2)
        status = ''
        if row_data[6] == '63': status = 'Invoice'
        elif row_data[6] == '60': status = 'Quote'
        elif row_data[6] == '62': status = 'Cancel'
        try:
            Invoice.objects.create(
                id = row_data[0],
                # quotation = row_data[],
                customer = customer,
                # work_site = row_data[],
                description = row_data[2],
                total = total,
                paid = paid,
                status = status,
                created_at= datetime,
                sub_total = sub,
                service_date = shipdatetime,
                shipment_date = shipdatetime,
                note = row_data[18],
                sale_tax = tax,
                balance = balance,
            )
        except: pass

    return HttpResponse('Invoices Added Successfully!')

def update_detail(request):
    Invoice_Detail.objects.all().delete()
    workbook = xlrd.open_workbook((BASE_DIR / 'static/xls/InvoiceDetail.xls'))
    sheet = workbook.sheet_by_index(0)
    count = 0
    for row_index in range(1, sheet.nrows): # start from row 1 to skip header row
        row_data = sheet.row_values(row_index)

        invoice = Invoice.objects.get(id=row_data[1])
        product = Product.objects.get(id=row_data[2])

        total = 0.0
        try:
            total = float(row_data[4]) * float(row_data[3])
        except: pass
        try:
            Invoice_Detail.objects.create(
                id = row_data[0],
                invoice = invoice,
                product = product,
                amount = row_data[3], #price
                units = row_data[4],
                qty = row_data[4],
                total = total,
                description = row_data[7],
            )
        except: pass
    return HttpResponse('Invoice Details Added Successfully!')

def update_cat(request):
    cat_list = ['OTHER', 'OTRO3', 'GLASS', 'OTHER1', 'ACCESSORIES', 'OTRO4', 'MIRROR', 'SERVICE']

    for cat in cat_list:
        Product_Category.objects.create(name=cat)





# apis 
@api_view(['GET'])
def get_product(request):
    product = Product.objects.all()
    seraiz = ProductSerializer(product, many=True).data
    return JsonResponse(seraiz, safe=False)

@api_view(['GET'])
def get_unit(request):
    units = Unit.objects.annotate(lower_name=Lower('name')).order_by('lower_name')
    seraiz = APIUnitSerializer(units, many=True).data

    unit_dict = {}
    for unit in seraiz:
        lower_name = unit['lower_name']
        if lower_name not in unit_dict:
            unit_dict[lower_name] = []
        unit_dict[lower_name].append(unit)

    result_dict = {}
    for key, value in unit_dict.items():
        result_dict[key] = [entry for entry in value]  
    return JsonResponse(result_dict, safe=False)


@csrf_exempt
def add_customer_from_invoice(request):
    # d = request.body
    data = json.loads(request.body)
    first_name = data['first_name']
    contact = data['contact']
    street = data['street']
    phone_no = data['phone_no']
    fax_no = data['fax_no']
    email = data['email']
    address = data['address']

    cust = Customer.objects.create(
        first_name = first_name,
        contact = contact,
        street = street,
        phone_no = phone_no,
        fax_no = fax_no,
        email = email,
        address = address,
    )

    customer = Customer.objects.filter(is_deleted=False).order_by('-id')
    seraiz = CustomerSerializer(customer, many=True).data
    return JsonResponse(seraiz, safe=False)

@csrf_exempt
def add_sale_rep_from_invoice(request):
    # d = request.body
    data = json.loads(request.body)
    name = data['name']
    try: phone_no = data['phone_no']
    except: phone_no = ''
    try: email = data['email']
    except: email = ''
    try: address = data['address']
    except: address = ''

    sr = Sale_Rep.objects.create(
        name = name,
        phone_no = phone_no,
        email = email,
        address = address,
    )

    sale_rep = Sale_Rep.objects.all().order_by('-id')
    seraiz = SaleRepSerializer(sale_rep, many=True).data
    return JsonResponse(seraiz, safe=False)

@csrf_exempt
def add_site_from_invoice(request):
    # d = request.body
    data = json.loads(request.body)
    cusId = data['cusId']
    street = data['street']
    address = data['address']
    start_date = data['start_date']

    customer = Customer.objects.get(pk=cusId)

    cust = Work_Site.objects.create(
        customer=customer,
        street = street,
        address = address,
        start_date = start_date,
    )

    customer = Work_Site.objects.filter(customer=customer).order_by('-id')
    seraiz = WorkSiteSerializer(customer, many=True).data
    return JsonResponse(seraiz, safe=False)

@csrf_exempt
def add_shipping_from_invoice(request):
    # d = request.body
    data = json.loads(request.body)
    cusId = data['cusId']
    address = data['address']

    customer = Customer.objects.get(pk=cusId)

    cust = Shipping_Address.objects.create(
        customer=customer,
        address = address,
    )

    customer = Shipping_Address.objects.filter(customer=customer).order_by('-id')
    seraiz = ShippingAddressSerializer(customer, many=True).data
    return JsonResponse(seraiz, safe=False)

@csrf_exempt
def add_billing_from_invoice(request):
    # d = request.body
    data = json.loads(request.body)
    cusId = data['cusId']
    address = data['address']

    customer = Customer.objects.get(pk=cusId)

    cust = Billing_Address.objects.create(
        customer=customer,
        address = address,
    )

    customer = Billing_Address.objects.filter(customer=customer).order_by('-id')
    seraiz = BillingAddressSerializer(customer, many=True).data
    return JsonResponse(seraiz, safe=False)


# apis 
# datatable 
def invoice_datatable_search(request, id, account,invoice):


    if id == 0 and (account == 'null' or account == '0') and  (invoice == 'null' or invoice == '0'):
        response_data = {
            'data': [],
        }
        print(response_data)
        return JsonResponse(response_data)

    if id != 0:
        customer = Customer.objects.get(pk=id)
        invoices = Invoice.objects.filter(Q(status='Invoice') & Q(customer=customer))
    else: invoices = Invoice.objects.filter(status='Invoice')

    if account != '0' and account != 'null': invoices = invoices.filter(customer__id__icontains=account)
    if invoice != '0' and invoice != 'null': invoices = invoices.filter(pk__icontains=invoice)

    total_records = invoices.count()

    # Parse Datatables parameters from request
    start = int(request.GET.get('start', 0))
    length = int(request.GET.get('length', 20))
    search_value = request.GET.get('search[value]', None)
    order_column = int(request.GET.get('order[0][column]', 0))
    order_dir = request.GET.get('order[0][dir]', 'asc')

    # Perform search
    if search_value:
        invoices = invoices.filter(Q(pk__icontains = search_value) & Q(customer__first_name__icontains = search_value))

    # Perform sorting
    if order_column == 0: col_name = 'id'
    elif order_column == 1: col_name = 'customer__first_name'
    elif order_column == 3: col_name = 'total'
    elif order_column == 4: col_name = 'balance'
    elif order_column == 5: col_name = 'created_at'

    if order_dir == 'asc':
        sort_column = f'{col_name}'
    else:
        sort_column = f'-{col_name}'
    invoices = invoices.order_by(sort_column)

    # Paginate the data
    paginator = Paginator(invoices, length)
    page_number = (start // length) + 1
    page_obj = paginator.get_page(page_number)

    data = [invoice.get_data() for invoice in page_obj]

    # Construct JSON response
    response_data = {
        'draw': int(request.GET.get('draw', 1)),
        'recordsTotal': total_records,
        'recordsFiltered': paginator.count,
        'data': data,
    }
    return JsonResponse(response_data)
    # search_value = request.GET.get('search[value]')

    # objects = Invoice.objects.filter(status='Invoice')

    # if search_value:
    #     objects = objects.filter(customer__first_name__icontains=search_value)

    
    # paginator = Paginator(objects, 20)
    # page_number = request.GET.get('page')
    # page_obj = paginator.get_page(page_number)

    # objects = [invoice.get_data() for invoice in page_obj]

    # data = {
    #     'data': list(objects),
    # }

    # return JsonResponse(data)

def quotation_datatable_search(request, id, account, invoice):

    if id == 0 and (account == 'null' or account == '0') and  (invoice == 'null' or invoice == '0'):
        response_data = {
            'data': [],
        }
        print(response_data)
        return JsonResponse(response_data)

    if id != 0:
        customer = Customer.objects.get(pk=id)
        invoices = Invoice.objects.filter(Q(status='Quote') & Q(customer=customer))
    else: invoices = Invoice.objects.filter(status='Quote')

    if account != '0' and account != 'null': invoices = invoices.filter(customer__id__icontains=account)
    if invoice != '0' and invoice != 'null': invoices = invoices.filter(pk__icontains=invoice)


    total_records = invoices.count()

    # Parse Datatables parameters from request
    start = int(request.GET.get('start', 0))
    length = int(request.GET.get('length', 20))
    search_value = request.GET.get('search[value]', None)
    order_column = int(request.GET.get('order[0][column]', 0))
    order_dir = request.GET.get('order[0][dir]', 'asc')

    # Perform search
    # if search_value:
    #     q_obj = Q()
    #     for field in Invoice._meta.fields:
    #         if field.get_internal_type() in ['CharField', 'FloatField', 'DateField']:
    #             q_obj |= Q(**{f'{field.name}__icontains': search_value})
    #     invoices = invoices.filter(q_obj)

    if search_value:
        invoices = invoices.filter(Q(pk__icontains = search_value) & Q(customer__first_name__icontains = search_value))

    # Perform sorting
    if order_column == 0: col_name = 'id'
    elif order_column == 1: col_name = 'customer__first_name'
    elif order_column == 3: col_name = 'total'
    elif order_column == 4: col_name = 'balance'
    elif order_column == 5: col_name = 'created_at'

    if order_dir == 'asc':
        sort_column = f'{col_name}'
    else:
        sort_column = f'-{col_name}'
        
    invoices = invoices.order_by(sort_column)

    # Paginate the data
    paginator = Paginator(invoices, length)
    page_number = (start // length) + 1
    page_obj = paginator.get_page(page_number)

    data = [invoice.get_data() for invoice in page_obj]

    # Construct JSON response
    response_data = {
        'draw': int(request.GET.get('draw', 1)),
        'recordsTotal': total_records,
        'recordsFiltered': paginator.count,
        'data': data,
    }
    print(response_data)
    print(type(response_data))
    return JsonResponse(response_data)

def customer_datatable_search(request):
    customers = Customer.objects.filter(is_deleted=False)
    total_records = customers.count()

    # Parse Datatables parameters from request
    start = int(request.GET.get('start', 0))
    length = int(request.GET.get('length', 20))
    search_value = request.GET.get('search[value]', None)
    order_column = int(request.GET.get('order[0][column]', 0))
    order_dir = request.GET.get('order[0][dir]', 'asc')

    # Perform search
    if search_value:
        customers = customers.filter(first_name__icontains=search_value)
        print('in')

    # Perform sorting

    if order_column == 0: col_name = 'id'
    elif order_column == 1: col_name = 'first_name'
    elif order_column == 3: col_name = 'fax_no'

    if order_dir == 'asc':
        sort_column = f'{col_name}'
    else:
        sort_column = f'-{col_name}'

    customers = customers.order_by(sort_column)

    # Paginate the data
    paginator = Paginator(customers, length)
    page_number = (start // length) + 1
    page_obj = paginator.get_page(page_number)

    data = [customer.get_data() for customer in page_obj]

    # Construct JSON response
    response_data = {
        'draw': int(request.GET.get('draw', 1)),
        'recordsTotal': total_records,
        'recordsFiltered': paginator.count,
        'data': data,
    }
    return JsonResponse(response_data)

def work_site_datatable_search(request, id):

    if id != 0:
        customer = Customer.objects.get(pk=id)
        sites = Work_Site.objects.filter(customer=customer)
    else: sites = Work_Site.objects.filter(is_deleted=False)
    total_records = sites.count()

    # Parse Datatables parameters from request
    start = int(request.GET.get('start', 0))
    length = int(request.GET.get('length', 20))
    search_value = request.GET.get('search[value]', None)
    order_column = int(request.GET.get('order[0][column]', 0))
    order_dir = request.GET.get('order[0][dir]', 'asc')

    # Perform search
    if search_value:
        # search in every column 
        q_obj = Q()
        for field in Work_Site._meta.fields:
            if field.get_internal_type() in ['CharField', 'FloatField', 'DateField']:
                q_obj |= Q(**{f'{field.name}__icontains': search_value})
        sites = sites.filter(q_obj)


    # Perform sorting
    if order_column == 0: col_name = 'id'
    elif order_column == 1: col_name = 'customer__first_name'

    if order_dir == 'asc':
        sort_column = f'{col_name}'
    else:
        sort_column = f'-{col_name}'

    sites = sites.order_by(sort_column)

    # Paginate the data
    paginator = Paginator(sites, length)
    page_number = (start // length) + 1
    page_obj = paginator.get_page(page_number)

    data = [site.get_data() for site in page_obj]

    # Construct JSON response
    response_data = {
        'draw': int(request.GET.get('draw', 1)),
        'recordsTotal': total_records,
        'recordsFiltered': paginator.count,
        'data': data,
    }
    return JsonResponse(response_data)

def product_datatable_search(request):
    products = Product.objects.all()

    total_records = products.count()

    # Parse Datatables parameters from request
    start = int(request.GET.get('start', 0))
    length = int(request.GET.get('length', 20))
    search_value = request.GET.get('search[value]', None)
    order_column = int(request.GET.get('order[0][column]', 0))
    order_dir = request.GET.get('order[0][dir]', 'asc')

    # Perform search
    if search_value:
        products = products.filter(name__icontains=search_value)

    # Perform sorting
    if order_column == 0: col_name = 'id'
    elif order_column == 1: col_name = 'code_id'
    elif order_column == 2: col_name = 'name'
    elif order_column == 4: col_name = 'price'
    elif order_column == 5: col_name = 'category__name'
    elif order_column == 6: col_name = 'qty'

    if order_dir == 'asc':
        sort_column = f'{col_name}'
    else:
        sort_column = f'-{col_name}'

    products = products.order_by(sort_column)

    # Paginate the data
    paginator = Paginator(products, length)
    page_number = (start // length) + 1
    page_obj = paginator.get_page(page_number)

    data = [product.get_data() for product in page_obj]

    # Construct JSON response
    response_data = {
        'draw': int(request.GET.get('draw', 1)),
        'recordsTotal': total_records,
        'recordsFiltered': paginator.count,
        'data': data,
    }
    return JsonResponse(response_data)





@login_required
def index(request):
    last_month = datetime.today() - timedelta(days=30)
    invoice = Invoice.objects.filter(created_at__gte = last_month).count()
    work_site = Work_Site.objects.filter(is_deleted=False).count()
    customer = Customer.objects.filter(is_deleted=False).count()
    product = Product.objects.all().count()
    temp = Invoice_Detail.objects.filter(invoice__created_at__gte = last_month)
    productSale = 0.0
    amountSale = 0.0
    for i in temp:
        if i.qty is None: i.qty = 0
        if i.amount is None: i.amount = 0
        productSale += i.qty
        amountSale += i.qty * i.amount
    
    current_month = timezone.now().month
    current_year = timezone.now().year
    temp = Invoice_Detail.objects.filter(Q(invoice__created_at__month=current_month) & Q(invoice__created_at__year=current_year))
    monthSale = 0
    for i in temp:
        if i.qty is None: i.qty = 0
        if i.amount is None: i.amount = 0
        monthSale += i.qty * i.amount

    context = {'work_site':work_site,'invoice':invoice,'product':product, 'customer': customer, 'productsale':productSale,
               'amountsale':"{:.2f}".format(amountSale), 'monthly': "{:.2f}".format(monthSale)}
    return render(request, 'pos_system/index.html', context)

def admin_login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = authenticate(username=username, password=password)
        if user is not None:
            login(request, user)
            return redirect('index')  # Redirect to the homepage after login
        else:
            return render(request, 'pos_system/login.html', {'error_message': 'Invalid login credentials'})
    else:
        return render(request, 'pos_system/login.html')

@login_required
def admin_logout(request):
    logout(request)
    return redirect('login')

@login_required
def change_password(request):
    if request.method == "POST":
        post = request.POST
        password = post.get("password")
        new_password = post.get("new_password")

        # try:
        user = User.objects.get(id=request.user.id)
        
        # if user.check_password(password):
        user.set_password(new_password)
        user.save()
        # messages.success(request, "Password Changed")
        logout(request)
        return redirect("login")    

            # else:
            #     messages.error(request, "Password Does Not Match")

        # except Exception as err:
        #     messages.error(request, "Password Change Failed")

    return render(request, 'pos_system/change_password.html')
    
@login_required
def default_config(request):
    default = Default_Config.objects.all().first()
    if request.method == 'POST':
        name = request.POST.get('name')
        street = request.POST.get('street')
        address = request.POST.get('address')
        email = request.POST.get('email')
        phone_no = request.POST.get('phone_no')
        fax = request.POST.get('fax')
        
        default = Default_Config.objects.all()

        if len(default) <= 0:
            config = Default_Config.objects.create(
                name = name,
                street = street,
                email = email,
                address = address,
                phone_no = phone_no,
                fax = fax,
            )
        else:
            default = default.first()
            default.name = name
            default.email = email
            default.street = street
            default.address = address
            default.phone_no = phone_no
            default.fax = fax
            default.save()
        messages.success(request,'Deafult COnfig updated Successfully')        
           
        return redirect('default_config')
    
    return render(request, 'pos_system/default/default_config.html', {'config':default})
    




@login_required
def customer(request):
    if request.method == 'POST':
        type = request.POST.get('type')
        first_name = request.POST.get('first_name')
        contact = request.POST.get('contact')
        # last_name = request.POST.get('last_name')
        phone_no = request.POST.get('phone_no')
        fax_no = request.POST.get('fax_no')
        email = request.POST.get('email')
        street = request.POST.get('street')
        address = request.POST.get('address')

        if type == 'edit':
            customerId = request.POST.get('customerId')
            obj = Customer.objects.get(pk=customerId)
            obj.first_name = first_name
            obj.street = street
            obj.contact = contact
            obj.phone_no = phone_no
            obj.fax_no = fax_no
            obj.email = email
            obj.address = address
            obj.save()
            messages.success(request,'Customer Edited Successfully')        

        else:
            cust = Customer.objects.create(
                first_name = first_name,
                contact = contact,
                street = street,
                phone_no = phone_no,
                fax_no = fax_no,
                email = email,
                address = address,
            )
            messages.success(request,'Customer Added Successfully')        

        return redirect('customer')
    
    # items_per_page = 20
    # queryset = Customer.objects.filter(is_deleted=False)
    # paginator = Paginator(queryset, items_per_page)

    # page_number = request.GET.get('page')
    # page_obj = paginator.get_page(page_number)

    # context = {'page_obj': page_obj}
    # return render(request, 'pos_system/customer/customer.html', context)
    return render(request, 'pos_system/customer/customer.html')

@login_required
@api_view(['GET'])
def edit_customer(request, id):
    customer = Customer.objects.get(pk=id)
    customerSeriaz = CustomerSerializer(customer).data
    return Response(customerSeriaz)

@login_required
def delete_customer(request, id):
    try: customer  = Customer.objects.get(pk=id).delete()
    except ProtectedError:  Customer.objects.filter(pk=id).update(is_deleted=True)
    return redirect('customer')




@login_required
def sale_rep(request):
    if request.method == 'POST':
        type = request.POST.get('type')
        # phone_no = request.POST.get('phone_no')
        # fax_no = request.POST.get('fax_no')
        # email = request.POST.get('email')
        name = request.POST.get('name')
        # address = request.POST.get('address')

        if type == 'edit':
            sale_rep_id= request.POST.get('saleRepId')
            obj = Sale_Rep.objects.get(pk=sale_rep_id)
            obj.name = name
            obj.save()
            messages.success(request,'Sale Rep Edited Successfully')        

        else:
            cust = Sale_Rep.objects.create(
                name = name,
            )
            messages.success(request,'Sale Rep Added Successfully')        

        return redirect('sale_rep')
    
    sale_rep = Sale_Rep.objects.all().order_by('-id')
    context = {'sale_rep':sale_rep}
    return render(request, 'pos_system/sale_rep/sale_rep.html', context)

@login_required
@api_view(['GET'])
def edit_sale_rep(request, id):
    sale_rep = Sale_Rep.objects.get(pk=id)
    sale_rep_seriaz = SaleRepSerializer(sale_rep).data
    return Response(sale_rep_seriaz)

@login_required
def delete_sale_rep(request, id):
    sale_rep  = Sale_Rep.objects.get(pk=id).delete()
    return redirect('sale_rep')







@login_required
def work_site(request):
    if request.method == 'POST':
        type = request.POST.get('type')
        cus_id = request.POST.get('customer')
        street = request.POST.get('street')
        address = request.POST.get('address')
        start_date = request.POST.get('start_date')
        
        customer = Customer.objects.get(pk=cus_id)

        if type == 'edit':
            id = request.POST.get('workSiteId')
            cust = Work_Site.objects.get(pk=id)
            cust.customer = customer
            cust.street = street
            cust.address = address
            cust.start_date = start_date
            cust.save()
            messages.success(request,'Work Site updated Successfully')        
        else:
            cust = Work_Site.objects.create(
                customer=customer,
                street = street,
                address = address,
                start_date = start_date,
            )
            messages.success(request,'Work Site added Successfully')        
        return redirect('work_sites')
    
    customer = Customer.objects.filter(is_deleted=False)
    # queryset = Work_Site.objects.filter(is_deleted=False)

    # items_per_page = 20
    # paginator = Paginator(queryset, items_per_page)

    # page_number = request.GET.get('page')
    # page_obj = paginator.get_page(page_number)

    context = {'page_obj': [], 'customer': customer, 'is_all_sites': True}
    return render(request, 'pos_system/worksite/work-site.html', context)

@login_required
@api_view(['GET'])
def edit_work_site(request, id):
    site = Work_Site.objects.get(pk=id)
    Seriaz = WorkSiteSerializer(site).data
    return Response(Seriaz)

@login_required
def delete_work_site(request, id):
    try: Work_Site.objects.get(pk=id).delete()
    except ProtectedError: Work_Site.objects.filter(pk=id).update(is_deleted=True)
    return redirect('work_site')


@login_required
def product_category(request):
    if request.method == 'POST':
        type = request.POST.get('type')
        name = request.POST.get('name')

        if type == 'edit':
            id = request.POST.get('catId')
            cat = Product_Category.objects.get(pk=id)
            cat.name = name
            cat.save()
            messages.success(request, 'Product Category Updated Successfully')
        else:            
            Product_Category.objects.create(
                name = name
            )
            messages.success(request, 'Product Category Added Successfully')
        
        return redirect('product_category')
    
    category = Product_Category.objects.all()
    context = {'category':category}
    return render(request, 'pos_system/product/product-category.html', context)

@login_required
@api_view(['GET'])
def edit_product_category(request, id):
    category = Product_Category.objects.get(pk=id)
    Seriaz = ProductCategorySerializer(category).data
    return Response(Seriaz)

@login_required
def delete_product_category(request, id):
    customer  = Product_Category.objects.get(pk=id).delete()
    return redirect('product_category')



@login_required
def product(request):
    if request.method == 'POST':
        type = request.POST.get('type')
        cat_id = request.POST.get('category')
        name = request.POST.get('name')
        unit_id = request.POST.get('unit')
        price = request.POST.get('price')
        qty = request.POST.get('qty')
        code = request.POST.get('code')
        # description = request.POST.get('description')
        try: unit = Unit.objects.get(pk=unit_id)
        except: unit = None
        category = Product_Category.objects.get(pk=cat_id)
        print(category)
        if type == 'edit':
            id = request.POST.get('productId')
            product = Product.objects.get(pk=id)
            product.category = category
            product.name = name
            if unit is not None: product.unit = unit
            product.price = price
            product.qty = qty
            product.code_id = code
            # product.description = description
            product.save()
            messages.success(request, 'Product Updated Successfully')
        else:
            cust = Product.objects.create(
                category = category,
                name = name,
                qty = qty,
                price = price,
                code_id = code,
                # description = description,
            )
            if unit is not None: cust.unit = unit
            messages.success(request, 'Product Added Successfully')
            return redirect('product')
        

    # items_per_page = 20
    # queryset = Product.objects.all()

    # paginator = Paginator(queryset, items_per_page)
    # page_number = request.GET.get('page')
    # page_obj = paginator.get_page(page_number)

    category = Product_Category.objects.all()
    unit = Unit.objects.all()
    # context = {'page_obj': page_obj,  'category':category, 'unit':unit}
    context = {'page_obj': [],  'category':category, 'unit':unit}

    return render(request, 'pos_system/product/product.html', context)

@login_required
@api_view(['GET'])
def edit_product(request, id):
    product = Product.objects.get(pk=id)
    Seriaz = ProductSerializer(product).data
    return Response(Seriaz)

@login_required
def delete_product(request, id):
    customer  = Product.objects.get(pk=id).delete()
    return redirect('product')


# payments
@login_required
def invoice_payment(request, id):
    if request.method == 'POST':
        inoviceId = request.POST.get('inoviceId')
        type = request.POST.get('type')
        amountToPay = request.POST.get('amountToPay')
        message = request.POST.get('message')

        inv = Invoice.objects.get(pk=inoviceId)
        payment = Invoice_Payment.objects.create(
            invoice=inv,
            type = type,
            paid_amount = float(amountToPay),
            message = message,
        )

        inv.balance = "{:.2f}".format(float(inv.balance)-float(amountToPay))
        inv.save()

        if type == 'Bank':
            name = request.POST.get('name')
            account = request.POST.get('account')
            payment.card_holder_name = name
            payment.card_no = account
            payment.save()

        messages.success(request, 'Payment Paid Succesfully.')
        return redirect("invoice_payment",id=id)
    
    invoice = Invoice.objects.get(pk=id)
    payment = Invoice_Payment.objects.filter(invoice=invoice).order_by('-id')
    context = {'payment':payment, 'invoice':invoice}
    return render(request, 'pos_system/invoice/invoice_payment.html', context)



from django.core.paginator import Paginator
# invoice data
@login_required
def invoice(request):
    if request.method == 'POST':
        inoviceId = request.POST.get('inoviceId')
        type = request.POST.get('type')
        amountToPay = request.POST.get('amountToPay')
        message = request.POST.get('message')

        inv = Invoice.objects.get(pk=inoviceId)
        payment = Invoice_Payment.objects.create(
            invoice=inv,
            type = type,
            paid_amount = float(amountToPay),
            message = message,
        )

        inv.balance = "{:.2f}".format(float(inv.balance)-float(amountToPay))
        inv.save()

        if type == 'Bank':
            name = request.POST.get('name')
            account = request.POST.get('account')
            payment.card_holder_name = name
            payment.card_no = account
            payment.save()

        messages.success(request, 'Payment Added Succesfully.')
        return redirect("invoice")


    # invoices = Invoice.objects.all()
    # paginator = Paginator(invoices, 20)
    # page_number = request.GET.get('page')
    # page_obj = paginator.get_page(page_number)

    # items_per_page = 20
    # queryset = Invoice.objects.filter(status='Invoice')

    # paginator = Paginator(queryset, items_per_page)

    # page_number = request.GET.get('page')
    # page_obj = paginator.get_page(page_number)
    customers = Customer.objects.filter(is_deleted=False)
    context = {'page_obj': [], 'customers': customers}
    # return render(request, 'pos_system/invoice/invoice.html', context)
    return render(request, 'pos_system/invoice/invoice.html', context)

def invoice_list(request):
    invoices = Invoice.objects.all()
    total_records = invoices.count()

    # Parse Datatables parameters from request
    start = int(request.GET.get('start', 0))
    length = int(request.GET.get('length', 20))
    search_value = request.GET.get('search[value]', None)
    order_column = int(request.GET.get('order[0][column]', 0))
    order_dir = request.GET.get('order[0][dir]', 'asc')

    # Perform search
    if search_value:
        invoices = invoices.filter(invoice_number__icontains=search_value)

    # Perform sorting
    if order_dir == 'asc':
        sort_column = 'invoice_number'
    else:
        sort_column = '-invoice_number'
    invoices = invoices.order_by(sort_column)

    # Paginate the data
    paginator = Paginator(invoices, length)
    page_number = (start // length) + 1
    page_obj = paginator.get_page(page_number)
    data = [{
        'invoice_number': invoice.invoice_number,
        'customer': invoice.customer,
        'amount': invoice.amount,
        'date': invoice.date
    } for invoice in page_obj]

    # Construct JSON response
    response_data = {
        'draw': int(request.GET.get('draw', 1)),
        'recordsTotal': total_records,
        'recordsFiltered': paginator.count,
        'data': data,
    }
    return JsonResponse(response_data)

@login_required
def edit_invoice(request, id):

    invoice = Invoice.objects.get(pk=id)
    detail = Invoice_Detail.objects.filter(invoice=invoice)
    if request.method == 'POST':
        data = json.loads(request.body)
        item = data['item']

        # shipping_address = data['shipping_address']
        billing_address = data['billing_address']
        sale_rep_id = data['sale_rep']
        service_date = data['service_date']
        # status = data['status']
        # payment_type = data['payment_type']
        tax = data['tax']
        note = data['note']
        discount = data['discount']
        deposit = data['deposit']
        surcharge = data['surcharge']
        subtotal = data['subtotal']
        total = data['total']
        balance = data['balance']

        # invoice = Invoice.objects.get(pk=id)
        # detail = Invoice_Detail.objects.filter(invoice=invoice)

        customer = Customer.objects.get(pk=data['customer'])
        sale_rep = Sale_Rep.objects.get(pk=sale_rep_id)

        invoice.customer = customer
        invoice.work_site = site
        invoice.service_date = service_date
        invoice.sale_rep = sale_rep
        # invoice.status = status
        # invoice.term = payment_type
        invoice.sale_tax = tax
        invoice.note = note
        invoice.energy_surcharge = surcharge
        invoice.discount = discount
        invoice.sub_total = float(subtotal)
        invoice.deposit = deposit
        invoice.total = float(total)
        invoice.balance = "{:.2f}".format(float(balance))


        # if shipping_address is not None:
        #     shipping = Shipping_Address.objects.get(pk=shipping_address)
        #     invoice.shipping_address = shipping

        if billing_address is not None:
            # billing = Billing_Address.objects.get(pk=billing_address)
            invoice.billing_address = billing_address

        if data['site'] is not None:
            site = Work_Site.objects.get(pk=data['site'])
            invoice.work_site = site
        invoice.save()


        # deleteing all invoice daetails and adding product qty to them
        detail = Invoice_Detail.objects.filter(invoice=invoice)
        for i in detail:
            pro = Product.objects.get(pk=i.product.id)
            pro.qty += i.qty
            pro.save()
            i.delete()


        # Now again cretaing invoice detail and subtracting qty ffrom producst
        for i in item:
            product = Product.objects.get(pk=i['product-id'])
            detail = Invoice_Detail.objects.create(
                invoice = invoice,
                product = product,
                amount = i['price'],
                qty = i['qty'],
                width = i['width'],
                height = i['height'],
                total = "{:.2f}".format(float(i['qty'])*float(i['price'])),
            )
            product.qty = product.qty - float(i['qty'])
            product.save()
                
            # subtotal += float(i['price']) * float(i['qty'])

        return HttpResponse(invoice.id)
    
    customer = Customer.objects.filter(is_deleted=False).order_by('-id')
    site = Work_Site.objects.filter(customer=customer[0])
    product = Product.objects.all()
    sale_rep = Sale_Rep.objects.all().order_by('-id')
    # ship = Shipping_Address.objects.all()
    # bill = Billing_Address.objects.all()
    context = {'customer':customer, 'site':site, 'product':product, 'invoice':invoice, 'detail':detail,'sale_rep':sale_rep}
    return render(request, 'pos_system/invoice/edit-invoice.html', context)

@login_required
def add_invoice(request,id):
    if request.method == 'POST':
        data = json.loads(request.body)
        item = data['item']

        quotation_id = data['quotation']
        # shipping_address = data['shipping_address']
        billing_address = data['billing_address']
        note = data['note']
        sale_rep_id = data['sale_rep']
        service_date = data['service_date']
        payment_type = data['payment_type']
        tax = data['tax']
        discount = data['discount']
        deposit = data['deposit']
        surcharge = data['surcharge']
        subtotal = data['subtotal']
        total = data['total']
        amountToPay = data['amountToPay']
        cardholderName = data['cardholderName']
        cardNumber = data['cardNumber']
        message = data['message']

        customer = Customer.objects.get(pk=data['customer'])
        sale_rep = Sale_Rep.objects.get(pk=sale_rep_id)

        if quotation_id != 'none':
            invoice = Invoice.objects.get(pk=quotation_id)
            invoice.customer = customer
            invoice.service_date = service_date
            invoice.sale_rep = sale_rep
            # invoice.status = status
            # invoice.term = payment_type
            invoice.sale_tax = tax
            invoice.note = note
            invoice.status = 'Invoice'
            invoice.energy_surcharge = surcharge
            invoice.discount = discount
            invoice.sub_total = float(subtotal)
            invoice.deposit = deposit
            invoice.total = float(total)
        else:
            invoice = Invoice.objects.create(
                sale_rep = sale_rep,
                service_date = service_date,
                customer = customer,
                status = 'Invoice',
                term = payment_type,
                note = note,
                # sale_rep = 
                # shipment_date = models.DateField(null=True)
                sale_tax = tax,
                energy_surcharge = surcharge,
                discount = discount,
                sub_total = float(subtotal),
                deposit = deposit,
                total = float(total),
            )

        # if shipping_address is not None:
        #     shipping = Shipping_Address.objects.get(pk=shipping_address)
        #     invoice.shipping_address = shipping

        if billing_address is not None:
            # billing = Billing_Address.objects.get(pk=billing_address)
            invoice.billing_address = billing_address

        if data['site'] is not None:
            print('in')
            site = Work_Site.objects.get(pk=data['site'])
            invoice.work_site = site
        invoice.save()

        pattern = r'[1-9]'
        if re.search(pattern, amountToPay):
            invoice.balance = "{:.2f}".format(float(total)-float(amountToPay))
            invoice.save()
            Invoice_Payment.objects.create(
                invoice = invoice,
                type = payment_type,
                card_holder_name = cardholderName,
                card_no = cardNumber,
                message = message,
                paid_amount = float(amountToPay),
            )
        else:
            invoice.balance = "{:.2f}".format(float(total))
            invoice.save()

        for i in item:
            product = Product.objects.get(pk=i['product-id'])
            detail = Invoice_Detail.objects.create(
                invoice = invoice,
                product = product,
                amount = i['price'],
                qty = i['qty'],
                width = i['width'],
                height = i['height'],
                total = "{:.2f}".format(float(i['qty'])*float(i['price'])),
            )
            product.qty = product.qty - float(i['qty'])
            product.save()

        # if quotation_id != 'none':
        #     invoice.quotation = quotation
        #     invoice.save()

        return HttpResponse(invoice.id)
    
    today = date.today()
    customer = Customer.objects.filter(is_deleted=False).order_by('-id')

    if len(customer) > 0:
        site = Work_Site.objects.filter(customer=customer[0])
        # ship = Shipping_Address.objects.filter(customer=customer[0])
        # bill = Billing_Address.objects.filter(customer=customer[0])
    else:
        site = []
        ship = []
        bill = []

    product = Product.objects.all()
    sale_rep = Sale_Rep.objects.all().order_by('-id')
    quotation = Invoice.objects.filter(status='Quote').order_by('-id')
    context = {'quotation':quotation,'customer':customer, 'site':site, 'product':product, 'sale_rep':sale_rep,
               'is_from_quotation':False, 'today':today.strftime('%Y-%m-%d')}
    return render(request, 'pos_system/invoice/add-invoice.html', context)

@login_required
@api_view(['GET'])
def invoice_detail(request, id):
    config = Default_Config.objects.all().first()
    invoice = Invoice.objects.get(pk=id)
    # invoiceSeriaz = InvoiceSerializer(invoice).data
    detail = Invoice_Detail.objects.filter(invoice=invoice)
    # detailSeraiz = InvoiceDetailSerializer(detail, many=True).data
    payment = Invoice_Payment.objects.filter(invoice=invoice)
    # paymentSeraiz = InvoicePaymentSerializer(payment, many=True).data
    context = {'invoice': invoice, 'detail': detail, 'payment':payment, 'config':config}
    # context = {'invoice': invoice, 'detail': detail, 'payment':payment, 'img':'/static/images/email/email.jpg'}
    return render(request, 'pos_system/invoice/invoice_detail.html', context)
    # return render(request, 'pos_system/email/send_invoice.html', context)

@login_required
@api_view(['GET'])
def invoice_detail_api(request, id):
    invoice = Invoice.objects.get(pk=id)
    invoiceSeriaz = InvoiceSerializer(invoice).data
    product = Product.objects.all().order_by('-id')
    seraiz = ProductSerializer(product, many=True).data
    context = {'invoice': invoiceSeriaz, 'product':seraiz}
    return JsonResponse(context, safe=False)

@login_required
def add_invoice_from_quotaion(request,id):
    if request.method == 'POST':
        data = json.loads(request.body)
        item = data['item']

        # shipping_address = data['shipping_address']
        billing_address = data['billing_address']
        # status = data['status']
        note = data['note']
        payment_type = data['payment_type']
        tax = data['tax']
        sale_rep_id = data['sale_rep']
        service_date = data['service_date']
        discount = data['discount']
        deposit = data['deposit']
        surcharge = data['surcharge']
        subtotal = data['subtotal']
        total = data['total']
        amountToPay = data['amountToPay']
        cardholderName = data['cardholderName']
        cardNumber = data['cardNumber']
        message = data['message']

        customer = Customer.objects.get(pk=data['customer'])
        invoice = Invoice.objects.get(pk=id)
        sale_rep = Sale_Rep.objects.get(pk=sale_rep_id)

        invoice.customer = customer
        invoice.service_date = service_date
        invoice.sale_rep = sale_rep
        # invoice.status = status
        # invoice.term = payment_type
        invoice.sale_tax = tax
        invoice.note = note
        invoice.status = 'Invoice'
        invoice.energy_surcharge = surcharge
        invoice.discount = discount
        invoice.sub_total = float(subtotal)
        invoice.deposit = deposit
        invoice.total = float(total)

        # if shipping_address is not None:
        #     shipping = Shipping_Address.objects.get(pk=shipping_address)
        #     invoice.shipping_address = shipping

        if billing_address is not None:
            # billing = Billing_Address.objects.get(pk=billing_address)
            invoice.billing_address = billing_address

        if data['site'] is not None:
            site = Work_Site.objects.get(pk=data['site'])
            invoice.work_site = site
        invoice.save()

        pattern = r'[1-9]'
        if re.search(pattern, amountToPay):
            invoice.balance = "{:.2f}".format(float(total)-float(amountToPay))
            invoice.save()
            Invoice_Payment.objects.create(
                invoice = invoice,
                type = payment_type,
                card_holder_name = cardholderName,
                card_no = cardNumber,
                message = message,
                paid_amount = float(amountToPay),
            )
        else:
            invoice.balance = "{:.2f}".format(float(total))
            invoice.save()

        for i in item:
            product = Product.objects.get(pk=i['product-id'])
            detail = Invoice_Detail.objects.create(
                invoice = invoice,
                product = product,
                amount = i['price'],
                qty = i['qty'],
                width = i['width'],
                height = i['height'],
                total = "{:.2f}".format(float(i['qty'])*float(i['price'])),
            )
            product.qty = product.qty - float(i['qty'])
            product.save()
        return HttpResponse(invoice.id)
    
    customer = Customer.objects.filter(is_deleted=False).order_by('-id')
    if len(customer) > 0:
        site = Work_Site.objects.filter(customer=customer[0])
        # ship = Shipping_Address.objects.filter(customer=customer[0])
        # bill = Billing_Address.objects.filter(customer=customer[0])
    else:
        site = []
        ship = []
        bill = []
    product = Product.objects.all()
    quotation = Invoice.objects.get(pk=id)
    sale_rep = Sale_Rep.objects.all().order_by('-id')
    context = {'quotation':quotation,'customer':customer, 'site':site, 'product':product, 'sale_rep':sale_rep, 'is_from_quotation':True}
    return render(request, 'pos_system/invoice/add-invoice.html', context)



@login_required
@api_view(['GET'])
def onchange_work_site(request, cus_id):
    customer = Customer.objects.get(pk=cus_id)
    sites = Work_Site.objects.filter(customer=customer).exclude(street='')
    seriaz = WorkSiteSerializer(sites, many=True).data

    # billing = Billing_Address.objects.filter(customer=customer)
    # billSeraiz = BillingAddressSerializer(billing, many=True).data

    # shipping = Shipping_Address.objects.filter(customer=customer)
    # shipSeraiz = c=ShippingAddressSerializer(shipping, many=True).data

    # data = {'site':seriaz, 'bill':billSeraiz,'ship':shipSeraiz}
    data = {'site':seriaz}
    return Response(data)




@login_required
def unit(request):
    if request.method == 'POST':
        type = request.POST.get('type')
        name = request.POST.get('name')
        unitId = request.POST.get('unit')
        conversion_rate = request.POST.get('conversion_rate')

        try:
            unit = Unit.objects.get(pk=unitId)
        except:
            pass

        if type == 'edit':
            id = request.POST.get('unitId')
            cat = Unit.objects.get(pk=id)
            cat.name = name
            cat.refunit = unit
            cat.conversion_rate = conversion_rate
            cat.save()
            messages.success(request, 'Unit Updated Successfully')
        else:            
            u = Unit.objects.create(
                name = name,
                conversion_rate = conversion_rate
            )
            u.refunit = u
            u.save()
            messages.success(request, 'Unit Added Successfully')
        
        return redirect('unit')
    
    units = Unit.objects.all().order_by('-id')
    context = {'unit':units}
    return render(request, 'pos_system/product/unit.html', context)

@login_required
@api_view(['GET'])
def edit_unit(request, id):
    category = Unit.objects.get(pk=id)
    Seriaz = UnitSerializer(category).data
    return Response(Seriaz)


@login_required
def delete_unit(request, id):
    customer  = Unit.objects.get(pk=id).delete()
    return redirect('unit')




# invoice data
@login_required
def quotation(request):
    # items_per_page = 20
    # queryset = Invoice.objects.filter(status='Quote').order_by('-id')

    # paginator = Paginator(queryset, items_per_page)

    # page_number = request.GET.get('page')
    # page_obj = paginator.get_page(page_number)
    customers = Customer.objects.filter(is_deleted=False)

    context = {'page_obj': [], 'customers': customers}
    return render(request, 'pos_system/quotation/quotation.html', context)

@login_required
def edit_quotation(request, id):

    quotation = Invoice.objects.get(pk=id)
    detail = Invoice_Detail.objects.filter(invoice=quotation)
    if request.method == 'POST':
        data = json.loads(request.body)
        item = data['item']

        # shipping_address = data['shipping_address']
        billing_address = data['billing_address']
        sale_rep_id = data['sale_rep']
        service_date = data['service_date']
        tax = data['tax']
        discount = data['discount']
        surcharge = data['surcharge']
        subtotal = data['subtotal']
        total = data['total']


        customer = Customer.objects.get(pk=data['customer'])
        sale_rep = Sale_Rep.objects.get(pk=sale_rep_id)

        quotation.customer = customer
        quotation.sale_rep = sale_rep
        quotation.service_date = service_date
        quotation.sale_tax = tax
        quotation.energy_surcharge = surcharge
        quotation.discount = discount
        quotation.sub_total = float(subtotal)
        quotation.total = float(total)

        # if shipping_address is not None:
        #     shipping = Shipping_Address.objects.get(pk=shipping_address)
        #     quotation.shipping_address = shipping

        if billing_address is not None:
            # billing = Billing_Address.objects.get(pk=billing_address)
            quotation.billing_address = billing_address

        if data['site'] is not None:
            site = Work_Site.objects.get(pk=data['site'])
            quotation.work_site = site

        quotation.save()


        # deleteing all quotation details
        detail = Invoice_Detail.objects.filter(invoice=quotation).delete()

        # Now again cretaing Quotation detail
        for i in item:
            product = Product.objects.get(pk=i['product-id'])
            detail = Invoice_Detail.objects.create(
                invoice = quotation,
                product = product,
                amount = i['price'],
                qty = i['qty'],
                width = i['width'],
                height = i['height'],
                total = "{:.2f}".format(float(i['qty'])*float(i['price'])),
            )
                
            # subtotal += float(i['price']) * float(i['qty'])

        return HttpResponse(quotation.id)
    
    customer = Customer.objects.filter(is_deleted=False).order_by('-id')
    site = Work_Site.objects.filter(customer=customer[0])
    product = Product.objects.all()
    sale_rep = Sale_Rep.objects.all().order_by('-id')
    # ship = Shipping_Address.objects.all()
    # bill = Billing_Address.objects.all()
    context = {'sale_rep':sale_rep,'customer':customer, 'site':site, 'product':product, 'quotation':quotation, 'detail':detail}
    return render(request, 'pos_system/quotation/edit-quotation.html', context)

@login_required
def add_quotation(request, id):
    if request.method == 'POST':
        data = json.loads(request.body)
        item = data['item']

        # shipping_address = data['shipping_address']
        sale_rep_id = data['sale_rep']
        billing_address = data['billing_address']
        tax = data['tax']
        discount = data['discount']
        service_date = data['service_date']
        deposit = data['deposit']
        surcharge = data['surcharge']
        subtotal = data['subtotal']
        total = data['total']

        customer = Customer.objects.get(pk=data['customer'])
        sale_rep = Sale_Rep.objects.get(pk=sale_rep_id)
        dat = dateTime().split(' ')[0]
        quotation = Invoice.objects.create(
            service_date = service_date,
            customer = customer,
            sale_rep = sale_rep,
            status = 'Quote',
            sale_tax = tax,
            energy_surcharge = surcharge,
            discount = discount,
            sub_total = float(subtotal),
            deposit = deposit,
            total = float(total),
            created_at = dat,
        )

        # if shipping_address is not None:
        #     shipping = Shipping_Address.objects.get(pk=shipping_address)
        #     quotation.shipping_address = shipping
        #     quotation.save()

        if billing_address is not None:
            # billing = Billing_Address.objects.get(pk=billing_address)
            quotation.billing_address = billing_address
            quotation.save()

        if data['site'] is not None:
            site = Work_Site.objects.get(pk=data['site'])
            quotation.work_site = site
            quotation.save()


        for i in item:
            product = Product.objects.get(pk=i['product-id'])
            detail = Invoice_Detail.objects.create(
                invoice = quotation,
                product = product,
                amount = i['price'],
                qty = i['qty'],
                width = i['width'],
                height = i['height'],
                total = "{:.2f}".format(float(i['qty'])*float(i['price'])),
            )
        return HttpResponse(quotation.id)
    
    today = date.today()
    customer = Customer.objects.filter(is_deleted=False).order_by('-id')
    product = Product.objects.all()
    sale_rep = Sale_Rep.objects.all().order_by('-id')
    if len(customer) > 0:
        site = Work_Site.objects.filter(customer=customer[0])
        # ship = Shipping_Address.objects.filter(customer=customer[0])
        # bill = Billing_Address.objects.filter(customer=customer[0])
    else:
        site = []
        ship = []
        bill = []

    context = {'customer':customer, 'site':site, 'product':product, 'sale_rep':sale_rep, 
               'today':today.strftime('%Y-%m-%d')}
    return render(request, 'pos_system/quotation/add-quotation.html', context)

@login_required
@api_view(['GET'])
def quotation_detail(request, id):
    print('***********',id)
    config = Default_Config.objects.all().first()
    quotation = Invoice.objects.get(pk=id)
    detail = Invoice_Detail.objects.filter(invoice=quotation)
    context = {'quotation': quotation, 'detail': detail, 'config':config}
    return render(request, 'pos_system/quotation/quotation_detail.html', context)

@login_required
@api_view(['GET'])
def quotation_detail_api(request, id):
    quotation = Invoice.objects.get(pk=id)
    quotationSeriaz = QuotationSerializer(quotation).data
    product = Product.objects.all().order_by('-id')
    seraiz = ProductSerializer(product, many=True).data
    context = {'quotation': quotationSeriaz, 'product':seraiz}
    return JsonResponse(context, safe=False)








# reports 
@login_required
def balance_due_report(request):
    customers = Customer.objects.filter(is_deleted=False)
    customer_id = 0
    if request.method == 'POST':
        customer_id = request.POST.get('customer')
        froms = request.POST.get('from_date')
        to = request.POST.get('to_date')

        if customer_id == '0':
            invoices_by_customer = Invoice.objects.filter(Q(status='Invoice') & Q(created_at__gte = parse_datetime(froms)) & Q(created_at__lte = parse_datetime(to))).values('customer').annotate(total_amount=Sum('total'), total_balance=Sum('balance'))

            customer_data = []
            for customer_info in invoices_by_customer:
                customer = customer_info['customer']
                total_amount = round(customer_info['total_amount'], 2)
                total_balance = round(customer_info['total_balance'], 2)
                
                print(customer)
                customer_obj = Customer.objects.get(id=customer)
                invoices = Invoice.objects.filter(Q(status='Invoice') & Q(customer=customer_obj) & Q(created_at__gte = parse_datetime(froms)) & Q(created_at__lte = parse_datetime(to))).exclude(balance__lte=0)
                if len(invoices) > 0:
                    customer_data.append({'customer': customer_obj, 'invoices': invoices, 'total':total_amount, 'balance':total_balance})

            context = {'customer_data':customer_data,'from':froms, 'to':to, 'customers':customers, 'customer_id':int(customer_id)}
        else:
            customer_obj = Customer.objects.get(id=customer_id)
            invoices= Invoice.objects.filter(Q(customer=customer_obj) & Q(created_at__gte = parse_datetime(froms)) & Q(created_at__lte = parse_datetime(to)))
            prices = invoices.aggregate(total_amount=Sum('total'), total_balance=Sum('balance'))

            customer_data = []
            total_amount = 0.0
            total_balance = 0.0
            if prices['total_amount']: total_amount = round(prices['total_amount'], 2)
            if prices['total_balance']: total_balance = round(prices['total_balance'], 2)
                
            customer_data.append({'customer': customer_obj, 'invoices': invoices, 'total':total_amount, 'balance':total_balance})

            context = {'customer_data':customer_data,'from':froms, 'to':to, 'customers':customers, 'customer_id':int(customer_id)}

        return render(request, 'pos_system/reports/balance_due_report.html', context)
    
    today = date.today()
    invoices_by_customer = Invoice.objects.filter(Q(created_at__gte = today) & Q(created_at__lte = today)).values('customer').annotate(total_amount=Sum('total'), total_balance=Sum('balance'))

    customer_data = []
    for customer_info in invoices_by_customer:
        customer = customer_info['customer']
        total_amount = round(customer_info['total_amount'], 2)
        total_balance = round(customer_info['total_balance'], 2)
        
        customer_obj = Customer.objects.get(id=customer)
        invoices = Invoice.objects.filter(Q(customer=customer_obj) & Q(created_at__gte = today) & Q(created_at__lte = today)).exclude(balance__lte=0)
        if len(invoices) > 0:
            customer_data.append({'customer': customer_obj, 'invoices': invoices, 'total':total_amount, 'balance':total_balance})

    today = today.strftime('%Y-%m-%d')
    context = {'customer_data':customer_data, 'from':today, 'to':today, 'customers':customers, 'customer_id':customer_id}
    return render(request, 'pos_system/reports/balance_due_report.html', context)

@login_required
def product_by_category(request):
    allCat = Product_Category.objects.all()
    seriaz = ProductCategorySerializer(allCat, many=True).data
    context = {'category':seriaz, 'allcategory':allCat, 'catId': 'all'}
    if request.method == 'POST':
        catId = request.POST.get('category')
        if catId == 'all':
            category = Product_Category.objects.all()
        else:
            category = Product_Category.objects.filter(pk=catId)
        seriaz = ProductCategorySerializer(category, many=True).data
        context = {'category':seriaz, 'allcategory':allCat, 'catId': catId}
    return render(request, 'pos_system/reports/product_by_category.html', context)

@login_required
def product_sale_report(request):

    all_products = Product.objects.all()

    data_invoice = []
    data_quote = []
    data_cancel = []
    if request.method == 'POST':
        froms = request.POST.get('from_date')
        to = request.POST.get('to_date')
        product_id = request.POST.get('product')

        if product_id != '0': products = Product.objects.filter(pk=product_id)

        for product in products:
            quotes = Invoice_Detail.objects.filter(Q(product=product) & Q(invoice__status='Quote') & Q(invoice__created_at__gte = parse_datetime(froms)) & Q(invoice__created_at__lte = parse_datetime(to)))
            quote_total = quotes.aggregate(Sum('total'))['total__sum'] or 0

            if len(quotes) > 0:
                data_quote.append({
                    'list':quotes,
                    'total': round(quote_total, 2),
                })

            invoices = Invoice_Detail.objects.filter(Q(product=product) & Q(invoice__status='Invoice') & Q(invoice__created_at__gte = parse_datetime(froms)) & Q(invoice__created_at__lte = parse_datetime(to)))
            invoice_total = invoices.aggregate(Sum('total'))['total__sum'] or 0

            if len(invoices) > 0:
                data_invoice.append({
                    'list':invoices,
                    'total': round(invoice_total, 2),
                })

            cancels = Invoice_Detail.objects.filter(Q(product=product) & Q(invoice__status='Cancel') & Q(invoice__created_at__gte = parse_datetime(froms)) & Q(invoice__created_at__lte = parse_datetime(to)))
            cancel_total = cancels.aggregate(Sum('total'))['total__sum'] or 0

            if len(cancels) > 0:
                data_cancel.append({
                    'list':cancels,
                    'total': round(cancel_total, 2),
                })
            
        data = [
            {'des':'Quote', 'detail':data_quote},
            {'des':'Cancel', 'detail':data_cancel},
            {'des':'Invoice', 'detail':data_invoice},
        ]
        context = {'data': data,'from':froms, 'to':to, 'products':all_products, 'product_id': int(product_id)}
        print(context)

        return render(request, 'pos_system/reports/product_sale_report.html', context)
    
    today = date.today()
    # for product in products:
    #     quotes = Invoice_Detail.objects.filter(Q(product=product) & Q(invoice__status='Quote') & Q(invoice__created_at__gte =today) & Q(invoice__created_at__lte =today))
    #     quote_total = quotes.aggregate(Sum('total'))['total__sum'] or 0

    #     if len(quotes) > 0:
    #         data_quote.append({
    #             'list':quotes,
    #             'total': quote_total,
    #         })

    #     invoices = Invoice_Detail.objects.filter(Q(product=product) & Q(invoice__status='Invoice') & Q(invoice__created_at__gte =today) & Q(invoice__created_at__lte =today))
    #     invoice_total = invoices.aggregate(Sum('total'))['total__sum'] or 0

    #     if len(invoices) > 0:
    #         data_invoice.append({
    #             'list':invoices,
    #             'total': invoice_total,
    #         })

    #     cancels = Invoice_Detail.objects.filter(Q(product=product) & Q(invoice__status='Cancel') & Q(invoice__created_at__gte =today) & Q(invoice__created_at__lte =today))
    #     cancel_total = cancels.aggregate(Sum('total'))['total__sum'] or 0

    #     if len(cancels) > 0:
    #         data_cancel.append({
    #             'list':cancels,
    #             'total': cancel_total,
    #         })
        
    # data = [
    #     {'des':'Quote', 'detail':data_quote},
    #     {'des':'Cancel', 'detail':data_cancel},
    #     {'des':'Invoice', 'detail':data_invoice},
    # ]
    today = today.strftime('%Y-%m-%d'), 
    context = {'data': [],  'from':today, 'to':today, 'products':all_products}
    # products = Product.objects.annotate(total_qty=Sum('invoice_product__qty'),total_amount=Sum(F('invoice_product__qty')*F('invoice_product__amount')))
    # context = {'product': products}
    return render(request, 'pos_system/reports/product_sale_report.html', context)

@login_required
def active_customers(request):
    customer = Customer.objects.filter(is_deleted=False)
    context = {'customer':customer}
    return render(request, 'pos_system/reports/active_customer.html', context)







# view encrypted url invoice details from email
def secure_invoice_detail(request,token):
    try: id = signing.loads(token)
    except: return HttpResponse('Link is not valid. Plz click the button again from mail send to you from DUNRITE GLASS CO. LTD')
    invoice = Invoice.objects.get(pk=id)
    config = Default_Config.objects.all().first()
    detail = Invoice_Detail.objects.filter(invoice=invoice)
    payment = Invoice_Payment.objects.filter(invoice=invoice)
    context = {'invoice': invoice, 'detail': detail, 'payment':payment, 'config':config}
    return render(request, 'pos_system/invoice/secure_invoice_detail.html', context)

@login_required
def send_invoice(request,id):
    email_send_invoice(request, id)
    messages.success(request, 'Mail sent Successfully.')
    return redirect('detail_invoice',id=id)


# view encrypted url invoice details from email
def secure_quotation_detail(request,token):
    try: id = signing.loads(token)
    except: return HttpResponse('Link is not valid. Plz click the button again from mail send to you from DUNRITE GLASS CO. LTD')
    config = Default_Config.objects.all().first()
    quotation = Invoice.objects.get(pk=id)
    detail = Invoice_Detail.objects.filter(quotation=quotation)
    context = {'quotation': quotation, 'detail': detail, 'config':config}
    return render(request, 'pos_system/quotation/secure_quotation_detail.html', context)

@login_required
def send_quotation(request,id):
    email_send_quotation(request, id)
    messages.success(request, 'Mail sent Successfully.')
    return redirect('detail_quotation',id=id)



@login_required
def add_work_site(request, cus_id):
    if request.method == 'POST':
        name = request.POST.get('name')
        address = request.POST.get('address')
        start_date = request.POST.get('start_date')

        customer = Customer.objects.get(pk=cus_id)

        cust = Work_Site.objects.create(
            customer=customer,
            name = name,
            address = address,
            start_date = start_date,
        )
        messages.success(request,'Work Site added Successfully')
        return redirect('/work-sites/'+str(customer.id))

    return render(request, 'pos_system/worksite/add-work-site.html')

@login_required
def all_work_site(request):
    sites = Work_Site.objects.filter(is_deleted=False)
    context = {'work_site':sites, 'is_all_sites': True}
    return render(request, 'pos_system/worksite/work-site.html', context)

@login_required
def add_all_work_site(request):
    if request.method == 'POST':
        cus_id = request.POST.get('customer')
        name = request.POST.get('name')
        address = request.POST.get('address')
        start_date = request.POST.get('start_date')
        
        customer = Customer.objects.get(pk=cus_id)

        cust = Work_Site.objects.create(
            customer=customer,
            name = name,
            address = address,
            start_date = start_date,
        )
        messages.success(request,'Work Site added Successfully')        
        return redirect('/work-sites')

    customer = Customer.objects.filter(is_deleted=False)
    context = {'customer':customer}
    return render(request, 'pos_system/worksite/add-all-work-site.html', context)




