• Saad Ahmad 27
  • NEWBIE
  • 90 Points
  • Member since 2016

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 15
    Questions
  • 18
    Replies
My requirement is to be able to import quote line items into a quote using a CSV. I have written the following code but I'm unable to get it working. The code shows no errors but when I try to import a CSV, it doesn work. Thank you in advance for any guidance you can provide:

APEX Code:
public class importDataFromCSVController {
	public Blob csvFileBody{get;set;}
	public string csvAsString{get;set;}
	public String[] csvFileLines{get;set;}
	public List<QuoteLineItem> quoteLineItemList{get;set;}
    public List<Quote> quoteNumberList{get;set;}
  	public importDataFromCSVController(){
    
    csvFileLines = new String[]{};
    quoteLineItemList = New List<QuoteLineItem>(); 
  	}
  
  	public void importCSVFile(){
      List<String> allProductCodes = new List<String>();
      List<String> allQuoteNumbers = new List<String>();
      Map<String, Id> quoteNumber = new Map<String, Id>();
      
      //Query for Products that have matching Product Code
      Map<String, Id> productCode = new Map<String, Id>();
      for (Product2 p : [SELECT Id, Name from Product2 where Name in :allProductCodes LIMIT 1]) {
          productCode.put(p.Name,p.Id);
      }
      
      //Query for Quotes that have matching Quote Number
      Map<String, Id> quoteNum = new Map<String, Id>();
        for (Quote q : [SELECT Id, QuoteNumber from Quote where QuoteNumber in :allQuoteNumbers LIMIT 1]) {
            quoteNum.put(q.QuoteNumber, q.Id);
      }
      
      // Set the Product Id for each Product Code  
      for(Integer j=0;j<quoteLineItemList.size();){
          QuoteLineItem qli1;
          Id Productid = productCode.get(allProductCodes[j]);
          if (Productid != null) {
              qli1.Product2.Id = Productid;
          }
      // Set the Quote Id for each Quote
          for (Integer z=0;z<quoteNumberList.size();){
              Quote q1;
              Id quoteNumberId = quoteNum.get(allQuoteNumbers[z]);
              if (quoteNumberId != null) {
                  q1.Id = quoteNumberId;
              }
          }    
      }
       try{
           csvAsString = csvFileBody.toString();
           csvFileLines = csvAsString.split('\n'); 
            
           for(Integer i=1;i<csvFileLines.size();i++){
               QuoteLineItem lineItem = new QuoteLineItem() ;
               string[] csvRecordData = csvFileLines[i].split(',');
               allQuoteNumbers.add(csvRecordData[0]);
               allProductCodes.add(csvRecordData[1]);
               lineItem.Quantity = decimal.valueof(csvRecordData[2]);
               lineItem.UnitPrice = decimal.valueof(csvRecordData[3]);
               lineItem.Global_Discount__c = decimal.valueof(csvRecordData[4]);                                                                    
               quoteLineItemList.add(lineItem);   
           }
        insert quoteLineItemList;
        }
        catch (Exception e)
        {
            ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.severity.ERROR,'An error has occured. Please try importing the file again');
            ApexPages.addMessage(errorMessage);
        }  
  }
}

Visualforce Page Code
<apex:page controller="importDataFromCSVController">
    <apex:form >
        <apex:pagemessages />
        <apex:pageBlock >
            <apex:pageBlockSection columns="5"> 
                  <apex:inputFile value="{!csvFileBody}"  filename="{!csvAsString}"/>
                  <apex:commandButton value="Import Quote Line Items" action="{!importCSVFile}"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
        <apex:pageBlock >
           <apex:pageblocktable value="{!quoteLineItemList}" var="acc">
              <apex:column value="{!acc.Quote}" /> 
              <apex:column value="{!acc.Product2}" />
              <apex:column value="{!acc.Quantity}" />
              <apex:column value="{!acc.UnitPrice}" />
              <apex:column value="{!acc.Global_Discount__c}" />
        </apex:pageblocktable>
     </apex:pageBlock>
   </apex:form>
</apex:page>

 
I have the following piece of code that I am unable to figure out how to include in test. I've tried a couple of different ways but I am unable to get Line 8 included in the test scenario. Any help is greatly appreciated!! 
 
trigger SetCaseDetails on Case (before insert, before update) {
    Id ITSRecordID = O__c.getOrgDefaults().ITS_Case_Record_Type__c;
    Id TechRecordID = O__c.getOrgDefaults().TechSupportID__c;
    Map<Id, Case> parentCaseOwners = new Map<Id, Case>();
    Map<String, Repair_History__c> repairHistories = new Map<String, Repair_History__c>();
    for (Case c : Trigger.new) {
        if (c.ParentId != null &  c.Parent.Is_Owner_Active__c != false) {
            parentCaseOwners.put(c.ParentId, null);
        }
        if (c.SO__c != null) {
            repairHistories.put(c.SO__c, null);
        } if (c.Status == 'Closed' || c.Status == 'No Bid' || c.Status == 'Complete' || c.Status == 'Cancelled') {
            c.Open_Lookup__c = null;
       } else if (c.AccountId != null) {
            c.Open_Lookup__c = c.AccountId;
        }
    }    
    if (!parentCaseOwners.isEmpty()) {
        for (Case pc: [SELECT Id, OwnerId FROM Case WHERE Id in :parentCaseOwners.keySet()]) {
            parentCaseOwners.put(pc.Id,pc);
        }        
        for (Case c : Trigger.new) {
            if (c.ParentId != null & c.RecordTypeID != ITSRecordID & c.RecordTypeID != TechRecordID & c.Parent.Is_Owner_Active__c != false) 
				          
            {
                c.OwnerId = parentCaseOwners.get(c.ParentId).OwnerId;
            }
        }
    }

My test code:
 
@isTest
private class TestSetCaseDetails {
 	static testMethod void test() {    
 	Profile pf= [Select Id from profile where Name='System Administrator' limit 1]; 
        
        String orgId=UserInfo.getOrganizationId(); 
        String dateString=String.valueof(Datetime.now()).replace(' ','').replace(':','').replace('-','') ;
        Integer RandomId=Integer.valueOf(Math.rint(Math.random()*1000000)); 
        String uniqueName=orgId+dateString+RandomId; 
        User uu=new User(firstname = 'ABC', 
                         lastName = 'XYZ', 
                         email = uniqueName + '@test' + orgId + '.org', 
                         Username = uniqueName + '@test' + orgId + '.org', 
                         EmailEncodingKey = 'ISO-8859-1', 
                         Alias = uniqueName.substring(18, 23), 
                         TimeZoneSidKey = 'America/Los_Angeles', 
                         LocaleSidKey = 'en_US', 
                         LanguageLocaleKey = 'en_US', 
                         ProfileId = pf.Id,
                         isActive = True
                        ); 
      	insert uu;
      	system.debug('User active ' + uu.IsActive);
      
	System.runAs(uu){
		
        List<Repair_History__c> repairhistories = new List<Repair_History__c>();
        List<Case> caseowners = new List<Case>();
      
      	Map<id,Case> parentCaseOwners = new Map<id,Case>();
      
      	Id caserec = Schema.SObjectType.Case.getRecordTypeInfosByName().get('BA Support Case').getRecordTypeId();
      
        Account a1 = new Account(
            Name='A1',
            BillingStreet = 'Street',
            BillingCity = 'City',
            BillingPostalCode = 'Postal Code',
            BillingState = 'ON',
            BillingCountry = 'Country'        
        );
        insert a1;
        
        case c1 = new Case(
        	Status='New',
        	Origin='Email',
			SO__c='12345678',
            subject='parent case',
            Open_Lookup__c=a1.id,
            accountid=a1.id,
            ownerid=uu.Id
        	);
        insert c1;
        c1 = [select id, Is_Owner_Active__c from Case where id=:c1.id];
        system.debug('Case User Is active: ' + c1.Is_Owner_Active__c);
      	
        caseowners.add(c1);
        parentCaseOwners.put(c1.id, c1);
      
     	case c2 = new Case(
        	Status='Closed',
        	Origin='Email',
            subject='child case',
			Parentid=c1.Id,
            SO__c='12345678',
            RecordTypeId=caserec
        	);
        //insert c2;
        c2 = [select id, Is_Owner_Active__c from Case where id=:c1.id];
        system.debug('Child Case User Is active: ' + c2.Is_Owner_Active__c);
        parentCaseOwners.put(c2.id, c2);
      
      case c3 = new Case(
        	Status='Closed',
        	Origin='Email',
            subject='child case',
            Parentid=c1.Id,
            SO__c='12345678'
        	);
        insert c3;
        c3 = [select id, Is_Owner_Active__c from Case where id=:c3.id];
      	caseowners.add(c2);
        caseowners.add(c3);
        
        Account a2 = new Account(
            Name = 'A2',
            JDE_Account_Number__c='JDE',
            ParentId=a1.Id,
            BillingStreet = 'Street',
            BillingCity = 'City',
            BillingPostalCode = 'Postal Code',
            BillingState = 'ON',
            BillingCountry = 'Country'
        );
        insert a2;
        
		
		Product2 prod = new Product2(Name = 'Laptop X200', 
                                     Family = 'Hardware');
        insert prod;
        
		
		
      	Repair_History__c p1 = new Repair_History__c();
            p1.Repair_Number__c  = '123456';
            p1.Total_Price__c  = 100;
            p1.Account__c = a1.Id;
		p1.product__c = prod.Id;
            insert p1;
      
      	Repair_History__c p2 = new Repair_History__c();
            p2.Repair_Number__c  = '1234567';
            p2.Total_Price__c  = 100;
            p2.Account__c = a2.Id;
				 p2.product__c = prod.Id;
            insert p2;
      
      	repairhistories.add(p1);
        repairhistories.add(p2);
      
    }
  }
}

 
I have some  code that was previously written for us for a visualforce page in our instance of SFDC. I'm just trying to get a better understanding of the following:
 
var vendor_category = $('.row-vendor-'+row_no).val();

Can someone help me understand what the above line does and where would I go about to find '.row-vendor' ?

Please let me know if there are any additional question. Thank you in advance for your help!!
I wrote this code but I'm only getting 60% coverage. I'm unable to figure out how to get to 100% coverage. Any help will be much appreciated!
 
global class InvoiceLineItemCleanUp implements Database.Batchable<SObject>, Database.Stateful {
	
    Date CutoffDate = Olympus__c.getOrgDefaults().Last_Modified_Date__c;
    
    global InvoiceLineItemCleanUp() {
    }
    
    global Database.QueryLocator start(Database.BatchableContext bc) {
        String searchRec = 'SELECT Id FROM Order_Line_Item__c WHERE CreatedDate > :CutoffDate AND LastModifiedDate <> LAST_N_DAYS:30';
        return Database.getQueryLocator(searchRec);
    }

    global void execute(Database.BatchableContext bc, List<SObject> batch) {
        List<Order_Line_Item__c> b = (List<Order_Line_Item__c>)batch;
        
        Database.delete(b);
        if(!b.isEmpty()) { Database.emptyRecycleBin(b); }
    }
    
    global void finish(Database.BatchableContext bc) {
    }
}



Here is my test code 
 
@isTest
private class InvoiceLineItemCleanUp_test {    
    static testMethod void test() { 
        Order_Line_Item__c invoiceLine = new Order_Line_Item__c(Quantity__c = 1);
        insert invoiceLine;
               
        Datetime yesterday = Datetime.now().addDays(-31);
        Test.setCreatedDate(invoiceLine.Id, yesterday);
               
        Test.startTest();
        Database.executeBatch(new InvoiceLineItemCleanUp());
        Test.stopTest();
    }
}


​​​​​​​
I have 10 look up fields that need to be updated based on 10 text fields on the custom object. The text field contains the user ID of a person and this field is used to fill out the look up field. 
e.g. CDS User ID (text field) = 12345, the look up field (related to User object) will be updated with user who's federation identifier = 12345.

I have written a trigger to update 1 look up field but i'm unable to expand this to include all 10 fields.
 
trigger UpdateUserOnRepairHistory on Repair_History__c (before insert, before update) {
    
    Map<String, Repair_History__c> RepHistorytoUser = new Map<String, Repair_History__c>();
    
    for (Repair_History__c rH:Trigger.new)
    {
        RepHistorytoUser.put(rH.CDS_End_User_ID__c, rH);
    }
	
    List<User> userList = [SELECT Id, FederationIdentifier from User where FederationIdentifier in :RepHistorytoUser.keySet()];
    
    for (User usr : userList){
        RepHistorytoUser.get(usr.FederationIdentifier).CDS_End_User_Name__c = usr.Id;
    }
    
}

 
I have written the following trigger, however I'm unable to cover the following lines in my test class. Unable to figure out what I'm missing. Thank you in advance for everyones help!

User-added image
Here is the trigger:
trigger SetCaseDetails on Case (before insert, before update) {
    Id ITSRecordID = Olympus__c.getOrgDefaults().ITS_Case_Record_Type__c;
    Id TechRecordID = Olympus__c.getOrgDefaults().TechSupportID__c;
    Map<Id, Case> parentCaseOwners = new Map<Id, Case>();
    Map<String, Repair_History__c> repairHistories = new Map<String, Repair_History__c>();
    for (Case c : Trigger.new) {
        if (c.ParentId != null) {
            parentCaseOwners.put(c.ParentId, null);
        }
        if (c.SO__c != null) {
            repairHistories.put(c.SO__c, null);
        } if (c.Status == 'Closed' || c.Status == 'No Bid' || c.Status == 'Complete' || c.Status == 'Cancelled') {
            c.Open_Lookup__c = null;
       } else if (c.AccountId != null) {
            c.Open_Lookup__c = c.AccountId;
        }
    }    
    if (!parentCaseOwners.isEmpty()) {
        for (Case pc: [SELECT Id, OwnerId FROM Case WHERE Id in :parentCaseOwners.keySet()]) {
            parentCaseOwners.put(pc.Id,pc);
        }        
        for (Case c : Trigger.new) {
            if (c.ParentId != null & c.RecordTypeID != ITSRecordID & c.RecordTypeID != TechRecordID) {
                c.OwnerId = parentCaseOwners.get(c.ParentId).OwnerId;
            }
        }
    }   
    if (!repairHistories.isEmpty()) {
        for (Repair_History__c rh : [SELECT Id, Account__c, Repair_Number__c, Product__c FROM Repair_History__c WHERE Repair_Number__c in : repairHistories.keySet()]) {
            repairHistories.put(rh.Repair_Number__c, rh);
        }        
        for (Case c : Trigger.new) {
            if (c.SO__c != null && repairHistories.get(c.SO__c) != null) {
                c.Repair_History__c = repairHistories.get(c.SO__c).Id;
                c.ProductId = repairHistories.get(c.SO__c).Product__c;
                if (c.AccountId == null && repairHistories.get(c.SO__c).Account__c != null) {
                    c.AccountId = repairHistories.get(c.SO__c).Account__c;
                }
            }
        }
    }
}

Here is the test class:
 
@isTest
private class TestSetCaseDetails {
  static testMethod void test() {       
        List<Repair_History__c> repairhistories = new List<Repair_History__c>();
        List<Case> caseowners = new List<Case>();
      
      	Map<id,Case> newMap = new Map<id,Case>();
      
      	Id caserec = Schema.SObjectType.Case.getRecordTypeInfosByName().get('BA Support Case').getRecordTypeId();
      
        Account a1 = new Account(
            Name='A1',
            BillingStreet = 'Street',
            BillingCity = 'City',
            BillingPostalCode = 'Postal Code',
            BillingState = 'ON',
            BillingCountry = 'Country'        
        );
        insert a1;
        
        case c1 = new Case(
        	Status='New',
        	Origin='Email',
            subject='parent case',
            Open_Lookup__c=a1.id,
            accountid=a1.id
        	);
        insert c1;
      newMap.put(c1.id,null);
      caseowners.add(c1);
      
     	case c2 = new Case(
        	Status='closed',
        	Origin='Email',
            subject='child case',
            parent=caseowners[0],
            SO__c='12345678',
            RecordTypeId=caserec
        	);
        insert c2;
      newMap.put(c2.id,null);
      
      case c3 = new Case(
        	Status='closed',
        	Origin='Email',
            subject='child case',
            parent=caseowners[0],
            SO__c='12345678'
        	);
        insert c3;
      
      caseowners.add(c2);
      
        Account a2 = new Account(
            Name = 'A2',
            JDE_Account_Number__c='JDE',
            ParentId=a1.Id,
            BillingStreet = 'Street',
            BillingCity = 'City',
            BillingPostalCode = 'Postal Code',
            BillingState = 'ON',
            BillingCountry = 'Country'
        );
        insert a2;
        
      	Repair_History__c p1 = new Repair_History__c();
            p1.Repair_Number__c  = '123456';
            p1.Total_Price__c  = 100;
            p1.Account__c = a1.Id;
            insert p1;
      
      	Repair_History__c p2 = new Repair_History__c();
            p2.Repair_Number__c  = '1234567';
            p2.Total_Price__c  = 100;
            p2.Account__c = a2.Id;
            insert p2;
      
      	repairhistories.add(p1);
        repairhistories.add(p2);
      
    }

}

​​​​​​​
 
I have created a Visual Flow to update look up fields based on the User ID field. E.g.
User ID field = 1234. The Visual Flow looks up all the User records from the User object and assigns the name of User ID 1234 to the User Name field on the record.
Due to the number of User ID fields that have to be looked up, the Flow is hitting governer limits. I'd like to create a batchable Apex to achieve this and I was wondering if this would be possible? I'd appreciate any help/guidance on this!

User-added image

 
I have writted the following trigger along with the test below. I'm unable to figure out how to cover the for loop in my test class. Looking forward to your advise.
 
List<Account> accountUpdatedList = new List<Account>();
    Map<string,string> territoryWithParentTerritoryNameMap = new map<string,string>();
    for(Territory2 tr : [SELECT id, Name,Territory2.ParentTerritory2.Name FROM Territory2 WHERE Territory2.ParentTerritory2.Name != Null Limit 50000])
    {
        territoryWithParentTerritoryNameMap.put(tr.name,tr.ParentTerritory2.Name);
    }
        
    for (Account ac : Trigger.new) {
        ac.Sales_Rep_Region__c = ' ';
        Integer counter = 0;
        if (ac.Territories__c != null) {
            for (String t : ac.Territories__c.split(',')) {
                counter += 1;
            }
            ac.Team_count__c = counter - 3;
        }
    
    if(ac.Territories__c != Null && ac.Territory_Has_Changed__c != False) 
        {
            for(string str : ac.Territories__c.split(',')){
                if(str != '104B' && str != '109B' && str != '109A' && str != ac.RVP_Code__c && str != '104A'){ 
                    if(territoryWithParentTerritoryNameMap.containsKey(str)){
                    
                        string tempParentTerritoryName = territoryWithParentTerritoryNameMap.get(str);
                        if(ac.RVP_Code__c != tempParentTerritoryName){                                
                            if(!ac.Sales_Rep_Region__c.contains(str)){                                    
                                ac.Sales_Rep_Region__c += str + ',';
                                accountUpdatedList.add(ac);   
                                    
                            }
                            
                        }
                       
                    }
                    
                }
              
            }
        }
        
    }

Test:
@istest
private class AccountTerritoryCount_test {
    static testMethod void TestAccount(){
        Account acc = new Account(name='test', 
                              jde_account_number__c='1234',
                              Territories__c='1234,1234,1234,1234,1234,1224,1234,1234,1234,');
    	insert acc;
        
    }
    
    static testMethod void myAccountTest()
    {
        List<Account> accountUpdatedList = new List<Account>();
        Map<string,string> territoryWithParentTerritoryNameMap = new map<string,string>();
    	for(Territory2 tr : [SELECT id, Name,Territory2.ParentTerritory2.Name FROM Territory2 
                         WHERE Territory2.ParentTerritory2.Name != '109N' Limit 50000])
        {
        	territoryWithParentTerritoryNameMap.put(tr.name,tr.ParentTerritory2.Name);
        }
        
        Account ac = new Account();
        ac.name = 'Toronto';
        ac.JDE_Account_Number__c = '12345678';
        ac.Territories__c = '1011,1436';
        ac.RVP_Code__c = '109N';
        insert ac;
        
        Account ac2 = new Account();
        ac2.name = 'Toronto2';
        ac2.JDE_Account_Number__c = '12345679';
        ac2.Territories__c = '1011,1436';
        ac2.RVP_Code__c = '109N';
        insert ac2;
        
        ac = [SELECT Sales_Rep_Region__c,Territories__c from Account where Id =:ac.Id];
        
        system.assertEquals(ac.Sales_Rep_Region__c, null);
        
    }
    
}
Lines 
User-added image
I have a list of territories names that are inserted into a custom field, Territories__c from an external system via dataloader. The names are split by a comma. eg: 1234,2345,9564 etc. Another custom field called RVP_Code__c stores the parent territory name. e.g. 1111

I'd like to go thru the list of these territories and add the territories names that don't have the same parent territory into a new field, Sales_Rep_Region__c, for review. I wrote a trigger below but it doesn't seem to be working. Would love to get some help regarding this. Thank you in advance!! 
trigger AccountTerritoryReview on Account (before insert) {
	
    List<Account> RepstoAdd = new List<Account>();
    
    if(TriggerHandler.run ){
        TriggerHandler.run = false;
        
        for (account acc : Trigger.new){
            if (acc.Territories__c != null) {
                for (string t : acc.Territories__c.split(',')) {
                    List<Territory2> tt = new List<Territory2>([SELECT Name,Territory2.ParentTerritory2.Name FROM Territory2 WHERE Territory2.Name = :t]);
                    for (Territory2 tx : tt){
                        if (tx.ParentTerritory2.Name != acc.RVP_Code__c){
                            acc.Sales_Rep_Region__c = tx.Name;
                            RepstoAdd.add(acc);
                        }
                    }
                    }                       
                }
            }
            
            
        }
    
    update RepstoAdd;
    
}


 
Hello, I have a custom object that has a look up to the account object. I've written the trigger below to count the child records and update a field on the Account object. The code also sums the total of the child records and updates a field on the Account.

The trigger works fine if I update one child record but throws a DML error "InvoiceRollUp: System.LimitException: Too many SOQL queries: 101"  when I do a bulk update via dataloader. Thank you in advance for your help!
trigger InvoiceRollUp on Order_Line_Item__c (after insert, after update,after delete,after undelete) {
    
    set<id> AccountIds = new set<id>();
    
    if(trigger.isInsert || trigger.isUpdate){
        for(Order_Line_Item__c li : trigger.new){
            AccountIds.add(li.Ship_To__c);
        }
    }
    
    //When deleting payments
    if(trigger.isDelete){
        for(Order_Line_Item__c li : trigger.old){
            AccountIds.add(li.Ship_To__c);
        }
    }
    
   map<Id,Double> AccountMap = new map<Id,Double>();
   
    for(AggregateResult q : [select Ship_To__c , sum(Line_Item_Total__c) from Order_Line_Item__c where (Ship_To__c IN :AccountIds AND (Invoice_Date__c=Last_N_Months:12)) group by Ship_To__c]){
        AccountMap.put((Id)q.get('Ship_To__c'),(Double)q.get('expr0'));
    }

    List<Account> AccountsToUpdate = new List<Account>();
    
    for(Account acc : [Select Id, Invoice_Total__c from Account where Id IN :AccountIds]){
        Double PaymentSum = AccountMap.get(acc.Id);
        acc.Invoice_Total__c = PaymentSum;
        AccountsToUpdate.add(acc);
    }
    
    for(AggregateResult OC : [select Ship_To__c , count(Id) from Order_Line_Item__c where (Ship_To__c IN :AccountIds) group by Ship_To__c]){
        AccountMap.put((Id)OC.get('Ship_To__c'),(Double)OC.get('expr0'));
    }
    
    List<Account> AccountsToCount = new List<Account>();
    
    for(Account ac : [Select Id, Invoice_Total__c from Account where Id IN :AccountIds]){
        Double counter = AccountMap.get(ac.Id);
        ac.Invoice_Line_Item_Count__c = counter;
        AccountsToCount.add(ac);
    }
 
  update AccountsToUpdate;
  update AccountsToCount;
}

 
My Code is: 
public class AssociateSOExtController {

    public Quote quote { get; set; }
    
    public AssociateSOExtController() {
        
        String quoteId = ApexPages.currentPage().getParameters().get('id');
        quote = [SELECT Id, Name, Service_Repair__c FROM quote WHERE Id =: quoteId];
        
    }
    
    public PageReference associate () {
        
        Repair_History__c SORepair = new Repair_History__c ( Id = quote.Service_Repair__c, Quote__c = quote.Id);
        
        try {
        	Database.update(SORepair);
        } catch (Exception error) {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Error while associating.' + error.getMessage()));
        }
        
        PageReference page = new PageReference('/' + quote.Id);
        
        return page.setRedirect(true);
    }
    
    public PageReference cancel () {
        PageReference page = new PageReference('/' + quote.Id);
        return page.setRedirect(true);        
    }
    
}

Thank you all for your help!
I’ve been struggling for a while trying to find the best solution for managing cases internally within the org. Would love to get other Salesforce experts ideas/suggestions.

Requirement: To have multiple departments within the company use Salesforce cases to track their projects/tickets.

We currently use email2case to forward emails to Salesforce and have cases created along with an acknowledgement email sent to the contact. As the case progresses or if further information is needed from the customer, the users use an email button shortcut to reach out the to customer from within the case. This solution works very well when customers are working one-on-one with different departments.
The issue arises when one department 1 (D1) requires additional information or support from department 2 (D2). When D1 emails D2’s email from within the case, D2’s email account then forwards this case to Salesforce. But since there is a reference ID attached to this email, instead of D2 getting a new case notification, the email just ends up back in D1’s original case.

There are different options I’m looking into to mitigate this issue:
  1. D1 creates a child case and assigns it to D2. D2 then manages this child case until completion. My only concern is how communication would work between D1 and D2. We want to minimize chatter use as this isn’t reportable.
  2. D1 switches the case owner to D2. D2 now completes anything required, once complete; D2 switches the case back to D1.
  3. D1 uses web2case to create a new case if they need any assistance from D2 with regards to the original case.
I’m fairly new to Service cloud and would love to get some advise from others who might have dealt with a similar situation.
Thank you all!
 
Hi All,

I'm new to apex coding and wrote my first trigger. I'm not sure how to go about writing a test class. I read up a couple of different forums but haven't been able to figure it out.

trigger OpenRepairs on Repair_History__c (before insert, before update) {
    for (Repair_History__c R: Trigger.new) {
        if (R.Status__c == 'Closed') {
            R.OpenRepair__c = null;
        } else if (R.Status__c == 'Closed - Traded In') {
            R.OpenRepair__c = null;
        } else if (R.Status__c == 'Closed - Return Unrepair') {
            R.OpenRepair__c = null;
        } else if (R.Account__c != null) {
            R.OpenRepair__c = R.Account__c;
        }
    }
}
I have a visualforce page and would like retain the picklist value that the user selects on page reload. It's set to "Internal" by default, however, if the user chooses "External", this should now be the default on page reload. Thank you all for your advise!

<apex:page controller="ExternalReportsController" action="{!getReports}" showChat="false" sidebar="false" showHeader="false">
    <style>body { background-color: inherit !important; }</style>
    <apex:form id="theForm">
        <apex:outputLabel value="<b>Network: </b>" escape="false"/>
        <apex:selectList value="{!selectedNetwork}" multiselect="false" size="1">
            <apex:selectOption itemLabel="Internal" itemValue="Internal"/>
            <apex:selectOption itemLabel="External" itemValue="External"/>
            <apex:actionSupport event="onchange" action="{!getReports}" reRender="theForm"/>
        </apex:selectList>
        <br/>
        <apex:repeat value="{!reports}" var="r" id="reportList">
            <a href="{!IF(selectedNetwork = 'External', r.External_Server__c, r.Internal_Server__c) + r.Link__c}{!IF(r.Add_Territory__c, territories, null)}" target="_blank">{!r.Name}</a><br/>
            <apex:variable value="{!0}" var="temp" rendered="{!r.Line_Break__c}"><br/></apex:variable>
        </apex:repeat>
    </apex:form> 
</apex:page>
I'm trying to create a field on the Product page that references the Unit Price field in the Price Book Entries object. I'm not sure of the best possible way to implement this and would love to get some help from the experts here.

Thanks!
My requirement is to be able to import quote line items into a quote using a CSV. I have written the following code but I'm unable to get it working. The code shows no errors but when I try to import a CSV, it doesn work. Thank you in advance for any guidance you can provide:

APEX Code:
public class importDataFromCSVController {
	public Blob csvFileBody{get;set;}
	public string csvAsString{get;set;}
	public String[] csvFileLines{get;set;}
	public List<QuoteLineItem> quoteLineItemList{get;set;}
    public List<Quote> quoteNumberList{get;set;}
  	public importDataFromCSVController(){
    
    csvFileLines = new String[]{};
    quoteLineItemList = New List<QuoteLineItem>(); 
  	}
  
  	public void importCSVFile(){
      List<String> allProductCodes = new List<String>();
      List<String> allQuoteNumbers = new List<String>();
      Map<String, Id> quoteNumber = new Map<String, Id>();
      
      //Query for Products that have matching Product Code
      Map<String, Id> productCode = new Map<String, Id>();
      for (Product2 p : [SELECT Id, Name from Product2 where Name in :allProductCodes LIMIT 1]) {
          productCode.put(p.Name,p.Id);
      }
      
      //Query for Quotes that have matching Quote Number
      Map<String, Id> quoteNum = new Map<String, Id>();
        for (Quote q : [SELECT Id, QuoteNumber from Quote where QuoteNumber in :allQuoteNumbers LIMIT 1]) {
            quoteNum.put(q.QuoteNumber, q.Id);
      }
      
      // Set the Product Id for each Product Code  
      for(Integer j=0;j<quoteLineItemList.size();){
          QuoteLineItem qli1;
          Id Productid = productCode.get(allProductCodes[j]);
          if (Productid != null) {
              qli1.Product2.Id = Productid;
          }
      // Set the Quote Id for each Quote
          for (Integer z=0;z<quoteNumberList.size();){
              Quote q1;
              Id quoteNumberId = quoteNum.get(allQuoteNumbers[z]);
              if (quoteNumberId != null) {
                  q1.Id = quoteNumberId;
              }
          }    
      }
       try{
           csvAsString = csvFileBody.toString();
           csvFileLines = csvAsString.split('\n'); 
            
           for(Integer i=1;i<csvFileLines.size();i++){
               QuoteLineItem lineItem = new QuoteLineItem() ;
               string[] csvRecordData = csvFileLines[i].split(',');
               allQuoteNumbers.add(csvRecordData[0]);
               allProductCodes.add(csvRecordData[1]);
               lineItem.Quantity = decimal.valueof(csvRecordData[2]);
               lineItem.UnitPrice = decimal.valueof(csvRecordData[3]);
               lineItem.Global_Discount__c = decimal.valueof(csvRecordData[4]);                                                                    
               quoteLineItemList.add(lineItem);   
           }
        insert quoteLineItemList;
        }
        catch (Exception e)
        {
            ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.severity.ERROR,'An error has occured. Please try importing the file again');
            ApexPages.addMessage(errorMessage);
        }  
  }
}

Visualforce Page Code
<apex:page controller="importDataFromCSVController">
    <apex:form >
        <apex:pagemessages />
        <apex:pageBlock >
            <apex:pageBlockSection columns="5"> 
                  <apex:inputFile value="{!csvFileBody}"  filename="{!csvAsString}"/>
                  <apex:commandButton value="Import Quote Line Items" action="{!importCSVFile}"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
        <apex:pageBlock >
           <apex:pageblocktable value="{!quoteLineItemList}" var="acc">
              <apex:column value="{!acc.Quote}" /> 
              <apex:column value="{!acc.Product2}" />
              <apex:column value="{!acc.Quantity}" />
              <apex:column value="{!acc.UnitPrice}" />
              <apex:column value="{!acc.Global_Discount__c}" />
        </apex:pageblocktable>
     </apex:pageBlock>
   </apex:form>
</apex:page>

 
I have the following piece of code that I am unable to figure out how to include in test. I've tried a couple of different ways but I am unable to get Line 8 included in the test scenario. Any help is greatly appreciated!! 
 
trigger SetCaseDetails on Case (before insert, before update) {
    Id ITSRecordID = O__c.getOrgDefaults().ITS_Case_Record_Type__c;
    Id TechRecordID = O__c.getOrgDefaults().TechSupportID__c;
    Map<Id, Case> parentCaseOwners = new Map<Id, Case>();
    Map<String, Repair_History__c> repairHistories = new Map<String, Repair_History__c>();
    for (Case c : Trigger.new) {
        if (c.ParentId != null &  c.Parent.Is_Owner_Active__c != false) {
            parentCaseOwners.put(c.ParentId, null);
        }
        if (c.SO__c != null) {
            repairHistories.put(c.SO__c, null);
        } if (c.Status == 'Closed' || c.Status == 'No Bid' || c.Status == 'Complete' || c.Status == 'Cancelled') {
            c.Open_Lookup__c = null;
       } else if (c.AccountId != null) {
            c.Open_Lookup__c = c.AccountId;
        }
    }    
    if (!parentCaseOwners.isEmpty()) {
        for (Case pc: [SELECT Id, OwnerId FROM Case WHERE Id in :parentCaseOwners.keySet()]) {
            parentCaseOwners.put(pc.Id,pc);
        }        
        for (Case c : Trigger.new) {
            if (c.ParentId != null & c.RecordTypeID != ITSRecordID & c.RecordTypeID != TechRecordID & c.Parent.Is_Owner_Active__c != false) 
				          
            {
                c.OwnerId = parentCaseOwners.get(c.ParentId).OwnerId;
            }
        }
    }

My test code:
 
@isTest
private class TestSetCaseDetails {
 	static testMethod void test() {    
 	Profile pf= [Select Id from profile where Name='System Administrator' limit 1]; 
        
        String orgId=UserInfo.getOrganizationId(); 
        String dateString=String.valueof(Datetime.now()).replace(' ','').replace(':','').replace('-','') ;
        Integer RandomId=Integer.valueOf(Math.rint(Math.random()*1000000)); 
        String uniqueName=orgId+dateString+RandomId; 
        User uu=new User(firstname = 'ABC', 
                         lastName = 'XYZ', 
                         email = uniqueName + '@test' + orgId + '.org', 
                         Username = uniqueName + '@test' + orgId + '.org', 
                         EmailEncodingKey = 'ISO-8859-1', 
                         Alias = uniqueName.substring(18, 23), 
                         TimeZoneSidKey = 'America/Los_Angeles', 
                         LocaleSidKey = 'en_US', 
                         LanguageLocaleKey = 'en_US', 
                         ProfileId = pf.Id,
                         isActive = True
                        ); 
      	insert uu;
      	system.debug('User active ' + uu.IsActive);
      
	System.runAs(uu){
		
        List<Repair_History__c> repairhistories = new List<Repair_History__c>();
        List<Case> caseowners = new List<Case>();
      
      	Map<id,Case> parentCaseOwners = new Map<id,Case>();
      
      	Id caserec = Schema.SObjectType.Case.getRecordTypeInfosByName().get('BA Support Case').getRecordTypeId();
      
        Account a1 = new Account(
            Name='A1',
            BillingStreet = 'Street',
            BillingCity = 'City',
            BillingPostalCode = 'Postal Code',
            BillingState = 'ON',
            BillingCountry = 'Country'        
        );
        insert a1;
        
        case c1 = new Case(
        	Status='New',
        	Origin='Email',
			SO__c='12345678',
            subject='parent case',
            Open_Lookup__c=a1.id,
            accountid=a1.id,
            ownerid=uu.Id
        	);
        insert c1;
        c1 = [select id, Is_Owner_Active__c from Case where id=:c1.id];
        system.debug('Case User Is active: ' + c1.Is_Owner_Active__c);
      	
        caseowners.add(c1);
        parentCaseOwners.put(c1.id, c1);
      
     	case c2 = new Case(
        	Status='Closed',
        	Origin='Email',
            subject='child case',
			Parentid=c1.Id,
            SO__c='12345678',
            RecordTypeId=caserec
        	);
        //insert c2;
        c2 = [select id, Is_Owner_Active__c from Case where id=:c1.id];
        system.debug('Child Case User Is active: ' + c2.Is_Owner_Active__c);
        parentCaseOwners.put(c2.id, c2);
      
      case c3 = new Case(
        	Status='Closed',
        	Origin='Email',
            subject='child case',
            Parentid=c1.Id,
            SO__c='12345678'
        	);
        insert c3;
        c3 = [select id, Is_Owner_Active__c from Case where id=:c3.id];
      	caseowners.add(c2);
        caseowners.add(c3);
        
        Account a2 = new Account(
            Name = 'A2',
            JDE_Account_Number__c='JDE',
            ParentId=a1.Id,
            BillingStreet = 'Street',
            BillingCity = 'City',
            BillingPostalCode = 'Postal Code',
            BillingState = 'ON',
            BillingCountry = 'Country'
        );
        insert a2;
        
		
		Product2 prod = new Product2(Name = 'Laptop X200', 
                                     Family = 'Hardware');
        insert prod;
        
		
		
      	Repair_History__c p1 = new Repair_History__c();
            p1.Repair_Number__c  = '123456';
            p1.Total_Price__c  = 100;
            p1.Account__c = a1.Id;
		p1.product__c = prod.Id;
            insert p1;
      
      	Repair_History__c p2 = new Repair_History__c();
            p2.Repair_Number__c  = '1234567';
            p2.Total_Price__c  = 100;
            p2.Account__c = a2.Id;
				 p2.product__c = prod.Id;
            insert p2;
      
      	repairhistories.add(p1);
        repairhistories.add(p2);
      
    }
  }
}

 
I have some  code that was previously written for us for a visualforce page in our instance of SFDC. I'm just trying to get a better understanding of the following:
 
var vendor_category = $('.row-vendor-'+row_no).val();

Can someone help me understand what the above line does and where would I go about to find '.row-vendor' ?

Please let me know if there are any additional question. Thank you in advance for your help!!
I wrote this code but I'm only getting 60% coverage. I'm unable to figure out how to get to 100% coverage. Any help will be much appreciated!
 
global class InvoiceLineItemCleanUp implements Database.Batchable<SObject>, Database.Stateful {
	
    Date CutoffDate = Olympus__c.getOrgDefaults().Last_Modified_Date__c;
    
    global InvoiceLineItemCleanUp() {
    }
    
    global Database.QueryLocator start(Database.BatchableContext bc) {
        String searchRec = 'SELECT Id FROM Order_Line_Item__c WHERE CreatedDate > :CutoffDate AND LastModifiedDate <> LAST_N_DAYS:30';
        return Database.getQueryLocator(searchRec);
    }

    global void execute(Database.BatchableContext bc, List<SObject> batch) {
        List<Order_Line_Item__c> b = (List<Order_Line_Item__c>)batch;
        
        Database.delete(b);
        if(!b.isEmpty()) { Database.emptyRecycleBin(b); }
    }
    
    global void finish(Database.BatchableContext bc) {
    }
}



Here is my test code 
 
@isTest
private class InvoiceLineItemCleanUp_test {    
    static testMethod void test() { 
        Order_Line_Item__c invoiceLine = new Order_Line_Item__c(Quantity__c = 1);
        insert invoiceLine;
               
        Datetime yesterday = Datetime.now().addDays(-31);
        Test.setCreatedDate(invoiceLine.Id, yesterday);
               
        Test.startTest();
        Database.executeBatch(new InvoiceLineItemCleanUp());
        Test.stopTest();
    }
}


​​​​​​​
Some buttons and fields are not displaying in the layout, even though I can see them during preview. I'm guessing it has something to do with permissions, but I'm too new of a user to figure it out.
I have writted the following trigger along with the test below. I'm unable to figure out how to cover the for loop in my test class. Looking forward to your advise.
 
List<Account> accountUpdatedList = new List<Account>();
    Map<string,string> territoryWithParentTerritoryNameMap = new map<string,string>();
    for(Territory2 tr : [SELECT id, Name,Territory2.ParentTerritory2.Name FROM Territory2 WHERE Territory2.ParentTerritory2.Name != Null Limit 50000])
    {
        territoryWithParentTerritoryNameMap.put(tr.name,tr.ParentTerritory2.Name);
    }
        
    for (Account ac : Trigger.new) {
        ac.Sales_Rep_Region__c = ' ';
        Integer counter = 0;
        if (ac.Territories__c != null) {
            for (String t : ac.Territories__c.split(',')) {
                counter += 1;
            }
            ac.Team_count__c = counter - 3;
        }
    
    if(ac.Territories__c != Null && ac.Territory_Has_Changed__c != False) 
        {
            for(string str : ac.Territories__c.split(',')){
                if(str != '104B' && str != '109B' && str != '109A' && str != ac.RVP_Code__c && str != '104A'){ 
                    if(territoryWithParentTerritoryNameMap.containsKey(str)){
                    
                        string tempParentTerritoryName = territoryWithParentTerritoryNameMap.get(str);
                        if(ac.RVP_Code__c != tempParentTerritoryName){                                
                            if(!ac.Sales_Rep_Region__c.contains(str)){                                    
                                ac.Sales_Rep_Region__c += str + ',';
                                accountUpdatedList.add(ac);   
                                    
                            }
                            
                        }
                       
                    }
                    
                }
              
            }
        }
        
    }

Test:
@istest
private class AccountTerritoryCount_test {
    static testMethod void TestAccount(){
        Account acc = new Account(name='test', 
                              jde_account_number__c='1234',
                              Territories__c='1234,1234,1234,1234,1234,1224,1234,1234,1234,');
    	insert acc;
        
    }
    
    static testMethod void myAccountTest()
    {
        List<Account> accountUpdatedList = new List<Account>();
        Map<string,string> territoryWithParentTerritoryNameMap = new map<string,string>();
    	for(Territory2 tr : [SELECT id, Name,Territory2.ParentTerritory2.Name FROM Territory2 
                         WHERE Territory2.ParentTerritory2.Name != '109N' Limit 50000])
        {
        	territoryWithParentTerritoryNameMap.put(tr.name,tr.ParentTerritory2.Name);
        }
        
        Account ac = new Account();
        ac.name = 'Toronto';
        ac.JDE_Account_Number__c = '12345678';
        ac.Territories__c = '1011,1436';
        ac.RVP_Code__c = '109N';
        insert ac;
        
        Account ac2 = new Account();
        ac2.name = 'Toronto2';
        ac2.JDE_Account_Number__c = '12345679';
        ac2.Territories__c = '1011,1436';
        ac2.RVP_Code__c = '109N';
        insert ac2;
        
        ac = [SELECT Sales_Rep_Region__c,Territories__c from Account where Id =:ac.Id];
        
        system.assertEquals(ac.Sales_Rep_Region__c, null);
        
    }
    
}
Lines 
User-added image
I have a list of territories names that are inserted into a custom field, Territories__c from an external system via dataloader. The names are split by a comma. eg: 1234,2345,9564 etc. Another custom field called RVP_Code__c stores the parent territory name. e.g. 1111

I'd like to go thru the list of these territories and add the territories names that don't have the same parent territory into a new field, Sales_Rep_Region__c, for review. I wrote a trigger below but it doesn't seem to be working. Would love to get some help regarding this. Thank you in advance!! 
trigger AccountTerritoryReview on Account (before insert) {
	
    List<Account> RepstoAdd = new List<Account>();
    
    if(TriggerHandler.run ){
        TriggerHandler.run = false;
        
        for (account acc : Trigger.new){
            if (acc.Territories__c != null) {
                for (string t : acc.Territories__c.split(',')) {
                    List<Territory2> tt = new List<Territory2>([SELECT Name,Territory2.ParentTerritory2.Name FROM Territory2 WHERE Territory2.Name = :t]);
                    for (Territory2 tx : tt){
                        if (tx.ParentTerritory2.Name != acc.RVP_Code__c){
                            acc.Sales_Rep_Region__c = tx.Name;
                            RepstoAdd.add(acc);
                        }
                    }
                    }                       
                }
            }
            
            
        }
    
    update RepstoAdd;
    
}


 
Hello, I have a custom object that has a look up to the account object. I've written the trigger below to count the child records and update a field on the Account object. The code also sums the total of the child records and updates a field on the Account.

The trigger works fine if I update one child record but throws a DML error "InvoiceRollUp: System.LimitException: Too many SOQL queries: 101"  when I do a bulk update via dataloader. Thank you in advance for your help!
trigger InvoiceRollUp on Order_Line_Item__c (after insert, after update,after delete,after undelete) {
    
    set<id> AccountIds = new set<id>();
    
    if(trigger.isInsert || trigger.isUpdate){
        for(Order_Line_Item__c li : trigger.new){
            AccountIds.add(li.Ship_To__c);
        }
    }
    
    //When deleting payments
    if(trigger.isDelete){
        for(Order_Line_Item__c li : trigger.old){
            AccountIds.add(li.Ship_To__c);
        }
    }
    
   map<Id,Double> AccountMap = new map<Id,Double>();
   
    for(AggregateResult q : [select Ship_To__c , sum(Line_Item_Total__c) from Order_Line_Item__c where (Ship_To__c IN :AccountIds AND (Invoice_Date__c=Last_N_Months:12)) group by Ship_To__c]){
        AccountMap.put((Id)q.get('Ship_To__c'),(Double)q.get('expr0'));
    }

    List<Account> AccountsToUpdate = new List<Account>();
    
    for(Account acc : [Select Id, Invoice_Total__c from Account where Id IN :AccountIds]){
        Double PaymentSum = AccountMap.get(acc.Id);
        acc.Invoice_Total__c = PaymentSum;
        AccountsToUpdate.add(acc);
    }
    
    for(AggregateResult OC : [select Ship_To__c , count(Id) from Order_Line_Item__c where (Ship_To__c IN :AccountIds) group by Ship_To__c]){
        AccountMap.put((Id)OC.get('Ship_To__c'),(Double)OC.get('expr0'));
    }
    
    List<Account> AccountsToCount = new List<Account>();
    
    for(Account ac : [Select Id, Invoice_Total__c from Account where Id IN :AccountIds]){
        Double counter = AccountMap.get(ac.Id);
        ac.Invoice_Line_Item_Count__c = counter;
        AccountsToCount.add(ac);
    }
 
  update AccountsToUpdate;
  update AccountsToCount;
}

 
My Code is: 
public class AssociateSOExtController {

    public Quote quote { get; set; }
    
    public AssociateSOExtController() {
        
        String quoteId = ApexPages.currentPage().getParameters().get('id');
        quote = [SELECT Id, Name, Service_Repair__c FROM quote WHERE Id =: quoteId];
        
    }
    
    public PageReference associate () {
        
        Repair_History__c SORepair = new Repair_History__c ( Id = quote.Service_Repair__c, Quote__c = quote.Id);
        
        try {
        	Database.update(SORepair);
        } catch (Exception error) {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Error while associating.' + error.getMessage()));
        }
        
        PageReference page = new PageReference('/' + quote.Id);
        
        return page.setRedirect(true);
    }
    
    public PageReference cancel () {
        PageReference page = new PageReference('/' + quote.Id);
        return page.setRedirect(true);        
    }
    
}

Thank you all for your help!
Hi All,

I'm new to apex coding and wrote my first trigger. I'm not sure how to go about writing a test class. I read up a couple of different forums but haven't been able to figure it out.

trigger OpenRepairs on Repair_History__c (before insert, before update) {
    for (Repair_History__c R: Trigger.new) {
        if (R.Status__c == 'Closed') {
            R.OpenRepair__c = null;
        } else if (R.Status__c == 'Closed - Traded In') {
            R.OpenRepair__c = null;
        } else if (R.Status__c == 'Closed - Return Unrepair') {
            R.OpenRepair__c = null;
        } else if (R.Account__c != null) {
            R.OpenRepair__c = R.Account__c;
        }
    }
}

Hi All,

How I will import csv file through visualforce page into Object in salesforce ?

please help me,

Thanks,

Dileep Kumar

I have a visualforce page and would like retain the picklist value that the user selects on page reload. It's set to "Internal" by default, however, if the user chooses "External", this should now be the default on page reload. Thank you all for your advise!

<apex:page controller="ExternalReportsController" action="{!getReports}" showChat="false" sidebar="false" showHeader="false">
    <style>body { background-color: inherit !important; }</style>
    <apex:form id="theForm">
        <apex:outputLabel value="<b>Network: </b>" escape="false"/>
        <apex:selectList value="{!selectedNetwork}" multiselect="false" size="1">
            <apex:selectOption itemLabel="Internal" itemValue="Internal"/>
            <apex:selectOption itemLabel="External" itemValue="External"/>
            <apex:actionSupport event="onchange" action="{!getReports}" reRender="theForm"/>
        </apex:selectList>
        <br/>
        <apex:repeat value="{!reports}" var="r" id="reportList">
            <a href="{!IF(selectedNetwork = 'External', r.External_Server__c, r.Internal_Server__c) + r.Link__c}{!IF(r.Add_Territory__c, territories, null)}" target="_blank">{!r.Name}</a><br/>
            <apex:variable value="{!0}" var="temp" rendered="{!r.Line_Break__c}"><br/></apex:variable>
        </apex:repeat>
    </apex:form> 
</apex:page>
Hello,
we would like to create quote line itemsfrom a CSV file (3 columns : productCode, Qty and Unit Price).
After creating a new quote, we would have a button to select the file and data to import.

Several objects are impacted : quote (id to retrieve), Products2 (product ID to retrieve) and PriceBook2 (right price book has to be selected).

How is it possible to do ?
Please advice and suggest me.