/// <summary> /// Execute Add command in OpenErp with context params. /// /// Exclude id property because OpenErp will return it after creation. /// </summary> /// <param name="context"></param> /// <returns></returns> private int AddCommand(OdooCommandContext context) { int res; _context.UserId = Login(); XmlRpcStruct fields = new XmlRpcStruct(); foreach (OdooCommandArgument argument in context.Arguments) { if (!argument.ReadOnly) { if (!argument.Property.Equals("id")) { fields.Add(argument.Property, argument.Value); } } } try { res = _context.OdooData.Create(_context.Database, _context.UserId, _context.Password, context.EntityName, "create", fields); } catch (XmlRpcFaultException e) { throw OdooException.GetException(e); } return(res); }
private void UpdateCommand(OdooCommandContext context) { _context.UserId = Login(); var idArray = new int[1]; //Transformamos los argumentos en XmlRpcStruct var fields = new XmlRpcStruct(); foreach (var argument in context.Arguments) { if (!argument.Property.Equals("id")) { if (argument.Value != null) { fields.Add(argument.Property, argument.Value); } } else { if (argument.Value != null) { idArray[0] = (int)argument.Value; } } } try { _context.OdooData.Write(_context.Database, _context.UserId, _context.Password, context.EntityName, "write", idArray, fields); } catch (XmlRpcFaultException e) { throw OdooException.GetException(e); } }
/// <summary> /// Update OpenErp entity with current entity values /// </summary> /// <typeparam name="T"></typeparam> /// <param name="entity"></param> internal int UpdateEntity <T>(T entity) where T : IOdooObject { OdooCommandContext context = OdooCommandContextFactory.BuildCommandContextFromEntity <T>(entity); UpdateCommand(context); return(entity.Id); }
private static void SetProperty(Expression expression, OdooCommandContext context, OdooCommandArgument argument) { if (expression == null) { return; } argument.Property = string.Empty; switch (expression.NodeType) { case ExpressionType.Call: MethodCallExpression methodCall = expression as MethodCallExpression; SetProperty(methodCall.Object, context, argument); if (string.IsNullOrEmpty(argument.Property)) { foreach (Expression item in methodCall.Arguments) { SetProperty(item, context, argument); } } break; case ExpressionType.MemberAccess: MemberExpression memberAccess = expression as MemberExpression; if (memberAccess.Expression is ParameterExpression) { if ((memberAccess.Expression as ParameterExpression).Name.Equals(context.ParameterName)) { argument.Property = GetOdooPropertyName(memberAccess as MemberExpression); argument.ArgumentType = GetOdooPropertyType(memberAccess as MemberExpression); } } else { } break; case ExpressionType.Constant: argument.Property = (expression as ConstantExpression).Value.ToString(); break; default: if (expression is BinaryExpression) { BinaryExpression binary = expression as BinaryExpression; SetProperty(binary.Left, context, argument); if (string.IsNullOrEmpty(argument.Property)) { SetProperty(binary.Right, context, argument); } } break; } }
/// <summary> /// Executes delete command in OpenErp. Get id from context. /// </summary> /// <param name="context"></param> private void DeleteCommand(OdooCommandContext context) { _context.UserId = Login(); OdooCommandArgument idArgument = context.Arguments.FirstOrDefault(x => x.Property.Equals("id")); if (idArgument != null) { DeleteCommand((int)idArgument.Value, context.EntityName); } }
private static void ProcessMemberAccess(Expression expression, OdooCommandContext context, int counter) { if (expression.Type == typeof(bool)) { var argument = new OdooCommandArgument(); argument.Order = counter; argument.Value = expression.NodeType != ExpressionType.Not; argument.Operation = "="; SetProperty(expression, context, argument); context.Arguments.Add(argument); } }
/// <summary> /// Gets an entity from openerp. Reads openerpmap attribute for underlaying property type and /// gets from openerp. /// </summary> /// <param name="property">Property info</param> /// <param name="id">Id of entity to search</param> /// <returns>Entity object</returns> internal object GetEntityById(OdooCommandContext context, int id) { ResultSet resultset; resultset = GetEntityCommand(context, new object[] { id }); //Call a BuildEntities genereci method from this class MethodInfo method = typeof(OdooObjectFactory).GetMethod("BuildEntities", new[] { this.GetType(), typeof(ResultSet) }); method = method.MakeGenericMethod(context.EntityType); IEnumerable res = method.Invoke(this, new object[] { this, resultset }) as IEnumerable; return(res.Cast <object>().First()); }
public ResultSet GetEntityCommand(OdooCommandContext commandContext, IEnumerable <object> ids) { _context.UserId = Login(); try { var resultset = _context.OdooData.Read(_context.Database, _context.UserId, _context.Password, commandContext.EntityName, "read", ids.ToArray(), commandContext.GetArguments()); return(new ResultSet(resultset)); } catch (XmlRpcFaultException e) { throw OdooException.GetException(e); } }
public IEnumerable GetEntities(OdooCommandContext context) { ResultSet resultset; IEnumerable <object> ids; ids = SearchCommand(context); context.ClearArguments(); resultset = GetEntityCommand(context, ids); MethodInfo method = typeof(OdooObjectFactory).GetMethod("BuildEntities", new[] { this.GetType(), typeof(ResultSet) }); method = method.MakeGenericMethod(context.EntityType); IEnumerable res = method.Invoke(this, new object[] { this, resultset }) as IEnumerable; return(res.Cast <object>()); }
private IEnumerable <object> SearchCommand(OdooCommandContext commandContext) { _context.UserId = Login(); try { if (commandContext.Limit != 0) { return(_context.OdooData.Search(_context.Database, _context.UserId, _context.Password, commandContext.EntityName, "search", commandContext.GetArguments(), commandContext.Offset, commandContext.Limit, commandContext.Order)); } return(_context.OdooData.Search(_context.Database, _context.UserId, _context.Password, commandContext.EntityName, "search", commandContext.GetArguments())); } catch (XmlRpcFaultException e) { throw OdooException.GetException(e); } }
/// <summary> /// Create a <see cref="OdooCommandContext"/> with all /// </summary> /// <typeparam name="T"></typeparam> /// <param name="entity"></param> /// <returns></returns> public static OdooCommandContext BuildCommandContextFromEntity <T>(T entity) where T : IOdooObject { var context = new OdooCommandContext(); context.EntityType = typeof(T); var attributes = (OdooMapAttribute[])context.EntityType.GetCustomAttributes(typeof(OdooMapAttribute), false); if (attributes.Length > 0) { context.EntityName = attributes[0].OdooName; } else { String message = string.Format("Entity {0} has no Odoo attributed defined", context.EntityType.Name); throw new InvalidOperationException(message); } foreach (PropertyInfo property in context.EntityType.GetProperties()) { var argument = new OdooCommandArgument(); attributes = (OdooMapAttribute[])property.GetCustomAttributes(typeof(OdooMapAttribute), false); if (attributes.Length > 0) { argument.Property = attributes[0].OdooName; argument.ArgumentType = attributes[0].OdooType; argument.Value = property.GetValue(entity, null); argument.Operation = "="; argument.ReadOnly = attributes[0].ReadOnly; if (argument.Value == null) { argument.Value = false; } context.Arguments.Add(argument); } } return(context); }
private static void ProcessBinaryExpression(BinaryExpression operation, OdooCommandContext context, int order) { var argument = new OdooCommandArgument(); argument.Order = order; argument.Value = GetValue(operation, context); SetProperty(operation, context, argument); switch (operation.NodeType) { case ExpressionType.GreaterThan: argument.Operation = ">"; break; case ExpressionType.GreaterThanOrEqual: argument.Operation = ">="; break; case ExpressionType.LessThan: argument.Operation = "<"; break; case ExpressionType.LessThanOrEqual: argument.Operation = "<="; break; case ExpressionType.Equal: argument.Operation = "="; break; case ExpressionType.NotEqual: argument.Operation = "!="; break; } context.Arguments.Add(argument); }
private static object GetValue(Expression expression, OdooCommandContext context) { if (expression == null) { return(null); } object res = null; switch (expression.NodeType) { case ExpressionType.Call: var methodCall = expression as MethodCallExpression; res = GetValue(methodCall.Object, context); if (res == null) { foreach (Expression item in methodCall.Arguments) { var tmp = GetValue(item, context); if (tmp != null) { res = tmp; } } } break; case ExpressionType.MemberAccess: var memberAccess = expression as MemberExpression; if (memberAccess.Expression is ParameterExpression) { if (!(memberAccess.Expression as ParameterExpression).Name.Equals(context.ParameterName)) { if (memberAccess.Type.IsGenericCollection()) { var methodToArray = memberAccess.Type.GetMethods().FirstOrDefault(m => m.Name == "ToArray"); var expresion = Expression.Call(memberAccess, methodToArray); var getterLambda = Expression.Lambda <Func <object> >(expresion); var getter = getterLambda.Compile(); res = getter(); } else if (memberAccess.Type.IsNullable()) { string test = "hola"; } else { var objectMember = Expression.Convert(memberAccess, typeof(object)); var getterLambda = Expression.Lambda <Func <object> >(objectMember); var getter = getterLambda.Compile(); res = getter(); } } } else { if (memberAccess.Type.IsGenericCollection()) { MethodInfo methodToArray = memberAccess.Type.GetMethods().FirstOrDefault(m => m.Name == "ToArray"); var expresion = Expression.Call(memberAccess, methodToArray); var getterLambda = Expression.Lambda <Func <object> >(expresion); var getter = getterLambda.Compile(); res = getter(); } else { if (memberAccess.Member.GetCustomAttributes(typeof(OdooMapAttribute)) .Any()) { } else { var objectMember = Expression.Convert(memberAccess, typeof(object)); var getterLambda = Expression.Lambda <Func <object> >(objectMember); var getter = getterLambda.Compile(); res = getter(); } } } break; case ExpressionType.Constant: res = (expression as ConstantExpression).Value; break; default: if (expression is BinaryExpression) { var binary = expression as BinaryExpression; res = GetValue(binary.Right, context) ?? GetValue(binary.Left, context); } break; } return(res); }
public static OdooCommandContext BuildCommandContextFromExpression <T>(Expression <Func <T, bool> > conditions) where T : IOdooObject { if (!CheckCompatibility(conditions)) { throw new NotImplementedException("And Or mixing is not supported"); } var context = new OdooCommandContext(); context.ParameterName = conditions.Parameters[0].Name; context.EntityName = GetOdooEntityName(conditions.Parameters[0]); var initialExpression = conditions.Body; if (initialExpression != null) { var counter = 9999; while (initialExpression != null) { if (initialExpression.NodeType == ExpressionType.AndAlso || initialExpression.NodeType == ExpressionType.OrElse) { if (initialExpression.NodeType == ExpressionType.OrElse) { if (context.Arguments.All(x => x.CompareType != "|")) { context.Arguments.Add(new OdooCommandArgument { CompareType = "|", Order = counter }); counter--; } } var operation = initialExpression as BinaryExpression; if (operation.Right is MethodCallExpression) { ProcessMethodCallExpression(operation.Right as MethodCallExpression, context, counter); } if (operation.Right is BinaryExpression) { ProcessBinaryExpression(operation.Right as BinaryExpression, context, counter); } initialExpression = operation.Left as BinaryExpression; if (initialExpression == null) { initialExpression = operation.Left as MethodCallExpression; } } else { if (initialExpression is MethodCallExpression) { ProcessMethodCallExpression(initialExpression as MethodCallExpression, context, counter); } if (initialExpression is BinaryExpression) { ProcessBinaryExpression(initialExpression as BinaryExpression, context, counter); } if (initialExpression.NodeType == ExpressionType.MemberAccess || initialExpression.NodeType == ExpressionType.Not) { ProcessMemberAccess(initialExpression, context, counter); } initialExpression = null; } counter--; } } return(context); }
private static void ProcessMethodCallExpression(MethodCallExpression expression, OdooCommandContext context, int order) { var argument = new OdooCommandArgument(); argument.Order = order; if (expression != null) { switch (expression.Method.Name) { case "Contains": argument.Value = GetValue(expression, context); SetProperty(expression, context, argument); if (argument.Value is string) { argument.Operation = "ilike"; } if (argument.Value is Array) { argument.Operation = "in"; } context.Arguments.Add(argument); break; case "StartsWith": argument.Value = GetValue(expression, context) + "%"; SetProperty(expression, context, argument); argument.Operation = "like"; context.Arguments.Add(argument); break; case "EndsWith": argument.Value = "%" + GetValue(expression, context); SetProperty(expression, context, argument); argument.Operation = "like"; context.Arguments.Add(argument); break; case "Equals": argument.Value = GetValue(expression, context); SetProperty(expression, context, argument); argument.Operation = "="; context.Arguments.Add(argument); break; } } }
/// <summary> /// If property passed in path argument is a OpenErp class, /// it will load from OpenErp and set path property. /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TProperty"></typeparam> /// <param name="source"></param> /// <param name="path">Property to load</param> /// <returns></returns> public static IEnumerable <T> Include <T, TProperty>(this IEnumerable <T> source, Expression <Func <T, TProperty> > path) where T : IOdooObject, new() { var enumerable = source as OdooCollection <T>; if (enumerable != null) { var service = enumerable.Service; var memberAccess = path.Body as MemberExpression; if (memberAccess != null) { var member = memberAccess.Member; if (member != null) { //Search for openerpmap attribute Type memberType = ((PropertyInfo)memberAccess.Member).PropertyType; OdooMapAttribute[] attributes; if (memberType != null) { if (memberType.IsGenericCollection()) { //Collection, load entities //If collection is type of OpenErpSet, just load data. //Else, try to get openerpattribute Type EnumerationType = memberType.GetGenericArguments()[0]; attributes = (OdooMapAttribute[])EnumerationType.GetCustomAttributes(typeof(OdooMapAttribute), false); var accessFunction = path.Compile(); foreach (T item in enumerable) { var value = accessFunction(item); if (value != null) { //Check for OpenErpSet and call load. Type openErpSetType = typeof(OdooCollection <>).MakeGenericType(EnumerationType); if (value.GetType() == openErpSetType) { //call load data var res = value.GetType().GetMethod("LoadData").Invoke(value, null); } } else { //if has openerpmap attribute, load related data, else nothing can be done if (EnumerationType != null) { if (attributes.Length > 0) { //property type has a OpenErp mapped attribute PropertyInfo idProperty = member.DeclaringType.GetProperties().Where(p => p.Name.Equals("Id")).Single(); int id = (int)idProperty.GetValue(item, null); OdooCommandContext context = new OdooCommandContext(); context.EntityName = attributes[0].OdooName; context.EntityType = EnumerationType; string fieldName = ((OdooMapAttribute)(member.GetCustomAttributes(false).First())).OdooName; context.Arguments.Add(new OdooCommandArgument() { Operation = "=", Property = fieldName, Value = id }); Object res = service.GetEntities(context); ((PropertyInfo)memberAccess.Member).SetValue(item, res, null); } } } } } else { //Single entity to load. //Check basic type if (memberType.IsPrimitive || memberType.Equals(typeof(string))) { // Nothing can be done } else { // Have an entity OdooForeignKeyAttribute fk; OdooCommandContext context = new OdooCommandContext(); context.EntityName = OdooCommandContextFactory.GetOdooEntityName(memberType); context.EntityType = memberType; fk = (OdooForeignKeyAttribute)member.GetCustomAttributes(typeof(OdooForeignKeyAttribute), false).FirstOrDefault(); if (fk != null) { PropertyInfo idProperty = member.DeclaringType.GetProperties().Where(p => p.Name.Equals(fk.PropertyName)).Single(); foreach (T item in enumerable) { int id = (int)idProperty.GetValue(item, null); //Buscamos en OpenErp Object res = service.GetEntityById(context, id); ((PropertyInfo)memberAccess.Member).SetValue(item, res, null); } } } } } } } else { throw new ArgumentException("Not a valid property to include."); } } return(source); }