次の方法で共有


SLA KPI のカスタム時間計算を有効にする

この記事では、規定の時間計算をオーバーライドする方法を説明しています。

サービス レベル アグリーメント (SLA) での時間計算では、WarningTime (タイプ DateTime フィールドの StartTime)、FailureTime (GUID)、および ApplicableFrom (警告期間または失敗期間 (分単位)) のような入力パラメータを考慮した SLA 主要業績評価指標 (KPI) の CalendarIdDuration を計算します。 最終的な WarningTimeFailureTime は、SLA アイテムに関連付けられた顧客サービス スケジュールと祝日スケジュールに基づいて計算します。

警告と失敗の時間に加えて、SLA に一時停止と再開のシナリオが構成されている場合は、経過時間も計算されます。 SLA KPI の一時停止中に費やした作業時間を無視する場合は、最終的な障害時間に経過時間を追加します。

独自の時間計算を可能にするには、入出力パラメータが固定された API インターフェースを定義し、時間計算を行うカスタム ロジックを追加します。

カスタム時間計算はプラグインの一部としてのみサポートされ、他のエンティティ (たとえば、カスタム ワークフローなど) ではサポートされません。

SLA KPI のカスタム時間計算を有効にする

  1. make.powerapps.com に移動します。

  2. 詳細設定>カスタマイズ>システムのカスタマイズ>プロセス>新規 に移動します。

  3. プロセスの作成 ダイアログに、次の詳細を入力します。

    1. プロセス名を入力します (例: CustomPluginTimeCalculation)。
    2. カテゴリ ドロップダウン リストから、アクション を選択します。
    3. エンティティ のドロップ ダウンリストから、なし (グローバル) を選択します。
    4. 既存テンプレートからのプロセスの新規作成 (一覧から選択) オプションを選択します。
    5. リストから SLACustomTimeCalculationTemplate テンプレートを選択します。
    6. OK を選択します。

    カスタム時間計算テンプレート

  4. テンプレートで、必要なパラメーター (該当する場合) を追加し、ライセンス認証を行うを選択します。

    SLA アイテムのプロセス引数を有効にする

  5. プラグインの記述

    必要なプラグインを選択するための情報 シナリオとプラグイン に移動してください。

  6. 手順 3 で作成した カスタム アクション にリンクするには、プラグイン登録ツールに移動し、作成したプラグインを組織に登録します。 プラグインの詳細については、プラグインの登録を参照してください。

    プラグインを登録してリンクする

  7. Copilot Service 管理センターで、以前に作成したカスタム アクションを SLA 項目で追加または編集します。

    1. カスタム時間計算を許可するはい に切り替えます。
    2. カスタム時間計算 API フィールドで、手順 3 で作成したカスタム アクションを選択します。
    3. 保存して閉じる を選択します。
  8. SLAフォームで、ライセンス認証を行う を選択し、必要なエンティティに適用します。 SLA KPI の警告時間と失敗時間は、カスタム アクションで提供される時間計算ロジックに従って表示されます。

    SLA の適用方法については、SLA の適用にアクセスしてください

  9. ソリューションを別の環境にエクスポートする場合は、最初に SLA (アイテムにカスタム アクション参照がある) をカスタム ソリューションに追加できます。 SLA を追加すると、カスタム アクション ワークフロー プロセスもエクスポートされます。 次に、ソリューションに SDK メッセージを含めます。これにより、前に作成したプラグインがエクスポートされます。

シナリオとプラグイン

カスタム アクションに関連付けられたプラグイン コードを実装するには、次のシナリオとそのプラグインを参照してください。

シナリオ 1:

一時停止または再開のシナリオがない場合は、WarningTimeFailureTime のみを計算します。 新しい KPI インスタンスが作成されるたびに、SLA はカスタム時間計算 API を開始して、1 回の呼び出しで WarningTimeFailureTime のみを計算します。

このような場合には、requestTypegetEndTime になり、その他の属性は、次の例で定義されているようにフェッチできます。

public void Execute(IServiceProvider serviceProvider)
{

	IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
	IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
	_service = factory.CreateOrganizationService(context.UserId);

	// Step 1: Retrieving Input Parameters.
	string regardingId = context.InputParameters["regardingId"] as string;
	string calendarId = context.InputParameters["calendarId"] as string;
	string requestType = context.InputParameters["requestType"] as string;
	string slaItemId = context.InputParameters["slaItemId"] as string;
	string entityName = context.InputParameters["entityName"] as string;
	

	try
	{
		// implement this requestType for any new SLA KPi instance creation.
		if (requestType.Equals("getEndTime", StringComparison.CurrentCultureIgnoreCase))
		{
			int warningDuration = (int)context.InputParameters["firstInputDuration"];
			int failureDuration = (int)context.InputParameters["secondInputDuration"];
			DateTime warningStartTime = (DateTime)context.InputParameters["firstInputDate"];
			DateTime failureStartTime = (DateTime)context.InputParameters["secondInputDate"];

			// Step 2 : Add the custom Logic to calculate the WarningTime and FailureTime
			string returnCalendarId = CalculateWarningAndFailureTime(regardingId, calendarId, slaItemId, entityName, warningStartTime, failureStartTime, warningDuration, failureDuration, out DateTime warningTime, out DateTime failureTime);

			// Step 3 : return the output values.
			context.OutputParameters["firstOutputValue"] = DateTime.SpecifyKind(warningTime, DateTimeKind.Utc).ToString();
			context.OutputParameters["secondOutputValue"] = DateTime.SpecifyKind(failureTime, DateTimeKind.Utc).ToString();
			context.OutputParameters["returnCalendarId"] = returnCalendarId;			
			return;
		}

		// implement this requestType for finding Paused time for any new SLA KPi instance after it resumed.
		if (requestType.Equals("getElapsedTime", StringComparison.CurrentCultureIgnoreCase))
		{
			DateTime casePausedTime = (DateTime)context.InputParameters["firstInputDate"];
			DateTime caseResumedTime = (DateTime)context.InputParameters["secondInputDate"];
			int existingElapsedTime = (int)context.InputParameters["firstInputDuration"];
			// Step 2 : Add the custom Logic to calculate the elapsedTime between startTime(paused) and endTime(resumed)
			double elapsedTimeInMinutes = CalculateElapsedTime(regardingId, calendarId, slaItemId, entityName, casePausedTime, caseResumedTime, existingElapsedTime);

			// Step 3 : return the output values.
			context.OutputParameters["firstOutputValue"] = elapsedTimeInMinutes.ToString();
			context.OutputParameters["secondOutputValue"] = elapsedTimeInMinutes.ToString();			
			return;
		}
	} catch (Exception ex) {
		return;			
	}

	throw new Exception("Invalid requestType:" + requestType+ " for entityName:" + entityName + " of id:" + regardingId);
}

// in this example, we're using Custom Field(new_country) on the Case entity to apply the required calendar.

private string CalculateWarningAndFailureTime(string regardingId, string calendarId, string slaItemId, string entityName, DateTime warningStartTime, DateTime failureStartTime, int warningDuration, int failureDuration, out DateTime warningTime, out DateTime failureTime)
{
	OrganizationResponse customizedTimeCalculationResponse;
	warningTime = DateTime.UtcNow;
	failureTime = DateTime.UtcNow;
	int newWarningTime = warningDuration;
	int newFailureTime = failureDuration;
	int customCode = 0;

	// Step 1: fetch the Case Entity record	
	Entity caseRecord = FetchCaseRecord(entityName, regardingId);

	if (caseRecord.Attributes.Contains("new_country"))
	{
		customCode = (int)(((OptionSetValue)(caseRecord.Attributes["new_country"])).Value);

		// Example 1: Override calendar at runtime: Choose Calendar based on any custom logic
		if (customCode == 0)
		{
			// fetch IST calendar & override CalendarId
			IST_CALENDAR = FetchCalendar("IST_CALENDAR", _service);
			calendarId = IST_CALENDAR;
		}
		else if (customCode == 1)
		{
			// fetch PST calendar & override CalendarId
			PST_CALENDAR = FetchCalendar("PST_CALENDAR", _service);
			calendarId = PST_CALENDAR;
		}		
	}
	// use OOB SLATimeCalculation Custom Action to do actual calculation_
	OrganizationRequest requestTimeCalculation = new OrganizationRequest("msdyn_SLATimeCalculation");
	
	requestTimeCalculation["requestType"] = "getEndTime";
	requestTimeCalculation["calendarId"] = calendarId;

	// calculate warning time
	if (warningDuration != -1)
	{
		requestTimeCalculation["startTime"] = warningStartTime;
		requestTimeCalculation["minutes"] = newWarningTime;
		customizedTimeCalculationResponse = _service.Execute(requestTimeCalculation);
		customizedTimeCalculationResponse.Results.TryGetValue("returnValue", out object outputValue1);
		warningTime = DateTime.SpecifyKind(DateTime.Parse((string)outputValue1), DateTimeKind.Utc);
	}

	// calculate Failure time
	if (failureDuration != -1)
	{
		requestTimeCalculation["startTime"] = failureStartTime;
		requestTimeCalculation["minutes"] = newFailureTime;
		customizedTimeCalculationResponse = _service.Execute(requestTimeCalculation);
		customizedTimeCalculationResponse.Results.TryGetValue("returnValue", out object outputValue2);
		failureTime = DateTime.SpecifyKind(DateTime.Parse((string)outputValue2), DateTimeKind.Utc);				
	}

	return calendarId;
}

シナリオ 2:

一時停止または再開のシナリオがある場合は、次の計算が行われます:

  • 一時停止と再開状態との間の elapsedTime の計算。 このシナリオでは、SLA はカスタム時間計算 API を呼び出して、一時停止から再開までの経過時間を計算します。 このような場合には、requestType は getElapsedTime になり、その他の属性は、プラグイン コード例で定義されているようにフェッチできます。
  • 再開されたインスタンスの新規の WarningTimeFailureTime 評価の計算。 このような場合には、requestTypegetEndTime になり、その他の属性は、次の例で定義されているようにフェッチできます。
private double CalculateElapsedTime(string regardingId, string calendarId, string slaItemId, string entityName, DateTime casePausedTime, DateTime caseResumedTime, int existingElapsedTime)
{
    if (caseRecord.Attributes.Contains("new_country"))
    {
        if ((int)(((OptionSetValue)(caseRecord.Attributes["new_country"])).Value) == 0)
        {
        // fetch IST id
        IST_CALENDAR = FetchCalendar("IST_CALENDAR", _service);
        calendarId = IST_CALENDAR;
        }
        else if ((int)(((OptionSetValue)(caseRecord.Attributes["new_country"])).Value) == 1)
        {
        // fetch PST  id
        PST_CALENDAR = FetchCalendar("PST_CALENDAR", _service);
        calendarId = PST_CALENDAR;
        }
    }

	// use OOB SLATimeCalculation Custom Action to do actual calculation_
	OrganizationRequest requestTimeCalculation = new OrganizationRequest("msdyn_SLATimeCalculation");
	requestTimeCalculation["startTime"] = casePausedTime;
	requestTimeCalculation["endTime"] = caseResumedTime;
	requestTimeCalculation["requestType"] = "getElapsedTime";
	requestTimeCalculation["calendarId"] = calendarId;

	// calculate elapsed time
	customizedTimeCalculationResponse = _service.Execute(requestTimeCalculation);
	customizedTimeCalculationResponse.Results.TryGetValue("returnValue", out object outputValue1);
	double totalElapsedTime = existingElapsedTime + Double.Parse(outputValue1.ToString());
	return totalElapsedTime;
}

カスタム時間計算のエラー コード

以下は、カスタム時間の計算中に発生する可能性のあるさまざまなエラー シナリオのエラー コードです。

エラー コード: 10000004

エラー メッセージ: "SLA アイテム {0} のカスタム時間計算 API のワークフローがアクティブである必要があります。"

理由

カスタム時間計算ワークフローが無効になっている場合、エラーが発生します。

解決策

SLA が有効で、カスタム時間計算ワークフローが無効になっている場合、SLA を開くと、有効化 ボタンとともにフォーム通知が表示されます。 この問題を回避するには、カスタム時間計算ワークフロー プロセスが常に アクティブ 状態であることを確認します。 SLA 導入を実行し、それが完了した後にのみ検証します。 ワークフロー プロセスを手動またはカスタマイズによって削除または非アクティブ化しないようにしてください。

エラー コード: 10000005

エラー メッセージ: "カスタム時間計算プロセスを選択してください。"

理由

カスタム時間計算ワークフローが有効になっているが、ワークフロー プロセス アクションが SLA アイテムに関連付けられていない場合、エラーが発生します。

解決策

ワークフロー プロセスを追加して、SLA アイテムを保存します。 この問題を回避するには、切り替えが オン に設定されている場合、カスタム時間計算ワークフロー プロセスにルックアップ値が入力されていることを確認してください。

エラー コード: 10000006

エラー メッセージ: "SLA アイテム {0} のカスタム時間計算プロセスのワークフローがありません。 {Placeholder="{0}"} は SLA アイテム ID を参照します。"

理由

このエラーは、SLA のアクティブ化中にカスタム時間計算ワークフローが有効になっていて、ワークフロー プロセス アクションが有効な GUID を持つ SLA アイテムに関連付けられているが、ワークフローが削除された場合に発生します。

解決策

無効なワークフローを修正する必要があります。 SLA アイテムから既存のワークフローを削除し、新しいワークフローを作成してから、新しいワークフローを同じ SLA アイテムに追加します。 この問題を回避するには、ワークフローを手動で、または展開プロセスの一部として削除しないようにしてください。 また、運用環境に直接インポートする前に、変更を確認してください。

エラー コード: 10000007

エラー メッセージ: "スラブ アイテム ID を示す SLA アイテム {0} {Placeholder="{0}"} のカスタム時間計算プロセスにプラグインの実装がありません。"

理由

エラーは、カスタム時間計算ワークフローが有効になっているが、関連するプラグイン SDK メッセージング プロセス ステップがないか、プラグインが登録されていない場合に発生します。

解決策

ソースまたは開発環境から SLA をエクスポートするときは、SDK ステップを必ず追加してください。 この問題を回避するには、SLA ソリューションに SDK メッセージ ステップとプラグイン アセンブリを必ず追加してください。

エラー コード: 10000008

エラー メッセージ: "警告または SLA アイテム {0} のカスタム時間計算プロセスによって返された失敗時間が無効です。 {Placeholder="{0}"} は sla アイテム ID を参照します。"

理由

カスタム時間計算ワークフロー アクションが requestType getEndTime に対して無効な 失敗時間 を返すと、エラーが発生します。

解決策

カスタム ワークフロー プロセスが適切な値を返さない理由を調べるには、デバッグする必要があります。 この問題を回避するには、シナリオを運用環境に展開する前に、すべてのシナリオを追加してテストしてください。 たとえば、これには、さまざまな SLA アイテムの適用と、一時停止または再開のシナリオが含まれます。

エラー コード: 10000009

エラー メッセージ: "SLA アイテム {0} のカスタム時間計算プロセスによって返された経過時間が無効です。 {Placeholder="{0}"} は sla アイテム ID を参照します。"

理由

カスタム時間計算ワークフロー アクションが requestType getElapsedTime に対して無効な 経過時間 を返すと、エラーが発生します。

解決策

サポート案件を一時停止して再開したときに、カスタムワークフロープロセスが適切な値を返さない原因を突き止めるには、デバッグが必要です。 この問題を回避するには、シナリオを運用環境に展開する前に、すべてのシナリオを追加してテストしてください。 たとえば、これには一時停止または再開のシナリオが含まれます。

エラー コード: 10000010

エラー メッセージ: "{0}SLA アイテム{1} に対するカスタム時間計算プロセスのワークフローがありません。"

理由

カスタム時間計算のカスタム アクションがシステムに見つからない場合、エラーが発生します。

解決策

デバッグして、エラーに示されているものと同じ名前のカスタム アクションがシステムに存在するかどうかを確認する必要があります。 この問題を回避するには、エラー メッセージに示されているのと同じカスタム アクション名のプレフィックスを作成してください。 ソリューションのプレフィックスを変更するか、アンマネージド ソリューションとしてエクスポートしないようにする必要があります。 管理ソリューションにワークフロー インターフェイスを直接作成するのではなく、代わりにデフォルトのカスタマイズで管理ソリューションを作成してからソリューションに追加することもできます。

よくあるご質問

SLA KPI のカスタム時間計算に関するよくある質問と、その回答については、SLA KPI のカスタム時間計算に関する FAQ を参照してください。

サービス レベル アグリーメントを定義する

SLA を適用する

SLA の記録を有効にする