This commit is contained in:
bcomsugi 2024-07-27 05:09:55 +07:00
parent a7a1c6528d
commit 118ceb824d
4 changed files with 136 additions and 18 deletions

View File

@ -387,7 +387,7 @@ class SalesOrderQuery(baseQBQuery):
self.QBDict[self.__class__.__name__ + "Rq"]={} self.QBDict[self.__class__.__name__ + "Rq"]={}
### End Required Variable. can put ENUM list below this (eg: self.ENUM_GeneralSummaryReportQuery=[]) ### End Required Variable. can put ENUM list below this (eg: self.ENUM_GeneralSummaryReportQuery=[])
if 'TxnID' in kwargs and kwargs['TxnID']: if 'TxnID' in kwargs and kwargs['TxnID'] and len(kwargs['TxnID'])>0:
self.QBDict[self.__class__.__name__ + "Rq"]["TxnID"]=kwargs['TxnID'] self.QBDict[self.__class__.__name__ + "Rq"]["TxnID"]=kwargs['TxnID']
elif 'RefNumber' in kwargs and kwargs['RefNumber']: elif 'RefNumber' in kwargs and kwargs['RefNumber']:
self.QBDict[self.__class__.__name__ + "Rq"]["RefNumber"]=kwargs['RefNumber'] self.QBDict[self.__class__.__name__ + "Rq"]["RefNumber"]=kwargs['RefNumber']
@ -467,14 +467,11 @@ class InvoiceQuery(baseQBQuery):
if 'TxnID' in kwargs and kwargs['TxnID']: if 'TxnID' in kwargs and kwargs['TxnID']:
_txnIDs=makeAList(kwargs['TxnID']) _txnIDs=makeAList(kwargs['TxnID'])
self.QBDict[self.__class__.__name__ + "Rq"]["TxnID"]= _txnIDs self.QBDict[self.__class__.__name__ + "Rq"]["TxnID"]= makeAList(kwargs['TxnID'])
elif 'RefNumber' in kwargs and kwargs['RefNumber']: elif 'RefNumber' in kwargs and kwargs['RefNumber']:
_refNumbers=makeAList(kwargs['RefNumber']) self.QBDict[self.__class__.__name__ + "Rq"]['RefNumber']=makeAList(kwargs['RefNumber'])
# print(f'{_refNumbers=}')
self.QBDict[self.__class__.__name__ + "Rq"]['RefNumber']=_refNumbers
elif 'RefNumberCaseSensitive' in kwargs and kwargs['RefNumberCaseSensitive']: elif 'RefNumberCaseSensitive' in kwargs and kwargs['RefNumberCaseSensitive']:
_refNumbersCaseSensitive=makeAList(kwargs['RefNumberCaseSensitive']) self.QBDict[self.__class__.__name__ + "Rq"]["RefNumberCaseSensitive"]=makeAList(kwargs['RefNumberCaseSensitive'])
self.QBDict[self.__class__.__name__ + "Rq"]["RefNumberCaseSensitive"]=_refNumbersCaseSensitive
else: else:
if 'MaxReturned' in kwargs: if 'MaxReturned' in kwargs:
self.QBDict[self.__class__.__name__ + "Rq"]["MaxReturned"]=kwargs['MaxReturned'] self.QBDict[self.__class__.__name__ + "Rq"]["MaxReturned"]=kwargs['MaxReturned']
@ -486,18 +483,20 @@ class InvoiceQuery(baseQBQuery):
self.QBDict[self.__class__.__name__ + "Rq"]["TxnDateRangeFilter"]={'DateMacro':kwargs['TxnDateRangeFilter_DateMacro']} self.QBDict[self.__class__.__name__ + "Rq"]["TxnDateRangeFilter"]={'DateMacro':kwargs['TxnDateRangeFilter_DateMacro']}
if 'EntityFilter_ListID' in kwargs: if 'EntityFilter_ListID' in kwargs:
self.QBDict[self.__class__.__name__ + "Rq"]["EntityFilter"]={'ListID':kwargs['EntityFilter_ListID']} # self.QBDict[self.__class__.__name__ + "Rq"]["EntityFilter"]={'ListID':kwargs['EntityFilter_ListID']}
self.QBDict[self.__class__.__name__ + "Rq"]['EntityFilter']={'ListID':makeAList(kwargs['EntityFilter_ListID'])}
elif 'EntityFilter_FullName' in kwargs: elif 'EntityFilter_FullName' in kwargs:
self.QBDict[self.__class__.__name__ + "Rq"]["EntityFilter"]={'FullName':kwargs['EntityFilter_FullName']} # self.QBDict[self.__class__.__name__ + "Rq"]["EntityFilter"]={'FullName':kwargs['EntityFilter_FullName']}
self.QBDict[self.__class__.__name__ + "Rq"]['EntityFilter']={'FullName':makeAList(kwargs['EntityFilter_FullName'])}
elif 'EntityFilter_ListIDWithChildren' in kwargs: elif 'EntityFilter_ListIDWithChildren' in kwargs:
self.QBDict[self.__class__.__name__ + "Rq"]["EntityFilter"]={'ListIDWithChildren':kwargs['EntityFilter_ListIDWithChildren']} self.QBDict[self.__class__.__name__ + "Rq"]["EntityFilter"]={'ListIDWithChildren':kwargs['EntityFilter_ListIDWithChildren']}
elif 'EntityFilter_FullNameWithChildren' in kwargs: elif 'EntityFilter_FullNameWithChildren' in kwargs:
self.QBDict[self.__class__.__name__ + "Rq"]["EntityFilter"]={'FullNameWithChildren':kwargs['EntityFilter_FullNameWithChildren']} self.QBDict[self.__class__.__name__ + "Rq"]["EntityFilter"]={'FullNameWithChildren':kwargs['EntityFilter_FullNameWithChildren']}
if 'AccountFilter_ListID' in kwargs: if 'AccountFilter_ListID' in kwargs:
self.QBDict[self.__class__.__name__ + "Rq"]["AccountFilter"]={'ListID':kwargs['AccountFilter_ListID']} self.QBDict[self.__class__.__name__ + "Rq"]["AccountFilter"]={'ListID':makeAList(kwargs['AccountFilter_ListID'])}
elif 'AccountFilter_FullName' in kwargs: elif 'AccountFilter_FullName' in kwargs:
self.QBDict[self.__class__.__name__ + "Rq"]["AccountFilter"]={'FullName':kwargs['AccountFilter_FullName']} self.QBDict[self.__class__.__name__ + "Rq"]["AccountFilter"]={'FullName':makeAList(kwargs['AccountFilter_FullName'])}
elif 'AccountFilter_ListIDWithChildren' in kwargs: elif 'AccountFilter_ListIDWithChildren' in kwargs:
self.QBDict[self.__class__.__name__ + "Rq"]["AccountFilter"]={'ListIDWithChildren':kwargs['AccountFilter_ListIDWithChildren']} self.QBDict[self.__class__.__name__ + "Rq"]["AccountFilter"]={'ListIDWithChildren':kwargs['AccountFilter_ListIDWithChildren']}
elif 'AccountFilter_FullNameWithChildren' in kwargs: elif 'AccountFilter_FullNameWithChildren' in kwargs:
@ -506,7 +505,8 @@ class InvoiceQuery(baseQBQuery):
if 'RefNumberFilter_MatchCriterion' in kwargs and 'RefNumberFilter_RefNumber' in kwargs: if 'RefNumberFilter_MatchCriterion' in kwargs and 'RefNumberFilter_RefNumber' in kwargs:
self.QBDict[self.__class__.__name__ + "Rq"]["RefNumberFilter"]={'MatchCriterion':kwargs['RefNumberFilter_MatchCriterion', 'RefNumber':kwargs['RefNumberFilter_RefNumber']]} self.QBDict[self.__class__.__name__ + "Rq"]["RefNumberFilter"]={'MatchCriterion':kwargs['RefNumberFilter_MatchCriterion', 'RefNumber':kwargs['RefNumberFilter_RefNumber']]}
elif 'RefNumberRangeFilter_FromRefNumber' in kwargs or 'RefNumberRangeFilter_ToRefNumber' in kwargs: #if or then use {'key1':kwargs.get('key1',""), 'key2':kwargs.get('key2', "")} elif 'RefNumberRangeFilter_FromRefNumber' in kwargs or 'RefNumberRangeFilter_ToRefNumber' in kwargs: #if or then use {'key1':kwargs.get('key1',""), 'key2':kwargs.get('key2', "")}
self.QBDict[self.__class__.__name__ + "Rq"]["RefNumberRangeFilter"]={'FromRefNumber':kwargs.get('RefNumberRangeFilter_FromRefNumber', ""), 'ToRefNumber':kwargs.get('RefNumberRangeFilter_ToRefNumber', "")} ##### CAREFULL with the get() coz "" will get anything
self.QBDict[self.__class__.__name__ + "Rq"]["RefNumberRangeFilter"]={'FromRefNumber':kwargs.get('RefNumberRangeFilter_FromRefNumber', ""), 'ToRefNumber':kwargs.get('RefNumberRangeFilter_ToRefNumber', "")}
if 'CurrencyFilter_ListID' in kwargs: if 'CurrencyFilter_ListID' in kwargs:
self.QBDict[self.__class__.__name__ + "Rq"]["CurrencyFilter"]=kwargs['CurrencyFilter_ListID'] self.QBDict[self.__class__.__name__ + "Rq"]["CurrencyFilter"]=kwargs['CurrencyFilter_ListID']

View File

@ -1,6 +1,6 @@
from QBClasses import SalesOrderQuery, InvoiceQuery, TransactionQuery from QBClasses import SalesOrderQuery, InvoiceQuery, TransactionQuery
from utils import timing, makeAList from utils import timing, makeAList, makeLinkedTxnList
from pprint import pprint from pprint import pprint, PrettyPrinter
# h1="17b2d5" # h1="17b2d5"
# h2="17b2c1" # h2="17b2c1"
# res = int(h2,16)-int(h1,16) # res = int(h2,16)-int(h1,16)
@ -16,14 +16,113 @@ def main():
"IsToBeEmailed", "ExternalGUID", "IsToBeEmailed", "ExternalGUID",
"LinkedTxn", "InvoiceLineRet", "InvoiceLineGroupRet", "LinkedTxn", "InvoiceLineRet", "InvoiceLineGroupRet",
] ]
so_IncludeRetElements = ["TxnID", "TimeCreated", "TimeModified", "EditSequence", "TxnNumber", "CustomerRef",
"TxnDate", "RefNumber", "PONumber,", "SalesRepRef", "SubTotal", "TotalAmount",
"IsManuallyClosed", "IsFullyInvoiced", "Memo", "CustomerMsgRef", "LinkedTxn", "SalesOrderLineRet", "SalesOrderLineGroupRet",
]
refNumbers_listofdict= [{'RefNumber': '0099'}, {'RefNumber': '0100'}, {'RefNumber': '0103'}] refNumbers_listofdict= [{'RefNumber': '0099'}, {'RefNumber': '0100'}, {'RefNumber': '0103'}]
refNumbers_list= makeAList(refNumbers_listofdict,dictvalue=True, listofdict=True) refNumbers_list= makeAList(refNumbers_listofdict,dictvalue=True, listofdict=True)
print(refNumbers_list) print(refNumbers_list)
invQ = InvoiceQuery(**{'debug':False, 'MaxReturned':100, 'RefNumber':refNumbers_list, 'IncludeLineItems':'true', 'IncludeLinkedTxns':'true'})#, 'IncludeRetElements':IncludeRetElements})#, 'OwnerID':0} ) # invQ = InvoiceQuery(**{'debug':False, 'MaxReturned':1, 'RefNumber':refNumbers_list, 'IncludeLineItems':'true', 'IncludeLinkedTxns':'true', 'IncludeRetElements':IncludeRetElements})#, 'OwnerID':0} )
invQ = InvoiceQuery(**{'debug':False, 'MaxReturned':1, 'IncludeLineItems':'true', 'IncludeLinkedTxns':'true', 'IncludeRetElement':IncludeRetElements})#, 'OwnerID':0} )
# print(pprint(invQ), type(invQ), pprint(invQ.all())) # print(pprint(invQ), type(invQ), pprint(invQ.all()))
# print(invQ.response_string) # print(invQ.response_string)
print(invQ.filter("RefNumber")) # print(invQ.filter(["RefNumber","txnid"]))
print(invQ.count()) # print(invQ.all(), type(invQ.all()))
# PrettyPrinter( sort_dicts=False).pprint(invQ.all())
# pprint(invQ.all(),sort_dicts=False)
print(f'{invQ.count() =}')
## start process ##
invdicts = invQ.all()
if isinstance(invdicts,dict):
invdicts=[invdicts]
print("SALES ORDER")
for inv_idx, invdict in enumerate(invdicts): #loop over every Invoice, and get the linkedtxnID
InvoiceLineRet = invQ.filter("InvoiceLineRet").all(invdict)
linkedtxns = invQ.filter("LinkedTxn").all(invdict)
print(f'{InvoiceLineRet=}', type(InvoiceLineRet))
# print(linkedtxns, type(linkedtxns))
linkedTxnIDs=makeLinkedTxnList(linkedtxns, 'SalesOrder') #this is the list of linkedTxn.TxnID
print(f'{inv_idx=} of {len(invdicts)}; {linkedTxnIDs = }')
so_init={'IncludeLineItems':'true', 'IncludeLinkedTxns':'true', 'TxnID':linkedTxnIDs, 'IncludeRetElement': so_IncludeRetElements}
SOOrders=SalesOrderQuery(**so_init)
# pprint(SOOrders.all(), sort_dicts=False)
solineret = SOOrders.filter(["TxnID", "RefNumber", "SalesOrderLineRet"]).all()
# print(solineret)
sorefnumbers = SOOrders.filter("RefNumber").getValuesOf("RefNumber")
print(f'{sorefnumbers=}')
is_soRefNumber_duplicated = False
for sorefNumber in sorefnumbers: #check if SO RefNumber is duplicated, not valid RefNumber raise error
checkduplicateRefNumber = SalesOrderQuery(RefNumber=sorefNumber)
if checkduplicateRefNumber.count()==1:
pass # SOrefnumber no duplicate
print("no duplicate refnumber")
elif checkduplicateRefNumber.count()>1:
is_soRefNumber_duplicated=True
print(f"there is duplicate in one of there refnumbers:{sorefNumber=}")
raise Exception(f"there is duplicate in one of there refnumbers:{sorefNumber=}")
break
print(f'{checkduplicateRefNumber.count() = }')
if is_soRefNumber_duplicated:
return
#prepare SOOrders to be a list of dict
soorders = SOOrders.all()
if isinstance(soorders, dict):
soorders=[soorders]
#start comparing inv to so line by line
invLineRets = InvoiceLineRet[0].get('InvoiceLineRet')
for invLineRet in invLineRets:
FullName_inv = invLineRet['ItemRef']['FullName']
TxnLineID_inv = invLineRet['TxnLineID']
Quantity_inv = invLineRet['Quantity']
UnitOfMeasure_inv = invLineRet['UnitOfMeasure']
OverrideUOMSetRef_inv = invLineRet['OverrideUOMSetRef']['FullName']
Rate_inv = invLineRet['Rate']
Amount_inv = invLineRet['Amount']
for soorder in soorders:
pass
TxnID_so = soorder['TxnID']
RefNumber_so = soorder['RefNumber']
IsFullyInvoiced_so = soorder['IsFullyInvoiced']
IsManuallyClosed_so = soorder['IsManuallyClosed']
SalesOrderLineRet_so = soorder['SalesOrderLineRet']
LinkedTxn_so = soorder['LinkedTxn']
#prepare SalesOrderLineRet to be a list of dict
if isinstance(SalesOrderLineRet_so, dict):
SalesOrderLineRet_so = [SalesOrderLineRet_so]
# print(f'{SalesOrderLineRet_so = }')
for soLineRet_idx, soLineRet in enumerate(SalesOrderLineRet_so):
# print(soLineRet_idx, soLineRet)
print(f"{soLineRet_idx} {soLineRet.get('checked', False) = }")
if soLineRet.get('checked', False): # if can find checked key and not True, then skip next soLineRet
# print(soLineRet_idx,"continue")
continue
print(f'{soLineRet_idx = }->{soLineRet}')
FullName_so = soLineRet['ItemRef']['FullName']
TxnLineID_so = soLineRet['TxnLineID']
Quantity_so = soLineRet['Quantity']
UnitOfMeasure_so = soLineRet['UnitOfMeasure']
OverrideUOMSetRef_so = soLineRet['OverrideUOMSetRef']['FullName']
Rate_so = soLineRet['Rate']
Amount_so = soLineRet['Amount']
Invoiced_so = soLineRet.get('Invoiced',0)
IsManuallyClosed_so = soLineRet['IsManuallyClosed']
SalesOrderLineRet_so[soLineRet_idx]['checked']=True
# break only if match with invlineret==solineret
# pprint(solineret, sort_dicts=False)
# pprint(SOOrders.all(), sort_dicts=False)
# pprint(invQ.all())
print(f'{SOOrders.count() = }')
if __name__=='__main__': if __name__=='__main__':

View File

@ -69,7 +69,7 @@ class baseQBQuery:
dataDict["?qbxml"]["QBXML"] = {"QBXMLMsgsRq": { ### Example with multiple FullName Item ### dataDict["?qbxml"]["QBXML"] = {"QBXMLMsgsRq": { ### Example with multiple FullName Item ###
"@onError": self.onError, "@onError": self.onError,
firstKey: self.QBDict[firstKey]}} firstKey: self.QBDict[firstKey]}}
print(f'{dataDict = }') # print(f'{dataDict = }')
# # QBXML = '<?qbxml version="13.0"?>' + xmltodict.unparse(dataDict, pretty=True) # # QBXML = '<?qbxml version="13.0"?>' + xmltodict.unparse(dataDict, pretty=True)
self.QBXML = xmltodict.unparse(dataDict, pretty=True).replace("</?qbxml>", "").replace(f'version="{version}"', f'version="{version}"?') self.QBXML = xmltodict.unparse(dataDict, pretty=True).replace("</?qbxml>", "").replace(f'version="{version}"', f'version="{version}"?')
print(self.QBXML, type(self.QBXML)) print(self.QBXML, type(self.QBXML))

View File

@ -2,6 +2,25 @@
from time import time from time import time
from typing import Union from typing import Union
def makeLinkedTxnList(x:list, key:str=None)->list:
txnIDs=[]
if isinstance(x, dict):
x=[x]
print(f'{type(x)=}')
for y in x: #y = each dict of LinkedTxn, and it has a listofdict or a dict inside
linkedTxns=y.get('LinkedTxn',None)
if linkedTxns is None:
return
if isinstance(linkedTxns, dict):
linkedTxns = [linkedTxns]
for linkedTxn in linkedTxns:
# print(f'{key = }')
if key and linkedTxn.get('TxnType')==key:
txnIDs.append(linkedTxn.get('TxnID',None))
print(f'{txnIDs = }')
return txnIDs
def makeAList(x:Union[str , dict , list], dictvalue:bool=False, listofdict:bool=False)->list : def makeAList(x:Union[str , dict , list], dictvalue:bool=False, listofdict:bool=False)->list :
if isinstance(x,str): if isinstance(x,str):
x=[x] x=[x]