Skip to content

Commit 46872ca

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
feat(oracle-fusion-scm): add supply chain integration
1 parent 29d3eee commit 46872ca

87 files changed

Lines changed: 8490 additions & 8 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎apps/docs/components/ui/icon-mapping.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
480480
onedrive: MicrosoftOneDriveIcon,
481481
onepassword: OnePasswordIcon,
482482
openai: OpenAIIcon,
483+
oracle_fusion_scm: NetSuiteIcon,
483484
outlook: OutlookIcon,
484485
pagerduty: PagerDutyIcon,
485486
parallel_ai: ParallelIcon,

‎apps/docs/content/docs/integrations/meta.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@
187187
"onedrive",
188188
"onepassword",
189189
"openai",
190+
"oracle_fusion_scm",
190191
"outlook",
191192
"pagerduty",
192193
"parallel_ai",

‎apps/docs/content/docs/integrations/oracle_fusion_scm.mdx‎

Lines changed: 953 additions & 0 deletions
Large diffs are not rendered by default.

‎apps/sim/blocks/blocks/oracle_fusion_scm.ts‎

Lines changed: 1056 additions & 0 deletions
Large diffs are not rendered by default.

‎apps/sim/blocks/registry-maps.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ import { MSSQLBlock, MSSQLBlockMeta } from '@/blocks/blocks/mssql'
237237
import { MySQLBlock, MySQLBlockMeta } from '@/blocks/blocks/mysql'
238238
import { Neo4jBlock, Neo4jBlockMeta } from '@/blocks/blocks/neo4j'
239239
import { NetSuiteBlock, NetSuiteBlockMeta } from '@/blocks/blocks/netsuite'
240+
import { OracleFusionScmBlock, OracleFusionScmBlockMeta } from '@/blocks/blocks/oracle_fusion_scm'
240241
import { NeverBounceBlock, NeverBounceBlockMeta } from '@/blocks/blocks/neverbounce'
241242
import { NewRelicBlock, NewRelicBlockMeta } from '@/blocks/blocks/new_relic'
242243
import { NoteBlock } from '@/blocks/blocks/note'
@@ -584,6 +585,7 @@ export const BLOCK_REGISTRY: Record<string, BlockConfig> = {
584585
mysql: MySQLBlock,
585586
neo4j: Neo4jBlock,
586587
netsuite: NetSuiteBlock,
588+
oracle_fusion_scm: OracleFusionScmBlock,
587589
new_relic: NewRelicBlock,
588590
note: NoteBlock,
589591
notion: NotionBlock,
@@ -905,6 +907,7 @@ export const BLOCK_META_REGISTRY: Record<string, BlockMeta> = {
905907
mysql: MySQLBlockMeta,
906908
neo4j: Neo4jBlockMeta,
907909
netsuite: NetSuiteBlockMeta,
910+
oracle_fusion_scm: OracleFusionScmBlockMeta,
908911
neverbounce: NeverBounceBlockMeta,
909912
new_relic: NewRelicBlockMeta,
910913
notion: NotionBlockMeta,

‎apps/sim/lib/copilot/generated/docs-manifest.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ export const DOCS_MANIFEST: readonly string[] = [
243243
'integrations/onedrive.mdx',
244244
'integrations/onepassword.mdx',
245245
'integrations/openai.mdx',
246+
'integrations/oracle_fusion_scm.mdx',
246247
'integrations/outlook.mdx',
247248
'integrations/pagerduty.mdx',
248249
'integrations/parallel_ai.mdx',

‎apps/sim/lib/integrations/icon-mapping.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
462462
okta: OktaIcon,
463463
onedrive: MicrosoftOneDriveIcon,
464464
onepassword: OnePasswordIcon,
465+
oracle_fusion_scm: NetSuiteIcon,
465466
outlook: OutlookIcon,
466467
pagerduty: PagerDutyIcon,
467468
parallel_ai: ParallelIcon,
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { OracleFusionProviderError } from '@/lib/internal/oracle-fusion/errors'
2+
import {
3+
executeOracleFusionScmReadOperation,
4+
isOracleFusionScmReadToolId,
5+
executeOracleFusionScmUpdateItem,
6+
executeOracleFusionScmCreateSupplyRequest,
7+
executeOracleFusionScmUpdateSupplyRequest,
8+
executeOracleFusionScmUpdateTransferOrder,
9+
executeOracleFusionScmUpdateTransferOrderLine,
10+
executeOracleFusionScmCreateManufacturingWorkOrder,
11+
executeOracleFusionScmUpdateManufacturingWorkOrder,
12+
executeOracleFusionScmCreateMaintenanceWorkOrder,
13+
executeOracleFusionScmUpdateMaintenanceWorkOrder,
14+
executeOracleFusionScmCreateSalesOrder,
15+
executeOracleFusionScmUpdateSalesOrder,
16+
executeOracleFusionScmDeleteSalesOrder,
17+
executeOracleFusionScmPickReleaseShipmentLines,
18+
executeOracleFusionScmConfirmQuickShipLines,
19+
} from '@/lib/internal/oracle-fusion-scm/operations'
20+
import type { InternalToolOperationHandler } from '@/lib/internal/tool-operations/types'
21+
22+
export const executeOracleFusionScmTool: InternalToolOperationHandler = async ({
23+
toolId,
24+
input,
25+
signal,
26+
}) => {
27+
signal?.throwIfAborted()
28+
try {
29+
if (isOracleFusionScmReadToolId(toolId)) {
30+
return Response.json(await executeOracleFusionScmReadOperation(toolId, input, signal))
31+
}
32+
switch (toolId) {
33+
case 'oracle_fusion_scm_update_item':
34+
return Response.json(await executeOracleFusionScmUpdateItem(input, signal))
35+
case 'oracle_fusion_scm_create_supply_request':
36+
return Response.json(await executeOracleFusionScmCreateSupplyRequest(input, signal))
37+
case 'oracle_fusion_scm_update_supply_request':
38+
return Response.json(await executeOracleFusionScmUpdateSupplyRequest(input, signal))
39+
case 'oracle_fusion_scm_update_transfer_order':
40+
return Response.json(await executeOracleFusionScmUpdateTransferOrder(input, signal))
41+
case 'oracle_fusion_scm_update_transfer_order_line':
42+
return Response.json(await executeOracleFusionScmUpdateTransferOrderLine(input, signal))
43+
case 'oracle_fusion_scm_create_manufacturing_work_order':
44+
return Response.json(await executeOracleFusionScmCreateManufacturingWorkOrder(input, signal))
45+
case 'oracle_fusion_scm_update_manufacturing_work_order':
46+
return Response.json(await executeOracleFusionScmUpdateManufacturingWorkOrder(input, signal))
47+
case 'oracle_fusion_scm_create_maintenance_work_order':
48+
return Response.json(await executeOracleFusionScmCreateMaintenanceWorkOrder(input, signal))
49+
case 'oracle_fusion_scm_update_maintenance_work_order':
50+
return Response.json(await executeOracleFusionScmUpdateMaintenanceWorkOrder(input, signal))
51+
case 'oracle_fusion_scm_create_sales_order':
52+
return Response.json(await executeOracleFusionScmCreateSalesOrder(input, signal))
53+
case 'oracle_fusion_scm_update_sales_order':
54+
return Response.json(await executeOracleFusionScmUpdateSalesOrder(input, signal))
55+
case 'oracle_fusion_scm_delete_sales_order':
56+
return Response.json(await executeOracleFusionScmDeleteSalesOrder(input, signal))
57+
case 'oracle_fusion_scm_pick_release_shipment_lines':
58+
return Response.json(await executeOracleFusionScmPickReleaseShipmentLines(input, signal))
59+
case 'oracle_fusion_scm_confirm_quick_ship_lines':
60+
return Response.json(await executeOracleFusionScmConfirmQuickShipLines(input, signal))
61+
default:
62+
return Response.json({ success: false, output: {}, error: 'Unsupported Oracle Fusion SCM tool' }, { status: 500 })
63+
}
64+
} catch (error) {
65+
signal?.throwIfAborted()
66+
if (error instanceof OracleFusionProviderError) {
67+
return Response.json(
68+
{ success: false, output: {}, error: error.message },
69+
{ status: error.status }
70+
)
71+
}
72+
const validationFailure = error instanceof Error && error.name === 'ZodError'
73+
return Response.json(
74+
{
75+
success: false,
76+
output: {},
77+
error: validationFailure
78+
? 'Invalid Oracle Fusion SCM input'
79+
: 'Oracle Fusion SCM request failed',
80+
},
81+
{ status: validationFailure ? 400 : 500 }
82+
)
83+
}
84+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { z } from 'zod'
2+
import { requestOracleFusionJson } from '@/lib/internal/oracle-fusion/client'
3+
import { unexpectedOracleFusionScmResponse } from '@/lib/internal/oracle-fusion-scm/operations/read-resource'
4+
import { oracleFusionScmMutationInputSchema } from '@/lib/internal/oracle-fusion-scm/schema'
5+
import type { ToolResponse } from '@/tools/types'
6+
7+
const inputSchema = oracleFusionScmMutationInputSchema(z.object({
8+
details: z.array(z.object({
9+
ShipmentLine: z.string().min(1).max(128),
10+
}).strict()).min(1).max(100),
11+
}).strict())
12+
13+
// Oracle documents a dynamic result map, not a fixed status/message envelope.
14+
const responseSchema = z.object({
15+
result: z.record(z.string(), z.array(z.record(z.string(), z.string()))),
16+
})
17+
18+
/** Confirms only quick-ship eligible lines in a quick-ship enabled organization. */
19+
export async function executeOracleFusionScmConfirmQuickShipLines(
20+
rawInput: unknown,
21+
signal?: AbortSignal
22+
): Promise<ToolResponse> {
23+
const input = inputSchema.parse(rawInput)
24+
const payload = await requestOracleFusionJson(input, {
25+
method: 'POST',
26+
address: { family: 'fscm', relativePath: 'shipmentLineChangeRequests/action/confirm' },
27+
mediaType: 'application/vnd.oracle.adf.action+json',
28+
body: input.body,
29+
}, signal)
30+
const output = unexpectedOracleFusionScmResponse(() => responseSchema.parse(payload))
31+
return { success: true, output }
32+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { z } from 'zod'
2+
import { requestOracleFusionJson } from '@/lib/internal/oracle-fusion/client'
3+
import {
4+
oracleFusionScmCollectionPath,
5+
projectOracleFusionScmResource,
6+
unexpectedOracleFusionScmResponse,
7+
} from '@/lib/internal/oracle-fusion-scm/operations/read-resource'
8+
import {
9+
oracleFusionScmIntegerInput,
10+
oracleFusionScmMutationInputSchema,
11+
} from '@/lib/internal/oracle-fusion-scm/schema'
12+
import type { ToolResponse } from '@/tools/types'
13+
14+
// Contract: op-maintenanceworkorders-post.html
15+
const bodySchema = z.object({
16+
InventoryItemId: oracleFusionScmIntegerInput('int64'),
17+
PlannedStartQuantity: z.number().finite(),
18+
UOMCode: z.string().max(3).min(1),
19+
WorkOrderTypeCode: z.string().max(30).min(1),
20+
OrganizationId: oracleFusionScmIntegerInput('int64').optional(),
21+
OrganizationCode: z.string().max(255).nullable().optional(),
22+
WorkOrderNumber: z.string().max(120).nullable().optional(),
23+
WorkOrderDescription: z.string().max(240).nullable().optional(),
24+
WorkOrderStatusCode: z.string().max(255).nullable().optional(),
25+
WorkOrderSubTypeCode: z.string().max(30).nullable().optional(),
26+
WorkOrderPriority: z.number().finite().nullable().optional(),
27+
PlannedStartDate: z.string().datetime({ offset: true }).nullable().optional(),
28+
PlannedCompletionDate: z.string().datetime({ offset: true }).nullable().optional(),
29+
WorkDefinitionId: oracleFusionScmIntegerInput('int64').nullable().optional(),
30+
AssetId: oracleFusionScmIntegerInput('int64').nullable().optional(),
31+
AssetNumber: z.string().nullable().optional(),
32+
}).strict()
33+
34+
const inputSchema = oracleFusionScmMutationInputSchema(bodySchema, [])
35+
36+
/** Creates the documented maintenance work order fields without numeric identifier rounding. */
37+
export async function executeOracleFusionScmCreateMaintenanceWorkOrder(
38+
rawInput: unknown,
39+
signal?: AbortSignal
40+
): Promise<ToolResponse> {
41+
const input = inputSchema.parse(rawInput)
42+
const collection = oracleFusionScmCollectionPath('maintenanceWorkOrders', input)
43+
const relativePath = collection
44+
const payload = await requestOracleFusionJson(input, {
45+
method: 'POST',
46+
address: { family: 'fscm', relativePath },
47+
mediaType: 'application/vnd.oracle.adf.resourceitem+json',
48+
body: input.body,
49+
}, signal)
50+
const item = unexpectedOracleFusionScmResponse(() =>
51+
projectOracleFusionScmResource('maintenanceWorkOrders', payload, input.instanceUrl, collection)
52+
)
53+
return { success: true, output: { maintenanceWorkOrder: item } }
54+
}

0 commit comments

Comments
 (0)