logo

Are you need IT Support Engineer? Free Consultant

Extend Sales Order with Issue Summary by Using BAd…

  • By Sanjay
  • 26/06/2026
  • 5 Views


In previous blogs, we shared how to use the Cloud BAdI to Update Sales Order in Finalize Phase and how to Trigger Sales Order Approval Workflow Based on Profit Margin by using the extensibility tools in SAP S/4HANA Cloud Public Edition.

In this blog, I will share another real business use case where the developer extensibility BAdI SD_SLS_END_OF_FINALIZE is used to automatically maintain a custom field that provides a human-readable summary of current issues on a sales order, right before saving.

Developer extensibility is one of the three extensibility types available in SAP S/4HANA Cloud Public Edition. Unlike key user extensibility — which is configuration-based and available to business users — developer extensibility requires ABAP development skills and is implemented in ABAP Development Tools (ADT). It allows customers to add custom business logic using released, cloud-compliant APIs under a strict C1 contract, ensuring upgrade stability. 

SD_SLS_END_OF_FINALIZE is the first developer-extensibility BAdI defined specifically for the sales order process. It is called at the very end of the Finalize phase, after all standard processing is complete, so the document state it reads (credit status, block status, incompleteness) is final and fully committed. Unlike earlier BAdIs in the finalize sequence, changes made here do not trigger redetermination of dependent values, which makes it ideal for writing derived or summary fields. It can also return messages to the user and, when necessary, prevent the document from being saved.

For a full comparison of all diffferent BAdIs, including when each fires, what it can modify, and its recommended use case, refer to the SAP Help documentation.

The Supplier Company XYZ is a wholesale distributor operating across multiple sales organizations. Their inside sales team processes a high volume of orders daily, and order quality is a constant focus: orders must be complete, credit-approved, and free of supply or delivery blocks before they can be fulfilled.

When an order is flagged as “incomplete” in standard SAP, the system only shows the sales order is incomplete with relevant statuses — it does not tell the user which specific fields are missing, unless user opens the sales order to check for details. 

The Company XYZ wants a single, readable field on the sales order — visible in list reports — that surfaces most relevant issues in one place: for example, [CREDIT BLOCK] [DELIVERY BLOCK] [INCOMPLETE: Payment Terms]. This would allow their order management team to triage issues at a glance without opening each order individually. The standard SAP S/4HANA Cloud incompleteness log does not satisfy this requirement because it is only accessible from within the order itself and does not consolidate blocks and missing fields into a single explainable field.

Let's see how developer extensibility fulfills this requirement.

We will use the developer-extensibility BAdI SD_SLS_END_OF_FINALIZE to evaluate the state of the sales order immediately before saving and write the result into a custom header field called YY1_ISSUE_SUMMARY_SDH. This field will contain a concise, machine-parseable text string summarizing all active issues.

The BAdI SD_SLS_END_OF_FINALIZE belongs to enhancement spot ES_SD_SLS_DEV_EXTEND and fires at the end of the finalize phase — that is, right before a sales document is saved — regardless of whether the trigger is a manual save, an approval workflow update, a credit decision, or any other process. This makes it the ideal hook for maintaining derived fields that should always reflect the current state of the document.

The solution consists of three parts: creating the custom field, implementing the BAdI logic, and verifying the result in the Fiori UI.

Step 1 — Create the custom field

Open the Custom Fields Fiori app and create a new field for the Sales Document business context:

Field name: YY1_ISSUE_SUMMARY_SDH

Enable the field for the sales order UI and publish it. Publishing the field also generates the corresponding control-YY1_ISSUE_SUMMARY_SDH flag in the BAdI interface, which is required to make writes take effect.

Zhaoyo_1-1782444637810.Png

Step 2 — Implement the BAdI

Open ADT (ABAP Development Tools) and navigate to enhancement spot ES_SD_SLS_DEV_EXTEND. Create a new BAdI implementation for SD_SLS_END_OF_FINALIZE and implement the method IF_SD_SLS_END_OF_FINALIZE~MODIFY_FIELDS.

Zhaoyo_2-1782444944512.Png

Implement following logic to convert issues into custom field as explainable texts.

The method receives two objects: a dataprovider (read-only access to the document) and a dataprocessor (write access to custom fields). First, skip the method body when called in simulation mode — this avoids side effects during OData simulation API calls:

IF dataprovider->is_simulation_mode( ) = abap_true.

  RETURN.

ENDIF.

Next, read the header fields and derive the flags needed for the summary:

DATA(lv_credit_status)      = dataprovider->get_salesdocument( )-totalcreditcheckstatus.
DATA(lv_head_incomp_status) = dataprovider->get_salesdocument( )-headerdelivincompletionstatus.
DATA(lv_credit_blocked)     = abap_false.

IF lv_credit_status="B" OR lv_credit_status="C".
  lv_credit_blocked = abap_true.
ENDIF.

Then retrieve the incompleteness information. The method GET_INCOMPLETENESS_INFO_INTRNL returns all incomplete field entries, with each entry carrying the technical field name (FDNAM) and the item number (POSNR). A POSNR of 000000 indicates a header-level field; any other value is an item-level field.

DATA(lt_incompletion_info) = dataprovider->get_incompleteness_info_intrnl( ).
DATA lv_summary TYPE string.

Build the summary string by appending tokens for each active issue. Credit block comes first, followed by one token per incomplete field. A SWITCH maps each technical field name to a human-readable label; unknown field names fall back to the raw technical name:

IF lv_credit_blocked = abap_true.
  lv_summary = |[CREDIT BLOCK] |.
ENDIF.

LOOP AT lt_incompletion_info INTO DATA(ls_incompl).
  DATA(lv_field_label) = SWITCH string( ls_incompl-fdnam
    WHEN 'AUGRU'   THEN 'Order Reason'
    WHEN 'BSTKD'   THEN 'PO Number'
    WHEN 'BSTDK'   THEN 'PO Date'
    WHEN 'INCO1'   THEN 'Incoterms'
    WHEN 'INCO2_L' THEN 'Incoterms Location'
    WHEN 'KDGRP'   THEN 'Customer Group'
    WHEN 'KTGRD'   THEN 'Account Assignment Group'
    WHEN 'KUNNR'   THEN 'Ship-to Party'
    WHEN 'LIFSK'   THEN 'Delivery Block'
    WHEN 'LPRIO'   THEN 'Delivery Priority'
    WHEN 'PRSDT'   THEN 'Pricing Date'
    WHEN 'ROUTE'   THEN 'Route'
    WHEN 'VKBUR'   THEN 'Sales Office'
    WHEN 'VKGRP'   THEN 'Sales Group'
    WHEN 'VSBED'   THEN 'Shipping Conditions'
    WHEN 'VSTEL'   THEN 'Shipping Point'
    WHEN 'WAERK'   THEN 'Currency'
    WHEN 'WERKS'   THEN 'Plant'
    WHEN 'ZTERM'   THEN 'Payment Terms'
    ELSE ls_incompl-fdnam ).

  IF ls_incompl-posnr="000000".
    lv_summary = lv_summary && |[INCOMPLETE: { lv_field_label }] |.
  ELSE.
    lv_summary = lv_summary && |[ITEM { ls_incompl-posnr } INCOMPLETE: { lv_field_label }] |.
  ENDIF.
ENDLOOP.

Finally, truncate to 200 characters and write to the custom field using SET_HEAD_CUSTOM_FIELDS. The control- flag must always be set to IF_ABAP_BEHV=>MK-ON — only fields with this flag set are actually persisted:

CONDENSE lv_summary.
IF strlen( lv_summary ) > 200.
  lv_summary = lv_summary(200).
ENDIF.


dataprocessor->set_head_custom_fields(
  VALUE #( yy1_issue_summary_sdh         = lv_summary
           control-yy1_issue_summary_sdh = if_abap_behv=>mk-on ) ).

Save and activate the implementation class in ADT. 

Step 3 — Verify in the Fiori UI

Log on as an Internal Sales Representative and open the Manage Sales Orders – Version 2 Fiori app. Create a new sales order and intentionally leave following fields empty, and save the order without completing it:

  • Customer Reference (header)
  • Shipping Point (item 10)
  • Terms of Payment (item 20)

Zhaoyo_7-1782457242519.Png

Zhaoyo_8-1782457262281.Png

Zhaoyo_9-1782457292315.Png

Open the saved order and check the custom field — the Issue Summary field shows below:

Zhaoyo_10-1782458054684.Png

Edit the sales order to provide the customer reference, and then Save the sales order. 

Zhaoyo_0-1782458240848.Png

Open the sales order after it is saved, the custom field “Issue Summary” is updated accordingly. 

Zhaoyo_0-1782458525406.Png

In this blog, we used the BAdI SD_SLS_END_OF_FINALIZE to implement a lightweight but powerful order quality indicator. By reading the document state — credit check status, delivery block status, and the incompleteness log — right before save, and writing the result into a custom header field, we gave the order management team a consolidated, queryable view of every issue on every order. No batch job, no separate report, no custom Fiori app required.

The BAdI SD_SLS_END_OF_FINALIZE is part of the Developer Extensibility framework in SAP S/4HANA Cloud Public Edition. It is implemented in ABAP Development Tools (ADT) using only released, cloud-compliant APIs (C1 contract), and it fires on every save regardless of the triggering scenario — manual save, approval workflow, credit decision, and more. This makes it a reliable, low-maintenance extension point for derived fields that must always reflect current document state.

Please stay tuned for more custom sales order type use cases, and feel free to submit your requirements through the Customer Influence Portal to help us prioritize our product roadmap.



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *

//
Our customer support team is here to answer your questions. Ask us anything!
👋 Hi, how can I help?
Chat with us on WhatsApp!