cancel
Showing results for 
Search instead for 
Did you mean: 

Mapping question - which mapping to use ?

Former Member
0 Kudos
146

Hi

   We are on PI 7.1 EHP1 SP05 and have a scenario to map . Flat text file --> idoc mapping. Each line in the text file maps to a line item in the idoc P01 segment.

Have a text file in the following structure  - shown using a sample file as an example : 6 fields in fixed width format ( last column is the mapping action to be taken )

PO Number

Store Number

Part Number

SAP Code

SAP Code Type

Quantity Order

Blank

Action to take and reason

WH00261

12750

62225

PP635211

002

3

Map to Idoc - standalone sku

WH00261

12750

1109025

PP683008

002

1

Map to Idoc - standalone sku

WH00261

12750

84266

PP767197

002

2

Map to Idoc - standalone sku

WH00261

12750

3102202

PP263194

002

4

Map to Idoc - standalone sku

WH00261

12750

1122203

PP799412

002

1

Map to Idoc - standalone sku

WH00261

12750

91002274

PP707768

002

4

Map to Idoc - virtual "Y" BOM header

WH00261

12750

6338655

PP145428

002

1

Do not map - Y-BOM component

WH00261

12750

91002264

4

Do not map - special deal 9-code

WH00261

12750

63492

PP472885

002

4

Map to Idoc - special deal component

As we see from the above , there are special lines called BOM header lines ( ones with Part number starting with 9 ) followed by child part numbers. There is no explicitly specified link between the parent and child items except that child items follow the BOM header lines. For BOM header lines that have a non-blank SAP Code , those BOM header lines should be mapped to idoc line item. The child item records following this BOM header line should NOT be mapped to idoc line item. As a second possibility , if a BOM header line has a blank SAP code , then that line should not be mapped to the idoc line item, but the child items following that BOM header line should be mapped to idoc line item. Apart from the BOM header lines and the child line items following it, there are normal line that map unconditionally to idoc line item segment.

Question - can the above be achieved using a message mapping or is a Java / ABAP mapping needed for the complexity above ?  Any approaches suggested to map the flat file as above to idoc line item segments ?

View Entire Topic
former_member184681
Active Contributor
0 Kudos

Hi,

Generally, it is a matter of your own preference, competence and comfort to choose the mapping method. But in this particular case I agree with Baskar Gopalakrishnan and Raja Sekhar Reddy that graphical ("standard") mapping should be able to handle this case. It is only a matter of building some conditions and setting contexts properly.

>>> Any approaches suggested to map the flat file as above to idoc line item segments ?

Of course Use File Content Conversion (http://help.sap.com/saphelp_nwpi71/helpdata/en/44/6713ec3f914ddee10000000a1553f7/content.htm) to convert the source flat file to an XML structure that you will be able to map easily to the target IDoc, graphically.

Hope this helps,
Greg

Former Member
0 Kudos

Hi

  Thanks for your reply. I would prefer using message mapping ( graphical ) with use of udfs if needed. Would need your help here to answer a few main questions that I have while implementing this in message mapping.

Yes, content conversion to move the text file to an xml , given, no issues there.

When I start with message mapping , how do I set the condition for the child item ( occuring under the type 9 header item ) to be mapped or not mapped ? I was thinking of the use of a global variable and setting that variable to true or false depending on whether the header item is mapped and then check for the value of this global variable and then map the child item .

I have the following map as a condition to map to the target - I have used a createif node function at the end. How do I also set the value of the global variable ( in the approach mentioned above ) in the message mapping - under the condition that the type 9 header records maps to target ( createif - has a TRUE condition ) and the child items following it have to refer to this global variable value and not be mapped .

Can you give me some idea of how to go about this condition in graphical mapping.

former_member184681
Active Contributor
0 Kudos

Hi,

I believe here is where you will need a small UDF, at least if you want your solution to be readable . Map the node as: source node -> UDF -> removeContexts -> target node. And here is the UDF (assuming that it has two input values: partNumber and sapCode, and the execution type is set to "All Values of Queue"):

boolean isBomItem = false;
for(int i = 0; i < partNumber.length; i++) {
  if (isBomItem) isBomItem = false;
  else if (!sapCode[i].equals("")) result.addValue(partNumber[i]);
  if (!sapCode[i].equals("") && partNumber[i].substring(0,1).equals("9")) {
    isBomItem = true;
  }
}

Remark: the logic above will only work assuming that your BOMs always have only one subitem. I believe your logic is only achievable if this condition is true, in general.

Hope this helps,
Greg

Former Member
0 Kudos

Greg

      When you say in the Remarks section , BOMs having only one subitem , you mean only one level of subitem right ? Or do you mean - one child item only ? A type 9 header record can have many child items following it before the next type 9 appears .

The above logic would not work  if a BOM type 9 header record has multiple line items following it ?

former_member184681
Active Contributor
0 Kudos

Hi,

You are right, this logic will not work for multiple BOM subitems. Now let me ask a question: is the sequence fixed: "normal" items first, then BOMs? In other words: after a first BOM appears, will there be no "normal" items? Because otherwise, how will you differentiate a "normal" item from a BOM subitem? For instance for the following:
1. BOM header
2. some non-BOM item
3. some non-BOM item
How would you know whether item 3 is still a subitem of BOM (1) that should be removed, or a "normal" item that should be mapped to target?

Based on your answer, I will provide a small fix to the code .

Regards,
Greg

Former Member
0 Kudos

BOM items appear at the end of the file , right. After BOM items appear , the other non-BOM items following that type 9 item are all child items under that type 9. There could another type 9 after a few child items, but that would be a new BOM header again followed by its child items.

I made some changes to your code and updated the UDF to be this ( whole code given below ), but when I test with two lines in the file ( using the test option in design time )- a type 9 with blank SAP code and a child item following it, the mapping maps the type 9 and not the child item ( it should be the other way around ).  The check in the line  if ( sapCode[i] != null && !sapCode[i].equals("")) seems to be failing - since the flow is going through this check and mapping the type 9 items to the target and setting the isBomitem to false.

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

Boolean isBomitem = true;

for(int i = 0; i < partNumber.length; i++) {

if (partNumber[i].substring(0,1).equals("9")) {
  if ( sapCode[i] != null && !sapCode[i].equals("")) {

  1. result.addValue(partNumber[i]);

isBomitem = false;
  }

else

{

                isBomitem=true;

}

}

else

{

                if (isBomitem)

{

  1. result.addValue(partNumber[i]);

}

}

}

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

former_member184681
Active Contributor
0 Kudos

Hi,

Try with the following code:

Boolean bomItems = false;
Boolean isBomitem = false;
for(int i = 0; i < partNumber.length; i++) {
  if (partNumber[i].substring(0,1).equals("9")) bomItems = true; //BOM items start here
  if (bomItems == true) {
    if (partNumber[i].substring(0,1).equals("9")) {
    if (sapCode[i].equals("")) isBomItem = false;
    else { result.addValue(partNumber[i]); isBomItem = true; }
  }
  else {
    if (isBomItem == false) result.addValue(partNumber[i]);
  }
}
else {
  result.addValue(partNumber[i]);
}

You might also need to use mapWithDefault("") standard function between the source field sapCode and the UDF, in case the condition you mentioned still fails.

Hope this helps,

Greg

Former Member
0 Kudos

Hi

  I think the following code works now - I can use this udf for my unbounded node mapping.

Now - each of my target elements under the unbounded node ( eg : item node unbounded has element a,b, c, d, e , f )  has to use this udf to map so that the conditions in this udf apply to each of the target element mapping, right ?

But , how do I put the element name as a variable in the result.addValue(??) statement of the udf so that each target element gets the correct source element value mapped to it ? Do I have to create a separate udf for each element mapping ?

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


MappingTrace trace = container.getTrace();
Boolean isBomitem = true;

for(int i = 0; i < partNumber.length; i++) {
System.out.println ( sapCode[i]);

if (partNumber[i].substring(0,1).equals("9")) {
  int length = sapCode[i].length();
//trace.addInfo("hey type 9" + length);

  if ( sapCode[i] != null && !sapCode[i].equals("") && length != 0 ) {

//trace.addInfo("hey type 9,should not be going here :" +  i);
result.addValue(partNumber[i]);
isBomitem = false;
  }
else
{
//        trace.addInfo("hey type 9,setting child item map to true :" + i);
                isBomitem=true;
}
}
else
{  //         trace.addInfo("child item processing :" + i);
                if (isBomitem)
{     //  trace.addInfo("child item processing : inside : " + i  +partNumber[i]);
result.addValue(partNumber[i]);
}
}
}

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


 

former_member184681
Active Contributor
0 Kudos

>>> Now - each of my target elements under the unbounded node ( eg : item node unbounded has element a,b, c, d, e , f )  has to use this udf to map so that the conditions in this udf apply to each of the target element mapping, right ?

Not really. You use this UDF to create the nodes themselves, and thanks to that you can use even straight 1:1 mappings for the subfields. So if you build good conditions for the root (which you have just done), you do not have to repeat the UDF for each subfield.

Hope this helps,

Greg

Former Member
0 Kudos

Hi Greg

            I tried a straigt source element to target element mapping for each of the elements under the unbounded node. I see that in the case of two records - first one with a 9 and blank SAP code hence not mapped to target, the next record - which is the child record after the type 9 gets mapped to the target for the partcode value correctly ( since partcode [i] is specified in the udf ) . The other target elements of the child record get the values of the elements of type 9 record.

Former Member
0 Kudos

Sorry - even the partcode value mapped to the target element of the child record is the wrong one - its the partcode of the type 9 record.

former_member184681
Active Contributor
0 Kudos

It looks like a matter of setting contexts properly in the mapping. The best solution I can see is to change the UDF as follows, then use: source -> UDF -> createIf -> removeContexts -> target for the node, then simple 1:1 mappings for the fields. Find the latest UDF update in attachment.

Regards,

Greg

Former Member
0 Kudos

Thanks  a lot Greg for your help. This gave me my mapping solution.