Fractional Product Planning in MRP
I will start by explaining what fraction products, the subject of this blog post, mean.
First of all, I will start with the meaning of fractional products, which is the subject of this blog post. An example of an MRP project in SPRO Technology company was carried out with an oil producing company. Fraction actually means to divide. The place of use in this company is that while some oils at the semi-finished product level are produced, another material with a fraction is also released. So it comes out just like a co-product. However, the need for this project is that these products are produced according to a certain ratio and planning is required according to this ratio while MRP is working.
In order to meet the need reported to us, it was necessary to intervene with a development in order to enable MRP to plan for a fractional product while planning for a material. So, first thing we debugged the code running behind while MRP was running to figure out where to make this improvement. After debugging, we decided to include named “MM61XMDV_READ_NEXT_MDMMX_PL” for this process.
In the MARA table, the materials have a value with the technical name DISST. Its definition is “MIP Level”. This value is used to determine the order in which materials will be scheduled while MRP is running. The materials we find are included in the table named MDMMX according to their DISST. It is determined that the included will be written to the enhancement spot at the beginning. After this information is obtained, it is finalized where the development will be made.
As we mentioned at the beginning of the article, since fractional products emerge according to a ratio, there is a need for a table to keep these ratios. For this reason, a maintenance table was created and filled in so that the rate data could be kept. The final image of the table was as follows:
Fraction Ratio Table
Of course, since users need to keep this data up-to-date and the table needs to be maintained in cases such as adding new material, an operation code has been defined in the maintenance table. With this operation code, users are able to maintain the table when they deem it necessary.
Let's come to the part of the code where we are enhancing. As soon as MRP works, when it falls into the enhancement for the first time, first of all, the delete_run variable, which is defined in order to delete the planned orders created through our development, is imported and its value is checked in order to understand whether the deletion is done. If delete_run is empty, it will enter the condition written for deletion of planned orders created in previous plans. This means that the deletion is not yet done.
After entering this condition, the thing to check is whether the planning scenario (PLSCN field) is full. Because if the planning scenario is filled, the planning scenario information is recorded in the tables as full. In order to delete, records should be searched with this information while searching in the database.
A planned order profile (PASCH) with the code "ZA" has been created in order to distinguish the planned orders that will be created through the development that is the subject of this block. However, this order profile was also written in the "Fixed Vendor" (FLIEF) field, which is not used in the system where the development was made, since it could not be written to the PASCH field while the planned orders were created with the help of bapi. Therefore, while the planned orders to be deleted were pulled from the database, the planning scenario (if full) and fixed vendors were pulled from the PLAF table and filled into an internal table called gt_plaf.
After the planned orders that were requested to be deleted were taken, they were deleted from the database by giving the "BAPI_PLANNEDORDER_DELETE" planned order numbers (PLNUM) in the loop. After the deletion is done, the first checked "delete_run" variable is Xed and imported to memory id in order to understand that the deletion is done when the code falls into this part again.
Then "IF rm61x-werks = '0191' AND mdmmx-disst = '999'." control is done.
The reason for this condition is that after MRP finishes its scheduling, it will process those with the last DISST of 999. We do the development just before processing the 999 ones, as this is the least important part of the planning.
Then select count is thrown into the fraction ratio table and if the subrc returns 0, the code continues. Here it is checked whether the table is full.
Then, two different variables named gv_first_run and gv_oncelik are imported. The reason why we have 2 different variables in this way is that the operations we do when we drop into this section for the first time are separated, and the fractional materials to be planned have an order of importance in themselves.
If gv_first_run is empty, that is, if this is the first time to drop into this section, then the fraction rates are filled into an internal table. In the fraction ratio table, there are 2 materials in a row, as the ratios of materials to each other are available. In order to write each material in a single line, these materials are returned in a loop, filled again into a separate internal table and ordered from smallest to largest.
After sorting, the BOM is exploded with the CS_BOM_EXPL_MAT_V2 function for all materials in this table. After the BOMs are exploded, all components are filled into a separate internal table with their crown materials and their ranks in the BOM. Afterwards, this table is read by giving the materials in the table containing the fraction materials to the IDNRK (i.e. component) field, if these materials cannot be found as components, the priority value is filled with "1" since they are the top material. If they are found in the component area, the stufe (step) value of the component they are in is written to the relevant one of two different variables named lv_matnr1_stufe and lv_matnr2_stufe. These variables are then compared among themselves. If the variable of both materials in the relevant row of the table is full, 1 is added to the level of the larger one and written in the priority field of the relevant record. If either one is full, 1 is added to the value of the full one and written in the priority field of the row. This process continues until all records in the table have been processed.
After all records are processed and priority values are determined, these records are thrown into a table with Z. (Table fields: MATNR1, RATIO1, MATNR2, RATIO2, PRIORITY) Then, the value of the gv_first_run variable is set to "X" and the value of the gv_priority variable to "1" and exported to two separate memory ids.
These were the jobs performed if gv_first_run was empty, that is, if it was being dropped for the first time. If it is not deducted for the first time, that is, if the value of the gv_first_run variable that we read with the memory ID is X, the value of the gv_first_run variable is increased by 1 and continued.
The next step is to read the current requirement/stock list (MD04) data of the fraction materials that are being planned by MRP and to extract what is needed from the data read for fractional product planning. The "MD_STOCK_REQUIREMENTS_LIST_API" function is used to read these data. To run the function, the MATNR, WERKS fields are filled. However, if the planning scenario is entered while running the MRP (if long-term planning is made), the PLSCN field is also filled.
After the function is run, records that do not have a PLUMI value of "+" in MDPSX, which returns from the function as an export table, are deleted. Records with a PLUMI value of + are records that will enter / enter the stock (planned order, process order, etc.), while those with a - value are records that will be out of stock (required). Since the records to be taken into account in the fractional product planning will be the records that will enter the stock, the records that are not + have been deleted. Then, records without DELKZ (Mip Element Indicator) field SA are deleted in MDPSX if it is long-term planning (planning scenario is full), records without DELKZ field PA and BR if it is not long-term planning (planning scenario is empty). In these records, SA stands for "Simulation Order", PA stands for "Planned Order" and BR stands for "Process Order".
After leaving only the records to be taken into account in the fractional product planning in the MDPSX table, the week information of the records is needed because the production planning is made on a weekly basis in the company where the development is made. In order to obtain this information, the “GET_WEEK_INFO_BASED_ON_DATE” function was used in the development. When the date of learning the week information is entered into this function, it gives the information of which week of the year the relevant date is. In this part of the development, the DAT00 (date) field of the records left in the MDPSX table is given to the "DATE" field of this function one by one, and the week information is written together with the other fields (material, planned order, etc.) into the wa_calculate structure created for use in calculations.
In the calculations, the logic of filling all the data into an internal table and making calculations by comparing the data over this table was carried out. In this calculation table, the process and fixed planned orders are evaluated in the same status as the system evaluates it in the same way. The fields in the table are production location, planning scenario (leave blank if there is none), material, week, process + fixed planned order, planned order, total production, arrivals from previous weeks, total quantity, co-calculation, addition.
From these areas, the production site, the planning scenario and the material come as standard from the material being processed and the planning parameters. The “Process Order + Fixed Plan Order” field is obtained by adding the MNG01 (Quantity) values of the records with DELKZ BR and PA and FIX01 (Fixing Indicator) field X in the MDPSX table on a week-based basis. The “Planned Order” field is obtained by summing the MNG01 values of the records with DELKZ PA and empty FIX01 field in the MDPSX table.
The “Total Production” field is obtained by summing the values in the “Process Order + Fixed Scheduled Order” field and the “Planned Order” field.
In order to find the value of the "Incoming from Previous Weeks" field, firstly the value of the "Total Production" field in the previous record is checked. If the "Total Production" value is 0, the "Add" value in the previous record + the values in the "Incoming from Previous Weeks" field of that record are added together. However, if the "Total Production" field is not 0, only the "Add" value from the previous record is written. But in the algorithm, after the insertion value in the row being processed is calculated, it is written in the field from previous weeks of the next related record.
In the "Total Quantity" field, if the "From Previous Weeks" value is greater than the "Total Production" value, directly write the "Process + Fixed Plan Order" value, if not, add the "Planned Order" and "Process + Fixed Plan Order" fields, " It is found by subtracting the “From Previous Weeks” value.
The “Co-Calculation” field indicates the amount that should be planned by comparing the material currently being processed with its equivalent product according to the ratios in the fraction ratio table. The value of this field is calculated by multiplying the value in the "Total Amount" column with its own ratio in the fraction table and dividing by its partner's ratio.
Finally, to find the value of the "Add" field, it is checked whether the "Peer Calculation" field is greater than the "Total Amount" field. If it is large, the value of "Process + Fixed Plan Order" is subtracted from the "Co-Calculation" field and written in the "Adding" field. If it is small, “0” is written as there is no amount to be added anyway. We have explained how the areas are calculated here, but let's rewrite the area below to make it easier to see.
Production Place: Standard
Planning Scenario: Standard
Material: Standard
Week: Week Value Returned from Function
Process Order + Fixed Schedule Order: Sum of MNG01 of records with DELKZ of BR and PA and FIX01 of X in MDPSX table
Planned Order: The sum of MNG01s of records with DELKZ PA and empty FIX01 in the MDPSX table
Total Production: Combining the “Process Order + Fixed Plan Order” field with the “Planned Order” field
From Previous Weeks: Equal to the value of the "Add" field from the previous week of the same item
Total Quantity: “From Previous Weeks” > “Process Order + Fixed Schedule Order” if “Planned Order”, otherwise “Planned Order” + “Process Order + Fixed Schedule Order” – “Incoming from Previous Weeks”
Co Calculation: “Total Quantity” value in the processed record * Ratio of material in the fraction table / Ratio of its Equivalent in the fraction table
Add: If “Co-Calculation” value is greater than “Total Quantity” = “Co-Calculation” – “Process Order + Fixed Plan Order”. If less = “0”.
According to these calculation methods, records are calculated one by one by rotating in their related rows. As a result of the calculations, a table appears as in the image below.
Rate table
After the above table is revealed, it becomes clear that a supply proposal should be created from which materials for which weeks and in which quantities. After this data is obtained, what needs to be done is to add these data to the table containing the information about which materials will be planned in which order while MRP is running.
At this stage, records with the "Add" field greater than 0 (that is, additional procurement proposals need to be created) and the components of these records should be added to the MDMMX table. To process these records, a loop is created for the records whose "Add" field is larger than 0. Inside this loop, data is filled into an internal table to perform the related operation.
Next, the BAPI_PLANNEDORDER_CREATE function will be called to create a planned order for records with the "Add" field greater than 0. However, first of all, the WEEK_GET_FIRST_DAY function is called to find the date of the first day of the relevant week of the records with week information in the calculation table and for which planned order will be created. The week information is given to the function as the import parameter and the date returned as export is given to the order_start_date (planned order start date) field in the import structure of the BAPI_PLANNEDORDER_CREATE function.
Then, the import parameters of the BAPI_PLANNEDORDER_CREATE function are filled with the data in the relevant record of the table returned with the loop, that is, the planning scenario, planned order profile, fixed vendor, material, manufacturing plant fields, if any, with the available data. The planned order quantity is filled with the values written in the "Adding" field. The "Convert" and "Fix" indicators are Xed and the function is run. Then, if the data in the "return" table is returned as "return_type = 'S'", "return_id = '61'" and "return_number = '010'", it is committed by calling BAPI_TRANSACTION_COMMIT for commit. If the data is not returned in this way, rollback is done with the BAPI_TRANSACTION_ROLLBACK function for rollback. For all records with the "add" value greater than 0, this process repeats in a loop.
Then, if the internal table filled for the MDMMX table is full, go to the MARA table for the data (materials and components) in this internal table and get the DISST value. As I mentioned at the beginning of the blog post, this area is the area that determines the order in which MRP will plan the material. After the DISST of all materials is taken and written to the internal table, the data in this table is thrown into the MDMMX table collectively and sorted from the smallest to the largest according to the DISST value.
Finally, the final version of the calculation table is tabulated into the log table created so that the intervention of the development in the planning work can be examined. After this process, the work of the algorithm is completed.