Acumatica - Adding Employee Selector to Journal Transactions - customization

I am trying to add an Employees selector to the Journal Transactions screen (GL301000) specifically in the grid. I have created the DAC extension code using the GLTran DAC as the base.
Here is my code:
using PX.Common;
using PX.Data.ReferentialIntegrity.Attributes;
using PX.Data;
using PX.Objects.AP;
using PX.Objects.CM;
using PX.Objects.CR;
using PX.Objects.CS;
using PX.Objects.EP;
using PX.Objects.GL;
using PX.Objects.IN;
using PX.Objects.PM;
using PX.Objects.TX;
using PX.Objects;
using System.Collections.Generic;
using System;
namespace PX.Objects.GL
{
public class GLTranExt : PXCacheExtension<PX.Objects.GL.GLTran>
{
#region Resource
public class emp: PX.Data.Constant<string>
{
public emp() : base("EMPHOUR") { }
}
public abstract class resource: PX.Data.IBqlField
{
}
protected int? _Resource;
[PXDBInt]
[PXDefault()]
[PXUIField(DisplayName="Resource")]
[PXSelector(typeof(Search2<BAccount.bAccountID,
InnerJoin<Vendor,
On<Vendor.bAccountID,
Equal<BAccount.bAccountID>>>,
Where<Vendor.vendorClassID,
Equal<emp>>>),
SubstituteKey = typeof(BAccount.acctName))]
public virtual int? Resource
{
get
{
return this._Resource;
}
set
{
this._Resource = value;
}
}
#endregion
}
}
I am getting an error when I try to add the field to the grid and this is my error:
Error: An invalid selector column has been provided.
Parameter name: fieldList
Can anyone point me in the right direction? I do know that to get the correct Employee's names to show up you must use a where or join on the Vendor table and the BAccount tables. When I tried the LeftJoin method however, I got an error saying multi-part identifier could not be bound.

I have found a solution.
I needed to add a persisting check to the PXDefault and also change the CommitChanges property to true.
Here is the correct code below:
public class GLTranExt : PXCacheExtension<PX.Objects.GL.GLTran>
{
#region Resource
public class emp: PX.Data.Constant<string>
{
public emp() : base("EMPHOUR") { }
}
public abstract class resource: PX.Data.IBqlField
{
}
protected int? _Resource;
[PXDBInt]
[PXDefault(PersistingCheck=PXPersistingCheck.Nothing)]
[PXUIField(DisplayName="Resource")]
[PXSelector(typeof(Search2<BAccount.bAccountID,
InnerJoin<Vendor,
On<Vendor.bAccountID,
Equal<BAccount.bAccountID>>>,
Where<Vendor.vendorClassID,
Equal<emp>>>),
SubstituteKey = typeof(BAccount.acctName))]
public virtual int? Resource
{
get
{
return this._Resource;
}
set
{
this._Resource = value;
}
}
#endregion
}
Also remember to create a DB Script to add the Resource field to the GLTran table of the value INT.

Related

Acumatica - Approach to custom screen to link GL and Sub Accounts for custom restrictions

The requirement is to build a custom form tab screen that starts of with an account selector. After choosing the account, the bottom grid is populated with a list of custom DAC's that basically consists of a key of CompanyID, AccountID, SubID that is stored in a custom table. The existing Account DAC does not have a selector component, which I can use for the top selection. The solution I tried to get past this is to create a new DAC but with only one unbound property, but this is giving me issues on the BQL side when setting up the Master/Detail data views for the screen. I will then attempt to setup a master detail relationship between my custom DAC and the Account DAC. Is this the best approach to build this screen, or is there another which I haven't thought of?
Screen Graph (ignore the where and filters, just doing a proof of concept first):
using System;
using PX.Data;
using PX.Data.BQL.Fluent;
using PX.Objects.GL;
namespace IP_GLRestrictions2
{
public class IPGLAcctToSubLinkMaint : PXGraph<IPGLAcctToSubLinkMaint>
{
public PXSave<IPAccount> Save;
public PXCancel<IPAccount> Cancel;
public PXFilter<IPAccount> MasterView;
public PXFilter<IPAcctSubLink> DetailsView;
public SelectFrom<IPAccount>.View AccountView;
public SelectFrom<IPAcctSubLink>
//.Where<IPAcctSubLink.accountID.IsEqual<IPAccount.accountID.FromCurrent>>
.View SubLinkView;
}
}
Custom DAC ( I want to show the Description and Active as unbound fields as soon as a subaccount ID is chosen in the details grid):
[Serializable]
[PXCacheName("Account To Subaccount Link")]
public class IPAcctSubLink : IBqlTable
{
#region AccountID
[PXDBInt(IsKey = true)]
[PXUIField(DisplayName = "Account ID")]
[PXDBDefault(typeof(IPAccount.accountID))]
[PXParent(typeof(SelectFrom<IPAccount>.Where<IPAccount.accountID.IsEqual<IPAcctSubLink.accountID.FromCurrent>>))]
////[PXSelector(typeof(Search<IPAccount.accountID>),
//// typeof(Account.accountCD),
//// typeof(Account.description),
//// SubstituteKey = typeof(Account.accountCD))]
public virtual int? AccountID { get; set; }
public abstract class accountID : PX.Data.BQL.BqlInt.Field<accountID> { }
#endregion
#region Subid
[PXDBInt(IsKey = true)]
[PXUIField(DisplayName = "Subaccount ID")]
[PXSelector(typeof(Search<Sub.subID>),
typeof(Sub.subCD),
typeof(Sub.description),
typeof(Sub.active),
SubstituteKey = typeof(Sub.subCD))]
public virtual int? Subid { get; set; }
public abstract class subid : PX.Data.BQL.BqlInt.Field<subid> { }
#endregion
#region Description
[PXString]
[PXUIField(DisplayName = "Description")]
//[PXDefault(typeof(Search<Sub.description, Where<Sub.subID, Equal<Current<IPAcctSubLink.subid>>>>))]
public virtual int? SubDescription { get; set; }
public abstract class subdescription : PX.Data.BQL.BqlInt.Field<subdescription> { }
#endregion
#region Active
[PXBool]
[PXUIField(DisplayName = "Active")]
//[PXDefault(typeof(Search<Sub.active, Where<Sub.subID, Equal<Current<IPAcctSubLink.subid>>>>))]
public virtual int? SubActive { get; set; }
public abstract class subActive : PX.Data.BQL.BqlInt.Field<subActive> { }
#endregion
If you just need a selector for a specific field in a DAC the easiest way to do that would be via a cache extension.
You can simply add the PXSelector attribute inside the cache extension.
public sealed class CacheExtension : PXCacheExtension<YourDAC>{
public static bool IsActive() => true;
[YourSelectorAttribute]
public int? AccountID { get; set; }
}

Open Generics with injected primitive

How can I register an Open Generic type with another open generic and primitive injected in the constructor?See example below.In this example, Resolve is throwing "Unable to resolve String as parameter "connectionString"" exception. (you can check live code here)
using System;
using DryIoc;
public class Program
{
public static void Main()
{
var container = new Container();
container.RegisterInstance("some_connection_string", serviceKey: "connectionString");
container.Register(typeof(Configuration<>), Reuse.Singleton);
container.Register(typeof (IEntityUpdater<>), typeof (SqlEntityUpdater<>), Reuse.Singleton);
var p = container.Resolve<IEntityUpdater<EventArgs>>();
Console.WriteLine(p);
}
}
public class Configuration<T> where T : class { }
internal interface IEntityUpdater<in T> where T : class
{
void Update(T entity);
}
internal class SqlEntityUpdater<T> : IEntityUpdater<T> where T : class
{
public SqlEntityUpdater(Configuration<T> configuration, string connectionString)
{
}
public void Update(T entity) { }
}
First, RegisterInstance is depricated, use UseInstance.
Second, the actual problem is that you registering instance with serviceKey and nowhere using this key for injection.
So, you either remove the serviceKey parameter.
Or, specify the key on injection side:
container.Register(typeof(IEntityUpdater<>), typeof(SqlEntityUpdater<>), Reuse.Singleton,
made: Parameters.Of.Type<string>(serviceKey: "connectionString"));

Struts2 get object attribute from select tag

My problem is that I don't succeed in getting the attribute of the object of the list of my select tag.
I have a select tag in my .jsp like this :
<s:select list="listFonction" listKey="code" listValue="Libelle"
name="fonctionSelectionne" value="defaultFonction" />
and in my action, i declared an arraylist (with getter and setter) :
private ArrayList<Fonction> listFonction = new ArrayList<Fonction>();
I also have another class Fonction :
public class Fonction {
private int code;
private String libelle;
public Fonction(int code, String libelle)
{
this.code = code;
this.libelle =libelle;
}
public Fonction()
{
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getLibelle() {
return libelle;
}
public void setLibelle(String libelle) {
this.libelle = libelle;
}
}
To get the selected value in my action i declared (whith getter and setter):
Private String fonctionSelectionne;
but i am just abbled to get the code (listkey) of my object with getFonctionSelectionne.
I want to get the code attribute (listkey) and the libelle attribute (listvalue).
Does anyone know how help me ?
thanks
2 points:
it should be libelle, not Libelle
<s:select list="listFonction" listKey="code" listValue="libelle"
name="fonctionSelectionne" value="defaultFonction" />
for list="listFunction", you need getter Collection getListFunction(){} in your action class
UPDATE
i'am not sure to this. but you can give a try.
here is the idea, don't deliver a list, but a map to select tag
Map getListFunction(){
Map<Object, String> map;
Function f = new Function(1, "test");
map.put(f, f.libelle);
return map;
}
then in the jsp:
<s:select list="listFonction" listKey="key" listValue="value"
name="fonctionSelectionne"/>
You should make the setter of the attribute listFonction on the ClassAction

ReportViewer Table with list of inherited objects

I need to show a table with a list of inherited objects.
For example:
public abstract class Animal
{
public string Name { get; set; }
public abstract string Detail { get; }
}
public class Dog : Animal
{
public override Detail { get { return "A dog"; } }
}
public class Cat : Animal
{
public override Detail { get { return "A cat"; } }
}
It seems that the datasource takes de first object class type and the other objects shows with #ERROR
How I can fix it?
You need to map your properties using the expressions area. If you want to show a column with the cats details, add this to the expression for that field.
=Fields!Cat.Value.Detail

MockUnitOfWork 'Cannot resolve symbol MockUnitOfWork'

I'm trying to get Figure 3 Fake Database from IRepository using the example here
http://msdn.microsoft.com/en-us/magazine/dd263069.aspx
public class InMemoryRepository : IRepository
{
private readonly Cache<Type, object> _types;
private MockUnitOfWork _lastUnitOfWork;
public InMemoryRepository()
{
_types = new Cache<Type, object>(type =>
{
Type listType = typeof(List<>).MakeGenericType(type);
return Activator.CreateInstance(listType);
});
}
private IList<T> listFor<T>()
{
return (IList<T>)_types.Get(typeof(T));
}
public T Find<T>(long id) where T : Entity
{
return listFor<T>().FirstOrDefault(t => t.Id == id);
}
public void Delete<T>(T target)
{
listFor<T>().Remove(target);
}
public T[] Query<T>(Expression<Func<T, bool>> where)
{
var query = from item in listFor<T>() select item;
return query.Where(where.Compile()).ToArray();
}
public void Save<T>(T target)
{
listFor<T>().Add(target);
}
}
I'm getting 'Cannot resolve symbol MockUnitOfWork.
I have NUnit/Moq/Rhino.Mock installed/referenced but I cannot find any reference to MockUnitOfWork.
Any help appreciated.
You can just remove the MockUnitOfWork, because it is never used in the code.
I think it is a remnant left over after a refactoring.
The article doesn't explicitly say anything about what MockUnitOfWork is, but since it is an explicitly declared type, it must be a hand-rolled Mock.
Despite its semantic equivalence, it has nothing to do with Moq or RhinoMocks.
If you can download the source code for the article, I'm pretty sure you will find a class called MockUnitOfWork in the test project.