When MS PSA has been set up there are various customizations needed in addition. Depending on your business processes and requirements new elements might be added or already existing needed to be modified. However in MS PSA there is not so much customization possible as there are many OOTB Workflows, JScripts and custom Actions running on new as well as already existing Entities.

One Example is the Project Entity which is also used for the Project Template. Both elements are one Entity which uses the Information Form where a On-Load-Script from the Webressource ProjectRibbon.js handles the visibility of certain fields for Projects and Templates. Per default the value no is set on the field msdyn_istemplate (bool).

When adding new Fields to the Project Form you might also see those on the Project Template Form. To avoid this you can either write an own Script which handles visibility of certain fields or you extend the current Script. Both ideas have their drawbacks however.

The first option requires to time the On-Load of the current Script to avoid getting dirty data.

The second Option requires you to adjust the Webressource ProjectRibbon.js which also needs to be checked constantly in Case of any new PSA-Updates. Beware that those updates might overwrite the Webressource and the modifications need to be done again.

I will dive a little bit deeper into the second Option.

To understand the mechanics how the Script works when opening either a Project or a Project Template. It loads the onLoadProjectForm Function which calls the SetFormForProjectTemplate function and hides Tabs and Sections on the Project Template.

The visibility of Tabs are handled with the function _hideTabonForm which needs the name of the Tab as parameter whereas the visibility of Sections are handled with the function _hideSectiononForm which needs the Tab and the Section name as Parameters.

Here is an example:

function setFormForProjectTemplate() {
    'use strict';
    _hideTabOnForm(Project_od4uSalesTabName); // manually created
    _hideTabOnForm(Project_od4uProjectOrganizationTabName); // manually created
    _hideSectionOnForm(Project_SummaryTabName, Project_ActivitySectionName); // manually created
    _hideSectionOnForm(Project_TeamTabName, Project_ResourceRequirementsSectionName);
    if (Xrm.Page.ui.process) {

The Tab names are defined at the beginning of the Webressource as seen in the following example:

var Project_CreateProjectFromTemplateParameter = "createProjectFromTemplate_0";
var Project_SalesTabName = "Sales";
var Project_SummaryTabName = "Summary" // manually created
var Project_ActivitySectionName = "od4u_activity"; // manually created
var Project_od4uSalesTabName = "od4u_sales"; // manually created
var Project_od4uProjectOrganizationTabName = "od4u_projectorganization"; // manually created
var Project_StatusTabName = "Status";
var Project_StatusPerformanceTabName = "StatusPerformance";
var Project_ProjectTemplateTabName = "Project Template";

If you set those correctly you can use the OOTB Script as advantage without much effort.