diff --git a/QBClasses.py b/QBClasses.py index 98ea5f3..fc67e29 100644 --- a/QBClasses.py +++ b/QBClasses.py @@ -3,7 +3,7 @@ import pprint import timeit import xml.dom.minidom from utils import timing, cleanIncludeRetElements - +import json # from functools import wraps @@ -56,8 +56,9 @@ class ItemInventoryQuery(baseQBQuery): self.QBDict[self.__class__.__name__ + "Rq"]["ToModifiedDate"]=kwargs['ToModifiedDate'] if 'MatchCriterion' in kwargs and 'Name' in kwargs: self.QBDict[self.__class__.__name__ + "Rq"]["NameFilter"]={'MatchCriterion':kwargs['MatchCriterion', 'Name':kwargs['Name']]} - if 'FromName' in kwargs or 'ToName' in kwargs: + elif 'FromName' in kwargs or 'ToName' in kwargs: #if or then use {'key1':kwargs.get('key1',""), 'key2':kwargs.get('key2', "")} self.QBDict[self.__class__.__name__ + "Rq"]["NameRangeFilter"]={'FromName':kwargs.get('FromName', ""), 'ToName':kwargs.get('ToName', "")} + if 'IncludeRetElement' in kwargs: IRE = cleanIncludeRetElements(self.includeRetElements_allowed, kwargs["IncludeRetElement"]) # IRE->IncludeRetElements cleaned version print(f"{IRE = }") @@ -65,7 +66,8 @@ class ItemInventoryQuery(baseQBQuery): if self.defaultFilterKey not in IRE: # defaultFilterKey is for BaseClass.count() eg: after instantiate, then print obj.count() IRE.append(self.defaultFilterKey) self.QBDict[self.__class__.__name__ + "Rq"]["IncludeRetElement"]=IRE - if 'OwnerID' in kwargs: + + if 'OwnerID' in kwargs: # usually value=0 to get to DataExtRet (additional data) self.QBDict[self.__class__.__name__ + "Rq"]["OwnerID"]=kwargs['OwnerID'] # print(self.__class__.__name__ + "Rq") @@ -101,6 +103,7 @@ class GeneralSummaryReportQuery(baseQBQuery): else: print("Error -> GeneralSummaryReportType is required") return + if 'FromReportDate' in kwargs or 'ToReportDate' in kwargs: self.QBDict[self.__class__.__name__ + "Rq"]["ReportPeriod"]={'FromReportDate':kwargs.get('FromReportDate', ""), 'ToReportDate':kwargs.get('ToReportDate', "")} elif 'ReportDateMacro' in kwargs: @@ -119,8 +122,9 @@ class GeneralSummaryReportQuery(baseQBQuery): self.QBDict[self.__class__.__name__ + "Rq"]["ToModifiedDate"]=kwargs['ToModifiedDate'] if 'MatchCriterion' in kwargs and 'Name' in kwargs: self.QBDict[self.__class__.__name__ + "Rq"]["NameFilter"]={'MatchCriterion':kwargs['MatchCriterion', 'Name':kwargs['Name']]} - if 'FromName' in kwargs or 'ToName' in kwargs: + elif 'FromName' in kwargs or 'ToName' in kwargs: self.QBDict[self.__class__.__name__ + "Rq"]["NameRangeFilter"]={'FromName':kwargs.get('FromName', ""), 'ToName':kwargs.get('ToName', "")} + if 'IncludeRetElement' in kwargs: IRE = cleanIncludeRetElements(self.includeRetElements_allowed, kwargs["IncludeRetElement"]) #IRE->IncludeRetElements cleaned version print(f"{IRE = }") @@ -128,13 +132,13 @@ class GeneralSummaryReportQuery(baseQBQuery): if self.defaultFilterKey not in IRE: #defaultFilterKey is for BaseClass.count() eg: after instantiate, then print obj.count() IRE.append(self.defaultFilterKey) self.QBDict[self.__class__.__name__ + "Rq"]["IncludeRetElement"]=IRE - if 'OwnerID' in kwargs: - self.QBDict[self.__class__.__name__ + "Rq"]["OwnerID"]=kwargs['OwnerID'] # print(self.__class__.__name__ + "Rq") # print(f'{self.QBDict = }') self.runCheck() ### running the qbxml connection to get data ### + + class InvoiceAdd(baseQBQuery): def __init__(self, *args, **kwargs): print(f'{args = }') @@ -227,9 +231,155 @@ class CustomerQuery(baseQBQuery): self.runCheck() ### running the qbxml connection to get data ### +class TransactionQuery(baseQBQuery): + def __init__(self, *args, **kwargs): + print(f'{args = }') + print(f'{kwargs = }') + super().__init__(*args, **kwargs) + ### Required Variable + self.includeRetElements_allowed = ["TxnType", "TxnID", "TxnLineID", "TimeCreated", "TimeModified", "EntityRef", "AccountRef", "TxnDate", "RefNumber", + "Amount", "CurrencyRef", "ExchangeRate", "AmountInHomeCurrency", "Memo", + ] + self.onError = "stopOnError" + self.retName = 'TransactionRet' + self.defaultFilterKey = "TxnID" + if 'debug' in kwargs and isinstance(kwargs['debug'], bool): + self.class_debug=kwargs["debug"] + + self.QBDict[self.__class__.__name__ + "Rq"]={} + ### End Required Variable. can put ENUM list below this (eg: self.ENUM_GeneralSummaryReportQuery=[]) + + if 'TxnID' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TxnID"]=kwargs['TxnID'] + else: + if 'MaxReturned' in kwargs: + if kwargs['MaxReturned'] is None: + if 'TxnID' in kwargs: + MaxReturned = None + elif len(kwargs)>1 : + MaxReturned = None + else: + MaxReturned = 1000 + elif isinstance(kwargs['MaxReturned'], str) and not kwargs['MaxReturned'].isdigit(): + MaxReturned = 0 + elif not isinstance(kwargs['MaxReturned'], int): + MaxReturned = 0 + elif int(kwargs['MaxReturned']) > 1000: + MaxReturned = 1000 + elif int(kwargs['MaxReturned']) > 0: + MaxReturned = kwargs['MaxReturned'] + else: + MaxReturned = 0 + else: + MaxReturned = 0 + self.QBDict[self.__class__.__name__ + "Rq"]["MaxReturned"]=MaxReturned + + if 'RefNumber' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["RefNumber"]=kwargs['RefNumber'] + elif 'RefNumberCaseSensitive' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["RefNumberCaseSensitive"]=kwargs['RefNumberCaseSensitive'] + elif 'RefNumberFilter_MatchCriterion' in kwargs and 'RefNumberFilter_RefNumber' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["RefNumberFilter"]={'MatchCriterion':kwargs['RefNumberFilter_MatchCriterion', 'RefNumber':kwargs['RefNumberFilter_RefNumber']]} + elif 'RefNumberFilter_FromRefNumber' in kwargs or 'RefNumberFilter_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('RefNumberFilter_FromRefNumber', ""), 'ToRefNumber':kwargs.get('RefNumberFilter_ToRefNumber', "")} + + if 'TransactionModifiedDateRangeFilter_FromModifiedDate' in kwargs or 'TransactionModifiedDateRangeFilter_ToModifiedDate' in kwargs: #if or then use {'key1':kwargs.get('key1',""), 'key2':kwargs.get('key2', "")} + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionModifiedDateRangeFilter"]={'FromModifiedDate':kwargs.get('TransactionModifiedDateRangeFilter_FromModifiedDate', ""), 'ToModifiedDate':kwargs.get('TransactionModifiedDateRangeFilter_ToModifiedDate', "")} + elif 'TransactionModifiedDateRangeFilter_DateMacro' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionModifiedDateRangeFilter"]={'DateMacro':kwargs['TransactionModifiedDateRangeFilter_DateMacro']} + + if 'TransactionDateRangeFilter_FromTxnDate' in kwargs or 'TransactionDateRangeFilter_ToTxnDate' in kwargs: #if or then use {'key1':kwargs.get('key1',""), 'key2':kwargs.get('key2', "")} + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionDateRangeFilter"]={'FromTxnDate':kwargs.get('TransactionDateRangeFilter_FromTxnDate', ""), 'ToTxnDate':kwargs.get('TransactionDateRangeFilter_ToTxnDate', "")} + elif 'TransactionDateRangeFilter_DateMacro' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionDateRangeFilter"]={'DateMacro':kwargs['TransactionDateRangeFilter_DateMacro']} + + if 'TransactionEntityFilter_EntityTypeFilter' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionEntityFilter"]={'EntityTypeFilter':kwargs['TransactionEntityFilter_EntityTypeFilter']} + elif 'TransactionEntityFilter_ListID' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionEntityFilter"]={'ListID':kwargs['TransactionEntityFilter_ListID']} + elif 'TransactionEntityFilter_FullName' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionEntityFilter"]={'FullName':kwargs['TransactionEntityFilter_FullName']} + elif 'TransactionEntityFilter_ListIDWithChildren' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionEntityFilter"]={'ListIDWithChildren':kwargs['TransactionEntityFilter_ListIDWithChildren']} + elif 'TransactionEntityFilter_FullNameWithChildren' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionEntityFilter"]={'FullNameWithChildren':kwargs['TransactionEntityFilter_FullNameWithChildren']} + + if 'TransactionAccountFilter_AccountTypeFilter' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionAccountFilter"]={'AccountTypeFilter':kwargs['TransactionAccountFilter_AccountTypeFilter']} + elif 'TransactionAccountFilter_ListID' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionAccountFilter"]={'ListID':kwargs['TransactionAccountFilter_ListID']} + elif 'TransactionAccountFilter_FullName' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionAccountFilter"]={'FullName':kwargs['TransactionAccountFilter_FullName']} + elif 'TransactionAccountFilter_ListIDWithChildren' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionAccountFilter"]={'ListIDWithChildren':kwargs['TransactionAccountFilter_ListIDWithChildren']} + elif 'TransactionAccountFilter_FullNameWithChildren' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionAccountFilter"]={'FullNameWithChildren':kwargs['TransactionAccountFilter_FullNameWithChildren']} + + if 'TransactionItemFilter_ItemTypeFilter' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionItemFilter"]={'ItemTypeFilter':kwargs['TransactionItemFilter_ItemTypeFilter']} + elif 'TransactionItemFilter_ListID' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionItemFilter"]={'ListID':kwargs['TransactionItemFilter_ListID']} + elif 'TransactionItemFilter_FullName' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionItemFilter"]={'FullName':kwargs['TransactionItemFilter_FullName']} + elif 'TransactionItemFilter_ListIDWithChildren' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionItemFilter"]={'ListIDWithChildren':kwargs['TransactionItemFilter_ListIDWithChildren']} + elif 'TransactionItemFilter_FullNameWithChildren' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionItemFilter"]={'FullNameWithChildren':kwargs['TransactionItemFilter_FullNameWithChildren']} + + if 'TransactionClassFilter_ListID' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionClassFilter"]={'ListID':kwargs['TransactionClassFilter_ListID']} + elif 'TransactionClassFilter_FullName' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionClassFilter"]={'FullName':kwargs['TransactionClassFilter_FullName']} + elif 'TransactionClassFilter_ListIDWithChildren' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionClassFilter"]={'ListIDWithChildren':kwargs['TransactionClassFilter_ListIDWithChildren']} + elif 'TransactionClassFilter_FullNameWithChildren' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionClassFilter"]={'FullNameWithChildren':kwargs['TransactionClassFilter_FullNameWithChildren']} + + if 'TransactionTypeFilter_TxnTypeFilter' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionTypeFilter"]={'TxnTypeFilter':kwargs['TransactionTypeFilter_TxnTypeFilter']} + + if 'TransactionDetailLevelFilter' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionDetailLevelFilter"]=kwargs['TransactionDetailLevelFilter'] + + if 'TransactionPostingStatusFilter' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionPostingStatusFilter"]=kwargs['TransactionPostingStatusFilter'] + + if 'TransactionPaidStatusFilter' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["TransactionPaidStatusFilter"]=kwargs['TransactionPaidStatusFilter'] + + if 'CurrencyFilter_ListID' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["CurrencyFilter"]=kwargs['CurrencyFilter_ListID'] + elif 'CurrencyFilter_FullName' in kwargs: + self.QBDict[self.__class__.__name__ + "Rq"]["CurrencyFilter"]=kwargs['CurrencyFilter_FullName'] + + if 'IncludeRetElement' in kwargs: + IRE = cleanIncludeRetElements(self.includeRetElements_allowed, kwargs["IncludeRetElement"]) # IRE->IncludeRetElements cleaned version + print(f"{IRE = }") + if len(IRE)>0: + if self.defaultFilterKey not in IRE: # defaultFilterKey is for BaseClass.count() eg: after instantiate, then print obj.count() + IRE.append(self.defaultFilterKey) + self.QBDict[self.__class__.__name__ + "Rq"]["IncludeRetElement"]=IRE + + + # print(self.__class__.__name__ + "Rq") + # print(self.QBDict) + self.runCheck() ### running the qbxml connection to get data ### + if __name__ == "__main__": + @timing + def transactionquery(): + g=TransactionQuery(debug=False, MaxReturned=None, TransactionTypeFilter_TxnTypeFilter="SalesOrder", TransactionEntityFilter_FullName="Abadi Serpong", + TransactionDetailLevelFilter="All", TransactionPaidStatusFilter="Open", TransactionDateRangeFilter_DateMacro="LastFiscalYear") + # print(g.response_string) + # pprint.pprint({"temp":g.filter(['TxnType', 'TxnID', 'Entityref', 'accountref', 'txndate', 'refnumber'])}) + # print(json.dumps(g.filter(['TxnType', 'TxnID', 'Entityref', 'accountref', 'refnumber','txndate',"amount" ]).all(), indent=3)) + + print(json.dumps(g.filter().all(), indent=3)) + + print(g.count()) + @timing def main(): g= GeneralSummaryReportQuery(debug=False, GeneralSummaryReportType="ProfitAndLossStandard", ReportDateMacro="ThisYear") @@ -331,9 +481,10 @@ if __name__ == "__main__": print() print(recursiveDict(varDict, f, enumDict)) f.close - + + transactionquery() # main() - iteminventoryquery() + # iteminventoryquery() # customerquery() # readxmltodict() diff --git a/server.py b/server.py index 1728d8d..641d816 100644 --- a/server.py +++ b/server.py @@ -106,7 +106,7 @@ class baseQBQuery: # print(xmltodict.parse(self.response_string)) self.varDict = xmltodict.parse(self.response_string) if self.class_debug: - pprint.pprint(self.varDict) + pprint.pprint("isDataOK", self.varDict) self.listOfDict.varDict = self.varDict self.listOfDict.filterKey = ["@statusCode"] self.statusCode = self.listOfDict.firstValue().get('@statusCode',None) @@ -115,7 +115,8 @@ class baseQBQuery: self.listOfDict.filterKey = ["@statusSeverity"] self.statusSeverity = self.listOfDict.firstValue().get('@statusSeverity') self.listOfDict.filterKey = [self.retName] - print(self.listOfDict.firstValue()) + if self.class_debug: + print(f'isDataOK -> {self.listOfDict.firstValue() = }') if self.listOfDict.firstValue().get(self.retName,None)==None: return False @@ -203,6 +204,9 @@ class baseQBQuery: pass elif isinstance(key, dict): key = [x for x,y in key.items()] + elif key is None: + # print(f"key is none. {self.retName = }") + return self.ListOfDict(self.retName, self.varDict, self.retName, self.includeRetElements_allowed, self.statusOk)#.firstValue()#[self.retName] else: return [] key = cleanIncludeRetElements(self.includeRetElements_allowed, key) @@ -236,7 +240,10 @@ class baseQBQuery: # print(f'{key =}, {var =}') # self.first = self.find_firstListOfDict(key) if key: - self.filterKey = key + if isinstance(key, str): + self.filterKey = [key] + else: + self.filterKey = key else: self.filterKey = [retName] # print(f"{self.filterKey = }")