properly extending the User model?

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!
kopz
Posts: 8
Joined: 18 Jan 2024, 14:11

properly extending the User model?

Post by kopz » 22 Jan 2024, 13:40

Hi,

Using:
aimeos/aimeos-headless (latest)
PHP 8.2
Laravel v10.40.0

How should one approach this:

I need to add a new table user_partners and modify the existing users table with a new field PartnerNo (users.PartnerNo - user_partnes.PartnerNo).

I have a migration for both tables (that does what it is supposed to do) but do I need to add a migration also for mshop_customers table?

What else do I need to do to be able to get to "customer partner" data via the customer manager?

Migration:

Code: Select all

return [
    'table' => [
        'users' => function (\Aimeos\Upscheme\Schema\Table $table) {
            $table->string('PartnerNo', 64)->null(true);
            $table->index(['PartnerNo'], 'idx_lvu_partner_no');
        },
	'users_partner' => function( \Aimeos\Upscheme\Schema\Table $table ) {
	   $table->engine = 'InnoDB';

	    $table->string('PartnerNo', 64)->primary();
	    $table->string('RecordTypeId', 100);			
	    $table->string('NameShort');
	    $table->string('Name1');
            $table->string('Name2')->null(true);
            $table->smallint('SupplierYesNo')->default(0);
            $table->smallint('B2BBuyerYesNo')->default(0);
            $table->smallint('ContractorYesNo')->default(0);
            $table->smallint('RecipientYesNo')->default(0);
            $table->string('TaxNumber', 48);
            $table->string('TaxCountryName', 48);
            $table->string('RegistrationNumber', 100);
            $table->string('GLN', 48);
            $table->string('Email', 255);
            $table->string('Phone', 100)->null(true);
            $table->string('MobilePhone', 100)->null(true);
            $table->string('WebAddress', 255)->null(true);
            $table->string('Street', 100);
            $table->string('City', 100);
            $table->string('PostalCode', 32);
            $table->string('CountryName', 100);
            $table->string('PartnerStatus', 4);
            $table->string('PartnerMark', 48);
            $table->string('RegionalSales', 255);
            $table->string('TargetGroup', 255);
            $table->string('TargetGroupSegment', 255);
            $table->string('PartnerOrganisationUnit', 32);
            $table->string('WholesaleOrRepro', 32);
            $table->string('AbcCustomer', 3);
            $table->string('PartnerRank', 255);
            $table->string('InterestPercent', 3);
            $table->string('Insurance', 8);
            $table->string('LimitType', 8);
            $table->string('Amount', 255);

            $table->unique(['PartnerNo'], 'unq_lvup_partnerno');
	    $table->index( ['RecordTypeId'], 'idx_lvup_recordtypeid' );
            $table->index( ['NameShort'], 'idx_lvup_nameshort' );
            $table->index( ['TaxNumber'], 'idx_lvup_taxnumber' );
            $table->index( ['TaxCountryName'], 'idx_lvup_taxcountryname' );
            $table->index( ['RegistrationNumber'], 'idx_lvup_registrationnumber' );
            $table->index( ['GLN'], 'idx_lvup_gln' );
            $table->index( ['Email'], 'idx_lvup_email' );
            $table->index( ['PartnerMark'], 'idx_lvup_partnermark' );
            $table->index( ['WholesaleOrRepro'], 'idx_lvup_wholesaleorrepro' );
            $table->index( ['AbcCustomer'], 'idx_lvup_abccustomer' );
            $table->index( ['LimitType'], 'idx_lvup_limittype' );
            $table->index( ['SupplierYesNo'], 'idx_lvup_supplieryesno' );
            $table->index( ['B2BBuyerYesNo'], 'idx_lvup_b2bbuyeryesno' );
            $table->index( ['ContractorYesNo'], 'idx_lvup_contractoryesno' );
            $table->index( ['RecipientYesNo'], 'idx_lvup_recipientyesno' );
            $table->index( ['PartnerNo'], 'idx_lvup_partnerno' );
            $table->index( ['PartnerStatus'], 'idx_lvup_partnerstatus' );
            $table->index( ['PartnerOrganisationUnit'], 'idx_lvup_partnerorganisationunit' );
            $table->index( ['Insurance'], 'idx_lvup_insurance' );
            $table->index( ['TargetGroup'], 'idx_lvup_targetgroup' );
            $table->index( ['PartnerRank'], 'idx_lvup_partnerrank' );
            $table->index( ['Street', 'City', 'PostalCode'], 'idx_lvup_street_city_postalcode' );

	   $table->foreign( 'PartnerNo', 'users', 'PartnerNo', 'fk_lvup_pno' );
		},        
    ],
];
I will also need the data from user_partners available via jsonapi.

Documentation does not seem to have a good example of this so thank you in advance for any help.

kopz
Posts: 8
Joined: 18 Jan 2024, 14:11

Re: properly extending the User model?

Post by kopz » 23 Jan 2024, 07:22

I'm also having trouble saving the new field:

Code: Select all

 
 $item = $manager->create([
            'customer.email' => time(). '@test.com',
            'customer.name' => $decodedToken->name,
            'customer.company' => $decodedToken->name,
            'customer.password' => '',
            'customer.PartnerNo' => '12345'
 ]);
 $manager->save($item);
 $item->setModified();
 
This saves the customer (users table) but PartnerNo remains null.

edit:
Seems I need to extend the customer manager. Which I'm trying to do but without success.

packages/user-partner/src/MShop/Customer/Manager/Partner/Standard.php

Code: Select all

namespace Aimeos\MShop\Customer\Manager\Partner;

class Standard
	extends \Aimeos\MShop\Customer\Manager\Base
	implements \Aimeos\MShop\Customer\Manager\Iface, \Aimeos\MShop\Common\Manager\Factory\Iface
{
    public function getSaveAttributes() : array
    {
        return $this->createAttributes( [
            'ParentNo' => [
                'type' => 'string',
                'public' => true,
                'label' => 'Partner No.',
            ],
        ] );
    }	
}
What am I missing?

edit2:
Yeah, I was actually trying to create a manager instead of extending the existing customer manager.

Solved with a decorator
packages/user-partner/src/MShop/Customer/Manager/Decorator/PartnerNo.php

Code: Select all

namespace Aimeos\MShop\Customer\Manager\Decorator;

class PartnerNo  extends \Aimeos\MShop\Common\Manager\Decorator\Base
{
    private $attr = [
        'PartnerNo' => [
            'internalcode' => 'lvus."PartnerNo"',
            'label' => 'Partner No.',
            'type' => 'string',
        ],
    ];

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

    public function getSearchAttributes( bool $sub = true ) : array
    {
        return parent::getSearchAttributes( $sub ) + $this->createAttributes( $this->attr );
    }
}
packages/user-partner/config/mshop.php

Code: Select all

return [
    'customer' => [
        'manager' => [
            'decorators' => [
                'local' => ['PartnerNo']
            ]
        ]
    ]    
];

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

Re: properly extending the User model?

Post by aimeos » 23 Jan 2024, 11:40

This would be correct:

Code: Select all

 
 $item = $manager->create([
            'customer.email' => time(). '@test.com',
            'customer.name' => $decodedToken->name,
            'customer.company' => $decodedToken->name,
            'customer.password' => '',
            'PartnerNo' => '12345'
 ]);
 $manager->save($item);
 
Custom attributes must be named exactly like defined in your decorator and contains no "customer." prefix in your case.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

kopz
Posts: 8
Joined: 18 Jan 2024, 14:11

Re: properly extending the User model?

Post by kopz » 23 Jan 2024, 13:01

Code: Select all

$customer = $manager->create([
            'customer.email' => time().'@test.com',
            'customer.name' => $decodedToken->name,
            'customer.company' => $decodedToken->name,
            'customer.password' => '',
            'PartnerNo' => 12231,
 ]);
 
Yes this works with a decorator ... however it breaks jsonapi & jqadm api.

Error on: /admin/default/jqadm/search/dashboard?locale=en
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'lvu.PartnerNo' in 'field list': SELECT lvu."PartnerNo", mcus."id" AS "customer.id", mcus."siteid" AS "customer.siteid", mcus."name" AS "customer.label", mcus."email" AS "customer.code", mcus."company" AS "customer.company", mcus."vatid" AS "customer.vatid", mcus."salutation" AS "customer.salutation"
Customer manager create inserts a record in the users table (lvu.PartnerNo), what am I missing?

Im also having trouble with making a manager for customer/partner where partners.PartnerNo = users.PartnerNo ...

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

Re: properly extending the User model?

Post by aimeos » 24 Jan 2024, 09:07

kopz wrote: 23 Jan 2024, 13:01
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'lvu.PartnerNo' in 'field list': SELECT lvu."PartnerNo", mcus."id" AS "customer.id", mcus."siteid" AS "customer.siteid", mcus."name" AS "customer.label", mcus."email" AS "customer.code", mcus."company" AS "customer.company", mcus."vatid" AS "customer.vatid", mcus."salutation" AS "customer.salutation"
Your alias is wrong and must be "mcus" instead of "lvu".
kopz wrote: 23 Jan 2024, 13:01 Im also having trouble with making a manager for customer/partner where partners.PartnerNo = users.PartnerNo ...
Because you don't use the users_list table to reference the partners or using a parent/child relationship between the users and the users_partner table, you have to instantiate the customer/partner manager and fetch the items yourself.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

kopz
Posts: 8
Joined: 18 Jan 2024, 14:11

Re: properly extending the User model?

Post by kopz » 24 Jan 2024, 11:39

Thank you.
Because you don't use the users_list table to reference the partners or using a parent/child relationship between the users and the users_partner table, you have to instantiate the customer/partner manager and fetch the items yourself.
Is this covered anywhere in the documentation?

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

Re: properly extending the User model?

Post by aimeos » 25 Jan 2024, 14:14

Docs are a bit poor on this point. The article only describes how to create new managers in common:
https://aimeos.org/docs/latest/models/create-managers/

Items references via the "users_list" table (as well as all other *_list tables) can be automatically retrieved by adding the new (sub-)domain to the second parameter of the search() method. In your case it would be "customer/partner". For parent/child relationships, you need to overwrite the search() method of the manager at the moment to retrieve and add the child items.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

kopz
Posts: 8
Joined: 18 Jan 2024, 14:11

Re: properly extending the User model?

Post by kopz » 26 Jan 2024, 06:44

Thank you for pointing me in the right direction.

I now have a customer/partner manager with working create, find, search ... this is fine for managing new partners but I'm still a bit confused on how to add partners to a customer (if I manually add a record to usesr_list I see a working relation on customer-partner).

I am looking at the code for groups as an example:

Code: Select all

 $customer->setGroups([
    $group->get('customer.group.id')
]);
vendor/aimeos/aimeos-core/src/MShop/Customer/Item/Standard.php

Code: Select all

public function setGroups( array $ids ) : \Aimeos\MShop\Customer\Item\Iface
{
	$list = $this->getGroups();

	if( array_diff( $ids, $list ) !== [] || array_diff( $list, $ids ) !== [] )
	{
		$this->groups = $ids;
		$this->setModified();
	}

	return $this;
}
Where does the value of $this->groups get written to the database?

How should I approach this to get something like the following pseudo-code:

Code: Select all

 $customer->setPartner($partnerId);
edit:

ahhh, vendor/aimeos/aimeos-core/src/MShop/Customer/Manager/Base.php, addGroups

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

Re: properly extending the User model?

Post by aimeos » 27 Jan 2024, 10:42

If you want to use the users_list table, add a list item to the customer item and use the manager to save the customer item:
https://aimeos.org/docs/latest/models/m ... nced-items
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

Post Reply