+ Start a Discussion
Micky MMicky M 

Trigger not firing

Hi All, 

I have a problem, where im calling a method in a controller from a button on a visual force page. The controller updates some records but the trigger that i have which is an after update doesnt fire (well acutally it seems like its firing at random there are a good few hundred records) has anyone else had this problem and know how to solve the issue? thanks.
Swayam  AroraSwayam Arora
Please share the Controller and Trigger code.
Sandeep Kumar 84Sandeep Kumar 84
it is random probably beacuse controller's "update" dml is not being called.
Micky MMicky M
OK so how would i solve that?
Swayam  AroraSwayam Arora
Micky, kindly share the code then only we will be able to help you.
Micky MMicky M
Here's the VF code

<apex:page StandardController="BillingDate__c" extensions="BillingCommandCenter" tabStyle="Billing__tab">
    <head>
        <apex:includeScript value="{!URLFOR($Resource.Jquery2, 'jquery-2.0.2.min.js')}"/>
        
        <script>
            function setFocusOnLoad() {}
            
            var j$ = jQuery.noConflict(); 
            
            j$(document).ready(function() 
                {                                                           
                    j$("[id$=fadeInControl]").fadeIn("slow");
                });
        </script>
        
        <style type="text/css">
            .myPaddingClass { padding: 0px 0px;}
            .myButtonClass{ color:white !important;
                            background:red !important; 
                            width:105px; height:50px; 
                            font-size: 200% !important; 
                            border: 5px solid; 
                            border-radius: 100px !important;}
        </style> 
    </head>
     <div id="fadeInControl" style="display:none">
        <apex:form >
        
            <apex:sectionHeader title="Logged in as : {!$User.FirstName} {!$User.LastName}" subtitle="Billing Command Center"/>
            
            <apex:outputPanel id="errorMessage">
                 <apex:pageMessages />
            </apex:outputPanel>
            
            <p><p>Set the Date, Do a billing run, go away and update all your values then come back and click <i>"Commit"</i>.</p></p>
            
            <apex:pageBlock title="Scary Buttons"> 
            
                
                <apex:pageBlockSection >            
                    <apex:pageBlockSectionItem labelTitle="Set Date">
                        <apex:outputLabel value="Select a Billing Date" for="BillingDate__c.Billing_Date__c"/>
                        <apex:inputField value="{!BillingDate__c.Billing_Date__c}" />
                    </apex:pageBlockSectionItem>
                    
                    <apex:pageBlockSectionItem >
                        <apex:outputLabel value="Execute Billing Run" for="DoABillingRun"/>
                        <apex:commandButton styleClass="myButtonClass" value="GO!" action="{!DoABillingRun}" reRender="workingMessage, errorMessage" status="workingMessage"/>
                    </apex:pageBlockSectionItem>
                    
                    <!-- line up the go and commit buttons -->
                    <apex:pageBlockSectionItem >
                    </apex:pageBlockSectionItem>
                
                    <apex:pageBlockSectionItem >
                            <apex:outputLabel value="Everything up to date? then" for="DoABillingRun"/>
                            <apex:commandButton styleClass="myButtonClass" value="Commit!" action="{!DoACommit}" reRender="workingMessage, errorMessage" status="workingMessage"/>
                     </apex:pageBlockSectionItem>
                 </apex:pageBlockSection> 
                 <p></p>   
                 
                 <apex:pageBlock >
                     <apex:outputText value="Job Status : " id="counter"/>
                     <apex:actionStatus startText=" Working Hard..." stopText=" All Done" id="workingMessage">
                         <apex:facet name="start">
                             Processing ... 
                             <img src="{!$Resource.Spinner}"/>
                         </apex:facet>
                      </apex:actionStatus>
                 </apex:pageBlock>
            </apex:pageBlock>
        </apex:form>
    </div>
</apex:page>

<----------------------------------------- Here's the trigger ------------------------------->

//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Calculate the totals (Banding Total) for each breakdown. The banding total is then rolled up on the 
// line item (Recurring Service Total) 
//////////////////////////////////////////////////////////////////////////////////////////////////////////
trigger mcsBreakdownTotals on MCS_Contract_Invoice_Line_Item_Breakdown__c (after insert, after update) 
{
    System.debug('Running mcsBreakdownTotals trigger');

    // As this is an after insert trigger we have a class (staticFlagsForRecursionTriggers) which has a boolean,
    // firstRun, this is initialised to true and is in scope in the current execution context.
    if(staticFlagsForRecursionTriggers.firstRun)
        {
            set<id> breakdownIds = new set<id>();

        for(MCS_Contract_Invoice_Line_Item_Breakdown__c  so : Trigger.new) 
            breakdownIds.add(so.MCS_Contract_Invoice_Line_Item__c);
        // Get all the breakdown obects attached to the line item ordered by start quantity
        list<MCS_Contract_Invoice_Line_Item__c> LineItemsWithBreakdowns = new list<MCS_Contract_Invoice_Line_Item__c>();

        LineItemsWithBreakdowns = [SELECT Quantity__c, Id, (SELECT Billing_Term__c, Break_Down_Type__c, End_Quantity__c, Start_Quantity__c, Customer_Allowance__c, Invoice_Period_From__c, Invoice_Period_To__c,
                            Invoice_Date__c, Band_Quantity__c, MCS_Contract_Invoice_Line_Item__c, Unit_Sell_Price__c, Line_Item_Quantity__c, Committed__c, BillingDate__c FROM MCS_Contract_Invoice_Line_Item_Breakdown__r order by Start_Quantity__c) FROM MCS_Contract_Invoice_Line_Item__c where Id IN :breakdownIds];        

        System.debug('LineItemsWithBreakdowns = ' + LineItemsWithBreakdowns);

        list<MCS_Contract_Invoice_Line_Item_Breakdown__c> breakdowns = new list<MCS_Contract_Invoice_Line_Item_Breakdown__c>();

        //////////////////////////////////////////////////////////////////////////////////
        // Loop around the line items and breakdowns and work out the banding total for each 
        //////////////////////////////////////////////////////////////////////////////////
        for(MCS_Contract_Invoice_Line_Item__c l : LineItemsWithBreakdowns) 
        {
            System.debug('breakdown trigger: l = ' + l);

            //The quantity from the breakdown line item, just in case we need it.
            //Decimal quantity = l.Quantity__c;
            //System.debug('Line item quantity = ' + quantity);

            //Loop around the breakdowns
            for(MCS_Contract_Invoice_Line_Item_Breakdown__c b : l.MCS_Contract_Invoice_Line_Item_Breakdown__r)
            {
                if(b.Committed__c != true)
                {
                    System.debug('breakdown trigger: b = ' + b);

                    //Decimal banding = b.End_Quantity__c - b.Start_Quantity__c;

                    //Just check the input data
                    //convert to lower case so the nobhead users can type any old bumpf in.
                    String lowerCaseBillingTerm = b.Billing_Term__c != null ? b.Billing_Term__c.toLowerCase() : '';
                    if(b.Customer_Allowance__c == null) b.Customer_Allowance__c = 0;
                    if(b.Unit_Sell_Price__c == null) b.Unit_Sell_Price__c = 0;
                    
                    System.debug('lowerCaseBillingTerm = ' + lowerCaseBillingTerm);

                    if(b.Unit_Sell_Price__c != null && b.billingDate__c != null)
                    {
                        System.debug('Trigger billing date = ' + b.billingDate__c);

                        if(lowerCaseBillingTerm == 'monthly in advance' || lowerCaseBillingTerm == 'annually in advance' || lowerCaseBillingTerm == 'quarterly in advance')
                        {
                            System.debug('The billingTerm check worked ...');

                            b.Banding_Total__c = ( (b.Band_Quantity__c - b.Customer_Allowance__c) -  (b.End_Quantity__c - b.Start_Quantity__c)  ) * b.Unit_Sell_Price__c;

                            if( b.Invoice_Date__c.Month() == b.billingDate__c.month() &&  b.Invoice_Date__c.Year() == b.billingDate__c.year() )
                            {
                                b.Banding_Total__c  += period(lowerCaseBillingTerm) * (b.End_Quantity__c - b.Start_Quantity__c) *b.Unit_Sell_Price__c;
                                System.debug('mcsBreakdownTotals trigger In advance - b.Banding_Total__c  = ' + b.Banding_Total__c + ' ' + b.Id);
                            }
                            b.Unbilled_Usage__c = 0;
                        }
                        else
                        {
                            System.debug('Breakdown Trigger in arrears bit');
                            
                            Decimal tempTotal = (b.Band_Quantity__c - b.Customer_Allowance__c) * b.Unit_Sell_Price__c;    

                            if((b.Invoice_Date__c !=null)  && (b.Invoice_Date__c.Month() == b.billingDate__c.month() &&  b.Invoice_Date__c.Year() == b.billingDate__c.year()) )
                            {
                                b.Unbilled_Usage__c = 0;
                                b.Banding_Total__c = tempTotal;
                            }
                            else
                            {
                                b.Banding_Total__c = 0;
                                b.Unbilled_Usage__c = tempTotal;
                            }  
                            System.debug('mcsBreakdownTotals trigger In arrears - b.Banding_Total__c  = ' + b.Banding_Total__c + ' ' + b.Id);
                        }            
                    }
                    else
                    {
                        b.Banding_Total__c = 0;
                        b.Unbilled_Usage__c = 0;
                        System.debug('mcsBreakdownTotals trigger Reseting values');
                    }

                    //Work out the invoice period dates

                    //If needed later work out the last day of the month
                    //Date firstDayOfMonth = System.today().toStartOfMonth();
                    //Date lastDayOfMonth = firstDayOfMonth.addDays(Date.daysInMonth(firstDayOfMonth.year(), firstDayOfMonth.month()) - 1);

                    b.Invoice_Period_From__c =  CalculateFromInvoicePeriodDates(b.Invoice_Date__c, lowerCaseBillingTerm);
                    b.Invoice_Period_To__c     =  CalculateToInvoicePeriodDates(b.Invoice_Date__c, lowerCaseBillingTerm);
                    System.debug('b.Invoice_Period_From__c after method = ' + b.Invoice_Period_From__c);

                    //Add the breakdowns to a list so we can update them with a banding total
                    breakdowns.add(b);
                }            
            }
        }

        //Set the firstRun flag to fales before the update so the trigger will exit nicely.
        staticFlagsForRecursionTriggers.firstRun = FALSE;
        
        //finally if the list contains any breakdowns then update them.
        System.debug('breakdowns = ' + breakdowns);

        if(!breakdowns.isEmpty())
            update(breakdowns);
        }

        Integer period(String p)
        {
         Integer result = 0;

            if(p.contains('monthly'))
                result = 1;

            if(p.contains('quarterly'))    
                result = 3;

            if(p.contains('annually'))
                result = 12;

            return result;
        }

        public Date CalculateFromInvoicePeriodDates(Date invoiceDate, String billingTerm)
        {
            System.debug('fromDate in method = ' + invoiceDate);
            System.debug('billingTerm in method = ' + billingTerm);

            Date fromDate = null;

            if(billingTerm == 'monthly in arrears')
                fromDate = invoiceDate.addMonths(-1);
            if(billingTerm == 'quarterly in arrears')
                fromDate = invoiceDate.addMonths(-3);
            if(billingTerm == 'annually in arrears')
                fromDate = invoiceDate.addMonths(-12);

            if(billingTerm == 'monthly in advance')
                fromDate = invoiceDate.addMonths(0);
            if(billingTerm == 'quarterly in advance')
                fromDate = invoiceDate.addMonths(0);
            if(billingTerm == 'annually in advance')
                fromDate = invoiceDate.addMonths(0);

            return fromDate;
        }

        public Date CalculateToInvoicePeriodDates(Date invoiceDate, String billingTerm)
        {
            System.debug('fromDate in method = ' + invoiceDate);
            System.debug('billingTerm in method = ' + billingTerm);

            Date toDate = null;

            if(billingTerm == 'monthly in arrears')
                toDate = invoiceDate.addMonths(0);
            if(billingTerm == 'quarterly in arrears')
                toDate = invoiceDate.addMonths(0);
            if(billingTerm == 'annually in arrears')
                toDate = invoiceDate.addMonths(0);

            if(billingTerm == 'monthly in advance')
                toDate = invoiceDate.addMonths(1);
            if(billingTerm == 'quarterly in advance')
                toDate = invoiceDate.addMonths(3);
            if(billingTerm == 'annually in advance')
                toDate = invoiceDate.addMonths(12);    

            return toDate;
        }
}
Micky MMicky M
I'll have to post the contoller in two halves as its quite big

public class MCSContractInvoices 
{
    //Generate invoices for this date
    Date billingDate;

    //Time attached to the invoice name
    String theCurrentTime;

    //Holds contracts with recurring invoices.
    list<Contract> ContractsWithContractRecurringServices = null;

    //Holds contract Id and a list of recurring servies.
    map<id, list<MCS_Contract_Recurring_Service__c>> ContractRecurringServices = new map<id, list<MCS_Contract_Recurring_Service__c>>();
    
    //Map to hold contract ID and the newly created invoice.
    map<id, MCS_Contract_Recurring_Service_Invoice__c> InvoiceMap = null;

    //Recurring line items to attach to the invoice.
    list<MCS_Contract_Invoice_Line_Item__c> MCS_Contract_Invoice_Line_ItemsList = null;

    //list to hold the recurring service ids so we can use this to select the breakdown items and loop though
    list<id> ContractRecurringSerivceIdList = new list<id>();


    ////////////////////////////////////////////////////////////
    // Start Here
    ////////////////////////////////////////////////////////////
    public void GenerateContractInvoices()
    {
        System.debug('In - GenerateContractInvoices');

        System.debug('Running - GetBillingDate');
        GetBillingDate();

        System.debug('Running - GetContractsAndRecurringServices');
        GetContractsAndRecurringServices();
        System.debug('Running - CreateAndAddInvoices');
        CreateAndAddInvoices();
        System.debug('Running - CreateAndAddLineItemsToInvoice');
        CreateAndAddLineItemsToInvoice();
        System.debug('Running - CreateAndAddBreakdowns');
        CreateAndAddBreakdowns();
        System.debug('Running - CreateStartupServicesAndAttachToInvoice');
        CreateStartupServicesAndAttachToInvoice();
    }

    ////////////////////////////////////////////////////////////
    // Get the last save billing date
    ////////////////////////////////////////////////////////////
    public void GetBillingDate()
    {
        System.debug('The Billing date = ' + billingDate);

        list<BillingDate__c> dateList = [SELECT Billing_Date__c FROM BillingDate__c ORDER BY CreatedDate DESC];

            if(!dateList.isEmpty())
                billingDate = dateList[0].Billing_Date__c;
            //else billingDate = System.today();
    }

    ////////////////////////////////////////////////////////////
    // Get the current date time and stip the time and return it.
    ////////////////////////////////////////////////////////////
    public String getTheCurrentTime() 
    {
            String theCurrentTimeAndDate = Datetime.now().format();
        String[] theCurrentTime = theCurrentTimeAndDate.split(' ');

        return (theCurrentTime[1] != '' ? theCurrentTime[1] : '00:00:00');
        }

    /////////////////////////////////////////////////////////
    // Setup a list of contractId->list<recurring services>
    /////////////////////////////////////////////////////////
    public void  GetContractsAndRecurringServices()
    {
        ContractsWithContractRecurringServices = new List<Contract>([SELECT AccountId, Id, Name, ContractNumber, Contract_End_Date__c, 
                                                Contract_Start_Date__c, ContractTerm, (SELECT Id, Asset__c,Billing_Term__c,Charging_Metric__c,Contract__c,
                                                    Contract_Term__c,Start_Date__c, End_Date__c,Name,MCS_Opportunity_Recurring_Service__c,Quantity__c,
                                                        Unit_Cost__c,Unit_Hard_Cost__c,Unit_Price__c,Unit_Sales_Margin__c,Unit_Sell_Price__c,
                                                            Unit_Soft_Cost__c, Service__c, Invoice_Date__c FROM MCS_Contract_Recurring_Services__r) 
                                                                FROM Contract c where Id IN (Select Contract__c from MCS_Contract_Recurring_Service__c)]);

        /*ContractsWithContractRecurringServices = new List<Contract>([SELECT AccountId, Id, Name, ContractNumber, Contract_End_Date__c, 
                                                Contract_Start_Date__c, ContractTerm, (SELECT Id, Asset__c,Billing_Term__c,Charging_Metric__c,Contract__c,
                                                    Contract_Term__c,Start_Date__c, End_Date__c,Name,MCS_Opportunity_Recurring_Service__c,Quantity__c,
                                                        Unit_Cost__c,Unit_Hard_Cost__c,Unit_Price__c,Unit_Sales_Margin__c,Unit_Sell_Price__c,
                                                            Unit_Soft_Cost__c, Service__c, Invoice_Date__c FROM MCS_Contract_Recurring_Services__r) 
                                                                FROM Contract c where Id = '800M0000000Z0vM']);*/
        
        for(Contract c : ContractsWithContractRecurringServices)
        {
            list<MCS_Contract_Recurring_Service__c> MCS_Contract_Recurring_Service_List = new List<MCS_Contract_Recurring_Service__c>();

            for(MCS_Contract_Recurring_Service__c ContractRecurringService : c.MCS_Contract_Recurring_Services__r)
                MCS_Contract_Recurring_Service_List.add(ContractRecurringService);
    
            ContractRecurringServices.put(c.id, MCS_Contract_Recurring_Service_List);
        }
    }    


    ///////////////////////////////////////////////////////
    // Create Invoices and attach them to the contracts
    ///////////////////////////////////////////////////////
    public void CreateAndAddInvoices()
    {
         InvoiceMap = new map<id, MCS_Contract_Recurring_Service_Invoice__c>();

        //loop through the list of contracts and generate new invoices and attach them to the contract
        list<MCS_Contract_Recurring_Service_Invoice__c> MCS_Contract_Recurring_Service_Invoices_List = new list<MCS_Contract_Recurring_Service_Invoice__c>();

        for(Contract c : ContractsWithContractRecurringServices)
        {
            MCS_Contract_Recurring_Service_Invoice__c tempInvoice = new MCS_Contract_Recurring_Service_Invoice__c();
            tempInvoice.Name = string.valueOf(billingDate)  +  ' ' + getTheCurrentTime(); 
            tempInvoice.Contract__c = c.Id;
            tempInvoice.Account__c = c.AccountId;
            tempInvoice.BillingDate__c = billingDate;

            MCS_Contract_Recurring_Service_Invoices_List.add(tempInvoice);

            //the new invoice and the id of the contract
            InvoiceMap.put(c.id, tempInvoice);
        }
        insert(MCS_Contract_Recurring_Service_Invoices_List);
    }


    /////////////////////////////////////////////////////////////
    // Create the recurring line items and add them to the contract
    /////////////////////////////////////////////////////////////
    public void CreateAndAddLineItemsToInvoice()
    {
        //list of line items to insert.
        MCS_Contract_Invoice_Line_ItemsList = new list<MCS_Contract_Invoice_Line_Item__c>();

        //Create a list of dates that we need to update for next months invoices
        list<MCS_Contract_Recurring_Service__c> lineItemDatesToUpdate = new list<MCS_Contract_Recurring_Service__c>();

        //loop though each contract
        for(Contract c : ContractsWithContractRecurringServices)
        {
            //for each contract get the associated list of recurring services.
            list<MCS_Contract_Recurring_Service__c> ContratRecurringServicesList = ContractRecurringServices.Get(c.id);

            //then for each recurring service
            for(MCS_Contract_Recurring_Service__c rs : ContratRecurringServicesList)
            {
                //create a temp line item to be added to the list
                MCS_Contract_Invoice_Line_Item__c tempLineItem = new MCS_Contract_Invoice_Line_Item__c();

                //get the id of the new invoice attached to the contract
                tempLineItem.MCS_Contract_Recurring_Service_Invoice__c = InvoiceMap.get(c.id).id;
                
                //map the fields
                //This is a link back to the original recurring service.
                tempLineItem.MCS_Recurring_Service__c = rs.Id;
                tempLineItem.Asset__c = rs.Asset__c;
                tempLineItem.Billing_Term__c = rs.Billing_Term__c;
                tempLineItem.Charging_Metric__c = rs.Charging_Metric__c;
                tempLineItem.Quantity__c = rs.Quantity__c;
                tempLineItem.Service__c = rs.Service__c;
                tempLineItem.Unit_Cost__c = rs.Unit_Cost__c;
                tempLineItem.Unit_Sales_Margin__c = rs.Unit_Sales_Margin__c;
                tempLineItem.Unit_Sell_Price__c = rs.Unit_Sell_Price__c;
                tempLineItem.Unit_Soft_Cost__c = rs.Unit_Soft_Cost__c;
                tempLineItem.Unit_Price__c = rs.Unit_Price__c;
                tempLineItem.Unit_Hard_Cost__c = rs.Unit_Hard_Cost__c;
                tempLineItem.ContractTerm__c = c.ContractTerm;

                //Keep a list of the recurring service id's
                ContractRecurringSerivceIdList.add(rs.Id);

                //add the line items to the list
                MCS_Contract_Invoice_Line_ItemsList.add(tempLineItem);

                lineItemDatesToUpdate.add(rs); 
            }
        }
        //save the line items
        insert(MCS_Contract_Invoice_Line_ItemsList);
        //Update the line items on the contract
        update(lineItemDatesToUpdate);
    } 
Micky MMicky M
///////////////////////////////////////////////////////////////
    // Add the breakdowns to the invoice line items
    //////////////////////////////////////////////////////////////
    public void CreateAndAddBreakdowns()
    {
        //Get the contract recurring services with associated breakdown objects
        list<MCS_Contract_Recurring_Service__c> RecurringServiceIdWithBreakDownsList = new list<MCS_Contract_Recurring_Service__c>([SELECT Id, (SELECT Hold_Date__c, Break_Down_Type__c,Name,Customer_Allowance__c, Customer_Allowance_Allowed__c, Billing_Term__c, Invoice_Date__c,
                                                                                                                End_Quantity__c,MCS_Recurring_Service__c,Metric__c, Start_Date__c, End_Date__c,
                                                                                                                    Id,Start_Quantity__c,Unit_Sell_Price__c FROM Contract_Recurring_Service_Breakdown__r) 
                                                                                                                        FROM MCS_Contract_Recurring_Service__c where Id IN :ContractRecurringSerivceIdList and 
                                                                                                                            Id IN (select MCS_Recurring_Service__c from Contract_Recurring_Service_Breakdown__c)]);

        //map to hold the recurring service id and a list of breakdowns
        map<id, list<Contract_Recurring_Service_Breakdown__c>> ContractRecurringServiceIdWithBreakDownMap = new map<id, list<Contract_Recurring_Service_Breakdown__c>>();
        
    
        //////////////////////////////////////////////////////////////////////////////
        // Now we have a list of Contract Recurring Service IDs with a list of breakdowns.        
        //////////////////////////////////////////////////////////////////////////////
        for(MCS_Contract_Recurring_Service__c crs : RecurringServiceIdWithBreakDownsList)
        {
            //breakdown list used by the map 
            list<Contract_Recurring_Service_Breakdown__c> breakDownList = new list<Contract_Recurring_Service_Breakdown__c>();    

            for(Contract_Recurring_Service_Breakdown__c rsb : crs.Contract_Recurring_Service_Breakdown__r)
                breakDownList.add(rsb);

            if(!breakDownList.isEmpty())
                ContractRecurringServiceIdWithBreakDownMap.put(crs.id, breakDownList);    
        }

        //Invoice breakdown items to insert
        list<MCS_Contract_Invoice_Line_Item_Breakdown__c> breakDownsToInsert = new list<MCS_Contract_Invoice_Line_Item_Breakdown__c>();

        //update the invoice date on the original breakdowns
        list<Contract_Recurring_Service_Breakdown__c> originalBreakdowns = new list<Contract_Recurring_Service_Breakdown__c>();

        //loop round the MCS_Contract_Invoice_Line_ItemsList 
        for(MCS_Contract_Invoice_Line_Item__c li : MCS_Contract_Invoice_Line_ItemsList)
        {
            system.debug('line items = ' + li);

            list<Contract_Recurring_Service_Breakdown__c> breakdowns = ContractRecurringServiceIdWithBreakDownMap.get(li.MCS_Recurring_Service__c);

            system.debug('Key = ' + li.MCS_Recurring_Service__c);
            system.debug('breakdowns = ' + breakdowns);

            if(breakdowns != null)
            {
                System.debug('CHECK THESE! ' + breakdowns + ' ' + li.MCS_Recurring_Service__c);
                for(Contract_Recurring_Service_Breakdown__c b : breakdowns)
                {
                    System.debug('MCSContractInvoices b =  ' + b);

                    if(b != null)
                    {
                        System.debug('Im in the if!!!!');
                        //Put some breakdown date checking in here.
                        if( (b.End_Date__c != null && b.Start_Date__c != null) &&  (b.Start_Date__c <= system.today() && b.End_Date__c >= system.today() ) && (b.Invoice_Date__c != null) )
                        {
                            MCS_Contract_Invoice_Line_Item_Breakdown__c tempBreakdown = new MCS_Contract_Invoice_Line_Item_Breakdown__c();
                            
                            //Assign values to the invoice line item breakdown object while checking for incoming nulls.
                            tempBreakdown.MCS_Contract_Invoice_Line_Item__c = li.id;
                            tempBreakdown.Contract_Recurring_Service_Breakdown__c = b.id; //this links the invoice breakdown to the contract breadown.
                            tempBreakdown.Break_Down_Type__c = (b.Break_Down_Type__c == null) ? 'Flexible' : b.Break_Down_Type__c;
                            tempBreakdown.Customer_Allowance__c = (b.Customer_Allowance__c == null) ? 0 : b.Customer_Allowance__c;
                            tempBreakdown.Customer_Allowance_Allowed__c = (b.Customer_Allowance_Allowed__c == null) ? false : b.Customer_Allowance_Allowed__c;
                            tempBreakdown.End_Quantity__c = (b.End_Quantity__c == null) ? 0 : b.End_Quantity__c;
                            tempBreakdown.Metric__c = (b.Metric__c == null) ? 'None' : b.Metric__c;
                            tempBreakdown.Start_Quantity__c = (b.Start_Quantity__c == null) ? 0 : b.Start_Quantity__c;
                            tempBreakdown.Unit_Sell_Price__c = (b.Unit_Sell_Price__c == null) ? 0 : b.Unit_Sell_Price__c;
                            tempBreakdown.Billing_Term__c = (b.Billing_Term__c == null) ? 'monthly in advance' : b.Billing_Term__c;
                            tempBreakdown.Invoice_Date__c = (b.Invoice_Date__c == null) ? System.today() : b.Invoice_Date__c;
                            tempBreakdown.Start_Date__c = (b.Start_Date__c == null) ? System.today() : b.Start_Date__c;
                            tempBreakdown.End_Date__c = (b.End_Date__c == null) ? System.today() : b.End_Date__c;
                            tempBreakdown.Hold_Date__c = (b.Hold_Date__c == null) ? null : b.Hold_Date__c;
                            
                            //convert the billing term to lower case, that way the user can enter any old bumpf
                            /*String lowerCaseBillingTerm = b.Billing_Term__c.toLowerCase();

                            //Only update the invoice date on the original line items if th invoice date is the billing date
                            System.debug('breakdown b.Invoice_Date__c = '+ b.Invoice_Date__c + ' : billingDate = ' + billingDate);

                            if(billingDate != null && b.Invoice_Date__c.toStartOfMonth() == billingDate.toStartOfMonth())
                            {
                                if(lowerCaseBillingTerm == 'monthly in advance')
                                {
                                    b.Invoice_Date__c = b.Invoice_Date__c.addMonths(1);
                                }
                                else if(lowerCaseBillingTerm == 'monthly in arrears')
                                {
                                    b.Invoice_Date__c = b.Invoice_Date__c.addMonths(1);
                                }
                                else if(lowerCaseBillingTerm == 'quarterly in advance')
                                {
                                    b.Invoice_Date__c = b.Invoice_Date__c.addMonths(3);
                                }
                                else if(lowerCaseBillingTerm == 'quarterly in arrears')
                                {
                                    b.Invoice_Date__c = b.Invoice_Date__c.addMonths(3);
                                }
                                else if(lowerCaseBillingTerm == 'annually in advance')
                                {
                                    b.Invoice_Date__c = b.Invoice_Date__c.addMonths(12);
                                }
                                else if(lowerCaseBillingTerm == 'annually in arrears')
                                {
                                    b.Invoice_Date__c = b.Invoice_Date__c.addMonths(12);
                                }
                                //We also need to update the invoice date on the original breakdown.
                                originalBreakdowns.add(b);
                            }*/
                            
                            //Whack the new breakdowns in a list
                            breakDownsToInsert.add(tempBreakdown);
                        }
                    }
                }
            }
        }

        //update the original breakdowns.
        if(!originalBreakdowns.isEmpty())
            update(originalBreakdowns);
        
        System.debug('Trying to insert - breakDownsToInsert' + breakDownsToInsert);

        if(!breakDownsToInsert.isEmpty())
            insert(breakDownsToInsert);
    }


    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Get a list of startup services per contract and create new mcs startup objects and attach them to the invoices.
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public void CreateStartupServicesAndAttachToInvoice()
    {
        //Pull out the invoice id's from the map
        list<id> InvoiceIds = new list<id>();

        list<MCS_Contract_Startup_Service__c> StartupBilledFlagUpdate = new list<MCS_Contract_Startup_Service__c>();

        for(id i : InvoiceMap.keySet())
            InvoiceIds.add(InvoiceMap.get(i).Id);
    
        System.debug('Start up InvoiceIds = ' + InvoiceIds);

        //Then select all the startup services from the contracts
        list<Contract> contractsWithStartupServices = new list<Contract>([SELECT Id, (SELECT Asset__c, Billed__c, Contract__c,Invoice_Date__c,Name,Quantity__c,Service__c, Description__c,
                                                                            Unit_Cost__c,Unit_Hard_Cost__c,Unit_Price__c,Unit_Sales_Margin__c,Unit_Sell_Price__c,
                                                                                Unit_Soft_Cost__c, Unit_Sell__c FROM MCS_Contract_Startup_Services__r) FROM Contract where id IN :InvoiceMap.keySet()]);

        System.debug('Start up contractsWithStartupServices = ' + contractsWithStartupServices);    

        //create a map with contractId as the key and the startup service as the value
        map<Id, List<MCS_Contract_Startup_Service__c>> startupServicesWithContractIdMap = new map<Id, List<MCS_Contract_Startup_Service__c>>();

        for(Contract c : contractsWithStartupServices)
        {
            list<MCS_Contract_Startup_Service__c> tempService = new list<MCS_Contract_Startup_Service__c>();

            for(MCS_Contract_Startup_Service__c css : c.MCS_Contract_Startup_Services__r)
                tempService.add(css);
            
            startupServicesWithContractIdMap.put(c.Id, tempService);
        }

        System.debug('Start up startupServicesWithContractIdMap = ' + startupServicesWithContractIdMap);

        //create a list of new invoice line items to insert
        list<MCS_Contract_Invoice_Startup_Line_Item__c> startupItemsToInsert = new list<MCS_Contract_Invoice_Startup_Line_Item__c>();

        //loop round all the contract ids
        for(Id key : InvoiceMap.keySet())
        {
            //pull out all the line items for the first contract
            list<MCS_Contract_Startup_Service__c> startups = new list<MCS_Contract_Startup_Service__c>(startupServicesWithContractIdMap.get(key));
    
            //loop round the line items and create new invoice invoice startup items
            for(MCS_Contract_Startup_Service__c l : startups)
            {
                System.debug('Startup - l = ' + l);
                System.debug('Startup - Invoice_Date__c = ' + l.Invoice_Date__c);

                //Check Invoice date to see if this line item should be placed on the invoice
                if(l.Billed__c == false && l.Invoice_Date__c != null && (l.Invoice_Date__c.Month() == system.today().month() && l.Invoice_Date__c.Year() == system.today().year()))
                {
                    System.debug('IT WORKS');
                    MCS_Contract_Invoice_Startup_Line_Item__c tempItem = new MCS_Contract_Invoice_Startup_Line_Item__c();

                    tempItem.MCS_Contract_Recurring_Service_Invoice__c = InvoiceMap.get(key).Id;
                    tempItem.Asset__c = l.Asset__c;
                    tempItem.Service__c = l.Service__c;
                    tempItem.Quantity__c = l.Quantity__c;
                    tempItem.Unit_Cost__c = l.Unit_Cost__c;
                    tempItem.Unit_Price__c = l.Unit_Price__c;
                    tempItem.Unit_Sell__c = l.Unit_Sell__c;
                    tempItem.Description__c = l.Description__c;

                    startupItemsToInsert.add(tempItem);

                    //Set the billed flag to true and add it to the list to update at the end.
                    l.Billed__c = true;
                    StartupBilledFlagUpdate.add(l);
                }
            }
        }
        
        if(!startupItemsToInsert.isEmpty())
            insert(startupItemsToInsert);

        update(StartupBilledFlagUpdate);
    }
}
Micky MMicky M
right gents thats the lot, can anyone see whats going on? cos im stumped as to why the trigger seems to be running at random
 
Sandeep Kumar 84Sandeep Kumar 84
I Cann you are making one flag false before update.

//Set the firstRun flag to fales before the update so the trigger will exit nicely.
        staticFlagsForRecursionTriggers.firstRun = FALSE;
        
        //finally if the list contains any breakdowns then update them.
        System.debug('breakdowns = ' + breakdowns);

        if(!breakdowns.isEmpty())
            update(breakdowns);
        }


and you putting if(staticFlagsForRecursionTriggers.firstRun) in the trigger. can you make sure if these are fine. second you have debug statement also  System.debug('breakdowns = ' + breakdowns); you need to see the size of record in the cases where you triggers are not firing.
 
Micky MMicky M
Hi Sandeep this is the static class

public with sharing class staticFlagsForRecursionTriggers 
{
    public static boolean firstRun = true;
}

so i initially set the flag to true I'll check whats coming through in the debug.
Micky MMicky M
ok looks like i am getting breakdowns 

10:00:23:114 USER_DEBUG [118]|DEBUG|breakdowns = (MCS_Contract_Invoice_Line_Item_Breakdown__c:{Break_Down_Type__c=Flexible, Invoice_Period_From__c=2014-10-30 00:00:00, CurrencyIsoCode=GBP, Band_Quantity__c=0.00, Customer_Allowance__c=0.00, Invoice_Date__c=2014-11-30 00:00:00, Line_Item_Quantity__c=0.00, BillingDate__c=2014-11-01 00:00:00, Invoice_Period_To__c=2014-11-30 00:00:00, Start_Quantity__c=0.00, Unit_Sell_Price__c=0.0246, End_Quantity__c=0.00, Billing_Term__c=Monthly In Arrears, Committed__c=false, Id=a1jD0000001YZxeIAG, MCS_Contract_Invoice_Line_Item__c=a1iD0000001F4kGIAS, Unbilled_Usage__c=0, Banding_Total__c=0.000000}, MCS_Contract_Invoice_Line_Item_Breakdown__c:{Break_Down_Type__c=Minimum Commit, Invoice_Period_From__c=2014-11-30 00:00:00, CurrencyIsoCode=GBP, Band_Quantity__c=1.00, Customer_Allowance__c=0.00, Invoice_Date__c=2014-11-30 00:00:00, Line_Item_Quantity__c=1.00, BillingDate__c=2014-11-01 00:00:00, Invoice_Period_To__c=2015-02-28 00:00:00, Start_Quantity__c=0.00, Unit_Sell_Price__c=4533.72, End_Quantity__c=1.00, Billing_Term__c=Quarterly In Advance, Committed__c=false, Id=a1jD0000001YZxfIAG, MCS_Contract_Invoice_Line_Item__c=a1iD0000001F4kHIAS, Unbilled_Usage__c=0, Banding_Total__c=13601.1600}, MCS_Contract_Invoice_Line_Item_Breakdown__c:{Break_Down_Type__c=Flexible, Invoice_Period_From__c=2014-10-30 00:00:00, CurrencyIsoCode=GBP, Band_Quantity__c=0.00, Customer_Allowance__c=0.00, Invoice_Date__c=2014-11-30 00:00:00, Line_Item_Quantity__c=0.00, BillingDate__c=2014-11-01 00:00:00, Invoice_Period_To__c=2014-11-30 00:00:00, Start_Quantity__c=0.00, Unit_Sell_Price__c=19.53, End_Quantity__c=0.00, Billing_Term__c=Monthly In Arrears, Committed__c=false, Id=a1jD0000001YZxgIAG, MCS_Contract_Invoice_Line_Item__c=a1iD0000001F4kIIAS, Unbilled_Usage__c=0, Banding_Total__c=0.0000}, MCS_Contract_Invoice_Line_Item_Breakdown__c:{Break_Down_Type__c=Minimum Commit, Invoice_Period_From__c=2014-10-30 00:00:00, CurrencyIsoCode=GBP, Band_Quantity__c=16.00, Customer_Allowance__c=0.00, Invoice_Date__c=2014-11-30 00:00:00, Line_Item_Quantity__c=16.00, BillingDate__c=2014-11-01 00:00:00, Invoice_Period_To__c=2014-11-30 00:00:00, Start_Quantity__c=0.00, Unit_Sell_Price__c=17.28, End_Quantity__c=16.00, Billing_Term__c=Monthly In Arrears, Committed__c=false, Id=a1jD0000001YZxhIAG, MCS_Contract_Invoice_Line_Item__c=a1iD0000001F4kJIAS, Unbilled_Usage__c=0, Banding_Total__c=276.4800}, MCS_Contract_Invoice_Line_Item_Breakdown__c:{Break_Down_Type__c=Minimum Commit, Invoice_Period_From__c=2014-10-30 00:00:00, CurrencyIsoCode=GBP, Band_Quantity__c=5.00, Customer_Allowance__c=0.00, Invoice_Date__c=2014-11-30 00:00:00, Line_Item_Quantity__c=5.00, BillingDate__c=2014-11-01 00:00:00, Invoice_Period_To__c=2014-11-30 00:00:00, Start_Quantity__c=0.00, Unit_Sell_Price__c=13.64, End_Quantity__c=5.00, Billing_Term__c=Monthly In Arrears, Committed__c=false, Id=a1jD0000001YZxiIAG, MCS_Contract_Invoice_Line_Item__c=a1iD0000001F4kKIAS, Unbilled_Usage__c=0, Banding_Total__c=68.2000}, MCS_Contract_Invoice_Line_Item_Breakdown__c:{Break_Down_Type__c=Minimum Commit, Invoice_Period_From__c=2014-10-30 00:00:00, CurrencyIsoCode=GBP, Band_Quantity__c=16.00, Customer_Allowance__c=0.00, Invoice_Date__c=2014-11-30 00:00:00, Line_Item_Quantity__c=16.00, BillingDate__c=2014-11-01 00:00:00, Invoice_Period_To__c=2014-11-30 00:00:00, Start_Quantity__c=0.00, Unit_Sell_Price__c=17.28, End_Quantity__c=16.00, Billing_Term__c=Monthly In Arrears, Committed__c=false, Id=a1jD0000001YZxjIAG, MCS_Contract_Invoice_Line_Item__c=a1iD0000001F4kLIAS, Unbilled_Usage__c=0, Banding_Total__c=276.4800}, MCS_Contract_Invoice_Line_Item_Breakdown__c:{Break_Down_Type__c=Minimum Commit, Invoice_Period_From__c=2014-10-30 00:00:00, CurrencyIsoCode=GBP, Band_Quantity__c=4.00, Customer_Allowance__c=0.00, Invoice_Date__c=2014-11-30 00:00:00, Line_Item_Quantity__c=4.00, BillingDate__c=2014-11-01 00:00:00, Invoice_Period_To__c=2014-11-30 00:00:00, Start_Quantity__c=0.00, Unit_Sell_Price__c=252.03, End_Quantity__c=4.00, Billing_Term__c=Monthly In Arrears, Committed__c=false, Id=a1jD0000001YZxkIAG, MCS_Contract_Invoice_Line_Item__c=a1iD0000001F4kMIAS, Unbilled_Usage__c=0, Banding_Total__c=1008.1200}, MCS_Contract_Invoice_Line_Item_Breakdown__c:{Break_Down_Type__c=Minimum Commit, Invoice_Period_From__c=2014-10-30 00:00:00, CurrencyIsoCode=GBP, Band_Quantity__c=5.00, Customer_Allowance__c=0.00, Invoice_Date__c=2014-11-30 00:00:00, Line_Item_Quantity__c=5.00, BillingDate__c=2014-11-01 00:00:00, Invoice_Period_To__c=2014-11-30 00:00:00, Start_Quantity__c=0.00, Unit_Sell_Price__c=13.64, End_Quantity__c=5.00, Billing_Term__c=Monthly In Arrears, Committed__c=false, Id=a1jD0000001YZxlIAG, MCS_Contract_Invoice_Line_Item__c=a1iD0000001F4kNIAS, Unbilled_Usage__c=0, Banding_Total__c=68.2000}, MCS_Contract_Invoice_Line_Item_Breakdown__c:{Break_Down_Type__c=Minimum Commit, Invoice_Period_From__c=2014-10-30 00:00:00, CurrencyIsoCode=GBP, Band_Quantity__c=21.00, Customer_Allowance__c=0.00, Invoice_Date__c=2014-11-30 00:00:00, Line_Item_Quantity__c=21.00, BillingDate__c=2014-11-01 00:00:00, Invoice_Period_To__c=2014-11-30 00:00:00, Start_Quantity__c=0.00, Unit_Sell_Price__c=10.00, End_Quantity__c=21.00, Billing_Term__c=Monthly In Arrears, Committed__c=false, Id=a1jD0000001YZxmIAG, MCS_Contract_Invoice_Line_Item__c=a1iD0000001F4kOIAS, Unbilled_Usage__c=0, Banding_Total__c=210.0000}, MCS_Contract_Invoice_Line_Item_Breakdown__c:{Break_Down_Type__c=Flexible, Invoice_Period_From__c=2014-10-30 00:00:00, CurrencyIsoCode=GBP, Band_Quantity__c=0.00, Customer_Allowance__c=0.00, Invoice_Date__c=2014-11-30 00:00:00, Line_Item_Quantity__c=21.00, BillingDate__c=2014-11-01 00:00:00, Invoice_Period_To__c=2014-11-30 00:00:00, Start_Quantity__c=21.00, Unit_Sell_Price__c=10.00, End_Quantity__c=0.00, Billing_Term__c=Monthly In Arrears, Committed__c=false, Id=a1jD0000001YZxnIAG, MCS_Contract_Invoice_Line_Item__c=a1iD0000001F4kOIAS, Unbilled_Usage__c=0, Banding_Total__c=0.0000}, ...)

this is whats in the debug
Micky MMicky M
Slight update, ive just put a debug right after the if(staticFlagsForRecursionTriggers.firstRun) and it doesnt look as thought its getting through this condition, does this work differently if we are using a vf page call the controller?
Micky MMicky M
And even more of an update ive worked out its the staticflag thats causing the issue it doesnt seem to get set up when i call the methods from a VF page, has anyone any idea how i can get that flag to work? thanks.