Not able to save objects in Grails - grails

I am developing one application in grails. I have following kind of mapping. Now I am saving object of DemoD class but its not saving values neither showing me any error while save. I have printed all created object and all looks fine. but still I am now able to save records.
class DemoS {
String firstName
String lastName
Long rollNumber
String address1
String address2
String city
String state
static constraints = {
address2 nullable:true
}
static hasMany = [demoAList: DemoA]
}
class DemoD {
Date date
static hasMany = [demoAList: DemoA]
def beforeInsert = {
date = new Date()
}
}
class DemoA {
Long id
Boolean absent
Boolean halfday
String notes
Date date
static belongsTo = [demoS:DemoS, demoD:DemoD]
static constraints = {
notes nullable: true
}
}
class UploadDataService {
def saveUploadedData(def dataList) {
def i = 0
DemoD ddObj = new DemoD()
//Getting this dataList from excel and now creating object for each row.
dataList?.each{ rowList ->
if(i != 0){
def dsObj = DemoS.get(rowList[0]?.longValue())
DemoA daObj = new DemoA([id:rowList[0]?.longValue(),absent:rowList[1],halfday:rowList[2],notes:rowList[3] ? rowList[3] : ''])
dsObj.addToDemoAList(daObj)
daObj.demoS = dsObj
ddObj.addToDemoAList(daObj)
daObj.demoD = ddObj
}
i++
}
ddObj.save(saveOnError: true)
}
}

Related

grails multiple table criteria

My application works for everything except the call to display members of different boards. I can get the correct output in the db with an SQL query but having issues trying it in Grails using createCriteria.
Have to use Oracle 11g as my DB.
Grails 2.3.3
both the DB and Grails are local.
Here are my domains
class Trustee {
String salutation
String firstName
String middleName
String lastName
static hasMany = [board:Boards, membership:TrusteeMembership]
static constraints = {
salutation nullable: true
firstName nullable: true
middleName nullable: true
lastName nullable: true
}
//map to the existing DB table
static mapping = {
table 'BOT_TRUSTEE'
id column:'TRUSTEE_ID'
salutation column: 'SALUTATION'
firstName column: 'FIRST_NAME'
middleName column: 'MIDDLE_INITIAL'
lastName column: 'LAST_NAME'
version false
}
}
class Boards {
String boardName
static belongsTo = [trustee:Trustee, hospital:Hospitals]
static constraints = {
boardName nullable:true
}
static mapping = {
table name:"BOT_BOARD"
id column:'BOARD_ID'
trustee column:'TRUSTEE_ID'
hospital column:'HOSPITAL_ID'
boardName column:'BOARD'
version false
}
}
class Hospitals {
String hospitalName
static hasMany = [committees:Committees, board:Boards]
static constraints = {
hospitalName nullable:true
}
static mapping = {
table 'BOT_HOSPITAL'
id column:'HOSPITAL_ID'
hospitalName column:'HOSPITAL'
version false
}
}
class Committees {
String committeeName
String description
static belongsTo = [hospital: Hospitals]
static hasMany = [membership:TrusteeMembership]
static constraints = {
committeeName nullable:true
description nullable:true
}
static mapping = {
table 'BOT_COMMITTEE'
id column:'COMMITTEE_ID'
hospital column:'HOSPITAL_ID'
committeeName column:'COMMITTEE'
description column:'DESCRIPTION'
version false
}
}
class TrusteeMembership implements Serializable{
String position
String type
static belongsTo = [trustee:Trustee, committees:Committees]//
static constraints = {
position nullable:true
type nullable:true
}
static mapping = {
table 'BOT_TRUSTEE_COMMITTEES'
version false
id composite: ['trustee','committees']
trustee column:'TRUSTEE_ID'
committees column: 'COMMITTEE_ID'
position column:'POSITION'
type column:'TYPE'
}
Here is my controller
def members(){
def letter = params.letter
def commId = params.committee
params.max = Math.min(params.max ? params.int('max'): 15, 100)
def indexSearch = Trustee.createCriteria().list(params){
//search by First letter of lastName
if(letter != null){
ilike("lastName", "${letter}%")
}
//search by lastName
if(params.lastName){
ilike("lastName", "%${params.lastName}%")
}
//search by firstName
if(params.firstName){
ilike("firstName", "%${params.firstName}%")
}
//search by boardName
if(params.boardId){
//display only members within a board id
board{
eq("id", "%${params.boardId}%")
}
}
order("lastName", "asc")
}
respond Hospitals.list(params), model:[hospitalsInstanceCount: Hospitals.count(),
trusteeInstanceList : indexSearch]
}
//search by boardName
if(params.boardId){
//display only members with the boardName
board{
eq("id", params.long('boardId'))
}
}
I ended up with this for the correct result.

Grails domain class transient collection attribute setter issue

I am trying to set (or bind) value to a transient List attribute. But I failed with collections.
On the other hand transient String attribute working well on setter.
Grails version 2.4.3
Any advice?
#Resource(uri = "/api/samples", formats = ["json"])
class Sample {
static transients = ["fields","sample"]
String regions
String name
String sample
List<String> fields
List<String> getFields() {
this.regions != null ? Arrays.asList(regions.split("\\s*,\\s*")) : new ArrayList<String>();
}
void setFields(List<String> fields) {
if (fields != null && !fields.isEmpty()) {
this.regions = fields.join(",")
}
}
void setSample(String sample){
this.name = sample
}
static mapping = {
}
}
Untyped fields are transient by default, so this alternative approach should work (and is a lot more concise):
#Resource(uri = "/api/samples", formats = ["json"])
class Sample {
static transients = ["sample"]
String regions
String name
String sample
def getFields() {
this.regions != null ? Arrays.asList(regions.split("\\s*,\\s*")) : []
}
void setFields(def fieldList) {
if (fieldList) {
this.regions = fieldList.join(",")
}
}
void setSample(String sample){
this.name = sample
}
static mapping = {
}
}

uCommerce - add dynamic property to order line

I have hit a problem building a uCommerce site based on top of the demo razor store available http://thesitedoctor.co.uk/portfolio/avenue-clothingcom/
The demo uses servicestack and the ucommerceapi for its basket functions.
I am trying to add a dynamic property to the basket (on an order line) at the point where the user clicks buy. I traced through the productpage.js file and amended the code to add a new property ('message'):
function (data) {
var variant = data.Variant;
$.uCommerce.addToBasket(
{
sku: variant.Sku,
variantSku: variant.VariantSku,
quantity: qty,
message: $('#personalisedMessage').val()
},
function () {
updateCartTotals(addToCartButton);
}
);
});
using firebug, i checked the data that is being posted
addToExistingLine: true
message: "this is a message"
quantity:"1"
sku: "Product (options: none)"
variantSku:""
Posting this does not cause an error, but I cannot tell if it has worked either - I cannot find it in the database, assuming that it would be stored in OrderProperty table. In this scenario, I am 'buying' a product with no variations.
Any help is greatly appreciated with this.
Out of the box you can't add order/line item properties via the API like that. The API payload that you've added to is specified although valid JSON won't get interpreted/used by the API.
Instead what you'll need to do is add your own method to the API. To do this you'll need to implement a service from IUCommerceApiService and then you can do what you need. I've created an example (untested) below and will get it added to the demo store as I think it's a useful bit of functionality to have.
public class AddOrderLineProperty
{
public int? OrderLineId { get; set; }
public string Sku { get; set; }
public string VariantSku { get; set; }
public string Key { get; set; }
public string Value { get; set; }
}
public class AddOrderLinePropertyResponse : IHasResponseStatus
{
public AddOrderLinePropertyResponse() { }
public AddOrderLinePropertyResponse(UCommerce.EntitiesV2.OrderLine line)
{
if (line == null)
{
UpdatedLine = new LineItem();
return;
}
var currency = SiteContext.Current.CatalogContext.CurrentCatalog.PriceGroup.Currency;
var lineTotal = new Money(line.Total.Value, currency);
UpdatedLine = new LineItem()
{
OrderLineId = line.OrderLineId,
Quantity = line.Quantity,
Sku = line.Sku,
VariantSku = line.VariantSku,
Price = line.Price,
ProductName = line.ProductName,
Total = line.Total,
FormattedTotal = lineTotal.ToString(),
UnitDiscount = line.UnitDiscount,
VAT = line.VAT,
VATRate = line.VATRate
};
}
public ResponseStatus ResponseStatus { get; set; }
public LineItem UpdatedLine { get; set; }
}
public class AddOrderLinePropertyService : ServiceBase<AddOrderLineProperty>, IUCommerceApiService
{
protected override object Run(AddOrderLineProperty request)
{
var orderLineId = request.OrderLineId;
var sku = request.Sku;
var variantSku = request.VariantSku;
var orderLine = findOrderLine(orderLineId, sku, variantSku);
addPropertyToOrderLine(orderLine, request.Key, request.Value);
TransactionLibrary.ExecuteBasketPipeline();
var newLine = findOrderLine(orderLineId, sku, variantSku);
return new AddOrderLinePropertyResponse(newLine);
}
private void addPropertyToOrderLine(OrderLine orderLine, string key, string value)
{
if (orderLine == null)
return;
orderLine[key] = value;
orderLine.Save();
}
private static OrderLine findOrderLine(int? orderLineId, string sku, string variantSku)
{
return orderLineId.HasValue
? getOrderLineByOrderLineId(orderLineId)
: getOrderLineBySku(sku, variantSku);
}
private static OrderLine getOrderLineBySku(string sku, string variantSku)
{
return String.IsNullOrWhiteSpace(variantSku)
? getOrderLines().FirstOrDefault(l => (l.Sku == sku))
: getOrderLines().FirstOrDefault(l => (l.Sku == sku && l.VariantSku == variantSku));
}
private static OrderLine getOrderLineByOrderLineId(int? orderLineId)
{
return getOrderLines().FirstOrDefault(l => l.OrderLineId == orderLineId);
}
private static ICollection<OrderLine> getOrderLines()
{
return TransactionLibrary.GetBasket().PurchaseOrder.OrderLines;
}
}
You'll need to add the new method to uCommerce.jQuery.js as well something like this:
addOrderLineProperty: function (options, onSuccess, onError) {
var defaults = {
orderLineId: 0
};
var extendedOptions = $.extend(defaults, options);
callServiceStack({ AddOrderLineProperty: extendedOptions }, onSuccess, onError);
}
Let me know if you have any issues using it.
Tim

Creating a list from ENUM into Model

I got the following model piece of code:
public enum EnumTest
{
[Description ("Enum Text 1")]
Value_1 = 1,
[Description ("Enum Text 2")]
Value_2 = 2,
}
public List<Fields> listFields = new List<Fields>();
public class Fields
{
public int Code { get; set;}
public string Description { get; set;}
}
I got an Enum and I would like to fill my variable CODE with enum value and the variable Description with the same enum description. I looked up a long time and failed to initialize my "ListFields" into its constructor with the enum VALUE/DESCRIPTION.
I already got the enum and the method to get its description.. I found it usefull, so I'll leave it here, maybe it can be useful for someone..
public static string GetDescription(this Enum value)
{
return (from m in value.GetType().GetMember(value.ToString())
let attr =(DescriptionAttribute)m.GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault()
select attr == null ? value.ToString() : attr.Description).FirstOrDefault();
}
To use this you just need to do something like this:
String xx = Enum.EnumName.GetDescription();
You have to use reflection.
public static Fields[] GetEnumFields(Type enumType)
{
if (enumType == null)
throw new ArgumentNullException("enumType");
if (!enumType.IsEnum)
throw new ArgumentException("Not an enum");
FieldInfo[] fieldInfos = enumType.GetFields(BindingFlags.Static | BindingFlags.Public);
Fields[] result = new Fields[fieldInfos.Length];
for (int i = 0; i < fieldInfos.Length; ++i)
{
FieldInfo field = fieldInfos[i];
int value = (int)field.GetValue(null);
DescriptionAttribute attrib = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
string desc = attrib != null ? attrib.Description : field.Name;
result[i] = new Fields(value, desc);
}
return result;
}
public class Fields
{
private int value;
private string description;
public int Value
{
get { return this.value; }
}
public string Description
{
get { return this.description; }
}
public Fields(int value, string description)
{
this.value = value;
this.description = description;
}
}
To use it is quite simple:
enum test
{
[Description("hello!")]
ciao,
www
}
static void Main(string[] args)
{
foreach (Fields f in GetEnumFields(typeof(test)))
{
Console.WriteLine(f.Description);
}
}
In my implementation when a descriptionattribute is not found, field name is used.
We must also say that reflection can be slow and rebuilding the entire array when you need it is a waste of time, if you need it often.
You can store the array somewhere so you can compute it only once and keep it cached.
This of course and as I said, makes sense only if you need this readonly list very often.

How to get list of customers, jobs, and employeers using Quickbooks QBFC (8.0 SDK)

I have been given the painful task of writing a C# application to sync up employee time entries in a separate database with Quickbooks. Since I'm brand new to QB programming, I'm trying to peform basic tasks, such as getting a list of customers, then jobs for each customer, then employees. I've been reading the SDK documentation, but I'm still a little fuzzy on the details because the examples I'm finding are a little too advanced for me at the moment :-P
To keep things simple, I would like to ask for a code snippet that gives me the list of customers for starters. Here's the code I've got:
QBSessionManager SessionManager = new QBSessionManager();
IMsgSetRequest customerSet = SessionManager.CreateMsgSetRequest("US", 8, 0);
//
// Code to get list of customers here.
//
SessionManager.OpenConnection2("", "New App", ENConnectionType.ctLocalQBD);
SessionManager.BeginSession(string.Empty, ENOpenMode.omDontCare);
IMsgSetResponse Resp = SessionManager.DoRequests(customerSet);
MessageBox.Show(Resp.ToXMLString());
SessionManager.EndSession();
SessionManager.CloseConnection();
Can anyone fill in the "code to get list of customers here" for me? Thank you very much in advance!
Victor
customers.IncludeRetElementList.Add("IsActive");
customers.IncludeRetElementList.Add("ListID");
customers.IncludeRetElementList.Add("EditSequence");
customers.IncludeRetElementList.Add("Name");
customers.IncludeRetElementList.Add("ParentRef");
Only the fields specified in the above list will be returned from QuickBooks - it is very important to use the correct strings in the correct case - no error messages will result if something is wrong. You cannot specify sub-fields (eg, City within an Address block; you must get the entire Address block). For custom fields, you also must specify the OwnerID (use 0 for custom fields that are not private to an application)
customers.IncludeRetElementList.Add("DataExtRet"); //will return non-private and/or private data extension fields depending on the OwnerIDList, below
customers.OwnerIDList.Add("0"); // required for non-private data extn fields
customers.OwnerIDList.Add("Your Appln GUID"); // Use this to get private data extns for the Appln identified by the GUID
Ok, seems like I found the missing piece:
ICustomerQuery customers = customerSet.AppendCustomerQueryRq();
This produces all the data related to each customer, which is a step forward. Parsing the XML for customers should be pretty straightforward, but parsing the individual tasks/jobs for each customer will be laborious, because there are no subnodes for each task - basically you get repeating chunks of XML with all the basic customer info (address, billing address, shipping address, etc.), then this one property called "FullName" which appends a colon to the customer name, followed by the task title (which itself can be followed by another colon with a subtask title, etc.). I'm wondering if there's something clever I can do with the request query to get a better xml response (for instance, specify what properties I want returned, and maybe enforce the creation of subnodes for each task for a given customer)...comments are appreciated.
Adding to Victors, Chili and Hassan's answer. Glad to have stumbled on this question as I myself was struggling with the QBFC examples.
Here is a full set of code that might just help someone down the road. If in the meantime someone could just point me in the direction of some useful documentation...that would be great.
Getting the Employee data to an XML string
public static string EmployeeListXML()
{
QBSessionManager SessionManager = new QBSessionManager();
IMsgSetRequest msgSetReq = SessionManager.CreateMsgSetRequest("US", 8, 0);
IEmployeeQuery employee = msgSetReq.AppendEmployeeQueryRq();
employee.IncludeRetElementList.Add("IsActive");
employee.IncludeRetElementList.Add("ListID");
employee.IncludeRetElementList.Add("EditSequence");
employee.IncludeRetElementList.Add("FirstName");
employee.IncludeRetElementList.Add("LastName");
employee.IncludeRetElementList.Add("SSN");
//employee.IncludeRetElementList.Add("ParentRef");
//employee.IncludeRetElementList.Add("DataExtRet"); //will return non-private and/or private data extension fields depending on the OwnerIDList, below
employee.OwnerIDList.Add("0"); // required for non-private data extn fields
//customers.OwnerIDList.Add("Your Appln GUID"); // Use this to get private data extns for the Appln identified by the GUID
SessionManager.OpenConnection2("", Application.ProductName, ENConnectionType.ctLocalQBD);
//SessionManager.BeginSession(string.Empty, ENOpenMode.omDontCare);
SessionManager.BeginSession(frmMain.QBFileName, ENOpenMode.omDontCare); // I have the filename on frmMain
IMsgSetResponse Resp = SessionManager.DoRequests(msgSetReq);
SessionManager.EndSession();
SessionManager.CloseConnection();
//MessageBox.Show(Resp.ToXMLString());
return Resp.ToXMLString();
}
Putting the XML string into a List of Emplpoyee Objects
public static List<Employee> EmployeeXMLtoList()
{
string sXML = EmployeeListXML();
List<Employee> lstEmp = new List<Employee>();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(sXML);
XmlNodeList parentNode = xmlDoc.GetElementsByTagName("EmployeeRet");
foreach (XmlNode childNode in parentNode)
{
Employee oEmp = new Employee();
oEmp.ListID = childNode.SelectSingleNode("ListID").InnerText;
oEmp.EditSequence = childNode.SelectSingleNode("EditSequence").InnerText;
oEmp.Active = childNode.SelectSingleNode("IsActive").InnerText;
oEmp.FirstName = childNode.SelectSingleNode("FirstName").InnerText;
oEmp.LastName = childNode.SelectSingleNode("LastName").InnerText;
oEmp.SSN = childNode.SelectSingleNode("SSN").InnerText;
lstEmp.Add(oEmp);
}
return lstEmp;
}
Function that return an Employee Object using Linq
public static Employee GetEmployeeObject(string sSSN)
{
Employee oReturn = null;
List<Employee> lstEmployee = EmployeeXMLtoList();
IEnumerable<Employee> lstEmps = from oEmp in lstEmployee
where oEmp.SSN == sSSN
select oEmp;
foreach (var oEmp in lstEmps)
{
oReturn = oEmp;
}
return oReturn;
}
Example of Code
Employee oEmployee = QB.GetEmployeeObject("112-35-8560");
Employee Class
public class Employee
{
private string sEmployeeID;
private string sSSN;
private string sLastName;
private string sFirstName;
private string sAddress1;
private string sAddress2;
private string sCity;
private string sState;
private string sZipCode;
private string sGender;
private string sEthnicity;
private DateTime dDOB;
private string sMaritalStatus;
private int iDependants;
private string sUScitizen;
private decimal iPayRate;
private string sPhone;
private DateTime dHireDate;
private string sEmail;
public Employee() { }
public string EmployeeID
{
get { return sEmployeeID; }
set { sEmployeeID = value; }
}
public string ListID
{
get; set;
}
public string EditSequence
{
get; set;
}
public string Active
{
get; set;
}
public string SSN
{
get { return sSSN; }
set { sSSN = value; }
}
public string LastName
{
get { return sLastName; }
set { sLastName = value; }
}
public string FirstName
{
get { return sFirstName; }
set { sFirstName = value; }
}
public string FullName
{
get { return FirstName + " " + LastName; }
set { }
}
public string Address1
{
get { return sAddress1; }
set { sAddress1 = value; }
}
public string Address2
{
get { return sAddress2; }
set { sAddress2 = value; }
}
public string State
{
get { return sState; }
set { sState = value; }
}
public string City
{
get { return sCity; }
set { sCity = value; }
}
public string ZipCode
{
get { return sZipCode; }
set { sZipCode = value; }
}
public string Gender
{
get { return sGender; }
set { sGender = value; }
}
public string Ethnicity
{
get { return sEthnicity; }
set { sEthnicity = value; }
}
public DateTime DOB
{
get { return dDOB; }
set { dDOB = value; }
}
public string MaritalStatus
{
get { return sMaritalStatus; }
set { sMaritalStatus = value; }
}
public int Dependants
{
get { return iDependants; }
set { iDependants = value; }
}
public string UScitizen
{
get { return sUScitizen; }
set { sUScitizen = value; }
}
public decimal PayRate
{
get { return iPayRate; }
set { iPayRate = value; }
}
public DateTime HireDate
{
get { return dHireDate; }
set { dHireDate = value; }
}
public string Phone
{
get { return sPhone; }
set { sPhone = value; }
}
public string Email
{
get { return sEmail; }
set { sEmail = value; }
}
}

Resources