How to Append Acumatica DAC attribute [PXEmailSource] - acumatica

I want to know the best way to append the DAC attributes..Please note I need Appending method for DAC Attributes not DAC Field Attributes.
Specifically I need to append [PXEMailSource] to some of the existing DACs
Eg: PX.Objects.IN.INRegister
What is the best way to do it ...?
Any helps regarding this will be highly appreciated

You can change the attribute of the DAC using PXSubstituteAttribute
Note from Acumatica Framework Development Guide(page 95)
PXSubstitute Attribute
Indicates that the derived DAC should replace its base DACs in a specific graph or all graphs.
• public Type GraphType
Gets or sets the specific graph in which the derived DAC replaces base DACs.
• public Type ParentType
Gets or sets the base DAC type up to which all types in the inheritance
hierarchy are substituted with the derived DAC. By default, the property
has the null value, which means that all base DACs are substituted with the
derived DAC
Remarks
The attribute is placed on the definition of a DAC that is
derived from another DAC. The attribute is used primarily to make the
declarative references of the base DAC in definitions of calculations
and links from child objects to parent objects be interpreted as the
references of the derived DAC.
Below is the example how to use Attribute on INRegister DAC.
[PXPrimaryGraph(new Type[]
{
typeof(INReceiptEntry),
typeof(INIssueEntry),
typeof(INTransferEntry),
typeof(INAdjustmentEntry),
typeof(KitAssemblyEntry),
typeof(KitAssemblyEntry)
}, new Type[]
{
typeof(Where<INRegister.docType, Equal<INDocType.receipt>>),
typeof(Where<INRegister.docType, Equal<INDocType.issue>>),
typeof(Where<INRegister.docType, Equal<INDocType.transfer>>),
typeof(Where<INRegister.docType, Equal<INDocType.adjustment>>),
typeof(Select<INKitRegister, Where<INKitRegister.docType, Equal<INDocType.production>, And<INKitRegister.refNbr, Equal<Current<INRegister.refNbr>>>>>),
typeof(Select<INKitRegister, Where<INKitRegister.docType, Equal<INDocType.disassembly>, And<INKitRegister.refNbr, Equal<Current<INRegister.refNbr>>>>>)
})]
[INRegisterCacheName("Receipt")]
[Serializable]
[PXSubstitute(GraphType = typeof(REQUIREDGRAPH_WHERE_SHOULD_BE_SUBSTITED))]
[PXEMailSource]
public class INRegisterExt: INRegister
{
//...
}

Related

How to add a column to the grid that shows value from another screen in Acumatica?

I'm new to Acumatica, could you please help me? I have too screens IN202500 (stock items) and SO301000(sales orders). I added a field to stock items and now I need to show a value from that field in grid column of sale orders for each stock items. I suppose that I need to use PXDefault attribute for this?
There are a number of ways you can do this. I'll provide 3 possibilities.
If your View used by the grid contains InventoryItem, you may be able simply to select your custom field from InventoryItem and add it directly to the screen. I'll assume this is not an option or you likely would have found it already.
Create a custom field in a DAC extension on SOLine where you add your custom field as unbound (PXString, not PXDBString) and then use PXDBScalar or PXFormula to populate it. I haven't used PXDBScalar or PXFormula to retrieve a value from a DAC Extension, so I'll leave it to you to research. I do know this is super easy if you were pulling a value directly from InventoryItem, so worth doing the research.
Create as an unbound field as in #2, but populate it in the SOLine_RowSelecting event. This is similar to JvD's suggestion, but I'd go with RowSelecting because it is the point where the cache data is being built. RowSelected should be reserved, in general, for controlling the UI experience once the record is already in the cache. Keep in mind that this will require using a new PXConnectionScope, as Acuminator will advise and help you add. (Shown in example.) In a pinch, this is how I would do it if I don't have time to sort out the generally simpler solution provided as option 2.
Code for Option 3:
#region SOLine_RowSelecting
protected virtual void _(Events.RowSelecting<SOLine> e)
{
SOLine row = (SOLine)e.Row;
if (row == null)
{
return;
}
using (new PXConnectionScope())
{
SOLineExt rowExt = row.GetExtension<SOLineExt>();
InventoryItem item = SelectFrom<InventoryItem>
.Where<InventoryItem.inventoryID.IsEqual<#P.AsInt>>
.View.Select(Base, row.InventoryID);
InventoryItemExt itemExt = item.GetExtension<InventoryItemExt>();
rowExt.UsrSSMyDatAField = itemExt.UsrSSMyDataField;
}
}
#endregion

PXDBCreatedDateTime doesn't work in Extension Table

I have a User Defined Table that I link to the BAccount table in Acumatica. What I'm trying to do is use the PXDBCreatedDateTime attribute to save the CreateDateTime when the UDFs are set. Is this posssible? It doesn't seem to work right now.
[PXTable(typeof(BAccount.bAccountID),IsOptional=true)]
public class CustomerExtension : PXCacheExtension<BAccount>
{
[PXDBCreatedDateTime()]
[PXUIField(DisplayName = "Date")]
public DateTime? CreatedDateTime { get; set; }
public class createdDateTime : IBqlField { }
}
I would assume it would not work as the BAccount table already contains a field with the same name 'CreatedDateTime'. I would first use a different field name for table extension fields as this could create some conflicts to those fields that already exist with the same name. Also, extension tables are inserted when the base table is either inserted or updated (first time after extension table is added) which may or may not occur from changes to your extension fields. This would also cause some issues for getting a good date from your PXDBCreatedDateTime field. You might be better off using a standard date time field and use some type of formula to update the date when your fields change. I would have to research the formula. You could use logic inside the setter of your user fields and add the PXDependsOnFields attribute to your date field and set your date field if null. I have not tried PXDependsOnFields in an extension - but the logic could be promising.

WPFExtendedToolkit PropertyGrid Standard Values

I'm trying to display XmlElement's attributes in Xceed PropertyGrid. For that purpose I defined custom wrapper class. It wraps XmlElement, iterates over XmlAttributes and creates custom PropertyDescriptor for each XmlAttribute. All "virtual" properties' type is String. All works fine.
Now I want to have drop-down list of possible attribute values for every attribute that has restricted set of values. In Xceed's PropertyGrid, there is ItemsSourceAttribute for that. But it has to be applied as follows:
ItemsSourceAttribute(typeof(MyCustomItemsSource))
And here is the problem - I can not provide proper argument for MyCustomItemsSource constructor. What can I do about this?
It seems that there is another possibility - to define a TypeConverter, override GetStandardValues, and supply this converter to "virtual" property. But PropertyGrid just ignores this attribute.
How this simple task can be done with Xceed PropertyGrid?
Solved. I implemented custom editor
public class AttributeValuesEditor: Xceed.Wpf.Toolkit.PropertyGrid.Editors.ComboBoxEditor
{
protected override IEnumerable CreateItemsSource(PropertyItem propertyItem)
{
var property = propertyItem.PropertyDescriptor as XmlAttributePropertyDescriptor;
Debug.Assert(property!=null);
return property.GetCompletionValues();
}
}
Here, the context is passed into method in the form of PropertyItem. Now it is possible to differentiate between different attributes and return appropriate items.

Resharper create property with backing field

How do you create property with a backing field in Resharper?
This is the first thing you would want to do with a class and I cannot find how to it.
Its so simple.
Within the body of the class, type prop and hit Tab. Supply the property's type and name. This will create an autoproperty (these days, it is typically one of these you would want to create).
Then, with the cursor on the property name, hit Alt+Enter and choose To property with backing field.
The quickest way I've found is to type your property as if it exists already:
this.MyProperty = "hello";
Then Alt-Return on the property name, and choose Create Property 'MyProperty' then hit tab to choose between auto-property, managed backing field, or default member body.
I believe this is quicker than using the prop shortcut, hitting tab, specifying the property type, hitting tab twice, specifying the name, and then pressing Alt-Return on the property name and choosing the 'to property with backing field' selection.
You could also create a Live Template so that there is slightly less work, e.g:
/// <summary>
/// Private backing field for $Property$ property
/// </summary>
private $Type$ $BackingField$;
public $Type$ $Property$
{
get
{
return this.$BackingField$;
}
set
{
this.$BackingField$ = value;
}
}
The parameter $BackingField$ can be generated automatically from $Property$ by the "first character in lower case" macro of the template editor and setting it to "Not editable".
But I believe the first method is the quickest and easiest.
If you already have a property with a getter and setter, sometimes you will find that the backing field you used is no longer available because you changed the base class for the current class or you made other changes. For example, in the LinesMax property below, the backing field Height is available from an inherited class:
public int LinesMax
{
get { return ConvertValGet(AdjustMetricEnum.Height, Height); }
set { Height = ConvertValSet(AdjustMetricEnum.Height, value); }
}
If the above code works but I decide afterwards no longer to inherit the class that exposes the Height property, the two Height variable names will turn red in the IDE to indicate that they're no longer available to the code.
At that point, I may want to create a private backing field. To easily create that, I can first modify the Height name to _height, then place the cursor on either _height name, hit Alt-Enter then choose Create field '_height'. A backing field will be created.

Disable a EditorGrid row when a model attribute has been updated

Here's my request :
I have an EditorGrid which renders some rows based on its associated ListStore.
The ListStore has a collection of instances of my model which has an attribute called "markeAsDeleted" which is updated elsewhere in the UI.
My question is :
How is-it possible to change the rendering of the corresponding row to turn it 'disabled' when my 'markAsDeleted' attribute is 'true' ?
What's I'm expecting is a kind of a rendrer to add to my EditorGrid instance which updates the row as the model attribute is updated.
Thanks
Hiding the column with filtering would be your best best.
If you set store.setMonitoChanges(true); then I believe it will reconise when anything changes that model in the store and fire an storeUpdate from there you could re-Apply your filter (if it doesnt do that automatically anyway);
example
store.addStoreListener(new StoreListener<BaseModelData>() {
public void storeUpdate(StoreEvent<M> se) {
store.applyFilters("");
}
})
edit:
After reading the comments on another answer I notice you are using a Grid filter to filter the columns you could just as easily use addFilter on a store.
example
store.addFilter(new StoreFilter<BaseModelData>() {
public boolean select(Store<T> store, T parent, T item, String property) {
return !item.get("markAsDeleted");
}
});
GXT makes sure that when your Grid's store gets modified, the Grid is re-Rendered. So when other part of your application does update on the model, make sure that the same model gets updated on store EXPLICITLY.
You can use store.remove(), store.removeAll(), store.addAll() to replace the model with the updated one.

Resources