QueryOptions - Nioron07/Easy-Acumatica GitHub Wiki

QueryOptions is a container class that bundles all common OData parameters into a single, easy-to-use object. It works seamlessly with the F object to handle $filter expressions and provides intelligent helpers for $custom and $expand.

To use it, import the necessary helpers:

from easy_acumatica.models.filter_builder import F  
from easy_acumatica.models.query_builder import QueryOptions, CustomField

After constructing your QueryOptions object, call the .to_params() method to get a dictionary that you can pass directly to your HTTP client.

1. Basic Usage

Here’s how to combine a filter with other parameters like $select and $top.

# Create a filter using the F object  
my_filter = (F.Category == 'Hardware') & (F.Stock < 20)

# Bundle it into QueryOptions  
opts = QueryOptions(  
    filter=my_filter,  
    select=["ItemID", "Name", "Stock"],  
    top=10  
)

# Generate the parameters for the request  
print(opts.to_params())  
# {  
#   '$filter': "((Category eq 'Hardware') and (Stock lt 20))",  
#   '$select': 'ItemID,Name,Stock',  
#   '$top': '10'  
# }

2. Expanding Related Entities ($expand)

The expand parameter lets you retrieve related entities in a single API call. You can also select fields from these expanded entities.

opts = QueryOptions(  
    filter=F.Status == 'Active',  
    expand=["Supplier", "MainContact/Address"],  
    select=["ItemID", "Supplier/SupplierName", "MainContact/Address/City"]  
)  
# params['$expand'] will be 'MainContact/Address,Supplier' (sorted alphabetically)

3. Pagination with $skip and $top

You can easily implement pagination by using skip and top together.

# Get the first page of 20 records  
page1_opts = QueryOptions(filter=my_filter, top=20, skip=0)

# Get the second page  
page2_opts = QueryOptions(filter=my_filter, top=20, skip=20)

4. Smart Custom Fields ($custom)

The custom parameter accepts a list of CustomField objects, which makes formatting safe and easy.

Key Feature: If you request a custom field from a detail entity, QueryOptions will automatically add that entity to the $expand list for you, preventing common errors.

opts = QueryOptions(  
    filter=F.Type == 'SalesOrder',  
    expand=["MainContact"], # Note: "Details" is NOT included here  
    custom=[  
        # A custom field on the top-level entity  
        CustomField.field("OrderProperties", "UsrPriority"),

        # A custom field on the "Details" entity  
        CustomField.field("Transactions", "UsrSpecialCode", entity_name="Details"),  
          
        # A user-defined attribute  
        CustomField.attribute("Document", "OPERATSYST")  
    ]  
)

# Generate the parameters  
params = opts.to_params()

# The '$custom' parameter is correctly formatted:  
# 'OrderProperties.UsrPriority,Details/Transactions.UsrSpecialCode,Document.AttributeOPERATSYST'

# And '$expand' has been automatically updated:  
# 'Details,MainContact'

5. Using Raw String Filters

If you need to use complex OData syntax not covered by the F object, you can always provide a raw string to the filter parameter.

opts_raw = QueryOptions(  
    filter="substringof('special', Description) and Price gt 100",  
    select=["Description", "Price"]  
)