勤務時間の選択的な制限
[シフトと共にサービステリトリーの営業時間を使用] スケジュールポリシーを有効にしている場合、Salesforce Scheduler ではシフトとサービステリトリーの業務時間の交差部分を使用して、すべてのサービスリソースの対応可能状況を決定します。ただし、数人のサービスリソースのみについては勤務時間をサービステリトリーの業務時間に制限する場合は、トリガーを使用します。
必要なエディション
| 使用可能なインターフェース: Lightning Experience。 |
| 使用可能なエディション: Enterprise Edition および Unlimited Edition |
まず、カスタム Boolean 項目の OvertimeEnabled を作成して、サービステリトリーの業務時間を超えて作業できるリソースを指定します。次に、サービステリトリーメンバーのシフトのみを使用して予定へのサービスリソースの対応可能状況を決定するようにスケジュールポリシーを変更します。次に、シフトの作成前および更新前に実行される Apex トリガーをシフトオブジェクトに作成します。トリガーではシフト時間を検証し、OvertimeEnabled 項目値が false になっているリソースのサービステリトリーの業務時間内にシフト時間が入っていることを確認します。
- サービスリソースのオブジェクト管理設定から、[項目とリレーション] に移動します。
- [新規] をクリックします。
- [チェックボックス] を選択し、[次へ] をクリックします。
- [項目の表示ラベル] 項目に「OvertimeEnabled」と入力し、[次へ] をクリックします。
- 項目レベルセキュリティを設定し、必要なプロファイルへのアクセス権を指定して、[次へ] をクリックします。
- 変更内容を保存します。
- [設定] の [クイック検索] ボックスに「スケジュールポリシー」と入力し、[スケジュールポリシー] を選択します。
- [サービステリトリーメンバーのシフトを使用] スケジュールポリシーを選択し、[シフトと共にサービステリトリーの営業時間を使用] スケジュールポリシーを選択解除します。
- シフトのオブジェクト管理設定から、[トリガー] に移動します。
- [新規] をクリックします。
-
デフォルトコードを次のコードに置き換えます。
trigger ShiftValidation on Shift (before insert, before update) { List<Shift> shifts = Trigger.new; Set<String> sr = new Set<String>(); for(Shift shift: shifts) { sr.add(shift.ServiceResourceId); } List<ServiceResource> extendedSr = [SELECT Id FROM ServiceResource WHERE OvertimeEnabled__c = False AND Id IN :sr]; Set<String> srIds = new Set<String>(); for(ServiceResource sr1: extendedSr) { srIds.add(sr1.Id); } Set<Shift> confirmedShifts = new Set<Shift>(); Set<String> territoryIds = new Set<String>(); //We will only run this validation for Shifts with Status Category = "Confirmed" AND Service Resource can work extended hours for(Shift shift: shifts) { if(shift.StatusCategory == 'Confirmed' && srIds.contains(shift.ServiceResourceId)) { confirmedShifts.add(shift); territoryIds.add(shift.ServiceTerritoryId); } } if(confirmedShifts.size() > 0) { //Get all Service Territory IDs along with their OperatingHourId ServiceTerritory[] territoryIdsWithOperatingHours = [SELECT Id, OperatingHoursId FROM ServiceTerritory WHERE Id IN :territoryIds]; Set<String> operatingHourIds = new Set<String>(); for(ServiceTerritory st: territoryIdsWithOperatingHours) { //Service Territory may not have Operating Hour defined if(st.OperatingHoursId != null) { operatingHourIds.add(st.OperatingHoursId); } } //Get Timeslot information for all Operating Hours got in previous step. We disregard all STM level concurrent timeslots (Shifts with MaxAppointments set to 1) TimeSlot[] timeSlots = [SELECT Id, DayOfWeek, StartTime, EndTime, OperatingHoursId FROM TimeSlot WHERE MaxAppointments = 1 AND OperatingHoursId IN :operatingHourIds]; //Complex data structure to store Working hours for all Service territories. We will store empty inner map in case Service Territory does not have Operating Hour defined Map<String, Map<String, TimeSlot>> serviceTerritoryWithTimeSlotsPerDay = new Map<String, Map<String, TimeSlot>>(); for(ServiceTerritory territory: territoryIdsWithOperatingHours) { Map<String, TimeSlot> timeSlotsPerDay = new Map<String, TimeSlot>(); for(TimeSlot timeSlot: timeSlots) { if(timeslot.OperatingHoursId == territory.OperatingHoursId) { timeSlotsPerDay.put(TimeSlot.DayOfWeek.substring(0,3), TimeSlot); } } serviceTerritoryWithTimeSlotsPerDay.put(territory.Id, timeSlotsPerDay); } //Main validation logic for all confirmed shifts for(Shift s: confirmedShifts) { String dayOfShiftStart = ((Datetime) s.StartTime).format('E').substring(0,3); String dayOfShiftEnd = ((Datetime) s.EndTime).format('E').substring(0,3); Map<String, TimeSlot> slots = serviceTerritoryWithTimeSlotsPerDay.get(s.ServiceTerritoryId); if(dayOfShiftStart != dayOfShiftEnd) { s.addError('Shift should be within Service Territory\'s Operating hours '); } else if(slots.get(dayOfShiftStart) == null || slots.get(dayOfShiftEnd) == null) { s.addError('Operating Hours for Service Territory not set up correctly'); }else if(s.StartTime.time() < slots.get(dayOfShiftStart).StartTime || s.EndTime.time() > slots.get(dayOfShiftEnd).EndTime) { s.addError('Shift should be within Service Territory\'s Operating hours '); } } } } - 変更内容を保存します。
この記事で問題は解決されましたか?
ご意見をお待ちしております。
