dasaproject/django/Invoice/views.py
2023-12-29 04:41:31 +07:00

528 lines
23 KiB
Python

from django.shortcuts import render, get_object_or_404, redirect
from django.urls import reverse
from django.http import HttpResponse, JsonResponse
from django.forms import modelformset_factory, inlineformset_factory
from django.db import transaction
from django.core import serializers
from .models import Invoice, InvoiceItemLine
from Item.models import Item, PriceLevel, PriceLevelItem
from Customer.models import Customer
from .forms import InvoiceForm, InvoiceItemLineForm, GeeksForm
import json
from django.core.serializers.json import DjangoJSONEncoder
from django.contrib import messages
import os
import pandas as pd
from django.conf import settings
from icecream import ic
ic.configureOutput(includeContext= True)
def get_SalesOrderQuery(customer_name):
try:
print("try")
from SO_to_Inv.readSO import SalesOrderQuery
except:
import sys
sys.path.append('.')
sys.path.append('..')
print("except")
print(sys.path)
from SO_to_Inv.readSO import SalesOrderQuery
print("salesorderquery imported")
# print(os.getcwd())
# parentdir = os.path.dirname(os.getcwd())
# print(parentdir)
basedir = settings.BASE_DIR
parentdir = os.path.dirname(basedir)
ini=SalesOrderQuery(FullName= customer_name, IncludeRetElement = ['TxnID', 'TimeCreated', 'TimeModified','TxnNumber', 'CustomerRef', 'TxnDate', 'RefNumber', 'IsManuallyClosed', 'IsFullyInvoiced','TotalAmount'], cwd=parentdir)
return ini
return None
def show_customer(request):
pass
# thispath = os.getcwd()
# print(thispath)
basedir = settings.BASE_DIR
parent = os.path.dirname(basedir)
print(f'parent dir= {parent}')
print(f"Base_DIR: {settings.BASE_DIR}")
customers_file = os.path.join(parent, "ItemInventory", "CustomerList.xlsx")
df = pd.read_excel(customers_file, usecols=["FullName"])
context={"customers": df.values.tolist()}
if request.method =="POST":
customer_name = request.POST.get("customerreffullname")
print(f'customer_name: {customer_name}')
context['objects'] = [['abc', 'def', 'ghi', 'jkl']]
context['objects'] = []
if customer_name:
ini = get_SalesOrderQuery(customer_name)
if ini:
print("after ini")
qbxml = ini.create_QBXML()
print(qbxml)
response_string = ini.connect_to_quickbooks(qbxml)
print(response_string)
open_sales_orders = ini.get_open_so()
print(f'open sales orders:{open_sales_orders}')
ini=None
if open_sales_orders:
context['objects'] = open_sales_orders
context['customer_fullname'] = customer_name
return render(request, "Invoice/so_list_form.html", context)
# print(df.values.tolist())
return render(request, "Invoice/show-customers.html", context)
def select_so(request):
pass
def choose_inv(request):
print("choose_inv")
context={}
if request.method == "POST":
print(request.POST)
data = dict(request.POST)
del data['csrfmiddlewaretoken']
del data['customer_fullname']
# if 'other_items' in data:
# del data['other_items']
# del data['other_qty']
# del data['other_rate']
# del data['selected_items']
print(f"datadict:{data}")
try:
df = pd.DataFrame(data)
print(df)
except:
print(Exception)
return HttpResponse("DataFrame Error")
print(f'json:{df.to_json(orient="records")}')
print(df.to_dict("records"))
if ('so_field' in request.POST) and ('customer_fullname' in request.POST):
print(request.POST.getlist('so_field'))
open_sales_orders_TxnID = request.POST.getlist('so_field')
customer_fullname = request.POST.get('customer_fullname')
print(f'Customer_fullname:{customer_fullname} -> request values:{open_sales_orders_TxnID}')
### get the SO detail
ini=get_SalesOrderQuery(customer_fullname)
print(f'ini::{ini}')
print("before ITU")
itu = ini.get_open_sales_order(open_sales_orders_TxnID)
# print(itu)
print(f'get_open_sales_order:{itu}')
if itu:
context['objects'] = itu
context['customer_fullname'] = customer_fullname
print("Invoiceaddqbxml:")
invoiceaddQBXML=ini.create_invoiceadd_QBXML()
print(invoiceaddQBXML)
result=None
# result = ini.connect_to_quickbooks(ini.create_invoiceadd_QBXML())
print("RESULT:")
print(result)
return render(request, "Invoice/so_details_form.html", context)
elif 'customer_fullname' in request.POST:
customer_name = request.POST.get('customer_fullname')
ini = get_SalesOrderQuery(customer_name)
if ini:
print("after ini")
qbxml = ini.create_QBXML()
# print(qbxml)
response_string = ini.connect_to_quickbooks(qbxml)
print(response_string)
open_sales_orders = ini.get_open_so()
print(f'open sales orders:{open_sales_orders}')
ini=None
if open_sales_orders:
context['objects'] = open_sales_orders
context['customer_fullname'] = customer_name
return render( request, "Invoice/so_list_form.html", context)
# return HttpResponse('')
def unique(list1):
# insert the list to the set
list_set = set(list1)
# convert the set to the list
unique_list = (list(list_set))
return unique_list
def save_inv(request):
print("save_inv")
context={}
if request.method == "POST":
# print(request.POST)
data = dict(request.POST)
del data['csrfmiddlewaretoken']
del data['customer_fullname']
if 'other_items' in data:
del data['other_items']
del data['other_qty']
del data['other_rate']
if 'selected_items' in data:
del data['selected_items']
# print(f"datadict:{data}")
try:
df = pd.DataFrame(data)
print(df)
except:
print(Exception)
return HttpResponse("DataFrame Error")
# print(f'json:{df.to_json(orient="records")}')
web_dict = df.to_dict("records")
# print(f'web_dict:{web_dict}' )
web_dict = sorted(web_dict, key=lambda x: x['TxnLineID'])
# print(f'Sorted web_dict:{web_dict}' )
if ('so_field' in request.POST) and ('customer_fullname' in request.POST):
print(request.POST.getlist('so_field'))
open_sales_orders_TxnID = unique(request.POST.getlist('so_field'))
customer_fullname = request.POST.get('customer_fullname')
print(f'Customer_fullname:{customer_fullname} -> request values:{open_sales_orders_TxnID}')
### get the SO detail
ini=get_SalesOrderQuery(customer_fullname)
print(f'ini::{ini}')
print("before ITU")
itu = ini.get_open_sales_order(open_sales_orders_TxnID)
# print(itu)
itu = sorted(itu, key=lambda x: x['TxnID'])
print(f'get_open_sales_order:{itu}')
if itu:
### do the checking web_dict and openSO ###
data_to_save = []
dict_ = {}
txnids = []
disc_amount = 0
for web in web_dict:
for tu_ in itu:
# print(tu_)
if web['TxnID'] == tu_['TxnID'] and web['TxnDate'] == tu_['TxnDate'] and web['RefNumber'] == tu_['RefNumber']:
if web['TxnID'] not in txnids: # new txn
if dict_:
dict_['Disc_Amount']=disc_amount
data_to_save.append(dict_)
dict_ = {'RefNumber': web['RefNumber'], 'CustomerFullName': tu_['CustomerFullName'], 'TxnID': web['TxnID'],
'TxnDate': web['TxnDate'], 'TxnNumber': tu_['TxnNumber'],
'TotalAmount': '0.00', 'IsFullyInvoiced': tu_['IsFullyInvoiced'], 'IsManuallyClosed': tu_['IsManuallyClosed'],
'SalesOrderLineRet': [] }
disc_amount = 0
txnids.append(web['TxnID'])
txnids = unique(txnids) ### not usefull
for tu_line_ret in tu_['SalesOrderLineRet']:
# print(tu_line_ret)
if web['TxnLineID']==tu_line_ret['TxnLineID'] and web['ItemFullName']==tu_line_ret['ItemFullName']:
if 0 < float(web['backordered']) <= float(tu_line_ret['BackOrdered']):
# print('put in list')
discPerPcs=0
discPerItem=0
if float(web['rate']) == float(tu_line_ret['Rate']):
discPerPcs = ini.get_discperpcs(web['ItemFullName'], float(web['rate']))
elif float(web['rate']) < float(tu_line_ret['Rate']):
discPerPcs = float(tu_line_ret['Rate']) - float(web['rate'])
discPerItem = float(web['backordered']) * discPerPcs
disc_amount += discPerItem
SalesOrderLinedict = {'TxnLineID':web['TxnLineID'],
'ItemFullName':web['ItemFullName'],
'Quantity':tu_line_ret['Quantity'],
'UOM':tu_line_ret['UOM'],
'Rate':float(web['rate']),
'Amount':float(tu_line_ret['Amount']),
'BackOrdered':float(web['backordered']),
'Invoiced':tu_line_ret['Invoiced'],
'LineIsManuallyClosed':tu_line_ret['LineIsManuallyClosed'],
'discPerItem':discPerItem, # backorder qty * disc per pcs
'discPerPcs':discPerPcs,
}
# print(f'salesorderlineddict:{SalesOrderLinedict}')
_salesorderlineret = dict_['SalesOrderLineRet']
_salesorderlineret.append(SalesOrderLinedict)
dict_['SalesOrderLineRet'] = _salesorderlineret
break
break
print(f'last:{dict_}')
if dict_ != data_to_save[-1]:
dict_['Disc_Amount']=disc_amount
data_to_save.append(dict_)
print('save the last dict')
else:
print('last data to save == dict')
print(f'Final List:{data_to_save}')
print("")
# print(itu)
context['objects'] = itu
context['customer_fullname'] = customer_fullname
print(context['objects'])
print("Invoiceaddqbxml:")
invoiceaddQBXML=ini.create_invoiceadd_QBXML(data_to_save)
print(invoiceaddQBXML)
result=None
# result = ini.connect_to_quickbooks(ini.create_invoiceadd_QBXML())
print("RESULT:")
print(result)
return render(request, "Invoice/so_details_form.html", context)
else:
return HttpResponse(f"You cannot Save, because There Is No Open Sales Order for Customer: {customer_fullname}")
elif 'customer_fullname' in request.POST:
customer_name = request.POST.get('customer_fullname')
ini = get_SalesOrderQuery(customer_name)
if ini:
print("after ini")
qbxml = ini.create_QBXML()
# print(qbxml)
response_string = ini.connect_to_quickbooks(qbxml)
print(response_string)
open_sales_orders = ini.get_open_so()
print(f'open sales orders:{open_sales_orders}')
ini=None
if open_sales_orders:
context['objects'] = open_sales_orders
context['customer_fullname'] = customer_name
return render( request, "Invoice/so_list_form.html", context)
# return HttpResponse('')
def index(request):
print("index Inv")
context = {}
context['objects'] = Invoice.objects.order_by('-TimeCreated')
context['addurl'] = reverse('Invoice:add_so')
return render(request, "Invoice/index_invoice.html", context=context)
DEMO_CHOICES2 =(
("10", "Naveen"),
("20", "Pranav"),
("30", "Isha"),
("40", "Saloni"),
("50", "Sg"),
)
def home_view(request):
if request.method == "POST":
print(request.POST)
if 'geeks_field' in request.POST:
print(request.POST.getlist('geeks_field'))
multivals = request.POST.getlist('geeks_field')
print(multivals)
form = GeeksForm(request.POST)
if form.is_valid():
print('good')
demochc = ()
for i in range(2,6):
demochc += ((i, str(i)))
context = {}
print (demochc)
form = GeeksForm()
# form.fields['geeks_field'].choices = demochc
context['form'] = form
return render( request, "Invoice/home.html", context)
def add_so(request, pk=None):
print("add INV")
context = {}
obj=None
plname = None
if pk:
obj = get_object_or_404(Invoice.objects.select_related(), pk=pk)
# obj = get_object_or_404(Invoice, pk=pk)
plname = obj.CustomerRefFullName.PriceLevelRefFullName.Name
# print(f"{obj.CustomerRefFullName.PriceLevelRefFullName.Name}")
form = InvoiceForm(request.POST or None, instance=obj)
# InvoiceItemLineFormset = modelformset_factory(InvoiceItemLine, form=InvoiceItemLineForm, extra=0) #cannot use extra >0 because the formset is zip with the qs below
InvoiceItemLineFormset = inlineformset_factory(Invoice, InvoiceItemLine, form=InvoiceItemLineForm, extra=0) #cannot use extra >0 because the formset is zip with the qs below
# InvoiceItemLineFormset = modelformset_factory(InvoiceItemLine, fields = ('ItemRefFullName', 'Desc', 'Quantity', 'UnitOfMeasure', 'Rate', 'Amount', 'Invoiced', 'LineIsManuallyClosed',), extra=1)
# InvoiceItemLineFormset = modelformset_factory(InvoiceItemLine, fields = ('ItemRefFullName', 'Desc', 'Quantity', 'UnitOfMeasure', 'Rate', 'Amount', 'Invoiced', 'LineIsManuallyClosed',), extra=1)
qs=None
formset = InvoiceItemLineFormset(request.POST or None)
if pk:
print("got ID")
qs = obj.invoiceitemline_set.all().order_by('id').select_related('ItemRefFullName')
# formset = InvoiceItemLineFormset(request.POST or None, queryset=qs)
formset = InvoiceItemLineFormset(request.POST or None, instance=obj)
print(request.POST)
# print(formset)
# print(len(formset))
# print(f"queryset={qs}")
# print(f"queryset={qs[0].ItemRefFullName}")
# qsItemList = list(x.ItemRefFullName for x in qs)
# print(qsItemList)
print(f'plname:{plname}')
qsIn = Item.objects.filter(itempricelevel__PL__Name=plname).prefetch_related("itempricelevel").values('id', 'FullName','SalesDesc', 'SalesPrice', 'itempricelevel__Price')
qsEx = Item.objects.exclude(itempricelevel__PL__Name=plname).prefetch_related("itempricelevel").values( "id", "FullName", "SalesDesc", "SalesPrice", "AlwaysNull")
# print(qsIn)
# print("qsEx")
# print(qsEx)
context['itemdatalist'] = qsIn.union(qsEx)
context['object'] = obj
context['qsformset'] = None
if pk:
context['qsformset'] = list(zip(qs, formset))
if request.method == "POST":
with transaction.atomic():
if form.is_valid():
# print(form.cleaned_data)
# with transaction.atomic():
# print(formset)
if formset.is_valid():
for delform in formset.deleted_forms:
pass
totalamount=form.cleaned_data['TotalAmount']
print(totalamount, type(totalamount))
totalamountChildren=0
for fm in formset:
# print(fm)
print(fm['DELETE'].value())
if not fm['DELETE'].value() and 'Amount' in fm.cleaned_data:
# print(fm.cleaned_data['Amount'])
amount=fm.cleaned_data['Amount']
# print(amount)
print(fm['DELETE'].value())
totalamountChildren+=amount
print(totalamountChildren)
if totalamount==totalamountChildren:
print("correct total amount")
else:
print(f"not correct total amount:{totalamount} supposed={totalamountChildren}")
# form.cleaned_data['TotalAmount'] = totalamountChildren
parentobj = form.save(commit=False)
parentobj.TotalAmount = totalamountChildren
parentobj.save()
# print(parentobj)
print("formset valid")
instances = formset.save(commit=False)
for obj in formset.deleted_objects:
print("deelted object")
print(obj)
obj.delete()
for instance in instances:
# print(instance.ItemRefFullName)
# print(instance.pk)
# print(parentobj.id)
instance.Invoice = parentobj
instance.save()
context['message'] = "All Data Saved"
print("all formset saved")
print(parentobj.pk, type(parentobj.pk))
print(reverse('Invoice:edit_so', args=[parentobj.pk]))
messages.success(request, "All Data is Saved")
return redirect(reverse('Invoice:edit_so', args=[parentobj.pk]))
else:
print("formset error")
print(formset.errors)
else:
print("form error")
print(form.errors)
context['form'] = form
context['formset'] = formset
return render(request, "Invoice/create-update.html", context=context)
# def add_so(request):
# print("create SO")
# context = {}
# # obj = get_object_or_404(Invoice, pk=id)
# obj=None
# form = InvoiceForm(request.POST or None, )
# InvoiceItemLineFormset = modelformset_factory(InvoiceItemLine, form=InvoiceItemLineForm, extra=1)
# # qs = obj.invoiceitemline_set.all()
# qs=None
# formset = InvoiceItemLineFormset(request.POST or None, )
# context['form'] = form
# context['formset'] = formset
# context['object'] = obj
# if all([form.is_valid(), formset.is_valid()]):
# print(form.cleaned_data)
# for form in formset:
# print(form.clean_data)
# context['message'] = "All Data saved"
# return render(request, "Invoice/create-update.html", context=context)
def getpricelist_so(request, pk=None):
print(f"getpricelist INV; pk={pk}")
context = {}
obj=None
plname = None
if pk:
# obj = get_object_or_404(Invoice.objects.select_related(), pk=pk)
obj = get_object_or_404(Customer.objects.select_related(), pk=pk)
plname = obj.PriceLevelRefFullName.Name
# print(f"{obj.CustomerRefFullName.PriceLevelRefFullName.Name}")
# form = InvoiceForm(request.POST or None, instance=obj)
# InvoiceItemLineFormset = inlineformset_factory(Invoice, InvoiceItemLine, form=InvoiceItemLineForm, extra=0) #cannot use extra >0 because the formset is zip with the qs below
print(obj)
qs=None
# formset = InvoiceItemLineFormset(request.POST or None)
# if pk:
# print("got ID")
# qs = obj.invoiceitemline_set.all().order_by('id').select_related('ItemRefFullName')
# # formset = InvoiceItemLineFormset(request.POST or None, queryset=qs)
# formset = InvoiceItemLineFormset(request.POST or None, instance=obj)
print(request.GET)
# print(len(formset))
# print(f"queryset={qs}")
# print(f"queryset={qs[0].ItemRefFullName}")
# qsItemList = list(x.ItemRefFullName for x in qs)
# print(qsItemList)
print(f'plname1:{plname}')
qsIn = Item.objects.filter(itempricelevel__PL__Name=plname).prefetch_related("itempricelevel").values('id', 'FullName','SalesDesc', 'SalesPrice', 'itempricelevel__Price')
qsEx = Item.objects.exclude(itempricelevel__PL__Name=plname).prefetch_related("itempricelevel").values( "id", "FullName", "SalesDesc", "SalesPrice", "AlwaysNull")
context['itemdatalist'] = qsIn.union(qsEx)
serialized_q = json.dumps(list( context['itemdatalist']), cls=DjangoJSONEncoder)
# p=json.loads(serialized_q)
print(f'serialized_q:{serialized_q}')
serialized_obj = serializers.serialize('json', [ obj, ])
context['obj'] = serialized_obj
context['itemdatalist'] = serialized_q
# serialized_q = serialized_q + serialized_obj
# print(serialized_obj)
data = json.dumps(context, indent=4, sort_keys=True, default=str)
# print(data)
# print(serialized_q)
return JsonResponse(data, safe=False)
def edit_so(request):
print("Edit SO")
context = {}
obj = get_object_or_404(Invoice, pk=id)
form = InvoiceForm(request.POST or None, instance=obj)
InvoiceItemLineFormset = modelformset_factory(InvoiceItemLine, form=InvoiceItemLineForm, extra=1)
qs = obj.invoiceitemline_set.all()
formset = InvoiceItemLineFormset(request.POST or None, isinstance=qs)
context['form'] = form
context['formset'] = formset
context['object'] = obj
if all([form.is_valid(), formset.is_valid()]):
print(form.cleaned_data)
for form in formset:
print(form.clean_data)
context['message'] = "All Data saved"
return render(request, "Invoice/create-update.html", context=context)
def delete_so(request):
pass