This commit is contained in:
bcomsugi 2023-12-29 04:41:31 +07:00
parent dfabdf35bb
commit 9e65890d0f
6 changed files with 363 additions and 37 deletions

View File

@ -25,6 +25,7 @@ class SalesOrderQuery:
self._df_price_level = pd.read_excel(os.path.join(self.cwd, self.item_inventory_path, self.price_level_filename), usecols=['FullName', 'PriceLevelName', 'CustomPrice'],)
print(self._df_price_level)
print(type(self._df_price_level.loc[(self._df_price_level['FullName']=="ECO:0:ECO-002") & (self._df_price_level['PriceLevelName']=="T 202202")].values.tolist()[0][2]))
print(self._df_price_level.loc[(self._df_price_level['FullName']=="TEDG:S122:EDG-009-1/22") & (self._df_price_level['PriceLevelName']=="T 202202")].values.tolist()[0][2])
self.FullName = kwargs['FullName'] if 'FullName' in kwargs else None
self.CustomerPriceLevelName_filename = "CustomerList.xlsx"
@ -33,8 +34,9 @@ class SalesOrderQuery:
print(self._df_customer)
self.Customer = None
if self.FullName:
self.Customer = self._df_customer.loc[(self._df_customer["FullName"]==self.FullName)].values.tolist()[0]
print(f'Customer:{self.Customer}')
if self.FullName in self._df_customer['FullName'].values:
self.Customer = self._df_customer.loc[(self._df_customer["FullName"]==self.FullName)].values.tolist()[0]
print(f'Customer:{self.Customer}')
self.DN = kwargs['DN'] if 'DN' in kwargs else {}
self.Reuse = kwargs['Reuse'] if 'Reuse' in kwargs else None
@ -176,8 +178,11 @@ class SalesOrderQuery:
return self.get_customer_pricelevel(response_string)
return response_string
def create_invoiceadd_QBXML(self):
def create_invoiceadd_QBXML(self, soList=None):
print('create_ionvoiceadd_QBXML')
if soList:
self.SalesOrderList = soList
root = ET.Element("QBXML")
root.tail = "\n"
root.text = "\n "
@ -225,12 +230,12 @@ class SalesOrderQuery:
# ItemFullName = self.create_sub_element(ET, ItemRef, "FullName", "400_Sales Discount", 12)
# ItemRate = self.create_sub_element(ET, InvoiceLineAdd, "Rate", str(disc_amount), 10)
if disc_amount != 0:
# disc_amount=format(disc_amount, ".2f")
InvoiceLineAdd = self.create_sub_element(ET, InvoiceAdd, "InvoiceLineAdd", "\n ", 10 )
ItemRef = self.create_sub_element(ET, InvoiceLineAdd, "ItemRef", "\n ", 12)
ItemFullName = self.create_sub_element(ET, ItemRef, "FullName", "400_Sales Discount", 12)
ItemRate = self.create_sub_element(ET, InvoiceLineAdd, "Rate", str(disc_amount), 10)
if salesorder['Disc_Amount']!=0: # disc_amount != 0:
# disc_amount=format(disc_amount, ".2f")
InvoiceLineAdd = self.create_sub_element(ET, InvoiceAdd, "InvoiceLineAdd", "\n ", 10 )
ItemRef = self.create_sub_element(ET, InvoiceLineAdd, "ItemRef", "\n ", 12)
ItemFullName = self.create_sub_element(ET, ItemRef, "FullName", "400_Sales Discount", 12)
ItemRate = self.create_sub_element(ET, InvoiceLineAdd, "Rate", str(disc_amount), 10)
mydata = ET.tostring(root, encoding = "unicode")
@ -293,10 +298,22 @@ class SalesOrderQuery:
else:
return False, status_code
def get_discperpcs(self, ItemFullName, Rate:float):
discPerPcs = 0
if self.Customer:
if self.Customer[2]:
pricelist = self._df_price_level.loc[(self._df_price_level['FullName']==ItemFullName) & (self._df_price_level['PriceLevelName']==self.Customer[2])].values.tolist()[0][2]
discPerPcs = Rate-pricelist
# ic(Rate, disc, (Rate - self._df_price_level.loc[(self._df_price_level['FullName']==ItemFullName) & (self._df_price_level['PriceLevelName']==self.SPPriceLevelName)].values.tolist()[0][2]))
if discPerPcs < 0 :
discPerPcs = 0
print(f"WARNING: Rate is Lower than Pricelist Cust:{self.Customer} ItemName:{ItemFullName} Rate:{Rate} < {pricelist}")
return discPerPcs
def _get_sales_order_header(self, response_string):
def _get_sales_order_header(self, response_string, includefullInvoiced=False):
print('_get_sales_order_header')
print(f'responsestring:{self.pprintXml(response_string)}')
# print(f'responsestring:{self.pprintXml(response_string)}')
QBXML = ET.fromstring(response_string)
datadict = {}
SalesOrderdict = {}
@ -319,14 +336,19 @@ class SalesOrderQuery:
TotalAmount = SalesOrderRet.find('TotalAmount').text
IsFullyInvoiced = SalesOrderRet.find('IsFullyInvoiced').text
IsManuallyClosed = SalesOrderRet.find('IsManuallyClosed').text
if includefullInvoiced==False:
if IsFullyInvoiced.lower()=='true':
# print(IsFullyInvoiced)
continue
# print(CustomerFullName, TxnID, TotalAmount)
SalesOrderdict = {'RefNumber':RefNumber, 'CustomerFullName':CustomerFullName, 'TxnID':TxnID,
'TxnDate':TxnDate, 'TxnNumber':TxnNumber,
'TotalAmount':TotalAmount, 'IsFullyInvoiced':IsFullyInvoiced, 'IsManuallyClosed':IsManuallyClosed, 'SalesOrderLineRet':[]}
SalesOrderLineRet = SalesOrderRet.findall('SalesOrderLineRet')
# ic(len(SalesOrderLineRet))
disc_amount=0
if len(SalesOrderLineRet) > 0:
disc_amount=0
# disc_amount=0
for SalesOrderLineRet in SalesOrderLineRet:
discPerItem = 0
discPerPcs = 0
@ -353,17 +375,20 @@ class SalesOrderQuery:
BackOrdered = float(Quantity) - float(Invoiced)
if BackOrdered > 0 and LineIsManuallyClosed.lower() == 'false' :
# ic(self.Customer)
if self.Customer:
if self.Customer[2]:
discPerPcs = Rate-self._df_price_level.loc[(self._df_price_level['FullName']==ItemFullName) & (self._df_price_level['PriceLevelName']==self.Customer[2])].values.tolist()[0][2]
# ic(Rate, disc, (Rate - self._df_price_level.loc[(self._df_price_level['FullName']==ItemFullName) & (self._df_price_level['PriceLevelName']==self.SPPriceLevelName)].values.tolist()[0][2]))
if discPerPcs > 0:
print(Quantity, BackOrdered, Rate, (Rate - self._df_price_level.loc[(self._df_price_level['FullName']==ItemFullName) & (self._df_price_level['PriceLevelName']==self.Customer[2])].values.tolist()[0][2]))
discPerItem = BackOrdered * discPerPcs
disc_amount += discPerItem
# disc_amount += BackOrdered * discPerPcs # (Rate-self._df_price_level.loc[(self._df_price_level['FullName']==ItemFullName) & (self._df_price_level['PriceLevelName']==self.Customer[2])].values.tolist()[0][2])
else:
discPerPcs = 0
discPerPcs = self.get_discperpcs(ItemFullName, Rate)
discPerItem = BackOrdered * discPerPcs
disc_amount += discPerItem
# if self.Customer:
# if self.Customer[2]:
# discPerPcs = Rate-self._df_price_level.loc[(self._df_price_level['FullName']==ItemFullName) & (self._df_price_level['PriceLevelName']==self.Customer[2])].values.tolist()[0][2]
# # ic(Rate, disc, (Rate - self._df_price_level.loc[(self._df_price_level['FullName']==ItemFullName) & (self._df_price_level['PriceLevelName']==self.SPPriceLevelName)].values.tolist()[0][2]))
# if discPerPcs > 0:
# print(Quantity, BackOrdered, Rate, (Rate - self._df_price_level.loc[(self._df_price_level['FullName']==ItemFullName) & (self._df_price_level['PriceLevelName']==self.Customer[2])].values.tolist()[0][2]))
# discPerItem = BackOrdered * discPerPcs
# disc_amount += discPerItem
# # disc_amount += BackOrdered * discPerPcs # (Rate-self._df_price_level.loc[(self._df_price_level['FullName']==ItemFullName) & (self._df_price_level['PriceLevelName']==self.Customer[2])].values.tolist()[0][2])
# else:
# discPerPcs = 0
SalesOrderLinedict = {'TxnLineID':TxnLineID,
'ItemFullName':ItemFullName,
'Quantity':Quantity,
@ -567,11 +592,12 @@ class SalesOrderQuery:
print(f'txnid: {txnlist}', type(txnlist))
txnid = []
for x in txnlist:
# print(x, type(x))
if isinstance(x, list):
txnid.append(x[0])
else:
txnid.append(x)
break
# break
# txnid = [x[0] if isinstance(x, list) else x for x in txnid ]
print(txnid)
if txnid:

View File

@ -0,0 +1,104 @@
{% extends 'base.html' %}
{% block body %}
<!-- <form method="POST" action="{{ request.path }}"> -->
<div class="container">
<form method="POST" action="{% url 'Invoice:save_inv' %}" class="modal-content">
{% csrf_token %}
<div class="modal-header">
<h1>Choose Items</h1>
</div>
<div class="modal-body">
<div class="mb-3 mt-3">
<input type="hidden" name="customer_fullname" value="{{ customer_fullname }}">
<!-- <input name="customerreffullname" type='text' list='itemname' value='{{customer_name}}' id='id_CustomerRefFullName' class='textinput form-control' autofocus> -->
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Item</th>
<th scope="col">Date</th>
<th scope="col">SO Number</th>
<th scope="col">Ordered</th>
<th scope="col">Prev. Inv</th>
<th scope="col">To Invoice</th>
<th scope="col">UOM</th>
<th scope="col">Rate</th>
</tr>
</thead>
<tbody>
{% for so_dict in objects %}
{{so_dict}}
{{so_dict.RefNumber}}
{% for so_line in so_dict.SalesOrderLineRet %}
{{so_dict.RefNumber}}
{{so_line.ItemFullName}}
<tr>
<td>
<input type="hidden" name="RefNumber" value="{{ so_dict.RefNumber }}">
<input type="hidden" name="CustomerFullName" value="{{ so_dict.CustomerFullName }}">
<input type="hidden" name="TxnID" value="{{ so_dict.TxnID }}">
<input type="hidden" name="TxnDate" value="{{ so_dict.TxnDate }}">
<input type="hidden" name="TotalAmount" value="{{ so_dict.TotalAmount }}">
{% for k, v in so_line.items %}
<input type="hidden" name="{{ k }}" value="{{ v }}">
{% endfor %}
<div class="form-check">
<input type="checkbox" name="so_field" value="{{ so_dict.TxnID }}" id="id_so_field_{{forloop.counter}}" class="form-check-input" checked>
<label for="id_so_field_{{ forloop.counter }}" class="form-check-label">{{so_line.ItemFullName}}
</label>
</div>
</td>
<td>{{ so_dict.TxnDate }}</td>
<td>{{ so_dict.RefNumber }}</td>
<td>{{ so_line.Quantity }}</td>
<td>{{ so_line.Invoiced }}</td>
<td><input type="number" name="backordered" required value="{{ so_line.BackOrdered }}" min="0" max="{{ so_line.BackOrdered }}"> </td>
<td>{{ so_line.UOM }}</td>
<td><input type="number" name="rate" required value="{{ so_line.Rate }}" min="0" > </td>
</tr>
{% endfor %}
{% endfor %}
<tr>
<!-- bisa jadikan for loop jika banyak item lagi -->
<td>
<input type="hidden" name="other_items" value="peti">
<div class="form-check">
<input type="checkbox" name="selected_items" value="peti" class="form-check-input peti">
<label class="form-check-label">PETI</label>
</div>
</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><input type="number" name="other_qty" required value="1" min="0" max="100"> </td>
<td>PETI</td>
<td><input type="number" name="other_rate" required value="40000" min="0" max="40000000"> </td>
</tr>
<tr>
<td>
<input type="hidden" name="other_items" value="expedition">
<div class="form-check">
<input type="checkbox" name="selected_items" value="expedition" class="form-check-input expedition">
<label class="form-check-label">Ekspedisi</label>
</div>
</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><input type="number" name="other_qty" required value="1" min="0" max="1"> </td>
<td></td>
<td><input type="number" name="other_rate" required value="0" min="0" max="10000000"> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary mt-2 me-2 ms-2" id="id_btnsave" >Save</button>
</div>
</form>
</div>
{% endblock %}

View File

@ -2,7 +2,7 @@
{% block body %}
<!-- <form method="POST" action="{{ request.path }}"> -->
<div class="container">
<form method="POST" action="{% url 'Invoice:show_inv' %}" class="modal-content">
<form method="POST" action="{% url 'Invoice:choose_inv' %}" class="modal-content">
{% csrf_token %}
<div class="modal-header">
<h1>Choose SO</h1>

View File

@ -10,7 +10,8 @@ urlpatterns = [
# path('', views.home_view ),
path('', views.show_customer, name="show_customer" ),
path('selectso', views.select_so, name="select_so" ),
path('showinv', views.show_inv, name="show_inv" ),
path('showinv', views.choose_inv, name="choose_inv" ),
path('saveinv', views.save_inv, name="save_inv" ),
path('', views.index, name="index"),

View File

@ -26,6 +26,7 @@ def get_SalesOrderQuery(customer_name):
except:
import sys
sys.path.append('.')
sys.path.append('..')
print("except")
print(sys.path)
from SO_to_Inv.readSO import SalesOrderQuery
@ -77,39 +78,232 @@ def show_customer(request):
context['customer_fullname'] = customer_name
return render(request, "Invoice/so_list_form.html", context)
# print(df.values.tolist())
# print(df.values.tolist())
return render(request, "Invoice/show-customers.html", context)
def select_so(request):
pass
def show_inv(request):
print("show_inv")
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 = request.POST.getlist('so_field')
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}')
print(f'Customer_fullname:{customer_fullname} -> request values:{open_sales_orders_TxnID}')
### get the SO detail
ini=get_SalesOrderQuery(customer_fullname)
itu = ini.get_open_sales_order(open_sales_orders)
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)
# print(ini.connect_to_quickbooks(ini.create_invoiceadd_QBXML()))
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 = {}

1
records Normal file
View File

@ -0,0 +1 @@
{"itemfullname":{"0":"TACO:G_D:TH-017D","1":"TEDG:S122:EDG-009-1\/22","2":"TIERO:AF:TI-Q-9002-AF"},"txnlineid":{"0":"1786D7-1689047665","1":"178970-1689047665","2":"1796BD-1689144572"},"so_field":{"0":"1786D5-1689047665, 1786D7-1689047665","1":"1786D5-1689047665, 178970-1689047665","2":"1796BB-1689144572, 1796BD-1689144572"},"backordered":{"0":"11","1":"1.0","2":"8.0"},"rate":{"0":"179500.0","1":"380000.0","2":"1080000.0"}}