diff --git a/QBClass/QBClasses.py b/QBClass/QBClasses.py index 048098a..04f0fab 100644 --- a/QBClass/QBClasses.py +++ b/QBClass/QBClasses.py @@ -96,7 +96,7 @@ class GeneralSummaryReportQuery(baseQBQuery): if 'GeneralSummaryReportType' in kwargs: enum=cleanIncludeRetElements(self.ENUM_GeneralSummaryReportType, kwargs['GeneralSummaryReportType']) - print(enum) + print(f'{enum = }') self.QBDict[self.classNameRq]["GeneralSummaryReportType"]=enum[0] else: print("Error -> GeneralSummaryReportType is required") @@ -181,8 +181,8 @@ class GeneralSummaryReportQuery(baseQBQuery): self.QBDict[self.classNameRq]["IncludeSubColumns"]=kwargs['IncludeSubColumns'] if 'ReportCalendar' in kwargs: self.QBDict[self.classNameRq]["ReportCalendar"]=cleanIncludeRetElements(['CalendarYear', 'FiscalYear', 'TaxYear'], kwargs['ReportCalendar'], default_val='CalendarYear') - if 'ReturnsRows' in kwargs: - self.QBDict[self.classNameRq]["ReturnsRows"]=cleanIncludeRetElements(['ActiveOnly', 'NonZero', 'All'], kwargs['ReturnsRows'], default_val='ActiveOnly') + if 'ReturnRows' in kwargs: + self.QBDict[self.classNameRq]["ReturnRows"]=cleanIncludeRetElements(['ActiveOnly', 'NonZero', 'All'], kwargs['ReturnRows'], default_val='ActiveOnly') if 'ReturnColumns' in kwargs: self.QBDict[self.classNameRq]["ReturnColumns"]=cleanIncludeRetElements(['ActiveOnly', 'NonZero', 'All'], kwargs['ReturnColumns'], default_val='ActiveOnly') if 'ReportBasis' in kwargs: @@ -200,6 +200,69 @@ class GeneralSummaryReportQuery(baseQBQuery): # print(f'{self.QBDict = }') if self.__class__.__name__==self.className: self.runCheck() ### running the qbxml connection to get data ### + + +class PriceLevelQuery(baseQBQuery): + def __init__(self, *args, **kwargs): + print(f'{args = }') + print(f'{kwargs = }') + super().__init__( ) + ## Required variable + self.includeRetElements_allowed = ["ListID", "TimeCreated", "TimeModified", "EditSequence", "Name", "isActive", "PriceLevelType", "PriceLevelFixedPercentage", + "PriceLevelPerItemRet", "ItemRef", "CustomPrice", "CustomePricePercent", "CurrencyRef"] + self.onError = "stopOnError" + self.retName = 'PriceLevelRet' + self.defaultFilterKey = "ListID" + self.className = "PriceLevelQuery" + self.classNameRq:str = self.__class__.__name__ + 'Rq' + if 'debug' in kwargs and isinstance(kwargs['debug'], bool): + self.class_debug=kwargs["debug"] + + self.QBDict[self.classNameRq]={} #Required + ### End Required variable + + self.ENUM_ActiveStatus = ['ActiveOnly', 'InactiveOnly', 'All'] + self.ENUM_MatchCriterion = ['StartsWith', 'Contains', 'EndsWith'] + + if 'ListID' in kwargs: + self.QBDict[self.classNameRq]["ListID"]=kwargs['ListID'] + elif 'FullName' in kwargs: + self.QBDict[self.classNameRq]["FullName"]=kwargs['FullName'] + else: + if 'MaxReturned' in kwargs: + self.QBDict[self.classNameRq]["MaxReturned"]=kwargs['MaxReturned'] + if 'ActiveStatus' in kwargs: + enum=cleanIncludeRetElements(self.ENUM_ActiveStatus, kwargs['ActiveStatus']) + self.QBDict[self.classNameRq]["ActiveStatus"]=enum[0] + if 'FromModifiedDate' in kwargs: + self.QBDict[self.classNameRq]["FromModifiedDate"]=kwargs['FromModifiedDate'] + if 'ToModifiedDate' in kwargs: + self.QBDict[self.classNameRq]["ToModifiedDate"]=kwargs['ToModifiedDate'] + if 'NameFilter_MatchCriterion' in kwargs and 'NameFilter_Name' in kwargs: + enum= cleanIncludeRetElements(self.ENUM_MatchCriterion, kwargs['NameFilter_MatchCriterion']) + self.QBDict[self.classNameRq]["NameFilter"]={'MatchCriterion': enum[0], 'Name': kwargs['NameFilter_Name']} + elif 'NameRangeFilter_FromName' in kwargs or 'NameRangeFilter_ToName' in kwargs: + self.QBDict[self.classNameRq]["NameRangeFilter"]={'FromName':kwargs.get('NameRangeFilter_FromName', None), 'ToReportDate':kwargs.get('NameRangeFilter_ToName', None)} + if 'ItemRef_ListID' in kwargs or 'ItemRef_FullName' in kwargs: + self.QBDict[self.classNameRq]["ItemRef"]={'ListID':kwargs.get('ItemRef_ListID', None), 'FullName':kwargs.get('ItemRef_FullName', None)} + if 'CurrencyFilter_ListID' in kwargs: + self.QBDict[self.classNameRq]["CurrencyFilter"]=kwargs['CurrencyFilter_ListID'] + elif 'CurrencyFilter_FullName' in kwargs: + self.QBDict[self.classNameRq]["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.classNameRq]["IncludeRetElement"]=IRE + + # print(self.classNameRq) + # print(f'{self.QBDict = }') + if self.__class__.__name__==self.className: + self.runCheck() ### running the qbxml connection to get data ### + + import xmltodict def LineAdd(lineAdd:Union[list, dict])->dict: if not(isinstance(lineAdd, list) or isinstance(lineAdd, dict)): @@ -483,13 +546,15 @@ class CustomerQuery(baseQBQuery): if 'Operator' in kwargs and 'Amount' in kwargs: self.QBDict[self.classNameRq]["TotalBalanceFilter"]={'Operator':kwargs['Operator'], 'Amount':kwargs['Amount']} - if 'IncludeRetElement' in kwargs: + if 'IncludeRetElement' in kwargs and kwargs['IncludeRetElement']: IRE = cleanIncludeRetElements(self.includeRetElements_allowed, kwargs['IncludeRetElement']) print(f'{IRE = }') if len(IRE)>0: if self.defaultFilterKey not in IRE: IRE.append(self.defaultFilterKey) self.QBDict[self.classNameRq]["IncludeRetElement"]=IRE + else: + self.QBDict[self.classNameRq]["IncludeRetElement"]=self.includeRetElements_allowed if 'OwnerID' in kwargs: self.QBDict[self.classNameRq]["OwnerID"]=kwargs['OwnerID'] @@ -1190,6 +1255,7 @@ if __name__ == "__main__": print(g.count()) + @timing def main(): g= GeneralSummaryReportQuery(debug=False, GeneralSummaryReportType="ProfitAndLossStandard", ReportDateMacro="ThisYear") @@ -1229,7 +1295,7 @@ if __name__ == "__main__": @timing def customerquery(): - g= CustomerQuery(MaxReturned=3, IncludeRetElement=["fullname", "name", "CompanyName", "BillAddressBlock", "ShipAddressBlock"]) + g= CustomerQuery(MaxReturned=3, IncludeRetElement=["fullname", "name", "CompanyName", "BillAddressBlock", "ShipAddressBlock", "Notes", "AdditionalNotesRet", 'creditlimit']) # g= CustomerQuery(MaxReturned=20, ActiveStatus="ActiveOnly", MatchCriterion="StartsWith", Name="to", IncludeRetElement=["fullname", "name", "billaddressblock", "currencyfilter"]) # print(g.IncludeRetElements_allowed) print("init finish") @@ -1237,14 +1303,14 @@ if __name__ == "__main__": print("before g.all") print(f'{g.all() = }') print("after g.all") - pprint.pprint(f'{g.filter(["FullName", "Name"]).all() = }') + pprint.pprint(f'{g.filter(["FullName", "Name", "Notes"]).all() = }') print(f'{g.filter() = }') # pprint.pprint(g.filter(["FullName", "abc", "BillAddressBlock"]).all()) - print(f'{g.filter(["FullName", "abc", "BillAddressBlock"]).all() = }') - print("") - print(f'{g.filter([ "Addr1", "Addr2", "Addr3", "Addr4", "Addr5"]).all() = }') - print(f'{g.filter([ "Addr1", "Addr2", "Addr3", "Addr4", "Addr5"]) = }') - print(f'{g.filter(["fullname", "name"]).lastValue() = }') + # print(f'{g.filter(["FullName", "abc", "BillAddressBlock"]).all() = }') + # print("") + # print(f'{g.filter([ "Addr1", "Addr2", "Addr3", "Addr4", "Addr5"]).all() = }') + # print(f'{g.filter([ "Addr1", "Addr2", "Addr3", "Addr4", "Addr5"]) = }') + # print(f'{g.filter(["fullname", "name"]).lastValue() = }') def readxmltodict(): import xmltodict @@ -1292,10 +1358,22 @@ if __name__ == "__main__": print(recursiveDict(varDict, f, enumDict)) f.close + @timing + def pricelevel(): + g = PriceLevelQuery(FullName = 'B 202112', ItemRef_FullName = "TEDG:WG42:EDG-905/42") + g = PriceLevelQuery( NameFilter_MatchCriterion='Contains', NameFilter_Name='202112' ) + # print(g.filter('PriceLevelPerItemRet').all()) + print(g.all()) + print(len(g.filter('PriceLevelPerItemRet').all())) + for x in g.all(): + print([y for y in x]) + print(f"{x.get('Name')} : {len(x.get('PriceLevelPerItemRet'))}") + + pricelevel() # invoicequery() - salesorderquery() + # salesorderquery() # transactionquery() - # main() + # pprint.pprint(InventoryStockStatusByVendor(), sort_dicts=False) # iteminventoryquery() # customerquery() # readxmltodict() diff --git a/SO_to_Inv/CustomerQuery.py b/SO_to_Inv/CustomerQuery.py index 6f99075..aa8067e 100644 --- a/SO_to_Inv/CustomerQuery.py +++ b/SO_to_Inv/CustomerQuery.py @@ -53,7 +53,7 @@ class CustomerQuery: if billaddressRet.find('Addr3')!=None: Addr3 = billaddressRet.find('Addr3').text if billaddressRet.find('Addr4')!=None: Addr4 = billaddressRet.find('Addr4').text if billaddressRet.find('Addr5')!=None: Addr5 = billaddressRet.find('Addr5').text - print(Addr1, Addr2,) + # print(Addr1, Addr2,) Addr1s.append(Addr1) Addr2s.append(Addr2) Addr3s.append(Addr3) @@ -88,7 +88,7 @@ class CustomerQuery: Customer['Addr5']=Addr5s # print(Customer) _df = pd.DataFrame.from_dict(Customer) - print(_df) + # print(_df) _df.to_excel(os.path.join(os.getcwd(), self.item_inventory_path, self._filename), index=False) CustomerDict = _df.to_dict('records') return CustomerDict diff --git a/main.py b/main.py index 2523ae4..eb91492 100644 --- a/main.py +++ b/main.py @@ -18,7 +18,8 @@ import pdfexcel4DNwithxlrd from ItemInventoryQuery import ItemInventoryQuery from SO_to_Inv import readSO, CustomerQuery import os -from QBClass.QBClasses import SalesOrderAdd, InventoryStockStatusByVendor +from QBClass.QBClasses import SalesOrderAdd, InventoryStockStatusByVendor, PriceLevelQuery +from QBClass.QBClasses import CustomerQuery as CQ import pprint @@ -72,19 +73,61 @@ async def get_iteminventory_fullname(maxreturned:Union[int, None] = None): @app.get('/get-customer-fullname') -async def get_customer_fullname(maxreturned:Union[int, None] = None): - print(f'{maxreturned = }') +# async def get_customer_fullname(MaxReturned:Union[int, None] = None, request:Request): +async def get_customer_fullname(request:Request): + # print(f'{MaxReturned = }') + print(f'{request = }') + print(f'{request.query_params = }') + MaxReturned = request.query_params.get('MaxReturned') # item_inv = CustomerQuery( IncludeRetElement=['FullName'], MaxReturned=maxreturned) #MaxReturned=None means get ALL items - customer = CustomerQuery.CustomerQuery(MaxReturned=maxreturned) + customer = CustomerQuery.CustomerQuery(MaxReturned=MaxReturned) # QBXML = customer.create_QBXML() itu = customer.create_customerquery_QBXML() - print(itu) + # print(itu) status, data = customer.to_json() + print(f'{MaxReturned = }') + print(f'{request.query_params = }') if status: return data else: return {'Info': f"NOT Saved", 'Status':'ERROR', 'msg':data} + +@app.get('/get-customer') +# async def get_customer_fullname(MaxReturned:Union[int, None] = None, request:Request): +async def get_customer(request:Request): + print(f'{request.query_params = }') + params = await request.json() + print(f'{params = }') + # print(type(params), params) + # params = request.query_params._dict + print(type(params), f'{params = }') + # customer = CustomerQuery.CustomerQuery(**params) + customer = CQ(**params) + # print(customer.all()) + # status, data = customer.to_json() + # print(f'{MaxReturned = }') + # print(f'{request.query_params = }') + if len(customer.all())>0: + return customer.all() + else: + return {'Info': f"CANNOT Get", 'Status':'ERROR', 'msg':f'Cannot Get Customer with params: {params}'} + + +@app.get('/get-pricelevel') +async def get_pricelevel(name:Union[str, None] = None): + print(f'{name = }') + # item_inv = CustomerQuery( IncludeRetElement=['FullName'], MaxReturned=maxreturned) #MaxReturned=None means get ALL items + pricelevel = PriceLevelQuery( NameFilter_MatchCriterion='Contains', NameFilter_Name=name, ) + # print(pricelevel.all()) + print(f'{len(pricelevel.all()) = }') + # status, data = customer.to_json() + if len(pricelevel.all())>0: + return pricelevel.all()#len(pricelevel.all()) #pricelevel.all() + else: + return {'Info': f"CANNOT Get PriceLevel", 'Status':'ERROR', 'msg':f'Cannot get Pricelevel with {name}'} + + @app.get('/get-inventorystockstatusbyvendor') async def get_inventorystockstatusbyvendor(): items = InventoryStockStatusByVendor()