WSDL文件状态
编辑:完成大修,以显示如何在同一时间添加多个opps。如果你可以以某种方式错开它们的创建(将它们存储在本地数据库中,并且只有当你有足够的时间/足够的时间已经过去/用户按下“冲洗队列”按钮时)才会有用。
警告,代码实际上现在看起来更可怕,您可能会首先在编辑历史记录中检查previous version。
创建一个Apex类不会太难,它会接受带有2个参数的传入请求并尝试插入它们。进入设置 - >培养─>类 - >新建,试试这个:
global with sharing class OpportunityLinkedInsert{
static webservice Opportunity insertSingle(Opportunity opp, OpportunityLineItem[] lines){
if(opp == null || lines == null){
throw new IntegrationException('Invalid data');
}
Opportunity[] result = insertMultiple(new List<Opportunity>{opp}, new List<List<OpportunityLineItem>>{lines});
return result[0]; // I imagine you want the Id back :)
}
/* I think SOAP doesn't handle method overloading well so this method has different name.
'lines' are list of lists (jagged array if you like) so opps[i] will be inserted and then lines[i] will be linked to it etc.
You can insert up to 10,000 rows in one go with this function (remember to count items in both arrays).
*/
static webservice List<Opportunity> insertMultiple(List<Opportunity> opps, List<List<OpportunityLineItem>> lines){
if(opps == null || lines == null || opps.size() == 0 || opps.size() != lines.size()){
throw new IntegrationException('Invalid data');
}
insert opps;
// I need to flatten the structure before I insert it.
List<OpportunityLineItem> linesToInsert = new List<OpportunityLineItem>();
for(Integer i = 0; i < opps.size(); ++i){
List<OpportunityLineItem> linesForOne = lines[i];
if(linesForOne != null && !linesForOne.isEmpty()){
for(Integer j = 0; j < linesForOne.size(); ++j){
linesForOne[j].OpportunityId = opps[i].Id;
}
linesToInsert.addAll(linesForOne);
}
}
insert linesToInsert;
return opps;
}
// helper class to throw custom errors
public class IntegrationException extends Exception{}
}
您还需要在此之前的单元测试类可以去你的生产组织。类似的东西应该这样做(在100%可用之前需要充满更多的东西,see this question for more info)。
@isTest
public class OpportunityLinkedInsertTest{
private static List<Opportunity> opps;
private static List<List<OpportunityLineItem>> items;
@isTest
public static void checSingleOppkErrorFlow(){
try{
OpportunityLinkedInsert.insertSingle(null, null);
System.assert(false, 'It should have failed on null values');
} catch(Exception e){
System.assertEquals('Invalid data',e.getMessage());
}
}
@isTest
public static void checkMultiOppErrorFlow(){
prepareTestData();
opps.remove(1);
try{
OpportunityLinkedInsert.insertMultiple(opps, items);
System.assert(false, 'It should have failed on list size mismatch');
} catch(Exception e){
System.assertEquals('Invalid data',e.getMessage());
}
}
@isTest
public static void checkSuccessFlow(){
prepareTestData();
List<Opportunity> insertResults = OpportunityLinkedInsert.insertMultiple(opps, items);
List<Opportunity> check = [SELECT Id, Name,
(SELECT Id FROM OpportunityLineItems)
FROM Opportunity
WHERE Id IN :insertResults
ORDER BY Name];
System.assertEquals(items[0].size(), check[0].OpportunityLineItems.size(), 'Opp 1 should have 1 product added to it');
System.assertEquals(items[1].size(), check[0].OpportunityLineItems.size(), 'Opp 3 should have 1 products');
}
// Helper method we can reuse in several tests. Creates 2 Opportunities with different number of line items.
private static void prepareTestData(){
opps = new List<Opportunity>{
new Opportunity(Name = 'Opp 1', StageName = 'Prospecting', CloseDate = System.today() + 10),
new Opportunity(Name = 'Opp 2', StageName = 'Closed Won', CloseDate = System.today())
};
// You might have to fill in more fields here!
// Products are quite painful to insert with all their standard/custom pricebook dependencies etc...
items = new List<List<OpportunityLineItem>>{
new List<OpportunityLineItem>{
new OpportunityLineItem(Description = 'Opp 1, Product 1', Quantity = 1, UnitPrice = 10)
},
new List<OpportunityLineItem>{
new OpportunityLineItem(Description = 'Opp 2, Product 1', Quantity = 1, UnitPrice = 10),
new OpportunityLineItem(Description = 'Opp 2, Product 2', Quantity = 1, UnitPrice = 10),
new OpportunityLineItem(Description = 'Opp 2, Product 3', Quantity = 1, UnitPrice = 10)
}
};
}
}
这就是在顶点代码方面非常。
如果任何一个插入操作失败,您将返回一个SOAP异常。这在交易方面也有所改善,ACID等 - 如果您的订单项插入失败,您准备从PHP端清理它吗?如果在Salesforce中设置了一些自动电子邮件通知等并且已经发送了,会怎么样?通过一次调用Apex将确保整个请求将被回滚,就像存储过程在数据库中一样。
尝试在沙箱中创建这些类,然后在类的列表中找到第一个类。它将有一个链接来生成一个WSDL文件,您可以使用它来生成您的PHP类。 转到第二个,你会看到一个“运行测试”按钮。你必须确保测试通过之后再推到你的生产组织 - 但这是全新的世界programming on the platform为你:)
真的很好的问题,我很好奇!但是,如果API请求的数量确实令人担忧,那么您是否可以仅仅支付更多的用户许可证,而每个用户都可以给予更多的1-5K电话费用? https://eu1.salesforce.com/help/doc/en/integrate_api_rate_limiting.htm。另外 - 是创建Apex webservice类,可以接受机会和OLI数组一个有效的选择吗? – eyescream
@eyescream老板对Licenses说不,Apex webservice是一个不错的主意,我会研究一下,但我现在没有技能,所以PHP解决方案仍然是理想选择。 –