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