diff --git a/CustomerQuery.xml b/CustomerQuery.xml
new file mode 100644
index 0000000..8e7954d
--- /dev/null
+++ b/CustomerQuery.xml
@@ -0,0 +1,236 @@
+
+
+
+
+
+
+ IDTYPE
+
+ STRTYPE
+
+ INTTYPE
+
+ ENUMTYPE
+ DATETIMETYPE
+ DATETIMETYPE
+
+
+
+ ENUMTYPE
+ STRTYPE
+
+
+
+ STRTYPE
+ STRTYPE
+
+
+
+
+ ENUMTYPE
+ AMTTYPE
+
+
+
+ IDTYPE
+
+ STRTYPE
+
+
+
+
+ IDTYPE
+
+ STRTYPE
+
+ IDTYPE
+
+ STRTYPE
+
+
+
+ STRTYPE
+ GUIDTYPE
+
+
+
+
+ IDTYPE
+ DATETIMETYPE
+ DATETIMETYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ BOOLTYPE
+
+ IDTYPE
+ STRTYPE
+
+
+ IDTYPE
+ STRTYPE
+
+ INTTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+
+
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+
+
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+
+
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+
+
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ BOOLTYPE
+
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+
+ STRTYPE
+ STRTYPE
+
+
+ IDTYPE
+ DATETIMETYPE
+ DATETIMETYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+
+ STRTYPE
+ STRTYPE
+
+
+
+ IDTYPE
+ STRTYPE
+
+
+ IDTYPE
+ STRTYPE
+
+
+ IDTYPE
+ STRTYPE
+
+ AMTTYPE
+ AMTTYPE
+
+ IDTYPE
+ STRTYPE
+
+
+ IDTYPE
+ STRTYPE
+
+
+ ENUMTYPE
+ STRTYPE
+ STRTYPE
+ AMTTYPE
+
+ IDTYPE
+ STRTYPE
+
+
+ STRTYPE
+ INTTYPE
+ INTTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+
+
+ ENUMTYPE
+ DATETYPE
+ DATETYPE
+ DATETYPE
+ STRTYPE
+
+ IDTYPE
+ STRTYPE
+
+ STRTYPE
+
+ INTTYPE
+ DATETYPE
+ STRTYPE
+
+
+ ENUMTYPE
+
+ IDTYPE
+ STRTYPE
+
+ GUIDTYPE
+ STRTYPE
+
+ IDTYPE
+ STRTYPE
+
+
+ GUIDTYPE
+ STRTYPE
+
+ ENUMTYPE
+ STRTYPE
+
+
+
+
+
diff --git a/InvoiceAdd.xml b/InvoiceAdd.xml
new file mode 100644
index 0000000..918fc30
--- /dev/null
+++ b/InvoiceAdd.xml
@@ -0,0 +1,174 @@
+
+
+
+ IDTYPE
+ STRTYPE
+
+
+ IDTYPE
+ STRTYPE
+
+
+ IDTYPE
+ STRTYPE
+
+
+ IDTYPE
+ STRTYPE
+
+ DATETYPE
+ STRTYPE
+
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+
+
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+ STRTYPE
+
+ BOOLTYPE
+ BOOLTYPE
+ STRTYPE
+
+ IDTYPE
+ STRTYPE
+
+ DATETYPE
+
+ IDTYPE
+ STRTYPE
+
+ STRTYPE
+ DATETYPE
+
+ IDTYPE
+ STRTYPE
+
+
+ IDTYPE
+ STRTYPE
+
+ STRTYPE
+
+ IDTYPE
+ STRTYPE
+
+ BOOLTYPE
+ BOOLTYPE
+ BOOLTYPE
+
+ IDTYPE
+ STRTYPE
+
+ STRTYPE
+ FLOATTYPE
+ GUIDTYPE
+ IDTYPE
+
+ IDTYPE
+ AMTTYPE
+ BOOLTYPE
+
+
+
+
+ IDTYPE
+ STRTYPE
+
+ STRTYPE
+ QUANTYPE
+ STRTYPE
+
+ PRICETYPE
+
+ PERCENTTYPE
+
+
+ IDTYPE
+ STRTYPE
+
+
+
+ IDTYPE
+ STRTYPE
+
+ AMTTYPE
+
+ ENUMTYPE
+
+ IDTYPE
+ STRTYPE
+
+
+ IDTYPE
+ STRTYPE
+
+
+ STRTYPE
+
+ STRTYPE
+
+ DATETYPE
+
+ IDTYPE
+ STRTYPE
+
+
+ IDTYPE
+ STRTYPE
+
+ STRTYPE
+ STRTYPE
+
+ IDTYPE
+ IDTYPE
+
+
+ GUIDTYPE
+ STRTYPE
+ STRTYPE
+
+
+
+
+
+ IDTYPE
+ STRTYPE
+
+ QUANTYPE
+ STRTYPE
+
+ IDTYPE
+ STRTYPE
+
+
+ IDTYPE
+ STRTYPE
+
+
+ GUIDTYPE
+ STRTYPE
+ STRTYPE
+
+
+
+
+ STRTYPE
+
+
diff --git a/ItemInventoryQuery.xml b/ItemInventoryQuery.xml
new file mode 100644
index 0000000..7cecb4c
--- /dev/null
+++ b/ItemInventoryQuery.xml
@@ -0,0 +1,38 @@
+
+
+ IDTYPE
+
+ STRTYPE
+
+ INTTYPE
+
+ ENUMTYPE
+ DATETIMETYPE
+ DATETIMETYPE
+
+
+
+ ENUMTYPE
+ STRTYPE
+
+
+
+ STRTYPE
+ STRTYPE
+
+
+
+
+ IDTYPE
+
+ STRTYPE
+
+ IDTYPE
+
+ STRTYPE
+
+
+
+ STRTYPE
+ GUIDTYPE
+
diff --git a/QBClasses.py b/QBClasses.py
index 4c8a8cc..1fe9fb2 100644
--- a/QBClasses.py
+++ b/QBClasses.py
@@ -1,5 +1,9 @@
-from server import baseQBQuery
+from server import baseQBQuery, timing
import pprint
+import timeit
+
+
+# from functools import wraps
class ItemInventoryQuery(baseQBQuery):
def __init__(self, *args, **kwargs):
@@ -74,6 +78,40 @@ class GeneralSummaryReportQuery(baseQBQuery):
print(self.__class__.__name__ + "Rq")
print(f'{self.QBDict = }')
+class InvoiceAdd(baseQBQuery):
+ def __init__(self, *args, **kwargs):
+ print(f'{args = }')
+ print(f'{kwargs = }')
+ super().__init__(*args, **kwargs)
+ self.retName = 'InvoiceAddRet'
+ self.reqSubName = self.retName.replace('Ret', '')
+ self.QBDict[self.__class__.__name__ + "Rq"]={}
+ if 'CustomerFullName' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["ListID"]=kwargs['ListID']
+ if 'ListID' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["ListID"]=kwargs['ListID']
+ elif 'FullName' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["FullName"]=kwargs['FullName']
+ else:
+ if 'MaxReturned' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["MaxReturned"]=kwargs['MaxReturned']
+ if 'ActiveStatus' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["ActiveStatus"]=kwargs['ActiveStatus']
+ if 'FromModifiedDate' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["FromModifiedDate"]=kwargs['FromModifiedDate']
+ if 'ToModifiedDate' in kwargs:
+ 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:
+ self.QBDict[self.__class__.__name__ + "Rq"]["NameRangeFilter"]={'FromName':kwargs.get('FromName', ""), 'ToName':kwargs.get('ToName', "")}
+ if 'IncludeRetElement' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["IncludeRetElement"]=kwargs['IncludeRetElement']
+ if 'OwnerID' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["OwnerID"]=kwargs['OwnerID']
+
+ # print(self.__class__.__name__ + "Rq")
+ # print(self.QBDict)
# x=ItemInventoryQuery('bagus', 'kedua', key5=5, key2="hore", FullName1='hooooo', FromName1="sg", ToName1="sugi", IncludeRetElement1=['Name', 'FullName'], MaxReturned="2")
# x.create_QBXML()
@@ -112,7 +150,109 @@ class GeneralSummaryReportQuery(baseQBQuery):
# print(a2)
# print(a1)
-g= GeneralSummaryReportQuery(GeneralSummaryReportType="ProfitAndLossStandard", ReportDateMacro="ThisYear")
-print(type(g.all()))
-print(g.all())
-pprint.pprint(g.filter("ColData").all())
\ No newline at end of file
+class CustomerQuery(baseQBQuery):
+ def __init__(self, *args, **kwargs):
+ print(f'{args = }')
+ print(f'{kwargs = }')
+ super().__init__(*args, **kwargs)
+ self.onError = "stopOnError"
+ self.retName = 'CustomerRet'
+ self.QBDict[self.__class__.__name__ + "Rq"]={}
+ if 'ListID' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["ListID"]=kwargs['ListID']
+ elif 'FullName' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["FullName"]=kwargs['FullName']
+ else:
+ if 'MaxReturned' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["MaxReturned"]=kwargs['MaxReturned']
+ if 'ActiveStatus' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["ActiveStatus"]=kwargs['ActiveStatus']
+ if 'FromModifiedDate' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["FromModifiedDate"]=kwargs['FromModifiedDate']
+ if 'ToModifiedDate' in kwargs:
+ 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']}
+ elif 'FromName' in kwargs or 'ToName' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["NameRangeFilter"]={'FromName':kwargs.get('FromName', ""), 'ToName':kwargs.get('ToName', "")}
+
+ if 'Operator' in kwargs and 'Amount' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["TotalBalanceFilter"]={'Operator':kwargs['Operator'], 'Amount':kwargs['Amount']}
+ if 'IncludeRetElement' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["IncludeRetElement"]=kwargs['IncludeRetElement']
+ if 'OwnerID' in kwargs:
+ self.QBDict[self.__class__.__name__ + "Rq"]["OwnerID"]=kwargs['OwnerID']
+
+ print(self.__class__.__name__ + "Rq")
+ print(self.QBDict)
+
+
+@timing
+def main():
+ g= GeneralSummaryReportQuery(GeneralSummaryReportType="ProfitAndLossStandard", ReportDateMacro="ThisYear")
+ print(type(g.all()))
+ print(g.all())
+ pprint.pprint(g.filter("ColData").all())
+
+def customerquery():
+ g= CustomerQuery(MaxReturned=3, IncludeRetElement=["FullName", "Name", "CompanyName", "BillAddressBlock", "ShipAddress"])
+ print("init finish")
+ print(f'{type(g.all()) = }')
+ print("before g.all")
+ print(f'{g.all() = }')
+ # print("after g.all")
+ # pprint.pprint(g.filter("ColData").all())
+
+def readxmltodict():
+ import xmltodict
+ filename="ItemInventoryQuery.xml"
+ filename="InvoiceAdd.xml"
+ with open(filename, "r") as f:
+ xml = f.read()
+ print(xml)
+ print("")
+ print("")
+ with open(filename, "r") as f:
+ xmllines = f.readlines()
+ print(xmllines)
+ varDict = xmltodict.parse(xml)
+ # print(f"{varDict = }")
+ print()
+ f = open(filename)
+ enumDict ={}
+ def recursiveDict(varDict, f, enumDict):
+ # print(varDict)
+ for dKey in varDict:
+ print(dKey)
+ if not isinstance(varDict[dKey], (list, dict)):
+ if dKey[0]=='@' or dKey[0]=="#":
+ continue
+ _ = f.readline()
+ dKey = dKey.replace("#", "")
+ print(dKey)
+ # print(f'{dKey = }, {varDict[dKey]}, {_}')
+ _strOptional = ""
+ while not dKey in _:
+ _ = f.readline()
+ # print(f'{dKey = }, {varDict[dKey]}, {_}')
+ if "values:" in _:
+ enumDict[dKey]=_.split(":")[-1].replace("[DEFAULT]","").replace("-->","").replace(" ","").replace("\n","").split(",")
+ _ = f.readline()
+ _strOptional = _.split("--")[1].strip()
+ varDict[dKey]+=";"+_strOptional
+ print(f'{varDict[dKey] = }')
+ elif isinstance(varDict[dKey], dict):
+ varDict[dKey], enumDict=recursiveDict(varDict[dKey], f, enumDict)##### istirahat dulu ah
+ return varDict, enumDict
+ print(f'{varDict = }')
+ print()
+ print(recursiveDict(varDict, f, enumDict))
+ f.close
+
+
+if __name__ == "__main__":
+ # main()
+ customerquery()
+ # readxmltodict()
+
+
diff --git a/server.py b/server.py
index c1765a8..db9ba1a 100644
--- a/server.py
+++ b/server.py
@@ -3,6 +3,20 @@ import xmltodict
import win32com.client
import xml.etree.ElementTree as ET
+from time import time
+
+def timing(f):
+ # @wraps(f)
+ def wrap(*args, **kw):
+ ts = time()
+ result = f(*args, **kw)
+ te = time()
+ print('func:%r args:[%r, %r] took: %2.6f sec' % \
+ (f.__name__, args, kw, te-ts))
+ return result
+ return wrap
+
+
class baseQBQuery:
def __init__(self, *args, **kwargs, ) -> None:
# print(f'{kwargs = }')
@@ -18,7 +32,8 @@ class baseQBQuery:
self.statusCode = -1
self.statusMessage = ""
self.statusSeverity = ""
-
+
+ @timing
def create_QBXML(self):
dataDict = { ### Header for qmxml with version attribute
"?qbxml": {
@@ -50,7 +65,8 @@ class baseQBQuery:
self.QBXML = xmltodict.unparse(dataDict, pretty=True).replace("?qbxml>", "")
print(self.QBXML)
return self.QBXML
-
+
+ @timing
def connect_to_quickbooks(self, qbxml_query=None):
# Connect to Quickbooks
sessionManager = win32com.client.Dispatch("QBXMLRP2.RequestProcessor")