Magento 2 – How to Create Customer Group Programmatically

customer-groupmagento2setup-script

I'd like to know if it's possible (if so, how) to programmatically create a new customer group using the Magento 2 framework. Ideally I'd like to do this in a setup class.

Looking at the GroupRegistry class, I only see a retrieve() and remove() method. The class also doesn't extend anything so wouldn't inherit these methods – so I know this isn't the right place to look.

Of course, I'm probably looking in the wrong place or misunderstand the concept of how it works.

Do I even need to bother trying to find the class that will handle this, or should I just specify a GroupRepositoryInterface in the constructor of the class and assume it'll be provided by the object manager? The interface provides the save() method, which is what I need.

This is what I'm thinking so far:

namespace MyCompany\MyModule\Setup;

use Magento\Framework\Module\Setup\Migration;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Customer\Api\GroupRepositoryInterface;
use Magento\Customer\Model\GroupFactory;

class InstallData implements InstallDataInterface
{
    protected $groupFactory;
    protected $groupRepository;

    /**
     * I'd like a customer group factory and a customer group repository
     */
    public function __construct(
        GroupFactory $groupFactory,
        GroupRepositoryInterface $groupRepository
    ) {
        $this->groupFactory = $groupFactory;
        $this->groupRepository = $groupRepository;
    }

    public function install(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $setup->startSetup();

        // Create the new group
        $group = $this->groupFactory->create();

        $group->setCode('My New Group');
        $group->setTaxClassId(3); // magic number is only for demo..

        // Use the group repository to save it
        $this->groupRepository->save($group);

        $setup->endSetup();
    }
}

Am I close? If I run this, I get the following exception:

Argument 1 passed to Magento\Customer\Model\ResourceModel\GroupRepository\Interceptor::save() must implement interface Magento\Customer\Api\Data\GroupInterface, instance of Magento\Customer\Model\Group\Interceptor given

Best Answer

May as well answer this since I figured it out.

The problem with my example above is that I was trying to use the GroupRepository to push the new model to the database.

Instead, I should have just used $group->save() on the model returned by the GroupFactory:

<?php
namespace MyCompany\MyModule\Setup;

use Magento\Framework\Module\Setup\Migration;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Customer\Model\GroupFactory;

class InstallData implements InstallDataInterface
{
    protected $groupFactory;

    /**
     * I'd like a customer group factory please Sir!
     */
    public function __construct(GroupFactory $groupFactory) {
        $this->groupFactory = $groupFactory;
    }

    public function install(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $setup->startSetup();

        // Create the new group
        /** @var \Magento\Customer\Model\Group $group */
        $group = $this->groupFactory->create();
        $group
            ->setCode('My New Group')
            ->setTaxClassId(3) // magic numbers OK, core installers do it?!
            ->save();

        $setup->endSetup();
    }
}
Related Topic