SAP¶
The SAP class talks to SAP S/4HANA via OData REST APIs and remote function calls (RFC).
OData needs no extra packages. Optional features need these extras:
pip install "pyxecm[sap]" # RFC calls via PyRFC (also needs the SAP NW RFC SDK)
pip install "pyxecm[saml]" # principal propagation - see SAP Authentication / SSO
See SAP Authentication / SSO for calling SAP as the individual user and SAP APIs that must be activated for the required OData services.
Look up a workspace's SAP business object¶
Use SAP.get_business_object(bo_type, bo_id) to retrieve the SAP object referenced
by a workspace payload's business object connection:
connection = workspace["business_objects"][0] # A connection to the SAP system
sap_object = sap.get_business_object(
bo_type=connection["bo_type"],
bo_id=connection["bo_id"],
)
if sap_object is not None:
print("The SAP object exists:", sap_object)
The method uses match / case to call the corresponding OData getter and returns
its typed response model unchanged, including its default expanded related data.
It supports the BOR types in SAP_BUSINESS_OBJECT_TYPES in sap_models.py.
IDs use SAP's internal format (leading zeros and concatenated composite keys);
single-field IDs also accept the external format. For example, BUS2017 with
49000001232026 looks up material document 4900000123 in year 2026.
None means the lookup did not succeed, not necessarily that the object is
absent: unsupported types, malformed IDs, authorization errors, and connectivity
failures also return None. Inspect sap.last_error or use
pyxecm.capture_errors() to distinguish failures. This method does not change
workspace payload processing automatically.
sap
¶
SAP Module to talk to SAP S/4HANA via Remote Function Calls (RFC) and OData REST APIs.
The module supports two integration channels:
- RFC (via PyRFC) - see call(). PyRFC is no longer maintained by SAP and requires the proprietary SAP NW RFC SDK. Use it only for existing RFC / BAPI use cases.
- OData (via HTTPS) - see do_request(). This is the future-proof channel based on SAP's released APIs (SAP Business Accelerator Hub: https://api.sap.com). It requires the 'base_url' parameter of the SAP class.
OData specifics handled by this module: * Basic authentication with the SAP user and password (or a custom requests auth object, e.g. a per-user bearer token - see the 'auth' parameter of the SAP class). * Principal propagation (calls under the identity of the individual user): pyxecm acts as a minimal SAML 2.0 identity provider (get_saml_assertion()) and exchanges the assertion for an SAP OAuth 2.0 access token (get_oauth_access_token(), RFC 7522). See docs/pyxecm-customizer/sap-authentication.md for the SAP configuration. * The readable error of the last failed request is available via 'last_error'. * The SAP client ("Mandant") and the logon language are passed as query parameters ('sap-client' and 'sap-language') with every request. * Modifying requests (POST, PUT, PATCH, MERGE, DELETE) get a CSRF token that is fetched and renewed automatically. It is bound to the SAP session cookies, so each thread uses its own requests.Session.
OData services must be activated in S/4HANA (verify with check_odata_apis()):
1. /IWFND/MAINT_SERVICE: "Add Service" -> backend system alias (e.g. LOCAL),
technical service name (e.g. API_MAINTENANCEORDER) -> "Get Services" ->
select the versions (0001, 0002) -> "Add Selected Services".
2. SICF: the ICF node /sap/opu/odata/sap/
OData services used by this module (see SAP_ODATA_SERVICES) - they have to be activated (OData V2) or published (OData V4) in the SAP Gateway of the S/4HANA system before the corresponding methods can be used. check_odata_apis() checks all of them.
OData V2 - activate in /IWFND/MAINT_SERVICE ("Add Service", see above): * Plant Maintenance: API_MAINTENANCEORDER (version 0002), API_MAINTNOTIFICATION, API_MAINTORDERCONFIRMATION, API_MAINTENANCEPLAN * Sales: API_SALES_ORDER_SRV, API_SALES_CONTRACT_SRV * Purchasing: API_PURCHASECONTRACT_PROCESS_SRV * Inventory Management: API_MATERIAL_DOCUMENT_SRV, API_MATERIAL_STOCK_SRV * Production: API_PRODUCTION_ORDER_2_SRV * Master data: API_PRODUCT_SRV, API_STORAGELOCATION_SRV, API_WORK_CENTERS, API_EQUIPMENT, API_FUNCTIONALLOCATION, API_BUSINESS_PARTNER, API_COMPANYCODE_SRV, API_SALESORGANIZATION_SRV, API_COSTCENTER_SRV, API_PROFITCENTER_SRV, API_GLACCOUNTINCHARTOFACCOUNTS_SRV
OData V4 - publish the service group in /IWFND/V4_ADMIN ("Publish Service Groups"),
the ICF node /sap/opu/odata4 must be active and S_SERVICE is granted per service group
(role menu entry "TADIR Service" R3TR G4BA
SAP documentation of the OData APIs used by this module:
* SAP Business Accelerator Hub - API_MAINTENANCEORDER (properties, EDMX):
https://api.sap.com/api/API_MAINTENANCEORDER/overview
* SAP Help - Maintenance Order (deprecated in S/4HANA Cloud 2308):
https://help.sap.com/docs/SAP_S4HANA_CLOUD/f9ba73d1b8c543c2bd2ba1666271af86/d3f02cfccf00407ab9776ea2ec2030d3.html
* SAP Help - Maintenance Order (Version 2), the successor (OData V2, ;v=0002):
https://help.sap.com/docs/SAP_S4HANA_CLOUD/f9ba73d1b8c543c2bd2ba1666271af86/c1457e0e539740a29932fbdcf36fea3c.html
* SAP Help - Create Maintenance Order Operation:
https://help.sap.com/docs/SAP_S4HANA_CLOUD/f9ba73d1b8c543c2bd2ba1666271af86/7dbab77fa358454caa4289bc057cf66d.html
* SAP Help - Maintenance Order API (S/4HANA on-premise):
https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/9a02a02d849d4b38a7320d94a71d2a22/f3521b71f69b4cbf81ab21a7c2c01527.html
* Metadata of a system:
For documentation of PyRFC see here: https://github.com/SAP/PyRFC and here: https://sap.github.io/PyRFC/pyrfc.html
RFC typically uses port 3300 to communicate with the SAP server. Make sure this port is not blocked by your firewall.
Connection Parameter: * ashost (hostname or IP address of the application server - this should NOT be a full URL!) * sysnr (the backend's system number, e.g. 00) * client (the client or "Mandant" to which to logon, e.g. 100) * user (e.g. "nwheeler") * passwd (password of the user) * lang (logon language as two-character ISO-Code, e.g. EN) * trace (one of 0(off), 1(brief), 2(verbose), 3(detailed), 4(full)) * use_tls (activates SSL/TLS encryption. Set to 0 or 1. By default TLS is turned on (1)) * tls_client_pse (Specifies the PSE file containing the necessary certificates for TLS communication. A PSE file is a SAP proprietary certificate store, similar to a p12 file, containing the private key and the certificate chain to be used in the TLS handshake with the server, beginning with the server's public certificate and ending with the root CA certificate. It should also contain the client certificate used for login at the server, if your client program does not use basic user & password authentication)
Classes:
| Name | Description |
|---|---|
SAPODataItemSet |
The items of an SAP document (e.g. the items of a sales order) - how to read them for an update. |
SAPODataIterator |
Iterator over the entities of an SAP OData collection (e.g. maintenance orders). |
BearerAuth |
Authenticate OData requests with an SAP OAuth 2.0 access token ("Authorization: Bearer"). |
SAPError |
An error recorded by the SAP module (SAP class) for pyxecm.capture_errors(). |
SAP |
Implement Remote Function Calls (RFC) and OData REST API calls to SAP S/4HANA. |
Functions:
| Name | Description |
|---|---|
get_oauth_scope |
Build the scope parameter of the OAuth token request from SAP_ODATA_SERVICES. |
parse_bearer_error |
Parse the OAuth error of an SAP response from its WWW-Authenticate header (RFC 6750). |
SAPODataItemSet
dataclass
¶
SAPODataItemSet(
collection_path: str,
entity_set: str,
key_properties: tuple[str, ...],
number_property: str,
text_property: str | None = None,
params: dict | None = None,
version_property: str | None = None,
label: str = "item",
)
The items of an SAP document (e.g. the items of a sales order) - how to read them for an update.
See SAP._update_odata_document(). The items are read with a GET of the collection path. The entity path of an item is taken from its __metadata.uri (OData V2) or built from the key properties (OData V4) - so internal keys (e.g. of production order operations) work as well.
SAPODataIterator
¶
Bases: Iterator[T]
Iterator over the entities of an SAP OData collection (e.g. maintenance orders).
The entities are read page by page while iterating - only one page is held in memory at a time, so even very large collections can be processed. Errors are logged and end the iteration; afterwards the attribute 'failed' tells whether the iteration ended because of an error (True) or because all entities have been read (False).
Example
orders = sap.iter_maintenance_orders(query=SAPMaintenanceOrderQueryModel(planning_plant="3000")) for order in orders: ... print(order.order_id, order.description) if orders.failed: ... print("Not all orders could be read!")
Initialize the iterator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entities
|
Iterator[T]
|
The underlying generator that reads the entities page by page. |
required |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
BearerAuth
¶
Bases: AuthBase
Authenticate OData requests with an SAP OAuth 2.0 access token ("Authorization: Bearer").
Used for principal propagation: pass it as the 'auth' parameter of an SAP object, so that all OData calls of this object run as the user the token was issued for.
Example
token = idp_sap.get_oauth_access_token_for_user(user_id="jane.smith@example.com", ...) user_sap = SAP(username="", password="", system_id="S4H", base_url=..., auth=BearerAuth(token["access_token"], token["scope"]))
The token is not renewed - create a new SAP object (with a new token) before it expires ('expires_in' of the token response). Each user needs an SAP object of their own, as SAP binds its session cookies and CSRF tokens to the user.
Initialize the authentication with an SAP access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
access_token
|
str
|
The "access_token" of a token response of get_oauth_access_token(). |
required |
scope
|
str | None
|
The "scope" of the token response - the space-separated scopes SAP granted (the requested scopes the OAuth client and the user are authorized for). Defaults to None (unknown). |
None
|
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
SAPError
dataclass
¶
SAPError(
message: str,
category: ErrorCategory = UNKNOWN,
severity: ErrorSeverity = ERROR,
status_code: int | None = None,
server_message: str | None = None,
method: str | None = None,
url: str | None = None,
timestamp: datetime = (lambda: now(UTC))(),
)
SAP
¶
SAP(
username: str,
password: str,
system_id: str,
ashost: str = "",
mshost: str = "",
msport: str = "3601",
group: str = "PUBLIC",
destination: str = "",
client: str = "100",
system_number: str = "00",
lang: str = "EN",
trace: str = "3",
base_url: str = "",
verify_ssl: bool = True,
auth: AuthBase | None = None,
saml_idp_private_key: str | None = None,
saml_idp_certificate: str | None = None,
saml_issuer: str = "",
saml_audience: str = "",
logger: Logger = default_logger,
)
Implement Remote Function Calls (RFC) and OData REST API calls to SAP S/4HANA.
Initialize the SAP object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
username
|
str
|
The SAP user name (used for RFC and OData). |
required |
password
|
str
|
The password of the SAP user (used for RFC and OData). |
required |
system_id
|
str
|
The SAP system ID (RFC only). |
required |
ashost
|
str
|
Hostname of the application server for direct application server logon (RFC only). |
''
|
mshost
|
str
|
Hostname of the message server for logon with load balancing (RFC only). |
''
|
msport
|
str
|
Port of the message server (RFC only). Defaults to "3601". |
'3601'
|
group
|
str
|
Logon group for logon with load balancing (RFC only). Defaults to "PUBLIC". |
'PUBLIC'
|
destination
|
str
|
RFC destination (RFC only). |
''
|
client
|
str
|
The SAP client ("Mandant"), used for RFC and OData. Defaults to "100". |
'100'
|
system_number
|
str
|
The SAP system number (RFC only). Defaults to "00". |
'00'
|
lang
|
str
|
The logon language (used for RFC and OData). Defaults to "EN". |
'EN'
|
trace
|
str
|
The RFC trace level (RFC only). Defaults to "3". |
'3'
|
base_url
|
str
|
Base URL of the SAP system for OData REST API calls, e.g. "https://s4.example.com:44300". Required to use the OData methods like do_request(), check_odata_apis() or create_maintenance_order(). |
''
|
verify_ssl
|
bool
|
Whether to verify the TLS certificate of the SAP system for OData calls. Disable only for test systems with self-signed certificates. Defaults to True. |
True
|
auth
|
AuthBase | None
|
Authentication for OData calls that replaces the basic authentication with username and password, e.g. a bearer token of the individual user obtained via principal propagation (OAuth 2.0 SAML bearer assertion). RFC calls are not affected. Defaults to None (basic authentication). |
None
|
saml_idp_private_key
|
str | None
|
PEM-encoded, unencrypted RSA private key (at least 2048 bits) of pyxecm's SAML 2.0 identity provider. It signs the assertions of get_saml_assertion() for principal propagation into SAP (SAML 2.0 Bearer Assertion grant, RFC 7522). Whoever holds this key can obtain an SAP access token for every SAP user the SAP-side NameID mapping reaches - keep it in a secret store. The key pair is created once per deployment (see docs/pyxecm-customizer/sap-authentication.md), it is not generated by pyxecm. The key, the certificate, saml_issuer and saml_audience are validated here; if anything is wrong an error is logged and get_saml_assertion() refuses to mint assertions. Requires the 'saml' extra of pyxecm. Defaults to None (principal propagation disabled). |
None
|
saml_idp_certificate
|
str | None
|
PEM-encoded X.509 certificate of saml_idp_private_key. The SAP administrator imports it as the signing certificate of the trusted identity provider in transaction SAML2. It is also embedded in the assertion's signature (ds:KeyInfo). Recommended - it is checked against the private key at startup and its expiry date also before each assertion. Defaults to None (no embedded certificate). |
None
|
saml_issuer
|
str
|
The |
''
|
saml_audience
|
str
|
The |
''
|
logger
|
Logger
|
The logging object to use for all log messages. Defaults to default_logger. |
default_logger
|
Methods:
| Name | Description |
|---|---|
call |
Do an RFC Call. |
request_session |
Return the calling thread's requests.Session for OData calls, creating it on first use. |
log_error |
Log an error and keep it as the error of the calling thread's last method call (see last_error). |
oauth_token_url |
Return the URL of SAP's OAuth 2.0 token endpoint, including the SAP client. |
get_saml_assertion |
Mint and sign a SAML 2.0 bearer assertion for a user (pyxecm as SAML 2.0 identity provider). |
get_oauth_access_token |
Exchange a SAML 2.0 bearer assertion of a user for an SAP OAuth 2.0 access token. |
get_oauth_access_token_for_user |
Get an SAP OAuth 2.0 access token for a user via principal propagation, in one call. |
service_url |
Return the full URL of the root of an OData service. |
csrf_token |
Get a CSRF token for modifying OData requests to the service the URL belongs to. |
parse_request_response |
Convert the text of a response object to a Python dict safely. |
do_request |
Call an SAP OData REST API in a safe way. |
check_odata_apis |
Check if the required OData APIs are activated and usable in the S/4HANA system. |
check_oauth_token_endpoint |
Check if SAP's OAuth 2.0 token endpoint is activated and reachable. |
check_principal_propagation |
Check the full SAML 2.0 bearer assertion / OAuth 2.0 principal propagation round trip. |
get_odata_entity_type |
Return the entity type of an entity set as defined in the $metadata of the service. |
create_maintenance_order |
Create an SAP Plant Maintenance order (including its operations and their components). |
expand_maintenance_order_task_list |
Take over the operations and materials of the task list referenced by a new maintenance order. |
create_maintenance_order_component |
Create a component (material) for an operation of an existing SAP maintenance order. |
iter_maintenance_orders |
Iterate over SAP maintenance orders - reading them page by page from SAP. |
get_business_object |
Get an SAP object by the business object reference used by an Extended ECM workspace. |
get_maintenance_orders |
Get SAP maintenance orders as a list. |
get_maintenance_order |
Get a single SAP Plant Maintenance order by its order number. |
update_maintenance_order |
Update individual fields of an SAP maintenance order. |
change_maintenance_order_status |
Change the status of an SAP maintenance order (e.g. release, technically complete or close). |
get_maintenance_order_deletion_steps |
Return the status actions needed to delete an SAP maintenance order (see delete_maintenance_order()). |
delete_maintenance_order |
Delete an SAP maintenance order by setting its deletion flag (status DLFL). |
create_maintenance_order_operation |
Add an operation (work step) to an existing SAP maintenance order. |
update_maintenance_order_operation |
Update individual fields of an operation of an SAP maintenance order. |
delete_maintenance_order_operation |
Delete an operation of an SAP maintenance order. |
change_maintenance_order_operation_status |
Change the status of an operation of an SAP maintenance order (e.g. dispatch it). |
create_purchase_order |
Create an SAP purchase order including its items, schedule lines and account assignments. |
iter_purchase_orders |
Iterate over SAP purchase orders - reading them page by page from SAP. |
get_purchase_orders |
Get SAP purchase orders as a list. |
get_purchase_order |
Get a single SAP purchase order by its number. |
update_purchase_order |
Update individual fields of an SAP purchase order and of its items. |
delete_purchase_order |
Delete an SAP purchase order. |
create_maintenance_notification |
Create an SAP maintenance notification (including its items). |
iter_maintenance_notifications |
Iterate over SAP maintenance notifications - reading them page by page from SAP. |
get_maintenance_notifications |
Get SAP maintenance notifications as a list. |
get_maintenance_notification |
Get a single SAP maintenance notification by its number. |
update_maintenance_notification |
Update individual fields of an SAP maintenance notification and of its items. |
change_maintenance_notification_status |
Change the status of an SAP maintenance notification (e.g. complete or set in process). |
create_sales_order |
Create an SAP sales order (including its items). |
iter_sales_orders |
Iterate over SAP sales orders - reading them page by page from SAP. |
get_sales_orders |
Get SAP sales orders as a list. |
get_sales_order |
Get a single SAP sales order by its number. |
update_sales_order |
Update individual fields of an SAP sales order and of its items. |
delete_sales_order |
Delete an SAP sales order. |
create_sales_contract |
Create an SAP sales contract (including its items). |
iter_sales_contracts |
Iterate over SAP sales contracts - reading them page by page from SAP. |
get_sales_contracts |
Get SAP sales contracts as a list. |
get_sales_contract |
Get a single SAP sales contract by its number. |
update_sales_contract |
Update individual fields of an SAP sales contract and of its items. |
delete_sales_contract |
Delete an SAP sales contract. |
create_purchase_contract |
Create an SAP purchase contract (including its items). |
iter_purchase_contracts |
Iterate over SAP purchase contracts - reading them page by page from SAP. |
get_purchase_contracts |
Get SAP purchase contracts as a list. |
get_purchase_contract |
Get a single SAP purchase contract by its number. |
update_purchase_contract |
Update individual fields of an SAP purchase contract and of its items. |
update_purchase_contract_item |
Update individual fields of an item of an SAP purchase contract. |
delete_purchase_contract |
Delete an SAP purchase contract or some of its items (set their deletion indicator). |
create_purchase_requisition |
Create an SAP purchase requisition including its items (and their account assignments). |
iter_purchase_requisitions |
Iterate over SAP purchase requisitions - reading them page by page from SAP. |
get_purchase_requisitions |
Get SAP purchase requisitions as a list. |
get_purchase_requisition |
Get a single SAP purchase requisition by its number. |
update_purchase_requisition |
Update individual fields of an SAP purchase requisition and of its items. |
create_credit_memo_request |
Create an SAP credit memo request (including its items). |
iter_credit_memo_requests |
Iterate over SAP credit memo requests - reading them page by page from SAP. |
get_credit_memo_requests |
Get SAP credit memo requests as a list. |
get_credit_memo_request |
Get a single SAP credit memo request. |
update_credit_memo_request |
Update individual fields of an SAP credit memo request and of its items. |
delete_credit_memo_request |
Delete an SAP credit memo request. |
change_credit_memo_request_status |
Approve (release) or reject an SAP credit memo request that is in approval. |
create_debit_memo_request |
Create an SAP debit memo request (including its items). |
iter_debit_memo_requests |
Iterate over SAP debit memo requests - reading them page by page from SAP. |
get_debit_memo_requests |
Get SAP debit memo requests as a list. |
get_debit_memo_request |
Get a single SAP debit memo request. |
update_debit_memo_request |
Update individual fields of an SAP debit memo request and of its items. |
delete_debit_memo_request |
Delete an SAP debit memo request. |
iter_billing_document_requests |
Iterate over SAP billing document requests - reading them page by page from SAP. |
get_billing_document_requests |
Get SAP billing document requests as a list. |
get_billing_document_request |
Get a single SAP billing document request. |
delete_billing_document_request |
Delete an SAP billing document request (that has not been billed yet). |
reject_billing_document_request |
Reject an SAP billing document request - it will not be billed. |
iter_billing_documents |
Iterate over SAP billing documents (customer invoices, credit / debit memos) - reading them page by page. |
iter_billing_document_items |
Iterate over SAP billing document items - reading them page by page. |
get_billing_documents |
Get SAP billing documents (customer invoices, credit / debit memos) as a list. |
get_billing_document |
Get a single SAP billing document (customer invoice, credit / debit memo). |
cancel_billing_document |
Cancel an SAP billing document - SAP creates a cancellation billing document. |
get_billing_document_pdf |
Get the PDF (print form) of an SAP billing document - e.g. the invoice as sent to the customer. |
create_outbound_delivery |
Create an SAP outbound delivery for sales order items. |
iter_outbound_deliveries |
Iterate over SAP outbound deliveries - reading them page by page from SAP. |
iter_outbound_delivery_items |
Iterate over SAP outbound delivery items - reading them page by page. |
get_outbound_deliveries |
Get SAP outbound deliveries as a list. |
get_outbound_delivery |
Get a single SAP outbound delivery. |
update_outbound_delivery |
Update individual fields of an SAP outbound delivery and of its items. |
delete_outbound_delivery |
Delete an SAP outbound delivery (only possible before the goods issue). |
change_outbound_delivery_status |
Change the status of an SAP outbound delivery (e.g. pick all items or post the goods issue). |
create_inbound_delivery |
Create an SAP inbound delivery for purchase order items. |
iter_inbound_deliveries |
Iterate over SAP inbound deliveries - reading them page by page from SAP. |
iter_inbound_delivery_items |
Iterate over SAP inbound delivery items - reading them page by page. |
get_inbound_deliveries |
Get SAP inbound deliveries as a list. |
get_inbound_delivery |
Get a single SAP inbound delivery. |
update_inbound_delivery |
Update individual fields of an SAP inbound delivery and of its items. |
delete_inbound_delivery |
Delete an SAP inbound delivery (only possible before the goods receipt). |
change_inbound_delivery_status |
Change the status of an SAP inbound delivery (e.g. put away all items or post the goods receipt). |
create_supplier_invoice |
Create (post or park) an SAP supplier invoice including its items. |
iter_supplier_invoices |
Iterate over SAP supplier invoices - reading them page by page from SAP. |
get_supplier_invoices |
Get SAP supplier invoices as a list. |
get_supplier_invoice |
Get a single SAP supplier invoice. |
delete_supplier_invoice |
Delete an SAP supplier invoice - only parked or held invoices; posted ones are cancelled instead. |
cancel_supplier_invoice |
Cancel (reverse) a posted SAP supplier invoice - SAP posts a reversal document. |
release_supplier_invoice |
Release an SAP supplier invoice that is blocked for payment. |
post_supplier_invoice |
Post a parked SAP supplier invoice (see SAPSupplierInvoiceModel.status). |
create_goods_movement |
Post an SAP goods movement (material document with its items) - e.g. a goods receipt for a purchase order. |
iter_goods_movements |
Iterate over SAP goods movements - reading them page by page from SAP. |
iter_goods_movement_items |
Iterate over SAP material document items - reading them page by page. |
get_goods_movement_items |
Get SAP material document items as a list. |
get_goods_movements |
Get SAP goods movements as a list. |
get_goods_movement |
Get a single SAP material document (goods movement). |
cancel_goods_movement |
Cancel (reverse) an SAP material document or a single item of it. |
iter_material_stock |
Iterate over the SAP material stock - reading it page by page from SAP. |
get_material_stock |
Get the SAP material stock as a list of stock segments. |
create_maintenance_order_confirmation |
Confirm work (time, final confirmation) on an SAP maintenance order operation. |
iter_maintenance_order_confirmations |
Iterate over SAP maintenance order confirmations - reading them page by page from SAP. |
get_maintenance_order_confirmations |
Get SAP maintenance order confirmations as a list. |
get_maintenance_order_confirmation |
Get a single SAP maintenance order confirmation. |
cancel_maintenance_order_confirmation |
Cancel an SAP maintenance order confirmation. |
create_maintenance_plan |
Create an SAP maintenance plan with its cycles and maintenance items (scheduling is started separately). |
iter_maintenance_plans |
Iterate over SAP maintenance plans - reading them page by page from SAP. |
iter_maintenance_plan_items |
Iterate over SAP maintenance items (of maintenance plans) - reading them page by page. |
get_maintenance_plans |
Get SAP maintenance plans as a list. |
get_maintenance_plan |
Get a single SAP maintenance plan. |
update_maintenance_plan |
Update individual fields of an SAP maintenance plan and of its items. |
change_maintenance_plan_status |
Change the status of an SAP maintenance plan (e.g. start scheduling, activate or deactivate). |
create_task_list |
Create an SAP maintenance task list including its operations. |
iter_task_lists |
Iterate over SAP maintenance task lists - reading them page by page from SAP. |
get_task_lists |
Get SAP maintenance task lists as a list. |
get_task_list |
Get a single SAP maintenance task list. |
update_task_list |
Update individual fields of an SAP maintenance task list (its latest version) and of its operations. |
create_planned_order |
Create an SAP planned order (components and capacities are determined by SAP). |
iter_planned_orders |
Iterate over SAP planned orders - reading them page by page from SAP. |
get_planned_orders |
Get SAP planned orders as a list. |
get_planned_order |
Get a single SAP planned order. |
update_planned_order |
Update individual fields of an SAP planned order and of its components. |
delete_planned_order |
Delete an SAP planned order. |
schedule_planned_order |
Schedule an SAP planned order (determine its dates based on the routing / capacities). |
create_production_order |
Create an SAP production order - optionally released right away. |
convert_planned_order |
Convert an SAP planned order into a production order - optionally released right away. |
create_production_order_from_planned_order |
Create a production order via a planned order: create the planned order, convert and release it. |
iter_production_orders |
Iterate over SAP production orders - reading them page by page from SAP. |
get_production_orders |
Get SAP production orders as a list. |
get_production_order |
Get a single SAP production order. |
update_production_order |
Update individual fields of an SAP production order and of its operations. |
change_production_order_status |
Change the status of an SAP production order (e.g. release, technically complete or close). |
iter_plants |
Iterate over SAP plants - reading them page by page from SAP. |
get_plants |
Get SAP plants as a list. |
get_plant |
Get a single SAP plant (master data). |
iter_storage_locations |
Iterate over SAP storage locations - reading them page by page from SAP. |
get_storage_locations |
Get SAP storage locations as a list. |
get_storage_location |
Get a single SAP storage location (master data). |
create_product |
Create an SAP product / material with its descriptions and plant data. |
iter_products |
Iterate over SAP products - reading them page by page from SAP. |
get_products |
Get SAP products as a list. |
get_product |
Get a single SAP product (master data). |
update_product |
Update individual fields of an SAP product (material) on client level. |
update_product_description |
Change the description of an SAP product (material) in one language. |
update_product_plant |
Update individual fields of the plant data of an SAP product (material). |
create_product_plant |
Extend an existing SAP product (material) to a plant - with its storage locations in the plant. |
create_product_storage_location |
Extend an SAP product (material) that is already extended to the plant to a storage location. |
create_product_valuation |
Create the valuation data of an SAP product (material) in a valuation area (plant). |
delete_product |
Delete an SAP product (material) by setting its deletion flag (can be reset in SAP). |
undelete_product |
Remove the deletion flag of an SAP product (material) - the reverse of delete_product(). |
create_material_bom |
Create a material BOM (bill of material) of a product in a plant with its items. |
iter_material_boms |
Iterate over material BOMs - reading them page by page from SAP. |
get_material_boms |
Get material BOMs as a list - e.g. the spare parts list (usage "4") of a product. |
update_material_bom |
Update individual fields of a material BOM (header) and of its items. |
iter_production_versions |
Iterate over SAP production versions - reading them page by page from SAP. |
get_production_versions |
Get SAP production versions as a list. |
get_production_version |
Get a single SAP production version (master data). |
iter_work_centers |
Iterate over SAP work centers - reading them page by page from SAP. |
get_work_centers |
Get SAP work centers as a list. |
get_work_center |
Get a single SAP work center (master data). |
create_equipment |
Create an SAP equipment (master data). |
iter_equipments |
Iterate over SAP equipments - reading them page by page from SAP. |
get_equipments |
Get SAP equipments as a list. |
get_equipment |
Get a single SAP equipment (master data). |
update_equipment |
Update individual fields of an SAP equipment. |
delete_equipment |
Delete an SAP equipment by setting its deletion flag (can be reset in SAP). |
undelete_equipment |
Remove the deletion flag of an SAP equipment - the reverse of delete_equipment(). |
create_functional_location |
Create an SAP functional location (master data). |
iter_functional_locations |
Iterate over SAP functional locations - reading them page by page from SAP. |
get_functional_locations |
Get SAP functional locations as a list. |
get_functional_location |
Get a single SAP functional location (master data). |
update_functional_location |
Update individual fields of an SAP functional location. |
delete_functional_location |
Delete an SAP functional location by setting its deletion flag (can be reset in SAP). |
undelete_functional_location |
Remove the deletion flag of an SAP functional location - the reverse of delete_functional_location(). |
create_business_partner |
Create an SAP business partner (organization) with its addresses, roles and supplier / customer data. |
iter_business_partners |
Iterate over SAP business partners - reading them page by page from SAP. |
get_business_partners |
Get SAP business partners as a list. |
get_business_partner |
Get a single SAP business partner (master data). |
iter_customers |
Iterate over SAP customers - reading them page by page from SAP. |
get_customers |
Get SAP customers as a list. |
get_customer |
Get the business partner of a customer number (master data). |
iter_suppliers |
Iterate over SAP suppliers - reading them page by page from SAP. |
get_suppliers |
Get SAP suppliers as a list. |
get_supplier |
Get the business partner of a supplier number (master data). |
iter_company_codes |
Iterate over SAP company codes - reading them page by page from SAP. |
get_company_codes |
Get SAP company codes as a list. |
get_company_code |
Get a single SAP company code (master data). |
iter_sales_organizations |
Iterate over SAP sales organizations - reading them page by page from SAP. |
get_sales_organizations |
Get SAP sales organizations as a list. |
get_sales_organization |
Get a single SAP sales organization (master data). |
iter_purchasing_organizations |
Iterate over SAP purchasing organizations - reading them page by page from SAP. |
get_purchasing_organizations |
Get SAP purchasing organizations as a list. |
get_purchasing_organization |
Get a single SAP purchasing organization (master data). |
iter_cost_centers |
Iterate over SAP cost centers - reading them page by page from SAP. |
get_cost_centers |
Get SAP cost centers as a list. |
get_cost_center |
Get a single SAP cost center (master data). |
iter_profit_centers |
Iterate over SAP profit centers - reading them page by page from SAP. |
get_profit_centers |
Get SAP profit centers as a list. |
get_profit_center |
Get a single SAP profit center (master data). |
iter_gl_accounts |
Iterate over SAP G/L accounts - reading them page by page from SAP. |
get_gl_accounts |
Get SAP G/L accounts as a list. |
get_gl_account |
Get a single SAP G/L account (master data). |
Attributes:
| Name | Type | Description |
|---|---|---|
last_error |
str | None
|
Return the error of the calling thread's last failed OData request. |
granted_scopes |
set[str] | None
|
Return the OAuth scopes the access token of this SAP object was granted. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 | |
last_error
property
¶
Return the error of the calling thread's last failed OData request.
The error is reset with each new request (do_request()), so it describes why the last method call (e.g. create_maintenance_order()) returned None or False. Useful to show SAP's own error message to users (or LLMs).
Returns:
| Type | Description |
|---|---|
str | None
|
str | None: The readable error (SAP message code, text and details) or None if the last request did not fail. |
granted_scopes
property
¶
Return the OAuth scopes the access token of this SAP object was granted.
Returns:
| Type | Description |
|---|---|
set[str] | None
|
set[str] | None: The scopes (see BearerAuth) or None if the object does not use an access token or the scopes are unknown. |
call
¶
Do an RFC Call.
See http://sap.github.io/PyRFC/pyrfc.html#pyrfc.Connection.call
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rfc_name
|
str
|
This is the name of the RFC (typical in capital letters), e.g. SM02_ADD_MESSAGE. |
required |
options
|
dict
|
The call options for the RFC call. Potential options (keys): * not_requested: Allows to deactivate certain parameters in the function module interface. This is particularly useful for BAPIs which have many large tables, the Python client is not interested in. Deactivate those, to reduce network traffic and memory consumption in your application considerably. This functionality can be used for input and output parameters. If the parameter is an input, no data for that parameter will be sent to the backend. If it's an output, the backend will be informed not to return data for that parameter. * timeout: Cancel RFC connection if ongoing RFC call not completed within timeout seconds. Timeout can be also set as client connection configuration option, in which case is valid for all RFC calls. |
required |
rfc_parameters
|
dict
|
The actual RFC parameters that are specific for the type of the call. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: Result of the RFC call or None if the call fails or times out. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
request_session
¶
Return the calling thread's requests.Session for OData calls, creating it on first use.
The session is pre-configured with authentication (basic or the auth object passed to the constructor), TLS verification, default JSON headers and the SAP client / language query parameters. In contrast to the OTCS class, the session keeps cookies: SAP binds the CSRF token to the session cookies, so they must be sent with every modifying request.
Returns:
| Type | Description |
|---|---|
Session
|
requests.Session: A Session bound to the current thread. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
log_error
¶
Log an error and keep it as the error of the calling thread's last method call (see last_error).
do_request() sets last_error for failed requests. Methods that fail without a failed request (e.g. invalid input data, an unexpected response) must use this method - otherwise last_error would still show the error of an earlier call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
The error message with %-style placeholders (like for logger.error()). |
required |
*args
|
object
|
The values for the placeholders. |
()
|
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
oauth_token_url
¶
Return the URL of SAP's OAuth 2.0 token endpoint, including the SAP client.
SAP checks that the Recipient of a SAML bearer assertion is exactly the URL the token request is sent to - including the sap-client query parameter. Both get_saml_assertion() and get_oauth_access_token() therefore use this URL.
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
The token endpoint URL, e.g. "https://s4.example.com:44300/sap/bc/sec/oauth2/token?sap-client=100". |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_saml_assertion
¶
get_saml_assertion(
user_id: str,
nameid_format: str = SAML_NAMEID_FORMAT_UNSPECIFIED,
recipient: str | None = None,
audience: str | None = None,
validity_seconds: int = SAML_DEFAULT_VALIDITY_SECONDS,
) -> str | None
Mint and sign a SAML 2.0 bearer assertion for a user (pyxecm as SAML 2.0 identity provider).
SAP's OAuth 2.0 server issues an access token for a user if it gets a SAML 2.0 assertion for this user that is signed by a trusted identity provider (SAML 2.0 Bearer Assertion grant, RFC 7522 - see get_oauth_access_token()). Neither OTDS (a SAML service provider only) nor SAP can issue such an assertion for an arbitrary user, so pyxecm acts as a minimal identity provider: this method builds the assertion and signs it with saml_idp_private_key (see the SAP class constructor).
The assertion follows SAML 2.0 Core and the requirements of RFC 7522, section 3:
*
Security: the assertion grants SAP access as user_id. Only pass user IDs of users the calling application has authenticated (e.g. the user of a verified OTDS session) - never an unverified user ID from a request. Each minted assertion is logged with its ID, which also appears in SAP's SAML 2.0 trace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
The user to propagate - the assertion's NameID. SAP maps it to an SAP user as configured for the trusted identity provider in transaction SAML2 (e.g. via the SAP user ID, e-mail address or an alias, see nameid_format). |
required |
nameid_format
|
str
|
The NameID format - it must match the format configured in transaction SAML2 ("Identity Federation" tab), e.g. "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" for e-mail addresses. Defaults to "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified". |
SAML_NAMEID_FORMAT_UNSPECIFIED
|
recipient
|
str | None
|
The token endpoint URL the assertion is posted to (SubjectConfirmationData
Recipient). Defaults to None = oauth_token_url(), i.e.
" |
None
|
audience
|
str | None
|
The AudienceRestriction. Defaults to None = saml_audience of the constructor. |
None
|
validity_seconds
|
int
|
Lifetime of the assertion in seconds (1 to SAML_MAX_VALIDITY_SECONDS = 300). Defaults to SAML_DEFAULT_VALIDITY_SECONDS = 120. |
SAML_DEFAULT_VALIDITY_SECONDS
|
Returns:
| Type | Description |
|---|---|
str | None
|
str | None: The signed assertion as XML (for get_oauth_access_token(), which base64url- encodes it) or None if principal propagation is not configured correctly, the input is invalid or signing failed (see last_error). |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 | |
get_oauth_access_token
¶
get_oauth_access_token(
assertion: str,
client_id: str,
client_secret: str,
scope: str | None = None,
) -> dict | None
Exchange a SAML 2.0 bearer assertion of a user for an SAP OAuth 2.0 access token.
This is the token request of the OAuth 2.0 SAML bearer assertion flow (RFC 7522)
that SAP uses for principal propagation: SAP validates the assertion's signature
against a trusted identity provider, maps its subject (NameID) to an SAP user and
returns an access token for this user. OData calls with this token
("Authorization: Bearer
The request is sent as form data to oauth_token_url(). It does not use the session of this object (the token endpoint authenticates the OAuth client, not the technical user).
SAP prerequisites (the SAP S/4HANA administrator): 1. SAML2: SAML 2.0 is enabled for the client and the issuer of the assertion is a trusted OAuth 2.0 identity provider (signing certificate + NameID mapping). 2. SOAUTH2: an OAuth 2.0 client = an SU01 system user (client ID = user name, client secret = its password - not related to the end users) with grant type "SAML 2.0 Bearer Assertion" and the scopes of the OData services. 3. /IWFND/MAINT_SERVICE: OAuth is enabled for the OData services (this also creates their scope IDs, e.g. "API_MAINTENANCEORDER_0002" for version 0002).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
assertion
|
str
|
The signed SAML 2.0 assertion - the XML (it is base64url-encoded here) or an already base64url-encoded assertion. Its audience must be the SAML 2.0 provider name of the SAP system and its recipient the token endpoint URL. |
required |
client_id
|
str
|
The OAuth 2.0 client ID registered in SOAUTH2 - the user name of the SU01 system user that represents pyxecm as OAuth client. |
required |
client_secret
|
str
|
The password of that system user (SOAUTH2 client authentication "Password"). It authenticates pyxecm as the calling application - it is not the password of the end user the token is issued for. |
required |
scope
|
str | None
|
Space-separated scope IDs, e.g. "API_MAINTENANCEORDER_0002 API_MAINTNOTIFICATION_0001" - one per OData service that is called with the token. Defaults to None (no scope parameter). S/4HANA does not fall back to the scopes of the OAuth client then, but answers with "invalid_scope" - pass the scopes explicitly. |
None
|
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The token response or None if the request failed (see last_error). Example: { "access_token": "j0F2nk...", "token_type": "Bearer", "expires_in": "3600", "scope": "API_MAINTENANCEORDER_0002" } |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 | |
get_oauth_access_token_for_user
¶
get_oauth_access_token_for_user(
user_id: str,
client_id: str,
client_secret: str,
scope: str | None = None,
nameid_format: str = SAML_NAMEID_FORMAT_UNSPECIFIED,
recipient: str | None = None,
) -> dict | None
Get an SAP OAuth 2.0 access token for a user via principal propagation, in one call.
Mints a fresh SAML 2.0 bearer assertion for user_id with get_saml_assertion() and exchanges it right away for an SAP access token with get_oauth_access_token() - see both methods for the prerequisites. Only pass user IDs of users the calling application has authenticated (see the security note of get_saml_assertion()).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
The user to propagate - the assertion's NameID (see get_saml_assertion()). |
required |
client_id
|
str
|
The OAuth 2.0 client ID registered in SOAUTH2 - the user name of the SU01 system user that represents pyxecm as OAuth client. |
required |
client_secret
|
str
|
The password of that system user (SOAUTH2 client authentication "Password"). It authenticates pyxecm as the calling application - it is not the password of the end user the token is issued for. |
required |
scope
|
str | None
|
Space-separated scope IDs, e.g. "API_MAINTENANCEORDER_0002". Defaults to None (no scope parameter) - S/4HANA answers with "invalid_scope" then, see get_oauth_access_token(). |
None
|
nameid_format
|
str
|
The NameID format - must match transaction SAML2 (see get_saml_assertion()). Defaults to "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified". |
SAML_NAMEID_FORMAT_UNSPECIFIED
|
recipient
|
str | None
|
The Recipient of the assertion - only needed behind a reverse proxy (see get_saml_assertion()). Defaults to None = oauth_token_url(). |
None
|
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The token response (see get_oauth_access_token()) or None if minting the assertion or the token request failed (see last_error). |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
service_url
¶
Return the full URL of the root of an OData service.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
service
|
str | SAPODataServiceModel
|
The service definition or the technical service name. Names
that are not registered in SAP_ODATA_SERVICES are treated as
OData V2 services with the standard path /sap/opu/odata/sap/ |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
The service root URL, e.g. "https://s4.example.com:44300/sap/opu/odata/sap/API_MAINTENANCEORDER". |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
csrf_token
¶
Get a CSRF token for modifying OData requests to the service the URL belongs to.
The token is fetched once per service root and thread and then cached. SAP returns it in the 'x-csrf-token' response header of a GET request that has the request header 'x-csrf-token: Fetch'.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
Any URL of the OData service (the service root is derived from it). |
required |
refresh
|
bool
|
If True, a cached token is discarded and a new one is fetched. Used if SAP rejected the cached token. Defaults to False. |
False
|
Returns:
| Type | Description |
|---|---|
str | None
|
str | None: The CSRF token or None if it could not be fetched. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 | |
parse_request_response
¶
parse_request_response(
response_object: Response,
additional_error_message: str = "",
show_error: bool = True,
) -> dict | None
Convert the text of a response object to a Python dict safely.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response_object
|
Response
|
The response object delivered by the request call. |
required |
additional_error_message
|
str
|
Custom error message to include in logs. Defaults to "". |
''
|
show_error
|
bool
|
If True, logs an error. If False, logs a warning. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: Parsed response as a dictionary (empty dict for responses without content, e.g. HTTP 204 for updates), or None if the response is not valid JSON. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
do_request
¶
do_request(
url: str,
method: str = "GET",
headers: dict | None = None,
params: dict | None = None,
json_data: dict | None = None,
timeout: float | None = REQUEST_TIMEOUT,
show_error: bool = True,
show_warning: bool = False,
warning_message: str = "",
failure_message: str = "",
success_message: str = "",
max_retries: int = REQUEST_MAX_RETRIES,
parse_request_response: bool = True,
parse_error_response: bool = False,
) -> dict | Response | None
Call an SAP OData REST API in a safe way.
This method takes care of: * Authentication, SAP client and language (via the request session). * Fetching and renewing CSRF tokens for modifying requests (POST, PUT, PATCH, MERGE, DELETE). * HTTP 401: if the SAP session has ended, a new session is started once (SAP has not processed the request, so this is safe for all methods). Otherwise last_error tells whether the credentials or - with the 'auth' parameter - the access token were rejected (e.g. an expired token of principal propagation, which this object cannot renew). * Retries with exponential backoff for transient errors (timeouts, connection errors, HTTP 429/502/503/504). Non-idempotent requests (POST, PATCH, MERGE) are only retried if it is certain that SAP did not process them (connect timeout, HTTP 429/503) - otherwise a retry could create duplicate objects in SAP. * Logging of readable error messages extracted from SAP's OData error responses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
The full URL to send the request to (use service_url() to build it). |
required |
method
|
str
|
HTTP method (GET, POST, PATCH, ...). Defaults to "GET". |
'GET'
|
headers
|
dict | None
|
Additional request headers (merged with the default JSON headers). Defaults to None. |
None
|
params
|
dict | None
|
Additional query parameters, e.g. {"$filter": "...", "$top": 10}. Defaults to None. |
None
|
json_data
|
dict | None
|
Request payload that is sent as JSON. Defaults to None. |
None
|
timeout
|
float | None
|
Timeout for the request in seconds. Defaults to REQUEST_TIMEOUT. |
REQUEST_TIMEOUT
|
show_error
|
bool
|
Whether or not an error should be logged in case of a failed REST call. If False, a warning is logged if show_warning is True, otherwise only a debug message is logged. Defaults to True. |
True
|
show_warning
|
bool
|
Whether or not a warning should be logged in case of a failed REST call. This is only evaluated if show_error is False. Defaults to False. |
False
|
warning_message
|
str
|
Specific warning message. If not given, the failure_message will be used. Defaults to "". |
''
|
failure_message
|
str
|
Specific error message. Defaults to "". |
''
|
success_message
|
str
|
Specific success message. Defaults to "". |
''
|
max_retries
|
int
|
Maximum number of retries for transient errors. Defaults to REQUEST_MAX_RETRIES. |
REQUEST_MAX_RETRIES
|
parse_request_response
|
bool
|
Whether the response text should be interpreted as JSON and returned as a dictionary. If False, the requests.Response object is returned. Defaults to True. |
True
|
parse_error_response
|
bool
|
Whether the error response should be returned as a dictionary (SAPODataErrorModel.model_dump()) instead of None. Defaults to False. Deprecated: use capture_errors() to get the error details instead. |
False
|
Returns:
| Type | Description |
|---|---|
dict | Response | None
|
dict | requests.Response | None: The parsed response (dict), the response object (if parse_request_response is False), or None in case of an error (or the parsed error if parse_error_response is True). |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 | |
check_odata_apis
¶
check_odata_apis(
services: list[str | SAPODataServiceModel]
| None = None,
timeout: float = REQUEST_TIMEOUT,
) -> dict[str, SAPODataServiceStatusModel]
Check if the required OData APIs are activated and usable in the S/4HANA system.
For each service the service document (service root) is requested. The result is interpreted to distinguish the typical setup problems: * The service is not activated / published in SAP Gateway (/IWFND/MAINT_SERVICE for OData V2, /IWFND/V4_ADMIN for OData V4). * The ICF node of the OData endpoint is inactive (transaction SICF). * Authentication fails (wrong user, password or client) or the user lacks authorizations for the service (authorization object S_SERVICE). * The service is active but does not expose the expected entity sets (e.g. older S/4HANA release or a different service version). * The SAP system is not reachable at all (DNS, firewall, TLS, timeout).
The check uses the request session directly (not do_request()) as it needs the raw status code of failed requests and should not retry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
services
|
list[str | SAPODataServiceModel] | None
|
The services to check - either technical names or service definitions. Defaults to None which checks all services in SAP_ODATA_SERVICES. |
None
|
timeout
|
float
|
Timeout for each check request in seconds. Defaults to REQUEST_TIMEOUT. |
REQUEST_TIMEOUT
|
Returns:
| Type | Description |
|---|---|
dict[str, SAPODataServiceStatusModel]
|
dict[str, SAPODataServiceStatusModel]: The status per service name. Use status.active to check the result. Returns an empty dictionary if no base URL is configured. |
Example
statuses = sap.check_odata_apis() if not all(status.active for status in statuses.values()): ... print("SAP is not ready for OData integration!")
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 | |
check_oauth_token_endpoint
¶
Check if SAP's OAuth 2.0 token endpoint is activated and reachable.
This is the first step of the SAML 2.0 bearer assertion flow used for principal propagation (see get_oauth_access_token()) - before any OAuth client, SAML trust or user is involved. An intentionally incomplete token request without client credentials and grant_type is sent. A live endpoint answers it with HTTP 401 (the ICF node requires the client authentication) or a well-formed OAuth error (e.g. "invalid_request"), which is enough to tell apart the typical setup problems: * The ICF node /sap/bc/sec/oauth2/token is not active (transaction SICF). * The SAP system is not reachable at all (DNS, firewall, TLS, timeout). * The base URL points to something else (e.g. a login page of a reverse proxy).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
timeout
|
float
|
Timeout for the check request in seconds. Defaults to REQUEST_TIMEOUT. |
REQUEST_TIMEOUT
|
Returns:
| Name | Type | Description |
|---|---|---|
SAPAuthCheckStatusModel |
SAPAuthCheckStatusModel
|
The result of the check. Use status.ok to check the result. |
Example
status = sap.check_oauth_token_endpoint() if not status.ok: ... print(status.hint)
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 | |
check_principal_propagation
¶
check_principal_propagation(
user_id: str,
client_id: str,
client_secret: str,
scope: str | None = None,
nameid_format: str = SAML_NAMEID_FORMAT_UNSPECIFIED,
recipient: str | None = None,
) -> SAPAuthCheckStatusModel
Check the full SAML 2.0 bearer assertion / OAuth 2.0 principal propagation round trip.
Runs exactly what get_oauth_access_token_for_user() does for a real user: mint a SAML 2.0 assertion for user_id (get_saml_assertion()) and exchange it for an SAP access token (get_oauth_access_token()). Use this with a dedicated test user to verify the setup end-to-end - unlike check_oauth_token_endpoint() this needs a working OAuth client (SOAUTH2), a trusted SAML 2.0 identity provider (SAML2) and a valid NameID mapping for user_id. The message of a failed check (SAP's own OAuth error, e.g. "invalid_client", "invalid_grant", "unauthorized_client" or "invalid_scope") is kept as returned - see the hint for what it typically means.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
The user to propagate, e.g. a dedicated technical test user. See get_saml_assertion() for the security implications. |
required |
client_id
|
str
|
The OAuth 2.0 client ID registered in SOAUTH2. |
required |
client_secret
|
str
|
The password of the SU01 system user behind that OAuth client. |
required |
scope
|
str | None
|
Space-separated scope IDs to request, e.g. "API_MAINTENANCEORDER_0002". Defaults to None (no scope parameter) - S/4HANA answers with "invalid_scope" then, see get_oauth_access_token(). |
None
|
nameid_format
|
str
|
The NameID format - must match transaction SAML2. Defaults to "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified". |
SAML_NAMEID_FORMAT_UNSPECIFIED
|
recipient
|
str | None
|
The Recipient of the assertion - only needed behind a reverse proxy (see get_saml_assertion()). Defaults to None = oauth_token_url(). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
SAPAuthCheckStatusModel |
SAPAuthCheckStatusModel
|
The result of the check. Use status.ok to check the result. |
Example
status = sap.check_principal_propagation(user_id="jane.smith", client_id="PYXECM_OAUTH", client_secret="...") if not status.ok: ... print(status.message, "-", status.hint)
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 | |
get_odata_entity_type
¶
Return the entity type of an entity set as defined in the $metadata of the service.
The $metadata is read once per SAP system and service (and kept for all SAP objects). A failed read is not kept - the next call tries again.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
service
|
str
|
The name of the OData service in SAP_ODATA_SERVICES. |
required |
entity_set
|
str
|
The entity set, e.g. "A_SalesOrderItem". |
required |
Returns:
| Type | Description |
|---|---|
ODataEntityType | None
|
ODataEntityType | None: The entity type or None if the $metadata cannot be read or has no such entity set. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_maintenance_order
¶
Create an SAP Plant Maintenance order (including its operations and their components).
Uses the OData V2 API API_MAINTENANCEORDER: the order header and all operations are created (and committed) in one request (deep insert). SAP rejects components in this request ("Error reading the order in the document tables") - they are created for the new order afterwards (see create_maintenance_order_component()).
With a task list reference (SAPMaintenanceOrderModel.task_list), the operations and materials of the task list become the first operations and components of the order (see expand_maintenance_order_task_list()) - the API cannot include a task list.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order
|
SAPMaintenanceOrderModel | dict
|
The order data. A dictionary is validated against the SAPMaintenanceOrderModel model and can use either the snake case attribute names or the OData property names (e.g. "order_type" or "MaintenanceOrderType"). |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created order as returned by SAP (including "MaintenanceOrder") or None in case of an error. If the order has been created but components could not be created, the result has the key "ComponentErrors" with the error messages (and last_error is set). |
Example
sap.create_maintenance_order( ... { ... "order_type": "YA01", ... "description": "Replace pump seal", ... "planning_plant": "1010", ... "main_work_center": "RES-0100", ... "main_work_center_plant": "1010", ... "equipment": "210100001", ... "operations": [{"operation": "10", "description": "Replace seal", "control_key": "YBM1"}], ... "task_list": {"task_list_type": "A", "task_list_group": "17", "storage_location": "0001"}, ... } ... )
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 | |
expand_maintenance_order_task_list
¶
expand_maintenance_order_task_list(
order: SAPMaintenanceOrderModel,
) -> SAPMaintenanceOrderModel | None
Take over the operations and materials of the task list referenced by a new maintenance order.
The operations of the task list (number, text, control key, work center, work and number of people) become the first operations of the order, their materials the components of these operations. Operations of the order itself follow - their numbers must not clash with the ones of the task list.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order
|
SAPMaintenanceOrderModel
|
The order with a task list reference (SAPMaintenanceOrderModel.task_list). |
required |
Returns:
| Type | Description |
|---|---|
SAPMaintenanceOrderModel | None
|
SAPMaintenanceOrderModel | None: A copy of the order with the operations of the task list (and without the task list reference) or None in case of an error (e.g. the task list does not exist). |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 | |
create_maintenance_order_component
¶
create_maintenance_order_component(
order_id: str,
operation: str,
component: SAPMaintenanceOrderComponentModel | dict,
sub_operation: str = "",
) -> dict | None
Create a component (material) for an operation of an existing SAP maintenance order.
SAP reserves the material (stock item) for the operation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The maintenance order number, e.g. "4000340". |
required |
operation
|
str
|
The operation number, e.g. "0010". |
required |
component
|
SAPMaintenanceOrderComponentModel | dict
|
The component (material, quantity, unit, plant, storage location, item category). |
required |
sub_operation
|
str
|
The sub-operation number. Defaults to "" (the operation itself). |
''
|
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created component as returned by SAP (including "Reservation") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_maintenance_orders
¶
iter_maintenance_orders(
query: SAPMaintenanceOrderQueryModel | None = None,
) -> SAPODataIterator[SAPMaintenanceOrderResponseModel]
Iterate over SAP maintenance orders - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPMaintenanceOrderQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all maintenance orders). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPMaintenanceOrderResponseModel]
|
SAPODataIterator[SAPMaintenanceOrderResponseModel]: The iterator over the maintenance orders. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_business_object
¶
Get an SAP object by the business object reference used by an Extended ECM workspace.
Dispatch to the corresponding OData getter and return its response model unchanged. SAPBusinessObjectType.get_key_fields() converts the internal SAP ID into the individual keys, including composite keys such as material document number and year. Supported types are listed in SAP_BUSINESS_OBJECT_TYPES in sap_models.py.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bo_type
|
str
|
The SAP BOR object type, e.g. "BUS2007" or "BUS2017". |
required |
bo_id
|
str
|
The business object ID in SAP's internal format, e.g. "000004000340" or "49000001232026". Single-field IDs also accept the external format. |
required |
Returns:
| Type | Description |
|---|---|
SAPODataModel | None
|
SAPODataModel | None: The getter's typed SAP object, or None if it does not exist, the type is unsupported, the ID is invalid, or the request fails. Use last_error or pyxecm.capture_errors() to inspect failures; None alone does not prove that the object is absent. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 | |
get_maintenance_orders
¶
get_maintenance_orders(
query: SAPMaintenanceOrderQueryModel | None = None,
) -> list[SAPMaintenanceOrderResponseModel] | None
Get SAP maintenance orders as a list.
All matching maintenance orders are read (page by page, see iter_maintenance_orders()) and returned at once. For very large result sets prefer iter_maintenance_orders().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPMaintenanceOrderQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all maintenance orders). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPMaintenanceOrderResponseModel] | None
|
list[SAPMaintenanceOrderResponseModel] | None: The maintenance orders (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_maintenance_order
¶
get_maintenance_order(
order_id: str, expand_operations: bool = True
) -> SAPMaintenanceOrderResponseModel | None
Get a single SAP Plant Maintenance order by its order number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The maintenance order number, e.g. "4000340". |
required |
expand_operations
|
bool
|
Whether to read the operations of the order as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPMaintenanceOrderResponseModel | None
|
SAPMaintenanceOrderResponseModel | None: The maintenance order or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_maintenance_order
¶
Update individual fields of an SAP maintenance order.
The changes are validated with the field definitions of SAPMaintenanceOrderModel (e.g. upper case codes, lengths, date formats). Items cannot be changed with this method.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The maintenance order number, e.g. "4000340". |
required |
changes
|
dict
|
The fields to change - snake case attribute names of SAPMaintenanceOrderModel or OData property names, e.g. {"description": "Replace pump seal", "priority": "1"}. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the maintenance order has been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
change_maintenance_order_status
¶
change_maintenance_order_status(
order_id: str,
action: SAPMaintenanceOrderAction,
parameters: dict | None = None,
) -> bool
Change the status of an SAP maintenance order (e.g. release, technically complete or close).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The maintenance order number, e.g. "4000340". |
required |
action
|
SAPMaintenanceOrderAction
|
The status action, e.g. SAPMaintenanceOrderAction.RELEASE. |
required |
parameters
|
dict | None
|
Additional (optional) parameters of the action with their OData names. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the status has been changed, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_maintenance_order_deletion_steps
¶
Return the status actions needed to delete an SAP maintenance order (see delete_maintenance_order()).
SAP only accepts the deletion flag for closed orders - the order is closed first, depending on its status: * Created (CRTD, not released): DO_NOT_EXECUTE - closes the order as not performed (CLSD NCMP). * Released (REL): TECHNICALLY_COMPLETE (TECO) and CLOSE (CLSD). * Technically completed (TECO): CLOSE. * Closed (CLSD): nothing. The last step is always MARK_FOR_DELETION.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The maintenance order number, e.g. "4000340". |
required |
Returns:
| Type | Description |
|---|---|
list[SAPMaintenanceOrderAction] | None
|
list[SAPMaintenanceOrderAction] | None: The status actions in their order - empty if the order already has the deletion flag - or None if the order does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_maintenance_order
¶
delete_maintenance_order(
order_id: str,
include_notification: bool = True,
steps: list[SAPMaintenanceOrderAction] | None = None,
) -> bool
Delete an SAP maintenance order by setting its deletion flag (status DLFL).
API_MAINTENANCEORDER has no OData DELETE and SAP only accepts the deletion flag for closed orders (otherwise: IW/875 "You cannot change the status of order"). This method closes the order first, depending on its status (see get_maintenance_order_deletion_steps()): * Created (CRTD, not released): "do not execute" - closes the order as not performed (CLSD NCMP). * Released (REL): technically complete (TECO) and close (CLSD). This needs a settlement rule of the order - SAP rejects it otherwise with "account assignment not maintained". The deletion flag can be removed again with SAPMaintenanceOrderAction.RESET_MARKED_FOR_DELETION.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The maintenance order number, e.g. "4000340". |
required |
include_notification
|
bool
|
Whether the assigned maintenance notification is completed and gets the deletion flag as well. Defaults to True. |
True
|
steps
|
list[SAPMaintenanceOrderAction] | None
|
The status actions to do - e.g. the result of get_maintenance_order_deletion_steps() the user has confirmed. Defaults to None = determine them from the current status. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the order has the deletion flag, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_maintenance_order_operation
¶
create_maintenance_order_operation(
order_id: str,
operation: SAPMaintenanceOrderOperationModel | dict,
) -> dict | None
Add an operation (work step) to an existing SAP maintenance order.
The operation is created via the navigation property of the order (the entity set MaintenanceOrderOperation itself does not allow creates).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The maintenance order number, e.g. "4000340". |
required |
operation
|
SAPMaintenanceOrderOperationModel | dict
|
The new operation. The operation number must not exist in the order yet. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created operation as returned by SAP or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_maintenance_order_operation
¶
update_maintenance_order_operation(
order_id: str,
operation: str,
changes: dict,
sub_operation: str = "",
) -> bool
Update individual fields of an operation of an SAP maintenance order.
The changes are validated with the field definitions of SAPMaintenanceOrderOperationModel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The maintenance order number, e.g. "4000340". |
required |
operation
|
str
|
The operation number, e.g. "10" or "0010". |
required |
changes
|
dict
|
The fields to change - snake case attribute names of SAPMaintenanceOrderOperationModel or OData property names, e.g. {"planned_work": 6, "planned_work_unit": "H"}. |
required |
sub_operation
|
str
|
The sub-operation number. Empty (default) for operations. |
''
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the operation has been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_maintenance_order_operation
¶
delete_maintenance_order_operation(
order_id: str, operation: str, sub_operation: str = ""
) -> bool
Delete an operation of an SAP maintenance order.
Operations of orders that are not released yet (status CRTD) are removed. For released orders SAP typically keeps the operation with its deletion flag (IsMarkedForDeletion) - it is no longer planned or executed. Operations with confirmations or follow-on documents (e.g. purchase requisitions) cannot be deleted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The maintenance order number, e.g. "4000340". |
required |
operation
|
str
|
The operation number, e.g. "10" or "0010". |
required |
sub_operation
|
str
|
The sub-operation number. Empty (default) for operations. |
''
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the operation has been deleted, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
change_maintenance_order_operation_status
¶
change_maintenance_order_operation_status(
order_id: str,
operation: str,
action: SAPMaintenanceOrderOperationAction,
sub_operation: str = "",
) -> bool
Change the status of an operation of an SAP maintenance order (e.g. dispatch it).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The maintenance order number, e.g. "4000340". |
required |
operation
|
str
|
The operation number, e.g. "10" or "0010". |
required |
action
|
SAPMaintenanceOrderOperationAction
|
The status action, e.g. SAPMaintenanceOrderOperationAction.DISPATCH. |
required |
sub_operation
|
str
|
The sub-operation number. Empty (default) for operations. |
''
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the status has been changed, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_purchase_order
¶
Create an SAP purchase order including its items, schedule lines and account assignments.
Uses the OData V4 API API_PURCHASEORDER_2 with a deep create, so the whole purchase order is created (and committed) in one request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order
|
SAPPurchaseOrderModel | dict
|
The purchase order data. A dictionary is validated against the SAPPurchaseOrderModel and can use either the snake case attribute names or the OData property names (e.g. "supplier" or "Supplier"). |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created purchase order as returned by SAP (including the purchase order number in "PurchaseOrder") or None in case of an error. |
Example
sap.create_purchase_order( ... { ... "company_code": "3000", ... "purchasing_organization": "3000", ... "purchasing_group": "001", ... "supplier": "30050", ... "items": [ ... { ... "material": "R-9010", ... "plant": "3000", ... "quantity": "20", ... "net_price": "32.00", ... "account_assignment_category": "K", ... "schedule_lines": [{"delivery_date": "2026-11-01"}], ... "account_assignments": [{"cost_center": "4130", "gl_account": "400000"}], ... }, ... ], ... } ... )
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_purchase_orders
¶
iter_purchase_orders(
query: SAPPurchaseOrderQueryModel | None = None,
) -> SAPODataIterator[SAPPurchaseOrderResponseModel]
Iterate over SAP purchase orders - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPPurchaseOrderQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all purchase orders). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPPurchaseOrderResponseModel]
|
SAPODataIterator[SAPPurchaseOrderResponseModel]: The iterator over the purchase orders. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_purchase_orders
¶
get_purchase_orders(
query: SAPPurchaseOrderQueryModel | None = None,
) -> list[SAPPurchaseOrderResponseModel] | None
Get SAP purchase orders as a list.
All matching purchase orders are read (page by page, see iter_purchase_orders()) and returned at once. For very large result sets prefer iter_purchase_orders().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPPurchaseOrderQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all purchase orders). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPPurchaseOrderResponseModel] | None
|
list[SAPPurchaseOrderResponseModel] | None: The purchase orders (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_purchase_order
¶
get_purchase_order(
order_id: str, expand_items: bool = True
) -> SAPPurchaseOrderResponseModel | None
Get a single SAP purchase order by its number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The purchase order number, e.g. "4500001539". |
required |
expand_items
|
bool
|
Whether to read the items (with schedule lines and account assignments) as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPPurchaseOrderResponseModel | None
|
SAPPurchaseOrderResponseModel | None: The purchase order or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_purchase_order
¶
update_purchase_order(
order_id: str,
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of an SAP purchase order and of its items.
All changes are validated first and the items must belong to the purchase order - otherwise nothing is changed. The items are changed first, the header last (see _update_odata_document()).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The purchase order number, e.g. "4500001586". |
required |
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPPurchaseOrderModel or OData property names. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per item number, e.g. {"10": {"OrderQuantity": 20}} (snake case attribute names of SAPPurchaseOrderItemModel or OData property names). Defaults to None (items unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the purchase order (and its items) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_purchase_order
¶
Delete an SAP purchase order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The purchase order number, e.g. "4500001539". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the purchase order has been deleted, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_maintenance_notification
¶
create_maintenance_notification(
notification: SAPMaintenanceNotificationModel | dict,
) -> dict | None
Create an SAP maintenance notification (including its items).
Uses the OData V2 API API_MAINTNOTIFICATION with a deep insert, so the notification and all items are created (and committed) in one request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
notification
|
SAPMaintenanceNotificationModel | dict
|
The notification data. A dictionary is validated against the SAPMaintenanceNotificationModel and can use either the snake case attribute names or the OData property names (e.g. "text" or "NotificationText"). |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created notification as returned by SAP (including the notification number in "MaintenanceNotification") or None in case of an error. |
Example
sap.create_maintenance_notification( ... { ... "notification_type": "M2", ... "text": "Pump is leaking", ... "priority": "2", ... "technical_object": "P-3000-N001", ... "technical_object_type": "EAMS_EQUI", ... "breakdown": True, ... } ... )
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_maintenance_notifications
¶
iter_maintenance_notifications(
query: SAPMaintenanceNotificationQueryModel
| None = None,
) -> SAPODataIterator[
SAPMaintenanceNotificationResponseModel
]
Iterate over SAP maintenance notifications - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPMaintenanceNotificationQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all maintenance notifications). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPMaintenanceNotificationResponseModel]
|
SAPODataIterator[SAPMaintenanceNotificationResponseModel]: The iterator over the maintenance notifications. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_maintenance_notifications
¶
get_maintenance_notifications(
query: SAPMaintenanceNotificationQueryModel
| None = None,
) -> list[SAPMaintenanceNotificationResponseModel] | None
Get SAP maintenance notifications as a list.
All matching maintenance notifications are read (page by page, see iter_maintenance_notifications()) and returned at once. For very large result sets prefer iter_maintenance_notifications().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPMaintenanceNotificationQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all maintenance notifications). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPMaintenanceNotificationResponseModel] | None
|
list[SAPMaintenanceNotificationResponseModel] | None: The maintenance notifications (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_maintenance_notification
¶
get_maintenance_notification(
notification_id: str, expand_items: bool = True
) -> SAPMaintenanceNotificationResponseModel | None
Get a single SAP maintenance notification by its number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
notification_id
|
str
|
The notification number, e.g. "10000210" (leading zeros are optional). |
required |
expand_items
|
bool
|
Whether to read the items of the notification as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPMaintenanceNotificationResponseModel | None
|
SAPMaintenanceNotificationResponseModel | None: The notification or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_maintenance_notification
¶
update_maintenance_notification(
notification_id: str,
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of an SAP maintenance notification and of its items.
All changes are validated first and the items must belong to the maintenance notification - otherwise nothing is changed. The items are changed first, the header last (see _update_odata_document()). The codes of an item (damage, object part) can be set or replaced, but not removed (SAP only allows this in its UI).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
notification_id
|
str
|
The maintenance notification number, e.g. "10000239". |
required |
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPMaintenanceNotificationModel or OData property names. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per item number, e.g. {"1": {"MaintNotifItemText": "Seal leak"}} (snake case attribute names of SAPMaintenanceNotificationItemModel or OData property names). Defaults to None (items unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the maintenance notification (and its items) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 | |
change_maintenance_notification_status
¶
change_maintenance_notification_status(
notification_id: str,
action: SAPMaintenanceNotificationAction,
parameters: dict | None = None,
) -> bool
Change the status of an SAP maintenance notification (e.g. complete or set in process).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
notification_id
|
str
|
The maintenance notification number, e.g. "10000210". |
required |
action
|
SAPMaintenanceNotificationAction
|
The status action, e.g. SAPMaintenanceNotificationAction.COMPLETE. |
required |
parameters
|
dict | None
|
Additional (optional) parameters of the action with their OData names. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the status has been changed, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_sales_order
¶
Create an SAP sales order (including its items).
Uses the OData V2 API API_SALES_ORDER_SRV with a deep insert, so the sales order and all items are created (and committed) in one request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order
|
SAPSalesOrderModel | dict
|
The sales order data. A dictionary is validated against the SAPSalesOrderModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created sales order as returned by SAP (including the number in "SalesOrder") or None in case of an error. |
Example
sap.create_sales_order( ... { ... "order_type": "YT", ... "sales_organization": "3000", ... "distribution_channel": "10", ... "division": "00", ... "sold_to_party": "52001", ... "customer_reference": "PO-4711", ... "items": [{"material": "P-100", "quantity": "10"}], ... } ... )
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_sales_orders
¶
iter_sales_orders(
query: SAPSalesOrderQueryModel | None = None,
) -> SAPODataIterator[SAPSalesOrderResponseModel]
Iterate over SAP sales orders - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPSalesOrderQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all sales orders). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPSalesOrderResponseModel]
|
SAPODataIterator[SAPSalesOrderResponseModel]: The iterator over the sales orders. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_sales_orders
¶
get_sales_orders(
query: SAPSalesOrderQueryModel | None = None,
) -> list[SAPSalesOrderResponseModel] | None
Get SAP sales orders as a list.
All matching sales orders are read (page by page, see iter_sales_orders()) and returned at once. For very large result sets prefer iter_sales_orders().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPSalesOrderQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all sales orders). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPSalesOrderResponseModel] | None
|
list[SAPSalesOrderResponseModel] | None: The sales orders (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_sales_order
¶
Get a single SAP sales order by its number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The sales order number, e.g. "413". |
required |
expand_items
|
bool
|
Whether to read the items as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPSalesOrderResponseModel | None
|
SAPSalesOrderResponseModel | None: The sales order or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_sales_order
¶
update_sales_order(
order_id: str,
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of an SAP sales order and of its items.
All changes are validated first and the items must belong to the sales order - otherwise nothing is changed. The items are changed first, the header last (see _update_odata_document()).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The sales order number, e.g. "413". |
required |
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPSalesOrderModel or OData property names. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per item number, e.g. {"10": {"RequestedQuantity": 5}} (snake case attribute names of SAPSalesOrderItemModel or OData property names). Defaults to None (items unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the sales order (and its items) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_sales_order
¶
Delete an SAP sales order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The sales order number, e.g. "413". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the sales order has been deleted, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_sales_contract
¶
Create an SAP sales contract (including its items).
Uses the OData V2 API API_SALES_CONTRACT_SRV with a deep insert, so the sales contract and all items are created (and committed) in one request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract
|
SAPSalesContractModel | dict
|
The sales contract data. A dictionary is validated against the SAPSalesContractModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created sales contract as returned by SAP (including the number in "SalesContract") or None in case of an error. |
Example
sap.create_sales_contract( ... { ... "contract_type": "YC", ... "sales_organization": "1000", ... "distribution_channel": "10", ... "division": "00", ... "sold_to_party": "50031", ... "validity_start_date": "2026-11-01", ... "validity_end_date": "2027-10-31", ... } ... )
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_sales_contracts
¶
iter_sales_contracts(
query: SAPSalesContractQueryModel | None = None,
) -> SAPODataIterator[SAPSalesContractResponseModel]
Iterate over SAP sales contracts - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPSalesContractQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all sales contracts). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPSalesContractResponseModel]
|
SAPODataIterator[SAPSalesContractResponseModel]: The iterator over the sales contracts. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_sales_contracts
¶
get_sales_contracts(
query: SAPSalesContractQueryModel | None = None,
) -> list[SAPSalesContractResponseModel] | None
Get SAP sales contracts as a list.
All matching sales contracts are read (page by page, see iter_sales_contracts()) and returned at once. For very large result sets prefer iter_sales_contracts().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPSalesContractQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all sales contracts). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPSalesContractResponseModel] | None
|
list[SAPSalesContractResponseModel] | None: The sales contracts (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_sales_contract
¶
get_sales_contract(
contract_id: str, expand_items: bool = True
) -> SAPSalesContractResponseModel | None
Get a single SAP sales contract by its number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract_id
|
str
|
The sales contract number, e.g. "40000040". |
required |
expand_items
|
bool
|
Whether to read the items as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPSalesContractResponseModel | None
|
SAPSalesContractResponseModel | None: The sales contract or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_sales_contract
¶
update_sales_contract(
contract_id: str,
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of an SAP sales contract and of its items.
All changes are validated first and the items must belong to the sales contract - otherwise nothing is changed. The items are changed first, the header last (see _update_odata_document()).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract_id
|
str
|
The sales contract number, e.g. "40000039". |
required |
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPSalesContractModel or OData property names. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per item number, e.g. {"10": {"RequestedQuantity": 100}} (snake case attribute names of SAPSalesContractItemModel or OData property names). Defaults to None (items unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the sales contract (and its items) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_sales_contract
¶
Delete an SAP sales contract.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract_id
|
str
|
The sales contract number, e.g. "40000040". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the sales contract has been deleted, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_purchase_contract
¶
Create an SAP purchase contract (including its items).
Uses the OData V2 API API_PURCHASECONTRACT_PROCESS_SRV with a deep insert, so the purchase contract and all items are created (and committed) in one request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract
|
SAPPurchaseContractModel | dict
|
The purchase contract data. A dictionary is validated against the SAPPurchaseContractModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created purchase contract as returned by SAP (including the number in "PurchaseContract") or None in case of an error. |
Example
sap.create_purchase_contract( ... { ... "company_code": "3000", ... "purchasing_organization": "3000", ... "purchasing_group": "001", ... "supplier": "30010", ... "validity_start_date": "2026-11-01", ... "validity_end_date": "2027-10-31", ... "items": [{"material": "R-9000", "plant": "3000", "target_quantity": "100", "net_price": "950.00"}], ... } ... )
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_purchase_contracts
¶
iter_purchase_contracts(
query: SAPPurchaseContractQueryModel | None = None,
) -> SAPODataIterator[SAPPurchaseContractResponseModel]
Iterate over SAP purchase contracts - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPPurchaseContractQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all purchase contracts). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPPurchaseContractResponseModel]
|
SAPODataIterator[SAPPurchaseContractResponseModel]: The iterator over the purchase contracts. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_purchase_contracts
¶
get_purchase_contracts(
query: SAPPurchaseContractQueryModel | None = None,
) -> list[SAPPurchaseContractResponseModel] | None
Get SAP purchase contracts as a list.
All matching purchase contracts are read (page by page, see iter_purchase_contracts()) and returned at once. For very large result sets prefer iter_purchase_contracts().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPPurchaseContractQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all purchase contracts). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPPurchaseContractResponseModel] | None
|
list[SAPPurchaseContractResponseModel] | None: The purchase contracts (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_purchase_contract
¶
get_purchase_contract(
contract_id: str, expand_items: bool = True
) -> SAPPurchaseContractResponseModel | None
Get a single SAP purchase contract by its number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract_id
|
str
|
The purchase contract number, e.g. "4600000070". |
required |
expand_items
|
bool
|
Whether to read the items as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPPurchaseContractResponseModel | None
|
SAPPurchaseContractResponseModel | None: The purchase contract or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_purchase_contract
¶
update_purchase_contract(
contract_id: str,
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of an SAP purchase contract and of its items.
All changes are validated first and the items must belong to the purchase contract - otherwise nothing is changed. The items are changed first, the header last (see _update_odata_document()).
A deleted item is restored with the item change {"PurchasingContractDeletionCode": ""}. Some S/4HANA releases reject all header changes with "Purchase contract cannot be saved in preparation" (versions 0001 and 0002 of the API) while item changes work.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract_id
|
str
|
The purchase contract number, e.g. "4600000070". |
required |
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPPurchaseContractModel or OData property names. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per item number, e.g. {"10": {"net_price": 925.00}} (snake case attribute names of SAPPurchaseContractItemModel or OData property names). Defaults to None (items unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the purchase contract (and its items) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_purchase_contract_item
¶
Update individual fields of an item of an SAP purchase contract.
The changes are validated with the field definitions of SAPPurchaseContractItemModel. To change the header and several items at once, use update_purchase_contract(). The deletion indicator of the item can be changed with the OData property "PurchasingContractDeletionCode" ("L" = deleted, "S" = blocked, "" = active).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract_id
|
str
|
The purchase contract number, e.g. "4600000070". |
required |
item
|
str
|
The item number, e.g. "10" or "00010". |
required |
changes
|
dict
|
The fields to change - snake case attribute names of SAPPurchaseContractItemModel or OData property names, e.g. {"net_price": 925.00}. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the item has been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_purchase_contract
¶
Delete an SAP purchase contract or some of its items (set their deletion indicator).
API_PURCHASECONTRACT_PROCESS_SRV does not allow DELETE - like in SAP GUI (ME32K), contracts are deleted by setting the deletion indicator "L" of their items. Deleted items can no longer be referenced by purchase orders. The deletion can be undone per item with update_purchase_contract() and the item change {"PurchasingContractDeletionCode": ""}.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract_id
|
str
|
The purchase contract number, e.g. "4600000070". |
required |
items
|
list[str] | None
|
The item numbers to delete, e.g. ["10"]. Defaults to None = all items. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if all (given) items are deleted, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_purchase_requisition
¶
Create an SAP purchase requisition including its items (and their account assignments).
Uses the OData V4 API API_PURCHASEREQUISITION_2 with a deep create, so the whole purchase requisition is created (and committed) in one request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
requisition
|
SAPPurchaseRequisitionModel | dict
|
The purchase requisition data. A dictionary is validated against the SAPPurchaseRequisitionModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created purchase requisition as returned by SAP (including the number in "PurchaseRequisition") or None in case of an error. |
Example
sap.create_purchase_requisition( ... { ... "description": "Notebook web cams", ... "items": [ ... { ... "material": "R-9010", ... "quantity": "10", ... "plant": "3000", ... "purchasing_group": "003", ... "delivery_date": "2026-11-01", ... }, ... ], ... } ... )
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_purchase_requisitions
¶
iter_purchase_requisitions(
query: SAPPurchaseRequisitionQueryModel | None = None,
) -> SAPODataIterator[SAPPurchaseRequisitionResponseModel]
Iterate over SAP purchase requisitions - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPPurchaseRequisitionQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all purchase requisitions). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPPurchaseRequisitionResponseModel]
|
SAPODataIterator[SAPPurchaseRequisitionResponseModel]: The iterator over the purchase requisitions. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_purchase_requisitions
¶
get_purchase_requisitions(
query: SAPPurchaseRequisitionQueryModel | None = None,
) -> list[SAPPurchaseRequisitionResponseModel] | None
Get SAP purchase requisitions as a list.
All matching purchase requisitions are read (page by page, see iter_purchase_requisitions()) and returned at once. For very large result sets prefer iter_purchase_requisitions().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPPurchaseRequisitionQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all purchase requisitions). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPPurchaseRequisitionResponseModel] | None
|
list[SAPPurchaseRequisitionResponseModel] | None: The purchase requisitions (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_purchase_requisition
¶
get_purchase_requisition(
requisition_id: str, expand_items: bool = True
) -> SAPPurchaseRequisitionResponseModel | None
Get a single SAP purchase requisition by its number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
requisition_id
|
str
|
The purchase requisition number, e.g. "10000151". |
required |
expand_items
|
bool
|
Whether to read the items (with account assignments) as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPPurchaseRequisitionResponseModel | None
|
SAPPurchaseRequisitionResponseModel | None: The purchase requisition or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_purchase_requisition
¶
update_purchase_requisition(
requisition_id: str,
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of an SAP purchase requisition and of its items.
All changes are validated first and the items must belong to the purchase requisition - otherwise nothing is changed. The items are changed first, the header last (see _update_odata_document()).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
requisition_id
|
str
|
The purchase requisition number, e.g. "10000175". |
required |
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPPurchaseRequisitionModel or OData property names. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per item number, e.g. {"10": {"RequestedQuantity": 5}} (snake case attribute names of SAPPurchaseRequisitionItemModel or OData property names). Defaults to None (items unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the purchase requisition (and its items) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_credit_memo_request
¶
Create an SAP credit memo request (including its items).
Uses the OData V2 API API_CREDIT_MEMO_REQUEST_SRV with a deep insert. SAP creates the credit memo (a billing document) from the request - usually after an approval.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
SAPCreditMemoRequestModel | dict
|
The data. A dictionary is validated against the SAPCreditMemoRequestModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created credit memo request as returned by SAP (including the number in "CreditMemoRequest") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_credit_memo_requests
¶
iter_credit_memo_requests(
query: SAPCreditMemoRequestQueryModel | None = None,
) -> SAPODataIterator[SAPCreditMemoRequestResponseModel]
Iterate over SAP credit memo requests - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPCreditMemoRequestQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all credit memo requests). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPCreditMemoRequestResponseModel]
|
SAPODataIterator[SAPCreditMemoRequestResponseModel]: The iterator over the credit memo requests. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_credit_memo_requests
¶
get_credit_memo_requests(
query: SAPCreditMemoRequestQueryModel | None = None,
) -> list[SAPCreditMemoRequestResponseModel] | None
Get SAP credit memo requests as a list.
All matching credit memo requests are read (page by page, see iter_credit_memo_requests()) and returned at once. For very large result sets prefer iter_credit_memo_requests().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPCreditMemoRequestQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all credit memo requests). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPCreditMemoRequestResponseModel] | None
|
list[SAPCreditMemoRequestResponseModel] | None: The credit memo requests (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_credit_memo_request
¶
get_credit_memo_request(
request_id: str, expand_items: bool = True
) -> SAPCreditMemoRequestResponseModel | None
Get a single SAP credit memo request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
str
|
The credit memo request number, e.g. "60000012". |
required |
expand_items
|
bool
|
Whether to read the items as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPCreditMemoRequestResponseModel | None
|
SAPCreditMemoRequestResponseModel | None: The credit memo request or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_credit_memo_request
¶
update_credit_memo_request(
request_id: str,
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of an SAP credit memo request and of its items.
All changes are validated first and the items must belong to the credit memo request - otherwise nothing is changed. The items are changed first, the header last (see _update_odata_document()).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
str
|
The credit memo request number, e.g. "60000012". |
required |
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPCreditMemoRequestModel or OData property names. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per item number, e.g. {"10": {"RequestedQuantity": 1}} (snake case attribute names of SAPCreditMemoRequestItemModel or OData property names). Defaults to None (items unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the credit memo request (and its items) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_credit_memo_request
¶
Delete an SAP credit memo request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
str
|
The credit memo request number, e.g. "60000012". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the credit memo request has been deleted, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
change_credit_memo_request_status
¶
Approve (release) or reject an SAP credit memo request that is in approval.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
str
|
The credit memo request number, e.g. "60000012". |
required |
action
|
SAPCreditMemoRequestAction
|
The approval action, e.g. SAPCreditMemoRequestAction.RELEASE_APPROVAL_REQUEST. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the status has been changed, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_debit_memo_request
¶
Create an SAP debit memo request (including its items).
Uses the OData V2 API API_DEBIT_MEMO_REQUEST_SRV with a deep insert. SAP creates the debit memo (a billing document) from the request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
SAPDebitMemoRequestModel | dict
|
The data. A dictionary is validated against the SAPDebitMemoRequestModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created debit memo request as returned by SAP (including the number in "DebitMemoRequest") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_debit_memo_requests
¶
iter_debit_memo_requests(
query: SAPDebitMemoRequestQueryModel | None = None,
) -> SAPODataIterator[SAPDebitMemoRequestResponseModel]
Iterate over SAP debit memo requests - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPDebitMemoRequestQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all debit memo requests). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPDebitMemoRequestResponseModel]
|
SAPODataIterator[SAPDebitMemoRequestResponseModel]: The iterator over the debit memo requests. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_debit_memo_requests
¶
get_debit_memo_requests(
query: SAPDebitMemoRequestQueryModel | None = None,
) -> list[SAPDebitMemoRequestResponseModel] | None
Get SAP debit memo requests as a list.
All matching debit memo requests are read (page by page, see iter_debit_memo_requests()) and returned at once. For very large result sets prefer iter_debit_memo_requests().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPDebitMemoRequestQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all debit memo requests). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPDebitMemoRequestResponseModel] | None
|
list[SAPDebitMemoRequestResponseModel] | None: The debit memo requests (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_debit_memo_request
¶
get_debit_memo_request(
request_id: str, expand_items: bool = True
) -> SAPDebitMemoRequestResponseModel | None
Get a single SAP debit memo request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
str
|
The debit memo request number, e.g. "70000012". |
required |
expand_items
|
bool
|
Whether to read the items as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPDebitMemoRequestResponseModel | None
|
SAPDebitMemoRequestResponseModel | None: The debit memo request or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_debit_memo_request
¶
update_debit_memo_request(
request_id: str,
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of an SAP debit memo request and of its items.
All changes are validated first and the items must belong to the debit memo request - otherwise nothing is changed. The items are changed first, the header last (see _update_odata_document()).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
str
|
The debit memo request number, e.g. "70000012". |
required |
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPDebitMemoRequestModel or OData property names. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per item number, e.g. {"10": {"RequestedQuantity": 1}} (snake case attribute names of SAPDebitMemoRequestItemModel or OData property names). Defaults to None (items unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the debit memo request (and its items) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_debit_memo_request
¶
Delete an SAP debit memo request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
str
|
The debit memo request number, e.g. "70000012". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the debit memo request has been deleted, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_billing_document_requests
¶
iter_billing_document_requests(
query: SAPBillingDocumentRequestQueryModel
| None = None,
) -> SAPODataIterator[
SAPBillingDocumentRequestResponseModel
]
Iterate over SAP billing document requests - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPBillingDocumentRequestQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all requests). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPBillingDocumentRequestResponseModel]
|
SAPODataIterator[SAPBillingDocumentRequestResponseModel]: The iterator over the billing document requests. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_billing_document_requests
¶
get_billing_document_requests(
query: SAPBillingDocumentRequestQueryModel
| None = None,
) -> list[SAPBillingDocumentRequestResponseModel] | None
Get SAP billing document requests as a list.
All matching requests are read (page by page, see iter_billing_document_requests()) and returned at once. For very large result sets prefer iter_billing_document_requests().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPBillingDocumentRequestQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all requests). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPBillingDocumentRequestResponseModel] | None
|
list[SAPBillingDocumentRequestResponseModel] | None: The billing document requests (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_billing_document_request
¶
get_billing_document_request(
request_id: str, expand_items: bool = True
) -> SAPBillingDocumentRequestResponseModel | None
Get a single SAP billing document request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
str
|
The billing document request number. |
required |
expand_items
|
bool
|
Whether to read the items as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPBillingDocumentRequestResponseModel | None
|
SAPBillingDocumentRequestResponseModel | None: The billing document request or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_billing_document_request
¶
Delete an SAP billing document request (that has not been billed yet).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
str
|
The billing document request number. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the billing document request has been deleted, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
reject_billing_document_request
¶
Reject an SAP billing document request - it will not be billed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
str
|
The billing document request number. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the billing document request has been rejected, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_billing_documents
¶
iter_billing_documents(
query: SAPBillingDocumentQueryModel | None = None,
) -> SAPODataIterator[SAPBillingDocumentResponseModel]
Iterate over SAP billing documents (customer invoices, credit / debit memos) - reading them page by page.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPBillingDocumentQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all billing documents). The sales orders (an item property) are resolved via the billing document items first. |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPBillingDocumentResponseModel]
|
SAPODataIterator[SAPBillingDocumentResponseModel]: The iterator over the billing documents. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_billing_document_items
¶
iter_billing_document_items(
query: SAPBillingDocumentItemQueryModel | None = None,
) -> SAPODataIterator[SAPBillingDocumentItemResponseModel]
Iterate over SAP billing document items - reading them page by page.
Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPBillingDocumentItemQueryModel | None
|
The search criteria, e.g. the sales orders the items were billed for. Defaults to None (all billing document items). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPBillingDocumentItemResponseModel]
|
SAPODataIterator[SAPBillingDocumentItemResponseModel]: The iterator over the billing document items. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_billing_documents
¶
get_billing_documents(
query: SAPBillingDocumentQueryModel | None = None,
) -> list[SAPBillingDocumentResponseModel] | None
Get SAP billing documents (customer invoices, credit / debit memos) as a list.
All matching billing documents are read (page by page, see iter_billing_documents()) and returned at once. For very large result sets prefer iter_billing_documents().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPBillingDocumentQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all billing documents). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPBillingDocumentResponseModel] | None
|
list[SAPBillingDocumentResponseModel] | None: The billing documents (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_billing_document
¶
get_billing_document(
billing_document_id: str, expand_items: bool = True
) -> SAPBillingDocumentResponseModel | None
Get a single SAP billing document (customer invoice, credit / debit memo).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
billing_document_id
|
str
|
The billing document number, e.g. "90000123". |
required |
expand_items
|
bool
|
Whether to read the items as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPBillingDocumentResponseModel | None
|
SAPBillingDocumentResponseModel | None: The billing document or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
cancel_billing_document
¶
Cancel an SAP billing document - SAP creates a cancellation billing document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
billing_document_id
|
str
|
The billing document number, e.g. "90000123". |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The result (including the cancellation document in "CancellationBillingDocument") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_billing_document_pdf
¶
Get the PDF (print form) of an SAP billing document - e.g. the invoice as sent to the customer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
billing_document_id
|
str
|
The billing document number, e.g. "90000123". |
required |
Returns:
| Type | Description |
|---|---|
bytes | None
|
bytes | None: The PDF document or None in case of an error (e.g. no output form configured). |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_outbound_delivery
¶
Create an SAP outbound delivery for sales order items.
Uses the OData V2 API API_OUTBOUND_DELIVERY_SRV (version 0002) with a deep insert. Material, plant and customer are copied from the sales order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
delivery
|
SAPOutboundDeliveryModel | dict
|
The data. A dictionary is validated against the SAPOutboundDeliveryModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created delivery as returned by SAP (including the number in "DeliveryDocument") or None in case of an error. |
Example
sap.create_outbound_delivery( ... {"shipping_point": "1010", "items": [{"reference_document": "413", "reference_document_item": "10"}]} ... )
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_outbound_deliveries
¶
iter_outbound_deliveries(
query: SAPOutboundDeliveryQueryModel | None = None,
) -> SAPODataIterator[SAPOutboundDeliveryResponseModel]
Iterate over SAP outbound deliveries - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPOutboundDeliveryQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all deliveries). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPOutboundDeliveryResponseModel]
|
SAPODataIterator[SAPOutboundDeliveryResponseModel]: The iterator over the outbound deliveries. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_outbound_delivery_items
¶
iter_outbound_delivery_items(
query: SAPOutboundDeliveryItemQueryModel | None = None,
) -> SAPODataIterator[SAPOutboundDeliveryItemResponseModel]
Iterate over SAP outbound delivery items - reading them page by page.
Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPOutboundDeliveryItemQueryModel | None
|
The search criteria, e.g. the sales orders of the items. Defaults to None (all items). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPOutboundDeliveryItemResponseModel]
|
SAPODataIterator[SAPOutboundDeliveryItemResponseModel]: The iterator over the delivery items. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_outbound_deliveries
¶
get_outbound_deliveries(
query: SAPOutboundDeliveryQueryModel | None = None,
) -> list[SAPOutboundDeliveryResponseModel] | None
Get SAP outbound deliveries as a list.
All matching deliveries are read (page by page, see iter_outbound_deliveries()) and returned at once. For very large result sets prefer iter_outbound_deliveries().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPOutboundDeliveryQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all deliveries). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPOutboundDeliveryResponseModel] | None
|
list[SAPOutboundDeliveryResponseModel] | None: The outbound deliveries (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_outbound_delivery
¶
get_outbound_delivery(
delivery_id: str, expand_items: bool = True
) -> SAPOutboundDeliveryResponseModel | None
Get a single SAP outbound delivery.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
delivery_id
|
str
|
The delivery number, e.g. "80000123". |
required |
expand_items
|
bool
|
Whether to read the items as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPOutboundDeliveryResponseModel | None
|
SAPOutboundDeliveryResponseModel | None: The outbound delivery or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_outbound_delivery
¶
update_outbound_delivery(
delivery_id: str,
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of an SAP outbound delivery and of its items.
All changes are validated first and the items must belong to the outbound delivery - otherwise nothing is changed. The items are changed first, the header last (see _update_odata_document()).
SAP allows to change e.g. the storage location (required for the goods issue), the batch or the delivery quantity of the items - items can also be referred to by their material.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
delivery_id
|
str
|
The outbound delivery number, e.g. "80000123". |
required |
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPOutboundDeliveryModel or OData property names. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per item number, e.g. {"10": {"StorageLocation": "0001"}} (snake case attribute names of SAPOutboundDeliveryItemModel or OData property names). Defaults to None (items unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the outbound delivery (and its items) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_outbound_delivery
¶
Delete an SAP outbound delivery (only possible before the goods issue).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
delivery_id
|
str
|
The delivery number, e.g. "80000123". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the delivery has been deleted, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
change_outbound_delivery_status
¶
change_outbound_delivery_status(
delivery_id: str,
action: SAPOutboundDeliveryAction | str,
parameters: dict | None = None,
) -> bool
Change the status of an SAP outbound delivery (e.g. pick all items or post the goods issue).
The delivery functions require the current ETag of the delivery (If-Match header), so the delivery is read first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
delivery_id
|
str
|
The delivery number, e.g. "80000123". |
required |
action
|
SAPOutboundDeliveryAction | str
|
The status action, e.g. SAPOutboundDeliveryAction.POST_GOODS_ISSUE - or the name of another function of the API, e.g. "PickOneItem". |
required |
parameters
|
dict | None
|
Additional parameters of the action with their OData names, e.g. {"ActualGoodsMovementDate": date(2026, 11, 2)} for ReverseGoodsIssue or {"DeliveryDocumentItem": "000010"} for item actions. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the status has been changed, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_inbound_delivery
¶
Create an SAP inbound delivery for purchase order items.
Uses the OData V2 API API_INBOUND_DELIVERY_SRV (version 0002) with a deep insert.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
delivery
|
SAPInboundDeliveryModel | dict
|
The data. A dictionary is validated against the SAPInboundDeliveryModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created delivery as returned by SAP (including the number in "DeliveryDocument") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_inbound_deliveries
¶
iter_inbound_deliveries(
query: SAPInboundDeliveryQueryModel | None = None,
) -> SAPODataIterator[SAPInboundDeliveryResponseModel]
Iterate over SAP inbound deliveries - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPInboundDeliveryQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all deliveries). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPInboundDeliveryResponseModel]
|
SAPODataIterator[SAPInboundDeliveryResponseModel]: The iterator over the inbound deliveries. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_inbound_delivery_items
¶
iter_inbound_delivery_items(
query: SAPInboundDeliveryItemQueryModel | None = None,
) -> SAPODataIterator[SAPInboundDeliveryItemResponseModel]
Iterate over SAP inbound delivery items - reading them page by page.
Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPInboundDeliveryItemQueryModel | None
|
The search criteria, e.g. the purchase orders of the items. Defaults to None (all items). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPInboundDeliveryItemResponseModel]
|
SAPODataIterator[SAPInboundDeliveryItemResponseModel]: The iterator over the delivery items. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_inbound_deliveries
¶
get_inbound_deliveries(
query: SAPInboundDeliveryQueryModel | None = None,
) -> list[SAPInboundDeliveryResponseModel] | None
Get SAP inbound deliveries as a list.
All matching deliveries are read (page by page, see iter_inbound_deliveries()) and returned at once. For very large result sets prefer iter_inbound_deliveries().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPInboundDeliveryQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all deliveries). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPInboundDeliveryResponseModel] | None
|
list[SAPInboundDeliveryResponseModel] | None: The inbound deliveries (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_inbound_delivery
¶
get_inbound_delivery(
delivery_id: str, expand_items: bool = True
) -> SAPInboundDeliveryResponseModel | None
Get a single SAP inbound delivery.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
delivery_id
|
str
|
The delivery number, e.g. "180000123". |
required |
expand_items
|
bool
|
Whether to read the items as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPInboundDeliveryResponseModel | None
|
SAPInboundDeliveryResponseModel | None: The inbound delivery or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_inbound_delivery
¶
update_inbound_delivery(
delivery_id: str,
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of an SAP inbound delivery and of its items.
All changes are validated first and the items must belong to the inbound delivery - otherwise nothing is changed. The items are changed first, the header last (see _update_odata_document()).
SAP allows to change e.g. the delivered quantity or the batch of the items (not their storage location) - items can also be referred to by their material.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
delivery_id
|
str
|
The inbound delivery number, e.g. "180000123". |
required |
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPInboundDeliveryModel or OData property names. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per item number, e.g. {"10": {"ActualDeliveryQuantity": 4}} (snake case attribute names of SAPInboundDeliveryItemModel or OData property names). Defaults to None (items unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the inbound delivery (and its items) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_inbound_delivery
¶
Delete an SAP inbound delivery (only possible before the goods receipt).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
delivery_id
|
str
|
The delivery number, e.g. "180000123". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the delivery has been deleted, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
change_inbound_delivery_status
¶
change_inbound_delivery_status(
delivery_id: str,
action: SAPInboundDeliveryAction | str,
parameters: dict | None = None,
) -> bool
Change the status of an SAP inbound delivery (e.g. put away all items or post the goods receipt).
The delivery functions require the current ETag of the delivery (If-Match header), so the delivery is read first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
delivery_id
|
str
|
The delivery number, e.g. "180000123". |
required |
action
|
SAPInboundDeliveryAction | str
|
The status action, e.g. SAPInboundDeliveryAction.POST_GOODS_RECEIPT - or the name of another function of the API, e.g. "PutawayOneItem". |
required |
parameters
|
dict | None
|
Additional parameters of the action with their OData names, e.g. {"ActualGoodsMovementDate": date(2026, 11, 2)} for ReverseGoodsReceipt or {"DeliveryDocumentItem": "000010"} for item actions. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the status has been changed, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_supplier_invoice
¶
Create (post or park) an SAP supplier invoice including its items.
Uses the OData V2 API API_SUPPLIERINVOICE_PROCESS_SRV with a deep insert (logistics invoice verification, like transaction MIRO). The invoice is posted directly unless it is parked (status "A") - a parked invoice is posted with post_supplier_invoice() or deleted with delete_supplier_invoice().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
invoice
|
SAPSupplierInvoiceModel | dict
|
The data. A dictionary is validated against the SAPSupplierInvoiceModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created invoice as returned by SAP (including "SupplierInvoice" and "FiscalYear") or None in case of an error. |
Example
sap.create_supplier_invoice( ... { ... "company_code": "1010", ... "document_date": "2026-11-02", ... "posting_date": "2026-11-02", ... "supplier_invoice_reference": "INV-2026-0815", ... "currency": "EUR", ... "gross_amount": "297.50", ... "tax_is_calculated_automatically": True, ... "purchase_order_items": [ ... {"purchase_order": "4500001540", "purchase_order_item": "10", "amount": "250", "tax_code": "V1"}, ... ], ... } ... )
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_supplier_invoices
¶
iter_supplier_invoices(
query: SAPSupplierInvoiceQueryModel | None = None,
) -> SAPODataIterator[SAPSupplierInvoiceResponseModel]
Iterate over SAP supplier invoices - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPSupplierInvoiceQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all invoices). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPSupplierInvoiceResponseModel]
|
SAPODataIterator[SAPSupplierInvoiceResponseModel]: The iterator over the supplier invoices. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_supplier_invoices
¶
get_supplier_invoices(
query: SAPSupplierInvoiceQueryModel | None = None,
) -> list[SAPSupplierInvoiceResponseModel] | None
Get SAP supplier invoices as a list.
All matching invoices are read (page by page, see iter_supplier_invoices()) and returned at once. For very large result sets prefer iter_supplier_invoices().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPSupplierInvoiceQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all invoices). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPSupplierInvoiceResponseModel] | None
|
list[SAPSupplierInvoiceResponseModel] | None: The supplier invoices (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_supplier_invoice
¶
get_supplier_invoice(
invoice_id: str,
fiscal_year: str,
expand_items: bool = True,
) -> SAPSupplierInvoiceResponseModel | None
Get a single SAP supplier invoice.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
invoice_id
|
str
|
The supplier invoice number, e.g. "5105600123". |
required |
fiscal_year
|
str
|
The fiscal year of the invoice, e.g. "2026". |
required |
expand_items
|
bool
|
Whether to read the purchase order and G/L account items as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPSupplierInvoiceResponseModel | None
|
SAPSupplierInvoiceResponseModel | None: The supplier invoice or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_supplier_invoice
¶
Delete an SAP supplier invoice - only parked or held invoices; posted ones are cancelled instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
invoice_id
|
str
|
The supplier invoice number, e.g. "5105600123". |
required |
fiscal_year
|
str
|
The fiscal year of the invoice, e.g. "2026". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the invoice has been deleted, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
cancel_supplier_invoice
¶
cancel_supplier_invoice(
invoice_id: str,
fiscal_year: str,
reversal_reason: str = "01",
posting_date: date | None = None,
) -> dict | None
Cancel (reverse) a posted SAP supplier invoice - SAP posts a reversal document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
invoice_id
|
str
|
The supplier invoice number, e.g. "5105600123". |
required |
fiscal_year
|
str
|
The fiscal year of the invoice, e.g. "2026". |
required |
reversal_reason
|
str
|
The reversal reason, e.g. "01" (reversal in current period, default) or "02" (reversal in closed period) - system specific. |
'01'
|
posting_date
|
date | None
|
The posting date of the reversal. Defaults to None (today). |
None
|
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The result (including the reversal document in "ReverseDocument" and "FiscalYear") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
release_supplier_invoice
¶
release_supplier_invoice(
invoice_id: str,
fiscal_year: str,
shift_discount_days: bool = False,
) -> bool
Release an SAP supplier invoice that is blocked for payment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
invoice_id
|
str
|
The supplier invoice number, e.g. "5105600123". |
required |
fiscal_year
|
str
|
The fiscal year of the invoice, e.g. "2026". |
required |
shift_discount_days
|
bool
|
Whether the cash discount days are shifted by the time the invoice was blocked. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the invoice has been released, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
post_supplier_invoice
¶
Post a parked SAP supplier invoice (see SAPSupplierInvoiceModel.status).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
invoice_id
|
str
|
The supplier invoice number, e.g. "5105600123". |
required |
fiscal_year
|
str
|
The fiscal year of the invoice, e.g. "2026". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the invoice has been posted, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_goods_movement
¶
Post an SAP goods movement (material document with its items) - e.g. a goods receipt for a purchase order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
movement
|
SAPGoodsMovementModel | dict
|
The data. A dictionary is validated against the SAPGoodsMovementModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created goods movement as returned by SAP (including "MaterialDocument" and "MaterialDocumentYear") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_goods_movements
¶
iter_goods_movements(
query: SAPGoodsMovementQueryModel | None = None,
) -> SAPODataIterator[SAPGoodsMovementResponseModel]
Iterate over SAP goods movements - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPGoodsMovementQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all goods movements). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPGoodsMovementResponseModel]
|
SAPODataIterator[SAPGoodsMovementResponseModel]: The iterator over the goods movements. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 | |
iter_goods_movement_items
¶
iter_goods_movement_items(
query: SAPGoodsMovementItemQueryModel | None = None,
) -> SAPODataIterator[SAPGoodsMovementItemResponseModel]
Iterate over SAP material document items - reading them page by page.
Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPGoodsMovementItemQueryModel | None
|
The search criteria, e.g. the purchase orders of the items. Defaults to None (all items). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPGoodsMovementItemResponseModel]
|
SAPODataIterator[SAPGoodsMovementItemResponseModel]: The iterator over the material document items. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_goods_movement_items
¶
get_goods_movement_items(
query: SAPGoodsMovementItemQueryModel | None = None,
) -> list[SAPGoodsMovementItemResponseModel] | None
Get SAP material document items as a list.
All matching items are read (page by page, see iter_goods_movement_items()) and returned at once.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPGoodsMovementItemQueryModel | None
|
The search criteria, e.g. the purchase orders and movement types of the items. Defaults to None (all items). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPGoodsMovementItemResponseModel] | None
|
list[SAPGoodsMovementItemResponseModel] | None: The material document items (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_goods_movements
¶
get_goods_movements(
query: SAPGoodsMovementQueryModel | None = None,
) -> list[SAPGoodsMovementResponseModel] | None
Get SAP goods movements as a list.
All matching goods movements are read (page by page, see iter_goods_movements()) and returned at once. For very large result sets prefer iter_goods_movements().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPGoodsMovementQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all goods movements). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPGoodsMovementResponseModel] | None
|
list[SAPGoodsMovementResponseModel] | None: The goods movements (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_goods_movement
¶
get_goods_movement(
document_year: str,
document: str,
expand_items: bool = True,
) -> SAPGoodsMovementResponseModel | None
Get a single SAP material document (goods movement).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
document_year
|
str
|
The year of the material document, e.g. "2026". |
required |
document
|
str
|
The material document number, e.g. "4900000123". |
required |
expand_items
|
bool
|
Whether to read the items as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPGoodsMovementResponseModel | None
|
SAPGoodsMovementResponseModel | None: The material document or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
cancel_goods_movement
¶
cancel_goods_movement(
document_year: str,
document: str,
item: str | None = None,
posting_date: date | None = None,
) -> dict | None
Cancel (reverse) an SAP material document or a single item of it.
SAP posts a reversal material document - the original document is not changed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
document_year
|
str
|
The year of the material document, e.g. "2026". |
required |
document
|
str
|
The material document number, e.g. "4900000123". |
required |
item
|
str | None
|
The item to cancel, e.g. "1". Defaults to None (cancel all items). |
None
|
posting_date
|
date | None
|
The posting date of the reversal. Defaults to None (today). |
None
|
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The reversal material document (header or item) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_material_stock
¶
iter_material_stock(
query: SAPMaterialStockQueryModel | None = None,
) -> SAPODataIterator[SAPMaterialStockResponseModel]
Iterate over the SAP material stock - reading it page by page from SAP.
Each entry is the stock of a material in one stock segment (plant, storage location, batch, stock type and special stock). Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPMaterialStockQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all stock except segments with a quantity of 0). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPMaterialStockResponseModel]
|
SAPODataIterator[SAPMaterialStockResponseModel]: The iterator over the stock segments. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_material_stock
¶
get_material_stock(
query: SAPMaterialStockQueryModel | None = None,
) -> list[SAPMaterialStockResponseModel] | None
Get the SAP material stock as a list of stock segments.
All matching stock segments are read (page by page, see iter_material_stock()) and returned at once. For very large result sets prefer iter_material_stock().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPMaterialStockQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all stock except segments with a quantity of 0). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPMaterialStockResponseModel] | None
|
list[SAPMaterialStockResponseModel] | None: The stock segments (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_maintenance_order_confirmation
¶
create_maintenance_order_confirmation(
confirmation: SAPMaintenanceOrderConfirmationModel
| dict,
) -> dict | None
Confirm work (time, final confirmation) on an SAP maintenance order operation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
confirmation
|
SAPMaintenanceOrderConfirmationModel | dict
|
The data. A dictionary is validated against the SAPMaintenanceOrderConfirmationModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created maintenance order confirmation as returned by SAP (including "MaintOrderConf" and "MaintOrderConfCntrValue") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_maintenance_order_confirmations
¶
iter_maintenance_order_confirmations(
query: SAPMaintenanceOrderConfirmationQueryModel
| None = None,
) -> SAPODataIterator[
SAPMaintenanceOrderConfirmationResponseModel
]
Iterate over SAP maintenance order confirmations - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPMaintenanceOrderConfirmationQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all maintenance order confirmations). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPMaintenanceOrderConfirmationResponseModel]
|
SAPODataIterator[SAPMaintenanceOrderConfirmationResponseModel]: The iterator over the maintenance order confirmations. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_maintenance_order_confirmations
¶
get_maintenance_order_confirmations(
query: SAPMaintenanceOrderConfirmationQueryModel
| None = None,
) -> (
list[SAPMaintenanceOrderConfirmationResponseModel]
| None
)
Get SAP maintenance order confirmations as a list.
All matching maintenance order confirmations are read (page by page, see iter_maintenance_order_confirmations()) and returned at once. For very large result sets prefer iter_maintenance_order_confirmations().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPMaintenanceOrderConfirmationQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all maintenance order confirmations). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPMaintenanceOrderConfirmationResponseModel] | None
|
list[SAPMaintenanceOrderConfirmationResponseModel] | None: The maintenance order confirmations (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_maintenance_order_confirmation
¶
get_maintenance_order_confirmation(
confirmation_id: str, counter: str
) -> SAPMaintenanceOrderConfirmationResponseModel | None
Get a single SAP maintenance order confirmation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
confirmation_id
|
str
|
The confirmation number (of the operation), e.g. "1234". |
required |
counter
|
str
|
The confirmation counter, e.g. "1". |
required |
Returns:
| Type | Description |
|---|---|
SAPMaintenanceOrderConfirmationResponseModel | None
|
SAPMaintenanceOrderConfirmationResponseModel | None: The confirmation or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
cancel_maintenance_order_confirmation
¶
Cancel an SAP maintenance order confirmation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
confirmation_id
|
str
|
The confirmation number (of the operation), e.g. "1234". |
required |
counter
|
str
|
The confirmation counter, e.g. "1". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the confirmation has been cancelled, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_maintenance_plan
¶
Create an SAP maintenance plan with its cycles and maintenance items (scheduling is started separately).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plan
|
SAPMaintenancePlanModel | dict
|
The data. A dictionary is validated against the SAPMaintenancePlanModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created maintenance plan as returned by SAP (including "MaintenancePlan") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_maintenance_plans
¶
iter_maintenance_plans(
query: SAPMaintenancePlanQueryModel | None = None,
) -> SAPODataIterator[SAPMaintenancePlanResponseModel]
Iterate over SAP maintenance plans - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPMaintenancePlanQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all maintenance plans). The planning plants, functional locations and equipments (item properties) are resolved via the maintenance items first. |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPMaintenancePlanResponseModel]
|
SAPODataIterator[SAPMaintenancePlanResponseModel]: The iterator over the maintenance plans. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_maintenance_plan_items
¶
iter_maintenance_plan_items(
query: SAPMaintenancePlanItemQueryModel | None = None,
) -> SAPODataIterator[SAPMaintenancePlanItemResponseModel]
Iterate over SAP maintenance items (of maintenance plans) - reading them page by page.
Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPMaintenancePlanItemQueryModel | None
|
The search criteria, e.g. the planning plants of the items. Defaults to None (all maintenance items). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPMaintenancePlanItemResponseModel]
|
SAPODataIterator[SAPMaintenancePlanItemResponseModel]: The iterator over the maintenance items. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_maintenance_plans
¶
get_maintenance_plans(
query: SAPMaintenancePlanQueryModel | None = None,
) -> list[SAPMaintenancePlanResponseModel] | None
Get SAP maintenance plans as a list.
All matching maintenance plans are read (page by page, see iter_maintenance_plans()) and returned at once. For very large result sets prefer iter_maintenance_plans().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPMaintenancePlanQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all maintenance plans). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPMaintenancePlanResponseModel] | None
|
list[SAPMaintenancePlanResponseModel] | None: The maintenance plans (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_maintenance_plan
¶
get_maintenance_plan(
plan_id: str, expand_items: bool = True
) -> SAPMaintenancePlanResponseModel | None
Get a single SAP maintenance plan.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plan_id
|
str
|
The maintenance plan number, e.g. "10". |
required |
expand_items
|
bool
|
Whether to read the cycles and items as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPMaintenancePlanResponseModel | None
|
SAPMaintenancePlanResponseModel | None: The maintenance plan or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_maintenance_plan
¶
update_maintenance_plan(
plan_id: str,
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of an SAP maintenance plan and of its items.
All changes are validated first and the items must belong to the maintenance plan - otherwise nothing is changed. The items are changed first, the header last (see _update_odata_document()).
The item numbers (MaintenanceItem) are unique in the SAP system, not positions in the plan. Cycles cannot be changed with this method.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plan_id
|
str
|
The maintenance plan number, e.g. "2". |
required |
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPMaintenancePlanModel or OData property names. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per item number, e.g. {"142": {"functional_location": "CW"}} (snake case attribute names of SAPMaintenancePlanItemModel or OData property names). Defaults to None (items unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the maintenance plan (and its items) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
change_maintenance_plan_status
¶
change_maintenance_plan_status(
plan_id: str,
action: SAPMaintenancePlanAction,
parameters: dict | None = None,
) -> bool
Change the status of an SAP maintenance plan (e.g. start scheduling, activate or deactivate).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plan_id
|
str
|
The maintenance plan number, e.g. "10". |
required |
action
|
SAPMaintenancePlanAction
|
The status action, e.g. SAPMaintenancePlanAction.START_SCHEDULING. |
required |
parameters
|
dict | None
|
Additional (optional) parameters of the action with their OData names. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the status has been changed, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_task_list
¶
Create an SAP maintenance task list including its operations.
Uses the OData V4 API API_MAINTENANCETASKLIST with a deep create, so the whole task list is created (and committed) in one request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_list
|
SAPTaskListModel | dict
|
The data. A dictionary is validated against the SAPTaskListModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created task list as returned by SAP (including "TaskListGroup" and "TaskListGroupCounter") or None in case of an error. |
Example
sap.create_task_list( ... { ... "task_list_type": "A", ... "description": "Quarterly pump inspection", ... "planning_plant": "1010", ... "operations": [ ... {"description": "Check pump seal", "control_key": "PM01", "work": 2, "work_unit": "H"}, ... ], ... } ... )
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_task_lists
¶
iter_task_lists(
query: SAPTaskListQueryModel | None = None,
) -> SAPODataIterator[SAPTaskListResponseModel]
Iterate over SAP maintenance task lists - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPTaskListQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all task lists). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPTaskListResponseModel]
|
SAPODataIterator[SAPTaskListResponseModel]: The iterator over the task lists. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_task_lists
¶
get_task_lists(
query: SAPTaskListQueryModel | None = None,
) -> list[SAPTaskListResponseModel] | None
Get SAP maintenance task lists as a list.
All matching task lists are read (page by page, see iter_task_lists()) and returned at once. For very large result sets prefer iter_task_lists().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPTaskListQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all task lists). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPTaskListResponseModel] | None
|
list[SAPTaskListResponseModel] | None: The task lists (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_task_list
¶
get_task_list(
task_list_type: str,
task_list_group: str,
task_list_group_counter: str,
expand_items: bool = True,
) -> SAPTaskListResponseModel | None
Get a single SAP maintenance task list.
Task lists with change numbers can have several versions - the latest version is returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_list_type
|
str
|
The task list type, e.g. "A" (general), "E" (equipment) or "T" (functional location). |
required |
task_list_group
|
str
|
The task list group, e.g. "PUMP-01". |
required |
task_list_group_counter
|
str
|
The task list group counter, e.g. "1". |
required |
expand_items
|
bool
|
Whether to read the operations as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPTaskListResponseModel | None
|
SAPTaskListResponseModel | None: The task list or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_task_list
¶
update_task_list(
task_list_type: str,
task_list_group: str,
task_list_group_counter: str,
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of an SAP maintenance task list (its latest version) and of its operations.
All changes are validated first and the operations must belong to the task list - otherwise nothing is changed. The operations are changed first, the header last (see _update_odata_document()).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_list_type
|
str
|
The task list type, e.g. "A" (general), "E" (equipment) or "T" (functional location). |
required |
task_list_group
|
str
|
The task list group, e.g. "PUMP-01". |
required |
task_list_group_counter
|
str
|
The task list group counter, e.g. "1". |
required |
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPTaskListModel or OData property names, e.g. {"description": "Monthly pump inspection"}. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per operation number, e.g. {"10": {"OperationText": "Replace seal"}} (snake case attribute names of SAPTaskListOperationModel or OData property names). Defaults to None (operations unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the task list (and its operations) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455 8456 8457 8458 8459 8460 8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 8495 8496 8497 8498 8499 8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 | |
create_planned_order
¶
Create an SAP planned order (components and capacities are determined by SAP).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order
|
SAPPlannedOrderModel | dict
|
The data. A dictionary is validated against the SAPPlannedOrderModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created planned order as returned by SAP (including "PlannedOrder") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_planned_orders
¶
iter_planned_orders(
query: SAPPlannedOrderQueryModel | None = None,
) -> SAPODataIterator[SAPPlannedOrderResponseModel]
Iterate over SAP planned orders - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPPlannedOrderQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all planned orders). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPPlannedOrderResponseModel]
|
SAPODataIterator[SAPPlannedOrderResponseModel]: The iterator over the planned orders. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_planned_orders
¶
get_planned_orders(
query: SAPPlannedOrderQueryModel | None = None,
) -> list[SAPPlannedOrderResponseModel] | None
Get SAP planned orders as a list.
All matching planned orders are read (page by page, see iter_planned_orders()) and returned at once. For very large result sets prefer iter_planned_orders().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPPlannedOrderQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all planned orders). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPPlannedOrderResponseModel] | None
|
list[SAPPlannedOrderResponseModel] | None: The planned orders (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_planned_order
¶
Get a single SAP planned order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
planned_order_id
|
str
|
The planned order number, e.g. "1234". |
required |
Returns:
| Type | Description |
|---|---|
SAPPlannedOrderResponseModel | None
|
SAPPlannedOrderResponseModel | None: The planned order or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_planned_order
¶
update_planned_order(
planned_order_id: str,
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of an SAP planned order and of its components.
All changes are validated first and the components must belong to the planned order - otherwise nothing is changed. The components are changed first, the header last (see _update_odata_document()).
Like in SAP GUI (MD12), changing a component makes the planned order firm (PlannedOrderIsFirm, PlannedOrderBOMIsFixed) - MRP no longer changes it. The required quantity of a component cannot be changed (SAP ignores it) - it follows the planned order quantity and the bill of material.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
planned_order_id
|
str
|
The planned order number, e.g. "103". |
required |
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPPlannedOrderModel or OData property names. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per component - BOM item number or material - e.g. {"0010": {"StorageLocation": "0001"}} or {"100-100": {"StorageLocation": "0001"}} (snake case attribute names of SAPPlannedOrderComponentModel or OData property names). Defaults to None (components unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the planned order (and its components) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_planned_order
¶
Delete an SAP planned order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
planned_order_id
|
str
|
The planned order number, e.g. "1234". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the planned order has been deleted, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
schedule_planned_order
¶
Schedule an SAP planned order (determine its dates based on the routing / capacities).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
planned_order_id
|
str
|
The planned order number, e.g. "1234". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the planned order has been scheduled, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_production_order
¶
create_production_order(
order: SAPProductionOrderModel | dict,
release: bool = False,
) -> SAPProductionOrderResponseModel | None
Create an SAP production order - optionally released right away.
SAP determines operations and components from the routing / production version and the bill of material. To create a production order from a planned order instead, see create_production_order_from_planned_order().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order
|
SAPProductionOrderModel | dict
|
The production order data. A dictionary is validated against the SAPProductionOrderModel (snake case attribute names or OData property names). |
required |
release
|
bool
|
Whether to release the production order after the creation. Defaults to False. |
False
|
Returns:
| Type | Description |
|---|---|
SAPProductionOrderResponseModel | None
|
SAPProductionOrderResponseModel | None: The production order as it is in SAP after the creation (and release) - read again, so the status shows whether the release was done (is_released) - or None in case of an error. If the release fails, the created order is still returned and last_error tells why it was not released. If it cannot be read again, the response of the creation is returned. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
convert_planned_order
¶
convert_planned_order(
planned_order_id: str,
order_type: str | None = None,
production_order_id: str | None = None,
release: bool = False,
) -> str | None
Convert an SAP planned order into a production order - optionally released right away.
SAP deletes the planned order after the conversion.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
planned_order_id
|
str
|
The planned order number, e.g. "1234". |
required |
order_type
|
str | None
|
The production order type, e.g. "PP01". Defaults to None (SAP default). |
None
|
production_order_id
|
str | None
|
The production order number - only for external number assignment. Defaults to None (SAP assigns the number). |
None
|
release
|
bool
|
Whether to release the production order after the conversion. Defaults to False. |
False
|
Returns:
| Type | Description |
|---|---|
str | None
|
str | None: The number of the production order or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 | |
create_production_order_from_planned_order
¶
create_production_order_from_planned_order(
planned_order: SAPPlannedOrderModel | dict,
order_type: str | None = None,
release: bool = True,
) -> str | None
Create a production order via a planned order: create the planned order, convert and release it.
This mirrors the typical SAP process (planning -> production). If the conversion fails, the planned order remains in SAP (an error with its number is logged).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
planned_order
|
SAPPlannedOrderModel | dict
|
The planned order data (see create_planned_order()). |
required |
order_type
|
str | None
|
The production order type, e.g. "PP01". Defaults to None (SAP default). |
None
|
release
|
bool
|
Whether to release the production order. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
str | None
|
str | None: The number of the production order or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_production_orders
¶
iter_production_orders(
query: SAPProductionOrderQueryModel | None = None,
) -> SAPODataIterator[SAPProductionOrderResponseModel]
Iterate over SAP production orders - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPProductionOrderQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all production orders). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPProductionOrderResponseModel]
|
SAPODataIterator[SAPProductionOrderResponseModel]: The iterator over the production orders. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_production_orders
¶
get_production_orders(
query: SAPProductionOrderQueryModel | None = None,
) -> list[SAPProductionOrderResponseModel] | None
Get SAP production orders as a list.
All matching production orders are read (page by page, see iter_production_orders()) and returned at once. For very large result sets prefer iter_production_orders().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPProductionOrderQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all production orders). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPProductionOrderResponseModel] | None
|
list[SAPProductionOrderResponseModel] | None: The production orders (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_production_order
¶
get_production_order(
order_id: str, expand_items: bool = True
) -> SAPProductionOrderResponseModel | None
Get a single SAP production order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The production order number, e.g. "1000123". |
required |
expand_items
|
bool
|
Whether to read the operations and statuses as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPProductionOrderResponseModel | None
|
SAPProductionOrderResponseModel | None: The production order or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_production_order
¶
update_production_order(
order_id: str,
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of an SAP production order and of its operations.
All changes are validated first and the operations must belong to the production order - otherwise nothing is changed. The operations are changed first, the header last (see _update_odata_document()).
The item changes are changes of the operations (A_ProductionOrderOperation_2), e.g. their short text, work center, quantity or standard values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The production order number, e.g. "1000185". |
required |
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPProductionOrderModel or OData property names. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per operation number, e.g. {"0010": {"WorkCenter": "1320"}} (snake case attribute names of SAPProductionOrderOperationModel or OData property names). Defaults to None (operations unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the production order (and its operations) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
8986 8987 8988 8989 8990 8991 8992 8993 8994 8995 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010 9011 9012 9013 9014 9015 9016 9017 9018 9019 9020 9021 9022 9023 9024 9025 9026 9027 9028 9029 9030 9031 9032 9033 9034 9035 9036 9037 9038 9039 9040 9041 9042 9043 9044 9045 9046 9047 9048 9049 9050 9051 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 | |
change_production_order_status
¶
change_production_order_status(
order_id: str,
action: SAPProductionOrderAction,
parameters: dict | None = None,
) -> bool
Change the status of an SAP production order (e.g. release, technically complete or close).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order_id
|
str
|
The production order number, e.g. "1000123". |
required |
action
|
SAPProductionOrderAction
|
The status action, e.g. SAPProductionOrderAction.RELEASE. |
required |
parameters
|
dict | None
|
Additional (optional) parameters of the action with their OData names. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the status has been changed, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_plants
¶
iter_plants(
query: SAPPlantQueryModel | None = None,
) -> SAPODataIterator[SAPPlantResponseModel]
Iterate over SAP plants - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPPlantQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all plants). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPPlantResponseModel]
|
SAPODataIterator[SAPPlantResponseModel]: The iterator over the plants. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_plants
¶
Get SAP plants as a list.
All matching plants are read (page by page, see iter_plants()) and returned at once. For very large result sets prefer iter_plants().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPPlantQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all plants). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPPlantResponseModel] | None
|
list[SAPPlantResponseModel] | None: The plants (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_plant
¶
Get a single SAP plant (master data).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plant_id
|
str
|
The plant, e.g. "1000". |
required |
Returns:
| Type | Description |
|---|---|
SAPPlantResponseModel | None
|
SAPPlantResponseModel | None: The plant or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_storage_locations
¶
iter_storage_locations(
query: SAPStorageLocationQueryModel | None = None,
) -> SAPODataIterator[SAPStorageLocationResponseModel]
Iterate over SAP storage locations - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPStorageLocationQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all storage locations). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPStorageLocationResponseModel]
|
SAPODataIterator[SAPStorageLocationResponseModel]: The iterator over the storage locations. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_storage_locations
¶
get_storage_locations(
query: SAPStorageLocationQueryModel | None = None,
) -> list[SAPStorageLocationResponseModel] | None
Get SAP storage locations as a list.
All matching storage locations are read (page by page, see iter_storage_locations()) and returned at once. For very large result sets prefer iter_storage_locations().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPStorageLocationQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all storage locations). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPStorageLocationResponseModel] | None
|
list[SAPStorageLocationResponseModel] | None: The storage locations (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_storage_location
¶
Get a single SAP storage location (master data).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plant
|
str
|
The plant, e.g. "1000". |
required |
storage_location
|
str
|
The storage location, e.g. "0001". |
required |
Returns:
| Type | Description |
|---|---|
SAPStorageLocationResponseModel | None
|
SAPStorageLocationResponseModel | None: The storage location or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_product
¶
Create an SAP product / material with its descriptions and plant data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product
|
SAPProductModel | dict
|
The data. A dictionary is validated against the SAPProductModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created product as returned by SAP (including "Product") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_products
¶
iter_products(
query: SAPProductQueryModel | None = None,
) -> SAPODataIterator[SAPProductResponseModel]
Iterate over SAP products - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPProductQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all products). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPProductResponseModel]
|
SAPODataIterator[SAPProductResponseModel]: The iterator over the products. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_products
¶
Get SAP products as a list.
All matching products are read (page by page, see iter_products()) and returned at once. For very large result sets prefer iter_products().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPProductQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all products). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPProductResponseModel] | None
|
list[SAPProductResponseModel] | None: The products (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_product
¶
Get a single SAP product (master data).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product_id
|
str
|
The product (material) number, e.g. "P-100". |
required |
expand_items
|
bool
|
Whether to read the descriptions, plant data (with storage locations) and valuation data as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPProductResponseModel | None
|
SAPProductResponseModel | None: The product or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_product
¶
Update individual fields of an SAP product (material) on client level.
The changes are validated with the field definitions of SAPProductModel (e.g. upper case codes, lengths). The product number and the product type cannot be changed. Descriptions and plant data are changed with update_product_description() and update_product_plant().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product_id
|
str
|
The product (material) number, e.g. "FG126". |
required |
changes
|
dict
|
The fields to change - snake case attribute names of SAPProductModel or OData property names, e.g. {"product_group": "L001", "GrossWeight": "12.5"}. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the product has been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_product_description
¶
Change the description of an SAP product (material) in one language.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product_id
|
str
|
The product (material) number, e.g. "FG126". |
required |
language
|
str
|
The language key of the (existing) description, e.g. "EN". |
required |
description
|
str
|
The new description, e.g. "Pump seal 50 mm". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the description has been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_product_plant
¶
Update individual fields of the plant data of an SAP product (material).
The product must already be extended to the plant. The changes are validated with the field definitions of SAPProductPlantModel.
Changes of fields that belong to a view which is not maintained for the plant may be ignored by SAP without an error (e.g. the purchasing group without a purchasing view). Setting a field of another view can also add that view (e.g. the MRP view with the MRP type) - its required fields can then not be cleared any more.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product_id
|
str
|
The product (material) number, e.g. "FG126". |
required |
plant
|
str
|
The plant, e.g. "1010". |
required |
changes
|
dict
|
The fields to change - snake case attribute names of SAPProductPlantModel or OData property names, e.g. {"mrp_type": "PD", "purchasing_group": "001"}. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the plant data has been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_product_plant
¶
Extend an existing SAP product (material) to a plant - with its storage locations in the plant.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product_id
|
str
|
The product (material) number, e.g. "KT-4402". |
required |
plant
|
SAPProductPlantModel | dict
|
The plant data (incl. storage locations). A dictionary is validated against the SAPProductPlantModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created plant data as returned by SAP or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_product_storage_location
¶
create_product_storage_location(
product_id: str,
plant: str,
storage_location: SAPProductStorageLocationModel | dict,
) -> dict | None
Extend an SAP product (material) that is already extended to the plant to a storage location.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product_id
|
str
|
The product (material) number, e.g. "EP-300". |
required |
plant
|
str
|
The plant the product is extended to, e.g. "3000". |
required |
storage_location
|
SAPProductStorageLocationModel | dict
|
The storage location data, e.g. {"StorageLocation": "0001"}. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created storage location data as returned by SAP or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_product_valuation
¶
create_product_valuation(
product_id: str,
valuation: SAPProductValuationModel | dict,
) -> dict | None
Create the valuation data of an SAP product (material) in a valuation area (plant).
The valuation data is needed to post stock of the product (goods receipts and issues).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product_id
|
str
|
The product (material) number, e.g. "KT-4402". |
required |
valuation
|
SAPProductValuationModel | dict
|
The valuation data (valuation area, valuation class, price control and price). |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created valuation data as returned by SAP or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_product
¶
Delete an SAP product (material) by setting its deletion flag (can be reset in SAP).
SAP does not delete master data physically - the deletion flag (on client level) marks the product for archiving.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product_id
|
str
|
The product (material) number, e.g. "FG126". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the deletion flag has been set, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
undelete_product
¶
Remove the deletion flag of an SAP product (material) - the reverse of delete_product().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product_id
|
str
|
The product (material) number, e.g. "FG126". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the deletion flag has been removed, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_material_bom
¶
Create a material BOM (bill of material) of a product in a plant with its items.
With the usage "4" (plant maintenance) the BOM is the spare parts list of all equipment with this product as construction type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bom
|
SAPMaterialBOMModel | dict
|
The data. A dictionary is validated against the SAPMaterialBOMModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created BOM as returned by SAP (including "BillOfMaterial") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_material_boms
¶
iter_material_boms(
query: SAPMaterialBOMQueryModel | None = None,
) -> SAPODataIterator[SAPMaterialBOMResponseModel]
Iterate over material BOMs - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPMaterialBOMQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all BOMs). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPMaterialBOMResponseModel]
|
SAPODataIterator[SAPMaterialBOMResponseModel]: The iterator over the BOMs. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_material_boms
¶
get_material_boms(
query: SAPMaterialBOMQueryModel | None = None,
) -> list[SAPMaterialBOMResponseModel] | None
Get material BOMs as a list - e.g. the spare parts list (usage "4") of a product.
All matching BOMs are read (page by page, see iter_material_boms()) and returned at once.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPMaterialBOMQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all BOMs). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPMaterialBOMResponseModel] | None
|
list[SAPMaterialBOMResponseModel] | None: The BOMs (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_material_bom
¶
update_material_bom(
material: str,
plant: str,
usage: str = "1",
alternative: str = "1",
changes: dict | None = None,
item_changes: dict[str, dict] | None = None,
) -> bool
Update individual fields of a material BOM (header) and of its items.
All changes are validated first and the items must belong to the BOM - otherwise nothing is changed. The items are changed first, the header last (see _update_odata_document()). BOMs with engineering change management (change numbers) are not supported.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
material
|
str
|
The material (product) of the BOM, e.g. "P-100". |
required |
plant
|
str
|
The plant of the BOM, e.g. "3000". |
required |
usage
|
str
|
The BOM usage, e.g. "1" (production) or "4" (plant maintenance / spare parts). Defaults to "1". |
'1'
|
alternative
|
str
|
The alternative BOM. Defaults to "1". |
'1'
|
changes
|
dict | None
|
The header fields to change - snake case attribute names of SAPMaterialBOMModel or OData property names, e.g. {"BOMHeaderText": "Pump assembly"}. Defaults to None (header unchanged). |
None
|
item_changes
|
dict[str, dict] | None
|
The changes per item number or component, e.g. {"0010": {"BillOfMaterialItemQuantity": 2}} or {"100-100": {"BillOfMaterialItemQuantity": 2}} (snake case attribute names of SAPMaterialBOMItemModel or OData property names). Defaults to None (items unchanged). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the BOM (and its items) have been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
9719 9720 9721 9722 9723 9724 9725 9726 9727 9728 9729 9730 9731 9732 9733 9734 9735 9736 9737 9738 9739 9740 9741 9742 9743 9744 9745 9746 9747 9748 9749 9750 9751 9752 9753 9754 9755 9756 9757 9758 9759 9760 9761 9762 9763 9764 9765 9766 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 9778 9779 9780 9781 9782 9783 9784 9785 9786 9787 9788 9789 9790 9791 9792 9793 9794 9795 9796 9797 9798 9799 9800 9801 9802 9803 | |
iter_production_versions
¶
iter_production_versions(
query: SAPProductionVersionQueryModel | None = None,
) -> SAPODataIterator[SAPProductionVersionResponseModel]
Iterate over SAP production versions - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPProductionVersionQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all production versions). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPProductionVersionResponseModel]
|
SAPODataIterator[SAPProductionVersionResponseModel]: The iterator over the production versions. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_production_versions
¶
get_production_versions(
query: SAPProductionVersionQueryModel | None = None,
) -> list[SAPProductionVersionResponseModel] | None
Get SAP production versions as a list.
All matching production versions are read (page by page, see iter_production_versions()) and returned at once. For very large result sets prefer iter_production_versions().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPProductionVersionQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all production versions). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPProductionVersionResponseModel] | None
|
list[SAPProductionVersionResponseModel] | None: The production versions (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_production_version
¶
get_production_version(
material: str, plant: str, production_version: str
) -> SAPProductionVersionResponseModel | None
Get a single SAP production version (master data).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
material
|
str
|
The material, e.g. "P-100". |
required |
plant
|
str
|
The plant, e.g. "1000". |
required |
production_version
|
str
|
The production version, e.g. "0001". |
required |
Returns:
| Type | Description |
|---|---|
SAPProductionVersionResponseModel | None
|
SAPProductionVersionResponseModel | None: The production version or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_work_centers
¶
iter_work_centers(
query: SAPWorkCenterQueryModel | None = None,
) -> SAPODataIterator[SAPWorkCenterResponseModel]
Iterate over SAP work centers - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPWorkCenterQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all work centers). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPWorkCenterResponseModel]
|
SAPODataIterator[SAPWorkCenterResponseModel]: The iterator over the work centers. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_work_centers
¶
get_work_centers(
query: SAPWorkCenterQueryModel | None = None,
) -> list[SAPWorkCenterResponseModel] | None
Get SAP work centers as a list.
All matching work centers are read (page by page, see iter_work_centers()) and returned at once. For very large result sets prefer iter_work_centers().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPWorkCenterQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all work centers). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPWorkCenterResponseModel] | None
|
list[SAPWorkCenterResponseModel] | None: The work centers (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_work_center
¶
Get a single SAP work center (master data).
The work center is identified by its code and plant (the OData key is an internal ID).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
work_center
|
str
|
The work center, e.g. "1904". |
required |
plant
|
str
|
The plant of the work center, e.g. "3000". |
required |
Returns:
| Type | Description |
|---|---|
SAPWorkCenterResponseModel | None
|
SAPWorkCenterResponseModel | None: The work center or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_equipment
¶
Create an SAP equipment (master data).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
equipment
|
SAPEquipmentModel | dict
|
The data. A dictionary is validated against the SAPEquipmentModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created equipment as returned by SAP (including "Equipment") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_equipments
¶
iter_equipments(
query: SAPEquipmentQueryModel | None = None,
) -> SAPODataIterator[SAPEquipmentResponseModel]
Iterate over SAP equipments - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPEquipmentQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all equipments). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPEquipmentResponseModel]
|
SAPODataIterator[SAPEquipmentResponseModel]: The iterator over the equipments. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_equipments
¶
get_equipments(
query: SAPEquipmentQueryModel | None = None,
) -> list[SAPEquipmentResponseModel] | None
Get SAP equipments as a list.
All matching equipments are read (page by page, see iter_equipments()) and returned at once. For very large result sets prefer iter_equipments().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPEquipmentQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all equipments). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPEquipmentResponseModel] | None
|
list[SAPEquipmentResponseModel] | None: The equipments (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_equipment
¶
Get a single SAP equipment (master data).
Equipment data is time dependent - the currently valid version (latest validity end date) is returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
equipment_id
|
str
|
The equipment number, e.g. "210100001". |
required |
Returns:
| Type | Description |
|---|---|
SAPEquipmentResponseModel | None
|
SAPEquipmentResponseModel | None: The equipment or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_equipment
¶
Update individual fields of an SAP equipment.
The changes are validated with the field definitions of SAPEquipmentModel. The equipment number, the category and the installation location (functional location, superordinate equipment) cannot be changed. Equipment data is time dependent: the currently valid time segment is changed.
SAP ignores changes of an equipment with a deletion flag (without an error) - remove the flag with undelete_equipment() first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
equipment_id
|
str
|
The equipment number, e.g. "210100001". |
required |
changes
|
dict
|
The fields to change - snake case attribute names of SAPEquipmentModel or OData property names, e.g. {"name": "Centrifugal pump P-100", "construction_year": "2019"}. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the equipment has been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_equipment
¶
Delete an SAP equipment by setting its deletion flag (can be reset in SAP).
SAP does not delete master data physically - the deletion flag marks it for archiving. Equipment data is time dependent: the flag is set for the currently valid time segment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
equipment_id
|
str
|
The equipment number, e.g. "210100001". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the deletion flag has been set, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
undelete_equipment
¶
Remove the deletion flag of an SAP equipment - the reverse of delete_equipment().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
equipment_id
|
str
|
The equipment number, e.g. "210100001". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the deletion flag has been removed, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_functional_location
¶
create_functional_location(
functional_location: SAPFunctionalLocationModel | dict,
) -> dict | None
Create an SAP functional location (master data).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
functional_location
|
SAPFunctionalLocationModel | dict
|
The data. A dictionary is validated against the SAPFunctionalLocationModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created functional location as returned by SAP (including the internal ID "FunctionalLocation") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_functional_locations
¶
iter_functional_locations(
query: SAPFunctionalLocationQueryModel | None = None,
) -> SAPODataIterator[SAPFunctionalLocationResponseModel]
Iterate over SAP functional locations - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPFunctionalLocationQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all functional locations). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPFunctionalLocationResponseModel]
|
SAPODataIterator[SAPFunctionalLocationResponseModel]: The iterator over the functional locations. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_functional_locations
¶
get_functional_locations(
query: SAPFunctionalLocationQueryModel | None = None,
) -> list[SAPFunctionalLocationResponseModel] | None
Get SAP functional locations as a list.
All matching functional locations are read (page by page, see iter_functional_locations()) and returned at once. For very large result sets prefer iter_functional_locations().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPFunctionalLocationQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all functional locations). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPFunctionalLocationResponseModel] | None
|
list[SAPFunctionalLocationResponseModel] | None: The functional locations (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_functional_location
¶
get_functional_location(
functional_location_id: str,
) -> SAPFunctionalLocationResponseModel | None
Get a single SAP functional location (master data).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
functional_location_id
|
str
|
The (internal) functional location ID - see also get_functional_locations() with a filter on "FunctionalLocationLabelName" to read by label. |
required |
Returns:
| Type | Description |
|---|---|
SAPFunctionalLocationResponseModel | None
|
SAPFunctionalLocationResponseModel | None: The functional location or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
update_functional_location
¶
Update individual fields of an SAP functional location.
The changes are validated with the field definitions of SAPFunctionalLocationModel. The label (the key) cannot be changed. SAP rejects changes of a functional location with a deletion flag - remove the flag with undelete_functional_location() first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
functional_location_id
|
str
|
The internal functional location ID, e.g. "1010-SP-PMP". |
required |
changes
|
dict
|
The fields to change - snake case attribute names of SAPFunctionalLocationModel or OData property names, e.g. {"name": "Pump station 1", "main_work_center": "RES-0100"}. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the functional location has been updated, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
delete_functional_location
¶
Delete an SAP functional location by setting its deletion flag (can be reset in SAP).
SAP does not delete master data physically - the deletion flag marks it for archiving.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
functional_location_id
|
str
|
The internal functional location ID, e.g. "1010-SP-PMP". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the deletion flag has been set, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
undelete_functional_location
¶
Remove the deletion flag of an SAP functional location - the reverse of delete_functional_location().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
functional_location_id
|
str
|
The internal functional location ID, e.g. "1010-SP-PMP". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the deletion flag has been removed, False in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
create_business_partner
¶
Create an SAP business partner (organization) with its addresses, roles and supplier / customer data.
With a supplier or customer role (e.g. FLVN00 / FLCU00) SAP also creates the supplier / customer - depending on the customizing of the grouping. The purchasing organization data (role FLVN01) and company code data of the supplier and the sales area data (role FLCU01) and company code data of the customer can be created in the same request. Business partners cannot be deleted with the API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
business_partner
|
SAPBusinessPartnerModel | dict
|
The data. A dictionary is validated against the SAPBusinessPartnerModel and can use either the snake case attribute names or the OData property names. |
required |
Returns:
| Type | Description |
|---|---|
dict | None
|
dict | None: The created business partner as returned by SAP (including "BusinessPartner") or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_business_partners
¶
iter_business_partners(
query: SAPBusinessPartnerQueryModel | None = None,
) -> SAPODataIterator[SAPBusinessPartnerResponseModel]
Iterate over SAP business partners - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPBusinessPartnerQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all business partners). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPBusinessPartnerResponseModel]
|
SAPODataIterator[SAPBusinessPartnerResponseModel]: The iterator over the business partners. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_business_partners
¶
get_business_partners(
query: SAPBusinessPartnerQueryModel | None = None,
) -> list[SAPBusinessPartnerResponseModel] | None
Get SAP business partners as a list.
All matching business partners are read (page by page, see iter_business_partners()) and returned at once. For very large result sets prefer iter_business_partners().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPBusinessPartnerQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all business partners). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPBusinessPartnerResponseModel] | None
|
list[SAPBusinessPartnerResponseModel] | None: The business partners (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_business_partner
¶
get_business_partner(
business_partner_id: str, expand_items: bool = True
) -> SAPBusinessPartnerResponseModel | None
Get a single SAP business partner (master data).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
business_partner_id
|
str
|
The business partner number, e.g. "10300001". |
required |
expand_items
|
bool
|
Whether to read the roles, addresses, supplier data (purchasing organizations, company codes) and customer data (sales areas, company codes) as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPBusinessPartnerResponseModel | None
|
SAPBusinessPartnerResponseModel | None: The business partner or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_customers
¶
iter_customers(
query: SAPCustomerQueryModel | None = None,
) -> SAPODataIterator[SAPBusinessPartnerResponseModel]
Iterate over SAP customers - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPCustomerQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all customers). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPBusinessPartnerResponseModel]
|
SAPODataIterator[SAPBusinessPartnerResponseModel]: The iterator over the customers. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_customers
¶
get_customers(
query: SAPCustomerQueryModel | None = None,
) -> list[SAPBusinessPartnerResponseModel] | None
Get SAP customers as a list.
All matching customers are read (page by page, see iter_customers()) and returned at once. For very large result sets prefer iter_customers().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPCustomerQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all customers). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPBusinessPartnerResponseModel] | None
|
list[SAPBusinessPartnerResponseModel] | None: The customers (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_customer
¶
get_customer(
customer_id: str, expand_items: bool = True
) -> SAPBusinessPartnerResponseModel | None
Get the business partner of a customer number (master data).
In S/4HANA customers are business partners with the customer role (customer / vendor integration). The customer number (as used in business documents and as business object ID of KNA1 business workspaces) is not necessarily the business partner number, so the business partner is looked up by its "Customer" property.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
customer_id
|
str
|
The customer number, e.g. "17100001". |
required |
expand_items
|
bool
|
Whether to read the roles, addresses, supplier data (purchasing organizations, company codes) and customer data (sales areas, company codes) as well - see get_business_partner(). Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPBusinessPartnerResponseModel | None
|
SAPBusinessPartnerResponseModel | None: The business partner or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_suppliers
¶
iter_suppliers(
query: SAPSupplierQueryModel | None = None,
) -> SAPODataIterator[SAPBusinessPartnerResponseModel]
Iterate over SAP suppliers - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPSupplierQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all suppliers). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPBusinessPartnerResponseModel]
|
SAPODataIterator[SAPBusinessPartnerResponseModel]: The iterator over the suppliers. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_suppliers
¶
get_suppliers(
query: SAPSupplierQueryModel | None = None,
) -> list[SAPBusinessPartnerResponseModel] | None
Get SAP suppliers as a list.
All matching suppliers are read (page by page, see iter_suppliers()) and returned at once. For very large result sets prefer iter_suppliers().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPSupplierQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all suppliers). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPBusinessPartnerResponseModel] | None
|
list[SAPBusinessPartnerResponseModel] | None: The suppliers (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_supplier
¶
get_supplier(
supplier_id: str, expand_items: bool = True
) -> SAPBusinessPartnerResponseModel | None
Get the business partner of a supplier number (master data).
In S/4HANA suppliers are business partners with the supplier role (customer / vendor integration). The supplier (vendor) number (as used in business documents and as business object ID of LFA1 business workspaces) is not necessarily the business partner number, so the business partner is looked up by its "Supplier" property.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
supplier_id
|
str
|
The supplier number, e.g. "17300001". |
required |
expand_items
|
bool
|
Whether to read the roles, addresses, supplier data (purchasing organizations, company codes) and customer data (sales areas, company codes) as well - see get_business_partner(). Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPBusinessPartnerResponseModel | None
|
SAPBusinessPartnerResponseModel | None: The business partner or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_company_codes
¶
iter_company_codes(
query: SAPCompanyCodeQueryModel | None = None,
) -> SAPODataIterator[SAPCompanyCodeResponseModel]
Iterate over SAP company codes - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPCompanyCodeQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all company codes). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPCompanyCodeResponseModel]
|
SAPODataIterator[SAPCompanyCodeResponseModel]: The iterator over the company codes. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_company_codes
¶
get_company_codes(
query: SAPCompanyCodeQueryModel | None = None,
) -> list[SAPCompanyCodeResponseModel] | None
Get SAP company codes as a list.
All matching company codes are read (page by page, see iter_company_codes()) and returned at once. For very large result sets prefer iter_company_codes().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPCompanyCodeQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all company codes). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPCompanyCodeResponseModel] | None
|
list[SAPCompanyCodeResponseModel] | None: The company codes (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_company_code
¶
Get a single SAP company code (master data).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
company_code
|
str
|
The company code, e.g. "1000". |
required |
Returns:
| Type | Description |
|---|---|
SAPCompanyCodeResponseModel | None
|
SAPCompanyCodeResponseModel | None: The company code or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_sales_organizations
¶
iter_sales_organizations(
query: SAPSalesOrganizationQueryModel | None = None,
) -> SAPODataIterator[SAPSalesOrganizationResponseModel]
Iterate over SAP sales organizations - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPSalesOrganizationQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all sales organizations). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPSalesOrganizationResponseModel]
|
SAPODataIterator[SAPSalesOrganizationResponseModel]: The iterator over the sales organizations. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_sales_organizations
¶
get_sales_organizations(
query: SAPSalesOrganizationQueryModel | None = None,
) -> list[SAPSalesOrganizationResponseModel] | None
Get SAP sales organizations as a list.
All matching sales organizations are read (page by page, see iter_sales_organizations()) and returned at once. For very large result sets prefer iter_sales_organizations().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPSalesOrganizationQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all sales organizations). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPSalesOrganizationResponseModel] | None
|
list[SAPSalesOrganizationResponseModel] | None: The sales organizations (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_sales_organization
¶
get_sales_organization(
sales_organization: str, expand_items: bool = True
) -> SAPSalesOrganizationResponseModel | None
Get a single SAP sales organization (master data).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sales_organization
|
str
|
The sales organization, e.g. "1000". |
required |
expand_items
|
bool
|
Whether to read the names as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPSalesOrganizationResponseModel | None
|
SAPSalesOrganizationResponseModel | None: The sales organization or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_purchasing_organizations
¶
iter_purchasing_organizations(
query: SAPPurchasingOrganizationQueryModel
| None = None,
) -> SAPODataIterator[
SAPPurchasingOrganizationResponseModel
]
Iterate over SAP purchasing organizations - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPPurchasingOrganizationQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all purchasing organizations). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPPurchasingOrganizationResponseModel]
|
SAPODataIterator[SAPPurchasingOrganizationResponseModel]: The iterator over the purchasing organizations. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_purchasing_organizations
¶
get_purchasing_organizations(
query: SAPPurchasingOrganizationQueryModel
| None = None,
) -> list[SAPPurchasingOrganizationResponseModel] | None
Get SAP purchasing organizations as a list.
All matching purchasing organizations are read (page by page, see iter_purchasing_organizations()) and returned at once. For very large result sets prefer iter_purchasing_organizations().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPPurchasingOrganizationQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all purchasing organizations). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPPurchasingOrganizationResponseModel] | None
|
list[SAPPurchasingOrganizationResponseModel] | None: The purchasing organizations (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_purchasing_organization
¶
get_purchasing_organization(
purchasing_organization: str,
) -> SAPPurchasingOrganizationResponseModel | None
Get a single SAP purchasing organization (master data).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
purchasing_organization
|
str
|
The purchasing organization, e.g. "1000". |
required |
Returns:
| Type | Description |
|---|---|
SAPPurchasingOrganizationResponseModel | None
|
SAPPurchasingOrganizationResponseModel | None: The purchasing organization or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_cost_centers
¶
iter_cost_centers(
query: SAPCostCenterQueryModel | None = None,
) -> SAPODataIterator[SAPCostCenterResponseModel]
Iterate over SAP cost centers - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPCostCenterQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all cost centers). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPCostCenterResponseModel]
|
SAPODataIterator[SAPCostCenterResponseModel]: The iterator over the cost centers. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_cost_centers
¶
get_cost_centers(
query: SAPCostCenterQueryModel | None = None,
) -> list[SAPCostCenterResponseModel] | None
Get SAP cost centers as a list.
All matching cost centers are read (page by page, see iter_cost_centers()) and returned at once. For very large result sets prefer iter_cost_centers().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPCostCenterQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all cost centers). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPCostCenterResponseModel] | None
|
list[SAPCostCenterResponseModel] | None: The cost centers (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_cost_center
¶
get_cost_center(
controlling_area: str,
cost_center: str,
expand_items: bool = True,
) -> SAPCostCenterResponseModel | None
Get a single SAP cost center (master data).
Cost center data is time dependent - the currently valid version (latest validity end date) is returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
controlling_area
|
str
|
The controlling area, e.g. "A000". |
required |
cost_center
|
str
|
The cost center, e.g. "0000004130". |
required |
expand_items
|
bool
|
Whether to read the names as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPCostCenterResponseModel | None
|
SAPCostCenterResponseModel | None: The cost center or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_profit_centers
¶
iter_profit_centers(
query: SAPProfitCenterQueryModel | None = None,
) -> SAPODataIterator[SAPProfitCenterResponseModel]
Iterate over SAP profit centers - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPProfitCenterQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all profit centers). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPProfitCenterResponseModel]
|
SAPODataIterator[SAPProfitCenterResponseModel]: The iterator over the profit centers. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_profit_centers
¶
get_profit_centers(
query: SAPProfitCenterQueryModel | None = None,
) -> list[SAPProfitCenterResponseModel] | None
Get SAP profit centers as a list.
All matching profit centers are read (page by page, see iter_profit_centers()) and returned at once. For very large result sets prefer iter_profit_centers().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPProfitCenterQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all profit centers). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPProfitCenterResponseModel] | None
|
list[SAPProfitCenterResponseModel] | None: The profit centers (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_profit_center
¶
get_profit_center(
controlling_area: str,
profit_center: str,
expand_items: bool = True,
) -> SAPProfitCenterResponseModel | None
Get a single SAP profit center (master data).
Profit center data is time dependent - the currently valid version (latest validity end date) is returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
controlling_area
|
str
|
The controlling area, e.g. "A000". |
required |
profit_center
|
str
|
The profit center, e.g. "YB101". |
required |
expand_items
|
bool
|
Whether to read the names as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPProfitCenterResponseModel | None
|
SAPProfitCenterResponseModel | None: The profit center or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
iter_gl_accounts
¶
iter_gl_accounts(
query: SAPGLAccountQueryModel | None = None,
) -> SAPODataIterator[SAPGLAccountResponseModel]
Iterate over SAP G/L accounts - reading them page by page from SAP.
Use this for large result sets: only one page is held in memory at a time. Errors are logged and end the iteration (check the 'failed' attribute of the returned iterator afterwards).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPGLAccountQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all G/L accounts). |
None
|
Returns:
| Type | Description |
|---|---|
SAPODataIterator[SAPGLAccountResponseModel]
|
SAPODataIterator[SAPGLAccountResponseModel]: The iterator over the G/L accounts. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_gl_accounts
¶
get_gl_accounts(
query: SAPGLAccountQueryModel | None = None,
) -> list[SAPGLAccountResponseModel] | None
Get SAP G/L accounts as a list.
All matching G/L accounts are read (page by page, see iter_gl_accounts()) and returned at once. For very large result sets prefer iter_gl_accounts().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
SAPGLAccountQueryModel | None
|
The search criteria (filters, sort order, limit, page size). Defaults to None (all G/L accounts). |
None
|
Returns:
| Type | Description |
|---|---|
list[SAPGLAccountResponseModel] | None
|
list[SAPGLAccountResponseModel] | None: The G/L accounts (an empty list if none match) or None in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_gl_account
¶
get_gl_account(
chart_of_accounts: str,
gl_account: str,
expand_items: bool = True,
) -> SAPGLAccountResponseModel | None
Get a single SAP G/L account (master data).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chart_of_accounts
|
str
|
The chart of accounts, e.g. "YCOA". |
required |
gl_account
|
str
|
The G/L account number, e.g. "0000400000". |
required |
expand_items
|
bool
|
Whether to read the names as well. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
SAPGLAccountResponseModel | None
|
SAPGLAccountResponseModel | None: The G/L account or None if it does not exist or in case of an error. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
get_oauth_scope
¶
Build the scope parameter of the OAuth token request from SAP_ODATA_SERVICES.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
services
|
list[str] | None
|
Names of the OData services in SAP_ODATA_SERVICES to get the scopes for. Defaults to None (all services in SAP_ODATA_SERVICES). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
Space-separated scope IDs, e.g. "ZAPI_MAINTENANCEORDER_0002 ZAPI_MAINTNOTIFICATION_0001". Services that are not registered or have no scope are skipped. |
Source code in packages/pyxecm/src/pyxecm_customizer/sap.py
parse_bearer_error
¶
Parse the OAuth error of an SAP response from its WWW-Authenticate header (RFC 6750).
With an OAuth access token SAP names the actual problem of a 401 / 403 in this header - the body is just a generic HTML error page then, e.g.: Bearer realm="...", error="insufficient_scope", error_description="...", scope="ZAPI_SALES_ORDER_SRV_0001"
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response
|
Response
|
The response of SAP. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, str] | None
|
dict[str, str] | None: The fields of the header (e.g. "error", "error_description", "scope") or None if the response has no Bearer error. |