-
ChatterFeed
-
167Best Answers
-
1Likes Received
-
0Likes Given
-
4Questions
-
1416Replies
Need help on trigger with Map collection
Hi All,
Follwing trigger is not working ,Can someone help ?
I couldn't find much in the debug log except a query run.
(following snippet can be simply pasted in the dev org for quick review )
trigger A_ConPhoneFromCON on Contact (before insert, before update) { // Create a map to store the Account IDs and their corresponding phone numbers Map<Id, contact> accountIdToPhone = new Map<Id, contact>(); for (Contact updatedContact : Trigger.new) { // Check if the Contact has an associated Account if (updatedContact.AccountId != null) { // Add the related Account's ID and phone number to the map accountIdToPhone.put(updatedContact.AccountId, updatedContact); } } // Retrieve the related Account records and update the Contacts' phone numbers List<Account> relatedAccounts = [SELECT Id, Phone FROM Account WHERE Id IN :accountIdToPhone.keySet()]; for (Contact updatedContact : Trigger.new) { // Check if the Contact is associated with an Account if (updatedContact.AccountId != null) { // Update the Contact's phone number with the related Account's phone number updatedContact.Phone = accountIdToPhone.get(updatedContact.AccountId).phone; } } }
- Sridhar Reddy
- November 05, 2023
- Like
- 0
- Continue reading or reply
How to make 2 API calls for same endpoint in Synchronous Call
I'm making an synchronous call where I need to get more than 6MB. so I want to split the call and make 2 request.
For example, If I want to request 10,000 records to an external system then I need to request,
- 1-6000 in first API request call and
- 6001-10,000 in second API request call
Thanks you.
- Shyamala Varadharajan
- September 07, 2023
- Like
- 0
- Continue reading or reply
Create test class for this
public with sharing class LeadProcessor {
public static void updateLeadStatus(List<Lead> leadsToUpdate) {
Set<Id> accountIds = new Set<Id>();
// Loop through the leads and collect the Account Ids
for (Lead lead : leadsToUpdate) {
accountIds.add(lead.AccountId);
}
// Query the related Accounts to check for duplicate leads
List<Account> relatedAccounts = [SELECT Id, (SELECT Id, Email FROM Leads) FROM Account WHERE Id IN :accountIds];
Map<String, Set<String>> emailToLeadIds = new Map<String, Set<String>>();
// Loop through the related Accounts and Leads and create a map of Email to Lead Ids
for (Account account : relatedAccounts) {
for (Lead lead : account.Leads) {
if (lead.Email != null) {
String emailKey = lead.Email.toLowerCase();
if (emailToLeadIds.containsKey(emailKey)) {
emailToLeadIds.get(emailKey).add(lead.Id);
} else {
Set<String> leadIds = new Set<String>{lead.Id};
emailToLeadIds.put(emailKey, leadIds);
}
}
}
}
// Loop through the leads and check for duplicates based on Email
for (Lead lead : leadsToUpdate) {
if (lead.Email != null) {
String emailKey = lead.Email.toLowerCase();
if (emailToLeadIds.containsKey(emailKey) && !emailToLeadIds.get(emailKey).contains(lead.Id)) {
lead.addError('This Lead has the same email address as another Lead in the related Account.');
} else {
if (lead.Status == 'New') {
lead.Status = 'Open';
}
}
}
}
update leadsToUpdate;
}
}
- Andrew marshal 3
- April 26, 2023
- Like
- 0
- Continue reading or reply
how to connect my visualforce page with a class
here my class code
public class CatFactsDaily { public String catFact3{get;set;} public void toGetFacts() { String requestEndPoint = 'https://catfact.ninja/fact'; Http http=new Http(); HttpRequest request = new HttpRequest(); request.setEndpoint(requestEndPoint); request.setMethod('GET'); HttpResponse response=http.send(request); if(response.getStatusCode()==200){ Map<String, Object> results=(Map<String, Object>) JSON.deserializeUntyped(response.getBody()); catFact3=String.valueOf(results.get('fact')); } else { ApexPages.Message myMsg=new ApexPages.Message(ApexPages.Severity.ERROR, 'There was an error in reading Data'); ApexPages.addMessage(myMsg); } } }
here is my visualforce code
<apex:page controller="CatFactsDaily" > <apex:pageBlock title="Cat Fact of the day!!"> <apex:pageBlockSection > <apex:pageMessages ></apex:pageMessages> <apex:outputText label="CatFact" value="{!catFact3}"></apex:outputText> </apex:pageBlockSection> </apex:pageBlock> </apex:page>
and this is what i get
I ve tried this same api with for and account, and it works, but i cannot make it work for the home page
- Marjan Koneski
- December 08, 2022
- Like
- 0
- Continue reading or reply
Validation Rule for choosing any value in the picklist field making a text field mandatory
I previously created this VR and it was working fine until (at a later date) a 5th value was added to the picklist at which time I adjusted the numbers and values in the VR, but only the first picklist value was firing.
AND(
CASE( PICKLIST_FIELD__ c,
"Value 1",1,
"Value 2",2,
"Value 3",3,
"Value 4",4,
"Value 5",5,
0 ) = 1,
ISBLANK( TEXT_FIELD__c )
)
As a quick workaround I created five VRs, but would like to fix the above VR and remove the five VRs. Here's one of five VRs that's working:
AND(
ISPICKVAL( PICKLIST_FIELD__ c , "Value 1") ,
ISBLANK( TEXT_FIELD__c )
)
I'd appreciate any guidance! Thank you in advance! :)
- Fatemeh
- November 13, 2022
- Like
- 0
- Continue reading or reply
System.AsyncException: Based on configured schedule, the given trigger 'SCHEDULED_APEX_JOB_TYPE.000000000000000' will never fire.
*/
@isTest
public class NightlyDepositBatchTest {
public static String CRON_EXP = '0 0 0 15 3 ? 2022';
@testSetup
static void setup() {
List donations = new List();
for (Integer i=0;i donList = [SELECT Id, Donation_Use__c, Tributee__c, Gift_Type__c, Amount__c, GL_Code__c FROM Donations__c];
for(Donations__c donation: donList){
Test.setCreatedDate(donation.id, Datetime.newInstance(date.today(), Time.newInstance(0,0,0,0)).addDays(-1));
}
update donList;
}
@isTest static void test() {
Test.startTest();
NightlyDepositBatch uca = new NightlyDepositBatch(Date.today());
Id batchId = Database.executeBatch(uca);
Test.stopTest();
// after the testing stops, assert records were created properly
List depositLines = [SELECT Id,SUM(Amount__c) FROM QB_Deposit_Line__c GROUP BY Id LIMIT 1];
System.assertEquals(100, (Decimal)depositLines[0].get('expr0'));
}
@isTest static void test2() {
Test.startTest();
String jobId = System.schedule('ScheduledApexTest',
CRON_EXP,
new NightlyDepositSchedule());
Test.stopTest();
}
}
Unit test now returning error when deploying new test cases for other development being done and this test case not firing the scheduled test job. I have been searching for how to fix the test case and am not finding how to best resolve in the sandbox to update this and get any coverage listed for the Nightly Batch Schedule job in production.
With this above issue not able to get code coverage on this job -
global class NightlyDepositSchedule implements Schedulable{
global void execute(SchedulableContext sc) {
NightlyDepositBatch n1 = new NightlyDepositBatch(Date.today());
ID batchprocessid = Database.executeBatch(n1,Test.isRunningTest() ? 3 : 1);
}
}
- Lori Buchowicz
- November 13, 2022
- Like
- 0
- Continue reading or reply
How can I escape the double quotes and backslashes added in the string when making api call?
11:01:27.11 (14669480)|USER_DEBUG|[29]|DEBUG|{"User": {"account_expires" : "2022-11-18"}}but it seems variable assignment actually looks lke:
11:01:27.11 (14553531)|VARIABLE_ASSIGNMENT|[27]|body|"{\"User\": {\"account_e (24 more) ..."I am thinking I need to deseralize the JSON maybe by using another class but am having trouble with this. At the moment, the response I am receiving is:
11:01:28.153 (1172417713)|CALLOUT_RESPONSE|[34]|System.HttpResponse[Status=Not Found, StatusCode=404] 11:01:28.153 (1172459328)|HEAP_ALLOCATE|[34]|Bytes:90 11:01:28.153 (1172492874)|VARIABLE_SCOPE_BEGIN|[34]|response|System.HttpResponse|true|false 11:01:28.153 (1172567949)|VARIABLE_ASSIGNMENT|[34]|response|"System.HttpResponse[Status=Not Found, StatusCode=404]"|0x733b55dd
Does anyone have an idea to help me edit the below code so that I can receive the successful response?
Thanks!
public class LearnUponCalloutClass { @future(callout=true) public static void makeCallout(Integer UserId) { //declare variables String username = 'XYZ'; String password = 'XYZ'; //prepare request HTTP h = new HTTP(); HTTPRequest r = new HTTPRequest(); //set endpoint and authorize r.setEndpoint('https://dphie.learnupon.com/api/v1/users/' + UserId); Blob headerValue = Blob.valueOf(username + ':' + password); String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue); r.setHeader('Authorization', authorizationHeader); r.setMethod('PUT'); String body = '{"User": {"account_expires" : "2022-11-18"}}'; System.debug(body); r.setBody(body); //send request HTTPResponse response = h.send(r); }
- Jason Adler 14
- November 12, 2022
- Like
- 0
- Continue reading or reply
Automation using Flow/Apex
- First I need to find the users who have this particular profile and PS7.
- Then I need to check if the users having PS7 and this profile have all the permission sets (PS1-10) assigned to them.
- If there are less permission sets assigned, then return Missing, if there are more permission sets assigned, return Additional, else return No Change. I need to implement this using either Flow or Apex.
- The final output should give me the userID, the permission sets assigned to them and Missing/Additional/No change
Thank you
- SOURAV GUHA 9
- November 08, 2022
- Like
- 0
- Continue reading or reply
Find opened and closed cases using map
The following is not working, please suggest what is wrong.
// Trigger should update contact with total tickets : closed and Opened trigger Prac_caseUtil on Case (after insert, after delete, after update) { map<id,List<case>> caseMap = new map<id,list<case>>(); for(case caseObject : trigger.new){ if(caseObject.accountid !=NULL && caseMap.get(caseObject.accountid)==NULL){ caseMap.put(caseObject.accountid,new LIST<case>()); caseMap.get(caseObject.AccountId).add(caseObject); } } // SOQL LIST<contact> conListToUpdateOpen = [SELECT Id,Total_Open_Tickets__c,Total_Closed_Tickets__c,(SELECT ID FROM Cases WHERE IsClosed=FALSE) FROM CONTACT WHERE ID IN:caseMap.keySet()]; LIST<contact> conListToUpdateClosed = [SELECT Id,Total_Open_Tickets__c,Total_Closed_Tickets__c,(SELECT ID FROM Cases WHERE IsClosed=TRUE) FROM CONTACT WHERE ID IN:caseMap.keySet()]; for(contact c:conListToUpdateOpen){ c.Total_Open_Tickets__c = caseMap.get(c.id).size(); system.debug('###### open tickets' + caseMap.get(c.id).size()); } for(contact c:conListToUpdateClosed){ c.Total_Closed_Tickets__c = caseMap.get(c.id).size(); system.debug('###### closed tickets' + caseMap.get(c.id).size()); } update conListToUpdateOpen; update conListToUpdateClosed; }
- Gary Singh (BlackBeltHelp)
- November 04, 2022
- Like
- 0
- Continue reading or reply
getting an error message-System.NullPointerException: Attempt to de-reference a null object
trigger congatransaction on APXT_CongaSign__Transaction__c (before INSERT) {
congatransactionHandler.congatransactionMethod(Trigger.NewMap,Trigger.OldMap);
}
public class congatransactionHandler {
public static void congatransactionMethod(Map<Id,APXT_CongaSign__Transaction__c> newconMap, Map<Id,APXT_CongaSign__Transaction__c> oldconMap){
Set<Id> conIds = New Set<Id>();
List<APXT_CongaSign__Transaction__c> conList = New List<APXT_CongaSign__Transaction__c>();
for(APXT_CongaSign__Transaction__c con : newconMap.values()){
APXT_CongaSign__Transaction__c oldcontranmap = oldconMap.get(con.Id);
if(oldconMap!=null && oldconMap.size()>0)
// Trigger.new records are conveniently the "new" versions!
{ //Boolean oldcontransactionmap = oldcontranmap.APXT_CongaSign__Status__c.equals('SENT');
if((newconMap.get(con.Id).Parent_a29__c== oldcontranmap.Parent_a29__c) && oldcontranmap.APXT_CongaSign__Status__c.equals('SENT')){
con.adderror('You have already sent the conga transaction');
}
}
}
}
}
- Swaroopa Akula 10
- November 03, 2022
- Like
- 0
- Continue reading or reply
Someone help me with this code, very urgent?
1. Write a method that takes in a list of Account Ids. The method should have the return type: map<Id, map<Id, list<OpportunityLineItem>>>. Each account Id passed in should be mapped to a map of its opportunities mapped to the list of their respective opportunity line items. Only opportunities with an amount of 500,000 or more should be included in the return. There is a custom boolean field on the opportunity line item with API name Export_Ignore__c. If this field is true, the account should be removed from the return map.
2. Write a SOSL statement that returns any leads or contacts where either the first or last name contains ‘cha’. Both lead and contact results should contain the email address, first name, and last name. Contacts should also include the account Id.
3. Write a SOQL statement that returns the Id of 10 accounts and all of the opportunity names associated with each account.
- Inbox Outbox
- October 31, 2022
- Like
- 0
- Continue reading or reply
Validation rule OR function
AND(ISBLANK(TEXT(Total_Size_c)), ISPICKVAL(Investment_Name_c,"XYZ"))
I want to add additional consideration for another picklist field. I want the above to kick in only if Type_c field is equal to “Addition” OR “New Investment”.
I am not sure how to add this. Can anyone help?
- Vanessa Ramic
- October 03, 2022
- Like
- 0
- Continue reading or reply
System.null pointer exception argument cannot be null
Im getting a null pointer exception butwhen when i debug it everyone argument has a value but still it is throwing null pointer exxeption . can anyone please guide me
- pavan Kumar.v
- September 11, 2022
- Like
- 0
- Continue reading or reply
If a field contains a value then use this formula to determine the output
IF(Acq_Comm_Calc__c CONTAINS $500),Estimated_Net_Profit_Retail_Renovation__c+500,
IF(AND Acq_Comm_Calc__c CONTAINS 8%),Estimated_Net_Profit_Retail_Renovation__c*0.08,
IF(AND Acq_Comm_Calc__c CONTAINS 10%),Estimated_Net_Profit_Retail_Renovation__c*0.1,
IF(AND Acq_Comm_Calc__c CONTAINS 12%),Estimated_Net_Profit_Retail_Renovation__c*0.12,
IF(AND Acq_Comm_Calc__c CONTAINS 15%),Estimated_Net_Profit_Retail_Renovation__c*0.15,
IF(Acq_Comm_Calc__c CONTAINS $7000),Estimated_Net_Profit_Retail_Renovation__c+7000,)
)
)
)
)
)
- Robin Thomas 19
- August 04, 2022
- Like
- 0
- Continue reading or reply
Hi Everyone, I need to bulkify my apex trigger code, can anyone help me..
Trigger: trigger PDFGenrate on Opportunity (after insert, after update) { Set<Id> OppIds= new Set<Id>(); for(Opportunity opp: trigger.new){ if(opp.StageName=='Closed Won'){ OppIds.add(Opp.Id); } }OpportunityPdfController.pdfGenration(OppIds); } Trigger Handler: public class OpportunityPdfController { @future(callout=true) public static void pdfGenration(Set<Id> OppIds){ List<Sobject> attachmentlist = new List<Sobject>(); List<Sobject> ContentDocLink = new List<Sobject>(); for(Id OppId: OppIds){ Blob body; PageReference pdf = new PageReference('/apex/PrintPDF'); pdf.getParameters().put('Id',OppId); ContentVersion cv=new ContentVersion(); try{ body=pdf.getContentAsPDF(); }catch (Exception e) { body = Blob.valueOf('Text'); system.debug(e.getMessage()); } cv.PathOnClient= 'Invoice'+'.pdf'; cv.Title= 'Invoice'; cv.IsMajorVersion = true; cv.VersionData=body; attachmentlist.add(cv); // } // if(attachmentlist.size()>0){ insert attachmentlist; Id conDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id =:cv.Id].ContentDocumentId; system.debug(conDocId); ContentDocumentLink cdl = New ContentDocumentLink(); cdl.LinkedEntityId = OppId; cdl.ContentDocumentId = conDocId; cdl.shareType = 'V'; ContentDocLink.add(cdl); insert ContentDocLink; } } }
- H 007
- August 03, 2022
- Like
- 0
- Continue reading or reply
Expression cannot be assigned &&
and digito_da_conta return null and if they do I have a method that updates this field directly from another object
if(opp.Conta__c = null && opp.Banco__c = null && opp.Agencia__c = null ){ CheckBankDataOfTheOpportunity(ssi,opp); }
private void CheckBankDataOfTheOpportunity(SelfSignIn__c ssi, Opportunity opp){ opp.Agencia__c = ssi.Agencia__c; opp.Banco__c = ssi.Banco__c; opp.Conta__c = ssi.Conta__c; }
- jOseMC
- July 28, 2022
- Like
- 0
- Continue reading or reply
Adding the Trigger in the Apex class in Salesforce
Created a Trigger when the ParentAccount is selected in account object ,need to copy the phone number and name and insert the record.
how can i add the Trigger in the Apex Class and Write Test Class...
trigger CopyAccountTriggerTest on Account (before insert) { if(checkRecursiveTest.runOnce()) { Set<Id> accountIds = new Set<Id>(); for (Account acc : Trigger.new) { if (acc.ParentId != null){ accountIds.add(acc.ParentId); } if(accountIds.size() > 0){ List<Account> accounts = [select id,Name,Phone from account where id in :accountIds ]; for (Account acc2 : Trigger.new) { if (acc2.ParentId != null){ acc2.Name = 'Duplicate'+accounts[0].Name; acc2.Phone= 'Duplicate'+accounts[0].Phone; } } } } } }
Apex Class:
=========
public class checkRecursiveTest { private static boolean run = true; public static boolean runOnce(){ if(run){ run=false; return true; }else{ return run; } } }
- Samantha Reddy
- March 22, 2022
- Like
- 0
- Continue reading or reply
How to create a Test Class for the Trigger , weather we need to add it so the Apex Class
trigger CopyAccountTriggerTest on Account (before insert) { if(checkRecursiveTest.runOnce()) { Set<Id> accountIds = new Set<Id>(); for (Account acc : Trigger.new) { if (acc.ParentId != null){ accountIds.add(acc.ParentId); } if(accountIds.size() > 0){ List<Account> accounts = [select id,Name,Phone from account where id in :accountIds ]; for (Account acc2 : Trigger.new) { if (acc2.ParentId != null){ acc2.Name = 'Duplicate'+accounts[0].Name; acc2.Phone= 'Duplicate'+accounts[0].Phone; } } } } } }
ApexClass:
public class checkRecursiveTest { private static boolean run = true; public static boolean runOnce(){ if(run){ run=false; return true; }else{ return run; } } }
UseCase In Account Object:
Created a Trigger when the ParentAccount is selected in account object ,need to copy the phone number and name and insert the record.
how can i add the Trigger in the Apex Class and Write Test Class...
Thanks
Samantha
- Samantha Reddy
- March 22, 2022
- Like
- 0
- Continue reading or reply
aggregate list into map
The list TR2 will have duplicate values for Supplier__c. I want to end up with map with count of records for each Supplier__c.
What needs to go in the for loop to get this ? Thanks
List<Trading_Relationship__c> Tr2 = [SELECT Supplier__c FROM Trading_Relationship__c WHERE Supplier__c IN :AccIds ORDER By Supplier__c ASC]; Map<ID, Integer> Map1 = new Map<ID, Integer>(); for (Trading_Relationship__c eachTr : Tr2){ }
- Andrew Gray
- March 22, 2022
- Like
- 0
- Continue reading or reply
Insert records from wrapper class
CONTROLLER:
public class ApartmentMapLister {
public Map_Lead__c MapLead {get;set;}
public Map_Point__c MapPoint {get;set;}
public Map<Integer, Map_Point__c> ApartmentMap {get;set;}
Public List<Wrapper> Wrapperlist {get;set;}
public ApartmentMapLister() {
MapLead = [SELECT ID, NAME, First_Name__c, Last_Name__c FROM Map_Lead__c WHERE ID=:ApexPages.currentPage().getParameters().get('id')];
}
public Map<Integer, Map_Point__c> getonebedadmin() {
Wrapperlist = new List<Wrapper>();
ApartmentMap = new Map<Integer, Map_Point__c>();
List<Map_Point__c> ApartmentList = [SELECT Id, Name, IsSelected__c FROM Map_Point__c Order By Name];
for(Map_Point__c mp: ApartmentMap.values()) {
Wrapper wrap = new Wrapper();
wrap.mappoint = mp;
Wrapperlist.add(wrap);
}
for(Integer index = 0 ; index < ApartmentList.size() ; index++) {
ApartmentMap.put(index, ApartmentList[index]);
}
return ApartmentMap;
}
public class Wrapper{
public boolean isSelected {get;set;}
public Map_Point__c mappoint {get;set;}
}
public void InsertApartment(){
for(Wrapper wr : Wrapperlist){
if(wr.mappoint.isSelected__c == true){
Map_List__c ml = new Map_List__c();
ml.Map_Lead__c=ApexPages.currentPage().getParameters().get('id');
ml.Map_Point__c=wr.mappoint.ID;
ml.Unique__c=(MapLead.NAME + wr.mappoint.AIMid__c);
insert ml;
}
}
}
public PageReference SaveRecords(){
List<Map_Point__c> records = new List<Map_Point__c>();
for(Map_Point__c df : ApartmentMap.values()) {
records.add(df);
}
// Bulk update with one DML call
update records;
return null;
}
}
VISUALFORCE PAGE:
<apex:page sidebar="false" showHeader="false" cache="true" id="page" docType="HTML" readOnly="false" controller="ApartmentMapLister">
<apex:form >
{!MapLead.First_Name__c} {!MapLead.Last_Name__c}
<apex:pageBlock >
<apex:pageBlockButtons location="top">
<apex:commandButton value="Save" action="{!InsertApartment}"/>
</apex:pageBlockButtons>
<apex:pageBlockTable value="{!onebedadmin}" var="Map_Point__c">
<apex:column >
<apex:inputField value="{!onebedadmin[Map_Point__c].IsSelected__c}"/>
</apex:column>
<apex:column >
<apex:inputField value="{!onebedadmin[Map_Point__c].Name}"/>
</apex:column>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:form>
</apex:page>
- jls_74_tx
- October 31, 2021
- Like
- 0
- Continue reading or reply
Salesforce Continuous Integration
I am looking to see the best approach for Salesforce CI. I have gone through many forum and blogs but haven't been able to grasp them. I tried to setup CI for the entire org but facing a lot of challeges which I guess you guys quite aware of.
What I am looking to do incremental deployment based on the git diff, dynamically generate package.xml based on the metadata committed which I think would be manageable something like sfdc-git-package https://www.npmjs.com/package/sfdc-git-package. I am having a hard time implementing this.
Please someone help
- Abdul Khatri
- March 03, 2018
- Like
- 1
- Continue reading or reply
Customize Sales Console Lightning Layout
- Abdul Khatri
- August 10, 2017
- Like
- 0
- Continue reading or reply
Hide Save & New Button from Task Page Layout
I looked at everywhere and couldn't find the solution. I do want to give them Create/Edit Permission so no option there to remove that.
Please help
- Abdul Khatri
- October 10, 2016
- Like
- 0
- Continue reading or reply
Custom URL for task create inline page?
urlConcat += '&inline=0';
urlConcat += '&isdtp=lt';
urlConcat += '&isdtp=nv';
urlConcat += '&isdtp=vw';
the only one that work is '&isdtp=nv' but after saving the activity, the hyperlink in the related list doesn't work. I have attached a screen shot
Anyone can help?
- Abdul Khatri
- October 03, 2016
- Like
- 0
- Continue reading or reply
Salesforce Continuous Integration
I am looking to see the best approach for Salesforce CI. I have gone through many forum and blogs but haven't been able to grasp them. I tried to setup CI for the entire org but facing a lot of challeges which I guess you guys quite aware of.
What I am looking to do incremental deployment based on the git diff, dynamically generate package.xml based on the metadata committed which I think would be manageable something like sfdc-git-package https://www.npmjs.com/package/sfdc-git-package. I am having a hard time implementing this.
Please someone help
- Abdul Khatri
- March 03, 2018
- Like
- 1
- Continue reading or reply
Need help on trigger with Map collection
Hi All,
Follwing trigger is not working ,Can someone help ?
I couldn't find much in the debug log except a query run.
(following snippet can be simply pasted in the dev org for quick review )
trigger A_ConPhoneFromCON on Contact (before insert, before update) { // Create a map to store the Account IDs and their corresponding phone numbers Map<Id, contact> accountIdToPhone = new Map<Id, contact>(); for (Contact updatedContact : Trigger.new) { // Check if the Contact has an associated Account if (updatedContact.AccountId != null) { // Add the related Account's ID and phone number to the map accountIdToPhone.put(updatedContact.AccountId, updatedContact); } } // Retrieve the related Account records and update the Contacts' phone numbers List<Account> relatedAccounts = [SELECT Id, Phone FROM Account WHERE Id IN :accountIdToPhone.keySet()]; for (Contact updatedContact : Trigger.new) { // Check if the Contact is associated with an Account if (updatedContact.AccountId != null) { // Update the Contact's phone number with the related Account's phone number updatedContact.Phone = accountIdToPhone.get(updatedContact.AccountId).phone; } } }
- Sridhar Reddy
- November 05, 2023
- Like
- 0
- Continue reading or reply
Pass Selected Case Record Id from Aura to lwc Component
I have Lightning Aura Component Name as caseList3
not passing selected case record id in js controller
below is the code (YOU CAN CHECK IN BROWSER BY CLTR+SHIFT+i) so it show selected record Id
as below line
console.log("Selected Case Id: " + selectedCaseId);
Now i want an lwc component which will take this Selected record Id as Input and display case and associated product details
My lightning components working perfectly
you can copy and test in your org
only issue i am getting with lwc
My Linghtning component code
APEX
public with sharing class CaseListController {
public CaseListController() {
}
@AuraEnabled
public static List<Case> getCases() {
return [SELECT Id, Subject FROM Case Order By createdDate DESC LIMIT 5];
}}
COMPONENT
caseList3.cmp
<aura:component controller="CaseListController"
implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,forceCommunity:availableForAllPageTypes,force:lightningQuickAction"
access="global">
<aura:attribute name="caseList" type="Case[]" />
<aura:attribute name="selectedCaseId" type="String" />
<aura:attribute name="selectedRecordId" type="String" />
<aura:handler name="init" value="{!this}" action="{!c.loadCases}" />
<div class="slds-card">
<div class="slds-card__header slds-grid">
<h2 class="slds-text-heading_medium slds-col">Case Information</h2>
</div>
<div class="slds-card__body">
<ul class="slds-list_dotted">
<aura:iteration items="{!v.caseList}" var="caseRecord">
<li class="slds-p-around_small slds-box slds-box_small">
<p class="slds-text-title"><strong>Case Number:</strong> {!caseRecord.CaseNumber}</p>
<p class="slds-text-title"><strong>Subject:</strong> {!caseRecord.Subject}</p>
<p><strong>Description:</strong> {!caseRecord.Description}</p>
<!-- Add more case fields here -->
<button class="slds-button slds-button_brand select-case-button" data-caseid="{!caseRecord.Id}" onclick="{!c.selectCase}">Select Case😀</button>
</li>
</aura:iteration>
</ul>
</div>
</div>
<lightning:workspaceAPI aura:id="workspace" />
</aura:component>
caseList3Controller.js
({
selectCase: function (component, event, helper) {
var selectedCaseId = event.currentTarget.getAttribute("data-caseid");
component.set("v.selectedCaseId", selectedCaseId);
console.log("Selected Case Id: " + selectedCaseId);
var messagePayload = {
selectedCaseId: selectedCaseId
};
var messageContext = component.find("workspace").getMessageContext();
var message = {
recordId: component.get("v.recordId"),
messageBody: JSON.stringify(messagePayload)
};
messageContext
.publishMessage(CASE_SELECTION_CHANNEL, message)
.then(response => {
console.log("Message published successfully");
})
.catch(error => {
console.error("Error publishing message: " + error);
});
},
loadCases: function (component, event, helper) {
var action = component.get("c.getCases");
action.setCallback(this, function (response) {
var state = response.getState();
if (state === "SUCCESS") {
var caseRecords = response.getReturnValue();
component.set("v.caseList", caseRecords);
} else {
console.error("Error fetching case data: " + state);
}
});
$A.enqueueAction(action);
},
handleRecordSelection: function(component, event, helper) {
var selectedRecordId = event.getParam("recordId");
component.set("v.selectedRecordId", selectedRecordId);
}
})
- VICKY_SFDC
- September 19, 2023
- Like
- 0
- Continue reading or reply
How to make 2 API calls for same endpoint in Synchronous Call
I'm making an synchronous call where I need to get more than 6MB. so I want to split the call and make 2 request.
For example, If I want to request 10,000 records to an external system then I need to request,
- 1-6000 in first API request call and
- 6001-10,000 in second API request call
Thanks you.
- Shyamala Varadharajan
- September 07, 2023
- Like
- 0
- Continue reading or reply
apex class execution
Hi Everyone,
i was struck on the one condition, my requirement is update the contact status Cancelled when Account status is Cancelled but not update if Account status is "Pending"/"In progress".
I have added my code below , please check let me know how to add that condification or any hints please
public class AccountUpdate { public void getIds() { List<Account> accIds = new List<Account>(); Set<Id> getIds = new Set<Id>(); for(Account a :[select Id, Name from Account]) { getIds.add(a.Id); } System.debug('Print all the Account Ids =>' +getIds); //get the related contacts associated to Account List<Contact> con = [Select Id, Name, AccountId From Contact Where AccountId IN :getIds]; System.debug('Print all related Contacts'+con); List<Contact> getupdateContacts = new List<Contact>(); if(Account.Account_Status__c == 'Cancelled'){ getupdateContacts.add(con); } update getupdateContacts; } } }
- Babar Hussain 13
- September 06, 2023
- Like
- 0
- Continue reading or reply
Open edit fields for triggers but close for users
Have a task with triggers.
I'm have a custom object with fields, one of trigger method change fields value on values at child lookup object, sum some score.
I need to close edit for this fields, but with profiles i cant do this. When I write in trigger i can close this fields, but trigger also can't edit them.
How I can write trigger or can i try another option for close edit this fields?
Here part of trigger and object with fields
private static final String STATUS_FOR_CHECK = 'Closed - Hired'; public static void getJobApplicationsForChangeStatusAfterUpdate(List<Job_Application__c> newJobApplications, Map<Id, Job_Application__c> oldJobApplications) { Set<Id> positionsToClose = new Set<Id>(); for (Job_Application__c newJobApp : newJobApplications) { Job_Application__c oldJobApp = oldJobApplications.get(newJobApp.Id); if (newJobApp.Overall_Average_Reviwes_Score__c != oldJobApp.Overall_Average_Reviwes_Score__c || newJobApp.Overal_Reviews__c != oldJobApp.Overal_Reviews__c) { newJobApp.addError('Fields with Reviews scores can not be changed'); } else { if (newJobApp.Status__c == STATUS_FOR_CHECK && oldJobApp != null && oldJobApp.Status__c != STATUS_FOR_CHECK) { positionsToClose.add(newJobApp.Position__c); } } } List<Position__c> positionsToUpdate = [SELECT Id, Status__c FROM Position__c WHERE Id IN :positionsToClose]; for (Position__c pos : positionsToUpdate) { pos.Status__c = STATUS_FOR_CHECK; } update positionsToUpdate; }
in this part I can check this fields
if (newJobApp.Overall_Average_Reviwes_Score__c != oldJobApp.Overall_Average_Reviwes_Score__c || newJobApp.Overal_Reviews__c != oldJobApp.Overal_Reviews__c) { newJobApp.addError('Fields with Reviews scores can not be changed'); }
- Vitalii Sysak
- September 04, 2023
- Like
- 0
- Continue reading or reply
Trigger on ContentDocumentLink
- sharv
- August 29, 2023
- Like
- 0
- Continue reading or reply
Anyone help me with this asynchronous apex requirement
I have two objects 1. Employee 2. Attendance
Employee, Attendance has master detail relation.
Actually i already implemented everything getting attendance creating attendance using Aura Component. For the below requirement solution needed in asynchronous apex.
Requirement:- Create an automated process which runs every 3 days starting from 3rd day of the month to determine if the employee has any days where the attendance Status (Field) is –
1.Present,
2.Less than 9.15
3.Status Unknown
4.Shortfall
Once the above is determined an email should trigger to the employee with manager in CC informing about the same
Manager Field has self look up with employee object.
I need the above requirement solution implementation using asynchronous apex.
Below is the apex code for previos all requirements.
Apex Class:-
public class Employee_Attendance_Apex { @AuraEnabled public static ContactDataTableWrapper getAttendance( Integer pageNumber, Integer pageSize, String recordId, String eNumber, String sDate, String eDate, String empName) { System.debug('getContactData '+empName); if(eNumber !=null && sDate != null && eDate != null || empName != null) { Date startDate = Date.valueOf(sDate); Date endDate = Date.valueOf(eDate); //Offset for SOQL Integer offset = (pageNumber - 1) * pageSize; // Get the total number of records that match the criteria Integer totalRecords = [SELECT COUNT() FROM Attendance__c WHERE (Date__c >= :startDate AND Date__c <= :endDate) AND (Employee__r.Employee_ID__c = :eNumber OR Employee__c = :empName)]; //Total Records // Integer totalRecords = [SELECT COUNT() FROM Attendance__c]; // Integer recordEnd = pageSize * pageNumber; //Instance of Contact DataTable Wrapper Class ContactDataTableWrapper objDT = new ContactDataTableWrapper(); objDT.pageSize = pageSize; objDT.pageNumber = pageNumber; objDT.recordStart = offset + 1; // objDT.recordEnd = totalRecords >= recordEnd ? recordEnd : totalRecords; System.debug('eNumber '+eNumber); objDT.recordEnd = Math.min(offset + pageSize, totalRecords); objDT.totalRecords = totalRecords; objDT.AttendanceList = [Select Id, Name, Employee__r.Name, Employee__c, Employee_Name__c, Employee__r.Employee_Name__c, Employee__r.Employee_ID__c, Date__c, Day__c, From_Time__c, To_Time__c, Total_Hours__c, Statuss__c from Attendance__c WHERE (Date__c >= :startDate AND Date__c <= :endDate) AND (Employee__r.Employee_ID__c = :eNumber OR Employee__c =:empName) ORDER BY CreatedDate DESC LIMIT :pageSize OFFSET :offset]; return objDT; } return null; } @AuraEnabled public static ContactDataTableWrapper getAttendanceDownload(String recordId, String eNumber, String sDate, String eDate, String empName) { System.debug('getContactData '+empName); if(eNumber !=null && sDate != null && eDate != null || empName != null) { Date startDate = Date.valueOf(sDate); Date endDate = Date.valueOf(eDate); //Offset for SOQL //Integer offset = (pageNumber - 1) * pageSize; //Total Records Integer totalRecords = [SELECT COUNT() FROM Attendance__c]; //Integer recordEnd = pageSize * pageNumber; //Instance of Contact DataTable Wrapper Class ContactDataTableWrapper objDT = new ContactDataTableWrapper(); //objDT.pageSize = pageSize; //objDT.pageNumber = pageNumber; //objDT.recordStart = offset + 1; //objDT.recordEnd = totalRecords >= recordEnd ? recordEnd : totalRecords; //objDT.totalRecords = totalRecords; objDT.AttendanceList = [Select Id, Name, Employee__r.Name, Employee__c, Employee_Name__c, Employee__r.Employee_Name__c, Employee__r.Employee_ID__c, Date__c, Day__c, From_Time__c, To_Time__c, Total_Hours__c, Statuss__c from Attendance__c WHERE (Date__c >= :startDate AND Date__c <= :endDate) AND (Employee__r.Employee_ID__c = :eNumber OR Employee__c =:empName) ORDER BY CreatedDate DESC]; return objDT; } return null; } @AuraEnabled public static List<Employee__c> getAttendanceByName(String empName) { System.debug('getContactData '+empName); List<Employee__c> empRec = new List<Employee__c>(); if(empName != '') { String empNameVal = '%'+empName+'%'; empRec = [Select Id, Name from Employee__c Where Name Like:empNameVal Order By CreatedDate DESC]; } return empRec; } public class ContactDataTableWrapper { @AuraEnabled public Integer pageSize {get;set;} @AuraEnabled public Integer pageNumber {get;set;} @AuraEnabled public Integer totalRecords {get;set;} @AuraEnabled public Integer recordStart {get;set;} @AuraEnabled public Integer recordEnd {get;set;} @AuraEnabled public List<Attendance__c> AttendanceList {get;set;} } /*@AuraEnabled public static List<Attendance__c> getAttendance(String recordId, String eNumber, String sDate, String eDate, String empName){ List<Attendance__c> AttendanceList = new List<Attendance__c>(); if(eNumber !=null && sDate != null && eDate != null || empName != null){ Date startDate = Date.valueOf(sDate); Date endDate = Date.valueOf(eDate); AttendanceList = [Select Id, Name, Employee__r.Name, Employee__c, Employee__r.Employee_Name__c, Employee__r.Employee_ID__c, Date__c, Day__c, From_Time__c, To_Time__c, Total_Hours__c, Statuss__c from Attendance__c WHERE (Date__c >= :startDate AND Date__c <= :endDate) AND (Employee__r.Employee_ID__c = :eNumber OR Employee_Name__c =:empName) ORDER BY CreatedDate DESC]; } return AttendanceList; }*/ @AuraEnabled public static String createAttendance(String recordId, String dateInput, String inTime, String outTime) { Attendance__c attendance = new Attendance__c(); String result = ''; Date dateValue; Time inTimeChange; Time outTimeChange; if (recordId != null) { try { Employee__c empRec = [SELECT Id, Name, OwnerId, Manager__c, Manager__r.Email__c FROM Employee__c WHERE Id = :recordId LIMIT 1]; if (empRec != null) { // Setting Attendance fields based on input parameters attendance.Name = empRec.Name + ' 1'; attendance.Employee__c = empRec.Id; if (dateInput != null) { dateValue = Date.valueOf(dateInput); Date date1 = System.today(); Date date2 = dateValue; Integer dateDifference = date2.daysBetween(date1); if (dateDifference >= 7) { return 'dateDifference'; } else { attendance.Date__c = dateValue; } } if (inTime != null) { List<String> strTimeSplit = inTime.split(':'); inTimeChange = Time.newInstance(Integer.valueOf(strTimeSplit[0]), Integer.valueOf(strTimeSplit[1]), 0, 0); attendance.From_Time__c = inTimeChange; } if (outTime != null) { List<String> strTimeSplit = outTime.split(':'); outTimeChange = Time.newInstance(Integer.valueOf(strTimeSplit[0]), Integer.valueOf(strTimeSplit[1]), 0, 0); attendance.To_Time__c = outTimeChange; } // Insert the Attendance record insert attendance; // Get Manager's email String managerEmail = empRec.Manager__r.Email__c; // Send email to Manager if (managerEmail != null) { String emailSubject = 'Attendance Record Approval'; String emailBody = 'A new attendance record requires your approval.' + '\n\nRecord Link: ' + getRecordLink(attendance.Id); Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); email.setToAddresses(new List<String>{managerEmail}); email.setSubject(emailSubject); email.setPlainTextBody(emailBody); Messaging.SendEmailResult[] results = Messaging.sendEmail(new Messaging.SingleEmailMessage[]{email}); if (results[0].isSuccess()) { System.debug('Email sent successfully.'); } else { System.debug('Failed to send email. Error: ' + results[0].getErrors()[0].getMessage()); } } // Submit the record for approval using the Approval.ProcessSubmitRequest class Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest(); req.setComments('Submitting record for approval.'); req.setObjectId(Attendance.Id); // Make sure to use the correct Approval process name (replace 'Attendance_Approval' with your actual process name) req.setProcessDefinitionNameOrId('Attendance_Approval'); Approval.ProcessResult result2 = Approval.process(req); if (result2.isSuccess()) { System.debug('Record submitted for approval successfully.'); // If the record is submitted for approval successfully, update the Status__c field to "Pending Approval" update Attendance; } else { System.debug('Failed to submit record for approval. Error: ' + result2.getErrors()); } result = 'true'; } } catch (Exception ex) { System.debug('Ex: ' + ex.getMessage()); result = 'false'; } } return result; } // Helper method to get the Salesforce record link private static String getRecordLink(Id recordId) { String baseURL = URL.getSalesforceBaseUrl().toExternalForm(); return baseURL + '/' + recordId; } @AuraEnabled public static String updateAttendance(String row){ System.debug('row '+row); Map<String, Object> dataMap = (Map<String, Object>)JSON.deserializeUntyped(row); System.debug('Converted Map: ' + dataMap); System.debug('Key '+dataMap.get('Date')); String attId = (String)dataMap.get('Id'); String dateInput = (String)dataMap.get('Date'); String inTime = (String)dataMap.get('InTime'); String outTime = (String)dataMap.get('OutTime'); String result = ''; Attendance__c att = [Select Id, Date__c, From_Time__c, To_Time__c from Attendance__c Where Id =:attId]; if(dateInput!=null) { Date Datevalue = Date.valueOf(dateInput); Date date1 = att.Date__c; Date date2 = Datevalue; Integer dateDifference = date2.daysBetween(date1); if (dateDifference >= 7) { result = 'dateDifference'; } else { att.Date__c = Datevalue; } } if (inTime != null) { String[] strTimeSplit = inTime.split(':'); Time inTimeChange = Time.newInstance(Integer.valueOf(strTimeSplit[0]), Integer.valueOf(strTimeSplit[1]), 0, 0); att.From_Time__c = inTimeChange; } if (outTime != null) { String[] strTimeSplit = outTime.split(':'); Time outTimeChange = Time.newInstance(Integer.valueOf(strTimeSplit[0]), Integer.valueOf(strTimeSplit[1]), 0, 0); att.To_Time__c = outTimeChange; } try{ Update att; result = 'true'; } catch(Exception ex){ System.debug(ex.getMessage()); result = 'false'; } return result; } @AuraEnabled public static String getManagerEmail(Id employeeId) { try { if (employeeId != null) { Employee__c empRec = [SELECT Id, Manager__c, Manager__r.Email__c FROM Employee__c WHERE Id = :employeeId LIMIT 1]; // Check if the employee record has a manager and the manager has an email if (empRec != null && empRec.Manager__c != null && empRec.Manager__r != null && empRec.Manager__r.Email__c != null) { return empRec.Manager__r.Email__c; } } } catch (Exception ex) { // Handle exceptions here, such as logging or returning an error message. System.debug('Error occurred while fetching Manager\'s Email: ' + ex.getMessage()); } return null; } }
- Akash A
- August 11, 2023
- Like
- 0
- Continue reading or reply
opportunities on custom objects
We added Opportunity as a child of the custom object, but it still wants to always have an Opportunity connected to an Account. Is there some way to make an Opportunity that is attached to something other than a standard Account object?
- Alex Husted
- August 01, 2023
- Like
- 0
- Continue reading or reply
Import Data From SQL Server Into Salesforce
I am new to Salesforce but have experience working with API's.
What I want to know is do I use the BULK API for this?
Everything I have read says that to use the BULK API I have to upload the data using CSV. Is it possible to upload directly from SQL Server to Salesforce using a .net app?
TIA!
- Scott Trick
- July 31, 2023
- Like
- 0
- Continue reading or reply
HTTP Callout: Unexpected token N in JSON at position 1073
Error: SyntaxError: Unexpected token N in JSON at position 1073
- Anthony Calise
- July 31, 2023
- Like
- 0
- Continue reading or reply
Error Message: Can't update Price Book.
Hi,
I am receiving the following error message when trying to add a Product to a Renewal Opportunity:
"Can't update Price Book. Unexpected exception while validating invocable action requests"
I have recently implemented a few Flows for the Opportunity object, but none of those Flows include any fields related to Price Books or Products. Once I deactivated one of those Flows (to standardize the Opportunity Name), I was able to add a Product to the Opportunity, no problem.
Does anyone have any insight as to why this Flow would be causing an issue with the Products and Price Books if the Flow was seemingly unrelated?
- Jewels Gutowski
- July 31, 2023
- Like
- 0
- Continue reading or reply
Flow error failed records and too many SOQL
I have a flow and in the result, I get this:
Result
Failed to find records.
________________________________________
Error Occurred: Too many SOQL queries: 101
This means the flow has two errors? 1- Failed to find records with those logic and 2- Too many SOQL queries
OR it just has one error of too many SOQL queries and because of that it couldn't find any records?
- Arash Rah 5
- June 03, 2023
- Like
- 0
- Continue reading or reply
Whenever contact is created update status field from it' s associate account ??
whenever we we change any field in account ?? I am not getting this scenario...
- Paul H 5
- June 03, 2023
- Like
- 0
- Continue reading or reply
Test apex class - Code coverage
TRIGGER:
trigger opportunitytrigger on opportunity(after update){
Set<Id> oppIds = new Set<Id>();
// Set<Id> oppWithContractAgreement = new Set<Id>();
List<APXT_Redlining__Contract_Agreement__c> oppWithContractAgreement = new List<APXT_Redlining__Contract_Agreement__c>();
List<Opportunity> opportunity = new List<Opportunity>();
for(opportunity opp:Trigger.new)
{
if(opp.Stagename=='Closed Won')
{
oppIds.add(opp.id);
opportunity.add(opp);
}
}
List<APXT_Redlining__Contract_Agreement__c> con =[Select Id, Opportunity__c,APXT_Redlining__Status__c,Verified_Signed_IO__c from APXT_Redlining__Contract_Agreement__c where Opportunity__c IN :oppIds];
{
if(con.size()>0)
system.debug(+con.size());
{
for(APXT_Redlining__Contract_Agreement__c c :con)
{
if( c.APXT_Redlining__Status__c == 'Active' && c.Verified_Signed_IO__c ==FALSE){
oppWithContractAgreement.add(c);
system.debug('-----------'+oppWithContractAgreement.size());
}
}
}
}
For(Opportunity opps:opportunity)
{
if(oppWithContractAgreement.size()>0)
{
system.debug(oppWithContractAgreement.size());
opps.addError('Closed Won Opportunity must need to have active contract agreement and customer signed date captured or Closed Won Opportunity must need to have active contract agreement');
}
if(con.size()==0)
{
opps.addError('Closed Won Opportunity must need to have contract agreement' );
}
}
}
TEST CLASS:
@isTest
private class OpportunityTriggerHandler1_Test {
@isTest static void testCreateOpportunityTarget() {
//create Account
Account acc = new Account();
acc.Name = 'Test Account';
insert acc;
Test.startTest();
Opportunity opp = new Opportunity();
opp.AccountId = acc.Id;
opp.Name = 'Test Opportunity';
opp.StageName = 'Closed Won';
opp.CloseDate = Date.Today().addDays(20);
insert opp;
Test.stopTest();
List<APXT_Redlining__Contract_Agreement__c> CA = new List<APXT_Redlining__Contract_Agreement__c>();
CA = [Select Id, Opportunity__c,APXT_Redlining__Status__c,Verified_Signed_IO__c from APXT_Redlining__Contract_Agreement__c ];
System.assert(CA[0].Opportunity__c == opp.Id);
}
}
- Swaroopa Akula 10
- May 30, 2023
- Like
- 0
- Continue reading or reply
Sending Email notification on 1st of every month
I want to send notification to few contacts on 1st of every month without writing Schedulable Job. I have checked Scheduled Flow but it doesn't have option for sending every month. Is there any other solution available through point and click.
- Himanshu Patel 55
- May 29, 2023
- Like
- 0
- Continue reading or reply
CaseDemoRecordType: execution of AfterInsert caused by: System.FinalException: Record is read-only Trigger.CaseDemoRecordType: line 17, column 1
{
if((trigger.isAfter) && (trigger.isinsert || trigger.isupdate))
{
List<RecordType> recordTyp = [Select id , Name , Sobjecttype from RecordType];
List<Case> LstCs = [select id , CaseNumber , RecordTypeId from case ];
For(Case cs : Trigger.new)
{
For(RecordType RecTyp : recordTyp )
{
If(cs.RecordTypeID == RecTyp.id)
{
if(RecTyp.Name == 'School zone')
{
cs.Description = 'This is SCHOOL ZONE';
system.debug('This is SCHOOL zONE^^^^^'+RecTyp.Name);
}
else
cs.Description = 'This is COLLEGE ZONE';
system.debug('This is COLLEGE zONE......'+RecTyp.Name);
system.debug('The REcord Type Ids..............'+cs.RecordTypeId);
}
}
update cs;
}
}
}
- ss kumar
- May 28, 2023
- Like
- 0
- Continue reading or reply