• Jamal Arogundade
  • NEWBIE
  • 0 Points
  • Member since 2019

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 6
    Questions
  • 4
    Replies
The current code coverage is 25% 

BATCH CLASS

global class SendMembershipRenewalEmail30Days implements Database.Batchable<SObject>, schedulable {
    
    public Database.QueryLocator start(Database.BatchableContext bc){
        
        Date oneMonthFromToday  = Date.today().addDays(30); // Date 30 days from today
        return Database.getQueryLocator([select id, name, Organisation__r.npe01__one2onecontact__r.Email,regular_payment__c  FROM Membership__c WHERE Expiry_Date__c =: oneMonthFromToday and (regular_payment__r.npsp4hub__Payment_Method__c = 'cash' or regular_payment__r.npsp4hub__Payment_Method__c = 'Direct Debit' )]);
    }
    
    public void execute(Database.BatchableContext bc, list<Membership__c> scope){
        
        list <EmailTemplate> templateIds = new list <EmailTemplate> ([Select id from EmailTemplate where (name = 'Organisation Membership Renewals Direct Debit' OR name = 'Organisation Membership Renewals Not Direct Debit') ORDER BY name asc]);
        for(membership__c ta : (List<membership__c>)scope) {
            Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
            email.setToAddresses(new String[] {ta.Organisation__r.npe01__one2onecontact__r.Email});
            email.setSaveAsActivity(false);
            email.setTargetObjectId(ta.OwnerId);
            email.setTemplateId(ta.regular_payment__c == null ? templateIds[1].id : templateIds[0].id);
            email.setWhatId(ta.Id);
            Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
        }
    }
    
    public void finish(Database.BatchableContext bc){
        
        
    }
    
    global void execute(SchedulableContext SC) {
        database.executebatch(new SendMembershipRenewalEmail30Days());
    }
}


TEST CLASS 

@isTest(seeAllData = false)
private class Test_SendMembershipRenewalEmail30Days {
    
    static testMethod void unitTest_SendMembershipRenewalEmail30Days()
    {
        Test.startTest();
        Account acc = new Account(name ='test name');
        insert acc;
        
        Contact cont = new Contact();
        cont.FirstName ='Test';
        cont.LastName ='Test';
        cont.email ='Test@Test.com';
        cont.accountid = acc.id;
        insert cont;
        
        Id oppRecordTypeId = Schema.SObjectType.Opportunity.getRecordTypeInfosByName().get('Membership').getRecordTypeId();
        Opportunity opp = new Opportunity();
        opp.amount = 10.00;
        opp.Name = 'test name';
        opp.StageName = 'Closed Won';
        opp.RecordTypeId = oppRecordTypeId;
        opp.CloseDate = date.today();
        insert opp;
        
        
        
        
        
        SendMembershipRenewalEmail30Days obj = new SendMembershipRenewalEmail30Days();
        Database.executeBatch(obj);
        Test.stopTest();
        
    }
    
    
    
}
I would like to know how i can turn off lightning sync so that i can enable Einstein activity centre.

Thanks
// Query Opportunities where Stage is pledged , The SOQL will have Recurring Donation ID as well in WHERE condition
            // run a loop on List of Opps reterived in step 1
            // Create Allocation for each opp, Allocation you have created, should be added to a new list of type Allocation__c
            // Insert Allocation lIts


List<Opportunity> oppList = [SELECT ID FROM Opportunity WHERE StageName = 'pledged'];
            for (Opportunity opps: oppList){
                Allocation__c alls = new Allocation__c ();
                alls.Opportunity__c = opps.id;
            }
            insert oppList;
        }
Class.testUtility.test_get_membership_amount: line 89, column 1
System.AssertException: Assertion Failed


UtilityTest class

@isTest(SeeAllData=false)
private class testUtility {
    @isTest static void testDateUtility(){
    Date d1 = System.today();
    Date d2 = d1.addDays(10);
    Date d3 = null;
    system.assert(RamblersUtility.maxdate(d1, d2) == d2);
    system.assert(RamblersUtility.maxdate(d1, d3) == d1);
    system.assert(RamblersUtility.maxdate(d3, d2) == d2);
    system.assert(RamblersUtility.maxdate(d3, d3) == NULL);
    system.assert(RamblersUtility.maxdate(d2, d1) == d2);
    }
    
    @isTest static void testDecimalUtility(){
        Decimal dec1 = 1.0;
        Decimal dec2 = 2.0;
        Decimal dec3 = null;
        system.assert(RamblersUtility.maxDecimal(dec1, dec2) == dec2);
        system.assert(RamblersUtility.maxDecimal(dec1, dec3) == dec1);
        system.assert(RamblersUtility.maxDecimal(dec3, dec2) == dec2);
        system.assert(RamblersUtility.maxDecimal(dec3, dec3) == NULL);
        system.assert(RamblersUtility.maxDecimal(dec2, dec1) == dec2);
    }
    
    @istest
    static void test_get_renewal_lookup(){
        // First create a membership_amount__C
        List<npsp__Trigger_Handler__c> triggerHandlers = npsp.TDTM_Config_API.getCachedRecords(); 
        // Add our Trigger Handler to cached Trigger Handlers
        npsp__Trigger_Handler__c th = new npsp__Trigger_Handler__c();
        th.Name = 'Select_Membership_TDTM';
        th.npsp__class__c = 'Select_Membership_TDTM';
        th.npsp__Object__c = 'npe03__Recurring_Donation__c';
        th.npsp__trigger_action__c = 'BeforeInsert,BeforeUpdate';
        th.npsp__Active__c=True;
        th.npsp__load_order__c=0; 
        th.npsp__Asynchronous__c=False;
        triggerHandlers.add(th);
        membership_amount__c mem_amt = new Membership_Amount__c(Name = 'Select Membership', Start_date__c = Date.today().addDays(-45) , End_date__c = Date.today().addDays(50));
        insert mem_amt;
        system.test.startTest();
        system.test.stopTest();
        List<Membership_Amount_Line__c> ma_line_item_no_dates = ramblersutility.get_renewal_lookup(NULL, NULL);
        List<Membership_Amount_Line__c> ma_line_item_with_dates = ramblersutility.get_renewal_lookup(date.today().addDays(-1), date.today().addDays(1));
        system.assert(ma_line_item_no_dates.size()==23);
        system.assert(ma_line_item_with_dates.size()==23);
    }

    @istest
    static void test_get_membership_amount(){
        List<npsp__Trigger_Handler__c> th = npsp.TDTM_Config_API.getCachedRecords(); 
        // Add our Trigger Handler to cached Trigger Handlers
        th.add(new npsp__Trigger_Handler__c(Name='Select_Membership_TDTM', npsp__class__c='Select_Membership_TDTM', npsp__Object__c='npe03__Recurring_Donation__c', npsp__trigger_action__c='BeforeInsert,BeforeUpdate', npsp__Active__c=True, npsp__load_order__c=0, npsp__Asynchronous__c=False));
        Membership_Amount__c mem_amt = new membership_amount__c(name='Select membership', Start_date__c = Date.today().addDays(-45) , End_date__c = Date.today().addDays(50));
        insert mem_amt;
        List<Membership_Amount_Line__c> mas = RamblersUtility.get_renewal_lookup(date.today(), date.today());
        for (Membership_Amount_Line__c ma : mas){
            // We need to update this amount
            switch on string.valueof(ma.Concessionary__c) + ma.Payment_Method__c + ma.Payment_Frequency__c + ma.Membership_Type__c{ // TODO: replace the lookup to a composit key
                when 'trueDirect DebitMonthlyIndividual'{ma.amount__c = 1.0 * 12;}
                when 'trueOtherMonthlyIndividual'{ma.amount__c = 2.0 * 12;}
                when 'trueDirect DebitAnnualIndividual'{ma.amount__c = 3.0;}
                when 'trueOtherAnnualIndividual'{ma.amount__c = 4.0;}
                when 'falseDirect DebitMonthlyIndividual'{ma.amount__c = 5.0 * 12;}
                when 'falseOtherMonthlyIndividual'{ma.amount__c = 6.0 * 12;}
                when 'falseDirect DebitAnnualIndividual'{ma.amount__c = 7.0;}
                when 'falseOtherAnnualIndividual'{ma.amount__c = 8.0;}
                when 'trueDirect DebitMonthlyJoint'{ma.amount__c = 9.0 * 12;} 
                when 'trueOtherMonthlyJoint'{ma.amount__c = 10.0 * 12;}
                when 'trueDirect DebitAnnualJoint'{ma.amount__c = 11.0;}
                when 'trueOtherAnnualJoint'{ma.amount__c = 12.0;}
                when 'falseDirect DebitMonthlyJoint'{ma.amount__c = 13.0 * 12;}
                when 'falseOtherMonthlyJoint'{ma.amount__c = 14.0 * 12;}
                when 'falseDirect DebitAnnualJoint'{ma.amount__c = 15.0;}
                when 'falseOtherAnnualJoint'{ma.amount__c = 16.0;}
                when 'trueOtherAnnualLife'{ma.amount__c = 17.0;}
                when 'falseOtherAnnualLife'{ma.amount__c = 18.0;}
                when 'trueOtherAnnualLife Joint'{ma.amount__c = 19.0;}
                when 'falseOtherAnnualLife Joint'{ma.amount__c = 20.0;}
                when 'falseOtherAnnualArea affiliate'{ma.amount__c = 21.0;}
                when 'falseOtherAnnualNational affiliate'{ma.amount__c = 22.0;}
                when 'falseOtherAnnualCorporate'{ma.amount__c = 23.0;}
                when else {ma.amount__c = 500;}
            }
        }
        system.test.startTest();
        system.test.stoptest();
           system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Monthly', 'Individual', 'Standard', 'Direct debit', NULL, NULL)==1.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Monthly', 'Individual', 'Standard', 'Other', NULL, NULL)==2.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Annual', 'Individual', 'Standard', 'Direct debit', NULL, NULL)==3.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Annual', 'Individual', 'Standard', 'Other', NULL, NULL)==4.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Monthly', 'Individual', 'Standard', 'Direct debit', NULL, NULL)==5.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Monthly', 'Individual', 'Standard', 'Other', NULL, NULL)==6.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Individual', 'Standard', 'Direct debit', NULL, NULL)==7.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Individual', 'Standard', 'Other', NULL, NULL)==8.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Monthly', 'Joint', 'Standard', 'Direct debit', NULL, NULL)==9.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Monthly', 'Joint', 'Standard', 'Other', NULL, NULL)==10.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Annual', 'Joint', 'Standard', 'Direct debit', NULL, NULL)==11.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Annual', 'Joint', 'Standard', 'Other', NULL, NULL)==12.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Monthly', 'Joint', 'Standard', 'Direct debit', NULL, NULL)==13.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Monthly', 'Joint', 'Standard', 'Other', NULL, NULL)==14.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Joint', 'Standard', 'Direct debit', NULL, NULL)==15.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Joint', 'Standard', 'Other', NULL, NULL)==16.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Annual', 'Individual', 'Life', 'Other', NULL, NULL)==17.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Individual', 'Life', 'Other', NULL, NULL)==18.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Annual', 'Joint', 'Life', 'Other', NULL, NULL)==19.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Joint', 'Life', 'Other', NULL, NULL)==20.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Area affiliate', 'Organisation', 'Other', NULL, NULL)==21.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'National affiliate', 'Organisation', 'Other', NULL, NULL)==22.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Corporate', 'Organisation', 'Other', NULL, NULL)==23.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Monthly', 'Joint', 'Standard', 'Other', 100, NULL)==0.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Monthly', 'Joint', 'Standard', 'Other', NULL, 120.0)==0.0);
    }

    @istest
    static void test_installments_per_year(){
        map<string, integer> test_map = new map<string, integer>{'Yearly' => 1, 'Quarterly' => 4, 'Monthly' => 12, 'default' => 1};
        for (string s : test_map.keySet()){
            system.assert(ramblersutility.installments_per_year(s) == test_map.get(s));
        }
    }
}

Renewal Job

 
Batch job class:
public class Renewal_job implements Database.Batchable<SObject> {
    //public Renewal_job() {
    
    //}
    public Database.QueryLocator start(Database.BatchableContext bc){
        // TODO: the query below to only extract the memberships that we need to work on
        
        return Database.getQueryLocator([select id, name, membership_status__c, recordtype.name, regular_payment__c, member_1__c, expiry_date__c, consessionary__c, Discount__c, Next_Renewal_Date__c from membership__c where (Next_Renewal_Date__c <= TODAY  or expiry_date__c <= TODAY )and successor_membership__c = NULL]); // TODO: Add extra filters
    }
    
    public void execute(Database.BatchableContext bc, list<membership__c> scope){
        id renewal_opp_record_type = Schema.SObjectType.Opportunity.getRecordTypeInfosByName().get('Membership').getRecordTypeId();
        id renewal_camp_record_type = Schema.SObjectType.Campaign.getRecordTypeInfosByName().get('Renewal').getRecordTypeId();
        campaign renewal_campaign = [select id, name, StartDate,EndDate from campaign where recordtype.name = 'Renewal' and startdate <= TODAY  and enddate >= TODAY Order by startdate asc limit 1]; // TODO: Sort out this query
        if (renewal_campaign.id == NULL){
            // TODO: Add consent statement - Fix name. Not sure what else to be honest 
            Consent_statement__c consent_statement = new Consent_statement__c(name = 'Consent', Used_from__c = date.today(), Valid_consent_statement__c = TRUE, Consent_statement_text__c = 'Read' );
            insert consent_statement;
            renewal_campaign = new campaign(name='Renewals ' + string.valueof(date.today().month()) + ' ' + string.valueof(date.today().year()), recordtypeid=renewal_camp_record_type, startdate=date.today(), enddate=date.today().addMonths(1), isactive=True, Status='In progress');
            insert renewal_campaign;
            // TODO: Add a task to finish updating records assign to membership team queue?
            Group g = [Select Id from Group where Type = 'Task' AND NAME = 'Membership Team Queue'];
            //QueueSobject mappingObject = new QueueSobject(QueueId = g.Id, SobjectType = 'Membership__c');
            //insert mappingObject;
            ID qID = g.ID;      
            Task t = new Task();
            t.Subject = 'Other';
            t.Priority = 'Normal';
            t.Status = 'Not Started';
            t.OwnerId = qID;
            insert t;  
        }
        set<id> current_renewal_opps_ids = new set<id>();
        for (membership__c mem : scope){
           
            if (mem.Next_Payment__c != NULL){
                current_renewal_opps_ids.add(mem.Next_Payment__c);
            }
        }
        List<Membership_Amount_Line__c> mal = ramblersUtility.get_renewal_lookup(NULL, NULL);
        list<membership__c> mems_to_update = new list<membership__c>();
        list<CampaignMember> add_campaign_members = new list<campaignMember>();
        list<opportunity> opps_to_add = new List<Opportunity>();
        list<opportunity> opps_to_update = new List<Opportunity>();
        map<id, opportunity> existing_renewal_opps = new map<id, Opportunity>([select id, stagename, name, linked_membership__c from Opportunity where linked_membership__c = :current_renewal_opps_ids]);
        for (sobject s_mem : scope){
            membership__c mem = (membership__c)s_mem;
            decimal rebate_percentage = NULL;
            decimal rebate_cash = NULL;
            if (mem.Discount__r.Discount_renews__c){
                rebate_percentage = mem.discount__r.Discount_percentage__c;
                rebate_cash = mem.discount__r.Discount_amount__c;
            } else {
                mem.Discount__c = NULL; // If the rebate does not renew clear it from the membership.
            }
            
            
            if(Date.today() >= mem.Expiry_Date__c){
                // Update status for lapsed/inactive - I think we should update the name as well
                if (date.today().addMonths(-3) <= mem.Expiry_Date__c){
                    mem.Membership_Status__c = 'Payment pending';
                } else if (date.today().addMonths(-15) <= mem.Expiry_Date__c){
                    mem.Membership_Status__c = 'Lapsed';
                    if (!mem.Next_Payment__r.IsClosed){
                        // Close off the opportunity
                        existing_renewal_opps.get(mem.Next_Payment__c).StageName = 'Closed Lost';
                        opps_to_update.add(existing_renewal_opps.get(mem.next_payment__c));
                    }
                } else {
                    mem.Membership_Status__c = 'Inactive';
                }
                mems_to_update.add(mem);
            } else if (mem.Next_Renewal_Date__c <= Date.today()){
                // These records need to be renewed add them to the renewal campaign
                if (mem.recordtype.name == 'Life'){
                    // They are a life member - Add to campaign with correct status (essentially new card only)
                    // add_campaign_members.add(new CampaignMember(CampaignId=renewal_campaign, ContactId=mem.Member_1__c, Status='To Renew', ));
                }
                if (mem.regular_payment__c != NULL){
                    // Calculate membership amount. If it is 0 then we just add them with a new card
                    if (ramblersutility.get_membership_amount(mal, mem.Expiry_Date__c, mem.consessionary__c, mem.Regular_Payment__r.npe03__Installment_Period__c, mem.membership_type__c, mem.recordtype.name, mem.regular_payment__r.npsp4hub__Payment_Method__c, rebate_percentage, rebate_cash) == 0){
                        // Just send them a new card
                        //add_campaign_members.add(new CampaignMember());
                    } else {
                        // Send them details of new direct debit amount. No need to update the amount just yet. Need to wait until there are no further payments before the expiry date before we change the pricing
                        //add_campaign_members.add(new CampaignMember());
                    }
                } else {
                    // We need to create and insert the renewal opportunity
                    opps_to_add.add(new Opportunity(name='s', CloseDate=mem.Expiry_Date__c, Membership_Amount__c=ramblersutility.get_membership_amount(mal, mem.Expiry_Date__c, mem.consessionary__c, 'Annual', mem.Membership_Type__c, mem.recordtype.name, 'Cash', rebate_percentage, rebate_cash), accountid=mem.Member_1__r.AccountId, npsp__Primary_Contact__c=mem.member_1__c, StageName='Pledged', Discount__c = mem.Discount__c)); // TODO: Decide what stage this should be at
                    //add_campaign_members.add(new CampaignMember());
                }
                try{
                    mem.Next_Renewal_Date__c = mem.Next_Renewal_Date__c.addYears(1); // Update the renewal date
                } catch(Exception e){
                    mem.Next_Renewal_Date__c = mem.Next_Renewal_Date__c.adddays(365); // Inserted to account for leap years - I don't think it is absolutely necessary, but we may as well put it in
                }
                mems_to_update.add(mem);
            } else {
                // I don't think we need to do anything - But leave in place in case we do
            }
        }
        insert opps_to_add;
        update opps_to_update;
        set<id> opp_ids = new set<id>();
        for (opportunity o : opps_to_add){
            opp_ids.add(o.id);
        }
        List<Opportunity> opps = [select id, name, linked_membership__c from Opportunity where id =: opp_ids];
        insert add_campaign_members;
        // Now loop back through and back fill any links to new opportunities
        for (membership__c mem : mems_to_update){
            //membership__c mem = (membership__c)s_mem;
            if (mem.Next_Renewal_Date__c <= Date.today() && Date.today() < mem.Expiry_Date__c && mem.recordtype.name != 'Life' && mem.Regular_Payment__c == NULL){
                for (Opportunity o : opps){
                    if (o.linked_membership__c == mem.id){
                        mem.Next_Payment__c = o.id;
                        break;
                    }
                }
            }
            
        }
        update mems_to_update;
    }
    
    public void finish(Database.BatchableContext bc){
        system.debug('Completed Renewals');
        // TODO: add notifications 
        // Get the ID of the AsyncApexJob representing this batch job
        // from Database.BatchableContext.
        // Query the AsyncApexJob object to retrieve the current job's information.
       List<Group> GroupId =  [Select Id from Group where type='Queue' and Name='Membership Team Queue'];
       list<GroupMember> userIdList = [Select UserOrGroupId From GroupMember where GroupId =:GroupId];
        Set<ID> useridset = new Set<ID>();
        for (GroupMember gm : userIdList ){
           useridset.add(gm.UserOrGroupId);
        }
        
        list<User> user = [SELECT Id, Email FROM USER WHERE ID IN: useridset];
        List<String> emaillist = new List<String>();
        for (User u : user){
            emaillist.add(u.Email);
        }
        
        AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
                          TotalJobItems, CreatedBy.Email
                          FROM AsyncApexJob WHERE Id =
                          :BC.getJobId()];
        // Send an email to the Apex job's submitter notifying of job completion.
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {a.CreatedBy.Email};
            toAddresses.addAll(emaillist);
            mail.setToAddresses(toAddresses);
        mail.setSubject('Batch job status ' + a.Status);
        mail.setPlainTextBody
            ('The batch Apex job processed ' + a.TotalJobItems +
             ' batches with '+ a.NumberOfErrors + ' failures.');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
        
        
    }
}



Batch Test class:

@isTest
private class RenewalJobBatchTest {
    static testMethod void RenewalBatchTestMethod(){
        // Just in case pull trigger handlers for npsp triggers
        List<npsp__Trigger_Handler__c> triggerHandlers = npsp.TDTM_Config_API.getCachedRecords();
        //set up test data
        list<Contact> con = new list<Contact>();
        for (Integer i = 0; i < 20; i++){
            con.add(new Contact(lastName = 'test lastname ' + string.valueof(i), MailingStreet = 'test mailingstreet'));
        }
        insert con;
        list <npe03__Recurring_Donation__c> rc = new list <npe03__Recurring_Donation__c> ();
        for (Integer i = 0; i < 20; i ++){
            rc.add(new npe03__Recurring_Donation__c (npe03__Contact__c = con[0].id, npsp4hub__Payment_Method__c = 'Direct Debit', npe03__Installment_Period__c = 'Monthly', Top_up_Amount__c = 10, npe03__Open_Ended_Status__c = 'Open', npe03__Date_Established__c = date.today()) );
        }
        
        insert rc;
        Membership_Amount__c ma = new Membership_Amount__c(Name = 'Select Membership', Start_date__c = Date.today().addDays(-45) , End_date__c = Date.today().addDays(50) );
        insert ma;
        List<Membership_Amount_Line__c> malineitem = [SELECT id, Amount__c FROM Membership_Amount_Line__c WHERE Membership_Amount__c =: ma.Id];
        Decimal dec = 1.0;
        for (Membership_Amount_Line__c lineitem : malineitem){
            lineitem.Amount__c = dec;
            dec += 2.1;
        }
        
        update malineitem;
        list <Opportunity> opps = new list<Opportunity>();
        for (Integer i = 0; i < 20; i++){
            opps.add(new Opportunity(Amount = 10.00, Name = 'test name', stageName = 'Closed Won', CloseDate = date.today()));
        }
        insert opps;
        
        Discount__c discount_hundred = new Discount__c (name = '100% discount', Discount_percentage__c = 100, Discount_renews__c = TRUE);
        insert discount_hundred;
        system.debug('line 36');
        id life_membership_type = Schema.SObjectType.Membership__c.getRecordTypeInfosByName().get('Life Membership').getRecordTypeId();
        
        list<Membership__c> membership = new list<Membership__c> ();
        membership.add(new Membership__c(Member_1__c = con[0].id , Membership_Status__c = 'Active', Membership_type__c = 'Individual', Start_Date__c = Date.today(), Next_Renewal_Date__c = date.today().addMonths(-11), regular_payment__c = rc[0].id, consessionary__c = TRUE, expiry_date__c = Date.valueOf('2020-07-29')));
        membership.add(new Membership__c(Member_1__c = con[1].id , Membership_Status__c = 'Active', Membership_type__c = 'Individual', Start_Date__c = Date.today(), Next_Renewal_Date__c = date.today().addMonths(-11), Next_Payment__c = opps[0].id,regular_payment__c = null, consessionary__c = TRUE, expiry_date__c = Date.today().addMonths(-15)));
        membership.add(new Membership__c(Member_1__c = con[2].id , Membership_Status__c = 'Active', Membership_type__c = 'Individual', Start_Date__c = Date.today(), Next_Renewal_Date__c = date.today().addMonths(-11), regular_payment__c = rc[1].id, consessionary__c = TRUE, expiry_date__c = Date.today().addYears(-5)));
        membership.add(new Membership__c(Member_1__c = con[3].id , Membership_Status__c = 'Active', Membership_type__c = 'Individual', Start_Date__c = Date.today(), Next_Renewal_Date__c = date.today().addMonths(-11), regular_payment__c = null, consessionary__c = TRUE, expiry_date__c = null, last_payment__c = opps[1].id, RecordTypeId = life_membership_type));
        membership.add(new Membership__c(Member_1__c = con[4].id , Membership_Status__c = 'Active', Membership_type__c = 'Individual', Start_Date__c = Date.today(), Next_Renewal_Date__c = date.today().addMonths(-11), regular_payment__c = rc[2].id, consessionary__c = TRUE, expiry_date__c = date.today().addmonths(2), last_payment__c = null, Discount__c = discount_hundred.id));
        membership.add(new Membership__c(Member_1__c = con[5].id , Membership_Status__c = 'Active', Membership_type__c = 'Individual', Start_Date__c = Date.today(), Next_Renewal_Date__c = date.today().addMonths(-11), regular_payment__c = rc[3].id, consessionary__c = TRUE, expiry_date__c = date.today().addmonths(2), last_payment__c = null));
        membership.add(new Membership__c(Member_1__c = con[6].id , Membership_Status__c = 'Active', Membership_type__c = 'Individual', Start_Date__c = Date.today(), Next_Renewal_Date__c = date.today().addMonths(-11), regular_payment__c = rc[4].id, consessionary__c = TRUE, expiry_date__c = date.today().addmonths(2), last_payment__c = opps[1].id));
        
        insert membership;
        
        Test.startTest();
        Renewal_job ren = new Renewal_job();
        Database.executeBatch(ren);
           list<campaign> all_camps = [select id from campaign where recordtype.name = 'Renewal'];
           system.debug(all_camps.size());
        //system.assert(all_camps.size() == 1); // TODO: Get data and run tests.
        Test.stopTest();
        
    }
}
// Query Opportunities where Stage is pledged , The SOQL will have Recurring Donation ID as well in WHERE condition
            // run a loop on List of Opps reterived in step 1
            // Create Allocation for each opp, Allocation you have created, should be added to a new list of type Allocation__c
            // Insert Allocation lIts


List<Opportunity> oppList = [SELECT ID FROM Opportunity WHERE StageName = 'pledged'];
            for (Opportunity opps: oppList){
                Allocation__c alls = new Allocation__c ();
                alls.Opportunity__c = opps.id;
            }
            insert oppList;
        }
Class.testUtility.test_get_membership_amount: line 89, column 1
System.AssertException: Assertion Failed


UtilityTest class

@isTest(SeeAllData=false)
private class testUtility {
    @isTest static void testDateUtility(){
    Date d1 = System.today();
    Date d2 = d1.addDays(10);
    Date d3 = null;
    system.assert(RamblersUtility.maxdate(d1, d2) == d2);
    system.assert(RamblersUtility.maxdate(d1, d3) == d1);
    system.assert(RamblersUtility.maxdate(d3, d2) == d2);
    system.assert(RamblersUtility.maxdate(d3, d3) == NULL);
    system.assert(RamblersUtility.maxdate(d2, d1) == d2);
    }
    
    @isTest static void testDecimalUtility(){
        Decimal dec1 = 1.0;
        Decimal dec2 = 2.0;
        Decimal dec3 = null;
        system.assert(RamblersUtility.maxDecimal(dec1, dec2) == dec2);
        system.assert(RamblersUtility.maxDecimal(dec1, dec3) == dec1);
        system.assert(RamblersUtility.maxDecimal(dec3, dec2) == dec2);
        system.assert(RamblersUtility.maxDecimal(dec3, dec3) == NULL);
        system.assert(RamblersUtility.maxDecimal(dec2, dec1) == dec2);
    }
    
    @istest
    static void test_get_renewal_lookup(){
        // First create a membership_amount__C
        List<npsp__Trigger_Handler__c> triggerHandlers = npsp.TDTM_Config_API.getCachedRecords(); 
        // Add our Trigger Handler to cached Trigger Handlers
        npsp__Trigger_Handler__c th = new npsp__Trigger_Handler__c();
        th.Name = 'Select_Membership_TDTM';
        th.npsp__class__c = 'Select_Membership_TDTM';
        th.npsp__Object__c = 'npe03__Recurring_Donation__c';
        th.npsp__trigger_action__c = 'BeforeInsert,BeforeUpdate';
        th.npsp__Active__c=True;
        th.npsp__load_order__c=0; 
        th.npsp__Asynchronous__c=False;
        triggerHandlers.add(th);
        membership_amount__c mem_amt = new Membership_Amount__c(Name = 'Select Membership', Start_date__c = Date.today().addDays(-45) , End_date__c = Date.today().addDays(50));
        insert mem_amt;
        system.test.startTest();
        system.test.stopTest();
        List<Membership_Amount_Line__c> ma_line_item_no_dates = ramblersutility.get_renewal_lookup(NULL, NULL);
        List<Membership_Amount_Line__c> ma_line_item_with_dates = ramblersutility.get_renewal_lookup(date.today().addDays(-1), date.today().addDays(1));
        system.assert(ma_line_item_no_dates.size()==23);
        system.assert(ma_line_item_with_dates.size()==23);
    }

    @istest
    static void test_get_membership_amount(){
        List<npsp__Trigger_Handler__c> th = npsp.TDTM_Config_API.getCachedRecords(); 
        // Add our Trigger Handler to cached Trigger Handlers
        th.add(new npsp__Trigger_Handler__c(Name='Select_Membership_TDTM', npsp__class__c='Select_Membership_TDTM', npsp__Object__c='npe03__Recurring_Donation__c', npsp__trigger_action__c='BeforeInsert,BeforeUpdate', npsp__Active__c=True, npsp__load_order__c=0, npsp__Asynchronous__c=False));
        Membership_Amount__c mem_amt = new membership_amount__c(name='Select membership', Start_date__c = Date.today().addDays(-45) , End_date__c = Date.today().addDays(50));
        insert mem_amt;
        List<Membership_Amount_Line__c> mas = RamblersUtility.get_renewal_lookup(date.today(), date.today());
        for (Membership_Amount_Line__c ma : mas){
            // We need to update this amount
            switch on string.valueof(ma.Concessionary__c) + ma.Payment_Method__c + ma.Payment_Frequency__c + ma.Membership_Type__c{ // TODO: replace the lookup to a composit key
                when 'trueDirect DebitMonthlyIndividual'{ma.amount__c = 1.0 * 12;}
                when 'trueOtherMonthlyIndividual'{ma.amount__c = 2.0 * 12;}
                when 'trueDirect DebitAnnualIndividual'{ma.amount__c = 3.0;}
                when 'trueOtherAnnualIndividual'{ma.amount__c = 4.0;}
                when 'falseDirect DebitMonthlyIndividual'{ma.amount__c = 5.0 * 12;}
                when 'falseOtherMonthlyIndividual'{ma.amount__c = 6.0 * 12;}
                when 'falseDirect DebitAnnualIndividual'{ma.amount__c = 7.0;}
                when 'falseOtherAnnualIndividual'{ma.amount__c = 8.0;}
                when 'trueDirect DebitMonthlyJoint'{ma.amount__c = 9.0 * 12;} 
                when 'trueOtherMonthlyJoint'{ma.amount__c = 10.0 * 12;}
                when 'trueDirect DebitAnnualJoint'{ma.amount__c = 11.0;}
                when 'trueOtherAnnualJoint'{ma.amount__c = 12.0;}
                when 'falseDirect DebitMonthlyJoint'{ma.amount__c = 13.0 * 12;}
                when 'falseOtherMonthlyJoint'{ma.amount__c = 14.0 * 12;}
                when 'falseDirect DebitAnnualJoint'{ma.amount__c = 15.0;}
                when 'falseOtherAnnualJoint'{ma.amount__c = 16.0;}
                when 'trueOtherAnnualLife'{ma.amount__c = 17.0;}
                when 'falseOtherAnnualLife'{ma.amount__c = 18.0;}
                when 'trueOtherAnnualLife Joint'{ma.amount__c = 19.0;}
                when 'falseOtherAnnualLife Joint'{ma.amount__c = 20.0;}
                when 'falseOtherAnnualArea affiliate'{ma.amount__c = 21.0;}
                when 'falseOtherAnnualNational affiliate'{ma.amount__c = 22.0;}
                when 'falseOtherAnnualCorporate'{ma.amount__c = 23.0;}
                when else {ma.amount__c = 500;}
            }
        }
        system.test.startTest();
        system.test.stoptest();
           system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Monthly', 'Individual', 'Standard', 'Direct debit', NULL, NULL)==1.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Monthly', 'Individual', 'Standard', 'Other', NULL, NULL)==2.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Annual', 'Individual', 'Standard', 'Direct debit', NULL, NULL)==3.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Annual', 'Individual', 'Standard', 'Other', NULL, NULL)==4.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Monthly', 'Individual', 'Standard', 'Direct debit', NULL, NULL)==5.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Monthly', 'Individual', 'Standard', 'Other', NULL, NULL)==6.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Individual', 'Standard', 'Direct debit', NULL, NULL)==7.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Individual', 'Standard', 'Other', NULL, NULL)==8.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Monthly', 'Joint', 'Standard', 'Direct debit', NULL, NULL)==9.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Monthly', 'Joint', 'Standard', 'Other', NULL, NULL)==10.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Annual', 'Joint', 'Standard', 'Direct debit', NULL, NULL)==11.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Annual', 'Joint', 'Standard', 'Other', NULL, NULL)==12.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Monthly', 'Joint', 'Standard', 'Direct debit', NULL, NULL)==13.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Monthly', 'Joint', 'Standard', 'Other', NULL, NULL)==14.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Joint', 'Standard', 'Direct debit', NULL, NULL)==15.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Joint', 'Standard', 'Other', NULL, NULL)==16.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Annual', 'Individual', 'Life', 'Other', NULL, NULL)==17.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Individual', 'Life', 'Other', NULL, NULL)==18.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Annual', 'Joint', 'Life', 'Other', NULL, NULL)==19.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Joint', 'Life', 'Other', NULL, NULL)==20.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Area affiliate', 'Organisation', 'Other', NULL, NULL)==21.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'National affiliate', 'Organisation', 'Other', NULL, NULL)==22.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), False, 'Annual', 'Corporate', 'Organisation', 'Other', NULL, NULL)==23.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Monthly', 'Joint', 'Standard', 'Other', 100, NULL)==0.0);
        system.assert(RamblersUtility.get_membership_amount(mas, date.today(), True, 'Monthly', 'Joint', 'Standard', 'Other', NULL, 120.0)==0.0);
    }

    @istest
    static void test_installments_per_year(){
        map<string, integer> test_map = new map<string, integer>{'Yearly' => 1, 'Quarterly' => 4, 'Monthly' => 12, 'default' => 1};
        for (string s : test_map.keySet()){
            system.assert(ramblersutility.installments_per_year(s) == test_map.get(s));
        }
    }
}

Renewal Job

 
Batch job class:
public class Renewal_job implements Database.Batchable<SObject> {
    //public Renewal_job() {
    
    //}
    public Database.QueryLocator start(Database.BatchableContext bc){
        // TODO: the query below to only extract the memberships that we need to work on
        
        return Database.getQueryLocator([select id, name, membership_status__c, recordtype.name, regular_payment__c, member_1__c, expiry_date__c, consessionary__c, Discount__c, Next_Renewal_Date__c from membership__c where (Next_Renewal_Date__c <= TODAY  or expiry_date__c <= TODAY )and successor_membership__c = NULL]); // TODO: Add extra filters
    }
    
    public void execute(Database.BatchableContext bc, list<membership__c> scope){
        id renewal_opp_record_type = Schema.SObjectType.Opportunity.getRecordTypeInfosByName().get('Membership').getRecordTypeId();
        id renewal_camp_record_type = Schema.SObjectType.Campaign.getRecordTypeInfosByName().get('Renewal').getRecordTypeId();
        campaign renewal_campaign = [select id, name, StartDate,EndDate from campaign where recordtype.name = 'Renewal' and startdate <= TODAY  and enddate >= TODAY Order by startdate asc limit 1]; // TODO: Sort out this query
        if (renewal_campaign.id == NULL){
            // TODO: Add consent statement - Fix name. Not sure what else to be honest 
            Consent_statement__c consent_statement = new Consent_statement__c(name = 'Consent', Used_from__c = date.today(), Valid_consent_statement__c = TRUE, Consent_statement_text__c = 'Read' );
            insert consent_statement;
            renewal_campaign = new campaign(name='Renewals ' + string.valueof(date.today().month()) + ' ' + string.valueof(date.today().year()), recordtypeid=renewal_camp_record_type, startdate=date.today(), enddate=date.today().addMonths(1), isactive=True, Status='In progress');
            insert renewal_campaign;
            // TODO: Add a task to finish updating records assign to membership team queue?
            Group g = [Select Id from Group where Type = 'Task' AND NAME = 'Membership Team Queue'];
            //QueueSobject mappingObject = new QueueSobject(QueueId = g.Id, SobjectType = 'Membership__c');
            //insert mappingObject;
            ID qID = g.ID;      
            Task t = new Task();
            t.Subject = 'Other';
            t.Priority = 'Normal';
            t.Status = 'Not Started';
            t.OwnerId = qID;
            insert t;  
        }
        set<id> current_renewal_opps_ids = new set<id>();
        for (membership__c mem : scope){
           
            if (mem.Next_Payment__c != NULL){
                current_renewal_opps_ids.add(mem.Next_Payment__c);
            }
        }
        List<Membership_Amount_Line__c> mal = ramblersUtility.get_renewal_lookup(NULL, NULL);
        list<membership__c> mems_to_update = new list<membership__c>();
        list<CampaignMember> add_campaign_members = new list<campaignMember>();
        list<opportunity> opps_to_add = new List<Opportunity>();
        list<opportunity> opps_to_update = new List<Opportunity>();
        map<id, opportunity> existing_renewal_opps = new map<id, Opportunity>([select id, stagename, name, linked_membership__c from Opportunity where linked_membership__c = :current_renewal_opps_ids]);
        for (sobject s_mem : scope){
            membership__c mem = (membership__c)s_mem;
            decimal rebate_percentage = NULL;
            decimal rebate_cash = NULL;
            if (mem.Discount__r.Discount_renews__c){
                rebate_percentage = mem.discount__r.Discount_percentage__c;
                rebate_cash = mem.discount__r.Discount_amount__c;
            } else {
                mem.Discount__c = NULL; // If the rebate does not renew clear it from the membership.
            }
            
            
            if(Date.today() >= mem.Expiry_Date__c){
                // Update status for lapsed/inactive - I think we should update the name as well
                if (date.today().addMonths(-3) <= mem.Expiry_Date__c){
                    mem.Membership_Status__c = 'Payment pending';
                } else if (date.today().addMonths(-15) <= mem.Expiry_Date__c){
                    mem.Membership_Status__c = 'Lapsed';
                    if (!mem.Next_Payment__r.IsClosed){
                        // Close off the opportunity
                        existing_renewal_opps.get(mem.Next_Payment__c).StageName = 'Closed Lost';
                        opps_to_update.add(existing_renewal_opps.get(mem.next_payment__c));
                    }
                } else {
                    mem.Membership_Status__c = 'Inactive';
                }
                mems_to_update.add(mem);
            } else if (mem.Next_Renewal_Date__c <= Date.today()){
                // These records need to be renewed add them to the renewal campaign
                if (mem.recordtype.name == 'Life'){
                    // They are a life member - Add to campaign with correct status (essentially new card only)
                    // add_campaign_members.add(new CampaignMember(CampaignId=renewal_campaign, ContactId=mem.Member_1__c, Status='To Renew', ));
                }
                if (mem.regular_payment__c != NULL){
                    // Calculate membership amount. If it is 0 then we just add them with a new card
                    if (ramblersutility.get_membership_amount(mal, mem.Expiry_Date__c, mem.consessionary__c, mem.Regular_Payment__r.npe03__Installment_Period__c, mem.membership_type__c, mem.recordtype.name, mem.regular_payment__r.npsp4hub__Payment_Method__c, rebate_percentage, rebate_cash) == 0){
                        // Just send them a new card
                        //add_campaign_members.add(new CampaignMember());
                    } else {
                        // Send them details of new direct debit amount. No need to update the amount just yet. Need to wait until there are no further payments before the expiry date before we change the pricing
                        //add_campaign_members.add(new CampaignMember());
                    }
                } else {
                    // We need to create and insert the renewal opportunity
                    opps_to_add.add(new Opportunity(name='s', CloseDate=mem.Expiry_Date__c, Membership_Amount__c=ramblersutility.get_membership_amount(mal, mem.Expiry_Date__c, mem.consessionary__c, 'Annual', mem.Membership_Type__c, mem.recordtype.name, 'Cash', rebate_percentage, rebate_cash), accountid=mem.Member_1__r.AccountId, npsp__Primary_Contact__c=mem.member_1__c, StageName='Pledged', Discount__c = mem.Discount__c)); // TODO: Decide what stage this should be at
                    //add_campaign_members.add(new CampaignMember());
                }
                try{
                    mem.Next_Renewal_Date__c = mem.Next_Renewal_Date__c.addYears(1); // Update the renewal date
                } catch(Exception e){
                    mem.Next_Renewal_Date__c = mem.Next_Renewal_Date__c.adddays(365); // Inserted to account for leap years - I don't think it is absolutely necessary, but we may as well put it in
                }
                mems_to_update.add(mem);
            } else {
                // I don't think we need to do anything - But leave in place in case we do
            }
        }
        insert opps_to_add;
        update opps_to_update;
        set<id> opp_ids = new set<id>();
        for (opportunity o : opps_to_add){
            opp_ids.add(o.id);
        }
        List<Opportunity> opps = [select id, name, linked_membership__c from Opportunity where id =: opp_ids];
        insert add_campaign_members;
        // Now loop back through and back fill any links to new opportunities
        for (membership__c mem : mems_to_update){
            //membership__c mem = (membership__c)s_mem;
            if (mem.Next_Renewal_Date__c <= Date.today() && Date.today() < mem.Expiry_Date__c && mem.recordtype.name != 'Life' && mem.Regular_Payment__c == NULL){
                for (Opportunity o : opps){
                    if (o.linked_membership__c == mem.id){
                        mem.Next_Payment__c = o.id;
                        break;
                    }
                }
            }
            
        }
        update mems_to_update;
    }
    
    public void finish(Database.BatchableContext bc){
        system.debug('Completed Renewals');
        // TODO: add notifications 
        // Get the ID of the AsyncApexJob representing this batch job
        // from Database.BatchableContext.
        // Query the AsyncApexJob object to retrieve the current job's information.
       List<Group> GroupId =  [Select Id from Group where type='Queue' and Name='Membership Team Queue'];
       list<GroupMember> userIdList = [Select UserOrGroupId From GroupMember where GroupId =:GroupId];
        Set<ID> useridset = new Set<ID>();
        for (GroupMember gm : userIdList ){
           useridset.add(gm.UserOrGroupId);
        }
        
        list<User> user = [SELECT Id, Email FROM USER WHERE ID IN: useridset];
        List<String> emaillist = new List<String>();
        for (User u : user){
            emaillist.add(u.Email);
        }
        
        AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
                          TotalJobItems, CreatedBy.Email
                          FROM AsyncApexJob WHERE Id =
                          :BC.getJobId()];
        // Send an email to the Apex job's submitter notifying of job completion.
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {a.CreatedBy.Email};
            toAddresses.addAll(emaillist);
            mail.setToAddresses(toAddresses);
        mail.setSubject('Batch job status ' + a.Status);
        mail.setPlainTextBody
            ('The batch Apex job processed ' + a.TotalJobItems +
             ' batches with '+ a.NumberOfErrors + ' failures.');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
        
        
    }
}



Batch Test class:

@isTest
private class RenewalJobBatchTest {
    static testMethod void RenewalBatchTestMethod(){
        // Just in case pull trigger handlers for npsp triggers
        List<npsp__Trigger_Handler__c> triggerHandlers = npsp.TDTM_Config_API.getCachedRecords();
        //set up test data
        list<Contact> con = new list<Contact>();
        for (Integer i = 0; i < 20; i++){
            con.add(new Contact(lastName = 'test lastname ' + string.valueof(i), MailingStreet = 'test mailingstreet'));
        }
        insert con;
        list <npe03__Recurring_Donation__c> rc = new list <npe03__Recurring_Donation__c> ();
        for (Integer i = 0; i < 20; i ++){
            rc.add(new npe03__Recurring_Donation__c (npe03__Contact__c = con[0].id, npsp4hub__Payment_Method__c = 'Direct Debit', npe03__Installment_Period__c = 'Monthly', Top_up_Amount__c = 10, npe03__Open_Ended_Status__c = 'Open', npe03__Date_Established__c = date.today()) );
        }
        
        insert rc;
        Membership_Amount__c ma = new Membership_Amount__c(Name = 'Select Membership', Start_date__c = Date.today().addDays(-45) , End_date__c = Date.today().addDays(50) );
        insert ma;
        List<Membership_Amount_Line__c> malineitem = [SELECT id, Amount__c FROM Membership_Amount_Line__c WHERE Membership_Amount__c =: ma.Id];
        Decimal dec = 1.0;
        for (Membership_Amount_Line__c lineitem : malineitem){
            lineitem.Amount__c = dec;
            dec += 2.1;
        }
        
        update malineitem;
        list <Opportunity> opps = new list<Opportunity>();
        for (Integer i = 0; i < 20; i++){
            opps.add(new Opportunity(Amount = 10.00, Name = 'test name', stageName = 'Closed Won', CloseDate = date.today()));
        }
        insert opps;
        
        Discount__c discount_hundred = new Discount__c (name = '100% discount', Discount_percentage__c = 100, Discount_renews__c = TRUE);
        insert discount_hundred;
        system.debug('line 36');
        id life_membership_type = Schema.SObjectType.Membership__c.getRecordTypeInfosByName().get('Life Membership').getRecordTypeId();
        
        list<Membership__c> membership = new list<Membership__c> ();
        membership.add(new Membership__c(Member_1__c = con[0].id , Membership_Status__c = 'Active', Membership_type__c = 'Individual', Start_Date__c = Date.today(), Next_Renewal_Date__c = date.today().addMonths(-11), regular_payment__c = rc[0].id, consessionary__c = TRUE, expiry_date__c = Date.valueOf('2020-07-29')));
        membership.add(new Membership__c(Member_1__c = con[1].id , Membership_Status__c = 'Active', Membership_type__c = 'Individual', Start_Date__c = Date.today(), Next_Renewal_Date__c = date.today().addMonths(-11), Next_Payment__c = opps[0].id,regular_payment__c = null, consessionary__c = TRUE, expiry_date__c = Date.today().addMonths(-15)));
        membership.add(new Membership__c(Member_1__c = con[2].id , Membership_Status__c = 'Active', Membership_type__c = 'Individual', Start_Date__c = Date.today(), Next_Renewal_Date__c = date.today().addMonths(-11), regular_payment__c = rc[1].id, consessionary__c = TRUE, expiry_date__c = Date.today().addYears(-5)));
        membership.add(new Membership__c(Member_1__c = con[3].id , Membership_Status__c = 'Active', Membership_type__c = 'Individual', Start_Date__c = Date.today(), Next_Renewal_Date__c = date.today().addMonths(-11), regular_payment__c = null, consessionary__c = TRUE, expiry_date__c = null, last_payment__c = opps[1].id, RecordTypeId = life_membership_type));
        membership.add(new Membership__c(Member_1__c = con[4].id , Membership_Status__c = 'Active', Membership_type__c = 'Individual', Start_Date__c = Date.today(), Next_Renewal_Date__c = date.today().addMonths(-11), regular_payment__c = rc[2].id, consessionary__c = TRUE, expiry_date__c = date.today().addmonths(2), last_payment__c = null, Discount__c = discount_hundred.id));
        membership.add(new Membership__c(Member_1__c = con[5].id , Membership_Status__c = 'Active', Membership_type__c = 'Individual', Start_Date__c = Date.today(), Next_Renewal_Date__c = date.today().addMonths(-11), regular_payment__c = rc[3].id, consessionary__c = TRUE, expiry_date__c = date.today().addmonths(2), last_payment__c = null));
        membership.add(new Membership__c(Member_1__c = con[6].id , Membership_Status__c = 'Active', Membership_type__c = 'Individual', Start_Date__c = Date.today(), Next_Renewal_Date__c = date.today().addMonths(-11), regular_payment__c = rc[4].id, consessionary__c = TRUE, expiry_date__c = date.today().addmonths(2), last_payment__c = opps[1].id));
        
        insert membership;
        
        Test.startTest();
        Renewal_job ren = new Renewal_job();
        Database.executeBatch(ren);
           list<campaign> all_camps = [select id from campaign where recordtype.name = 'Renewal'];
           system.debug(all_camps.size());
        //system.assert(all_camps.size() == 1); // TODO: Get data and run tests.
        Test.stopTest();
        
    }
}