+ Start a Discussion
Abhilash Mishra 13Abhilash Mishra 13 
Hi, 
can i get all the values of a picklist field in a list some how?

I have picklist type custom field in the product. having some options.
In my apex class i want to use these options. can I get them some how throught code? 
Best Answer chosen by Abhilash Mishra 13
ManojjenaManojjena
Hi Abhilash,

If you want to display pick list values in your custom page through dyanamic apex .You can check below link it will help  .

https://developer.salesforce.com/blogs/developer-relations/2008/12/using-the-metadata-api-to-retrieve-picklist-values.html

If you want in a string array or list then you can use below code .
 
public List<String> getPickListValuesIntoList(){
       List<String> pickListValuesList= new List<String>();
		Schema.DescribeFieldResult fieldResult = ObjectApiName.FieldApiName.getDescribe();
		List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();
		for( Schema.PicklistEntry pickListVal : ple){
			pickListValuesList.add(pickListVal.getLabel());
		}     
		return pickListValuesList;
    }
Let us know if it helps !!
Thanks
Manoj
 
Sharon CrenshawSharon Crenshaw 
I keep getting the following error while running my Apex Test Class. If I could please get assistance in resolving the problem I would appreciate it. I continue getting the following error:

System.DmlException: Insert failed. First exception on row 0; first error: STRING_TOO_LONG, Alias: data value too large: Sminull90 (max length=8): [Alias]

Below is my code:

Apex Class:

public  class NewUtilStaffProcess {
       @future
       public static void createUtlUser(Id recid) {
            
           Contact gcon = [SELECT Email, Lastname, Firstname, Middlename, AcctId
                            FROM   Contact
                            WHERE  Id = :recid];
           
           Profile p = [SELECT Id FROM Profile WHERE Name='HAVNA City Public Utility Group'];
           
           Id acctsTypeId = [SELECT Id
                            FROM   RecordType
                            WHERE  SObjectType = 'Account'
                            AND    Name = 'Account Source'].Id;
           
           String groleId = [SELECT Id FROM UserRole WHERE Name = 'Utility Staff' LIMIT 1].Id;
           
           
           String formatUsrName;
           String setUsrLoc;
           
           Account retAcct = [SELECT Id, HAVNA_Country__r.HAVNA_Letter_Code__c, Hav_Locality__c, Hav_Street__c
                               FROM   Account
                               WHERE  Id = :gcon.AcctId
                               AND    recordTypeId = :acctsTypeId
                               LIMIT 1];
           
           if (retAcct.Hav_Street__c == 'Local/Surveyor')
              setUsrLoc = retAcct.HAVNA_Country__r.HAVNA_Letter_Code__c+retAcct.Hav_Locality__c;
        
           if (retAcct.Hav_Street__c == 'City/Surveyor')
              setUsrLoc = retAcct.HAVNA_Country__r.HAVNA_Letter_Code__c+'C1';
         
           if (retAcct.Hav_Street__c == 'State/Surveyor')
              setUsrLoc = retAcct.HAVNA_Country__r.HAVNA_Letter_Code__c+'C2';
        
             
           if (gcon.middlename == null) {
               formatUsrName = gcon.Lastname.deleteWhitespace().toLowercase().trim()+'.'+gcon.Firstname.deleteWhitespace().toLowercase().trim()+'.cnastaff'+setUsrLoc+'@HAVNA.gmail';
           } else {
               Integer midSize = gcon.Middlename.length();
               if (midSize == 1) {
                   formatUsrName = gcon.Lastname.deleteWhitespace().toLowercase().trim()+'.'+gcon.Firstname.deleteWhitespace().toLowercase().trim()+'.'+gcon.middlename.deleteWhitespace().toLowercase().trim()+'.cnastaff'+setUsrLoc+'@HAVNA.gmail';
               } else {
                   formatUsrName = gcon.Lastname.deleteWhitespace().toLowercase().trim()+'.'+gcon.Firstname.deleteWhitespace().toLowercase().trim()+'.'+gcon.middlename.deleteWhitespace().trim().substring(0,1).toLowercase()+'.cnastaff'+setUsrLoc+'@HAVNA.gmail';
               }    
           }

           System.debug('Formatted Username: '+formatUsrName);
      
           User u       = new User(Alias    = gcon.Lastname.deleteWhitespace().trim().length() > 4 ? gcon.Lastname.deleteWhitespace().trim().substring(0,3)+setUsrLoc: gcon.lastname+setUsrLoc,
                         Email              = gcon.Email,
                         EmailEncodingKey   = 'UTF-8',
                         LastName           = gcon.Lastname,
                         FirstName          = gcon.Firstname,
                         MiddleName         = gcon.Middlename,         
                         LanguageLocaleKey  = 'en_US',
                         LocaleSidKey       = 'en_US',
                         ProfileId          = p.Id,
                         UserRoleId         = groleid,          
                         TimeZoneSidKey     = 'America/New_York',
                         UserName           = formatUsrName);
          
           Insert(u);
           System.debug(u.id);
           
           UtilStaffPermSet.assgnPermissionSet(recId, u.Id);  
           System.resetPassword(u.Id, True);

      }
}

Apex Test Class:

@isTest
public class NewUtilStaffProcessTest {

   public static testMethod void InitialTest() {

        /* Get Record Id Type */   
        Id conTypeId;
        Id acctTypeId;
        String formatUsrName;
        String setUsrLoc;
        
        conTypeId = [SELECT Id  
                     FROM   RecordType
                     WHERE  SObjectType = 'Contact'
                     AND    Name = 'Utility Staffer'].Id;  

       
        Id acctsTypeId = [SELECT Id
                      FROM   RecordType
                      WHERE  SObjectType = 'Account'
                          AND    Name = 'Account Source'].Id;

        Profile p = [SELECT Id FROM Profile WHERE Name='HAVNA City Public Utility Group'];
        String groleId = [SELECT Id FROM UserRole WHERE Name = 'Utility Staff' LIMIT 1].Id;

        Integer midsize;
       
        //Create new State record; initialize required field(s), then insert
        HAV_State_and_Country__c state  = new HAV_State_and_Country__c();
        state.Name                = 'Oregon';
        state.HAV_Letter_Code__c = 'OR';
        state.HAV_Type__c        = 'State';
        Insert state;
        
        //Create new Account record; initialize required field(s), then insert
        Account acct = new Account(Name='Oregon Local 7');
        acct.Hav_Locality__c     = '90';
        acct.Hav_Street__c     = 'Local/Surveyor';
        acct.RecordTypeId     =  AcctTypeId;
        acct.HAV__Country__c    = state.id;
    insert acct;

        //Create new Contact record; initialize required field(s), then insert
        Contact con  = new Contact();   
        con.FirstName       = 'Ralph';  
        con.LastName        = 'Smith';
        con.Middlename      = 'Otis';
        con.RecordTypeId    =  conTypeId;
        con.email           = 'rsmith8@verizon.com';
        con.AcctId          = acct.id;
          
        //Insert Contact
        Insert con ;
       
          System.debug(con.id);
 
       Account retAcct = [SELECT Id, HAV_Country__r.HAV_Letter_Code__c, Hav_Locality__c, Hav_Street__c
                          FROM   Account
                          WHERE  Id           = :con.AcctId
                          AND    recordTypeId = :nomsTypeId
                          LIMIT 1];
                          
       if (retAcct.Hav_Street__c == 'Local/Surveyor')
              setUsrLoc = retAcct.HAV_Country__r.HAV_Letter_Code__c+retAcct.Hav_Locality__c;
 
       if (con.middlename == null) {
           System.debug('3: '+setUsrLoc);
               formatUsrName = con.Lastname.deleteWhitespace().toLowercase().trim()+'.'+con.Firstname.deleteWhitespace().toLowercase().trim()+'.cnastaff'+setUsrLoc+'@HAVNA.gmail';
           } else {
               System.debug('4: '+setUsrLoc);
               midSize = con.Middlename.length();
               if (midSize == 1) {
                   System.debug('5: '+setUsrLoc);
                   formatUsrName = con.Lastname.deleteWhitespace().toLowercase().trim()+'.'+con.Firstname.deleteWhitespace().toLowercase().trim()+'.'+con.middlename.deleteWhitespace().toLowercase().trim()+'.cnastaff'+setUsrLoc+'@HAVNA.gmail';
               } else {
                   System.debug('6: '+setUsrLoc);
                   formatUsrName = con.Lastname.deleteWhitespace().toLowercase().trim()+'.'+con.Firstname.deleteWhitespace().toLowercase().trim()+'.'+con.middlename.deleteWhitespace().trim().substring(0,1).toLowercase()+'.cnastaff'+setUsrLoc+'@HAVNA.gmail';
               }    
           }
           
 User thisUser = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()];
 system.runAs(thisUser){
         User u       = new User(Alias      = con.LastName.deleteWhitespace().trim().length() > 4 ? con.LastName.deleteWhitespace().trim().substring(0,4)+setUsrLoc: con.LastName+setUsrLoc,
                         Email              = con.email,
                         EmailEncodingKey   = 'UTF-8',
                         LastName           = con.LastName,
                         FirstName          = con.Firstname,
                         MiddleName         = con.Middlename,         
                         LanguageLocaleKey  = 'en_US',
                         LocaleSidKey       = 'en_US',
                         ProfileId          = p.Id,
                         UserRoleId         = groleid,          
                         TimeZoneSidKey     = 'America/New_York',
                         UserName           = formatUsrName);
          
           Insert(u);
           System.debug(u.id);  

                        
        Test.startTest();
       
        NewUtilStaffProcess.createUtlUser(con.id);
 
        Test.stopTest();
        system.debug('Done');
    }
     }
}

Thanks.
Best Answer chosen by Sharon Crenshaw
Maharajan CMaharajan C
Hi Sharon,

The User Alias field has default size limit which is Maximum 8 characters. But code generating more than 8 character (Sminull90). 

Your code generating the alias dynamically so you have to handle the characters limit. And also avoid the null by using proper null check because am seeing null got genereated in alias Sminull90.
Alias      = con.LastName.deleteWhitespace().trim().length() > 4 ? con.LastName.deleteWhitespace().trim().substring(0,4)+setUsrLoc: con.LastName+setUsrLoc

Thanks,
Maharajan.C
jadentjadent 

On the task there is a WhatId and a WhoId. Sometimes the WhatId is filled in and others have the WhoId filled in. In which situations is one used over the other?

 

Thanks 

Best Answer chosen by Admin (Salesforce Developers) 
dkorba2k5dkorba2k5

WhoID refers to people things.  So that would be typically a Lead ID or a Contact ID

WhatID refers to object type things.  That would typically be an Account ID or an Opportunity ID

Salesforce GeekSalesforce Geek 
Hi There,

I’m newbie to Salesforce.

I would like to know the syntax “How to subtract one minute and two minutes from the current time”? I have checked in Datemethods in Apex documentation. No luck found.

Can anyone help?

Thanks
 
Best Answer chosen by Salesforce Geek
PratikPratik (Salesforce Developers) 
Hi,

This will work:

For 1 minute:   NOW() - (1/1440)
For 2 minutes:  NOW() - (2/1440)

Thanks,
Pratik

P.S. If this answers you question, please mark it as "Best Answer" so it will help other community members too.
crop1645crop1645 

Problem statement:

 

When APEX inserting OpportunityShare records, you get DML Exception: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY

 

Why does this happen?

 

The obvious reasons are:

 

  • OpportunityShare.OpportunityId is for an invalid Opportunity (or not an opportunity at all)
  • Running user doesn't have access to the Opportunity in OpportunityId



But if neither of these are the case...what else could it be?

 

ANSWER:

 

You can not insert OpportunityShare records for the current owner of the record.  You'll need to modify the Apex code to see if the current owner is the same as OpportunityShare.UserOrGroupId.  If it is, then don't insert.  You can still create OpportunityTeamMember records for that user but not OpportunityShare.  Who the current user is will depend if you are doing the OpportunityShare Dml statement in a before trigger, after trigger, VF controller, or API.

 

Although I haven't tested this, I presume the above applies to AccountShare and CaseShare objects as well.

Best Answer chosen by Admin (Salesforce Developers) 
crop1645crop1645
post to mark as Solved
Tien Le 488Tien Le 488 
Hi,

I'm trying to complete the trailhead "" and encountering a challenge.  If anyone has any feedback for me on this, I'd appreciate very much.  

Added VerifyDate.apxc as I did with TemperatureConverter.apxc.  Added TestVerifyDate.apxc (even with VerifyDateTest.apxc) as I did with TemperatureConverterTest.apxc.  I verified that those classes exist per screenshot1 below:
User-added image

I'm supposed to be able to go to Test, select New Run, then with Select Tests pop-up, I'm supposed to see the TestVerifyDate (and/or VerifyDateTest) classes to select and run; however, I'm not seeing those test classes.  Why?  Even with "[All Namespaces]", they still don't show.  

Workaround for now is to run the test suite per instructions earlier in the trailhead.  

Reference screenshot2 below:
User-added image

Thanks in advance for your help.
Tien





 
Best Answer chosen by Tien Le 488
Tien Le 488Tien Le 488
User-added image
Jiahao Zheng 33Jiahao Zheng 33 
Hi Trailblazers, I have a custom field called CNO/RNO__c on the standard Account object and I want to customize this CNO/RNO__c field to auto generate 6 digit number wheneven a new Account object is created. Is it possible to do it using Formula? Or we need to apply Apex code here? 
 
Best Answer chosen by Jiahao Zheng 33
VinayVinay (Salesforce Developers) 
You can create account record not an account object.  You can generate random number once you set the start value.  Eg. Salesforce-0001,  Salesforce-0002 etc based on your prefix or only number.

User-added image

Let me know if you have any additional questions

Please mark as Best Answer if above information was helpful so that it can help others in the future.

Thanks,
HanumanHanuman 
Hi all,
When custom button in detail page of  custom object is clicked i'm generating the PDF . I want to send the generated PDF as email. Can  we do this...?
Can anyone help me over here.

Thanks in advance.
Best Answer chosen by Hanuman
Amit Singh 1Amit Singh 1
Hello,

Use below code.
 
-- JavaScript --
{!requireScript("/soap/ajax/16.0/connection.js")}
{!requireScript("/soap/ajax/16.0/apex.js")}
var a = sforce.apex.execute("SendEmail","emailPdf",{localId:"{!Application__c.Id}"});

-- Apex Class Method --
public void SendEmail(Id localId){
 Application__c inv = [Select Id, name From Application__c Where Id=:localId];
 PageReference pdf = Page.PDFpage;// Replace PdfOfInvoice with your Page which render as PDF.
 pdf.getParameters().put('id', localId);
// Blob b = pdf.getContentAsPDF();
 Blob b;
 if (Test.IsRunningTest()){b=Blob.valueOf('UNIT.TEST');}else{b = pdf.getContentAsPDF();}
 // Create Attachment Object to attach with Email
 Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
 efa.setFileName(inv.Name+'.pdf');
 efa.setBody(b);
 // Define the email
 Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
 // Sets the paramaters of the email
 email.setSubject('PDF of Invoice - '+inv.Name);
 email.setToAddresses( new List<String>{inv.Email__c} );
 //email.setbccAddresses( new List<String>{'admin@gmail.com'} );
 email.sethtmlBody('Hi '+inv.Name+',<br/><br/> '
                        +'Please find the attached Invoice.'
                        +'<br/><br/>'+'Thanks,'+'<br/>'
                        +UserInfo.getName()+'<br/>'
                        +UserInfo.getOrganizationName());
 email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});

 try{
      Messaging.SendEmailResult [] result = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
 }catch(System.Exception e){
     
 }
Let me know if this helps :)

Thanks,
Amit Singh

 
Sophia GSophia G 
Hi,
I am having trouble with my Visualforce page and Apex Class. Everything seems to be fine apart from the error Unknown Property 'NFOSDisplayDivisions2Controller.Division_Space2__c'. I can't seem to figure out what is going on, could someone please help me out. Thank you.

Apex Class:
public with sharing class NFOSDisplayDivisions2Controller {
    
    public List<DivisionWrapper> listDivisionWrapper{get;set;}
    public List<Division_Space2__c> selectedDivisions{get;set;}

    public NFOSDisplayDivisions2Controller ()
    {
            listDivisionWrapper = new List<DivisionWrapper>();
            searchRecord();
    }
    
    public void searchRecord()
    {
        listDivisionWrapper.clear();
            for(Division_Space2__c a: [select Id, Name,Number_of_Competitors__c, Availability__c, RecordTypeID ,Active__c from Division_Space2__c limit 30]) 
            {
                listDivisionWrapper.add(new DivisionWrapper(a));
            }
    }

    public void processSelected() 
    {
        selectedDivisions = new List<Division_Space2__c>();
        selectedDivisions.clear();
        for(DivisionWrapper wrapDivisionObj : listDivisionWrapper) 
        {
            if(wrapDivisionObj.selected == true) 
            {
                selectedDivisions.add(wrapDivisionObj.acc);
                // Here you can add the counter or you check the selectedAccounts.size()
            }
        }
    }

    public void ActivateData() 
    {
        for(Division_Space2__c acc : selectedDivisions )
        {
            acc.Active__c= true;
        }
        update selectedDivisions ;
        searchRecord();
    }

    public void DeActivateData() 
    {
        for(Division_Space2__c acc : selectedDivisions )
        {
            acc.Active__c = false;
        }
        update selectedDivisions ;
        searchRecord();
    }
    


    // This is our wrapper/container class. 
    public class DivisionWrapper 
    {
        public Division_Space2__c acc {get;set;}
        public Boolean selected {get;set;}
        public DivisionWrapper(Division_Space2__c a) 
        {
            acc = a;
            selected = false;
        }
    }

}

Visualforce Page:
<apex:page controller= "NFOSDisplayDivisions2Controller">
    
<script type="text/javascript">
        function selectAllCheckboxes(obj,receivedInputID){
            var inputCheckBox = document.getElementsByTagName("input");
            for(var i=0; i<inputCheckBox.length; i++){
                if(inputCheckBox[i].id.indexOf(receivedInputID)!=-1){
                    inputCheckBox[i].checked = obj.checked;
                }
            }
        }
    </script>
    <apex:form >
        <apex:pageBlock id="PB1">
            <apex:pageBlockButtons >
                <apex:commandButton value="Add to Grid" action="{!processSelected}" rerender="table2,PB2"/>
            </apex:pageBlockButtons>

            <apex:pageblockSection title="Division Types" collapsible="false" columns="1">
                <apex:pageBlockTable value="{!listDivisionWrapper}" var="accWrap" id="table" title="Division Types">
                    <apex:column >
                        <apex:facet name="header">
                            <apex:inputCheckbox onclick="selectAllCheckboxes(this,'inputId')"/>
                        </apex:facet>
                        <apex:inputCheckbox value="{!accWrap.selected}" id="inputId"/>
                    </apex:column>
                    <apex:column value="{!Division_Space2__c.acc.Name}" />
                    <apex:column value="{!Division_Space2__c.acc.Number_of_Competitors__c}" />
                    <apex:column value="{!Division_Space2__c.acc.Availability__c}" />
                    <apex:column value="{!Division_Space2__c.acc.Active__c}" />
                </apex:pageBlockTable>


            </apex:pageblockSection>
        </apex:pageBlock>
        
        <apex:pageBlock id="PB2" >
            <apex:pageBlockButtons >
                <apex:commandButton value="Activate" action="{!ActivateData}" rerender="PB1,PB2"/>
                <apex:commandButton value="DeActivate" action="{!DeActivateData}" rerender="PB1,PB2"/>
            </apex:pageBlockButtons>

                <apex:pageBlockTable value="{!selectedDivisions}" var="c" id="table2" title="Selected Divisions">
                    <apex:column value="{!c.Name}" headerValue="Division Type"/>
                    <apex:column value="{!c.Number_of_Competitors__c}" headerValue="Number of Competitors"/>
                    <apex:column value="{!c.Availability}" headerValue="Availability"/>
                    <apex:column value="{!c.Active__c}" headerValue="Active"/>
                </apex:pageBlockTable>
        </apex:pageBlock>

        
    </apex:form>
</apex:page>
Best Answer chosen by Sophia G
Maharajan CMaharajan C
Hi Sophia,

In the first pageblocktable you are wrongly refering the properties:

 <apex:column value="{!Division_Space2__c.acc.Name}" />  ==>  <apex:column value="{!accWrap.acc.Name}" />


Visualforce Page:
<apex:page controller= "NFOSDisplayDivisions2Controller">
    
<script type="text/javascript">
        function selectAllCheckboxes(obj,receivedInputID){
            var inputCheckBox = document.getElementsByTagName("input");
            for(var i=0; i<inputCheckBox.length; i++){
                if(inputCheckBox[i].id.indexOf(receivedInputID)!=-1){
                    inputCheckBox[i].checked = obj.checked;
                }
            }
        }
    </script>
    <apex:form >
        <apex:pageBlock id="PB1">
            <apex:pageBlockButtons >
                <apex:commandButton value="Add to Grid" action="{!processSelected}" rerender="table2,PB2"/>
            </apex:pageBlockButtons>

            <apex:pageblockSection title="Division Types" collapsible="false" columns="1">
                <apex:pageBlockTable value="{!listDivisionWrapper}" var="accWrap" id="table" title="Division Types">
                    <apex:column >
                        <apex:facet name="header">
                            <apex:inputCheckbox onclick="selectAllCheckboxes(this,'inputId')"/>
                        </apex:facet>
                        <apex:inputCheckbox value="{!accWrap.selected}" id="inputId"/>
                    </apex:column>
                    <apex:column value="{!accWrap.acc.Name}" />
                    <apex:column value="{!accWrap.acc.Number_of_Competitors__c}" />
                    <apex:column value="{!accWrap.acc.Availability__c}" />
                    <apex:column value="{!accWrap.acc.Active__c}" />

                </apex:pageBlockTable>


            </apex:pageblockSection>
        </apex:pageBlock>
        
        <apex:pageBlock id="PB2" >
            <apex:pageBlockButtons >
                <apex:commandButton value="Activate" action="{!ActivateData}" rerender="PB1,PB2"/>
                <apex:commandButton value="DeActivate" action="{!DeActivateData}" rerender="PB1,PB2"/>
            </apex:pageBlockButtons>

                <apex:pageBlockTable value="{!selectedDivisions}" var="c" id="table2" title="Selected Divisions">
                    <apex:column value="{!c.Name}" headerValue="Division Type"/>
                    <apex:column value="{!c.Number_of_Competitors__c}" headerValue="Number of Competitors"/>
                    <apex:column value="{!c.Availability}" headerValue="Availability"/>
                    <apex:column value="{!c.Active__c}" headerValue="Active"/>
                </apex:pageBlockTable>
        </apex:pageBlock>

        
    </apex:form>
</apex:page>

Thanks,
Maharajan.C

 
Saloni KhedkarSaloni Khedkar 
I have a custom object which has a list of products, country field and checkbox- inactive.

Use case: 
When I create an opportunity and add OpportunityLineItem, The line item should compare with the products field from the custom object.
Also, the Opportunity should look at Bill to country from the account attached and compare with the country field from the custom object.
And if the record matches and the "Inactive" checkbox from the custom object is true, then it should throw an error and not allow to save the opportunity.

For example,
Custom object:
Product: Pencil
Country: Mexico
Inavtive: True

Opportunity:
OpportunityLineItem: Pencil
Account - Bill to Country: Mexico
ERROR FLAG

Can this be achievable ? If so, can i receive some help on building the trigger ?

Thank you in advance.
Best Answer chosen by Saloni Khedkar
Maharajan CMaharajan C
Hi Saloni,

We can write trigger to handle this scenario:

Please refer the below code:

am considering Product__c  as Custom Object in below code
 
trigger OpportunityProductCheck on OpportunityLineItem (before insert) {
	set<Id> oppIds = new set<id>();
    set<Id> prodIds = new set<Id>();
    map<String,Boolean> prodcheckMap = new map<String,Boolean>();
    for(OpportunityLineItem oli : Trigger.New){
        oppIds.add(oli.OpportunityId);
        prodIds.add(oli.Product2Id);
    }
    Map<Id,Opportunity> oppMap = new Map<Id,Opportunity>([Select Id,Account.BillingCountry from Opportunity where ID IN: oppIds]);
    Map<Id,Product2> prodMap = new Map<Id,Product2>([Select Id,Name from Product2 where Id IN: prodIds]);
    for(Product__c prod : [Select Id,Inactive__c,Product__c,Country__c from Product__c]){
        String key = '';
        if(!String.isEmpty(prod.Product__c) && !String.isEmpty(prod.Country__c)){
            key = prod.Product__c + prod.Country__c;
            prodcheckMap.put(key, prod.Inactive__c);
        }
    }
    
    for(OpportunityLineItem oli : Trigger.New){
        string prodName = prodMap.containsKey(oli.Product2Id) ? prodMap.get(oli.Product2Id).Name : '';
        string acccountry = oppMap.containsKey(oli.OpportunityId) ? oppMap.get(oli.OpportunityId).Account.BillingCountry : '';
        //string olikey = prodMap.get(oli.Product2Id).Name + oppMap.get(oli.OpportunityId).Account.BillingCountry;
        string olikey = prodName + acccountry;
        if(prodcheckMap.containsKey(olikey)){
            boolean bool = prodcheckMap.get(olikey);
            if(bool){
                String errormsg = prodName + ' is Inactive for ' + acccountry;
                oli.addError(errormsg);
            }
        }
    }
}

Thanks,
Maharajan.C