function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
krios demokrios demo 

How to display LWC modal popup when opportunity Stage change to Closed Won.

I have a scenario. When user mark the Opportunity Stage as "Indent" i.e. "Closed Won" then LWC modal popup should be opened. 

I have developed the LWC modal popup. When User mark the Stage "Indent" as close then trigger will fire and platform event will be published. from that Platform event I sent the Current Opportunity Record ID, Current Logged In User ID, and Message.

I have subscribed the platform event in JS file and on the condition of Current UserID & Current Opportunity Record ID I am displaying the Modal popup.

if (objData.OpportunityId__c === self.recordId && obj.data.payload.
UserId__c === self.Current_UserId) 
{
console.log("Inside If Condition");
//this.message = objData.message__c;
self.OpenModal();
}

But issue which i am facing that when i indent the opportunity then modal popup will be opened to another users thos who are working on opportunities. 

Expected Result: when user indent the Opportunity then immediately modal should be opened only for that opportunity and for the same logged in user. 

Below is my Trigger and JS files.

Trigger:
trigger OpportunityStageTrigger on Opportunity (before update) {
    
    Map<Id, String> oldStageMap = new Map<Id, String>();
    List<OpportunityActivityEvent__e> eventList = new List<OpportunityActivityEvent__e>();
    
    for (Opportunity opp : Trigger.old) {
        oldStageMap.put(opp.Id, opp.StageName);
    }
    
    for (Opportunity opp : Trigger.new) {
        if (oldStageMap.containsKey(opp.Id)) {
            
            String oldStage = oldStageMap.get(opp.Id);
            String newStage = opp.StageName;
            
            if (oldStage != newStage) {
                if (oldStage != 'Indent' && newStage == 'Indent') {
                    
                    // opp.IsStageChanged__c = false;
                    opp.IsStageChanged__c = true;
                    
                    OpportunityActivityEvent__e event = new OpportunityActivityEvent__e();
                    event.message__c = 'Opportunity ' + opp.Name + ' has been closed as won.';
                    event.OpportunityId__c = opp.Id;
                    event.UserId__c = UserInfo.getUserId();
                    
                    System.debug('Event Message =>'+event.message__c);
                    System.debug('Current Opportunity RecordId:'+ event.OpportunityId__c);
                    System.debug('Current Logged In UserId:'+ event.UserId__c);
                    
                    eventList.add(event);
                    System.debug('Value Added to list');
                    
                    if (!eventList.isEmpty()) {
                        EventBus.publish(eventList);
                        System.debug(eventList);
                       }
                } 
            }
        }
    }
}
=====================================================
JS file:

import { LightningElement, api, wire, track} from 'lwc';
import getOppDetails from '@salesforce/apex/DealWonVerification.getOppDetails'; 
import getOpportunityLineItems from '@salesforce/apex/DealWonVerification.getOpportunityLineItems'; 
import getOrdersdetails from '@salesforce/apex/DealWonVerification.getOrdersdetails';
import toSendEmailWithTemplate from '@salesforce/apex/DealWonVerification.toSendEmailWithTemplate';
import getSaveData from '@salesforce/apex/DealWonVerification.getSaveData';
import { subscribe, unsubscribe, onError, setDebugFlag, isEmpEnabled } from 'lightning/empApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { refreshApex } from '@salesforce/apex';
import User_ID from '@salesforce/user/Id';
export default class Vip_DealWonVerification extends LightningElement {
    @api recordId;
    Current_UserId = User_ID;
    @track message;
    subscription = {};
    @api channelName = '/event/OpportunityActivityEvent__e';
    ShowModal = false;
    EditButton = false;
    booleanv = true;
    booleanvar = true;
    sendboolean = false;
    // Opportunity Properties
    @track OpportunityData;
    Opp_Id;
    Opp_Name;
    Acc_Name;
    Close_Date;
    Amt;
    Opp_Stage;
    @track RSCM;
    @track RSales;
    // Product Properties
    @track ProductData;
    @track Colour;
    @track Customization;
    @track Packing;
    @track New_Code_Required;
    @track OrderData;
    // handlechangeproperties
    RemarksSales;
    RemarksSCM;
    Prod_Colour;
    Prod_Customization;
    Prod_Packing;
    Prod_NewCode;

    OpenModal(){
        
        this.ShowModal = true;
    }
    
    CloseModal(){
        this.ShowModal = false;
        this.booleanv = true;
    }
    
    connectedCallback() {
        // Display Server Error     
        this.registerErrorListener();
        this.handleSubscribe();
    }
    registerErrorListener() {
        onError(error => {
            console.log('Received error from server: ', JSON.stringify(error));
        });
    }
    handleSubscribe() {
        console.log("Inside the handleSubscriber Function");
        const self = this;
        console.log("before messageCallback");
        const messageCallback = function (response) {
            console.log("Inside the messageCallback");
            console.log('Message Received in JSON Format ===>: ', JSON.stringify(response));
            console.log('Message Received===> ', response);
            var obj = JSON.parse(JSON.stringify(response));
            const Opp_Id = obj.data.payload.OpportunityId__c;
            const Curr_UserId = obj.data.payload.UserId__c;
            console.log(obj.data.payload);
            console.log(obj.data.payload.message__c);
            console.log(Opp_Id, "and", self.recordId);
            console.log(Curr_UserId , "and", self.Current_UserId);
            console.log(self.channelName);
            let objData = obj.data.payload;
            console.log("Before If Condition");
           if (objData.OpportunityId__c === self.recordId && obj.data.payload.UserId__c === self.Current_UserId) {
               console.log("Inside If Condition");
                //this.message = objData.message__c;
               self.OpenModal();
           }
        };
        subscribe(this.channelName, -1, messageCallback).then(response => {
            // Response contains the subscription information on subscribe call
            console.log('Subscription request sent to: ', JSON.stringify(response.channel));
            this.subscription = response;
        });
    }
    ShowToast(title, message, variant, mode) {
        const evt = new ShowToastEvent({
            title: title,
            message: message,
            variant: variant,
            mode: mode
        });
        this.dispatchEvent(evt);
    }
    @wire (getOppDetails,{OppId:'$recordId'}) 
    wiredOppData({error, data}){
        if(data){
            this.OpportunityData = data;
            console.log("Wired Opportunity Data:", this.OpportunityData);
            this.error = undefined;
            // Opportunity Fields
            this.Opp_Id = this.OpportunityData[0].Id;
            console.log('Opportunity Id =>', this.OpportunityData[0].Id);
            this.Opp_Name = this.OpportunityData[0].Name;
            console.log('Opportunity Name =>',this.OpportunityData[0].Name); 
            this.Acc_Name = this.OpportunityData[0].Account.Name;
            console.log('Account Name =>',this.OpportunityData[0].Account.Name);
            this.Close_Date = this.OpportunityData[0].CloseDate;
            console.log('Close Date =>',this.OpportunityData[0].CloseDate);
            this.Amt = this.OpportunityData[0].Amount;
            console.log('Amount =>',this.OpportunityData[0].Amount);
            this.Opp_Stage = this.OpportunityData[0].StageName;
            console.log('Opportunity Stage =>', this.Opp_Stage);
            this.RSCM = this.OpportunityData[0].Remark_by_SCM__c;
            console.log('Remarks By SCM =>', this.OpportunityData[0].Remark_by_SCM__c);
            this.RSales = this.OpportunityData[0].Remarks_by_the_Sales__c;
            console.log('Remarks By Sales =>',this.OpportunityData[0].Remarks_by_the_Sales__c);
        } else if(error){
            this.error = error;
            this.OpportunityData = undefined;
        }
    }
    @wire (getOpportunityLineItems, {OppId: '$recordId'})
    wiredProdData ({error, data}){
        if(data){
            this.ProductData = data;
            console.log("Wired Opportunity Line Item Data:", this.ProductData);
            this.error = undefined;
            this.Colour = this.ProductData[0].Colour__c;
            console.log('Colour:',this.ProductData[0].Colour__c);
            this.Customization = this.ProductData[0].Customization__c;
            console.log('Customization:', this.ProductData[0].Customization__c);
            this.Packing = this.ProductData[0].Packing__c;
            console.log('Packing:', this.ProductData[0].Packing__c);
            this.New_Code_Required = this.ProductData[0].New_Code_Required__c;
            console.log('New Code Required:',this.ProductData[0].New_Code_Required__c);
        }else if(error){
            this.error = error;
            this.ProductData = undefined;
        }
    }
    @wire (getOrdersdetails,{OppId: '$recordId'})
    wiredOrdData({error, data}){
        if(data){
            this.OrderData = data;
            console.log("Wired Order data:", this.OrderData);
            this.errorv = undefined;
        }else if(error){
            this.error = error;
            this.OrderData = undefined;
        }
    }
    handleEdit(event){
        this.EditButton = true;
        this.booleanvar = false;
        this.sendboolean = true;
        console.log("Inside the Edit Action");
        this.Opt.Remark_by_SCM__c = event.target.value;
        this.Opt.Remarks_by_the_Sales__c = event.target.value;
        this.OppLineIt.Colour__c = event.target.value;
        this.OppLineIt.Customization__c = event.target.value;
        this.OppLineIt.Packing__c = event.target.value;
        this.OppLineIt.New_Code_Required__c = event.target.value;
    }
    handleChange(event){
        if(event.target.name === 'RemarksBySales'){
            this.RemarksSales = event.target.value;
            console.log('Updated Remarks By Sales', this.RemarksSales);
        }
        if(event.target.name === 'RemarksBySCM'){
            this.RemarksSCM = event.target.value;
            console.log('Updated Remarks By SCM', this.RemarksSCM);
        }
        if(event.target.name === 'Colour'){
            this.Prod_Colour = event.target.value;
            console.log('Updated Colour:', this.Prod_Colour);
        }
        if(event.target.name === 'Customization'){
            this.Prod_Customization = event.target.value;
            console.log('Updated Customization value:', this.Prod_Customization);
        }
        if(event.target.name === 'Packing'){
            this.Prod_Packing = event.target.value;
            console.log('Updated Packing Value: ', this.Prod_Packing);
        }
        if(event.target.name === 'NewCode'){
            this.Prod_NewCode = event.target.value;
            console.log('Updated New Code: ', this.Prod_NewCode);
        }
    }
    // handle save operation should be async
    async handleSave(){
        console.log('Inside the Save Action');
        this.booleanvar = true;
        this.sendboolean = false;
        getSaveData ({OppId: this.recordId, remarksbyscm: this.RemarksSCM, remarksbysales: this.RemarksSales, colr: this.Prod_Colour, customization: this.Prod_Customization, packing: this.Prod_Packing, newcoderequired: this.Prod_NewCode})
        .then(result =>{
            console.log('Inside data');
            this.data = result;
            console.log('DATA ::',this.data);
     
                const evt = new ShowToastEvent({
                    title: 'Save Data',
                    message: 'Save sucessfully',
                    variant: 'success',
                    mode: 'dismissable'
                });
                this.dispatchEvent(evt);
                console.log("Event Dispatched...!");
                // location.reload();
                refreshApex(this.wiredOppData);
        })
        .catch(error => {
            console.log('Inside error');
            this.error = error;
            console.log('Error ::',this.error);
        })
    }
    handleSendEmail(){
        
        console.log('Inside the Send Email Method');
        toSendEmailWithTemplate({OppId: this.recordId})
        .then((data) => {
            console.log('Email sent successfully:', data);
            
            const evt = new ShowToastEvent({
                title: 'Send Indent Email',
                message: 'Email Send Successfully',
                variant: 'success',
                mode: 'dismissable'
            });
            this.dispatchEvent(evt);
          })
          .catch((error) => {
            console.error('Error sending email:', error);
          });
    }
}

 
SubratSubrat (Salesforce Developers) 
Hello ,

Currently, you are checking if the Opportunity ID from the platform event matches the current record ID and if the User ID from the platform event matches the current logged-in User ID. This condition will always evaluate to true for any user who is currently viewing the Opportunity record.

To ensure that the modal popup is only displayed to the user who marked the Opportunity as "Closed Won," you can modify the condition as follows:
if (objData.OpportunityId_c === self.recordId && obj.data.payload.UserId_c === self.Current_UserId) {
    self.OpenModal();
}
Here, instead of checking the current User ID, you are comparing it with the User ID received from the platform event payload. This way, the modal popup will only be displayed to the specific user who triggered the event.

Make sure to update the condition in your JavaScript file accordingly and test it with the updated logic.

Thank you.