MM (Materials Management)

Mass Purchase Order Reprice with S/4 HANA

Introduction:

In this blog, I will try to demonstrate the functionality of mass purchase order reprice in SAP S/4 HANA.

The pandemic lead to a massive shutdown followed by a slowdown and cause supply chain disruption. Disruption in the supply chain, raising fuel and freight costs often leads to frequent price changes from the vendors (especially oversees long lead time items). As a buyer, it’s important to catch up with frequent and fast changes to make sure the landed cost of the product is correct and 3-way match happens as accurately as possible. This blog will help on how to achieve the solution.

Prerequisites:

  • Price update from the vendor will be updated on Purchasing Info Record as a new valid condition record.

Standard SAP options:

Below is the standard SAP option that was explored:

  • Standard SAP has t-code: MEI1 which allows updating PO based on condition changes, but standard SAP looks at the PO creation date and condition validity period date and updates the price.
  • It was also found that once we process records using MEI1, it is deleting the Table: WIND entries for that vendor of all the items. That means as a buyer, if you want to work on certain items on the PO the next day, you lost visibility of price updates.

Both of the above challenges force me to think of a custom solution.

Solution Approach/Design:

  • Create a Fiori tile as per the below layout
Selection Layout
  • No of Day in the Past*: Mandatory; This is for performance. From day of execution, how many days back do we want to go for the document date; by default 180 days.
  • Purchasing Group: Mandatory; Multiple selection drop-down; Validation: T024- T024; E: Purchasing Group Required or E: Invalid Purchasing Group.
  • Purchasing Document Type: Optional; Multiple selection drop-down; Validation: T161- BSART; E: Invalid Document type.
  • Supplier: Optional; Multiple selection drop-down; Validation: LFA1- LIFNR; E: Invalid Supplier.
  • Supplier Subrange: Optional; Multiple selection drop-down; Validation: WYT1- LTSNR; E: Invalid Supplier Subrange.
  • Plant#: Optional; Multiple selection drop-down; Validation: T001W-WERKS; E: Invalid Plant.
  • Material Group#: Optional; Multiple selection drop-down; Validation: T023-MATKL; E: Invalid material group.
  • Material#: Optional; Multiple selection drop-down; Validation: MARC-MATNR; E: Invalid material.
  • Next Period Price/Currency: Optional;
  • Price Over-Ride: Optional
  • Future Cost Match: Optional; drop-down; values are Yes Or No
  • Fiori tile validates the data keyed in by the user and captures the appropriate error message in case of errors as stated above.
  • After validating input screen data, once the user clicks on go, the program does the following:
    • Based on the input, fetch the only open PO(s) undelete and without Free of Charge. Open PO(s) can be found where EKPO-ELIKZ not equal to X and undeleted PO(s) can be found where EKPO-LOEKZ is not equal to L and EKPO- REPOS = X (Excluding Free PO(s) as well).
    • Only fetch the PO(s) where item category EKPO-PSTYP not equal to 2 – Consignment and 7 – Stock Transfer (Basically, we don’t want consignment and stock transfer PO(s) as it doesn’t have net price).
  • Below are the fields and logic:
Field(s) Logic 
Purchase Order  From EKPO-EBELN 
Vendor  From EKKO-LIFNR 
Vendor Name  Pass Vendor from EKKO to LFA1 and get LFA1-NAME1 
Supplier Subrange  From EKPO-LTSNR 
Supplier Subrange Description  Pass Vendor and Subrange to WYT1 and get WYT1-LTSBZ 
Purchasing Group  From EKKO-EKGRP 
Purchasing Group Name  Pass the purchasing group code to T024 and get T024 – EKNAM. 
Document Type  From EKKO-BSART 
Item No  EKPO-EBELP 
Item Category  EKPO-PSTYP 
Material  EKPO-MATNR 
Material Group  EKPO-MATKL 
Material Group Description  Pass material group to T023 and get T023- WGBEZ 
Plant  EKPO-WERKS 
Material Description  MARA-MAKTX 
PO Creation Date  EKKO-AEDAT 
PO Quantity  EKPO-MENGE 
Ordering Unit  EKPO-MEINS 
Conf. Control  EKPO-BSTAE 
Inbound Delivery  Pass PO number, item number, Confirm. Cat.: LA to EKES and get the inbound delivery number. If multiple found, then sort in descending order and get the latest one. 
PO History  Pass PO and item to EKBE and see entries found. If entry is there, then show the graph. Note: T-code: ME2N is prime example on how to show the graph. If developer can find, then we should leverage that. 
PO Item Delivery Date  Pass PO and item number to EKET and get EKET-EINDT 
Price Overwrite  Pass PO to Table: EKKO and get the Doc. Condition No. (EKKO- KNUMV). Pass Condition No. To table: PRCD_ELEMENTS with PO item number and Inactive condition (KINAK) as blank and see if we have PBXX. If yes then show PBXX else blank 
PO Net Price/Currency  EKPO-NETPR/EKKO-WAERS (for example $2800/USD) 
PO Price Unit/Ordering Price Unit  EKPO-PEINH/EKPO-BPRME (for example 100/EA) 
Current Period Validity Date (From – to) 

Note: Within PB00 pricing team is loading price in tables: A017 and A018. If the A017 record then gets trigger else it will go to A018.

*****************************************************

Logic: (Developer can explore functional module. I have tried using ME_GET_INFORECORD_CONDITIONS which works fine for PB00 and PB01)

Pass Application – KAPPL = M, Condition Type – KSCHL = PB00, Vendor – LIFNR, Material – MATNR, Purchasing Org – EKORG, Plant – WERKS, Info Type – from PO line to Table: A017 and get the condition record number where Valid From < = System Date and Valid To > = System Date. Pass all the records to KONP, sort by ascending order and select 1st non-delete record. If no record is found then go to next.

Pass Application – KAPPL = M, Condition Type – KSCHL = PB00, Vendor – LIFNR, Material – MATNR, Purchasing Org – EKORG, Plant – WERKS, Info Type – from PO line to Table : A018 and get the condition record number where Valid From < = System Date and Valid To > = System Date. Pass all the records to KONP, sort by ascending order and select 1st non-delete record. If no record found, then go to next.

Also get A017-DATAB to A017-DATBI or A018-DATAB to A018-DATBI for valid record 

Current Period Price/Currency  For the valid condition record get the KONP-KBETR/KONP-KONWA (For example $284/USD) 
Current Period Price Unit/UoM  Also get the KONP-KPEIN/KONP-KMEIN (For example 100/LB) 
Scale Exist? (Flag Yes or No)  If KONP- KZBZG has value, then Scale Exist = Yes else No 
Apply Updated Cost  Checkbox 
Yes or No value for PO Price Vs. Next Period Price  Compare PO Net Price/Current, PO Price Unit/Ordering Price Unit with Next Period Price/Currency and Next Period Price Unit/UoM. If it’s matching, then show Yes else No. 
Previous Period Validity Date (From – to) 

Pass Application – KAPPL = M, Condition Type – KSCHL = PB00, Vendor – LIFNR, Material – MATNR, Purchasing Org – EKORG, Plant – WERKS, Info Type – from PO line to Table : A017 and get the condition record number where Valid From < System Date. Pass all the records to KONP, sort by descending order and select 1st non-delete record. If no record found then go to next. 

Pass Application – KAPPL = M, Condition Type – KSCHL = PB00, Vendor – LIFNR, Material – MATNR, Purchasing Org – EKORG, Plant – WERKS, Info Type -from PO line to Table: A018 and get the condition record number where Valid From < System Date. Pass all the records to KONP, sort by descending order and select 1st non-delete record. If no record found, then go to next.

Also, get A017-DATAB to A017-DATBI or A018-DATAB to A018-DATBI for valid record

Previous Period Price/Currency  For the valid condition record get the KONP-KBETR/KONP-KONWA (For example $284/USD) 
Previous Period Price Unit/UoM  Also get the KONP-KPEIN/KONP-KMEIN (For example 100/LB) 
Yes or No value for PO Price Vs. Previous Period Price  Compare PO Net Price/Current, PO Price Unit/Ordering Price Unit with Previous Period Price/Currency and Previous Period Price Unit/UoM. If it’s matching, then Yes else No. 
Purchasing Info Record 

Pass PO number and line item to EKPO and get the EKPO- INFNR. Show that as Hyperlink and when user clicks on it, it should call T-code:ME13 (Fiori tile:

Display Purchasing Info Record). Pass the PIR Number, Purchase Organization and Plant to display the record. 

Status Log  Successful/Failed message 
  • After displaying output and sorting output user will select checkbox for “apply updated cost”. Program should do following:
    • For selected PO & line items, it should say “Ready to update the price”? If user click YES, then go to next. If user click NO, then cancel the update.
    • Upon yes, update the price on PO for that item.
    • Developer can use functional module: BAPI_PO_CHANGE to update the price on PO.
    • For PO change, enter the condition type: PBXX to suggest price change.

Results after Implementing solution:

Selection Screen

Buyers click on go after entering single or multiple purchasing groups

Output
More fields in the Output
More Fields In the Output

As shown below, buyer can select one purchase order or multiple purchase orders and click on “Apply PO Cost”

Apply PO Cost
Confirmation for Update
Update Message