Extend Generic Inquiry to Show the Number of records - acumatica

Is it possible to extend the Generic Inquiry screen so that it shows the number of records retrieved? Or perhaps is it possible to use PXGenericInqGrph to get the number of records of a Generic Inquiry?
However, it is important, for performance reasons that I only retrieve one record with the total from the Database. and not getting all records from the database and doing a Count at the Application layer.

At least up until Acumatica 7.207.0029 there is no method to extend the Generic Inquiry results screen.
If you only need the record count, what you can do is edit your GI or create a copy to get the total and use the special <Count> field to get the record count.
Of course this requires you to set a GroupBy field and you need this to be the same for all records if you want a total record count.
If your query has a field you know to be equal to all records, you can use that field in the GroupBy tab. If not, there is a way to do this by adding a join to an number table.
Number Table Workaround
This technique uses a table with numbers to create specific queries. In this case we can join it to your query to add a known common value to all rows.
Here is the XML for a Customization Project that creates this table and makes it available as the Is.Objects.Core.ISNumbers DAC.
<Customization level="200" description="Number utility table" product-version="17.207">
<Graph ClassName="ISNumbers" Source="#CDATA" IsNew="True" FileType="NewDac">
<CDATA name="Source"><![CDATA[using System;
using PX.Data;
namespace IS.Objects.Core
{
[Serializable]
public class ISNumbers: IBqlTable
{
#region Number
[PXDBInt(IsKey = true)]
[PXUIField(DisplayName = "Number", IsReadOnly = true)]
public int? Number { get; set; }
public class number : IBqlField{}
#endregion
}
}]]></CDATA>
</Graph>
<Sql TableName="ISNumbers" CustomScript="#CDATA">
<CDATA name="CustomScript"><![CDATA[IF OBJECT_ID('ISNumbers', 'U') IS NOT NULL DROP TABLE ISNumbers;
SELECT TOP 10000 IDENTITY(int,1,1) AS Number
INTO ISNumbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
ALTER TABLE ISNumbers ADD CONSTRAINT PK_ISNumbers PRIMARY KEY CLUSTERED (Number)]]></CDATA>
</Sql>
</Customization>
Just add the table to the GI and crate an INNER JOIN relation where the value of the number field equals 1:
Then you can use this field in the GroupBy condition.
Then you can add the Numbers field and set its value to <Count>. Leave all your other result fields to keep the logic but hide them if you don't need them (they will be automatically grouped by max value).
All queries performed by GIs are executed in the DB so you don't need to worry about it running in the App side.

Related

Best way to retrieve an item from dynamoDB using attribute which is not partition key

I am new to dynamoDB and need some suggestion from experienced people here . There is a table created with below model
orderId - PartitionKey
stockId
orderDetails
and there is a new requirement to fetch all the orderIds which includes particular stockId. The item in the table looks like
{
"orderId":"ord_12234",
"stockId":[
123221,
234556,
123231
],
"orderDetails":{
"createdDate":"",
"dateOfDel":""
}
}
provided the scenario that stockId can be an array of id it cant be made as GSI .Performing scan would be heavy as the table has large number of records and keeps growing . what would be the best option here , How the existing table can be modified to achieve this in efficient way
You definitely want to avoid scanning the table. One option is to modify your schema to a Single Table Design where you have order items and order/stock items.
For example:
pk
sk
orderDetails
stockId
...
order#ord_12234
order#ord_12234
{createdDate:xxx, dateOfDel:yyy}
...
order#ord_12234
stock#123221
23221
...
order#ord_12234
stock#234556
234556
...
order#ord_12234
stock#123231
123231
...
You can then issue the following queries, as needed:
get the order details with a query on pk=order#ord_12234, sk=order#ord_12234
get the stocks for a given order with a query on pk=order#ord_12234, sk=stock#
get everything associated with the order with a query on pk=order#ord_12234

Using SubstituteKey with Joined Table

I have a selector defined in this manner:
[PXSelector(typeof(Search2<TableA.id, LeftJoin<TableB, On<TableB.refNbr, Equal<TableA.refNbr>>>,
Where<TableA.woid, IsNull, And<TableB.tranType, Equal<TranType>, And<TableB.lotSerialNbr, NotEqual<StringEmpty>>>>>),
typeof(TableA.id), typeof(TableB.lotSerialNbr), SubstituteKey = typeof(TableB.lotSerialNbr))]
However the selector does not show the SubstituteKey value. Am I able to assign the SubsistiteKey belonging to a joined table instead of the original table and show/fetch its value?
It's not supported to assign the SubsistiteKey to a joined table field. As an alternative, let me suggest to declare an unbound field in TableA and decorate it with the PXDBScalarAttribute to calculate its value on database level:
[PXDBScalar(typeof(Search<TableB.lotSerialNbr, <TableB.refNbr, Equal<TableA.refNbr>>>))]

Insert data in two Table using Mybatis

I am very new to Mybatis and stuck in a situation I have some questions
The complete scenario is I need to read and excel file and insert the excel data in database in two different tables having primary and foreign key relationship .
I am able to read the excel data and able to insert in primary table but not getting how to insert data in second table actually the problem is I have two different pojo classes having separate data for for each table two different mappers.
I am achiving association by defining the pojo of child table inside the pojo of parent class
Is there any way to insert data in two different table.
Is is possible to run 2 insert queries in single tag
Any help would be appreciable
There are lot of ways to do that.
Here is demonstration of one of the most straightforward ways to do that - using separate inserts. The exact solution may vary insignificantly depending mainly on whether primary keys are taken from excel or are generated during insertion into database. Here I suppose that keys are generated during insertion (as this is a slightly more complicated case)
Let's assume you have these POJOs:
class Parent {
private Integer id;
private Child child;
// other fields, getters, setters etc
}
class Child {
private Integer id;
private Parent parent;
// other fields, getters, setters etc
}
Then you define two methods in mapper:
public interface MyMapper {
#Insert("Insert into parent (id, field1, ...)
values (#{id}, #{field1}, ...)")
#Options(useGeneratedKeys = true, keyProperty = "id")
void createParent(Parent parent);
#Insert("Insert into child(id, parent_id, field1, ...)
values (#{id}, #{parent.id}, #{field1}, ...)")
#Options(useGeneratedKeys = true, keyProperty = "id")
void createChild(Child child);
}
and use them
MyMapper myMapper = createMapper();
Parent parent = getParent();
myMapper.createParent(parent);
myMapper.createChild(parent.getChild());
Instead of single child there can be a collection. In that case createChild is executed in the loop for every child.
In some databases (posgresql, sql server) you can insert into two tables in one statement. The query however will be more complex.
Another possibility is to use multiple insert statements in one mapper method. I used code similar to this in postgresql with mapping in xml:
<insert id="createParentWithChild">
insert into parent(id, field1, ...)
values (#{id}, #{field1}, ...);
insert into child(id, parent_id, field1, ...)
values (#{child.id}, #{id}, #{child.field1},...)
</insert>
and method definition in mapper interface:
void createParentWIthChild(Parent parent);
I know this is a little old, but the solution which worked best for me was implementing 2 insert stanzas in my mapping xml.
<insert id="createParent">
insert into parent(id, field1, ...)
values (#{id}, #{field1}, ...);
</insert>
<insert id="createChild">
insert into child(id, parent_id, field1, ...)
values (#{child.id}, #{id}, #{child.field1},...);
</insert>
And then chaining them. ( if the parent call failed do not continue to call the child)
As a side note, In my case I am using camel-mybatis so my camel-config had
<from uri="stream:in"/>
<to uri="mybatis:createParent?statementType=Insert"/>
<to uri="mybatis:createChild?statementType=Insert"/>

How to update multiple rows using Hector

Is there a way I can update multiple rows in cassandra database using column family template like supply a list of keys.
currently I am using updater columnFamilyTemplate to loop through a list of a keys and do an update for each row. I have seen queries like multigetSliceQuery but I don't know their equivalence in doing updates.
There is no utility method in ColumnFamilyTemplate that allow you to just pass a list of keys with a list of mutation in one call.
You can implement your own using mutators.
This is the basic code on how to do it in hector
Set<String> keys = MY_KEYS;
Map<String, String> pairsOfNameValues = MY_MUTATION_BY_NAME_AND_VALUE;
Set<HColumn<String, String>> colums = new HashSet<HColumn<String,String>>();
for (Entry<String, String> pair : pairsOfNameValues.entrySet()) {
colums.add(HFactory.createStringColumn(pair.getKey(), pair.getValue()));
}
Mutator<String> mutator = template.createMutator();
String column_family_name = template.getColumnFamily();
for (String key : keys) {
for (HColumn<String, String> column : colums) {
mutator.addInsertion(key, BASIC_COLUMN_FAMILY, column);
}
}
mutator.execute();
Well it should look like that. This is an example for insertion, be sure to use the following methods for batch mutations:
mutator.addInsertion
mutator.addDeletion
mutator.addCounter
mutator.addCounterDeletion
since this ones will execute right away without waiting for the mutator.execute():
mutator.incrementCounter
mutator.deleteCounter
mutator.insert
mutator.delete
As a last note: A mutator allows you to batch mutations on multiple rows on multiple column families at once ... which is why I generally prefer to use them instead of CF templates. I have a lot of denormalization for functionalities that use the "push-on-write" pattern of NoSQL.
You can use a batch mutation to insert as much as you want (within thrift_max_message_length_in_mb). See http://hector-client.github.com/hector//source/content/API/core/1.0-1/me/prettyprint/cassandra/model/MutatorImpl.html.

Querying multiple tables with a where clause in LINQ to SQL

Forgive my ignorance with Linq to SQL but...
How do you query mulitple tables in one fell swoop?
Example:
I want to query, say 4 tables for a title that includes the following word "penguin". Funnily enough each table also has a field called TITLE.
Tables are like so:
I want to query each table (column: TITLE) for the word "penguin". Each table is referenced (via foreign key) to a parent table that is simply called Reference, and is linked on a column called REF_ID. So ideally the result should come back with a list of REF_ID's where the query criteria was matched.
If you can help you will be richly rewarded....... (with a green tick ;)
The code I have works for just one table - but not for two:
var refs = db.REFERENCEs
.Include(r => r.BOOK).Where(r => r.BOOK.TITLE.Contains(titleString)).Include(r => r.JOURNAL.AUTHORs)
.Include(r => r.JOURNAL).Where(r => r.JOURNAL.TITLE.Contains(titleString));
I had a similar scenario a while back and ended up creating a view that unioned my tables and then mapped that view to a LINQ-to-SQL entity.
Something like this:
create view dbo.References as
select ref_id, title, 'Book' as source from dbo.Book
union all
select ref_id, title, 'Journal' from dbo.Journal
union all
select ref_id, title, 'Magazine' from dbo.Magazine
union all
select ref_id, title, 'Report' from dbo.Report
The mapping would look like this (using attributes):
[Table(Name="References")]
public class Reference {
[Column(Name="Ref_Id", IsPrimaryKey=true)]
public int Id {get;set;}
[Column]
public string Title {get;set;}
[Column]
public string Source {get;set;}
}
Then a query might look like this:
var query = db.GetTable<Reference>().Where(r => r.Title.Contains(titleString));

Resources