[SalesForce] FATAL_ERROR|System.LimitException: Too many DML statements: 1

Facing an issue when we want to update our payment object in bulk. Works fine on sandbox but throws an exception error in production. Mentioning the controller below. The Error occurs at update statement in the end. Please help.

public with sharing class MassFeeReceiptController {
    public String startingNumber {get;set;}
    public String endingNumber {get;set;}
    public String ListReceiptNumber {get;set;}
    public List < nm_Payment__c > lstpayment {get;set;}
    public nm_Payment__c objPayment {get;set;}
    public list < nm_Payment__c > emptyListToUpdate = new list < nm_Payment__c > ();
    public list < nm_Payment__c > existingListOfPayments = new list < nm_Payment__c > ();
    map < String, boolean > mapOfReceiptNumbersAndProcessedStatus = new map < String, boolean > ();
    public MassFeeReceiptController() {
        existingListOfPayments = [select ExportFeeReceipt__c, Receipt_Number__c from nm_Payment__c where ExportFeeReceipt__c = true]; //This list will get all payments which have been processed//
        System.debug('Value of existingListOfPayments--->' + existingListOfPayments);
        mapOfReceiptNumbersAndProcessedStatus = GenerateMapOfProcessedPayments(existingListOfPayments);
        System.debug('Value of mapOfReceiptNumbersAndProcessedStatus--->' + mapOfReceiptNumbersAndProcessedStatus);
        ListReceiptNumber = '';
        lstpayment = new List < nm_Payment__c > ();
        objPayment = new nm_Payment__c();
    }
    map < String, boolean > GenerateMapOfProcessedPayments(list < nm_Payment__c > listOfPayments) //This will generate the required map For payments processed//
        {
            map < String, boolean > emptyMap = new map < String, boolean > ();
            if (listOfPayments != null && listOfPayments.size() > 0) {
                for (nm_Payment__c payments: listOfPayments) {
                    emptyMap.put(payments.Receipt_Number__c, payments.ExportFeeReceipt__c);
                }
            }
            return emptyMap;
        }
    public PageReference search() {
        if (ListReceiptNumber == '') //Will check if the Text Area is empty//
        {
            ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, 'Receipt No should not be empty');
            ApexPages.addMessage(myMsg);
            return null;
        } else if (ListReceiptNumber != null) {
            list < String > listOfPaymentsWhichAreProcessed = MethodToCheckIfPaymentsAreProcessed(ListReceiptNumber); //This method will get all the payments which are processed//
            System.debug('listOfPaymentsWhichAreProcessed value-->' + listOfPaymentsWhichAreProcessed.size());
            if (listOfPaymentsWhichAreProcessed == null || listOfPaymentsWhichAreProcessed.size() == 0) {
                System.debug('Entered if block for processing-->');
                GenerateFeeReceiptAndUpdateTheRecords(ListReceiptNumber, 'downloadAndUpdate'); //Will Generate Fee Receipt for the Desired Receipt numbers//
            } else {
                GenerateErrorList(listOfPaymentsWhichAreProcessed); //This method will generate all the Payments which have been processed//
                return null;
            }
        }
        System.debug('List Payment-->' + lstpayment);
        return Page.nmFeeTest;
    }
    public list < String > MethodToCheckIfPaymentsAreProcessed(String stringOfNumbers) {
        System.debug('Entered MethodToCheckIfPaymentsAreProcessed' + stringOfNumbers);
        list < String > receiptList = stringOfNumbers.split(',');
        list < String > emptyListToReturn = new list < String > ();
        for (String num: receiptList) {
            if (mapOfReceiptNumbersAndProcessedStatus.get(num) == true) {
                emptyListToReturn.add(num);
            }
        }
        System.debug('emptyListToReturn-->' + emptyListToReturn);
        return emptyListToReturn;
    }
    public void GenerateErrorList(list < String > receiptNumbers) {
        System.debug('Entered GenerateErrorList--->' + receiptNumbers);
        for (String receipt: receiptNumbers) {
            ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, ' Fee Receipt For This Payment Record Already Generated' + ' ' + receipt);
            ApexPages.addMessage(myMsg);
        }
    }
    public PageReference View() {
        if (ListReceiptNumber == '') {
            ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, 'Receipt No should not be empty');
            ApexPages.addMessage(myMsg);
            return null;
        } else {
            GenerateFeeReceiptAndUpdateTheRecords(ListReceiptNumber, 'view');
            return null;
        }
    }
    public void GenerateFeeReceiptAndUpdateTheRecords(String receiptNumbers, String process) {
        list < String > listOfReceiptNumbers = receiptNumbers.split(',');
        set < String > setOfReceiptNumbers = new set < String > (listOfReceiptNumbers);
        System.debug('Set Of Receipt Numbers' + setOfReceiptNumbers);
        if (setOfReceiptNumbers != null && setOfReceiptNumbers.size() > 0) {
            System.debug('Receipt Numbers--->' + setOfReceiptNumbers);
            lstpayment = [select id, Name, nm_OpportunityNew__c, Semester_Line_Item__c, nm_TransactionID__c, nm_ModeOfPayment__c, IcChangeFee__c, ProgramChangeFee__c,
                nm_Merchant_Track_Id__c, nm_DemandDraftDate__c, nm_TransactionDate__c, Currency_To_Words__c, Tuition_Fees__c, nm_OpportunityNew__r.Account.IC_Name__c,
                nm_OpportunityNew__r.Sum__c, Registration_Fee__c, nm_OpportunityNew__r.nm_Semester__c, Receipt_Number__c,
                nm_OpportunityNew__r.Academic_Year__c, nm_OpportunityNew__r.Account.nm_StudentNo__c, nm_PaymentStatus__c, nm_PaymentType__c,
                nm_OpportunityNew__r.Account.Name, nm_OpportunityNew__r.Account.Salutation, nm_Payment__c.nm_OpportunityNew__r.nm_Program__r.Fee_Program__c, nm_OpportunityNew__r.Account.LC_Name__c, nm_SAPTransactionDate__c,
                nm_OpportunityNew__r.nm_InformationCenters__r.nm_LearningCenter__r.nm_CenterCity__c, nm_BankLocation__c, ExportFeeReceipt__c,
                nm_DemandDraftNumber__c, nm_SAPDDDate__c, nm_NameoftheBank__c, nm_OpportunityNew__r.nm_LateFee__c from nm_Payment__c
                where nm_PaymentStatus__c = 'Payment Approved'
                and nm_PaymentType__c = 'Admission'
                and Receipt_Number__c in: setOfReceiptNumbers
            ];
            System.debug('List Of Payments After Query--->' + lstpayment);
            if (process == 'downLoadAndUpdate') {
                if (lstpayment != null && lstpayment.size() > 0) {
                    for (nm_Payment__c nm: lstpayment) {
                        nm.ExportFeeReceipt__c = true;
                        emptyListToUpdate.add(nm);
                    } **
                    update emptyListToUpdate; **
                }
            }
        }
    }
}

Best Answer

In <apex:page> tag, if attribute "readonly" is true and if we try to execute DML statements(Insert, Update, Delete), then it shows Too many DML statements: 1 out of 0 Error in Salesforce.

So, in order to rectify this error, set readOnly = "false" or remove this attribute in <apex:page> tag