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解決方案仍然是理想選擇。 –