You need to sign in to do that
Don't have an account?
Michael M
Trigger- keep current record the same, but insert new record with updates
Hi, We have a daily scheduled import (from a 3rd party app) of several records to a custom object. The import is set as an "upsert". I need to add a trigger that adds one more condition to decide whether to insert or update. Specifically, if a field called "discharge_date__c" is more than 5 days apart from the existing record, I want to INSERT the new record rather than UPDATING the previous one. The error I am receiving is " System.FinalException: Record is read-only". I need a way to bypass this error. Any suggestions are greatly appreciated.Here is my current Trigger and Class.:
TRIGGER:
trigger DischargeTrigger2 on Discharge__c (after update) {
if(system.isFuture()) return;
//insert new Discharge record..
for (Discharge__c dis : trigger.new){
if (dis.Discharge_Date__c != null && trigger.oldMap.get(dis.Id).Discharge_Date__c !=null){
date oldDd = trigger.oldMap.get(dis.Id).Discharge_Date__c;
date newDd = dis.Discharge_Date__c;
Integer difDate = oldDd.daysBetween(newDd);
Integer diffDate = newDd.daysBetween(oldDd);
if (difDate > 5 || diffDate > 5){
Discharge2Class.generateNewDischarge(dis.id);
}}
}
//If Discharge Date is more than 5 days apart from existing record, leave existing record alone and create new record, with instance counter and link to existing record
for (Discharge__c dis : trigger.new){
if (dis.Discharge_Date__c != null && trigger.oldMap.get(dis.Id).Discharge_Date__c !=null){
date oldDd = trigger.oldMap.get(dis.Id).Discharge_Date__c;
date newDd = dis.Discharge_Date__c;
Integer difDate = oldDd.daysBetween(newDd);
Integer diffDate = newDd.daysBetween(oldDd);
if (difDate > 5 || diffDate > 5){
//Prevent changing existing record
dis.Action_Code_ID__c = trigger.oldMap.get(dis.Id).Action_Code_ID__c;
dis.Address__c = trigger.oldMap.get(dis.Id).Address__c;
dis.City__c = trigger.oldMap.get(dis.Id).City__c;
dis.Date_of_Birth__c = trigger.oldMap.get(dis.Id).Date_of_Birth__c;
dis.Discharge_Date__c = trigger.oldMap.get(dis.Id).Discharge_Date__c;
dis.name = trigger.oldMap.get(dis.Id).name;
dis.State__c = trigger.oldMap.get(dis.Id).State__c;
dis.Status_Code_ID__c = trigger.oldMap.get(dis.Id).Status_Code_ID__c;
dis.Zip__c = trigger.oldMap.get(dis.Id).Zip__c;
dis.Progress_Notes__c = trigger.oldMap.get(dis.Id).Progress_Notes__c;
}
}
}
}
CLASS:
public class Discharge2Class {
@future(callout = true)
public static void generateNewDischarge(id i){
Discharge__c disch = [select id,Action_Code_ID__c,Address__c,City__c,Date_of_Birth__c,
Discharge_Date__c, State__c,Status_Code_ID__c,Zip__c,Progress_Notes__c
from Discharge__c where id =: i];
Discharge__c newDis = new Discharge__c();
newdis.Action_Code_ID__c = disch.Action_Code_ID__c;
newdis.Address__c = disch.Address__c;
newdis.City__c = disch.City__c;
newdis.Date_of_Birth__c = disch.Date_of_Birth__c;
newdis.Discharge_Date__c = disch.Discharge_Date__c;
newdis.Discharge_Location_Type__c =disch.Discharge_Location_Type__c;
newdis.Discharge_Location__c =disch.Discharge_Location__c ;
newdis.Facility_ID__c = disch.Facility_ID__c;
newdis.Facility_Name__c = disch.Facility_Name__c;
newdis.name = disch.name;
newdis.State__c = disch.State__c;
newdis.Status_Code_ID__c = disch.Status_Code_ID__c;
newdis.Zip__c = disch.Zip__c;
newdis.Progress_Notes__c = disch.Progress_Notes__c;
insert newDis;
}
}
TRIGGER:
trigger DischargeTrigger2 on Discharge__c (after update) {
if(system.isFuture()) return;
//insert new Discharge record..
for (Discharge__c dis : trigger.new){
if (dis.Discharge_Date__c != null && trigger.oldMap.get(dis.Id).Discharge_Date__c !=null){
date oldDd = trigger.oldMap.get(dis.Id).Discharge_Date__c;
date newDd = dis.Discharge_Date__c;
Integer difDate = oldDd.daysBetween(newDd);
Integer diffDate = newDd.daysBetween(oldDd);
if (difDate > 5 || diffDate > 5){
Discharge2Class.generateNewDischarge(dis.id);
}}
}
//If Discharge Date is more than 5 days apart from existing record, leave existing record alone and create new record, with instance counter and link to existing record
for (Discharge__c dis : trigger.new){
if (dis.Discharge_Date__c != null && trigger.oldMap.get(dis.Id).Discharge_Date__c !=null){
date oldDd = trigger.oldMap.get(dis.Id).Discharge_Date__c;
date newDd = dis.Discharge_Date__c;
Integer difDate = oldDd.daysBetween(newDd);
Integer diffDate = newDd.daysBetween(oldDd);
if (difDate > 5 || diffDate > 5){
//Prevent changing existing record
dis.Action_Code_ID__c = trigger.oldMap.get(dis.Id).Action_Code_ID__c;
dis.Address__c = trigger.oldMap.get(dis.Id).Address__c;
dis.City__c = trigger.oldMap.get(dis.Id).City__c;
dis.Date_of_Birth__c = trigger.oldMap.get(dis.Id).Date_of_Birth__c;
dis.Discharge_Date__c = trigger.oldMap.get(dis.Id).Discharge_Date__c;
dis.name = trigger.oldMap.get(dis.Id).name;
dis.State__c = trigger.oldMap.get(dis.Id).State__c;
dis.Status_Code_ID__c = trigger.oldMap.get(dis.Id).Status_Code_ID__c;
dis.Zip__c = trigger.oldMap.get(dis.Id).Zip__c;
dis.Progress_Notes__c = trigger.oldMap.get(dis.Id).Progress_Notes__c;
}
}
}
}
CLASS:
public class Discharge2Class {
@future(callout = true)
public static void generateNewDischarge(id i){
Discharge__c disch = [select id,Action_Code_ID__c,Address__c,City__c,Date_of_Birth__c,
Discharge_Date__c, State__c,Status_Code_ID__c,Zip__c,Progress_Notes__c
from Discharge__c where id =: i];
Discharge__c newDis = new Discharge__c();
newdis.Action_Code_ID__c = disch.Action_Code_ID__c;
newdis.Address__c = disch.Address__c;
newdis.City__c = disch.City__c;
newdis.Date_of_Birth__c = disch.Date_of_Birth__c;
newdis.Discharge_Date__c = disch.Discharge_Date__c;
newdis.Discharge_Location_Type__c =disch.Discharge_Location_Type__c;
newdis.Discharge_Location__c =disch.Discharge_Location__c ;
newdis.Facility_ID__c = disch.Facility_ID__c;
newdis.Facility_Name__c = disch.Facility_Name__c;
newdis.name = disch.name;
newdis.State__c = disch.State__c;
newdis.Status_Code_ID__c = disch.Status_Code_ID__c;
newdis.Zip__c = disch.Zip__c;
newdis.Progress_Notes__c = disch.Progress_Notes__c;
insert newDis;
}
}
Trigger:
-------------------
trigger DischargeTrigger on Discharge__c (before update) {
// After event
if(Trigger.isBefore) {
if(Trigger.isUpdate) {
DischargeHandler.onAfterSave(Trigger.New, Trigger.oldMap);
}
}
}
Apex class:
----------------------
public with sharing class DischargeHandler {
// Trigger handler Method to call from the Trigger
public static void onAfterSave(List<Discharge__c> dischargeList, Map<Id, Discharge__c> oldDischargeMap) {
System.debug('Discharge List : ' + dischargeList.size());
List<Discharge__c> newDischargeList = new List<Discharge__c>(); // List to perform the DML operation
Integer dateDiff;
// Loop to Iterate over the records that were updated
for(Discharge__c discharge : dischargeList) {
dateDiff = oldDischargeMap.get(discharge.Id).Discharge_Date__c.daysBetween(discharge.Discharge_Date__c); // To calculate the days
System.debug('Date difference : ' +dateDiff);
// Condition to check for the days count
if( dateDiff > 5 ) {
Discharge__c newDischarge = new Discharge__c();
// Assign all the field over here
newDischarge.Address__c = discharge.Address__c;
newDischarge.City__c = discharge.City__c;
newDischarge.Date_of_Birth__c = discharge.Date_of_Birth__c;
newDischarge.Discharge_Date__c = discharge.Discharge_Date__c; // It will put the updated value here
newDischarge.Discharge_Location_Type__c = discharge.Discharge_Location_Type__c;
newDischarge.Discharge_Location__c = discharge.Discharge_Location__c ;
newDischarge.Facility_ID__c = discharge.Facility_ID__c;
newDischarge.Facility_Name__c = discharge.Facility_Name__c;
newDischarge.name = discharge.name;
newDischarge.State__c = discharge.State__c;
newDischarge.Status_Code_ID__c = discharge.Status_Code_ID__c;
newDischarge.Zip__c = discharge.Zip__c;
newDischarge.Progress_Notes__c = discharge.Progress_Notes__c;
newDischarge.Medicaid_ID__c = discharge.Medicaid_ID__c;
newDischarge.Medicare_ID__c = discharge.Medicare_ID__c;
newDischarge.Other_Diagnosis_ICD_Codes__c = discharge.Other_Diagnosis_ICD_Codes__c;
newDischarge.Other_Diagnosis_ICD_Descriptions__c = discharge.Other_Diagnosis_ICD_Descriptions__c;
newDischarge.Patient_ID_PCC__c = discharge.Patient_ID_PCC__c;
newDischarge.Primary_Diagnosis_ICD_Code__c = discharge.Primary_Diagnosis_ICD_Code__c;
newDischarge.Primary_Diagnosis_ICD_Description__c = discharge.Primary_Diagnosis_ICD_Description__c;
}//IF ENDS
}// FOR ENDS
// Loop to iterate over the List of updating records
for(Discharge__c discharge : dischargeList) {
dateDiff = oldDischargeMap.get(discharge.Id).Discharge_Date__c.daysBetween(discharge.Discharge_Date__c); // To calculate the days
System.debug('Date difference : ' +dateDiff);
// Condition to check for the days count
if( dateDiff > 5 ) {
// Assigning the values from Insert scenario
discharge.Address__c = oldDischargeMap.get(discharge.Id).Address__c;
discharge.City__c = oldDischargeMap.get(discharge.Id).City__c;
discharge.Date_of_Birth__c = oldDischargeMap.get(discharge.Id).Date_of_Birth__c;
discharge.Discharge_Date__c = oldDischargeMap.get(discharge.Id).Discharge_Date__c;
discharge.Discharge_Location_Type__c = oldDischargeMap.get(discharge.Id).Discharge_Location_Type__c;
discharge.Discharge_Location__c = oldDischargeMap.get(discharge.Id).Discharge_Location__c ;
discharge.Facility_ID__c = oldDischargeMap.get(discharge.Id).Facility_ID__c;
discharge.Facility_Name__c = oldDischargeMap.get(discharge.Id).Facility_Name__c;
discharge.name = oldDischargeMap.get(discharge.Id).name;
discharge.State__c = oldDischargeMap.get(discharge.Id).State__c;
discharge.Status_Code_ID__c = oldDischargeMap.get(discharge.Id).Status_Code_ID__c;
discharge.Zip__c = oldDischargeMap.get(discharge.Id).Zip__c;
discharge.Progress_Notes__c = oldDischargeMap.get(discharge.Id).Progress_Notes__c;
discharge.Medicaid_ID__c = oldDischargeMap.get(discharge.Id).Medicaid_ID__c;
discharge.Medicare_ID__c = oldDischargeMap.get(discharge.Id).Medicare_ID__c;
discharge.Other_Diagnosis_ICD_Codes__c = oldDischargeMap.get(discharge.Id).Other_Diagnosis_ICD_Codes__c;
discharge.Other_Diagnosis_ICD_Descriptions__c = oldDischargeMap.get(discharge.Id).Other_Diagnosis_ICD_Descriptions__c;
discharge.Patient_ID_PCC__c = oldDischargeMap.get(discharge.Id).Patient_ID_PCC__c;
discharge.Primary_Diagnosis_ICD_Code__c = oldDischargeMap.get(discharge.Id).Primary_Diagnosis_ICD_Code__c;
discharge.Primary_Diagnosis_ICD_Description__c = oldDischargeMap.get(discharge.Id).Primary_Diagnosis_ICD_Description__c;
}
}
try {
// check to see if the list is empty before performing the DML operation
if(!newDischargeList.isEmpty()) {
insert newDischargeList;
}
}catch(DMLException e) {
System.debug('Unable to insert the Account record : ' + e.getMessage());
}
}
}
This is working for me.
What it will do.
Create a new record
Name = Prakash
Discharge Date = today
Save the record
Update the same record and change the discharge from today to today + 5
then
Update record will save with
Name = Prakash
Discharge Date = today
Create a new record
Name = Prakash
Discharge Date = today + 5
This is the test performed. If this is the same case then you can use the above code.
Thanks,
All Answers
The issue is due to the SOQL that you wrote on the object after update the record will be locked for 10 sec. If you try to access that record then the system will throw you that error message. with trigger.New you will get the all the data that related to that record and in your code your are not pulling child record data so you don't need a query.
Trigger:
------------------
trigger DischargeTrigger2 on Discharge__c (after update) {
if(Trigger.isAfter){
if(Trigger.isUpdate){
Discharge2Class.generateNewDischarge(Trigger.New);
}
}
}
Apex class:
------------------------
public class Discharge2Class {
@future(callout = true)
public static void generateNewDischarge(List<Discharge__c> dischargeList){
List<Discharge__c> newDischargeList = new List<Discharge__c>();
for(Discharge__c dis : dischargeList) {
if (dis.Discharge_Date__c > dis.Discharge_Date__c+5 ){
Discharge__c newDis = new Discharge__c();
newdis.Action_Code_ID__c = dis.Action_Code_ID__c;
newdis.Address__c = dis.Address__c;
newdis.City__c = dis.City__c;
newdis.Date_of_Birth__c = dis.Date_of_Birth__c;
newdis.Discharge_Date__c = dis.Discharge_Date__c;
newdis.Discharge_Location_Type__c =dis.Discharge_Location_Type__c;
newdis.Discharge_Location__c =dis.Discharge_Location__c ;
newdis.Facility_ID__c = dis.Facility_ID__c;
newdis.Facility_Name__c = dis.Facility_Name__c;
newdis.name = dis.name;
newdis.State__c = disch.State__c;
newdis.Status_Code_ID__c = dis.Status_Code_ID__c;
newdis.Zip__c = dis.Zip__c;
newdis.Progress_Notes__c = dis.Progress_Notes__c;
newDischargeList.add(newdis);
}
}
try{
if(!newDischargeList.isEmpty()) {
insert newDischargeList;
}
}catch(DMLException e) {
System.debug('Unable to Insert the Discharge Records : '+e.getMessage());
}
}
}
In this way you can do your logic.
A couple points:
1. With that code, it is giving me this error: "Future methods do not support parameter type of List<Discharge__c>".
2. Will this keep the original Discharge record the same? I want the original record to stay the same, and I just want the updates to be applied to the newly created/inserted record?
Thank you so much for your help.
In the handler change the values that you need. check the mapping I used in the code and you can easily correct it. we are using on after update so it won't update the old record.
For testing:
Edit the existing record and change the discharge date and save it so it should create the new one.
To stop duplicates you can do like this
Trigger:
-------------
trigger DischargeTrigger2 on Discharge__c (after update) {
if(Trigger.isAfter){
if(Trigger.isUpdate){
Discharge2Class.generateNewDischarge(Trigger.New, Trigger.oldMap);
}
}
}
Apex class:
---------------------
public class Discharge2Class {
public static void generateNewDischarge(List<Discharge__c> dischargeList, Map<Id, Discharge__c> oldMap){
List<Discharge__c> newDischargeList = new List<Discharge__c>();
for(Discharge__c dis : dischargeList) {
if (dis.Discharge_Date__c > dis.Discharge_Date__c+5 && oldMap.get(dis.Id).Discharge_Date__c != dis.Discharge_Date__c){ // Changed line
Discharge__c newDis = new Discharge__c();
newdis.Action_Code_ID__c = dis.Action_Code_ID__c;
newdis.Address__c = dis.Address__c;
newdis.City__c = dis.City__c;
newdis.Date_of_Birth__c = dis.Date_of_Birth__c;
newdis.Discharge_Date__c = dis.Discharge_Date__c; // you need to correct the right hand side to get the new values.
newdis.Discharge_Location_Type__c =dis.Discharge_Location_Type__c;
newdis.Discharge_Location__c =dis.Discharge_Location__c ;
newdis.Facility_ID__c = dis.Facility_ID__c;
newdis.Facility_Name__c = dis.Facility_Name__c;
newdis.name = dis.name;
newdis.State__c = disch.State__c;
newdis.Status_Code_ID__c = dis.Status_Code_ID__c;
newdis.Zip__c = dis.Zip__c;
newdis.Progress_Notes__c = dis.Progress_Notes__c;
newDischargeList.add(newdis);
}
}
try{
if(!newDischargeList.isEmpty()) {
insert newDischargeList;
}
}catch(DMLException e) {
System.debug('Unable to Insert the Discharge Records : '+e.getMessage());
}
}
}
By this example, you can work out on your logic. Hope this helps you to build your logic.
Here is the exact code I'm using:
TRIGGER:
trigger DischargeTrigger2 on Discharge__c (after update) {
if(system.isFuture()) return;
if(Trigger.isAfter){
if(Trigger.isUpdate){
for (Discharge__c dis : trigger.new){
if (dis.Discharge_Date__c != null && trigger.oldMap.get(dis.Id).Discharge_Date__c !=null){
date oldDd = trigger.oldMap.get(dis.Id).Discharge_Date__c;
date newDd = dis.Discharge_Date__c;
Integer difDate = oldDd.daysBetween(newDd);
Integer diffDate = newDd.daysBetween(oldDd);
if (difDate > 5 || diffDate > 5){
Discharge2Class.generateNewDischarge(Trigger.New, Trigger.oldMap);
}
}}}}
CLASS:
public class Discharge2Class {
public static void generateNewDischarge(List<Discharge__c> dischargeList, Map<Id, Discharge__c> oldMap){
List<Discharge__c> newDischargeList = new List<Discharge__c>();
for(Discharge__c dis : dischargeList) {
Discharge__c newDis = new Discharge__c();
newdis.Action_Code_ID__c = dis.Action_Code_ID__c;
newdis.Address__c = dis.Address__c;
newdis.City__c = dis.City__c;
newdis.Date_of_Birth__c = dis.Date_of_Birth__c;
newdis.Discharge_Date__c = dis.Discharge_Date__c; // you need to correct the right hand side to get the new values.
newdis.Discharge_Location_Type__c =dis.Discharge_Location_Type__c;
newdis.Discharge_Location__c =dis.Discharge_Location__c ;
newdis.Facility_ID__c = dis.Facility_ID__c;
newdis.Facility_Name__c = dis.Facility_Name__c;
newdis.name = dis.name;
newdis.State__c = dis.State__c;
newdis.Status_Code_ID__c = dis.Status_Code_ID__c;
newdis.Zip__c = dis.Zip__c;
newdis.Progress_Notes__c = dis.Progress_Notes__c;
newdis.Medicaid_ID__c = dis.Medicaid_ID__c;
newdis.Medicare_ID__c = dis.Medicare_ID__c;
newdis.Other_Diagnosis_ICD_Codes__c =dis.Other_Diagnosis_ICD_Codes__c;
newdis.Other_Diagnosis_ICD_Descriptions__c = dis.Other_Diagnosis_ICD_Descriptions__c;
newdis.Patient_ID_PCC__c = dis.Patient_ID_PCC__c;
newdis.Primary_Diagnosis_ICD_Code__c =dis.Primary_Diagnosis_ICD_Code__c;
newdis.Primary_Diagnosis_ICD_Description__c =dis.Primary_Diagnosis_ICD_Description__c;
newDischargeList.add(newdis);
}
try{
if(!newDischargeList.isEmpty()) {
insert newDischargeList;
}
}catch(DMLException e) {
System.debug('Unable to Insert the Discharge Records : '+e.getMessage());
}
}
}
1. do NOT apply the updates being made to the current record. Instead, keep the OLD values of the current record.
2. Create a new record with the updates that were trying to be made to the original record.
2. print the list that you are inserting check how many records are there and check for the created by for those 2 records if there are any other active triggers related to this please stop for this testing.
If that is the case merger your code to that trigger. You don't need duplicate logic.
trigger DischargeTrigger2 on Discharge__c (after update) {
if(system.isFuture()) return;
//insert new Discharge record..
if(Trigger.isAfter){
if(Trigger.isUpdate){
for (Discharge__c dis : trigger.new){
if (dis.Discharge_Date__c != null && trigger.oldMap.get(dis.Id).Discharge_Date__c !=null){
date oldDd = trigger.oldMap.get(dis.Id).Discharge_Date__c;
date newDd = dis.Discharge_Date__c;
Integer difDate = oldDd.daysBetween(newDd);
Integer diffDate = newDd.daysBetween(oldDd);
if (difDate > 5 || diffDate > 5){
Discharge2Class.generateNewDischarge(Trigger.New, Trigger.oldMap);
}
}}}}
//If Discharge Date is more than 5 days apart from existing record, leave existing record alone and create new record, with instance counter and link to existing record
for (Discharge__c dis : trigger.new){
if (dis.Discharge_Date__c != null && trigger.oldMap.get(dis.Id).Discharge_Date__c !=null){
date oldDd = trigger.oldMap.get(dis.Id).Discharge_Date__c;
date newDd = dis.Discharge_Date__c;
Integer difDate = oldDd.daysBetween(newDd);
Integer diffDate = newDd.daysBetween(oldDd);
if (difDate > 5 || diffDate > 5){
//Prevent changing existing record
dis.Action_Code_ID__c = trigger.oldMap.get(dis.Id).Action_Code_ID__c;
dis.Address__c = trigger.oldMap.get(dis.Id).Address__c;
dis.City__c = trigger.oldMap.get(dis.Id).City__c;
dis.Date_of_Birth__c = trigger.oldMap.get(dis.Id).Date_of_Birth__c;
dis.Discharge_Date__c = trigger.oldMap.get(dis.Id).Discharge_Date__c;
dis.Discharge_Location_Type__c = trigger.oldMap.get(dis.Id).Discharge_Location_Type__c;
dis.Discharge_Location__c = trigger.oldMap.get(dis.Id).Discharge_Location__c;
dis.Facility_ID__c = trigger.oldMap.get(dis.Id).Facility_ID__c;
dis.Facility_Name__c = trigger.oldMap.get(dis.Id).Facility_Name__c;
//dis.First_Name__c = trigger.oldMap.get(dis.Id).First_Name__c;
//dis.Last_Name__c = trigger.oldMap.get(dis.Id).Last_Name__c;
//dis.name = trigger.oldMap.get(dis.Id).name;
dis.Medicaid_ID__c = trigger.oldMap.get(dis.Id).Medicaid_ID__c;
dis.Medicare_ID__c = trigger.oldMap.get(dis.Id).Medicare_ID__c;
dis.Other_Diagnosis_ICD_Codes__c = trigger.oldMap.get(dis.Id).Other_Diagnosis_ICD_Codes__c;
dis.Other_Diagnosis_ICD_Descriptions__c = trigger.oldMap.get(dis.Id).Other_Diagnosis_ICD_Descriptions__c;
dis.Patient_ID_PCC__c = trigger.oldMap.get(dis.Id).Patient_ID_PCC__c;
dis.Primary_Diagnosis_ICD_Code__c = trigger.oldMap.get(dis.Id).Primary_Diagnosis_ICD_Code__c;
dis.Primary_Diagnosis_ICD_Description__c = trigger.oldMap.get(dis.Id).Primary_Diagnosis_ICD_Description__c;
dis.Primary_Phone_PCC__c = trigger.oldMap.get(dis.Id).Primary_Phone_PCC__c;
dis.SSN__c = trigger.oldMap.get(dis.Id).SSN__c;
dis.State__c = trigger.oldMap.get(dis.Id).State__c;
dis.Status_Code_ID__c = trigger.oldMap.get(dis.Id).Status_Code_ID__c;
dis.Zip__c = trigger.oldMap.get(dis.Id).Zip__c;
dis.Progress_Notes__c = trigger.oldMap.get(dis.Id).Progress_Notes__c;
}
}
}
}
What am I doing wrong?
2. there are no other triggers on this object that insert new records.
I used my environment to create the same as and worked on this and it is working for me without updating the old record and it is creating the new record.
It should work for you as well. If I added the debugs as well.
Trigger:
------------------
trigger DischargeTrigger on Discharge__c (after update) {
// After event
if(Trigger.isAfter) {
if(Trigger.isUpdate) {
DischargeHandler.onAfterSave(Trigger.New, Trigger.oldMap);
}
}
}
Handler:
------------------------
/*
* Author: Prakash
* Created Date : Feb 13, 2020
* Based on Days count the system will insert the new record from old record but it should not update the old record.
*/
public with sharing class DischargeHandler {
// Trigger handler Method to call from the Trigger
public static void onAfterSave(List<Discharge__c> dischargeList, Map<Id, Discharge__c> oldDischargeMap) {
System.debug('Discharge List : ' + dischargeList.size());
List<Discharge__c> newDischargeList = new List<Discharge__c>(); // List to perform the DML operation
// Loop to Iterate over the records that were updated
for(Discharge__c discharge : dischargeList) {
Integer dateDiff = oldDischargeMap.get(discharge.Id).Discharge_Date__c.daysBetween(discharge.Discharge_Date__c); // To calculate the days
System.debug('Date difference : ' +dateDiff);
// Condition to check for the days count
if( dateDiff > 5 ) {
Discharge__c newDischarge = new Discharge__c();
// Assign all the field over here
newDischarge.Address__c = discharge.Address__c;
newDischarge.City__c = discharge.City__c;
newDischarge.Date_of_Birth__c = discharge.Date_of_Birth__c;
newDischarge.Discharge_Date__c = discharge.Discharge_Date__c; // It will put the updated value here
newDischarge.Discharge_Location_Type__c = discharge.Discharge_Location_Type__c;
newDischarge.Discharge_Location__c = discharge.Discharge_Location__c ;
newDischarge.Facility_ID__c = discharge.Facility_ID__c;
newDischarge.Facility_Name__c = discharge.Facility_Name__c;
newDischarge.name = discharge.name;
newDischarge.State__c = discharge.State__c;
newDischarge.Status_Code_ID__c = discharge.Status_Code_ID__c;
newDischarge.Zip__c = discharge.Zip__c;
newDischarge.Progress_Notes__c = discharge.Progress_Notes__c;
newDischarge.Medicaid_ID__c = discharge.Medicaid_ID__c;
newDischarge.Medicare_ID__c = discharge.Medicare_ID__c;
newDischarge.Other_Diagnosis_ICD_Codes__c = discharge.Other_Diagnosis_ICD_Codes__c;
newDischarge.Other_Diagnosis_ICD_Descriptions__c = discharge.Other_Diagnosis_ICD_Descriptions__c;
newDischarge.Patient_ID_PCC__c = discharge.Patient_ID_PCC__c;
newDischarge.Primary_Diagnosis_ICD_Code__c = discharge.Primary_Diagnosis_ICD_Code__c;
newDischarge.Primary_Diagnosis_ICD_Description__c = discharge.Primary_Diagnosis_ICD_Description__c;
newDischargeList.add(newDischarge); // Preparing the list for DML operation
}//IF ENDS
}// FOR ENDS
try {
// check to see if the list is empty before performing the DML operation
if(!newDischargeList.isEmpty()) {
insert newDischargeList;
}
}catch(DMLException e) {
System.debug('Unable to insert the Account record : ' + e.getMessage());
}
}
}
I believe this time you will be all set.
1. Append your name to the last name in the code and save it.
2. Please enable the debug logs for you in the environment that you are testing.
3. Create a new record with the discharge date manually and edit that record and change the discharge date to discharge date + 5 days.
4. Now go and verify the 2 records that were creating. It would
5. Go to the debug logs to open the apex log that created for this transaction and copy the statements from system.debug and do a search. The statement should appear only one time. If it is occurring more than once then you need to do a search in (developer console --> edit --> search in all files --> past the object api name) object if there are any DML statements. that will help you to understand more.
Hope this helps.
I added a Trigger Handler class to prevent it from creating 2 new records, and this seems to be working.
Here is what it looks like:
CLASS:
public class RecursiveTriggerHandler{
public static Boolean isFirstTime = true;
}
TRIGGER:
trigger DischargeTrigger2 on Discharge__c (after update) {
if(RecursiveTriggerHandler.isFirstTime){
RecursiveTriggerHandler.isFirstTime = false;
// After event
if(Trigger.isAfter) {
if(Trigger.isUpdate) {
DischargeHandler.onAfterSave(Trigger.New, Trigger.oldMap);
}
}
}
}
However, the other problem is still there. I am creating a new record manually, with e.g. Name= 'Old', DischargeDate = 2/1/2020. I save it. Then I change the name to 'New' and the DischargeDate to 2/15/20. The record saves and updates, and a new record is created with the same information. I need to prevent the record from updating itself. I don't see where in the code this is being prevented... all the code is doing is inserting the new record with the same information. But the trigger is "After update" so by definition the updates are already taking effect in the old record... Right? What am I missing here- where is the code telling it not to accept the updates for the original ('Old') record?
I still don't see where in the code we are telling it not to update the old record.
Trigger:
-------------------
trigger DischargeTrigger on Discharge__c (before update) {
// After event
if(Trigger.isBefore) {
if(Trigger.isUpdate) {
DischargeHandler.onAfterSave(Trigger.New, Trigger.oldMap);
}
}
}
Apex class:
----------------------
public with sharing class DischargeHandler {
// Trigger handler Method to call from the Trigger
public static void onAfterSave(List<Discharge__c> dischargeList, Map<Id, Discharge__c> oldDischargeMap) {
System.debug('Discharge List : ' + dischargeList.size());
List<Discharge__c> newDischargeList = new List<Discharge__c>(); // List to perform the DML operation
Integer dateDiff;
// Loop to Iterate over the records that were updated
for(Discharge__c discharge : dischargeList) {
dateDiff = oldDischargeMap.get(discharge.Id).Discharge_Date__c.daysBetween(discharge.Discharge_Date__c); // To calculate the days
System.debug('Date difference : ' +dateDiff);
// Condition to check for the days count
if( dateDiff > 5 ) {
Discharge__c newDischarge = new Discharge__c();
// Assign all the field over here
newDischarge.Address__c = discharge.Address__c;
newDischarge.City__c = discharge.City__c;
newDischarge.Date_of_Birth__c = discharge.Date_of_Birth__c;
newDischarge.Discharge_Date__c = discharge.Discharge_Date__c; // It will put the updated value here
newDischarge.Discharge_Location_Type__c = discharge.Discharge_Location_Type__c;
newDischarge.Discharge_Location__c = discharge.Discharge_Location__c ;
newDischarge.Facility_ID__c = discharge.Facility_ID__c;
newDischarge.Facility_Name__c = discharge.Facility_Name__c;
newDischarge.name = discharge.name;
newDischarge.State__c = discharge.State__c;
newDischarge.Status_Code_ID__c = discharge.Status_Code_ID__c;
newDischarge.Zip__c = discharge.Zip__c;
newDischarge.Progress_Notes__c = discharge.Progress_Notes__c;
newDischarge.Medicaid_ID__c = discharge.Medicaid_ID__c;
newDischarge.Medicare_ID__c = discharge.Medicare_ID__c;
newDischarge.Other_Diagnosis_ICD_Codes__c = discharge.Other_Diagnosis_ICD_Codes__c;
newDischarge.Other_Diagnosis_ICD_Descriptions__c = discharge.Other_Diagnosis_ICD_Descriptions__c;
newDischarge.Patient_ID_PCC__c = discharge.Patient_ID_PCC__c;
newDischarge.Primary_Diagnosis_ICD_Code__c = discharge.Primary_Diagnosis_ICD_Code__c;
newDischarge.Primary_Diagnosis_ICD_Description__c = discharge.Primary_Diagnosis_ICD_Description__c;
}//IF ENDS
}// FOR ENDS
// Loop to iterate over the List of updating records
for(Discharge__c discharge : dischargeList) {
dateDiff = oldDischargeMap.get(discharge.Id).Discharge_Date__c.daysBetween(discharge.Discharge_Date__c); // To calculate the days
System.debug('Date difference : ' +dateDiff);
// Condition to check for the days count
if( dateDiff > 5 ) {
// Assigning the values from Insert scenario
discharge.Address__c = oldDischargeMap.get(discharge.Id).Address__c;
discharge.City__c = oldDischargeMap.get(discharge.Id).City__c;
discharge.Date_of_Birth__c = oldDischargeMap.get(discharge.Id).Date_of_Birth__c;
discharge.Discharge_Date__c = oldDischargeMap.get(discharge.Id).Discharge_Date__c;
discharge.Discharge_Location_Type__c = oldDischargeMap.get(discharge.Id).Discharge_Location_Type__c;
discharge.Discharge_Location__c = oldDischargeMap.get(discharge.Id).Discharge_Location__c ;
discharge.Facility_ID__c = oldDischargeMap.get(discharge.Id).Facility_ID__c;
discharge.Facility_Name__c = oldDischargeMap.get(discharge.Id).Facility_Name__c;
discharge.name = oldDischargeMap.get(discharge.Id).name;
discharge.State__c = oldDischargeMap.get(discharge.Id).State__c;
discharge.Status_Code_ID__c = oldDischargeMap.get(discharge.Id).Status_Code_ID__c;
discharge.Zip__c = oldDischargeMap.get(discharge.Id).Zip__c;
discharge.Progress_Notes__c = oldDischargeMap.get(discharge.Id).Progress_Notes__c;
discharge.Medicaid_ID__c = oldDischargeMap.get(discharge.Id).Medicaid_ID__c;
discharge.Medicare_ID__c = oldDischargeMap.get(discharge.Id).Medicare_ID__c;
discharge.Other_Diagnosis_ICD_Codes__c = oldDischargeMap.get(discharge.Id).Other_Diagnosis_ICD_Codes__c;
discharge.Other_Diagnosis_ICD_Descriptions__c = oldDischargeMap.get(discharge.Id).Other_Diagnosis_ICD_Descriptions__c;
discharge.Patient_ID_PCC__c = oldDischargeMap.get(discharge.Id).Patient_ID_PCC__c;
discharge.Primary_Diagnosis_ICD_Code__c = oldDischargeMap.get(discharge.Id).Primary_Diagnosis_ICD_Code__c;
discharge.Primary_Diagnosis_ICD_Description__c = oldDischargeMap.get(discharge.Id).Primary_Diagnosis_ICD_Description__c;
}
}
try {
// check to see if the list is empty before performing the DML operation
if(!newDischargeList.isEmpty()) {
insert newDischargeList;
}
}catch(DMLException e) {
System.debug('Unable to insert the Account record : ' + e.getMessage());
}
}
}
This is working for me.
What it will do.
Create a new record
Name = Prakash
Discharge Date = today
Save the record
Update the same record and change the discharge from today to today + 5
then
Update record will save with
Name = Prakash
Discharge Date = today
Create a new record
Name = Prakash
Discharge Date = today + 5
This is the test performed. If this is the same case then you can use the above code.
Thanks,
"System.DmlException: Update failed. First exception on row 0 with id a0N2g000000JrnyEAC; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, DischargeTrigger2: execution of AfterUpdate caused by: System.FinalException: Record is read-only Class.DischargeHandler.onAfterSave: line 53, column 1 Trigger.DischargeTrigger2: line 7, column 1: []"
Line 7 column1 on the trigger is: DischargeHandler.onAfterSave(Trigger.New, Trigger.oldMap);
Line 53 column 1 on the class is: discharge.Address__c = oldDischargeMap.get(discharge.Id).Address__c;
Name = Prakash
Discharge Date = today
Save the record
Update the same record and change the discharge from today to today + 5
then
Update record will save with
Name = Prakash
Discharge Date = today
Create a new record
Name = Prakash
Discharge Date = today + 5
Do this step and check for the results it is working for me.
Sorry about the back and forth.
1. Did the code save perfectly? without any issues?
2. The trigger event is "Before update", if condition should be Trigger.isBefore and second if condition should be Trigger.isUpdate?
3. The calling method from the trigger is equal to the called method in the Handler that is onAfterSave?
4. Are you sure that you are creating and updating the record in way I mentioned? (In my example I said today +5 meaning please do not test with exactly 5 days from now please add days more than 5 that what you are expecting).
5. Enable the debug log for you. Create a record and update the record as I mentioned above. open the debug log and do ctrl+f and paste the below lines by removing the double quotes
"Discharge List: " Result should be 1
"Date difference: "Result should be 6 or above
it should not equal to 5 because you are strictly checking for more than 5 days.
6. Let me know if the above 5 are good.
1. Yes, it saved just as it would normally without any trigger.
2. No - I forgot this step, my apologies. I did this and it works! Thank you so much for all your patience. I will mark as best answer.
Thank you so much for your patience. Much appreciated.
Have a great rest of your day.
We also have a "before insert" trigger on Discharge object, and we need that if a user inserts a new Record where that name already exists, we want to run the whole before discharge operation discussed above. I wrote this trigger:
trigger DischargeTrigger on Discharge__c (before insert) {
Set<String> newNameSet = new Set<String>();
for (Discharge__c disch : trigger.new){
if (disch.Name != null && disch.Other_Diagnosis_ICD_Descriptions__c !=null ){
newNameSet.add(disch.name);
}
Discharge__c oldDis = [SELECT Id, name, Discharge_Date__c FROM Discharge__c WHERE name =:newNameSet];
Integer dateDiff;
Integer datedif;
dateDiff = disch.Discharge_Date__c.daysBetween(oldDis.Discharge_Date__c); // To calculate the days
dateDif = oldDis.Discharge_Date__c.daysBetween(disch.Discharge_Date__c);
if( dateDiff > 5 || dateDif > 5) {
oldDis.Discharge_Date__c = disch.Discharge_Date__c;
update oldDis;
}
}
}
I am adding a new record with a name which already exists, but yet am getting this error: "System.QueryException: List has no rows for assignment to SObject". What should I do about it?
Should I open up a new case?
trigger DischargeTrigger3 on Discharge__c (after insert) {
Set<String> newNameSet = new Set<String>();
if (trigger.isafter){
for (Discharge__c disch : trigger.new){
if (disch.Name != null ){
newNameSet.add(disch.name);
}
Discharge__c oldDis = [SELECT Id, name, Discharge_Date__c FROM Discharge__c WHERE name =:newNameSet order by createddate desc limit 1];
Integer dateDiff;
Integer datedif;
dateDiff = disch.Discharge_Date__c.daysBetween(oldDis.Discharge_Date__c); // To calculate the days
dateDif = oldDis.Discharge_Date__c.daysBetween(disch.Discharge_Date__c);
if( dateDiff > 5 || dateDif > 5) {
oldDis.Discharge_Date__c = disch.Discharge_Date__c;
update oldDis;
delete disch;
}
}
}
}
However, when I add a new record with the same name as the old one, the new record is not getting deleted and nothing really is happening.
Set<String> newNameSet = new Set<String>();
Set<DateTime> createDateSet = new Set<DateTime>();
if (trigger.isafter){
if(Trigger.isInsert) {
for (Discharge__c disch : trigger.new){
if (disch.Name != null ){
newNameSet.add(disch.name);
createDateSet.add(disch.CreatedDate);
}
Discharge__c oldDis = [SELECT Id, name, Discharge_Date__c
FROM Discharge__c
WHERE name =:newNameSet AND
CreatedDate != :createDateSet
order by createddate desc limit 1];
Integer dateDiff;
Integer datedif;
dateDiff = disch.Discharge_Date__c.daysBetween(oldDis.Discharge_Date__c); // To calculate the days
datedif = oldDis.Discharge_Date__c.daysBetween(disch.Discharge_Date__c);
if( dateDiff > 5 || datedif > 5) {
oldDis.Discharge_Date__c = disch.Discharge_Date__c;
update oldDis;
//delete disch;
}
}
}
if(trigger.isUpdate) {
Set<String> newNameSet = new Set<String>();
for(Discharge__c discharege : Trigger.New) {
if (discharege.Name != null ){
newNameSet.add(discharege.name);
}
Discharge__c oldDis = [SELECT Id, name, Discharge_Date__c
FROM Discharge__c
WHERE name =:newNameSet
order by createddate desc limit 1];
delete oldDis;
}
}
}
}
1. The reason for not working because you have a filter saying created date desc and that will bring the same record so the data difference is 0. So I added one more set to take the created date and changed the query as well in the where clause so it will update the old record.
2. for delete you can not delete the records on after insert because they fall under trigger.new so salesforce limitation on trigger.new and trigger.old variables. so I used on after update logically here a new record is the old one that we are updating so we can delete the new one.
Try it and let me know if it is working for you. It is working for me.
DischargeTrigger3: execution of AfterInsert caused by: System.DmlException: Update failed. First exception on row 0 with id a0N2g000000JrkwEAC; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, DischargeTrigger2: execution of BeforeUpdate caused by: System.NullPointerException: Attempt to de-reference a null object Class.DischargeHandler.onBeforeUpdate: line 46, column 1 Trigger.DischargeTrigger2: line 7, column 1: [] Trigger.DischargeTrigger3: line 27, column 1
New Logic. If a user creates a new record you are again updating the old one and deleting the new one.
If this needs to work with code.
you need to create a new field with Import action.
Create, Update as values if it hard to give it to the third party then you can default the value to Insert as a picklist field. Create a flag and check it after insert if that flag is true then you know it is updated. On Update, you can reverse back the old values and you can create a new one with import action as a Create. So that it won't delete the record with update action which is set to the 3rd party record. Now if the user is creating a new record that will fall under the import action Insert so you can compare the records based on discharge data and import action from there you can decide whether you can delete or update the records based on your requirement. This is just an idea.