Как заполнить поле поиска при создании нового пользовательского объекта в SFDC

Я борюсь с этой ситуацией. У меня есть стандартный объект в SFDC (возможность), в котором есть настраиваемое поле поиска, указывающее на объект пользователя, что я пытаюсь сделать, это заполнить это поле именем пользователя, который создает настраиваемый объект, доступный в макете возможной сделки...

т. е. Новый контрольный список GOP --- Затем выберите тип контрольного списка --- а затем заполните все необходимые поля и нажмите «Сохранить», это указывает на представление «Возможность». Для начала, это что-то выполнимое? я знаю, что поля поиска могут быть сложными. и мой второй вопрос: как лучше всего сделать это программно (триггер) или с использованием функций рабочего процесса и обновления полей?

Спасибо !!

trigger TR_OrderChecklist on Order_Checklist__c (before insert) {

//----------------------------------------------------------------------------------
// Function 1: Update COS Operations Attribute in Opportunity
//----------------------------------------------------------------------------------

for(Order_Checklist__c o : trigger.new){
  if(o.Opportunity__r.CARE_Operations__c == null) {
    o.Opportunity__r.CARE_Operations__c = UserInfo.getUserId();
  }
}

}

Вот что они придумали. В стандартном объекте возможностей у нас есть поле поиска, привязанное к пользователю.. CARE_Operations__c.. Теперь триггер должен делать следующее..

1.- При создании нового контрольного списка GOP, если пользователь заполнит новое настраиваемое поле поиска в объекте GOP с именем COSOperations_c, сохраните это имя, 2.- Если пользователь не заполнил COSOperations_c поле, но поле на уровне Opp CARE_Operations__c заполнено, используйте это имя. 3.- Если ни CARE_Operations_c, ни COSOperations_c не заполнены (пользовательский ввод), то COSOperations__c будет человеком, который только что создал объект GOP.

Это то, что у меня есть до сих пор..

trigger TR_OrderChecklist on Order_Checklist__c (before insert) {
List<Opportunity> COS_Op = new List<Opportunity>();
COS_Op = [select CARE_Operations__c from Opportunity where id in (select   Opportunity__c from Order_Checklist__c where COSOperations__c != null)];
for(Order_Checklist__c OC : trigger.new) {
    if(OC.COSOperations__c != null) {
       break;}
    if(COS_Op != null){
       OC.COSOperations__c = OC.Opportunity__r.CARE_Operations__c;} 
    if(OC.COSOperations__c == null){
       OC.COSOperations__c = UserInfo.getUserId();}
}       
} 

Моя проблема во втором операторе if.. остальные 2 условия работают правильно..! Любые идеи ? Спасибо !!!


person JeyJim    schedule 29.08.2012    source источник
comment
@Twanley Привет, Тванли. Теперь требования другие.. Пожалуйста, проверьте мой вопрос еще раз и спасибо за все ваши отзывы..!   -  person JeyJim    schedule 17.09.2012


Ответы (2)


Мой (второй) подход к исправлению кода триггера, который вы разместили:

trigger TR_OrderChecklist on Order_Checklist__c (after update) {
    List<Opportunity> opptsToUpdate = new List<Opportunity>();
    for(Order_Checklist__c o : trigger.new) {
        if(o.Opportunity__r.CARE_Operations__c == null) {
            o.Opportunity__r.CARE_Operations__c = UserInfo.getUserId();
            // Queue it up for one update statement later
            opptsToUpdate.add(o.Opportunity__r);
        }
    }
    // Commit any changes we've accumulated for the opportunity records
    if (opptsToUpdate.size() > 0)
        update opptsToUpdate;
}

Предполагая, что у вас есть Opportunity.My_User__c в качестве поиска (пользователь) и My_Object__c.Opportunity__c в качестве поиска (возможность), этот триггер является хорошим началом:

trigger HandleMyObjectInsert on My_Object__c (before insert) {
    User actingUser = [SELECT id FROM User WHERE Id = :UserInfo.getUserId()];
    List<Opportunity> oppts = new List<Opportunity>();
    for (My_Object__c myobj : trigger.new) {
        Opportunity o = new Opportunity();
        o.Id = myobj.Opportunity__c;
        o.My_User__c = actingUser.Id;
        oppts.add(o);
    }
    update oppts;
}

Для доказательства того, что Lookup(User) — это просто поле Id, попробуйте это упражнение. Создайте новое поле «Поиск (пользователь)» в объекте «Возможность» с именем «Мой пользователь».

  • Тип данных: отношение поиска
  • Связано с: Пользователь
  • Метка поля: Мой пользователь
  • Имя поля: My_User (превращается в My_User__c, а также доступно через My_User__r)

На веб-странице Salesforce выберите существующую запись возможной сделки, задайте в поле «Мой пользователь» случайного пользователя и сохраните запись. Теперь из консоли разработчика выполните этот анонимный APEX:

Opportunity[] oppts = [
    SELECT id, My_User__c, My_User__r.Name
    FROM Opportunity
    WHERE My_User__c != null
];
for (Opportunity o : oppts) {
    system.debug('##### Opportunity.My_User__c = ' 
        + o.My_User__c 
        + ', o.My_User__r.Name = ' 
        + o.My_User__r.Name);
}

Закройте причудливое представление журнала и нажмите «Открыть необработанный журнал», и вы увидите строку, подобную этой:

16:42:37.077 (77645000)|USER_DEBUG|[7]|DEBUG|##### Opportunity.My_User__c = 00530000000grcbAAA, o.My_User__r.Name = John Doe

Видите ли, Salesforce рассматривает поля поиска __c как поля идентификатора. В данном случае это отношение внешнего ключа к идентификатору объекта пользователя. Salesforce заставляет вас думать, что поле «Имя» является первичным ключом, но на самом деле это поле «Идентификатор» (хорошо, я на самом деле не видел ERD Salesforce, но я почти уверен, что это правильно). Обратите внимание, что вы можете получить доступ к полям объекта поиска с помощью конструкции __r.

Обновление поля — это просто изменение идентификатора My_User__c:

Opportunity[] oppts = [
    SELECT id, My_User__c
    FROM Opportunity
    WHERE My_User__c != null
    LIMIT 1
];
for (Opportunity o : oppts) {
    o.My_User__c = :UserInfo.getUserId();
}
update oppts;

Или вы можете получить идентификатор пользователя из запроса soql следующим образом:

// Let's query all users and use the 3rd one in the list (zero-index 2)
User[] users = [select id from user];
Opportunity o = new Opportunity(My_User__c = users[2].id, Name='Testing', StageName = 'Prospecting', CloseDate = System.today());
insert o;

Или найдите пользователя по его адресу электронной почты:

User[] users = [select id from user where email = '[email protected]' and IsActive = true];
if (users.size() > 0) {
    Opportunity o = new Opportunity(My_User__c = users[0].id, Name='Testing', StageName = 'Prospecting', CloseDate = System.today());
    insert o;
}

Это действительно хороший способ получить идентификатор текущего пользователя:

UserInfo.getUserId()
person twamley    schedule 30.08.2012
comment
Привет, twanley.. в этом случае вы назначаете идентификатор из оператора SOQL для o.My_User__c, но как мне назначить то же значение идентификатора для поля поиска?? это выполнимо? если вы можете показать мне, как я действительно ценю это. ! Спасибо - person JeyJim; 30.08.2012
comment
Я думаю, что если вы откроете капот, вы обнаружите, что поля поиска на самом деле являются полями идентификаторов. Я предоставил своего рода учебник, чтобы помочь сделать это. Рад помочь, если вы все еще застряли. - person twamley; 31.08.2012
comment
Привет, Твэмли... Вот триггер, который я написал... он не работает...!! и я понятия не имею, почему..! :С - person JeyJim; 06.09.2012
comment
@JeyJim, извините, ваше изменение было отклонено. Пожалуйста, добавьте дополнительные вещи, которые вы хотите сказать, используя комментарии или обновив исходный вопрос. Редактирование ответов других людей, чтобы выразить свои мысли, не очень приветствуется. - person Andrejs Cainikovs; 06.09.2012
comment
@twamley Пожалуйста, проверьте триггер в моем исходном вопросе и дайте мне знать, что я здесь делаю неправильно .. !! Спасибо !! - person JeyJim; 06.09.2012
comment
Опубликовал мой взгляд на исправление вашего триггера. Дайте мне знать, как это происходит. - person twamley; 07.09.2012
comment
Привет, Твэмли.. Я потерялся.. !!! Я пытаюсь заставить триггер работать, но получаю сообщение об ошибке, что поле Opportunity.id недоступно для записи... и на самом деле это имеет смысл... я пытаюсь обновить поле в объекте "Возможность" ( возможность уже создана) что я могу сделать, чтобы изменить эти 2 строки и получить текущий идентификатор opp Opportunity oppToUpdate = new Opportunity(); oppToUpdate.Id = o.Opportunity__c; Новая возможность (); Я думаю, что создает для него новый идентификатор, и я пытаюсь присвоить идентификатор ссылки только что созданному правильно? Пожалуйста, порекомендуйте.. !! Спасибо ! - person JeyJim; 07.09.2012
comment
Извините, мне нелегко тестировать этот код. Я просматривал эту страницу и, возможно, все, что вы В вашем триггере отсутствует эта строка update o.Opportunity__r; Я обновил свой триггер до версии с более удобными ограничениями регулятора. - person twamley; 08.09.2012
comment
@Twanley Привет, Тванли. Теперь требования другие.. Пожалуйста, проверьте мой вопрос еще раз и спасибо за все ваши отзывы..! - person JeyJim; 17.09.2012
comment
После борьбы с тем, как использовать идентификатор родительской возможности, я смог выполнить, я тоже пытался.. Спасибо за всю вашу помощь, ребята! - person JeyJim; 20.09.2012

Я немного запутался здесь с требованиями. Говорим ли мы, что вам нужно создать новую запись возможной сделки при создании записи пользовательского объекта?

Если да, то возможно. Вы можете написать триггер APEX для объекта клиента типа «после вставки», создать новую запись возможной сделки и заполнить ее поля по мере необходимости.

person Richard N    schedule 29.08.2012
comment
Привет, Ричард. Что я пытаюсь сделать, так это как только я создам новый пользовательский объект в этом случае (контрольный список GOP), я хочу заполнить имя человека, создавшего контрольный список GOP, в одном пользовательском поле, которое принадлежит возможности Объект (поле поиска, привязанное к пользовательскому объекту) это выполнимо ?? Спасибо !!! - person JeyJim; 30.08.2012