How to implement PXStringListAttribute in Acumatica

Hello,

today I want to leave a post about code quality regarding of PXStringListAttribute. If to look in older versions of Acumatica manuals ( for example T200 manual ) you can see something like this:

public class Something : IBqlTable
{
 
    [PXStringList(
        new string[]
        {
            ShipmentTypes.CollectorNew,
            ShipmentTypes.CollectorSent,
            ShipmentTypes.CollectorResponded,
            ShipmentTypes.CollectorExpired
        },
        new string[]
        {
            "New",
            "Sent",
            "Responded",
            "Expired"
        })]
    [PXString]
    public virtual string Field { getset; }
}

Recommended syntax as of now looks like this:

public class Something : IBqlTable
{
 
    [SurveyResponseStatus.List]
    [PXString]
    public virtual string Field { getset; }
}
 
 
public static class SurveyResponseStatus
{
    public class ListAttribute : PXStringListAttribute
    {
        public ListAttribute() : base(
            new string[] { CollectorNew, CollectorSent, CollectorResponded, CollectorExpired },
            new string[] { Messages.CollectorNew, Messages.CollectorSent, Messages.CollectorResponded, Messages.CollectorExpired })
        { }
    }
 
    public const string CollectorNew = "N";
    public const string CollectorSent = "S";
    public const string CollectorResponded = "R";
    public const string CollectorExpired = "E";
 
    public class CollectorNewStatus : PX.Data.BQL.BqlString.Constant<CollectorNewStatus> { public CollectorNewStatus() : base(CollectorNew) { } }
    public class CollectorSentStatus : PX.Data.BQL.BqlString.Constant<CollectorSentStatus> { public CollectorSentStatus() : base(CollectorSent) { } }
    public class CollectorRespondedStatus : PX.Data.BQL.BqlString.Constant<CollectorRespondedStatus> { public CollectorRespondedStatus() : base(CollectorResponded) { } }
    public class CollectorExpiredStatus : PX.Data.BQL.BqlString.Constant<CollectorExpiredStatus> { public CollectorExpiredStatus() : base(CollectorExpired) { } }
}

and also class Messages looks somehow like this:

[PXLocalizable(Prefix)]
public static class Messages
{

    #region Survey Response Status
 
    public const string CollectorNew = "New";
    public const string CollectorSent = "Sent";
    public const string CollectorResponded = "Responded";
    public const string CollectorExpired = "Expired";

also new code from initial standpoint looks as much bigger amount of lines, but from standpoint of reusability, it's much better. It's easier to decorate any String column, which is much easier to use. Also in your code, you can make comparisons against compiled constant instead of hard coding string values.

Summary

Take your time to kind of memorize, or bookmark new way of using syntax, which will be easier to re-use and maitan.

How to deal with Could not load file or assembly in Acumatica

Hello everybody,

today I want to share one workaround, which I sometime use as temporary measure for migration projects. Imagine, that you've added reference to your bin folder of one of your old customizations. Then you build it, and you've got this error message:

Server Error in '/xxx' Application.


Could not load file or assembly 'xxxx' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

 

This error happens because you have in your customization C# part references to some older dll's which are not compatible with current version of Acumatica. So ideal solution would be to re-add to your current class library proper dll.

Another TEMPORARY measure would be add something like this to your Post-build event command line:

command similar to this:

xcopy /Y /I "d:\SourceCode\build20r1core\KNMCCore\obj\Debug\KNMCCore.*" "c:\Program Files\Acumatica ERP\Matrix\Bin\"

Summary

xcopy says to visual studio please make copy

/Y - don't ask for confirmation

/I - copy multiple items

and then goes two string parameters - source with it's mask, and destination.