Intechnity-com / OdooJsonRpcClient

Odoo Client Json Rpc
MIT License
70 stars 31 forks source link

Odoo model class could be created dynamically instead of fetched and pasted #72

Closed JRB202 closed 1 year ago

JRB202 commented 1 year ago

Patrick,

In order to avoid to fetch and paste objects class corresponding to OdooProduct, OdooAccountInvoice, ... models

I suggest you to dynamically create these models classes based on result of fetch from : var tableName = "product.product"; var modelResult = await odooClient.GetModelAsync(tableName); var model = OdooModelMapper.GetDotNetModel(tableName, modelResult.Value);

So you will find encloded below a prototype of dynamic class creation which is working great based on my own tests.

Then we can use it to dynamically populate model Class with something like :

// Create dynamically a class for tableName value ("product.product") var ProductProductOdoo = new DynamicClass(tableName);

// Populate properties of this class with modelResult or model from your code foreach (var field in OdooModelMapper.GetDotNetModel(tableName, modelResult.Value)) // or modelResult ? var String NewField = field.Id // Or something based on field.Id var String NewValue = field.Value // Or something based on field.Value, could also be object instead of string DynClassEmployee.AddAttribute(NewField , NewValue ); // Dynamically add String property to Class // or DynClassEmployee.AddAttribute(NewField , NewValue ); // Dynamically add object property to Class next

You can use AddAttribute on any type Object, String, ...

At the end of loop we should get the ProductProductOdoo class corresponding to fetched content for product.product Odoo table and we can use this class with the rest of your API without having to fetch, copy, paste and maintain Odoo model Class manually.

I am sure you can finalize based on this idea.

Keep me updated, I have to use your API to write models in Odoo as interface between existing application based on SQL server and Odoo.

Jean-Regis


Dynamic Class Creation

using System; using System.Collections.Generic; using Microsoft.VisualBasic.CompilerServices; // Install-Package Microsoft.VisualBasic

public partial class DynamicClass { private string _Name;

public string Name
{
    get
    {
        return _Name;
    }
    private set
    {
        _Name = value;
    }
}
public Dictionary<string, object> Attributes;

public DynamicClass(string name)
{
    Name = name;
    Attributes = new Dictionary<string, object>();
    Attributes.Add("LogicalName", name);
    Attributes.Add("Id", Guid.NewGuid());
}

public object this[string key]
{
    get
    {
        return Attributes[key];
    }

    set
    {
        Attributes[key] = value;
    }
}

public void AddAttribute<T>(string attributeName, T data)
{
    Attributes.Add(attributeName, data);
}

public void SetAttributeValue<T>(string attributeName, T data)
{
    Attributes[attributeName] = data;
}

public T GetAttributeValue<T>(string attributeName)
{
    return Conversions.ToGenericParameter<T>(Attributes[attributeName]);
}

}

// Usage in code

{ var DynClassEmployee = new DynamicClass("employee"); // Create dynamically a class named "employee"

DynClassEmployee.AddAttribute<int>("EmployeeID", 10); // Add New Integer Attribute and populate

string FieldName = "Address";
DynClassEmployee.AddAttribute<string>(FieldName, "India"); // Add New String Attribute and populate

FieldName = "EmpStruct";
object StoredObject = null;
DynClassEmployee.AddAttribute<object>(FieldName, StoredObject); // Add New Object Attribute using field variable

FieldName = "Address";
DynClassEmployee.SetAttributeValue<string>(FieldName, "New Dheli in India");  // 'Update String Attribute 

int MyReadId = DynClassEmployee.GetAttributeValue<int>("EmployeeID"); // Read Integer Attribute
string MyReadAdress = DynClassEmployee.GetAttributeValue<string>("Address"); // Read String Attribute
var MyReadAdress2 = DynClassEmployee.Attributes("Address");     // Read "Address" Attribute
object MyReadObject = DynClassEmployee.GetAttributeValue<object>("EmpStruct"); // Read Object Attribute

}

patricoos commented 1 year ago

The main advantage of this library is that the models are strongly typed, but you can use non-typable models. See OdooDictionaryModel class insted off OdooDictionaryModel<T>. Learn to read the code or I'll block you

JRB202 commented 1 year ago

Patrick,

Sorry, but I just don't understand this from you answer below :

See OdooDictionaryModel class instead of OdooDictionaryModel.

The 2 proposals seems to be the same ... can you clarify ?

And I just try to help and collaborate, nothing else ...

Best regards

Jean-Régis

On Thu, Apr 27, 2023 at 2:38 PM Patrick @.***> wrote:

The main advantage of this library is that the models are strongly typed, but you can use non-typable models. See OdooDictionaryModel class insted off OdooDictionaryModel. Learn to read the code or I'll block you

— Reply to this email directly, view it on GitHub https://github.com/Intechnity-com/OdooJsonRpcClient/issues/72#issuecomment-1525624179, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHT5UEFX4I6MAQYGW24TJ63XDJSDLANCNFSM6AAAAAAXNYUPHQ . You are receiving this because you authored the thread.Message ID: @.***>

patricoos commented 1 year ago

Read carefully my answer, one model is generic.

patricoos commented 1 year ago

check it out

var model = OdooDictionaryModel.Create(() => new ResPartnerOdooModel()
{
    Name = "test name",
    CountryId = 20,
    City = "test city",
    Zip = "12345",
    Street = "test address",
    CompanyType = CompanyTypeResPartnerOdooEnum.Company
});

var model2 = new OdooDictionaryModel("res.partner") {
    { "name", "test name" },
    { "country_id", 20 },
    { "city", "test city" },
    { "zip", "12345" },
    { "street", "test address" },
    { "company_type", "company" },
};

var odooClient = new OdooClient(TestConfig);

var products = await odooClient.CreateAsync(model2);
JRB202 commented 1 year ago

Thanks Patrick for this suggestion.

The second one is working like a charm for create, update and delete.

How can I declare query for "res.partner" by the same kind of way (I mean without fetch, copy and paste model.)

var repository .????.. "res.partner";var partners = await repository.Query().ToListAsync();

Thanks

Jean-Régis

On Thu, Apr 27, 2023 at 4:28 PM Patrick @.***> wrote:

check it out

var model = OdooDictionaryModel.Create(() => new ResPartnerOdooModel() { Name = "test name", CountryId = 20, City = "test city", Zip = "12345", Street = "test address", CompanyType = CompanyTypeResPartnerOdooEnum.Company });

        var model2 = new OdooDictionaryModel("res.partner") {
            { "name", "test name" },
            { "country_id", 20 },
            { "city", "test city" },
            { "zip", "12345" },
            { "street", "test address" },
            { "company_type", "company" },
        };

        var odooClient = new OdooClient(TestConfig);

        var products = await odooClient.CreateAsync(model2);

— Reply to this email directly, view it on GitHub https://github.com/Intechnity-com/OdooJsonRpcClient/issues/72#issuecomment-1525798801, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHT5UEHMYPPRX4CGV3S6BCTXDJ7ABANCNFSM6AAAAAAXNYUPHQ . You are receiving this because you authored the thread.Message ID: @.***>