Hi,
I’m a retailer with a distributor using Acumatica for their ERP. They gave me a login so I can check inventory balances in real time, but as we carry thousands of their products I need an automated way to check stock level daily.
I noticed that their implementation seems to have some web services enabled via a SOAP endpoint when visiting a “Web Services” link from the SP700000 screen (sclientname].acumatica.com/(W(1))/Soap/SP700000.asmx). I’m quite familiar with developing Python apps so I’ve been working on using this endpoint to pull their catalog down into a CSV file.
So far I’m able to connect and authenticate to the endpoint and run GetSchema, but when I request the fields I want the endpoint just times out. Even if I specify just one Inventory ID the endpoint just times out eventually.
Here’s my code for reference:
import requests
from zeep import Client
from zeep.transports import Transport
import csv
import logging
import sys
from datetime import datetime
# Set up logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Also log to console
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(asctime)s - %(message)s')
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
# API endpoint
url = 'https://>client-name].acumatica.com/Soap/SP700000.asmx'
# Your credentials
username = 'user-login'
password = 'password'
logger.info(f"Connecting to API at {url}")
# Create a session to handle cookies
session = requests.Session()
# Create a Zeep client
client = Client(wsdl=url + '?wsdl', transport=Transport(session=session))
logger.info("SOAP client created successfully")
# Login
logger.info("Attempting to log in...")
login_result = client.service.Login(username, password)
if login_result.Code != 'OK':
logger.error(f"Login failed: {login_result.Message}")
exit()
logger.info("Login successful")
# Set business date to today
today = datetime.now().date()
logger.info(f"Setting business date to {today}...")
try:
client.service.SetBusinessDate(today)
logger.info("Business date set successfully")
except Exception as e:
logger.error(f"Error setting business date: {str(e)}")
exit()
# Clear any existing data
logger.info("Clearing existing data...")
try:
client.service.Clear()
logger.info("Data cleared successfully")
except Exception as e:
logger.error(f"Error clearing data: {str(e)}")
exit()
# Set up the screen with filter for specific InventoryID
logger.info("Setting up the screen with filter for InventoryID '123456'...")
try:
commands = client.get_type('ns0:ArrayOfCommand')(r
client.get_type('ns0:Command')(
FieldName='InventoryID',
ObjectName='Filter',
Value='123456'
)
])
result = client.service.Submit(commands)
logger.info("Screen set up successfully")
logger.info(f"Submit result: {result}")
except Exception as e:
logger.error(f"Error setting up screen: {str(e)}")
exit()
# Prepare export commands
logger.info("Preparing export commands...")
export_commands = client.get_type('ns0:ArrayOfCommand')(r
client.get_type('ns0:Command')(
FieldName='InventoryID',
ObjectName='FilteredItems'
),
client.get_type('ns0:Command')(
FieldName='InventoryCD',
ObjectName='FilteredItems'
),
client.get_type('ns0:Command')(
FieldName='CuryUnitPrice',
ObjectName='FilteredItems'
),
client.get_type('ns0:Command')(
FieldName='TotalWarehouse',
ObjectName='FilteredItems'
)
])
# Export data
logger.info("Exporting data...")
try:
export_result = client.service.Export(
commands=export_commands,
filters=None,
topCount=0,
includeHeaders=True,
breakOnError=True
)
logger.info(f"Export result: {export_result}")
except Exception as e:
logger.error(f"Error exporting data: {str(e)}")
logger.error(f"Full exception: {repr(e)}")
if hasattr(e, 'detail'):
logger.error(f"SOAP fault detail: {e.detail}")
exit()
# Logout
logger.info("Logging out...")
try:
client.service.Logout()
logger.info("Logged out successfully")
except Exception as e:
logger.error(f"Error during logout: {str(e)}")
# Process the exported data
if export_result:
logger.info(f"Processing exported data. Data type: {type(export_result)}, Length: {len(export_result)}")
try:
with open('inv_update.csv', 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
for row in export_result:
writer.writerow(row)
logger.info("Data exported successfully to inv_update.csv")
except Exception as e:
logger.error(f"Error writing to CSV: {str(e)}")
logger.error(f"Data causing the error: {export_result}")
else:
logger.warning("No data was exported")
logger.info("Script execution completed")
I’m entirely new to Acumatica so this may be a very simple mistake or misunderstanding on my part. I really appreciate any help I can get from the community.
Thanks!