Records Service
The `RecordsService` is a powerful, generic wrapper for performing CRUD (Create, Read, Update, Delete) operations on **any** top-level Acumatica entity, such as `StockItem`, `SalesOrder`, or `PurchaseOrder`. It's your go-to service when a more specialized one (like `CustomersService`) doesn't exist for your target entity.
Importing Helpers
You will need the generic `RecordBuilder` for creating and updating records, along with `QueryOptions` and `F` for filtering.
from easy_acumatica.models.filter_builder import F
from easy_acumatica.models.query_builder import QueryOptions
from easy_acumatica.models.record_builder import RecordBuilder
CRUD Methods
create_record(api_version, entity, record, ...)
Creates a new record for any specified entity. You must provide the entity name as a string and the payload using the `RecordBuilder`.
# Use RecordBuilder to construct the payload for a new Stock Item
item_payload = (
RecordBuilder()
.field("InventoryID", "NEW-ITEM-001")
.field("Description", "A Brand New Stock Item")
.field("ItemClass", "STOCKITEM")
)
# Call the service to create the record
new_item = client.records.create_record(
"24.200.001",
entity="StockItem",
record=item_payload
)
The service provides three methods for fetching records based on different criteria:
- get_records_by_filter: The most flexible method, uses a `QueryOptions` object with a `$filter` to find records.
- get_record_by_id: Retrieves a single record using its internal Acumatica GUID.
- get_record_by_key_field: Retrieves a single record using its primary key fields (e.g., Order Type and Order Number).
# Example of get_records_by_filter
low_stock_filter = (F.ItemClass.ID == 'FINISHGOOD') & (F.QtyOnHand < 10)
opts = QueryOptions(filter=low_stock_filter)
low_stock_items = client.records.get_records_by_filter(
"24.200.001",
entity="StockItem",
options=opts
)
# Example of get_record_by_id
order = client.records.get_record_by_id(
"24.200.001", "SalesOrder", "a1b2c3d4-e5f6-..."
)
update_record(api_version, entity, record, options)
Updates one or more existing records. You must provide a filter in the `options` to specify which record(s) to update.
# Specify which record to update using a filter
update_opts = QueryOptions(filter=(F.InventoryID == 'NEW-ITEM-001'))
# Define the fields to change
update_payload = RecordBuilder().field("Description", "An Updated Item Description")
# Perform the update
updated_item = client.records.update_record(
"24.200.001",
entity="StockItem",
record=update_payload,
options=update_opts
)
The service offers two ways to permanently delete records:
- delete_record_by_id: Deletes a record using its internal GUID.
- delete_record_by_key_field: Deletes a record using its primary key(s).
# Delete by primary key fields
client.records.delete_record_by_key_field(
"24.200.001",
entity="SalesOrder",
key="SO",
value="SO006724"
)
# Delete by internal GUID
client.records.delete_record_by_id(
"24.200.001",
entity="SalesOrder",
record_id="a1b2c3d4-e5f6-a7b8-c9d0-e1f2a3b4c5d6"
)
Utility Methods
get_custom_field_schema(api_version, entity)
A powerful introspection tool that retrieves the schema for all custom and user-defined fields associated with an entity. This is useful for dynamically building integrations.
# Get the custom field schema for the StockItem entity
schema = client.records.get_custom_field_schema(
"24.200.001",
entity="StockItem"
)
# The 'schema' variable now holds a dictionary detailing all custom fields
print(schema)
request_report(...)
Initiates a report request and polls until the report is ready. This method follows Acumatica's asynchronous report generation flow and returns the final report content as a `requests.Response` object.
# Define the report parameters
report_params = {
"FromDate": { "value": "2023-01-01" },
"ToDate": { "value": "2023-01-31" }
}
# Request the report and wait for it to generate
response = client.records.request_report(
report_entity="CashAccountSummary",
endpoint_name="Report",
endpoint_version="0001",
parameters=report_params,
output_format="PDF"
)
# Save the report content to a file
with open("cash_summary.pdf", "wb") as f:
f.write(response.content)