obuchmann / odoo-jsonrpc

PHP Odoo Json-RPC connector, prepared for laravel integration
MIT License
34 stars 11 forks source link

Model definition: HasMany/BelongsTo not being hydrated #4

Open xewl opened 2 years ago

xewl commented 2 years ago

I was trying to define a model for Sales Order, with a relation for its Lines. I saw that the PurchaseOrder model in the test folders had a ::read method to grab with an array of id's. And given there are Relation Attribute types like HasMany , BelongsTo, etc I thought it would be easy to get Lines etc.

But.. :D

Situation 1:

Using Service Provider directly Works, order_line is filled and can be used.

#[Model('sale.order.line')]
class SaleOrderLine extends OdooModel {}

public function debug(Odoo $odoo, int $id)
{
    $order = $odoo->find('sale.order', $id);
    $lines = SaleOrderLine::read($order->order_line) // :array 
}

Situation 2:

Using Model Error: App\Odoo\SaleOrder::$orderLine must not be accessed before initialization

#[Model('sale.order.line')]
class SaleOrderLine extends OdooModel {}

#[Model('sale.order')]
class SaleOrder extends OdooModel
{
    // #[Field('order_line')] // this one works
    #[HasMany(SaleOrderLine::class, 'order_line')]
    public array $orderLine;

    public function orderLines(): array
    {
        return SaleOrderLine::read($this->orderLine); // *
    }
}

public function debug(int $id)
{
    $order = SaleOrder::find($id);
    // then, where it fails:
    $lines = $order->orderLine; // error: see above
    $lines = $order->orderLines(); // error: see above
}

(kept it "orderLine" for clarity, could've used lines of course, order_line has the same result)

I'm guessing the relations aren't fully working yet, while filling up the model? ( OdooModel::hydrate , which is on the HasFields trait)?

There's currently only a test to check for saving a relation (PurchaseOrder). So I'm not quite sure how to go about this.

rjocoleman commented 1 year ago

This library is super helpful! I came across this same issue today and had a quick pass at hydrating relations: https://github.com/rjocoleman/odoo-jsonrpc/commit/0b471b7bb8f08d86432ff4436f6611db3b590853

Thanks for writing this issue up as you gave me a couple of nudges in a working direction. It's quite naive and has no tests, or docs, at present.

I'll make this a bit more robust, add tests, docs and raise a PR. If anyone has any feedback I'd be happy to incorporate it.

I did this for both HasMany and BelongsTo. I could see a case for HasManyThrough too e.g. stock.picking -> stock.move -> stock.move.lines

Usage (example, might not run exactly as I copy/pasted & trimmed down from a working code base without testing it but should show the ideas):

use Obuchmann\OdooJsonRpc\Attributes\Field;
use Obuchmann\OdooJsonRpc\Attributes\HasMany;
use Obuchmann\OdooJsonRpc\Attributes\BelongsTo;
use Obuchmann\OdooJsonRpc\Attributes\Key;
use Obuchmann\OdooJsonRpc\Attributes\Model;
use Obuchmann\OdooJsonRpc\Odoo\OdooModel;

#[Model('stock.picking')]
class StockPicking extends OdooModel
{
    #[BelongsTo(Partner::class, 'partner_id')]
    public Partner $vendor;

    #[Field('name')]
    public string $reference;

    #[Field('date')]
    public \DateTime $date;

    #[HasMany(StockMoveLine::class, 'move_line_ids')]
    public array $move_lines = [];
}
use Obuchmann\OdooJsonRpc\Attributes\Field;
use Obuchmann\OdooJsonRpc\Attributes\Key;
use Obuchmann\OdooJsonRpc\Attributes\Model;
use Obuchmann\OdooJsonRpc\Odoo\OdooModel;

#[Model('res.partner')]
class Partner extends OdooModel
{
    #[Field]
    public string $name;

    #[Field('email')]
    public ?string $email;
}
use Obuchmann\OdooJsonRpc\Attributes\Field;
use Obuchmann\OdooJsonRpc\Attributes\Key;
use Obuchmann\OdooJsonRpc\Attributes\BelongsTo;
use Obuchmann\OdooJsonRpc\Attributes\Model;
use Obuchmann\OdooJsonRpc\Odoo\OdooModel;

#[Model('stock.move.line')]
class StockMoveLine extends OdooModel
{
    #[BelongsTo(StockMove::class, 'move_id')]
    public StockMove $move;

    #[Field('price_unit')]
    public ?float $price_unit;

    #[Field('product_qty')]
    public int $product_qty;

    #[Field('quantity_done')]
    public int $quantity_done;
}
$pickings = StockPicking::query()
  ->where('partner_id', '=', 1)
  ->where('state', '=', 'assigned')
  ->get();

// for example - will be hydrated
$pickings[0]->move_lines;
$pickings[0]->vendor; 
obuchmann commented 1 year ago

Hi Robert,

looks like a promising way. Could you please open a PR in the main repo: https://github.com/obuchmann/odoo-jsonrpc

There we can open discuss any implications or any potential problems.


Von: Robert Coleman @.> Gesendet: Dienstag, 7. März 2023 10:23 An: obuchmann/odoo-jsonrpc @.> Cc: Subscribed @.***> Betreff: Re: [obuchmann/odoo-jsonrpc] Model definition: HasMany/BelongsTo not being hydrated (Issue #4)

This library is super helpful! I came across this same issue today and had a quick pass at hydrating relations: @.***https://github.com/rjocoleman/odoo-jsonrpc/commit/0b471b7bb8f08d86432ff4436f6611db3b590853

Thanks for writing this issue up as you gave me a couple of nudges in a working direction. It's quite naive and has no tests, or docs, at present.

I'll make this a bit more robust, add tests, docs and raise a PR. If anyone has any feedback I'd be happy to incorporate it.

I did this for both HasMany and BelongsTo. I could see a case for HasManyThrough too e.g. stock.picking -> stock.move -> stock.move.lines

Usage:

use Obuchmann\OdooJsonRpc\Attributes\Field; use Obuchmann\OdooJsonRpc\Attributes\HasMany; use Obuchmann\OdooJsonRpc\Attributes\BelongsTo; use Obuchmann\OdooJsonRpc\Attributes\Key; use Obuchmann\OdooJsonRpc\Attributes\Model; use Obuchmann\OdooJsonRpc\Odoo\OdooModel;

[Model('stock.picking')]

class StockPicking extends OdooModel {

[BelongsTo(Partner::class, 'partner_id')]

public Partner $vendor;

#[Field('name')]
public string $reference;

#[Field('date')]
public \DateTime $date;

#[HasMany(StockMoveLine::class, 'move_line_ids')]
public array $move_lines = [];

}

use Obuchmann\OdooJsonRpc\Attributes\Field; use Obuchmann\OdooJsonRpc\Attributes\Key; use Obuchmann\OdooJsonRpc\Attributes\Model; use Obuchmann\OdooJsonRpc\Odoo\OdooModel;

[Model('res.partner')]

class Partner extends OdooModel {

[Field]

public string $name;

#[Field('email')]
public ?string $email;

}

use Obuchmann\OdooJsonRpc\Attributes\Field; use Obuchmann\OdooJsonRpc\Attributes\Key; use Obuchmann\OdooJsonRpc\Attributes\BelongsTo; use Obuchmann\OdooJsonRpc\Attributes\Model; use Obuchmann\OdooJsonRpc\Odoo\OdooModel;

[Model('stock.move.line')]

class StockMoveLine extends OdooModel {

[BelongsTo(StockMove::class, 'move_id')]

public StockMove $move;

#[Field('price_unit')]
public ?float $price_unit;

#[Field('product_qty')]
public int $product_qty;

#[Field('quantity_done')]
public int $quantity_done;

}

$pickings = StockPicking::query() ->where('partner_id', '=', 1) ->where('state', '=', 'assigned') ->get();

// for example - will be hydrated $pickings[0]->move_lines; $pickings[0]->vendor;

— Reply to this email directly, view it on GitHubhttps://github.com/obuchmann/odoo-jsonrpc/issues/4#issuecomment-1457830298, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AA5VRFQVCDHE6OJAHQEVTZDW235CVANCNFSM5J25PO6Q. You are receiving this because you are subscribed to this thread.Message ID: @.***>