mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-28 03:00:29 -04:00
feat(sap_s4hana): add get_material_document and fix supplier invoice key order (#4317)
* fix(sap_s4hana): require non-empty items in create_purchase_order Why: SAP A_PurchaseOrder POST silently fails or returns opaque errors without to_PurchaseOrderItem entries. Block already required this body but the tool marked it optional and didn't validate items presence — mismatched contract with create_sales_order / create_purchase_requisition. Also clarifies the deliveryDocument placeholder to show both outbound and inbound number ranges. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(sap_s4hana): add get_material_document and fix supplier invoice key order Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(sap_s4hana): align material doc key order in description and require purchase order body type --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -844,6 +844,36 @@ List material document headers (goods movements) from SAP S/4HANA Cloud (API_MAT
|
||||
| `status` | number | HTTP status code returned by SAP |
|
||||
| `data` | json | Array of A_MaterialDocumentHeader entities |
|
||||
|
||||
### `sap_s4hana_get_material_document`
|
||||
|
||||
Retrieve a single material document header by composite key (MaterialDocument + MaterialDocumentYear) from SAP S/4HANA Cloud (API_MATERIAL_DOCUMENT_SRV, A_MaterialDocumentHeader).
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `subdomain` | string | Yes | SAP BTP subaccount subdomain \(technical name of your subaccount, not the S/4HANA host\) |
|
||||
| `region` | string | Yes | BTP region \(e.g. eu10, us10\) |
|
||||
| `clientId` | string | Yes | OAuth client ID from the S/4HANA Communication Arrangement |
|
||||
| `clientSecret` | string | Yes | OAuth client secret from the S/4HANA Communication Arrangement |
|
||||
| `deploymentType` | string | No | Deployment type: cloud_public \(default\), cloud_private, or on_premise |
|
||||
| `authType` | string | No | Authentication type: oauth_client_credentials \(default\) or basic |
|
||||
| `baseUrl` | string | No | Base URL of the S/4HANA host \(Cloud Private / On-Premise\) |
|
||||
| `tokenUrl` | string | No | OAuth token URL \(Cloud Private / On-Premise + OAuth\) |
|
||||
| `username` | string | No | Username for HTTP Basic auth |
|
||||
| `password` | string | No | Password for HTTP Basic auth |
|
||||
| `materialDocumentYear` | string | Yes | MaterialDocumentYear \(4-character year, e.g., "2024"\) |
|
||||
| `materialDocument` | string | Yes | MaterialDocument key \(string, up to 10 characters\) |
|
||||
| `select` | string | No | Comma-separated fields to return \($select\) |
|
||||
| `expand` | string | No | Comma-separated navigation properties to expand \(e.g., "to_MaterialDocumentItem"\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `status` | number | HTTP status code returned by SAP |
|
||||
| `data` | json | A_MaterialDocumentHeader entity |
|
||||
|
||||
### `sap_s4hana_list_purchase_requisitions`
|
||||
|
||||
List purchase requisitions from SAP S/4HANA Cloud (API_PURCHASEREQ_PROCESS_SRV, A_PurchaseRequisitionHeader) with optional OData $filter, $top, $skip, $orderby, $select, $expand. Note: API_PURCHASEREQ_PROCESS_SRV is deprecated since S/4HANA Cloud Public Edition 2402; the successor is API_PURCHASEREQUISITION_2 (OData v4). This tool still works against tenants where the legacy service is enabled.
|
||||
@@ -1047,7 +1077,7 @@ Create a purchase order in SAP S/4HANA Cloud (API_PURCHASEORDER_PROCESS_SRV, A_P
|
||||
| `purchasingOrganization` | string | Yes | PurchasingOrganization \(4 chars\) |
|
||||
| `purchasingGroup` | string | Yes | PurchasingGroup \(3 chars\) |
|
||||
| `supplier` | string | Yes | Supplier business partner key \(up to 10 chars\) |
|
||||
| `body` | json | No | Additional A_PurchaseOrder fields and to_PurchaseOrderItem deep-insert items merged into the create payload \(e.g., \{"to_PurchaseOrderItem":\[\{"PurchaseOrderItem":"10","Material":"TG11","OrderQuantity":"5","Plant":"1010","PurchaseOrderQuantityUnit":"PC","NetPriceAmount":"100.00","DocumentCurrency":"USD"\}\]\}\). |
|
||||
| `body` | json | Yes | A_PurchaseOrder body containing to_PurchaseOrderItem deep-insert items \(required by SAP\) plus any additional header fields, e.g., \{"to_PurchaseOrderItem":\[\{"PurchaseOrderItem":"10","Material":"TG11","OrderQuantity":"5","Plant":"1010","PurchaseOrderQuantityUnit":"PC","NetPriceAmount":"100.00","DocumentCurrency":"USD"\}\]\}. |
|
||||
|
||||
#### Output
|
||||
|
||||
|
||||
@@ -925,6 +925,139 @@ Create a canvas pinned to a Slack channel as its resource hub
|
||||
| --------- | ---- | ----------- |
|
||||
| `canvas_id` | string | ID of the created channel canvas |
|
||||
|
||||
### `slack_get_canvas`
|
||||
|
||||
Get Slack canvas file metadata by canvas ID
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `authMethod` | string | No | Authentication method: oauth or bot_token |
|
||||
| `botToken` | string | No | Bot token for Custom Bot |
|
||||
| `canvasId` | string | Yes | Canvas file ID to retrieve \(e.g., F1234ABCD\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `canvas` | object | Canvas file information returned by Slack |
|
||||
| ↳ `id` | string | Unique canvas file identifier |
|
||||
| ↳ `created` | number | Unix timestamp when the canvas was created |
|
||||
| ↳ `timestamp` | number | Unix timestamp associated with the canvas |
|
||||
| ↳ `name` | string | Canvas file name |
|
||||
| ↳ `title` | string | Canvas title |
|
||||
| ↳ `mimetype` | string | MIME type of the canvas file |
|
||||
| ↳ `filetype` | string | Slack file type for the canvas |
|
||||
| ↳ `pretty_type` | string | Human-readable file type |
|
||||
| ↳ `user` | string | User ID of the canvas creator |
|
||||
| ↳ `editable` | boolean | Whether the canvas file is editable |
|
||||
| ↳ `size` | number | Canvas file size in bytes |
|
||||
| ↳ `mode` | string | File mode |
|
||||
| ↳ `is_external` | boolean | Whether the canvas is externally hosted |
|
||||
| ↳ `is_public` | boolean | Whether the canvas is public |
|
||||
| ↳ `url_private` | string | Private URL for the canvas file |
|
||||
| ↳ `url_private_download` | string | Private download URL for the canvas file |
|
||||
| ↳ `permalink` | string | Permanent URL for the canvas |
|
||||
| ↳ `channels` | array | Public channel IDs where the canvas appears |
|
||||
| ↳ `groups` | array | Private channel IDs where the canvas appears |
|
||||
| ↳ `ims` | array | Direct message IDs where the canvas appears |
|
||||
| ↳ `canvas_readtime` | number | Approximate read time for canvas content |
|
||||
| ↳ `is_channel_space` | boolean | Whether this canvas is linked to a channel |
|
||||
| ↳ `linked_channel_id` | string | Channel ID linked to this canvas |
|
||||
| ↳ `canvas_creator_id` | string | User ID of the canvas creator |
|
||||
|
||||
### `slack_list_canvases`
|
||||
|
||||
List Slack canvases available to the authenticated user or bot
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `authMethod` | string | No | Authentication method: oauth or bot_token |
|
||||
| `botToken` | string | No | Bot token for Custom Bot |
|
||||
| `channel` | string | No | Filter canvases appearing in a specific channel ID |
|
||||
| `count` | number | No | Number of canvases to return per page |
|
||||
| `page` | number | No | Page number to return |
|
||||
| `user` | string | No | Filter canvases created by a single user ID |
|
||||
| `tsFrom` | string | No | Filter canvases created after this Unix timestamp |
|
||||
| `tsTo` | string | No | Filter canvases created before this Unix timestamp |
|
||||
| `teamId` | string | No | Encoded team ID, required when using an org-level token |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `canvases` | array | Canvas file objects returned by Slack |
|
||||
| ↳ `id` | string | Unique canvas file identifier |
|
||||
| ↳ `created` | number | Unix timestamp when the canvas was created |
|
||||
| ↳ `timestamp` | number | Unix timestamp associated with the canvas |
|
||||
| ↳ `name` | string | Canvas file name |
|
||||
| ↳ `title` | string | Canvas title |
|
||||
| ↳ `mimetype` | string | MIME type of the canvas file |
|
||||
| ↳ `filetype` | string | Slack file type for the canvas |
|
||||
| ↳ `pretty_type` | string | Human-readable file type |
|
||||
| ↳ `user` | string | User ID of the canvas creator |
|
||||
| ↳ `editable` | boolean | Whether the canvas file is editable |
|
||||
| ↳ `size` | number | Canvas file size in bytes |
|
||||
| ↳ `mode` | string | File mode |
|
||||
| ↳ `is_external` | boolean | Whether the canvas is externally hosted |
|
||||
| ↳ `is_public` | boolean | Whether the canvas is public |
|
||||
| ↳ `url_private` | string | Private URL for the canvas file |
|
||||
| ↳ `url_private_download` | string | Private download URL for the canvas file |
|
||||
| ↳ `permalink` | string | Permanent URL for the canvas |
|
||||
| ↳ `channels` | array | Public channel IDs where the canvas appears |
|
||||
| ↳ `groups` | array | Private channel IDs where the canvas appears |
|
||||
| ↳ `ims` | array | Direct message IDs where the canvas appears |
|
||||
| ↳ `canvas_readtime` | number | Approximate read time for canvas content |
|
||||
| ↳ `is_channel_space` | boolean | Whether this canvas is linked to a channel |
|
||||
| ↳ `linked_channel_id` | string | Channel ID linked to this canvas |
|
||||
| ↳ `canvas_creator_id` | string | User ID of the canvas creator |
|
||||
| `paging` | object | Pagination information from Slack |
|
||||
| ↳ `count` | number | Number of items requested per page |
|
||||
| ↳ `total` | number | Total number of matching files |
|
||||
| ↳ `page` | number | Current page number |
|
||||
| ↳ `pages` | number | Total number of pages |
|
||||
|
||||
### `slack_lookup_canvas_sections`
|
||||
|
||||
Find Slack canvas section IDs matching criteria for later edits
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `authMethod` | string | No | Authentication method: oauth or bot_token |
|
||||
| `botToken` | string | No | Bot token for Custom Bot |
|
||||
| `canvasId` | string | Yes | Canvas ID to search \(e.g., F1234ABCD\) |
|
||||
| `criteria` | json | Yes | Section lookup criteria, such as \{"section_types":\["h1"\],"contains_text":"Roadmap"\} |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `sections` | array | Canvas sections matching the lookup criteria |
|
||||
| ↳ `id` | string | Canvas section identifier |
|
||||
|
||||
### `slack_delete_canvas`
|
||||
|
||||
Delete a Slack canvas by its canvas ID
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `authMethod` | string | No | Authentication method: oauth or bot_token |
|
||||
| `botToken` | string | No | Bot token for Custom Bot |
|
||||
| `canvasId` | string | Yes | Canvas ID to delete \(e.g., F1234ABCD\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `ok` | boolean | Whether Slack deleted the canvas successfully |
|
||||
|
||||
### `slack_create_conversation`
|
||||
|
||||
Create a new public or private channel in a Slack workspace.
|
||||
|
||||
@@ -11493,6 +11493,10 @@
|
||||
"name": "List Material Documents",
|
||||
"description": "List material document headers (goods movements) from SAP S/4HANA Cloud (API_MATERIAL_DOCUMENT_SRV, A_MaterialDocumentHeader) with optional OData $filter, $top, $skip, $orderby, $select, $expand."
|
||||
},
|
||||
{
|
||||
"name": "Get Material Document",
|
||||
"description": "Retrieve a single material document header by composite key (MaterialDocument + MaterialDocumentYear) from SAP S/4HANA Cloud (API_MATERIAL_DOCUMENT_SRV, A_MaterialDocumentHeader)."
|
||||
},
|
||||
{
|
||||
"name": "List Purchase Requisitions",
|
||||
"description": "List purchase requisitions from SAP S/4HANA Cloud (API_PURCHASEREQ_PROCESS_SRV, A_PurchaseRequisitionHeader) with optional OData $filter, $top, $skip, $orderby, $select, $expand. Note: API_PURCHASEREQ_PROCESS_SRV is deprecated since S/4HANA Cloud Public Edition 2402; the successor is API_PURCHASEREQUISITION_2 (OData v4). This tool still works against tenants where the legacy service is enabled."
|
||||
@@ -11538,7 +11542,7 @@
|
||||
"description": "Make an arbitrary OData v2 call against any SAP S/4HANA Cloud whitelisted Communication Scenario. Use when no dedicated tool exists for the entity. The proxy handles auth, CSRF, and OData unwrapping."
|
||||
}
|
||||
],
|
||||
"operationCount": 37,
|
||||
"operationCount": 38,
|
||||
"triggers": [],
|
||||
"triggerCount": 0,
|
||||
"authType": "none",
|
||||
@@ -12150,6 +12154,22 @@
|
||||
"name": "Create Channel Canvas",
|
||||
"description": "Create a canvas pinned to a Slack channel as its resource hub"
|
||||
},
|
||||
{
|
||||
"name": "Get Canvas Info",
|
||||
"description": "Get Slack canvas file metadata by canvas ID"
|
||||
},
|
||||
{
|
||||
"name": "List Canvases",
|
||||
"description": "List Slack canvases available to the authenticated user or bot"
|
||||
},
|
||||
{
|
||||
"name": "Lookup Canvas Sections",
|
||||
"description": "Find Slack canvas section IDs matching criteria for later edits"
|
||||
},
|
||||
{
|
||||
"name": "Delete Canvas",
|
||||
"description": "Delete a Slack canvas by its canvas ID"
|
||||
},
|
||||
{
|
||||
"name": "Create Conversation",
|
||||
"description": "Create a new public or private channel in a Slack workspace."
|
||||
@@ -12175,7 +12195,7 @@
|
||||
"description": "Publish a static view to a user"
|
||||
}
|
||||
],
|
||||
"operationCount": 25,
|
||||
"operationCount": 29,
|
||||
"triggers": [
|
||||
{
|
||||
"id": "slack_webhook",
|
||||
|
||||
@@ -48,6 +48,7 @@ export const SapS4HanaBlock: BlockConfig<SapProxyResponse> = {
|
||||
{ label: 'Update Product', id: 'sap_s4hana_update_product' },
|
||||
{ label: 'List Material Stock', id: 'sap_s4hana_list_material_stock' },
|
||||
{ label: 'List Material Documents', id: 'sap_s4hana_list_material_documents' },
|
||||
{ label: 'Get Material Document', id: 'sap_s4hana_get_material_document' },
|
||||
{ label: 'List Purchase Requisitions', id: 'sap_s4hana_list_purchase_requisitions' },
|
||||
{ label: 'Get Purchase Requisition', id: 'sap_s4hana_get_purchase_requisition' },
|
||||
{ label: 'Create Purchase Requisition', id: 'sap_s4hana_create_purchase_requisition' },
|
||||
@@ -189,6 +190,7 @@ export const SapS4HanaBlock: BlockConfig<SapProxyResponse> = {
|
||||
'sap_s4hana_get_product',
|
||||
'sap_s4hana_list_material_stock',
|
||||
'sap_s4hana_list_material_documents',
|
||||
'sap_s4hana_get_material_document',
|
||||
'sap_s4hana_list_purchase_requisitions',
|
||||
'sap_s4hana_get_purchase_requisition',
|
||||
'sap_s4hana_list_purchase_orders',
|
||||
@@ -225,6 +227,7 @@ export const SapS4HanaBlock: BlockConfig<SapProxyResponse> = {
|
||||
'sap_s4hana_get_product',
|
||||
'sap_s4hana_list_material_stock',
|
||||
'sap_s4hana_list_material_documents',
|
||||
'sap_s4hana_get_material_document',
|
||||
'sap_s4hana_list_purchase_requisitions',
|
||||
'sap_s4hana_get_purchase_requisition',
|
||||
'sap_s4hana_list_purchase_orders',
|
||||
@@ -417,7 +420,7 @@ export const SapS4HanaBlock: BlockConfig<SapProxyResponse> = {
|
||||
id: 'deliveryDocument',
|
||||
title: 'DeliveryDocument',
|
||||
type: 'short-input',
|
||||
placeholder: '80000000',
|
||||
placeholder: 'e.g., 80000000 (outbound) or 180000000 (inbound)',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: ['sap_s4hana_get_outbound_delivery', 'sap_s4hana_get_inbound_delivery'],
|
||||
@@ -556,6 +559,24 @@ export const SapS4HanaBlock: BlockConfig<SapProxyResponse> = {
|
||||
required: true,
|
||||
},
|
||||
|
||||
// Material Document: get
|
||||
{
|
||||
id: 'materialDocumentYear',
|
||||
title: 'MaterialDocumentYear',
|
||||
type: 'short-input',
|
||||
placeholder: '2024',
|
||||
condition: { field: 'operation', value: 'sap_s4hana_get_material_document' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'materialDocument',
|
||||
title: 'MaterialDocument',
|
||||
type: 'short-input',
|
||||
placeholder: '4900000000',
|
||||
condition: { field: 'operation', value: 'sap_s4hana_get_material_document' },
|
||||
required: true,
|
||||
},
|
||||
|
||||
// Supplier Invoice: get
|
||||
{
|
||||
id: 'supplierInvoice',
|
||||
@@ -844,6 +865,7 @@ export const SapS4HanaBlock: BlockConfig<SapProxyResponse> = {
|
||||
'sap_s4hana_update_product',
|
||||
'sap_s4hana_list_material_stock',
|
||||
'sap_s4hana_list_material_documents',
|
||||
'sap_s4hana_get_material_document',
|
||||
'sap_s4hana_list_purchase_requisitions',
|
||||
'sap_s4hana_get_purchase_requisition',
|
||||
'sap_s4hana_create_purchase_requisition',
|
||||
@@ -991,6 +1013,13 @@ export const SapS4HanaBlock: BlockConfig<SapProxyResponse> = {
|
||||
return { ...auth, ...listFields }
|
||||
case 'sap_s4hana_list_material_documents':
|
||||
return { ...auth, ...listFields }
|
||||
case 'sap_s4hana_get_material_document':
|
||||
return {
|
||||
...auth,
|
||||
...entityFields,
|
||||
materialDocumentYear: params.materialDocumentYear,
|
||||
materialDocument: params.materialDocument,
|
||||
}
|
||||
case 'sap_s4hana_list_purchase_requisitions':
|
||||
return { ...auth, ...listFields }
|
||||
case 'sap_s4hana_get_purchase_requisition':
|
||||
@@ -1124,6 +1153,8 @@ export const SapS4HanaBlock: BlockConfig<SapProxyResponse> = {
|
||||
purchaseOrderBody: { type: 'json', description: 'Items and additional A_PurchaseOrder fields' },
|
||||
supplierInvoice: { type: 'string', description: 'SupplierInvoice key' },
|
||||
fiscalYear: { type: 'string', description: 'FiscalYear (4-digit year)' },
|
||||
materialDocumentYear: { type: 'string', description: 'MaterialDocumentYear (4-digit year)' },
|
||||
materialDocument: { type: 'string', description: 'MaterialDocument key' },
|
||||
odataService: { type: 'string', description: 'OData service name' },
|
||||
odataPath: { type: 'string', description: 'OData entity path' },
|
||||
odataMethod: { type: 'string', description: 'HTTP method for OData call' },
|
||||
|
||||
@@ -2258,6 +2258,7 @@ import {
|
||||
getBusinessPartnerTool as sapS4HanaGetBusinessPartnerTool,
|
||||
getCustomerTool as sapS4HanaGetCustomerTool,
|
||||
getInboundDeliveryTool as sapS4HanaGetInboundDeliveryTool,
|
||||
getMaterialDocumentTool as sapS4HanaGetMaterialDocumentTool,
|
||||
getOutboundDeliveryTool as sapS4HanaGetOutboundDeliveryTool,
|
||||
getProductTool as sapS4HanaGetProductTool,
|
||||
getPurchaseOrderTool as sapS4HanaGetPurchaseOrderTool,
|
||||
@@ -5334,6 +5335,7 @@ export const tools: Record<string, ToolConfig> = {
|
||||
sap_s4hana_get_business_partner: sapS4HanaGetBusinessPartnerTool,
|
||||
sap_s4hana_get_customer: sapS4HanaGetCustomerTool,
|
||||
sap_s4hana_get_inbound_delivery: sapS4HanaGetInboundDeliveryTool,
|
||||
sap_s4hana_get_material_document: sapS4HanaGetMaterialDocumentTool,
|
||||
sap_s4hana_get_outbound_delivery: sapS4HanaGetOutboundDeliveryTool,
|
||||
sap_s4hana_get_product: sapS4HanaGetProductTool,
|
||||
sap_s4hana_get_purchase_order: sapS4HanaGetPurchaseOrderTool,
|
||||
|
||||
@@ -107,10 +107,10 @@ export const createPurchaseOrderTool: ToolConfig<CreatePurchaseOrderParams, SapP
|
||||
},
|
||||
body: {
|
||||
type: 'json',
|
||||
required: false,
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Additional A_PurchaseOrder fields and to_PurchaseOrderItem deep-insert items merged into the create payload (e.g., {"to_PurchaseOrderItem":[{"PurchaseOrderItem":"10","Material":"TG11","OrderQuantity":"5","Plant":"1010","PurchaseOrderQuantityUnit":"PC","NetPriceAmount":"100.00","DocumentCurrency":"USD"}]}).',
|
||||
'A_PurchaseOrder body containing to_PurchaseOrderItem deep-insert items (required by SAP) plus any additional header fields, e.g., {"to_PurchaseOrderItem":[{"PurchaseOrderItem":"10","Material":"TG11","OrderQuantity":"5","Plant":"1010","PurchaseOrderQuantityUnit":"PC","NetPriceAmount":"100.00","DocumentCurrency":"USD"}]}.',
|
||||
},
|
||||
},
|
||||
request: {
|
||||
@@ -119,6 +119,12 @@ export const createPurchaseOrderTool: ToolConfig<CreatePurchaseOrderParams, SapP
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => {
|
||||
const extra = parseJsonInput<Record<string, unknown>>(params.body, 'body') ?? {}
|
||||
const items = Array.isArray(extra.to_PurchaseOrderItem) ? extra.to_PurchaseOrderItem : null
|
||||
if (!items || items.length === 0) {
|
||||
throw new Error(
|
||||
'body must include a non-empty "to_PurchaseOrderItem" array of purchase order line items'
|
||||
)
|
||||
}
|
||||
const payload: Record<string, unknown> = {
|
||||
...extra,
|
||||
PurchaseOrderType: params.purchaseOrderType,
|
||||
|
||||
122
apps/sim/tools/sap_s4hana/get_material_document.ts
Normal file
122
apps/sim/tools/sap_s4hana/get_material_document.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import type { GetMaterialDocumentParams, SapProxyResponse } from '@/tools/sap_s4hana/types'
|
||||
import {
|
||||
baseProxyBody,
|
||||
buildEntityQuery,
|
||||
quoteOdataKey,
|
||||
SAP_PROXY_URL,
|
||||
transformSapProxyResponse,
|
||||
} from '@/tools/sap_s4hana/utils'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const getMaterialDocumentTool: ToolConfig<GetMaterialDocumentParams, SapProxyResponse> = {
|
||||
id: 'sap_s4hana_get_material_document',
|
||||
name: 'SAP S/4HANA Get Material Document',
|
||||
description:
|
||||
'Retrieve a single material document header by composite key (MaterialDocument + MaterialDocumentYear) from SAP S/4HANA Cloud (API_MATERIAL_DOCUMENT_SRV, A_MaterialDocumentHeader).',
|
||||
version: '1.0.0',
|
||||
params: {
|
||||
subdomain: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description:
|
||||
'SAP BTP subaccount subdomain (technical name of your subaccount, not the S/4HANA host)',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'BTP region (e.g. eu10, us10)',
|
||||
},
|
||||
clientId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'OAuth client ID from the S/4HANA Communication Arrangement',
|
||||
},
|
||||
clientSecret: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'OAuth client secret from the S/4HANA Communication Arrangement',
|
||||
},
|
||||
deploymentType: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Deployment type: cloud_public (default), cloud_private, or on_premise',
|
||||
},
|
||||
authType: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Authentication type: oauth_client_credentials (default) or basic',
|
||||
},
|
||||
baseUrl: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Base URL of the S/4HANA host (Cloud Private / On-Premise)',
|
||||
},
|
||||
tokenUrl: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'OAuth token URL (Cloud Private / On-Premise + OAuth)',
|
||||
},
|
||||
username: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Username for HTTP Basic auth',
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Password for HTTP Basic auth',
|
||||
},
|
||||
materialDocumentYear: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'MaterialDocumentYear (4-character year, e.g., "2024")',
|
||||
},
|
||||
materialDocument: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'MaterialDocument key (string, up to 10 characters)',
|
||||
},
|
||||
select: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated fields to return ($select)',
|
||||
},
|
||||
expand: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Comma-separated navigation properties to expand (e.g., "to_MaterialDocumentItem")',
|
||||
},
|
||||
},
|
||||
request: {
|
||||
url: SAP_PROXY_URL,
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
...baseProxyBody(params),
|
||||
service: 'API_MATERIAL_DOCUMENT_SRV',
|
||||
path: `/A_MaterialDocumentHeader(MaterialDocument=${quoteOdataKey(params.materialDocument)},MaterialDocumentYear=${quoteOdataKey(params.materialDocumentYear)})`,
|
||||
method: 'GET',
|
||||
query: buildEntityQuery(params),
|
||||
}),
|
||||
},
|
||||
transformResponse: transformSapProxyResponse,
|
||||
outputs: {
|
||||
status: { type: 'number', description: 'HTTP status code returned by SAP' },
|
||||
data: { type: 'json', description: 'A_MaterialDocumentHeader entity' },
|
||||
},
|
||||
}
|
||||
@@ -108,7 +108,7 @@ export const getSupplierInvoiceTool: ToolConfig<GetSupplierInvoiceParams, SapPro
|
||||
body: (params) => ({
|
||||
...baseProxyBody(params),
|
||||
service: 'API_SUPPLIERINVOICE_PROCESS_SRV',
|
||||
path: `/A_SupplierInvoice(SupplierInvoice=${quoteOdataKey(params.supplierInvoice)},FiscalYear=${quoteOdataKey(params.fiscalYear)})`,
|
||||
path: `/A_SupplierInvoice(FiscalYear=${quoteOdataKey(params.fiscalYear)},SupplierInvoice=${quoteOdataKey(params.supplierInvoice)})`,
|
||||
method: 'GET',
|
||||
query: buildEntityQuery(params),
|
||||
}),
|
||||
|
||||
@@ -7,6 +7,7 @@ export { getBillingDocumentTool } from '@/tools/sap_s4hana/get_billing_document'
|
||||
export { getBusinessPartnerTool } from '@/tools/sap_s4hana/get_business_partner'
|
||||
export { getCustomerTool } from '@/tools/sap_s4hana/get_customer'
|
||||
export { getInboundDeliveryTool } from '@/tools/sap_s4hana/get_inbound_delivery'
|
||||
export { getMaterialDocumentTool } from '@/tools/sap_s4hana/get_material_document'
|
||||
export { getOutboundDeliveryTool } from '@/tools/sap_s4hana/get_outbound_delivery'
|
||||
export { getProductTool } from '@/tools/sap_s4hana/get_product'
|
||||
export { getPurchaseOrderTool } from '@/tools/sap_s4hana/get_purchase_order'
|
||||
|
||||
@@ -110,7 +110,7 @@ export interface CreatePurchaseOrderParams extends SapBaseParams {
|
||||
purchasingOrganization: string
|
||||
purchasingGroup: string
|
||||
supplier: string
|
||||
body?: Record<string, unknown> | string
|
||||
body: Record<string, unknown> | string
|
||||
}
|
||||
|
||||
export interface ListSupplierInvoicesParams extends SapBaseParams {
|
||||
@@ -228,6 +228,13 @@ export interface GetInboundDeliveryParams extends SapBaseParams {
|
||||
expand?: string
|
||||
}
|
||||
|
||||
export interface GetMaterialDocumentParams extends SapBaseParams {
|
||||
materialDocumentYear: string
|
||||
materialDocument: string
|
||||
select?: string
|
||||
expand?: string
|
||||
}
|
||||
|
||||
export interface ListMaterialDocumentsParams extends SapBaseParams {
|
||||
filter?: string
|
||||
top?: number
|
||||
|
||||
Reference in New Issue
Block a user