Financial Management Blog Posts by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 

The Problem

In many businesses, the same product is sold in different units of measure depending on the customer, the order type, or the packaging: one customer orders in individual Bottles (BT), another in Cartons (CAR), and yet another in full Pallets (PAL). This is common practice within a single sales organization and has no impact on the sales or logistics process. However, it creates a reporting challenge in Margin Analysis.

The apps of the Market Segments family — such as Profitability — Market Segments — display quantity measures (Valuation Quantity, Act Valuation Qty, Act Reference Qty, Act Qty in Base Unit) in whichever unit of measure was used on the originating billing document. Without a conversion to a unified base unit, it is impossible to aggregate or compare sold volumes across line items, customers, or periods. Customers want to see their contribution margin not only per sales unit — which differs by packaging — but also per base unit, enabling a true like-for-like comparison.

Operating across multiple sales organizations that invoice in different units adds a further dimension to the same challenge, but the core problem is already present within a single sales organization.

You may notice that apps in the Sales Volumes family do not have this problem: they correctly convert quantities to a unified base unit. This is not a bug in either app family — it reflects a fundamental difference in where each reads its data.

 

Market Segments Apps

Sales Volumes Apps

Data source

Universal Journal (ACDOCA) — CO document items

Billing document tables (VBRP)

UoM at posting time

Billing/sales UoM stored as-is in the CO document

Full SD document chain with material master conversion available

Result

Shows original sales unit (e.g., 30 CAR)

Can convert to base unit (e.g., 300 BT)

 

When a billing document is posted, the SD-to-CO transfer writes the billing quantity into the CO document item and from there into ACDOCA in the billing UoM, without converting to the material's base unit. The Quantity Conversion Extension described in this blog closes this gap by populating additional quantity fields at posting time.

Section 1: Prerequisites — Product Master Data Setup

To demonstrate the Quantity Conversion Extension, three products representing the same physical item — water — are created, each sold in a different packaging unit. All three products are set up in the Manage Product Master Data app in SAP S/4HANA Cloud Public Edition.

roman_rapp_0-1789123935057.png

 

Figure 1: Overview of the three products RR01, RR02, RR03 in Manage Product Master Data

All three products are of type Trading Goods (HAWA) and share the same base unit: Bottle (BT). This is a critical design choice — the base unit acts as the common denominator to which all alternative units are converted.

Product RR01 — Water - Bottle

RR01 has only one unit of measure defined: Bottle (BT), with a self-referencing conversion of 1 BT = 1 BT. This is the simplest case — the product is sold in its base unit, so no conversion is needed.

roman_rapp_1-1789123962433.png

Figure 2: RR01 — Units of Measure, base unit Bottle (BT) only

Product RR02 — Water - Carton

RR02 has two units of measure: Bottle (BT) as the base unit, and Carton (CAR) as an alternative sales unit with the conversion factor 1 CAR = 10 BT. This conversion factor, defined on the General Information tab under Units of Measure, tells the system how many bottles are contained in one carton.

roman_rapp_2-1789123987449.png

Figure 3: RR02 — Units of Measure showing 1 CAR = 10 BT

On the Distribution Chains tab, the Sales Unit for Sales Organization 1010 / Direct Sales (10) is set to Carton (CAR). This means sales orders for RR02 default to CAR as the invoicing unit.

roman_rapp_3-1789123987458.png

Figure 4: RR02 — Distribution Chains showing Sales Unit = CAR

Product RR03 — Water - Pallet

RR03 follows the same pattern with a larger packaging unit: Bottle (BT) as the base unit, and Pallet (PAL) with the conversion factor 1 PAL = 180 BT. One pallet contains 180 bottles (equivalent to 18 cartons of 10 bottles each).

roman_rapp_4-1789124018324.png

Figure 5: RR03 — Units of Measure showing 1 PAL = 180 BT

Accordingly, the Sales Unit for this product is set to Pallet (PAL) in the Distribution Chains.

roman_rapp_5-1789124018331.png

Figure 6: RR03 — Distribution Chains showing Sales Unit = PAL

Why This Setup Matters

The conversion factors defined in the product master are the foundation of the entire Quantity Conversion Extension. Without them, there is no basis for converting quantities at any point in the process. The table below shows the full picture — base unit, sales unit, and the conversion factor for each product:

Product ID

Description

Base Unit

Sales Unit of Measure

Conversion Factor

RR01

Water - Bottle

Bottle (BT)

Bottle (BT)

1 BT = 1 BT

RR02

Water - Carton

Bottle (BT)

Carton (CAR)

1 CAR = 10 BT

RR03

Water - Pallet

Bottle (BT)

Pallet (PAL)

1 PAL = 180 BT

Note: Every product sold in a non-base unit must have its alternative UoM conversion defined on the product master before any sales orders or billing documents are created. Missing conversions will cause the extension to fall back to the original sales unit quantity.

Section 3: Creating the BAdI Implementation in the Custom Logic App

The Quantity Conversion Extension is created entirely through the Custom Logic app — no external development tools or transport requests are required. This app is SAP's entry point for BAdI-based extensibility in SAP S/4HANA Cloud Public Edition, fully aligned with the Clean Core principle.

Step 1 — Find the Extension Point

Open the Custom Logic app and choose New Implementation. In the Extension Point search field, enter FIN_CODOC_ITEM_QUANTITY and press Search.

roman_rapp_6-1789124090096.png

Figure 8: Searching for BAdI FIN_CODOC_ITEM_QUANTITY in the Custom Logic app

The system returns exactly one result:

Description

ID

Controlling Document Line Item Additional Quantities

FIN_CODOC_ITEM_QUANTITY

 

This BAdI is called every time a Controlling document line item is created — for example, when a billing document is transferred to Margin Analysis. The View Documentation link provides the full interface specification directly in the system. Select the entry and proceed to Step 2.

Step 2 — Implementation Attributes

In the Implementation Attributes section, BAdI filters can optionally be defined to restrict when the implementation is executed. In this scenario, no filters are needed — the extension applies to all relevant postings, so the Filters table is left empty.

Step 3 — Implementation ID

roman_rapp_7-1789124116061.png

Figure 9: Implementation Attributes and Implementation ID

Field

Value

Implementation Description

Additional Product Quantities

Implementation ID

YY1_ADDITIONALPRODUCTQUANTITIE

 

The prefix YY1_ is the customer namespace for custom implementations in SAP S/4HANA Cloud Public Edition, ensuring clean separation from SAP standard objects. Once the details are entered, click Review to validate, then Create to generate the implementation shell.

Section 4: Implementing the Code in the Custom Logic Editor

After clicking Create, the system opens the Custom Logic code editor. The implementation is developed on the Develop tab. The right-hand panel shows all available BAdI parameters — two importing structures are key:

Structure

Description

Key Fields Used

CODOCHEADER

CO Document Header

REFERENCEDOCUMENTTYPE (VBRK = Billing, MKPF = Material Doc)

CODOCITEM

CO Document Line Item

MATERIAL, TOTALQUANTITY, UNITUOM, PLANT, SALESORGANIZATION

 

The output variables ADDITIONALQUANTITY1, ADDITIONALQUANTITY1UNIT, ADDITIONALQUANTITY2, and ADDITIONALQUANTITY2UNIT are writable — the code writes the calculated values into them before the CO document item is persisted to ACDOCA.

roman_rapp_8-1789124147405.png

 

Figure 10: Custom Logic editor — published code and BAdI parameter panel

The Code

IF codocitem-material IS NOT INITIAL AND

   ( codocheader-referencedocumenttype = 'MKPF' OR

     codocheader-referencedocumenttype = 'VBRK' ).

 

  IF codocitem-unituom IS NOT INITIAL.

 

    "AdditionalQuantity1: Convert Sales UoM to base unit for billing docs.

    "For material documents the quantity is already in base unit.

    IF codocheader-referencedocumenttype = 'VBRK'.

      SELECT SINGLE

          GrossWeight,

          WeightUnit,

          QuantityNumerator,

          QuantityDenominator,

          BaseUnit

        FROM I_ProductUnitsOfMeasure

        WHERE Product         = @codocitem-material

          AND AlternativeUnit = @codocitem-unituom

       INTO @DATA(ls_uom).

      IF sy-subrc = 0.

        additionalquantity1unit = ls_uom-baseunit.

        additionalquantity1     = codocitem-totalquantity

                                  * ls_uom-quantitynumerator

                                  / ls_uom-quantitydenominator.

      ELSE.

        additionalquantity1unit = codocitem-unituom.

        additionalquantity1     = codocitem-totalquantity.

      ENDIF.

    ELSE.

      "MKPF: quantity already in base unit

      additionalquantity1unit = codocitem-unituom.

      additionalquantity1     = codocitem-totalquantity.

    ENDIF.

 

    "AdditionalQuantity2: Gross weight of the posted quantity

    "Step 1: Try to read weight directly for the UoM of the posting

    IF ls_uom IS INITIAL.

      SELECT SINGLE

          GrossWeight,

          WeightUnit,

          QuantityNumerator,

          QuantityDenominator,

          BaseUnit

        FROM I_ProductUnitsOfMeasure

        WHERE Product         = @codocitem-material

          AND AlternativeUnit = @codocitem-unituom

       INTO @LS_uom.

    ENDIF.

 

    IF sy-subrc = 0 AND ls_uom-GrossWeight IS NOT INITIAL.

      "Weight is maintained per UoM — multiply directly

      additionalquantity2     = codocitem-totalquantity * ls_uom-GrossWeight.

      additionalquantity2unit = ls_uom-WeightUnit.

      RETURN.

    ENDIF.

 

    "Step 2: Fall back to base-unit weight from I_Product

    SELECT SINGLE

        GrossWeight,

        WeightUnit,

        BaseUnit

      FROM I_Product

      WHERE Product = @codocitem-material

      INTO @DATA(ls_product).

 

    IF sy-subrc = 0 AND ls_product-GrossWeight IS NOT INITIAL.

      "Use base-unit quantity (additionalquantity1) x weight per base unit

      additionalquantity2     = additionalquantity1 * ls_product-GrossWeight.

      additionalquantity2unit = ls_product-weightunit.

    ELSE.

      "No weight data available

      additionalquantity2 = 0.

      CLEAR additionalquantity2unit.

    ENDIF.

 

  ENDIF.

ENDIF.

Code Walkthrough

Entry Condition

The BAdI is called for every CO document item. The code only acts when a material is present on the line item and the posting originates from a billing document (VBRK) or a material document / goods issue (MKPF). All other document types — manual journal entries, allocations — are skipped.

Additional Quantity 1 — Base Unit Quantity

The behavior of Additional Quantity 1 differs depending on the source document type.

For billing documents (VBRK), the CO document item carries the quantity in the sales unit of measure — the unit the customer was invoiced in (e.g., CAR or PAL). The system does not automatically convert this to the base unit when writing to ACDOCA. The extension therefore performs this conversion explicitly by reading the product's UoM conversion factors from the released CDS view I_ProductUnitsOfMeasure. The result is the quantity expressed in the product's base unit — for example, 30 CAR becomes 300 BT. If no conversion record exists, the original sales unit quantity is used as a safe fallback.

For material documents (MKPF) — such as goods issues — SAP already converts the quantity to the base unit automatically during posting. No additional conversion is needed, so the code simply passes the existing quantity and unit through to Additional Quantity 1 unchanged.

Additional Quantity 2 — Product Mass

For all document types (both VBRK and MKPF), Additional Quantity 2 is populated with the gross weight of the posted quantity. This enables weight-based analysis in the Market Segments apps regardless of whether the posting originated from a billing or a goods movement.

The weight is determined in two steps: first by checking whether a gross weight is maintained directly on the alternative unit of measure in I_ProductUnitsOfMeasure; if not, by falling back to the base-unit weight from I_Product and multiplying it by the base-unit quantity already calculated in Additional Quantity 1.

Key Design Decisions

Decision

Rationale

Only VBRK and MKPF

Avoids unintended side effects on other CO posting types

I_ProductUnitsOfMeasure (CDS view)

Released SAP API — clean core compliant

Fallback to original UoM if no conversion found

Prevents data loss for products without alternative UoM definitions

Two-step weight logic

Supports both detailed per-UoM weight maintenance and simpler base-unit weight setups

 

Publishing the Implementation

Once the code is saved, it is in draft status and not yet active. To activate the extension, click Publish in the Custom Logic editor. After publishing, the editor confirms the activation with the publisher name and timestamp. From this point on, every new CO document item created from a billing document or material document will be processed by the BAdI.

Note: Only published implementations are active. If you later edit the code, the changes remain in draft until you publish again. The previously published version continues to run in the meantime.

Section 5: Creating the Sales Order

With the product master data configured and the Quantity Conversion Extension published, we use the Manage Sales Orders app to create Sales Order 14487 — a Standard Order (OR) with three line items, one for each of the three water products.

roman_rapp_9-1789124184721.png

 

Figure 11: Sales Order 14487 — Items tab showing three products with different sales units

Item

Product

Requested Quantity

Sales Unit

10

RR01 — Water - Bottle

100

BT

20

RR02 — Water - Carton

30

CAR

30

RR03 — Water - Pallet

2

PAL

 

Each item automatically defaults to the sales unit configured on the product master's Distribution Chains. This reflects a realistic scenario where different sales channels invoice the same physical product in different packaging units — precisely where the reporting challenge arises.

With the extension active, once this order is billed, the BAdI will convert all quantities to the base unit Bottle (BT) in Additional Quantity 1:

Item

Sales Quantity

Conversion

Additional Quantity 1 (BT)

10 — RR01

100 BT

1 BT = 1 BT

100

20 — RR02

30 CAR

1 CAR = 10 BT

300

30 — RR03

2 PAL

1 PAL = 180 BT

360

Total

 

 

760 BT

Section 6: Verifying the Result in the Product Profitability Review Booklet (Ledger 0E)

Context — Predictive Accounting and Ledger 0E

If the scope item Predictive Accounting for Incoming Sales Orders is activated, SAP S/4HANA Cloud Public Edition already posts predicted revenues and COGS to Ledger 0E at the time the sales order is saved — before delivery or billing occurs. The Quantity Conversion Extension applies equally to these Predictive Accounting postings, since they also create CO document line items processed by the BAdI.

Setup in the Product Profitability Review Booklet

We open the Product Profitability Review Booklet app and apply the following settings: Ledger 0E, Products RR01/RR02/RR03, and a Page Filter for Sales Document 14487. In the layout, Product Sold and Source Ledger are selected as columns.

We also add a custom calculated measure CM I per Base Unit using the Create Calculation functionality:

roman_rapp_10-1789124200056.png

Figure 12: Create Calculation — CM I per Base Unit formula

Field

Value

Description

CM I per Base Unit

ID

MARGINBASEUNIT

Formula

[ContrbnMargin1AmtInDspCrcy] / [BlldAddl1QuantityInAddl1Unit]

Results in Ledger 0E

roman_rapp_11-1789124218456.png

Figure 13: Product Profitability Review Booklet — Ledger 0E, Sales Document 14487

Measure

Unit

RR01 — Water-Bottle

RR02 — Water-Carton

RR03 — Water-Pallet

Contribution Margin I

EUR

21,00

46,50

55,80

Recognized Revenue

EUR

121,00

346,50

415,80

COGS Variable

EUR

-100,00

-300,00

-360,00

Billed Quantity

 

100 BT

30 CAR

2 PAL

Margin per Unit (CM I)

 

0,21 EUR/BT

1,55 EUR/CAR

27,90 EUR/PAL

Billed Additional Qty 1

BT

100

300

360

Shipped Quantity

BT

100

300

360

CM I per Base Unit

EUR/BT

0,21

0,16

0,16

 

Billed Quantity reflects the original sales units (100 BT, 30 CAR, 2 PAL). Billed Additional Quantity 1 shows all products unified in Bottle (BT). Shipped Quantity also shows the base-unit quantities, confirming that SAP automatically handles this for material documents. CM I per Base Unit delivers a fully comparable margin metric across all three products.

Section 7: Delivery, Billing, and the Complete Process Flow

With the sales order in place, we process the outbound delivery and create the billing document. The full document chain can be traced on the Process Flow tab of Sales Order 14487.

roman_rapp_12-1789124251283.png

 

Figure 14: Sales Order 14487 — Process Flow showing the complete document chain

Step

Document

Status

Order Processing

14487

Completed

Delivery Processing

80007474

Shipped

Billing

90003192

Completed

Accounting

9400000320

Not Cleared

 

The green checkmarks on all steps confirm successful completion. The Accounting document is posted but not yet cleared by an incoming payment — expected status at this point.

Posting to Ledger 0L

With the billing document completed, revenue and COGS are now posted in Ledger 0L — the leading operational ledger. Two CO document items are created:

  • From the billing document (VBRK): The Quantity Conversion Extension converts billing quantities from their sales units to the base unit BT and writes the result into Additional Quantity 1. Additional Quantity 2 is populated with the gross weight.

From the delivery / goods issue (MKPF): SAP already converts goods issue quantities to the base unit automatically. The extension passes the quantity through unchanged.

Section 8: Verification in Ledger 0L — Actual Postings

We return to the Product Profitability Review Booklet. The layout now shows both Ledger 0E and Ledger 0L side by side as column dimensions, giving a clear picture of how the predictive postings have been replaced by the actual postings.

roman_rapp_13-1789124271587.png

 

Figure 15: Product Profitability Review Booklet — Ledger 0E cleared, Ledger 0L with actual postings

Ledger 0E — Cleared

All values in the Ledger 0E (Commitment/Prediction) columns are now 0 across all three products. Once the billing document was created and posted to Ledger 0L, the system automatically reversed the predicted postings in Ledger 0E. Billed Additional Quantity 1 in Ledger 0E also shows 0, confirming that the reversal covers the additional quantity fields populated by the extension.

Ledger 0L — Actual Values Confirmed

Measure

Unit

RR01 — Water-Bottle

RR02 — Water-Carton

RR03 — Water-Pallet

Contribution Margin I

EUR

21,00

46,50

55,80

Recognized Revenue

EUR

121,00

346,50

415,80

COGS Variable

EUR

-100,00

-300,00

-360,00

Billed Quantity

 

100 BT

30 CAR

2 PAL

Margin per Unit (CM I)

 

0,21 EUR/BT

1,55 EUR/CAR

27,90 EUR/PAL

Billed Additional Qty 1

BT

100

300

360

Shipped Quantity

BT

100

300

360

CM I per Base Unit

EUR/BT

0,21

0,16

0,16

The results mirror exactly what was observed in Ledger 0E — confirming that the Quantity Conversion Extension works consistently across both ledgers and for both predicted and actual postings.

Conclusion and Summary

This blog has demonstrated how the Quantity Conversion Extension based on BAdI FIN_CODOC_ITEM_QUANTITY addresses a real reporting challenge in SAP S/4HANA Cloud Public Edition: the inability of the Market Segments app family to display quantities in a unified unit of measure when different subsidiaries or sales channels invoice in different sales units.

The solution is built entirely on SAP's supported extensibility framework — no modifications, no custom tables, no transport requests outside the Clean Core model. The steps covered end-to-end are:

  1. Product Master Data — Define alternative units of measure with conversion factors (e.g., 1 CAR = 10 BT, 1 PAL = 180 BT) and assign the correct sales unit per distribution chain.
  2. Configuration (SSCUI 102406) — Activate Additional Quantity fields in Profitability Analysis with the appropriate physical dimensions (No dimensions for countable units, Mass for weight).
  3. Custom Logic App — Create a BAdI implementation for FIN_CODOC_ITEM_QUANTITY (Controlling Document Line Item Additional Quantities) with no filters required.
  4. ABAP Implementation — For billing documents, convert the sales unit quantity to the base unit using I_ProductUnitsOfMeasure. For material documents, pass the quantity through. Populate Additional Quantity 2 with the gross weight for all document types.
  5. Publish — Activate the implementation in the Custom Logic app.

 

The result is verified in the Product Profitability Review Booklet, where Billed Additional Quantity 1 shows all products in the unified base unit, and the calculated measure CM I per Base Unit delivers a comparable margin metric across products — regardless of the invoicing unit. The extension also works seamlessly with Predictive Accounting (Ledger 0E), with predicted postings correctly cleared and replaced by actual Ledger 0L postings once billing is complete.

Outlook — Company Profitability Review Booklet (2702)

We plan to include the Additional Quantity fields also in the Company Profitability Review Booklet with release 2702, so it can also be used for Contribution Margin reporting on product level with both sales unit and base unit measures.

roman_rapp_14-1789124322478.png

Figure 16: Company Profitability Review Booklet (Ledger 0L)

This blog covers SAP S/4HANA Cloud Public Edition. The BAdI FIN_CODOC_ITEM_QUANTITY and the Additional Quantity fields in Profitability Analysis are available in the current release. The planned extension of the Company Profitability Review Booklet is subject to the standard SAP release process.