acumatica add field to display values from database - customization

I created a custom field UsrFOBprice in Stock Items Screen(IN202500),
I also created a new custom screen in Purchase Order.
enter image description here
How do I add Inventory ID lookup field and the custom field FOB price in this new screen which would display the values from the database?
(When I try to add new field on the new screen it says MasterTable does not exist in the database)
using System;
using PX.Data;
namespace NewScreen
{
public class NewPurchaseOrder : PXGraph<NewPurchaseOrder>
{
public PXCancel<MasterTable> Cancel;
public PXFilter<MasterTable> MasterView;
public PXFilter<DetailsTable> DetailsView;
[Serializable]
public class MasterTable : IBqlTable
{
}
[Serializable]
public class DetailsTable : IBqlTable
{
}
}
}
DAC

Related

How to add multiple wrapper lists into single list

I have created apex class to pull multiple object records into single list. Where objects does not have any relationship (lets say account, contact, lead. Consider account and contact dont have any relationship). I used for loop seperately for each object and saved into wrapperlist. For three objects I have three wrapper list. Now big challenge is I need to add three wrappers(wrapAccount, wrapContact, wrapLead) into single list. So in that list I need all three objects records.
#Auraenabled(cacheable=true)
public static List<sObject> wrapData() {
List<WrapperContact> wrapContact = new List<WrapperContact>();
List<WrapperAccount> wrapAccount = new List<WrapperAccount>();
List<WrapperLead> wrapLead = new List<WrapperLead>();
for(Contact ct : [select id, name from Contact LIMIT 10]){
wrapContact.add(new WrapperContact(ct));
}
for(Account acct : [select id, name from Account LIMIT 10]){
wrapAccount.add(new WrapperAccount(acct));
}
for(Lead ld : [select id, name from Lead LIMIT 10]){
wrapLead.add(new WrapperLead(ld));
}
system.debug('wrapContact'+wrapContact);
system.debug('wrapAccount'+wrapAccount);
system.debug('wrapLead'+wrapLead);
List<SObject> s = new List<SObject>{
new Contact(),
new Account(),
new Lead()
};
public class WrapperAccount{
#Auraenabled
public Account ac{get;set;}
public WrapperAccount(Account acct){
ac=acct;
}
}
public class WrapperContact{
#Auraenabled
public Contact cont{get;set;}
public WrapperContact(Contact ct){
cont=ct;
}
}
public class WrapperLead{
#Auraenabled
public Lead ldd{get;set;}
public WrapperLead(Lead ld){
ldd=ld;
}
}
An example of what I mean:
public class tester {
#Auraenabled(cacheable=true)
public static List<Wrapper> wrapData() {
List<Wrapper> wrap = new List<Wrapper>();
for(Contact ct : [select id, name from Contact LIMIT 10]){
wrap.add(new Wrapper(ct,'contact'));
}
for(Account acct : [select id, name from Account LIMIT 10]){
wrap.add(new Wrapper(acct,'account'));
}
for(Lead ld : [select id, name from Lead LIMIT 10]){
wrap.add(new Wrapper(ld, 'lead'));
}
return wrap;
}
public class Wrapper{
#Auraenabled
public sObject ac{get;set;}
public string objType{get;set;}
public Wrapper(sObject obj, string objtype){
ac=obj;
objType= objtype;
}
}
}
You can then loop through the returned wrapData and display them as you like using a switch and converting them to the correct type. There may be better methods though.

Sum values of detail rows (in extension) and put it in header (in extension)

Acumatica 2021 R1 - Customizations
I am using PXFormula to multiply a qty and cost to create a new extension field in the details of Physical Inventory Review (although I would think the specific screen wouldn’t matter.) That part is working fine. However, I then want to sum that new column’s values into a new extension field in the header. I can't get that part to work.
Here is the relevant detail code:
using PX.Data;
using System;
namespace PX.Objects.IN
{
public class INPIDetailExt : PXCacheExtension<PX.Objects.IN.INPIDetail>
{
#region UsrExtBookCost
[PXDecimal]
[PXUIField(DisplayName="Ext. Book Cost")]
[PXFormula(typeof(Mult<INPIDetail.bookQty, INPIDetail.unitCost>),
typeof(SumCalc<INPIHeaderExt.usrTotalBookCost>))]
public virtual Decimal? UsrExtBookCost { get; set; }
public abstract class usrExtBookCost : PX.Data.BQL.BqlDecimal.Field<usrExtBookCost> { }
#endregion
}
}
Here’s the header code:
using PX.Data;
using System;
namespace PX.Objects.IN
{
public class INPIHeaderExt : PXCacheExtension<PX.Objects.IN.INPIHeader>
{
#region UsrTotalBookCost
[PXDecimal]
[PXUIField(DisplayName="Total Book Cost")]
public virtual Decimal? UsrTotalBookCost { get; set; }
public abstract class usrTotalBookCost : PX.Data.BQL.BqlDecimal.Field<usrTotalBookCost> { }
#endregion
}
}
I feel it has something to do with the fact that these are extensions and that somehow the PXParent that is called in INPIDetail does not cover these extension.
Any suggestions would be appreciated.
By any chance are you calling the PXFormulaAttribute.CalcAggregate in the row selected event of the INPIHeader. This should force the SumCalc to recalculate and update your value
PXFormulaAttribute.CalcAggregate<INPIDetailExt.usrExtBookCost>(DetailView.Cache, e.Row);

Issue in setting AbpUsers as foreign key in another table

We are using ABP.io in our project. We have requirement to map UserId as foreign key in my new table.
I mapped foreign key to new table as
public class NewEntity : FullAuditedEntity<int>, IHasIsActive
{
....
[ForeignKey("UserId")]
public IdentityUser AppUser { get; set; }
}
It successfully created foreign key relationship to AbpUsers table.
Now, I am trying to insert record in NewEntity table but it is throwing error
The entity type 'IdentityUserLogin' requires a primary key to be
defined. If you intended to use a keyless entity type call
'HasNoKey()'.
We have used CrudAppService in our code.
public class NewEntityAppService :
CrudAppService<NewEntity, NewEntityDto, int, PagedAndSortedResultRequestDto,
CreateUpdatePropertyTypeDto, CreateUpdatePropertyTypeDto>,
IPropertyTypeAppService
{
private readonly IRepository<NewEntity, int> _newType;
public PropertyTypeAppService(IRepository<NewEntity, int> newType)
: base(newType)
{
_newType= newType;
}
}
Error reference to the AppUser table because IdentityUser class has IdentityUserLogin. If I comment ForeignKey then it is working fine.
Need help to setup User ForeignKey properly.

Designing Model with foreign key

I am building an ORM by using Unit or Work and Repository using Dapper. I have searched the internet on this problem and no luck.
I have the following tables:
As you can see, Instance has Entity inside. I have 2 approaches:
Approach 1:
public class Entity
{
public int Id {get;set;}
public string Name {get;set;}
}
public class Instance
{
public int Id {get;set;}
public Entity Entity {get;set;}
public string Name {get;set;}
}
How can I get value for Entity with this approach?
Approach 2 (according to this link):
public class Entity
{
public int Id {get;set;}
public string Name {get;set;}
}
public class Instance
{
public int Id {get;set;}
public int EntityId {get;set;}
public string Name {get;set;}
}
Which design is better for use?
You can use QueryMultiple if you want to fetch the data from two different tables and fill it up in two different POCO classes. Following is copied from here:
string sql = "SELECT * FROM Invoice WHERE InvoiceID = #InvoiceID; SELECT * FROM InvoiceItem WHERE InvoiceID = #InvoiceID;";
using (var connection = My.ConnectionFactory())
{
connection.Open();
using (var multi = connection.QueryMultiple(sql, new {InvoiceID = 1}))
{
var invoice = multi.Read<Invoice>().First();
var invoiceItems = multi.Read<InvoiceItem>().ToList();
}
}
Both the models you mentioned in your code can be handled with this approach.
As an alternative approach, you can combine your two POCOs in one or you can use inheritance as well. But, looking at your data model, I do not think this is applicable to this particular case.
Which design is better for use?
Up to you. Whatever suits your project needs keeping down the unnecessary complexities is good for you.

Sitecore Glass data model inheritence

I am using the Glass Mapper on a Sitecore instance where I have a basic data template structure of
Base
BaseWithList
BaseWithExtraContent
BaseWithExtraContentAndCallToActionLink
I have added model classes in my project to follow this structure too. My class names match my template names.
[SitecoreType(TemplateId = "{5D19BD92-799E-4DC1-9A4E-1DDE3AD68DAD}", AutoMap = true)]
public class Base
{
public virtual string Title {get;set;}
public virtual string Content {get;set;}
}
[SitecoreType(TemplateId = "{0491E3D6-EBAA-4E21-B255-80F0607B176D}", AutoMap = true)]
public class BaseWithExtraContent : Base
{
public virtual string ExtraContent {get;set;}
}
[SitecoreType(TemplateId = "{95563412-7A08-46A3-98CB-ABC4796D57D4}", AutoMap = true)]
public class BaseWithExtraContentAndCallToActionLink : BaseWithExtraContent
{
public virtual string CallToActionLink {get;set;}
}
These data models are used from another class that has a list of base type, I want to be able to store any derived type in here so I added attributes as detailed in this tutorial
[SitecoreType(AutoMap = true)]
public class HomePage
{
[SitecoreChildren(InferType = true)]
[SitecoreField(FieldName = "Widgets")]
public virtual IEnumerable<Base> Widgets { get; set; }
}
According to the tutorial this should work. However the list of widget just contains class of the base type.
I then found a later tutorial that said that if you have separated out the models to a different assemblies than the one Glass is installed in you have to add an AttributeConfigurationLoader pointing to the assembly your models are in. The base and derived types are all in the same assembly so I wasn't sure this would solve the issue, but I tried it anyway.
My custom loader config looks like this:
public static class GlassMapperScCustom
{
public static void CastleConfig(IWindsorContainer container)
{
var config = new Config {UseWindsorContructor = true};
container.Install(new SitecoreInstaller(config));
}
public static IConfigurationLoader[] GlassLoaders()
{
var attributes = new AttributeConfigurationLoader("Project.Data");
return new IConfigurationLoader[] {attributes};
}
public static void PostLoad(){
//Remove the comments to activate CodeFist
/* CODE FIRST START
var dbs = Sitecore.Configuration.Factory.GetDatabases();
foreach (var db in dbs)
{
var provider = db.GetDataProviders().FirstOrDefault(x => x is GlassDataProvider) as GlassDataProvider;
if (provider != null)
{
using (new SecurityDisabler())
{
provider.Initialise(db);
}
}
}
* CODE FIRST END
*/
}
}
Upon doing the custom loader config I now get an "Ambiguous match found" exception. I have checked to see if there are any other non Glass attributes set in the classes in that assembly and there aren't.
Any ideas? I guess there are 2 questions.
Why does using the inferred type attribute not load the correct types and only the base types?
Why when I attempt to solve this by adding a custom attribute loader do I get the exception?
Widgets property has two attributes - it's either mapped to the children elements of the item, or a field, can't be both.