+ Start a Discussion
Michael Degn JensenMichael Degn Jensen 
Hi,

I am fairly new to working with Aura Components but have managed to build a component which shows all non-completed tasks on the user Home Page.
I have added a checkbox next to each Task and this is where I am stuck. I would like the Task Status to be updatet to 'Completed' when the checkbox i marked (true). How to accomplish this?

Any help is appreciated, thanks!

ApexController:
public class ALTaskController {
    @AuraEnabled
    public static List<Task> getTasks(){
        List<Task> taskList = [SELECT Id,Subject,Description,OwnerId,ActivityDate,WhoId,Priority,Status,Type FROM Task WHERE ActivityDate <= NEXT_N_DAYS:3 AND Status != 'Completed' ORDER BY ActivityDate ASC];
        return taskList;
    }
}
Component:
<aura:component controller="ALTaskController" implements="flexipage:availableForAllPageTypes,force:appHostable" access="global">
	<aura:attribute name="tasks" type="List" />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />


        <lightning:card class="accountCard" variant="Narrow" iconName="standard:task" footer="Card Footer">
            <aura:set attribute="title">
                Mine opgaver
            </aura:set>
            <aura:set attribute="actions">
                <lightning:buttonIcon iconName="utility:down" variant="border-filled" alternativeText="Show More"/>
            </aura:set>
            <aura:set attribute="body">
                <p class="slds-p-horizontal_small">
                    <aura:iteration items="{!v.tasks}" var="task"> <!-- Use the Apex model and controller to fetch server side data -->
                    <lightning:tile label="{!task.Subject}" href="{!'/one/one.app?#/sObject/'+ task.Id + '/view'}">
                        <aura:set attribute="media">
							<lightning:input type="checkbox" name="input1" title="Fuldført"/>
                            <!--<lightning:icon iconName="standard:task"/>-->
                        </aura:set>
                        <div class="demo-only demo-only--sizing slds-grid slds-wrap">
                            <div class="slds-size_3-of-12">
                                <div class=""><p class="slds-truncate">Forfaldsdato:</p></div>
                            </div>
                            <div class="slds-size_9-of-12">
                                <div class=""><p class="slds-truncate"><lightning:formattedDateTime value="{!task.ActivityDate}" year="numeric" month="numeric" day="numeric"/></p></div>
                            </div>
                            <div class="slds-size_3-of-12">
                                <div class=""><p class="slds-truncate">Status:</p></div>
                            </div>
                            <div class="slds-size_9-of-12">
                                <div class=""><p class="slds-truncate">{!task.Status}</p></div>
                            </div>
                            <div class="slds-size_3-of-12">
                                <div class=""><p class="slds-truncate">Kommentar:</p></div>
                            </div>
                            <div class="slds-size_9-of-12">
                                <div class="" title="{!task.Description}"><p class="slds-truncate">{!task.Description}</p></div>
                            </div>
                        </div>
                    </lightning:tile>
                    </aura:iteration>
                </p>
            </aura:set>
            <aura:set attribute="footer">
            </aura:set>
        </lightning:card>
</aura:component>
Controller:
({
	doInit: function(component, event, helper) {
        // Fetch the task list from the Apex controller
        helper.getTaskLists(component);
    }
})
Helper:
({
	// Fetch the accounts from the Apex controller
    getTaskLists: function(component) {
        var action = component.get('c.getTasks');
        // Set up the callback
        var self = this;
        action.setCallback(this, function(actionResult) {
            component.set('v.tasks', actionResult.getReturnValue());
        });
        $A.enqueueAction(action);
    }
})
Best Answer chosen by Michael Degn Jensen
Khan AnasKhan Anas (Salesforce Developers) 
Hi Michael,

Greetings to you!

Please try the below code, I have tested in my org and it is working fine. Kindly modify the code as per your requirement.

Apex:
public class ALTaskController {
    
    @AuraEnabled
    public static List<Task> getTasks(){
        List<Task> taskList = [SELECT Id,Subject,Description,OwnerId,ActivityDate,WhoId,Priority,Status,Type FROM Task WHERE ActivityDate <= NEXT_N_DAYS:3 AND Status != 'Completed' ORDER BY ActivityDate ASC];
        return taskList;
    }
    
    @AuraEnabled
    public static void updateDetails(List<String> lstRecordId) {
        List<Task> lstUpdate = new List<Task>();
        for(Task t : [SELECT Id, Status FROM Task WHERE Id IN : lstRecordId]){
            t.Status = 'Completed'; // Add fields which you want to update
            lstUpdate.add(t);
        }
        
        if(lstUpdate.size() > 0){
            update lstUpdate;
        }
        
    }
}

Component:
<aura:component controller="ALTaskController" implements="flexipage:availableForAllPageTypes,force:appHostable" access="global">
    <aura:attribute name="tasks" type="List" />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <aura:handler event="force:refreshView" action="{!c.doInit}" />
    
    <lightning:card class="accountCard" variant="Narrow" iconName="standard:task" footer="Card Footer">
        <aura:set attribute="title">
            Mine opgaver
        </aura:set>
        <aura:set attribute="actions">
            <lightning:buttonIcon iconName="utility:down" variant="border-filled" alternativeText="Show More"/>
        </aura:set>
        <aura:set attribute="body">
            <p class="slds-p-horizontal_small">
                <aura:iteration items="{!v.tasks}" var="task"> <!-- Use the Apex model and controller to fetch server side data -->
                    <lightning:tile label="{!task.Subject}" href="{!'/one/one.app?#/sObject/'+ task.Id + '/view'}">
                        <aura:set attribute="media">
                            <lightning:input type="checkbox" 
                                             name="input1" 
                                             title="Fuldført"
                                             value="{!task}"
                                             onchange="{!c.updateStatus}"/>
                            <!--<lightning:icon iconName="standard:task"/>-->
                        </aura:set>
                        <div class="demo-only demo-only--sizing slds-grid slds-wrap">
                            <div class="slds-size_3-of-12">
                                <div class=""><p class="slds-truncate">Forfaldsdato:</p></div>
                            </div>
                            <div class="slds-size_9-of-12">
                                <div class=""><p class="slds-truncate"><lightning:formattedDateTime value="{!task.ActivityDate}" year="numeric" month="numeric" day="numeric"/></p></div>
                            </div>
                            <div class="slds-size_3-of-12">
                                <div class=""><p class="slds-truncate">Status:</p></div>
                            </div>
                            <div class="slds-size_9-of-12">
                                <div class=""><p class="slds-truncate">{!task.Status}</p></div>
                            </div>
                            <div class="slds-size_3-of-12">
                                <div class=""><p class="slds-truncate">Kommentar:</p></div>
                            </div>
                            <div class="slds-size_9-of-12">
                                <div class="" title="{!task.Description}"><p class="slds-truncate">{!task.Description}</p></div>
                            </div>
                        </div>
                    </lightning:tile>
                </aura:iteration>
            </p>
        </aura:set>
        <aura:set attribute="footer">
        </aura:set>
    </lightning:card>
</aura:component>

Controller:
({
	doInit: function(component, event, helper) {
        // Fetch the task list from the Apex controller
        helper.getTaskLists(component);
    },
    
    updateStatus: function(component, event, helper) {
        helper.updateTaskStatus(component, event);
    }
})

Helper:
({
    // Fetch the accounts from the Apex controller
    getTaskLists: function(component) {
        var action = component.get('c.getTasks');
        // Set up the callback
        var self = this;
        action.setCallback(this, function(actionResult) {
            component.set('v.tasks', actionResult.getReturnValue());
        });
        $A.enqueueAction(action);
    },
    
    updateTaskStatus: function(component, event) {
        var rowRecord = event.getSource().get('v.value');
        console.log('rowRecord--->>> ' + JSON.stringify(rowRecord));
        var tid = rowRecord.Id;
        console.log('tid-> ' + tid);
        
        var action = component.get('c.updateDetails');
        action.setParams({
            "lstRecordId": tid
        });
        action.setCallback(this, function(response) {
            
            var state = response.getState();
            if (state === "SUCCESS") {
                console.log(state);
                $A.get('e.force:refreshView').fire();
            }
        });
        $A.enqueueAction(action);
    }
})

I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in the future. It will help to keep this community clean.

Thanks and Regards,
Khan Anas
Sreenu Reddy 16Sreenu Reddy 16 
sfdc flocks can you give me  help on below code .

Method does not exist or incorrect signature: void put(Decimal, String) from the type Map<Id,String> at line 8 column 24

trigger changeowner on Lead (before insert) {
     Map<Id,String> zipCodeUserMap = new Map<Id,String>();
     List<Zip_Code__c> zipCodes = new List<Zip_Code__c>();
     zipCodes = [Select id,ZipCode__c,Counserlor__c  from Zip_Code__c];
      
      for (Zip_Code__c zc :zipCodes){
        
        zipCodeUserMap.put(zc.ZipCode__c,zc.Counserlor__c);   
     }
       
       
       
       for(Lead l : Trigger.new) 
       {
        if(zipCodeUserMap.containsKey(l.Zip_Code__c)) 
        {
            l.Ownerid = zipCodeUserMap.get(l.Zip_Code__c);
        }
       }
}
Best Answer chosen by Sreenu Reddy 16
Ajay K DubediAjay K Dubedi
Hi Sreenu,
Try this trigger:

trigger changeowner on Lead (before insert) {
    Map<String, Id> zipCodeUserMap = new Map<String, Id>();
    List<Zip_Code__c> zipCodes = new List<Zip_Code__c>();
    zipCodes = [Select id, ZipCode__c, Counserlor__c  from Zip_Code__c WHERE ZipCode__c != null AND Counserlor__c != null];
    if(zipCodes.size() > 0) {
        for (Zip_Code__c zc : zipCodes) {
            zipCodeUserMap.put(String.ValueOf(zc.ZipCode__c), Id.ValueOf(zc.Counserlor__c));   
        }
        for(Lead l : Trigger.new) 
        {
            if(zipCodeUserMap.containsKey(l.Zip_Code__c)) 
            {
                l.Ownerid = zipCodeUserMap.get(l.Zip_Code__c);
            }
        }
    }  
}

I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.
Thanks,
Ajay Dubedi
Hung Vo 891Hung Vo 891 
I'm doing the "Test Apex Triggers" challenge and get this error:
"The 'RestrictContactByName' class did not achieve 100% code coverage via your test methods"

I also attach my code here, can you show me where could it be the wrong spot?
 
@isTest
public class TestRestrictContactByName {
    @isTest static void TestInsertContact_INVALIDNAME(){
		Contact contact = new Contact(LastName='INVALIDNAME');
        Test.startTest();
        Database.SaveResult result = Database.insert(contact);
        Test.stopTest();
        System.assert(!result.isSuccess());
        System.assert(result.getErrors().size() > 0);
        System.assertEquals('The Last Name "'+contact.LastName+'" is not allowed for DML',
                             result.getErrors()[0].getMessage());
    }
    
    @isTest static void TestInsertContact_VALIDNAME(){
		Contact contact = new Contact(LastName='VALIDNAME');
        Test.startTest();
        Database.SaveResult result = Database.insert(contact);
        Test.stopTest();
        System.assert(result.isSuccess());
    }
    
    @isTest(SeeAllData=true) static void TestUpdateContact_INVALIDNAME(){
		Contact contact = [SELECT Id FROM Contact WHERE LastName = 'Test Contact' LIMIT 1];
        contact.LastName = 'INVALIDNAME';
        Test.startTest();
        Database.SaveResult result = Database.update(contact);
        Test.stopTest();
        System.assert(!result.isSuccess());
        System.assert(result.getErrors().size() > 0);
        System.assertEquals('The Last Name "'+contact.LastName+'" is not allowed for DML',
                             result.getErrors()[0].getMessage());
    }
    
    @isTest(SeeAllData=true) static void TestUpdateContact_VALIDNAME(){
		Contact contact = [SELECT Id FROM Contact WHERE LastName = 'Test Contact' LIMIT 1];
        contact.LastName = 'VALIDNAME';
        Test.startTest();
        Database.SaveResult result = Database.update(contact);
        Test.stopTest();
        System.assert(result.isSuccess());
    }
}

 
Best Answer chosen by Hung Vo 891
Hung Vo 891Hung Vo 891
Hello,

After a few try out, my code worked.
The reason maybe something went wrong and I just log out and login again, and everything works fine.
Also remember to to this step
Run your test class at least once (via 'Run All' tests the Developer Console) before attempting to verify this challenge.

 
David Autry 4David Autry 4 

Been banging my head against the wall for a bit on this one.  Given a global picklist that is added to two objects can a SOQL query be constructed such that the query will return a collection of objects A or B where the global picklist on each contains one matching value in the set pair?

Given MultipickList__c is a global picklist on ObjectA and ObjectB :

SELECT Id FROM ObjectA WHERE Multipicklist__c INCLUDES(ObjectB.Multipicklist__c)

Thank you.

David

Best Answer chosen by David Autry 4
David Autry 4David Autry 4

Settled on a FOR loop.  Broke ObjectA.Multipicklist__c into an array and used it to query against ObjectB.

 

                string[] multipickA = ObjectA.MultiPickList__c.split(';');
                List<ObjectB> finalList = new List<ObjectB>();
                integer i = 0;
                for (string s : multipickA)
                {
                    List<ObjectB> tempList = [SELECT Id 
                                                          FROM ObjectB
                                                          WHERE MultiPickList__c INCLUDES(:multipickA[i])]
                    finalList.addall(tempList);
                    i++;                    
                }

 

If there is a more elegant solution please let me know.

Thanks all.

Sepur AnilSepur Anil 
I have Standard Object and Custom Object 
Standard Object fields are Id, LastactivityDate. Object name is Leads
Custom Object fields are Id, Lead__c. Object Name Email_Lead_Sync__c
I need LastActivity < Last_N_Days:90   Soql Query can any one help me.
Best Answer chosen by Sepur Anil
Ajay K DubediAjay K Dubedi
Hi Sepur,

If you want to do SOQL query using LAST_N_DAYS:90 functinality in a simple way then you can write this:
//It will return all the list of leads having LastActivityDate < LAST_N_DAYS:90
List<Lead> leadList = [Select Id,LastActivityDate  from Lead WHERE LastActivityDate < LAST_N_DAYS:90 Limit 10000];

And if you want to use custom Object(Email_Lead_Sync__c) and standared object(Lead). If Custom object(Email_Lead_Sync__c) have the lookup(relation) with Lead(standared object) in the Lead__c field then you can try this:

List<Lead> leadList = [Select Id,LastActivityDate  from Lead WHERE LastActivityDate < LAST_N_DAYS:90 Limit 10000];
if(leadList.size()>0) {
    Set<Id> leadIdSet = new Set<Id>();
    for (Lead temp : leadList) {
        leadIdSet.add(temp.Id);
    }
//'emailLeadList'- contains all the list of 'email Lead List' having the relation with Lead and LastActivityDate < LAST_N_DAYS:90
    List<Email_Lead_Sync__c> emailLeadList = new List<Email_Lead_Sync__c>();
    emailLeadList = [SELECT Id, Lead__c FROM Email_Lead_Sync__c WHERE Lead__c IN: leadIdSet Limit 10000];
}

If your requirement is anything else then please provide me whole requirement.

I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.
Thanks,
Ajay Dubedi
RarLopzRarLopz 
Why does my chart has month names on wedges but the sample example doesn't ? 

In my sandbox I  copied and pasted exact code from the salesforce documentation as shown here https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_charting_overview_simple_example.htm

Created a Apex Controller, Created a Wrapper Class, Created a VFP.
 
The output as shown in this example doesn't have month names on the wedges. However the output I get has month names on the wedges. This example doesn't uses rendererFn property. I am wondering why i see month names and the example shown does'nt?

This is my output 
User-added imageHowever I was expecting to see this 

User-added image

Here the Code exactly as copied from the documentation 
 
<apex:page controller="PieChartController" title="Pie Chart">
    <apex:chart height="350" width="450" data="{!pieData}">
        <apex:pieSeries dataField="data" labelField="name"/>
        <apex:legend position="right"/>
    </apex:chart>
</apex:page>



public class PieChartController {
    public List<PieWedgeData> getPieData() {
        List<PieWedgeData> data = new List<PieWedgeData>();
        data.add(new PieWedgeData('Jan', 30));
        data.add(new PieWedgeData('Feb', 15));
        data.add(new PieWedgeData('Mar', 10));
        data.add(new PieWedgeData('Apr', 20));
        data.add(new PieWedgeData('May', 20));
        data.add(new PieWedgeData('Jun', 5));
        return data;
    }

    // Wrapper class
    public class PieWedgeData {

        public String name { get; set; }
        public Integer data { get; set; }

        public PieWedgeData(String name, Integer data) {
            this.name = name;
            this.data = data;
        }
    }
}

 
Best Answer chosen by RarLopz
Dushyant SonwarDushyant Sonwar
Hi RarLopz,

You need to use apex:chartLabel tag to remove the label.
<apex:chartLabel display="none" />

After using this your code will be something like this below.
<apex:page controller="PieChartController" title="Pie Chart">
    <apex:chart height="350" width="450" data="{!pieData}" >
        <apex:pieSeries dataField="data" labelField="name">
            <apex:chartLabel display="none" />
        </apex:pieSeries>
        <apex:legend position="right"/>
    </apex:chart>
</apex:page>

Hope this helps.
SF Beginner 2019SF Beginner 2019 
How to call this apex class to make it a batch job?
 
public class ApplicationYearsinService{

    public static void YearsinService(List<Application__c> appList){
        //Declares the Variables, List, ID to be used
        Date dat = System.today();
        Integer yr = dat.year();   
        Map<Id, Set<Integer>> setofYear = new Map<Id, Set<Integer>>();
        Set<Id> accountIdSet = new set<Id>();
        
        //Gets the values of the Account(Account__c from the Application
        for(Application__c cs: appList ){
            accountIdSet.add(cs.Account__c);            
        }
        
        //Query in the Application to get the value from the Account
        for(Application__c p : [SELECT ID, Account__c, Received_Date__c from Application__c where Account__c IN : accountIdSet ]){
            if(p.Received_Date__c != null){
                if(setofYear.containskey(p.Account__c)){
                    if(p.Received_Date__c != NULL) {
                        setofYear.get(p.Account__c).add(p.Received_Date__c.Year());
                    }
                }
                else {
                    setofYear.put(p.Account__c, new Set<Integer>{p.Received_Date__c.Year()});
                }     
            }
        }
        
        Map<String, List<Application__c>> appMap = new Map<String ,List<Application__c>>();
        Map<String, Account> lisAcct = new  Map<String, Account>();
        List<Account> acctToUpdate = new  List<Account>();
        List<Account> accountListToLoop = [Select Id, YearsinService__c, (Select Id FROM Applications__r LIMIT 1) from Account where Id=:accountIdSet];
        for(Account acc: accountListToLoop){
            lisAcct.put(acc.Id+'', acc);
        }       
        for(Account act : accountListToLoop ){
            if(setofYear.containskey(act.id)){
                act.YearsinService__c = setofYear.get(act.id).size();
                acctToUpdate.add(act);
                lisAcct.remove(act.Id+'');
            }
            else {
                act.YearsinService__c = 0;
                acctToUpdate.add(act);
            }
        }
        Database.upsert(acctToUpdate, false); 
    }
}

 
Best Answer chosen by SF Beginner 2019
Ajay K DubediAjay K Dubedi
Hi SF,
Write below scheduler for call ApplicationYearsinService class to make it a batch job. And Instead of params pass Application__c list.

global with sharing class ApplicationYearsinService_Scheduler implements Schedulable {

    Public static void SchedulerMethod() {
        string timeinterval = '0 0 0 1/1 ? ';
        System.schedule('Batch Class will run every day at 12:00 AM',timeinterval, new ApplicationYearsinService_Scheduler());
    }
    global void execute(SchedulableContext SC) {
        ApplicationYearsinService.YearsinService(params);
    }

}

I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.
Thanks,
Ajay Dubedi
JJ WurtzJJ Wurtz 
I 'm in the process of beginning this superbadge and all my videos say "Access Denied This player has restricted access"   I've not had probelems on watching other videos.

Do I need to adjust something?   Thanks.
Best Answer chosen by JJ Wurtz
Ajay K DubediAjay K Dubedi
Hi JJ,
First, make sure that you are logging into trailhead with Aloha Credentials.
The problem may be the VPN. Change the setup to connect to some other VPN.
That can solve your problem.

I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.
Thanks,
Ajay Dubedi
Christopher MilnerChristopher Milner 
I am attempting to write a validation rule to fulfill a customer request. Essentially, we have a custom field on the contact record called "Division". The short version is, I would like a validation rule that restricts a record from being created/saved if "Division" is blank when the related account = 0013200001FTkYh (ID of the account in question). Any help would be appreciated!
Best Answer chosen by Christopher Milner
Christopher MilnerChristopher Milner
That did not quite do it for me, but it helped point me in the correct direction, thanks! I actually got it to work with the following:
AND( 
AccountId = '0013200001FTkYh', 
ISBLANK( Division__c ))
siva kurmasiva kurma 
APEX CLASS
public class AccountOwnerCheck {
    public static void OwnerCheck(list<Account> VarAccList){
        for(Account VarAccounts:VarAccList){
            if(VarAccounts.OwnerId != UserInfo.getUserId()) {
                VarAccounts.addError('You dont have the permission to delete the record, Only Owner can delete');
            }          
        }
    }
}

APEX TRIGGER
trigger AccountDeleteTrigger on Account (before Delete) {
    
    if(Trigger.iSBefore == true && Trigger.isDelete == True){
        AccountOwnerCheck.OwnerCheck(Trigger.Old);
    }
}


TEST CLASS
@isTest
class AccountOwnerCheckTest {
   static testMethod void testMethod1() 
    {
            Account newAcc = new Account() ;
            newAcc.Name = 'Cole';
            insert newAcc;

            try
            {
                Delete     newAcc;
            }
            catch(Exception ee)
            {}
    }
}
Best Answer chosen by siva kurma
Ajay K DubediAjay K Dubedi
Hi Siva,
Try this test class:
@isTest
class AccountOwnerCheck_Test {
    @isTest static void testmethod1()
    {
        String orgId = UserInfo.getOrganizationId();
        String dateString = String.valueof(Datetime.now()).replace(' ','').replace(':','').replace('-','');
        Integer randomInt = Integer.valueOf(math.rint(math.random()*1000000));
        String uniqueName = orgId + dateString + randomInt;
        Test.startTest();
        Profile p = [SELECT Id FROM Profile WHERE Name='System Administrator']; 
        User usr = new User(Alias = 'standt', Email= uniqueName + '@test' + orgId + '.org', 
                            EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', 
                            LocaleSidKey='en_US', ProfileId = p.Id, 
                            TimeZoneSidKey='America/Los_Angeles', UserName= uniqueName + '@test' + orgId + '.org');
        insert usr ;
        createAcc(usr.Id);
    }
    @Future
    public static void createAcc(Id usrId)
    {
        try{
            
            Account newAcc = new Account() ;
            newAcc.Name = 'Test';
            newAcc.OwnerId = usrId;
            insert newAcc;
            delete newAcc;
        }
        catch(Exception ex)
        {
            System.debug('Exception on Line Number ' + ex.getLineNumber() + ' Message ---- ' + ex.getMessage());
        }
    }
}



I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.
Thanks,
Ajay Dubedi