• Uma Prabhakar
  • NEWBIE
  • 10 Points
  • Member since 2019

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 6
    Questions
  • 10
    Replies
Hello Experts

I am New to the Salesforce Ecosystem, i am trying to design a functionality where custom reports needs to be sent via Email With attachment, i know this beta version, but i need to design through customization, i have researched a lot and finally came up with the link

https://blogs.absyz.com/2018/09/27/sending-reports-to-email-as-an-attachment/

i have done exactly the same but dont know why its not working, could any one 

Visualforce Component
 
<apex:component controller="ReportsToEmailController" access="global">
    <apex:attribute name="ReportId" description="Report ID" type="Id" assignTo="{!rptId}"/>
    <apex:outputPanel>         
        <table style="width: 100%;">
            <thead>                 
                <apex:repeat value="{!ReportResult.reportMetadata.detailColumns}" var="colName"> 
 
                    <!-- reportMetadata is a class where it contains metadata of a report.
                        DetailColumns is a method of ReportMetadata class, it returns the API names (Columns Names) 
                            for the fields that contain detailed data-->
 
                    <th><apex:outputText value="{!ReportResult.reportExtendedMetadata.detailColumnInfo[colName].label}"/></th>
 
                    <!-- reportExtendedMetadata is class where it contains Report extended metadata and
                            it provides data type and label information.
                        detailColumnInfo is a method of reportExtendedMetadata class, it returns map of columns names 
                            and its label to Display as Header -->
 
                </apex:repeat> 
            </thead> 
            <tbody> 
                <apex:repeat value="{!ReportResult.factMap['T!T'].rows}" var="row" rows="999"> 
                    <!-- Here we will get entire data of each row and T refers to the Row -->
                    <tr> <apex:repeat value="{!row.dataCells}" var="cell">
                        <!-- Here we will get data of each cell and displayed -->
                        <td><apex:outputText value="{!cell.label}"/></td>
                        </apex:repeat> </tr> 
                </apex:repeat>
            </tbody>
        </table>
    </apex:outputPanel> 
</apex:component>

Apex Controller: ReportsToEmailController
 
public class ReportsToEmailController {
    public Id rptId { get; set; } // Here we will get the report Id from the VF Component
    private transient Reports.ReportResults results; // It will hold the entire data of a report
 
    /*********************
     // Method Name : getReportResult
     // Description : Here we will get the data of a report and send to the VF Component
    /********************/
 
    public Reports.ReportResults getReportResult() {
        // Here it will run the report with that report ID and adding the report data into results
        results = Reports.ReportManager.runReport(rptId, true);
        return results;
    }
}

My custom VF template where 
 
<messaging:emailTemplate subject="Report" recipientType="User" >
    <messaging:plainTextEmailBody >
        Hi {!recipient.FirstName}
        Please find the below attachments. 
 
    </messaging:plainTextEmailBody>
    <messaging:attachment filename="Opp Record Report.xls">
        <!-- Here we can add multiple Reports -->
        <c:ReportsToEmail ReportId="00O2w000003DegwEAC"/>
        <c:ReportsToEmail ReportId="00O2w000003DegwEAC"/>
    </messaging:attachment>
</messaging:emailTemplate>


Next i have Designed workflow rule where when checkbox update  with Email alert, but i am not recieveing any mails, Any help will be highly appreciated


 
Hello Developers

i am new to the apex development, i have been given a task for creating Triggers to prevent duplicate records on multiple fields , i know this is can be achived through Duplicate Rules, but still i want to try with the Apex trigger

Assignedto__c (Lookup(User)

Quater_Year__c(Picklist)

Month__c(Picklist)

i want to create a Duplication rule on these 3 fields, 

i refered the below link, but i could not get the correct code

https://www.mstsolutions.com/technical/preventing-duplicate-records-based-on-multiple-fields-in-salesforce/

 
i have written a increment trigger, where there are 5 custom field(India,ME,US,SEA,EU),all these fields are Incremented based on a formula field(PraticeLWC__Region__c), now if i update for ME the record should increment for 1 and 2, and if i delete a record related to ME and again add the record the record for ME it should take as 2 itself and not 3, how do i achive this

so basically when i add the records based on the region it should get incremented and if i delete a record it should get decremented

Region1
 
trigger Increment on Lead (before insert,Before Update) {
    if(trigger.isBefore && (trigger.isInsert || trigger.isUpdate || Trigger.IsUnDelete))  {
        List<Lead> leadList = [Select Id,PraticeLWC__Lead_No_Region_IN__c From Lead Where PraticeLWC__Region__c = 'India'];
        For(Lead l : trigger.New ) {
            if(l.PraticeLWC__Region__c == 'India') {
                if(leadList.size() > 0){
                    l.PraticeLWC__Lead_No_Region_IN__c = leadList.size()+0;   
                } else {
                    l.PraticeLWC__Lead_No_Region_IN__c = 1;
                }
            }
        }
        List<Lead> leadListt = [Select Id,PraticeLWC__Lead_No_Region_USA__c From Lead Where PraticeLWC__Region__c = 'US'];
        For(Lead m : trigger.New) {
            if(m.PraticeLWC__Region__c == 'US') {
                if(leadListt.size() > 0){
                    m.PraticeLWC__Lead_No_Region_USA__c = leadListt.size()+0;   
                } else {
                    m.PraticeLWC__Lead_No_Region_USA__c = 1;
                }
            }
        } 
        List<Lead> leadListm = [Select Id,PraticeLWC__Lead_No_Region_EU__c From Lead Where PraticeLWC__Region__c = 'EU'];
        For(Lead n : trigger.New) {
            if(n.PraticeLWC__Region__c == 'EU') {
                if(leadListm.size() > 0){
                    n.PraticeLWC__Lead_No_Region_EU__c = leadListm.size()+0;   
                } else {
                    n.PraticeLWC__Lead_No_Region_EU__c = 1;
                }
            }
        } 
        List<Lead> leadListo = [Select Id,PraticeLWC__Lead_No_Region_SEA__c From Lead Where PraticeLWC__Region__c = 'SEA'];
        For(Lead o : trigger.New) {
            if(o.PraticeLWC__Region__c == 'SEA') {
                if(leadListo.size() > 0){
                    o.PraticeLWC__Lead_No_Region_SEA__c = leadListo.size()+0;   
                } else {
                    o.PraticeLWC__Lead_No_Region_SEA__c = 1;
                }
            }
        }
        List<Lead> leadListp = [Select Id,PraticeLWC__Lead_No_Region_ME__c From Lead Where PraticeLWC__Region__c = 'ME'];
        For(Lead p : trigger.New) {
            if(p.PraticeLWC__Region__c == 'ME') {
                if(leadListp.size() > 0){
                    p.PraticeLWC__Lead_No_Region_ME__c = leadListp.size()+0;   
                } else {
                    p.PraticeLWC__Lead_No_Region_ME__c = 1;
                }
            }
        } 
        
    }                   
}

 
Hello Everyone

I need some help and suggestion regarding the email alert when lead is not modified for 24 Hrs, i tried with the workflow alert and time based Triggers but it was not working, 
Workflow rule:-

Evaluation criteria:- Every time record is created & subsequently meet criteria

Formula:- LastmodifiedDate=Created Date

and Created a Timetrigger actions for 24 Hrs, but it did not fire

I have Faced a lot of issues with Workflows and Prosess Builders, so i need help for designing a Batch class When Lead  is Created and if the lead is not modified for 24Hrs it should send an Email alert
This is what i have come up with till now
global class Emailalertbatchclass implements Database.Batchable<sObject>, Schedulable, Database.Stateful {

    //Variable Section
    global FINAL String strQuery;
    global List<String> errorMessages = new List<String>();
    
    global Emailalertbatchclass() { 
        this.strQuery = getBatchQuery();
    }
    
    //Returns the Query String to Batch constructor to fetch right records.
    private String getBatchQuery() {
        String strQuery = 'SELECT Id, name, Owner.Email FROM Lead WHERE CreatedDate >= YESTERDAY'; 
        return strQuery;
    }
    
    //Batch Start method
    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator(strQuery);
    }

    //Batch Execute method calls findCostForWoD method
    global void execute(Database.BatchableContext BC, List<sObject> scopeList) {
        System.debug(LoggingLevel.INFO, '== scopeList size ==' + scopeList.size());
        
        List<Lead> ld = (List<Lead>) scopeList;
        if(!ld.isEmpty()) { 
            List<Messaging.SingleEmailMessage> mailList = new List<Messaging.SingleEmailMessage>();
            for (Lead prod : ld)
            {               
                
                Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage(); 
                String[] toAddresses = new String[] {prod.Owner.Email};
                Message.setToAddresses(toAddresses); 
                Message.SaveAsActivity = false;
                mailList.add(Message);
                
            }
            if(!mailList.isEmpty()) {
                try{
                    Messaging.sendEmail(mailList);
                }
                catch (Exception ex) {
                    errorMessages.add('Unable to send email to Tech: '+ ex.getStackTraceString());
                }
            }
        }
    }  

    //Batch Finish method for after execution of batch work
    global void finish(Database.BatchableContext BC) { 
        AsyncApexJob aaj = [Select Id, Status, NumberOfErrors, JobItemsProcessed, MethodName, 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[] {aaj.CreatedBy.Email};
        mail.setToAddresses(toAddresses);
        mail.setSubject('JOB Salesforce Send Notification Batch: ' + aaj.Status);
        String bodyText='Total Job Items ' + aaj.TotalJobItems + ' Number of records processed ' + aaj.JobItemsProcessed + ' with '+ aaj.NumberOfErrors + ' failures.\n';
        bodyText += 'Number of Error Messages ' + errorMessages.size() + '\n';
        bodyText += 'Error Message' + String.join(errorMessages, '\n');
        mail.setPlainTextBody(bodyText);
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
    
    //Method which schedules the ProductDownloadBatch
    global void execute(SchedulableContext sc) {        
        Emailalertbatchclass snInstance = new Emailalertbatchclass();
        ID batchprocessid = Database.executeBatch(snInstance);
    }
}
Any help would be Highly Appericiated 



 
Hello All

Need small Help with the Flows
I have been given assignment to Update Existing Products, when new Opportunity is created from Flows By Invoking Process Builder, 
i have been Referencing the below links by dint help, since these links are very old

 https://success.salesforce.com/answers?id=9063A000000laEIQAY
    
https://developer.salesforce.com/forums/?id=9060G000000XcqLQAS

any guidence would highly be appriciated
Hello Salesforce Expertrs 

i am new to the salesforce and i am trying to write test class for the Content document trigger, So when partner user tries a Upload a document through files, automatically he gets email saying that document has been uploaded with the document link, the trigger was successful and with great difficulty i wrote a test class with 100% code coverage, but when i see the test result i see that there is erro "INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY" i have checked in the profile, as well as the OWD settings, still i was not able to resolve this issue, any help will be highly appreciated

User-added image
trigger ContentDocumentTrigger on ContentDocument (after insert) {
    static boolean firstRun = true; 
    if(Trigger.isInsert && Trigger.isAfter){
        for(ContentDocument cd: trigger.new){ 
            if(firstRun){
                if(cd.ownerid!=null){
                    List<user> userlist = [SELECT id,Profile.UserLicense.Name from user WHERE id=:cd.ownerid AND Profile.UserLicense.Name='Partner Community'];
                    if(!userlist.isempty()){
                        List<Partner_Upload_Email_Addresses__mdt> custmeta = [select id,Email_Addresses__c from Partner_Upload_Email_Addresses__mdt];
                        String[] toAddresses = new String[]{};
                            for(Partner_Upload_Email_Addresses__mdt custemailvales: custmeta){
                                toAddresses.add(custemailvales.Email_Addresses__c);
                            }
                        Messaging.Singleemailmessage email = new Messaging.Singleemailmessage();
                        email.setReplyTo('manjuzmail053@gmail.com');
                        email.setSenderDisplayName('Partner Upload File ');
                        //String[] toAddresses = new String[] {'manjuzmail053@gmail.com'};
                        if(!toAddresses.isempty()){
                            email.setToAddresses(toAddresses);
                            String body = '<html><body>Please note: A new document has been added\n \n ';
                            body += 'File name: '+ cd.title+'\n\n' ;
                            body += 'Created By: '+ cd.createdbyid+ '\n\n';
                            body += 'Created Date: '+ cd.CreatedDate+ '\n\n';
                            body += 'link to file: https://moengage--partnersf.lightning.force.com/lightning/r/ContentDocument/'+cd.id+'/view </body></html>';
                            email.setSubject('A new file is uploaded by your Partner with file name :  '+cd.Title);
                            email.setHtmlBody(body);
                            Messaging.sendEmail(new Messaging.SingleEmailmessage[] {email});
                            firstRun = false;
                        }
                    }
                }
            }
        }
    }
}

@isTest
public class ContentDocumentTestclass {
    public static testmethod void ContentDocumentInsertTest()
    {
        List<user> userlist = [SELECT id,Profile.UserLicense.Name,isactive from user WHERE Profile.UserLicense.Name='Partner Community' AND isactive=true];
        
        System.runAs(userlist[1]) {
            // The following code runs as user 'u' 
            System.debug('Current User: ' + UserInfo.getUserName());
            System.debug('Current Profile: ' + UserInfo.getProfileId());

            ContentVersion contentVersionInsert = new ContentVersion(
                Title = 'Tes11t',
                PathOnClient = 'Test1.jpg',
                VersionData = Blob.valueOf('Test 11Content Data'),
                IsMajorVersion = true
            );
            insert contentVersionInsert;
            system.debug('User' + UserInfo.getUserName());
            List<ContentDocument> documents = [SELECT Id, Title, LatestPublishedVersionId FROM ContentDocument];
        }
    }
}

 
Hello Experts

I am New to the Salesforce Ecosystem, i am trying to design a functionality where custom reports needs to be sent via Email With attachment, i know this beta version, but i need to design through customization, i have researched a lot and finally came up with the link

https://blogs.absyz.com/2018/09/27/sending-reports-to-email-as-an-attachment/

i have done exactly the same but dont know why its not working, could any one 

Visualforce Component
 
<apex:component controller="ReportsToEmailController" access="global">
    <apex:attribute name="ReportId" description="Report ID" type="Id" assignTo="{!rptId}"/>
    <apex:outputPanel>         
        <table style="width: 100%;">
            <thead>                 
                <apex:repeat value="{!ReportResult.reportMetadata.detailColumns}" var="colName"> 
 
                    <!-- reportMetadata is a class where it contains metadata of a report.
                        DetailColumns is a method of ReportMetadata class, it returns the API names (Columns Names) 
                            for the fields that contain detailed data-->
 
                    <th><apex:outputText value="{!ReportResult.reportExtendedMetadata.detailColumnInfo[colName].label}"/></th>
 
                    <!-- reportExtendedMetadata is class where it contains Report extended metadata and
                            it provides data type and label information.
                        detailColumnInfo is a method of reportExtendedMetadata class, it returns map of columns names 
                            and its label to Display as Header -->
 
                </apex:repeat> 
            </thead> 
            <tbody> 
                <apex:repeat value="{!ReportResult.factMap['T!T'].rows}" var="row" rows="999"> 
                    <!-- Here we will get entire data of each row and T refers to the Row -->
                    <tr> <apex:repeat value="{!row.dataCells}" var="cell">
                        <!-- Here we will get data of each cell and displayed -->
                        <td><apex:outputText value="{!cell.label}"/></td>
                        </apex:repeat> </tr> 
                </apex:repeat>
            </tbody>
        </table>
    </apex:outputPanel> 
</apex:component>

Apex Controller: ReportsToEmailController
 
public class ReportsToEmailController {
    public Id rptId { get; set; } // Here we will get the report Id from the VF Component
    private transient Reports.ReportResults results; // It will hold the entire data of a report
 
    /*********************
     // Method Name : getReportResult
     // Description : Here we will get the data of a report and send to the VF Component
    /********************/
 
    public Reports.ReportResults getReportResult() {
        // Here it will run the report with that report ID and adding the report data into results
        results = Reports.ReportManager.runReport(rptId, true);
        return results;
    }
}

My custom VF template where 
 
<messaging:emailTemplate subject="Report" recipientType="User" >
    <messaging:plainTextEmailBody >
        Hi {!recipient.FirstName}
        Please find the below attachments. 
 
    </messaging:plainTextEmailBody>
    <messaging:attachment filename="Opp Record Report.xls">
        <!-- Here we can add multiple Reports -->
        <c:ReportsToEmail ReportId="00O2w000003DegwEAC"/>
        <c:ReportsToEmail ReportId="00O2w000003DegwEAC"/>
    </messaging:attachment>
</messaging:emailTemplate>


Next i have Designed workflow rule where when checkbox update  with Email alert, but i am not recieveing any mails, Any help will be highly appreciated


 
Hello Developers

i am new to the apex development, i have been given a task for creating Triggers to prevent duplicate records on multiple fields , i know this is can be achived through Duplicate Rules, but still i want to try with the Apex trigger

Assignedto__c (Lookup(User)

Quater_Year__c(Picklist)

Month__c(Picklist)

i want to create a Duplication rule on these 3 fields, 

i refered the below link, but i could not get the correct code

https://www.mstsolutions.com/technical/preventing-duplicate-records-based-on-multiple-fields-in-salesforce/

 
Hello Everyone

I need some help and suggestion regarding the email alert when lead is not modified for 24 Hrs, i tried with the workflow alert and time based Triggers but it was not working, 
Workflow rule:-

Evaluation criteria:- Every time record is created & subsequently meet criteria

Formula:- LastmodifiedDate=Created Date

and Created a Timetrigger actions for 24 Hrs, but it did not fire

I have Faced a lot of issues with Workflows and Prosess Builders, so i need help for designing a Batch class When Lead  is Created and if the lead is not modified for 24Hrs it should send an Email alert
This is what i have come up with till now
global class Emailalertbatchclass implements Database.Batchable<sObject>, Schedulable, Database.Stateful {

    //Variable Section
    global FINAL String strQuery;
    global List<String> errorMessages = new List<String>();
    
    global Emailalertbatchclass() { 
        this.strQuery = getBatchQuery();
    }
    
    //Returns the Query String to Batch constructor to fetch right records.
    private String getBatchQuery() {
        String strQuery = 'SELECT Id, name, Owner.Email FROM Lead WHERE CreatedDate >= YESTERDAY'; 
        return strQuery;
    }
    
    //Batch Start method
    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator(strQuery);
    }

    //Batch Execute method calls findCostForWoD method
    global void execute(Database.BatchableContext BC, List<sObject> scopeList) {
        System.debug(LoggingLevel.INFO, '== scopeList size ==' + scopeList.size());
        
        List<Lead> ld = (List<Lead>) scopeList;
        if(!ld.isEmpty()) { 
            List<Messaging.SingleEmailMessage> mailList = new List<Messaging.SingleEmailMessage>();
            for (Lead prod : ld)
            {               
                
                Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage(); 
                String[] toAddresses = new String[] {prod.Owner.Email};
                Message.setToAddresses(toAddresses); 
                Message.SaveAsActivity = false;
                mailList.add(Message);
                
            }
            if(!mailList.isEmpty()) {
                try{
                    Messaging.sendEmail(mailList);
                }
                catch (Exception ex) {
                    errorMessages.add('Unable to send email to Tech: '+ ex.getStackTraceString());
                }
            }
        }
    }  

    //Batch Finish method for after execution of batch work
    global void finish(Database.BatchableContext BC) { 
        AsyncApexJob aaj = [Select Id, Status, NumberOfErrors, JobItemsProcessed, MethodName, 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[] {aaj.CreatedBy.Email};
        mail.setToAddresses(toAddresses);
        mail.setSubject('JOB Salesforce Send Notification Batch: ' + aaj.Status);
        String bodyText='Total Job Items ' + aaj.TotalJobItems + ' Number of records processed ' + aaj.JobItemsProcessed + ' with '+ aaj.NumberOfErrors + ' failures.\n';
        bodyText += 'Number of Error Messages ' + errorMessages.size() + '\n';
        bodyText += 'Error Message' + String.join(errorMessages, '\n');
        mail.setPlainTextBody(bodyText);
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
    
    //Method which schedules the ProductDownloadBatch
    global void execute(SchedulableContext sc) {        
        Emailalertbatchclass snInstance = new Emailalertbatchclass();
        ID batchprocessid = Database.executeBatch(snInstance);
    }
}
Any help would be Highly Appericiated 



 
Hello Salesforce Expertrs 

i am new to the salesforce and i am trying to write test class for the Content document trigger, So when partner user tries a Upload a document through files, automatically he gets email saying that document has been uploaded with the document link, the trigger was successful and with great difficulty i wrote a test class with 100% code coverage, but when i see the test result i see that there is erro "INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY" i have checked in the profile, as well as the OWD settings, still i was not able to resolve this issue, any help will be highly appreciated

User-added image
trigger ContentDocumentTrigger on ContentDocument (after insert) {
    static boolean firstRun = true; 
    if(Trigger.isInsert && Trigger.isAfter){
        for(ContentDocument cd: trigger.new){ 
            if(firstRun){
                if(cd.ownerid!=null){
                    List<user> userlist = [SELECT id,Profile.UserLicense.Name from user WHERE id=:cd.ownerid AND Profile.UserLicense.Name='Partner Community'];
                    if(!userlist.isempty()){
                        List<Partner_Upload_Email_Addresses__mdt> custmeta = [select id,Email_Addresses__c from Partner_Upload_Email_Addresses__mdt];
                        String[] toAddresses = new String[]{};
                            for(Partner_Upload_Email_Addresses__mdt custemailvales: custmeta){
                                toAddresses.add(custemailvales.Email_Addresses__c);
                            }
                        Messaging.Singleemailmessage email = new Messaging.Singleemailmessage();
                        email.setReplyTo('manjuzmail053@gmail.com');
                        email.setSenderDisplayName('Partner Upload File ');
                        //String[] toAddresses = new String[] {'manjuzmail053@gmail.com'};
                        if(!toAddresses.isempty()){
                            email.setToAddresses(toAddresses);
                            String body = '<html><body>Please note: A new document has been added\n \n ';
                            body += 'File name: '+ cd.title+'\n\n' ;
                            body += 'Created By: '+ cd.createdbyid+ '\n\n';
                            body += 'Created Date: '+ cd.CreatedDate+ '\n\n';
                            body += 'link to file: https://moengage--partnersf.lightning.force.com/lightning/r/ContentDocument/'+cd.id+'/view </body></html>';
                            email.setSubject('A new file is uploaded by your Partner with file name :  '+cd.Title);
                            email.setHtmlBody(body);
                            Messaging.sendEmail(new Messaging.SingleEmailmessage[] {email});
                            firstRun = false;
                        }
                    }
                }
            }
        }
    }
}

@isTest
public class ContentDocumentTestclass {
    public static testmethod void ContentDocumentInsertTest()
    {
        List<user> userlist = [SELECT id,Profile.UserLicense.Name,isactive from user WHERE Profile.UserLicense.Name='Partner Community' AND isactive=true];
        
        System.runAs(userlist[1]) {
            // The following code runs as user 'u' 
            System.debug('Current User: ' + UserInfo.getUserName());
            System.debug('Current Profile: ' + UserInfo.getProfileId());

            ContentVersion contentVersionInsert = new ContentVersion(
                Title = 'Tes11t',
                PathOnClient = 'Test1.jpg',
                VersionData = Blob.valueOf('Test 11Content Data'),
                IsMajorVersion = true
            );
            insert contentVersionInsert;
            system.debug('User' + UserInfo.getUserName());
            List<ContentDocument> documents = [SELECT Id, Title, LatestPublishedVersionId FROM ContentDocument];
        }
    }
}