業務量を使用したシフト作業トピックの初期化
組織のシフト作業トピックの業務量を初期化します。
必要なエディション
| 使用可能なインターフェース: Lightning Experience。 |
| 使用可能なエディション: Enterprise Edition および Unlimited Edition |
| 必要なユーザー権限 | |
|---|---|
| スクリプトを実行します。 | 「API の有効化」 および 「すべてのデータの参照」 および Apex 開発 |
デフォルトでは、業務量ベースのスケジュールを有効にすると、シフト作業トピックの業務量は 0 に設定されます。 これらのスクリプトを使用してシフト作業トピックに値を入力し、業務量ベースのスケジュールを有効にする前と同じようにスケジュールを機能させます。ビジネス継続性を確保するためにすばやく更新する必要がある既存のシフトレコードがある場合、これらのスクリプトを使用することをお勧めします。または、シフト作業トピックの業務量を手動で設定できます。
-
組織の [Scheduler for Health Cloud] 設定に応じて、次のいずれかのスクリプトを使用します。
- 無効
//For Health Cloud Disabled global class InitialiseExistingSWTWithCapacity implements Database.Batchable<SObject> { global Database.QueryLocator start(Database.BatchableContext BC) { return Database.getQueryLocator([SELECT Id, StartTime, EndTime FROM Shift]); } global void execute(Database.BatchableContext BC, List<SObject> scope) { List<String> shiftIds = new List<String>(); for (Shift shift : (List<Shift>) scope) { shiftIds.add(shift.Id); } // create maps to avoid queries in the loop List<Shift> shiftInfo = [ SELECT ServiceTerritoryId, Id, StartTime, EndTime FROM Shift WHERE Id IN :shiftIds ]; List<String> serviceTerriroryIds = new List<String>(); for (Shift shift : shiftInfo) { serviceTerriroryIds.add(shift.ServiceTerritoryId); } Map<String, String> mapStToServiceAppointmentLimitType = new Map<String, String>(); List<ServiceTerritory> sts = [ SELECT ServiceAppointmentLimitType, Id FROM ServiceTerritory WHERE Id IN :serviceTerriroryIds ]; for (ServiceTerritory st : sts) { mapStToServiceAppointmentLimitType.put( st.Id, st.ServiceAppointmentLimitType ); } Map<String, String> mapShiftToServiceTerritory = new Map<String, String>(); Map<String, Decimal> mapShiftToDuration = new Map<String, Decimal>(); for (Shift shift : shiftInfo) { mapShiftToServiceTerritory.put(shift.Id, shift.ServiceTerritoryId); Decimal shiftDuration = (shift.EndTime.getTime() - shift.StartTime.getTime()) / (1000 * 60); mapShiftToDuration.put(shift.Id, shiftDuration); } Map<String, Decimal> mapWorkTypeToDuration = new Map<String, Decimal>(); List<WorkType> wts = [SELECT Id, DurationInMinutes FROM WorkType]; for (WorkType wt : wts) { mapWorkTypeToDuration.put(wt.Id, wt.DurationInMinutes); } Map<String, List<String>> mapShiftToWorkTypeGroupList = new Map<String, List<String>>(); List<ShiftWorkTopic> shiftWorkTopics = [ SELECT Id, WorkTypeGroupId, ShiftId, MaxAppointments FROM ShiftWorkTopic WHERE ShiftId IN :shiftIds AND WorkTypeGroupId != NULL ]; for (ShiftWorkTopic swt : shiftWorkTopics) { List<String> existingSWTList = mapShiftToWorkTypeGroupList.get( swt.ShiftId ); if (existingSWTList == null) { existingSWTList = new List<String>{ (String) swt.WorkTypeGroupId }; } else { existingSWTList.add(swt.WorkTypeGroupId); } mapShiftToWorkTypeGroupList.put(swt.ShiftId, existingSWTList); } Map<String, String> mapWorkTypeGroupToWorkType = new Map<String, String>(); List<WorkTypeGroupMember> wtgms = [ SELECT Id, WorkTypeGroupId, WorkTypeId FROM WorkTypeGroupMember ]; for (WorkTypeGroupMember wtgm : wtgms) { mapWorkTypeGroupToWorkType.put(wtgm.WorkTypeGroupId, wtgm.WorkTypeId); } Map<String, List<ShiftWorkTopic>> mapShiftToSWTList = new Map<String, List<ShiftWorkTopic>>(); for (ShiftWorkTopic swt : shiftWorkTopics) { List<ShiftWorkTopic> existingSWTList = mapShiftToSWTList.get(swt.ShiftId); if (existingSWTList == null) { existingSWTList = new List<ShiftWorkTopic>{ swt }; } else { existingSWTList.add(swt); } mapShiftToSWTList.put(swt.ShiftId, existingSWTList); } Map<String, Integer> mapSWTToConcurrency = new Map<String, Integer>(); for (ShiftWorkTopic swt : shiftWorkTopics) { if (swt.MaxAppointments != null) { mapSWTToConcurrency.put(swt.Id, swt.MaxAppointments); } else { mapSWTToConcurrency.put(swt.Id, 1); } } // main code starts here for (String shiftId : shiftIds) { String ServiceAppointmentLimitType = mapStToServiceAppointmentLimitType.get( mapShiftToServiceTerritory.get(shiftId) ); if ( ServiceAppointmentLimitType == 'Maximum Limit' || ServiceAppointmentLimitType == null ) { Double shiftDuration = mapShiftToDuration.get(shiftId); for (ShiftWorkTopic swt : mapShiftToSWTList.get(shiftId)) { Double workTypeDuration = mapWorkTypeToDuration.get( mapWorkTypeGroupToWorkType.get((swt.WorkTypeGroupId)) ); Double concurrency = mapSWTToConcurrency.get(swt.Id); swt.ServiceAppointmentLimit = ((shiftDuration / workTypeDuration) .intValue() * concurrency) .intValue(); } } else if (ServiceAppointmentLimitType == 'Achievable Limit') { List<ShiftWorkTopic> swtList = mapShiftToSWTList.get(shiftId); if (swtList == null) { // No SWT in this shift do no process continue; } Integer maximumCapacity = 0; Decimal shiftDuration = mapShiftToDuration.get(shiftId); for (ShiftWorkTopic swt : mapShiftToSWTList.get(shiftId)) { Integer concurrency = mapSWTToConcurrency.get(swt.Id); Double workDuration = mapWorkTypeToDuration.get( mapWorkTypeGroupToWorkType.get((swt.WorkTypeGroupId)) ); maximumCapacity = Math.max( maximumCapacity, (shiftDuration / workDuration).intValue() * concurrency ); } Integer finalCapacity = 0; for (Integer cap = 0; cap <= maximumCapacity; cap++) { Double sumLHS = 0; for (ShiftWorkTopic swt : mapShiftToSWTList.get(shiftId)) { Integer concurrency = mapSWTToConcurrency.get(swt.Id); Double workDuration = mapWorkTypeToDuration.get( mapWorkTypeGroupToWorkType.get((swt.WorkTypeGroupId)) ); sumLHS += Math.ceil((1.0 * cap) / concurrency) * workDuration; } if (sumLHS <= shiftDuration) { finalCapacity = cap; } else { break; } } for (ShiftWorkTopic swt : mapShiftToSWTList.get(shiftId)) { swt.ServiceAppointmentLimit = finalCapacity; } } } update shiftWorkTopics; } global void finish(Database.BatchableContext BC) { // Send notification or log the completion System.debug('Batch job completed successfully.'); } } - 有効
//For Health Cloud Enabled global class InitialiseExistingSWTWithCapacity implements Database.Batchable<SObject> { global Database.QueryLocator start(Database.BatchableContext BC) { return Database.getQueryLocator([SELECT Id, StartTime, EndTime FROM Shift]); } global void execute(Database.BatchableContext BC, List<SObject> scope) { List<String> shiftIds = new List<String>(); for (Shift shift : (List<Shift>) scope) { shiftIds.add(shift.Id); } // create maps to avoid queries in the loop List<Shift> shiftInfo = [ SELECT ServiceTerritoryId, Id, StartTime, EndTime FROM Shift WHERE Id IN :shiftIds ]; List<String> serviceTerriroryIds = new List<String>(); for (Shift shift : shiftInfo) { serviceTerriroryIds.add(shift.ServiceTerritoryId); } Map<String, String> mapSwtToServiceAppointmentLimitType = new Map<String, String>(); Map<String, String> mapStToServiceAppointmentLimitType = new Map<String, String>(); List<ServiceTerritory> sts = [ SELECT ServiceAppointmentLimitType, Id FROM ServiceTerritory WHERE Id IN :serviceTerriroryIds ]; for (ServiceTerritory st : sts) { mapStToServiceAppointmentLimitType.put( st.Id, st.ServiceAppointmentLimitType ); } Map<String, String> mapShiftToServiceTerritory = new Map<String, String>(); Map<String, Decimal> mapShiftToDuration = new Map<String, Decimal>(); for (Shift shift : shiftInfo) { mapShiftToServiceTerritory.put(shift.Id, shift.ServiceTerritoryId); Decimal shiftDuration = (shift.EndTime.getTime() - shift.StartTime.getTime()) / (1000 * 60); mapShiftToDuration.put(shift.Id, shiftDuration); } Map<String, Decimal> mapWorkTypeToDuration = new Map<String, Decimal>(); List<WorkType> wts = [SELECT Id, DurationInMinutes FROM WorkType]; for (WorkType wt : wts) { mapWorkTypeToDuration.put(wt.Id, wt.DurationInMinutes); } Map<String, List<String>> mapShiftToWorkTypeGroupList = new Map<String, List<String>>(); List<ShiftWorkTopic> shiftWorkTopics = [ SELECT Id, WorkTypeId, ShiftId, MaxAppointments FROM ShiftWorkTopic WHERE ShiftId IN :shiftIds AND WorkTypeId != NULL ]; for (ShiftWorkTopic swt : shiftWorkTopics) { List<String> existingSWTList = mapShiftToWorkTypeGroupList.get( swt.ShiftId ); if (existingSWTList == null) { existingSWTList = new List<String>{ (String) swt.WorkTypeId }; } else { existingSWTList.add(swt.WorkTypeId); } mapShiftToWorkTypeGroupList.put(swt.ShiftId, existingSWTList); } Map<String, List<ShiftWorkTopic>> mapShiftToSWTList = new Map<String, List<ShiftWorkTopic>>(); for (ShiftWorkTopic swt : shiftWorkTopics) { List<ShiftWorkTopic> existingSWTList = mapShiftToSWTList.get(swt.ShiftId); if (existingSWTList == null) { existingSWTList = new List<ShiftWorkTopic>{ swt }; } else { existingSWTList.add(swt); } mapShiftToSWTList.put(swt.ShiftId, existingSWTList); } Map<String, Integer> mapSWTToConcurrency = new Map<String, Integer>(); for (ShiftWorkTopic swt : shiftWorkTopics) { if (swt.MaxAppointments != null) { mapSWTToConcurrency.put(swt.Id, swt.MaxAppointments); } else { mapSWTToConcurrency.put(swt.Id, 1); } } // main code starts here for (String shiftId : shiftIds) { String ServiceAppointmentLimitType = mapStToServiceAppointmentLimitType.get( mapShiftToServiceTerritory.get(shiftId) ); if ( ServiceAppointmentLimitType == 'Maximum Limit' || ServiceAppointmentLimitType == null ) { if (mapShiftToSWTList.get(shiftId) == null) { // No SWT in this shift do no process continue; } Double shiftDuration = mapShiftToDuration.get(shiftId); for (ShiftWorkTopic swt : mapShiftToSWTList.get(shiftId)) { Double workTypeDuration = mapWorkTypeToDuration.get(swt.WorkTypeId); Double concurrency = mapSWTToConcurrency.get(swt.Id); swt.ServiceAppointmentLimit = ((shiftDuration / workTypeDuration) .intValue() * concurrency) .intValue(); } } else if (ServiceAppointmentLimitType == 'Achievable Limit') { List<ShiftWorkTopic> swtList = mapShiftToSWTList.get(shiftId); if (swtList == null) { // No SWT in this shift do no process continue; } Integer maximumCapacity = 0; Decimal shiftDuration = mapShiftToDuration.get(shiftId); for (ShiftWorkTopic swt : mapShiftToSWTList.get(shiftId)) { Integer concurrency = mapSWTToConcurrency.get(swt.Id); Double workDuration = mapWorkTypeToDuration.get((swt.WorkTypeId)); maximumCapacity = Math.max( maximumCapacity, (shiftDuration / workDuration).intValue() * concurrency ); } Integer finalCapacity = 0; for (Integer cap = 0; cap <= maximumCapacity; cap++) { Double sumLHS = 0; for (ShiftWorkTopic swt : mapShiftToSWTList.get(shiftId)) { Integer concurrency = mapSWTToConcurrency.get(swt.Id); Double workDuration = mapWorkTypeToDuration.get(swt.WorkTypeId); sumLHS += Math.ceil((1.0 * cap) / concurrency) * workDuration; } if (sumLHS <= shiftDuration) { finalCapacity = cap; } else { break; } } for (ShiftWorkTopic swt : mapShiftToSWTList.get(shiftId)) { swt.ServiceAppointmentLimit = finalCapacity; } } } update shiftWorkTopics; } global void finish(Database.BatchableContext BC) { // Send notification or log the completion System.debug('Batch job completed successfully.'); } }
- 無効
- 承認ワークフローをトリガーする InitialiseExistingSWTWithCapacity という Apex クラスを作成します。「Define Apex Classes」を参照してください。
- [設定] で [開発者コンソール] を選択します。
- 開発者コンソールで、[Debug (デバッグ)] をクリックし、[Open Execute Anonymous Window (実行匿名ウィンドウを開く)] をクリックします。
- このコードを実行します。
- スクリプトの進行状況を表示するには、[設定] で [Apex ジョブ] を見つけて選択します。
この記事で問題は解決されましたか?
ご意見をお待ちしております。

