• Luke Higgins 22
  • NEWBIE
  • 60 Points
  • Member since 2018

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 4
    Likes Given
  • 21
    Questions
  • 13
    Replies
I'm trying to update a field on ts2__Placement__c records that meet the criteria. I believe it's because I am doing a DML statement within a for loop. How do I avoid this and get the same results?
 
public class plc2WeekAudit implements Database.Batchable<sObject>, Database.Stateful {
    
    List<Change_Request__c> plcList = [SELECT Related_Placement__c FROM Change_Request__c WHERE End_Date__c != null AND Related_Placement__r.ts2__Status__c ='Active' AND Related_Placement__r.ts2__End_Date__c < LAST_N_MONTHS:1];
    Set<String> duplicatePlc = new Set<String>();

    public Database.QueryLocator start(Database.BatchableContext bc) {
        for(Change_Request__c item : plcList){
                duplicatePlc.add(item.Related_Placement__c);
        }
        System.debug('the size is : ' +duplicatePlc.size());
        System.debug(duplicatePlc);

        return Database.getQueryLocator('SELECT Id,ts2__Status__c FROM ts2__Placement__c WHERE Id IN :duplicatePlc');    
    }
    public void execute(Database.BatchableContext BC, List<ts2__Placement__c> returnedPlcs){
        System.debug(returnedPlcs);
        for(ts2__Placement__c plc : returnedPlcs){
            plc.ts2__Status__c = 'Inactive';
        }
        update returnedPlcs;
    }
    public void finish(Database.BatchableContext BC){
    }
}

 
What I have so far covers 26% of the batch class. I'm not able to cover the execute portion of the batch class.

batch.cls
public class Batch implements Database.Batchable<sObject> {

	public Database.QueryLocator start(Database.BatchableContext bc) {
        String query = 'SELECT Id, jstcl__Consultant__r.Previous_Timesheet_Status__c FROM jstcl__TG_Timesheet__c WHERE jstcl__Placement__r.ts2__Status__c =\'Active\' AND jstcl__Placement__r.VMS__c = \'\' AND jstcl__Week_Ending__c = LAST_N_DAYS:4 AND jstcl__Status__c = \'Pending\'';
          return Database.getQueryLocator(query);
    }
   public void execute(Database.BatchableContext BC, List<jstcl__TG_Timesheet__c> timesheets){
       List<Contact> consultants = new List<Contact>();
       List<Contact> consultants2 = new List<Contact>();

       for(jstcl__TG_Timesheet__c timesheet : timesheets){
           Contact consultant = timesheet.jstcl__Consultant__r; 
           if (consultant == null) continue;
           consultant.Previous_Timesheet_Status__c = 'Pending';
           if(consultants.contains(consultant)){
               consultants2.add(consultant);
           }else{consultants.add(consultant);}
           }
           update consultants;
        }
   public void finish(Database.BatchableContext BC){}
}
test.cls
@istest 
private class Test {

static TestMethod void hfTest() {
     Profile prof = [select id from profile where name='system Administrator'];
     User usr = new User(alias = 'usr', email='us.name@vmail.com',
                emailencodingkey='UTF-8', lastname='lstname',
                timezonesidkey='America/Los_Angeles',
                languagelocalekey='en_US',
                localesidkey='en_US', profileid = prof.Id,
                username='testuser128@testorg.com');
                insert usr;
    Id idRecordId = Schema.SObjectType.Contact.getRecordTypeInfosByDeveloperName().get('Candidate').getRecordTypeId();

    	ts2__Source__c source = new ts2__Source__c(Name = 'LinkedIn.com - Resume Search');
    	Account acc = new Account(Name = 'Express Scripts Holding Company');
        insert acc;
  		Account acc2 = new Account(Name = 'Candidates- 10-2018');
        insert acc2;
    	Contact con = new Contact(FirstName='fnadmes', LastName = 'lnamdes', Email = 'emadils@gmail.com', Phone = '9744800300', AccountId = acc2.Id, ts2__Source__c = source.Id, ts2__People_Status__c = 'Placed');
        Contact con2=new Contact(FirstName='fnames', LastName = 'lnames', Email = 'emails@gmail.com', Phone = '9743800300', AccountId=acc.Id, Relationship_Status__c = 'Lunch'); 
    	insert con; insert con2;
        ADP_Department__c adp = new ADP_Department__c(Name = 'Georgia');
        insert adp;
        ts2__Job__c job = new ts2__Job__c(Name = 'Software Engineer',Hiring_Manager_Contact__c = con2.Id);
        insert job;
        ts2__HolidayCalendar__c hcal = new ts2__HolidayCalendar__c(Name= 'Holiday Calendar');
        insert hcal;
        Labor_Category__c lcat = new Labor_Category__c(Name='Software Engineer 1');  
        insert lcat;
        ts2__Placement__c plc = new ts2__Placement__c(ts2__Job__c = job.Id, Contractor_Type__c = 'Technical Youth', Onboarding_Method__c= 'Staff Augmentation', ts2__Start_Date__c= Date.newInstance(2019, 1, 7), ts2__End_Date__c= Date.newInstance(2019, 2, 15),
        jstcl__HireType__c= 'W2', ADP_Department__c= adp.Id, ts2__Bill_Rate__c= 60.00, ts2__Pay_Rate__c= 30.00, jstcl__Invoice_Batch__c= 'Placement', ts2__Client__c= acc.Id, ts2__Hiring_Manager__c= con2.Id, jstcl__TimecardApprover__c= con2.Id, jstcl__HolidayCalendar__c= hcal.Id,
		State_Worked_In_Non_TFI_Placements__c= 'GA - Georgia', jstcl__Overtime_Bill_Rate__c= 60, jstcl__Burden__c= 0.20, jstcl__Accounts_Receivable_U__c= '00537000005d7F2AAI', jstcl__Terms__c= 'Net 60', ts2__Employee__c= con.Id, Labor_Category__c= lcat.Id);
		insert plc;
     	List<jstcl__TG_Timesheet__c> tsList = new List<jstcl__TG_Timesheet__c>();
    	 jstcl__TG_Timesheet__c ts = new jstcl__TG_Timesheet__c(jstcl__Consultant__c = con2.Id, jstcl__Placement__c = plc.Id, jstcl__Week_Ending__c = Date.newInstance(2019, 2, 15));
    tsList.add(ts);

	Test.startTest(); 
     Batch abcd = new Batch();
     ID batchprocessid = Database.executeBatch(abcd);
	Test.stopTest();
 }    
}

 
I have a lightning web component with a record-edit-form and a button to submit the form. I am trying to prevent the form submission when a required field is missing, but it's not working properly with just the "required" attribute of the lightning-input-field. This is what I have so far:

component.html
<lightning-record-edit-form object-api-name="ts2__Placement__c" record-id={recordId} onsuccess={handleSuccess} onsubmit={handleSubmit1}>
            <lightning-messages></lightning-messages>
            <div class="slds-grid slds-gutters">
                <div class="slds-col slds-size_6-of-12"> 
               <lightning-output-field field-name="ts2__Employee__c"></lightning-output-field>
                <lightning-input-field id="onboardingMeth" field-name="Onboarding_Method__c" onchange={handleChange2} value={oboMeth} required></lightning-input-field>
                 <lightning-input-field name="contractorType" field-name="Contractor_Type__c" onchange={handleChange3} value={conType} required></lightning-input-field>
                    </div>
                    </div>
    </lightning-record-edit-form>  
<lightning-button variant="brand" class="slds-m-left_x-small" icon-name="utility:forward" type="submit" icon-position=right label="Submit" onclick={handleNext}></lightning-button>
</template>
component.js
import { LightningElement , api, track} from 'lwc';

export default class LwcBasicWizard extends LightningElement {
    @api recordId;

handleSubmit1(){
     this.template.querySelector('lightning-record-edit-form').submit();
    }

 
I am trying to remove and replace a few strings that are rendering incorrectly for a Rich Text field through an Apex Trigger. Any idea what is incorrect with the following code?
 
trigger removeCharacters on ts2__Job__c (before insert) {
    String str = '\u00A0';
    String str2 = 'Â';
    String replacement = ' ';
    for(ts2__Job__c des : trigger.new){
        if(des.ts2__Job_Advertisement__c.contains(str)){
            des.ts2__Job_Advertisement__c.replace(str, replacement);
        }
        if(des.ts2__Job_Advertisement__c.contains(str2)){
            des.ts2__Job_Advertisement__c.replace(str2, replacement);
        }
    }

}

 

I am trying to update the Hours_Worked_Last_2_Weeks__c field on the Placement__c object through running a batch class on the related Timesheet__c object. Each Timesheet__c that meets the criteria, should add it's Total_Hours__c to it's Placement__c's Hours_Worked_Last_2_Weeks__c. I'm getting no error but the Hours_Worked_Last_2_Weeks__c is not populating.

Batch Class:

public class hfFlagB implements Database.Batchable<sObject>, Database.Stateful{
   List<Timesheet__c> tsList = [SELECT Id FROM Timesheet__c WHERE Status__c ='Approved' AND Week_Ending__c = LAST_N_DAYS:15 ];
   Set<String> tsSet = new Set<String>();
	public Database.QueryLocator start(Database.BatchableContext bc) {
     for(Timesheet__c ts : tsList){
        tsSet.add(ts.Id);
     }
        return Database.getQueryLocator('SELECT Id, Total_Hours__c, Placement__r.Hours_Worked_Last_2_Weeks__c, Placement__c FROM Timesheet__c WHERE Id IN :tsSet');
        }
   public void execute(Database.BatchableContext BC, List<Timesheet__c> a){
      for(Timesheet__c t : a){
         t.Placement__r.Hours_Worked_Last_2_Weeks__c +=  t.Total_Hours__c;   
        }
     }
   public void finish(Database.BatchableContext BC){
   }
}

I am trying to get the sum of a result from a parent-child query and insert the sum into a field on the parent. The object placement__c has a child record timesheet__c with the field, hours__c, for each week. I am trying to get the total of approved hours for the last 2 weeks on the placement__c record through a batch class. I can get the timesheet__c records grouped with this SOQL query of the placements__c, but I'm not sure how to get to the final product of adding them.

SELECT Id, Name, (SELECT jstcl__Total_Hours__c FROM jstcl__Timesheets__r WHERE jstcl__Week_Ending__c = LAST_N_DAYS:15 AND jstcl__Status__c = 'Approved') FROM ts2__Placement__c
Hi, 

I've been trying to write a test class for this Apex class that is the controller for a lightning:fileUploader that uploads files and shows a list of the uploaded files. I've worked on it for a while now and nothing has worked so far. Can someone give me some assistance? 

Apex class:
public class fileUploaderClass {  
   @AuraEnabled  
   public static List<ContentDocument> getFiles(string recordId){  
     List<ContentDocument> DocumentList = new List<ContentDocument>();  
     Set<Id> documentIds = new Set<Id>();  //store file ids
     List<ContentDocumentLink> cdl=[select id,LinkedEntityId,ContentDocumentId from ContentDocumentLink where LinkedEntityId=:recordId];  
     for(ContentDocumentLink cdLink:cdl){  
       documentIds.add(cdLink.ContentDocumentId);  // Document ids
     }      
     DocumentList = [select Id,Title,FileType,ContentSize,Description from ContentDocument where id IN: documentIds];  
     return DocumentList;  
   }  
   @AuraEnabled  
   public static List<ContentDocument> UpdateFiles(string documentId,string title,string recordId){  
     system.debug('title: ' +title);  
     ContentDocument cd = [select id,title from ContentDocument where Id=:documentId]; // Getting files from Parent record 
     cd.Title = title;  // Changing file Title with user entered title
     try{  
       update cd;  // Update ContentDocument (File)
     }  
     catch(DMLException e){  
       system.debug('Exception has occurred! ' +e.getMessage());  
     }  
      List<ContentDocument> DocumentList = new List<ContentDocument>();  
     Set<Id> documentIds = new Set<Id>();  
     List<ContentDocumentLink> cdl=[select id,LinkedEntityId,ContentDocumentId from ContentDocumentLink where LinkedEntityId=:recordId];  
     for(ContentDocumentLink cdLink:cdl){  
       documentIds.add(cdLink.ContentDocumentId);  
     }      
     DocumentList = [select Id,Title,FileType,ContentSize,Description from ContentDocument where id IN: documentIds];  
     return DocumentList;  // Return list of files on parent record
   }  
 }

 
I'm trying to figure out how to add X amount of days to a date through the lightning component controller. Here is what I have been trying:

.cmp - 
<aura:component implements="flexipage:availableForAllPageTypes">
        <aura:attribute name="dataInValue" type="Date" />
        <aura:attribute name="dataEndValue" type="Date"/>

        <lightning:input aura:id="startDate" type="date" label="Enter Date" value="{!v.dataInValue}" onchange="{!c.validDate}"/>
        <br/>
        <lightning:input aura:id="endDate" type="date" label="Day they get benefits:" value="{!v.dataEndValue}"/>
        
</aura:component>
.js - 
({
    validDate : function(component,event,helper){
               var data_in = component.get("v.dataInValue");
               var data_out = formatDate(data_in) + 30;
               component.set("v.dataEndValue", data_out);
    }
})
I'm trying to make a custom user lookup component and I've gotten to where the lookup's dropdown works, but only after the space bar is hit. Is there anyway for this to update on every key hit instead? I've already tried to use oninput and onchange with no luck. Here's what I have:

usernameLookup.cmp
<aura:component controller="lookupSearch"> 
     <aura:attribute Name="selItem" type="object" access="public" 
                     description="This attribute can be used by parent component to read selected record"/>  
     <aura:attribute Name="server_result" type="object[]" access="private" /> 
     <aura:attribute name="lookupIcon" type="String" access="public" default="standard:contact"/>
    <aura:attribute name="objectName" type="String" access="public" 
                    description="Name of Object to be searched"/>
    <aura:attribute name="field_API_text" type="String" access="public" 
                    description="API Name of field, to be used to show text"/>
    <aura:attribute name="field_API_val" type="String" access="public" 
                    description="API Name of field, to be returned from component"/>
    <aura:attribute name="field_API_search" type="String" access="public" 
                    description="API Name of field to be searched"/>
    <aura:attribute name="limit" type="Integer" access="public" default="5" 
                    description="Total number of record to be returned"/>
    <aura:attribute name="placeholder" type="String" access="public" 
                    default="Space character is used to search" />
    <aura:attribute name="last_SearchText" type="String" access="private" />
    <aura:attribute name="last_ServerResult" type="object[]" access="private" /> 

    <div class="slds">      
        <div class="slds-form-element"> 
            <div class="slds-form-element__control">
                <div class="slds-combobox_container slds-has-inline-listbox">
                    <div class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-is-open" 
                         aria-expanded="true" aria-haspopup="listbox" role="combobox" style="width:95%">
                        <div class="slds-combobox__form-element slds-input-has-icon slds-input-has-icon_right">
                            <div> 
                                <aura:if isTrue="{! empty(v.selItem) }"> 
                                         <input type="text" class="slds-input slds-combobox__input" id="combobox-unique-id" 
                                                aria-activedescendant="listbox-option-unique-id-01" aria-autocomplete="list" 
                                                aria-controls="listbox-unique-id" autocomplete="off" role="combobox" 
                                                placeholder="{!v.placeholder}" 
                                                oninput="{!c.serverCall}" />
                                        
                                        <aura:set attribute="else"> 
                                                <span class="slds-pill slds-pill_link fullWidth"> 
                                                  <a href="javascript:void(0);" 
                                                     class="slds-pill__action slds-p-left_x-small" title="{#v.selItem.text}">
                                                    <lightning:icon iconName="{#v.lookupIcon}" size="x-small"/>
                                                    <span class="slds-pill__label slds-p-left_x-small">{#v.selItem.text}</span>
                                                  </a>
                                                  <button onclick="{!c.clearSelection}" 
                                                          class="slds-button slds-button_icon slds-button_icon slds-pill__remove" 
                                                          title="Remove">
                                                    <lightning:icon iconName="utility:close" size="small" 
                                                                    alternativeText="Press delete or backspace to remove"/>
                                                    <span class="slds-assistive-text" >Remove</span>
                                                  </button>
                                                </span> 
                                        </aura:set>
                                    </aura:if> 
                           	 	</div> 
                            </div>
                            <aura:if isTrue="{! greaterthanorequal(v.server_result.length,1) }"> 
                                <div id="listbox-unique-id" role="listbox">
                                    <ul class="slds-listbox slds-listbox_vertical slds-dropdown slds-dropdown_fluid" role="presentation"
                                        style="display: block; min-width: auto; max-width: 100% ; width: 100%;">
                                        <aura:iteration items="{!v.server_result}" var="item" indexVar="i">
                                            <li role="presentation" class="slds-listbox__item" data-selectedIndex="{#i}" 
                                                onclick="{!c.itemSelected}">
                                                <span id="{#'listbox-option-unique-id-'+i+1}"  
                                                      class="slds-media slds-listbox__option slds-listbox__option_entity 
                                                             slds-listbox__option_has-meta" 
                                                      role="option">
                                                    <span class="slds-media__figure optionIcon">
                                                        <span class="slds-icon_container" >
                                                            <lightning:icon iconName="{#v.lookupIcon}" size="small"/>
                                                            <span class="slds-assistive-text">{#v.objectName}</span>
                                                        </span>
                                                    </span>
                                                    <span class="slds-media__body singleRow">
                                                        <span 
                                                              class="optionTitle slds-listbox__option-text 
                                                                     slds-listbox__option-text_entity">{#item.text}</span>
                                                    </span>
                                                </span>
                                            </li>
                                        </aura:iteration> 
                                    </ul>
                                </div>
                            </aura:if> 
                        </div>
                    </div>
                </div>
            </div> 
    </div>     
</aura:component>

userLookupController.js

({
	itemSelected : function(component, event, helper) {
		helper.itemSelected(component, event, helper);
	}, 
    serverCall :  function(component, event, helper) {
		helper.serverCall(component, event, helper);
	},
    clearSelection : function(component, event, helper){
        helper.clearSelection(component, event, helper);
    } 
})
usernameLookupHelper.js
({
	itemSelected : function(component, event, helper) {
        var target = event.target;   
        var SelIndex = helper.getIndexFrmParent(target,helper,"data-selectedIndex");  
        if(SelIndex){
            var serverResult = component.get("v.server_result");
            var selItem = serverResult[SelIndex];
            if(selItem.val){
               component.set("v.selItem",selItem);
               component.set("v.last_ServerResult",serverResult);
            } 
            component.set("v.server_result",null); 
        } 
	}, 
    serverCall : function(component, event, helper) {  
        var target = event.target;  
        var searchText = target.value; 
        var last_SearchText = component.get("v.last_SearchText");
        //Escape button pressed 
        if (event.keyCode == 27 || !searchText) { 
            helper.clearSelection(component, event, helper);
        }else if(searchText != last_SearchText  && /\s+$/.test(searchText) ){ 
            //Save server call, if last text not changed
            //Search only when space character entered
         
            var objectName = component.get("v.objectName");
            var field_API_text = component.get("v.field_API_text");
            var field_API_val = component.get("v.field_API_val");
            var field_API_search = component.get("v.field_API_search");
            var limit = component.get("v.limit");
            
            var action = component.get('c.searchDB');
            action.setStorable();
            
            action.setParams({
                objectName : objectName,
                fld_API_Text : field_API_text,
                fld_API_Val : field_API_val,
                lim : limit, 
                fld_API_Search : field_API_search,
                searchText : searchText
            });
    
            action.setCallback(this,function(a){
                this.handleResponse(a,component,helper);
            });
            
            component.set("v.last_SearchText",searchText);
            console.log('Server call made');
            $A.enqueueAction(action); 
        }else if(searchText && last_SearchText && searchText == last_SearchText){ 
            component.set("v.server_result",component.get("v.last_ServerResult"));
            console.log('Server call saved');
        }         
	},
    handleResponse : function (res,component,helper){
        if (res.getState() === 'SUCCESS') {
            var retObj = JSON.parse(res.getReturnValue());
            if(retObj.length <= 0){
                var noResult = JSON.parse('[{"text":"No Results Found"}]');
                component.set("v.server_result",noResult); 
            	component.set("v.last_ServerResult",noResult);
            }else{
                component.set("v.server_result",retObj); 
            	component.set("v.last_ServerResult",retObj);
            }  
        }else if (res.getState() === 'ERROR'){
            var errors = res.getError();
            if (errors) {
                if (errors[0] && errors[0].message) {
                    alert(errors[0].message);
                }
            } 
        }
    },
    getIndexFrmParent : function(target,helper,attributeToFind){
        //User can click on any child element, so traverse till intended parent found
        var SelIndex = target.getAttribute(attributeToFind);
        while(!SelIndex){
            target = target.parentNode ;
			SelIndex = helper.getIndexFrmParent(target,helper,attributeToFind);           
        }
        return SelIndex;
    },
    clearSelection: function(component, event, helper){
        component.set("v.selItem",null);
        component.set("v.server_result",null);
    } 
})
And this is how it is on the parent component:
<div class="slds">
                                <div class="slds-grid slds-wrap slds-p-bottom_xx-large">
                                    <div class="slds-size_1-of-1 
                                                slds-small-size_1-of-1 
                                                slds-medium-size_1-of-2 
                                                slds-large-size_1-of-2 ">
                                        <c:usernameLookup objectName="User"
                                                  field_API_text="Name"
                                                  field_API_val="Username"
                                                  limit="4"
                                                  field_API_search="Name"
                                                  lookupIcon="standard:user" 
                                                  selItem="{!v.selItem}" 
                                                  placeholder="Enter space after text to search Users"
                                                  />  
                                                  <aura:if isTrue="{! not(empty(v.selItem)) }"> 
                                                    <br />
                                                    User Selected : {#v.selItem.text}<br />
                                                    Username - {#v.selItem.val} <br /> 
                                                </aura:if> 
                                    </div>
                                </div>
                            </div>

 

Hi,

I am trying to show a footer with navigation buttons on this lwc when the "currentStep" attribute reaches 5. This child component gets the number of "currentStep" from the parent. Once the 'Next' button is pressed, I want it to change the number to 6. I can't figure out how to send the change in number of 'currentStep' to the parent component.

shortened version of lwc.html - 

<footer class="slds-modal__footer slds-modal__footer_directional">
     <div if:true={currentStepCheck}>
            <lightning-button  variant="neutral" label="Back" icon-name="utility:back" icon-position="left"  title="Back" onclick={moveBack}>
            </lightning-button>
            <lightning-button variant="brand"  label="Next" icon-name="utility:forward  icon-position="right" title="Next" onclick={moveNext}>
            </lightning-button>
      </div>
</footer>
shortened lwc.js
import { LightningElement, api} from 'lwc';

export default class PtmForWizard extends LightningElement {
    @api recordId;
    @api parentId;
    @api currentStep;

    currentStepCheck(){
        this.currentStep = '5';
    }
    moveNext(){
         this.currentStep = '6';
    }
      moveBack(){
        this.currentStep = '4';
   }
}
shortened parent.cmp
<aura:component  implements="flexipage:availableForRecordHome,force:hasRecordId,flexipage:availableForAllPageTypes,force:lightningQuickAction,force:appHostable" access="global"> 
    <aura:attribute name="recordId" type="Id"/>
    <aura:attribute name="parentId" type="Id"/>
    <aura:attribute name="currentStep" type="String" default="1"/>

    <aura:registerEvent name="recordUpdated" type="c:selectedsObjectRecordsEvent"/>

     <force:recordData aura:id="record"
                      layoutType="FULL"
                      recordId="{!v.recordId}"
                      targetRecord="{!v.record}"
                      targetFields="{!v.efRecord }"
                      mode="VIEW"/>

     <div class="{!v.currentStep == '5' ? 'slds-show' : 'slds-hide'}" >
             <c:ptmForWizard recordId="{!v.efRecord.jstcl__PlacementTeamMember__c}" aura:id="childCmp5" parentId="{!v.recordId}" currentStep="{!v.currentStep}"/>
      </div>
</aura:component>
shortened parent.js

 
I have a component that displays a list retrieved from an Apex method along with a section to add to the list featured below it. Once the user adds to the list, I want to call the apex method to rerender the list to show the updated version with the newly added record. Here's what I have so far: 

Aplex class:
public class getPTM {
@AuraEnabled(cacheable=true)
    public static List<jstcl__PlacementTeamMember__c> plcWizGetPTM(List<Id> plcIds) {
        return [SELECT id,jstcl__Placement__r.Name,jstcl__User__r.Name,jstcl__CommissionPlan__r.Name,jstcl__SplitPercent__c 
                   FROM jstcl__PlacementTeamMember__c 
                   WHERE jstcl__Placement__r.Id IN :plcIds ];
    }
}
ptmForWizard.html
<template>
        <table class="slds-table slds-table--bordered slds-table--striped slds-table--cell-buffer">
            <thead>
                    <tr class="slds-text-heading--small slds-line-height_reset"> 
                        <th scope="col"><span class="slds-truncate">Placement  </span></th>
                        <th scope="col"><span class="slds-truncate">User</span></th>
                        <th scope="col"><span class="slds-truncate">Commission Plan</span></th>
                        <th scope="col"><span class="slds-truncate">Split Percentage</span></th>                
                    </tr>
            </thead>
            <template for:each={members.data} for:item='member'>      
                <tbody key={member.id}>
                    <tr  class="slds-hint-parent">
                        <td class="slds-truncate">{member.jstcl__Placement__r.Name}</td>
                        <td class="slds-truncate">{member.jstcl__User__r.Name}</td>
                        <td class="slds-truncate">{member.jstcl__CommissionPlan__r.Name}</td>
                        <td class="slds-truncate">{member.jstcl__SplitPercent__c} %</td>
                    </tr>
                </tbody>
            </template>
        </table>
<br/> 
    <lightning-record-edit-form object-api-name="jstcl__PlacementTeamMember__c" record-id={recordId} onsuccess={successsave}>
        <lightning-messages></lightning-messages>
        
        <div class="slds-grid slds-gutters slds-p-horizontal_small">
            <div class="slds-p-around_xx-small slds-size_2-of-8">
                <lightning-input-field 
                    field-name="jstcl__Placement__c"
                    value={parentId}>
                </lightning-input-field>
            </div>
            <div class="slds-p-around_xx-small slds-size_2-of-8">
                <lightning-input-field 
                    field-name="jstcl__User__c"
                    value={user}>
                </lightning-input-field>
           </div>
           <div class="slds-p-around_xx-small slds-size_2-of-8">
                <lightning-input-field 
                    field-name="jstcl__CommissionPlan__c"
                    value={commPlan}>
                </lightning-input-field>
            </div>
            <div class="slds-p-around_xx-small slds-size_1-of-8">
                <lightning-input-field 
                    field-name="jstcl__SplitPercent__c"
                    value={splitPer}>
                </lightning-input-field>
            </div>
            <div class="slds-p-around_xx-small slds-size_1-of-8 slds-m-top_large">
                <lightning-button type="submit"
                                  variant="brand" 
                                  icon-name="utility:add"
                                  title = "Add User"
                                  label="Add User">
                </lightning-button>
            </div>
        </div>
    </lightning-record-edit-form>
 </template>
ptmForWizard.js
import { LightningElement, api, wire, track} from 'lwc';
import plcWizGetPTM from '@salesforce/apex/getPTM.plcWizGetPTM';

export default class PtmForWizard extends LightningElement {
    @wire(plcWizGetPTM, {plcIds: '$parentId'}) members;
    @api recordId;
    @api parentId;
    @track plcIds = '';
    @track error;
    @track members;

    successsave(){        
        plcWizGetPTM()
            .then(result => {
                this.members = result;
            })
            .catch(error => {
                this.error = error;
            });

        this.user = null;
        this.commPlan = null;
        this.splitPer = '';
    }
}

 

Hello I need help writing a tet class for a trigger. 

Trigger-
 

trigger addPTMplc on jstcl__PlacementTeamMember__c (after insert) {

    List<ID> listIds = new List<ID>();
    
    for(jstcl__PlacementTeamMember__c ptm : Trigger.new){
        listIds.add(ptm.jstcl__Placement__c);
    }
    List<String> lstNames = new List<String>();
    List<ts2__Placement__c> plcList = [SELECT Id, ts2__Filled_By__c FROM ts2__Placement__c WHERE Id IN :listIds];
    for(jstcl__PlacementTeamMember__c ptm : [SELECT jstcl__User__r.name , jstcl__SplitPercent__c From jstcl__PlacementTeamMember__c WHERE jstcl__Placement__c IN :listIds AND jstcl__CommissionPlan__r.name LIKE '%Recruiter%' ORDER BY jstcl__SplitPercent__c DESC NULLS LAST LIMIT 1]){
        
        if(lstNames.contains(ptm.jstcl__User__r.Name)){

        }
        else{
            lstNames.add(ptm.jstcl__User__c);
        }
    for(integer i=0;i<plcList.size();i++){
        String names = string.join(lstNames, ', ');
        plcList[i].ts2__Filled_By__c =names;
        }
    }
    update plcList;
    
    
    List<ID> listIds2 = new List<ID>();
    
    for(jstcl__PlacementTeamMember__c ptm2 : Trigger.new){
        listIds2.add(ptm2.jstcl__Placement__c);
    }
    List<String> lstNames2 = new List<String>();
    List<ts2__Placement__c> plcList2 = [SELECT Id, ts2__Sales_Rep__c FROM ts2__Placement__c WHERE Id IN :listIds2];
    for(jstcl__PlacementTeamMember__c ptm2 : [SELECT jstcl__User__r.name From jstcl__PlacementTeamMember__c WHERE jstcl__Placement__c IN :listIds2 AND jstcl__CommissionPlan__r.name LIKE '%Account Executive%' ORDER BY jstcl__SplitPercent__c DESC NULLS LAST LIMIT 1]){
        
        if(lstNames2.contains(ptm2.jstcl__User__r.Name)){

        }
        else{
            lstNames2.add(ptm2.jstcl__User__c);
        }
    for(integer i=0;i<plcList2.size();i++){
        String names2 = string.join(lstNames2, ', ');
        plcList2[i].ts2__Sales_Rep__c =names2;
        }
    }
    update plcList2;
}

What I have so far for the test class-
@isTest(SeeAllData=true)
public class addPTMplcTest {
    private static testMethod void testPTM(){
 ADP_Department__c adp = new ADP_Department__c();
        adp.Name = 'Georgia';
        insert adp;
         Contact con=new Contact(
            FirstName='fname',
            LastName = 'lname',
            Email = 'email@gmail.com',
            Phone = '9743800309'); 
        insert con; 
       
        ts2__Job__c job = new ts2__Job__c();
        job.Name = 'Software Engineer';
        insert job;
        Account acc = new Account(Name = 'Test Company');
        insert acc;
        ts2__HolidayCalendar__c hcal = new ts2__HolidayCalendar__c();
        hcal.Name= 'Holiday Calendar';
        insert hcal;
        Labor_Category__c lcat = new Labor_Category__c(Name='Software Engineer 1');  
        insert lcat;
         ts2__Placement__c plc = new ts2__Placement__c();
        plc.ts2__Job__c = job.Id;
        plc.Contractor_Type__c = 'Test';
        plc.Onboarding_Method__c= 'Staff Augmentation';
        plc.ts2__Start_Date__c= Date.newInstance(2019, 1, 7);
        plc.ts2__End_Date__c= Date.newInstance(2019, 2, 15);
        plc.jstcl__HireType__c= 'W2';
        plc.ADP_Department__c= adp.Id;
        plc.ts2__Bill_Rate__c= 60.00;
        plc.ts2__Pay_Rate__c= 30.00;
        plc.jstcl__Invoice_Batch__c= 'Placement';
        plc.ts2__Client__c= acc.Id;
        plc.ts2__Hiring_Manager__c= con.Id;
        plc.jstcl__TimecardApprover__c= con.Id;
        plc.jstcl__HolidayCalendar__c= hcal.Id;
		plc.State_Worked_In_Non_TFI_Placements__c= 'GA - Georgia';
        plc.jstcl__Overtime_Bill_Rate__c= 60;
        plc.jstcl__Burden__c= 0.20;
        plc.jstcl__Accounts_Receivable_U__c= '00537000005d7F2AAI';
        plc.jstcl__Terms__c= 'Net 60';
        plc.ts2__Employee__c= con.Id;
        plc.Labor_Category__c= lcat.Id;
        plc.Placement_Team_Member_List__c= 'Test User';
        insert plc;
        User u = new User(
 	    ProfileId = [SELECT Id FROM Profile WHERE Name = 'National Sales'].Id,
	     LastName = 'last',
    	 Email = 'abc@123.com',
	     Username = 'abc@123.com',
    	 CompanyName = 'TEST',
   	 	 Title = 'title',
   	 	 Alias = 'alias',
   		 TimeZoneSidKey = 'America/Los_Angeles',
     	 EmailEncodingKey = 'UTF-8',
    	 LanguageLocaleKey = 'en_US',
    	 LocaleSidKey = 'en_US'
		);
         
        jstcl__TG_Commission_Plan__c cp = new jstcl__TG_Commission_Plan__c(name = 'National Vertical Manager (NVM or NAM)' );
        insert cp;
        
        
        Test.startTest();
        System.debug('>>>>>>>>> Starting Test');
        jstcl__PlacementTeamMember__c ptm = new jstcl__PlacementTeamMember__c(jstcl__Placement__c = plc.Id,
                                                                              jstcl__User__c = u.Id,
                                                                              jstcl__CommissionPlan__c = cp.Id,
                                                                              jstcl__SplitPercent__c = 100);
        insert ptm;
        System.assertEquals(ptm.jstcl__User__c, plc.Placement_Team_Member_List__c);
        System.debug('>>>>>>>>> Ending Test');
        Test.stopTest();

    }
}

​​​​​​​

I am trying to run a batch class once a week to update the Filled_By__c field on the Placement__c object from the User__c field on the PlacementTeamMember__c object. I'm usure how to do this since they are unrelate objects.

This is the code I have so far-
 

global class ptmToOldCommissions implements Database.Batchable<sObject>, Database.Stateful {
	
    List<jstcl__PlacementTeamMember__c> plcTeamMemIds = [SELECT Id, jstcl__User__c FROM jstcl__PlacementTeamMember__c WHERE jstcl__CommissionPlan__r.Name LIKE '%Recruiter%' LIMIT 1];
    
	global Database.QueryLocator start(Database.BatchableContext BC){
        String plcIds = 'SELECT Id, ts2__Filled_By__c FROM ts2__Placement__c WHERE ts2__Status__c = "Active"';
        return Database.getQueryLocator(plcIds);
    }

    global void execute(Database.BatchableContext BC, List<ts2__Placement__c> scope){

        for ( ts2__Placement__c a : scope){
            for ( jstcl__PlacementTeamMember__c b : plcTeamMemIds){
                
           a.ts2__Filled_By__c = b.jstcl__User__c;
        }
            update scope;
        }
    }  
    global void finish(Database.BatchableContext BC){
    }
}
I am trying to display a message after clicking a button and I want the content of the message to change depending on whether a list, returned from a SOQL query, is empty or not. 

plcTM.cmp
<aura:component  implements="flexipage:availableForRecordHome,force:hasRecordId,flexipage:availableForAllPageTypes,force:lightningQuickAction,force:appHostable" controller="getPTM" access="global">
    
    <aura:attribute name="recordId" type="Id"/>
    <aura:attribute name="plc" type="ts2__Placement__c"/>
    
    <aura:attribute name="user" type="User"/>
    <aura:attribute name="plan" type="jstcl__TG_Commission_Plan__c"/>
    
    <aura:attribute name="doesItPass" type="String" />
    <aura:attribute name="parentId" type="String"/>
    
	<aura:handler event="c:selectedsObjectRecordsEvent" action="{!c.submitIt}" />

    <lightning:recordEditForm aura:id="editfrm" recordId="{!v.recordId}" objectApiName="jstcl__PlacementTeamMember__c" onload="{!c.onloadrec}" onsuccess="{!c.successsave}" onsubmit="{!c.onsubmittxt}" > 
        <div class="slds-grid slds-gutters slds-p-horizontal_small">
       1.     
            <div class="slds-p-around_xx-small slds-size_2-of-8">   <lightning:inputField aura:id="plc" fieldName="jstcl__Placement__c" value="{!v.parentId}"/></div>
            <div class="slds-p-around_xx-small slds-size_2-of-8">   <lightning:inputField aura:id="user" fieldName="jstcl__User__c" value="{!v.user}"/></div>
            <div class="slds-p-around_xx-small slds-size_2-of-8">   <lightning:inputField aura:id="plan" fieldName="jstcl__CommissionPlan__c" value="{!v.plan}"/></div>
            <div class="slds-p-around_xx-small slds-size_1-of-8">   <lightning:inputField aura:id="split" fieldName="jstcl__SplitPercent__c"/></div>
            <div class="slds-p-around_xx-small slds-size_1-of-8 slds-m-top_large">   <lightning:button variant="brand" iconName="utility:add" label="Add User" title="Add User" onclick="{! c.greyOut }" /></div>
        </div>
    </lightning:recordEditForm>

</aura:component>

plcTMController.js
greyOut : function(component , event , helper){
        var toastEvent = $A.get("e.force:showToast");
        
         var user = component.get("v.user");
        var plan = component.get("v.plan");
      
        
         var action = component.get("c.plcGetCPA");
        action.setParams({"userId" : user,
                          "planId" : plan                         
                         });
       
        // Add callback behavior for when response is received
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
               component.set("v.doesItPass", response.getReturnValue());
            }
            else {
                console.log("Failed with state: " + state);
             }
        });
        // Send action off to be executed
        $A.enqueueAction(action);
       
        
        var doesItPass = component.get("v.doesItPass");

   //     recUpdate.fire();
        component.set("v.isOpen", !component.get("v.isOpen"));
      if(doesItPass = 'yes'){
          toastEvent.setParams({
            title : 'Success',
              message:'Commission Plan does not match the user.' + doesItPass + user + plan,
            duration:'5000',
            key: 'info_alt',
            type: 'error',
            mode: 'pester' });
        toastEvent.fire();}   
     else { toastEvent.setParams({
            title : 'Error',
              message:'Commission Plan does not match the user.'+ doesItPass +' '+ user +' '+ plan,
            duration:'5000',
            key: 'info_alt',
            type: 'error',
            mode: 'pester' });
        toastEvent.fire();}   
        
    }
getPTM.apxc
public class getPTM {
@AuraEnabled
    public static String plcGetCPA(string userId, String planId){
        String doesItPass = '';
        List<jstcl__TG_Commission_Plan_Assignment__c> cpaList= new List<jstcl__TG_Commission_Plan_Assignment__c>();
        cpaList = [SELECT Id, jstcl__Commission_Plan__c, jstcl__User__c FROM jstcl__TG_Commission_Plan_Assignment__c WHERE jstcl__User__r.Id = :userId AND jstcl__Commission_Plan__r.Id = :planId];
        if(cpaList != null || cpaList.size() > 0){
            doesItPass = 'yes';
        }
        return doesItPass;
        
    }
}


 
I have written a subpar test class for a trigger that doesn't cover lines 33-50 on the trigger.

Trigger code:
trigger autoAddNAM_VAM on ts2__Placement__c (after insert) {
    List<jstcl__PlacementTeamMember__c> teamMems = new List<jstcl__PlacementTeamMember__c>();
     Set<Id> tsClientSet = new Set<id>();
      Map<ID, Account> tsClientmap = new Map<ID, Account> (); 
    Map<ID, Account> tsClientmap2 = new Map<ID, Account> (); 
    
    
    
 for(ts2__Placement__c newTeamMem : Trigger.New)
    {
        
        if(newTeamMem.ts2__Client__c != null)
        {
            
            tsClientSet.add(newTeamMem.ts2__Client__c);
        }
    }
    
    if(tsClientSet.size() > 0)
    {
        tsClientmap = new Map<ID, Account>([SELECT Id, National_Account_Manager__c from Account where Id IN: tsClientSet]);
        tsClientmap2 = new Map<ID, Account>([SELECT Id, Vertical_Account_Manager__c	from Account where Id IN: tsClientSet]);
    }
    for(ts2__Placement__c newTeamMem : Trigger.New){

        if(tsClientmap.Containskey(newTeamMem.ts2__Client__C))
        {
             System.debug('tsClientmap = ' + tsClientmap);
            System.debug('tsClientmap2 = ' + tsClientmap2);
                      
  try{ 
            if (tsClientmap.get(newTeamMem.ts2__Client__C).National_Account_Manager__c != null ){
                teamMems.add(new jstcl__PlacementTeamMember__c(
                        jstcl__Placement__c = newTeamMem.Id,
                        jstcl__User__c = tsClientmap.get(newTeamMem.ts2__Client__C).National_Account_Manager__c,
                        jstcl__CommissionPlan__c = [Select jstcl__Commission_Plan__c
                                                    FROM jstcl__TG_Commission_Plan_Assignment__c 
                                                    WHERE jstcl__Commission_Plan__r.Name LIKE '%NVM%' AND jstcl__User__c = :tsClientmap.get(newTeamMem.ts2__Client__C).National_Account_Manager__c LIMIT 1].jstcl__Commission_Plan__c,
                        jstcl__SplitPercent__c = 100));
            }
      else if (tsClientmap2.get(newTeamMem.ts2__Client__C).Vertical_Account_Manager__c != null ){
                teamMems.add(new jstcl__PlacementTeamMember__c(
                        jstcl__Placement__c = newTeamMem.Id,
                        jstcl__User__c = tsClientmap2.get(newTeamMem.ts2__Client__C).Vertical_Account_Manager__c,
                        jstcl__CommissionPlan__c = [Select jstcl__Commission_Plan__c
                                                    FROM jstcl__TG_Commission_Plan_Assignment__c 
                                                    WHERE jstcl__Commission_Plan__r.Name LIKE '%NVM%' AND jstcl__User__c = :tsClientmap2.get(newTeamMem.ts2__Client__C).Vertical_Account_Manager__c LIMIT 1].jstcl__Commission_Plan__c,
                        jstcl__SplitPercent__c = 100));
            }
  }catch(exception e){
       System.debug('The following exception has occurred: ' + e.getMessage());
  }   
        
    }
   
    insert teamMems;
    }
}
Test class so far:
@isTest
private class addNAM_VAMtest{
    private static testMethod void testNAM_VAM(){
        Test.startTest();
        ADP_Department__c adp = new ADP_Department__c();
        adp.Name = 'Georgia';
        insert adp;
         Contact con=new Contact(
            FirstName='fname',
            LastName = 'lname',
            Email = 'email@gmail.com',
            Phone = '9743800309'); 
        insert con; 
       
        ts2__Job__c job = new ts2__Job__c();
        job.Name = 'Software Engineer';
        insert job;
        Account acc = new Account(Name = 'Time Warner Inc.');
        insert acc;
        ts2__HolidayCalendar__c hcal = new ts2__HolidayCalendar__c();
        hcal.Name= 'Holiday Calendar';
        insert hcal;
        Labor_Category__c lcat = new Labor_Category__c(Name='Software Engineer 1');  
        insert lcat;
         ts2__Placement__c plc = new ts2__Placement__c();
        plc.ts2__Job__c = job.Id;
        plc.Contractor_Type__c = 'Technical Youth';
        plc.Onboarding_Method__c= 'Staff Augmentation';
        plc.ts2__Start_Date__c= Date.newInstance(2019, 1, 7);
        plc.ts2__End_Date__c= Date.newInstance(2019, 2, 15);
        plc.jstcl__HireType__c= 'W2';
        plc.ADP_Department__c= adp.Id;
        plc.ts2__Bill_Rate__c= 60.00;
        plc.ts2__Pay_Rate__c= 30.00;
        plc.jstcl__Invoice_Batch__c= 'Placement';
        plc.ts2__Client__c= acc.Id;
        plc.ts2__Hiring_Manager__c= con.Id;
        plc.jstcl__TimecardApprover__c= con.Id;
        plc.jstcl__HolidayCalendar__c= hcal.Id;
		plc.State_Worked_In_Non_TFI_Placements__c= 'GA - Georgia';
        plc.jstcl__Overtime_Bill_Rate__c= 60;
        plc.jstcl__Burden__c= 0.20;
        plc.jstcl__Accounts_Receivable_U__c= '00537000005d7F2AAI';
        plc.jstcl__Terms__c= 'Net 60';
        plc.ts2__Employee__c= con.Id;
        plc.Labor_Category__c= lcat.Id;
        
        insert plc;
        User u = new User(
 	    ProfileId = [SELECT Id FROM Profile WHERE Name = 'National Sales - Brooksource'].Id,
	     LastName = 'last',
    	 Email = 'puser000@amamama.com',
	     Username = 'puser000@amamama.com' + System.currentTimeMillis(),
    	 CompanyName = 'TEST',
   	 	 Title = 'title',
   	 	 Alias = 'alias',
   		 TimeZoneSidKey = 'America/Los_Angeles',
     	 EmailEncodingKey = 'UTF-8',
    	 LanguageLocaleKey = 'en_US',
    	 LocaleSidKey = 'en_US'
		);
         
        jstcl__TG_Commission_Plan__c cp = new jstcl__TG_Commission_Plan__c(name = 'National Vertical Manager (NVM or NAM)');
        insert cp;
        
        
        
        System.debug('>>>>>>>>> Starting Test');
        jstcl__PlacementTeamMember__c ptm = new jstcl__PlacementTeamMember__c(jstcl__Placement__c = plc.Id,
                                                                              jstcl__User__c = u.Id,
                                                                    //          jstcl__CommissionPlan__c = cp.Id,
                                                                              jstcl__SplitPercent__c = 100);
        insert ptm;
        
        System.assertEquals(ptm.jstcl__User__c, acc.National_Account_Manager__c);
         System.assertEquals(ptm.jstcl__User__c, acc.Vertical_Account_Manager__c);
        System.debug('>>>>>>>>> Ending Test');
        Test.stopTest();

   

    }
}


 
I can't seem to figure out how to get this test class working:

getPTM.apxc - 
public class getPTM {
@AuraEnabled
    public static List<jstcl__PlacementTeamMember__c> plcWizGetPTM(List<Id> plcIds) {
        List<jstcl__PlacementTeamMember__c> rlist= new List<jstcl__PlacementTeamMember__c>();
        rlist = [SELECT id,jstcl__Placement__r.Name,jstcl__User__r.Name,jstcl__CommissionPlan__r.Name,jstcl__SplitPercent__c 
                                                        FROM jstcl__PlacementTeamMember__c 
                                                        WHERE jstcl__Placement__r.Id IN :plcIds ];
        return rlist;
    }
}

Test class so far - 
@isTest
public class getPTMtest {
    static testMethod void testPTM(){
        jstcl__PlacementTeamMember__c testTeamMem = new jstcl__PlacementTeamMember__c();
        testTeamMem.jstcl__Placement__c = 'a211G000001IvdlQAC';
        testTeamMem.jstcl__User__c = '00537000003HbjPAAS';
        testTeamMem.jstcl__CommissionPlan__c = 'a4g370000008PGTAA2';
        testTeamMem.jstcl__SplitPercent__c = 100;
        testTeamMem.OwnerId = '00537000003HbjPAAS';
		
		  insert testTeamMem;
        
        Test.startTest();
          getPTM.plcWizGetPTM(testTeamMem, 'a211G000001IvdlQAC');
        Test.stopTest();
        
    }
}

Thanks
 
I recieved this error when testing a few things on a recently implemented trigger - "CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, addPTMplc: execution of AfterUpdate caused by: System.DmlException: Update failed"
Here's the code:
trigger addPTMplc on jstcl__PlacementTeamMember__c (after insert, after update) {

    List<ID> listIds = new List<ID>();
    
    for(jstcl__PlacementTeamMember__c ptm : Trigger.new){
        listIds.add(ptm.jstcl__Placement__c);
    }
    List<String> lstNames = new List<String>();
	List<ts2__Placement__c> plcList = [SELECT Id, Placement_Team_Member_List__c FROM ts2__Placement__c WHERE Id IN :listIds];
    for(jstcl__PlacementTeamMember__c ptm : [SELECT jstcl__User__r.name From jstcl__PlacementTeamMember__c WHERE jstcl__Placement__c IN :listIds]){
        
        if(lstNames.contains(ptm.jstcl__User__r.Name)){

        }
        else{
            lstNames.add(ptm.jstcl__User__r.Name);
        }
    for(integer i=0;i<plcList.size();i++){
        String names = string.join(lstNames, ', ');
        plcList[i].Placement_Team_Member_List__c =names;
    	}
    }
    update plcList;
}

 
I have a custom lightning component that includes a table of contact records showing columns with various fields. I am able to click the contact link and it will take me to the record page. However when I try to right click and open the link in a new tab in chrome, it opens a blank tab with the title 'about:blank#blocked'. Is there a way to get around this?

Hi, 

I am trying to query a list of the latest 10 records from the same object and look to see if they are all equal. I'm struggling to find how to get a list of 10 placements with the same client name. Here is the code that I have come up with so far - 

@AuraEnabled
    public static ts2__Placement__c getPlcClient(Id recordId) {
        List<ts2__Placement__c> plc = new List<ts2__Placement__c> ();
        plc = [
               SELECT Id, ts2__Client__r.Name 
               FROM ts2__Placement__c
               WHERE Id =:recordId
           	];
      
        List<ts2__Placement__c> plcClient = new List<ts2__Placement__c> ();
        plcClient = [
                SELECT Id FROM ts2__Placement__c
                WHERE ts2__Client__r.Name = :plc
                ORDER BY createdDate DESC LIMIT 10
        ];

        return plcClient;
    }
I'm trying to make a calculator lightning component and I got everything working fine up until the "burdenPer" field is edited. If it stays as it's default, the calculation is correct, but if that particular field is edited the calculation jumps down to the negative thousands. 

component:
<aura:component implements="flexipage:availableForAllPageTypes"
                access="global">
    
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="placement" type="ts2__Placement__c" />
    
        <force:recordData recordId="{!v.recordId}" 
                          targetFields="{!v.placement}" 
                          layoutType="FULL" 
                          recordUpdated="{!c.recordUpdated}"/>
        
    <aura:attribute name="burden" type="Integer" />
    <aura:attribute name="hours" type="Integer" default="40"/>
    <aura:attribute name="payrate" type="Decimal" default="0.00"/>
    <aura:attribute name="billrate" type="Decimal" default="0.00"/>
    <aura:attribute name="burdenPer" type="Decimal" default="0.20"/>

 	<!-- Overtime items -->
    <aura:attribute name="othours" type="Integer" default="0"/>
    <aura:attribute name="otbillrate" type="Decimal" default="0.00"/>
    <aura:attribute name="otpayrate" type="Decimal" default="0.00"/>
    
    <!--Net spread items -->
    <aura:attribute name="miscSpreadDed" type="Decimal" default="0.00"/>
    <aura:attribute name="nonbillexp" type="Decimal" default="0.00"/>
    <aura:attribute name="nonbilloth" type="Decimal" default="0.00"/>
    <aura:attribute name="nonbillbon" type="Decimal" default="0.00"/>
    <aura:attribute name="referfee" type="Decimal" default="0.00"/>
    <aura:attribute name="compbon" type="Decimal" default="0.00"/>
    <aura:attribute name="vms" type="Decimal" default="0.00"/>
    <aura:attribute name="discount" type="Decimal" default="0.00"/>
    <aura:attribute name="perdiem" type="Decimal" default="0.00"/>
    
    
    <aura:attribute name="spread" type="Decimal"/>
    <aura:attribute name="netspread" type="Decimal"/>

  
    <aura:registerEvent name="change" type="c:spreadEvent"/>
    
    <aura:handler name="change" value="{!v.hours}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.payrate}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.billrate}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.vms}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.discount}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.perdiem}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.othours}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.otbillrate}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.otpayrate}" action="{!c.calculateSpread}"/>
	<aura:handler name="change" value="{!v.burdenPer}" action="{!c.calculateSpread}"/>
    
    <aura:handler name="change" value="{!v.miscSpreadDed}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.nonbillexp}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.nonbilloth}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.nonbillbon}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.referfee}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.compbon}" action="{!c.calculateSpread}"/>

    <aura:handler name="init" value="{!this}" action="{!c.calculateSpread}" />
	
	<div> <div class="title2">Spread Calculator: </div>
        <div class="input">
            <lightning:input aura:id="hours" type="number" label="Hours worked a week:" step="0.1" value="{!v.hours}"/>
            <lightning:input aura:id="payrate" type="number" label="Pay rate:" formatter="currency"  step="0.01" value="{!v.payrate}"/>
            <lightning:input aura:id="billrate" type="number" label="Bill Rate:" formatter="currency"  step="0.01" value="{!v.billrate}"></lightning:input>

            <!-- drop down code -->
            
            <div class="slds-page-header11" style="cursor: pointer;" onclick="{!c.sectionOne}">
              <section class="slds-clearfix">
                <div class="slds-float--left ">
                    <lightning:icon class="slds-show" aura:id="articleOne" iconName="utility:right" size="xx-small" alternativeText="Indicates add"/>
                    <lightning:icon class="slds-hide" aura:id="articleOne" iconName="utility:down" size="xx-small" alternativeText="Indicates dash"/>
                </div>
                <div class="slds-m-left-x-small">Overtime Entry (optional)</div>
              </section>
   			</div>
            <div class="slds-hide slds-p-around--medium" aura:id="articleOne">
               <lightning:input aura:id="othours" type="number" label="Overtime hours worked a week:" step="0.1" value="{!v.othours}"/>
               <lightning:input aura:id="otpayrate" type="number" label="Overtime Pay Rate:" formatter="currency" step="0.01" value="{!v.otpayrate}"/>
               <lightning:input aura:id="otbillrate" type="number" label="Overtime Bill Rate:" formatter="currency" step="0.01" value="{!v.otbillrate}"/>
            </div>
            
             
           
                        <lightning:input aura:id="burdenPer" type="number" label="Burden:" formatter="percent"  step="0.01" value="{!v.burdenPer}"></lightning:input>
						 <lightning:helptext content="Enter burden in decimal form. (Example: .03 = 3%)"/> 
           
        </div>
        <div class="result">
            Spread Amount: 
            <br/>
            <lightning:formattedNumber value="{!v.spread}" style="currency" currencyCode="USD"/>
        </div>
        
        <!-- Net Spread dropdown -->

            
        <div class="slds-page-header11" style="cursor: pointer;" onclick="{!c.sectionOne1}">
          <section class="slds-clearfix">
            <div class="slds-float--left ">
                <lightning:icon class="slds-show" aura:id="articleOne1" iconName="utility:right" size="xx-small" alternativeText="Indicates add"/>
                <lightning:icon class="slds-hide" aura:id="articleOne1" iconName="utility:down" size="xx-small" alternativeText="Indicates dash"/>
            </div>
            <div class="slds-m-left-x-small">Calculate Net Spread</div>
          </section>
    	</div>
        
        <div class="slds-hide slds-p-around--medium" aura:id="articleOne1">
                        <lightning:helptext content="Enter percentages in decimal form. (Example: .03 = 3%)"/> 

            <lightning:input aura:id="vms" type="number" label="VMS Fee:" formatter="percent"  step="0.01" value="{!v.vms}"></lightning:input>
            <lightning:input aura:id="discount" type="number" label="Discount Fee:" formatter="percent"  step="0.01" value="{!v.discount}"></lightning:input>
            <lightning:input aura:id="perdiem" type="number" label="Per Diem:" formatter="currency"  step="0.01" value="{!v.perdiem}"></lightning:input>
            <lightning:input aura:id="miscSpreadDed" type="number" label="Misc Spread Deductions:" formatter="currency"  step="0.01" value="{!v.miscSpreadDed}"></lightning:input>
            <lightning:input aura:id="nonbillexp" type="number" label="All Nonbillable Expenses" formatter="currency"  step="0.01" value="{!v.nonbillexp}"></lightning:input>
            <lightning:input aura:id="nonbilloth" type="number" label="Nonbillable Other Earnings" formatter="currency"  step="0.01" value="{!v.nonbilloth}"></lightning:input>
            <lightning:input aura:id="nonbillbon" type="number" label="Nonbillable Bonus" formatter="currency"  step="0.01" value="{!v.nonbillbon}"></lightning:input>
            <lightning:input aura:id="referfee" type="number" label="Referral Fees" formatter="currency"  step="0.01" value="{!v.referfee}"></lightning:input>
            <lightning:input aura:id="compbon" type="number" label="Completion Bonus" formatter="currency"  step="0.01" value="{!v.compbon}"></lightning:input>

 			<div class="result">
                Net Spread Amount: 
                <br/>
                <lightning:formattedNumber value="{!v.netspread}" style="currency" currencyCode="USD"/>
        	</div>        
        
        </div>

    </div>    
    
</aura:component>
helper:
({
	calculateSpread : function(component) {
        // 1. Calculate monthly payment
        var payrate = component.get("v.payrate");
        var billrate = component.get("v.billrate");
        var burdenPer = component.get("v.burdenPer");
        var hours = component.get("v.hours");
        var othours = component.get("v.othours");
        var otbillrate = component.get("v.otbillrate");
        var otpayrate = component.get("v.otpayrate");
        	 var vms = component.get("v.vms");
        	 var discount = component.get("v.discount");
        	 var perdiem = component.get("v.perdiem");
         	 var miscSpreadDed = component.get("v.miscSpreadDed");
             var nonbillexp = component.get("v.nonbillexp");
             var nonbilloth = component.get("v.nonbilloth");
             var nonbillbon = component.get("v.nonbillbon");
             var referfee = component.get("v.referfee");
             var compbon = component.get("v.compbon");
        
        
        if (payrate && billrate > 0){
            
            var totalBillings = (hours * billrate) + (othours * otbillrate);
            var totalPayroll = (hours * payrate) + (othours * otpayrate);
            var totburden = (1 + burdenPer)
            var spread = totalBillings - (totalPayroll * (totburden));
                
        	component.set("v.spread", spread);
            
            var vmsfee = billrate * (1- vms);
            var discountfee = billrate * (1-discount);
            
            var netVariables = (perdiem + miscSpreadDed + nonbillexp + nonbilloth + nonbillbon + vmsfee + discountfee + referfee + compbon)
            var netspread = spread - netVariables
            component.set("v.netspread", netspread);

            
            
            // 2. Fire event with new spread data
            var event = $A.get("e.c:spreadEvent");
            event.setParams({"payrate": payrate,
                             "billrate": billrate,
                             "burdenPer": burdenPer,
                             "vms": vms,
                             "discount": discount,
                             "hours": hours,
                             "perdiem": perdiem,
                             "othours": othours,
                             "otbillrate": otbillrate,
                             "otpayrate": otpayrate,
                                "miscSpreadDed": miscSpreadDed,
                                "nonbillexp": nonbillexp,
                                "nonbilloth": nonbilloth,
                                "nonbillbon": nonbillbon,
                                "referfee": referfee,
                                "compbon": compbon,
                             "netspread": netspread,
                             "spread": spread});
            event.fire();
        }
	},
    	helperFun : function(component,event,secId) {
	  var acc = component.find(secId);
        	for(var cmp in acc) {
        	$A.util.toggleClass(acc[cmp], 'slds-show');  
        	$A.util.toggleClass(acc[cmp], 'slds-hide');  
       }
	},
    
	helperFun1 : function(component,event,secId1) {
	  var acc1 = component.find(secId1);
        	for(var cmp1 in acc1) {
        	$A.util.toggleClass(acc1[cmp1], 'slds-show');  
        	$A.util.toggleClass(acc1[cmp1], 'slds-hide');  
       }
	}
})

 
I'm trying to update a field on ts2__Placement__c records that meet the criteria. I believe it's because I am doing a DML statement within a for loop. How do I avoid this and get the same results?
 
public class plc2WeekAudit implements Database.Batchable<sObject>, Database.Stateful {
    
    List<Change_Request__c> plcList = [SELECT Related_Placement__c FROM Change_Request__c WHERE End_Date__c != null AND Related_Placement__r.ts2__Status__c ='Active' AND Related_Placement__r.ts2__End_Date__c < LAST_N_MONTHS:1];
    Set<String> duplicatePlc = new Set<String>();

    public Database.QueryLocator start(Database.BatchableContext bc) {
        for(Change_Request__c item : plcList){
                duplicatePlc.add(item.Related_Placement__c);
        }
        System.debug('the size is : ' +duplicatePlc.size());
        System.debug(duplicatePlc);

        return Database.getQueryLocator('SELECT Id,ts2__Status__c FROM ts2__Placement__c WHERE Id IN :duplicatePlc');    
    }
    public void execute(Database.BatchableContext BC, List<ts2__Placement__c> returnedPlcs){
        System.debug(returnedPlcs);
        for(ts2__Placement__c plc : returnedPlcs){
            plc.ts2__Status__c = 'Inactive';
        }
        update returnedPlcs;
    }
    public void finish(Database.BatchableContext BC){
    }
}

 
What I have so far covers 26% of the batch class. I'm not able to cover the execute portion of the batch class.

batch.cls
public class Batch implements Database.Batchable<sObject> {

	public Database.QueryLocator start(Database.BatchableContext bc) {
        String query = 'SELECT Id, jstcl__Consultant__r.Previous_Timesheet_Status__c FROM jstcl__TG_Timesheet__c WHERE jstcl__Placement__r.ts2__Status__c =\'Active\' AND jstcl__Placement__r.VMS__c = \'\' AND jstcl__Week_Ending__c = LAST_N_DAYS:4 AND jstcl__Status__c = \'Pending\'';
          return Database.getQueryLocator(query);
    }
   public void execute(Database.BatchableContext BC, List<jstcl__TG_Timesheet__c> timesheets){
       List<Contact> consultants = new List<Contact>();
       List<Contact> consultants2 = new List<Contact>();

       for(jstcl__TG_Timesheet__c timesheet : timesheets){
           Contact consultant = timesheet.jstcl__Consultant__r; 
           if (consultant == null) continue;
           consultant.Previous_Timesheet_Status__c = 'Pending';
           if(consultants.contains(consultant)){
               consultants2.add(consultant);
           }else{consultants.add(consultant);}
           }
           update consultants;
        }
   public void finish(Database.BatchableContext BC){}
}
test.cls
@istest 
private class Test {

static TestMethod void hfTest() {
     Profile prof = [select id from profile where name='system Administrator'];
     User usr = new User(alias = 'usr', email='us.name@vmail.com',
                emailencodingkey='UTF-8', lastname='lstname',
                timezonesidkey='America/Los_Angeles',
                languagelocalekey='en_US',
                localesidkey='en_US', profileid = prof.Id,
                username='testuser128@testorg.com');
                insert usr;
    Id idRecordId = Schema.SObjectType.Contact.getRecordTypeInfosByDeveloperName().get('Candidate').getRecordTypeId();

    	ts2__Source__c source = new ts2__Source__c(Name = 'LinkedIn.com - Resume Search');
    	Account acc = new Account(Name = 'Express Scripts Holding Company');
        insert acc;
  		Account acc2 = new Account(Name = 'Candidates- 10-2018');
        insert acc2;
    	Contact con = new Contact(FirstName='fnadmes', LastName = 'lnamdes', Email = 'emadils@gmail.com', Phone = '9744800300', AccountId = acc2.Id, ts2__Source__c = source.Id, ts2__People_Status__c = 'Placed');
        Contact con2=new Contact(FirstName='fnames', LastName = 'lnames', Email = 'emails@gmail.com', Phone = '9743800300', AccountId=acc.Id, Relationship_Status__c = 'Lunch'); 
    	insert con; insert con2;
        ADP_Department__c adp = new ADP_Department__c(Name = 'Georgia');
        insert adp;
        ts2__Job__c job = new ts2__Job__c(Name = 'Software Engineer',Hiring_Manager_Contact__c = con2.Id);
        insert job;
        ts2__HolidayCalendar__c hcal = new ts2__HolidayCalendar__c(Name= 'Holiday Calendar');
        insert hcal;
        Labor_Category__c lcat = new Labor_Category__c(Name='Software Engineer 1');  
        insert lcat;
        ts2__Placement__c plc = new ts2__Placement__c(ts2__Job__c = job.Id, Contractor_Type__c = 'Technical Youth', Onboarding_Method__c= 'Staff Augmentation', ts2__Start_Date__c= Date.newInstance(2019, 1, 7), ts2__End_Date__c= Date.newInstance(2019, 2, 15),
        jstcl__HireType__c= 'W2', ADP_Department__c= adp.Id, ts2__Bill_Rate__c= 60.00, ts2__Pay_Rate__c= 30.00, jstcl__Invoice_Batch__c= 'Placement', ts2__Client__c= acc.Id, ts2__Hiring_Manager__c= con2.Id, jstcl__TimecardApprover__c= con2.Id, jstcl__HolidayCalendar__c= hcal.Id,
		State_Worked_In_Non_TFI_Placements__c= 'GA - Georgia', jstcl__Overtime_Bill_Rate__c= 60, jstcl__Burden__c= 0.20, jstcl__Accounts_Receivable_U__c= '00537000005d7F2AAI', jstcl__Terms__c= 'Net 60', ts2__Employee__c= con.Id, Labor_Category__c= lcat.Id);
		insert plc;
     	List<jstcl__TG_Timesheet__c> tsList = new List<jstcl__TG_Timesheet__c>();
    	 jstcl__TG_Timesheet__c ts = new jstcl__TG_Timesheet__c(jstcl__Consultant__c = con2.Id, jstcl__Placement__c = plc.Id, jstcl__Week_Ending__c = Date.newInstance(2019, 2, 15));
    tsList.add(ts);

	Test.startTest(); 
     Batch abcd = new Batch();
     ID batchprocessid = Database.executeBatch(abcd);
	Test.stopTest();
 }    
}

 

I am trying to get the sum of a result from a parent-child query and insert the sum into a field on the parent. The object placement__c has a child record timesheet__c with the field, hours__c, for each week. I am trying to get the total of approved hours for the last 2 weeks on the placement__c record through a batch class. I can get the timesheet__c records grouped with this SOQL query of the placements__c, but I'm not sure how to get to the final product of adding them.

SELECT Id, Name, (SELECT jstcl__Total_Hours__c FROM jstcl__Timesheets__r WHERE jstcl__Week_Ending__c = LAST_N_DAYS:15 AND jstcl__Status__c = 'Approved') FROM ts2__Placement__c

Hello I need help writing a tet class for a trigger. 

Trigger-
 

trigger addPTMplc on jstcl__PlacementTeamMember__c (after insert) {

    List<ID> listIds = new List<ID>();
    
    for(jstcl__PlacementTeamMember__c ptm : Trigger.new){
        listIds.add(ptm.jstcl__Placement__c);
    }
    List<String> lstNames = new List<String>();
    List<ts2__Placement__c> plcList = [SELECT Id, ts2__Filled_By__c FROM ts2__Placement__c WHERE Id IN :listIds];
    for(jstcl__PlacementTeamMember__c ptm : [SELECT jstcl__User__r.name , jstcl__SplitPercent__c From jstcl__PlacementTeamMember__c WHERE jstcl__Placement__c IN :listIds AND jstcl__CommissionPlan__r.name LIKE '%Recruiter%' ORDER BY jstcl__SplitPercent__c DESC NULLS LAST LIMIT 1]){
        
        if(lstNames.contains(ptm.jstcl__User__r.Name)){

        }
        else{
            lstNames.add(ptm.jstcl__User__c);
        }
    for(integer i=0;i<plcList.size();i++){
        String names = string.join(lstNames, ', ');
        plcList[i].ts2__Filled_By__c =names;
        }
    }
    update plcList;
    
    
    List<ID> listIds2 = new List<ID>();
    
    for(jstcl__PlacementTeamMember__c ptm2 : Trigger.new){
        listIds2.add(ptm2.jstcl__Placement__c);
    }
    List<String> lstNames2 = new List<String>();
    List<ts2__Placement__c> plcList2 = [SELECT Id, ts2__Sales_Rep__c FROM ts2__Placement__c WHERE Id IN :listIds2];
    for(jstcl__PlacementTeamMember__c ptm2 : [SELECT jstcl__User__r.name From jstcl__PlacementTeamMember__c WHERE jstcl__Placement__c IN :listIds2 AND jstcl__CommissionPlan__r.name LIKE '%Account Executive%' ORDER BY jstcl__SplitPercent__c DESC NULLS LAST LIMIT 1]){
        
        if(lstNames2.contains(ptm2.jstcl__User__r.Name)){

        }
        else{
            lstNames2.add(ptm2.jstcl__User__c);
        }
    for(integer i=0;i<plcList2.size();i++){
        String names2 = string.join(lstNames2, ', ');
        plcList2[i].ts2__Sales_Rep__c =names2;
        }
    }
    update plcList2;
}

What I have so far for the test class-
@isTest(SeeAllData=true)
public class addPTMplcTest {
    private static testMethod void testPTM(){
 ADP_Department__c adp = new ADP_Department__c();
        adp.Name = 'Georgia';
        insert adp;
         Contact con=new Contact(
            FirstName='fname',
            LastName = 'lname',
            Email = 'email@gmail.com',
            Phone = '9743800309'); 
        insert con; 
       
        ts2__Job__c job = new ts2__Job__c();
        job.Name = 'Software Engineer';
        insert job;
        Account acc = new Account(Name = 'Test Company');
        insert acc;
        ts2__HolidayCalendar__c hcal = new ts2__HolidayCalendar__c();
        hcal.Name= 'Holiday Calendar';
        insert hcal;
        Labor_Category__c lcat = new Labor_Category__c(Name='Software Engineer 1');  
        insert lcat;
         ts2__Placement__c plc = new ts2__Placement__c();
        plc.ts2__Job__c = job.Id;
        plc.Contractor_Type__c = 'Test';
        plc.Onboarding_Method__c= 'Staff Augmentation';
        plc.ts2__Start_Date__c= Date.newInstance(2019, 1, 7);
        plc.ts2__End_Date__c= Date.newInstance(2019, 2, 15);
        plc.jstcl__HireType__c= 'W2';
        plc.ADP_Department__c= adp.Id;
        plc.ts2__Bill_Rate__c= 60.00;
        plc.ts2__Pay_Rate__c= 30.00;
        plc.jstcl__Invoice_Batch__c= 'Placement';
        plc.ts2__Client__c= acc.Id;
        plc.ts2__Hiring_Manager__c= con.Id;
        plc.jstcl__TimecardApprover__c= con.Id;
        plc.jstcl__HolidayCalendar__c= hcal.Id;
		plc.State_Worked_In_Non_TFI_Placements__c= 'GA - Georgia';
        plc.jstcl__Overtime_Bill_Rate__c= 60;
        plc.jstcl__Burden__c= 0.20;
        plc.jstcl__Accounts_Receivable_U__c= '00537000005d7F2AAI';
        plc.jstcl__Terms__c= 'Net 60';
        plc.ts2__Employee__c= con.Id;
        plc.Labor_Category__c= lcat.Id;
        plc.Placement_Team_Member_List__c= 'Test User';
        insert plc;
        User u = new User(
 	    ProfileId = [SELECT Id FROM Profile WHERE Name = 'National Sales'].Id,
	     LastName = 'last',
    	 Email = 'abc@123.com',
	     Username = 'abc@123.com',
    	 CompanyName = 'TEST',
   	 	 Title = 'title',
   	 	 Alias = 'alias',
   		 TimeZoneSidKey = 'America/Los_Angeles',
     	 EmailEncodingKey = 'UTF-8',
    	 LanguageLocaleKey = 'en_US',
    	 LocaleSidKey = 'en_US'
		);
         
        jstcl__TG_Commission_Plan__c cp = new jstcl__TG_Commission_Plan__c(name = 'National Vertical Manager (NVM or NAM)' );
        insert cp;
        
        
        Test.startTest();
        System.debug('>>>>>>>>> Starting Test');
        jstcl__PlacementTeamMember__c ptm = new jstcl__PlacementTeamMember__c(jstcl__Placement__c = plc.Id,
                                                                              jstcl__User__c = u.Id,
                                                                              jstcl__CommissionPlan__c = cp.Id,
                                                                              jstcl__SplitPercent__c = 100);
        insert ptm;
        System.assertEquals(ptm.jstcl__User__c, plc.Placement_Team_Member_List__c);
        System.debug('>>>>>>>>> Ending Test');
        Test.stopTest();

    }
}

​​​​​​​

I am trying to run a batch class once a week to update the Filled_By__c field on the Placement__c object from the User__c field on the PlacementTeamMember__c object. I'm usure how to do this since they are unrelate objects.

This is the code I have so far-
 

global class ptmToOldCommissions implements Database.Batchable<sObject>, Database.Stateful {
	
    List<jstcl__PlacementTeamMember__c> plcTeamMemIds = [SELECT Id, jstcl__User__c FROM jstcl__PlacementTeamMember__c WHERE jstcl__CommissionPlan__r.Name LIKE '%Recruiter%' LIMIT 1];
    
	global Database.QueryLocator start(Database.BatchableContext BC){
        String plcIds = 'SELECT Id, ts2__Filled_By__c FROM ts2__Placement__c WHERE ts2__Status__c = "Active"';
        return Database.getQueryLocator(plcIds);
    }

    global void execute(Database.BatchableContext BC, List<ts2__Placement__c> scope){

        for ( ts2__Placement__c a : scope){
            for ( jstcl__PlacementTeamMember__c b : plcTeamMemIds){
                
           a.ts2__Filled_By__c = b.jstcl__User__c;
        }
            update scope;
        }
    }  
    global void finish(Database.BatchableContext BC){
    }
}
I am trying to display a message after clicking a button and I want the content of the message to change depending on whether a list, returned from a SOQL query, is empty or not. 

plcTM.cmp
<aura:component  implements="flexipage:availableForRecordHome,force:hasRecordId,flexipage:availableForAllPageTypes,force:lightningQuickAction,force:appHostable" controller="getPTM" access="global">
    
    <aura:attribute name="recordId" type="Id"/>
    <aura:attribute name="plc" type="ts2__Placement__c"/>
    
    <aura:attribute name="user" type="User"/>
    <aura:attribute name="plan" type="jstcl__TG_Commission_Plan__c"/>
    
    <aura:attribute name="doesItPass" type="String" />
    <aura:attribute name="parentId" type="String"/>
    
	<aura:handler event="c:selectedsObjectRecordsEvent" action="{!c.submitIt}" />

    <lightning:recordEditForm aura:id="editfrm" recordId="{!v.recordId}" objectApiName="jstcl__PlacementTeamMember__c" onload="{!c.onloadrec}" onsuccess="{!c.successsave}" onsubmit="{!c.onsubmittxt}" > 
        <div class="slds-grid slds-gutters slds-p-horizontal_small">
       1.     
            <div class="slds-p-around_xx-small slds-size_2-of-8">   <lightning:inputField aura:id="plc" fieldName="jstcl__Placement__c" value="{!v.parentId}"/></div>
            <div class="slds-p-around_xx-small slds-size_2-of-8">   <lightning:inputField aura:id="user" fieldName="jstcl__User__c" value="{!v.user}"/></div>
            <div class="slds-p-around_xx-small slds-size_2-of-8">   <lightning:inputField aura:id="plan" fieldName="jstcl__CommissionPlan__c" value="{!v.plan}"/></div>
            <div class="slds-p-around_xx-small slds-size_1-of-8">   <lightning:inputField aura:id="split" fieldName="jstcl__SplitPercent__c"/></div>
            <div class="slds-p-around_xx-small slds-size_1-of-8 slds-m-top_large">   <lightning:button variant="brand" iconName="utility:add" label="Add User" title="Add User" onclick="{! c.greyOut }" /></div>
        </div>
    </lightning:recordEditForm>

</aura:component>

plcTMController.js
greyOut : function(component , event , helper){
        var toastEvent = $A.get("e.force:showToast");
        
         var user = component.get("v.user");
        var plan = component.get("v.plan");
      
        
         var action = component.get("c.plcGetCPA");
        action.setParams({"userId" : user,
                          "planId" : plan                         
                         });
       
        // Add callback behavior for when response is received
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
               component.set("v.doesItPass", response.getReturnValue());
            }
            else {
                console.log("Failed with state: " + state);
             }
        });
        // Send action off to be executed
        $A.enqueueAction(action);
       
        
        var doesItPass = component.get("v.doesItPass");

   //     recUpdate.fire();
        component.set("v.isOpen", !component.get("v.isOpen"));
      if(doesItPass = 'yes'){
          toastEvent.setParams({
            title : 'Success',
              message:'Commission Plan does not match the user.' + doesItPass + user + plan,
            duration:'5000',
            key: 'info_alt',
            type: 'error',
            mode: 'pester' });
        toastEvent.fire();}   
     else { toastEvent.setParams({
            title : 'Error',
              message:'Commission Plan does not match the user.'+ doesItPass +' '+ user +' '+ plan,
            duration:'5000',
            key: 'info_alt',
            type: 'error',
            mode: 'pester' });
        toastEvent.fire();}   
        
    }
getPTM.apxc
public class getPTM {
@AuraEnabled
    public static String plcGetCPA(string userId, String planId){
        String doesItPass = '';
        List<jstcl__TG_Commission_Plan_Assignment__c> cpaList= new List<jstcl__TG_Commission_Plan_Assignment__c>();
        cpaList = [SELECT Id, jstcl__Commission_Plan__c, jstcl__User__c FROM jstcl__TG_Commission_Plan_Assignment__c WHERE jstcl__User__r.Id = :userId AND jstcl__Commission_Plan__r.Id = :planId];
        if(cpaList != null || cpaList.size() > 0){
            doesItPass = 'yes';
        }
        return doesItPass;
        
    }
}


 
I can't seem to figure out how to get this test class working:

getPTM.apxc - 
public class getPTM {
@AuraEnabled
    public static List<jstcl__PlacementTeamMember__c> plcWizGetPTM(List<Id> plcIds) {
        List<jstcl__PlacementTeamMember__c> rlist= new List<jstcl__PlacementTeamMember__c>();
        rlist = [SELECT id,jstcl__Placement__r.Name,jstcl__User__r.Name,jstcl__CommissionPlan__r.Name,jstcl__SplitPercent__c 
                                                        FROM jstcl__PlacementTeamMember__c 
                                                        WHERE jstcl__Placement__r.Id IN :plcIds ];
        return rlist;
    }
}

Test class so far - 
@isTest
public class getPTMtest {
    static testMethod void testPTM(){
        jstcl__PlacementTeamMember__c testTeamMem = new jstcl__PlacementTeamMember__c();
        testTeamMem.jstcl__Placement__c = 'a211G000001IvdlQAC';
        testTeamMem.jstcl__User__c = '00537000003HbjPAAS';
        testTeamMem.jstcl__CommissionPlan__c = 'a4g370000008PGTAA2';
        testTeamMem.jstcl__SplitPercent__c = 100;
        testTeamMem.OwnerId = '00537000003HbjPAAS';
		
		  insert testTeamMem;
        
        Test.startTest();
          getPTM.plcWizGetPTM(testTeamMem, 'a211G000001IvdlQAC');
        Test.stopTest();
        
    }
}

Thanks
 
I have a custom lightning component that includes a table of contact records showing columns with various fields. I am able to click the contact link and it will take me to the record page. However when I try to right click and open the link in a new tab in chrome, it opens a blank tab with the title 'about:blank#blocked'. Is there a way to get around this?
I'm trying to make a calculator lightning component and I got everything working fine up until the "burdenPer" field is edited. If it stays as it's default, the calculation is correct, but if that particular field is edited the calculation jumps down to the negative thousands. 

component:
<aura:component implements="flexipage:availableForAllPageTypes"
                access="global">
    
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="placement" type="ts2__Placement__c" />
    
        <force:recordData recordId="{!v.recordId}" 
                          targetFields="{!v.placement}" 
                          layoutType="FULL" 
                          recordUpdated="{!c.recordUpdated}"/>
        
    <aura:attribute name="burden" type="Integer" />
    <aura:attribute name="hours" type="Integer" default="40"/>
    <aura:attribute name="payrate" type="Decimal" default="0.00"/>
    <aura:attribute name="billrate" type="Decimal" default="0.00"/>
    <aura:attribute name="burdenPer" type="Decimal" default="0.20"/>

 	<!-- Overtime items -->
    <aura:attribute name="othours" type="Integer" default="0"/>
    <aura:attribute name="otbillrate" type="Decimal" default="0.00"/>
    <aura:attribute name="otpayrate" type="Decimal" default="0.00"/>
    
    <!--Net spread items -->
    <aura:attribute name="miscSpreadDed" type="Decimal" default="0.00"/>
    <aura:attribute name="nonbillexp" type="Decimal" default="0.00"/>
    <aura:attribute name="nonbilloth" type="Decimal" default="0.00"/>
    <aura:attribute name="nonbillbon" type="Decimal" default="0.00"/>
    <aura:attribute name="referfee" type="Decimal" default="0.00"/>
    <aura:attribute name="compbon" type="Decimal" default="0.00"/>
    <aura:attribute name="vms" type="Decimal" default="0.00"/>
    <aura:attribute name="discount" type="Decimal" default="0.00"/>
    <aura:attribute name="perdiem" type="Decimal" default="0.00"/>
    
    
    <aura:attribute name="spread" type="Decimal"/>
    <aura:attribute name="netspread" type="Decimal"/>

  
    <aura:registerEvent name="change" type="c:spreadEvent"/>
    
    <aura:handler name="change" value="{!v.hours}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.payrate}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.billrate}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.vms}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.discount}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.perdiem}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.othours}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.otbillrate}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.otpayrate}" action="{!c.calculateSpread}"/>
	<aura:handler name="change" value="{!v.burdenPer}" action="{!c.calculateSpread}"/>
    
    <aura:handler name="change" value="{!v.miscSpreadDed}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.nonbillexp}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.nonbilloth}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.nonbillbon}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.referfee}" action="{!c.calculateSpread}"/>
    <aura:handler name="change" value="{!v.compbon}" action="{!c.calculateSpread}"/>

    <aura:handler name="init" value="{!this}" action="{!c.calculateSpread}" />
	
	<div> <div class="title2">Spread Calculator: </div>
        <div class="input">
            <lightning:input aura:id="hours" type="number" label="Hours worked a week:" step="0.1" value="{!v.hours}"/>
            <lightning:input aura:id="payrate" type="number" label="Pay rate:" formatter="currency"  step="0.01" value="{!v.payrate}"/>
            <lightning:input aura:id="billrate" type="number" label="Bill Rate:" formatter="currency"  step="0.01" value="{!v.billrate}"></lightning:input>

            <!-- drop down code -->
            
            <div class="slds-page-header11" style="cursor: pointer;" onclick="{!c.sectionOne}">
              <section class="slds-clearfix">
                <div class="slds-float--left ">
                    <lightning:icon class="slds-show" aura:id="articleOne" iconName="utility:right" size="xx-small" alternativeText="Indicates add"/>
                    <lightning:icon class="slds-hide" aura:id="articleOne" iconName="utility:down" size="xx-small" alternativeText="Indicates dash"/>
                </div>
                <div class="slds-m-left-x-small">Overtime Entry (optional)</div>
              </section>
   			</div>
            <div class="slds-hide slds-p-around--medium" aura:id="articleOne">
               <lightning:input aura:id="othours" type="number" label="Overtime hours worked a week:" step="0.1" value="{!v.othours}"/>
               <lightning:input aura:id="otpayrate" type="number" label="Overtime Pay Rate:" formatter="currency" step="0.01" value="{!v.otpayrate}"/>
               <lightning:input aura:id="otbillrate" type="number" label="Overtime Bill Rate:" formatter="currency" step="0.01" value="{!v.otbillrate}"/>
            </div>
            
             
           
                        <lightning:input aura:id="burdenPer" type="number" label="Burden:" formatter="percent"  step="0.01" value="{!v.burdenPer}"></lightning:input>
						 <lightning:helptext content="Enter burden in decimal form. (Example: .03 = 3%)"/> 
           
        </div>
        <div class="result">
            Spread Amount: 
            <br/>
            <lightning:formattedNumber value="{!v.spread}" style="currency" currencyCode="USD"/>
        </div>
        
        <!-- Net Spread dropdown -->

            
        <div class="slds-page-header11" style="cursor: pointer;" onclick="{!c.sectionOne1}">
          <section class="slds-clearfix">
            <div class="slds-float--left ">
                <lightning:icon class="slds-show" aura:id="articleOne1" iconName="utility:right" size="xx-small" alternativeText="Indicates add"/>
                <lightning:icon class="slds-hide" aura:id="articleOne1" iconName="utility:down" size="xx-small" alternativeText="Indicates dash"/>
            </div>
            <div class="slds-m-left-x-small">Calculate Net Spread</div>
          </section>
    	</div>
        
        <div class="slds-hide slds-p-around--medium" aura:id="articleOne1">
                        <lightning:helptext content="Enter percentages in decimal form. (Example: .03 = 3%)"/> 

            <lightning:input aura:id="vms" type="number" label="VMS Fee:" formatter="percent"  step="0.01" value="{!v.vms}"></lightning:input>
            <lightning:input aura:id="discount" type="number" label="Discount Fee:" formatter="percent"  step="0.01" value="{!v.discount}"></lightning:input>
            <lightning:input aura:id="perdiem" type="number" label="Per Diem:" formatter="currency"  step="0.01" value="{!v.perdiem}"></lightning:input>
            <lightning:input aura:id="miscSpreadDed" type="number" label="Misc Spread Deductions:" formatter="currency"  step="0.01" value="{!v.miscSpreadDed}"></lightning:input>
            <lightning:input aura:id="nonbillexp" type="number" label="All Nonbillable Expenses" formatter="currency"  step="0.01" value="{!v.nonbillexp}"></lightning:input>
            <lightning:input aura:id="nonbilloth" type="number" label="Nonbillable Other Earnings" formatter="currency"  step="0.01" value="{!v.nonbilloth}"></lightning:input>
            <lightning:input aura:id="nonbillbon" type="number" label="Nonbillable Bonus" formatter="currency"  step="0.01" value="{!v.nonbillbon}"></lightning:input>
            <lightning:input aura:id="referfee" type="number" label="Referral Fees" formatter="currency"  step="0.01" value="{!v.referfee}"></lightning:input>
            <lightning:input aura:id="compbon" type="number" label="Completion Bonus" formatter="currency"  step="0.01" value="{!v.compbon}"></lightning:input>

 			<div class="result">
                Net Spread Amount: 
                <br/>
                <lightning:formattedNumber value="{!v.netspread}" style="currency" currencyCode="USD"/>
        	</div>        
        
        </div>

    </div>    
    
</aura:component>
helper:
({
	calculateSpread : function(component) {
        // 1. Calculate monthly payment
        var payrate = component.get("v.payrate");
        var billrate = component.get("v.billrate");
        var burdenPer = component.get("v.burdenPer");
        var hours = component.get("v.hours");
        var othours = component.get("v.othours");
        var otbillrate = component.get("v.otbillrate");
        var otpayrate = component.get("v.otpayrate");
        	 var vms = component.get("v.vms");
        	 var discount = component.get("v.discount");
        	 var perdiem = component.get("v.perdiem");
         	 var miscSpreadDed = component.get("v.miscSpreadDed");
             var nonbillexp = component.get("v.nonbillexp");
             var nonbilloth = component.get("v.nonbilloth");
             var nonbillbon = component.get("v.nonbillbon");
             var referfee = component.get("v.referfee");
             var compbon = component.get("v.compbon");
        
        
        if (payrate && billrate > 0){
            
            var totalBillings = (hours * billrate) + (othours * otbillrate);
            var totalPayroll = (hours * payrate) + (othours * otpayrate);
            var totburden = (1 + burdenPer)
            var spread = totalBillings - (totalPayroll * (totburden));
                
        	component.set("v.spread", spread);
            
            var vmsfee = billrate * (1- vms);
            var discountfee = billrate * (1-discount);
            
            var netVariables = (perdiem + miscSpreadDed + nonbillexp + nonbilloth + nonbillbon + vmsfee + discountfee + referfee + compbon)
            var netspread = spread - netVariables
            component.set("v.netspread", netspread);

            
            
            // 2. Fire event with new spread data
            var event = $A.get("e.c:spreadEvent");
            event.setParams({"payrate": payrate,
                             "billrate": billrate,
                             "burdenPer": burdenPer,
                             "vms": vms,
                             "discount": discount,
                             "hours": hours,
                             "perdiem": perdiem,
                             "othours": othours,
                             "otbillrate": otbillrate,
                             "otpayrate": otpayrate,
                                "miscSpreadDed": miscSpreadDed,
                                "nonbillexp": nonbillexp,
                                "nonbilloth": nonbilloth,
                                "nonbillbon": nonbillbon,
                                "referfee": referfee,
                                "compbon": compbon,
                             "netspread": netspread,
                             "spread": spread});
            event.fire();
        }
	},
    	helperFun : function(component,event,secId) {
	  var acc = component.find(secId);
        	for(var cmp in acc) {
        	$A.util.toggleClass(acc[cmp], 'slds-show');  
        	$A.util.toggleClass(acc[cmp], 'slds-hide');  
       }
	},
    
	helperFun1 : function(component,event,secId1) {
	  var acc1 = component.find(secId1);
        	for(var cmp1 in acc1) {
        	$A.util.toggleClass(acc1[cmp1], 'slds-show');  
        	$A.util.toggleClass(acc1[cmp1], 'slds-hide');  
       }
	}
})

 
I'm trying to write a batch class that queries for timesheets (jstcl__TG_Timesheet__c) that has its lookup related placement occur twice or more from the query, and then use the list of flagged duplicate timesheets to update a checkbox field on them. My thought was to go through the queried results, add them to a list and then iterate through that list in to see if they already have been anaylized in order to flag them as having the same related placement.

Here is the code:
global class placementTimecardAuditFlag implements Database.Batchable<sObject>, Database.Stateful {

  List<jstcl__TG_Timesheet__c> query = [SELECT jstcl__Placement__r.Name FROM jstcl__TG_Timesheet__c WHERE jstcl__Placement__r.ts2__Status__c ='Active' AND jstcl__Week_Ending__c = LAST_N_DAYS:15 AND jstcl__Status__c = 'Pending'];
    List<jstcl__TG_Timesheet__c> myList = new List<jstcl__TG_Timesheet__c>();
    List<jstcl__TG_Timesheet__c> myList2 = new List<jstcl__TG_Timesheet__c>();

global Database.QueryLocator start(Database.BatchableContext bc) {
        for(jstcl__TG_Timesheet__c item : query){
    if(myList.contains(item)){
        myList2.add(item);
    }
    else{myList.add(item);}
    }
      return Database.getQueryLocator('SELECT Id,Checkbox1__c FROM jstcl__TG_Timesheet__c WHERE jstcl__Placement__r.Name IN :myList2');}
      

 global void execute(Database.BatchableContext BC, List<jstcl__TG_Timesheet__c> a){
    for(jstcl__TG_Timesheet__c b : a) {
        if(b.Checkbox1__c = True){
           b.Checkbox1__c = False;
        }
        else{b.Checkbox1__c = True;}}
update a;        
    }
global void finish(Database.BatchableContext BC){}
}
Thank you
I currently am working on creating a Scheduled Apex Batch Class that pulls all jstcl__Placement__r.Name that exist on Timesheet__C that currently exceed 14 days since they have had time entered AND jstcl__Placement__r.ts2__Status__c = 'Active'. These are related objects that have some field relationships that I'm using.
It then takes that list of Placement Names from the Timesheet and the execute portion of the batch class needs to determine if there are duplicates within that list and + 1 to the placement.TimecardEnddateAudit__c field (picklist) of any duplicate record returned. What I have adds +1 to ALL the returned placements which isn't quite there. (or maybe that's entirely wrong too) Here is what I have so far. Any help is much appreciated. Appologies if my explaination is rough. 
 
global class timecardEndDateAudit implements Database.Batchable<sObject>, Database.Stateful {

  global Database.QueryLocator start(Database.BatchableContext BC){
        String query = 'SELECT jstcl__Placement__r.Name, Primary_Recruiter__c FROM jstcl__TG_Timesheet__c WHERE jstcl__Placement__r.ts2__Status__c = \'Active\' AND jstcl__Week_Ending__c = LAST_N_DAYS:14 AND (jstcl__Status__c = \'Pending\')';
        return Database.getQueryLocator(query);
  }
  
  global void execute(Database.BatchableContext BC, List<sObject> placements){
        for (ts2__Placement__c placement : (List<ts2__Placement__c>) placements) {

            placement.TimecardEnddateAudit__c = placement.TimecardEnddateAudit__c + 1;
        }
       
        update placements;
  }
  global void finish(Database.BatchableContext BC){ }
}

 
When I attempt to save my Apex Class I receive the error "Error: Compile Error: Unexpected token 'class timecardEndDateAudit implements Database.Batchable'. at line 3 column 8"
I can't seem to figure out what I'm missing here. 

gobal class timecardEndDateAudit implements Database.Batchable<sObject>,Database.Stateful{

global Database.QueryLocator start(Database.BatchableContext bc){

String query = 'SELECT jstcl__Placement__r.Name , Account_Executive__c , jstcl__Placement__r.Timecard_End_Date_Audit__c FROM jstcl__TG_Timesheet__c WHERE jstcl__Week_Ending__c >= LAST_N_DAYS:14'

return Database.getQueryLocator(query);
global void execute(Database.BatchableContext bc,List<Placement>scope){

for (Placement Placements :scope){
Placements.Timecard_End_Date_Audit__c ='1';
}
update scope;
}
global void finish(Database.BatchableContext bc){}
}
I am pretty new at this and trying to create a lightning component so that community users that can't remember their username are able to enter an email address to retrieve their username. If the email they enter matches an existing user account's listed email address it will kick an email to that address with the username of the account. Anyone have anything or knowledge of an open source resource that might have something similar? Thank you!
Hi, I would like to update a field value when a user clicks on a link or button on a email sent out by salesforce. 

We have a workflow that sends out automatic reminders about certain jobs. I would like to setup a second workflow that sends an email 2 days later with a button or link (e.g. "Job completed? Yes, No?") for the user to click on. That button or link should then update a field value in salesforce to "Job completed" or "Job cannot be completed". It doesn't matter if it's a picklist or text field, - I just can't figure out a way to update a field by clicking on a button/link in an email. 

I greatly appreciate any help. 

Alex