cancel
Showing results for 
Search instead for 
Did you mean: 
Subscribe

Hello Experts,


Facing a unique error in one of the CPI artifacts we have been working on. Please find the error description below:

com.sap.it.rt.adapter.http.api.exception.HttpResponseException: An internal server error occured: No signature of method: AvgCostKafka__Script$_processData_closure7$_closure12.doCall() is applicable for argument types: (groovy.json.internal.LazyMap) values: [[MaterialGroup: , CompanyCode: , CurrencyRole: , PriceDeterminationControl: , ...]]

Hiding the actual values for the fields Material Group, Company Code, Currency Role and Price Determination Control.

Somehow whenever I am getting this specific combination of values the Groovy script is failing.

Possible solutions: doCall(java.lang.Object, java.lang.Object), findAll(), findAll(), isCase(java.lang.Object), isCase(java.lang.Object).

Let me know if you need any more information. Thanks.

Let me also share the Avg Cost Kafka Script here for your reference.

Thanks,

Rohit Sinha

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.json.*;
import groovy.xml.*;
import groovy.util.*

def Message processData(Message message) {
    //Body 
    def body = message.getBody(String.class);
    
    if (body.charAt(0) != '[') {
        body = "[" + body + "]";
    }

   def mapArray = new JsonSlurper().parseText(body);

//Key and value schemas
    def keySchema = [   type: "string"]; 
    
    def keySchemaValue = JsonOutput.toJson(keySchema);
    def keySchemaJson = JsonOutput.toJson([key_schema: keySchemaValue]);
    
    keySchemaJson = keySchemaJson.substring(0,keySchemaJson.length()-1) + ",";
		            
	def header = 	[
		             [name: "PartNumber", type: "string"],
                     [name: "MaterialDescription", type: ["string", "null"]],
                    ];

    def items =     [ name: "WarehouseAverageCosts",
         type: [
             type: "array",
             items: [
                 name: "WarehouseAverageCost",
                 type: "record",
                 fields: [
                                [name: "MaterialGroup", type: ["string", "null"]],
                                [name: "CompanyCode", type: ["string", "null"]],
                                [name: "CurrencyRole", type: ["string", "null"]],
                                [name: "PriceDeterminationControl", type: ["string", "null"]],
                                [name: "Plant", type: "string"],
                                [name: "MaterialPriceUnitQty", type: "int"],
                                [name: "MovingAveragePrice", type: "double"],
                                [name: "BaseUnit", type: "string"],
                                [name: "Currency", type: "string"],
                                [name: "TotalValuatedStockQty", type: "double"],
                                [name: "WarehouseCode", type: "string"]
                            ]
             ]
        ]   
    ] 

    def fields = header;
    fields.add(items);

    def valueSchema = [ type: "record", name: "AverageCostDetails", fields: fields ];
    def valueSchemaValuePart = JsonOutput.toJson(valueSchema);
    def valueSchemaJson = JsonOutput.toJson([value_schema: valueSchemaValuePart])
    valueSchemaJson = valueSchemaJson.substring(1, valueSchemaJson.length()-1) + "," ; 
    def avroMap = [:];
    def itemList = mapArray.WarehouseAverageCosts;

    def fieldTypes = header.collectEntries { [it.name, it.type] } ;

    def mapsize = 0;
    itemList.each { item-> 
      item.each { 
         mapsize++;
      }
    }
  
    items.type.items.fields.collectEntries { [it.name, it.type] }.each { key, value ->
    fieldTypes.put(key, value);   
    }
    // println bodyMap;
    // println body;
        mapArray.each {record ->
          record.each { key, val ->
        if(key != "WarehouseAverageCosts") {
            if(fieldTypes[key] instanceof List){
                avroMap.put(key, [(fieldTypes[key].get(0)) :  val]);
            } else avroMap.put(key, val) 
        }
          }
    };

      def tempMap = [:];
      def tempList = [];
      
       if ( mapsize != 11 )   {            
        itemList.each {item-> 
           item.each { record->
            record.each { key, val ->
           if(fieldTypes[key] instanceof List){
                if (val != "" && val != "000") {
                    println val
                    tempMap.put(key, [(fieldTypes[key].get(0)) : (convertValue(fieldTypes[key].get(1), val))]);
                } else {
                    tempMap.put(key, null);
                }
            } else tempMap.put(key, toDouble(fieldTypes[key],val)) 
        
           }
        tempList.add(tempMap.clone());
           }
    } } 
    else {
          itemList.each { record->
            record.each { key, val ->
           if(fieldTypes[key] instanceof List){
                if (val != "" && val != "000") {
                    println val
                    tempMap.put(key, [(fieldTypes[key].get(0)) : (convertValue(fieldTypes[key].get(1), val))]);
                } else {
                    tempMap.put(key, null);
                }
            } else tempMap.put(key, toDouble(fieldTypes[key],val)) 
        
           }
        tempList.add(tempMap.clone());
           }
    } ;
     
    avroMap.put("WarehouseAverageCosts", tempList)

    def keyval = mapArray.PartNumber.join(', ');
    def records = [[key: keyval, value: avroMap ]];
    def kafkaPayload = [records: records];
    def output = JsonOutput.toJson(kafkaPayload);
  
    def messageOutput = JsonOutput.toJson(kafkaPayload);
    messageOutput = messageOutput.substring(1,messageOutput.length()-1);

    def finaloutput = keySchemaJson + valueSchemaJson + messageOutput + "}"; 
    
    message.setBody(finaloutput);

	return message;

}
def convertValue (type, value) {
    switch(type) {
        case "int":
            if (value instanceof Integer) {
                return value  
            } else 
                return convertToInt(value)
        case "string":
            if (value instanceof String) {
                return value 
            } else 
                return value.toString()
        case "boolean":
            return convertToBoolean(value)
        case "double":
            if (value instanceof String){
                return  convertToDouble(value) 
            } else
                return value
        default:
            return value
    }
}

def convertToInt(String input) {
    int output = (int) input.toDouble() ;//input.toInteger();
    return output;
}

def convertToDouble(String input) {
    Double output = input.toDouble();
    return output;
}

def convertToBoolean(String input) {
    Boolean output = input.toBoolean();
    return output;
}

def convertToNull(String input) {
    if(input != ""){
        return input
    } else
        return null;
}

def toDouble( type, val) {
    if (type=="double") {
        return Double.parseDouble(val); 
    } else if( type=="int") {
        return convertToInt(val)
    } else
        return val
}
0 Likes
View Entire Topic
rohit131086
Explorer
0 Likes

Hello Jwan,

Will share the artifact flow and the error log information in subsequent note.

Putting the XSLT code for Group by Part Number

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" indent="yes"/>
	<xsl:key name="PartNo" match="root" use="PartNumber"/>
	<xsl:template match="/record">
		<record>
			<xsl:for-each select="//root[generate-id() = generate-id(key('PartNo', PartNumber)[1])]">
				<group>
					<xsl:copy-of select="PartNumber"/>
					<xsl:copy-of select="MaterialDescription"/>
					<xsl:for-each select="key('PartNo', PartNumber)">
						<WarehouseAverageCosts>
							<xsl:copy-of select="MaterialGroup"/>
							<xsl:copy-of select="CompanyCode"/>
							<xsl:copy-of select="CurrencyRole"/>
							<xsl:copy-of select="PriceDeterminationControl"/>
							<xsl:copy-of select="Plant"/>
							<xsl:copy-of select="MaterialPriceUnitQty"/>
							<xsl:copy-of select="MovingAveragePrice"/>
							<xsl:copy-of select="BaseUnit"/>
							<xsl:copy-of select="Currency"/>
							<xsl:copy-of select="TotalValuatedStockQty"/>
							<xsl:copy-of select="WarehouseCode"/>
						</WarehouseAverageCosts>
					</xsl:for-each>
				</group>
			</xsl:for-each>
		</record>
	</xsl:template>
</xsl:stylesheet>
Pls find the code for Set header part number.
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.json.*;
import groovy.xml.*;
import groovy.util.*

def Message processData(Message message) {

    def body = message.getBody(String.class);
     
	def root = new XmlSlurper().parseText(body);
    def PartNumber = root.group.PartNumber.text();
	
	message.setHeaders([:]);
    message.setHeader("PartNumber", PartNumber);
    
    return message;
}