0

I have apex class SalesProcess which has 100% code coverage in UAT. But during deployment to Production I get error saying that it is only 63 % covered. No other error just that. The class:

    public class SalesProcess {
        
    
        @invocableMethod( label='Service Quote Threshold Checker' description='This class accepts as inut list of Quote Line Items ( classic quote ) and as result provides booleand, where true is message there are records Service_Quote_Threshold_Holder__c which meet criteria from Quote Line Items.' category='Sales Process' )
        public static List<Boolean> serviceQuoteThresholdCheckker( List<List<QuoteLineItem>> filterRecords ) {
    
            List<String> filtersValues = new List<String>();
            Double quoteAmount = 0;
            String subsidiary = '';
            String currency_IsoCode = '';
            if( filterRecords[0].size() > 0 ){
                subsidiary = filterRecords[0][0].mepl_Subsidiary__c;
                currency_IsoCode = filterRecords[0][0].mepl_Quote_Currency__c;
                quoteAmount = filterRecords[0][0].mepl_Quote_Amount__c;
                for( QuoteLineItem q: filterRecords[0] ) {
                    filtersValues.add( q.mepl_Product_Family__c );
                }
    
                List<Service_Quote_Threshold_Holder__c> thresholdRecords = [SELECT id FROM Service_Quote_Threshold_Holder__c WHERE mepl_Product_Family__c IN :filtersValues AND mepl_Amount__c <= :quoteAmount AND mepl_Subsidiary__c = :subsidiary AND CurrencyIsoCode = :currency_IsoCode];
                if( thresholdRecords.size() > 0 ) return new List<Boolean>{ true };
            }
            return new List<Boolean>{ false };
        }
    
        public static void quoteLineItemSpecialPriceCheckker( Map<Id,sObject> qlRecords, Boolean isUpdate, Map<Id,sObject> qlOldRecords ) {
            List<Id> qlIdList = new List<Id>();
            if( isUpdate ){
                for( Id qlId: qlRecords.keySet() ){
                    if( qlRecords.get( qlId ).get('Product2Id') != qlOldRecords.get( qlId ).get('Product2Id') || qlRecords.get( qlId ).get('Quantity') != qlOldRecords.get( qlId ).get('Quantity') ) qlIdList.add( qlId );
                }
                if( qlIdList.size() == 0 ) return;
            }
            else{
                qlIdList = new List<Id>( qlRecords.keySet() );
            }
    
            List<QuoteLineItem> newQlList = [SELECT id, UnitPrice, ListPrice, Quantity, Quote.CreatedDate, Quote.CurrencyIsoCode, Quote.Opportunity.Account.Subsidiary__c, Quote.Opportunity.Account.CPQ_Customer_Price_Group__c, Quote.Opportunity.Account.AccountNumber, Product2.ProductCode, Product2Id  FROM QuoteLineItem WHERE Id in :qlIdList];
    
            List<String> hashTexts = new List<String>();
            for( QuoteLineItem singleQL: newQlList ){
                for( Integer i = 0 ; i<2 ; ++i ){
                    for( Integer j = 0 ; j<2 ; ++j ){
                        if( hashTexts.contains( singleQL.Quote.CurrencyIsoCode + singleQL.Quote.Opportunity.Account.Subsidiary__c + (i==0?singleQL.Quote.Opportunity.Account.AccountNumber:singleQL.Quote.Opportunity.Account.CPQ_Customer_Price_Group__c) + (j==0?(String)singleQL.Product2Id:singleQL.Product2.ProductCode) ) != true )hashTexts.add( singleQL.Quote.CurrencyIsoCode + singleQL.Quote.Opportunity.Account.Subsidiary__c + (i==0?singleQL.Quote.Opportunity.Account.AccountNumber:singleQL.Quote.Opportunity.Account.CPQ_Customer_Price_Group__c) + (j==0?(String)singleQL.Product2Id:singleQL.Product2.ProductCode) );
                    }
                }
            }
    
            List<CPQ_PriceAdministration_Condition__c> hashedPacRecords = [SELECT id, CPQ_Discount_Percent__c, CPQ_Unit_Price__c, CurrencyIsoCode, CPQ_Subsidiary__c, CPQ_Start_Date__c, CPQ_End_Date__c, CPQ_Quantity_LowerBound__c, CPQ_Quantity_UpperBound__c, CPQ_Type__c, CPQ_Item_Number__c, CPQ_Item_PriceGroup__c, CPQ_Customer_Number__c, CPQ_Customer_PriceGroup__c FROM CPQ_PriceAdministration_Condition__c WHERE mepl_Query_Helper__c IN :hashTexts];
    
            List<QuoteLineItem> toUpdateQL = new List<QuoteLineItem>();
            // This will allow future changes in discount logic
            CPQ_PriceAdministration_Condition__c discountPAC = null;
            CPQ_PriceAdministration_Condition__c pricePAC = null;
    
            for( QuoteLineItem singleQL: newQlList ){
                for( CPQ_PriceAdministration_Condition__c singlePAC: hashedPacRecords ){
                    if( (singleQL.Product2Id == singlePAC.CPQ_Item_Number__c || singleQL.Product2.ProductCode == singlePAC.CPQ_Item_PriceGroup__c) && ( singleQL.Quote.Opportunity.Account.AccountNumber == singlePAC.CPQ_Customer_Number__c || singleQL.Quote.Opportunity.Account.CPQ_Customer_Price_Group__c == singlePAC.CPQ_Customer_PriceGroup__c ) && singleQL.Quote.Opportunity.Account.Subsidiary__c == singlePAC.CPQ_Subsidiary__c && singleQL.Quote.CurrencyIsoCode == singlePAC.CurrencyIsoCode ){
                        if( singlePAC.CPQ_Start_Date__c != null && singlePAC.CPQ_End_Date__c != null && ( singleQL.Quote.CreatedDate < singlePAC.CPQ_Start_Date__c || singleQL.Quote.CreatedDate > singlePAC.CPQ_End_Date__c ) ) continue;
                        if( singlePAC.CPQ_Quantity_LowerBound__c != null && singlePAC.CPQ_Quantity_UpperBound__c != null && ( singleQL.Quantity < singlePAC.CPQ_Quantity_LowerBound__c || singleQL.Quantity > singlePAC.CPQ_Quantity_UpperBound__c ) ) continue;
                        if( singlePAC.CPQ_Type__c == 'Discount' ){                 // We need to check which discount should be applyed if there is already one other matching requirements
                            if( discountPAC == null ) discountPAC = singlePAC;
                            else{
                                if( singlePAC.CPQ_Customer_Number__c != null && discountPAC.CPQ_Customer_Number__c != null ){
                                    discountPAC = singlePAC.CPQ_Discount_Percent__c > discountPAC.CPQ_Discount_Percent__c ? singlePAC : discountPAC;
                                    continue;
                                }
                                else{
                                    if( singlePAC.CPQ_Customer_Number__c != null || discountPAC.CPQ_Customer_Number__c != null ) discountPAC = singlePAC.CPQ_Customer_Number__c != null ? singlePAC : discountPAC;
                                    else discountPAC = discountPAC.CPQ_Discount_Percent__c < singlePAC.CPQ_Discount_Percent__c ? singlePAC : discountPAC;
                                    continue;
                                }
                            }
                        }
                        else{
                            if( pricePAC == null ) pricePAC = singlePAC;
                            else{
                                if( singlePAC.CPQ_Customer_Number__c != null && pricePAC.CPQ_Customer_Number__c != null ){
                                    pricePAC = singlePAC.CPQ_Unit_Price__c < pricePAC.CPQ_Unit_Price__c ? singlePAC : pricePAC;
                                    continue;
                                }
                                else{
                                    if( singlePAC.CPQ_Customer_Number__c != null || pricePAC.CPQ_Customer_Number__c != null ) pricePAC = singlePAC.CPQ_Customer_Number__c != null ? singlePAC : pricePAC;
                                    else pricePAC = pricePAC.CPQ_Unit_Price__c > singlePAC.CPQ_Unit_Price__c ? singlePAC : pricePAC;
                                    continue;
                                }
                            }
                        }
                    }
                }
                if( discountPAC != null ){
                    singleQL.Discount = discountPAC.CPQ_Discount_Percent__c;
                    discountPAC = null;
                }
                if( pricePAC != null ){
                    singleQL.UnitPrice = pricePAC.CPQ_Unit_Price__c;
                    pricePAC = null;
                }
                else{
                    singleQL.UnitPrice = singleQL.ListPrice;
                }
                toUpdateQL.add( singleQL );
                
            }
    
            update toUpdateQL;
        }
    }

The unit test class:

    @isTest
    public class SalesProcess_Test {
        @testSetup static void setup() {
            //  Create Account, 2 x Opportunity both service and Quote with quote lines
            List<Product2> theProducts = new List<Product2>();
            theProducts.add( new Product2(
                Name = 'test Product1',
                Family = 'CIJ',
                ProductCode = 'Device'
            ));
            theProducts.add( new Product2(
                Name = 'test Product2',
                Family = 'TIJ',
                ProductCode = 'Parts'
            ));
            insert theProducts;
    
            PriceBook2 thePriceBook = new PriceBook2( Name = 'test Pricebook', isActive = true );
            insert thePriceBook;
            Id theStandardPricebook = Test.getStandardPricebookId();
    
            List<PricebookEntry> theEntry = new List<PricebookEntry>();
            theEntry.add( new PricebookEntry( isActive = true, CurrencyIsoCode = 'USD', UnitPrice = 5, Pricebook2Id = theStandardPricebook, Product2Id = theProducts[0].Id ) );
            theEntry.add( new PricebookEntry( isActive = true, CurrencyIsoCode = 'USD', UnitPrice = 10, Pricebook2Id = thePriceBook.Id, Product2Id = theProducts[0].Id ) );
            theEntry.add( new PricebookEntry( isActive = true, CurrencyIsoCode = 'EUR', UnitPrice = 5, Pricebook2Id = theStandardPricebook, Product2Id = theProducts[0].Id ) );
            theEntry.add( new PricebookEntry( isActive = true, CurrencyIsoCode = 'EUR', UnitPrice = 10, Pricebook2Id = thePriceBook.Id, Product2Id = theProducts[0].Id ) );
            theEntry.add( new PricebookEntry( isActive = true, CurrencyIsoCode = 'USD', UnitPrice = 50, Pricebook2Id = theStandardPricebook, Product2Id = theProducts[1].Id ) );
            theEntry.add( new PricebookEntry( isActive = true, CurrencyIsoCode = 'USD', UnitPrice = 100, Pricebook2Id = thePriceBook.Id, Product2Id = theProducts[1].Id ) );
            theEntry.add( new PricebookEntry( isActive = true, CurrencyIsoCode = 'EUR', UnitPrice = 50, Pricebook2Id = theStandardPricebook, Product2Id = theProducts[1].Id ) );
            theEntry.add( new PricebookEntry( isActive = true, CurrencyIsoCode = 'EUR', UnitPrice = 100, Pricebook2Id = thePriceBook.Id, Product2Id = theProducts[1].Id ) );
            insert theEntry;
    
            List<Account> theAccounts = new List<Account>();
            theAccounts.add(
                new Account( Name = 'TestAcc1', Vertical__c = 'Other', Subsidiary__c = 'VTI France', CurrencyIsoCode = 'USD', AccountNumber = 'VTIFranceTestAcc1', CPQ_Customer_Price_Group__c = null, SIC_4_digit__c = '0711-Soil preparation services' )
            );
            theAccounts.add(
                new Account( Name = 'TestAcc2', Vertical__c = 'Other', Subsidiary__c = 'VTI Germany', CurrencyIsoCode = 'EUR', AccountNumber = 'VTIGermanyTestAcc2', CPQ_Customer_Price_Group__c = 'TestPriceGroup1', SIC_4_digit__c = '0711-Soil preparation services' )
            );
            insert theAccounts;
    
            List<Opportunity> theOpportunities = new List<Opportunity>();
            Id serviceOppRecordType = Schema.SObjectType.Opportunity.getRecordTypeInfosByName().get('Service\\Parts').getRecordTypeId();
            theOpportunities.add( new Opportunity( AccountId = theAccounts[0].Id, recordTypeId = serviceOppRecordType, Name = 'TestOpp1.1', CloseDate = Date.today(), StageName = 'Qualify', CurrencyIsoCode = 'USD' ) );
            theOpportunities.add( new Opportunity( AccountId = theAccounts[0].Id, recordTypeId = serviceOppRecordType, Name = 'TestOpp1.2', CloseDate = Date.today(), StageName = 'Qualify', CurrencyIsoCode = 'USD' ) );
            theOpportunities.add( new Opportunity( AccountId = theAccounts[1].Id, recordTypeId = serviceOppRecordType, Name = 'TestOpp2.1', CloseDate = Date.today(), StageName = 'Qualify', CurrencyIsoCode = 'EUR' ) );
            theOpportunities.add( new Opportunity( AccountId = theAccounts[1].Id, recordTypeId = serviceOppRecordType, Name = 'TestOpp2.2', CloseDate = Date.today(), StageName = 'Qualify', CurrencyIsoCode = 'EUR' ) );
            insert theOpportunities;
    
            List<Quote> theQuote = new List<Quote>();
            theQuote.add( new Quote( Name = 'TestQuote1.1', OpportunityId = theOpportunities[0].Id, Pricebook2Id = thePriceBook.Id ) );
            theQuote.add( new Quote( Name = 'TestQuote1.2', OpportunityId = theOpportunities[1].Id, Pricebook2Id = thePriceBook.Id ) );
            theQuote.add( new Quote( Name = 'TestQuote2.1', OpportunityId = theOpportunities[2].Id, Pricebook2Id = thePriceBook.Id ) );
            theQuote.add( new Quote( Name = 'TestQuote2.2', OpportunityId = theOpportunities[3].Id, Pricebook2Id = thePriceBook.Id ) );
            insert theQuote;
    
            List<QuoteLineItem> theQuoteLineItems = new List<QuoteLineItem>();
            theQuoteLineItems.add( new QuoteLineItem( Product2Id = theProducts[0].Id, Quantity = 10, UnitPrice = 10, Discount = 0, PricebookEntryId = theEntry[1].Id, QuoteId = theQuote[0].Id ) ); // This record is used in threshold check
            theQuoteLineItems.add( new QuoteLineItem( Product2Id = theProducts[0].Id, Quantity = 5, UnitPrice = 10, Discount = 0, PricebookEntryId = theEntry[1].Id, QuoteId = theQuote[1].Id ) ); // This record is used in threshold check
            theQuoteLineItems.add( new QuoteLineItem( Product2Id = theProducts[1].Id, Quantity = 20, UnitPrice = 10, Discount = 0, PricebookEntryId = theEntry[5].Id, QuoteId = theQuote[0].Id ) ); // This record is used in threshold check
    
            theQuoteLineItems.add( new QuoteLineItem( Product2Id = theProducts[0].Id, Quantity = 5, UnitPrice = 10, Discount = 0, PricebookEntryId = theEntry[3].Id, QuoteId = theQuote[2].Id ) );
            theQuoteLineItems.add( new QuoteLineItem( Product2Id = theProducts[0].Id, Quantity = 10, UnitPrice = 10, Discount = 0, PricebookEntryId = theEntry[3].Id, QuoteId = theQuote[3].Id ) );
            theQuoteLineItems.add( new QuoteLineItem( Product2Id = theProducts[1].Id, Quantity = 5, UnitPrice = 10, Discount = 0, PricebookEntryId = theEntry[7].Id, QuoteId = theQuote[3].Id ) );
            insert theQuoteLineItems;
        }
        @isTest Static void tresholdCheck_Test() {
            // This test will check if result of SalesProcess.serviceQuoteThresholdCheckker method returns correct values
            Service_Quote_Threshold_Holder__c thresholdRecord = new Service_Quote_Threshold_Holder__c( mepl_Product_Family__c = 'CIJ', mepl_Amount__c = 100, CurrencyIsoCode = 'USD', mepl_Subsidiary__c = 'VTI France');
            insert thresholdRecord;
            
            List<QuoteLineItem> testRecords = [SELECT Id, Quantity, ListPrice, mepl_Quote_Amount__c, mepl_Product_Family__c, mepl_Subsidiary__c, mepl_Quote_Currency__c FROM QuoteLineItem WHERE Quote.Opportunity.CurrencyIsoCode = 'USD'];
            System.assertEquals(3, testRecords.size(), 'Method tresholdCheck_Test expected only 2 QuoteLineItems. Update logic if new has been added to setup method.');
    
            List<List<QuoteLineItem>> testSet;
            for( Integer i = 0 ; i<2 ; ++i ){
                testSet = new List<List<QuoteLineItem>>{ new List<QuoteLineItem>() };
                testSet[0].add( testRecords[i] );
                if( testRecords[i].Quantity >= 10 && testRecords[i].mepl_Product_Family__c == 'CIJ' ) System.assertEquals( true, SalesProcess.serviceQuoteThresholdCheckker( testSet )[0] );
                else System.assertEquals( false, SalesProcess.serviceQuoteThresholdCheckker( testSet )[0] );
            }
    
        }
        @isTest static void priceAdministrationConditionCheck_ConditionsCheck() {
    
            List<CPQ_PriceAdministration_Condition__c> priceConditionsList = new List<CPQ_PriceAdministration_Condition__c>();
            
            Product2 theProductDevice = [SELECT id, Name, Family, ProductCode FROM Product2 WHERE ProductCode = 'Device'];
            Product2 theProductParts = [SELECT id, Name, Family, ProductCode FROM Product2 WHERE ProductCode = 'Parts'];
    
            List<QuoteLineItem> theQLItemsGermany = [SELECT id, Product2Id, Discount, Quantity, UnitPrice, PricebookEntryId, QuoteId FROM QuoteLineItem WHERE Quote.Opportunity.Account.Subsidiary__c = 'VTI Germany']; // Record to check update
    
            priceConditionsList.add( new CPQ_PriceAdministration_Condition__c(
                CPQ_Customer_PriceGroup__c = 'TestPriceGroup1',
                CPQ_Discount_Percent__c = 10,
                CPQ_Item_PriceGroup__c = 'Parts',
                CPQ_Subsidiary__c = 'VTI Germany',
                CPQ_Type__c = 'Discount',
                CPQ_Start_Date__c = Date.today().addDays(-20),
                CPQ_End_Date__c = Date.today().addDays(-10),
                CurrencyIsoCode = 'EUR'
            ) );
            priceConditionsList.add( new CPQ_PriceAdministration_Condition__c(
                CPQ_Customer_PriceGroup__c = 'TestPriceGroup1',
                CPQ_Discount_Percent__c = 10,
                CPQ_Item_PriceGroup__c = 'Parts',
                CPQ_Subsidiary__c = 'VTI Germany',
                CPQ_Type__c = 'Discount',
                CPQ_Start_Date__c = Date.today().addDays(10),
                CPQ_End_Date__c = Date.today().addDays(20),
                CurrencyIsoCode = 'EUR'
            ) );        // This two price conditions shouldn't work because of Date ( so no 10 discount on product [1] )
            priceConditionsList.add( new CPQ_PriceAdministration_Condition__c(
                CPQ_Customer_Number__c = 'VTIGermanyTestAcc2',
                CPQ_Unit_Price__c = 1,
                CPQ_Item_Number__c = theProductParts.Id,
                CPQ_Subsidiary__c = 'VTI Germany',
                CPQ_Type__c = 'Price',
                CPQ_Start_Date__c = Date.today().addDays(-2),
                CPQ_End_Date__c = Date.today().addDays(4),
                CurrencyIsoCode = 'USD'
            ) );        // This PAC will not work because of Currency
    
            insert priceConditionsList;
    
            for( Integer i = 0 ; i< theQLItemsGermany.size() ; ++i ){
                System.assertNotEquals( theQLItemsGermany[i].UnitPrice , 1 , 'The price of test QL shouldn\'t be 1 before update' );
                System.assertNotEquals( theQLItemsGermany[i].Discount , 10 , 'The discount of test QL shouldn\'t be 10 before update' );
                theQLItemsGermany[i].Quantity = 9;
            }
    
            update theQLItemsGermany;
            theQLItemsGermany = [SELECT id, Product2Id, Discount, Quantity, UnitPrice, PricebookEntryId, QuoteId FROM QuoteLineItem WHERE Quote.Opportunity.Account.Subsidiary__c = 'VTI Germany'];
    
            for( Integer i = 0 ; i< theQLItemsGermany.size() ; ++i ){
                System.assertNotEquals( theQLItemsGermany[i].UnitPrice , 1 , 'The price of test QL shouldn\'t be 1 after update' );
                System.assertNotEquals( theQLItemsGermany[i].Discount , 10 , 'The discount of test QL shouldn\'t be 10 after update' );
                theQLItemsGermany[i].Quantity = 11;
            }
    
            priceConditionsList.clear();
            priceConditionsList.add( new CPQ_PriceAdministration_Condition__c(
                CPQ_Customer_PriceGroup__c = 'TestPriceGroup1',
                CPQ_Discount_Percent__c = 10,
                CPQ_Item_PriceGroup__c = 'Parts',
                CPQ_Subsidiary__c = 'VTI Germany',
                CPQ_Type__c = 'Discount',
                CPQ_Start_Date__c = Date.today().addDays(-2),
                CPQ_End_Date__c = Date.today().addDays(4),
                CurrencyIsoCode = 'EUR'
            ) );
            priceConditionsList.add( new CPQ_PriceAdministration_Condition__c(
                CPQ_Customer_Number__c = 'VTIGermanyTestAcc2',
                CPQ_Unit_Price__c = 1,
                CPQ_Item_Number__c = theProductParts.Id,
                CPQ_Subsidiary__c = 'VTI Germany',
                CPQ_Type__c = 'Price',
                CPQ_Start_Date__c = Date.today().addDays(-2),
                CPQ_End_Date__c = Date.today().addDays(4),
                CurrencyIsoCode = 'EUR'
            ) );
    
            insert priceConditionsList;
            update theQLItemsGermany;
    
            theQLItemsGermany = [SELECT id, Product2Id, Discount, Quantity, UnitPrice, PricebookEntryId, QuoteId FROM QuoteLineItem WHERE Quote.Opportunity.Account.Subsidiary__c = 'VTI Germany'];
            for( Integer i = 0 ; i< theQLItemsGermany.size() ; ++i ){
                if( theQLItemsGermany[i].Product2Id == theProductParts.Id ){
                    //System.assertEquals( theQLItemsGermany[i].UnitPrice , 1 , 'The price of test QL shouldn be 1 after second update' );
                    //System.assertEquals( theQLItemsGermany[i].Discount , 10 , 'The discount of test QL shouldn be 10 second after update' );
                }
            }
        }  
        @isTest static void priceAdministrationConditionCheck_DoubleConditions() {
    
            List<CPQ_PriceAdministration_Condition__c> priceConditionsList = new List<CPQ_PriceAdministration_Condition__c>();
            
            Product2 theProductDevice = [SELECT id, Name, Family, ProductCode FROM Product2 WHERE ProductCode = 'Device'];
            Product2 theProductParts = [SELECT id, Name, Family, ProductCode FROM Product2 WHERE ProductCode = 'Parts'];
    
            Account germanAcc = [SELECT id, Subsidiary__c, AccountNumber, CPQ_Customer_Price_Group__c FROM Account WHERE Subsidiary__c = 'VTI Germany'];
    
            List<QuoteLineItem> theQLItemsGermany = [SELECT id, Product2Id, Discount, Quantity, UnitPrice, PricebookEntryId, QuoteId, Product2.ProductCode FROM QuoteLineItem WHERE Quote.Opportunity.Account.Subsidiary__c = 'VTI Germany'];
            List<QuoteLineItem> theQLItemsFrance = [SELECT id, Product2Id, Discount, Quantity, UnitPrice, PricebookEntryId, QuoteId FROM QuoteLineItem WHERE Quote.Opportunity.Account.Subsidiary__c = 'VTI France'];
    
            priceConditionsList.add( new CPQ_PriceAdministration_Condition__c(
                CPQ_Customer_PriceGroup__c = germanAcc.CPQ_Customer_Price_Group__c,
                CPQ_Discount_Percent__c = 10,
                CPQ_Item_PriceGroup__c = 'Parts',
                CPQ_Subsidiary__c = germanAcc.Subsidiary__c,
                CPQ_Type__c = 'Discount',
                CPQ_Start_Date__c = Date.today().addDays(-2),
                CPQ_End_Date__c = Date.today().addDays(4),
                CurrencyIsoCode = 'EUR'
            ) );
            priceConditionsList.add( new CPQ_PriceAdministration_Condition__c(
                CPQ_Customer_PriceGroup__c = germanAcc.CPQ_Customer_Price_Group__c,
                CPQ_Discount_Percent__c = 9,
                CPQ_Item_PriceGroup__c = 'Parts',
                CPQ_Subsidiary__c = germanAcc.Subsidiary__c,
                CPQ_Type__c = 'Discount',
                CPQ_Start_Date__c = Date.today().addDays(-2),
                CPQ_End_Date__c = Date.today().addDays(4),
                CurrencyIsoCode = 'EUR'
            ) );
            priceConditionsList.add( new CPQ_PriceAdministration_Condition__c(
                CPQ_Customer_Number__c = germanAcc.AccountNumber,
                CPQ_Discount_Percent__c = 15,
                CPQ_Item_PriceGroup__c = 'Parts',
                CPQ_Subsidiary__c = germanAcc.Subsidiary__c,
                CPQ_Type__c = 'Discount',
                CPQ_Start_Date__c = Date.today().addDays(-2),
                CPQ_End_Date__c = Date.today().addDays(4),
                CurrencyIsoCode = 'EUR'
            ) );
            priceConditionsList.add( new CPQ_PriceAdministration_Condition__c(
                CPQ_Customer_Number__c = germanAcc.AccountNumber,
                CPQ_Unit_Price__c = 15,
                CPQ_Item_PriceGroup__c = 'Parts',
                CPQ_Subsidiary__c = germanAcc.Subsidiary__c,
                CPQ_Type__c = 'Price',
                CPQ_Start_Date__c = Date.today().addDays(-2),
                CPQ_End_Date__c = Date.today().addDays(4),
                CurrencyIsoCode = 'EUR'
            ) );
            priceConditionsList.add( new CPQ_PriceAdministration_Condition__c(
                CPQ_Customer_PriceGroup__c = germanAcc.CPQ_Customer_Price_Group__c,
                CPQ_Unit_Price__c = 19,
                CPQ_Item_PriceGroup__c = 'Parts',
                CPQ_Subsidiary__c = germanAcc.Subsidiary__c,
                CPQ_Type__c = 'Price',
                CPQ_Start_Date__c = Date.today().addDays(-2),
                CPQ_End_Date__c = Date.today().addDays(4),
                CurrencyIsoCode = 'EUR'
            ) );
            priceConditionsList.add( new CPQ_PriceAdministration_Condition__c(
                CPQ_Customer_PriceGroup__c = germanAcc.CPQ_Customer_Price_Group__c,
                CPQ_Unit_Price__c = 17,
                CPQ_Item_PriceGroup__c = 'Parts',
                CPQ_Subsidiary__c = germanAcc.Subsidiary__c,
                CPQ_Type__c = 'Price',
                CPQ_Start_Date__c = Date.today().addDays(-2),
                CPQ_End_Date__c = Date.today().addDays(4),
                CurrencyIsoCode = 'EUR'
            ) );
            priceConditionsList.add( new CPQ_PriceAdministration_Condition__c(
                CPQ_Customer_Number__c = germanAcc.AccountNumber,
                CPQ_Unit_Price__c = 25,
                CPQ_Item_PriceGroup__c = 'Parts',
                CPQ_Subsidiary__c = germanAcc.Subsidiary__c,
                CPQ_Type__c = 'Price',
                CPQ_Start_Date__c = Date.today().addDays(-2),
                CPQ_End_Date__c = Date.today().addDays(4),
                CurrencyIsoCode = 'EUR'
            ) );            // Two discounts for same product and customer matched based on both number and price group should discount with account number win
    
            insert priceConditionsList;
    
            for( Integer i = 0 ; i<theQLItemsGermany.size() ; ++i ){
                theQLItemsGermany[i].UnitPrice = 99;
            }
            update theQLItemsGermany;       // this update shouldn't trigger price conditions 
            theQLItemsGermany = [SELECT id, Product2Id, Discount, Quantity, UnitPrice, PricebookEntryId, QuoteId, Product2.ProductCode FROM QuoteLineItem WHERE Quote.Opportunity.Account.Subsidiary__c = 'VTI Germany'];
    
            for( Integer i = 0 ; i<theQLItemsGermany.size() ; ++i ){
                if( theQLItemsGermany[i].Product2.ProductCode == 'Parts' ) System.assertNotEquals( theQLItemsGermany[i].Discount, 15, 'Update not changing Quantity or product shouldn\'t trigger any price change.' );
                else System.assertEquals( theQLItemsGermany[i].Discount, 0, 'Other products should have 0 discount.' );
            }
    
            for( Integer i = 0 ; i<theQLItemsGermany.size() ; ++i ){
                theQLItemsGermany[i].Quantity = 111;
            }
            update theQLItemsGermany;       // this update should trigger price conditions 
            theQLItemsGermany = [SELECT id, Product2Id, Discount, Quantity, UnitPrice, PricebookEntryId, QuoteId, Product2.ProductCode FROM QuoteLineItem WHERE Quote.Opportunity.Account.Subsidiary__c = 'VTI Germany'];
    
            List<CPQ_PriceAdministration_Condition__c> priceConditionsListSecond = new List<CPQ_PriceAdministration_Condition__c>();
            priceConditionsListSecond.add( new CPQ_PriceAdministration_Condition__c(
                CPQ_Customer_Number__c = germanAcc.AccountNumber,
                CPQ_Discount_Percent__c = 20,
                CPQ_Item_PriceGroup__c = 'Parts',
                CPQ_Subsidiary__c = germanAcc.Subsidiary__c,
                CPQ_Type__c = 'Discount',
                CPQ_Start_Date__c = Date.today().addDays(-2),
                CPQ_End_Date__c = Date.today().addDays(4),
                CurrencyIsoCode = 'EUR'
            ) );
    
            insert priceConditionsListSecond;
    
            for( Integer i = 0 ; i<theQLItemsGermany.size() ; ++i ){
                theQLItemsGermany[i].Quantity = 222;
            }
            update theQLItemsGermany;       // this update should trigger price conditions 
            theQLItemsGermany = [SELECT id, Product2Id, Discount, Quantity, UnitPrice, PricebookEntryId, QuoteId, Product2.ProductCode FROM QuoteLineItem WHERE Quote.Opportunity.Account.Subsidiary__c = 'VTI Germany'];
        }
    }
3
  • I had to delete some System.asserts cause of character limit for question. There was no error from assert. Also I separated the class trigger and test class from other components and deployed everything else except this. Only this class throws this error. Nov 19, 2020 at 12:07
  • 3
    I can suggest to refresh your sandbox and run test class again. I think that production has some flows or processes that sandbox does not have and the test class just cannot go in some if-clauses. Nov 19, 2020 at 12:25
  • @MariiaIllarionova You were right. I finally managed to find solution. I think I should be downrated for thisquestion. Issue was that there was second processbuilder that was to auto populate fields on one of objects. During tests it was inactive and didn't populate the field. After few mixes in between automations information from that field was used by me. I wrongly assumed it will be populated. Sorry every one for waisting Your time. Nov 19, 2020 at 14:57

1 Answer 1

0

I learned that there is some other process builder that populates fields on CPQ_PriceAdministration_Condition__c that later i need to use to find test records. Since the field has been empty test were doing 30% of one method.

Nobady could help with that so sorry for this I think this question will not help any one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.