on 2012 Apr 05 2:23 AM
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 ?
Request clarification before answering.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
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
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 ?
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
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("")) {
isBomitem = false;
}
else
{
isBomitem=true;
}
}
else
{
if (isBomitem)
{
}
}
}
****************************************************************************************
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
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]);
}
}
}
***************************************************************************************
>>> 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
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.
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
Very much possible using Message mapping it self,prepare clear mapping document and start bulding the interface. you may required UDF's combination.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
i think java/xslt mapping is better than Abap mapping because in feature pI versions(from 7.3v) will not support abap mapping on single stack and if mapping is very complexity so better to go java / xslt only.
Message was edited by: solasu bhavanisankar
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I think this can be achieved using standard message mapping. If not, then go for either java or xslt mapping. Considering future PI versions, I would not recommend for ABAP Mapping.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I find that XSLT is a good mapping technique when working with IDOC's. It handles recursive processing really well and parent/child elements.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
82 | |
29 | |
9 | |
8 | |
7 | |
7 | |
7 | |
6 | |
6 | |
5 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.