• Rob P12
  • NEWBIE
  • 0 Points
  • Member since 2005

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 10
    Questions
  • 11
    Replies
 Hello,

I am trying to deploy Apex Code into production. The code coverage is 92%. In the Force.Com IDE I select the Validate
Deployment option. I get this error message 'incompatible key type Double for Map; String, String. I do have a line of code
Map<string, string> varRoleMap = New Map<string, string> ();

For (OIP_Partner__c oip : [Select Partner_Key__c, Partner_Type__c
    From OIP_Partner__c where Partner_Key_c IN varKeySet]) { // varKeySet created earlier
    
varRoleMap.put(oip_Partner_Key__c, oip.Partner_Type__c); 

Notes:
    oip_Partner_Key__c  string
    oip_Partner_Type__c picklist

I also tried string Partner_Type = oip.Partner_Type__c and used Partner_Type in the Put

Thanks
System.QueryException: Non-Selective against large Oject type

This in a Before Update Trigger: on Opportunity

The Marketplace_Partner_Key__c is a field on the Account Object and the Opportunity. This field is passed from an external source who omitted the Account.Id. Therefore what I am trying to do is get to the the Account Object
using the Marketplace_Partner_Key__c on the Opportunity. This is not an indexed field so I'm trying to load only those Account Records where the Marketplace_Partner_Key__c is not null.

Here is the code that raises the error message:

    Set<Id> idSet = New Set<Id>();

    For (account tmp : [Select Id, Name, Marketplace_Partner_Key__c
        From account Where Marketplace_Partner_Key__c != Null
        Order by Marketplace_Partner_Key__c]) {
       
        
        if (tmp.Marketplace_Partner_Key__C != Null) {
            idset.add(tmp.Marketplace_Partner_Key__c);
           
         }
        
    }    
    

Thanks for any help
    Hello, I have an Apex class and Trigger than I am trying to deploy from Sandbox into production.
    In the Force.com IDE I select the Validate Deployment this is where I get Not in Manifest on both the Class and Trigger.
    My TestMethod reaches 100% coverage. I am adding functionality to an unpackaged appexchange application.
Document Force.com for ASP.NET Developers page 12 Code Sample: Cut and Pasted this code in and getting error message when saving. Error:Read only Property 'leadLookupController.searchString' :
 I am trying to get to the Child Relationship Data.
 
In SF Explorer:
   QMB_Cost_Center__c
     Child Relationships:
       R00n0000001OrWrEAK
          Child Fields:
             Budget_Actual__c
          Child Object: QMB_Budget__c
          Related Field: QMB_Cost_Center__c
          Relationship Name: R00n0000001OrWrEAK
trigger getBudgetData on QMB_Cost_Center__c (before insert) {
  For (QMB_Cost_Center__c cc : [Select id, name, (Select Budget_Actual__c from        R00n60000001OrWrEAK)
      from QMB_Cost_Center__c]){
  }
}
Error: Compile Error: Didn't understand relationship 'R00n60000001OrWrEAK' in FROM part of query call. If you are attempting to use a custom relationship, be sure to append the '__r' after the custom relationship name. Please reference your WSDL or the describe call for the appropriate names. at line 2 column 32
Tried:
     R00N0000001OrWrEAK__c
     R00N0000001OrWrEAK__r
     QMB_Budget__c
     QMB_Budget__r
Has anyone had any success with Roll-up Calculations across objects?
Here is my need.
 
example
 
Bill of Material               - Detail Record
      Build Box-A for Account Name
 
------------------------------------------------------------------------------
Related List
      Object Material =       1,000.00
           # of Material 5   - -----------------------> transactions wood, metal, paper Etc unlimited
      Object Supplies =        500.00
      Object Labor     =       2,000.00
           # of Labor = 4----------------------------> the # of Workers and hrs
       Misc                               50.00 -----------> other transactions
 
                             total      3,550.00
 
Note: Box-A could have several hundred components.(Related-Lists ??).
 
How can I get this $3,550.00 to show on the detail record?  APEX, VB, Triggers, anything or can it be done.
Thanks
Is there a way to fetch the values from the View Dashboard and Report Folder/Folder Drop-Down Pick-list through the Api or Apex?  cut-and-paste is ok if possible.
How do I activate Apex Code in the SandBox?
Setup/Build/Code     Code new Button is not there and the Admin Profile/ Author Apex Code check box is not there. My Profile is Sys Admin.

My Development area is Apex Enabled but I can't test the code against the SandBox Data..
I am reading data from an external system that is passing the OIP Number as Field goipno_pos the value in this field is 73015. I am trying to match this number is SF, But when the query is executed the record is not Found. When I hardcode the number in place of goipno_pos the record is found. What should I do to get the argument to work. Here is the programs query statment: Set qr = g_sfApi.Query("select ID, Name, Named_Opportunity__c, OIPCloseDate__c, OIPNumber__c, OIP_Expiration_Date__c, Opp_Number__c, Special_Pricing_Status__c from Opportunity where (OIPNumber__c = 'goipno_pos')", False) Help J. Taylor - TrailBlazer
Hi!
 
In our implementation we have member field on account object. Every month we want to update this field with some value derived from child record.
 
 
1)Should we code Trigger OR  Apex class to be call from S-control?
 
 2)If it is trigger  then how would you mass update all accounts?
3)Can we write Apex class and call it from s-control
4)Can you automate the process to run at the end of the month?
5) Please provide sample code for the solution for above.
 
Thanks
 
 
 
 
 
 


Message Edited by aj4 on 05-12-2008 04:56 PM
  • May 12, 2008
  • Like
  • 0
Pardon me please. I am just totally perplexed about the testing. It's required , but hardly explained.  Here is my code.
 
What and how should the test be done so I can get this deployed today !
 
trigger MakeRouteEvents on Account (before insert, before update)
{
// Create routes for FAR's based on choices in Accounts.
// DECLARATIONS: OLD VALUES IN RECORD vs NEW VALUES IN RECORD.
Account[] oldRecords; // GET THE OLD VALUES
Account[] newRecords; // GET THE NEW VALUES
// DECLARATIONS: CONVERSIONS FROM THE FORM TO DATATYPES NEEDED BY EVENT.
Date VisitStartDate; // From Form: Date from date picker
String strVisitStartDate; // Visit Start Date - just date portion - converted to a string.
DateTime finalVisitStartDate; // This is the one written to the field 'RecurrenceStartDateTime'
String strVisitTime; // The time of day from the VISIT TIME picklist
String strDuration; // Duration of visit from Picklist
Integer intDuration; // Duration of site visit in minutes - converted to Integer
String strFrequency; // How often should the visit occur - form Picklist
Integer intFrequency; // How often should the visit occur - converted to integer.
String strVisitDayOfWeek; // Visit day of week, from Picklist.
Integer intVisitDayOfWeek; // Visit day of week, Mon, Tues: converted to Integer
//DateTime timeOfVisit; // converted to time for the Event table.
// DECLARATIONS: OTHER VARIABLES NEEDED BY EVENT
String strAccountId; // From Screen. Get The Account Id
String strUserId; // From API.
String strUserTimeZone; // From User Table. NEEDED BY EVENT.
Event[] existingEvents; // From User Table GET EXISTING ROUTE EVENTS FOR ACCOUNT SO WE CAN DELETE THEM.
// =================================================================
// START PROCESSING
// =================================================================
// GET THE OLD RECORD VALUES AND THE NEW RECORD VALUES
oldRecords = Trigger.old; // old trigger has old record values
newRecords= Trigger.new; // new trigger has new record values
Boolean WorkToDo; // Flag indicates if we have work to do, yes or no.
// DO WE HAVE ANYTHING TO DO?
WorkToDo = FALSE;
if (oldRecords[0].Visit_Start_Date__c != newRecords[0].Visit_Start_Date__c){WorkToDo = TRUE;}
else if (oldRecords[0].Visit_Day_of_Wk__c != newRecords[0].Visit_Day_of_Wk__c){WorkToDo = TRUE;}
else if (oldRecords[0].Visit_Time__c != newRecords[0].Visit_Time__c){WorkToDo = TRUE;}
else if (oldRecords[0].Visit_Wk__c != newRecords[0].Visit_Wk__c){WorkToDo = TRUE;}
else if (oldRecords[0].Visit_Wk_Freq__c != newRecords[0].Visit_Wk_Freq__c){WorkToDo = TRUE;}

// WHAT WOULD CAUSE US TO NOT WANT TO WORK?
if (newRecords[0].Visit_Start_Date__c == null) {WorkToDo = FALSE;}
System.debug('Work To do ' + WorkToDo);
if (WorkTodo)
{
// SCRAPE THE FORM AND SET VARIABLE VALUES
strAccountId = newRecords[0].Id; // Account
VisitStartDate = newRecords[0].Visit_Start_Date__c; // Visit Starting Date
strVisitTime = newRecords[0].Visit_Time__c;
strFrequency = newRecords[0].Visit_Wk_Freq__c; // Frequency
strDuration = newRecords[0].Visit_Duration__c; // Duration of Visit
strVisitDayOfWeek = newRecords[0].Visit_Day_of_Wk__c;
//CONVERT VISIT DAY OF WEEK TO RECURRENCE DAY OF WEEK MASK
System.debug('Day Of Week ' + strVisitDayOfWeek);
if (strVisitDayOfWeek == 'Sunday') {intVisitDayOfWeek = 1;}
else if (strVisitDayOfWeek == 'Monday') {intVisitDayOfWeek = 2;}
else if (strVisitDayOfWeek == 'Tuesday') {intVisitDayOfWeek = 4;}
else if (strVisitDayOfWeek == 'Wednesday') {intVisitDayOfWeek = 8;}
else if (strVisitDayOfWeek == 'Thursday') {intVisitDayOfWeek = 16;}
else if (strVisitDayOfWeek == 'Friday') {intVisitDayOfWeek = 32;}
else if (strVisitDayOfWeek == 'Saturday') {intVisitDayOfWeek = 64;}
// CONVERT DURATION OF VISIT FROM STRING TO INTEGER
if (strDuration == '15 Minutes') {intDuration = 15;}
else if (strDuration == '30 Minutes') {intDuration = 30;}
else if (strDuration == '45 Minutes') {intDuration = 45;}
else if (strDuration == '60 Minutes') {intDuration = 60;}
// CONVERT THE RECURRENCE INTERVAL FROM STRING TO INTEGER.
System.debug('strFrequency ' + strFrequency);
if (strFrequency == 'Weekly') {intFrequency = 1;}
else if (strFrequency == 'Two Weeks') {intFrequency = 2;}
else if (strFrequency == 'Three Weeks') {intFrequency = 3;}
else if (strFrequency == 'Four Weeks') {intFrequency = 4;}
else if (strFrequency == 'Six Weeks') {intFrequency = 6;}
else if (strFrequency == 'Eight Weeks') {intFrequency = 8;}
// CONVERT TIME OF DAY FROM STRING TO DATE
if (strVisitTime == '7:00 AM') {strVisitTime = '07:00';}
else if (strVisitTime == '7:30 AM') {strVisitTime = '07:30:00';}
else if (strVisitTime == '8:00 AM') {strVisitTime = '08:00:00';}
else if (strVisitTime == '8:30 AM') {strVisitTime = '08:30:00';}
else if (strVisitTime == '9:00 AM') {strVisitTime = '09:00:00';}
else if (strVisitTime == '9:30 AM') {strVisitTime = '09:30:00';}
else if (strVisitTime == '10:00 AM') {strVisitTime = '10:00:00';}
else if (strVisitTime == '10:30 AM') {strVisitTime = '10:30:00';}
else if (strVisitTime == '11:00 AM') {strVisitTime = '11:00:00';}
else if (strVisitTime == '11:30 AM') {strVisitTime = '11:30:00';}
else if (strVisitTime == '12 NOON') {strVisitTime = '12:00:00';}
else if (strVisitTime == '12:30 PM') {strVisitTime = '12:30:00';}
else if (strVisitTime == '1:00 PM') {strVisitTime = '13:00:00';}
else if (strVisitTime == '1:30 PM') {strVisitTime = '13:30:00';}
else if (strVisitTime == '2:00 PM') {strVisitTime = '14:00:00';}
else if (strVisitTime == '2:30 PM') {strVisitTime = '14:30:00';}
else if (strVisitTime == '3:00 PM') {strVisitTime = '15:00:00';}
else if (strVisitTime == '3:30 PM') {strVisitTime = '15:30:00';}
else if (strVisitTime == '4:00 PM') {strVisitTime = '16:00:00';}
else if (strVisitTime == '4:30 PM') {strVisitTime = '16:30:00';}
else if (strVisitTime == '5:00 PM') {strVisitTime = '17:00:00';}
else if (strVisitTime == '5:30 PM') {strVisitTime = '17:30:00';}
else if (strVisitTime == '6:00 PM') {strVisitTime = '18:00:00';}
// GET THE USER TIMEZONE
strUserId = UserInfo.getUserId(); // First, get the User ID
//System.debug('User Id is ' + strUserId);
strUserTimeZone = [SELECT TimeZoneSidKey from User where Id = :strUserId][0].TimeZoneSidKey;
//System.debug('Time Zone is ' + strUserTimeZone);
// ASSEMBLE DATES
System.debug('Now ' + System.Now());
System.debug('First Event Date is ' + VisitStartDate);
//System.debug(' Visit Start Date ' + newRecords[0].Visit_Start_Date__c);
strVisitStartDate = String.valueOf(VisitStartDate).substring(0,10); // get date portion, not time portion
System.debug('strVisitTime ' + strVisitTime);
strVisitStartDate = strVisitStartDate + ' ' + strVisitTime;
system.debug('strVisitStartDate ' + strvisitStartDate);
finalVisitStartDate = DateTime.valueOf(strVisitStartDate);
//strVisitStartDate = String.valueOf(VisitStartDate); // get date portion, not time portion
// EVERYTHING IS SET SO DROP EXISTING EVENTS AND CREATE NEW SCHEDULE OF EVENTS
existingEvents = [select Id, AccountId, isRecurrence from Event where AccountId = :strAccountId and isRecurrence = TRUE];
delete existingEvents;
Event newEvent = new Event
(
WhatId = strAccountId,
Subject = 'Route',
Location = 'On-Site',
Description = 'Scheduled Route Site Visit',
ShowAs = 'Busy',
IsReminderSet = FALSE,
IsRecurrence = TRUE,
DurationInMinutes = intDuration,
ActivityDate = date.today(),
ActivityDateTime = System.now(),
RecurrenceDayOfWeekMask = intVisitDayOfWeek,
RecurrenceInterval = intFrequency,
RecurrenceType = 'RecursWeekly',
//RecurrenceStartDateTime = strVisitStartDate,
RecurrenceStartDateTime = finalVisitStartDate,
RecurrenceEndDateOnly = Date.valueOf('2009-03-30'),
RecurrenceTimeZoneSidKey = strUserTimeZone
//ActivityDateTime = '9pm'
);
insert newEvent;

}

}
Hi All,

I've written and deployed several triggers now, but I seem to be having trouble with one Trigger that keeps saying that it's only covered 72% by test unit. I've included the trigger and the testcase. Could anybody help me please. 

What the trigger does is it calculates the total rate on insertion order record, and sum them to quota's monthly field. So that we can easily see our salesperson's projected and actual quotas.

It is working perfectly on our sandbox environment, but I can't get the test case right to be able to deploy it.


Here's the trigger:
trigger InsertQuotaBefore on Quota__c (before insert, before update) {
    Integer START_FISCAL_MONTH = 9; //September
   
    Integer startYear = 0;
    Integer nextYear = 0;
   
    Trigger.new[0].Jan_Actual__c = 0;
    Trigger.new[0].Feb_Actual__c = 0;
    Trigger.new[0].Mar_Actual__c = 0;
    Trigger.new[0].Apr_Actual__c = 0;
    Trigger.new[0].May_Actual__c = 0;
    Trigger.new[0].Jun_Actual__c = 0;
    Trigger.new[0].Jul_Actual__c = 0;
    Trigger.new[0].Aug_Actual__c = 0;
    Trigger.new[0].Sept_Actual__c = 0;
    Trigger.new[0].Oct_Actual__c = 0;
    Trigger.new[0].Nov_Actual__c = 0;
    Trigger.new[0].Dec_Actual__c = 0;
   
    String startYearStr = Trigger.new[0].Financial_Year__c.substring( 0, 4 );
   
    startYear = Integer.valueOf( startYearStr );
    nextYear = startYear + 1;   

    Insertion_Order__c [] ios = [select Id, CreatedDate, Total_Rate_after_disc__c, created_year__c, created_month__c from Insertion_Order__c where Sales_Person__c= :Trigger.new[0].Sales_Person__c and (( created_year__c = :startYear and created_month__c >= :START_FISCAL_MONTH ) or ( created_year__c = :nextYear and created_month__c < :START_FISCAL_MONTH ))];
               
    for ( Integer i = 0; i < ios.size(); i++ ) {
        if ( ios[i].created_month__c == 1 ) {
            Trigger.new[0].Jan_Actual__c = Trigger.new[0].Jan_Actual__c + ios[i].Total_Rate_after_disc__c;
        } else if ( ios[i].created_month__c == 2 ) {
            Trigger.new[0].Feb_Actual__c = Trigger.new[0].Feb_Actual__c + ios[i].Total_Rate_after_disc__c;
        } else if ( ios[i].created_month__c == 3 ) {
            Trigger.new[0].Mar_Actual__c = Trigger.new[0].Mar_Actual__c + ios[i].Total_Rate_after_disc__c;
        } else if ( ios[i].created_month__c == 4 ) {
            Trigger.new[0].Apr_Actual__c = Trigger.new[0].Apr_Actual__c + ios[i].Total_Rate_after_disc__c;
        } else if ( ios[i].created_month__c == 5 ) {
            Trigger.new[0].May_Actual__c = Trigger.new[0].May_Actual__c + ios[i].Total_Rate_after_disc__c;
        } else if ( ios[i].created_month__c == 6 ) {
            Trigger.new[0].Jun_Actual__c = Trigger.new[0].Jun_Actual__c + ios[i].Total_Rate_after_disc__c;
        } else if ( ios[i].created_month__c == 7 ) {
            Trigger.new[0].Jul_Actual__c = Trigger.new[0].Jul_Actual__c + ios[i].Total_Rate_after_disc__c;
        } else if ( ios[i].created_month__c == 8 ) {
            Trigger.new[0].Aug_Actual__c = Trigger.new[0].Aug_Actual__c + ios[i].Total_Rate_after_disc__c;
        } else if ( ios[i].created_month__c == 9 ) {
            Trigger.new[0].Sept_Actual__c = Trigger.new[0].Sept_Actual__c + ios[i].Total_Rate_after_disc__c;
        } else if ( ios[i].created_month__c == 10 ) {
            Trigger.new[0].Oct_Actual__c = Trigger.new[0].Oct_Actual__c + ios[i].Total_Rate_after_disc__c;
        } else if ( ios[i].created_month__c == 11 ) {
            Trigger.new[0].Nov_Actual__c = Trigger.new[0].Nov_Actual__c + ios[i].Total_Rate_after_disc__c;
        } else if ( ios[i].created_month__c == 12 ) {
            Trigger.new[0].Dec_Actual__c = Trigger.new[0].Dec_Actual__c + ios[i].Total_Rate_after_disc__c;
        }   
    }
}



And here's my test class:
public class InsertQuotaBeforeTestCase {
    static testMethod void testInsertQuotaBefore() {
        Date dt = System.today();

        Insertion_Order__c io1 = new Insertion_Order__c( E_Campaign_Start_Date__c = dt,
            Contract_Period__c = 3,
            Sales_Person__c = '00520000000whV2AAI',
            CCRID__c = '1234567890',
            Account_Number__c = '1234567890',
            Type__c = 'New Business',
            Invoice_Status__c = 'Pending',
            Order_Status__c = 'Draft'
        );
           
        insert io1;
        Insertion_Order__c [] ios = [select Contract_Period__c from Insertion_Order__c where Id = :io1.Id];
        System.assertEquals( ios[0].Contract_Period__c, 3 );

        InvoiceOB__c[] inList = [select Id from InvoiceOB__c where Insertion_Order_No__c= :io1.Id];       
        System.assertEquals( inList.size(), 0 );

        io1.Order_Status__c = 'Signed';
        update io1;
       
        inList = [select Id from InvoiceOB__c where Insertion_Order_No__c= :io1.Id];
        System.assertEquals( inList.size(), 1 );

        Order_Details__c od1 = new Order_Details__c( Name = '01',
            Product_Category__c = 'Directory Listing',
            Unit_Price__c = 800,
            CurrencyIsoCode = 'SGD',
            Quantity__c = 3,
            Insertion_Order__c = io1.Id );

        insert od1;

        ios = [select Total_Rate_after_disc__c from Insertion_Order__c where Id = :io1.Id];
        System.assertEquals( ios[0].Total_Rate_after_disc__c, 2400 );
           
        Order_Details__c od2 = new Order_Details__c( Name = '02',
            Product_Category__c = 'Directory Listing',
            Unit_Price__c = 200,
            CurrencyIsoCode = 'SGD',
            Quantity__c = 3,
            Insertion_Order__c = io1.Id );
           
        insert od2;
        ios = [select Total_Rate_after_disc__c from Insertion_Order__c where Id = :io1.Id];
        System.assertEquals( ios[0].Total_Rate_after_disc__c, 3000 );
       
        Quota__c qu1 = new Quota__c( Name = '01',
            Financial_Year__c = '2007/08',
            Sales_Person__c = '00520000000whV2AAI' );
   
        insert qu1;
        Quota__c[] quotas = [select Sales_Person__c, Apr_Actual__c from Quota__c where Sales_Person__c = '00520000000whV2AAI'];
        System.assertEquals( quotas.size(), 1 );
        System.assertEquals( quotas[0].Apr_Actual__c, 3000 );

       
        update qu1;
        quotas = [select Sales_Person__c, Apr_Actual__c from Quota__c where Sales_Person__c = '00520000000whV2AAI'];
        System.assertEquals( quotas.size(), 1 );
        System.assertEquals( quotas[0].Apr_Actual__c, 3000 );

        ios = [select Total_Rate_after_disc__c, created_month__c from Insertion_Order__c where Id = :io1.Id];
        System.assertEquals( ios[0].Total_Rate_after_disc__c, 3000 );
        System.assertEquals( ios[0].created_month__c, 4 );
       
        io1.CCRID__C = '9876543210';
        update io1;
       
        ios = [select Total_Rate_after_disc__c from Insertion_Order__c where Id = :io1.Id];
        System.assertEquals( ios[0].Total_Rate_after_disc__c, 3000 );
       
        od2.Unit_Price__c = 300;
        update od2;
       
        ios = [select Total_Rate_after_disc__c from Insertion_Order__c where Id = :io1.Id];
        System.assertEquals( ios[0].Total_Rate_after_disc__c, 3300 );
       
        delete od2;
       
        ios = [select Total_Rate_after_disc__c, created_month__c from Insertion_Order__c where Id = :io1.Id];
        System.assertEquals( ios[0].Total_Rate_after_disc__c, 2400 );
       
        quotas = [select Id, Sales_Person__c, Sept_Actual__c, Oct_Actual__c, Nov_Actual__c, Dec_Actual__c, Jan_Actual__c, Feb_Actual__c, Mar_Actual__c, Apr_Actual__c, May_Actual__c, Jun_Actual__c, Jul_Actual__c, Aug_Actual__c, Q1_Actual__c, Q2_Actual__c, Q3_Actual__c, Q4_Actual__c from Quota__c where Sales_Person__c = '00520000000whV2AAI'];


        System.assertEquals( quotas[0].Q3_Actual__c, quotas[0].Mar_Actual__c + quotas[0].Apr_Actual__c + quotas[0].May_Actual__c);
        Quota__c qu2 = new Quota__c( Name = '01',
            Financial_Year__c = '2008/09',
            Sales_Person__c = '00520000000whV2AAI' );
           
        insert qu2;
       
        quotas = [select Sales_Person__c, Apr_Actual__c from Quota__c where Id = :qu2.Id];
        System.assertEquals( quotas.size(), 1 );
        System.assertEquals( quotas[0].Apr_Actual__c, 0 );
       
        io1.

        delete io1;
        update qu1;
       
        quotas = [select Sales_Person__c, Apr_Actual__c from Quota__c where Sales_Person__c = '00520000000whV2AAI'];
        System.assertEquals( quotas.size(), 2 );
        System.assertEquals( quotas[0].Apr_Actual__c, 0 );
       
       
      }
}


Thank you before hand for your help
Bastian

I don't know how many people have managed to deploy to their production environment without a single issue in Eclipse, but this process has been a nightmare for me causing me hours of completely unnecessary work, so now I'm going to take some time to write up the crap I've gone through to inform other users as well as Salesforce. Before I say anything else, though, I'd like to propose that Salesforce enable a means to directly transfer code from a sandbox to live within the Salesforce UI with the possibility of not requiring unit testing. Now, on with my story.

I wrote a trigger and a utility class and modified them directly in the sandbox environment without the use of Eclipse. I did most of the revisions in an external editor then copied/pasted those modifications into the sandbox. I performed a variety of tests to prove that my code was working properly without the use of unit tests. When I was ready to deploy my code to the live environment almost THREE WEEKS AGO, I was at a complete loss of what to do. I didn't see any buttons in the sandbox that said "move to live" or anything in the live environment that would allow me to create a trigger by editing code directly (like you can do with s-controls), so I began doing some research. I discovered two paths to deployment: the ANT tool and Eclipse. Honestly, I was opposed to having to use either route. It seemed to me that having to download third party tools to move code from the sandbox to live was a very broken process. I researched using the ANT tool, as there appeared to be more documentation provided by Salesforce for using this tool than using Eclipse, but then I saw a few posts in this community suggesting that using the ANT tool was a very tedious, error-prone process, so I went with Eclipse (version 3.3.1.1). There was almost no documentation provided by Salesforce regarding the use of Eclipse--documentation that did exist for this route was exceedingly sparse and lacks any real substance or troubleshooting information.

So, I started a new Force.com project in Eclipse we'll call Foo. I entered all the credentials and made the "SOAP Endpoint" point to "https://www.salesforce.com/services/Soap/u/11.1", which is the live environment. I figured I could just paste all my code into this new project then save it to live. When the project was created, the first thing I noticed were subfolders in Foo/src that had no value to this project whatsoever; these were subfolders named "AJAX Tools", "crystalreports.com release v1.2", "Financial", and "VerticalResponse for AppExchange". I could only guess these were installed applications/packages in our Salesforce environment, but what were they doing in my project?! I figured, okay, well, this is stupid, but I'll ignore these folders and put everything beneath the "unpackaged" subfolder. I recreated my trigger and utility class, then attempted to "Synchronize with Server", "Save to Server", and "Refresh from Server", but nothing worked. A dialog would pop up saying "Operation in progress..." but then it would close without any information. Nothing was working. I did more research and figured it might have to do with the fact that I wasn't running any tests, so I created a quick testMethod and ran it. Still nothing. I went in and tweaked the project settings, changed the "SOAP Endpoint" to "https://test.salesforce.com/services/Soap/u/11.1" and modified the credentials so I could access the sandbox and magically, all of the Force.com menu options started doing something. So that's great, I thought, now I can manipulate items in the sandbox, but that doesn't achieve anything.

More research led me to trying the test unit route. I figured if I created some code to test my trigger and utility class and achieve full coverage, I'd be past one of the stages of this horrible deployment process. So, I created a new class to house my testMethods and the first testMethod I wrote was to test my utility class. Right-click, Force.com, Run Tests and voila, utility class is 100% covered--it was small, had almost no conditionals, and didn't modify any objects in Salesforce, so 100% coverage for this was trivial. Now, time to test the trigger. Developing the testMethod for this was beyond tedious, causing me days of trouble, and I had other tasks and projects to attend to at work that actually accomplished something. Ultimately, with another pair of eyes examining the test code, I discovered the error was a misplaced 'insert' line. Fortunately, all this time I was running tests, all I had to do was right click in the code of my test class, go down to Force.com, and 'Run Tests'. The test coverage status would display in a pane in the "Apex Code Test Runner" and it applied to both my trigger and my utility class. After finally achieving 100% coverage of the trigger, I attempted the first deploy. First, I was prompted about files not being synchronized so I decided to attmept a synchronization, but because of the presence of some oddities in other files beneath those extra packages, such as "Financial", full synchronization didn't seem to work, so I skipped this and continued with deployment. Second, I encountered problems with the version number, since the sandbox is running 12.0 and this would be written into the meta files for the code, but the live environment is running 11.1, so conflicts arose. Next, I was posed with a deployment plan which had all kinds of references to things associated with the other aforementioned applications, and this was yet another annoyance, but I could safely ignore these inclusions. So, I found the pieces of the plan relating to my trigger, utility class, and test class, checked them, validated deployment, and finally deployed successfully--that was fairly painless.

Then my next nightmare started: I had to change a single literal string value being assigned to a variable in my trigger, so I would have to do this then redeploy. I modified the literal string and ran tests again. This time, however, the code coverage shown in the "Apex Code Test Runner" applied to the test class itself (which makes no sense) and neither the trigger nor the utility class were mentioned. The only way I could get the test class to run against something other than itself was to right click on the "classes" subfolder (i.e. Foo/src/unpackaged/classes), which contained both the test class and utility class, then go to Force.com > Run Tests. The code coverage then showed 100% coverage for both the utility class and the test class. I decided to try a deploy without running the tests directly like this, and when I came to the deployment plan I noticed something very odd: the deployment plan had "Overwrite" options for my trigger and utility class, but they belonged to the "Financial" application and were not in the "unpackaged" category. I exited the deployment dialog and expanded the "Financial" folder and its "classes" and "triggers" subfolders which revealed copies of my utility class and trigger. Now, beneath my project, my trigger and utility class existed both beneath "Financial" and "unpackaged". I selected the copies beneath "Financial" and deleted them, a dialog appeared saying they did not exist on the server so they would only be deleted locally--wonderful. Then I went to issue another deployment. Oops, version issues, have to modify those meta files then deploy again. Came back to the deployment plan (after having to enter my credentials and select a SOAP Endpoint for the deployment for the umpteenth time) and found my trigger and utility class marked for deletion from the Financial package, but there was no mention of "Adding" or "Overwriting" for my trigger and utility class under the "unpackaged" package. So, I ran the deploy, deleted the faux trigger and utility class from "Financial" and attempted to deploy again hoping the plan would display my classes under the "unpackaged"--nothing. Where the hell did they go?

I created another project, pasted my code, attempted to run tests but saw my test class was receiving 100% coverage with no mention of my trigger or utility class, so that's still broken, but I issued a deploy, anyway. Deploy failed saying my trigger was only 35% covered. I examined the test code and discovered a line I must have commented out somewhere in the confusion, then deployed, again. Finally, almost three weeks later, 100% coverage, successful validation, successful deployment.

I shouldn't have to massage a third party IDE to deploy something from the sandbox to live, but I did and needless to say, I'm beyond frustrated.


Message Edited by soma on 03-07-2008 11:54 AM
  • March 07, 2008
  • Like
  • 0
Hi all,

I have created a trigger whose code is  running fine  on the dev instance but when I tried to deploy in the production instace the deployment failed and gives me a error message as given below, on the third step of deployment using the Eclips deployment wizard. while validating the trigger.

Test coverage of selected Apex Trigger is 0%, at least 1% test coverage is required.

Test coverage of selected Apex Class and Trigger is 0%, at least 75% test coverage is required.

here is the code for the trigger:-
trigger trytrigger on OpportunityLineItem (after insert)
{
  if(trigger.isAfter)
   {
     if (trigger.isInsert)
      {
       for (OpportunityLineItem c :trigger.new)
        {
          Date strDate;
          Integer intDayTotal;
          Integer intMonth;
          OpportunityLineItemSchedule [] OLI = [Select Id, ScheduleDate from OpportunityLineItemSchedule where OpportunityLineItemId=:c.Id order by ScheduleDate];
          OpportunityLineItem opp = new OpportunityLineItem(Id=c.Id);
          for(OpportunityLineItemSchedule o:OLI)
           {
               strDate=o.ScheduleDate;
               Integer strMonth=strDate.month();
               Integer intDay=strDate.day();
               if(strMonth==1 || strMonth==3 || strMonth==5 || strMonth==7  || strMonth== 8 || strMonth==10 || strMonth==12)
               {
                   intDayTotal=31;
                   intDayTotal=intDayTotal-intDay;
               }
               else if(strMonth==4 || strMonth==6 || strMonth==9 || strMonth==11)
               {
                   intDayTotal=30;
                   intDayTotal=intDayTotal-intDay;
               }
               else if(strMonth==2)
               {
                   intDayTotal=28;
                   intDayTotal=intDayTotal-intDay;
               }
               strDate=strDate.addDays(intDayTotal);
               opp.Test_Field__c=strDate;
           }
           update opp;
        }
      }
   }
}

Please let me know what I am doing wrong??
Thanks in anticipation of your reponse.

thanks and regards
pallav

  • January 31, 2008
  • Like
  • 0
Has anyone had any success with Roll-up Calculations across objects?
Here is my need.
 
example
 
Bill of Material               - Detail Record
      Build Box-A for Account Name
 
------------------------------------------------------------------------------
Related List
      Object Material =       1,000.00
           # of Material 5   - -----------------------> transactions wood, metal, paper Etc unlimited
      Object Supplies =        500.00
      Object Labor     =       2,000.00
           # of Labor = 4----------------------------> the # of Workers and hrs
       Misc                               50.00 -----------> other transactions
 
                             total      3,550.00
 
Note: Box-A could have several hundred components.(Related-Lists ??).
 
How can I get this $3,550.00 to show on the detail record?  APEX, VB, Triggers, anything or can it be done.
Thanks
Hi All,

I'm having difficulty figuring out how to test my trigger so that I can put it in my production environment. My trigger is simple and checks to see if a field has been changed and if so it updates another field with the current date and time like so:

trigger PIFDateUpdate on Account bulk (before update) {
for (Account an : Trigger.new) {for (Account ao : Trigger.old) {
if (an.PIF_Available_Balance__c ao.PIF_Available_Balance__c) {
an.As_of_2__c = System.Now();
}
}
}
}

However, I can't figure out how to get 75% test coverage for this. Any thoughts?
How do I activate Apex Code in the SandBox?
Setup/Build/Code     Code new Button is not there and the Admin Profile/ Author Apex Code check box is not there. My Profile is Sys Admin.

My Development area is Apex Enabled but I can't test the code against the SandBox Data..
I receive a VB error 91, Object variable or With block variable not set after trying to execute the Query command.
 
Here is my code:
 
Option Compare Database
Option Explicit
'Declare an OfficeToolkit object.
'The WithEvents keyword enables asynchronous function calls
Public WithEvents g_sfApi As SForceOfficeToolkitLib3.SForceSession3
Dim MyValue As String
Dim Rectype As String
Dim acctname As String
Dim squery As String
Dim asynch As Boolean
 
Private Sub Form_Load()
Set g_sfApi = New SForceOfficeToolkitLib3.SForceSession3
Form!SFUser.SetFocus
Form!SFUser.Text = " "
Form!SFPassword.Value = " "
End Sub
 
....  Login function here and login is successsful
 
Private Sub Login_to_Salesforce_Click()
SFLogin Username, Password
If g_sfApi.IsLoggedIn Then
     
    Dim Message As String
    Dim Title As String
    Message = "Type in Account name to retrieve"
    Title = "Retrieve Account from SalesForce"
    MyValue = InputBox(Message, Title)
   
    If MyValue > "" Then
        Dim qr As QueryResultSet3
        ' create a session object
        'Set g_sfApi = New SForceOfficeToolkitLib3.SForceSession3
        acctname = MyValue
        Rectype = g_sfApi.EntityNames(0)
        asynch = False
        squery = "Select Id,Name,BillingCity,BillingCountry, BillingState, BillingPostalCode,Fax,Phone FROM " & Rectype & " WHERE Name = '" & MyValue & "'"
        
        SFQuery squery, asynch
        If s.Error <> NO_SF_ERROR Then
           MsgBox s.ErrorMessage
        End If
                   
            For Each v In qr
'loop through the results
'cast to an sobject3 to see more helpful debug info
            Set s = v
            
                If s.Error <> NO_SF_ERROR Then
                    MsgBox s.ErrorMessage
                Else
'use the object
                    MsgBox s.Item(0)
                       
'NOTE you cannot call async methods until this method returns
                End If
            Next
    Else
        Exit Sub
    End If
Else
    If g_sfApi.Error <> NO_SF_ERROR Then
        MsgBox g_sfApi.ErrorMessage
    End If
End If
End Sub

Public Function SFQuery(squery, asynch) As QueryResultSet3
'setup for exception type error handling
On Error GoTo handleError
    SFQuery = g_sfApi.Query(squery, asynch)   <----- Error occurs here
        
    If g_sfApi.Error <> NO_SF_ERROR Then
        MsgBox g_sfApi.ErrorMessage
    End If
    Stop
Exit Function
handleError:
look at the exception message
MsgBox Err.Description
'look at the message in the session
'MsgBox g_sfApi.ErrorMessage
End Function
 
I am not a VB programmer and most of this code was used from information I found on the Web.
Does anyone know why I am receiving a VB error when using the SF Office Toolkit Query command?
Thanks,
 - Vicki