• Narender Singh(Nads)
  • PRO
  • 2877 Points
  • Member since 2018
  • Salesforce Dev & Admin
  • Miri Infotech


  • Chatter
    Feed
  • 93
    Best Answers
  • 0
    Likes Received
  • 1
    Likes Given
  • 0
    Questions
  • 754
    Replies
trigger capture on Appointment__c (after update) 
{
   list<account> acclist = new list<account> ();
    
    for(Appointment__c app: trigger.new)
    {
        if(app.Status__c=='Confirmed' &&  trigger.oldMap.get(app.Id).Status__c=='Visited')
        {
            account acc = new account();
            acc.Patient_Name__c = app.Id;
            acc.Phone_Number__c = app.Contact_Number__c;
            acc.Email__c = app.Email__c;
            
            acclist.add(acc);
        }
    }
    
    if(acclist.size()>0)
    {
        
        try{
            insert acclist;
            }
        catch(System.DmlException e)      
        {
            System.debug(e);
        }
            
    }
    
}
Hello,


I was wondering if it is possible to prevent a user from creating a task object with a Related To field that is assigned to an account of a specific record type? Tried using validation rules but unfortunately there I cannot find a way to reference the record type of the object in order to create the conditions



Thanks
MV
Hi, 

I'm Trying create an action for my Cases and when I select the action type Email, returns a message like this:
The Send Email action is off or activities are not allowed. Turn on the Email Email action and allow activities, then try again.
List<sObject> allResult= OV_Searchcc360.isDuplicate(objectType, fields, sources, null);

So allResult is a List of array having multiple records of one object , each record having several fields. I need to use  id from this collection in a Set. so i written this below code to iterate.
        Set<String> resultIds = new Set<String>();
        for (String sourceId : allResult.keySet())  
          {
          resultIds.add(sourceId .DSE__DS_Account__c);  
           system.debug('-------resultIds-----'+resultIds); 
          } 

I need help getting error
how to add a global action or button, that by clicking on it, it will start the job batch ? 

here is the code to start the job in console 

Id batchJobId = Database.executeBatch(new FindAccounts(), 100);

 
Hello,

i have an related list on contacts for an custom object. Until Summer 18 new new button submitted the contact.id, but its submits the name. And spaces are filled with +. Like: 
Name: Peter Boelke
Submitted: Peter+Boelke

I have dialog which parses the url String, early i got the ID from it, now i need to change to work with the name. But because of the replacement it doesnt really work.
ich do "Peter+Boelke".replace('+', ' ')  its ok
but "Peter+Boelke+somewhat".replace('+', ' ') it returns Peter Boelke+somewhat

How can i solve my matter?
Part of my script
<script type="text/javascript">
        sforce.connection.sessionId = '{!$Api.Session_ID}';
    var conn = new jsforce.Connection({ accessToken: '{!$Api.Session_Id}' });
    var url_string = window.location.href;
    var url = new URL(url_string);
    console.log(url);
    var c = url.searchParams.get('href');
    var contact = window.location.search.substr(1).split('&')[1].split('=')[1].replace('+', ' ');
    console.log(contact);
    var queryCon = "SELECT Id, Name, Account.Name from Contact WHERE Name LIKE '" + contact + "'";
    var recordsCon = sforce.connection.query(queryCon).getArray('records');
    console.log(recordsCon[0].Id);
    var query = "SELECT Warengruppe__c, Kontakt__c from Warengruppen_Zuordnung__c WHERE Kontakt__c = '" + recordsCon[0].Id + "'"; 
    var records = sforce.connection.query(query).getArray('records');
    var selKeys;
    var unselKeys = [];
    var path = '/services/data/v41.0';
    var queryCon = "SELECT Name, Account.Name from Contact WHERE Name = '" + contact + "'";

</>

 
I am trying to display list of Accounts using Standard controller and allow inline edit of records displayed. The Save button I have added is not working/saving the udpate in database. Can someone please help, what m I missing
Do I need to write extension for this?

Code piece:
<apex:page standardController="Account" recordSetVar="Account">  <!-- extensions="myControllerExtension"> -->
    <apex:form >
    <apex:pageBlock title="Account Summary" mode="inlineEdit">
    <apex:inlineEditSupport showOnEdit="saveButton, cancelButton" 
                        hideOnEdit="editButton" event="ondblclick" 
                        changedStyleClass="myBoldClass" resetFunction="resetInlineEdit"/>
                        
                <apex:commandButton action="{!quicksave}" id="saveButton" value="Save" rendered="true"/>
                <apex:commandButton onclick="resetInlineEdit()" id="cancelButton" value="Cancel" rendered="true"/>
  <apex:pageBlockTable value="{! Account}" var="at">
            <apex:column value="{! at.Name }"/>
            <apex:column value="{! at.Phone}"/>
            <apex:column value="{! at.Industry}"/>
            <apex:column value="{! at.AnnualRevenue }"/>
            <apex:column value="{! at.Id }"/>
        </apex:pageBlockTable>
    </apex:pageBlock>
     </apex:form>
</apex:page>
I was trying to log in to Dataloader as part of the "User Data Loader to Expert Data" Module and it's not recognizing my login and password, I tried using my trailhead URL, but still nothing. Any ideas?
Given I have an Opportunity and there are no open Mandatory sales tasks associated to it When I try and change the opportunity stage
then this shall be allowed by the system. Given I have an Opportunity and there are open Mandatory sales tasks associated to it
When I try and change the opportunity stagetThen the system shall throw a validation error.

trigger Opportunity_Task on Opportunity (before update) {
    List<Task> ts =new List<Task> ();
    List<Opportunity> op =new List<Opportunity>();
    Map<Id,Opportunity> oldMap = trigger.oldMap;
    Map<Id,Opportunity> newMap = trigger.newMap;
    List<id> optyid = new List<id>();
    for(id opid:oldMap.keySet()) {
        Opportunity op =new Opportunity();
        if(oldMap.get(opid).tasks == null && op.stageName=='Closed Won') {
            op.addError('You can create a new task for that Opportunity');
            task t = new task();
            t.WhatId=opid;
            t.Description='kjdkfhsdkf';
            t.Status='open';
            ts.add(t);
        }
        else{
            if(oldMap.get(opid).tasks!=null && op.StageName=='Closed Won')
            op.addError('You cannot modify the opportunity status');
            
        }
    }
    
}
I am an experienced Administrator but not a developer. I tried my hand at creating a very simple ApexClass with a Visual Force Page. The page is meant to be embeded on an Asset Page Layout, and return Custom Object Records where the Name matches the Asset's Serial Number. This part works fine, the problem is the test class. I have spent more time than I care to admit (days) trying to figure this out, looking at documentation and code examples. I am at a loss and hoping someone can lend a hand.

Here is my ApexClass:
public class DongleRecords
{
    public List<Dongle_Record__c> DongleRecords { get; set; }
   
    Public DongleRecords ( ApexPages.StandardController std )
    {
        if( std.getRecord().Id != null )
        {
            Asset con = [ Select Id, SerialNumber from Asset where Id =: std.getRecord().Id ];
           
            DongleRecords = [ Select Name, Application_Name__c, Number_of_Licenses__c, Release_Date__c, Expiry_Date__c, Last_Upgrade_Date__c from Dongle_Record__c where Name =: con.SerialNumber ];
        }
        else
        {
            DongleRecords = new List<Dongle_Record__c>();
        }
    }        
}
Here is my VF Page
<apex:page StandardController="Asset" extensions="DongleRecords">
    <apex:form >
        <apex:pageBlock title="Dongle Licenses">
            <apex:pageBlockTable value="{!DongleRecords}" var="dg">
                <apex:column value="{!dg.Name}"/>
                <apex:column value="{!dg.Application_Name__c}"/>
                <apex:column value="{!dg.Number_of_Licenses__c}"/>
                <apex:column value="{!dg.Release_Date__c}"/>
                <apex:column value="{!dg.Expiry_Date__c}"/>
                <apex:column value="{!dg.Last_Upgrade_Date__c}"/>
            </apex:pageBlockTable>   
        </apex:pageBlock>
    </apex:form>
</apex:page>
Here is my Test Class so far:
Attempting to Create an Account, an Asset, and a Dongle_Record__c, and then somehow test the Calss and VF Page.
@isTest
public class DongleRecordsTest
{
    static testMethod void testMethod1()
    {
        Account testAccount = new Account();
        testAccount.Name='Test Account' ;
        insert testAccount;
       
        Asset ast = new Asset();
        ast.Name ='Test Asset';
        ast.SerialNumber ='TEST0000';
        ast.accountid = testAccount.id;
        insert ast;
       
        Dongle_Record__c dng = new Dongle_Record__c ();
        dng.Name = 'TEST0000';
        insert dng;
       
        Test.StartTest();

         ApexPages.currentPage().getParameters().put('id', String.valueOf(ast.Id));

        Test.StopTest();
    }
}
Any help would be tremendously appreciated...


 
Hi,
I am currently trying to learn salesforce.
Following is my understanding(correct me if i am wrong)

Database.com
-Database as a service.
-Uses oracle under the hood.
-Provides REST API service to interact with database.

Force.com
-Platform as a service.
-Provides metadata layer(Apex language,tool to edit/debug code,visualforce page etc.)
-Provides default metadata for database.com field types.
-Uses Database.com under the hood(for storing data and metadata).

Salesforce.com
-Software as a service.
-Uses Force.com under the hood.
-Provides few data model (i.e.schema) eg:-sales,marketing.
-Provides a framework(mainly UI) to create/configure various parameters of metadata and data model.

Question
I believe database.com, force.com and salesforce.com are 3 different services. But on searching I am always end up at salesforce CRM.Is it possible to use Database.com or Force.com alone i.e. without salesforce CRM?
Thank you!
I'm trying to get the below work but it's not populating the way I want it to.
1. Needs to be true
2. Needs to be true
3. Needs to be true
6  Needs to be true
and if 4 and 5 are true it needs to not appear on the report.

Any ideas On what I need to change as that is the only part that isn't working properly.

(3 OR 2 OR (4 AND 5))Filter Logic: (1 AND (3 OR 2 OR (4 AND 5)) AND 6)
1. Responsible Company equals "Enterprise Insurance Group"
2. Record Type not equal to "PEO"
3. Status equals "Active"
4. Record Type Equal to "Workers Compensation"
5. Premium greater than ""15,000""
6. Special Account not equal to "True"
Is it possible to have a modal or toast appear on a list view when the case status or owner change? Or have them appear on their home page when they log in?
Error: "The field 'Potential_Value__c' does not exist"

But it does!
Not only do I see it, I have also tried a different playground and despite of seeing it there too, I get the same message. 
It has to be a bug, but what can I do on my end?
Thanks!
 
Hello,
How can a VF page be centered in the users window?  It either opens in left cowner or full screen.
Thanks,
M
Hi All,
I am trying to update the info on a Visualforce page from the REST API from the site.  I was given a bearer token and I used Postman to get the access token.  I am confused because there are no errors, but the code isn't working.  How do I make this code work?
 
public class AccountShippingController {
   
    public String trackingnumber {get;set;}
    public String shipmentStatus {get;set;}
    public String shipperAddr {get;set;}
    public String consigneeAddr {get;set;}

    public AccountShippingController(ApexPages.StandardController stdController){
                    
        			Account account =(Account)stdController.getRecord();
                    account = [SELECT Id, XPO_Tracking__c FROM Account WHERE Id =:account.Id];
                    
                    String accountTracking = account.XPO_Tracking__c;
                    String apiKey = 'XXXXXXXX';
                    
                    String requestEndpoint = 'https://api.ltl.xpo.com/tracking/1.0/shipments/shipment-status-details';
                    requestEndpoint += '?referenceNumbers[]=' + accountTracking;
        			requestEndpoint += '&APPID=' + apiKey;
                    
                    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());
                        trackingnumber = String.valueOf(results.get('referenceNumbers'));
                        
                        Map<String, Object> shipmentStatusDtlsResults = (Map<String, Object>)(results.get('shipmentStatusDtls'));
                        shipmentStatus = String.valueOf(shipmentStatusDtlsResults.get('shipmentStatus'));
                        shipperAddr = String.valueOf(shipmentStatusDtlsResults.get('shipperAddr'));
                        consigneeAddr = String.valueOf(shipmentStatusDtlsResults.get('consigneeAddr'));
                    } else {
                        ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, 'There was an error retrieving the information.  Double check the Tracking Number, then contact a system administrator.');
                        ApexPages.addMessage(myMsg);
                        
                    }
                }
            }
 
<apex:page standardController="Account" extensions="AccountShippingController" showHeader="false" sidebar="false">
           <apex:pageBlock title="Shipping Information">
    			<apex:pageBlockSection >
                
                    <apex:pageMessages />
               
                    <apex:outputText label="Shipping Status" value="{!shipmentStatus}"/>
                    <apex:outputText label="Shipper Information" value="{!shipperAddr}"/>
                    <apex:outputText label="Consignee Information" value="{!consigneeAddr}"/>
                                                                                                            
                </apex:pageBlockSection>
    </apex:pageBlock>
</apex:page>

 
Hi Everyone,

I am trying to add 100++ campaign members to the campaign that I have created.
However while doing this we encounter a SOQL queries:101 error.
After doing some checking this error is caused by this 3 process builders:
1. Process builder to update a campaign member field based on contact field whenever it is created.
2. Process builder to update a campaign member field based on other campaign member field whenever it is created.
3. Process builder to update campaign member field based on other campaign field whenever it is created or edited.

If the we limit the upload to 25 or 50 members at once we will not receive this error.
After deactivating these 3 process builder the upload can work correctly even with 100++ member at once

Are there any solution to solve this? Does process builder do not support bulkified upload?

User-added image
In below screenshot:
User-added image

1) I am not able to see value in above section
table value should be shown in above section like:
In the table, We have 2 Rejected and 1 Accepted. These values should be shown in above. 
2) When I click on either accept or Reject button then status value should be change accordigly
I have created a component for this. How can i do this?
trigger capture on Appointment__c (after update) 
{
   list<account> acclist = new list<account> ();
    
    for(Appointment__c app: trigger.new)
    {
        if(app.Status__c=='Confirmed' &&  trigger.oldMap.get(app.Id).Status__c=='Visited')
        {
            account acc = new account();
            acc.Patient_Name__c = app.Id;
            acc.Phone_Number__c = app.Contact_Number__c;
            acc.Email__c = app.Email__c;
            
            acclist.add(acc);
        }
    }
    
    if(acclist.size()>0)
    {
        
        try{
            insert acclist;
            }
        catch(System.DmlException e)      
        {
            System.debug(e);
        }
            
    }
    
}
I override the account "edit" button. I made visualforce page and apex class for this. In visualforce page, there are contacts that are related to account and each contact have an edit and delete button. When i click on "edit" button it opens a contact edit page(Standard) and save that record.
My requirement is -
when i edit a record and save it. After saving it goes to Parent page(Visualforce page- Account edit page).

Visualforce Page
<apex:page standardController="Account" extensions="AccountEditButtonPage" tabStyle="Account">
    <apex:sectionHeader title="Account Edit" subtitle="New Account" />
    <apex:form id="RID">
        <apex:pageblock title="Account Edit"> 
            <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!Save}"/>
                <apex:commandButton action="{!cancel}" value="Cancel"/>                       
            </apex:pageBlockButtons>                       
            <apex:pageBlockSection title="Account Information" collapsible="false" columns="2">
                <apex:inputField value="{!Account.ownerId}" />
                <apex:inputField value="{!Account.Rating}" />
                <apex:inputField value="{!Account.name}" />
                <apex:inputField value="{!Account.Phone}" />
                <apex:inputField value="{!Account.ParentId}" />
                <apex:inputField value="{!Account.fax}" />
                <apex:inputField value="{!Account.AccountNumber}" />
                <apex:inputField value="{!Account.Website}" />
                <apex:inputField value="{!Account.Site}" />
                <apex:inputField value="{!Account.TickerSymbol}" />
                <apex:inputField value="{!Account.type}" />
                <apex:inputField value="{!Account.ownership}" />
                <apex:inputField value="{!Account.Industry}" />
                <apex:inputField value="{!Account.NumberOfEmployees}" />
                <apex:inputField value="{!Account.AnnualRevenue}" />
                <apex:inputField value="{!Account.Sic}" />
                <apex:inputField value="{!Account.Contact__c}" />
                <apex:inputField value="{!Account.site}" />
                </apex:pageBlockSection>
                
                <apex:pageBlockSection title="Address Information" collapsible="false" columns="2">
                <apex:inputField value="{!Account.BillingStreet}" />
                <apex:inputField value="{!Account.ShippingStreet}" />
                <apex:inputField value="{!Account.BillingCity}" />
                <apex:inputField value="{!Account.ShippingCity}" />
                <apex:inputField value="{!Account.BillingState}" />
                <apex:inputField value="{!Account.ShippingState}" />
                <apex:inputField value="{!Account.BillingPostalCode}" />
                <apex:inputField value="{!Account.ShippingPostalCode}" />
                <apex:inputField value="{!Account.BillingCountry}" />
                <apex:inputField value="{!Account.ShippingCountry}" />
            </apex:pageBlockSection>            
            <apex:pageBlockSection title="Additional Information" collapsible="false" columns="2">
                <apex:inputField value="{!Account.CustomerPriority__c}" />
                <apex:inputField value="{!Account.SLA__c}" />
                <apex:inputField value="{!Account.SLAExpirationDate__c}" />
                <apex:inputField value="{!Account.SLASerialNumber__c}" />
                <apex:inputField value="{!Account.NumberofLocations__c}" />
                <apex:inputField value="{!Account.UpsellOpportunity__c}" />
                <apex:inputField value="{!Account.Active__c}" />
                <apex:inputField value="{!Account.AccountSource}" />
                </apex:pageBlockSection>
                
                <apex:pageBlockSection title="Description Information" collapsible="false">
                <apex:inputField value="{!Account.Description}" />
            </apex:pageBlockSection>
        </apex:pageBlock>
        <apex:pageBlock title="Contacts">
            <apex:pageBlockTable value="{!conList}" var="con">
                <apex:column >
                <apex:commandButton value="Edit" action="{!editCont}" reRender="RID">
                <apex:param value="{!con.id}" name="editId" assignTo="{!editId}"/>
                </apex:commandButton>
                <apex:commandButton value="Delete" action="{!delContact}" reRender="RID">
                    <apex:param value="{!con.id}" name="contactId" assignTo="{!contactId}"/>
                </apex:commandButton>
                </apex:column>
                <apex:column value="{!con.Name}"/>
                <apex:column value="{!con.Email}"/>
                <apex:column value="{!con.Phone}"/>                
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Apex Class
public class AccountEditButtonPage {        
    public String accId {get;set;}       
    public List<Contact> conList{get;set;}
    public String contactId{get;set;}  
    public String editId{get;set;}
    public AccountEditButtonPage(ApexPages.StandardController controller) {
        accId  = ApexPages.CurrentPage().getparameters().get('id');
        conList = [select id,Name,email,Phone from contact where AccountId =: accId];
        system.debug('--8--' +conList);
    }
    public pageReference delContact(){        
        system.debug('--12--'+contactId);
        Contact conRecord = [select id from contact where id= :contactId];
        Delete conRecord;
        PageReference retURL = new PageReference('/apex/AccEditButtonOverridePage?id='+accId);
        retURL.setRedirect(true);
        return retURL;
    }
    public PageReference editCont(){
        system.debug('--10--'+editId);
         PageReference editURL = new PageReference('/'+editId+'/e');     
        editURL.setRedirect(true);
        return editURL;
        }  
    
}


 
Hi everyone, 

I keep getting this error message no matter what I change and try, any insights?

"There was an unexpected error in your org which is preventing this assessment check from completing: System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Requirements for opportunities > $100,000: []"

Can anyone isolate it to the Approval Process or Process Builder?
Type of field Pass__c is Text (Encrypted):
I create function login:
MyAccount__c  accountToUpdate =  [SELECT UserName__c FROM MyAccount__c   WHERE Status__c=1 and UserName__c=:username and Pass__c=:password   LIMIT 1];
But it show error:
and UserName__c=:username and Pass__c=:password   LIMIT 1
                              ^
ERROR at Row:1:Column:88
field 'Pass__c' can not be filtered in a query call
How can fillter field is Text (Encrypted)?


 
Hi, 
I just can't seem to get pass stage 10, as I keep getting, the below error:
"The View Lightning Campaign Influence Report link on the Campaign object must use a relative URL and dynamic filter values."
I have tried with different trail orgs and same issue persists.  Has anyone tried this challenge recently and do you have this issue?

The link in the button I have is "/one/one.app#/sObject/00O0N000004ti60/view?fv0={!Campaign.Id}" - the ID of the report is correct and when clicked from campaign it filters correctly.
Screenshot:
Campaign report link

 
how to add a global action or button, that by clicking on it, it will start the job batch ? 

here is the code to start the job in console 

Id batchJobId = Database.executeBatch(new FindAccounts(), 100);

 
I was trying to log in to Dataloader as part of the "User Data Loader to Expert Data" Module and it's not recognizing my login and password, I tried using my trailhead URL, but still nothing. Any ideas?
Hello

ive created a flow that I need to pull in or select the profile ID on the user object. I keep receiving this error

MALFORMED_ID: Profile ID: id value of incorrect type:

has anyone successfully created the correct flow syntax when creating a user record?,
Hi,

I am not able to get the license and profile set up correctly for Ada Balewa, and I have tried all the licences available.

User-added image

User-added image

User-added image

Any tip?

Thanks a lot

Dani
Hi there,

I just thought I'll write the results of my journey through the Salesforce APEX REST world. This is not a question, rather a documentation. Please note that I'm more of a newbie rather than an experienced programmer. I'll try to be precise but sometimes I might simply don't know better. In the end it did work for me - after several hours of looking, testing and reading.
What do I want to do?
The primary intention is to offer a form on my web server (NOT Salesforce) for people to register. In our case we already have Accounts and Contacts in our Salesforce system and we want to ask (some) of the contacts to go to our web-site and apply for the restriceted area. They would be supplying their email address, their account number and a password.
Later - after their request has been approved - they gain access to the web server's restricted site (again - NOT Salesforce) by checking the Salesforce data.
What was my first thought?
Easy, I thought. Create some Javascript. The customer loads the JS into his browser. Upon the button pressed event it takes the data from the form and does post it against a REST endpoint at Salesforce. There I would have a REST service - simply a very basic APEX class with some special "comments" - and this class would be doing the thing.
What I did forget...
was that stuff with the security.
First trap was the so-called CORS stuff (Cross-Origin Resource Sharing). The customer's browser is loading code from my web server. And the JS code loaded from this server, running on the customer's client, would be calling something on a different domain - Salesforce. So browsers do not allow this. Unless - well - unless the second server allows it --> you have to whitelist the web server.
I tried this - but it did not work. Basically the message is: you are not allowed to call an APEX REST service if you didn't authenticate yourself. So - how would we be doing this?
Use OAUTH...
Salesforce offers several so-called flows to authenticate a user. It is really worth spending a few minutes to read the help here - https://help.salesforce.com/articleView?id=remoteaccess_authenticate.htm&type=5 . The thing is that - at least to the extend I understood the documentation - you either prompt the user for a SALESFORCE UserId and Password throught the standard login screen (which isn't really nice, and which requires every user to have corresponding SALESFORCE license), or you do use some kind of pre-shared secret (my understanding is based upon docs like this: https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/extend_code_cors.htm where it says at the bootom: „CORS does not support requests for unauthenticated resources, including OAuth endpoints. You must pass an OAuth token with requests that require it.“)
I decided to go with the so-called Java Web Token JWT. Well - nice - but then my Javascript would have the pre-shared secret somewhere on the browser. And if it's on the browser it's no secret anymore.... So I did
Get rid of CORS
and decided to implement the connectivity to Salesforce not with Javascript in the browser on the customer's client but using PHP on web server.
The JWT scenario works like this:
- you set up a so-called "Connected app" in Salesforce (Set-up -> Build --> Create --> Apps
- I did specify to use OAuth
- the OAuth policy included:
* Admin approved users are pre-authorized
* Scope includes "Perform requests on your behalf at any time" and "Access and manage your data"
* a digital certificate - I created a selfsigned certificate using openssl (openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365) - I did upload the cert.pem to Salesforce - and the key.pem on my webserver - surely not into the webroot - you know – this file should be kept REALLY confidentially...
- I then did create a permission set to include the connected app and assigned the permission set to a user (AFAIK the APEX REST class to do the work for the service runs at system level - so who-ever this user is - he/she can do a LOT...
So now - what happens?
The PHP code on the server creates a request. It addresses a well-know endpoint and fills in some data. It signs the data with the private key that we did generate earlier. Then it calls the endpoint. Salesforce checks the signature using the certificate, finds the connected app based upon the data in the request and provides a token - a "newly generated password" back to the PHP code.
The PHP code uses this token to authenticate the request that it sends to the Salesforce APEX REST endpoint.
The code
Let me give you some example.
The HTML file on the web server
<!DOCTYPE html> 
<html lang="en"> 
<head> 
<meta charset="utf-8"> 
<title>Integration to Salesforce - Test</title> 
</head>
<body>
<!-- Form -->
<form name="applicant" id="applicant" autocomplete="off">
<p>
<label>Email</label><input type="text" id="email" size="64" autofocus>
</p>
<p>
<label>Ext.Account No.</label><input type="text" id="kdnr" size="64">
</p>
<p>
<label>Password</label><input type="password" id="password" size="64">
</p>
<p><button class="btn btn-success" id="btnSubmit" type="button" onclick="btnSubmitOnClick()">Submit</button></p>


<p><span id="insertresult"></span></p>
</form>
<script type="text/javascript" src="md5.min.js"></script>

<script type="text/javascript" src="testsf.js"></script>

</body>
</html>
The testsf.js Javascript on the webserver (md5.min.js is a tool library that also resides on the server - get it in the internet..)
function btnSubmitOnClick() {
	var email = document.getElementById( "email").value;
	var kdnr = document.getElementById( "kdnr").value;
// we won't be storing the password anywhere in clear text - use the md5 coded value - and yes I know - this is NOT secure - but this is a demonstration only
	var password = md5( document.getElementById( "password").value);

// and yes - we should be doing some checks here to make sure we do not get malformed data --> https://stackoverflow.com/questions/295566/sanitize-rewrite-html-on-the-client-side/430240#430240
    
	var xhr;
	var data = 'email=' + email + '&kdnr=' + kdnr + '&password=' + password;

	xhr = new XMLHttpRequest();
	xhr.open( "POST", "jwtbearer.php", true);
	xhr.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded");
	xhr.addEventListener( "load", display_insert);
	xhr.send( data);

	function display_insert() {
		document.getElementById( "insertresult").innerHTML = xhr.responseText;
	}
}
Now for the PHP code in jwtbearer.php on the web server:
<?php
// ini_set('display_errors', 'On');
// error_reporting(E_ALL | E_STRICT);
$email = $_POST ['email'];
$kdnr = $_POST ['kdnr'];
$password = $_POST ['password'];

// documentation in https://help.salesforce.com/articleView?id=remoteaccess_oauth_jwt_flow.htm&type=5
// code based upon https://developer.salesforce.com/forums/?id=906F00000005HTiIAM

// the following values ought to be defined via $_SERVER ['variables']
// this is the client ID in the connected app
define('CONSUMER_KEY', 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXX');
// and this is the secret of the connected app - actually we do not use it
define('CONSUMER_SECRET', '99999999999999');
// the subject is a name of a user. Make sure that
// - the connected application is set to "Admin approved users are pre-authorized"
// - there exists a permission set that has the right to access the connected application
// - this user is assigned to the permission set
// - the connected application has at least the following two scopes: "Access and manage your data (api)", "Perform requests on your behalf at any time (refresh_token, offline_access)"
// - the connected app has attached the certificate for the private key further down
define('SUBJECT', 'user@domain.test');

define('LOGIN_BASE_URL', 'https://test.salesforce.com');

// First step: get an authorization token from Salesforce that allows us to later call the APEX REST service
// we do this using the so-called JWT bearer flow --> https://help.salesforce.com/articleView?id=remoteaccess_oauth_jwt_flow.htm&type=5

// this is where we'll getting the token from
$token_url = LOGIN_BASE_URL.'/services/oauth2/token';

// JSon Header
$h = array(
	"alg" => "RS256"	
);

$jsonH = json_encode(($h));	

// ATTENTION: it has to be base64URL encoded!!!
$header = rtrim(strtr(base64_encode($jsonH), '+/', '-_'), '=');

// Create JSon Claim/Payload
$c = array(
	"iss" => CONSUMER_KEY, 
	"sub" => SUBJECT, 
	"aud" => LOGIN_BASE_URL, 
	"exp" => strval(time() + (5 * 60))
);

$jsonC = (json_encode($c));	

$payload = rtrim(strtr(base64_encode($jsonC), '+/', '-_'), '='); 

$jwtToBeSigned = $header.'.'.$payload;

// This is where openssl_sign will put the signature
$signature = "";

// get the private key from a file (and supply the password for this key - ought to be stored in a S_SERVER variable as well
$pkeyid = openssl_pkey_get_private("file:///etc/php5/apache2/mykey.pem", "9999999999");

// Sign the header and payload
openssl_sign($jwtToBeSigned, $signature, $pkeyid, OPENSSL_ALGO_SHA256);
openssl_free_key($pkeyid);

// Base64URL encode the signature
$secret = rtrim(strtr(base64_encode($signature), '+/', '-_'), '=');

// construct the "assertion" that Salesforce will use to test
$assertion = $header.'.'.$payload.'.'.$secret;

// and from this construct the array of fields to post
$post_fields = array(
	'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
	'assertion' => $assertion
);

// now prepare the cURL session
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $token_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

// Make the API call, and then extract the information from the response
$token_request_body = curl_exec($ch);
if ( $token_request_body === FALSE) {
    echo "<pre>";        
    echo "Error from curl_exec during JWT bearer token request: " . curl_error( $ch);
    echo "</pre>";   
    return;
}

// so now we got the token - let's extract the relevant info
$token_request_array = json_decode( $token_request_body, true);

$theToken = $token_request_array[ 'access_token'];
$theInstance = $token_request_array[ 'instance_url'];

curl_close($ch);

// now start the real Service call
// salesforce will tell us where EXACTLY we have to ring...
$token_url = $theInstance . '/services/apexrest/hpp/v1';

// remember: the APEX class in salesforce defines the path; the methods in this class correspond to the various types like POSt, GET....
// Content-type has to be correct
$headers = array( 
            "POST " . "/services/apexrest/test/v1". " HTTP/1.1",
            "Content-type: application/json", 
            "Accept: */*", 
            "Cache-Control: no-cache", 
            "Pragma: no-cache",
            "Authorization: Bearer " . $theToken
        ); 

// these are the fields we want to submit to the APEX REST service
$post_fields = array(
	'email' => $email,
	'kdnr' => $kdnr,
	'password' => $password
);


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $token_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_fields));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 

$service_request_body = curl_exec($ch) ;
   
if ( $service_request_body === FALSE) {
    echo "<pre>";        
    echo "Error from curl_exec during APEX REST call: " . curl_error( $ch);
    echo "</pre>";    
    return;
}
    
curl_close($ch);
echo "Success!";
Now to Salesforce. I addedd two checkbox fields to the Contact standard object - Applied_for_web_access__c and Granted_web_access__c. I also added a text(32) field to store the hashed password: Web_Hash__c.
Here is the sample code for the APEX class serving as the REST service:
@RestResource(urlMapping='/test/*')
global with sharing class testRestInterface {
    @HttpPost
    global static String createApplicationForAccess( String email, String kdnr, String password) {
        Contact[] cList = [Select Id From Contact Where Email = :email and Account.ExtAccountNo__c = :kdnr];
        if ( !cList.isEmpty()) {
            Contact aContact = cList[0];
            aContact.Applied_for_web_access__c = true;
            aContact.Web_Hash__c = password;
            update aContact;
        } else {
/* here I decided to create a lead... */
            Lead aLead = new Lead( Lastname='Unknown web access requestor', Company='unkonwn company', Applied_for_web_access__c = true, Web_Hash__c = password);
            insert aLead;
        }
        return 'SUCCESS';
    }

}
Later in the project I did use Email Actions with Email Templates that get send upon Changes to the Checkboxes caught in Process Builder - but that's another story....

Lessons learned:
- no APEX REST access without authentication
- authentication done on the web server - not on the client
- base64URL encoded values in the JWT bearer section
- pre-authorized users, with permission set

So - hopefully I did not state something totally wrong here and hopefully too this will help somebody someday.