Override order item

Help for integrating the Laravel package
Forum rules
Always add your Laravel, Aimeos and PHP version as well as your environment (Linux/Mac/Win)
Spam and unrelated posts will be removed immediately!
User avatar
PraveenJayakody
Posts: 7
Joined: 15 Nov 2022, 22:58

Override order item

Post by PraveenJayakody » 05 Dec 2022, 00:12

Hi,

I'm on Laravel 9, Aimeos 2022.x and PHP 8 on Mac.

I want to override Order Item so that I can introduce a custom field (that would be shown when `GET /basket` is called. I tried to do it using a decorator approach. I was able to add the decorator but this would not change the attributes shown on the API call. Next, I overrode the Order Manager. I was able to override the Manager but not the item ( so that I could add my own `toArray()` implementation). I overrode the Order manager by creating files at '<extension>/src/MShop/Order/Manager/Base/RentalOrder' and '<extension>/src/MShop/Order/Manager/RentalOrder'. I also created '<extension>/src/MShop/Order/Item/RentalOrder' however this is not being used.

My '<extension>/config/mshop.php' is like `return [ 'order' => [ 'manager' => [ 'name' => 'Myprojectbase', 'search', ...] ]`

How do I add new fields to order so that they will be shown in the API call and Admin portal?

Any help is appreciated,
TIA

User avatar
aimeos
Administrator
Posts: 7866
Joined: 01 Jan 1970, 00:00

Re: Override order item

Post by aimeos » 05 Dec 2022, 11:47

If your new property isn't added to the frontend because toArray() doesn't include it, this may be a bug. If you can provide more information, then we can fix it and you don't need to create the code for a custom order manager. The custom properties should be returned here:
https://github.com/aimeos/aimeos-core/b ... #L406-L411
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

User avatar
PraveenJayakody
Posts: 7
Joined: 15 Nov 2022, 22:58

Re: Override order item

Post by PraveenJayakody » 06 Dec 2022, 01:04

Hi thank you for the reply.

At this point, I have only added the rental_start_date and rental_end_date to the mshop_order table schema.

Code: Select all

		'mshop_order' => function( \Aimeos\Upscheme\Schema\Table $table ) {

			$table->engine = 'InnoDB';

			$table->bigid()->primary( 'pk_msord_id' );
			$table->string( 'siteid' );
			$table->bigint( 'baseid' );
			$table->refid( 'relatedid' )->default( '' );
			$table->string( 'channel', 16 )->default( '' );
			$table->string( 'invoiceno', 32 )->default( '' );
			$table->datetime( 'datepayment' )->null( true );
			$table->datetime( 'datedelivery' )->null( true );
			$table->smallint( 'statuspayment' )->default( -1 );
			$table->smallint( 'statusdelivery' )->default( -1 );
			$table->string( 'cdate', 10 )->default( '' );
			$table->string( 'cmonth', 7 )->default( '' );
			$table->string( 'cweek', 7 )->default( '' );
			$table->string( 'cwday', 1 )->default( '' );
			$table->string( 'chour', 2 )->default( '' );
			$table->date( 'rental_start_date' )->null( true ); // new column
			$table->date( 'rental_end_date' )->null( true ); // new column
			$table->meta();
			
			...

What does it take to get these two columns when `GET /basket` is called. And how do I set these columns in the relevant JSONAPI calls? I need to simply add two custom properties to the order. Is there a better way to accomplish this?

User avatar
aimeos
Administrator
Posts: 7866
Joined: 01 Jan 1970, 00:00

Re: Override order item

Post by aimeos » 07 Dec 2022, 09:15

You need to create a manager decorator so Aimeos knows that columns and that they can be used for searching, saving and in the items:
https://aimeos.org/docs/latest/models/e ... /#easy-way
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

User avatar
PraveenJayakody
Posts: 7
Joined: 15 Nov 2022, 22:58

Re: Override order item

Post by PraveenJayakody » 14 Dec 2022, 21:29

I have the decorator in packages\<extension>\src\MShop\Order\Manager\Decorator\Rental.php

Code: Select all

<?php

namespace Aimeos\MShop\Order\Manager\Decorator;

class Rental extends \Aimeos\MShop\Common\Manager\Decorator\Base
{
    private $attr = [
        'rental_start_date' => [
            'code' => 'rental_start_date',
            'internalcode' => 'mord."rental_start_date"',
            'label' => 'Rental start date',
            'type' => 'datetime',
            'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
        ],
    ];

    public function getSaveAttributes() : array
    {
        return parent::getSaveAttributes() + $this->createAttributes( $this->attr );
    }

    public function getSearchAttributes( bool $sub = true ) : array
    {
//        dd(parent::getSearchAttributes( $sub ) + $this->createAttributes( $this->attr ));
        return parent::getSearchAttributes( $sub ) + $this->createAttributes( $this->attr );
    }
}

packages/<extension>/config/mshop.php is:

Code: Select all

 return [
     'order' => [
         'manager' => [
             'decorators' => [
                 'local' => ['Rental']
             ]
         ]
     ]
 ];
And I executed POST /order (after doing the necessary like adding addresses...etc) with the folowing body:

Code: Select all

{
    "data": {
        "attributes": {
            "order.baseid": "8",
            "order.rental_start_date": "2022-12-20"
        }
    }
}
However, the database table column mshop_order.rental_start_date is not populated with the string value. How can I edit/read attributes added using a decorator?

User avatar
aimeos
Administrator
Posts: 7866
Joined: 01 Jan 1970, 00:00

Re: Override order item

Post by aimeos » 15 Dec 2022, 18:06

Your new attribute is named "rental_start_date":

Code: Select all

{
    "data": {
        "attributes": {
            "order.baseid": "8",
            "rental_start_date": "2022-12-20"
        }
    }
}
The prefix ("order." in that case) will be only used for core attributes.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

User avatar
PraveenJayakody
Posts: 7
Joined: 15 Nov 2022, 22:58

Re: Override order item

Post by PraveenJayakody » 18 Dec 2022, 23:48

I had to add this to my Rental.php from earlier:

Code: Select all

    public function save( $items, bool $fetch = true )
    {
        $rental_start_date = parent::context()->view()->request()->getParsedBody()['data']['attributes']['rental_start_date'];
        $items['rental_start_date'] = $rental_start_date;
        
        return parent::save($items, $fetch);
    }
After this I could send the `rental_start_date` in the data['attributes] request body and the DB mshop_order table column wold be updated

User avatar
aimeos
Administrator
Posts: 7866
Joined: 01 Jan 1970, 00:00

Re: Override order item

Post by aimeos » 20 Dec 2022, 15:41

The problem with adding custom properties to the JSON API order endpoint is that the endpoint isn't prepared to accept custom properties. Instead, it's only for used for tracking the state of the order itself (order/base). It would be better if you add your custom property to the mshop_order_base table where you can so so without problems.

Note: In the lastest dev-master branch, the order and order/base tables have been merged so this won't be a problem in the future.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

Post Reply