 Hello everyone, I am Sanjay Gupta, I welcome you on Sanjay Gupta Tech School. In this video, I am going to demonstrate a scenario based on trigger. So the requirement is when an opportunity is updated to close lost and closed lost reason is not populated, then we need to throw a validation error saying please populate closed lost reason. So here closed lost is basically pick list value of stays field and closed lost reason will be a field. So we just need to check whether this field is available under opportunity object. If it is not available, then first we will be creating closed lost reason field and then we will be implementing trigger and trigger handler and later I will demo you how you can implement its test class so that code will be covered. So let's jump to developer edition or and here I'm jumping to object manager. And under object manager, I'm going to search for opportunity object. So under opportunity object under fields and relationships, I'm going to search for closed lost reason. So it is not available. So I'm going to create a new field and it will be of type text. So its label will be closed lost reason and length I'm specifying as 255. Then next visible to all the profiles, then again next and save. So this way the field is created. Now we will be able to use this field in the code. So I just need to implement this code on opportunity. So here you can see opportunity trigger is already open. So here I need to call a method that method I will be defining in the opportunity trigger handler. Right. So here I'm going to write the method so that that method can be called in the trigger. So public static void. So method name is populate closed lost reason. The first parameter will be list of opportunity. So it will be new list. So we are trying to update the record. So when we update the record, so there will be two states of that record. One is the new and one is the old. So new states will be available in the new list that we will be passing through trigger dot new from the trigger and old values we will be passing through trigger dot old map. So here's second parameter I'm using as map of ID comma opportunity and old map. Right. So I'm just saving this method so that I can call it in the trigger. I'm just going to copy this method name later on. So it will be called in update. So before updates, so I'm just copying this statement and I'm pasting it here. And now I'm going to copy the method name and I will be pasting it here. Right. So this statement I written here name method name is populate closed lost reason. And then I'm passing two parameters trigger dot new and trigger dot old map. So trigger dot new will be having the new values of that record. And the same record will be available in the old map as well having the old values of that particular record. So I'm just saving this trigger. Now here I just need to implement the code. So first of all, I'm going to iterate a loop on opportunity list so that one by one each opportunity will be processed. Now inside the loop I'm going to apply if condition. So I need to check the stage. So stage should be closed lost. Then I'm applying and so now I just need to check whether this stage is changed from any other value to closed lost or it is already closed lost. So for that I just need to check the new as well as old value of the stage field. So new value I can get through obp dot stage name then not equals to old value I can find from old map dot get then OPP dot ID. So this way I'm passing the key and then here I can just search for stage name. Right. So this way here you can see OPP dot stage name will be providing the new value of that record new stage value and through this old map dot get OPP dot ID. So get is the method which will receive a key and it will return the value and the value of this map is whole opportunity and through that whole opportunity, we just want the stage name field. That is why it is written like this. So the new stage value if it is not equals to old stage value, it means stage field is changed and we already checked whether a stage name is closed lost or not. And third thing we need to check whether closed lost reason is null or not. So closed lost reason underscore underscore C double equals to null. If all three things are matching, then it is validating like your stage is changed from any other to closed lost and your closed lost reason is null. So in this case what we can do, we just need to throw an error message. So I'm just writing OPP dot add error and here I can write the error message like please populate closed lost reason and I'm saving this code. So it is throwing an error and let's see what is the error. So it is saying variable does not exist. So why it is happening because we created the field in the object manager and this developer console was already open. It is not refreshed. So I'm just going to copy this code because it is not saved and I'm going to refresh this developer console. So it may happen our actual files get closed. So we just need to close all these files and I'm going to open opportunity trigger. So I'm going to open opportunity trigger, opportunity trigger handler and here I'm going to paste the method and now if I save the code, so it will be saved appropriately. No, it is showing error. Okay, the error is because I just didn't write OPP dot closed lost reason. Now it is saved, right? So this code is saved now correctly and now we can go to the UI and we can just try and test it. So if I open this report and here if I check the stage it is prospecting and here we have closed lost reason as well. So if I change this stage from prospecting to closed lost and I leave this closed lost reason blank and click on save. So here you can see the error message is available. Please populate closed lost reason, right? So this way, this code is working fine and it is validating the update as required. So now next step is to implement the test class for this. So I'm going to open opportunity trigger handler test class and here I will be implementing the method. So I'm going to copy existing method and I will be modifying that method. So don't worry, I will be explaining each and every step properly. So here I need to implement the test method. So I'm just going to copy the name of this method and I am appending test, right? So what is happening here? First of all, a list is created of OPP list. Then a loop is iterated, which is creating five opportunity records and it is filling name, closed date and stage, right? Stage is prospecting and all the records are added into OPP list. Then records will be inserted. So we can just insert the record outside here, right? Now, if you want to update the record, so what we can do, we can just iterate one loop and inside that loop we can update stage name from prospecting to closed lost, right? So basically I'm going to implement that loop inside try block because what will happen if closed lost reason is not filled? So whenever I will be updating the record, so it will throw an error, right? So let me just show you that error message as well. So I'm just cutting this code and here I'm going to implement the loop first. So opportunity OPP, then OPP list and here I'm going to update the stage to closed lost and I'm writing update OPP list, right? So I just updated the stage name. I didn't update, updated the closed lost region. So it will be throwing an error message. So I'm just running the test method. So I just run the whole test class. So you will see this particular method will fail. So here you can see test class is failing and which method is failing? Populate closed lost reason test. Why it is failing because a custom validation is available. So here it is showing amount field cannot be done. So let me just fill because this is because of any other implementation. So I'm just filling amount here and I'm going to run this test class again so that we see the another custom validation. So again it is failing. This time you can see different message available. It is showing please populate closed lost reason, right? So while we are updating stage, so it is throwing that error. Now to control this error because if this error is coming so your test class is not passing completely. So in case of custom validation if you want to implement the test method and you want to pass that test method. So what you need to do you need to implement your code in try block, right? So what I'm going to do I'm just pasting the code here, removing the try then cutting it here and pasting it inside try, right? So inside try this loop and update statement is available. Then if there is any exception any custom validation is thrown. So catch will be catching that and here you can see we have a variable exception thrown that is false. So it is set as true here. Now what we are going to do, okay this variable is actually not required. So I'm just removing it, okay? So we just require this variable which is checking whether message is containing the error message. So here I just need to provide this error message because in prior example I just used the custom label. So here instead of custom label I'm going to use that message, right? So if the error is containing this message so true will be returned otherwise false. So this is a conditional statement. Now this true false will be available in this variable and here in this assert equal we are checking whether this variable is containing true or false. So if it is containing true so your exception will be passed and test method will be passed, right? If it is containing false then it will be throwing an error message. So generally if you are changing it to close lost and your close loss vision is not populated. So this variable will be having true so this assert will pass and your test method will also get passed because we just know like it will be throwing a custom validation error and we just need to handle that error because this is the requirement of the problem, okay? So this way if you want to handle any custom validation exception issue in the test class so you can just implement try and catch plot. Now if I try to run this test method so it will pass. So you can see whole test class is passing and all the methods are passing. So populate close test, close lost vision test is also passing, right? So this way I demoed you like if you have implemented any custom validation with the help of trigger and you want to implement its test class so this way you can just implement. So I hope this way you understood like how we can apply custom validation while we are updating a particular record. Thank you.