Salesforce报价同步解决方案 - 自动同步与关闭/同步自定义字段

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

场景描述

在使用Sales Cloud报价功能时,经常会有报价产品与业务机会产品同步的需求,但标准同步功能存在一些局限性,比如只能同步标准字段,至于是不是可以同步所有标准字段并不清楚,再比如一旦记录锁定后,非系统管理员用户不能操作同步与停止同步按钮等等。
在阅读此篇blog前,有必要知道报价的基础知识,如报价字段报价的同步方式报价同步故障排除。\

问题与方案

问题1:如何解决报价与业务机会自定义字段同步问题?
A:安装AppExchange中的package之后,进入Custom Seting管理同步字段映射关系即可。Custom Quote Sync在AppExchange上有Managed和Unmanaged两个版本,相关的安装步骤和异常详见Custom Quote Sync Setup Guide

问题2:非管理员用户在记录锁定后,如何实现自动同步和关闭?
思路:需要使用Trigger和@future异步方式解决,若记录锁定,则需要使用webservice技术。
Code Sample:下面是解决报价审批通过后,自动同步和停止同步报价与业务机会

public class ACC_QuoteTriggerHandler extends ACC_TriggerHandler {
	public static boolean isExecuting = false;// Prevent recursion
	public override void afterUpdate() {
        if(ACC_QuoteTriggerFunction.isExecuting) {
            return;
        }
        ACC_QuoteTriggerHandler.isExecuting = true;

        Map<Id, Quote> quoteMap = new Map<Id, Quote>([SELECT OpportunityId, Opportunity.StageName FROM Quote WHERE Id IN :Trigger.New AND RecordTypeId = :rtMap.get('ACC_PAPAGZ') AND Status = :Label.ACC_GZ_Quote_Approved_in_Salesforce]);
        Map<String, String> quoteId2oppIdMap = new Map<String, String>();
        if(quoteMap.size() > 0) {
            for(String str : quoteMap.keySet()) {
                if(quoteId2oppIdMap.keySet().contains(str)) {
                    continue;
                }else {
                    quoteId2oppIdMap.put(str, quoteMap.get(str).OpportunityId);
                }
            }
            System.debug('quoteId2oppIdMap: ' + quoteId2oppIdMap);
        }
        if(quoteId2oppIdMap.size() > 0) {
            System.debug('start to syncAndUnsyncQuote...');
            if(!System.isFuture() && !System.isBatch()) {// very important
                ACC_QuoteOnClickJsHandler.syncAndUnsyncQuote(quoteId2oppIdMap);
            }
        }
        ACC_QuoteTriggerHandler.isExecuting = false;
    }  

}
global class ACC_QuoteOnClickJsHandler {
    /**
    Function Description: sync and unsync Quote called by apex trigger.
    Parameters: Map<String, String> quoteId2oppIdMap
    Return Value: void
    Author: Wilson Xu
    Date: 2018-1-15
    **/
    @future (callout=true) 
    public static void syncAndUnsyncQuote(Map<String, String> quoteId2oppIdMap) {
        List<Opportunity> oppList = new List<Opportunity>();
        for(String str : quoteId2oppIdMap.keySet()) {
            Opportunity opp = new Opportunity();
            opp.Id = quoteId2oppIdMap.get(str);
            opp.SyncedQuoteId = str;
            oppList.add(opp);
        }
        System.debug('oppList: ' + oppList);
        try{
            if(oppList.size() > 0) {
                Database.SaveResult[] srList = Database.update(oppList, false);
                List<Opportunity> successOppList = new List<Opportunity>();
                for(Database.SaveResult sr : srList) {
                    if (sr.isSuccess()) {
                        Opportunity successOpp = new Opportunity();
                        successOpp.Id = sr.getId();
                        successOpp.SyncedQuoteId = null;
                        successOppList.add(successOpp);
                    }else {
                        System.debug('Updating returned the following errors.');
                        for(Database.Error e : sr.getErrors()) {
                            System.debug(e.getMessage());
                        }
                    }
                }
                System.debug('successOppList: ' + successOppList);
                if(successOppList.size() > 0) {
                    update successOppList;
                }
            }
        }catch(Exception e) {
            System.debug('syncAndUnsyncQuote failed: ' + e.getMessage());
        }
    } 

}
复制代码

以上不难看出,同步与否的核心为Opportunity的SyncedQuoteId字段,为null,则停止同步,当不为null时,相关的Opportunity的IsSyncing将被自动勾上。\

相关资源

报价自动同步

猜你喜欢

转载自juejin.im/post/7107574244879368223
今日推荐