Users often want to be able to filter on high cardinality dimensions such as ISIN or counterpartyID.
Is there a way to use such dimensions as slicers but block them for being used in rows / columns ?
Best regards,
Christophe
You can easily do it with the MDX-based web client interface ActivePivot Live.
To do so, you need to extend the class OlapEntityToWizardExpressionConverter and rebind the interface IOlapEntityToWizardExpressionConverter to your custom class through GIN (GWT INjection). Easily doable (only one line of code):
bind(IOlapEntityToWizardExpressionConverter.class).to(MyCustomizedOlapEntityToWizardExpressionConverter.class);
Then in your class, simply override the visit(final Hierarchy hierarchy) method:
...
if(section.equals(ROWS) || section.equals(COLUMNS)){
if(hierarchy.getName().equals(ISIN) || hierarchy.getName().equals(counterpartyID))){
//Do something here (display a message...)
return;
}
}
super.visit(hiearchy);
...
Users won't be able to put the dimension on an axis anymore.
Related
I need to work with the reusable business objects for Sales tax, discounts, etc. and need to override some of the methods in these graph extensions. For example I am starting with the Opportunities graph. I have a set of order totals that need to calculate into the overall products amount and in the past we just overrode the tax attribute on (I think) tax category. Anyhow I don't see how its possible to use the PXOverrideAttribute on a method from a second level graph extension.
Here is my example:
public class OpportunityMaintExtOne : PXGraphExtension<PX.Objects.CR.OpportunityMaint.SalesTax, PX.Objects.CR.OpportunityMaint>
{
[PXOverride]
public virtual void CalcDocTotals(object row, decimal CuryTaxTotal, decimal CuryInclTaxTotal, decimal CuryWhTaxTotal,
Action<object, decimal, decimal, decimal> del)
{
del?.Invoke(row, CuryTaxTotal, CuryInclTaxTotal, CuryWhTaxTotal);
var someOtherTotal = Base1.Documents.Cache.GetValueAsDecimal<CROpportunityExtension.aMCurySomeOtherTotal>(row);
if (someOtherTotal == 0)
{
return;
}
var curyDocTotal = someOtherTotal + Base1.Documents.Cache.GetValueAsDecimal<CROpportunity.curyProductsAmount>(row);
Base1.Documents.Cache.SetValue<CROpportunity.curyProductsAmount>(row, curyDocTotal);
}
}
What is going on inside of CalcDocTotals in my graph extension is not the focus. It is the fact that I cannot override the OpportunityMaint.SalesTax CalcDocTotals method as I could if the method was in the first level (Base) graph. The SalesTax graph extension has the method as protected but protected methods (if it was in the base graph) are overrideable using the PXOverrideAttribute if you make your method call public which is what I have done. I also tried using a declared delegate in place of the Action but same results (as I expected but wanted to confirm).
My question: Is it possible to override a second, third, etc. level graph extension method using the PXOverrideAttribute?
When I compile the code above and the page loads I get this error:
Method Void CalcDocTotals(System.Object, System.Decimal,
System.Decimal, System.Decimal,
System.Action`4[System.Object,System.Decimal,System.Decimal,System.Decimal])
in graph extension is marked as [PXOverride], but the original method
with such name has not been found in PXGraph
The ability to override extension methods from a higher level extension has been added in 2018R1 Update 4 (18.104.0023). This resolves my question/issue and allows for the code posted in my question to function as is.
You cannot override methods from Extension1 in Extension2 etc as far as I've been able to see in my years with Acumatica. My solution to the problem was thus : Create a helper graph with your basic methodology, create a field or property for it in whatever graph you wish to use it in (Preferably a Lazy initialized one), then in whatever project you must override the logic on, just reference your original project, and create an extension of your helper graph.
I know pxformula could do it, but pxformula only accepts two argument parameters. how can i add (sum) multiple fields of the same DAC? can i nest it?
thanks. some working examples would be appreciated, some other methods would also be appreciated.
As suggested in another answer, PXFormula can be used to perform a multi field calculation. However, PXFormula always assigns calculated value to the field it decorates.
PXUnboundFormulaAttribute might be a better approach in case you don't need to store calculated value in any field:
[PXUnboundFormulaAttribute(typeof(Switch<Case<Where<GLTranDoc.debitAccountID, IsNotNull>, GLTranDoc.curyTranTotal>, Sub<GLTranDoc.curyTaxAmt, GLTranDoc.curyInclTaxAmt>>),
typeof(SumCalc<GLDocBatch.curyDebitTotal>))]
For additional examples on the PXUnboundFormulaAttribute, please check Example 7.3: Adding Conditional Calculation of Aggregated Values in the T200 developer class guide at Acumatica University or Acumatica Open University
I know this post is old, but I have been stuck on this for a while. I finally found a simple solution using [PXFormula] by nesting ADD's.
I had made a new grid screen and I wanted the final column to total all the other columns.
MY DAC’s :
one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve
The solution:
[PXFormula(typeof(Add<Add<Add<Add<Add<Add<one, two>,
Add<three, four>>, Add<five, six>>, Add<seven, eight>>,
Add<nine, ten>>, Add < eleven, twelve >>), typeof(SumCalc<total>))]
[PXDBDecimal()]
[PXUIField(DisplayName = "Total", Enabled = false)]
public virtual Decimal? Total { get; set; }
public abstract class total : PX.Data.BQL.BqlDecimal.Field<total> { }
If you do a code search on PXFormula you should find many examples. I usually search the code found in your site/App_data/CpdeRepository directory if you have access to a local site.
If you are looking to perform a multi field calculations, you nest your Add, Sub, Mult, Div, etc. calls.
Here are some examples from my search on "PXFormula" or "Mult<" or "Add<":
Found in ARTranRUTROT.CuryRUTROTTotal, this example will subtrack curyExtPrice from curyDiscAmt and add curyRUTROTTaxAmountDeductible (unless null use zero)
[PXFormula(typeof(Add<Sub<ARTran.curyExtPrice, ARTran.curyDiscAmt>,
IsNull<curyRUTROTTaxAmountDeductible, decimal0>>))]
Found in GLTaxTran.CuryExpenseAmt. This example again uses multiple fields in the calculation all nested.
[PXFormula(typeof(Mult<Mult<GLTaxTran.curyTaxableAmt,
Div<GLTaxTran.taxRate, decimal100>>, Sub<decimal1,
Div<GLTaxTran.nonDeductibleTaxRate, decimal100>>>), null)]
I need to perform a search on several entities with the same string then order the results.
I've heard/read a little about FOSElasticaBundle, would this bundle be able to do it? It seems (to me) to have almost to much features for this purpose and I'm not sure it could run on a shared server (hostgator).
The other solution I can think of at the moment is doing the search "manually" (by using join and union) but I'm wondering where should I put such a function: in an existing controller, a new one, a new bundle or somewhere else?
I'm worried as well that this manual solution could come to a cost, especially on some non-indexable fields.
You would do custom entity repositories. Check out the docs. Basically this extends the default FindAll, FindOneBy, etc.
You would have a function like so:
class MyEntityRepository extends Doctrine\ORM\EntityRepository {
public function findByCustomRule(){
//this is mapped to your entity (automatically adds the select)
$queryBuilder = $this->createQueryBuilder('someAlias');
$queryBuilder->orderBy('...');
//this is mapped to any entity
$queryBuilder = $this->getEntityManager()->createQueryBuilder();
$queryBuilder->select('...');
//result
$result = $queryBuilder->getQuery()->getResult();
}
}
This class is defined in the doctrine mapping and lives inside the Entity folder.. Check the docs out and you should get a basic idea.
I have a method on an object oriented database that creates tables based on their type.
I want to be able to send a list of types to get created, but i'm hoping to limit them to only classes derived from a specific base class (MyBase).
Is there a way i can require this in the method signature?
Instead of
CreateTables(IList<Type> tables)
Can i do something that would
CreateTables(IList<TypeWithBaseTypeMyBase> tables)
I know i could check the base class of each type sent over, but if possible i'd like this verified at compile time.
Any suggestions?
You could do the following:
CreateTables(IList<MyBase> tables)
{
// GetType will still return the original (child) type.
foreach(var item in tables)
{
var thisType = item.GetType();
// continue processing
}
}
Have you tried this?
CreateTables(IList<MyBase> tables)
I think that's all you have to do.
Why not just change the signature to:
CreateTables(IList<BaseType> tables)
I need to query a table using FreeTextTable (because I need ranking), with SubSonic. AFAIK, Subsonic doesn't support FullText, so I ended up creating a simple UDF function (Table Function) which takes 2 params (keywords to search and max number of results).
Now, how can I inner join the main table with this FreeTextTable?
InlineQuery is not an option.
Example:
table ARTICLE with fields Id, ArticleName, Author, ArticleStatus.
The search can be done by one of more of the following fields: ArticleName (fulltext), Author (another FullText but with different search keywords), ArticleStatus (an int).
Actually the query is far more complex and has other joins (depending on user choice).
If SubSonic cannot handle this situation, probably the best solution is good old plain sql (so there would be no need to create an UDF, too).
Thanks for your help
ps: will SubSonic 3.0 handle this situation?
3.0 can do this for you but you'd need to make a template for it since we don't handle functions (yet) out of the box. I'll be working on this in the coming weeks - for now I don't think 2.2 will do this for you.
I realize your question is more complex than this, but you can get results from a table valued function via SubSonic 2.2 with a little massaging.
Copy the .cs file from one of your generated views into a safe folder, and then change all the properties to match the columns returned by your UDF.
Then, on your collection, add a constructor method with your parameters and have it execute an InlineQuery.
public partial class UDFSearchCollection
{
public UDFSearchCollection(){}
public UDFSearchCollection(string keyword, int maxResults)
{
UDFSearchCollection coll = new InlineQuery().ExecuteAsCollection<UDFSearchCollection>("select resultID, resultColumn from dbo.udfSearch(#keyword, #maxResults)",keyword,maxResults);
coll.CopyTo(this);
coll = null;
}
}
public partial class UDFSearch : ReadOnlyRecord<UDFSearch>, IReadOnlyRecord
{
//all the methods for read only record go here
...
}
An inner join would be a little more difficult because the table object doesn't have it's own parameters collection. But it could...