Skip to content

Add a persistent modification field

M · Modification / 26R1 reference / Source-informed tutorial draft

Add a fictional CExternalReference text field to an existing order header and display it on its detail page. This tutorial is based on documentation and a traced core field pattern. The new code has not been generated, compiled, or deployed in IFS.

All names below are teaching aliases: DEMO, OrderHeader, OrderHeaderHandling, and OrderHeaderGeneralGroup. Replace them with names discovered in your solution. There is no claim that these fictional objects exist in IFS.

First choose configuration or modification

Section titled “First choose configuration or modification”

If a supported custom attribute and Page Designer satisfy the requirement, use the configuration recipe instead. The procedure below is for an approved Cust-layer modification, which needs a compatible build home, Developer Studio, a solution build and delivery.

Use a nonproduction development database, compatible Developer Studio/build home, and a solution project that permits Cust-layer changes. You need access to the parent models and permission to generate, build, and deploy the affected component. Arrange a normal update-capable test user and a separate read-only user.

Download the target worksheet and acceptance checks. Keep the original page’s behavior, a disposable record key, and the current source revision as your baseline.

If a customization project is needed, choose File → New Project → IFS → IFS Customization Project → Next. Set the project name/location and target version, select the database technology, configure the development database, and finish. Confirm its build-home configuration before creating the Cust files: parent-source resolution and generation depend on it.

Outcome: an authorized user saves DEMO-HO-014 in the new field and sees it after reopening the record, while existing fields and commands continue to work.

  1. Open the target page and its test record. Use User Menu → Debug Console → Page Info to identify the page element and entity/logical unit.
  2. Locate the corresponding client model in your build home/source checkout and follow its projection declaration.
  3. Find the group that renders the record, then follow its entity through the projection and any mapping to the backing entity model.
  4. Record the component, actual model names, group, and service property mapping in the worksheet. Confirm whether another Cust file already changes them.

Before creating any file, complete this map:

Client page / group
→ projection declared in the client header
→ entity used by that group
→ projection entity and any "using" mapping
→ base entity model and owning component

A page can use fragments or a projection entity whose name differs from its storage entity. Follow those relationships rather than assuming matching filenames.

Search in your local checkout, substituting actual names:

Terminal window
rg --files --no-ignore -g '*OrderHeader*'
rg -n '^projection |^include fragment |^group ' path/to/OrderHeader.client
rg -n '^entity |use attributes|attribute ' path/to/OrderHeaderHandling.projection

These commands inspect files only. Substitute your actual object names and file paths before running them.

Paths are relative patterns, not a ready-to-apply patch.

File or artifact Role Action
<component>/model/<component>/OrderHeader.entity Core storage model Inspect; do not edit Core
<component>/model/<component>/OrderHeader-Cust.entity Added persistent attribute Create through the customization workflow, or amend the existing Cust model
<component>/model/<component>/OrderHeaderHandling-Cust.projection API exposure and label Amend the mapped projection entity
<component>/model/<component>/OrderHeader-Cust.client Visible field in the correct group Add the field to the mapped group
<component>/source/<component>/database/OrderHeader-Cust.plsql Additional business validation/defaults Only when required; a simple optional field may not need handwritten logic
<component>/source/<component>/database/OrderHeaderHandling-Cust.plsvc Projection operation implementation Only if adding/changing an implemented action or function
<component>/test/<component>/database/... Entity/service regression checks Follow the existing test conventions
Generated database/API/client artifacts Output of the model changes Generate using the configured tools; do not patch a generated package to bypass the model

The target view, generated names, and output locations must come from your build, not from the aliases above.

3. Define the attribute in the entity model

Section titled “3. Define the attribute in the entity model”
  1. Open the existing Cust entity model, or create its customization using the model editor’s supported workflow for the parent entity. Preserve any existing customer attributes.
  2. Add CExternalReference as an optional, stored Text attribute with maximum length 50.
  3. Set it public/queryable and permit insert/update. Leave mandatory, derived, primary-key, parent-key, and server-generated flags disabled for this exercise.
  4. Save the model and review the diff: the intended change is one new attribute, not a copied/replaced Core definition.

Public here describes entity modeling, not anonymous web access.

The inspected checkout contains XML entity models; the reference documentation also demonstrates text model syntax. Keep the format created by your project’s model editor. Do not paste a complete text model over an XML file.

For an XML model, the following is an attribute fragment, not a complete file:

<ATTRIBUTE>
<NAME>CExternalReference</NAME>
<IS_PRIMARY_KEY>0</IS_PRIMARY_KEY>
<IS_PARENT_KEY>0</IS_PARENT_KEY>
<IS_PUBLIC>1</IS_PUBLIC>
<IS_MANDATORY>0</IS_MANDATORY>
<IS_SERVER_GENERATED>0</IS_SERVER_GENERATED>
<IS_UPDATE_ALLOWED>1</IS_UPDATE_ALLOWED>
<IS_UPDATE_ALLOWED_IF_NULL>0</IS_UPDATE_ALLOWED_IF_NULL>
<IS_DEFAULT_LOV>0</IS_DEFAULT_LOV>
<IS_QUERYABLE>1</IS_QUERYABLE>
<IS_DERIVED>0</IS_DERIVED>
<DATATYPE>TEXT</DATATYPE>
<LENGTH>50</LENGTH>
</ATTRIBUTE>

Use the model editor to preserve the file’s layer, namespace, identity, and any required generation metadata. Confirm that the generated persistent column and allowed operations match the definition. Existing rows need an explicit migration decision if you later make the value mandatory.

Use Customize This on the actual projection when there is no Cust version. Keep existing customizations and add only the changed section.

projection OrderHeaderHandling;
component DEMO;
layer Cust;
@Override
entity OrderHeader {
attribute CExternalReference Text {
label = "External Reference";
}
}

This assumes the attribute belongs to the backing entity and the generated projection can map it. If the projection uses a query, virtual, structure, alias, or explicit mapping, inspect that contract and adapt the exposure. A client-only label cannot create persistence.

Do not replace a Core use attributes list with a one-field list. Review the merged/generated model to ensure existing attributes remain available.

Open the real client in the build home and use Customize This if no Cust version exists. Open the resulting Cust client and override the existing group that displays the mapped entity. Add the field below, preserve other customer changes, and save. Do not invent a group and expect it to appear automatically.

client OrderHeader;
component DEMO;
layer Cust;
projection OrderHeaderHandling;
@Override
group OrderHeaderGeneralGroup for OrderHeader {
field CExternalReference {
size = Small;
}
}

A new group would also need placement on the page. If the existing group comes from a fragment, trace its ownership and supported customization point first. Page Designer configurations can also affect the layout visible to a particular context.

6. Add business logic only when the requirement needs it

Section titled “6. Add business logic only when the requirement needs it”

Length, optionality, and insert/update flags belong in the model where supported. For a new business rule, use the actual generated method signature and an appropriate Cust override in the entity’s .plsql file. Preserve inherited behavior and avoid a full overtake unless required.

Do not invent a Check_Insert___ signature from another entity. Inspect the generated contract and the approved layer pattern. Client validation is not a substitute for server-side enforcement.

7. Generate and inspect the complete change

Section titled “7. Generate and inspect the complete change”
  1. Match Developer Studio’s target version to the build home and generate the entity change.
  2. Inspect the generated schema and entity API diff. Confirm the new persistent column’s actual name, length, nullability, and insert/update handling. Existing columns and methods should remain intact.
  3. Apply the entity/schema change in the development environment through the project’s supported deployment process. Inspect logs and invalid-object reports before continuing.
  4. Generate/deploy the projection. Inspect its merged model and generated service metadata: the mapped entity must expose CExternalReference with the intended type.
  5. Generate/deploy the client after its dependency is available. Reopen the page in the intended configuration context.
  6. Review the merged client group: inherited fields and commands must still be present alongside the added field.

Do not fix a missing column by manually altering the database while leaving the source model unchanged. A fresh environment must be reproducible from the delivered source and artifacts.

  1. As the update-capable user, open the baseline record, enter DEMO-HO-014, and save. Navigate away and reopen by the same record key.
  2. Confirm the value persists. Change it to DEMO-HO-015, save, and reopen again.
  3. Clear the optional field and save. Verify that an existing record with no value still opens normally.
  4. Paste the 50-character ASCII value below, save, and reopen. Append X for a 51-character attempt. The extra character should be prevented or rejected, not silently lost.
  5. Repeat viewing and an attempted update using the read-only test user. Where the projection exposes writes, repeat the authorized service test to confirm that UI restrictions are not the only control.
  6. Exercise the page’s existing required fields and one existing business command with appropriate training data; compare behavior with the baseline.
12345678901234567890123456789012345678901234567890

Record the real result and error messages for each case:

Test Expected evidence
Existing record with no value Opens and preserves existing behavior
Permitted create/update Fictional value persists after save and reload
50-character value Accepted if the agreed business rule allows it
51-character value Extra character prevented or request rejected; no silent truncation
User without update access Cannot update through the UI or direct service
Existing fields and commands Still behave as before
Actual target configuration context Field is visible in the intended layout

If the property is missing from metadata, investigate entity/projection generation. If metadata contains it but the page does not, investigate client placement and configuration context. If it displays but does not persist, trace the backing entity and update behavior.

  1. Review the source diff and generated output together. Include the entity, projection, and client Cust changes, plus any deliberately added business logic/tests.
  2. Build the affected solution with the matching build home and retain build/deployment logs. Do not deliver three edited files without their required generation and schema artifacts.
  3. Deploy the reviewed build into the compatible target test environment through the normal pipeline. Confirm schema changes complete before dependent service/client use.
  4. Check the target’s effective permissions and Page Designer context; they may differ from development.
  5. Repeat step 8 and record the build identity, user roles, record key, and actual results. Review customization impacts during future IFS updates.
Symptom Investigation and correction
Generation cannot find parent model Verify build home, target version, component, and parent source availability
Field absent from API metadata Trace backing entity/mapping and deployed projection generation
API has field but page does not Inspect group placement, merged client, and configuration context
Value shows but does not persist Inspect storage mapping and generated insert/update behavior
Existing controls disappear Review override versus overtake and whether inherited declarations were replaced
Old rows fail after deployment Check that the optional field did not acquire a mandatory rule or unplanned migration

Exercise: change the label to “Partner handover reference” while retaining the stored field and previously entered values. Identify which files require review.

Show the solution

Change the projection attribute’s label (and relevant translations), then regenerate/deploy the dependent artifacts and inspect the client. Retain the entity attribute name and length; no new storage column is needed. Check any client or Page Designer label override if the old label remains. Reopen an existing record and confirm its saved value is unchanged.

Restore the previous UI/service behavior through a reviewed source change and normal build. Preserve existing reference data before considering schema removal. A rollback that hides the field can retain the nullable column; dropping it is a separate data-affecting migration, not an automatic cleanup step. Remove only disposable test records that your exercise created.

Status: source-informed 26R1 draft. The model snippets and IFS procedure have not been generated, compiled, deployed, or executed here. Record those results in the worksheet before marking a particular release verified.

Review naming and layering, optional dependencies, entity security and time zones, and upgrade scripts before delivering the change.

Generic snippets are original teaching examples. Local source inspection supports the file relationships; only execution in a matching IFS environment can establish that a particular implementation works.