add two fields and insert into third in domain class in grails - grails

I am working on a grails project in which i have a domain class having 3 fields. my requirement is to input only 2 fields and 3rd field get populated with the sum of both the fields. can anyone send me the code. thnks

See Derived properties
Example from above link
class Product {
Float price
Float taxRate
Float tax
static mapping = {
tax formula: 'PRICE * TAX_RATE'
}
}

Here's two complete ways of doing it, depending on your needs.
If you don't need to store the third field, meaning it's only used for display, you can do this:
class MyDomain {
int field1
int field2
static transients = ['field3']
getField3() {
field1 + field2
}
}
This will allow you to access the sum as myDomain.field3.
If you need to store it, say because it's heavily used in calculations, you can use events to automatically calculate and store the sum, like so:
class MyDomain {
int field1
int field2
int field3
def beforeInsert() {
field3 = field1 + field2
}
def beforeUpdate() {
field3 = field1 + field2
}
}
The benefit of doing it this way is that the third field is populated no matter where it's created or updated.
Two Notes:
If you only want to sum field3 when it's created, and not on updates, then remove beforeUpdate.
If you are doing more complex calculations than that simple sum, throw them in another method (like updateField3), and call that instead of hard-coding it.

Related

Vaadin7 table sort label column numerically

I have vaadin table with multiple columns. One of the column is of label class
container.addContainerProperty(ID_COLUMN, Label.class, "");
and I fill it up like
referenceItem.getItemProperty(ID_COLUMN).setValue(new Label(new Integer(reference.getId()).toString()));
When I sort the table by clicking on this table, it sorts the data like
1
10
100
2
200
7
So, I tried to change the class to Integer, then it works fine, but I get the numbers with comma like
1
2
...
..
7,456
8,455
How can I have the data sorted numerically and no commas.
I was able to figure out. I used Integer as class for my column and used following
referenceTable = new Table()
{
#Override
protected String formatPropertyValue(final Object a_row_id, final Object a_col_id, final Property<?> a_property)
{
if (a_property.getType() == Integer.class && null != a_property.getValue())
{
DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance(getLocale());
df.applyLocalizedPattern("#0");
return df.format(a_property.getValue());
}
return super.formatPropertyValue(a_row_id, a_col_id, a_property);
}
};
It has been a while since i have been having fun with Vaadin Table.
There are property formatters, generators etc... stuff but in this case it might be easiest just to:
container.addContainerProperty(ID_COLUMN, String.class, "");
referenceItem.getItemProperty(ID_COLUMN).setValue(""+reference.‌​getId());

Grails: How do I retrieve records by a specific property?

I am creating a basic CRUD application with a Person entity:
class Person {
public int Age;
...
public int getAge() {
return this.Age;
}
public void setAge(int AgeToSet) {
this.Age = AgeToSet;
}
}
I have a controller and I want to retrieve all Persons with an age of 20:
def filter = {
def c = Person.createCriteria();
def persons = c.list{
eqProperty("Age", "20");
}
[persons: persons];
}
But this is not working and is, instead, giving me the error:
ERROR StackTrace - Full Stack Trace:
org.hibernate.QueryException: could not resolve property: Age of: project.Person
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:62)
What could be the problem?
Three things:
Your Age needs to start with lowercase: age.
Your criteria is wrong, you want to use eq. eqProperty compares two properties, but you only need one and a value.
Your comparision must be with an int, like this: eq("myage", 20).
Since this query is so simple, you may want to just use a DynamicFinder: http://gorm.grails.org/6.0.x/hibernate/manual/index.html#finders
With a Dynamic Finder, you could simplify the query to:
def persons = Person.findAllByAge(20)
Just a suggestion. I use Dynamic Finders as my primary query method. If I need a query that is more complex, I'll resort to a .createCriteria and then a .executeQuery which takes HQL.

Grails projection on arithmetic expression with executeQuery()?

I need to get a sum of all items sold per order per store. I am running a sum() on expression using executeQuery(). It works fine as shown below but I wanted to know if there is a better, groovier way to do it.
StoreService {
static transactional = false
def getTotalOrders(def store) {
return Store.executeQuery("select sum(a.soldQuantity * a.soldPrice) as total
from OrderItem a inner join a.order b inner join b.store c
where c= :store", [store: store]).get(0)
}
}
Store {
transient storeService
def getTotalSales() {
storeService.getTotalSales()
}
static hasMany = [items: Item]
// no hasMany to Order
}
Item {
static belongsTo = [store: Store]
// no hasMany to OrderItem
}
Order {
static hasMany = [orderItems: OrderItem]
static belongsTo = [store: Store]
}
OrderItem {
BigDecimal soldPrice
Integer soldQuantity
static belongsTo = [order: Order, item: Item]
}
I think withCriteria() would be easier to read but I couldn't figure out how to do it with expressions within sum() wouldn't take for obvious reasons.
projections {
sum("soldPrice * soldQuantity")
}
Thanks
There are two options you can go with.
Option 1
You can add a formula mapping to your domain class then query it directly.
OrderItem {
BigDecimal soldPrice
Integer soldQuantity
BigDecimal totalPrice
static mapping = {
totalPrice formula: "sold_price * sold_quantity"
}
static belongsTo = [order: Order, item: Item]
}
Now your criteria query can just contain
projections {
sum("totalPrice")
}
Not only that but you can query it with dynamic finders OrderItem.findAllByTotalPriceGreaterThan(20.00) as well as simple access println "The final price is ${orderInstance.totalPrice}. We find this really nifty however there are times when you would want to get totalPrice before the OrderItem has been persisted so we usually write a simple(Not DRY) getter
BigDecimal getTotalPrice() {
totalPrice ?: (soldPrice && soldQuantity) ? soldPrice * soldQuantity : null
}
But you only need this sort of thing if you require totalPrice before it has been persisted.
Option 2
Before formula mappings we used to drop down to the Hibernate Criteria API and use a sqlProjection Projection as part of our criteria query.
projections {
addProjectionToList(Projections.sqlProjection(
"sum(sold_price * sold_quantity) as totalPrice",
["totalPrice"] as String[],
[Hibernate.LONG] as Type[],
), "sumProjection")
}
Note
I think it is important to note that in both the formula and the sql projection, use the column names in the database and your database specific sum syntax.
As of Grails 2.2, SQL projections are supported without having to drop down to the Hibernate Criteria API. Note that a formula mapping may still be more desirable, but with this you can directly implement the sum('soldPrice * soldQuantity') style projection as per your question.
http://grails.org/doc/latest/guide/single.html#criteria
I'd try to add a transient derived property total to OrderItem and use sum() on it.
Try SQL Projection
projections {
sqlProjection 'sum("soldPrice * soldQuantity") as total', 'total', StandardBasicTypes.DOUBLE
}
For farther details
http://docs.grails.org/2.5.6/guide/GORM.html#criteria

Grails additional columns in table or list

I'm trying for several days to receive a list from my Data. The Domain looks like this:
class Alpha {
String a
String b
etc.
static hasMany = [beta:Beta]
}
class Beta {
String a
Integer foo
String status
static belongsTo = [alpha:Alpha]
static constraints = {
status(nullable:false, inList:["val1","val2","val3", "val4"])
}
}
I'd like to have in Alpha the sum of all Beta.foo and of all Beta.foo in a certain status. Best would be something like an additional row ( Integer sumVal1 ... ).
I tried named queries:
static namedQueries = {
erledigterProbeAufwend {
createAlias ('Beta', 'b')
eq ('b.status', 'val1')
projections {
groupProperty('b.alpha')
sum('b.foo', 'sumFooVal1')
}
}
}
But this just give me one sum at a time.
I'm looking forward to get some help on that.
Greetings
Bas
This could be calculated formula field, but with a subquery trick:
static mapping = {
betaCount formula: "(SELECT count(*) FROM Beta b WHERE b.alpha_id = id and b.status in('a', 'b'))"
}
Create transient variables in your Alpha class and populate them in an onLoad event.
class Alpha {
String a
String b
etc.
static transients = ["sumVal1",...]
static hasMany = [beta:Beta]
def onLoad = {
sumVal1 = ....
}
}

How to do multiple Group By's in linq to sql?

how can you do multiple "group by's" in linq to sql?
Can you please show me in both linq query syntax and linq method syntax.
Thanks
Edit.
I am talking about multiple parameters say grouping by "sex" and "age".
Also I forgot to mention how would I say add up all the ages before I group them.
If i had this example how would I do this
Table Product
ProductId
ProductName
ProductQty
ProductPrice
Now imagine for whatever reason I had tons of rows each with the same ProductName, different ProductQty and ProductPrice.
How would I groupt hem up by Product Name and add together ProductQty and ProductPrice?
I know in this example it probably makes no sense why there would row after row with the same product name but in my database it makes sense(it is not products).
To group by multiple properties, you need to create a new object to group by:
var groupedResult = from person in db.People
group by new { person.Sex, person.Age } into personGroup
select new
{
personGroup.Key.Sex,
personGroup.Key.Age,
NumberInGroup = personGroup.Count()
}
Apologies, I didn't see your final edit. I may be misunderstanding, but if you sum the age, you can't group by it. You could group by sex, sum or average the age...but you couldn't group by sex and summed age at the same time in a single statement. It might be possible to use a nested LINQ query to get the summed or average age for any given sex...bit more complex though.
EDIT:
To solve your specific problem, it should be pretty simple and straightforward. You are grouping only by name, so the rest is elementary (example updated with service and concrete dto type):
class ProductInventoryInfo
{
public string Name { get; set; }
public decimal Total { get; set; }
}
class ProductService: IProductService
{
public IList<ProductInventoryInfo> GetProductInventory()
{
// ...
var groupedResult = from product in db.Products
group by product.ProductName into productGroup
select new ProductInventoryInfo
{
Name = productGroup.Key,
Total = productGroup.Sum(p => p.ProductCost * p.ProductQty)
}
return groupedResult.ToList();
}
}

Resources