from django.shortcuts import render, get_object_or_404, redirect from django.urls import reverse from django.http import HttpResponse, JsonResponse, HttpResponseRedirect 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 import timeit from decimal import Decimal from datetime import datetime # ic.configureOutput(includeContext= True) def get_SalesOrderQuery(customer_name, txnid=None): 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) if txnid: ini=SalesOrderQuery(FullName= customer_name, TxnID=txnid, IncludeRetElement = ['TxnID', 'TimeCreated', 'TimeModified','TxnNumber', 'CustomerRef', 'TxnDate', 'RefNumber', 'IsManuallyClosed', 'IsFullyInvoiced','TotalAmount'], cwd=parentdir) pass else: ini=SalesOrderQuery(FullName= customer_name, IncludeRetElement = ['TxnID', 'TimeCreated', 'TimeModified','TxnNumber', 'CustomerRef', 'TxnDate', 'RefNumber', 'IsManuallyClosed', 'IsFullyInvoiced','TotalAmount'], cwd=parentdir) return ini def get_TransactionQuery(txnid=None, refnumber=None, customername=None, txntypefilter=None, includeret=[ 'TxnID', 'EntityRef', 'TxnDate', 'RefNumber', 'Memo'] ): try: print("try") from qbtransactionquery import TransactionQuery except: import sys sys.path.append('.') sys.path.append('..') print("except") print(sys.path) from qbtransactionquery import TransactionQuery print("transactionquery imported") basedir = settings.BASE_DIR parentdir = os.path.dirname(basedir) if txnid: ini=TransactionQuery(FullName= customername, RefNumber = refnumber, TxnID=txnid, IncludeRetElement = includeret, cwd=parentdir) else: ini=TransactionQuery(FullName= customername, RefNumber = refnumber, IncludeRetElement =includeret, cwd=parentdir) return ini def show_customer(request): pass print("show_customer") starttime = timeit.default_timer() # 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'] = [] print("The time difference is bef show customer :", timeit.default_timer() - starttime) if customer_name: ini = get_SalesOrderQuery(customer_name) print("The time difference is mid show customer :", timeit.default_timer() - starttime) if ini: print("after ini show customer") qbxml = ini.create_QBXML() # print(qbxml) print("The time difference is :", timeit.default_timer() - starttime) print("timeeint") response_string = ini.connect_to_quickbooks(qbxml) # print(response_string) open_sales_orders = ini.get_open_so() print(f'open sales orders showcustomer:{open_sales_orders}') ini=None if not open_sales_orders: messages.info(request, f"There is No open SO for {customer_name}") return redirect("Invoice:show_customer") # if open_sales_orders: context['objects'] = open_sales_orders context['customer_fullname'] = customer_name print("The time difference is :", timeit.default_timer() - starttime) return render(request, "Invoice/so_list_form.html", context) # print(df.values.tolist()) print("The time difference is :", timeit.default_timer() - starttime) return render(request, "Invoice/show-customers.html", context) def select_so(request): pass def choose_inv(request): print("choose_inv") starttime = timeit.default_timer() 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, open_sales_orders_TxnID) # ini=get_SalesOrderQuery(customer_fullname) print("") print("The time difference chooseinv is :", timeit.default_timer() - starttime) print(f'ini::{ini}') print("The time difference chooseinv is :", timeit.default_timer() - starttime) print("before ITU") itu = ini.get_open_sales_order(open_sales_orders_TxnID) # print(itu) print("The time difference after itu is :", timeit.default_timer() - starttime) 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) # print("") # result=None # print("") # result = ini.connect_to_quickbooks(ini.create_invoiceadd_QBXML()) # print("RESULT:") # print(result) print("The time difference finish choose inv is :", timeit.default_timer() - starttime) return render(request, "Invoice/so_details_form.html", context) else: messages.warning(request, "Customer PriceLevel or PriceLevelList not found. please prepare data first and check Customer 'Special Customer Custom Field'") 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 print("The time difference is :", timeit.default_timer() - starttime) 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 check_duplicate_refnumber(refnumber): ini = get_TransactionQuery(refnumber=refnumber, includeret=['TxnID', 'RefNumber']) status, statuscode = ini.status_ok(ini.connect_to_quickbooks(ini.create_QBXML())) print(f'check duplicate refnumber:{status}; {statuscode}') return status ### status=True -> duplicate refnumber def save_inv(request): print("save_inv") starttime = timeit.default_timer() context={} if request.method == "POST": # print(request.POST) data = dict(request.POST) del data['csrfmiddlewaretoken'] del data['customer_fullname'] ### get others items into list of dict ### others=[] otherFullName = {'peti': 'PETI', 'expedition':'Sales_Ekspedisi'} ref_number = request.POST.get('ref_number', None) txn_date = request.POST.get('date', None) print(ref_number, txn_date) if len(ref_number)>20: return HttpResponse("RefNumber Invalid. ") elif ref_number.strip()=="": ref_number = None if ref_number and check_duplicate_refnumber(ref_number): messages.warning(request, 'RefNumber already Exist. please choose other RefNumber') return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) return HttpResponse('RefNumber already Exist. please choose other RefNumber') if len(txn_date)<6: return HttpResponse("Date is Invalid") del data['ref_number'] del data['date'] if 'selected_items' in data: for _ in data['selected_items']: if _ in data['other_items']: data_idx = data['other_items'].index(_) print(f'selected item:{_} is in index:{data_idx}') other_qty = int(data['other_qty'][data_idx]) other_rate = float(data['other_rate'][data_idx]) if other_qty<=0: other_qty = 1 if other_rate <= 0: continue temp_ = {'other_item':data['other_items'][data_idx], 'other_itemFullName': otherFullName[data['other_items'][data_idx]], 'other_qty':other_qty, 'other_rate': other_rate} others.append(temp_) del data['selected_items'] if 'other_items' in data: del data['other_items'] if 'other_qty' in data: del data['other_qty'] if 'other_rate' in data: del data['other_rate'] print(f'others:{others}') print(f"datadict:{data}") required_data = ['RefNumber', 'CustomerFullName', 'TxnID', 'TxnDate', 'TotalAmount', 'TxnLineID', 'ItemFullName', 'Quantity', 'UOM', 'Rate', 'Amount', 'Invoiced', 'LineIsManuallyClosed', 'backordered', 'rate', 'convertQTY'] if 'so_field' not in data: return HttpResponse("no Selected Items. Please select at least 1 item to be invoiced.") for _ in required_data: if _ not in data: return HttpResponse(f"Required data not returned from the form: {_}") ### retrieve only the selected so_field ### so_field = data['so_field'] del data['so_field'] selectedItems = [] for _ in so_field: if _ not in data['TxnLineID']: return HttpResponse(f"One of the TxnLineID is not valid: {_}") data_idx = data['TxnLineID'].index(_) try: df = pd.DataFrame(data) print(df) df = df[df['TxnLineID'].isin(so_field)].reset_index() 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['TxnID']) # 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')) open_sales_orders_TxnID = unique(df['TxnID'].to_list()) 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']: ### modified back the rate and backordered using convertQTY ### convertQTY = int(tu_line_ret['convertQTY']) webbackordered = Decimal(web['backordered']) * convertQTY webrate = Decimal(web['rate']) / convertQTY ### if 0 < webbackordered <= Decimal(tu_line_ret['BackOrdered']): # print('put in list') discPerPcs=0 discPerItem=0 if webrate == Decimal(tu_line_ret['Rate']): discPerPcs = ini.get_discperpcs(web['ItemFullName'], webrate) elif webrate < Decimal(tu_line_ret['Rate']): discPerPcs = Decimal(tu_line_ret['Rate']) - webrate discPerItem = webbackordered * discPerPcs disc_amount += discPerItem SalesOrderLinedict = {'TxnLineID':web['TxnLineID'], 'ItemFullName':tu_line_ret['ItemFullName'], 'Quantity':tu_line_ret['Quantity'], 'UOM':tu_line_ret['UOM'], 'Rate':webrate, 'Amount':Decimal(tu_line_ret['Amount']), 'BackOrdered':webbackordered, 'Invoiced':tu_line_ret['Invoiced'], 'LineIsManuallyClosed':tu_line_ret['LineIsManuallyClosed'], 'discPerItem':discPerItem, # backorder qty * disc per pcs 'discPerPcs':discPerPcs, 'convertQTY':tu_line_ret['convertQTY'] } # print(f'salesorderlineddict:{SalesOrderLinedict}') _salesorderlineret = dict_['SalesOrderLineRet'] _salesorderlineret.append(SalesOrderLinedict) dict_['SalesOrderLineRet'] = _salesorderlineret break break print(f'last:{dict_}') print(f'datatosaveonly:{data_to_save}') if not data_to_save: dict_['Disc_Amount']=disc_amount data_to_save.append(dict_) elif dict_ != data_to_save[-1]: #append the last dict_ dict_['Disc_Amount']=disc_amount data_to_save.append(dict_) print('save the last dict') else: print('last data to save == dict') for _ in others: data_to_save.append(_) dict_to_save = {'customer_fullname': customer_fullname, 'ref_number':ref_number, 'txn_date':txn_date, 'data':data_to_save } print(f'Final List:{dict_to_save}') print("") # print(itu) context['objects'] = itu context['customer_fullname'] = customer_fullname # print(context['objects']) print("Invoiceaddqbxml:") invoiceaddQBXML=ini.create_invoiceadd_QBXML(dict_to_save) print(invoiceaddQBXML) result=None result = ini.connect_to_quickbooks(invoiceaddQBXML) print("RESULT:") print(result) rst, status_msg = ini.status_ok(result) if rst: saved_inv = ini.get_saved_refnumber(result) print(saved_inv) # context['messages']=[{"alert":"info", "message": "invoice Is Good"}] messages.success(request, f"Customer:{saved_inv['Customer_FullName']}\nInvoice No: {saved_inv['RefNumber']} Date: {saved_inv['TxnDate']}\nAmount Invoiced: {saved_inv['BalanceRemaining']}\n Has Been SAVED with link SO No. : {unique(df['RefNumber'].to_list())}") # messages.info(request, 'Invoice Has Been SAVED2') else: messages.warning(request, f"") print("The time difference finish Save Inv is :", timeit.default_timer() - starttime) return redirect('Invoice:show_customer') return render(request, "Invoice/show-customers.html", context) 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 prepare_data(request): starttime = timeit.default_timer() import sys sys.path.append('.') sys.path.append('..') context = {} FullName = "" if request.method=='POST': print(request.POST) subject = request.POST.get("subject", None) print(subject, type(subject)) if subject and isinstance(subject, str): ret=False # import sys # sys.path.append('.') # sys.path.append('..') if subject.upper() == "ITEM INVENTORY": # try: print("try iteminventory import") from ItemInventoryQuery import ItemInventoryQuery ini= ItemInventoryQuery( OwnerID ="0") itu = ini.connect_to_quickbooks(ini.create_QBXML()) ret, msg = ini.status_ok(itu) if ret: print("YEAH") df = pd.DataFrame.from_dict(ini.get_data(itu)) print(df) df.to_excel('ItemInventory\ItemInventory_FromQB.xlsx', index=False) modtime = datetime.fromtimestamp(os.path.getmtime('ItemInventory\ItemInventory_FromQB.xlsx')) print(f"modified Time:{modtime}") # print(ini.status_ok(itu)) else: messages.warning(request, f"Saving {subject} NOT success: {msg}") elif subject.upper() == "CUSTOMER LIST": # try: print("try customerlist import") from SO_to_Inv.CustomerQuery import CustomerQuery ini=CustomerQuery() itu = ini.create_customerquery_QBXML() # print(f'itu:{itu}') print(f'get customer pricelevel list:{ini.get_customer_pricelevel_list(itu)}') ret=True elif subject.upper() == "PRICE LEVEL LIST": # try: print("try pricelevelquery import") from SO_to_Inv.PriceLevelQuery import PriceLevelQuery FullName = ['t 202202', 'M 202202', 'b 202202', 'sp 202202'] FullName = request.POST.getlist("selected_items", FullName) # print(f'fullname:{FullName}') ini = PriceLevelQuery(FullName = FullName, ) itu = ini.connect_to_quickbooks(ini.create_QBXML()) ret, msg = ini.get_pricelevel() ini= None itu = None if ret: print(f'Success Save Price Level : {FullName}') else: messages.warning(request, f"Saving Not Success. status: {msg}") print(f"Saving Not Success. status: {msg}") if ret: messages.info(request, "
You are pretty
smart