I am trying to create Approval process using Metadata API but unable to figure out what i am missing.
One doubt is XML don't have any symbol why which me or Salesforce could identify on which object i am creating the approval process.
I have tried by using wsdl and REST API but no success.
Receiving error:
soapenv:ClientMust specify a {http://www.w3.org/2001/XMLSchema-instance}type attribute value for the {http://soap.sforce.com/2006/04/metadata}metadata element
Using WSDL:
MetadataService_Chris.Metadata_Chris service = new MetadataService_Chris.Metadata_Chris();
service.SessionHeader = new MetadataService_Chris.SessionHeader_element();
service.SessionHeader.sessionId = UserInfo.getSessionId();
MetadataService_Chris.ApprovalProcess process = new MetadataService_Chris.ApprovalProcess();
process.fullName = 'TestApproval';
process.active = true;
process.allowRecall = true;
MetadataService_Chris.ApprovalSubmitter submitter = new MetadataService_Chris.ApprovalSubmitter();
submitter.type_x = 'user';
submitter.submitter = UserInfo.getUserId();
List<MetadataService_Chris.ApprovalSubmitter> submitters = new List<MetadataService_Chris.ApprovalSubmitter>();
submitters.add(submitter);
process.allowedSubmitters = submitters;
process.label = 'Test Approval';
process.showApprovalHistory = true;
//MetadataService_Chris.Metadata mdata = new MetadataService_Chris.Metadata();
//mdata.fullName = 'Test Metadata';
MetadataService_Chris.AsyncResult[] results = service.create(new List<MetadataService_Chris.Metadata> { process });
System.debug('---------------------------------- '+results);
Using REST:
HTTP h = new HTTP();
HTTPRequest req = new HTTPRequest();
req.setMethod('POST');
req.setHeader('Content-Type', 'text/xml');
req.setHeader('SOAPAction', 'create');
String xml = /*'<?xml version="1.0" encoding="UTF-8"?>'+
'<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'+
'<env:Header>'+
'<SessionHeader xmlns="http://soap.sforce.com/2006/04/metadata">'+
'<sessionId>'+userinfo.getSessionId()+'</sessionId>'+
'</SessionHeader>'+
'</env:Header>'+
'<env:Body>'+
'<create xmlns="http://soap.sforce.com/2006/04/metadata">'+
'<metadata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'+ // xsi:type="Account"
'<active>false</active>'+
'<allowRecall>true</allowRecall>'+
'<allowedSubmitters>'+
'<submitter>005i00000033nPoAAI</submitter>'+
'<type />'+
'</allowedSubmitters>'+
'<label>Test Approval</label>'+
'<recordEditability />'+
'<showApprovalHistory>true</showApprovalHistory>'+
'</metadata>'+
'</create>'+
'</env:Body>'+
'</env:Envelope>';
req.setBody(xml);
req.setCompressed(false);
req.setEndpoint('https://na15.salesforce.com/services/Soap/m/29.0');
HTTPResponse resp = h.send(req);
System.debug(resp.getBody());
I have tried with several combinations but no success. In back-end XML formed as:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Header>
<SessionHeader xmlns="http://soap.sforce.com/2006/04/metadata">
<sessionId>00Di0000000k2kv!AR4AQBKoHVPE4sLzQbOuu.CAU0o1qsMldVzPRDGFStoboKik1lt_WUNe.5YiHR2MQOlrKExKf05TnYB_7SO7kPdwQGfjwNis</sessionId>
</SessionHeader>
</env:Header>
<env:Body>
<create xmlns="http://soap.sforce.com/2006/04/metadata">
<metadata>
<active>true</active>
<allowRecall>true</allowRecall>
<allowedSubmitters>
<submitter>005i00000033nPoAAI</submitter>
<type />
</allowedSubmitters>
<label>Test Approval</label>
<recordEditability />
<showApprovalHistory>true</showApprovalHistory>
</metadata>
</create>
</env:Body>
</env:Envelope>
The problem is "xsi:type="ApprovalProcess" which throws exception.
Attribution to: Ashwani
Possible Suggestion/Solution #1
I've just uploaded a new MetadataService.cls with support for this, you can also see in the MetadataSeviceExamples.cls class an example as follows below on how to do this. I'm not 100% what your issue was with your copy of the generated class, but at least you could compare with the one above if your interested.
MetadataService.MetadataPort service = createService();
MetadataService.ApprovalProcess approvalProcess = new MetadataService.ApprovalProcess();
approvalProcess.fullName = 'Test__c.TestApproval';
approvalProcess.label = 'Test Approval';
approvalProcess.active = false;
approvalProcess.allowRecall = false;
approvalProcess.showApprovalHistory = true;
approvalProcess.recordEditability = 'AdminOnly';
approvalProcess.finalApprovalRecordLock = false;
approvalProcess.finalRejectionRecordLock = false;
approvalProcess.showApprovalHistory = false;
MetadataService.ApprovalSubmitter submitter = new MetadataService.ApprovalSubmitter();
submitter.type_x = 'user';
submitter.submitter = UserInfo.getUserName();
approvalProcess.allowedSubmitters = new List<MetadataService.ApprovalSubmitter> { submitter };
MetadataService.AsyncResult[] results = service.create(new List<MetadataService.Metadata> { approvalProcess });
Finally, keep in mind (at least for now) there is only an Async option for the create operation, which means you need to check back using the checkAsync method the final status. For more information about doing this you can read this blog.
Once Spring'14 is released (later in April) i will update the library to support the new immediate create operation which does not require you to poll for the result.
Attribution to: Andrew Fawcett
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/30425