How To Make Selector For Csanswers

 

Hello everybody,

recently one of the colleagues asked me how to make selector from Attributes values. Also that request seem trivial, but still took some time, especially with usage of FBQL query to build. 

Below goes template you may use if you'll need some kind of selector for attributes by some predefined value:

 

public class SOOrderExt : PXCacheExtension<SOOrder>
    {
        public class Codes
        {
            public const string MediaCode = "MEDIACODE";

            public class mEdiaCode : BqlType<IBqlStringstring>.Constant<mEdiaCode>
            {
                public mEdiaCode() : base("mEdiaCode")
                {
                }
            }

            public const string OrdOrigin = "ORDORIGIN";

            public class ordOrigin : BqlType<IBqlStringstring>.Constant<ordOrigin>
            {
                public ordOrigin() : base("ORDORIGIN")
                {
                }
            }
        }

        [PXSelector(typeof(SearchFor<CSAnswers.value>.Where<CSAnswers.attributeID.IsEqual<Codes.ordOrigin>>))]
        [PXDBString(50)]
        public string SomeValue1 { getset; }

        [PXSelector(typeof(SearchFor<CSAnswers.value>.Where<CSAnswers.attributeID.IsEqual<Codes.mEdiaCode>>))]
        [PXDBString(50)]
        public string SomeValue { getset; }
    }

 

 For me it was also interesting to note, that in the past it was common to use for Selector combination of PXSelector with Search, but in FBQL you'll need PXSelector with SearchFor.

How To Manage Default Order Of Columns In Selector Of Acumatica

 

Hello everybody,

today I want to leave a short notice on how to manage order of columns in Selector of Acumatica. Quite often customers has desire to manage default order of columns in selector. That is very easy to achieve with new Type[] parameter added to your selector. Take a look on how I've managed list of columns for Carrier with help of new Type[]:

[PXDBString(15, InputMask = ">aaaaaaaaaaaaaaa", IsKey = true, IsUnicode = true)]
[PXDefault]
[PXUIField(DisplayName = "Ship Via", Visibility = PXUIVisibility.SelectorVisible)]
[PXSelector(typeof(Search<Carrier.carrierID>), new Type[]
       {
         typeof(Carrier.description), typeof(CarrierExt.usrDeliveryLength), typeof(Carrier.confirmationRequired),
         typeof(Carrier.packageRequired), typeof(Carrier.isCommonCarrier)
       },
        CacheGlobal = true, DescriptionField = typeof(Carrier.description))]
protected void Carrier_CarrierID_CacheAttached(PXCache sender)
       {
       }
    }

And below goes screenshot of selector:

As you can see at screenshot, column Delivery duration appeared second in the list, but by default, if I've added that column later, it would be displayed in the end of list.

No Comments

Add a Comment
 

 

Pxdimensionselector And Pxselector In Acumatica

 

Hello everybody,

Today I want to describe PXDimensionSelector attribute usage in Acumatica. According to manual PXDimensionSelector attribute has following purpose:

Defines an input control that combines the functionality of the PXDimenstion attribute and the PXSelector attribute. A user can view the data set defined by the attribute and select a data record from this data set to assign its segmented key value to the field or to replace it with the surrogate key

After reading such purpose, I've decided to read purpose of PXDimension attribute:

Defines an input control that formats the input as a segmented key value and displays the list of allowed values for each key segment.

If those two descriptionss made you understand their pupose and way of usage, then congratulations, but for me it took muuuuuuuch longer. 

Business case ( some details intentionally changed )

I was asked to create table, which has some information about Accounts and their belonging to branches ( later I'll provide sql for table creation as well as filling of created table it with some data ). Then page Sales orders has column Branch, Account, SubAccount should filter list of Accounts and SubAccounts as you can see on the screenshot:

requirement is the following: values at column Account should be filtered by what is selected in the Column Branch by means of showing only those Accounts, which has the same branch in table CompanyAccount.

Preparation

In order to give you a better idea how data was looking like, I've created some sample data with DAC class. Also in order to have some data to play around, I've installed Acumatica with SalesDemo data in order to avoid headache of configuring all from scratch.

Below goes SQL for table creation and filling with some data.

Table creation sql:

SET ANSI_NULLS ON
GO
 
SET QUOTED_IDENTIFIER ON
GO
 
CREATE TABLE [dbo].[CompanyAccount](
	[CompanyID] [int] NOT NULL,
	[CmpBranchID] [int] NOT NULL,
	[AccountID] [int] NOT NULL,
	[Description] [nvarchar](60) NULL,
	[tstamp] [timestamp] NOT NULL,
	[CreatedByID] [uniqueidentifier] NOT NULL,
	[CreatedByScreenID] [char](8) NOT NULL,
	[CreatedDateTime] [datetime] NOT NULL,
	[LastModifiedByID] [uniqueidentifier] NOT NULL,
	[LastModifiedByScreenID] [char](8) NOT NULL,
	[LastModifiedDateTime] [datetime] NOT NULL,
	[NoteID] [uniqueidentifier] NULL,
 CONSTRAINT [PK_CompanyAccount] PRIMARY KEY CLUSTERED 
(
	[CompanyID] ASC,
	[CmpBranchID] ASC,
	[AccountID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
 
ALTER TABLE [dbo].[CompanyAccount] ADD  CONSTRAINT [DF_CompanyAccount_CompanyID]  DEFAULT ((0)) FOR [CompanyID]
GO
 
ALTER TABLE [dbo].[CompanyAccount] ADD  CONSTRAINT [DF_Table_1_CNBranchID]  DEFAULT ((0)) FOR [CmpBranchID]
GO

Filling with data of CompanyAccount table:

INSERT INTO [dbo].[CompanyAccount] ([CompanyID],[CmpBranchID],[AccountID],[Description],[CreatedByID],[CreatedByScreenID],[CreatedDateTime]
		,[LastModifiedByID],[LastModifiedByScreenID],[LastModifiedDateTime],[NoteID])
     VALUES (
				2, 16,1195, 'Discount Taken', 'B5344897-037E-4D58-B5C3-1BDFD0F47BF9', 'AR301000', '2018-12-13 00:52:31.550', 
				'B5344897-037E-4D58-B5C3-1BDFD0F47BF9', 'AR301000', '2018-12-13 00:52:31.550', NULL)
 
INSERT INTO [dbo].[CompanyAccount] ([CompanyID],[CmpBranchID],[AccountID],[Description],[CreatedByID],[CreatedByScreenID],[CreatedDateTime]
		,[LastModifiedByID],[LastModifiedByScreenID],[LastModifiedDateTime],[NoteID])
     VALUES
           (
				2,16,1223,'Office Expense', 'B5344897-037E-4D58-B5C3-1BDFD0F47BF9', 'AR301000', '2018-12-13 00:52:31.550', 
				'B5344897-037E-4D58-B5C3-1BDFD0F47BF9', 'AR301000', '2018-12-13 00:52:31.550', NULL
		   )
INSERT INTO [dbo].[CompanyAccount] ([CompanyID],[CmpBranchID],[AccountID],[Description],[CreatedByID],[CreatedByScreenID],[CreatedDateTime]
		,[LastModifiedByID],[LastModifiedByScreenID],[LastModifiedDateTime],[NoteID])
     VALUES
           (
				2,16,1224,'Postage and Delivery', 'B5344897-037E-4D58-B5C3-1BDFD0F47BF9', 'AR301000', '2018-12-13 00:52:31.550', 
				'B5344897-037E-4D58-B5C3-1BDFD0F47BF9', 'AR301000', '2018-12-13 00:52:31.550', NULL
		   )
INSERT INTO [dbo].[CompanyAccount] ([CompanyID],[CmpBranchID],[AccountID],[Description],[CreatedByID],[CreatedByScreenID],[CreatedDateTime]
		,[LastModifiedByID],[LastModifiedByScreenID],[LastModifiedDateTime],[NoteID])
     VALUES
           (
				2,21,1166,'Computer & Office Equipment', 'B5344897-037E-4D58-B5C3-1BDFD0F47BF9', 'AR301000', '2018-12-13 00:52:31.550', 
				'B5344897-037E-4D58-B5C3-1BDFD0F47BF9', 'AR301000', '2018-12-13 00:52:31.550', NULL
		   )
INSERT INTO [dbo].[CompanyAccount] ([CompanyID],[CmpBranchID],[AccountID],[Description],[CreatedByID],[CreatedByScreenID],[CreatedDateTime]
		,[LastModifiedByID],[LastModifiedByScreenID],[LastModifiedDateTime],[NoteID])
     VALUES
           (
				2,21,1167,'Machinery & Equipment', 'B5344897-037E-4D58-B5C3-1BDFD0F47BF9', 'AR301000', '2018-12-13 00:52:31.550', 
				'B5344897-037E-4D58-B5C3-1BDFD0F47BF9', 'AR301000', '2018-12-13 00:52:31.550', NULL
		   )

As you can see from the sql, Branch with id 16

DAC class for CompanyTable:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PX.Data;
using PX.Objects.GL;
 
namespace AcumaticaSamples
{
    [Serializable]
    public class CompanyAccount : IBqlTable
    {
        #region NoteID
 
        public abstract class noteID : PX.Data.IBqlField
        {
        }
 
        [PXNote]
        public virtual Guid? NoteID { getset; }
 
        #endregion
 
        #region BranchID
        public abstract class cmpBranchID : IBqlField
        {
        }
 
        [PXDBInt(IsKey = true)]
        [PXDefault]
        [PXUIField(DisplayName = "Branch ID")]
        public virtual int? CmpBranchID { getset; }
 
        #endregion
 
        #region AccountID
        public abstract class accountID : IBqlField
        {
        }
 
        [PXDBInt(IsKey = true)]
        [PXDefault]
        [PXUIField(DisplayName = "Account", IsReadOnly = true)]
        [PXSelector(typeof(Search<Account.accountID>), SubstituteKey = typeof(Account.accountCD))]
        public virtual int? AccountID { getset; }
 
        #endregion
 
 
        #region Description
        public abstract class description : IBqlField
        {
        }
        [PXDBString(60)]
        [PXUIField(DisplayName = "Description")]
        public virtual string Description { getset; }
        #endregion
        #region CreatedByID
        public abstract class createdByID : IBqlField
        {
        }
        protected Guid? _CreatedByID;
        [PXDBCreatedByID()]
        public virtual Guid? CreatedByID
        {
            get
            {
                return this._CreatedByID;
            }
            set
            {
                this._CreatedByID = value;
            }
        }
        #endregion
        #region CreatedByScreenID
        public abstract class createdByScreenID : PX.Data.IBqlField
        {
        }
        protected String _CreatedByScreenID;
        [PXDBCreatedByScreenID()]
        public virtual String CreatedByScreenID
        {
            get
            {
                return this._CreatedByScreenID;
            }
            set
            {
                this._CreatedByScreenID = value;
            }
        }
        #endregion
        #region CreatedDateTime
        public abstract class createdDateTime : IBqlField
        {
        }
        protected DateTime? _CreatedDateTime;
        [PXDBCreatedDateTime()]
        public virtual DateTime? CreatedDateTime
        {
            get
            {
                return this._CreatedDateTime;
            }
            set
            {
                this._CreatedDateTime = value;
            }
        }
        #endregion
        #region LastModifiedByID
        public abstract class lastModifiedByID : IBqlField
        {
        }
        protected Guid? _LastModifiedByID;
        [PXDBLastModifiedByID()]
        public virtual Guid? LastModifiedByID
        {
            get
            {
                return this._LastModifiedByID;
            }
            set
            {
                this._LastModifiedByID = value;
            }
        }
        #endregion
        #region LastModifiedByScreenID
        public abstract class lastModifiedByScreenID : PX.Data.IBqlField
        {
        }
        protected String _LastModifiedByScreenID;
        [PXDBLastModifiedByScreenID()]
        public virtual String LastModifiedByScreenID
        {
            get
            {
                return this._LastModifiedByScreenID;
            }
            set
            {
                this._LastModifiedByScreenID = value;
            }
        }
        #endregion
        #region LastModifiedDateTime
        public abstract class lastModifiedDateTime : IBqlField
        {
        }
        protected DateTime? _LastModifiedDateTime;
        [PXDBLastModifiedDateTime()]
        public virtual DateTime? LastModifiedDateTime
        {
            get
            {
                return this._LastModifiedDateTime;
            }
            set
            {
                this._LastModifiedDateTime = value;
            }
        }
        #endregion
        #region tstamp
        public abstract class Tstamp : PX.Data.IBqlField
        {
        }
        protected Byte[] _tstamp;
        [PXDBTimestamp]
        public virtual Byte[] tstamp
        {
            get
            {
                return this._tstamp;
            }
            set
            {
                this._tstamp = value;
            }
        }
        #endregion
    }
}

Limit Accounts

When I was asked to limit Accounts selector in Sales orders, I thought it would be easy task, so I went to definition of SOLine, and found the following C# code:

    [PXDefault(PersistingCheck = PXPersistingCheck.Nothing)]
    [Account(typeof (SOLine.branchID), Visible = false)]
    public virtual int? SalesAcctID
    {
      get
      {
        return this._SalesAcctID;
      }
      set
      {
        this._SalesAcctID = value;
      }
    }

Every time I see custom attributes of Acumatica during development I have some thought in background like ups, surprises will come for sure.

And they come. But let's try to make substitution for SalesAcctID with help of ordinary PXSelector in SOORderEntryExt:

public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
    {
        [PXDefault(PersistingCheck = PXPersistingCheck.Nothing)]
        [PXDBInt]
        [PXSelector(typeof(Search2<Account.accountID, 
            InnerJoin<CompanyAccountOn<Account.accountIDEqual<CompanyAccount.accountID>>>, 
                Where<CompanyAccount.cmpBranchIDEqual<Current<SOLine.branchID>>>>),
            typeof(Account.accountID), typeof(Account.accountCD), typeof(Account.description))]
        [PXUIField(DisplayName = "Account CD")]
        protected void SOLine_SalesAcctID_CacheAttached(PXCache sender)
        {
        }
    }

nothing fancy. Take a look at final result:

as you can see from screen recording, filtering works wonderful, but after selection of Account, field remains empty. How to deal with that? In that case on rescue comes PXDimensionSelector!

I will tell you mine own definition of PXDimensionSelector: Attribute, that allows you to modify any custom Acumatica selector. For example you can use PXDimensionSelector for filtering Accounts, SubAccounts ( but for that you'll need to play with  Segmented keys), etc.

Take a look on the code, which replaces PXSelector with PXDimensionSelector:

public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
    {
        [PXUIField(DisplayName = "Account", FieldClass = "ACCOUNT", Visibility = PXUIVisibility.Visible)]
        [PXDBInt]
        [PXDimensionSelector(AccountAttribute.DimensionName,
            typeof(Search2<Account.accountIDInnerJoin<CompanyAccountOn<Account.accountIDEqual<CompanyAccount.accountID>>>,
                Where<CompanyAccount.cmpBranchIDEqual<Current<SOLine.branchID>>>>), typeof(Account.accountCD),
            new Type[] { typeof(Account.accountCD), typeof(CompanyAccount.description) })]
        protected void SOLine_SalesAcctID_CacheAttached(PXCache sender)
        {
        }
    }
And final result:

As you can see from the screen recording, PXDimensionSelector allows you to filter account as well as select, while PXSelector only filters accounts, but doesn't allow you to select proper account

No Comments

Add a Comment
 

 

How To Work With Selector

 

Hello everybody,

today I want to write few words how to work with selectors in Acumatica.

So, imagine, you have the following selector in Acumatica:

<px:PXSelector ID="NmbUsrBillPMTask" runat="server" DataField="UsrBillPMTask"/>

In order to make it work as selector, you need to do the following:

[PXSelector(typeof(Search<PMTask.taskID>))]

if you'll do it, you'll receive following selector:

And if you choose there some value, you'll be able to see id represented as number. In my case it was 727.

But what if you want to make it more readable?

Then you can add following part:

[PXSelector(typeof(Search<PMTask.taskID>), SubstituteKey = typeof(PMTask.taskCD))]

Then instead of some strange number Acumatica will display TaskCD field. 

But what if you have desire to add as display one more field displayed after "-" sign, as it is in some Acumatica screens. You can add another element, which is named DescriptionField. 

And final part of advice, you can also customize which fields should go in the selector. Take see at the following code:

[PXSelector(typeof(Search<PMTask.taskID,
            Where<PMTask.projectID, Equal<Current<PMTask.projectID>>>>), new Type[]{typeof (PMTask.taskCD), typeof (PMTask.locationID),
                typeof (PMTask.description), typeof (PMTask.status)}, SubstituteKey = typeof(PMTask.taskCD), DescriptionField = typeof(PMTask.description))]

You can try to figure out details at screenshot:

Hope that can help somebody to create selector.

 

9 Comments

  • dedi said

    Hello

    I made code like this

    [PXDBString(5)]
    [PXUIField(DisplayName="Case No")]
    [PXSelector(typeof(Search<ShipmentSKR.SOShipLineCaseNoSKR.CaseNbr>))]



    I created this code for custom field in shipment tab packages, ShipmentSKR.SOShipLineCaseNoSKR.CaseNbr Is a custom table, But when publish, there is an error likes this

    IIS APPPOOL\SKRDevTest
    Building directory '\WebSiteValidationDomain\App_RuntimeCode\'.
    \App_RuntimeCode\PX_Objects_SO_SOPackageDetail_extensions.cs(19): error CS0118: 'ShipmentSKR.SOShipLineCaseNoSKR.CaseNbr' is a 'property' but is used like a 'type'
    \App_RuntimeCode\PX_Objects_SO_SOPackageDetail_extensions.cs(19): error CS0118: 'ShipmentSKR.SOShipLineCaseNoSKR.CaseNbr' is a 'property' but is used like a 'type'
    Compiler time, in seconds: 7,510337

    Please Help Me, thank you

  • docotor said

    Hello Dedi. Your problem is not with code, but with MS SQL configuration. Your code is correct. You need to add user SKRDevTest as authorized at your SQL server

  • Dave said

    Hi, I am getting a similar error to the above and wondering if you can help?

    I added a field to the customer master to link a business account as a "reseller". Below is my code:

    [PXUIField(DisplayName="Reseller",Visibility = PXUIVisibility.SelectorVisible)]
    [PXSelector(typeof(Search<BAccountR.bAccountID>),
    DescriptionField = typeof(BAccountR.AcctName),
    SubstituteKey = typeof(BAccountR.bAccountID))]

    I'm getting the below...

    Error:
    IIS APPPOOL\DefaultAppPool
    Building directory '\WebSiteValidationDomain\App_RuntimeCode\'.
    \App_RuntimeCode\PX_Objects_CR_BAccount_extensions.cs(26): error CS0118: 'PX.Objects.CR.BAccount.AcctName' is a 'property' but is used like a 'type'
    \App_RuntimeCode\PX_Objects_CR_BAccount_extensions.cs(26): error CS0118: 'PX.Objects.CR.BAccount.AcctName' is a 'property' but is used like a 'type'
    Compiler time, in seconds: 4.7926131

    But if I change BAccountR.AcctName to BAccount.bAccountID it works but on my screen it just shows the ID twice.

    Thanks!

  • docotor said

    Your questions shows that you need some improvement in code conventions used by Acumatica. Each column is reflected by two lines: capital letter of column name and small of column name. Instead of BAccountR.AcctName try to use BAccountR.acctName and error will go away.

  • Royce Lithgo said

    It looks like inclusion of the SubstituteKey = parameter makes the "Search<>" component redundant because the selected value will be whatever is nominated for the SubstiuteKey. Why is it then in your code and also the Framework training courses Select<> (on the primary key) is still specified even though the value returned will be the natural key (specified by SubstituteKey)?

    Here's an example - these 2 code segments produce exactly the same result:

    [PXSelector(
    typeof(Search<Customer.customerID>),
    typeof(Customer.customerCD),
    typeof(Customer.companyName),
    SubstituteKey = typeof(Customer.customerCD))]

    [PXSelector(
    typeof(Customer.customerID),
    typeof(Customer.customerCD),
    typeof(Customer.companyName),
    SubstituteKey = typeof(Customer.customerCD))]

    This however doesn't work (selector wont launch)
    [PXSelector(
    typeof(<Customer.customerID>,
    typeof(Customer.customerCD),
    typeof(Customer.companyName))]

    This works, but returns primary (numeric) key:
    [PXSelector(
    typeof(Search<Customer.customerID>),
    typeof(Customer.customerCD),
    typeof(Customer.companyName))]

  • docotor said

    I can't say about reasons of Acumatica manuals, but mine reason is that Search allows to add some kind of filtering with Where<> . Without Search add Where condition will be problematic

  • Prat said

    How do we use required<> in place of current<> and pass some string constant for selector?

  • docotor said

    Pratt, I'll create new article that explains this

  • docotor said

    Hi Pratt, please take a look: Hello Pratt, take a look: https://blog.zaletskyy.com/required-instead-of-current-in-acumatica

Add a Comment
 

 

Pxsmartpanel In Acumatica

 

Hello everybody,

today I want to write few words how to work with PXSmartPanel.

One of my clients asked following:

1. Press at button.

2. Pop up should appear with two buttons ( "OK" , "Cancel")

3. At pop up should be also selector of contracts and datetime.

4. Existing screen should be modified.

In order to do this, following actions were implemented:

1. Existing screen was CT301000.

2. If to look in screen source code, following line says about graph:

<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%" TypeName="PX.Objects.CT.ContractMaint"
        PrimaryView="Contracts" BorderStyle="NotSet">

3. It means, that we need to create extension class for ContractMaint.

4. For example like this:

public class ContractMaintExt : PXGraphExtension<ContractMaint>
{

        [PXCopyPasteHiddenView]
        public PXFilter<SubstituteSettingsFilter> SubstituteSettings;
        public PXAction<Contract> Substitute;
        [PXButton(CommitChanges = true)]
        [PXUIField(DisplayName = "Substitute")]
        protected void substitute()
        {
            if (this.SubstituteSettings.AskExt(new PX.Data.PXView.InitializePanel(this.fillFilter)) ==
                WebDialogResult.OK)
            {
                var subsFilter = (SubstituteSettingsFilter)this.SubstituteSettings.Cache.Current;
                CopyOpenPMTaskHistory(Base.Contracts.Current.ContractID, subsFilter.ContractID, subsFilter.TransitionDate);
            }
        }
}

5. In the line 4 we declared to Acumatica, that we want to extend ContractMaint, and we want to create some data input, which is related to SubstituteSettingsFilter. Take note of Substitute and substitute: both of them are needed in order to make processing of inputted values.

6. Take a look at SubstituteSettingsFilter class itself:

 [Serializable]
        public class SubstituteSettingsFilter  : IBqlTable
        {
            #region contractID

            public abstract class contractID : IBqlField, IBqlOperand
            {
            }

            protected int? _ContractID;
            [PXDefault]
            [PXDBInt]
            [PXDimensionSelector("CONTRACT", typeof(Search2<Contract.contractID, 
                InnerJoin<ContractBillingSchedule, On<Contract.contractID, Equal<ContractBillingSchedule.contractID>>, 
                LeftJoin<Customer, On<Customer.bAccountID, Equal<Contract.customerID>>>>, 
                Where<Contract.isTemplate, Equal<boolFalse>,
                And<Contract.baseType, Equal<Contract.ContractBaseType>>>>), 
                typeof(Contract.contractCD), 
                new System.Type[] { typeof(Contract.contractCD), typeof(Contract.customerID), typeof(Customer.acctName), 
                    typeof(Contract.locationID), typeof(Contract.description), typeof(Contract.status), typeof(Contract.expireDate), 
                    typeof(ContractBillingSchedule.lastDate), typeof(ContractBillingSchedule.nextDate) },
                    DescriptionField = typeof(Contract.description), Filterable = true)]
            [PXUIField(DisplayName = "Contract ID", Visibility = PXUIVisibility.SelectorVisible)]
            [PXFieldDescription]
            
            public virtual int? ContractID
            {
                get { return this._ContractID; }
                set { this._ContractID = value; }

            }

            #endregion contractID

            #region TransitionDate
            public abstract class transitionDate : PX.Data.IBqlField
            {
            }
            protected DateTime? _TransitionDate;
            [PXDBDate()]
            [PXDefault]
            [PXUIField(DisplayName = "Transition Date")]
            public virtual DateTime? TransitionDate
            {
                get
                {
                    return this._TransitionDate;
                }
                set
                {
                    this._TransitionDate = value;
                }
            }
            #endregion TransitionDate
         }

7. We described two properties: contractID and TransitionDate.

8. Now goes time of aspx page at <px:PXFormView> section I described the following:

<px:PXSmartPanel ID="pnlSubstitute" runat="server" AcceptButtonID="PXButtonOK" AutoReload="true" CancelButtonID="PXButtonCancel"
        Caption="Substitute" CaptionVisible="True" DesignView="Content" HideAfterAction="false" Key="SubstituteSettings"
        LoadOnDemand="true" Height="190px" Width="360px" DefaultControlID="edContract">
        <px:PXFormView ID="PXFormView6" runat="server" CaptionVisible="False" DataMember="SubstituteSettings" Width="100%"
            DefaultControlID="edActivationDate" DataSourceID="ds" TabIndex="1400">
            <ContentStyle BackColor="Transparent" BorderStyle="None">
            </ContentStyle>
            <Template>
                <px:PXLayoutRule runat="server" StartColumn="True" LabelsWidth="SM" ControlSize="M" />
                <px:PXSelector runat="server" ID="edContract" DataField="ContractID" CommitChanges="True" Width="130px" />
                <px:PXDateTimeEdit CommitChanges="True" ID="edTransitionDate" runat="server" DataField="TransitionDate" Width="130px" />
                <px:PXLayoutRule runat="server" StartRow="True" />
                <px:PXPanel ID="PXPanel1" runat="server" SkinID="Buttons">
                    <px:PXButton ID="OK" runat="server" DialogResult="OK" Text="OK" />
                    <px:PXButton ID="Cancel" runat="server" DialogResult="Cancel" Text="Cancel" />
                </px:PXPanel>
            </Template>
        </px:PXFormView>
</px:PXSmartPanel>

Few words. AcceptButtonID speak about who plays role of OK button, Caption means title, CaptionVisible means that title will be visible, HideAfterAction means hide or not after action, Key means name of member in extension or graph, DefaultControlID means which control is active by default. Another important detail is DataMember property, which equals to Key.  Then goes layout rules, which I ommit. Then in Template goes selector, and datetime input. 

9. Here how control look like:

Here it is. If you have any comments, wishes, etc, you are welcome to post them

No Comments

Add a Comment
 

 

Merged And Read Only Modes In Acumatica

 

Hello everybody,

today another notice. Acumatica can provide values in two modes: merged and read-only.

So, what is merged? Imagine that user worked about the form, and made some changes at grid. Will changes apper in DB? Untill will be executed Persist, not. Data will be only in cache. Some time it is useful to compare data in cache with data in db. In order to get merged data you can use PXSelectReadOnly type or PXSelectGroupBy. For merged results you can use PXSelect or PXSelectJoin.

No Comments

 

Add a Comment
 

 

Pxselect Vs Pxselectreadonly

Hello everybody,

today I want to share with you important difference between PXSelect  and PXSelectReadonly.

In my project I had the following situation. PXSelect of table name didn't give me what actually was in db. After a long research I found PXSelectReadonly and key difference is that PXSelectReadonly reads directly from db without usage of Acumatica Cache. 

No Comments

 

Add a Comment