Can some one help me on below apex code i want to update this code as per governor limits - apex

public static void updatecasefields(List<Case> lstcase) {
//List<Case> lstcase = new list<case>();
ID devRecordTypeId = Schema.SObjectType.Case.getRecordTypeInfosByDeveloperName().get('CRM_CSR_Case').getRecordTypeId();
for (Case cs: lstcase) {
if(cs.ID != null && cs.RecordTypeId == devRecordTypeId) {
}
List<CRM_CasePick__c> Casp = [SELECT Id, CRM_Carrier_Name__c,CRM_LOB__c, CRM_SLA_Turnaround_Time__c,CRM_Category__c, CRM_Issue_Sub_Type__c,CRM_Issue_Type__c,CRM_Turnaround_Time_Days__c FROM CRM_CasePick__c WHERE CRM_Carrier_Name__c = :cs.GiDP_CarrierName__c AND CRM_Category__c = :cs.CRM_Category__c AND CRM_Issue_Type__c = :cs.CRM_Issue_Type__c AND CRM_Issue_Sub_Type__c = :cs.CRM_Issue_Sub_Type__c AND CRM_LOB__c = :cs.CRM_Line_of_Business__c];
for(CRM_CasePick__c CP: Casp) {
cs.CRM_Turnaround_Time_Days__c = cp.CRM_Turnaround_Time_Days__c;
cs.CRM_SLA_Turnaround_time__c = cp.CRM_SLA_Turnaround_Time__c;
}
}
}

Remove the SOQL query from the for loop - best practice is to never run a query within a loop.
Right now it is running that query for every value of the initial list. If the list is over 100 records, it will exceed the governor limit.

Related

Apex class is called in a trigger based on some conditions.Test class passes the test but code coverage is stil 0%

When work order updates to Completed then a new water meter reading record needs to created with two field values from work order and two from another object att. Both work order and water meter reading have a look up(workorder) and master detail relation(water meter reading) with att.Sorry for so much code,but I am really stuck and need help.
trigger CreateWaterMeterReading on sm1e__smWork_Order__c (after update)
{
if (Trigger.new.size() == 1)
{
sm1e__smWork_Order__c wo = Trigger.new[0];
if(wo.sm1e__WO_Type__c == 'Meter Read Move In/Out ' && wo.sm1e__Status__c == 'Completed')
reateNewWaterMeterRead.createWMRforMoveInOrOut(wo.Id);
}
}
--Apex class
public class CreateNewWaterMeterRead {
public static void createWMRforMoveInOrOut(string workorderId)
{
Work_Order__c wo = [Select Equipment__r.Name,Completion_Date__c,Meter_Reading__c from Work_Order__c where Id = : workorderId ];
Equipment__c att = [Select Id,Last_Water_Meter_Reading_Date__c,Last_Water_Meter_Reading__c from Equipment__c where Name = : wo.Equipment__r.Name ];
List<Water_Meter_Readings__c> newwmr = new List<Water_Meter_Readings__c>();
Water_Meter_Readings__c wmr = new Water_Meter_Readings__c();
wmr.Meter__c = att.Id;
wmr.Current_Meter_Reading__c = wo.Meter_Reading__c;
wmr.Current_Read_Date__c = wo.sm1e__Completion_Date__c;
wmr.Prior_Meter_Reading__c = att.Last_Water_Meter_Reading__c;
wmr.Prior_Read_Date__c = att.Last_Water_Meter_Reading_Date__c;
wmr.Source__c = 'Manual Read';
newwmr.add(wmr);
if(newwmr.size() >0)
insert newwmr;
}
--Test Class
isTest(SeeAllData = true)
public class CreateNewWaterMeterReadTest
{
static testmethod void createWMRforMoveInOrOut()
{
Work_Order__c wo = [Select Id,Equipment__r.Name,Completion_Date__c,Meter_Reading__c from Work_Order__c where sm1e__Status__c != 'Completed' AND sm1e__WO_Type__c = 'Meter Read Move In/Out' LIMIT 1];
Equipment__c att = [Select Id,Last_Water_Meter_Reading_Date__c,Last_Water_Meter_Reading__c from Equipment__c where Name = : wo.Equipment__r.Name ];
test.startTest();
wo.Meter_Reading__c = 1317;
wo.sm1e__Status__c = 'Completed';
update wo;
test.stopTest();
System.debug('updated wo');
Water_Meter_Readings__c wmr = new Water_Meter_Readings__c();
System.debug('wmr for test');
wmr.Meter__c= att.Id;
wmr.Current_Meter_Reading__c = wo.Meter_Reading__c;
wmr.Current_Read_Date__c = wo.Completion_Date__c;
System.debug('in between wmr');
wmr.Prior_Meter_Reading__c = att.Last_Water_Meter_Reading__c;
wmr.Prior_Read_Date__c = att.Last_Water_Meter_Reading_Date__c;
wmr.Source__c = 'Manual';
insert wmr;
You've written trigger on after update. But in your test class you're inserting a record and not updating it. That is why your code coverage is 0%. Refer to this link
For executing trigger you must do dml operation for which you've written a trigger. Also you can invoke your class method from test class by creating its instance. Refer above link for the same.

Entity Framework 6 and Async() Performance

i have a question about Entity Framework 6 and ToListAsync()/ToList().
if i have a little amount of data (around 1000 rows) i have noticed that ToListAsync() is faster than ToList().
But if i have a huge amount of data (around 600.000 rows) ToList() is faster than ToListAsync().
Here you can fine the code, someone can explain me why?.
//SharedAnagra contains around 1000 rows
static List<SharedAnagra> GetSharedAnagraList()
{
using (Intranet2k3Entities intranet2K3Entities = new Intranet2k3Entities())
{
List<SharedAnagra> listaSharedAnagras = (from a in intranet2K3Entities.sharedAnagra
select new SharedAnagra
{
AnagraActive = a.AnagraActive,
AnagraId = a.AnagraID,
AnagraName = a.AnagraName,
OfficeId = a.OfficeID
}).ToList();
return listaSharedAnagras;
}
}
static async Task<List<SharedAnagra>> GetSharedAnagraListAsync()
{
using (Intranet2k3Entities intranet2K3Entities = new Intranet2k3Entities())
{
List<SharedAnagra> listaSharedAnagras = await (from a in intranet2K3Entities.sharedAnagra
select new SharedAnagra
{
AnagraActive = a.AnagraActive,
AnagraId = a.AnagraID,
AnagraName = a.AnagraName,
OfficeId = a.OfficeID
}).ToListAsync();
return listaSharedAnagras;
}
}
//sharedAnagraNDGClienti contains 950000 rows
static List<SharedAnagraNdgClienti> ListaSharedNdgClienti()
{
using (Intranet2k3Entities intranet2K3Entities = new Intranet2k3Entities())
{
List<SharedAnagraNdgClienti> lista = (from a in intranet2K3Entities.sharedAnagraNDGClienti
select new SharedAnagraNdgClienti
{
Cm = a.CM,
CodFisc = a.CodFisc,
Cognome = a.Cognome,
Descrizione = a.Descrizione,
FilialePrevalente = a.Filiale_Prevalente,
Ndg = a.NDG,
Nome = a.Nome,
Telefono = a.Telefono,
Tipologia = a.Tipologia,
Trae = a.TRAE,
Tsae = a.TSAE
}).AsNoTracking().ToList();
return lista;
}
}
static async Task<List<SharedAnagraNdgClienti>> GetIssueTypeByIdAsync()
{
List<SharedAnagraNdgClienti> listaSharedAnagraNdgClienti;
using (Intranet2k3Entities intranet2K3Entities = new Intranet2k3Entities())
{
listaSharedAnagraNdgClienti = await (from a in intranet2K3Entities.sharedAnagraNDGClienti
select new SharedAnagraNdgClienti
{
Cm = a.CM,
CodFisc = a.CodFisc,
Cognome = a.Cognome,
Descrizione = a.Descrizione,
FilialePrevalente = a.Filiale_Prevalente,
Ndg = a.NDG,
Nome = a.Nome,
Telefono = a.Telefono,
Tipologia = a.Tipologia,
Trae = a.TRAE,
Tsae = a.TSAE
}).AsNoTracking().ToListAsync();
}
return listaSharedAnagraNdgClienti;
}
I think this is not a problem of your query.This is an issue of EF 6+ framework itself.I personally didn't do any R&D about Asyn vc Sync.But I have found out some useful posts about that.Hope that will help to you.
When to really use async ?
In most applications using async will have no noticeable benefits and
even could be detrimental. Use tests, profiling and common sense to
measure the impact of async in your particular scenario before
committing to it.
Here is that article : Async Query & Save (EF6 onwards)
And here is the Great research done by one of the Stackoveflow user.You can read that too.Great one.
Entity Framework async operation takes ten times as long to complete

Why does this query always return ALL records?

I'm using WCF RIA in a Lightswitch project to create some query results. This query brings back all results regardless. I cannot make it filter the records based on the parameter passed (string Town).
public IQueryable<Enquiries> TestQuery(string Town)
{
List<Enquiries> riaenqs = new List<Enquiries>();
var enqs = this.Context.ClientEnquiries
.Include("Client")
.Include("Client.Town")
.OrderBy(enq => enq.Id);
if (Town != null)
{
enqs.Where(enq => enq.Client.Town.TownName == Town);
}
foreach (ClientEnquiry item in enqs.ToList())
{
Enquiries enq = new Enquiries();
enq.Id = item.Id;
enq.ClientName = item.Client.FirstName + " " + item.Client.Surname;
enq.Town = item.Client.Town != null ? item.Client.Town.TownName : null;
riaenqs.Add(enq);
}
return riaenqs.AsQueryable();
}
During debugging I can see that the Town is correctly populated and I can see that the query is built accordingly if Town is not null. However, when I hit the foreach statement where the linq to ef query is executed I always get all the results. I just cannot figure out where I'm slipping up.
The LINQ methods like the Where do not modify the collection/expression but always returning a new one.
So you need to reassign the result of the Where to your original variable enqs:
if (Town != null)
{
enqs = enqs.Where(enq => enq.Client.Town.TownName == Town);
}

Amount change on Opportunity Apex Trigger

I'm trying to create trigger if record type is Revenue Risk then amount should be saved in negative value, Here's my code in which I'm having error, I tried it two ways, second is in comments.. none of them is working
public with sharing class amountValidator {
//pull data of Opportunity in list
public static void validateAmount (list<Opportunity> oppList){
oppList = [Select amount FROM Opportunity WHERE RecordType.Name IN ('Revenue Risk')];
for(Opportunity opportunities : oppList){
if(oppList.amount >= '0'){
oppList.amount = oppList.amount * '-1';
}
}
/*Map<String,Schema.RecordTypeInfo> rtMapByName = d.getRecordTypeInfosByName();
Schema.RecordTypeInfo rtByName = rtMapByName.get('Revenue Risk');
for(Opportunity each : oppList){
if(rtByName.size == 0){
}
else{
if(oppList.Amount >= 0){
oppList.Amount = oppList.Amount*-1;
}
}
}*/
The error is very clear:
if(oppList.amount >= '0'){ // THIS LINE WILL THROW AN ERROR: 'Comparison arguments must be compatible types: Integer (or Double), String
oppList.amount = oppList.amount * '-1'; // THIS ONE TOO: 'Arithmetic expressions must use numeric arguments'
}
Your second code snippet is also wrong (same for first one).
if(oppList.Amount >= 0){
oppList.Amount = oppList.Amount*-1;
// MUST BE each.Amount = each.Amount * - 1; Please try not to use reserved words as variable names
}
You may want to take a look at a previous post describing strongly typed programming languages: Strongly Typed
Since we can't add comments just yet, we're going to add a new answer:
You're not updating/inserting the updated amount for your opportunity.
The correct way of doing this is to create a separate List of Opportunities (i.e. List oppsToUpdate) and add the updated opportunities to this list.
public static void validateAmount (list<Opportunity> oppList){
oppList = [Select amount FROM Opportunity WHERE RecordType.Name IN ('Revenue Risk')]; // Why are you requerying the Opportunity if you already have it??
List<Opportunity> oppsToUpdate = new List<Opportunity>();
for(Opportunity opportunities : oppList){
if(opportunities.amount > 0){
opportunities.amount = opportunities.amount * -1;
oppsToUpdate.add(opportunities);
}
}
upsert opportunities;
}
Remember to enclose your function with try-catch statements with system debugs to see what's going on with your code.
And this is the link to the input parameter modifications and why this is bad practice: Input Parameters
Working Code:
trigger Risk_NegativeQuantity on OpportunityLineItem (before insert) {
set<id> oppid = new set<id>();
for (OpportunityLineItem oli : trigger.new)
{
oppid.add(oli.opportunityid);
}
Id RevenueRisk= Schema.SObjectType.Opportunity.getRecordTypeInfosByName().get('Revenue Risk').getRecordTypeId();
list<opportunity> opplist = [select id, recordtype.name,recordtypeid from opportunity where id in : oppid ];
for (OpportunityLineItem oli : trigger.new)
{
for (opportunity opp: opplist)
{
if (oli.opportunityid == opp.id)
{
if(opp.recordtype.name == 'Revenue Risk')
{
if(oli.Quantity > 0)
{
oli.Quantity = oli.Quantity * -1;
}
}
}
}
}
}

View Criteria not returning row

I'm new to ADF BC and I'm trying to save a record in the DB.
If the record already exists, I'll update the fields if not I'll create a new row.
I'm using the same View Criteria in other methods and it works, but not in this method. Here's my code:
public String saveRecord() {
boolean isNewRow = false;
String merchId = generateIds(); //returns the correct Id, I've checked
DCIteratorBinding dc = (DCIteratorBinding)evaluteEL("#{bindings.GaeInitialSetup1Iterator}");
ViewObject vo = dc.getViewObject();
ViewCriteriaManager vcm = vo.getViewCriteriaManager();
vo.setNamedWhereClauseParam("merchId", merchId);
vcm.applyViewCriteria(vo.getViewCriteriaManager().getViewCriteria("GaeInitialSetupVOCriteria"));
vo.executeQuery();
Row rowSelected = vo.next(); //it's always null even if the record exists
if (rowSelected == null) { // null == null - leads to error when trying to insert the same Id twice
isNewRow = true;
rowSelected = vo.createRow();
rowSelected.setAttribute("MerchId", merchId);
rowSelected.setAttribute("MerchLevel", merchLevelCalc(merchId));
rowSelected.setAttribute("ParentId", parentIdCalc(merchId));
}
rowSelected.setAttribute("IpssDefault", validateIPSSDefault());
rowSelected.setAttribute("IpssBase", validateIPSSBase());
rowSelected.setAttribute("LimMinMdqPct", validateLIM_MIN_MDQ_PCT());
rowSelected.setAttribute("LimMinMdqPctNewSku", validateLIM_MIN_MDQ_PCT_NEW_SKU());
rowSelected.setAttribute("DifMdqPctMin", validateDIF_MDQ_PCT_MIN());
rowSelected.setAttribute("VarMinMdqChg", validateVAR_MIN_MDQ_CHG());
rowSelected.setAttribute("LimMinRotDays", validateLIM_MIN_ROT_DAYS());
rowSelected.setAttribute("LimMaxRotDays", validateLIM_MAX_ROT_DAYS());
rowSelected.setAttribute("DaysNewSku", validateDAYS_NEW_SKU());
rowSelected.setAttribute("IncrS1", validateINCR_S1());
rowSelected.setAttribute("IncrS2", validateINCR_S2());
rowSelected.setAttribute("IncrS3", validateINCR_S3());
rowSelected.setAttribute("IncrS4", validateINCR_S4());
rowSelected.setAttribute("ReplSuspComb", validateREPL_SUSP_COMB());
rowSelected.setAttribute("VarPctMinStkRot", validateVAR_PCT_MIN_STK_ROT());
rowSelected.setAttribute("AbcgA", validateABCG_A());
rowSelected.setAttribute("AbcgB", validateABCG_B());
rowSelected.setAttribute("AbcgC", validateABCG_C());
rowSelected.setAttribute("AbcgD", validateABCG_D());
rowSelected.setAttribute("AbcgE", validateABCG_E());
rowSelected.setAttribute("AbcgF", validateABCG_F());
rowSelected.setAttribute("AbcgG", validateABCG_G());
if (isNewRow) {
vo.insertRow(rowSelected);
}
DCBindingContainer bindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
OperationBinding operationBinding = (OperationBinding)bindings.getOperationBinding("Execute");
operationBinding.execute();
OperationBinding operationBinding2 = (OperationBinding)bindings.getOperationBinding("Commit");
operationBinding2.execute();
return null;
}
What am I missing?
Your code seems perfectly right, could you try making the below mentioned changes?
vo.executeQuery();
if (vo.hasNext()) {
Row rowSelected = vo.next();
//write rest of your logic here
}
This will not have null == null check and is the best practice.
I've fixed the problem.
I removed the line: Row rowSelected = vo.next();
And I've added: Row rowSelected = vo.first();