Question

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

Was it helpful?

Solution

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();
    }
}

OTHER TIPS

Save method is deprecated in Magento 2 try this code:

<?php
/**
 * Copyright © 2018 MyCompany. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace MyCompany\MyModule\Setup;

use Magento\Customer\Api\GroupRepositoryInterface;
use Magento\Customer\Api\Data\GroupInterfaceFactory;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

/**
 * Class InstallData
 *
 * @package MyCompany\MyModule\Setup
 */
class InstallData implements InstallDataInterface
{
    /**
     * @var GroupInterfaceFactory
     */
    private $groupFactory;

    /**
     * @var GroupRepositoryInterface
     */
    private $groupRepository;

    /**
     * InstallData constructor.
     *
     * @param GroupInterfaceFactory $groupFactory
     * @param GroupRepositoryInterface $groupRepository
     */
    public function __construct(
        GroupInterfaceFactory $groupFactory,
        GroupRepositoryInterface $groupRepository
    ) {
        $this->groupFactory = $groupFactory;
        $this->groupRepository = $groupRepository;
    }

    /**
     * Installs data for a module
     *
     * @param ModuleDataSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();

        try {
            // Create the new group
            /** @var \Magento\Customer\Model\Group $group */
            $group = $this->groupFactory->create();
            $group
                ->setCode('My New Group')
                ->setTaxClassId(3);
            $this->groupRepository->save($group);
        } catch (\Exception $e) {

        }

        $setup->endSetup();
    }
}

Since the version 2.2.1 the use of the ->save() method from the Magento\Customer\Model\Group implementations has been deprecated.

Instead, you should use:

use Magento\Customer\Api\Data\GroupInterfaceFactory;
use Magento\Customer\Api\GroupRepositoryInterface;

instead

use Magento\Customer\Model\GroupFactory;

Using Robbie Averill solution as a baseline: https://magento.stackexchange.com/a/93789/15530

Pass those classes to the constructor like:

public function __construct(
        GroupInterfaceFactory $groupFactory,
        GroupRepositoryInterface $groupInterface) {
        $this->groupFactory = $groupFactory;
        $this->groupInterface = $groupInterface;
}

And then just use it as per this example: $this->groupInterface->save($group);

Where group is created using the factory creator like: $group = $this->groupFactory->create();

You can create a single/multiples customer groups by below script code

File Path : app/code/MyCompany/MyModule/Setup/InstallData.php

<?php
namespace MyCompany\MyModule\Setup;

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

class InstallData implements InstallDataInterface
{

    protected $groupFactory;

    /**
     * Constructor
     *
     * @param Magento\Customer\Model\GroupFactory $groupFactory
     */
    public function __construct(

        GroupFactory $groupFactory
    ) {

        $this->groupFactory = $groupFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function install(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {


        /** Create a customer Group */
        /** @var \Magento\Customer\Model\Group $group */
        $setup->startSetup();

    /* Create a multiple customer group */
        $setup->getConnection()->insertForce(
            $setup->getTable('customer_group'),
            ['customer_group_code' => 'YourNewCustomerGroup', 'tax_class_id' => 3]
        );
        $setup->getConnection()->insertForce(
            $setup->getTable('customer_group'),
            ['customer_group_code' => 'YourNewCustomerGroup', 'tax_class_id' => 3]
        );

        $setup->endSetup();
    }
}

Instead of hardwrite 3 for tax_class_id, you can use constant for default tax id : \Magento\Customer\Api\GroupRepositoryInterface::DEFAULT_TAX_CLASS_ID

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top