Search code examples
acumaticaacumatica-kb

Kit Assembly - Custom Date Field


We need to add a custom field to store the Kit Assembly Start Date, but are unable to complete this task due to error "Table does not exist in database: INKitRegister"

If we needed a Date field instead of a text field and decorated our custom field with the following attributes + added PXDateTimeEdit on the Kit Assembly screen:

enter image description here

Now we receive a not very clear error message while entering some value in custom PXDateTimeEdit:

enter image description here


Solution

  • The INKitRegister DAC is decorated with PXProjectionAttribute and works with the INRegister database table - therefore you received the error message reported:

    [PXPrimaryGraph(typeof(KitAssemblyEntry))]
    [PXCacheName(Messages.INKit)]
    [PXProjection(typeof(Select2<INRegister, InnerJoin<INTran,
        On<INRegister.kitLineNbr, Equal<INTran.lineNbr>,
            And<INRegister.docType, Equal<INTran.docType>,
            And<INRegister.refNbr, Equal<INTran.refNbr>>>>>>), Persistent = true)]
    [Serializable]
    public partial class INKitRegister : IBqlTable, ILSPrimary
    {
        ...
    }
    

    As of right now Customization Manager does not support projection DACs and we'll have to right some code to add custom field on the Kit Assembly screen:

    1.In Customization Manager add new field for the IN.INRegister DAC following the screenshot below: enter image description here

    1. In Customization Manager add new Code file selecting DAC Extension as File Type and INKitRegister as Base DAC following the screenshot below: enter image description here

    2. Declare custom UsrTest field within the generated INKitRegister DAC extension:

      using System;
      using System.Collections.Generic;
      using System.Collections;
      using System.Text;
      using PX.Data;
      using PX.Objects.CS;
      using PX.Objects.IN.Overrides.INDocumentRelease;
      using PX.Objects.GL;
      using PX.Objects.CM;
      using System.Diagnostics;
      using PX.Objects;
      using PX.Objects.IN;
      
      namespace PX.Objects.IN
      {
        public class INKitRegisterExt : PXCacheExtension<PX.Objects.IN.INKitRegister>
        {
          #region UsrTest
          public abstract class usrTest: PX.Data.IBqlField
          {
          }
          protected String _BatchNbr;
          [PXDBString(50, BqlField = typeof(INRegisterExt.usrTest))]
          [PXUIField(DisplayName = "Test")]
          public virtual string UsrTest { get; set; }
          #endregion
        }
      }
      

    Note: to obtain BqlField name required for the DB[Type]Attribute, one should open INRegister custom field declaration in the Data Class Editor: enter image description here

    1. Publish current project

    2. Open Layout Editor for the Kit Assembly screen to add input control for the custom field declared within the INKitRegister DAC extension: enter image description here

    3. Publish current project and navigate to the Kit Assembly screen to make sure if customization was successfully applied: enter image description here

    To resolve "Unable to cast object of type A to type B" error, you should verify 2 things:

    1. if field attributes match in extensions of the INRegister and the INKitRegister DACs
    2. you declared field of the right type

    enter image description here

    In this specific case, the issue was resolved by changing type of the UsrKAStartDate to DateTime? (Nullable):

    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Text;
    using PX.Data;
    using PX.Objects.CS;
    using PX.Objects.IN.Overrides.INDocumentRelease;
    using PX.Objects.GL;
    using PX.Objects.CM;
    using System.Diagnostics;
    using PX.Objects;
    using PX.Objects.IN;
    
    namespace PX.Objects.IN
    {
        public class INKitRegisterExt : PXCacheExtension<PX.Objects.IN.INKitRegister>
        {
            #region UsrKAStartDate
            [PXDBDate]
            [PXUIField(DisplayName = "Start Date")]
            public virtual DateTime? UsrKAStartDate { get; set; }
            public abstract class usrKAStartDate : IBqlField { }
            #endregion
        }
    }