I have the following command object
class SaleDetailCommand implements Serializable {
Item item
Presentation presentation
String measure
Integer quantity
BigDecimal total
static constraints = {
importFrom SaleDetail
}
def beforeValidate() {
total = item.sellingPrice * quantity
}
}
in the above command object I am trying to calc total just before command object is validated, but beforeValidate is not call it when i try this code from controller
if (command.hasErrors()) {
command.errors.allErrors.each { error ->
log.error "[$error.field: $error.defaultMessage]"
}
return error()
}
I get this message in console
Error 2014-09-23 08:06:26,585 [http-bio-8080-exec-8] ERROR builder.ActionDelegate - [total: Property [{0}] of class [{1}] cannot be null]
I also tried !command.validate
Which is solution to perform this task?
thanks for your time!
Related
Grails 2.3.7, Java 1.7, tomcat
For no apparent reason(that I can see) the reviewResults property of the Review domain sometimes saves as the ordinal value of the enum.
The database schema says that the column is a varchar type.
Sometimes NA is saved as NA, however, sometimes it is saved as 0.
This is the same with passed, except passed is saved as 1 sometimes.
Any ideas why this might be happening?
abstract class Work {
// Nothing defined in here related
// to the review domain enum.
}
The Domain class in question.
class Review extends Work {
Results reviewResults
String notes
enum Results {
NA,
Passed,
Error
}
static constraints = {
reviewResults(nullable: true, enumType: 'string')
}
// Is this redundant if it is already declared in the constraints?
static mapping = {
reviewResults enumType: 'string'
}
}
The Domains related controller.
// Reviews created with Quartz job, results property is not set.
class ReviewController {
def reviewService
def show(Long id) {
def reviewInstance = Review.get(id)
def reviewResultsOptions = []
reviewResultsOptions.addAll(com.mycompany.app.Review.Results.values())
[reviewInstance: reviewInstance, reviewResultsOptions: reviewResultsOptions]
}
def closeWork(Long id, String reviewResults, String notes) {
def review = Review.get(id)
review.reviewResults = Review.Results.valueOf(reviewResults)
def result = reviewService.closeReview(review, notes)
}
}
The service for the controller/domain.
class ReviewService {
def workService
Review closeReview(Review work, String notes) {
work.notes = notes
workService.closeWork(work)
return work.errors.allErrors.empty ? work : null
}
}
The service where the Review object is finally saved.
class WorkService {
Tracking closeWork(Work workInstance) {
def tracked = new Tracking()
workInstance.setStatus(status)
workIntance.setClosed(new Date())
WorkInstance.save(flush: true)
// Set some tracking properties and save and return the tracking object.
}
}
Hi and since now thanks
In a Domain class I want to change a boolean property based on a condition using beforeInsert event, but boolean property is not affected. Here is the domain class:
class Pet {
String name
String type
Boolean status = true
static constraints = {
name blank:false
type inList:["Dog", "Cat"]
}
def beforeInsert() {
status = (type == "Dog") ? true : false
}
String toString() { name }
}
I try to create a some test data in bootstrap.groovy
class BootStrap {
def init = { servletContext ->
def nami = new Pet(name:"nami", type:"Dog")
if (!nami.save()) {
nami.errors.allErrors.each { error ->
log.error "[$error.field: $error.defaultMessage]"
}
}
def hotch = new Pet(name:"hotch", type:"Cat")
if (!hotch.save()) {
hotch.errors.allErrors.each { error ->
log.error "[$error.field: $error.defaultMessage]"
}
}
}
}
After grails run-app I get the following error message in console where i get the message that property status can not be null
| Error 2014-10-07 13:27:28,281 [localhost-startStop-1] ERROR conf.BootStrap - [status: Property [{0}] of class [{1}] cannot be null]
| Error 2014-10-07 13:27:28,314 [localhost-startStop-1] ERROR conf.BootStrap - [status: Property [{0}] of class [{1}] cannot be null]
I tried with no Boolean properties and beforeInsert is working well, I even create another project in order to replicate the scenario and same behavior.
What I am missing, i am using grails 2.3.8
Thanks
By definition beforeInsert will cancel the operation if you return false at the end.
beforeInsert - Executed before an object is initially persisted to the database.
If you return false, the insert will be cancelled.
Since your beforeInsert method has only one line and it is setting the status to true or false, groovy will return that boolean value. If that happens to be false, it will cancel your save. You might want to return true or something other than false to avoid cancellation.
def beforeInsert() {
status = (type == "Dog")
true
}
I'm trying to use the Grails shopping cart plugin found here: http://grails.org/plugin/shopping-cart
I was able to successfully install the plugin in my application, as well as inject the service in my Controller:
class TestController {
def shoppingCartService
def index() {
def s = new DomainObj(name: "A Plain Ole Domain Object")
s.addToShoppingCart()
}
}
This appears to be adding the product to my shopping cart, as I expected. However, the problem I'm encountering now is actually listing the items out from the cart. According to the debugger, after running the above code, the shopping cart does indeed have an item (s) in it, as it returns:
com.metasieve.shoppingcart.ShoppingItem : 1
The item is properly being added to the cart, but now I would like to actually list the name of the item out again, so in this case, I want to display the name A Plain Ole Domain Object. How do I do this?
I'm unsure of the syntax for getting the actual objects back from the cart. The documentation doesn't describe how to do this clearly, as it merely states that the following should work:
def checkedOutItems = shoppingCartService.checkOut()
checkedOutItems.each {
println it['item']
println it['qty']
}
But that outputs
com.metasieve.shoppingcart.ShoppingItem : 1 , which is only a reference to some arbitrary item in the cart. I want to get back the actual name of my item.
Thanks in advance.
EDIT:
My domain class (DomainObj) is defined as follows:
class DomainObj extends com.metasieve.shoppingcart.Shoppable {
String name
static constraints = {
name blank: false
}
}
EDIT #2:
def index() {
def s = new DomainObj(name: "A Plain Ole Domain Object")
s.addToShoppingCart()
def r = new DomainObj(name: "Second Plain Ole Domain Object")
r.addToShoppingCart()
def checkedOutItems = shoppingCartService.checkOut()
println currentItems
println "-----"
checkedOutItems.each {
println it['item']
println it['qty']
}
}
The output of this is:
[com.metasieve.shoppingcart.ShoppingItem : 1, com.metasieve.shoppingcart.ShoppingItem : 2]
com.metasieve.shoppingcart.ShoppingItem : 2
1
com.metasieve.shoppingcart.ShoppingItem : 1
1
According to the documentation it["item"] gives you back the entity of a domain class that extends Shoppable. So in this case when you are printing it out it's calling the toString() method of that domain class. If you want that to return the value of the name property you need to implement your own toString(). Here is such an example
#Override
String toString() {
return name
}
EDIT:
Well as it's not clear from the documentation it['item'] is a pointer to the Shoppable instance which you can then use to query for the actual product in your cart like this:
com.metasieve.shoppingcart.Shoppable.findByShoppingItem(it['item'])
Thus the following will print out the toString() value of your products
checkedOutItems.each {
println com.metasieve.shoppingcart.Shoppable.findByShoppingItem(it['item'])
println it['qty']
}
For testing I created the following domain and controller.
Domain:
package com.test
class MyProduct extends com.metasieve.shoppingcart.Shoppable {
String name
static constraints = {
name(blank: false)
}
#Override
String toString() {
return name
}
}
Controller:
package com.test
class MyProductController {
def shoppingCartService
def index() {
def p1 = new MyProduct(name: 'one')
p1.save(flush: true, failOnError: true)
p1.addToShoppingCart()
def p2 = new MyProduct(name: 'two')
p2.save(flush: true, failOnError: true)
p2.addToShoppingCart()
def checkedOutItems = shoppingCartService.checkOut()
checkedOutItems.each {
println com.metasieve.shoppingcart.Shoppable.findByShoppingItem(it['item'])
println it['qty']
}
}
}
I want to get the values of the enum property.
In activiti 5.13 userguide,
the enumeration values are accessible with formProperty.getType().getInformation("values")
In activiti docs,return type of getType() is FormType. But in my code getType() return type is String. So i couldn't call FormType's getInformation() method.
When i am using formProperty.getType().getInformation("values"), i got the following error.
Cannot cast object 'enum' with class 'java.lang.String' to class 'org.activiti.engine.form.FormType'.
How could i get the values of enum?
<userTask id="handleRequest" name="Handle vacation request" activiti:candidateGroups="management">
<documentation>${employeeName} would like to take ${numberOfDays} day(s) of vacation (Motivation: ${vacationMotivation}).</documentation>
<extensionElements>
<activiti:formProperty id="vacationApproved" name="Do you approve this vacation" type="enum" required="true">
<activiti:value id="true" name="Approve"></activiti:value>
<activiti:value id="false" name="Reject"></activiti:value>
</activiti:formProperty>
<activiti:formProperty id="managerMotivation" name="Motivation" type="string"></activiti:formProperty>
</extensionElements>
</userTask>
Consider above user Task and You can do like this
//passing Task Id and Process definition Id
def getFormForTask(taskId,pdId) {
RepositoryService repositoryService =processEngine.getRepositoryService()
// getting model
BpmnModel model = repositoryService.getBpmnModel(pdId);
// getting list process from model including tasks
List<Process> processes = model.getProcesses()
List<FormProperty> taskFormPropertyList =[]
for(Process proc : processes) {
for(Object obj : proc.getFlowElements()) {
// need form Property only for User Task
if(obj instanceof UserTask) {
UserTask userTask = (UserTask)obj
if(userTask.getId() == taskId){
// getting list of Form Property from task that matches taskId
taskFormPropertyList = userTask.getFormProperties()
}
}
}
}
// loop through from Property
taskFormPropertyList.each {
// getFormValues() returns Property values for the form Property (like enum)
def fvlist = it.getFormValues()
fvlist.each {
// prints id, in this case true and false
println it.getId()
// prints name, in this case Approve and Reject
println it.getName()
}
}
}
I have a Command Object as follows :
class TestCreationCommand {
String title
List testItems = [].withLazyDefault {new VocabQuestion()}
static constraints = {
title(blank:false,maxLength:150)
testItems( validator: { ti ->
ti.each {it.validate()}
} )
}
}
Test Items is a list of VocabQuestion objects. VocabQuestion is as follows :
class VocabQuestion {
static constraints = {
question(blank:false,maxLength:150)
answer(blank:false,maxLength:40)
}
static belongsTo = [vocabularyTest: VocabularyTest]
String question
String answer
}
I'm attempting to validate the constraints on the VocabQuestion using a custom vaildator ( in the constraints of the Command class above ), but I keep getting the following error message.
Return value from validation closure [validator] of property [testItems] of class [class vocabularytest.TestCreationCommand] is returning a list but the first element must be a string containing the error message code
I have had many different attempts at this .....
I am not sure what the message is telling me or how to go about debugging what the return value from the closure is.
Can anyone provide me any pointers?
You are not returning what Grails understands. You can't expect to just return anything and have Grails know what to do with it. Return a boolean or an error string.
static constraints = {
title(blank:false,maxLength:150)
testItems( validator: { ti ->
Boolean errorExists = false
ti.each {
if (!it.validate()) {
errorExists = true
}
}
errorExists
})
}
Check out this SO question It might be the format of the validator you need.
The .every will return a boolean.