Loading
ただいま大変多くのお問い合わせをいただいており、ご連絡までにお時間を頂戴しております続きを読む
サービス
ケースマイルストーンの自動完了

ケースマイルストーンの自動完了

一意の条件に合致するケースのマイルストーンを [完了] として自動的にマークする Apex トリガーを作成します。トリガーで、マイルストーンが [完了] とマークされるために満たす必要のあるイベントおよび関連ケースの条件を定義します。作業指示マイルストーンを自動完了する同様のトリガーを実装できます。

必要なエディション

サポートされているエディションを表示する。
必要なユーザー権限
Apex トリガーおよびクラスを定義する 「Apex 開発」
ヒント
ヒント Lightning Experience では、サポート担当者はマイルストーン コンポーネントの [Mark Completed (完了としてマーク)] リンクをクリックして、マイルストーンを完了としてマークできます。自動ではありませんが簡単です。詳細は、「マイルストーントラッカーの設定」を参照してください。

次のトリガーは、対象のケースが一意の条件を満たした場合に特定の種類のマイルストーンを [完了] とマークします。マイルストーンユーティリティ Apex クラスおよび付随する単体テストも次に示します。トリガーを使用する前に、マイルストーンユーティリティクラスを定義します。

マイルストーンユーティリティ Apex クラス
Apex クラスを使用することで、トリガーのサイズが小さくなり、Apex コードの再利用や管理が容易になります。この Apex クラスを組織で定義する手順は、次のとおりです。
  1. [設定] から、[クイック検索] ボックスに「Apex クラス」と入力し、[Apex クラス] をクリックします。
  2. [新規] をクリックします。
  3. クラスのテキストをコピーし、テキスト項目に貼り付けます。
  4. [保存] をクリックします。
public class MilestoneUtils {
    public static void completeMilestone(List<Id> caseIds, 
            String milestoneName, DateTime complDate) {  
    List<CaseMilestone> cmsToUpdate = [select Id, completionDate
            from CaseMilestone cm
            where caseId in :caseIds and cm.MilestoneType.Name=:milestoneName 
            and completionDate = null limit 1];
    if (cmsToUpdate.isEmpty() == false){
        for (CaseMilestone cm : cmsToUpdate){
            cm.completionDate = complDate;
            }
        update cmsToUpdate;
        }
    }
}
Apex クラスの単体テスト
開発者コンソールで Apex 単体テストを設定し、コードに問題がないかをスキャンできます。
/**
* This class contains unit tests for validating the behavior of Apex classes
* and triggers.
*
* Unit tests are class methods that verify whether a particular piece
* of code is working properly. Unit test methods take no arguments,
* commit no data to the database, and are flagged with the testMethod
* keyword in the method definition.
*
* All test methods in an organization are executed whenever Apex code is deployed
* to a production organization to confirm correctness, ensure code
* coverage, and prevent regressions. All Apex classes are
* required to have at least 75% code coverage in order to be deployed
* to a production organization. In addition, all triggers must have some code coverage.
*
* The @isTest class annotation indicates this class only contains test
* methods. Classes defined with the @isTest annotation do not count against
* the organization size limit for all Apex scripts.
*
* See the Apex Language Reference for more information about Testing and Code Coverage.
*/
@isTest
private class MilestoneTest {

static testMethod void TestCompleteMilestoneCase(){

List<Account> acts = new List<Account>();
Account myAcc = new Account(Name='TestAct', phone='1001231234');
acts.add(myAcc);

Account busAcc = new Account(Name = 'TestForMS', phone='4567890999');
acts.add(busAcc);
insert acts;
Contact cont = new Contact(FirstName = 'Test', LastName = 'LastName', phone='4567890999', accountid = busAcc.id);
insert(cont);

Id contactId = cont.Id;

Entitlement entl = new Entitlement(Name='TestEntitlement', AccountId=busAcc.Id);
insert entl;

String entlId;
if (entl != null)
entlId = entl.Id; 

List<Case> cases = new List<Case>{};
if (entlId != null){
Case c = new Case(Subject = 'Test Case with Entitlement ', 
EntitlementId = entlId, ContactId = contactId);
cases.add(c);
}
if (cases.isEmpty()==false){
insert cases;
List<Id> caseIds = new List<Id>();
for (Case cL : cases){
caseIds.add(cL.Id);
}
milestoneUtils.completeMilestone(caseIds, 'First Response', System.now());
}
}

static testMethod void testCompleteMilestoneViaCase(){

List<Account> acts = new List<Account>();
Account myAcc = new Account(Name='TestAct', phone='1001231234');
acts.add(myAcc);

Account busAcc = new Account(Name = 'TestForMS', phone='4567890999');
acts.add(busAcc);
insert acts;
Contact cont = new Contact(FirstName = 'Test', LastName = 'LastName', phone='4567890999', accountid = busAcc.id);
insert(cont);

Id contactId = cont.Id;

Entitlement entl = new Entitlement(Name='TestEntitlement', AccountId=busAcc.Id);
insert entl;

String entlId;
if (entl != null)
entlId = entl.Id; 

List<Case> cases = new List<Case>{};
for(Integer i = 0; i < 1; i++){
Case c = new Case(Subject = 'Test Case ' + i);
cases.add(c);
if (entlId != null){
c = new Case(Subject = 'Test Case with Entitlement ' + i, 
EntitlementId = entlId);
cases.add(c);
}
}
}
}
サンプルトリガー 1
「解決時間」というマイルストーンを作成し、ケースを一定の時間内にクローズするように要求することができます。この方法は、SLA のケース解決条件を適用するのに役立ちます。このサンプルケーストリガーは、ケースがクローズされたときに、各「解決時間」マイルストーンを [完了] とマークします。これにより、サポート担当がケースのクローズ後にマイルストーンを手動で完了とマークする必要がなくなります。
メモ
メモ このトリガーは、マイルストーンユーティリティテストクラスを参照するため、必ず先にテストクラスを定義します。

このトリガーを組織で定義する手順は、次のとおりです。

  1. [設定] から、[クイック検索] ボックスに「ケースのトリガー」と入力し、[ケースのトリガー] をクリックします。
  2. [新規] をクリックします。
  3. トリガーのテキストをコピーし、テキスト項目に貼り付けます。
  4. [保存] をクリックします。
trigger CompleteResolutionTimeMilestone on Case (after update) {
    if (UserInfo.getUserType() == 'Standard'){
        DateTime completionDate = System.now(); 
            List<Id> updateCases = new List<Id>();
            for (Case c : Trigger.new){
                    if (((c.isClosed == true)||(c.Status == 'Closed'))&&((c.SlaStartDate 
                        <= completionDate)&&(c.SlaExitDate == null)))
        updateCases.add(c.Id);
        }
    if (updateCases.isEmpty() == false)
        milestoneUtils.completeMilestone(updateCases, 'Resolution Time', completionDate);
    }
}
サンプルトリガー 2
「First Response」 (最初の対応) というマイルストーンを作成し、サポート担当者がケースの作成から X 分または数時間以内にケースの取引先責任者に連絡を取るように要求できます。この方法は、サポートチームができるだけ早くケースの取引先責任者と連絡を取るようにするのに役立ちます。このサンプルメールトリガーは、ケースの取引先責任者にメールが送られたときに「最初の対応」マイルストーンを [完了] とマークします。これにより、サポート担当者がケースの取引先責任者にメールを送信した後に [最初の対応] マイルストーンを手動で [完了] とマークする必要がなくなります。
メモ
メモ このトリガーは、マイルストーンユーティリティテストクラスを参照するため、必ず先にテストクラスを定義します。

このトリガーを組織で定義する手順は、次のとおりです。

  1. [設定] から、[クイック検索] ボックスに「メールのトリガー」と入力し、[メールのトリガー] をクリックします。
  2. [新規] をクリックします。
  3. トリガーのテキストをコピーし、テキスト項目に貼り付けます。
  4. [保存] をクリックします。
trigger CompleteFirstResponseEmail on EmailMessage (after insert) {
    if (UserInfo.getUserType() == 'Standard'){
        DateTime completionDate = System.now();
        Map<Id, String> emIds = new Map<Id, String>();
        for (EmailMessage em : Trigger.new){
            if(em.Incoming == false)
                emIds.put(em.ParentId, em.ToAddress);
        }
        if (emIds.isEmpty() == false){
            Set <Id> emCaseIds = new Set<Id>();
            emCaseIds = emIds.keySet();
                List<Case> caseList = [Select c.Id, c.ContactId, c.Contact.Email,
                    c.OwnerId, c.Status,
                    c.EntitlementId,
                    c.SlaStartDate, c.SlaExitDate
                    From Case c where c.Id IN :emCaseIds];
            if (caseList.isEmpty()==false){
                    List<Id> updateCases = new List<Id>();
                    for (Case caseObj:caseList) {
                        if ((emIds.get(caseObj.Id)==caseObj.Contact.Email)&&
                            (caseObj.Status == 'In Progress')&&
                            (caseObj.EntitlementId != null)&&
                            (caseObj.SlaStartDate <= completionDate)&&
                            (caseObj.SlaStartDate != null)&&
                            (caseObj.SlaExitDate == null))
                                updateCases.add(caseObj.Id);
                    }
                    if(updateCases.isEmpty() == false)
                        milestoneUtils.completeMilestone(updateCases, 
                                'First Response', completionDate);
            }
        }
    }        
}
サンプルトリガー 3
サンプルトリガー 2 はメールメッセージを扱うものでしたが、このサンプルケースコメントトリガーは、ケースに公開コメントが作成されたときに「最初の対応」マイルストーンを [完了] とマークします。このトリガーは、サポート条件で、公開ケースコメントが最初の対応として有効である場合に使用できます。
メモ
メモ このトリガーは、マイルストーンユーティリティテストクラスを参照するため、必ず先にテストクラスを定義します。

このトリガーを組織で定義する手順は、次のとおりです。

  1. [設定] から、[クイック検索] ボックスに「ケースコメントのトリガー」と入力し、[ケースコメントのトリガー] をクリックします。
  2. [新規] をクリックします。
  3. トリガーのテキストをコピーし、テキスト項目に貼り付けます。
  4. [保存] をクリックします。
trigger CompleteFirstResponseCaseComment on CaseComment (after insert) {
    if (UserInfo.getUserType() == 'Standard'){
        DateTime completionDate = System.now();
        List<Id> caseIds = new List<Id>();
        for (CaseComment cc : Trigger.new){
                if(cc.IsPublished == true)
                caseIds.add(cc.ParentId);
        }
        if (caseIds.isEmpty() == false){
            List<Case> caseList = [Select c.Id, c.ContactId, c.Contact.Email,
                    c.OwnerId, c.Status,
                    c.EntitlementId, c.SlaStartDate,
                    c.SlaExitDate
                    From Case c
                    Where c.Id IN :caseIds];
        if (caseList.isEmpty() == false){
            List<Id> updateCases = new List<Id>();
            for (Case caseObj:caseList) {
                if ((caseObj.Status == 'In Progress')&&
                        (caseObj.EntitlementId != null)&&
                        (caseObj.SlaStartDate <= completionDate)&&
                        (caseObj.SlaStartDate != null)&&
                        (caseObj.SlaExitDate == null))
                    updateCases.add(caseObj.Id);
                }
                if(updateCases.isEmpty() == false)
                    milestoneUtils.completeMilestone(updateCases, 
                    'First Response', completionDate);
            }
        }
    }
}
 
読み込み中
Salesforce Help | Article