# Infor LN AFS (stpapi) Session Automation Script Generator

> Source: https://netray.co/tools/infor-ln-afs-stpapi-session-script-generator
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: Free Tools

## Short answer

Generate Application Function Server (AFS) functions that insert, update and delete records through a standard LN session without its user interface.

## Category

developer

## Erp

Baan IV / Infor LN

## Audience

- LN developer
- Baan developer
- Integration developer

## Tool

**Kind:** template

**Output:** code

**Language:** text

**Fields:**

#### Session code

**Key:** session

**Type:** text

**Default:** tcmcs0145m000

**Help:** A 4GL session code, e.g. tcmcs0145m000 (Areas, table tcmcs045).

#### Key field (table.field)

**Key:** key_field

**Type:** text

**Default:** tcmcs045.creg

#### Key value

**Key:** key_value

**Type:** text

**Default:** EU1

#### Data field (table.field)

**Key:** data_field

**Type:** text

**Default:** tcmcs045.dsca

#### Data value

**Key:** data_value

**Type:** text

**Default:** Europe region 1

#### Function name prefix

**Key:** prefix

**Type:** text

**Default:** afs.area

**Blocks:**

#### Header

**Body:** |******************************************************************************
|* AFS functions driving session {{session}}
|* Values are passed as strings: use str$() for numbers, etol() for enums
|******************************************************************************
#pragma used dll ottstpapihand

#### Insert

**Body:** function extern long {{prefix}}.insert(ref string o.mess())
{
	long	retval
	string	recover.msg(500)

	stpapi.put.field("{{session}}", "{{key_field}}", "{{key_value}}")
	stpapi.put.field("{{session}}", "{{data_field}}", "{{data_value}}")

	retval = stpapi.insert("{{session}}", true, o.mess)
	if not retval then
		| ends the update mode of the session after an error
		retval = stpapi.recover("{{session}}", recover.msg)
	endif

	stpapi.end.session("{{session}}")
	return(isspace(o.mess))
}

#### Update

**Body:** function extern long {{prefix}}.update(ref string o.mess())
{
	long	retval
	string	recover.msg(500)

	stpapi.put.field("{{session}}", "{{key_field}}", "{{key_value}}")
	retval = stpapi.find("{{session}}", o.mess)
	if retval <> 1 then
		| 0 = not found or error, 2 = a different record was found
		stpapi.end.session("{{session}}")
		return(false)
	endif

	stpapi.put.field("{{session}}", "{{data_field}}", "{{data_value}}")
	retval = stpapi.update("{{session}}", true, o.mess)
	if not retval then
		retval = stpapi.recover("{{session}}", recover.msg)
	endif

	stpapi.end.session("{{session}}")
	return(isspace(o.mess))
}

#### Delete

**Body:** function extern long {{prefix}}.delete(ref string o.mess())
{
	long	retval
	string	recover.msg(500)

	stpapi.put.field("{{session}}", "{{key_field}}", "{{key_value}}")
	retval = stpapi.find("{{session}}", o.mess)
	if retval <> 1 then
		stpapi.end.session("{{session}}")
		return(false)
	endif

	| do.save must be true for delete
	retval = stpapi.delete("{{session}}", true, o.mess)
	if not retval then
		retval = stpapi.recover("{{session}}", recover.msg)
	endif

	stpapi.end.session("{{session}}")
	return(isspace(o.mess))
}

**Notes:** Signatures follow the Infor Integration 6.2 Developer's Guide for Application Function Server: stpapi.put.field(session, field, value), stpapi.find(session, err) returning 0, 1 or 2, stpapi.insert / stpapi.update / stpapi.delete(session, do.save, err) returning 1 on success, stpapi.recover(session, err) and stpapi.end.session(session). Compile with #pragma used dll ottstpapihand or link ottstpapihand. Multi-occurrence and main sessions with a separate detail session (such as sales orders) need stpapi.synchronize.dialog and stpapi.change.view calls; check the guide and the session's own AFS DLL before driving them.

## Content

**Intro:** The Application Function Server (AFS) runs a standard Baan or LN 4GL session without its form, so a program can insert, update and delete records with all of the session's own checks. This generator writes the stpapi calls in the order Infor documents, with error recovery and session cleanup.

**Sections:**

#### How to use it

**Body:** Enter the session code, the key field and value, and one data field and value, both as table.field names exactly as the session form uses them. The output has one function each for insert, update and delete. Add more stpapi.put.field lines for extra fields, in the order a user would enter them, because AFS runs the session's field logic and a field can depend on one entered earlier. Put the code in a library or 3GL script in your own VRC and call the function from your integration program. Every function returns true when the action succeeded and hands back the error text in o.mess when it did not.

#### How AFS works

**Body:** The first stpapi call for a session starts it and creates the field buffer; before.program and the main table and form before sections run at that point. stpapi.put.field only fills the buffer. stpapi.insert then runs the add choice, the field loop with each field's checks and the session's DAL check.property hooks, and with do.save set to true also the update.db choice. If anything fails, the function returns 0 with the message, and stpapi.recover must be called to leave update mode before any other call. stpapi.end.session ends the session and runs its end.program choice. For update and delete, stpapi.find with the key fields makes the record current first.

**Bullets:**

- AFS library naming: parent session with f after the module, e.g. tcmcsf0145m000
- stpapi.find returns 0 (not found or error), 1 (found) or 2 (a different record found)
- stpapi.delete only supports do.save = true

#### Worked example

**Body:** With the defaults the generator drives Areas (tcmcs0145m000), a simple single-occurrence session on table tcmcs045 with the area code creg and description dsca. The insert function puts EU1 and the description, inserts with do.save true and ends the session. The update function puts the key, finds the record, checks for return value 1, changes the description and updates. If you run the insert twice, the second call returns false with the session's duplicate key message in o.mess, which is exactly what a user would see.

#### Version notes and alternatives

**Body:** AFS follows UI logic, so a session redesign in a new feature pack can break an AFS program even though the table did not change. Sessions with question boxes need answers set in advance through the AFS functions for questions, and sessions with a main and detail form need dialog synchronization. Infor community answers report that calling standard sessions through AFS is not available in multi-tenant LN Cloud. For new integrations, BODs through ION or the LN REST APIs are the paths Infor develops further; keep AFS for existing on-prem programs and quick internal automation.

**Cta:** If you want routine LN updates driven from a plain-English request with a human approving each change, we can build that on your own servers on top of AFS or BODs.

**Faq:**

#### How do I start an LN session from a program?

**Answer:** With AFS you do not start it explicitly: the first stpapi call that names the session, usually stpapi.put.field, starts it in the background and creates the field buffer. End it with stpapi.end.session when you are done, otherwise the session instance stays active for later calls.

#### Why does stpapi.insert fail when the same data works in the session?

**Answer:** Usually the field order or a missing field. AFS runs the field checks in the session's order, so a field validated against an earlier one fails if that one is not put first. Questions the session asks also need preset answers. Read the message in the error string and compare with a manual entry.

#### Do I have to call stpapi.recover after an error?

**Answer:** Yes. After an insert, update or delete fails, call stpapi.recover before any other stpapi call on that session. Otherwise the session stays in update mode, and the later end.session call can still write the record you meant to reject.

#### Where can I see which AFS steps a session needs?

**Answer:** Look for an existing AFS DLL for the session (the session name with f after the module) and read its functions, such as the ones Infor generates with ttstpcreatdll. The Infor Developer's Guide for Application Function Server lists every stpapi function.

## Search terms

infor ln afs, baan afs stpapi, stpapi.put.field, stpapi.insert example, infor ln start session, infor ln development guide, baan application function server

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
