mirror of
https://github.com/bcomsugi/dasaproject.git
synced 2026-01-10 05:42:38 +07:00
update exim
This commit is contained in:
parent
89982de5b0
commit
c8c7816f01
238
exim.py
238
exim.py
@ -6,6 +6,8 @@ from QBClass.QBClasses import InvoiceQuery, SalesOrderQuery
|
|||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
import numpy as np
|
||||||
|
import datetime
|
||||||
|
|
||||||
print('succes Loading modules')
|
print('succes Loading modules')
|
||||||
|
|
||||||
@ -26,7 +28,7 @@ def timer(func):
|
|||||||
|
|
||||||
|
|
||||||
@timer
|
@timer
|
||||||
def get_all_so_from_invoice(MaxReturned=None, FromTxnDate=None, ToTxnDate=None):
|
def get_all_so_from_invoice( FromTxnDate=None, ToTxnDate=None, MaxReturned=None,):
|
||||||
print(MaxReturned, FromTxnDate, ToTxnDate)
|
print(MaxReturned, FromTxnDate, ToTxnDate)
|
||||||
start = time.time()
|
start = time.time()
|
||||||
print('Get Invoice Query List. Processing..... wait for at minute(1 month=90secs)')
|
print('Get Invoice Query List. Processing..... wait for at minute(1 month=90secs)')
|
||||||
@ -160,6 +162,7 @@ def process():
|
|||||||
|
|
||||||
@timer
|
@timer
|
||||||
def process_data(iq_list, so_dict):
|
def process_data(iq_list, so_dict):
|
||||||
|
print('process_data')
|
||||||
# iq = InvoiceQuery(MaxReturned= 20, IncludeLinkedTxns='true', IncludeLineItems='true', debug=False)
|
# iq = InvoiceQuery(MaxReturned= 20, IncludeLinkedTxns='true', IncludeLineItems='true', debug=False)
|
||||||
# iq = InvoiceQuery(TxnDateRangeFilter_FromTxnDate='2024-02-01', TxnDateRangeFilter_ToTxnDate='2024-02-29', IncludeLinkedTxns='true', IncludeLineItems='true')
|
# iq = InvoiceQuery(TxnDateRangeFilter_FromTxnDate='2024-02-01', TxnDateRangeFilter_ToTxnDate='2024-02-29', IncludeLinkedTxns='true', IncludeLineItems='true')
|
||||||
# pprint(iq_list, sort_dicts=False)
|
# pprint(iq_list, sort_dicts=False)
|
||||||
@ -214,81 +217,81 @@ def process_data(iq_list, so_dict):
|
|||||||
soNotInOneInv.append(sodt['RefNumber'])
|
soNotInOneInv.append(sodt['RefNumber'])
|
||||||
|
|
||||||
if float(linkedtxn['Amount'])<0:
|
if float(linkedtxn['Amount'])<0:
|
||||||
if sodt['TotalAmount']!=linkedtxn['Amount'][1:]:
|
# if sodt['TotalAmount']!=linkedtxn['Amount'][1:]:
|
||||||
if is_soLinkedToOneInvoice: #maybe the SO is manually closed, check it item by item, find which item is not in invoice
|
# pass
|
||||||
if sodt['IsManuallyClosed'] == 'true':
|
# if is_soLinkedToOneInvoice: #maybe the SO is manually closed, check it item by item, find which item is not in invoice
|
||||||
pass
|
# if sodt['IsManuallyClosed'] == 'true':
|
||||||
print(f"{sodt['TxnID'] = } {sodt['RefNumber'] = }")
|
# pass
|
||||||
manuallyClosedSO.append(sodt['RefNumber'])
|
# print(f"{sodt['TxnID'] = } {sodt['RefNumber'] = }")
|
||||||
else:
|
# manuallyClosedSO.append(sodt['RefNumber'])
|
||||||
print('SO TotalAmount<>Amount in Invoice. not Manually closed and not fully Invoiced')
|
# else:
|
||||||
pprint(f'{linkedtxn = }', sort_dicts=False)
|
# print('SO TotalAmount<>Amount in Invoice. not Manually closed and not fully Invoiced')
|
||||||
print(f"{sodt['TxnID'] = } {sodt['RefNumber'] = }")
|
# pprint(f'{linkedtxn = }', sort_dicts=False)
|
||||||
print(sodt)
|
# print(f"{sodt['TxnID'] = } {sodt['RefNumber'] = }")
|
||||||
openSO.append(sodt['RefNumber'])
|
# print(sodt)
|
||||||
else:
|
# openSO.append(sodt['RefNumber'])
|
||||||
pass # this SO is fully invoiced, starting process to export the details
|
# else:
|
||||||
try:
|
pass # this SO is fully invoiced, starting process to export the details
|
||||||
if not isinstance(sodt['SalesOrderLineRet'],list):
|
try:
|
||||||
sodt['SalesOrderLineRet'] = [sodt['SalesOrderLineRet']]
|
if not isinstance(sodt['SalesOrderLineRet'],list):
|
||||||
if not isinstance(txn['InvoiceLineRet'],list):
|
sodt['SalesOrderLineRet'] = [sodt['SalesOrderLineRet']]
|
||||||
txn['InvoiceLineRet'] = [txn['InvoiceLineRet']]
|
if not isinstance(txn['InvoiceLineRet'],list):
|
||||||
for so_line in sodt['SalesOrderLineRet']:
|
txn['InvoiceLineRet'] = [txn['InvoiceLineRet']]
|
||||||
checklist = ['ItemRef', ]
|
for so_line in sodt['SalesOrderLineRet']:
|
||||||
if len([ i for i in checklist if i in so_line])==0:
|
checklist = ['ItemRef', ]
|
||||||
continue
|
if len([ i for i in checklist if i in so_line])==0:
|
||||||
soitemref_fullname = so_line.get('ItemRef',{}).get('FullName')
|
continue
|
||||||
soquantity:str = so_line.get('Quantity')
|
soitemref_fullname = so_line.get('ItemRef',{}).get('FullName')
|
||||||
# print(f'{soquantity = }')
|
soquantity:str = so_line.get('Quantity')
|
||||||
sounitofmeasure = so_line.get('UnitOfMeasure')
|
# print(f'{soquantity = }')
|
||||||
# sooverrideuomsetref_fullname = so_line['OverrideUOMSetRef']['FullName']
|
sounitofmeasure = so_line.get('UnitOfMeasure')
|
||||||
sorate = so_line.get('Rate')
|
# sooverrideuomsetref_fullname = so_line['OverrideUOMSetRef']['FullName']
|
||||||
soamount = so_line.get('Amount')
|
sorate = so_line.get('Rate')
|
||||||
soinvoiced = so_line.get('Invoiced')
|
soamount = so_line.get('Amount')
|
||||||
soismanuallyclosed = so_line['IsManuallyClosed']
|
soinvoiced = so_line.get('Invoiced')
|
||||||
soother2 = so_line.get('Other2')
|
soismanuallyclosed = so_line['IsManuallyClosed']
|
||||||
|
soother2 = so_line.get('Other2')
|
||||||
|
|
||||||
#check compare to the invoicelineret
|
#check compare to the invoicelineret
|
||||||
for inv_line in txn['InvoiceLineRet']: #loop start from top in order
|
for inv_line in txn['InvoiceLineRet']: #loop start from top in order
|
||||||
is_inv_so_line_ok = True
|
is_inv_so_line_ok = True
|
||||||
if 'soline' not in inv_line: #this line has no so link yet
|
if 'soline' not in inv_line: #this line has no so link yet
|
||||||
if inv_line['ItemRef']['FullName'] != soitemref_fullname:
|
if inv_line.get('ItemRef',{}).get('FullName') != soitemref_fullname:
|
||||||
continue
|
continue
|
||||||
if inv_line.get('UnitOfMeasure') != sounitofmeasure:
|
if inv_line.get('UnitOfMeasure') != sounitofmeasure:
|
||||||
print(f"{inv_line['ItemRef']['FullName'] = } {inv_line['UnitOfMeasure']=} != {sounitofmeasure=}")
|
print(f"{inv_line['ItemRef']['FullName'] = } {inv_line['UnitOfMeasure']=} != {sounitofmeasure=}")
|
||||||
|
is_inv_so_line_ok = False
|
||||||
|
#do convertion????
|
||||||
|
# continue
|
||||||
|
if soinvoiced and inv_line.get('Quantity',0)!=soinvoiced: #compre with the invoiced
|
||||||
|
print(f"{inv_line['ItemRef']['FullName'] = } {inv_line['Quantity']=} != {soquantity=}")
|
||||||
|
is_inv_so_line_ok = False
|
||||||
|
if sorate:
|
||||||
|
if float(inv_line.get('Rate',0))!=float(sorate):
|
||||||
|
print(f"{inv_line['ItemRef']['FullName'] = } {inv_line['Rate']=} <> {sorate=} ; {float(inv_line.get('Rate',0)) = } {float(sorate) = }")
|
||||||
is_inv_so_line_ok = False
|
is_inv_so_line_ok = False
|
||||||
#do convertion????
|
# if soamount:
|
||||||
# continue
|
# if float(inv_line.get('Amount',0))!=float(soamount):
|
||||||
if soinvoiced and inv_line.get('Quantity',0)!=soinvoiced: #compre with the invoiced
|
# print(f"{txn['RefNumber']} {inv_line['ItemRef']['FullName'] = } {inv_line['Amount']=} != {soamount=}")
|
||||||
print(f"{inv_line['ItemRef']['FullName'] = } {inv_line['Quantity']=} != {soquantity=}")
|
# is_inv_so_line_ok = False
|
||||||
is_inv_so_line_ok = False
|
if not is_inv_so_line_ok:
|
||||||
if sorate:
|
print(f"{inv_line['ItemRef']['FullName'] = } Some detail not equal")
|
||||||
if float(inv_line.get('Rate',0))!=float(sorate):
|
continue
|
||||||
print(f"{inv_line['ItemRef']['FullName'] = } {inv_line['Rate']=} <> {sorate=} ; {float(inv_line.get('Rate',0)) = } {float(sorate) = }")
|
#add to the spesific invoiceline
|
||||||
is_inv_so_line_ok = False
|
inv_line['soline']= {'RefNumber':sodt['RefNumber'],
|
||||||
# if inv_line['Amount']!=soamount or float(inv_line['Amount'])!=float(soamount):
|
'TxnDate':sodt['TxnDate'],
|
||||||
if soamount:
|
'ItemRef_FullName':soitemref_fullname,
|
||||||
if float(inv_line.get('Amount',0))!=float(soamount):
|
'Quantity':soquantity,
|
||||||
print(f"{inv_line['ItemRef']['FullName'] = } {inv_line['Amount']=} != {soamount=}")
|
'UnitOfMeasure':sounitofmeasure,
|
||||||
is_inv_so_line_ok = False
|
'Rate':sorate,
|
||||||
if not is_inv_so_line_ok:
|
'Amount':soamount,
|
||||||
print(f"{inv_line['ItemRef']['FullName'] = } Some detail not equal")
|
'Invoiced':soinvoiced,
|
||||||
continue
|
'IsManuallyClosed':soismanuallyclosed,
|
||||||
#add to the spesific invoiceline
|
'Other2':soother2}
|
||||||
inv_line['soline']= {'RefNumber':sodt['RefNumber'],
|
break
|
||||||
'TxnDate':sodt['TxnDate'],
|
except Exception as e:
|
||||||
'ItemRef_FullName':soitemref_fullname,
|
print(f"SO {sodt['RefNumber'] = } {txn['RefNumber'] = }")
|
||||||
'Quantity':soquantity,
|
print(f'ERROR: {e}')
|
||||||
'UnitOfMeasure':sounitofmeasure,
|
|
||||||
'Rate':sorate,
|
|
||||||
'Amount':soamount,
|
|
||||||
'Invoiced':soinvoiced,
|
|
||||||
'IsManuallyClosed':soismanuallyclosed,
|
|
||||||
'Other2':soother2}
|
|
||||||
break
|
|
||||||
except Exception as e:
|
|
||||||
print(f"SO {sodt['RefNumber'] = } {txn['RefNumber'] = }")
|
|
||||||
print(f'ERROR: {e}')
|
|
||||||
else:
|
else:
|
||||||
print('Linkedtxn amount is positif(should be negatif')
|
print('Linkedtxn amount is positif(should be negatif')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -329,9 +332,7 @@ def checking_iqwith_so(iq_list):
|
|||||||
continue
|
continue
|
||||||
if 'ItemRef' not in inv_line:
|
if 'ItemRef' not in inv_line:
|
||||||
inv_line_no_itemref.append({'RefNumber':txn['RefNumber'],
|
inv_line_no_itemref.append({'RefNumber':txn['RefNumber'],
|
||||||
'idx':idx,
|
'idx':idx,})
|
||||||
'ItemRef_FullName':inv_line['ItemRef']['FullName'],
|
|
||||||
'Amount':inv_line['Amount']})
|
|
||||||
continue
|
continue
|
||||||
if '400_Sales' not in inv_line['ItemRef']['FullName']:
|
if '400_Sales' not in inv_line['ItemRef']['FullName']:
|
||||||
inv_line_no_soline.append({'RefNumber':txn['RefNumber'],
|
inv_line_no_soline.append({'RefNumber':txn['RefNumber'],
|
||||||
@ -364,7 +365,7 @@ def writeToFile(iq_list=None, so_dict=None, filename = "", suffix="", indent=2):
|
|||||||
so_dict_json = json.dumps(so_dict)
|
so_dict_json = json.dumps(so_dict)
|
||||||
else:
|
else:
|
||||||
so_dict_json = json.dumps(so_dict, indent=indent)
|
so_dict_json = json.dumps(so_dict, indent=indent)
|
||||||
with open(f"{filename}{suffix}.json", "w") as outfile:
|
with open(f"{filename}_so_dict{suffix}.json", "w") as outfile:
|
||||||
outfile.write(so_dict_json)
|
outfile.write(so_dict_json)
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -380,24 +381,71 @@ def readJsonFromFile(filename):
|
|||||||
print(e)
|
print(e)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# print(timeit.repeat(process, repeat=1))
|
|
||||||
# process()
|
|
||||||
|
|
||||||
invqueryfilename = 'exim\Data\iq'
|
def get_last_date_of_month(stryearmonth:str):
|
||||||
# iq_list, so_dict = get_all_so_from_invoice(MaxReturned=20)
|
# Get Last date of Month
|
||||||
### Reading from QB and write to a file depends on txndate
|
# Using replace() + timedelta()
|
||||||
# iq_list, so_dict = get_all_so_from_invoice(FromTxnDate="2024-08-01", ToTxnDate="2024-08-31")
|
|
||||||
# writeToFile(iq_list, so_dict)
|
|
||||||
|
|
||||||
### reading from existing file the iq_list and so_dict jsonfile
|
# initializing date
|
||||||
|
test_date = datetime.datetime.fromisoformat(stryearmonth)
|
||||||
|
# test_date = datetime.datetime(2018, 6, 4)
|
||||||
|
|
||||||
|
# printing original date
|
||||||
|
print("The original date is : " + str(test_date))
|
||||||
|
|
||||||
|
# getting next month
|
||||||
|
# using replace to get to last day + offset
|
||||||
|
# to reach next month
|
||||||
|
nxt_mnth = test_date.replace(day=28) + datetime.timedelta(days=4)
|
||||||
|
|
||||||
|
# subtracting the days from next month date to
|
||||||
|
# get last date of current Month
|
||||||
|
res = nxt_mnth - datetime.timedelta(days=nxt_mnth.day)
|
||||||
|
|
||||||
|
# printing result
|
||||||
|
datesplit = stryearmonth.split('-')
|
||||||
|
print("Last date of month : " + str(res.day), f"{datesplit[0]}-{datesplit[1]}-{str(res.day)}")
|
||||||
|
|
||||||
iq_list = readJsonFromFile(f"{invqueryfilename}.json")
|
return f"{datesplit[0]}-{datesplit[1]}-{str(res.day)}"
|
||||||
so_dict = readJsonFromFile(f"{invqueryfilename}_so_dict.json")
|
|
||||||
print(f'{len(iq_list) = } {len(so_dict) = }')
|
|
||||||
iq_list = process_data(iq_list, so_dict)
|
|
||||||
suffix = '_withsoindent2'
|
|
||||||
writeToFile(iq_list, filename=f'{invqueryfilename}', suffix=suffix, indent=2)
|
|
||||||
iq_list = readJsonFromFile(f'{invqueryfilename}{suffix}.json')
|
|
||||||
print(len(iq_list))
|
|
||||||
print(f'Seems {invqueryfilename}{suffix}.json is {checking_iqwith_so(iq_list)}') #checking the iq_list. is it good to import to new QB?
|
|
||||||
|
|
||||||
|
def main(fromtxndate, totxndate, maxreturned:int=None):
|
||||||
|
# print(timeit.repeat(process, repeat=1))
|
||||||
|
# process()
|
||||||
|
|
||||||
|
invqueryfilename = f'exim\Data\{fromtxndate}iq'
|
||||||
|
# if maxreturned:
|
||||||
|
# iq_list, so_dict = get_all_so_from_invoice(MaxReturned=maxreturned)
|
||||||
|
|
||||||
|
# else:
|
||||||
|
# try:
|
||||||
|
# _fromdate = datetime.datetime.fromisoformat(fromtxndate)
|
||||||
|
# _todate = datetime.datetime.fromisoformat(totxndate)
|
||||||
|
# except Exception as e:
|
||||||
|
# print('date format should be yyyy-mm-dd example: "2024-03-09"')
|
||||||
|
# return False
|
||||||
|
|
||||||
|
# ## Reading from QB and write to a file depends on txndate
|
||||||
|
# iq_list, so_dict = get_all_so_from_invoice(FromTxnDate=fromtxndate, ToTxnDate=totxndate)
|
||||||
|
# writeToFile(iq_list, so_dict, filename=invqueryfilename)
|
||||||
|
|
||||||
|
### reading from existing file the iq_list and so_dict jsonfile
|
||||||
|
|
||||||
|
iq_list = readJsonFromFile(f"{invqueryfilename}.json")
|
||||||
|
so_dict = readJsonFromFile(f"{invqueryfilename}_so_dict.json")
|
||||||
|
print(f'{len(iq_list) = } {len(so_dict) = }')
|
||||||
|
iq_list = process_data(iq_list, so_dict)
|
||||||
|
suffix = '_withsoindent2'
|
||||||
|
writeToFile(iq_list, filename=f'{invqueryfilename}', suffix=suffix, indent=2)
|
||||||
|
iq_list = readJsonFromFile(f'{invqueryfilename}{suffix}.json')
|
||||||
|
print(len(iq_list))
|
||||||
|
print(f'Seems {invqueryfilename}{suffix}.json is {checking_iqwith_so(iq_list)}') #checking the iq_list. is it good to import to new QB?
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=='__main__':
|
||||||
|
# print(np.arange('2021-02', '2021-03', dtype='datetime64[D]'))
|
||||||
|
fromtxndate = '2022-08-01'
|
||||||
|
totxndate = get_last_date_of_month(fromtxndate)
|
||||||
|
_fromdate = datetime.datetime.fromisoformat(fromtxndate)
|
||||||
|
|
||||||
|
print(fromtxndate)
|
||||||
|
main(fromtxndate, totxndate)
|
||||||
Loading…
Reference in New Issue
Block a user