mirror of
https://github.com/bcomsugi/dasaproject.git
synced 2026-01-10 06:12:37 +07:00
528 lines
23 KiB
Python
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
|
|
|
|
|