-
ChatterFeed
-
2Best Answers
-
2Likes Received
-
0Likes Given
-
5Questions
-
48Replies
Creating New Contacts from Email-To-Case
Hi all
I'm very new to Salesforce, and my first assignment is to get our Production Org's Email-To-Case working correctly, and to find a way to create new Contacts for the Cases if they did not already exist.
After some searching on these forums I found an Apex Trigger that worked perfectly within our Sandbox. However, it fails to create Contacts in Production.
I've checked the trigger is active and triggered and I have also checked permssions. It also has 96% code coverage in Production. Has anyone got any ideas why Sandbox works and Production does not?
Apex Trigger as follows:
trigger TriggertoCreateContactformCase on Case (before insert) {
List<String> UseremailAddresses = new List<String>();
//First exclude any cases where the contact is set
for (Case c:Trigger.new) {
if (c.ContactId==null &&
c.SuppliedEmail!=''|| c.SuppliedEmail==null)
{
UseremailAddresses.add(c.SuppliedEmail);
}
}
//Now we have a nice list of all the email addresses. Let's query on it and see how many contacts already exist.
List<Contact> listofallContacts = [Select Id,Email From Contact Where Email in:UseremailAddresses];
Set<String> ExstingEmails = new Set<String>();
for (Contact c:listofallContacts) {
ExstingEmails.add(c.Email);
}
Map<String,Contact> emailToContactMap = new Map<String,Contact>();
List<Case> casesToUpdate = new List<Case>();
for (Case c:Trigger.new) {
if (c.ContactId==null &&
c.SuppliedName!=null &&
c.SuppliedEmail!=null &&
c.SuppliedName!='' &&
!c.SuppliedName.contains('@') &&
c.SuppliedEmail!='' &&
!ExstingEmails.contains(c.SuppliedEmail))
{
//The case was created with a null contact
//Let's make a contact for it
String[] Emailheader = c.SuppliedName.split(' ',2);
if (Emailheader.size() == 2)
{
Contact conts = new Contact(FirstName=Emailheader[0],
LastName=Emailheader[1],
Email=c.SuppliedEmail
);
emailToContactMap.put(c.SuppliedEmail,conts);
casesToUpdate.add(c);
}
}
}
List<Contact> newContacts = emailToContactMap.values();
insert newContacts;
for (Case c:casesToUpdate) {
Contact newContact = emailToContactMap.get(c.SuppliedEmail);
c.ContactId = newContact.Id;
}
}
Many thanks in advance!!!!
- Simon Merton
- January 28, 2019
- Like
- 0
- Continue reading or reply
Trailhead Import Data, unable to complete Prepare for Data Import as i dont have any csv files
I am following the training suggestions to exercise data import.
I am not asking about how to complete the challange, as example CSV is available for downlad from the page. I am interested in completing the 2 exercises for importing data using Data Loader and the Wizard.
Under section: Prepare for Data Import
There are 4 steps to follow. First 2 say:
1. Use your existing software to create an export file.
2. Clean up the import file for accuracy and consistency. This involves updating the data to remove duplicates, delete unnecessary information, correct spelling and other errors, and enforce naming conventions.
Steps 1 and 2 suggest i should use some existing data for this exercise. I dont have any existing data, and i dont know how could i have any...its not like im running some CRM at home...
Am I missing something? How have you managed to complete exercises requiring that data.
Please advise.
- SomeDude
- January 16, 2018
- Like
- 0
- Continue reading or reply
Logger framework
Does anyone use a logger frameowrk in their salesforce org. If yes, which one?
I was having a look at
https://github.com/rsoesemann/apex-unified-logging
Has anyone implemented this in their org already? I have deployed this in my org already, however need a starting point as to how to catch exceptions in classes etc?
Thx
- Kaustubh Labhe
- May 09, 2019
- Like
- 0
- Continue reading or reply
VSCODE: Create Project vs Create project using manifest
Can someone tell me, what is the difference between Create Project and Create Project using Manifest?
Is the latter used for non-dx projects primarily?
Thx
- Kaustubh Labhe
- April 30, 2019
- Like
- 2
- Continue reading or reply
VScode connect to org in a project
Fairley new to SFDX and Vscode. If I have created a project folder once (remotely) via VSCode and say terminate the session. The next time I open VSCode, how can I easily log in to the same org or authenticate the same org which is saved under the 'Orgs' folder. Without having to reauthenticate it each time. Hope this makes sense.
- Kaustubh Labhe
- April 13, 2019
- Like
- 0
- Continue reading or reply
Custom apex rules in PMD static code scanner
I have configured PMD to run with ANT, however I am struggling to write custom rules. I am working with the standard rules which sourceforge provides. Has anyone written custom rules for apex in PMD?
Thanks for your time.
- Kaustubh Labhe
- January 28, 2019
- Like
- 0
- Continue reading or reply
Metadata from GITHUB to Sandbox.
I have downloaded a zipped file from a github repo. It contains many metadata components like an app, few classes, lightning components, custom labels etc.
Is there anyway I can install this in my sandbox. I use Eclipse IDE currently. Unfortunately cannot use AppExchange and/or any third party tool.
Thanks
- Kaustubh Labhe
- August 17, 2018
- Like
- 0
- Continue reading or reply
VSCODE: Create Project vs Create project using manifest
Can someone tell me, what is the difference between Create Project and Create Project using Manifest?
Is the latter used for non-dx projects primarily?
Thx
- Kaustubh Labhe
- April 30, 2019
- Like
- 2
- Continue reading or reply
Getting the following error when i am saving the apex class
I am getting the following compile error when saving the apex class
Compile Error: Invalid type: parkService.parksImplPort at line 3 column 1
And find below code:
public class ParkLocator{
public static String[] country(String country){
parkService.parksImplPort park= new parkService.parksImplPort();
String[] parksname = park.byCountry(country);
return parksname;
}
}
- Bhupathi Yadav
- April 30, 2019
- Like
- 0
- Continue reading or reply
VSCODE: Create Project vs Create project using manifest
Can someone tell me, what is the difference between Create Project and Create Project using Manifest?
Is the latter used for non-dx projects primarily?
Thx
- Kaustubh Labhe
- April 30, 2019
- Like
- 2
- Continue reading or reply
Apex Trigger on Leads to make "Assign using active assignment rule" unchecked by default upon Edit
On Leads, I would like to make "Assign using active assignment rule" checked by default upon Create, but unchecked by default upon Edit. I was told that I need an Apex Trigger to do this. Can you provide an example of this callout and information on how to implement it? Alternatively, is there a third-party app available that would provide this capability? Thanks in advance for any recommendations.
- Karen Roscoe - Administrator SFDC
- April 30, 2019
- Like
- 0
- Continue reading or reply
Process Builder send password (Pass password to apex class)
- camelUser
- April 30, 2019
- Like
- 0
- Continue reading or reply
How to integrate Lightning component within Visualforce Page
<!-- - Created by stefaans on 29/04/2019. --> <aura:component description="DocumillDocuments" implements="forceCommunity:availableForAllPageTypes" access="global" controller="DocumillHelper"> <aura:attribute name="objectType" type="String"/> <aura:attribute name="listDocuments" type="Documill_Template__mdt[]"/> <aura:handler name="init" value="{!this}" action="{!c.doInit}"/> <!-- PAGE HEADER --> <lightning:layout class="slds-page-header slds-page-header--object-home"> <lightning:layoutItem> <lightning:icon iconName="standard:scan_card" alternativeText="My Expenses"/> </lightning:layoutItem> <lightning:layoutItem padding="horizontal-small"> <div class="page-section page-header"> <h1 class="slds-text-heading--label">Documill</h1> <h2 class="slds-text-heading--medium">Documents</h2> </div> </lightning:layoutItem> </lightning:layout> <!-- / PAGE HEADER --> <!-- LIST DOCUMILL DOCS --> <lightning:layout> <lightning:layoutItem padding="around-small" size="6"> <aura:iteration var="doc" items="{!v.listDocuments}" > <p>{!doc.name}</p> </aura:iteration> </lightning:layoutItem> </lightning:layout> <!-- / LIST DOCUMILL DOCS --> </aura:component>
Here is the code of my VFPage :
<!-- - Created by stefaans on 29/04/2019. --> <apex:page id="DocumillDocuments" sidebar="false" showHeader="false" standardStylesheets="false"> <apex:includeLightning /> <div id="DocumillDocumentsDiv"></div> <script> $Lightning.use("c:DocumillApp", function() { $Lightning.createComponent("c:DocumillDocuments", {}, "DocumillDocumentsDiv", function(cmp) { console.log('>>>>> App is hosted'); }); }); </script> </apex:page>
As soon as the line hereunder is included within the component, I get this error.
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
If I remove this line, the component shows correctly in the Visualforce page.
In my handler I don't have any real logic yet
/** * Created by stefaans on 30/04/2019. */ ({ doInit : function(component, event, helper) { // component, event, helper are parameter of doinit function console.log('Init event is being triggered') /* var action= component.get('c.getDocuments'); // Calling apex method action.setCallback(this,function(response) // getting response back from apex method { var state=response.getState(); // getting the state if(state==='SUCCESS') { component.set('v.listDocuments',response.getReturnValue()); // setting the value in attribute } }); $A.enqueueAction(action);*/ } })
When I open the visualforce page, I get the following error :
aura_proddebug.js:43717 Uncaught (in promise) TypeError: Cannot set property 'innerHTML' of null
at AuraInstance.message (aura_proddebug.js:43717)
at AuraInstance.handleError (aura_proddebug.js:43632)
at AuraInstance.$reportError$ (aura_proddebug.js:43693)
at reportError (aura_proddebug.js:43429)
- Stefaan Somers 12
- April 30, 2019
- Like
- 0
- Continue reading or reply
Deployment Error PLEASE HELP
WITH that said I have written the code and have it executing fully in the Sandbox wihtout any erros, and have my code coverage passing 100% when I run the tests for the test class in the SB..
What I am struggling with is deploying the code to Production..
When I attempt to deplot the code I am recieving the following error and I am not sure why i am at all..
Here is my Code
public override void afterUpdate(SObject oldSo, SObject so) { Opportunity newOpp = (Opportunity)so; Opportunity oldOpp = (Opportunity)oldSo; if (newOpp.StageName == Constants.OPTY_STAGE_CLOSED_WON && newopp.Does_Not_Need_Resource_Request__c == FALSE){ list<pse__Resource_Request__c> resourceRequests = [select ID, pse__Opportunity__c, Pse__Status__c FROM pse__Resource_Request__c]; list<opportunity> opps = [Select ID, pse__Primary_Project__c from Opportunity]; boolean isValid = false; for (pse__Resource_Request__c resourceRequest : resourceRequests) { if (resourceRequest.pse__Opportunity__c == newOpp.Id) { //there is a resource request that has the opportunity id of the current opp meaning the opp is valid isValid = true; resourceRequest.pse__Project__c = newOpp.pse__Primary_Project__c; resourceRequest.pse__Status__c = 'Assigned'; } } // if we get out of the loop and isValid is false, it means there were 0 opps that matched the resource request // return error if (!isValid) { so.addError('Please add Resource Requests to this Opportunity before marking it as "Closed Won." If no Resource Requests need to be added to the Opportunity please check the "Does Not Need Resource Request" checkbox in order to Close Win.'); } } }
And here is my Test Class to go along with it.
@isTest static void aftUpTest() { TestDataFactory.initPermissionControls(); //Prep the data TestDataFactory.projects = TestDataFactory.createprojects(2); TestDataFactory.opportunities = TestDataFactory.createOpportunities(2); TestDataFactory.createResourceRequests(1, TestDataFactory.opportunities[0], TRUE); system.test.startTest(); TestDataFactory.opportunities[0].StageName = Constants.OPTY_STAGE_CLOSED_WON; TestDataFactory.opportunities[0].Does_Not_Need_Resource_Request__c = FALSE; TestDataFactory.opportunities[0].Create_Project__c = FALSE; TestDataFactory.opportunities[0].Info_Complete__c = TRUE; TestDataFactory.opportunities[0].Pse__Primary_Project__c = TestDataFactory.projects[0].id; update TestDataFactory.opportunities; system.test.stopTest(); } }
In the test code the test data factory is creating an opp for me, and setting it all up to be ready to close win, and then the test data factory is creating a resource request for me with the associated opportunity on the respource request set to the same opportunity the test data factory just created.
With all this said the error message I am recieving when attempting to deploy the code to Production reads..
"Methods defined as TestMethod do not support Web service callouts
Stack Trace: null"
PLEASE HELP.
I have spent 3 days trying to uncover the error and still nothing, so any help would be MUCH appreciated!
- Kris Webster
- February 18, 2019
- Like
- 0
- Continue reading or reply
Json data
I'm using Webhook to retrieve data from a Form provider. Data is in json format. I would like to map the data to each field of Contact and Opportunity in order to create an Opportunity. I want to map the data to these to Maps
Map<String,String> contactMap = new Map<String,String>();
Map<String,String> opportunityMap = new Map<String,String>();
From there, I already wrote a class to create an Opportunity. All I need is to map the data to that map.
Does anyone know how to do that, I'm new to Apex and Salesforce?
Thank you in advance.
- Victor Nguyen 13
- February 18, 2019
- Like
- 0
- Continue reading or reply
SOQL string search is not returning values
I am trying to search based on case subject
Example if different case have subject line as below
1. FW: Case for Testing
2. RW: Case for Testing
3. Case for Testing
I was all the above subject line return when I try to update " FW: Case for Testing"
In below code FW and RW start is getting return not the with out FW or RW.
String FWSubject; String RWSubject; String CaseSubject; list<case> cselst = new list<case>(); for (Case c : [select id,casenumber,subject,ownerid,owner.name from case where id = '5002D000004JCQr']) { system.debug('Case Number :' + c.casenumber); system.debug('Case Subject : ' + c.subject); system.debug('Case Subject length : ' + c.subject.length()); system.debug('Case Owner Name : ' + c.owner.name); CaseSubject = c.subject; //Search for FW and RW key word were length of the subject is more than 18 //if(c.subject != null && c.subject.length() > 18){ if(c.subject.Contains('FW:')){ FWSubject = c.subject.replaceAll('FW:',''); System.debug('FQ Trim String :' + FWSubject); } if(c.subject.Contains('RW:')){ RWSubject = c.subject.replaceAll('RW:',''); System.debug('RW Trim String :' + RWSubject); // } } } system.debug('FWSubject :' + FWSubject); system.debug('RWSubject :' + RWSubject); //Map<Id, case> c = new Map<Id, case>([select id, casenumber,subject,createddate,ownerid,owner.name from case where CreatedDate = this_year and subject like :('%' + CaseSubject + '%') order by createddate asc limit 10]); //Search for same case based on subject within 10days. list<case> ctendays = [select id, casenumber,subject,createddate,ownerid,owner.name from case where CreatedDate = this_year and ( subject like :('%' + CaseSubject + '%') or subject like :('%' + FWSubject + '%') or subject like :('%' + RWSubject + '%') ) order by createddate asc limit 100]; for(case ctndays : ctendays){ system.debug('Existing Cases :' + ctndays.casenumber + ' ' + ctndays.subject + ' ' + ctndays.createddate + ' ' + ctndays.owner.name); system.debug('Latest Case Owner ' + ctendays[0].owner.name); ctndays.ownerid = ctendays[0].ownerid; ctndays.Duplicate_With__c = ctendays[0].casenumber; cselst.add(ctndays); } //if(cselst.size()>0){ // update cselst; //}
Thanks
GMASJ
- GMASJ
- February 18, 2019
- Like
- 0
- Continue reading or reply
Deployment fails: Error: InfoNot a valid enumeration for type: class com.sforce.soap.metadata.DeployProblemType
I am going crazy trying to deploy a package from a Sandbox in a Production Org (one signed up Developer Org).
When the process begins to run it then ends with repetitive error:info lines:
It ends with:
[sf:deploy] Failed to check the status for request ID=0Af1i000000B87XCAS. Error: InfoNot a valid enumeration for type: class com.sforce.soap.metadata.DeployProblemType. Retrying...
Can please somebody help me here? I downloaded the version 45 of the ant jar file and put it in the ANT directory, but anyway the deployment is not working, why?
- Internal Partner
- February 18, 2019
- Like
- 0
- Continue reading or reply
Copy a related list record from record page
Is it possible to copy a child record from a related list as shown in the screenshot?
Thanks
- London Admin
- February 01, 2019
- Like
- 0
- Continue reading or reply
Custom Visualforce quick action is not rendered in Sandbox Mobile Environment
- Dinesh_Kumar_Nagarathinam
- February 01, 2019
- Like
- 0
- Continue reading or reply
Cannot find a user that matches any of the following usernames
- balaji rao
- February 01, 2019
- Like
- 0
- Continue reading or reply
Hi,I need to convert below VF Page into Lightning component I am new to lightning Can anybody could you please help me how to convert this VF into Lightning Component Please ?
~~~~~~~~~~~~~~~~~~
<apex:page standardController="Account" cache="true" extensions="BussinessController" sidebar="false" showHeader="false">
<head>
<title>Trade History - {!Account.Name}</title>
</head>
<apex:pageMessages />
<script>
function setFocusOnLoad() {}
</script>
<apex:form id="th_form">
<table>
<tr>
<td width="230px">
<apex:selectRadio value="{!report}" style="font-weight: bold;">
<apex:selectOptions value="{!reporttypes}"/>
</apex:selectRadio>
</td>
<td width="250px">
<apex:OutputLabel value="Start Date" for="c_startDate" />
<apex:inputField id="c_startDate" value="{!Start.ActivityDate}" />
</td>
<td width="250px">
<apex:OutputLabel value="End Date" for="c_endDate" />
<apex:inputField id="c_endDate" value="{!End.ActivityDate}" />
</td>
<td>
<apex:commandButton action="{!th_loaddata}" value="Retrieve Data" status="thtab_status"/>
</td>
</tr>
</table>
</apex:form>
<apex:outputPanel id="th_out">
<apex:actionstatus id="thtab_status" startText="Requesting...">
<apex:facet name="stop">
<apex:outputPanel >
<apex:outputText value="{!ErrorMessage}" style="font-style:italic; font-weight: bold; font-size: 12px;color: #AF0B1C;"/>
<p/>
<apex:iframe src="https://cognos-prod" />
</apex:outputPanel>
</apex:facet>
</apex:actionstatus>
</apex:outputPanel>
<p/>
</apex:page>
Apex Class:
~~~~~~~~~~~~~~~~~
public with sharing class BUssinessController {
private Account acct;
private String report = '1';
private Task edit_task1=null;
private Task edit_task2=null;
private String s_StartDate = null;
private String s_EndDate = null;
private String s_ErrorMessage = '';
private Boolean bshow_thMashup = true;
private String userId = '';
private Spotfire sptfire = new Spotfire();
public String FICClientID
{
get { return sptfire.ficClientID;}
set;
}
public Task getStart()
{
return edit_task1;
}
public Task getEnd()
{
return edit_task2;
}
public String getStartDate()
{
if(edit_task1 == null || edit_task1.ActivityDate==null ) return '';
else return s_StartDate;
}
public String getEndDate()
{
if(edit_task2 == null || edit_task2.ActivityDate==null) return '';
else return s_EndDate;
}
public String getErrorMessage()
{
return s_ErrorMessage;
}
public Boolean show_thMashup
{
get{return bshow_thMashup;}
set;
}
public PageReference th_loaddata() {
s_ErrorMessage='';
if(report == '1')
{
s_StartDate='';
s_EndDate='';
edit_task1.ActivityDate = null;
edit_task2.ActivityDate = null;
bshow_thMashup=true;
}
else
{
System.debug('report by date range!!! ' + edit_task1.ActivityDate + ', '+ edit_task2.ActivityDate);
if(edit_task1.ActivityDate == null || edit_task2.ActivityDate==null)
{
s_ErrorMessage = 'WARNING! Please enter a date range before retrieving data.';
bshow_thMashup=false;
}
else if(edit_task1.ActivityDate > edit_task2.ActivityDate )
{
System.debug('ERRROR 2 is set');
s_ErrorMessage = 'WARNING! The end date must occur after the selected start date.';
bshow_thMashup=false;
}
else
{
bshow_thMashup=true;
System.debug('NO ERROR for radio2!!');
Date ds = edit_task1.ActivityDate;
String s_year = String.valueOf(ds.year());
String s_month = String.valueOf(ds.month());
if(s_month.length()<2) s_month = '0' + s_month;
String s_day = String.valueOf(ds.day());
if(s_day.length()<2) s_day = '0' + s_day;
s_StartDate = s_year+s_month+s_day;
Date de = edit_task2.ActivityDate;
String e_year = String.valueOf(de.year());
String e_month = String.valueOf(de.month());
if(e_month.length()<2) e_month = '0' + e_month;
String e_day = String.valueOf(de.day());
if(e_day.length()<2) e_day = '0' + e_day;
s_EndDate = e_year+e_month+e_day;
}
}
return null;
}
public List<SelectOption> getreporttypes() {
List<SelectOption> options = new List<SelectOption>();
options.add(new SelectOption('1','Last 20 Deals'));
options.add(new SelectOption('2','By Date Range:'));
return options;
}
public String getreport() {
return report;
}
public void setreport(String r)
{
this.report = r;
}
public string Url {
get { return GeneralSettings.getValue(GeneralSettings.SpotfireURL);
}
}
//===================================================================
// Constructor
//
public BUssinessController(ApexPages.StandardController stdController)
//===================================================================
{
Apexpages.currentPage().getHeaders().put('X-UA-Compatible', 'IE=10');
this.acct= (Account)stdController.getRecord();
userId = UserInfo.getUserId();
sptfire.getSpotfireParams(this.acct.Id);
// Initialize tasks
edit_task1= new Task();
edit_task1.OwnerId = userId;
edit_task1.Priority = 'Normal';
edit_task1.ActivityDate = System.TODAY();
edit_task2= new Task();
edit_task2.OwnerId = userId;
edit_task2.Priority = 'Normal';
edit_task2.ActivityDate = System.TODAY();
}
}
- Rishikesh
- February 01, 2019
- Like
- 0
- Continue reading or reply
Is there a way to create a round/bullet type column that wrapper around a text
- SalesforceLearnerNewbie
- February 01, 2019
- Like
- 0
- Continue reading or reply
Custom apex rules in PMD static code scanner
I have configured PMD to run with ANT, however I am struggling to write custom rules. I am working with the standard rules which sourceforge provides. Has anyone written custom rules for apex in PMD?
Thanks for your time.
- Kaustubh Labhe
- January 28, 2019
- Like
- 0
- Continue reading or reply
Creating New Contacts from Email-To-Case
Hi all
I'm very new to Salesforce, and my first assignment is to get our Production Org's Email-To-Case working correctly, and to find a way to create new Contacts for the Cases if they did not already exist.
After some searching on these forums I found an Apex Trigger that worked perfectly within our Sandbox. However, it fails to create Contacts in Production.
I've checked the trigger is active and triggered and I have also checked permssions. It also has 96% code coverage in Production. Has anyone got any ideas why Sandbox works and Production does not?
Apex Trigger as follows:
trigger TriggertoCreateContactformCase on Case (before insert) {
List<String> UseremailAddresses = new List<String>();
//First exclude any cases where the contact is set
for (Case c:Trigger.new) {
if (c.ContactId==null &&
c.SuppliedEmail!=''|| c.SuppliedEmail==null)
{
UseremailAddresses.add(c.SuppliedEmail);
}
}
//Now we have a nice list of all the email addresses. Let's query on it and see how many contacts already exist.
List<Contact> listofallContacts = [Select Id,Email From Contact Where Email in:UseremailAddresses];
Set<String> ExstingEmails = new Set<String>();
for (Contact c:listofallContacts) {
ExstingEmails.add(c.Email);
}
Map<String,Contact> emailToContactMap = new Map<String,Contact>();
List<Case> casesToUpdate = new List<Case>();
for (Case c:Trigger.new) {
if (c.ContactId==null &&
c.SuppliedName!=null &&
c.SuppliedEmail!=null &&
c.SuppliedName!='' &&
!c.SuppliedName.contains('@') &&
c.SuppliedEmail!='' &&
!ExstingEmails.contains(c.SuppliedEmail))
{
//The case was created with a null contact
//Let's make a contact for it
String[] Emailheader = c.SuppliedName.split(' ',2);
if (Emailheader.size() == 2)
{
Contact conts = new Contact(FirstName=Emailheader[0],
LastName=Emailheader[1],
Email=c.SuppliedEmail
);
emailToContactMap.put(c.SuppliedEmail,conts);
casesToUpdate.add(c);
}
}
}
List<Contact> newContacts = emailToContactMap.values();
insert newContacts;
for (Case c:casesToUpdate) {
Contact newContact = emailToContactMap.get(c.SuppliedEmail);
c.ContactId = newContact.Id;
}
}
Many thanks in advance!!!!
- Simon Merton
- January 28, 2019
- Like
- 0
- Continue reading or reply