Hello please help my friend to write code, his task is
No contacts should be inserted or updated if email does not has " com. Net" email is a custom filed on contact. I want you to do it by trigger this trigger should only fire on insert and change of email
code he write
Code he write :
trigger InsertedUpdated on Contact (before insert,before update){
for(contact con:trigger.new)
if( con.Email=='xyz#gmail.com'){
// con.Last='.com /.net';
}
for( contact con:trigger.new ){
if(con.Email!=trigger.Oldmap.get(con.Id).Email || con.Email!=trigger.Oldmap.get(con.Id).Email){
if( con.Email=='xyz#gmail.com' ){
con.adderror('Email does not correct ');
}
x
}
}
}
Is it necessary to use a trigger? A validation rule seems better suited to this use case, and will provide friendlier errors when violated.
You can find information on using regex in a validation rule here
If it is absolutely necessary to use a trigger, this page has an example of how to write a regex in apex.
Related
I am attempting to use Apex to create a multi-contact event.
I have already enabled Allow Users to Relate Multiple Contacts to Tasks and Events in the activity settings in the scratch org.
I am following the guide and the example at the bottom of these docs but I am constantly getting an error when pushing to the scratch org:
// ...
event.setEventWhoIds(attendeeContactIds);
// ...
Method does not exist or incorrect signature: void setEventWhoIds(List<String>) from the type Event.
I also tried to write directly to the field with:
event.EventWhoIds = attendeeContactIds;
With that, I get the error, that the field is not writable.
attendeeContactIds is a List of Strings representing Contact IDs.
What could I be missing? 🤔🙇🏻♂️
It's bit stupid, it's readonly in apex. It's exposed so integrations can quickly create event and essentially a related list together in one all-or-nothing transaction. See also https://salesforce.stackexchange.com/questions/238094/eventwhoids-is-not-writeable-in-apex-class-but-working-on-jsforce
Try something like that?
Savepoint sp = Database.setSavepoint();
event e = new Event(
StartDateTime = System.now(),
EndDateTime = System.now().addHours(1)
);
insert e;
List<EventRelation> invitations = new List<EventRelation>();
for(Contact c : [SELECT Id FROM Contact LIMIT 5]){
invitations.add(new EventRelation(
EventId = e.Id,
RelationId = c.Id,
IsInvitee = true
));
}
insert invitations;
Database.rollback(sp); // unless you really want to send it out
I'm a noob in CakePHP and I've been trying to do some complex validations here:
I have the following models:
- Fonts (name, file);
- Settings(value1,value2,value3,type_id,script_id);
- Types(name)
Whenever I create a Font I also create a default setting associated to it. Also, this setting has a type associated. After the Font is created I can associate more settings to it (Font hasMany Settings), but I need to make sure that two settings of the same type are not added to that font. I don't know how to handle this case. Any help is appreciated. Thanks.
I'd use a simple beforeSave validation
//in setting.php model
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['font_id']) && isset($this->data[$this->alias]['type_id']) {
$otherSettings = $this->find('all', array('conditions'=>
array('type_id'=>$this->data[$this->alias]['type_id'],
'font_id'=>$this->data[$this->alias]['font_id']);
//check if it's insert or update
$updated_id = null;
if ($this->id)
$updated_id = $this->id;
if (isset($this->data[$this->alias][$this->primaryKey]))
$updated_id = $this->data[$this->alias][$this->primaryKey];
if (count($otherSettings) > 0) {
if ($updated_id == null)
return false; //it's not an update and we found other records, so fail
foreach ($otherSettings as $similarSetting)
if ($updated_id != $similarSetting['Setting']['id'])
return false; //found a similar record with other id, fail
}
}
return true; //don't forget this, it won't save otherwise
}
That will prevent inserting new settings to the same font with the same type. Have in mind that this validation will return false if the validation is incorrect, but you have to handle how you want to alert the user of the error. You can throw exceptions from the beforeSave and catch them in the controller to display a flash message to the user. Or you could just not save those settings and let the user figure it out (bad practice).
You could also create a similar function in the model like checkPreviousSettings with a similar logic as the one I wrote above, to check if the settings about to be saved are valid, if not display a message to the user before attempting a save.
The option I prefer is the exception handling error, in that case you'd have to replace the return false with
throw new Exception('Setting of the same type already associated to the font');
and catch it in the controller.
Actually, the better approach is to not even display the settings with the same type and font to the user, so he doesn't even have the option of choosing. But this behind-the-scenes validation would also be needed.
Use case
My use case is that I need to validate a Table Tennis score.
Form
<input name="data[MatchesPlayer][1][score]" type="number" id="MatchesPlayer1Score">
<input name="data[MatchesPlayer][2][score]" type="number" id="MatchesPlayer2Score">
Constraints
One score must be bigger than 11.
One score must be 2 points or greater than the other if the score is higher than 11.
Problem
When cake validates multiple rows from the same model, the model data is set to that record. This means that it's not possible to compare the two values as they aren't both available in $this->data. As I am using saveAll() each record is set to the model and then validated before it's saved.
Question
I'd like to know if there is a good way to validate this pair of data without resorting to saving it into the session or similar before I can validate it.
What I normally do here is I create a wrapper for the save method. This allows me to perform custom manipulation that would otherwise not be possible with model callbacks, or even use custom transactions etc.
In your case, it would be something like:
class MatchesPlayer extends Model {
protected $_saveData = null;
public function updateScore($data) {
$this->_saveData = $data;
try {
// You can use saveAll to validate
// only, and not actually save
$saved = $this->saveAll($data, array('validate' => 'only'));
} catch (Exception $e) {
// Catch exceptions here in case the
// saveAll is instead something that throws Exceptions
// Or your database uses exceptions
$saved = false;
}
$this->_saveData = null;
return $saved
}
}
You could then use $this->_saveData across the model. If you want to be clever with this, you could detect all sub-models that are being saved in the $data and then set the $this->_saveData on those as well - I would make this an AppModel method of course.
Note that you may want to throw exceptions from this updateScore() method when validation fails. Throwing an exception if validation fails - vs save - would allow you to set a custom flash message for the user as well, or even have an api that responds with a different status code.
Use custom validation rules in MatchesPlayer model, please check
http://book.cakephp.org/2.0/en/models/data-validation.html#adding-your-own-validation-methods
Here is the problem I'm trying to solve:
When a new TASK/EVENT is created, if the user is a certain profile - we want to update a field on CONTACT with the day the T/E was created.
I tried doing a workflow rule and field update- but I couldn't get it to work... I think since this is a Standard -Standard object relationship via lookup, it might have a problem doing a field update. Any other ideas?? I'd prefer to use the platform for this one...
HALP!
Thanks
We have done exactly what you are talking about via an Apex trigger. Something like this...
//I'm sure this doesn't compile, but it gives you the idea
trigger taskTrigger on Task( after insert, after update ){
Task t = trigger.new ;
Contact contact = [Select Id from Contact where Id = :t.whoId] ;
contact.yourfield = t.AcitivityDate ;
update contact ;
}
I have custom object KeywordAccountAssociation__c. This object has three fields
Account__c - Master-Detail(Account)
Keyword__c - Master-Detail(Keyword)
Compositecp__c - Text(255) (External ID) (Unique Case Sensitive)
I have a custom field in Account
DD_Segment__c - multi-picklist
Now I want to update (Insert is fine too) values of DD_Segment__c whenever KeywordAccountAssociation__c is updated. I could write trigger for this but I don't know how? I am new to Salesforce Development and my background is ruby (so getting accustomed to apex is bit difficult for me).
KeywordAccountAssociation__c has multiple rows of Account__c which has same account_id and those account_id are related to a record of custom object Keyword__c. I want to get all keywords related to one account and update in its (account's) multi-picklist. How can I achieve this? If you have doubts about this please do ask. Thanks!
One issue is related to learning to work with triggers in general, which can be started with Salesforce Apex Developer Documents on Triggers
but to answer your actual question, you would essentially need to build a trigger against your custom object that would update the related account. It might look something like this:
trigger keywordAccountUpdate on KeywordAccountAssociation__c (after insert, after update){
set<id> = new set<id>();
for (KeywordAccountAssociation__c a : Trigger.new)
accountIds.put(a.Account__c);
map<id,Account> accountMap = new map<id,Account>([select id, DD_Segment__c from Account where id in :accountIds]);
for (KeywordAccountAssociation__c kaa : Trigger.new){
if (AccountMap.containskey(kaa.Account__c)){
Account thisAccount = AccountMap.get(kaa.Account__c);
String s = thisAccount.DD_Segment__c + ';new value'; // Always add value
if ((thisAccount.DD_Segment__c).contains('second value')
s += ';second value';
AccountsToUpdate.add(new Account(id=thisAccount.id, DD_Segment__c = s));
}
}
}
Please keep in mind that I don't have the structure to test this trigger, I just free handded it, so YMMV.