• Itayb34
  • NEWBIE
  • 0 Points
  • Member since 2011

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 49
    Questions
  • 56
    Replies

Hello

 

I'm using the standard email-to-case functionality to attach emails to new and existing cases. I added the code below to "convert" emails into case comments.

I also want to add the email attachment as a case attachment. How can this be added to the code?

 

public class EmailMessageCopyToCaseCommentsTrigger
{
    public static void copyEmailMessagesToCaseComments(List<EmailMessage> emails)
    {
        List<CaseComment> comments = new List<CaseComment>();
        for (EmailMessage email:emails)
        {
            Id caseId = email.ParentId;
            CaseComment comment = new CaseComment(ParentId=caseId);
            comment.IsPublished = true;
            String header = 'From: '+ email.FromName + ' <' + email.FromAddress + '>\n';
            header += email.CcAddress!=null?'CC: '+ email.CcAddress + '\n\n':'\n';
          

            if (email.TextBody!=null) {
                comment.CommentBody = header + email.TextBody; } 


                else if (email.HtmlBody!=null) {
                comment.CommentBody = header + email.HtmlBody.replaceAll('\\<.*?>','');
            }
            
            comments.add(comment);
        }
        
        if (!comments.isEmpty())
        {
            insert comments;
        }
       
    }
    
    public static testMethod void testCopyEmailMessagesToCaseComments()
    {
        Case c1 = new Case(Subject='blah');
        insert c1;
        
        List<EmailMessage> emails = new List<EmailMessage>();
        emails.add(new EmailMessage(ParentId=c1.Id,FromAddress='yo@yo.com',FromName='Yo',Subject='Subject',TextBody='TextBody',ToAddress='to@to.com'));
        emails.add(new EmailMessage(ParentId=c1.Id,FromAddress='yo@yo.com',FromName='Yo',Subject='Subject',HtmlBody='<b>HtmlBody</b><i>more</i>',ToAddress='to@to.com'));
        insert emails;
        
        List<CaseComment> comments = [select Id,CommentBody from CaseComment where ParentId=:c1.Id];
        System.assert(comments.size()==2);
        
        for (CaseComment comment:comments) {
            System.debug(comment.CommentBody);
            System.assert(comment.CommentBody!=null && comment.CommentBody!='');
        }
    }
}

 

Hello, I would like parse an inbound email into a custom object (Training__c) and its fields. I was able to create the record, I need some help in "translating" the email body into fields (the needed fields appear in the code..).

I tried using substring below, but got an error that prevented the record insert..

 

Class:

 

global class ProcessTraining implements Messaging.InboundEmailHandler {
 
  global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email,
    Messaging.InboundEnvelope envelope) {
 
    Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();


   String[] emailBody = email.plainTextBody.split('\n', 0);
String Numberofcertificationattempts = emailBody[0].substring(0);

 Training__c em= new Training__c (Message__c = email.plainTextBody);
 
em.Number_of_certification_attempts__c = decimal.valueof(Numberofcertificationattempts);
em.Date_training_completed__c = 
em.Total_time_in_training_course__c = 
em.Training_certification_score__c =
    
    insert em;
    


   return result;

 

Email:

Email sent from the Demo version of the Email Reporting Widget:

***************************************************************************
*********              Project and access information               *******
***************************************************************************

Student name: 
Project name: 
Date completed: 6/12/2013
Time completed: 12:02:32
Total time spent in course: 

***************************************************************************
*********                 Quizzing Information                      *******
***************************************************************************

Quiz score in percent: 
Total Points Scored: 10
Total Points Available: 10
Points needed for a pass: 8

Number of quiz attempts: 1
Total number of quiz questions: 1
Total number of correct answers: 1
Total number of unanswered questions: 1

 

 

Thanks!

 

Itay

Hello

 

I created a new object called "Commissions" which will create a monthly record for each sales rep. What I want to achieve is populate information from an opportunity owned by the rep.

Logic: when an opportunity is closed won, check if there's already a "Commission" record exist for this month (I have a custom "month" field) - if there is, update a field in that record. if there isn't, create a new "Commission" record.

I did manage to add the commission creation part, but I'm a bit struggling with the updating of existing commission for the same month...could you assist me with that?

 

trigger createCommission on Opportunity (after update) {
    
    List <Commission__c> vehToInsert = new List <Commission__c> ();
    
    
    for (Opportunity o : Trigger.new) {
        
        
       
        //meets the criteria
        if (o.StageName == 'Closed Won') {  
        
        Commission__c com = new Commission__c (); //instantiate the object to put values for future record
        
        // now map opportunity fields to new commission object that is being created with this opportunity
                
        com.YTD_Closed_Won_Opportunities__c = o.amount;
com.month__c = o.closedate; //once done, you need to add this new object to the list that would be later inserted. vehToInsert.add(com); }//end if }//end for o //once loop is done, you need to insert new records in SF // dml operations might cause an error, so you need to catch it with try/catch block. try { insert vehToInsert; } catch (system.Dmlexception e) { system.debug (e); } }

 

Thanks!

 

Itay

 

Hello

 

I have a Visualforce page embedded in an iframe into another visualforce page (see below), the iframed page is a PDF.

When I click the custom button, the fields in the PDF are empty, but when I save the PDF into "Notes & Attachments", the PDF is populated with the information from the record...

I know that I need to pass variable from the parent, but what needs to be done? 

 

Custom Button: /apex/PdfGeneratorTemplate?id={!Monthly_Cloud_Bill__c.Id}

 

Class:

 

public with sharing class PdfGeneratorController {


  String parentId = ApexPages.currentPage().getParameters().get('id');


  Monthly_Cloud_Bill__c MCB = [SELECT Account__r.Id, Account__r.Name from Monthly_Cloud_Bill__c WHERE Id = :parentId];
  Account acc = MCB.Account__r;
  String AccountName = acc.Name;
  String AccountId = acc.Id;
  
   
 public PageReference savePdf() {
 
    //PageReference pdf = Page.PdfGeneratorTemplate;
    PageReference pdf = Page.InvoicePDF2;
    // add parent id to the parameters for standardcontroller
    pdf.getParameters().put('id',parentId);
 
    // create the new attachment
  Attachment attach = new Attachment();
 
    // the contents of the attachment from the pdf
    Blob body;
 
    try {
 
        // returns the output of the page as a PDF
        body = pdf.getContent();
 
    // need to pass unit test -- current bug    
    } catch (VisualforceException e) {
        body = Blob.valueOf('Some Text');
    }
 
    attach.Body = body;
    // add the user entered name
    attach.Name = AccountName + '.pdf';  
    attach.IsPrivate = false;
    // attach the pdf to the account
    attach.ParentId = parentId;
    insert attach; 
        
 
    // send the user to the account to view results
    //return new PageReference('/'+parentId);
    return new PageReference('/'+'flow/Email_Cloud_Invoice?MBCID='+parentId + '&AccountID='+AccountId + '&AttachmentID='+doc.id+ '&retURL='+parentId);
 
  }    
 
}

 

Iframe PDF:

<apex:page standardController="Monthly_Cloud_Bill__c" showHeader="false" renderas="pdf"> 

<table border="0" cellspacing="0" cellpadding="0" width="100%" id="table1">
<tr>
    <td align="right">       <img src='{!URLFOR($Resource.Logo)}' title="logo" />
     <br/>
     <img src='{!URLFOR($Resource.InvoiceLogo)}' title="logo" />
       </td>
    
</tr>



</table>
<table border="0" cellspacing="0" cellpadding="0" width="100%" id="table1">
<tr>    <td>
        <font face="Arial" >

        <apex:outputText value="{!Monthly_Cloud_Bill__c.Company_Address__c}" escape="false"/> 
        
        </font></td> 
        <td width="50%"></td>
   <td ><font face="Arial">Invoice Date:<apex:OutputField value="{!Monthly_Cloud_Bill__c.Create_Date__c}"/> <br/>
        Invoice #: {!Monthly_Cloud_Bill__c.Name}<br/> 
        Billing Period: {!Monthly_Cloud_Bill__c.Billing_Period__c}  <br/> 
        Customer ID: {!Monthly_Cloud_Bill__c.Account__r.Customer_ID__c} <br/>
       </font>
     </td>
</tr>
</table>

<p><b><font face="Arial" color="#000080">Customer Information</font></b></p>

<table border="0" width="100%" id="table2">
<tr>
       <td colspan="3">
           <font face="Arial">{!Monthly_Cloud_Bill__c.Account__r.Name} <br/></font>
       </td>
</tr>
<tr>
       <td>          
           <font face="Arial">Attn: {!Monthly_Cloud_Bill__c.Contact__r.Name}<br/>
           
                             {!Monthly_Cloud_Bill__c.Account__r.BillingStreet}<br/>
                             {!Monthly_Cloud_Bill__c.Account__r.BillingCity}, {!Monthly_Cloud_Bill__c.Account__r.BillingState} {!Monthly_Cloud_Bill__c.Account__r.BillingPostalCode} <br/>
                             {!Monthly_Cloud_Bill__c.Account__r.BillingCountry} <br/>
                             Tel: {!Monthly_Cloud_Bill__c.Contact__r.Name}
           </font>
        </td>

</tr>    
</table>

<p><b><font color="#000080" face="Arial">Order Description</font></b></p>
<table border="1" width="100%" id="table4">
<tr>
       <td bgcolor="#C0C0C0"><font face="Arial">Product</font></td>
       <td bgcolor="#C0C0C0" align="center"><font face="Arial">Price</font></td>
       <td bgcolor="#C0C0C0" align="center"><font face="Arial">Units</font></td>       
       <td bgcolor="#C0C0C0" align="center"><font face="Arial">Amount</font></td> 
</tr>
<tr>
       
             <td>Product</td>
             <td align="center"> {!Monthly_Cloud_Bill__c.Price__c}</td>  
             <td align="center">{!Monthly_Cloud_Bill__c.Net_Usage_For_Billing__c}</td>             
             <td align="center"><apex:OutputField value="{!Monthly_Cloud_Bill__c.Billing_Amount__c}"/></td> 
          </tr>
         

<tr>
       <td bgcolor="#C0C0C0" align="right" colspan="6">
       <font face="Arial"><b>Total Due:</b><apex:OutputField value="{!Monthly_Cloud_Bill__c.Billing_Amount__c}"/></font></td>
</tr>
</table>

<p><b><font color="#000080" face="Arial">Payment Instructions</font></b></p>
<table border="0" width="100%" id="table3">
 <tr>
       <td><font face="Arial">
        
             1. Payment is due in full 30 days from the INVOICE DATE <br/>
             2. Overdue payments will be subject to a charge of 1% per month <br/>
             3. Payment is accepted by wire transfer, check or credit card: 
            </font>
        </td>
   
   <br/>

</tr> 



<table border="0" width="100%" id="table4">
<!--<tr>
       <td colspan="3">
           
       </td>
</tr> -->
<tr>
       <td>          
           <font face="Arial"><b>Wire transfer instructions:</b><br/>
                             
                           <apex:OutputField value="{!Monthly_Cloud_Bill__c.Wire_transfer_instructions__c}"/>
           </font>
        </td>
    <!--    <td width="1%"></td> -->
        
        <td>
           <font face="Arial"><b>Check payment instructions:</b><br/>
                            <apex:OutputField value="{!Monthly_Cloud_Bill__c.Check_payment_instructions__c}"/>
           </font>
        </td>
        
      
</tr>    
</table>

</table>

<hr/>
<p align="center"><font face="Arial">If you have any question about this invoice, please contact. <br/>
{!Monthly_Cloud_Bill__c.Account__r.Owner.FirstName} {!Monthly_Cloud_Bill__c.Account__r.Owner.LastName}, {!Monthly_Cloud_Bill__c.Account__r.Owner.Phone}, {!Monthly_Cloud_Bill__c.Account__r.Owner.Email} <br/> <br/>
<b>Thank You For Your Business!</b>
</font></p>

</apex:page>

 

Parent Visualforce:

<apex:page controller="PdfGeneratorController">

   <apex:form >  
    
   <apex:pageBlock title="PDF Input">  
 
      <apex:pageBlockButtons >
        <apex:commandButton action="{!savePdf}" value="Save PDF"/>
      </apex:pageBlockButtons>
      <apex:pageMessages />
 
 <iframe height="600px" id="Page" name="InvoicePDF" src="/apex/InvoicePDF2" width="100%"></iframe>
 
    </apex:pageBlock> 
  </apex:form>
    
    
</apex:page>

 

Many Thanks!

 

Itay

Hello

 

I have a lookup field from opportunity (on record type "Renewal") to Service Contracts, and I'm trying to update a service contract field , based on changes on the opportunity stage. For example: if an opportunity is changed to won, custom field on SC will be "won", if it's changed to lost, field will be "Lost". if the stage is changed to an open stage, field is "Open".

I can't use workflows...but I managed to use the code below. The problem is it updates only when the Opportunity is closed (I want that the Service contract will be updated on any stage change)

 

trigger UpdateSCFromOpp on Opportunity (after update) {


  Set<Id> oppIds = new Set<Id>();
    
    RecordType debtRT = [Select Id From RecordType Where Name = 'Enterprise - Renewal'];
    for(Opportunity opps : Trigger.new){
        // Check for Renewal Deal Record Type and change from open to close
       if(opps.RecordTypeId == debtRT.Id && opps.isclosed == true && trigger.OldMap.get(opps.Id).isclosed == false && opps.Expired_Service_Contract__c != null)
        {
        
            oppids.add(opps.Expired_Service_Contract__c);
        }
        }
                   
        for (ServiceContract[] sc:[select id from ServiceContract where id in :oppids]) {
        
          for(ServiceContract c:sc) {
          
        
          c.Renewal_Opportunity_Status_Field__c = 'Closed Won';
 
       }
            update sc;
  }
}

 

 

 

Thanks!

 

Itay

 

 

Hello

 

I created a visualforce page create a PDF of Invoice and Invoice Line Items (Similar to the standard Quote functionality)

I would like to enhance it and be able to add "Save PDF" and "Email PDF" buttons into the PDF screen. I know it's possible via iframe, but I'm not sure what to do there...

 

Generate PDF:

 

<apex:page standardController="Invoice1__c" showHeader="false" renderas="pdf"> 


<table border="0" cellspacing="0" cellpadding="0" width="100%" id="table1">
<tr>
    <td>
        <img src='{!URLFOR($Resource.CompanyLogo)}' title="logo" />
    </td>
   <td  align="right"><font face="Arial" >
    <b>Invoice for {!Invoice1__c.Opportunity__r.Account.Name}</b></font><br/>
   </td> 
   
  
   
</tr>

<hr/>

</table>
<table border="0" cellspacing="0" cellpadding="0" width="100%" id="table1">
<tr>    <td><font face="Arial" >
        {!$Organization.Name}<br/>
        {!$Organization.Street}<br/>
        {!$Organization.PostalCode} {!$Organization.City}<br/>
        {!$Organization.Country}<br/>
        </font></td> 
        <td width="60%">&nbsp;</td>
   <td ><font face="Arial">Invoice number: "{!Invoice1__c.Name}" </font><br/>
  
   
   <font face="Arial">Invoice Date: "{!Invoice1__c.Invoice_Date__c}" </font>  
   </td>
 
   
  
</tr>
</table>
<br/>
<hr/>
<p><b><font face="Arial" color="#000080">Address Information</font></b></p>

<table border="0" width="100%" id="table2">
<tr>
       <td colspan="3">
           <font face="Arial">Account name: {!Invoice1__c.Opportunity__r.Account.Name} <br/><br/></font>
       </td>
</tr>
  <tr>
      <td>          
           <font face="Arial">Bill To:<br/>
                             {!Invoice1__c.Opportunity__r.Account.BillingStreet}<br/>
                             {!Invoice1__c.Opportunity__r.Account.BillingPostalCode} {!Invoice1__c.Opportunity__r.Account.BillingCity}
           </font>
        </td>
        <td width="50%"></td>
        <td >
           <font face="Arial">Ship To:<br/>
                              {!Invoice1__c.Opportunity__r.Account.ShippingStreet}<br/>
                              {!Invoice1__c.Opportunity__r.Account.ShippingPostalCode} {!Invoice1__c.Opportunity__r.Account.ShippingCity}
           </font>
        </td>
</tr>    
</table>  
<br/>
<hr/>
<p><b><font color="#000080" face="Arial">Products</font></b></p>
<table border="0" width="100%" id="table4">
<tr>
       <td bgcolor="#C0C0C0"><font face="Arial">Product</font></td>
       <td bgcolor="#C0C0C0"><font face="Arial">Quantity</font></td>
       <td bgcolor="#C0C0C0"><font face="Arial">Unit Price</font></td>
       <td bgcolor="#C0C0C0"><font face="Arial">Discount</font></td>
       <td bgcolor="#C0C0C0"><font face="Arial">Total Price</font></td>
</tr>
<tr>
       <apex:repeat value="{!Invoice1__c.Invoice_Line_Items__r}" var="line">
          <tr>
             <td>{!line.Product_Name__c}</td>
             <td>{!line.Quantity__c}</td>
             <td><apex:OutputField value="{!line.Unit_Price__c}"/></td>
             <td><apex:OutputField value="{!line.Discount__c}"/></td>
             <td><apex:OutputField value="{!line.Total_Price__c}"/></td>
          </tr>
       </apex:repeat>  
</tr>
<tr>
       <td bgcolor="#C0C0C0" align="right" colspan="6">
       <font face="Arial"><b>Total:</b>&nbsp;<apex:OutputField value="{!Invoice1__c.Opportunity__r.Amount}"/></font></td>
</tr>
</table>
<br/>
<hr/>
<p><b><font color="#000080" face="Arial">Terms and Conditions</font></b></p>
<table border="0" width="100%" id="table3">
<tr>
        
       
        <td><font face="Arial">
          Payment Method:&nbsp;<apex:OutputField value="{!Invoice1__c.Opportunity__r.QuotePaymentMode__c}"/><br/> 
          Payment Terms:&nbsp; <apex:OutputField value="{!Invoice1__c.Opportunity__r.QuotePaymentTime__c}"/><br/> 
            </font>
       </td>
</tr>
</table>
<br/>

<br/>
<hr/>
<table width="100%" id="table5">
Special Terms:
</table>
<p>&nbsp;</p>
<hr/>
<p align="center"><font face="Arial"><i>Copyright {!$Organization.Name}.</i></font></p> 
</apex:page>

 

Any help will be great

 

Itay

 

 

Hello

 

I have a general question regard Javascript in custom button. I want that the user will get an error message if a field is blank on the lead layout (in this case - company type).

The code below is working, just wanted to understand if "REQUIRESCRIPT" section is needed (connection and apex rows)

 

{!REQUIRESCRIPT("/soap/ajax/26.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/26.0/apex.js")}  

var leadObj = new sforce.SObject("Lead"); 
leadObj.Id = '{!Lead.Id}'; 
var type = "{!Lead.Company_Type__c}"; 
if (type == "") 
{ 
alert("Please enter company type before converting this lead"); 
} 

else{ 
var result = sforce.connection.update([leadObj]); 
window.location.href = "/lead/leadconvert.jsp?retURL=%2F{!Lead.Id}&id={!Lead.Id}"; 
}

 

Thanks!

 

Itay

I've added an output field to my flow, and I want to have some spaces between lines. for example, my text appears like this:

 

Hello

 
An Opportunity will be created
Name:
Close Date:
Stage:
 
Please click this link:
 

When I run the flow, I see this:

Hello

An Opportunity will be created
Name:
Close Date:
Stage:
Please click this link:
 

How can I fix that?
 
Thanks!
 
Itay
 

I've created a screen of new license with the following fields: License type (enterprise, cloud, trial), expiry date and contact

I've created a validation rule so if a user picked choice other than "Enterprise" without entering an expiry date, he will get an error message. This is the formula:

 

 

{!LicenseDropDown} <> {!Enterprise} && {Expiry_Date} == null

 

I don't get any validation error message. What am I missing?? Is this even possible?

 

Thanks!

 

Itay

Hello

 

I've added a multi-select checkbox with dynamic choice so a user will be able to pick additional contacts from an account. 

Choice Label is set to "Full Name & Email" (this is a custom field I created so user will see both name and email)

Choice Value Stored is email

 

I added an output screen to see the result, I see "Full Name & Email" as a result not "email".

What did I missed? I want to see name & email on choices, but just email on the next screen (so I will be able to use this in URL's)

 

Thanks!

 

Itay

Hello

 

I've added a screen which the user can pick which license to create with choices (Trial / Production / Cloud), but I'd like to have validation on some options. For example: user with "Support" profile can't pick production license.

I can create a decision option and route to two different screens, but i'm wondering if I can add validation on a choice (so when a support user picks "production" choice, an error message is displayed - "you can't pick this kind of license").

 

 

Thanks

 

Itay

Hello

 

I would like to display some help text on our self service portal, next to some field on "Log a Case" screen. What are my options? I noticed that:

  1. Visualforce is not supported in Self-service portal (correct me if iI'm wrong...)
  2. help text is not supported also

 

Any help will be great!

 

Itay

 

I have an opportunity with custom lookup field to accounts, this field is called "Assigned Partner" and it refers only "Reseller" record type accounts.

I want to display in the reseller account level some information about the initial closed won opportunity, such as date of closed won, source, days until closed, etc...

 

I'm not sure if it's possible via custom report type, or a coding is needed...any help?

 

 

Thanks!

 

Itay

Hello

 

I have a scenario when I need to upate Account and Opportunity fields (Next Step and Next Step Due Date) with Open Task Details (Next Step = Subject, Next Step DD = Due Date). if I have several tasks, the earlist one is displayed. If a task is closed, the next open task is displayed on Account / Opportunity.

Originaly, I had 2 triggers located under activities (one for accounts and one for activities). I wasn't sure if this was efficient so I changed that to 1 trigger that fires based on condition and launch a class.

trigger TasksToObjects on Task (after insert, after update) {

 Set<String> acctIdsSet = new Set<String>();
    for(Task t: Trigger.new) {
        String wId = t.WhatId;
       if (wId != null && wId.startsWith('001') ) {
            acctIdsSet.add(wId); 
            TaskToObject.Account(acctIdsSet); 
       }
       
        if (wId != null && wId.startsWith('006') ) {
            acctIdsSet.add(wId); 
            TaskToObject.Opportunity(acctIdsSet); 
       }
    }
}

 

public class TaskToObject {
 
  public static void Account(Set<String> acctIdsSet ) {
 
     List<Account> acctList = [SELECT Id, Next_Step__c, Next_Step_Due_Date__c, (SELECT Task.id, Task.Subject, Task.ActivityDate 
                                    FROM Tasks 
                                    WHERE Task.ActivityDate != NULL  AND Task.Status != 'Completed' ORDER BY Task.ActivityDate ASC limit 1) 
                                    FROM Account 
                                    WHERE Id IN :acctIdsSet ];
    
    if (acctList.size() > 0) {
     for(Account acct: acctList){
           if (acct.Tasks.size() != 0) {
                acct.Next_Step__c = acct.Tasks[0].Subject;
                acct.Next_Step_Due_Date__c = acct.Tasks[0].ActivityDate;
            } else {
                acct.Next_Step__c = 'No current activity';
                acct.Next_Step_Due_Date__c = null;
            }
        }
        try {
            update acctList;
        } catch(Exception ex) {
            System.debug('Problem updating the Accounts!');
    }
    }
}



  public static void Opportunity(Set<String> acctIdsSet ) {

List<Opportunity> oppList = [SELECT Id, NextStep, Next_Step_Due_Date__c, (SELECT Task.id, Task.Subject, Task.ActivityDate FROM Tasks WHERE Task.ActivityDate != NULL AND Task.Status != 'Completed' ORDER BY Task.ActivityDate ASC limit 1) FROM Opportunity WHERE Id IN :acctIdsSet ]; if (oppList.size() > 0) { for(Opportunity opp: oppList){ if (opp.Tasks.size() != 0) { opp.NextStep = opp.Tasks[0].Subject; opp.Next_Step_Due_Date__c = opp.Tasks[0].ActivityDate; } else { opp.NextStep = 'No current activity'; opp.Next_Step_Due_Date__c = null; } } try { update oppList; } catch(Exception ex) { System.debug('Problem updating the Opportunities!'); } } } }

 
The trigger & class work, I'm trying to determine if it is written in the most effieicnt way to write this (as this is my 1st time writing Apex Class).

 

 

Thanks!

 

Itay

Hello

 

I have the trigger below to copy opportunity M&S products to service contract when a service contract is created.

I have added the test coverage, but somehow I reach only 47% coverage, what am I missing? any help will be great!

 

Trigger:

trigger NewSCLineItems on ServiceContract (After Insert) {
    
    // Make a List of Opportunity ID's for all these quotes.
    Set<Id> oppIds = new Set<Id>();
    for(ServiceContract SC : Trigger.new) oppIds.add(SC.opportunity__c);
    
    // Fetch all the Opportunity Line Items for all these Opportunities
    List<OpportunityLineItem> olis = new List<OpportunityLineItem>([
        select 
             id, opportunityid, pricebookentryid, Quantity, UnitPrice, Discount
        from OpportunityLineItem 
        where opportunityid = :OppIds AND M_S_Product__c = 'TRUE'
    ]);
    

    // Build a Map, keyed by OppId, of Lists of the related OLI's
    Map<Id, List<OpportunityLineItem>> oliMap = new Map<Id, List<OpportunityLineItem>>();
    for (OpportunityLineItem oli: olis) {
       if (oliMap.containsKey(oli.OpportunityId)) {
            // If the map already has an entry for this Opp, add this OLI to the list.
            //oliMap.put(oli.OpportunityId, oliMap.get(oli.OpportunityId).add(oli));
            List<OpportunityLineItem> x;
            x = oliMap.get(oli.OpportunityId);
            x.add(oli);
            oliMap.put(oli.OpportunityId, x);
       } else {
            // This is the first entry for this Opportunity
            List<OpportunityLineItem> tmp = new List<OpportunityLineItem>();
            tmp.add(oli);
            oliMap.put(oli.OpportunityId, tmp);
       }
    }

   List<ContractLineItem> qli = new List<ContractLineItem>(); 
  
   // Iterate through each Contract
   for(ServiceContract sc : Trigger.new){
       // Do we have any OLI's for this Contract Opportunity?
       if (oliMap.containsKey(SC.opportunity__c)) {
           // Yes, so for each OLI in the List, create a QLI
           for (OpportunityLineItem oli: oliMap.get(SC.opportunity__c)) {
                qli.add(
                     New ContractLineItem (
                         ServiceContractId = SC.id,
                         pricebookentryid = oli.pricebookentryid,
                         UnitPrice = oli.UnitPrice,
                         Discount = oli.Discount,
                         Quantity = oli.Quantity
                     )
                );
           }
       }
    }
    if (! qli.isEmpty()) insert qli;
}

 

Test Class:

@IsTest(SeeAllData=true) private class CreateServiceContractLineItems{

    /* This is a basic test which simulates the primary positive case for the 
       save method in the quoteExt class. */

private static testMethod void myUnitTest() {

Account acc=new Account(Name='test');
insert acc;                

//Pricebook2 pb2=[Select id from Pricebook2 limit 1];

//Opportunity testOpp = new Opportunity(Name='TestOppty',closedate=date.parse('1/1/2222'),
//                    stagename = 'Qualification',AccountID=acc.id,Pricebook2Id=pb2.id);
//insert testOpp;

   Pricebook2 s = [select id from Pricebook2 where IsStandard = true];   
    
    // create the product
    Product2 p1 = new Product2(
        name='Test Product 1',
        IsActive=true,
        Description='My Product',
        ProductCode='12345'
    );
    insert p1;       
   
    // create the pricebookentry
    PricebookEntry pbe1 = new PricebookEntry(
        Pricebook2Id=s.id,
        Product2Id=p1.id,
        UnitPrice=0.00,
        IsActive=true,
        UseStandardPrice=false
    );
    insert pbe1;   
   
    // create the opportunity
    Opportunity opp1 = new Opportunity(
        name='Test Opp 1',
     ///   recordtypeid='01260000000DXrWxxx',
        StageName = 'Qualification',
        CloseDate = Date.newInstance(2009,01,01), 
        Pricebook2Id=s.id         
    );
    insert opp1;
    
   
    // add the line item
    OpportunityLineItem oli = new OpportunityLineItem();
    oli.Quantity = 1;
    oli.PricebookEntryId = pbe1.id;
    oli.OpportunityId = opp1.id;
    oli.UnitPrice=1;    
    insert oli;
    
    // add the 2nd line item
    OpportunityLineItem oli2 = new OpportunityLineItem();
    oli2.Quantity = 2;
    //oli2.TotalPrice = 2;
    oli2.PricebookEntryId = pbe1.id;
    oli2.OpportunityId = opp1.id;
    oli2.UnitPrice = 2;   
    insert oli2;
    
    ServiceContract sc =new ServiceContract(Name='test sc',AccountID=acc.id,Pricebook2Id=s.id, Opportunity__c=opp1.id );
    insert sc; 
    
    ContractLineItem cli = new ContractLineItem();
    cli.Quantity = oli.quantity;
    cli.PricebookEntryId = oli.PricebookEntryId;
    cli.ServiceContractId= sc.id;
    cli.UnitPrice= oli.UnitPrice;  
    insert cli;
    
    ContractLineItem cli2 = new ContractLineItem();
    cli2.Quantity = oli2.Quantity;
    cli2.PricebookEntryId = oli2.PricebookEntryId;
    cli2.ServiceContractId= sc.id;
    cli2.UnitPrice= oli2.UnitPrice;  
    insert cli2;
    
    System.assertEquals(cli2.UnitPrice, oli2.UnitPrice);

          }
}

 

Thanks in advance

 

Itay

Hello

 

I'm looking to create Service contracts with line items from opportunity using visual workflow. The process is:

1. opportunity is changed to closed won (includes opportunity products)

2. user clicks a "create Service contract" button

3.  user enters several input fields (related contact, expiration date)

4. service contract is created - start date is create date, end date is expiration date entered by the user. Most important are the line items, I want to add only M&S line items to the new SC.

 

Has anyone implemented something similar?

 

Thanks!

 

Itay

We're using the Self-Service portal to manage cases. I'm Looking for a way to pull the "Created by" field from case comments, so I'll know if a SSP user or an internal SF user created the case comments. 

 

Is this possible?

 

Thanks!

 

Itay

Hello

 

I'm trying to find out if it's possible to have follow up question if the user picked a certain value on the first question, something like:

1. what are your reasons to choosing company x:

a. service

b. qualify

c. price

d. other

 

if user pick "other", then question "please elaborate" is displayed.

One important thing to note is that i want this question to be displayed on the same screen (I know I can use the "Desicion" option, but I prefer reduce amount of screens as possible)

 

Thanks!

 

Itay

Hello

 

I've added a visualforce section to my case page layout, and the section is not aligned propertly (not according to each of the columns

What's the best way to align it according to the columns??

 

Visualforce:

<apex:page standardController="Case" extensions="stampLoginDetailsforPortalUser">
<apex:pageMessages />
<apex:pageBlock mode="maindetail" rendered="{!loginInfo.size >0}">
<apex:pageBlockTable value="{!loginInfo}" var="a" >
<apex:column headerValue="Last Login" value="{!a.LastLoginDate}"/>
<apex:column headerValue="IsActive" value="{!a.IsActive}"/>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:page>

 

 I posted the current situation: 

http://i46.tinypic.com/8xtpgn.jpg

 

Thanks!

 

Itay

Hello

 

I have a controller that shows on a Case if the contact is an active self-service user and its last login date.

 

Controller:

 

public with sharing  class stampLoginDetailsforPortalUser {
    private Case UserCase;

    public stampLoginDetailsforPortalUser(ApexPages.StandardController stdController) {
        Case temp = (Case) stdController.getRecord();
            this.UserCase = [select contactID from Case where ID = :temp.ID];
    }

    public List<SelfServiceUser> getloginInfo(){
        List<SelfServiceUser> us=[Select Id,LastLoginDate,IsActive,ContactId from SelfServiceUser where ContactId=:UserCase.ContactId];

        if(us.size()==0){
            ApexPages.addmessage(new ApexPages.message(ApexPages.Severity.INFO,  'Login for self service portal user not enabled'));
        }

        return us;
    }
}

 Visualforce Page: 

<apex:page standardController="Case" extensions="stampLoginDetailsforPortalUser">
  <apex:pageMessages />
  <apex:pageBlock rendered="{!loginInfo.size >0}">
  <apex:pageBlockTable value="{!loginInfo}" var="a">

 <apex:column headerValue="Last Login" value="{!a.LastLoginDate}"/>
  <apex:column headerValue="IsActive" value="{!a.IsActive}"/>
  </apex:pageBlockTable>
   </apex:pageBlock>
   </apex:page>

 I'm having difficulties with the test coverage...I can't create a test self service user, so I'm not sure how to cover this...

Any help?

 

Thanks!

 

Itay

Hello

 

I'm using the standard email-to-case functionality to attach emails to new and existing cases. I added the code below to "convert" emails into case comments.

I also want to add the email attachment as a case attachment. How can this be added to the code?

 

public class EmailMessageCopyToCaseCommentsTrigger
{
    public static void copyEmailMessagesToCaseComments(List<EmailMessage> emails)
    {
        List<CaseComment> comments = new List<CaseComment>();
        for (EmailMessage email:emails)
        {
            Id caseId = email.ParentId;
            CaseComment comment = new CaseComment(ParentId=caseId);
            comment.IsPublished = true;
            String header = 'From: '+ email.FromName + ' <' + email.FromAddress + '>\n';
            header += email.CcAddress!=null?'CC: '+ email.CcAddress + '\n\n':'\n';
          

            if (email.TextBody!=null) {
                comment.CommentBody = header + email.TextBody; } 


                else if (email.HtmlBody!=null) {
                comment.CommentBody = header + email.HtmlBody.replaceAll('\\<.*?>','');
            }
            
            comments.add(comment);
        }
        
        if (!comments.isEmpty())
        {
            insert comments;
        }
       
    }
    
    public static testMethod void testCopyEmailMessagesToCaseComments()
    {
        Case c1 = new Case(Subject='blah');
        insert c1;
        
        List<EmailMessage> emails = new List<EmailMessage>();
        emails.add(new EmailMessage(ParentId=c1.Id,FromAddress='yo@yo.com',FromName='Yo',Subject='Subject',TextBody='TextBody',ToAddress='to@to.com'));
        emails.add(new EmailMessage(ParentId=c1.Id,FromAddress='yo@yo.com',FromName='Yo',Subject='Subject',HtmlBody='<b>HtmlBody</b><i>more</i>',ToAddress='to@to.com'));
        insert emails;
        
        List<CaseComment> comments = [select Id,CommentBody from CaseComment where ParentId=:c1.Id];
        System.assert(comments.size()==2);
        
        for (CaseComment comment:comments) {
            System.debug(comment.CommentBody);
            System.assert(comment.CommentBody!=null && comment.CommentBody!='');
        }
    }
}

 

Hello

 

I created a new object called "Commissions" which will create a monthly record for each sales rep. What I want to achieve is populate information from an opportunity owned by the rep.

Logic: when an opportunity is closed won, check if there's already a "Commission" record exist for this month (I have a custom "month" field) - if there is, update a field in that record. if there isn't, create a new "Commission" record.

I did manage to add the commission creation part, but I'm a bit struggling with the updating of existing commission for the same month...could you assist me with that?

 

trigger createCommission on Opportunity (after update) {
    
    List <Commission__c> vehToInsert = new List <Commission__c> ();
    
    
    for (Opportunity o : Trigger.new) {
        
        
       
        //meets the criteria
        if (o.StageName == 'Closed Won') {  
        
        Commission__c com = new Commission__c (); //instantiate the object to put values for future record
        
        // now map opportunity fields to new commission object that is being created with this opportunity
                
        com.YTD_Closed_Won_Opportunities__c = o.amount;
com.month__c = o.closedate; //once done, you need to add this new object to the list that would be later inserted. vehToInsert.add(com); }//end if }//end for o //once loop is done, you need to insert new records in SF // dml operations might cause an error, so you need to catch it with try/catch block. try { insert vehToInsert; } catch (system.Dmlexception e) { system.debug (e); } }

 

Thanks!

 

Itay

 

Hello

 

I have a Visualforce page embedded in an iframe into another visualforce page (see below), the iframed page is a PDF.

When I click the custom button, the fields in the PDF are empty, but when I save the PDF into "Notes & Attachments", the PDF is populated with the information from the record...

I know that I need to pass variable from the parent, but what needs to be done? 

 

Custom Button: /apex/PdfGeneratorTemplate?id={!Monthly_Cloud_Bill__c.Id}

 

Class:

 

public with sharing class PdfGeneratorController {


  String parentId = ApexPages.currentPage().getParameters().get('id');


  Monthly_Cloud_Bill__c MCB = [SELECT Account__r.Id, Account__r.Name from Monthly_Cloud_Bill__c WHERE Id = :parentId];
  Account acc = MCB.Account__r;
  String AccountName = acc.Name;
  String AccountId = acc.Id;
  
   
 public PageReference savePdf() {
 
    //PageReference pdf = Page.PdfGeneratorTemplate;
    PageReference pdf = Page.InvoicePDF2;
    // add parent id to the parameters for standardcontroller
    pdf.getParameters().put('id',parentId);
 
    // create the new attachment
  Attachment attach = new Attachment();
 
    // the contents of the attachment from the pdf
    Blob body;
 
    try {
 
        // returns the output of the page as a PDF
        body = pdf.getContent();
 
    // need to pass unit test -- current bug    
    } catch (VisualforceException e) {
        body = Blob.valueOf('Some Text');
    }
 
    attach.Body = body;
    // add the user entered name
    attach.Name = AccountName + '.pdf';  
    attach.IsPrivate = false;
    // attach the pdf to the account
    attach.ParentId = parentId;
    insert attach; 
        
 
    // send the user to the account to view results
    //return new PageReference('/'+parentId);
    return new PageReference('/'+'flow/Email_Cloud_Invoice?MBCID='+parentId + '&AccountID='+AccountId + '&AttachmentID='+doc.id+ '&retURL='+parentId);
 
  }    
 
}

 

Iframe PDF:

<apex:page standardController="Monthly_Cloud_Bill__c" showHeader="false" renderas="pdf"> 

<table border="0" cellspacing="0" cellpadding="0" width="100%" id="table1">
<tr>
    <td align="right">       <img src='{!URLFOR($Resource.Logo)}' title="logo" />
     <br/>
     <img src='{!URLFOR($Resource.InvoiceLogo)}' title="logo" />
       </td>
    
</tr>



</table>
<table border="0" cellspacing="0" cellpadding="0" width="100%" id="table1">
<tr>    <td>
        <font face="Arial" >

        <apex:outputText value="{!Monthly_Cloud_Bill__c.Company_Address__c}" escape="false"/> 
        
        </font></td> 
        <td width="50%"></td>
   <td ><font face="Arial">Invoice Date:<apex:OutputField value="{!Monthly_Cloud_Bill__c.Create_Date__c}"/> <br/>
        Invoice #: {!Monthly_Cloud_Bill__c.Name}<br/> 
        Billing Period: {!Monthly_Cloud_Bill__c.Billing_Period__c}  <br/> 
        Customer ID: {!Monthly_Cloud_Bill__c.Account__r.Customer_ID__c} <br/>
       </font>
     </td>
</tr>
</table>

<p><b><font face="Arial" color="#000080">Customer Information</font></b></p>

<table border="0" width="100%" id="table2">
<tr>
       <td colspan="3">
           <font face="Arial">{!Monthly_Cloud_Bill__c.Account__r.Name} <br/></font>
       </td>
</tr>
<tr>
       <td>          
           <font face="Arial">Attn: {!Monthly_Cloud_Bill__c.Contact__r.Name}<br/>
           
                             {!Monthly_Cloud_Bill__c.Account__r.BillingStreet}<br/>
                             {!Monthly_Cloud_Bill__c.Account__r.BillingCity}, {!Monthly_Cloud_Bill__c.Account__r.BillingState} {!Monthly_Cloud_Bill__c.Account__r.BillingPostalCode} <br/>
                             {!Monthly_Cloud_Bill__c.Account__r.BillingCountry} <br/>
                             Tel: {!Monthly_Cloud_Bill__c.Contact__r.Name}
           </font>
        </td>

</tr>    
</table>

<p><b><font color="#000080" face="Arial">Order Description</font></b></p>
<table border="1" width="100%" id="table4">
<tr>
       <td bgcolor="#C0C0C0"><font face="Arial">Product</font></td>
       <td bgcolor="#C0C0C0" align="center"><font face="Arial">Price</font></td>
       <td bgcolor="#C0C0C0" align="center"><font face="Arial">Units</font></td>       
       <td bgcolor="#C0C0C0" align="center"><font face="Arial">Amount</font></td> 
</tr>
<tr>
       
             <td>Product</td>
             <td align="center"> {!Monthly_Cloud_Bill__c.Price__c}</td>  
             <td align="center">{!Monthly_Cloud_Bill__c.Net_Usage_For_Billing__c}</td>             
             <td align="center"><apex:OutputField value="{!Monthly_Cloud_Bill__c.Billing_Amount__c}"/></td> 
          </tr>
         

<tr>
       <td bgcolor="#C0C0C0" align="right" colspan="6">
       <font face="Arial"><b>Total Due:</b><apex:OutputField value="{!Monthly_Cloud_Bill__c.Billing_Amount__c}"/></font></td>
</tr>
</table>

<p><b><font color="#000080" face="Arial">Payment Instructions</font></b></p>
<table border="0" width="100%" id="table3">
 <tr>
       <td><font face="Arial">
        
             1. Payment is due in full 30 days from the INVOICE DATE <br/>
             2. Overdue payments will be subject to a charge of 1% per month <br/>
             3. Payment is accepted by wire transfer, check or credit card: 
            </font>
        </td>
   
   <br/>

</tr> 



<table border="0" width="100%" id="table4">
<!--<tr>
       <td colspan="3">
           
       </td>
</tr> -->
<tr>
       <td>          
           <font face="Arial"><b>Wire transfer instructions:</b><br/>
                             
                           <apex:OutputField value="{!Monthly_Cloud_Bill__c.Wire_transfer_instructions__c}"/>
           </font>
        </td>
    <!--    <td width="1%"></td> -->
        
        <td>
           <font face="Arial"><b>Check payment instructions:</b><br/>
                            <apex:OutputField value="{!Monthly_Cloud_Bill__c.Check_payment_instructions__c}"/>
           </font>
        </td>
        
      
</tr>    
</table>

</table>

<hr/>
<p align="center"><font face="Arial">If you have any question about this invoice, please contact. <br/>
{!Monthly_Cloud_Bill__c.Account__r.Owner.FirstName} {!Monthly_Cloud_Bill__c.Account__r.Owner.LastName}, {!Monthly_Cloud_Bill__c.Account__r.Owner.Phone}, {!Monthly_Cloud_Bill__c.Account__r.Owner.Email} <br/> <br/>
<b>Thank You For Your Business!</b>
</font></p>

</apex:page>

 

Parent Visualforce:

<apex:page controller="PdfGeneratorController">

   <apex:form >  
    
   <apex:pageBlock title="PDF Input">  
 
      <apex:pageBlockButtons >
        <apex:commandButton action="{!savePdf}" value="Save PDF"/>
      </apex:pageBlockButtons>
      <apex:pageMessages />
 
 <iframe height="600px" id="Page" name="InvoicePDF" src="/apex/InvoicePDF2" width="100%"></iframe>
 
    </apex:pageBlock> 
  </apex:form>
    
    
</apex:page>

 

Many Thanks!

 

Itay

Hello

 

I have a lookup field from opportunity (on record type "Renewal") to Service Contracts, and I'm trying to update a service contract field , based on changes on the opportunity stage. For example: if an opportunity is changed to won, custom field on SC will be "won", if it's changed to lost, field will be "Lost". if the stage is changed to an open stage, field is "Open".

I can't use workflows...but I managed to use the code below. The problem is it updates only when the Opportunity is closed (I want that the Service contract will be updated on any stage change)

 

trigger UpdateSCFromOpp on Opportunity (after update) {


  Set<Id> oppIds = new Set<Id>();
    
    RecordType debtRT = [Select Id From RecordType Where Name = 'Enterprise - Renewal'];
    for(Opportunity opps : Trigger.new){
        // Check for Renewal Deal Record Type and change from open to close
       if(opps.RecordTypeId == debtRT.Id && opps.isclosed == true && trigger.OldMap.get(opps.Id).isclosed == false && opps.Expired_Service_Contract__c != null)
        {
        
            oppids.add(opps.Expired_Service_Contract__c);
        }
        }
                   
        for (ServiceContract[] sc:[select id from ServiceContract where id in :oppids]) {
        
          for(ServiceContract c:sc) {
          
        
          c.Renewal_Opportunity_Status_Field__c = 'Closed Won';
 
       }
            update sc;
  }
}

 

 

 

Thanks!

 

Itay

 

 

Hello

 

I've added a screen which the user can pick which license to create with choices (Trial / Production / Cloud), but I'd like to have validation on some options. For example: user with "Support" profile can't pick production license.

I can create a decision option and route to two different screens, but i'm wondering if I can add validation on a choice (so when a support user picks "production" choice, an error message is displayed - "you can't pick this kind of license").

 

 

Thanks

 

Itay

Hello

 

I have a scenario when I need to upate Account and Opportunity fields (Next Step and Next Step Due Date) with Open Task Details (Next Step = Subject, Next Step DD = Due Date). if I have several tasks, the earlist one is displayed. If a task is closed, the next open task is displayed on Account / Opportunity.

Originaly, I had 2 triggers located under activities (one for accounts and one for activities). I wasn't sure if this was efficient so I changed that to 1 trigger that fires based on condition and launch a class.

trigger TasksToObjects on Task (after insert, after update) {

 Set<String> acctIdsSet = new Set<String>();
    for(Task t: Trigger.new) {
        String wId = t.WhatId;
       if (wId != null && wId.startsWith('001') ) {
            acctIdsSet.add(wId); 
            TaskToObject.Account(acctIdsSet); 
       }
       
        if (wId != null && wId.startsWith('006') ) {
            acctIdsSet.add(wId); 
            TaskToObject.Opportunity(acctIdsSet); 
       }
    }
}

 

public class TaskToObject {
 
  public static void Account(Set<String> acctIdsSet ) {
 
     List<Account> acctList = [SELECT Id, Next_Step__c, Next_Step_Due_Date__c, (SELECT Task.id, Task.Subject, Task.ActivityDate 
                                    FROM Tasks 
                                    WHERE Task.ActivityDate != NULL  AND Task.Status != 'Completed' ORDER BY Task.ActivityDate ASC limit 1) 
                                    FROM Account 
                                    WHERE Id IN :acctIdsSet ];
    
    if (acctList.size() > 0) {
     for(Account acct: acctList){
           if (acct.Tasks.size() != 0) {
                acct.Next_Step__c = acct.Tasks[0].Subject;
                acct.Next_Step_Due_Date__c = acct.Tasks[0].ActivityDate;
            } else {
                acct.Next_Step__c = 'No current activity';
                acct.Next_Step_Due_Date__c = null;
            }
        }
        try {
            update acctList;
        } catch(Exception ex) {
            System.debug('Problem updating the Accounts!');
    }
    }
}



  public static void Opportunity(Set<String> acctIdsSet ) {

List<Opportunity> oppList = [SELECT Id, NextStep, Next_Step_Due_Date__c, (SELECT Task.id, Task.Subject, Task.ActivityDate FROM Tasks WHERE Task.ActivityDate != NULL AND Task.Status != 'Completed' ORDER BY Task.ActivityDate ASC limit 1) FROM Opportunity WHERE Id IN :acctIdsSet ]; if (oppList.size() > 0) { for(Opportunity opp: oppList){ if (opp.Tasks.size() != 0) { opp.NextStep = opp.Tasks[0].Subject; opp.Next_Step_Due_Date__c = opp.Tasks[0].ActivityDate; } else { opp.NextStep = 'No current activity'; opp.Next_Step_Due_Date__c = null; } } try { update oppList; } catch(Exception ex) { System.debug('Problem updating the Opportunities!'); } } } }

 
The trigger & class work, I'm trying to determine if it is written in the most effieicnt way to write this (as this is my 1st time writing Apex Class).

 

 

Thanks!

 

Itay

Hello

 

I have the trigger below to copy opportunity M&S products to service contract when a service contract is created.

I have added the test coverage, but somehow I reach only 47% coverage, what am I missing? any help will be great!

 

Trigger:

trigger NewSCLineItems on ServiceContract (After Insert) {
    
    // Make a List of Opportunity ID's for all these quotes.
    Set<Id> oppIds = new Set<Id>();
    for(ServiceContract SC : Trigger.new) oppIds.add(SC.opportunity__c);
    
    // Fetch all the Opportunity Line Items for all these Opportunities
    List<OpportunityLineItem> olis = new List<OpportunityLineItem>([
        select 
             id, opportunityid, pricebookentryid, Quantity, UnitPrice, Discount
        from OpportunityLineItem 
        where opportunityid = :OppIds AND M_S_Product__c = 'TRUE'
    ]);
    

    // Build a Map, keyed by OppId, of Lists of the related OLI's
    Map<Id, List<OpportunityLineItem>> oliMap = new Map<Id, List<OpportunityLineItem>>();
    for (OpportunityLineItem oli: olis) {
       if (oliMap.containsKey(oli.OpportunityId)) {
            // If the map already has an entry for this Opp, add this OLI to the list.
            //oliMap.put(oli.OpportunityId, oliMap.get(oli.OpportunityId).add(oli));
            List<OpportunityLineItem> x;
            x = oliMap.get(oli.OpportunityId);
            x.add(oli);
            oliMap.put(oli.OpportunityId, x);
       } else {
            // This is the first entry for this Opportunity
            List<OpportunityLineItem> tmp = new List<OpportunityLineItem>();
            tmp.add(oli);
            oliMap.put(oli.OpportunityId, tmp);
       }
    }

   List<ContractLineItem> qli = new List<ContractLineItem>(); 
  
   // Iterate through each Contract
   for(ServiceContract sc : Trigger.new){
       // Do we have any OLI's for this Contract Opportunity?
       if (oliMap.containsKey(SC.opportunity__c)) {
           // Yes, so for each OLI in the List, create a QLI
           for (OpportunityLineItem oli: oliMap.get(SC.opportunity__c)) {
                qli.add(
                     New ContractLineItem (
                         ServiceContractId = SC.id,
                         pricebookentryid = oli.pricebookentryid,
                         UnitPrice = oli.UnitPrice,
                         Discount = oli.Discount,
                         Quantity = oli.Quantity
                     )
                );
           }
       }
    }
    if (! qli.isEmpty()) insert qli;
}

 

Test Class:

@IsTest(SeeAllData=true) private class CreateServiceContractLineItems{

    /* This is a basic test which simulates the primary positive case for the 
       save method in the quoteExt class. */

private static testMethod void myUnitTest() {

Account acc=new Account(Name='test');
insert acc;                

//Pricebook2 pb2=[Select id from Pricebook2 limit 1];

//Opportunity testOpp = new Opportunity(Name='TestOppty',closedate=date.parse('1/1/2222'),
//                    stagename = 'Qualification',AccountID=acc.id,Pricebook2Id=pb2.id);
//insert testOpp;

   Pricebook2 s = [select id from Pricebook2 where IsStandard = true];   
    
    // create the product
    Product2 p1 = new Product2(
        name='Test Product 1',
        IsActive=true,
        Description='My Product',
        ProductCode='12345'
    );
    insert p1;       
   
    // create the pricebookentry
    PricebookEntry pbe1 = new PricebookEntry(
        Pricebook2Id=s.id,
        Product2Id=p1.id,
        UnitPrice=0.00,
        IsActive=true,
        UseStandardPrice=false
    );
    insert pbe1;   
   
    // create the opportunity
    Opportunity opp1 = new Opportunity(
        name='Test Opp 1',
     ///   recordtypeid='01260000000DXrWxxx',
        StageName = 'Qualification',
        CloseDate = Date.newInstance(2009,01,01), 
        Pricebook2Id=s.id         
    );
    insert opp1;
    
   
    // add the line item
    OpportunityLineItem oli = new OpportunityLineItem();
    oli.Quantity = 1;
    oli.PricebookEntryId = pbe1.id;
    oli.OpportunityId = opp1.id;
    oli.UnitPrice=1;    
    insert oli;
    
    // add the 2nd line item
    OpportunityLineItem oli2 = new OpportunityLineItem();
    oli2.Quantity = 2;
    //oli2.TotalPrice = 2;
    oli2.PricebookEntryId = pbe1.id;
    oli2.OpportunityId = opp1.id;
    oli2.UnitPrice = 2;   
    insert oli2;
    
    ServiceContract sc =new ServiceContract(Name='test sc',AccountID=acc.id,Pricebook2Id=s.id, Opportunity__c=opp1.id );
    insert sc; 
    
    ContractLineItem cli = new ContractLineItem();
    cli.Quantity = oli.quantity;
    cli.PricebookEntryId = oli.PricebookEntryId;
    cli.ServiceContractId= sc.id;
    cli.UnitPrice= oli.UnitPrice;  
    insert cli;
    
    ContractLineItem cli2 = new ContractLineItem();
    cli2.Quantity = oli2.Quantity;
    cli2.PricebookEntryId = oli2.PricebookEntryId;
    cli2.ServiceContractId= sc.id;
    cli2.UnitPrice= oli2.UnitPrice;  
    insert cli2;
    
    System.assertEquals(cli2.UnitPrice, oli2.UnitPrice);

          }
}

 

Thanks in advance

 

Itay

We're using the Self-Service portal to manage cases. I'm Looking for a way to pull the "Created by" field from case comments, so I'll know if a SSP user or an internal SF user created the case comments. 

 

Is this possible?

 

Thanks!

 

Itay

Hi,

 

I want to create a 'create PDF' button on my new custom object. I would like it to look the same as the 'create PDF' function of the Quote standart object.

Is there a way to clone the functionality to my visualforce page?

 

Thanks for the assitance,

Liora

  • December 07, 2012
  • Like
  • 0

Hello

 

I've added a visualforce section to my case page layout, and the section is not aligned propertly (not according to each of the columns

What's the best way to align it according to the columns??

 

Visualforce:

<apex:page standardController="Case" extensions="stampLoginDetailsforPortalUser">
<apex:pageMessages />
<apex:pageBlock mode="maindetail" rendered="{!loginInfo.size >0}">
<apex:pageBlockTable value="{!loginInfo}" var="a" >
<apex:column headerValue="Last Login" value="{!a.LastLoginDate}"/>
<apex:column headerValue="IsActive" value="{!a.IsActive}"/>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:page>

 

 I posted the current situation: 

http://i46.tinypic.com/8xtpgn.jpg

 

Thanks!

 

Itay

Hello

 

I would like to know if it's possible to notify a user when there are field record changes. For example:case status was changed, priority was changed etc...

Structure of the email should be like this:

 

  • Who changed (I assume it can be "Last Modified By")
  • What was changed (Field and new value)
  • Link to case

I know that is possible to create a workflow and email for every field change, but i'm wondering if there's an elegant way (as I have around 10 fields)

 

Thanks

 

Itay

 

Hi,

I would like to have a custom field on the contact object that indicates if the contact is a self service portal user. The easiest solution would be a trigger/workflow on the SelfServiceUser object that sets a checkbox on the contact object - however there is no way to create a trigger or workflow on the SelfServiceUser object. Any suggestion?..

Hi,

 

I have Opportunity and Service Agreement being related via Look up(on Service Agreement).

Upon changing the stage of opportunity to "Won" , i want to create a New Service agreement and then carry over any Opportunity Line Items (Products) associated with that opportunity to Service Line agreements related to the Service agreement thats being created.

 

Can i accomplish this by writing one trigger on Opportunity itself or should i write 2 triggers, one on opportunity that would create the Service agreement and another on Service agreement that would again get the Opportunity products associated with that Service agreement.

 

Any help/pointers on this is highly appreciated.

 

I was able to create service agreements from the Opportunity, but was unsuccessful in adding the Opportunity Line Items within the same trigger.

 

 

trigger createAgreement on Opportunity (before update) {
List<ServiceContract> newServicecontract=New List<ServiceContract>();
Set<Id> oppIds=New Set<Id>();
for(Opportunity op : Trigger.New){
if(op.StageName=='Won' && op.workflow_Update__c==false && Trigger.oldMap.get(op.Id).StageName!='Won')
oppIds.Add(op.Id);
}
List<Opportunity> oppty=[Select Id,Name,AccountId,CloseDate,Contract_Activation_Date__c From Opportunity Where Id IN:oppIds];
System.Debug('List Size=='+oppty.size());
for(Integer i=0;i<oppty.size();i++){
ServiceContract sc=new ServiceContract();
String name='Service Contract For-';
sc.AccountId=oppty[i].AccountId;
sc.Name=name+oppty[i].Name;
sc.Opportunity__c=oppty[i].Id;
newServicecontract.Add(sc);
}
System.debug('Agreement Size=='+newServicecontract.size());
Database.insert(newServicecontract);
}

 

 

 

 

Thanks,

Sales4ce