minor update from mike

This commit is contained in:
bcomsugi 2025-07-22 05:07:49 +07:00
parent d415450cc6
commit 6af73dd990
4 changed files with 238 additions and 22 deletions

23
main.py
View File

@ -368,3 +368,26 @@ async def transactionquery(request: Request):
return tq.all()
@app.post('/dasa2/rawxml')
async def rawxml(request: Request):
raw = await request.body()
from sendItem import send_new_item
rawstr = raw.decode(encoding="utf-8")
# print(f'{raw = } {type(raw) = } {rawstr = } {type(rawstr) = }')
# print(f'{send_new_item(rawstr) = }')
result = send_new_item(rawstr)
# print(result, type(result))
return {'result': result}
# return {'msg':'ok'}
# return "ok world"
# # try:
# # transactiondict = json.loads(transactiondict)
# # except:
# # print('error TransactionQuery()')
# # return {'message':'error getting TransactionQuery Data. it is not json'}
# print(f'{type(transactiondict)}, {transactiondict = }')
# print(f'{transactiondict = }')
# tq = TransactionQuery(**transactiondict)
# print(tq.all())
# print(f'{len(tq.to_json()) = }')
# return tq.all()

126
sendItem.py Normal file
View File

@ -0,0 +1,126 @@
import pythoncom
import win32com.client
class QBSDK_NewItem:
def __init__(self):
pythoncom.CoInitialize()
print("[DEBUG} ✅ COM Initialized")
self.qb = None
print("[DEBUG] ✅ QBXMLRP2 Dispatch OK")
self.session_id = None
self.response_str = ""
# self.open_connection()
def open_connection(self):
print(self.qb)
self.qb = win32com.client.Dispatch("QBXMLRP2.RequestProcessor")
print("after dispatch")
# self.qb.OpenConnection2("DASA2", "DASA2", 1)
# self.qb.OpenConnection2("", "DASA2", 1)
# self.qb.OpenConnection2("", "Test qbXML Request", 1)
op = self.qb.OpenConnection('', 'DASA2')
#self.qb.OpenConnection('', 'Test qbXML Request')
print("[DEBUG] ✅ OpenConnection2 completed")
self.session_id = self.qb.BeginSession("", 2)
print("ok")
print("[DEBUG] ✅ BeginSession completed")
def close_connection(self):
if self.session_id:
self.qb.EndSession(self.session_id)
self.qb.CloseConnection()
pythoncom.CoUninitialize()
print("[DEBUG] ✅ QuickBooks connection closed")
def response_request(self, xml: str) -> str:
try:
print("\n---SENDING REQUEST TO QUICKBOOKS---\n")
print(xml)
response = self.qb.ProcessRequest(self.session_id, xml)
print("\n---RESPONSE RECEIVED FROM QUICKBOOKS---\n")
print(response if response else "No Response Received!")
return response
except Exception as e:
print("[DEBUG] ❌ Error Processing Request: ", str(e))
return ""
# def qbxml_itemAdd(self, data):
# type = data['type'].item_type if hasattr(data['type'], 'item_type') else data['type']
# purchase_from_vendor = data.get("purchase_from_vendor", False)
# if type == "Inventory Part":
# open_tag = "<ItemInventoryAdd>"
# close_tag = "</ItemInventoryAdd>"
# rq_open = "<ItemInventoryAddRq>"
# rq_close = "</ItemInventoryAddRq>"
# elif type == "Inventory Assembly":
# open_tag = "<ItemInventoryAssemblyAdd>"
# close_tag = "</ItemInventoryAssemblyAdd>"
# rq_open = "<ItemInventoryAssemblyAddRq>"
# rq_close = "</ItemInventoryAssemblyAddRq>"
# else:
# raise ValueError("Unsupported item type")
# mpn = f"<ManufacturerPartNumber >{data['mpn']}</ManufacturerPartNumber>" if data.get("mpn") else ""
# xml = f"""<?xml version="1.0" encoding="utf-8"?>
# <?qbxml version="13.0"?>
# <QBXML>
# <QBXMLMsgsRq onError="stopOnError">
# {rq_open}
# {open_tag}
# <Name >{data['name']}</Name>
# {mpn}
# <SalesDesc >{data['sdesc']}</SalesDesc>
# <SalesPrice >{data['sprice']}</SalesPrice>
# <IncomeAccountRef>
# <ListID >{data['income_acc']}</ListID>
# </IncomeAccountRef>
# <PurchaseDesc >{data['pdesc']}</PurchaseDesc>
# <PurchaseCost >{data['cost']}</PurchaseCost>
# <COGSAccountRef>
# <ListID >{data['cogs_acc']}</ListID>
# </COGSAccountRef>
# <PrefVendorRef>
# <FullName >{data['pref_vendor']}</FullName>
# </PrefVendorRef>
# <AssetAccountRef>
# <ListID >{data['asset_acc']}</ListID>
# </AssetAccountRef>
# <ReorderPoint >{data['min']}</ReorderPoint>
# <Max >{data['max']}</Max>
# <QuantityOnHand >{data['on_hand']}</QuantityOnHand>
# <TotalValue >{data['tot_value']}</TotalValue>
# <InventoryDate >{data['as_of']}</InventoryDate>
# <IsActive >{'false' if data.get('inactive') else 'true'}</IsActive>
# {close_tag}
# {rq_close}
# </QBXMLMsgsRq>
# </QBXML>
# """
# print("\n🔍 CHECKING QBXML FORMAT BEFORE SENDING:")
# qbxml = xml.strip()
# response = self.response_request(qbxml)
# return response
def send_rq_to_qb(self, xmlstr:str):
qbxml = xmlstr.strip()
self.response_str = self.response_request(qbxml)
return self.response_str
def send_new_item(dtstr:str):
print("start send new item")
qbdt = QBSDK_NewItem()
print(qbdt)
qbdt.open_connection()
qbdt.send_rq_to_qb(dtstr)
return qbdt.response_str
# if __name__=="__main__":
# test = QBSDK_NewItem()
# test.open_connection()

View File

@ -1,6 +1,7 @@
import win32com.client
import xml.etree.ElementTree as ET
from QBClass.QBClasses import GeneralSummaryReportQuery
import pprint
class QuickBooksSDK:
def __init__(self):
@ -108,30 +109,94 @@ class QuickBooksSDK:
response = self.send_request(qbxml)
return response
def get_keep_sales_orders(self, from_date: str, to_date: str) -> str:
""" Fetch sales orders from QuickBooks within date range """
qbxml = f"""
<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="13.0"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<CustomDetailReportQueryRq requestID="1">
<CustomDetailReportType>CustomTxnDetail</CustomDetailReportType>
<DisplayReport>true</DisplayReport>
<ReportDateMacro>All</ReportDateMacro>
<ReportEntityFilter>
<FullName>KEEP</FullName>
</ReportEntityFilter>
<ReportItemFilter>
<FullName>TACO:W:TH-001AA</FullName>
<FullName>TACO:W:TH-002AA</FullName>
<FullName>TACO:AA:TH-003AA</FullName>
<FullName>TACO:AA:TH-010AA</FullName>
</ReportItemFilter>
<ReportTxnTypeFilter>
<TxnTypeFilter>SalesOrder</TxnTypeFilter>
</ReportTxnTypeFilter>
<ReportPostingStatusFilter>NonPosting</ReportPostingStatusFilter>
<SummarizeRowsBy>TotalOnly</SummarizeRowsBy> <!-- required -->
<!-- IncludeColumn may have one of the following values: Account, Aging, Amount, AmountDifference, AverageCost, BilledDate, BillingStatus, CalculatedAmount,
Class, ClearedStatus, CostPrice, Credit, Currency, Date, Debit, DeliveryDate, DueDate, EstimateActive, ExchangeRate, FOB, IncomeSubjectToTax, Invoiced, Item, ItemDesc,
LastModifiedBy, LatestOrPriorState, Memo, ModifiedTime, Name, NameAccountNumber, NameAddress, NameCity, NameContact, NameEmail, NameFax, NamePhone, NameState, NameZip,
OpenBalance, OriginalAmount, PaidAmount, PaidStatus, PaidThroughDate, PaymentMethod, PayrollItem, PONumber, PrintStatus, ProgressAmount, ProgressPercent, Quantity,
QuantityAvailable, QuantityOnHand, QuantityOnSalesOrder, ReceivedQuantity, RefNumber, RunningBalance, SalesRep, SalesTaxCode, SerialOrLotNumber, ShipDate, ShipMethod,
SourceName, SplitAccount, SSNOrTaxID, TaxLine, TaxTableVersion, Terms, TxnID, TxnNumber, TxnType, UnitPrice, UserEdit, ValueOnHand, WageBase, WageBaseTips -->
<IncludeColumn>Amount</IncludeColumn>
<IncludeColumn>Item</IncludeColumn>
<IncludeColumn>Date</IncludeColumn>
<IncludeColumn>Memo</IncludeColumn>
<IncludeColumn>Quantity</IncludeColumn>
<IncludeColumn>RefNumber</IncludeColumn>
<IncludeColumn>Name</IncludeColumn>
<IncludeColumn>NameAddress</IncludeColumn>
<IncludeColumn>SourceName</IncludeColumn>
<IncludeColumn>TxnNumber</IncludeColumn>
<IncludeColumn>TxnType</IncludeColumn>
<IncludeColumn>ReceivedQuantity</IncludeColumn>
<IncludeColumn>PaidStatus</IncludeColumn>
<IncludeColumn>Invoiced</IncludeColumn>
<IncludeColumn>LatestOrPriorState</IncludeColumn>
</CustomDetailReportQueryRq>
</QBXMLMsgsRq>
</QBXML>
"""
# pprint.pprint(qbxml, sort_dicts=False)
qbxml = qbxml.strip()
print("\n🔍 CHECKING QBXML FORMAT BEFORE SENDING:")
print(qbxml) # Print request before sending
response = self.send_request(qbxml)
return response
# **🔹 Main Execution**
if __name__ == "__main__":
# qb = QuickBooksSDK()
qb = QuickBooksSDK()
# try:
# qb.open_connection()
try:
qb.open_connection()
# # Query sales orders from January 1, 2024 to January 5, 2024
# sales_orders = qb.get_sales_orders("2024-01-01", "2024-01-05")
# Query sales orders from January 1, 2024 to January 5, 2024
# sales_orders = qb.get_sales_orders("2024-01-01", "2024-01-05")
sales_orders = qb.get_keep_sales_orders("2024-01-01", "2024-01-05")
# # Print hasil dalam format dictionary
# print("Sales Orders:", sales_orders)
# Print hasil dalam format dictionary
# print("Sales Orders:", sales_orders)
# finally:
# qb.close_connection()
g= GeneralSummaryReportQuery(debug=False, GeneralSummaryReportType="InventoryStockStatusByItem", ReportItemFilter_FullName=['ECO:0:ECO-009', 'TACF:HNDL:TP-H04/MR','ECO:0:ECO-007', 'ECO:0:ECO-006'])
finally:
qb.close_connection()
# g= GeneralSummaryReportQuery(debug=False, GeneralSummaryReportType="InventoryStockStatusByItem", ReportItemFilter_FullName=['ECO:0:ECO-009', 'TACF:HNDL:TP-H04/MR','ECO:0:ECO-007', 'ECO:0:ECO-006'])
# print(g, type(g))
# print(type(g.all()))
# print(g.all())
# print(g.response_string)
# print(g.filter("reportdata").all())
# print(g.all())
print(f'{g.filter("datarow").getItemInventory_Report() = }')
# print(f'{g.filter("datarow").getItemInventory_Report() = }')

View File

@ -1,13 +1,15 @@
import requests
import json
url = 'http://127.0.0.1:5555/getopenso'
myobj = {"CustomerName":"Al Malik Paint",}
myobj = json.dumps(myobj)
x = requests.post(url, json=myobj)
print(x.text)
url = 'http://127.0.0.1:5555/getopensodetail'
y={'solist':x.text}
y=json.dumps(y)
x = requests.post(url, json= y)
print(json.loads(x.text))
import pprint
# url = 'http://127.0.0.1:5555/getopenso'
# myobj = {"CustomerName":"Al Malik Paint",}
# myobj = json.dumps(myobj)
# x = requests.post(url, json=myobj)
# print(x.text)
# url = 'http://127.0.0.1:5555/getopensodetail'
# y={'solist':x.text}
# y=json.dumps(y)
# x = requests.post(url, json= y)
# print(json.loads(x.text))
from QBClass.QBClasses import InventoryStockStatusByVendor
pprint.pprint(InventoryStockStatusByVendor(), sort_dicts=False)