• Indianajones
  • NEWBIE
  • 10 Points
  • Member since 2022

  • Chatter
    Feed
  • 0
    Best Answers
  • 1
    Likes Received
  • 0
    Likes Given
  • 8
    Questions
  • 1
    Replies
i have apex class and test class. topic: https://developer.salesforce.com/forums/ForumsMain?id=9062I000000gGOwQAM
I need code coverage 75% , but i new in salesforce and dont understand how up code coverage. help me please.
(Opportunity.Invoice_Number__c - custom field auto number)
global with sharing class controllerTest {
    public Opportunity opportunity {get; set;}
    public List<OpportunityLineItem> oppLineItem {get; set;}
    public list<OpportunityContactRole> contact {get; set;}
    @AuraEnabled
    public static void savePDF(id recordId){
        Opportunity opps = [SELECT Invoice_Number__c FROM Opportunity WHERE Id = :recordId];
        List<ContentVersion> contentVersionss = [SELECT ContentDocumentId FROM ContentVersion WHERE Title =: opps.Invoice_Number__c];
        if(!contentVersionss.isEmpty()){
            Id contentDocumentId = contentVersionss.get(0).ContentDocumentId;
            Opportunity opp = [SELECT Invoice_Number__c FROM Opportunity WHERE Id = :recordId];
            PageReference pdfPage = new PageReference('/apex/newPageVf');
            pdfPage.getParameters().put('Id', recordId);
             Blob pdfBlob;
            if(Test.isRunningTest()) { 
   pdfBlob = blob.valueOf('Unit.Test');
} else {
   pdfBlob = pdfPage.getContentAsPDF();
}
            String fileName = opp.Invoice_Number__c;
            List<ContentVersion> contentVersions = [SELECT ContentDocumentId FROM ContentVersion WHERE Title =: fileName];
            ContentVersion cv = new ContentVersion();
            cv.Title = fileName;
            cv.PathOnClient = fileName + '.pdf';
            cv.VersionData = pdfBlob;
            cv.contentDocumentId = contentDocumentId;
            INSERT cv;
        } else {
            Opportunity opp = [SELECT Invoice_Number__c FROM Opportunity WHERE Id = :recordId];
            PageReference pdfPage = new PageReference('/apex/newPageVf');
            pdfPage.getParameters().put('Id', recordId);
            Blob pdfBlob;
            if(Test.isRunningTest()) { 
   pdfBlob = blob.valueOf('Unit.Test');
} else {
   pdfBlob = pdfPage.getContentAsPDF();
}
           // Blob pdfBlob = pdfPage.getContentAsPDF();
            
            String fileName = opp.Invoice_Number__c;
            ContentVersion cv = new ContentVersion();
            cv.Title = fileName;
            cv.PathOnClient = fileName + '.pdf';
            cv.VersionData = pdfBlob;
            INSERT cv;
            Id contentDocumentId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId;
            Id opportunId = [SELECT Id FROM Opportunity WHERE id =: recordId].Id;
            ContentDocumentLink cdl = new ContentDocumentLink();
            cdl.ContentDocumentId = contentDocumentId;
            cdl.LinkedEntityId = opportunId;
            cdl.ShareType = 'V';
            INSERT cdl;  
        }
    }
  
    public controllerTest(ApexPages.StandardController stdController){
        Id oppId = apexpages.currentpage().getparameters().get('id');
        this.opportunity = [SELECT Id, Name, OwnerId, AccountId, Amount, Invoice_Number__c FROM Opportunity WHERE Id =: oppId];
        this.oppLineItem = [SELECT OpportunityId, Name, Quantity, UnitPrice, TotalPrice FROM OpportunityLineItem WHERE OpportunityId =: oppId];
        this.contact = [SELECT id, ContactId, Contact.Name, Contact.Phone, Contact.Email, IsPrimary, Contact.Account.Name FROM OpportunityContactRole WHERE OpportunityId =: oppId AND IsPrimary = true];    
    }      
}

test
@isTest
public class controllerTestTest{
    @isTest 
    public Static Void UnitTest(){
          Account Acc =new Account();
        Acc.Name = 'Account test';
        Insert Acc;
        
         Opportunity opp = new Opportunity();
        opp.Name = 'test opp';
        opp.Stagename = 'Closed Won';
        opp.CloseDate = System.today();
        opp.AccountId = Acc.Id;
        insert Opp;
        Opportunity opp1 = new Opportunity();
        opp1.Name = 'test opp';
        opp1.Stagename = 'Closed Won';
        opp1.CloseDate = System.today();
        opp1.AccountId = Acc.Id;
        insert opp1;
        
        ContentVersion contentVersionInsert = new ContentVersion(
            Title = 'Test',
            PathOnClient = 'Test.jpg',
            VersionData = Blob.valueOf('Test Content Data'),
            IsMajorVersion = true
        );
        
        insert contentVersionInsert;
        ContentVersion contentVersionInsert1 = new ContentVersion(
            Title = 'sample1',
            PathOnClient = 'Test.jpg',
            VersionData = Blob.valueOf('Test Content Data'),
            IsMajorVersion = true
        );
        
        insert contentVersionInsert1;
        ContentVersion contentVersionSelect = [SELECT Id, Title, ContentDocumentId FROM ContentVersion WHERE Id = :contentVersionInsert.Id LIMIT 1];
        List<ContentDocument> documents = [SELECT Id, Title, LatestPublishedVersionId FROM ContentDocument];
        System.assertEquals(documents.size(), 2);
        controllerTest.savePDF(opp.id);
        controllerTest.savePDF(opp1.id);
        
    }
}
User-added image

thanks
I create apex class and i need test class for this code:
global with sharing class controllerTest {
    public Opportunity opportunity {get; set;}
    public List<OpportunityLineItem> oppLineItem {get; set;}
    public list<OpportunityContactRole> contact {get; set;}
    @AuraEnabled
    public static void savePDF(id recordId){
        Opportunity opps = [SELECT Invoice_Number__c FROM Opportunity WHERE Id = :recordId];
        List<ContentVersion> contentVersionss = [SELECT ContentDocumentId FROM ContentVersion WHERE Title =: opps.Invoice_Number__c];
        if(!contentVersionss.isEmpty()){
            Id contentDocumentId = contentVersionss.get(0).ContentDocumentId;
            Opportunity opp = [SELECT Invoice_Number__c FROM Opportunity WHERE Id = :recordId];
            PageReference pdfPage = new PageReference('/apex/newPageVf');
            pdfPage.getParameters().put('Id', recordId);
            Blob pdfBlob = pdfPage.getContentAsPDF();
            String fileName = opp.Invoice_Number__c;
            List<ContentVersion> contentVersions = [SELECT ContentDocumentId FROM ContentVersion WHERE Title =: fileName];
            ContentVersion cv = new ContentVersion();
            cv.Title = fileName;
            cv.PathOnClient = fileName + '.pdf';
            cv.VersionData = pdfBlob;
            cv.contentDocumentId = contentDocumentId;
            INSERT cv;
        } else {
            Opportunity opp = [SELECT Invoice_Number__c FROM Opportunity WHERE Id = :recordId];
            PageReference pdfPage = new PageReference('/apex/newPageVf');
            pdfPage.getParameters().put('Id', recordId);
            Blob pdfBlob = pdfPage.getContentAsPDF();
            String fileName = opp.Invoice_Number__c;
            ContentVersion cv = new ContentVersion();
            cv.Title = fileName;
            cv.PathOnClient = fileName + '.pdf';
            cv.VersionData = pdfBlob;
            INSERT cv;
            Id contentDocumentId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId;
            Id opportunId = [SELECT Id FROM Opportunity WHERE id =: recordId].Id;
            ContentDocumentLink cdl = new ContentDocumentLink();
            cdl.ContentDocumentId = contentDocumentId;
            cdl.LinkedEntityId = opportunId;
            cdl.ShareType = 'V';
            INSERT cdl;  
        }
    }
    // Берём данные для VisualForce документа.
    public controllerTest(ApexPages.StandardController stdController){
        Id oppId = apexpages.currentpage().getparameters().get('id');
        this.opportunity = [SELECT Id, Name, OwnerId, AccountId, Amount, Invoice_Number__c FROM Opportunity WHERE Id =: oppId];
        this.oppLineItem = [SELECT OpportunityId, Name, Quantity, UnitPrice, TotalPrice FROM OpportunityLineItem WHERE OpportunityId =: oppId];
        this.contact = [SELECT id, ContactId, Contact.Name, Contact.Phone, Contact.Email, IsPrimary, Contact.Account.Name FROM OpportunityContactRole WHERE OpportunityId =: oppId AND IsPrimary = true];    
    }      
}

i new in salesforce and i create test class, but code coverage 0%. i study and i dont know how i can do 75+ code coverage.
 
@isTest
public class controllerTestTest{
    @isTest 
    public Static Void UnitTest(){
          Account Acc =new Account();
        Acc.Name = 'Account test';
        Insert Acc;
        
         Opportunity opp = new Opportunity();
        opp.Name = 'test opp';
        opp.Stagename = 'Closed Won';
        opp.CloseDate = System.today();
        opp.AccountId = Acc.Id;
        insert Opp;
        
        ContentVersion contentVersionInsert = new ContentVersion(
            Title = 'Test',
            PathOnClient = 'Test.jpg',
            VersionData = Blob.valueOf('Test Content Data'),
            IsMajorVersion = true
        );
        
        insert contentVersionInsert;
        ContentVersion contentVersionSelect = [SELECT Id, Title, ContentDocumentId FROM ContentVersion WHERE Id = :contentVersionInsert.Id LIMIT 1];
        List<ContentDocument> documents = [SELECT Id, Title, LatestPublishedVersionId FROM ContentDocument];
        System.assertEquals(documents.size(), 1);
        
        
    }
}
help me please.
thanks.
 
I created a lightning accordion with Account name and a lightning accordion section with Opportunity. I created a Tab for them and displayed it.
I need the following condition:
In case the component will be placed on the page with the account:
1. Only information about that account should be displayed.
2. Pagination, search, and filter by amount should be hidden.

how it look in tab:
User-added image

apex code:

OpportunityController.apxc
public class OpportunityController {
    @AuraEnabled(cacheable=true)
    public static List<Account> getAcc( String searchKey) {
        string searchKeyword = '%' + searchKey + '%';
           list<Account> accountListRecord = new list<Account>();
        	List<Opportunity> opportunityListRecord = new list<Opportunity>();
        for(Account accObj : [SELECT Id, Name, (select id,Name,Amount,CreatedDate,CloseDate, AccountId from opportunities where StageName = 'Closed Won') FROM Account
                            WHERE name LIKE : searchKeyword]){
           accountListRecord.add(accObj);
                            }
     //     for(opportunity oppObj : [select id,Name,Amount,CreatedDate,CloseDate, AccountId from opportunity
      //                      WHERE Amount LIKE : searchKeyword]){
       //    opportunityListRecord.add(oppObj);
        //                    }
         if(accountListRecord.size() == 0){
            throw new AuraHandledException('No Record Found..'); 
         }
      return accountListRecord;
    }    
     
}
LightningDatatableExample.html
<template>
    <lightning-card title="Lightning Datatable Example">
        <div class="slds-m-around_medium">
            <lightning-input type="search" onchange={handleKeyChange} class="slds-m-bottom_small" label="Search"
                value={searchKey}></lightning-input>
                <lightning-accordion allow-multiple-sections-open={multiple}>
                    <template if:true={data}>
                        <template for:each={data} for:item="acc">
                            <lightning-accordion-section name={acc.Name} label={acc.Name} key={acc.Id}>
                                <lightning-card  title="Opportunities">
                                    <table class="slds-table slds-table_cell-buffer slds-table_bordered">
                                        <thead>
                                            <tr class="slds-line-height_reset slds-text-title_caps">
                                                <th  class="slds-is-resizable" scope="col">
                                                    <div class="slds-truncate" title="Opportunity Name">
                                                        Opportunity Name
                                                    </div>
                                                </th>
                                                <th  class="slds-is-resizable" scope="col">
                                                    <div class="slds-truncate" title="Created Date">
                                                        Created Date
                                                    </div>
                                                </th>
                                                <th  class="slds-is-resizable" scope="col">
                                                    <div class="slds-truncate" title="Close Date">
                                                        Close Date
                                                    </div>
                                                </th>
                                                <th class="slds-is-resizable" scope="col">
                                                    <div class="slds-truncate" title="Amount">
                                                        Amount
                                                    </div>
                                                </th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            <template if:true={acc.Opportunities}>
                                                <template for:each={acc.Opportunities} for:item="opp">
                                                    <tr key={opp.Id}>
                                                        <th scope="row" data-label="Name">
                                                            <div class="slds-truncate" title={opp.Name}>{opp.Name}</div>
                                                        </th>
                                                        <th scope="row" data-label="Account Number">
                                                            <div class="slds-truncate" title={opp.CreatedDate}>{opp.CreatedDate}</div>
                                                        </th>
                                                        <th scope="row" data-label="Industry">
                                                            <div class="slds-truncate" title={opp.CloseDate}>{opp.CloseDate}</div>
                                                        </th>
                                                        <th scope="row" data-label="Phone">
                                                            <div class="slds-truncate" title={opp.Amount}>{opp.Amount}</div>
                                                        </th>
                                                        
                                                    </tr>
                                                    
                                                </template>
                                            </template>
                                        </tbody>
                                    </table>
                                    <lightning-button variant="brand" label="Show me Opportunity Product" title="Primary action" onclick={handleClick} class="slds-m-left_x-small"></lightning-button>
                                </lightning-card>   
            </lightning-accordion-section>
            </template>
            </template>
            </lightning-accordion>
            </br>
            <lightning-layout horizontal-align="space">
                <lightning-layout-item flexibility="auto">
                    <lightning-button label="Previous" icon-name="utility:chevronleft" onclick={previousHandler}>
                    </lightning-button>
                </lightning-layout-item>
                <lightning-layout-item flexibility="auto">
                    Page {page} of {totalPage}
                </lightning-layout-item>
                <lightning-layout-item flexibility="auto">
                    <lightning-button label="Next" icon-name="utility:chevronright" icon-position="right"
                        onclick={nextHandler}></lightning-button>
                </lightning-layout-item>
            </lightning-layout>
        </div>
    </lightning-card>
</template>
LightningDatatableExample.js
import { LightningElement, wire, api, track} from 'lwc';
import { refreshApex } from '@salesforce/apex';
import getAcc from '@salesforce/apex/OpportunityController.getAcc';
import getPreview from '@salesforce/apex/controllerTest.getPreview';
import { NavigationMixin } from 'lightning/navigation';

export default class LightningDatatableExample extends NavigationMixin(LightningElement) {
    @track value;
    @track error;
    @track data;
    @api searchKey = '';
    result;
    @track page = 1; 
    @track items = []; 
    @track data = []; 
    @track startingRecord = 1;
    @track endingRecord = 0; 
    @track pageSize = 10; 
    @track totalRecountCount = 0;
    @track totalPage = 0;

    @wire(getAcc, {searchKey: '$searchKey'})
    wiredAccounts({ error, data }) {
        if (data) {
        
            this.items = data;
            this.totalRecountCount = data.length; 
            this.totalPage = Math.ceil(this.totalRecountCount / this.pageSize); 
            
            this.data = this.items.slice(0,this.pageSize); 
            this.endingRecord = this.pageSize;
          

            this.error = undefined;
        } else if (error) {
            this.error = error;
            this.data = undefined;
        }
    }
   
    //clicking on previous button this method will be called
    previousHandler() {
        if (this.page > 1) {
            this.page = this.page - 1; //decrease page by 1
            this.displayRecordPerPage(this.page);
        }
    }

    //clicking on next button this method will be called
    nextHandler() {
        if((this.page<this.totalPage) && this.page !== this.totalPage){
            this.page = this.page + 1; //increase page by 1
            this.displayRecordPerPage(this.page);            
        }             
    }

    //this method displays records page by page
    displayRecordPerPage(page){

        this.startingRecord = ((page -1) * this.pageSize) ;
        this.endingRecord = (this.pageSize * page);

        this.endingRecord = (this.endingRecord > this.totalRecountCount) 
                            ? this.totalRecountCount : this.endingRecord; 

        this.data = this.items.slice(this.startingRecord, this.endingRecord);

        this.startingRecord = this.startingRecord + 1;
    }    
    
    handleKeyChange( event ) {
        this.searchKey = event.target.value;
        return refreshApex(this.result);
    }
    connectedCallback() {
        getPreview({ oppIds: this.recordId })
            .then((result) => {
              this.contents = result;
              this.error = undefined;
            })
            .catch((error) => {
              this.error = error;
              this.contents = undefined;
            });
        } 
    handleClick() {
        this[NavigationMixin.Navigate]({
            type: 'standard__recordRelationshipPage',
            attributes: {
                recordId: '0065j00000CLKkxAAH',
                objectApiName: 'OpportunityLineItem',
                relationshipApiName: 'OpportunityLineItems',
                actionName: 'view'
            },
        });
    }
}
xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
      <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__HomePage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>
help me please!
thanks!



 
I created a lwc component that sends information about Opportunity.
User-added image

The problem is that the data is written to Single Email only if I use 4 functions.  
1. handleToNameReceiverChange
2. handleToEmailAddressChange
3. handleToEmailSubjectChange
4. handleToEmailBodyChange

They work so that if I change the value of the field manually, the data is put into Email. If I don't change them, I get an undefined error and that the body is required in Email.

User-added image
If I change the data in the fields manually, such as writing forexample , it works fine.

User-added image

I want the fields to be taken as I specified in the queries, so that the Name of receiver, email, email subject were readonly and entered automatically in a single email. And the body remains editable.

Help me please.

SendInvoiceService.apxc
public with sharing class SendInvoiceService {
  //  @AuraEnabled
  //  public static List<ContentVersion> getPreview(id oppIds) {
   //     Opportunity oppor = [SELECT Id, Invoice_Number__c From Opportunity where id=:oppIds];
   //   return [SELECT Id, Title, FileExtension, ContentDocumentId From ContentVersion where title=:oppor.Invoice_Number__c];
   // }
    @AuraEnabled
    public static List<ContentDocument> getPreview(id oppIds) {
        try {
            Opportunity Opportunitys = [
                select id,Invoice_Number__c
                from Opportunity
                where id=:oppIds];
            
            List<ContentVersion> cvs = [SELECT Id, Title, FileExtension, ContentDocumentId From ContentVersion where Title=:Opportunitys.Invoice_Number__c];
            
            return [select Id from ContentDocument where LatestPublishedVersionId in :cvs];
        } catch (Exception e) {
            throw new AuraHandledException(e.getMessage());
        }
    }
    
      @AuraEnabled(cacheable=true)
    public static SendInvoice__c getInvoice(id oppId) {
        Opportunity Opportunity=[select id,Invoice_Number__c,
                                 (select IsPrimary,Contact.Email,Contact.AccountId,Contact.FirstName
                                  from OpportunityContactRoles where IsPrimary=true)
                                 from Opportunity where id=:oppId];
        OpportunityContactRole oppCR=Opportunity.OpportunityContactRoles;
        
        SendInvoice__c invoice=new SendInvoice__c();
        invoice.Body__c=[select body from EmailTemplate where name='OppTextAndr'].body+' body';
        invoice.Subject__c=Opportunity.Invoice_Number__c;
        invoice.Email__c=oppCR.Contact.Email;
        invoice.FirstName__c=oppCR.Contact.FirstName;	
        system.debug(invoice.Body__c+' '+invoice.Subject__c+' '+invoice.Email__c+' '+invoice.FirstName__c
                     +' '+invoice.LastName__c+' '+invoice.AttachId__c);
        return invoice;
    }
    @AuraEnabled
    public static void sendEmail(List<String> toAddress, String subject, String body, String name, id oppId) {      
        Messaging.reserveSingleEmailCapacity(1);
        try{
            
            messaging.SingleEmailMessage mail = new messaging.SingleEmailMessage();
            System.debug(toAddress);
            System.debug(body);
            System.debug(name);
            System.debug(subject);
            
            mail.setToAddresses(toAddress);
            mail.setReplyTo('no-reply@xooa.com');
            mail.setSenderDisplayName(name);
            mail.setSubject(subject);
            mail.setPlainTextBody(body);
            
            Messaging.sendEmail(new List<messaging.SingleEmailMessage> {mail});
        }
        catch (exception e){
            throw new AuraHandledException(e.getMessage());
        }
    }
}
SendInvoiceLWC.html
<template>  
<lightning-card title="Send Invoice" >
<lightning-input type="name" name="nameReceiver" label="Name of Receiver" onchange={handleToNameReceiverChange} value={realFormData.FirstName__c} if:true={realFormData} ></lightning-input>
<lightning-input type="email" name="emailAddress" label="Email" onchange={handleToEmailAddressChange}  value={realFormData.Email__c} if:true={realFormData} ></lightning-input>
<lightning-input type="emailsubject" name="emailSubject" onchange={handleToEmailSubjectChange}  label="EmailSubject" value={realFormData.Subject__c} if:true={realFormData}></lightning-input>
<lightning-input type="emailbody" name="emailBody" onchange={handleToEmailBodyChange} label="EmailBody" value={realFormData.Body__c} if:true={realFormData} ></lightning-input>
<lightning-button label="Show me PDF" onclick={openPDF}></lightning-button>
<lightning-button label="send Email" onclick={sendEmailHandler}></lightning-button> 
</lightning-card>

</template>
sendInvoiceLWC.js
import { LightningElement, api, wire, track } from 'lwc';
import getInvoice from '@salesforce/apex/SendInvoiceService.getInvoice';
import getPreview from '@salesforce/apex/SendInvoiceService.getPreview';
import sendEmail from '@salesforce/apex/SendInvoiceService.sendEmail';
import NAME_FIELD from '@salesforce/schema/SendInvoice__c.FirstName__c';
import SUBJECT_FIELD from '@salesforce/schema/SendInvoice__c.Subject__c';
import EMAIL_FIELD from '@salesforce/schema/SendInvoice__c.Email__c';
import BODY_FIELD from '@salesforce/schema/SendInvoice__c.Body__c';
import { getSObjectValue } from '@salesforce/apex';
import { NavigationMixin } from 'lightning/navigation';

export default class sendInvoiceLWC extends NavigationMixin(LightningElement) {
@track contents;
@track error;
@api recordId;



@track email = '';
@api wiredContact;
@api realFormData;
@api InvoiceObj;

@api wiredContent;
@api realFormContent;
@api PreviewObj;

@track content;
@track error;
@api contentVId;



 connectedCallback() {
  getPreview({ oppIds: this.recordId })
      .then((result) => {
        this.contents = result;
        this.error = undefined;
      })
      .catch((error) => {
        this.error = error;
        this.contents = undefined;
      });
  } 
  openPDF() {
    this[NavigationMixin.Navigate]({
      type: 'standard__namedPage',
      attributes: {
          pageName: 'filePreview'
      },
      state : {
          recordIds: '0695j000007MhNrAAK,0695j000007MhNrAAK',
          selectedRecordId:'0695j000007MhNrAAK'
      }
    })
  }

    
@wire(getInvoice, { oppId:'$recordId' }) fetchedInvoice( resp){
  this.wiredContact = resp;
  this.realFormData = this.wiredContact.data;
  this.InvoiceObj=resp;
  }
  get Subject() {
  return this.InvoiceObj.data?getSObjectValue(this.InvoiceObj.data,SUBJECT_FIELD,EMAIL_FIELD,BODY_FIELD,NAME_FIELD):'nothing';
  }

handleToNameReceiverChange(event) {
if (event.target.name === 'nameReceiver') {
  this.name = event.target.value;
  
}
}
handleToEmailAddressChange(event) {
if (event.target.name === 'emailAddress') {
  this.email = event.target.value;
}
}
handleToEmailSubjectChange(event) {
if (event.target.name === 'emailSubject') {
  this.emailsubject = event.target.value;
}
}
handleToEmailBodyChange(event) {
if (event.target.name === 'emailBody') {
  this.emailbody = event.target.value;
}
}


sendEmailHandler(event) {
  
console.log("Sending email to", this.email);
console.log("Email subject this subject", this.emailsubject);
console.log("Email body this body", this.emailbody);
sendEmail({ toAddress: this.email, subject: this.emailsubject, name: this.name, body: this.emailbody});
}
}
xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordAction</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordAction">
            <actionType>ScreenAction</actionType>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>
help me please!!!



 
I need to add a button in the tabs of lightning accordion , when you click on which will open a modal window with a list of sold products (opportunity product).

how it look:
User-added image

Code:
OpportunityController.apxc
public class OpportunityController {
    @AuraEnabled(cacheable=true)
    public static List<Account> getAcc( String searchKey) {
        string searchKeyword = '%' + searchKey + '%';
           list<Account> accountListRecord = new list<Account>();
        	List<Opportunity> opportunityListRecord = new list<Opportunity>();
        for(Account accObj : [SELECT Id, Name, (select id,Name,Amount,CreatedDate,CloseDate, AccountId from opportunities where StageName = 'Closed Won') FROM Account
                            WHERE name LIKE : searchKeyword]){
           accountListRecord.add(accObj);
                            }
     //     for(opportunity oppObj : [select id,Name,Amount,CreatedDate,CloseDate, AccountId from opportunity
      //                      WHERE Amount LIKE : searchKeyword]){
       //    opportunityListRecord.add(oppObj);
        //                    }
         if(accountListRecord.size() == 0){
            throw new AuraHandledException('No Record Found..'); 
         }
      return accountListRecord;
    }    
     
}
LightningDatatableExample.html
<template>
    <lightning-card title="Lightning Datatable Example">
        <div class="slds-m-around_medium">
            <lightning-input type="search" onchange={handleKeyChange} class="slds-m-bottom_small" label="Search"
                value={searchKey}></lightning-input>
                <lightning-accordion allow-multiple-sections-open={multiple}>
                    <template if:true={data}>
                        <template for:each={data} for:item="acc">
                            <lightning-accordion-section name={acc.Name} label={acc.Name} key={acc.Id}>
                                <lightning-card  title="Opportunities">
                                    <table class="slds-table slds-table_cell-buffer slds-table_bordered">
                                        <thead>
                                            <tr class="slds-line-height_reset slds-text-title_caps">
                                                <th  class="slds-is-resizable" scope="col">
                                                    <div class="slds-truncate" title="Opportunity Name">
                                                        Opportunity Name
                                                    </div>
                                                </th>
                                                <th  class="slds-is-resizable" scope="col">
                                                    <div class="slds-truncate" title="Created Date">
                                                        Created Date
                                                    </div>
                                                </th>
                                                <th  class="slds-is-resizable" scope="col">
                                                    <div class="slds-truncate" title="Close Date">
                                                        Close Date
                                                    </div>
                                                </th>
                                                <th class="slds-is-resizable" scope="col">
                                                    <div class="slds-truncate" title="Amount">
                                                        Amount
                                                    </div>
                                                </th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            <template if:true={acc.Opportunities}>
                                                <template for:each={acc.Opportunities} for:item="opp">
                                                    <tr key={opp.Id}>
                                                        <th scope="row" data-label="Name">
                                                            <div class="slds-truncate" title={opp.Name}>{opp.Name}</div>
                                                        </th>
                                                        <th scope="row" data-label="Account Number">
                                                            <div class="slds-truncate" title={opp.CreatedDate}>{opp.CreatedDate}</div>
                                                        </th>
                                                        <th scope="row" data-label="Industry">
                                                            <div class="slds-truncate" title={opp.CloseDate}>{opp.CloseDate}</div>
                                                        </th>
                                                        <th scope="row" data-label="Phone">
                                                            <div class="slds-truncate" title={opp.Amount}>{opp.Amount}</div>
                                                        </th>
                                                        
                                                    </tr>
                                                    
                                                </template>
                                            </template>
                                        </tbody>
                                    </table>
                                    <lightning-button variant="brand" label="Show me Opportunity Product" title="Primary action" onclick={handleClick} class="slds-m-left_x-small"></lightning-button>
                                </lightning-card>   
            </lightning-accordion-section>
            </template>
            </template>
            </lightning-accordion>
            </br>
            <lightning-layout horizontal-align="space">
                <lightning-layout-item flexibility="auto">
                    <lightning-button label="Previous" icon-name="utility:chevronleft" onclick={previousHandler}>
                    </lightning-button>
                </lightning-layout-item>
                <lightning-layout-item flexibility="auto">
                    Page {page} of {totalPage}
                </lightning-layout-item>
                <lightning-layout-item flexibility="auto">
                    <lightning-button label="Next" icon-name="utility:chevronright" icon-position="right"
                        onclick={nextHandler}></lightning-button>
                </lightning-layout-item>
            </lightning-layout>
        </div>
    </lightning-card>
</template>

js:
 
import { LightningElement, wire, api, track} from 'lwc';
import { refreshApex } from '@salesforce/apex';
import getAcc from '@salesforce/apex/OpportunityController.getAcc';
import getPreview from '@salesforce/apex/controllerTest.getPreview';
import { NavigationMixin } from 'lightning/navigation';

export default class LightningDatatableExample extends NavigationMixin(LightningElement) {
    @track value;
    @track error;
    @track data;
    @api searchKey = '';
    result;
    @track page = 1; 
    @track items = []; 
    @track data = []; 
    @track startingRecord = 1;
    @track endingRecord = 0; 
    @track pageSize = 10; 
    @track totalRecountCount = 0;
    @track totalPage = 0;

    @wire(getAcc, {searchKey: '$searchKey'})
    wiredAccounts({ error, data }) {
        if (data) {
        
            this.items = data;
            this.totalRecountCount = data.length; 
            this.totalPage = Math.ceil(this.totalRecountCount / this.pageSize); 
            
            this.data = this.items.slice(0,this.pageSize); 
            this.endingRecord = this.pageSize;
          

            this.error = undefined;
        } else if (error) {
            this.error = error;
            this.data = undefined;
        }
    }
   
    //clicking on previous button this method will be called
    previousHandler() {
        if (this.page > 1) {
            this.page = this.page - 1; //decrease page by 1
            this.displayRecordPerPage(this.page);
        }
    }

    //clicking on next button this method will be called
    nextHandler() {
        if((this.page<this.totalPage) && this.page !== this.totalPage){
            this.page = this.page + 1; //increase page by 1
            this.displayRecordPerPage(this.page);            
        }             
    }

    //this method displays records page by page
    displayRecordPerPage(page){

        this.startingRecord = ((page -1) * this.pageSize) ;
        this.endingRecord = (this.pageSize * page);

        this.endingRecord = (this.endingRecord > this.totalRecountCount) 
                            ? this.totalRecountCount : this.endingRecord; 

        this.data = this.items.slice(this.startingRecord, this.endingRecord);

        this.startingRecord = this.startingRecord + 1;
    }    
    
    handleKeyChange( event ) {
        this.searchKey = event.target.value;
        return refreshApex(this.result);
    }
    connectedCallback() {
        getPreview({ oppIds: this.recordId })
            .then((result) => {
              this.contents = result;
              this.error = undefined;
            })
            .catch((error) => {
              this.error = error;
              this.contents = undefined;
            });
        } 
    handleClick() {
        this[NavigationMixin.Navigate]({
            type: 'standard__recordRelationshipPage',
            attributes: {
                recordId: '0065j00000CLKkxAAH',
                objectApiName: 'OpportunityLineItem',
                relationshipApiName: 'OpportunityLineItems',
                actionName: 'view'
            },
        });
    }
}

meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
      <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__HomePage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>
help me please. thanks.



 
Hehy, i create lightning-accordion with account name. in my tabs i have opportunity with amount. I have search with Account name. I need search with Account name and Amount of Opportunity. I have Soql for Account Name:
 
public class OpportunityController {
    @AuraEnabled(cacheable=true)
    public static List<Account> getAcc( String searchKey) {
        string searchKeyword = '%' + searchKey + '%';
           list<Account> accountListRecord = new list<Account>();
        for(Account accObj : [SELECT Id, Name,(select id,Name,Amount,CreatedDate,CloseDate, AccountId from opportunities where StageName = 'Closed Won') FROM Account
                            WHERE name LIKE : searchKeyword]){
           accountListRecord.add(accObj);
                            }
         if(accountListRecord.size() == 0){
            throw new AuraHandledException('No Record Found..'); 
         }
      return accountListRecord;
    }    
}
How i can update my code for search account name + opportunity amount?

How its look:
User-added image
screen 2.
User-added image
There should be a search for the total closed Amount of all Accounts

Help me please!
thanks.
 
Salesforce provides the ability to both receive and send emails.  Email service  https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_email_inbound_what_is.htm How this should work  https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_email_inbound_using.htm How it should work: We received an order confirmation email. We have an indicator - the order number. Custom field with type Auto_Number.  Find it by the order number.  If Opportunity is still in the pending status, you need to decompress the reply that came in the email and put Opportunity in the appropriate status. (Approved - move to the next status, Rejected - move to Closed Lost)  . help me please. no idea how to do it.
Hey, i create lightning-accordion with account name. in my tabs i have opportunity with amount. I have search with Account name. I need search with Account name and Amount of Opportunity. I have Soql for Account Name:
 
public class OpportunityController {
    @AuraEnabled(cacheable=true)
    public static List<Account> getAcc( String searchKey) {
        string searchKeyword = '%' + searchKey + '%';
           list<Account> accountListRecord = new list<Account>();
        for(Account accObj : [SELECT Id, Name,(select id,Name,Amount,CreatedDate,CloseDate, AccountId from opportunities where StageName = 'Closed Won') FROM Account
                            WHERE name LIKE : searchKeyword]){
           accountListRecord.add(accObj);
                            }
         if(accountListRecord.size() == 0){
            throw new AuraHandledException('No Record Found..'); 
         }
      return accountListRecord;
    }    
}
How i can update my code for search account name + opportunity amount?

How its look:
User-added image

screen 2.

User-added image

thanks.


 
i have apex class and test class. topic: https://developer.salesforce.com/forums/ForumsMain?id=9062I000000gGOwQAM
I need code coverage 75% , but i new in salesforce and dont understand how up code coverage. help me please.
(Opportunity.Invoice_Number__c - custom field auto number)
global with sharing class controllerTest {
    public Opportunity opportunity {get; set;}
    public List<OpportunityLineItem> oppLineItem {get; set;}
    public list<OpportunityContactRole> contact {get; set;}
    @AuraEnabled
    public static void savePDF(id recordId){
        Opportunity opps = [SELECT Invoice_Number__c FROM Opportunity WHERE Id = :recordId];
        List<ContentVersion> contentVersionss = [SELECT ContentDocumentId FROM ContentVersion WHERE Title =: opps.Invoice_Number__c];
        if(!contentVersionss.isEmpty()){
            Id contentDocumentId = contentVersionss.get(0).ContentDocumentId;
            Opportunity opp = [SELECT Invoice_Number__c FROM Opportunity WHERE Id = :recordId];
            PageReference pdfPage = new PageReference('/apex/newPageVf');
            pdfPage.getParameters().put('Id', recordId);
             Blob pdfBlob;
            if(Test.isRunningTest()) { 
   pdfBlob = blob.valueOf('Unit.Test');
} else {
   pdfBlob = pdfPage.getContentAsPDF();
}
            String fileName = opp.Invoice_Number__c;
            List<ContentVersion> contentVersions = [SELECT ContentDocumentId FROM ContentVersion WHERE Title =: fileName];
            ContentVersion cv = new ContentVersion();
            cv.Title = fileName;
            cv.PathOnClient = fileName + '.pdf';
            cv.VersionData = pdfBlob;
            cv.contentDocumentId = contentDocumentId;
            INSERT cv;
        } else {
            Opportunity opp = [SELECT Invoice_Number__c FROM Opportunity WHERE Id = :recordId];
            PageReference pdfPage = new PageReference('/apex/newPageVf');
            pdfPage.getParameters().put('Id', recordId);
            Blob pdfBlob;
            if(Test.isRunningTest()) { 
   pdfBlob = blob.valueOf('Unit.Test');
} else {
   pdfBlob = pdfPage.getContentAsPDF();
}
           // Blob pdfBlob = pdfPage.getContentAsPDF();
            
            String fileName = opp.Invoice_Number__c;
            ContentVersion cv = new ContentVersion();
            cv.Title = fileName;
            cv.PathOnClient = fileName + '.pdf';
            cv.VersionData = pdfBlob;
            INSERT cv;
            Id contentDocumentId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId;
            Id opportunId = [SELECT Id FROM Opportunity WHERE id =: recordId].Id;
            ContentDocumentLink cdl = new ContentDocumentLink();
            cdl.ContentDocumentId = contentDocumentId;
            cdl.LinkedEntityId = opportunId;
            cdl.ShareType = 'V';
            INSERT cdl;  
        }
    }
  
    public controllerTest(ApexPages.StandardController stdController){
        Id oppId = apexpages.currentpage().getparameters().get('id');
        this.opportunity = [SELECT Id, Name, OwnerId, AccountId, Amount, Invoice_Number__c FROM Opportunity WHERE Id =: oppId];
        this.oppLineItem = [SELECT OpportunityId, Name, Quantity, UnitPrice, TotalPrice FROM OpportunityLineItem WHERE OpportunityId =: oppId];
        this.contact = [SELECT id, ContactId, Contact.Name, Contact.Phone, Contact.Email, IsPrimary, Contact.Account.Name FROM OpportunityContactRole WHERE OpportunityId =: oppId AND IsPrimary = true];    
    }      
}

test
@isTest
public class controllerTestTest{
    @isTest 
    public Static Void UnitTest(){
          Account Acc =new Account();
        Acc.Name = 'Account test';
        Insert Acc;
        
         Opportunity opp = new Opportunity();
        opp.Name = 'test opp';
        opp.Stagename = 'Closed Won';
        opp.CloseDate = System.today();
        opp.AccountId = Acc.Id;
        insert Opp;
        Opportunity opp1 = new Opportunity();
        opp1.Name = 'test opp';
        opp1.Stagename = 'Closed Won';
        opp1.CloseDate = System.today();
        opp1.AccountId = Acc.Id;
        insert opp1;
        
        ContentVersion contentVersionInsert = new ContentVersion(
            Title = 'Test',
            PathOnClient = 'Test.jpg',
            VersionData = Blob.valueOf('Test Content Data'),
            IsMajorVersion = true
        );
        
        insert contentVersionInsert;
        ContentVersion contentVersionInsert1 = new ContentVersion(
            Title = 'sample1',
            PathOnClient = 'Test.jpg',
            VersionData = Blob.valueOf('Test Content Data'),
            IsMajorVersion = true
        );
        
        insert contentVersionInsert1;
        ContentVersion contentVersionSelect = [SELECT Id, Title, ContentDocumentId FROM ContentVersion WHERE Id = :contentVersionInsert.Id LIMIT 1];
        List<ContentDocument> documents = [SELECT Id, Title, LatestPublishedVersionId FROM ContentDocument];
        System.assertEquals(documents.size(), 2);
        controllerTest.savePDF(opp.id);
        controllerTest.savePDF(opp1.id);
        
    }
}
User-added image

thanks
Hey, i create lightning-accordion with account name. in my tabs i have opportunity with amount. I have search with Account name. I need search with Account name and Amount of Opportunity. I have Soql for Account Name:
 
public class OpportunityController {
    @AuraEnabled(cacheable=true)
    public static List<Account> getAcc( String searchKey) {
        string searchKeyword = '%' + searchKey + '%';
           list<Account> accountListRecord = new list<Account>();
        for(Account accObj : [SELECT Id, Name,(select id,Name,Amount,CreatedDate,CloseDate, AccountId from opportunities where StageName = 'Closed Won') FROM Account
                            WHERE name LIKE : searchKeyword]){
           accountListRecord.add(accObj);
                            }
         if(accountListRecord.size() == 0){
            throw new AuraHandledException('No Record Found..'); 
         }
      return accountListRecord;
    }    
}
How i can update my code for search account name + opportunity amount?

How its look:
User-added image

screen 2.

User-added image

thanks.