4.2 [Function Components] Custom Function Description

Notes:

  1. Functions before, during, and after synchronization need to set the parameters uniformly, the type is Map, and the parameter name is syncArg. The return value must also be a map.
  2. In the function after synchronization, the Fx.object.update operation and the mapped field (including the field used by the data range) cannot exist at the same time, so as to avoid loop synchronization caused by modifying the data after synchronization. The above logic will be verified when the integration flow is enabled. If you are sure that loop synchronization will not be triggered and the above conditions are required, please consult the integrated platform R&D to provide a bypass method.

1. Attributes of syncArg

syncDataId Synchronization data id
sourceTenantId source enterprise id
sourceObjectApiName source object apiName
sourceEventType source event type, 1 is "new", 2 is "update"
destTenantId target enterprise id
destObjectApiName target object apiName
destEventType target event type, 1 is "new", 2 is "update"
objectData Main object data, the value of the field can be obtained through the field APIname.
details From the object data, you can get the value of the field through the field APIname.
Note: The function before synchronization, objectData, details carry the source object data. And does not support modifying target object data.
In synchronization, objectData and details carry the source object data, and support modification of the target object data.
After synchronization, objectData and details carry the target object data.
Execute the in-synchronization function before calling the write interface of the target system, and execute the post-synchronization function after calling the write interface.
The slave object data only has data if a new event is added.

2. Function before Synchronization

Data filter will be done for custom function before synchronization

The returned result contains "isExec": false, that is, the synchronization will not be executed in the future, and the target data will not be changed accordingly.
If the return result contains "isCover":false, the result returned in the custom function will not cover the original data.
The objectData may be the data of the master object or the data of the slave object. According to object_describe_api_name, it is judged whether the data of the master object or the data of the slave object is currently passed through the function before synchronization.
Test Scene: Add "isExec": "false" or "isExec":false to the Map returned by the custom function, and the target data will not change.
Map map = ["details":syncArg.details, "objectData":syncArg.objectData, "isExec":false, "isCover":false]; return map;

3. Function during Synchronization

In the custom function during synchronization, modify the data first, and then write the modified data to the target system

log.info("Event type: " + syncArg.destEventType); log.info(syncArg.objectData); log.info(syncArg.details); Map objectData = syncArg. objectData as Map; objectData.name="Custom function modified this field" Map map = ["details":syncArg.details, "objectData":syncArg.objectData]; log. info(map); return map;

4. Function after Synchronization

Backfill order id and code after K3Cloud order is synchronized from CRM to ERP

Using Scene: as title
Example Function:
//specified object, order def sourceObjectApiName = 'SalesOrderObj' //Backfill the ERPId field def erpIdF = "field_86Xfn__c" //Backfill the ERP code field def erpNoF = "field_K4xdf__c" def destEventType = syncArg.destEventType def completeDataWriteResult = syncArg.completeDataWriteResult as Map if( syncArg. sourceObjectApiName != sourceObjectApiName|| completeDataWriteResult.destEventType!=1|| !completeDataWriteResult.success ){ log.info("Do not process") //The following cases return directly //not processing order //not new // failed return syncArg; } log.info("Start backfilling id") String sourceDataId = syncArg. sourceDataId def writeResult = completeDataWriteResult.writeResult as Map String destDataId = writeResult. destDataId def split = destDataId. split("#", 2) def upArg = [(erpIdF):split[0],(erpNoF):split[1]] log. info(upArg) def upR = Fx.object.update(sourceObjectApiName, sourceDataId, upArg) log.info("Backfill result: "+upR)

5. Escaped Custom Functions (When accessing ERP interface, format conversion is necessary)

If the native API of the ERP system is not a standard open interface and is not preset in the integration platform, it is necessary to call the ERP interface by escaping a custom function, and then convert it to a standard API.
If conditional filtering is required, it cannot be placed in the escape custom function. If the data range setting can satisfy the data range, use the pre-synchronization function if it is not satisfied.
The type of the parameter must be Map, and the name is fixed as syncArg. The parameters of each interface can be printed and observed through log.info("request parameters: "+syncArg);
queryMasterBatch Get the parameters passed by the system //call parameters: log.info("Request parameters: "+syncArg); Integer offset=syncArg["objectData"]==null? 0:(Integer)syncArg["objectData"]["offset"]; Integer limit=syncArg["objectData"]==null? 10:(Integer)syncArg["objectData"]["limit"]; Long startTime=syncArg["objectData"]==null? 0:(Long)syncArg["objectData"]["startTime"]; Long endTime=syncArg["objectData"]==null?0:(Long)syncArg["objectData"]["endTime"];queryMasterById Get the parameters passed by the system //call parameters: log.info("Request parameters: "+syncArg); String dataId=syncArg["objectData"]["dataId"];

6. Asynchronous Push Interface Escapes through Custom Function

Push Execution Logic: The external interface actively calls the push interface of the integration platform to push data to the cache of the integration platform. The platform will pull data from the cache table asynchronously. If the writing to the cache table fails, an error message will be returned directly. If the data is pulled from the cache and the processing fails, you need to check the cause of the data error in the data maintenance of the integrated platform.
Request Method: POST
Request Header Parameters:
FieldDescription
tokenRequest authentication string【Please contact FanShare R&D side to provide】
tenantIdPlease contact the R&D side of FunShare to provide
dataCenterIdSingle account sets do not need to push this field, but multiple account sets must be pushed and filled in;
objectApiNameThe real object name on the ERP side can be found in Data Synchronization Settings -> ERP Object Settings -> ERP Object Code
versionv1
operationType3 Invalid, other states do not need to push this field;
Push Steps:
1. Create an erp object
2. Create a synchronization strategy.
3. Add a custom function for push (regardless of non-standard or standard push, as long as you use the push interface, you need to add this function)
log.info("Request parameter: "+Fx.json.toJson(syncArg)) String dataStr=syncArg["objectData"]["pushData"]; Map pushDataMap=Fx.json.parse(dataStr); List<Map> pushData=[]; if( pushDataMap["data"] instanceof List){// /* Push a data example data { "data": { "number": "A2001", "lrap_days": "2", "name": "Test Product 41" } } */ pushDatas=pushDataMap["data"] as List }else if( pushDataMap["data"] instanceof Map ){ /*//Push multiple data sample data { "data": [ { "number": "A2001", "lrap_days": "2", "name": "Test Product 41" } ] } */ pushDatas.add(pushDataMap["data"] as Map) } List resultList=[] pushDatas. each { map-> Map dataMap=map as Map; String id=map["code"];//Get which field in the main object can identify a unique value dataMap.put("id",id);//It is very important to have this key and value Map data=["masterFieldVal":dataMap]//Convert to the format of the platform resultList. add(data) } return ["dataList":resultList];//The return is an array type
Push failure example
push successfully

7. Scene Function

Trigger CRM to ERP data synchronization based on CRM data ID

Using Scene: Configure buttons on the CRM list and details page to trigger data synchronization. It can be used to solve the inconvenient modification or brush data requirements of CRM data.
Example Function:
//Required, CRM object apiName def crmObjApiName = context.data.object_describe_api_name; //Required, CRM data Id def crmDataId = context.data._id //Optional, ERP intermediate object apiName, if not specified, all strategies will be synchronized, if filled, only the strategy of the specified target ERP object will be synchronized def erpObjApiName = null //"BD_Customer.BillHead" def type = "manualSyncCrm2Erp" def params = ["crmObjectApiName":crmObjApiName, "crmDataId":crmDataId, "erpObjectApiName":erpObjApiName] def arg = ["type":type, "params":Fx.json.toJson(params)] def ret = Fx.proxy.callAPI("erp.syncData.executeCustomFunction", [:], arg) //Synchronization result processing logic: log. info(ret)

Trigger ERP to CRM data synchronization according to CRM data ID

//Required, CRM object apiName def crmObjApiName = context.data.object_describe_api_name; //Required, CRM data Id def crmDataId = context.data._id //Required, ERP intermediate object apiName def erpObjApiName = "BD_Customer. BillHead" //This type is used to trigger ERP to CRM data synchronization, using the crm data id def type = "manualSyncErpDataByCrmDataId" def params = ["crmObjectApiName":crmObjApiName, "crmDataId":crmDataId, "erpObjectApiName":erpObjApiName] def arg = ["type":type, "params":Fx.json.toJson(params)] def ret = Fx.proxy.callAPI("erp.syncData.executeCustomFunction", [:], arg) //Synchronization result processing logic: log. info(ret)

Call the webapi of Kingdee Cloud and Starry Sky

//The following code snippet demonstrates how to call the webapi in Funshare's CRM. // K3Cloud address String baseUrl = "http://172.31.100.60/K3Cloud/" //url interface variable String auth = "Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc" String query = "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc" String save = "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Save.common.kdsvc" String submit = "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Submit.common.kdsvc" String audit = "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Audit.common.kdsvc" //login information List param = ["5ec229fad54306", "ces", "888888", 2052] //Request parameter body Map body = ["parameters": param] Map headers = ["Content-Type": "application/json; charset=utf-8"] Map content = [:] //login connection def (Boolean error, HttpResult data, String errorMessage) = Fx.http.post(baseUrl + auth, headers, body) Map cookieHeader = [:] if (!error) { if (data. statusCode == 200) { content = json. parse(data. content as String) String logInType = content."LoginResultType" if (logInType == "1" || logInType == "-5") { log.info("Successful login, content:" + content) } else { log.info("Login failed, content:" + content) } } else { log.info("Request failed, HttpResult: " + data) } } else { log.info("Request error, errorMessage:" + errorMessage) } //Document query example (query inventory) body.put("parameters", [ [ "FormId" : "STK_Inventory", "FieldKeys" : "FID,FStockId.FNumber,FMaterialId.FNumber,FMaterialId.FName,FLot.FNumber,FLot,FS tockLocId,FBaseQty,FBaseAVBQty,FUpdateTIme", "FilterString": "FMaterialId. FNumber='CH4453'", "OrderString" : "", "TopRowCount" : "0", "StartRow" : "0", "Limit" : "0" ] ]) (error, data, errorMessage) = Fx.http.post(baseUrl + query, headers, body) log. info(data) /*--------------------------- Create order example ------------------ ---------------------*/ //Get order data from crm Map salesOrderMap = context.data log.info("Order: "+json.toJson(salesOrderMap)) // get product data (one) // order product Map salesProductMap = ((List)context.details.SalesOrderProductObj)[0] log.info("Order product: "+salesProductMap) //Product Map productData (error, productData, errorMessage) = object.findById("ProductObj", salesProductMap.product_id as String) log.info("product:"+productData) // add new order Map model = [:] //document type, required model.put("FBillTypeID", ["FNumber": "XSDD01_SYS"]) //sales organization, required model. put("FSaleOrgId", ["FNumber": "003"]) //Customer, required model.put("FCustId", ["FNumber": "4326rtyu"]) //date, required model.put("FDate", "2020-05-22 00:00:00") //salesperson, required model. put("FSalerId", ["FNumber": "88888"]) model. put("FSaleDeptId", ["FNumber": ""]) //k3cloud code is synchronized from the crm order model.put("FBillNo ", salesOrderMap.name) //order details Map material = [:] //Material code, required, the material needs to be assigned to the corresponding organization material. put("FMaterialId", ["FNumber": productData. product_code]) //sales unit, required material. put("FUnitID", ["FNumber": "Pcs"]) //Sales volume material.put("FQty", salesProductMap.quantity) // unit price including tax material.put("FTaxPrice", salesProductMap.sales_price) //Order details, required model. put("FSaleOrderEntry", [material]) //Financial Information Map finance = [:] //Settlement currency, required finance. put("FSettleCurrId", ["FNumber": "PRE001"]) finance.put("FExchangeTypeId", ["FNumber": "HLTX01_SYS"]) finance. put("FExchangeRate", 1) model. put("FSaleOrderFinance",finance) body.put("parameters",["SAL_SaleOrder", json.toJson(["Model":model])]) log. info(json. toJson(model)) (error, data, errorMessage) = Fx.http.post(baseUrl + save, headers, body) log. info(data) //submit body.put("parameters",["SAL_SaleOrder", ["Numbers": [salesOrderMap.name]]]) (error, data, errorMessage) = Fx.http.post(baseUrl + submit, headers, body) log.info(data) //Audit (error, data, errorMessage) = Fx.http.post(baseUrl + audit, headers, body) log. info(data) //This is just an example, please return according to the actual return type required by the current custom function. return "111"

Operate the intermediate table through the CRM custom function

Map header=[:] //Create data mapping Map param1=["ployDetailId":"155bd981457343f291e0edc13776217f",//policy detail id (see the figure below), if the policy is deleted and rebuilt, it needs to be changed here "sourceObjectApiName": "AccountObj",//source object apiName, if the object apiName changes, it needs to be changed here "destObjectApiName": "BD_Customer.BillHead",//The target object apiName, if the object apiName changes, it needs to be changed here "sourceDataId": "sourceDataId123",//source object data id "destDataId": "destDataId123666",//target object data id "sourceDataName": "sourceDataName3666", //source object data name attribute "destDataName": "destDataName66",//target object data name attribute "remark": "remark1341"];//remark def result1=Fx.proxy.callAPI("erp.syncData.createSyncDataMapping", header, param1); //[false, HttpResult(statusCode=200, content={"errCode":"s106240000","errMsg":"success"}, bytes=null), ] s106240000 succeeds, others fail log. info(result1) //Update the target object data id according to the source object data id Map param2=["sourceObjectApiName":"AccountObj",//source object apiName, if the object apiName changes, it needs to be changed here "destObjectApiName": "BD_Customer.BillHead",//The target object apiName, if the object apiName changes, it needs to be changed here "sourceDataId": "sourceDataId123",//source object data id "destDataId":"destDataId123666"]//target object data id def result2=Fx.proxy.callAPI("erp.syncData.updateSyncDataMapping", header, param2); //[false, HttpResult(statusCode=200, content={"errCode":"s106240000","errMsg":"success"}, bytes=null), ] s106240000 succeeds, others fail log. info(result2) //Query whether the source object data id has a mapping relationship Map param3=["sourceObjectApiName":"AccountObj",//source object apiName, if the object apiName changes, it needs to be changed here "destObjectApiName": "BD_Customer.BillHead",//The target object apiName, if the object apiName changes, it needs to be changed here "sourceDataId":["sourceDataId123"]]//source object data ids, List def result3=Fx.proxy.callAPI("erp.syncData.getSyncDataMappingBySourceDataId", header, param3); // [false, HttpResult(statusCode=200, content={"data":{"sourceDataId123":{"sourceDataId":"sourceDataId123","isCreated":true,"destDataId":"destDataId123666","sourceDataName": "sourceDataName1233","updateTime":1611047455451,"lastSyncStatus":6,"destDataName":"destDataName123","destTenantId":"81138","sourceObjectApiName":"AccountObj","destObjectApiName":"BD_Customer.BillHead", "sourceTenantId":"81138","statusName":"Added successfully","id":"aa46ed320312476485e932a1ca4b4263","lastSyncDataId":"92c86fb175254e54b990bd86b6ce1145","status":1}},"errCode"2:"s1 "errMsg":"Success"}, bytes=null), ] //s106240000 succeeds, others fail //data is a Map, which stores data with a mapping relationship, key is the source data id, and value is the existing corresponding relationship. log. info(result3)
Crawl policy detail ID ployDetailId
OA to-do message synchronization creates a mapping table through crm personnel
//The legal values ​​of channel are ERP_K3CLOUD, ERP_SAP, ERP_U8, OA, STANDARD_CHANNEL //"dataType":"employee" indicates that the new one is an employee //dataCenterId is the data center id //fsDataId is the data id on crm. For personnel, this is the employee ID, not the data id of the crm personnel object. //erpDataId is the data id on erp //fsDataName is the data name of crm //erpDataName is the data name on erp Map data = [ "dataCenterId": "701916*******319168", "channel": "OA", "dataType": "employee_oa", "fsDataId":fsDataId, "fsDataName":fsDataName, "erpDataId": erpDataId, "erpDataName": erpDataName ]; def ret = Fx.proxy.callAPI("erp.syncData.createErpfieldmapping", [:], data); Fx.log.info("ret is : "+ret)

8. Standard API Interface Description

The input parameters and return values ​​of the standard API interface have strict restrictions. The name of the input parameter is syncArg, the type is Map type, and the return value is Map type. The fields in the Map must be strictly in accordance with the integration platform
Connector management → connection object → generate API page http request response format to return data, must strictly follow this format to return, remember!
Example diagram of standard API interface return value:
For the k3cloud channel, code=0 in the return value of the interface means success, and non-zero means failure. When code=0, the data field must have a value, and the master object ID and detail object ID fields corresponding to masterDataId must be returned correctly, and must follow the The format and order required by the integrated platform return the ID value of the detailed object (if the object has a detailed object)
For standard channels and SAP channels, the code field, message field, data field name and successful code code in the interface return value can be customized, and can be set on the integration platform connector management→connection configuration page, as shown in the figure:
Once these field names and success codes are configured, in the custom function, the data must be returned in strict accordance with the fields in this configuration
DSS平台自定义函数适配.docx
245 KB

8.1 Description of Asyncpush Push Data Interface

Asyncpush is an interface executed asynchronously. If the interface returns successfully, it just means that the interface has successfully reached the integration platform, and the subsequent synchronization process is asynchronous batch processing of data.
Unless there is a high requirement for timeliness, please use the query interface queryMasterBatch to return data.
The advantage of using the query interface to return data is that it has good fault tolerance, and time-consuming and laborious operations such as refreshing historical data and re-synchronizing are supported by mature tools, without the intervention of account-side IT personnel.
For push, please refer to: Interface Development

8.2 create

When CRM->ERP creates data, call this interface.
This interface requires the ERP primary key to be included in the return value, and the ERP primary key cannot be returned asynchronously.
If the interface on the ERP cannot return within 30s, the ERP side needs to perform weight judgment processing. When retrying with the same data on the CRM, the result of the last successful creation should be returned.
Parameter Description { "objAPIName": "ERP object APIName", "masterFieldVal": "master data", "detailFieldVals": "from the data list" }
Return value description: { "code": "Error return code", "message": "Error message", "data": { "masterDataId": "Master Data Primary Key", "detailDataIds": { "List of data primary keys for each detail object" } } }
Example return value:

8.3 update

This interface is called when CRM->ERP updates master data. The master-slave data overwrites and updates the target data together.
parameter { "objAPIName": "ERP object APIName", "masterFieldVal": "master data", "detailFieldVals": "from the data list" }
return: { "code": "Error return code", "message": "Error message", "data": { "masterDataId": "Master Data Primary Key", "detailDataIds": { "List of data primary keys for each detail object" } } }
Example return value:

8.4 queryMasterBatch

ERP->CRM Incremental data query interface, the integrated platform regularly polls, and calls this interface to obtain incrementally changed data.
Parameter Description:
objAPIName: ERP object APIName
startTime: the start time of the data change (unix timestamp, in milliseconds)
endTime: the end time of the data change (unix timestamp, in milliseconds)
includeDetail: whether the returned result contains the slave data
offset: Get the offset of the record
limit: the number of records currently requested
Return value description:
{ "code": "Error return code", "message": "Error message", "data": { "totalNum": "Total number of records", "dataList": [{ "objAPIName": "Primary Object Name", "masterFieldVal": {master object data}, "detailFieldVals": { "from object 1": [{list of data from object 1}], "from object 2": [{list of data from object 2}] } }, { "objAPIName": "Primary Object Name", "masterFieldVal": {master object data}, "detailFieldVals": { "from object 1": [{list of data from object 1}], "from object 2": [{list of data from object 2}] } }] } }
The time slice polling termination instructions:
(1) The number of returned data items is 0. For example, the data of 6 minutes is returned in 10 pages. If 0 data is returned when querying the second page, it will not poll from the third page onwards. It will continue to poll for the next 6 minutes of data.
(2) The interface on the ERP side reports an error, and the polling of this time slice is skipped. Will continue to poll for the next time slice.
Example return value:

8.5 queryMasterById

ERP->CRM obtains data through the primary key ID. This interface will be called to obtain the latest data during resynchronization.
Parameter Description:
objAPIName: ERP object APIName
dataId: data primary key
includeDetail: Whether the returned result contains slave data
Return value description:
{ "code": "Error return code", "message": "Error message", "data": { "objAPIName": "ERP Object APIName", "masterFieldVal": {master object data}, "detailFieldVals": { "From Object APIName": [{From Object Data List}] } } }
Example return value:

8.6 invalid

When CRM->ERP invalidates master data, this interface is called.
Parameter Description:
{ "objAPIName": "ERP main object APIName", "masterFieldVal": { "_id": "ERP master object data master key" } }
Description of returned results:
{
"errCode": "Error return code",
"errMsg": "Error message"
}
Example return value:

8.7 Example of Query List Interface Function of XML Interface

/*list query*/ //call parameters: log.info("Request parameters: "+syncArg); Integer offset=syncArg["objectData"]==null?0:(Integer)syncArg["objectData"]["offset"];//Requested offset Integer limit=syncArg["objectData"]==null? 50:(Integer)syncArg["objectData"]["limit"];//The amount of data requested Long startTime=syncArg["objectData"]==null?0:(Long)syncArg["objectData"]["startTime"];//Request start time, timestamp format Long endTime=syncArg["objectData"]==null?0:(Long)syncArg["objectData"]["endTime"];//Request end time, timestamp format //You can modify the parameters of the request here: mainly the testing process. Set the parameters here directly. Easy to debug //Convert to page number format Integer page=((offset+limit)/limit).toInteger(); Integer pageSize=limit; //Timestamp to date format DateTime startDt = DateTime.of(startTime); DateTime endDt = DateTime.of(endTime); Integer startmonth=startDt.month; Integer startday=startDt.day; Integer starthour=startDt.hour; Integer startminute=startDt.minute; Integer endmonth=endDt.month; Integer endday=endDt.day; String startDateStr=startDt.year+"-"+(startmonth<10?"0"+startmonth:startmonth)+"-"+(startday<10?"0"+startday:startday); String endDateStr=endDt.year+"-"+(endmonth<10?"0"+endmonth:endmonth)+"-"+(endday<10?"0"+endday:endday); String startTimeStr=""+(starthour<10?"0"+starthour:starthour)+":"+(startminute<10?"0"+startminute:startminute)+":00"; //Request URL: The controller returns the request path corresponding to the corresponding object through the parameter urlName Map urlParams= ["urlName": ""]; //Basic data request URL: func_Yd9n2__c is the controller function, the controller function mainly encapsulates general logic or configuration information def (error,result,errorMessage) = Fx.function.executeFunc("func_Yd9n2__c",urlParams) String requestUrl =result["url"]; //Request header: mainly the requested authentication information can be placed in the controller Map header=["Authorization":"Basic " +Fx.crypto.base64.encode(Fx.utils.toUTF8Bytes("username:password")) ,"Content-Type":"text/xml; charset=utf-8"]; // request message String requestXml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:sap-com:document:sap:soap:functions: mc-style\">\n" + " <soapenv:Header/>\n" + " <soapenv:Body>\n" + " <urn:Zcrmfu0003>\n" + " <!--Optional:-->\n" + " <Enddate>"+endDateStr+"</Enddate>\n" + " <!--Optional:-->\n" + " <Endtime>23:59:59</Endtime>\n" + " <!--Optional:-->\n" + " <Pagenum>"+page+"</Pagenum>\n" + " <!--Optional:-->\n" + " <Pagesize>"+pageSize+"</Pagesize>\n" + " <!--Optional:-->\n" + " <Rtdetail>\n" + " </Rtdetail>\n" + " <!--Optional:-->\n" + " <Rtmaster>\n" + " </Rtmaster>\n" + " <!--Optional:-->\n" + " <Startdate>"+startDateStr+"</Startdate>\n" + " <!--Optional:-->\n" + " <Starttime>"+startTimeStr+"</Starttime>\n" + " <!--Optional:-->\n" + " <Vbeln></Vbeln>\n" + " </urn:Zcrmfu0003>\n" + " </soapenv:Body>\n" + "</soapenv:Envelope>"; log.info("Request path: "+requestUrl); log.info("Request message: "+requestXml); def (Boolean error2,HttpResult result2,String errorMessage2)= Fx.http.post(requestUrl,header,requestXml,30000,false,0) result2["bytes"]=null; if(result2==null){ Fx.message.throwErrorMessage("The interface timed out, please edit the synchronization field to retrigger the synchronization"); } if( error2 ){ log.info("Return message: "+result2); Fx.message.throwErrorMessage(errorMessage2); }else if(result2["statusCode"]!=200){ log.info("Return message: "+result2); Fx.message.throwErrorMessage("Please check whether the parameters are wrong"); } //Return data analysis def xmlSlurper = new XmlSlurper(); String content=result2["content"]; def responseMap=xmlSlurper. parseText(content) def masterArrays=responseMap.Body["Zcrmfu0003Response"]["Rtmaster"] as NodeChildren; def detailArrays=responseMap.Body["Zcrmfu0003Response"]["Rtdetail"] as NodeChildren; List<Map> dataList=[]; //You can specify the returned field (if there is a field requirement change later, the erp object needs to be modified. This place also needs to be modified). You can also convert all the messages into a Map and return them (you only need to configure the fields of the erp object for later changes) List returnMasterFields=["Vbeln","Lfart","Vstel","Kunnr","Vkorg",.....] // masterArrays.children().each{ String masterId=it["Vbeln"]; if((masterId!= null && ""!=masterId)){ Map dataMap=[:] return MasterFields. each { field-> // The node obtained by it is an object, which must be converted into a basic type for processing, otherwise the serialization will be garbled String fieldV=(it[field] as NodeChildren).text() as String; if(fieldV!=null&&""!=fieldV ){ dataMap. put(field, fieldV) } } dataMap["masterId"] = masterId; dataMap["Vstel"]="factory#"+dataMap["Vstel"];//Processing of special fields. For example, you need to splice fields dataList.add(["masterFieldVal":dataMap]) } } //If there are details, remember to process the detailed data ["masterFieldVal":dataMap,"detailFieldVals":[["Detailed APIName1":[]]],["Detailed APIName2":[]]]] Map resultMap=[:]; resultMap. put("dataList", dataList); return resultMap;
2023-02-23
0 0