Регистрация  |  Вход

Триггеры и Case.

И снова здравствуйте сеньоры, надеюсь, я ещё вас не задолбал И так новый мой вопрос по триггерам и кейсам, хотя скорее всего именно по кейсам.
К сути, по заданию мне требуется создать триггер который будет для создаваемого контакта создавать Case по определенным правилам, его я написал следующим образом:

trigger ContactTrigger on Contact (before insert) {
for(Contact item : Trigger.New){
Case cs = new Case();
cs.ContactId = item.Id;
cs.AccountId = item.AccountId != null ? item.AccountId : null;
cs.Status = 'Working';
cs.Origin = 'New Contact';
if (cs.AccountId != null){
List<Account> acc = new List<Account>([SELECT Id, OwnerId FROM Account WHERE Id = :cs.AccountId]);
cs.OwnerId = acc[0].OwnerId;
}
if(item.Contact_Level__c == 'Primary'){
cs.Priority = 'High';
}else if (item.Contact_Level__c == 'Secondary'){
cs.Priority = 'Medium';
}else {
cs.Priority = 'Low';
}
insert cs;
}
}

Вроде бы всё работает (и даже работает правильно) я вижу, что кейсы создаются, что они привязываются к контакту, !НО если я захожу в контакт я этот кейс почему-то не вижу... Вероятно, что так быть не должно, как это исправить просто ни малейшего понятия, если список кейсов в контакте это просто некий List<Case>, где ContactId == this.Id, то какого черта они не отображаются.:(

Следующей проблемой которую я заметил это то, что теперь я не могу удалить контакт, т.к. на него есть ссылка у кейса, т.е. надо доделать логику на удаление всех кейсов связанных с контактом?? Объясните на пальцах пожалуйста, что такое вообще Case? Я его сейчас понимаю как некоторый класс наследник в котором находятся какие-то задачи\проблемы\заказы\и т.д.

Да и вообще иерархия всех этих объектов мне представляется очень туманно и найти какую-то исчерпывающую информацию у меня не получается. Сейчас я понимаю так: Существует некий аккаунт -> ему может соответствовать n контактов -> которым может соответствовать n кейсов...

Извиняюсь если уже вас уже тошнит от моих нубских вопросов

Спасибо за уделённое время и заранее огромное спасибо за ответы

И снова здравствуйте сеньоры, надеюсь, я ещё вас не задолбал :) И так новый мой вопрос по триггерам и кейсам, хотя скорее всего именно по кейсам.
К сути, по заданию мне требуется создать триггер который будет для создаваемого контакта создавать Case по определенным правилам, его я написал следующим образом:
[code]trigger ContactTrigger on Contact (before insert) {
    for(Contact item : Trigger.New){
        Case cs = new Case();
        cs.ContactId = item.Id;
        cs.AccountId = item.AccountId != null ? item.AccountId : null;
        cs.Status = 'Working';
        cs.Origin = 'New Contact';
        if (cs.AccountId != null){
            List<Account> acc = new List<Account>([SELECT Id, OwnerId FROM Account WHERE Id = :cs.AccountId]);
            cs.OwnerId = acc[0].OwnerId;
        }
        if(item.Contact_Level__c == 'Primary'){
            cs.Priority = 'High';
        }else if (item.Contact_Level__c == 'Secondary'){
            cs.Priority = 'Medium';
        }else {
            cs.Priority = 'Low';
        }
        insert cs;
    }
}[/code]
Вроде бы всё работает (и даже работает правильно) я вижу, что кейсы создаются, что они привязываются к контакту, !НО если я захожу в контакт я этот кейс почему-то не вижу... Вероятно, что так быть не должно, как это исправить просто ни малейшего понятия, если список кейсов в контакте это просто некий List<Case>, где ContactId == this.Id, то какого черта они не отображаются.:(

Следующей проблемой которую я заметил это то, что теперь я не могу удалить контакт, т.к. на него есть ссылка у кейса, т.е. надо доделать логику на удаление всех кейсов связанных с контактом?? Объясните на пальцах пожалуйста, что такое вообще Case? Я его сейчас понимаю как некоторый класс наследник в котором находятся какие-то задачи\проблемы\заказы\и т.д.

Да и вообще иерархия всех этих объектов мне представляется очень туманно и найти какую-то исчерпывающую информацию у меня не получается. Сейчас я понимаю так: Существует некий аккаунт -> ему может соответствовать n контактов -> которым может соответствовать n кейсов... 

Извиняюсь если уже вас уже тошнит от моих нубских вопросов :)

Спасибо за уделённое время и заранее огромное спасибо за ответы :)


А ты уверен, что у тебя
item.Id
не пустой? Тесты у тебя проходит? ContactId не пустой в тесте?
Судя по https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers.htm там еще пусто.
Case - это sObject под свои задачи/нужды. Там есть поля lookup. Ничего сверхординарного в этом объекте нет. Schema Builder должен быть удобен для понимания вопроса.

А ты уверен, что у тебя 
item.Id
не пустой? Тесты у тебя проходит? ContactId не пустой в тесте?
Судя по https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers.htm там еще пусто.
Case - это sObject под свои задачи/нужды. Там есть поля lookup. Ничего сверхординарного в этом объекте нет. Schema Builder должен быть удобен для понимания вопроса.

Andrii Muzychuk
А ты уверен, что у тебя
item.Id
не пустой? Тесты у тебя проходит? ContactId не пустой в тесте?
Судя по https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers.htm там еще пусто.
Case - это sObject под свои задачи/нужды. Там есть поля lookup. Ничего сверхординарного в этом объекте нет. Schema Builder должен быть удобен для понимания вопроса.

Действительно был пустой id, переделал before insert на after insert теперь отображается) Это нормальное решение ?) А вот при удалении контакта как будет правильно сделать логику ? Сделать ещё один триггер который будет проверять есть ли у контакта кейс и в случае если Case.AccountId == null, то удалять Case и потом удалять контакт, а если Case.AccountId != null, то Case.ContactId = null; Или всё же правильнее будет при любых раскладах вместе с контактом удалять и все связанные с ним кейсы?

[quote="Andrii Muzychuk"]А ты уверен, что у тебя 
item.Id
не пустой? Тесты у тебя проходит? ContactId не пустой в тесте?
Судя по https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers.htm там еще пусто.
Case - это sObject под свои задачи/нужды. Там есть поля lookup. Ничего сверхординарного в этом объекте нет. Schema Builder должен быть удобен для понимания вопроса.[/quote]
Действительно был пустой id, переделал before insert на after insert теперь отображается) Это нормальное решение ?) А вот при удалении контакта как будет правильно сделать логику ? Сделать ещё один триггер который будет проверять есть ли у контакта кейс и в случае если Case.AccountId == null, то удалять Case и потом удалять контакт, а если Case.AccountId != null, то Case.ContactId = null; Или всё же правильнее будет при любых раскладах вместе с контактом удалять и все связанные с ним кейсы?

Ты ссылку прочитал? Выучил?

There are two types of triggers:
Before triggers are used to update or validate record values before they’re saved to the database.
After triggers are used to access field values that are set by the system (such as a record's Id or LastModifiedDate field), and to affect changes in other records, such as logging into an audit table or firing asynchronous events with a queue. The records that fire the after trigger are read-only.

Ты ссылку прочитал? Выучил?

There are two types of triggers:
Before triggers are used to update or validate record values before they’re saved to the database.
After triggers are used to access field values that are set by the system (such as a record's Id or LastModifiedDate field), and to affect changes in other records, such as logging into an audit table or firing asynchronous events with a queue. The records that fire the after trigger are read-only.

На счет удалений - это как задача стоит. Если задача стоит "Удалить все Case при удалении Contact." то да, надо удалить все Case при удалении Contact. before Contact delete

На счет удалений - это как задача стоит. Если задача стоит "Удалить все Case при удалении Contact." то да, надо удалить все Case при удалении Contact. before Contact delete

Andrii Muzychuk
Ты ссылку прочитал? Выучил?[quote="Andrii Muzychuk"]Ты ссылку прочитал? Выучил?

There are two types of triggers:
Before triggers are used to update or validate record values before they’re saved to the database.
After triggers are used to access field values that are set by the system (such as a record's Id or LastModifiedDate field), and to affect changes in other records, such as logging into an audit table or firing asynchronous events with a queue. The records that fire the after trigger are read-only.

Прочитал, выучил будет громко сказано) Я плохо воспринимаю теорию без практики )

Andrii Muzychuk
На счет удалений - это как задача стоит. Если задача стоит "Удалить все Case при удалении Contact." то да, надо удалить все Case при удалении Contact. before Contact delete

Ничего не сказано, просто я подумал, что достаточно странно будет если останется какой-то кейс не связанный ни с одной другой записью.

А в задание следующее:
"Напротив каждого контакта нужно показать кнопку Del, которая будет удалять контакт из базы данных."
"При создании нового контакта автоматически должен создаваться Case при помощи триггера. Case должен
привязываться к новому контакту."

[quote="Andrii Muzychuk"]Ты ссылку прочитал? Выучил?[quote="Andrii Muzychuk"]Ты ссылку прочитал? Выучил?

There are two types of triggers:
Before triggers are used to update or validate record values before they’re saved to the database.
After triggers are used to access field values that are set by the system (such as a record's Id or LastModifiedDate field), and to affect changes in other records, such as logging into an audit table or firing asynchronous events with a queue. The records that fire the after trigger are read-only.[/quote]

Прочитал, выучил будет громко сказано) Я плохо воспринимаю теорию без практики )

[quote="Andrii Muzychuk"]На счет удалений - это как задача стоит. Если задача стоит "Удалить все Case при удалении Contact." то да, надо удалить все Case при удалении Contact. before Contact delete[/quote]

Ничего не сказано, просто я подумал, что достаточно странно будет если останется какой-то кейс не связанный ни с одной другой записью.

А в задание следующее:
"Напротив каждого контакта нужно показать кнопку Del, которая будет удалять контакт из базы данных."
"При создании нового контакта автоматически должен создаваться Case при помощи триггера. Case должен
привязываться к новому контакту."


Kirill
А в задание следующее:
"Напротив каждого контакта нужно показать кнопку Del, которая будет удалять контакт из базы данных."
"При создании нового контакта автоматически должен создаваться Case при помощи триггера. Case должен
привязываться к новому контакту."

Собрат по ТЗ. Судя по дате, уже наверное разобрался и сдал ТЗ.
Для тех кто делает это же ТЗ, напоминаю, что:
1. Триггер там только для создания Кейса, впрочем как и удаления.
2. Кнопка ДЕЛ напротив каждого контакта, ведь наверное относится к VFpage, и писать ее надо там где страница и контроллер. код, пока лежит на гите, в открытом доступе, а почитать кое что можно тут: https://salesforce-developer.ru/forum/topic-salesforce-pagination-custom-controller-example

Вот что у меня получилось с триггером:

trigger CustomSorting181112Trigger on Contact (after insert, before delete) {

// Хэлпы тут:
// https://salesforce.stackexchange.com/questions/27241/write-a-trigger-that-automatically-create-a-contact-when-account-is-created
// https://trailhead.salesforce.com/en/content/learn/modules/apex_triggers/apex_triggers_intro
// https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers.htm
// https://developer.salesforce.com/forums/?id=906F00000008qelIAA
// https://salesforce-developer.ru/forum/topic-triggery-i-case

/*
1. При создании нового контакта автоматически должен создаваться Case при помощи триггера.
2.1. Case должен привязываться к новому контакту.
2.2. Если контакт ссылается на аккаунт, тогда новый Case также должен ссылаться на
этот аккаунт.
3.
3.1. Поле Status у нового Case должно принимать значение ‘Working’,
3.2. а поле Case Origin должно принимать значение ‘New Contact’.
4.
4.1. Поле Owner у Case должен быть таким же как Owner у аккаунта, на которого ссылается контакт.
4.2. Также поле Priority у нового Case должно зависеть от того,
какое значение было выбрано в поле Contact Level у контакта. Если оно было
‘Primary’ тогда Priority = ‘High’, если оно было
‘Secondary’ тогда Priority = ‘Medium’, если оно было
‘Tertiary’ тогда Priority = ‘Low’
*/

if (Trigger.isInsert) {
//Действия - after insert

// Создаем новый лист для записей Кейса
// Лист создается на случай добавления множества записей, за один раз
List<Case> newCaseList = new List<Case>();

for(Contact con : trigger.new) {

Case newCase = new Case();

// Реализуем зависимость полей Priority(Case) и Contact Level(Contact)
if (con.Contact_Level__c == 'Primary') {
newCase.Priority = 'High';
} else if (con.Contact_Level__c == 'Secondary') {
newCase.Priority = 'Medium';
} else {
newCase.Priority = 'Low';
}

// Значение полей поумолчанию, при создании нового контакта
newCase.Status = 'Working';
newCase.Origin = 'New Contact';
newCase.ContactId = con.Id;

// Если создается новый Аккаунт
if (newCase.AccountId != null) {
// 2.2. Если контакт ссылается на аккаунт, тогда
// новый Case также должен ссылаться на этот аккаунт.
newCase.AccountId = con.AccountId;
// 4.1. Поле Owner у Case(OwnerId) должен быть таким же как
// Owner(acc[0].OwnerId) у аккаунта, на которого ссылается контакт.
List<Account> acc = new List<Account>([SELECT Id, OwnerId FROM Account WHERE Id =: newCase.AccountId]);
newCase.OwnerId = acc[0].OwnerId;
}

// Добавляем запись в лист Кейс
newCaseList.add(newCase);
}

// Добавляем весь лист Кейс в ДБ
insert newCaseList;
}

else if (Trigger.isDelete) {

Set<Id> ConIDs = Trigger.oldMap.keyset();

delete [SELECT Id FROM Case WHERE ContactId IN:ConIDs]; // Удаляет Кейсы
// delete [SELECT Id FROM Account WHERE OwnerId IN:ConIDs]; // Хотел сделать удаление аккаунта, туплю...

// https://stackoverflow.com/questions/14843513/salesforce-trigger-deleting-object
// Контекстные переменные триггера
// https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables.htm

}

}

Один момент не работает, кто может подсказать, как сделать удаления записи аккаунта? И правильно ли вообще удалять аккаунт, который создавался триггером автоматически? Про удаление аккаунта, может быть и не стоит его удалять, по той причине, что на одном аккаунте, может быть уже несколько контактов и кейсов и тогда получится не логичная ситуация.
Хорошо, а как тогда сделать проверку на дублирование новых аккаунтов и может ли вообще существовать два аккаунта с одним именем?
Вобщем всем бобра, пишите письма, кто что думает.

[quote="Kirill"]А в задание следующее: 
"Напротив каждого контакта нужно показать кнопку Del, которая будет удалять контакт из базы данных." 
"При создании нового контакта автоматически должен создаваться Case при помощи триггера. Case должен 
привязываться к новому контакту."[/quote]

Собрат по ТЗ. Судя по дате, уже наверное разобрался и сдал ТЗ.
Для тех кто делает это же ТЗ, напоминаю, что:
1. Триггер там только для создания Кейса, впрочем как и удаления.
2. Кнопка ДЕЛ напротив каждого контакта, ведь наверное относится к VFpage, и писать ее надо там где страница и контроллер. код, пока лежит на гите, в открытом доступе, а почитать кое что можно тут: https://salesforce-developer.ru/forum/topic-salesforce-pagination-custom-controller-example

Вот что у меня получилось с триггером:
[code]trigger CustomSorting181112Trigger on Contact (after insert, before delete) {

	// Хэлпы тут:
	// https://salesforce.stackexchange.com/questions/27241/write-a-trigger-that-automatically-create-a-contact-when-account-is-created
	// https://trailhead.salesforce.com/en/content/learn/modules/apex_triggers/apex_triggers_intro
	// https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers.htm
	// https://developer.salesforce.com/forums/?id=906F00000008qelIAA
	// https://salesforce-developer.ru/forum/topic-triggery-i-case

/*
   1. При создании нового контакта автоматически должен создаваться Case при помощи триггера.
   2.1. Case должен привязываться к новому контакту.
   2.2. Если контакт ссылается на аккаунт, тогда новый Case также должен ссылаться на
   этот аккаунт.
   3.
   3.1. Поле Status у нового Case должно принимать значение ‘Working’,
   3.2. а поле Case Origin должно принимать значение ‘New Contact’.
   4.
   4.1. Поле Owner у Case должен быть таким же как Owner у аккаунта, на которого ссылается контакт.
   4.2. Также поле Priority у нового Case должно зависеть от того,
   какое значение было выбрано в поле Contact Level у контакта. Если оно было
   ‘Primary’ тогда Priority = ‘High’, если оно было
   ‘Secondary’ тогда Priority = ‘Medium’, если оно было
   ‘Tertiary’ тогда Priority = ‘Low’
 */

	if (Trigger.isInsert) {
		//Действия - after insert

		// Создаем новый лист для записей Кейса
		// Лист создается на случай добавления множества записей, за один раз
		List<Case> newCaseList = new List<Case>();

		for(Contact con : trigger.new) {

			Case newCase = new Case();

			// Реализуем зависимость полей Priority(Case) и Contact Level(Contact)
			if (con.Contact_Level__c == 'Primary') {
				newCase.Priority = 'High';
			} else if (con.Contact_Level__c == 'Secondary') {
				newCase.Priority = 'Medium';
			} else {
				newCase.Priority = 'Low';
			}

			// Значение полей поумолчанию, при создании нового контакта
			newCase.Status = 'Working';
			newCase.Origin = 'New Contact';
			newCase.ContactId = con.Id;

			// Если создается новый Аккаунт
			if (newCase.AccountId != null) {
				// 2.2. Если контакт ссылается на аккаунт, тогда
				// новый Case также должен ссылаться на этот аккаунт.
				newCase.AccountId = con.AccountId;
				// 4.1. Поле Owner у Case(OwnerId) должен быть таким же как
				// Owner(acc[0].OwnerId) у аккаунта, на которого ссылается контакт.
				List<Account> acc = new List<Account>([SELECT Id, OwnerId FROM Account WHERE Id =: newCase.AccountId]);
				newCase.OwnerId = acc[0].OwnerId;
			}

			// Добавляем запись в лист Кейс
			newCaseList.add(newCase);
		}

		// Добавляем весь лист Кейс в ДБ
		insert newCaseList;
	}

	else if (Trigger.isDelete) {

		Set<Id> ConIDs = Trigger.oldMap.keyset();
		
		delete [SELECT Id FROM Case WHERE ContactId IN:ConIDs]; // Удаляет Кейсы
		// delete [SELECT Id FROM Account WHERE OwnerId IN:ConIDs]; // Хотел сделать удаление аккаунта, туплю...

		// https://stackoverflow.com/questions/14843513/salesforce-trigger-deleting-object
		// Контекстные переменные триггера
		// https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables.htm

	}

}[/code]

Один момент не работает, кто может подсказать, как сделать удаления записи аккаунта? И правильно ли вообще удалять аккаунт, который создавался триггером автоматически? Про удаление аккаунта, может быть и не стоит его удалять, по той причине, что на одном аккаунте, может быть уже несколько контактов и кейсов и тогда получится не логичная ситуация.
Хорошо, а как тогда сделать проверку на дублирование новых аккаунтов и может ли вообще существовать два аккаунта с одним именем? 
Вобщем всем бобра, пишите письма, кто что думает.