我有Salesforce管理经验,但没有在Salesforce开发。
我的任务是将Salesforce中的订单推送到外部REST API,如果订单处于自定义状态“Processing”,并且订单开始日期(effecvedate)在10天内。
订单将比在下游系统中处理。
如果订单被成功推送到REST API,状态应该被更改为“Activated”。
有人能给我一些例子代码吗?
###有一个非常酷的指南,可以帮助我选择正确的机制,我一直在研究这个PDF文件中的SF认证之一:https://developer。salesforce。com/docs/atlas。en-us。integration_patterns_and_practices。meta/integration_patterns_and_practices/integ_pat_intro_overview。htm
这在很大程度上取决于端点是否可以从Salesforce访问(如果不是的话——你可能需要拉取数据而不是推),它需要什么身份验证。
对于Salesforce的推出,你可以使用
出站消息——它将是一个XML文档,当(在您的情况下是基于时间的?)工作流不触发REST时发送,但它只是单击没有代码。缺点是消息中只有一个对象。因此,您可以发送Order标题,但不能发送行项目。
外部服务将是无代码的,您可以用它构建流。
您总是可以使用Apex代码推送数据(类似这样)。我们把溶液分成两部分。
完成实际工作的部分:在较高的层次上,你可以编写一个函数来获取Order id的列表作为参数,调用request 。 setbody (JSON。(SELECT Id FROM Order WHERE Id IN:ids));…如果API需要一些特殊的身份验证——你可以查看“命名凭据”。在不了解目标的情况下,很难说你需要什么。
时机一到,这部分就叫做顶点。可能是更多的代码(一个每晚安排的作业,使这些调用在午夜之后1分钟?)https://salesforce。stackexchange。com/questions/226403/how-to-schedule-an-apex-batch-with-callout
可以是调用这个Apex的流/流程构建器(同样,您可能想要基于时间的流)。“工作者”代码必须“实现接口”(一种花哨的说法是,该代码承诺将有接受“suchAndSuch”参数的函数“suchAndSuchName”)。检查的过程。插件。
获取数据…良好的目标应用程序可以登录到SF (SOAP REST),每天查询一次订单表。很多集成工具都有Salesforce插件,你已经在使用Azure数据工厂了吗?Informatica吗?BizTalk吗?Mulesoft吗?
还有一种叫“长轮询”的东西,客户端应用程序订阅通知,SF向他们推送信息。你可能听说过CometD?在sf语言中,请阅读Platform Events Streaming API Change Data Capture(尽管最后一个会在更改时触发,并且只发送更改字段,不适合推送完整的订单+行项目)。您也可以从流发送平台事件。
So... don't dive straight to coding the solution. Plan a bit, the maintenance will be easier. This is untested, written in Notepad, I don't have org with orders handy... But in theory you should be able to schedule it to run at 1 AM for example. Or from dev console you can trigger it with Database.executeBatch(new OrderSyncBatch(), 1);
public class OrderSyncBatch implements Database.Batchable, Database.AllowsCallouts {
public Database.QueryLocator start(Database.BatchableContext bc) {
Date cutoff = System.today().addDays(10);
return Database.getQueryLocator([SELECT Id, Name, Account.Name, GrandTotalAmount, OrderNumber, OrderReferenceNumber,
(SELECT Id, UnitPrice, Quantity, OrderId FROM OrderItems)
FROM Order
WHERE Status = 'Processing' AND EffectiveDate = :cutoff]);
}
public void execute(Database.BatchableContext bc, List<sObject> scope) {
Http h = new Http();
List<Order> toUpdate = new List<Order>();
// Assuming you want 1 order at a time, not a list of orders?
for (Order o : (List<Order>)scope) {
HttpRequest req = new HttpRequest();
HttpResponse res;
req.setEndpoint('https://example.com'); // your API endpoint here, or maybe something that starts with "callout:" if you'd be using Named Credentials
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
req.setBody(JSON.serializePretty(o));
res = h.send(req);
if (res.getStatusCode() == 200) {
o.Status = 'Activated';
toUpdate.add(o);
}
else {
// Error handling? Maybe just debug it, maybe make a Task for the user or look into
// Database.RaisesPlatformEvents
System.debug(res);
}
}
update toUpdate;
}
public void finish(Database.BatchableContext bc) {}
public void execute(SchedulableContext sc){
Database.executeBatch(new OrderSyncBatch(), Limits.getLimitCallouts()); // there's limit of 10 callouts per single transaction
// and by default batches process 200 records at a time so we want smaller chunks
// https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_methods_system_limits.htm
// You might want to tweak the parameter even down to 1 order at a time if processing takes a while at the other end.
}
}