Вы находитесь здесь:
Пример триггера Apex для доступа к посещению и запасу
Внедрите соответствующие классы и триггеры Apex в организацию, чтобы контролировать общий доступ пользователей к посещениям и запасам. Эти классы и триггеры можно написать любым способом, наиболее соответствующим требованиям организации. Ниже указаны примеры классов и триггеров Apex, которые помогут вам начать работу. Триггер посещения предоставляет общий доступ к объекту посещения и связанным объектам во время создания или обновления посещения. Триггер посетителя предоставляет доступ пользователю, назначенному посещению. Вы можете использовать эти триггеры Apex с полномочиями на основе профиля и едиными параметрами общего доступа, чтобы обеспечить пользователям доступ только к посещениям и запасам.
Требуемые версии
Доступно в версиях: Lightning Experience Доступно в версиях: Enterprise Edition и Unlimited Edition с Health Cloud или Life Sciences Cloud |
| Необходимые полномочия пользователя | |
|---|---|
| Для определения, редактирования, удаления, настройки параметров безопасности и настройки версий для классов Apex: | Автор Apex |
| Для выполнения тестов Apex: | Просмотр настройки и конфигурации |
Чтобы настроить триггеры Apex, сперва необходимо создать несколько классов служебных программ.
- Нажмите «Настройка» и выберите «Консоль разработчика».
-
Создайте класс служебной программы
VisitAccess.- Выберите «Кл асс F | leNewApex». | New
- В качестве имени класса Apex введите VisitAccess.
-
Удалите автоматически созданное содержимое и вставьте следующий код.
public class VisitAccess { static Set<String> accessLevels = new Set<String>{'read', 'edit'}; public static void insertVisitAccess(Visit visit, User user, String accessType) { insertVisitAccess(visit, new List<User>{user}, accessType); } public static void insertVisitAccess(Visit visit, Id objectId, String accessType) { if(isUser(objectId)) { insertVisitAccess(visit, new User(id=objectId), accessType); } } public static void insertVisitAccess(Visit visit, List<User> users, String accessType) { if(visit==null || visit.Id==null || users==null || users.isEmpty()) { return; } List<VisitShare> shareVisitList = new List<VisitShare>(); for(User user: users) { if(user==null) continue; VisitShare shareVisit = New VisitShare(); shareVisit.ParentId=visit.Id; shareVisit.UserOrGroupID = user.Id; shareVisit.AccessLevel = accessType; shareVisitList.add(shareVisit); } try{ Database.insert(shareVisitList); } catch(Exception e) { System.debug('Unexpected exception : ' + e); } } public static void updateVisitAccess(Visit visit, List<Id> oldUsers, List<Id> newUsers, String access) { if(visit==null) { return; } if(oldUsers!=null) { for(Id userId : oldUsers) { if(isUser(userId)) { deleteVisitAccess(visit, new User(id=userId)); } } } if(newUsers!=null) { for(Id userId : newUsers) { if(isUser(userId)) { insertVisitAccess(visit, userId, access); } } } } public static void updateVisitAccess(Visit oldVisit, Visit updatedVisit, String access) { //Comment this condition if for any update visit need to be shared if(oldVisit.VisitorId==updatedVisit.VisitorId) { return; } updateVisitAccess(oldVisit, oldVisit!=null?new List<Id>{oldVisit.VisitorId}:new List<Id>(), updatedVisit!=null?new List<Id>{updatedVisit.VisitorId}:new List<Id>(), access); } //remove user from oldVisit if user does not have any more access to oldVisit, and link user to newVisit public static void updateVisitAccess(Visit oldVisit, Visit newVisit, List<User> users, String access) { if(users==null || users.isEmpty()) { return; } if(access==null||!accessLevels.contains(access)) { access='edit'; } for(User user : users) { if(oldVisit!=null) deleteVisitAccess(oldVisit, user); if(newVisit!=null) insertVisitAccess(newVisit, user, access); } } //remove user from oldVisit if user does not have any more access to oldVisit, and link user to newVisit public static void updateVisitAccess(Visit oldVisit, Visit newVisit, Id objectId, String access) { if(isUser(objectId)) { updateVisitAccess(oldVisit, newVisit, new List<User>{new User(id=objectId)}, access); } } public static void deleteVisitAccess(Visit visit, List<User> users) { List<VisitShare> visitShareList = new List<VisitShare>(); for(User user : users) { if(isUserLinkedToVisit(user, visit)) continue; List<VisitShare> visitShare = [select Id from VisitShare where ParentId = :visit.Id and UserOrGroupID = :user.Id and RowCause='Manual']; if(!visitShare.isEmpty()) { visitShareList.add(visitShare.get(0)); } } delete visitShareList; } public static void deleteVisitAccess(Visit visit, User user) { deleteVisitAccess(visit, new List<User>{user}); } public static void deleteVisitAccess(Visit visit, Id objectId) { if(isUser(objectId)) { deleteVisitAccess(visit, new User(id=objectId)); } } public static Boolean isUser(Id objId) { if(objId==null) return false; List<User> users = [select Id from User where Id = :objId]; return !users.isEmpty(); } public static Boolean isUser(Object obj) { if(obj==null) return false; try { User user = (User)obj; } catch(TypeException e) { return false; } return true; } public static Boolean isUserLinkedToVisit(User user, Visit visit) { List<Visit> visits = [select Id from Visit where VisitorId = :user.Id and Id=:visit.Id]; List<Visitor> visitors = [select Id from Visitor where AssigneeId = :user.Id and VisitId=:visit.Id]; return !visits.isEmpty() || !visitors.isEmpty(); } } - Выберите FileSave | Save.
-
Создайте триггер посещения.
- Выберите Триггер | FileNewApex | New.
- Введите VisitTrigger в имя триггера и выберите «Посещение» в раскрывающемся списке sObject.
-
Удалите автоматически созданное содержимое и вставьте следующий образец.
trigger VisitTrigger on Visit (after insert, after update) { List<VisitShare> visitShares = new List<VisitShare>(); for(Visit visit : trigger.new) { if(trigger.isUpdate) { Visit oldVisit = trigger.oldMap.get(visit.Id); VisitAccess.updateVisitAccess(oldVisit, visit, 'edit'); } if(trigger.isInsert) { VisitAccess.insertVisitAccess(visit, visit.VisitorId, 'edit'); } } } - Выберите FileSave | Save.
-
Создайте триггер посетителя.
- Выберите Триггер | FileNewApex | New.
- Введите VisitorTrigger в имя триггера и выберите «Посетитель» в раскрывающемся списке sObject.
-
Удалите автоматически созданное содержимое и вставьте следующий образец.
trigger VisitorTrigger on Visitor (after insert, after update, after delete) { if(trigger.isInsert) { for(Visitor visitor : trigger.new) { VisitAccess.insertVisitAccess(new Visit(id=visitor.VisitId), visitor.AssigneeId, 'edit'); } } if(trigger.isUpdate) { for(Visitor visitor : trigger.new) { Visitor oldVisitor = trigger.oldMap.get(visitor.Id); VisitAccess.updateVisitAccess(new Visit(id=oldVisitor.VisitId), new Visit(id=visitor.VisitId), visitor.AssigneeId, 'edit'); } } if(trigger.isDelete) { for(Visitor visitor : trigger.old) { VisitAccess.deleteVisitAccess(new Visit(id=visitor.VisitId), visitor.AssigneeId); } } } - Выберите FileSave | Save.
Теперь торговые представители могут видеть только посещения, назначенные им. -
Создайте класс служебной программы
ProductItemAccess.- Выберите «Кл асс F | leNewApex». | New
- В качестве имени класса Apex введите ProductItemAccess.
-
Удалите автоматически созданное содержимое и вставьте следующий образец.
public class ProductItemAccess { public static void insertAccess(List<ProductItem> productItems, List<Id> users, String access) { if(productItems==null || productItems.isEmpty() || users==null || users.isEmpty()) { return; } productItems = getProductItemsWithId(productItems); List<ProductItemShare> shareList = new List<ProductItemShare>(); for(Id user: users) { if(user==null) continue; for(ProductItem item : productItems) { ProductItemShare share = New ProductItemShare(); share.ParentId=item.Id; share.UserOrGroupID = user; share.AccessLevel = access; shareList.add(share); } } try{ Database.insert(shareList); } catch (Exception e) { System.debug(e); } } public static void deleteAccess(List<ProductItem> productItems, List<Id> users) { List<ProductItemShare> shareList = new List<ProductItemShare>(); for(Id userId : users) { for(ProductItem productItem : productItems) { List<ProductItemShare> shares = [select Id from ProductItemShare where ParentId = :productItem.Id and UserOrGroupID = :userId and RowCause='Manual']; if(!shares.isEmpty()) { shareList.addAll(shares); } } } delete shareList; } public static List<ProductItem> getProductItems(ProductFulfillmentLocation fulfillLocation) { return [select Id from ProductItem where Product2Id=:fulfillLocation.ProductId and LocationId=:fulfillLocation.FulfillmentLocationId]; } private static List<ProductItem> getProductItemsWithId(List<ProductItem> productItems) { List<ProductItem> productItemsWithId = new List<ProductItem>(); for(ProductItem item : productItems) { if(item==null) continue; if(item.id==null) { List<ProductItem> itemList = [select Id from ProductItem where Product2Id=:item.Product2Id and LocationId=:item.locationId]; productItemsWithId.addAll(itemList); } } return productItemsWithId; } } - Выберите FileSave | Save.
-
Создайте класс служебной программы
ProductFulfillmentLocationAccess.- Выберите «Кл асс F | leNewApex». | New
- В качестве имени класса Apex введите ProductFulfillmentLocationAccess.
-
Удалите автоматически созданное содержимое и вставьте следующий образец.
public class ProductFulfillmentLocationAccess { static Set<String> accessLevels = new Set<String>{'read', 'edit'}; /** * Gives access to users on all product fulfillment locations */ public static void insertAccessToAllLocations(ProductFulfillmentLocation locationToInsert, String accessType) { List<ProductFulfillmentLocation> fulfillLocations = [select Id, ProductId, FulfillmentLocationId from ProductFulfillmentLocation]; insertAccess(fulfillLocations, getAllResponsibleUsers(), accessType); insertProductItemAccess(new List<ProductFulfillmentLocation>{locationToInsert}, new List<Id>{locationToInsert.UserId}, accessType); } public static void insertAccess(List<ProductFulfillmentLocation> fulfillLocations, List<Id> users, String accessType) { if(fulfillLocations==null || fulfillLocations.isEmpty() || users==null || users.isEmpty()) { return; } List<ProductFulfillmentLocationShare> shareList = new List<ProductFulfillmentLocationShare>(); for(Id user: users) { if(user==null) continue; for(ProductFulfillmentLocation location : fulfillLocations) { if(location==null || location.Id==null) continue; ProductFulfillmentLocationShare share = New ProductFulfillmentLocationShare(); share.ParentId=location.Id; share.UserOrGroupID = user; share.AccessLevel = accessType; shareList.add(share); } } try{ Database.insert(shareList); } catch (Exception e) { System.debug(e); } } public static void updateAccess(ProductFulfillmentLocation oldLocation, ProductFulfillmentLocation updatedLocation, String access) { deleteAccess(oldLocation); insertAccessToAllLocations(updatedLocation, access); } public static void deleteAccess(List<Id> users) { List<ProductFulfillmentLocationShare> shareList = new List<ProductFulfillmentLocationShare>(); for(Id userId : users) { if(isUserLinkedTofulfillLocation(userId)) continue; List<ProductFulfillmentLocationShare> shares = [select Id from ProductFulfillmentLocationShare where UserOrGroupID = :userId and RowCause='Manual']; if(!shares.isEmpty()) { shareList.addAll(shares); } } delete shareList; } public static void deleteAccess(ProductFulfillmentLocation fulfillLocation) { deleteAccess(new List<Id>{fulfillLocation.UserId}); deleteProductItemAccess(fulfillLocation); } public static Boolean isUserLinkedTofulfillLocation(Id userId) { List<ProductFulfillmentLocation> fulfillLocations = [select Id from ProductFulfillmentLocation where UserId = :userId]; return !fulfillLocations.isEmpty(); } public static void deleteProductItemAccess(ProductFulfillmentLocation fulfillLocation) { ProductItemAccess.deleteAccess(ProductItemAccess.getProductItems(fulfillLocation), new List<id>{fulfillLocation.UserId}); } public static void insertProductItemAccess(List<ProductFulfillmentLocation> fulfillLocations, List<Id> users, String access) { List<ProductItem> productItems = new List<ProductItem>(); for(ProductFulfillmentLocation location : fulfillLocations) { productItems.add(new ProductItem(Product2Id=location.ProductId, LocationId=location.FulfillmentLocationId)); } ProductItemAccess.insertAccess(productItems, users, access); } public static List<Id> getAllResponsibleUsers() { List<Id> users = new List<Id>(); List<ProductFulfillmentLocation> fulfillLocations = [select UserId from ProductFulfillmentLocation]; for(ProductFulfillmentLocation location : fulfillLocations) { users.add(location.UserId); } return users; } } - Выберите FileSave | Save.
Теперь торговые представители могут видеть только запасы, за которые они ответственны.

