'Acumatica How to customize Time Entries and Activities with Custom Selector Field

We want to customize the time entries and activities logic to have a custom selector field that pulls information from an attribute that is setup in the system. It has to be a required field if the TimeSpent and BilledTime does not match, the entry is marked as billable, and the project has a customer loaded against it. I have successfully managed to get it working on the Employee Time Activities screen, but I am trying to use that same custom field on the Activities popup dialog. I also get an error when adding an Activity directly to project, which states that the Time Entry requires a Reason Code but I don't have access to add it to the list to display on the Activities Panel/Dialog. See screenshots below:

Employee Time Activities

List of Attributes

Ignore the Activity Reason Code, this is an additional custom field I added to test the customization. Add Activity to Project

I want to add my custom field in here: Customize Activities Dialog

Below is the extention class DAC.

using PX.Data;
using PX.Objects.CS;
using PX.Objects.PM;
using iPlanReasonCode.Helpers;

namespace PX.Objects.CR
{
    public class PMTimeActivityExt : PXCacheExtension<PX.Objects.CR.PMTimeActivity>
    {
        #region UsrReasonCode
        [PXDBString]
        [PXUIField(DisplayName = "Reason Code")]
        [PXDefault]
        [PXSelector(typeof(Search<CSAttributeDetail.valueID, Where<CSAttributeDetail.attributeID.IsEqual<ReasonCodeAttributeID>>>),
            typeof(CSAttributeDetail.valueID), typeof(CSAttributeDetail.description), SubstituteKey = typeof(CSAttributeDetail.valueID), DescriptionField = typeof(CSAttributeDetail.description))]
        [PXUIRequired(typeof(Where<PMTimeActivity.isBillable.IsEqual<True>.And<PMTimeActivity.timeSpent.IsNotEqual<PMTimeActivity.timeBillable>>.And<Where<Selector<PMTimeActivity.projectID, PMProject.customerID>, IsNotNull>>>))]
        public virtual string UsrReasonCode { get; set; }
        public abstract class usrReasonCode : PX.Data.BQL.BqlString.Field<usrReasonCode> { }
        #endregion
    }
}

Below is the helper constant class to point it to the correct attribute code.

using PX.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace iPlanReasonCode.Helpers
{
    public class ReasonCodeAttributeID  : PX.Data.BQL.BqlString.Constant<ReasonCodeAttributeID>   
    {
        public ReasonCodeAttributeID()
                : base("CUSTREASON")
        { }
    }
}



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source