from .server import baseQBQuery
# from server import baseQBQuery, timing
import pprint
# import timeit
# import xml.dom.minidom
from .utils import timing, cleanIncludeRetElements, makeAList
import json
from typing import Union

ENUM_DateMacro = ['All', 'Today', 'ThisWeek', 'ThisWeekToDate', 'ThisMonth', 'ThisMonthToDate', 'ThisCalendarQuarter', 'ThisCalendarQuarterToDate', 'ThisFiscalQuarter',
			'ThisFiscalQuarterToDate', 'ThisCalendarYear', 'ThisCalendarYearToDate', 'ThisFiscalYear', 'ThisFiscalYearToDate', 'Yesterday', 'LastWeek', 'LastWeekToDate', 'LastMonth', 
			'LastMonthToDate', 'LastCalendarQuarter', 'LastCalendarQuarterToDate', 'LastFiscalQuarter', 'LastFiscalQuarterToDate', 'LastCalendarYear', 'LastCalendarYearToDate', 
			'LastFiscalYear', 'LastFiscalYearToDate', 'NextWeek', 'NextFourWeeks', 'NextMonth', 'NextCalendarQuarter', 'NextCalendarYear', 'NextFiscalQuarter', 'NextFiscalYear'
			]

class ItemInventoryQuery(baseQBQuery):
	def __init__(self, *args, **kwargs):
		print(f'{args = }')
		print(f'{kwargs = }')
		super().__init__(*args, **kwargs)
		### Required Variable
		self.includeRetElements_allowed = ["ListID", "FullName", "TimeCreated", "TimeModified", "EditSequence", "Name", "IsActive", "ClassRef", "ParentRef", "Sublevel", "BarCodeValue", 
								"ManufacturerPartNumber", "UnitOfMeasureSetRef", "IsTaxIncluded", "SalesTaxCodeRef", "SalesDesc,", "SalesPrice", "IncomeAccountRef",
								"PurchaseDesc", "PurchaseCost", "PurchaseTaxCodeRef", "COGSAccountRef", "PrefVendorRef", "AssetAccountRef", "ReforderPoint", "Max", "QuantityOnHand",
								"AverageCost", "QuantityOnOrder", "QuantityOnSalesOrder",
								"ExternalGUID", "DataExtRet",
								]
		self.onError = "stopOnError"
		self.retName = 'ItemInventoryRet'
		self.defaultFilterKey = "ListID"
		self.className = "ItemInventoryQuery"
		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]={}
		### End Required Variable. can put ENUM list below this (eg: self.ENUM_GeneralSummaryReportQuery=[])

		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:
				self.QBDict[self.classNameRq]["ActiveStatus"]=kwargs['ActiveStatus']
			if 'FromModifiedDate' in kwargs:
				self.QBDict[self.classNameRq]["FromModifiedDate"]=kwargs['FromModifiedDate']
			if 'ToModifiedDate' in kwargs:
				self.QBDict[self.classNameRq]["ToModifiedDate"]=kwargs['ToModifiedDate']
			if 'MatchCriterion' in kwargs and 'Name' in kwargs:
				self.QBDict[self.classNameRq]["NameFilter"]={'MatchCriterion':kwargs['MatchCriterion', 'Name':kwargs['Name']]}
			elif 'FromName' in kwargs or 'ToName' in kwargs:  #if or then use {'key1':kwargs.get('key1',""), 'key2':kwargs.get('key2', "")}
				self.QBDict[self.classNameRq]["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 = }")
			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

		if 'OwnerID' in kwargs:     # usually value=0 to get to DataExtRet (additional data)
			self.QBDict[self.classNameRq]["OwnerID"]=kwargs['OwnerID']

		# print(self.classNameRq)
		# print(self.QBDict)
		if self.__class__.__name__==self.className:
			self.runCheck() ### running the qbxml connection to get data ###

class GeneralSummaryReportQuery(baseQBQuery):
	def __init__(self, *args, **kwargs):
		print(f'{args = }')
		print(f'{kwargs = }')
		super().__init__( )
		## Required variable
		self.includeRetElements_allowed = ["ReportTitle", "ReportSubtitle", "ReportBasis", "NumRows", "NumColumns", "NumColTitleRows",  "ReportData", "DataRow"]
		self.onError = "stopOnError"
		self.retName = 'ReportRet'
		self.defaultFilterKey = "ListID"
		self.className = "GeneralSummaryReportQuery"
		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_GeneralSummaryReportType = ["BalanceSheetByClass", "BalanceSheetPrevYearComp", "BalanceSheetStandard", "BalanceSheetSummary", "CustomerBalanceSummary",
						"ExpenseByVendorSummary", "IncomeByCustomerSummary", "InventoryStockStatusByItem", "InventoryStockStatusByVendor", "IncomeTaxSummary",
						"InventoryValuationSummary", "InventoryValuationSummaryBySite", "LotNumberInStockBySite", "PhysicalInventoryWorksheet", "ProfitAndLossByClass",
						"ProfitAndLossByJob", "ProfitAndLossPrevYearComp", "ProfitAndLossStandard", "ProfitAndLossYTDComp", "PurchaseByItemSummary", "PurchaseByVendorSummary",
						"SalesByCustomerSummary", "SalesByItemSummary", "SalesByRepSummary", "SalesTaxLiability", "SalesTaxRevenueSummary", "SerialNumberInStockBySite",
						"TrialBalance", "VendorBalanceSummary"]

		if 'GeneralSummaryReportType' in kwargs:
			enum=cleanIncludeRetElements(self.ENUM_GeneralSummaryReportType, kwargs['GeneralSummaryReportType'])
			print(f'{enum = }')
			self.QBDict[self.classNameRq]["GeneralSummaryReportType"]=enum[0]
		else:
			print("Error -> GeneralSummaryReportType is required")
			return

		# if 'DisplayReport_ReportPeriod_FromReportDate' in kwargs or 'DisplayReport_ReportPeriod_ToReportDate' in kwargs:
		#     self.QBDict[self.classNameRq]['DisplayReport']={'ReportPeriod':{}}
		#     if 'DisplayReport_ReportPeriod_FromReportDate' in kwargs:
		#         self.QBDict[self.classNameRq]["DisplayReport"]['ReportPeriod']['FromReportDate']=kwargs['DisplayReport_ReportPeriod_FromReportDate']
		#     if 'DisplayReport_ReportPeriod_ToReportDate' in kwargs:
		#         self.QBDict[self.classNameRq]["DisplayReport"]['ReportPeriod']['ToReportDate']=kwargs['DisplayReport_ReportPeriod_ToReportDate']
		# elif 'DisplayReport_ReportPeriod_ReportDateMacro' in kwargs:
		#     self.QBDict[self.classNameRq]['DisplayReport']={"ReportDateMacro":kwargs['DisplayReport_ReportPeriod_ReportDateMacro']}
		
		if 'DisplayReport' in kwargs:
			self.QBDict[self.classNameRq]["DisplayReport"]=kwargs['DisplayReport']

		if 'ReportPeriod_FromReportDate' in kwargs or 'ReportPeriod_ToReportDate' in kwargs:  #if or then use {'key1':kwargs.get('key1',""), 'key2':kwargs.get('key2', "")}
				self.QBDict[self.classNameRq]["ReportPeriod"]={'FromReportDate':kwargs.get('ReportPeriod_FromReportDate', None), 'ToReportDate':kwargs.get('ReportPeriod_ToReportDate', None)}
		elif 'ReportDateMacro' in kwargs:
				self.QBDict[self.classNameRq]["ReportDateMacro"]=kwargs['ReportDateMacro']

		if 'ReportAccountFilter_AccountTypeFilter' in kwargs:
			self.QBDict[self.classNameRq]["ReportAccountFilter"]={'AccountTypeFilter':kwargs['ReportAccountFilter_AccountTypeFilter']}
		elif 'ReportAccountFilter_ListID' in kwargs:
			self.QBDict[self.classNameRq]["ReportAccountFilter"]={'ListID':kwargs['ReportAccountFilter_ListID']}
		elif 'ReportAccountFilter_FullName' in kwargs:
			self.QBDict[self.classNameRq]["ReportAccountFilter"]={'FullName':kwargs['ReportAccountFilter_FullName']}
		elif 'ReportAccountFilter_ListIDWithChildren' in kwargs:
			self.QBDict[self.classNameRq]["ReportAccountFilter"]={'ListIDWithChildren':kwargs['ReportAccountFilter_ListIDWithChildren']}
		elif 'ReportAccountFilter_FullNameWithChildren' in kwargs:
			self.QBDict[self.classNameRq]["ReportAccountFilter"]={'FullNameWithChildren':kwargs['ReportAccountFilter_FullNameWithChildren']}

		if 'ReportEntityFilter_EntityTypeFilter' in kwargs:
			self.QBDict[self.classNameRq]["ReportEntityFilter"]={'EntityTypeFilter':kwargs['ReportEntityFilter_EntityTypeFilter']}
		elif 'ReportEntityFilter_ListID' in kwargs:
			self.QBDict[self.classNameRq]["ReportEntityFilter"]={'ListID':kwargs['ReportEntityFilter_ListID']}
		elif 'ReportEntityFilter_FullName' in kwargs:
			self.QBDict[self.classNameRq]["ReportEntityFilter"]={'FullName':kwargs['ReportEntityFilter_FullName']}
		elif 'ReportEntityFilter_ListIDWithChildren' in kwargs:
			self.QBDict[self.classNameRq]["ReportEntityFilter"]={'ListIDWithChildren':kwargs['ReportEntityFilter_ListIDWithChildren']}
		elif 'ReportEntityFilter_FullNameWithChildren' in kwargs:
			self.QBDict[self.classNameRq]["ReportEntityFilter"]={'FullNameWithChildren':kwargs['ReportEntityFilter_FullNameWithChildren']}

		if 'ReportItemFilter_ItemTypeFilter' in kwargs:
			self.QBDict[self.classNameRq]["ReportItemFilter"]={'ItemTypeFilter':kwargs['ReportItemFilter_ItemTypeFilter']}
		elif 'ReportItemFilter_ListID' in kwargs:
			self.QBDict[self.classNameRq]["ReportItemFilter"]={'ListID':kwargs['ReportItemFilter_ListID']}
		elif 'ReportItemFilter_FullName' in kwargs:
			self.QBDict[self.classNameRq]["ReportItemFilter"]={'FullName':kwargs['ReportItemFilter_FullName']}
		elif 'ReportItemFilter_ListIDWithChildren' in kwargs:
			self.QBDict[self.classNameRq]["ReportItemFilter"]={'ListIDWithChildren':kwargs['ReportItemFilter_ListIDWithChildren']}
		elif 'ReportItemFilter_FullNameWithChildren' in kwargs:
			self.QBDict[self.classNameRq]["ReportItemFilter"]={'FullNameWithChildren':kwargs['ReportItemFilter_FullNameWithChildren']}

		if 'ReportClassFilter_ListID' in kwargs:
			self.QBDict[self.classNameRq]["ReportClassFilter"]={'ListID':kwargs['ReportClassFilter_ListID']}
		elif 'ReportClassFilter_FullName' in kwargs:
			self.QBDict[self.classNameRq]["ReportClassFilter"]={'FullName':kwargs['ReportClassFilter_FullName']}
		elif 'ReportClassFilter_ListIDWithChildren' in kwargs:
			self.QBDict[self.classNameRq]["ReportClassFilter"]={'ListIDWithChildren':kwargs['ReportClassFilter_ListIDWithChildren']}
		elif 'ReportClassFilter_FullNameWithChildren' in kwargs:
			self.QBDict[self.classNameRq]["ReportClassFilter"]={'FullNameWithChildren':kwargs['ReportClassFilter_FullNameWithChildren']}

		if 'ReportTxnTypeFilter_ListID' in kwargs:
			self.QBDict[self.classNameRq]["ReportTxnTypeFilter"]={'TxnTypeFilter':makeAList(kwargs['ReportTxnTypeFilter_ListID'])}
		
		if 'ReportModifiedDateRangeFilter_FromReportModifiedDate' in kwargs or 'ReportModifiedDateRangeFilter_ToReportModifiedDate' in kwargs:  #if or then use {'key1':kwargs.get('key1',""), 'key2':kwargs.get('key2', "")}
			self.QBDict[self.classNameRq]["ReportModifiedDateRangeFilter"]={'FromReportModifiedDate':kwargs.get('ReportModifiedDateRangeFilter_FromReportModifiedDate', None), 'ToReportModifiedDate':kwargs.get('ReportModifiedDateRangeFilter_ToReportModifiedDate', None)}
		elif 'ReportModifiedDateRangeMacro' in kwargs:
			self.QBDict[self.classNameRq]["ReportModifiedDateRangeMacro"]=cleanIncludeRetElements(ENUM_DateMacro, kwargs['ReportModifiedDateRangeMacro'])

		if 'ReportDetailLevelFilter' in kwargs:
			self.QBDict[self.classNameRq]["ReportDetailLevelFilter"]=cleanIncludeRetElements(['All', 'AllExceptSummary', 'SummaryOnly'], kwargs['ReportDetailLevelFilter'], 'All')
		if 'ReportPostingStatusFilter' in kwargs:
			self.QBDict[self.classNameRq]["ReportPostingStatusFilter"]=cleanIncludeRetElements(['Either', 'NonPosting', 'Posting'], kwargs['ReportPostingStatusFilter'])
		if 'SummarizeColumnsBy' in kwargs:
			self.ENUM_SummarizeColumnsBy=['Account', 'BalanceSheet', 'Class', 'Customer', 'CustomerType', 'Day', 'Employee', 'FourWeek', 'HalfMonth', 'IncomeStatement', 'ItemDetail', 'ItemType', 'Month', 'Payee',
					'PaymentMethod', 'PayrollItemDetail', 'PayrollYtdDetail', 'Quarter', 'SalesRep', 'SalesTaxCode', 'ShipMethod', 'Terms', 'TotalOnly', 'TwoWeek', 'Vendor', 'VendorType', 'Week', 'Year']
			self.QBDict[self.classNameRq]["SummarizeColumnsBy"]=cleanIncludeRetElements(self.ENUM_SummarizeColumnsBy, kwargs['SummarizeColumnsBy'])
		if 'IncludeSubColumns' in kwargs:
			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 '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:
			self.QBDict[self.classNameRq]["ReportBasis"]=cleanIncludeRetElements(['Accrual', 'Cash', 'None'], kwargs['ReportBasis'], default_val='None')

		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 ###


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)):
		raise Exception(f"LineAdd Error. {type(lineAdd)}, should use dictionary or list of dictionary. ")
	if isinstance(lineAdd, dict):   #convert to listofdict
		lineAdd = [lineAdd]
	## process LineAdd dict
	resultList = []
	resdict = {}
	for xLineAdd in lineAdd:
		resdict={'@defMacro':'MACROTYPE'}
		resdict['abc']=""
		# resdict['ItemRef']={}
		if 'ItemRef_ListID' in xLineAdd and xLineAdd['ItemRef_ListID']:
			print(":he")
			if 'ItemRef' in resdict:
				resdict['ItemRef']['ListID']= xLineAdd['ItemRef_ListID']
			else:
				resdict['ItemRef']={'ListID': xLineAdd['ItemRef_ListID']}
			print(resdict)
		if 'ItemRef_FullName' in xLineAdd and xLineAdd['ItemRef_FullName']:
			resdict['ItemRef']['FullName']= xLineAdd['ItemRef_FullName']
		if 'Desc' in xLineAdd and xLineAdd['Desc']:
			resdict['Desc']= xLineAdd['Desc']
		
		resultList.append(resdict)
	print(f'{resultList = }')
	xyz=xmltodict.unparse({'root':{'LineAdd':resultList}}, pretty=True)
	print(xyz)
	txt = '''<?xml version="1.0" encoding="utf-8"?>
		<LineAdd macro="testmacro">
				<abc></abc>
				<ItemRef>
						<ListID>1234</ListID>
						<FullName>Sugiarto</FullName>
				</ItemRef>
				<Desc>lorem</Desc>
		</LineAdd>
		'''
	dct = xmltodict.parse(txt)
	print(f'{dct = }')

# x=[{'ItemRef_FullName': 'Sugiarto', 'ItemRef_ListID':1234, 'Desc':"lorem"}, {'ItemRef_FullName': 'Sugiarto', 'ItemRef_ListID':1234, 'Desc':"lorem"}]
# LineAdd(x)

# print(cleanIncludeRetElements(['ActiveOnly', 'NonZero', 'All'], "nonzero", 'ActiveOnly'))

class InvoiceAdd(baseQBQuery):
	def __init__(self, *args, **kwargs):
		print(f'{args = }')
		print(f'{kwargs = }')
		super().__init__(*args, **kwargs)
		# self.includeRetElements_allowed = ['TxnID', 'TimeCreated', 'TimeModified', 'EditSequence', 'TxnNumber', 'CustomerRef', 'ClassRef', 'ARAccontRef', 'TemplateRef']
		self.onError = "stopOnError"
		self.retName = 'InvoiceAddRet'

		self.defaultFilterKey = "TxnID"
		self.className = "InvoiceAdd"
		self.classNameRq:str = self.__class__.__name__ + 'Rq'
		self.reqSubName = self.className
		if 'debug' in kwargs and isinstance(kwargs['debug'], bool):
			self.class_debug=kwargs["debug"]

		self.QBDict[self.classNameRq]={}
		
		self.isRequiredFieldSatisfied = False
		self.QBDict[self.classNameRq][self.__class__.__name__]={'@defMacro':'MACROTYPE'}
		if 'CustomerRef_ListID' in kwargs:
			if 'CustomerRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerRef"]['ListID']= kwargs['CustomerRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerRef"]={'ListID': kwargs['CustomerRef_ListID']}
			self.isRequiredFieldSatisfied=True
		if 'CustomerRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerRef"]={'FullName': kwargs['CustomerRef_FullName']}
			self.isRequiredFieldSatisfied=True
		
		if not self.isRequiredFieldSatisfied:
			raise Exception("Need CustomerRef FullName and/or ListID")

		if 'ClassRef_ListID' in kwargs:
			if 'ClassRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["ClassRef"]['ListID']= kwargs['ClassRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["ClassRef"]={'ListID': kwargs['ClassRef_ListID']}
		if 'ClassRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ClassRef"]={'FullName': kwargs['ClassRef_FullName']}
		
		if 'ARAccountRef_ListID' in kwargs:
			if 'ARAccountRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["ARAccountRef"]['ListID']= kwargs['ARAccountRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["ARAccountRef"]={'ListID': kwargs['ARAccountRef_ListID']}
		if 'ARAccountRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ARAccountRef"]={'FullName': kwargs['ARAccountRef_FullName']}
		
		if 'TemplateRef_ListID' in kwargs:
			if 'TemplateRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["TemplateRef"]['ListID']= kwargs['TemplateRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["TemplateRef"]={'ListID': kwargs['TemplateRef_ListID']}
		if 'TemplateRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["TemplateRef"]={'FullName': kwargs['TemplateRef_FullName']}
		
		if 'TxnDate' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["TxnDate"]=kwargs['TxnDate']
		if 'RefNumber' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["RefNumber"]=kwargs['RefNumber']
		if 'BillAddress_Addr1' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'Addr1': kwargs['BillAddress_Addr1']}
		if 'BillAddress_Addr2' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'Addr2': kwargs['BillAddress_Addr2']}
		if 'BillAddress_Addr3' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'Addr3': kwargs['BillAddress_Addr3']}
		if 'BillAddress_Addr4' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'Addr4': kwargs['BillAddress_Addr4']}
		if 'BillAddress_Addr5' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'Addr5': kwargs['BillAddress_Addr5']}
		if 'BillAddress_City' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'City': kwargs['BillAddress_City']}
		if 'BillAddress_State' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'State': kwargs['BillAddress_State']}
		if 'BillAddress_PostalCode' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'PostalCode': kwargs['BillAddress_PostalCode']}
		if 'BillAddress_Country' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'Country': kwargs['BillAddress_Country']}
		if 'BillAddress_Note' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'Note': kwargs['BillAddress_Note']}

		if 'ShipAddress_Addr1' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'Addr1': kwargs['ShipAddress_Addr1']}
		if 'ShipAddress_Addr2' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'Addr2': kwargs['ShipAddress_Addr2']}
		if 'ShipAddress_Addr3' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'Addr3': kwargs['ShipAddress_Addr3']}
		if 'ShipAddress_Addr4' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'Addr4': kwargs['ShipAddress_Addr4']}
		if 'ShipAddress_Addr5' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'Addr5': kwargs['ShipAddress_Addr5']}
		if 'ShipAddress_City' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'City': kwargs['ShipAddress_City']}
		if 'ShipAddress_State' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'State': kwargs['ShipAddress_State']}
		if 'ShipAddress_PostalCode' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'PostalCode': kwargs['ShipAddress_PostalCode']}
		if 'ShipAddress_Country' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'Country': kwargs['ShipAddress_Country']}
		if 'ShipAddress_Note' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'Note': kwargs['ShipAddress_Note']}
		
		if 'IsPending' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["IsPending"]=kwargs['IsPending']
		if 'IsFinanceCharge' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["IsFinanceCharge"]=kwargs['IsFinanceCharge']
		if 'PONumber' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["PONumber"]=kwargs['PONumber']
		if 'TermsRef_ListID' in kwargs:
			if 'TermsRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["TermsRef"]['ListID']= kwargs['TermsRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["TermsRef"]={'ListID': kwargs['TermsRef_ListID']}
		if 'TermsRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["TermsRef"]={'FullName': kwargs['TermsRef_FullName']}
		
		if 'DueDate' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["DueDate"]=kwargs['DueDate']
		if 'SalesRepRef_ListID' in kwargs:
			if 'SalesRepRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["SalesRepRef"]['ListID']= kwargs['SalesRepRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["SalesRepRef"]={'ListID': kwargs['SalesRepRef_ListID']}
		if 'SalesRepRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["SalesRepRef"]={'FullName': kwargs['SalesRepRef_FullName']}
		
		if 'FOB' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["FOB"]=kwargs['FOB']
		if 'ShipDate' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipDate"]=kwargs['ShipDate']
		if 'ShipMethodRef_ListID' in kwargs:
			if 'ShipMethodRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["ShipMethodRef"]['ListID']= kwargs['ShipMethodRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["ShipMethodRef"]={'ListID': kwargs['ShipMethodRef_ListID']}
		if 'ShipMethodRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipMethodRef"]={'FullName': kwargs['ShipMethodRef_FullName']}
		
		if 'ItemSalesTaxRef_ListID' in kwargs:
			if 'ItemSalesTaxRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["ItemSalesTaxRef"]['ListID']= kwargs['ItemSalesTaxRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["ItemSalesTaxRef"]={'ListID': kwargs['ItemSalesTaxRef_ListID']}
		if 'ItemSalesTaxRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ItemSalesTaxRef"]={'FullName': kwargs['ItemSalesTaxRef_FullName']}
		
		if 'Memo' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["Memo"]=kwargs['Memo']
		if 'CustomerMsgRef_ListID' in kwargs:
			if 'CustomerMsgRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerMsgRef"]['ListID']= kwargs['CustomerMsgRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerMsgRef"]={'ListID': kwargs['CustomerMsgRef_ListID']}
		if 'CustomerMsgRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerMsgRef"]={'FullName': kwargs['CustomerMsgRef_FullName']}
		
		if 'IsToBePrinted' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["IsToBePrinted"]=kwargs['IsToBePrinted']
		if 'IsToBeEmailed' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["IsToBeEmailed"]=kwargs['IsToBeEmailed']
		if 'IsTaxIncluded' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["IsTaxIncluded"]=kwargs['IsTaxIncluded']
		if 'CustomerSalesTaxCodeRef_ListID' in kwargs:
			if 'CustomerSalesTaxCodeRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerSalesTaxCodeRef"]['ListID']= kwargs['CustomerSalesTaxCodeRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerSalesTaxCodeRef"]={'ListID': kwargs['CustomerSalesTaxCodeRef_ListID']}
		if 'CustomerSalesTaxCodeRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerSalesTaxCodeRef"]={'FullName': kwargs['CustomerSalesTaxCodeRef_FullName']}
		
		if 'Other' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["Other"]=kwargs['Other']
		if 'ExchangeRate' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ExchangeRate"]=kwargs['ExchangeRate']
		if 'ExternalGUID' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ExternalGUID"]=kwargs['ExternalGUID']
		if 'LinkToTxnID' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["LinkToTxnID"]=makeAList(kwargs['LinkToTxnID'])
		
		if 'SetCredit_CreditTxnID' in kwargs and 'SetCredit_AppliedAmount' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["SetCredit"]={'CreditTxnID':{'@useMacro':"MACROTYPE", '#text':kwargs['SetCredit_CreditTxnID']}, 'AppliedAmount': kwargs['SetCredit_AppliedAmount']}
			if 'SetCredit_Override' in kwargs:
				self.QBDict[self.classNameRq][self.__class__.__name__]["SetCredit"]["Override"]=kwargs['SetCredit_Override']
#add InvoiceLineAdd kwargs here
			

		if 'IncludeRetElement' in kwargs:
			self.QBDict[self.classNameRq]["IncludeRetElement"]=kwargs['IncludeRetElement']

		# print(self.classNameRq)
		# print(self.QBDict)



class CustomerQuery(baseQBQuery):
	def __init__(self, *args, **kwargs):
		print(f'{args = }')
		print(f'{kwargs = }')
		super().__init__(*args, **kwargs)
		self.includeRetElements_allowed = ["ListID", "FullName", "TimeCreated", "TimeModified", "EditSequence", "Name", "IsActive", "ClassRef", "ParentRef", "Sublevel", "CompanyName", "Salutation",
								"FirstName", "MiddleName", "LastName", "JobTitle", "BillAddress", "BillAddressBlock", "ShipAddress", "ShipAddressBlock", "ShipToAddress", "Phone",
								"AltPhone", "Fax", "Email", "Cc", "Contact", "AltContact", "AdditionalContactRef", "ContactsRet", "CustomerTypeRef", "TermsRef", "SalesRepRef", 
								"Balance", "TotalBalance", "SalesTaxCodeRef", "ItemSalesTaxRef", "SalesTaxCountry", "ResaleNumber", "AccountNumber", "CreditLimit", 
								"PreferredPaymentMethodRef", "CreditCardInfo", "JobStatus", "JobStartDate", "JobProjectedEndDate", "JobEndDate", "JobDesc", "JobTypeRef", "Notes", 
								"AdditionalNotesRet", "PreferredDeliveryMethod", "PriceLevelRef", "ExternalGUID", "TaxRegistrationNumber", "CurrencyRef", "DataExtRet"]
		self.onError = "stopOnError"
		self.retName = 'CustomerRet'
		self.defaultFilterKey = "ListID"
		self.className = "CustomerQuery"
		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]={}

		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:
				self.QBDict[self.classNameRq]["ActiveStatus"]=kwargs['ActiveStatus']
			if 'FromModifiedDate' in kwargs:
				self.QBDict[self.classNameRq]["FromModifiedDate"]=kwargs['FromModifiedDate']
			if 'ToModifiedDate' in kwargs:
				self.QBDict[self.classNameRq]["ToModifiedDate"]=kwargs['ToModifiedDate']
			if 'MatchCriterion' in kwargs and 'Name' in kwargs:
				self.QBDict[self.classNameRq]["NameFilter"]={'MatchCriterion':kwargs['MatchCriterion'], 'Name':kwargs['Name']}
			elif 'FromName' in kwargs or 'ToName' in kwargs:
				self.QBDict[self.classNameRq]["NameRangeFilter"]={'FromName':kwargs.get('FromName', ""), 'ToName':kwargs.get('ToName', "")}

			if 'Operator' in kwargs and 'Amount' in kwargs:
				self.QBDict[self.classNameRq]["TotalBalanceFilter"]={'Operator':kwargs['Operator'], 'Amount':kwargs['Amount']}
		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']

		print(self.classNameRq)
		print(f'{self.QBDict = }' )
		# print(f'{self.includeRetElements_allowed =}')
		if self.__class__.__name__==self.className:
			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"
		self.className = "TransactionQuery"
		self.classNameRq = self.__class__.__name__ + 'Rq'
		if 'debug' in kwargs and isinstance(kwargs['debug'], bool):
			self.class_debug=kwargs["debug"]

		self.QBDict[self.classNameRq]={}
		### End Required Variable. can put ENUM list below this (eg: self.ENUM_GeneralSummaryReportQuery=[])

		if 'TxnID' in kwargs:
			self.QBDict[self.classNameRq]["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.classNameRq]["MaxReturned"]=MaxReturned

			if 'RefNumber' in kwargs:
				self.QBDict[self.classNameRq]["RefNumber"]=kwargs['RefNumber']
			elif 'RefNumberCaseSensitive' in kwargs:
				self.QBDict[self.classNameRq]["RefNumberCaseSensitive"]=kwargs['RefNumberCaseSensitive']
			elif 'RefNumberFilter_MatchCriterion' in kwargs and 'RefNumberFilter_RefNumber' in kwargs:
				self.QBDict[self.classNameRq]["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.classNameRq]["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.classNameRq]["TransactionModifiedDateRangeFilter"]={'FromModifiedDate':kwargs.get('TransactionModifiedDateRangeFilter_FromModifiedDate', ""), 'ToModifiedDate':kwargs.get('TransactionModifiedDateRangeFilter_ToModifiedDate', "")}
			elif 'TransactionModifiedDateRangeFilter_DateMacro' in kwargs:
				self.QBDict[self.classNameRq]["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.classNameRq]["TransactionDateRangeFilter"]={'FromTxnDate':kwargs.get('TransactionDateRangeFilter_FromTxnDate', ""), 'ToTxnDate':kwargs.get('TransactionDateRangeFilter_ToTxnDate', "")}
			elif 'TransactionDateRangeFilter_DateMacro' in kwargs:
				self.QBDict[self.classNameRq]["TransactionDateRangeFilter"]={'DateMacro':kwargs['TransactionDateRangeFilter_DateMacro']}
			
			# <!-- EntityTypeFilter may have one of the following values: Customer, Employee, OtherName, Vendor -->
			if 'TransactionEntityFilter_EntityTypeFilter' in kwargs:
				self.QBDict[self.classNameRq]["TransactionEntityFilter"]={'EntityTypeFilter':kwargs['TransactionEntityFilter_EntityTypeFilter']}
			elif 'TransactionEntityFilter_ListID' in kwargs:
				self.QBDict[self.classNameRq]["TransactionEntityFilter"]={'ListID':kwargs['TransactionEntityFilter_ListID']}
			elif 'TransactionEntityFilter_FullName' in kwargs:
				self.QBDict[self.classNameRq]["TransactionEntityFilter"]={'FullName':kwargs['TransactionEntityFilter_FullName']}
			elif 'TransactionEntityFilter_ListIDWithChildren' in kwargs:
				self.QBDict[self.classNameRq]["TransactionEntityFilter"]={'ListIDWithChildren':kwargs['TransactionEntityFilter_ListIDWithChildren']}
			elif 'TransactionEntityFilter_FullNameWithChildren' in kwargs:
				self.QBDict[self.classNameRq]["TransactionEntityFilter"]={'FullNameWithChildren':kwargs['TransactionEntityFilter_FullNameWithChildren']}
			
			# <!-- AccountTypeFilter may have one of the following values: AccountsPayable, AccountsReceivable, AllowedFor1099, APAndSalesTax, APOrCreditCard, ARAndAP, Asset, BalanceSheet, Bank, BankAndARAndAPAndUF, BankAndUF, CostOfSales, CreditCard, CurrentAsset, CurrentAssetAndExpense, CurrentLiability, Equity, EquityAndIncomeAndExpense, ExpenseAndOtherExpense, FixedAsset, IncomeAndExpense, IncomeAndOtherIncome, Liability, LiabilityAndEquity, LongTermLiability, NonPosting, OrdinaryExpense, OrdinaryIncome, OrdinaryIncomeAndCOGS, OrdinaryIncomeAndExpense, OtherAsset, OtherCurrentAsset, OtherCurrentLiability, OtherExpense, OtherIncome, OtherIncomeOrExpense -->
			if 'TransactionAccountFilter_AccountTypeFilter' in kwargs:
				self.QBDict[self.classNameRq]["TransactionAccountFilter"]={'AccountTypeFilter':kwargs['TransactionAccountFilter_AccountTypeFilter']}
			elif 'TransactionAccountFilter_ListID' in kwargs:
				self.QBDict[self.classNameRq]["TransactionAccountFilter"]={'ListID':kwargs['TransactionAccountFilter_ListID']}
			elif 'TransactionAccountFilter_FullName' in kwargs:
				self.QBDict[self.classNameRq]["TransactionAccountFilter"]={'FullName':kwargs['TransactionAccountFilter_FullName']}
			elif 'TransactionAccountFilter_ListIDWithChildren' in kwargs:
				self.QBDict[self.classNameRq]["TransactionAccountFilter"]={'ListIDWithChildren':kwargs['TransactionAccountFilter_ListIDWithChildren']}
			elif 'TransactionAccountFilter_FullNameWithChildren' in kwargs:
				self.QBDict[self.classNameRq]["TransactionAccountFilter"]={'FullNameWithChildren':kwargs['TransactionAccountFilter_FullNameWithChildren']}

			# <!-- ItemTypeFilter may have one of the following values: AllExceptFixedAsset, Assembly, Discount, FixedAsset, Inventory, InventoryAndAssembly, NonInventory, OtherCharge, Payment, Sales, SalesTax, Service -->
			if 'TransactionItemFilter_ItemTypeFilter' in kwargs:
				self.QBDict[self.classNameRq]["TransactionItemFilter"]={'ItemTypeFilter':kwargs['TransactionItemFilter_ItemTypeFilter']}
			elif 'TransactionItemFilter_ListID' in kwargs:
				self.QBDict[self.classNameRq]["TransactionItemFilter"]={'ListID':kwargs['TransactionItemFilter_ListID']}
			elif 'TransactionItemFilter_FullName' in kwargs:
				self.QBDict[self.classNameRq]["TransactionItemFilter"]={'FullName':kwargs['TransactionItemFilter_FullName']}
			elif 'TransactionItemFilter_ListIDWithChildren' in kwargs:
				self.QBDict[self.classNameRq]["TransactionItemFilter"]={'ListIDWithChildren':kwargs['TransactionItemFilter_ListIDWithChildren']}
			elif 'TransactionItemFilter_FullNameWithChildren' in kwargs:
				self.QBDict[self.classNameRq]["TransactionItemFilter"]={'FullNameWithChildren':kwargs['TransactionItemFilter_FullNameWithChildren']}

			if 'TransactionClassFilter_ListID' in kwargs:
				self.QBDict[self.classNameRq]["TransactionClassFilter"]={'ListID':kwargs['TransactionClassFilter_ListID']}
			elif 'TransactionClassFilter_FullName' in kwargs:
				self.QBDict[self.classNameRq]["TransactionClassFilter"]={'FullName':kwargs['TransactionClassFilter_FullName']}
			elif 'TransactionClassFilter_ListIDWithChildren' in kwargs:
				self.QBDict[self.classNameRq]["TransactionClassFilter"]={'ListIDWithChildren':kwargs['TransactionClassFilter_ListIDWithChildren']}
			elif 'TransactionClassFilter_FullNameWithChildren' in kwargs:
				self.QBDict[self.classNameRq]["TransactionClassFilter"]={'FullNameWithChildren':kwargs['TransactionClassFilter_FullNameWithChildren']}
			
			# <!-- TxnTypeFilter may have one of the following values: All, ARRefundCreditCard, Bill, BillPaymentCheck, BillPaymentCreditCard, BuildAssembly, Charge, Check, CreditCardCharge, CreditCardCredit, CreditMemo, Deposit, Estimate, InventoryAdjustment, Invoice, ItemReceipt, JournalEntry, LiabilityAdjustment, Paycheck, PayrollLiabilityCheck, PurchaseOrder, ReceivePayment, SalesOrder, SalesReceipt, SalesTaxPaymentCheck, Transfer, VendorCredit, YTDAdjustment -->
			if 'TransactionTypeFilter_TxnTypeFilter' in kwargs:
				self.QBDict[self.classNameRq]["TransactionTypeFilter"]={'TxnTypeFilter':kwargs['TransactionTypeFilter_TxnTypeFilter']}
			
			# <!-- TransactionDetailLevelFilter may have one of the following values: All, SummaryOnly [DEFAULT], AllExceptSummary -->
			if 'TransactionDetailLevelFilter' in kwargs:
				self.QBDict[self.classNameRq]["TransactionDetailLevelFilter"]=kwargs['TransactionDetailLevelFilter']
			
			# <!-- TransactionPostingStatusFilter may have one of the following values: Either [DEFAULT], NonPosting, Posting -->
			if 'TransactionPostingStatusFilter' in kwargs:
				self.QBDict[self.classNameRq]["TransactionPostingStatusFilter"]=kwargs['TransactionPostingStatusFilter']
			
			# <!-- TransactionPaidStatusFilter may have one of the following values: Either [DEFAULT], Closed, Open -->
			if 'TransactionPaidStatusFilter' in kwargs:
				self.QBDict[self.classNameRq]["TransactionPaidStatusFilter"]=kwargs['TransactionPaidStatusFilter']
			
			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(self.QBDict)
		if self.__class__.__name__==self.className:
			self.runCheck() ### running the qbxml connection to get data ###


class SalesOrderAdd(baseQBQuery):
	def __init__(self, *args, **kwargs):
		print(f'{args = }')
		print(f'{kwargs = }')
		super().__init__(*args, **kwargs)
		# self.includeRetElements_allowed = ['TxnID', 'TimeCreated', 'TimeModified', 'EditSequence', 'TxnNumber', 'CustomerRef', 'ClassRef', 'ARAccontRef', 'TemplateRef']
		self.onError = "stopOnError"
		self.retName = 'SalesOrderRet'

		self.defaultFilterKey = "TxnID"
		self.className = "SalesOrderAdd"
		self.classNameRq:str = self.__class__.__name__ + 'Rq'
		self.reqSubName = self.className
		if 'debug' in kwargs and isinstance(kwargs['debug'], bool):
			self.class_debug=kwargs["debug"]

		self.QBDict[self.classNameRq]={}
		

		
		self.isRequiredFieldSatisfied = False
		if 'requestID' in kwargs:
			self.QBDict[self.classNameRq]={'@requestID':kwargs.get('requestID', '1')}
		self.QBDict[self.classNameRq][self.__class__.__name__]={'@defMacro':'MACROTYPE'}
		if 'CustomerRef_ListID' in kwargs:
			if 'CustomerRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerRef"]['ListID']= kwargs['CustomerRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerRef"]={'ListID': kwargs['CustomerRef_ListID']}
			self.isRequiredFieldSatisfied=True
		if 'CustomerRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerRef"]={'FullName': kwargs['CustomerRef_FullName']}
			self.isRequiredFieldSatisfied=True
		
		if not self.isRequiredFieldSatisfied:
			raise Exception("Need CustomerRef FullName and/or ListID")

		if 'ClassRef_ListID' in kwargs:
			if 'ClassRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["ClassRef"]['ListID']= kwargs['ClassRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["ClassRef"]={'ListID': kwargs['ClassRef_ListID']}
		if 'ClassRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ClassRef"]={'FullName': kwargs['ClassRef_FullName']}
		
		# if 'ARAccountRef_ListID' in kwargs:
		#     if 'ARAccountRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
		#         self.QBDict[self.classNameRq][self.__class__.__name__]["ARAccountRef"]['ListID']= kwargs['ARAccountRef_ListID']
		#     else:
		#         self.QBDict[self.classNameRq][self.__class__.__name__]["ARAccountRef"]={'ListID': kwargs['ARAccountRef_ListID']}
		# if 'ARAccountRef_FullName' in kwargs:
		#     self.QBDict[self.classNameRq][self.__class__.__name__]["ARAccountRef"]={'FullName': kwargs['ARAccountRef_FullName']}
		
		if 'TemplateRef_ListID' in kwargs:
			if 'TemplateRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["TemplateRef"]['ListID']= kwargs['TemplateRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["TemplateRef"]={'ListID': kwargs['TemplateRef_ListID']}
		if 'TemplateRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["TemplateRef"]={'FullName': kwargs['TemplateRef_FullName']}
		
		if 'TxnDate' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["TxnDate"]=kwargs['TxnDate']
		if 'RefNumber' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["RefNumber"]=kwargs['RefNumber']
		if 'BillAddress_Addr1' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'Addr1': kwargs['BillAddress_Addr1']}
		if 'BillAddress_Addr2' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'Addr2': kwargs['BillAddress_Addr2']}
		if 'BillAddress_Addr3' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'Addr3': kwargs['BillAddress_Addr3']}
		if 'BillAddress_Addr4' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'Addr4': kwargs['BillAddress_Addr4']}
		if 'BillAddress_Addr5' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'Addr5': kwargs['BillAddress_Addr5']}
		if 'BillAddress_City' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'City': kwargs['BillAddress_City']}
		if 'BillAddress_State' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'State': kwargs['BillAddress_State']}
		if 'BillAddress_PostalCode' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'PostalCode': kwargs['BillAddress_PostalCode']}
		if 'BillAddress_Country' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'Country': kwargs['BillAddress_Country']}
		if 'BillAddress_Note' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["BillAddress"]={'Note': kwargs['BillAddress_Note']}

		if 'ShipAddress_Addr1' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'Addr1': kwargs['ShipAddress_Addr1']}
		if 'ShipAddress_Addr2' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'Addr2': kwargs['ShipAddress_Addr2']}
		if 'ShipAddress_Addr3' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'Addr3': kwargs['ShipAddress_Addr3']}
		if 'ShipAddress_Addr4' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'Addr4': kwargs['ShipAddress_Addr4']}
		if 'ShipAddress_Addr5' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'Addr5': kwargs['ShipAddress_Addr5']}
		if 'ShipAddress_City' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'City': kwargs['ShipAddress_City']}
		if 'ShipAddress_State' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'State': kwargs['ShipAddress_State']}
		if 'ShipAddress_PostalCode' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'PostalCode': kwargs['ShipAddress_PostalCode']}
		if 'ShipAddress_Country' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'Country': kwargs['ShipAddress_Country']}
		if 'ShipAddress_Note' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipAddress"]={'Note': kwargs['ShipAddress_Note']}
		
		if 'IsPending' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["IsPending"]=kwargs['IsPending']
		if 'IsFinanceCharge' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["IsFinanceCharge"]=kwargs['IsFinanceCharge']
		if 'PONumber' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["PONumber"]=kwargs['PONumber']
		if 'TermsRef_ListID' in kwargs:
			if 'TermsRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["TermsRef"]['ListID']= kwargs['TermsRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["TermsRef"]={'ListID': kwargs['TermsRef_ListID']}
		if 'TermsRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["TermsRef"]={'FullName': kwargs['TermsRef_FullName']}
		
		if 'DueDate' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["DueDate"]=kwargs['DueDate']
		if 'SalesRepRef_ListID' in kwargs:
			if 'SalesRepRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["SalesRepRef"]['ListID']= kwargs['SalesRepRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["SalesRepRef"]={'ListID': kwargs['SalesRepRef_ListID']}
		if 'SalesRepRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["SalesRepRef"]={'FullName': kwargs['SalesRepRef_FullName']}
		
		if 'FOB' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["FOB"]=kwargs['FOB']
		if 'ShipDate' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipDate"]=kwargs['ShipDate']
		if 'ShipMethodRef_ListID' in kwargs:
			if 'ShipMethodRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["ShipMethodRef"]['ListID']= kwargs['ShipMethodRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["ShipMethodRef"]={'ListID': kwargs['ShipMethodRef_ListID']}
		if 'ShipMethodRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ShipMethodRef"]={'FullName': kwargs['ShipMethodRef_FullName']}
		
		if 'ItemSalesTaxRef_ListID' in kwargs:
			if 'ItemSalesTaxRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["ItemSalesTaxRef"]['ListID']= kwargs['ItemSalesTaxRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["ItemSalesTaxRef"]={'ListID': kwargs['ItemSalesTaxRef_ListID']}
		if 'ItemSalesTaxRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ItemSalesTaxRef"]={'FullName': kwargs['ItemSalesTaxRef_FullName']}
		
		if 'IsManuallyClosed' in kwargs:    #only SalesOrderAdd. not in InvoiceAdd
			self.QBDict[self.classNameRq][self.__class__.__name__]["IsManuallyClosed"]=kwargs['IsManuallyClosed']
		if 'Memo' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["Memo"]=kwargs['Memo']
		if 'CustomerMsgRef_ListID' in kwargs:
			if 'CustomerMsgRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerMsgRef"]['ListID']= kwargs['CustomerMsgRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerMsgRef"]={'ListID': kwargs['CustomerMsgRef_ListID']}
		if 'CustomerMsgRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerMsgRef"]={'FullName': kwargs['CustomerMsgRef_FullName']}
		
		if 'IsToBePrinted' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["IsToBePrinted"]=kwargs['IsToBePrinted']
		if 'IsToBeEmailed' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["IsToBeEmailed"]=kwargs['IsToBeEmailed']
		if 'IsTaxIncluded' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["IsTaxIncluded"]=kwargs['IsTaxIncluded']
		if 'CustomerSalesTaxCodeRef_ListID' in kwargs:
			if 'CustomerSalesTaxCodeRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
				self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerSalesTaxCodeRef"]['ListID']= kwargs['CustomerSalesTaxCodeRef_ListID']
			else:
				self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerSalesTaxCodeRef"]={'ListID': kwargs['CustomerSalesTaxCodeRef_ListID']}
		if 'CustomerSalesTaxCodeRef_FullName' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["CustomerSalesTaxCodeRef"]={'FullName': kwargs['CustomerSalesTaxCodeRef_FullName']}
		
		if 'Other' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["Other"]=kwargs['Other']
		if 'ExchangeRate' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ExchangeRate"]=kwargs['ExchangeRate']
		if 'ExternalGUID' in kwargs:
			self.QBDict[self.classNameRq][self.__class__.__name__]["ExternalGUID"]=kwargs['ExternalGUID']
		
		# if 'LinkToTxnID' in kwargs:
		#     self.QBDict[self.classNameRq][self.__class__.__name__]["LinkToTxnID"]=makeAList(kwargs['LinkToTxnID'])
		
		# if 'SetCredit_CreditTxnID' in kwargs and 'SetCredit_AppliedAmount' in kwargs:
		#     self.QBDict[self.classNameRq][self.__class__.__name__]["SetCredit"]={'CreditTxnID':{'@useMacro':"MACROTYPE", '#text':kwargs['SetCredit_CreditTxnID']}, 'AppliedAmount': kwargs['SetCredit_AppliedAmount']}
		#     if 'SetCredit_Override' in kwargs:
		#         self.QBDict[self.classNameRq][self.__class__.__name__]["SetCredit"]["Override"]=kwargs['SetCredit_Override']

#add InvoiceLineAdd kwargs here

		self.SalesOrderLineAdd = []
		if 'SalesOrderLineAdd' in kwargs:
			LineAdd = kwargs.get('SalesOrderLineAdd')
			self.isLineAddOk = True
			if isinstance(LineAdd, dict ):
				LineAdd = [LineAdd]
			elif isinstance(LineAdd, list):
				pass
			else:
				self.isLineAddOk = False

			if self.isLineAddOk: #check if each instance in the list are all dictionary. 
				for eachLineAdd in LineAdd:
					if not isinstance(eachLineAdd, dict):
						self.isLineAddOk = False
						break
			else:
				print("SalesOrderLineAdd Not OK. has to be lisst of dict or a dict")
			
			
			if self.isLineAddOk: #if everything good
				for eachLineAdd in LineAdd:
					self.LineAddDict = {}
					if 'ItemRef_ListID' in eachLineAdd:
						if 'ItemRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
							self.LineAddDict["ItemRef"]['ListID']= eachLineAdd['ItemRef_ListID']
						else:
							self.LineAddDict["ItemRef"]={'ListID': eachLineAdd['ItemRef_ListID']}
					if 'ItemRef_FullName' in eachLineAdd:
						self.LineAddDict["ItemRef"]={'FullName': eachLineAdd['ItemRef_FullName']}
					if 'Desc' in eachLineAdd:
						self.LineAddDict["Desc"]=eachLineAdd['Desc']
					if 'Quantity' in eachLineAdd:
						self.LineAddDict["Quantity"]=eachLineAdd['Quantity']
					if 'UnitOfMeasure' in eachLineAdd:
						self.LineAddDict["UnitOfMeasure"]=eachLineAdd['UnitOfMeasure']
					if 'Rate' in eachLineAdd:
						self.LineAddDict["Rate"]=eachLineAdd['Rate']
					elif 'RatePercent' in eachLineAdd:
						self.LineAddDict["RatePercent"]=eachLineAdd['RatePercent']
					elif 'PriceLevelRef_ListID' in eachLineAdd:
						if 'PriceLevelRef' in self.QBDict[self.classNameRq][self.__class__.__name__]:
							self.LineAddDict["PriceLevelRef"]['ListID']= eachLineAdd['PriceLevelRef_ListID']
						else:
							self.LineAddDict["PriceLevelRef"]={'ListID': eachLineAdd['PriceLevelRef_ListID']}
					elif 'PriceLevelRef_FullName' in eachLineAdd:
						self.LineAddDict["PriceLevelRef"]={'FullName': eachLineAdd['PriceLevelRef_FullName']}
					
					if 'Amount ' in eachLineAdd:
						self.LineAddDict["Amount "]=eachLineAdd['Amount ']
					# Others
					if 'Other1' in eachLineAdd:
						self.LineAddDict["Other1"]=eachLineAdd['Other1']
					if len(self.LineAddDict)>0:
						self.SalesOrderLineAdd.append(self.LineAddDict)
					
					#skip the rest, not too important
			else:
				print("SalesOrderLineAdd  has to be list of dict or a dict")
		print(f'{self.SalesOrderLineAdd = }')
		if len(self.SalesOrderLineAdd)>0:
			self.QBDict[self.classNameRq][self.__class__.__name__]['SalesOrderLineAdd']=self.SalesOrderLineAdd
		if 'IncludeRetElement' in kwargs:
			self.QBDict[self.classNameRq]["IncludeRetElement"]=kwargs['IncludeRetElement']

		# print(self.classNameRq)
		print(f'{self.QBDict = }')


class SalesOrderQuery(baseQBQuery):
	def __init__(self, *args, **kwargs):
		if 'debug' in kwargs and isinstance(kwargs['debug'], bool):
			self.class_debug=kwargs["debug"]
		else:
			self.class_debug=False
		if self.class_debug:
			print(f'{args = }')
			print(f'{kwargs = }')
		super().__init__(*args, **kwargs)
		### Required Variable
		self.includeRetElements_allowed = ["TxnID", "TimeCreated", "TimeModified", "EditSequence", "TxnNumber", "CustomerRef", "ClassRef", "TemplateRef",
					"TxnDate", "RefNumber", "BillAddress", "BillAddressBlock", "ShipAddress", "ShipAddressBlock", "PONumber,", "TermsRef", "DueDate",
					"SalesRepRef", "FOB", "ShipDate", "ShipMethodRef", "SubTotal", "ItemSalesTaxRef", "SalesTaxPercentage", "SalesTaxTotal", "TotalAmount",
					"CurrencyRef", "ExchangeRate", "TotalAmountInHomeCurrency", "IsManuallyClosed", "IsFullyInvoiced", "Memo", "CustomerMsgRef", "IsToBePrinted",
					"IsToBeEmailed", "IsTaxIncluded", "CustomerSalesTaxCodeRef", "Other", "ExternalGUID", "LinkedTxn", "SalesOrderLineRet", "SalesOrderLineGroupRet"
					]
		self.onError = "stopOnError"
		self.retName = 'SalesOrderRet'
		self.defaultFilterKey = "TxnID"
		self.className =  'SalesOrderQuery' #Hardcoded because for check if self.__class__.__name__==self.className
		self.classNameRq:str = self.__class__.__name__ + 'Rq'


		self.QBDict[self.classNameRq]={}
		### End Required Variable. can put ENUM list below this (eg: self.ENUM_GeneralSummaryReportQuery=[])
		# self.ENUM_DateMacro = ['All', 'Today', 'ThisWeek', 'ThisWeekToDate', 'ThisMonth', 'ThisMonthToDate', 'ThisCalendarQuarter', 'ThisCalendarQuarterToDate', 'ThisFiscalQuarter',
		#      'ThisFiscalQuarterToDate', 'ThisCalendarYear', 'ThisCalendarYearToDate', 'ThisFiscalYear', 'ThisFiscalYearToDate', 'Yesterday', 'LastWeek', 'LastWeekToDate', 'LastMonth', 
		#      'LastMonthToDate', 'LastCalendarQuarter', 'LastCalendarQuarterToDate', 'LastFiscalQuarter', 'LastFiscalQuarterToDate', 'LastCalendarYear', 'LastCalendarYearToDate', 
		#      'LastFiscalYear', 'LastFiscalYearToDate', 'NextWeek', 'NextFourWeeks', 'NextMonth', 'NextCalendarQuarter', 'NextCalendarYear', 'NextFiscalQuarter', 'NextFiscalYear'
		#      ]
		self.ENUM_MatchCriterion = ['StartsWith', 'Contains', 'EndsWith']

		if 'TxnID' in kwargs and kwargs['TxnID'] and len(kwargs['TxnID'])>0:
			self.QBDict[self.classNameRq]["TxnID"]=makeAList(kwargs['TxnID'])
		elif 'RefNumber' in kwargs and kwargs['RefNumber']:
			self.QBDict[self.classNameRq]["RefNumber"]=makeAList(kwargs['RefNumber'])
		elif 'RefNumberCaseSensitive' in kwargs and kwargs['RefNumberCaseSensitive']:
			self.QBDict[self.classNameRq]["RefNumberCaseSensitive"]=makeAList(kwargs['RefNumberCaseSensitive'])
		else:
			if 'MaxReturned' in kwargs:
				self.QBDict[self.classNameRq]["MaxReturned"]=kwargs['MaxReturned']
			if 'ModifiedDateRangeFilter_FromModifiedDate' in kwargs or 'ModifiedDateRangeFilter_ToModifiedDate' in kwargs:  #if or then use {'key1':kwargs.get('key1',""), 'key2':kwargs.get('key2', "")}
				self.QBDict[self.classNameRq]["ModifiedDateRangeFilter"]={'FromModifiedDate':kwargs.get('ModifiedDateRangeFilter_FromModifiedDate', ""), 'ToModifiedDate':kwargs.get('ModifiedDateRangeFilter_ToModifiedDate', "")}
			elif 'TxnDateRangeFilter_FromTxnDate' in kwargs or 'TxnDateRangeFilter_ToTxnDate' in kwargs:  #if or then use {'key1':kwargs.get('key1',""), 'key2':kwargs.get('key2', "")}
				self.QBDict[self.classNameRq]["TxnDateRangeFilter"]={'FromTxnDate':kwargs.get('TxnDateRangeFilter_FromTxnDate', ""), 'ToTxnDate':kwargs.get('TxnDateRangeFilter_ToTxnDate', "")}
			elif 'TxnDateRangeFilter_DateMacro' in kwargs:
				DM=cleanIncludeRetElements(ENUM_DateMacro, kwargs['TxnDateRangeFilter_DateMacro'])
				if len(DM)>0:
					self.QBDict[self.classNameRq]["TxnDateRangeFilter"]={'DateMacro':DM}

			if 'EntityFilter_ListID' in kwargs:
				self.QBDict[self.classNameRq]["EntityFilter"]={'ListID':makeAList(kwargs['EntityFilter_ListID'])}
			elif 'EntityFilter_FullName' in kwargs:
				self.QBDict[self.classNameRq]["EntityFilter"]={'FullName':makeAList(kwargs['EntityFilter_FullName'])}
			elif 'EntityFilter_ListIDWithChildren' in kwargs:
				self.QBDict[self.classNameRq]["EntityFilter"]={'ListIDWithChildren':kwargs['EntityFilter_ListIDWithChildren']}
			elif 'EntityFilter_FullNameWithChildren' in kwargs:
				self.QBDict[self.classNameRq]["EntityFilter"]={'FullNameWithChildren':kwargs['EntityFilter_FullNameWithChildren']}

			if 'RefNumberFilter_MatchCriterion' in kwargs and 'RefNumberFilter_RefNumber' in kwargs:
				RNFMC = cleanIncludeRetElements(self.ENUM_MatchCriterion, kwargs['RefNumberFilter_MatchCriterion'])
				if len(RNFMC)>0:
					self.QBDict[self.classNameRq]["RefNumberFilter"]={'MatchCriterion':RNFMC, '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', "")}
				self.QBDict[self.classNameRq]["RefNumberRangeFilter"]={'FromRefNumber':kwargs.get('RefNumberRangeFilter_FromRefNumber', ""), 'ToRefNumber':kwargs.get('RefNumberRangeFilter_ToRefNumber', "")}

			if 'CurrencyFilter_ListID' in kwargs:
				self.QBDict[self.classNameRq]["CurrencyFilter"]=makeAList(kwargs['CurrencyFilter_ListID'])
			elif 'CurrencyFilter_FullName' in kwargs:
				self.QBDict[self.classNameRq]["CurrencyFilter"]=makeAList(kwargs['CurrencyFilter_FullName'])

		if 'IncludeLineItems' in kwargs:
			self.QBDict[self.classNameRq]["IncludeLineItems"]=kwargs['IncludeLineItems']
		if 'IncludeLinkedTxns' in kwargs:
			self.QBDict[self.classNameRq]["IncludeLinkedTxns"]=kwargs['IncludeLinkedTxns']
		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

		if 'OwnerID' in kwargs:     # usually value=0 to get to DataExtRet (additional data)
			self.QBDict[self.classNameRq]["OwnerID"]=kwargs['OwnerID']

		# print(self.classNameRq)
		if self.class_debug:
			print(self.QBDict)
		if self.__class__.__name__==self.className:
			self.runCheck() ### running the qbxml connection to get data ###


class InvoiceQuery(baseQBQuery):
	def __init__(self, *args, **kwargs):

		print(f'{args = }')
		print(f'{kwargs = }')
		super().__init__(*args, **kwargs)
		### Required Variable
		self.includeRetElements_allowed = ["TxnID", "TimeCreated", "TimeModified", "EditSequence", "TxnNumber", "CustomerRef", "ClassRef", "ARAccountRef", "TemplateRef", 
					"TxnDate", "RefNumber", "BillAddress", "BillAddressBlock", "ShipAddress", "ShipAddressBlock", "IsPending", "IsFinanceCharge", "PONumber,", "TermsRef", "DueDate",
					"SalesRepRef", "FOB", "ShipDate", "ShipMethodRef", "SubTotal", "ItemSalesTaxRef", "SalesTaxPercentage", "SalesTaxTotal", "AppliedAmount", "BalanceRemaining",
					"CurrencyRef", "ExchangeRate", "BalanceRemainingInHomeCurrency", "Memo", "IsPaid", "CustomerMsgRef", "IsToBePrinted",
					"IsToBeEmailed", "IsTaxIncluded", "CustomerSalesTaxCodeRef", "SuggestedDiscountAmount", "SuggestedDiscountDate", "Other", "ExternalGUID",
					"LinkedTxn", "InvoiceLineRet", "InvoiceLineGroupRet",
					]
		self.onError = "stopOnError"
		self.retName = 'InvoiceRet'
		self.defaultFilterKey = "TxnID"
		self.className = 'InvoiceQuery'
		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]={}
		### End Required Variable. can put ENUM list below this (eg: self.ENUM_GeneralSummaryReportQuery=[])
		# self.ENUM_DateMacro = ['All', 'Today', 'ThisWeek', 'ThisWeekToDate', 'ThisMonth', 'ThisMonthToDate', 'ThisCalendarQuarter', 'ThisCalendarQuarterToDate', 'ThisFiscalQuarter',
		#      'ThisFiscalQuarterToDate', 'ThisCalendarYear', 'ThisCalendarYearToDate', 'ThisFiscalYear', 'ThisFiscalYearToDate', 'Yesterday', 'LastWeek', 'LastWeekToDate', 'LastMonth', 
		#      'LastMonthToDate', 'LastCalendarQuarter', 'LastCalendarQuarterToDate', 'LastFiscalQuarter', 'LastFiscalQuarterToDate', 'LastCalendarYear', 'LastCalendarYearToDate', 
		#      'LastFiscalYear', 'LastFiscalYearToDate', 'NextWeek', 'NextFourWeeks', 'NextMonth', 'NextCalendarQuarter', 'NextCalendarYear', 'NextFiscalQuarter', 'NextFiscalYear'
		#      ]    ## disabled, and move to outside class, on top of page
		self.ENUM_MatchCriterion = ['StartsWith', 'Contains', 'EndsWith']

		if 'TxnID' in kwargs and kwargs['TxnID'] and len(kwargs['TxnID'])>0:
			_txnIDs=makeAList(kwargs['TxnID'])
			self.QBDict[self.classNameRq]["TxnID"]= makeAList(kwargs['TxnID'])
		elif 'RefNumber' in kwargs and kwargs['RefNumber']:
			self.QBDict[self.classNameRq]['RefNumber']=makeAList(kwargs['RefNumber'])
		elif 'RefNumberCaseSensitive' in kwargs and kwargs['RefNumberCaseSensitive']:
			self.QBDict[self.classNameRq]["RefNumberCaseSensitive"]=makeAList(kwargs['RefNumberCaseSensitive'])
		else:
			if 'MaxReturned' in kwargs:
				self.QBDict[self.classNameRq]["MaxReturned"]=kwargs['MaxReturned']
			if 'ModifiedDateRangeFilter_FromModifiedDate' in kwargs or 'ModifiedDateRangeFilter_ToModifiedDate' in kwargs:  #if or then use {'key1':kwargs.get('key1',""), 'key2':kwargs.get('key2', "")}
				self.QBDict[self.classNameRq]["ModifiedDateRangeFilter"]={'FromModifiedDate':kwargs.get('ModifiedDateRangeFilter_FromModifiedDate', ""), 'ToModifiedDate':kwargs.get('ModifiedDateRangeFilter_ToModifiedDate', "")}
			elif 'TxnDateRangeFilter_FromTxnDate' in kwargs or 'TxnDateRangeFilter_ToTxnDate' in kwargs:  #if or then use {'key1':kwargs.get('key1',""), 'key2':kwargs.get('key2', "")}
				self.QBDict[self.classNameRq]["TxnDateRangeFilter"]={'FromTxnDate':kwargs.get('TxnDateRangeFilter_FromTxnDate', ""), 'ToTxnDate':kwargs.get('TxnDateRangeFilter_ToTxnDate', "")}
			elif 'TxnDateRangeFilter_DateMacro' in kwargs:
				DM=cleanIncludeRetElements(ENUM_DateMacro, kwargs['TxnDateRangeFilter_DateMacro'])
				if len(DM)>0:
					self.QBDict[self.classNameRq]["TxnDateRangeFilter"]={'DateMacro':DM}

			if 'EntityFilter_ListID' in kwargs:
				# self.QBDict[self.classNameRq]["EntityFilter"]={'ListID':kwargs['EntityFilter_ListID']}
				self.QBDict[self.classNameRq]['EntityFilter']={'ListID':makeAList(kwargs['EntityFilter_ListID'])}
			elif 'EntityFilter_FullName' in kwargs:
				# self.QBDict[self.classNameRq]["EntityFilter"]={'FullName':kwargs['EntityFilter_FullName']}
				self.QBDict[self.classNameRq]['EntityFilter']={'FullName':makeAList(kwargs['EntityFilter_FullName'])}
			elif 'EntityFilter_ListIDWithChildren' in kwargs:
				self.QBDict[self.classNameRq]["EntityFilter"]={'ListIDWithChildren':kwargs['EntityFilter_ListIDWithChildren']}
			elif 'EntityFilter_FullNameWithChildren' in kwargs:
				self.QBDict[self.classNameRq]["EntityFilter"]={'FullNameWithChildren':kwargs['EntityFilter_FullNameWithChildren']}

			if 'AccountFilter_ListID' in kwargs:
				self.QBDict[self.classNameRq]["AccountFilter"]={'ListID':makeAList(kwargs['AccountFilter_ListID'])}
			elif 'AccountFilter_FullName' in kwargs:
				self.QBDict[self.classNameRq]["AccountFilter"]={'FullName':makeAList(kwargs['AccountFilter_FullName'])}
			elif 'AccountFilter_ListIDWithChildren' in kwargs:
				self.QBDict[self.classNameRq]["AccountFilter"]={'ListIDWithChildren':kwargs['AccountFilter_ListIDWithChildren']}
			elif 'AccountFilter_FullNameWithChildren' in kwargs:
				self.QBDict[self.classNameRq]["AccountFilter"]={'FullNameWithChildren':kwargs['AccountFilter_FullNameWithChildren']}

			if 'RefNumberFilter_MatchCriterion' in kwargs and 'RefNumberFilter_RefNumber' in kwargs:
				RNFMC = cleanIncludeRetElements(self.ENUM_MatchCriterion, kwargs['RefNumberFilter_MatchCriterion'])
				if len(RNFMC)>0:
					self.QBDict[self.classNameRq]["RefNumberFilter"]={'MatchCriterion':RNFMC, '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', "")}
				##### CAREFULL with the get() coz "" will get anything
				self.QBDict[self.classNameRq]["RefNumberRangeFilter"]={'FromRefNumber':kwargs.get('RefNumberRangeFilter_FromRefNumber', ""), 'ToRefNumber':kwargs.get('RefNumberRangeFilter_ToRefNumber', "")} 

			if 'CurrencyFilter_ListID' in kwargs:
				self.QBDict[self.classNameRq]["CurrencyFilter"]=makeAList(kwargs['CurrencyFilter_ListID'])
			elif 'CurrencyFilter_FullName' in kwargs:
				self.QBDict[self.classNameRq]["CurrencyFilter"]=makeAList(kwargs['CurrencyFilter_FullName'])

		if 'IncludeLineItems' in kwargs:
			print(f'{self.QBDict} = ')
			self.QBDict[self.classNameRq]["IncludeLineItems"]=kwargs['IncludeLineItems']
		if 'IncludeLinkedTxns' in kwargs:
			self.QBDict[self.classNameRq]["IncludeLinkedTxns"]=kwargs['IncludeLinkedTxns']
		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

		if 'OwnerID' in kwargs:     # usually value=0 to get to DataExtRet (additional data)
			self.QBDict[self.classNameRq]["OwnerID"]=kwargs['OwnerID']
		# print(self.classNameRq)
		# print(self.QBDict)
		if self.__class__.__name__==self.className:
			self.runCheck() ### running the qbxml connection to get data ###


@timing
def InventoryStockStatusByVendor(ReportEntityFilter_FullName:str='TACO') -> dict:
	# g= GeneralSummaryReportQuery(debug=False, GeneralSummaryReportType="ProfitAndLossStandard", ReportDateMacro="ThisYear")
	g= GeneralSummaryReportQuery(debug=False, GeneralSummaryReportType="InventoryStockStatusByVendor", ReportEntityFilter_FullName=ReportEntityFilter_FullName, )
	# g= GeneralSummaryReportQuery(debug=False, GeneralSummaryReportType="InventoryStockStatusByVendor", ReportItemFilter_FullName=['TACH:RLC:BBS009PO45-500','TACH:RLC:BBS009PO45-400'], ReportEntityFilter_FullName='TACO' )
	# print(g, type(g))
	# print(type(g.all()))
	# print(g.all())
	# print(g.response_string)
	# print(g.all())
	# pprint.pprint(g.filter("reportdata").all())
	# abc = g.filter("reportdata").all()
	# print(abc)
	# print()
	# pprint.pprint(g.filter('datarow').all(abc), sort_dicts=False)
	datarows = g.filter('datarow').all()
	# pprint.pprint(datarows, sort_dicts=False)
	# print(type(datarows))
	dt = {}
	if len(datarows[0]['DataRow'])==0:
		return dt
	for datarow in datarows[0]['DataRow']:
		# print(datarow,)
		FullName=datarow['RowData']['@value']
		if len(FullName.split(':'))==3:
			ShortName=datarow['ColData'][0]['@value']
			QOH, QOSO, QA, UOM, QOPO, min, max, ND = None, None, None, None, None, None, None, None
			for coldata in datarow['ColData']:
				if coldata['@colID']=='5':
					QOH=coldata['@value']
				elif coldata['@colID']=='6':
					QOSO=coldata['@value']
				elif coldata['@colID']=='8':
					QA=coldata['@value']
				elif coldata['@colID']=='9':
					UOM=coldata['@value']
				elif coldata['@colID']=='11':
					QOPO=coldata['@value']
				elif coldata['@colID']=='3':
					min=coldata['@value']
				elif coldata['@colID']=='4':
					max=coldata['@value']
				elif coldata['@colID']=='13':
					ND=coldata['@value'] #Next Delivery Date
			dt[FullName]={'ShortName':ShortName, 'QOH':QOH, 'QOSO':QOSO, 'QA':QA, 'QOPO':QOPO, 'UOM':UOM, 'min':min, 'max':max, 'ND':ND}
	# print(f'{dt = }')
	print(f'InventoryStockStatusByVendor {len(dt) = }')
	return dt
	"""
	{'@rowNumber': '1016',
		'ColData': [{'@colID': '1',
					'@value': 'EDG-P1251-1/42'},
					{'@colID': '2',
					'@value': 'EDGING 42 X 1 MM P1251'},
					{'@colID': '5', '@value': '1'}, # QOH
					{'@colID': '6', '@value': '0'}, # QOSO
					{'@colID': '7', '@value': '0'}, #assembly
					{'@colID': '8', '@value': '1'}, # QA(available)(QOH-QOSO-assembly)
					{'@colID': '9', '@value': 'Roll'},  #base_uom
					{'@colID': '10', '@value': 'false'},
					{'@colID': '11', '@value': '0'},   #QOPO
					{'@colID': '12', '@value': '0'},    #ReorderqTY
					{'@colID': '13', '@value': '13/04/2022'},    #NextDeliver
					{'@colID': '14', '@value': '0'}],
		'RowData': {'@rowType': 'item',
					'@value': 'TEDG:P142:EDG-P1251-1/42'}},
	"""


if __name__ == "__main__":
	@timing
	def invoicequery():
		g=InvoiceQuery(debug=False, MaxReturned = 2,  IncludeLineItems="true", IncludeLinkedTxns="true",
				RefNumber="24010022")#"2023-08-22")
		print(json.dumps(g.filter().all(), indent=3))
		print(g.count())

	@timing
	def salesorderquery():
		g=SalesOrderQuery(debug=False, MaxReturned = 1,  TxnID=None, IncludeLineItems="true", IncludeLinkedTxns="true",
				)#RefNumber="24010022" )#"B23070857")
		print(json.dumps(g.filter().all(), indent=3))
		print(g.count())

	@timing
	def transactionquery():
		g=TransactionQuery(debug=False, MaxReturned=None, TransactionTypeFilter_TxnTypeFilter="Invoice", TransactionEntityFilter_FullName="Abadi Serpong",
					TransactionDetailLevelFilter="All", TransactionPaidStatusFilter="Open", TransactionDateRangeFilter_DateMacro="ThisFiscalYear")
		# 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")
		print(g, type(g))
		print(type(g.all()))
		print(g.all())
		print(g.response_string)
		pprint.pprint(g.filter("reportdata").all())
		print(g.count(), g.all())

	@timing
	def iteminventoryquery():
		# g=ItemInventoryQuery()
		g=ItemInventoryQuery(debug = False, MaxReturned = 5, IncludeRetElements = "abc")#  IncludeRetElement=["FullName", "DataExtRet", "Name", "QuantityOnHand", "QuantityOnSalesOrder", "QuantityOnOrder", "ManufacturerPartNumber"]) #put OwnerID=0 to get DataExtRet
		# print("before g.all")
		# print(f'{g.all() = }')
		# print("after g.all")
		# print("")
		# pprint.pprint(g.filter(["FullName", "Name", "sublevel"]).all())
		# print(f'{g.filter("fullname") = }')

		# print(f'{g  =  }')
		# pprint.pprint(g.response_string,indent=4 )
		print(g.response_string, type(g.response_string))
		print("before")
		# print(g.filter([ "Name", "QuantityOnHand", "QUantityOnSalesOrder", "QuantityonOrder"]).first())
		c = g.filter([ "Name", "QuantityOnHand", "QUantityOnSalesOrder", "QuantityonOrder"]).first()
		print("c:",type(c), c)
		# pprint.pprint(g.returnRet())
		# print(g.filter("name").firstValue())
		print(g.count())
		print(g.statusOk)
		print(g.filter(["name", "manufacturerpartnumber", "quantityonhand"]).getValuesOf(["Name","quantityonhand", "manufacturerpartnumber"]))


		# print(g.filter(["DataExtRet"]).all())

	@timing
	def customerquery():
		g= CustomerQuery(MaxReturned=3, IncludeRetElement=["fullname",  "name", "CompanyName", "BillAddressBlock", "ShipAddressBlock", "Notes", "AdditionalNotesRet", 'creditlimit'])
		g= CustomerQuery(MaxReturned=2, IncludeRetElement=["fullname",  "name", "CompanyName", "BillAddressBlock", "ShipAddress",  "ShipToAddress","Phone", "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")
		# print(f'{type(g.all()) = }')
		print("before g.all")
		print(f'{g.all() = }')
		print("after g.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() = }')

	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

	@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()
	# transactionquery()        
	# pprint.pprint(InventoryStockStatusByVendor(), sort_dicts=False)
	# iteminventoryquery()
	customerquery()
	# readxmltodict()
	# g=SalesOrderQuery(MaxReturned=1)
	# print(len(None))
