Skip to content
8 changes: 4 additions & 4 deletions PortaCapena.OdooJsonRpcClient.Example/OdooClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ public async Task Can_create_update_get_and_delete_customer()
products.Succeed.Should().BeTrue();
products.Value.Should().BePositive();

model.Add(x => x.Name, "new name");
model.AddOrUpdate(x => x.Name, "new name");

var editedCustomer = await odooClient.UpdateAsync(model, products.Value);
editedCustomer.Succeed.Should().BeTrue();
Expand Down Expand Up @@ -392,8 +392,8 @@ public async Task Can_create_product_from_dictionary_model()

var dictModel3 = OdooDictionaryModel.Create<ProductProductOdooModel>(x => x.InvoicePolicy, InvoicingPolicyProductProductOdooEnum.DeliveredQuantities);

dictModel.Add<ProductProductOdooModel>(x => x.CombinationIndices, "sadasd");
dictModel.Add<ProductProductOdooModel>(x => x.InvoicePolicy, InvoicingPolicyProductProductOdooEnum.DeliveredQuantities);
dictModel.AddOrUpdate<ProductProductOdooModel>(x => x.CombinationIndices, "sadasd");
dictModel.AddOrUpdate<ProductProductOdooModel>(x => x.InvoicePolicy, InvoicingPolicyProductProductOdooEnum.DeliveredQuantities);

var createResult = await odooClient.CreateAsync(dictModel);
createResult.Succeed.Should().BeTrue();
Expand Down Expand Up @@ -551,7 +551,7 @@ public async Task Can_create_purchase_order()
Name = "test purchase line",
})
};
purchaseOrder.Add(x => x.OrderLine, lines);
purchaseOrder.AddOrUpdate(x => x.OrderLine, lines);

var createResult = await odooClient.CreateAsync(purchaseOrder);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public async Task Update_name_in_nl()
result.Value.Name.Should().Be("Acoustic Bloc Screens");
result.Value.Name.Should().NotBe("Akoestische blokschermen");

var model = OdooDictionaryModel.Create<ProductProductOdooModel>().Add(x => x.Name, "Product new name NL");
var model = OdooDictionaryModel.Create<ProductProductOdooModel>().AddOrUpdate(x => x.Name, "Product new name NL");

repo.Config.Context.Language = "nl_BE";

Expand Down
55 changes: 55 additions & 0 deletions PortaCapena.OdooJsonRpcClient.Shared/Models/POSSessionOdooModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using PortaCapena.OdooJsonRpcClient.Attributes;
using PortaCapena.OdooJsonRpcClient.Converters;
using PortaCapena.OdooJsonRpcClient.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Text;

namespace PortaCapena.OdooJsonRpcClient.Shared.Models
{
[OdooTableName("pos.session")]
[JsonConverter(typeof(OdooModelConverter))]
public class POSSessionOdooModel : IOdooModel
{
[JsonProperty("id")]
public long Id { get; set; }

[JsonProperty("name")]
public string Name { get; set; }

[JsonProperty("config_id")]
public int ConfigId { get; set; }

[JsonProperty("user_id")]
public int UserId { get; set; }

[JsonProperty("state")]
public POSSessionOdooState State { get; set; }


[JsonProperty("start_at")]
public DateTime StartAt { get; set; }


}

[JsonConverter(typeof(StringEnumConverter))]
public enum POSSessionOdooState : int
{
[EnumMember(Value = "opening_control")]
OpeningControl = 1,
[EnumMember(Value = "opened")]
Opened = 2,
[EnumMember(Value = "closing_control")]
ClosingControl = 3,
[EnumMember(Value = "closed")]
Closed = 4,

}


}
10 changes: 5 additions & 5 deletions PortaCapena.OdooJsonRpcClient.Tests/OdooDictionaryModelTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void Can_create_dictionary_with_create_instance()
{
Name = "test name",
});
model.Add(x => x.CreateDate, new DateTime());
model.AddOrUpdate(x => x.CreateDate, new DateTime());

model.TableName.Should().NotBeEmpty();
model.Should().NotBeEmpty();
Expand All @@ -68,7 +68,7 @@ public void Can_create_dictionary_with_call_method()
{
Name = TestString(),
});
model.Add(x => x.DisplayName, TestString());
model.AddOrUpdate(x => x.DisplayName, TestString());

model.TableName.Should().NotBeEmpty();
model.Should().NotBeEmpty();
Expand All @@ -88,7 +88,7 @@ public void Can_create_dictionary_with_call_method_with_params()
{
Name = TestString("123"),
});
model.Add(x => x.DisplayName, TestString("456"));
model.AddOrUpdate(x => x.DisplayName, TestString("456"));

model.TableName.Should().NotBeEmpty();
model.Should().NotBeEmpty();
Expand All @@ -110,7 +110,7 @@ public void Can_create_dictionary_with_call_method_with_enum_params()
{
Name = TestString("123"),
});
model.Add(x => x.State, StatusPurchaseOrderOdooEnum.PurchaseOrder);
model.AddOrUpdate(x => x.State, StatusPurchaseOrderOdooEnum.PurchaseOrder);

model.TableName.Should().NotBeEmpty();
model.Should().NotBeEmpty();
Expand All @@ -132,7 +132,7 @@ public void Can_create_dictionary_with_array()
{
ActivityIds = new long[] { 1, 2, 3 }
});
model.Add(x => x.MessageFollowerIds, new long[] { 4, 5, 6 });
model.AddOrUpdate(x => x.MessageFollowerIds, new long[] { 4, 5, 6 });

model.TableName.Should().NotBeEmpty();
model.Should().NotBeEmpty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public static bool ConverOdooPropertyToDotNet(Type dotnetType, JToken value, out
return true;

case JTokenType.Integer when dotnetType == typeof(int) || dotnetType == typeof(int?) || dotnetType == typeof(long) || dotnetType == typeof(long?):
case JTokenType.Integer when dotnetType == typeof(float) || dotnetType == typeof(float?) || dotnetType == typeof(double) || dotnetType == typeof(double?):
case JTokenType.Float:
result = value.ToObject(dotnetType);
return true;
Expand Down
10 changes: 10 additions & 0 deletions PortaCapena.OdooJsonRpcClient/Models/IOdooMethodResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace PortaCapena.OdooJsonRpcClient.Models
{
public interface IOdooMethodResult
{
}
}
17 changes: 15 additions & 2 deletions PortaCapena.OdooJsonRpcClient/Models/OdooDictionaryModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ namespace PortaCapena.OdooJsonRpcClient.Models
{
public class OdooDictionaryModel : Dictionary<string, object>
{

public OdooRecordsListStructure GetRecord()
{
OdooRecordsListStructure odooRecordsListStructure = new OdooRecordsListStructure();

foreach (var key in this.Keys)
{

odooRecordsListStructure.Add(key, this[key]);
}
return odooRecordsListStructure;
}

public string TableName { get; internal set; }

public OdooDictionaryModel() { }
Expand Down Expand Up @@ -42,12 +55,12 @@ public static OdooDictionaryModel Create(string tableName)

public static OdooDictionaryModel Create<T>(Expression<Func<T, object>> expression, object value) where T : IOdooAtributtesModel, new()
{
return new OdooDictionaryModel<T>().Add(expression, value);
return new OdooDictionaryModel<T>().AddOrUpdate(expression, value);
}

//TODO: Rename to set / addOrUpdate ?

public OdooDictionaryModel Add<T>(Expression<Func<T, object>> expression, object value) where T : IOdooAtributtesModel
public OdooDictionaryModel AddOrUpdate<T>(Expression<Func<T, object>> expression, object value) where T : IOdooAtributtesModel
{
if (TableName != null && TryGetOdooTableName(expression, out var tableName))
TableName = tableName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ public static OdooDictionaryModel<T> Create(Expression<Func<T>> expression)

public static OdooDictionaryModel<T> Create(Expression<Func<T, object>> expression, object value)
{
return new OdooDictionaryModel<T>().Add(expression, value);
return new OdooDictionaryModel<T>().AddOrUpdate(expression, value);
}

public OdooDictionaryModel<T> Add(Expression<Func<T, object>> expression, object value)
public OdooDictionaryModel<T> AddOrUpdate(Expression<Func<T, object>> expression, object value)
{
Add<T>(expression, value);
AddOrUpdate<T>(expression, value);
return this;
}

Expand Down
164 changes: 164 additions & 0 deletions PortaCapena.OdooJsonRpcClient/Models/OdooRecordsListStructure.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PortaCapena.OdooJsonRpcClient.Models
{

public class OdooRecordsListStructure : Hashtable
{
private readonly ArrayList _keys = new ArrayList();
private readonly ArrayList _values = new ArrayList();

public override void Add(object key, object value)
{
if (!(key is string))
{
throw new ArgumentException("key must be a string.");
}

base.Add(key, value);
_keys.Add(key);
_values.Add(value);
}

public override object this[object key]
{
get => base[key];
set
{
if (!(key is string))
{
throw new ArgumentException("key must be a string.");
}

base[key] = value;
_keys.Add(key);
_values.Add(value);
}
}

public override bool Equals(object obj)
{
if (obj == null)
return false;

if (obj.GetType() != typeof(OdooRecordsListStructure))
return false;
var xmlRpcStruct = (OdooRecordsListStructure)obj;
if (Keys.Count != xmlRpcStruct.Count)
return false;

foreach (string key in Keys)
{
if (!xmlRpcStruct.ContainsKey(key))
return false;
if (!this[key].Equals(xmlRpcStruct[key]))
return false;
}
return true;
}

public override int GetHashCode()
{
return Values.Cast<object>().Aggregate(0, (current, obj) => current ^ obj.GetHashCode());
}

public override void Clear()
{
base.Clear();
_keys.Clear();
_values.Clear();
}

public new IDictionaryEnumerator GetEnumerator()
{
return new Enumerator(_keys, _values);
}

public override ICollection Keys => _keys;

public override void Remove(object key)
{
base.Remove(key);
var idx = _keys.IndexOf(key);
if (idx >= 0)
{
_keys.RemoveAt(idx);
_values.RemoveAt(idx);
}
}

public override ICollection Values => _values;

private class Enumerator : IDictionaryEnumerator
{
private readonly ArrayList _keys;
private readonly ArrayList _values;
private int _index;

public Enumerator(ArrayList keys, ArrayList values)
{
_keys = keys;
_values = values;
_index = -1;
}

public void Reset()
{
_index = -1;
}

public object Current
{
get
{
CheckIndex();
return new DictionaryEntry(_keys[_index], _values[_index]);
}
}

public bool MoveNext()
{
_index++;
return _index < _keys.Count;
}

public DictionaryEntry Entry
{
get
{
CheckIndex();
return new DictionaryEntry(_keys[_index], _values[_index]);
}
}

public object Key
{
get
{
CheckIndex();
return _keys[_index];
}
}

public object Value
{
get
{
CheckIndex();
return _values[_index];
}
}

private void CheckIndex()
{
if (_index < 0 || _index >= _keys.Count)
throw new InvalidOperationException(
"Enumeration has either not started or has already finished.");
}
}
}
}
Loading