Question

I want to create a company/company admin-user in Magento 2 (as what it does from the front-end/back-end panel) via a single API call.

Right now am doing with two API calls

First is creating a customer, then creating a company by giving superuser_id=" " the customer_id I created earlier.

Était-ce utile?

La solution

After lot of efforts and digging finaly got it done, note this for only B2B magento only.

We need to override the magento company module. create required files for module registration.php, module.xml

create webapi.xml at app/code/[vendor][overridemodule-name]/etc/webapi.xml

//give a unique url for api in this i have added /register here.

   <service class="[vendor]\[overridemodule-name]\Api\CompanyCustomInterface" method="createCompany"/>
    <resources>
        <resource ref="self"/>
    </resources>
</route>

Now create di.xml at app/code/[vendor][overridemodule-name]/etc/di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="[vendor]\[overridemodule-name]\Api\CompanyCustomInterface"
                type="[vendor]\[overridemodule-name]\Model\CompanyCustom"/>
</config>

Now create CompanyCustom.php in app/code/[vendor][overridemodule-name]/Model/CompanyCustom.php

namespace [vendor]\[overridemodule-name]\Model;

use [vendor]\[overridemodule-name]\Api\CompanyCustomInterface as CustomCompany;
use Magento\Company\Api\Data\CompanyInterface as CompanyInfo;
use Magento\Company\Model\Company\Save as CompanySave;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Customer\Model\Customer;
use Magento\Framework\Encryption\EncryptorInterface;
/**
 * Class that implements interface for data transfer object of company entity.
 *
 * @SuppressWarnings(PHPMD.ExcessivePublicCount)
 */
class CompanyCustom implements CustomCompany
{
    /**
     * @var CustomerRepositoryInterface
     */
    private $customerRepository;

    /**
     * @var CustomerInterface
     */
    private $customerInterface;

    /**
     * @var CustomerInterface
     */
    private $customerInfo;

    /**
     * @var CustomerFactory
     */
    private $customerLoad;

    /**
     * @var companyInfo
     */
    private $companyInfo;

    /**
     * @var EncryptorInterface
     */
    private $encrypt;

    /**
     * @var CompanySave
     */
    private $CompanySave;


    /**
     * @param CustomerRepositoryInterface $customerRepository
     * @param CustomerInterface $customerInfo
     * @param CustomerFactory $customerLoad
     * @param \Magento\Framework\Encryption\EncryptorInterface $encrypt
     * @param \Magento\Company\Api\Data\CompanyInterface $companyInfo
     * @param \Magento\Company\Model\Company\Save $companySave
     */
    public function __construct(
        CustomerRepositoryInterface $customerRepository,
        CustomerInterface $customerInfo,
        Customer $customerLoad,
        EncryptorInterface $encrypt,
        CompanyInfo $companyInfo,
        CompanySave $companySave
    ) {
        $this->customerRepository   = $customerRepository;
        $this->customerInfo         = $customerInfo;
        $this->customerLoad         = $customerLoad;
        $this->encrypt              = $encrypt;
        $this->companyInfo          = $companyInfo;
        $this->companySave          = $companySave;
    }

    /**
     * Post Company.
     *
     * @api
     * @param string[] $companyDetails
     * @param string[] $customerDetails
     * @param string[] $customerAddress
     * @return string[]
     */
    public function createCompany($companyDetails = null, $customerDetails = null, $customerAddress = null)
    {
        /*
         * Customer admin creation
         *
         */
        $websiteId  = 1;
        $this->customerInfo->setWebsiteId($websiteId);
        $this->customerLoad->setWebsiteId($websiteId);
        $email  = $customerDetails['email'];
        $firstName  = $customerDetails['firstname'];
        $lastName   = $customerDetails['lastname'];
        $customerData = $this->customerLoad->loadByEmail($email);
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        if ($customerData->getId()) {
            $customerId = $customerData->getId();
            return "Company admin already exists";
        } else {
            $password   = $customerDetails['password'];
            $groupId    = 1;
            $this->customerInfo->setEmail($email);
            $this->customerInfo->setFirstname($firstName);
            $this->customerInfo->setLastname($lastName);
            $this->customerInfo->setGroupId($groupId);
            $hashedPassword = $this->encrypt->getHash($password, true);
            $customerFinal = $this->customerRepository->save($this->customerInfo, $hashedPassword);
            $customerId = $customerFinal->getId();
            /*
             * Customer address creation
             *
             */
            $addresss = $objectManager->get('\Magento\Customer\Model\AddressFactory');
            $address = $addresss->create();
            $defaultBilling = 0;
            $defaultShipping = 0;
            if ($customerAddress['defaultBilling'] == "true") {
                $defaultBilling = 1;
            }
            if ($customerAddress['defaultShipping'] == "true") {
                $defaultShipping = 1;
            }
            $address->setCustomerId($customerId)
                    ->setFirstname($firstName)
                    ->setLastname($lastName)
                    ->setCountryId($customerAddress['countryId'])
                    ->setPostcode($customerAddress['postcode'])
                    ->setCity($customerAddress['city'])
                    ->setState($customerAddress['state'])
                    ->setTelephone($customerAddress['telephone'])
                    ->setFax($customerAddress['fax'])
                    ->setCompany($companyDetails['company_name'])
                    ->setStreet($customerAddress['street'])
                    ->setIsDefaultBilling($defaultBilling)
                    ->setIsDefaultShipping($defaultShipping)
                    ->setSaveInAddressBook('1');
            $address->save();
        }
        $resource = $objectManager->get('Magento\Framework\App\ResourceConnection');
        $write = $resource->getConnection();
        $companyFlag    = 'true';
        //Checking company already exists
        $company_query = "select entity_id from company where company_email = '".$companyDetails['company_email']."'";
        $companyExist = $write->fetchOne($company_query);
        if ($companyExist) {
            $companyId = $companyExist;
            return "Company already existed , skiping creation";
            $companyFlag = 'false';
        }

        $company_name_query = 'select entity_id from company where company_name = "'.$companyDetails['company_name'].'"';
        $companyNameExist = $write->fetchOne($company_name_query);
        if ($companyNameExist) {
            $companyId  = $companyNameExist;
            return "Company Name already existed , skiping creation";
            $companyFlag = 'false';
        }

        if ($companyFlag == 'true') {

            $companyObj     = $objectManager->create('Magento\Company\Model\Company');
            $companyObj->setCompanyName($companyDetails['company_name']);
            $companyObj->setCompanyEmail($companyDetails['company_email']);
            $companyObj->setStreet($companyDetails['street']);
            $companyObj->setCity($companyDetails['city']);
            $companyObj->setCountryId($companyDetails['country_id']);
            $companyObj->setRegionId($companyDetails['region_id']);
            $companyObj->setPostcode($companyDetails['postcode']);
            $companyObj->setTelephone($companyDetails['telephone']);
            $companyObj->setSuperUserId($customerId);
            $companyObj->setSalesRepresentativeId(1); // give default admin user ID here 
            $companyObj->setCustomerGroupId($companyDetails['customer_group_id']);
            $companyObj->save();
            $companyId  = $companyObj->getId();
            // company_advanced_customer_entity
            $insert_CACE_query = "UPDATE company_advanced_customer_entity set company_id = ".$companyId." where customer_id = ".$customerId;
            $write->query($insert_CACE_query);
            // company_credit
            $insert_CC_query = "INSERT INTO company_credit(company_id,balance,currency_code,exceed_limit) VALUES (".$companyId.",'0.0000','USD','0')";
            $write->query($insert_CC_query);
            //company_payment
            $insert_CP_query = "INSERT INTO company_payment(company_id,applicable_payment_method,available_payment_methods,use_config_settings) VALUES (".$companyId.",'0','braintree','1')";
            $write->query($insert_CP_query);
            //company_roles
            $insert_CR_query = "INSERT INTO company_roles(sort_order,role_name,company_id) VALUES ('0','Default User',".$companyId.")";
            $write->query($insert_CR_query);
            $role_id = $write->lastInsertId();
            //company_structure
            $insert_CS_query = "INSERT INTO company_structure(parent_id,entity_id,entity_type,path,position,level) VALUES ('0','".$companyId."','0','0','0','0')";
            $write->query($insert_CS_query);
            $cs_id = $write->lastInsertId();
            $update_CS_query = "UPDATE company_structure set path = '".$cs_id."' where structure_id = ".$cs_id;
            $write->query($update_CS_query);
            //company_permissions
            $permission_array   = ['Magento_Company::index' =>  'allow','Magento_Sales::all' => 'allow','Magento_Sales::place_order' => 'allow','Magento_Sales::payment_account' => 'deny','Magento_Sales::view_orders' => 'allow','Magento_Sales::view_orders_sub' => 'deny','Magento_NegotiableQuote::all' => 'allow','Magento_NegotiableQuote::view_quotes' =>   'allow','Magento_NegotiableQuote::manage' => 'allow','Magento_NegotiableQuote::checkout' => 'allow','Magento_NegotiableQuote::view_quotes_sub' => 'deny','Magento_Company::view' =>'allow','Magento_Company::view_account' => 'allow','Magento_Company::edit_account' =>    'deny','Magento_Company::view_address' => 'allow','Magento_Company::edit_address' =>'deny','Magento_Company::contacts' => 'allow','Magento_Company::payment_information' => 'allow','Magento_Company::user_management' => 'allow','Magento_Company::roles_view' => 'deny','Magento_Company::roles_edit' => 'deny','Magento_Company::users_view' => 'allow','Magento_Company::users_edit' => 'deny','Magento_Company::credit' => 'deny','Magento_Company::credit_history' => 'deny'];
            foreach ($permission_array as $perm_resource => $permission_val) {
                $insert_perm_query = "INSERT INTO company_permissions(role_id,resource_id,permission) VALUES (".$role_id.",'".$perm_resource."','".$permission_val."')";
                $write->query($insert_perm_query);
            }

        } else {

            $insert_CACE_query = "UPDATE company_advanced_customer_entity set company_id = ".$companyId." where customer_id = ".$customerId;
            $write->query($insert_CACE_query);
        }
        $result_array = ['success' => 'Company created successfully', 'customer_id' => $customerId, 'company_id' => $companyId];
        $result = json_encode($result_array);
        return $result;
    }
}

Now lets create API interfaces app/code/[vendor][overridemodule-name]/Api/CompanyCustomInterface.php

namespace [vendor]\[overridemodule-name]\Api;

/**
 * Company CRUD interface.
 * @api
 */
interface CompanyCustomInterface
{
    /**
     * Post Company.
     *
     * @api
     * @param string[] $companyDetails
     * @param string[] $customerDetails
     * @param string[] $customerAddress
     * @return string[]
     */
    public function createCompany($companyDetails = null, $customerDetails = null, $customerAddress = null);
}

ALL Set, This will crate an company and customer in magento when we call request thru REST API.

Api body can be

{
    "companyDetails" : {
        "company_name" : "Test company yes",
        "company_email" : "testcpm@mail.com",
        "street" : "100 big tree avenue",
        "city" : "san francisco",
        "country_id" : "US",
        "region" : "CA",
        "region_id" : "12",
        "postcode" : "32342",
        "telephone" : "9876543233",
        "super_user_id" : 0,
        "customer_group_id" : 1
    },
    "customerDetails" : {
        "email" : "testsfssa1212@mail.com",
        "firstname" : "asmdfda",
        "lastname" : "aniksdf",
        "password" : ""
    },
    "customerAddress" : {
       "firstname" : "ABC",
       "lastname" : "XYZ",
       "countryId" : "US",
       "street" : "1234 Example Street",
       "city" : "princeton",
       "state" : "NJ",
       "telephone" : "3322332233",
       "fax" : "4455445544",
       "postcode" : "11911",
       "defaultBilling" : "true",
       "defaultShipping" : "true"
    }
}

Note: this can only be used for POST Method For UPDATE,DELETE,GET use default magento api's.

Autres conseils

You can follow the simple 6 steps to create your custom web API in Magento 2

Step 1 – Create webapi.xml under your custom module \Scommerce\Custom\etc\

<route url="/V1/custom/:categoryId/products" method="GET">
    <service class="Scommerce\Custom\Api\CategoryLinkManagementInterface" method="getAssignedProducts" />
    <resources>
        <resource ref="self"/>
    </resources>
</route>

Step 2 – Lets now create the main interface file for our web API

CategoryLinkManagementInterface.php under Scommerce\Custom\Api\ as specified in webapi.xml in Step 1

namespace Scommerce\Custom\Api;

/**
 * @api
 */
interface CategoryLinkManagementInterface
{
    /**
     * Get products assigned to a category
     *
     * @param int $categoryId
     * @return \Scommerce\Custom\Api\Data\CategoryProductLinkInterface[]
     */
    public function getAssignedProducts($categoryId);
}

Step 3 – Based on the return parameter in Step 2, let’s create our data interface CategoryProductLinkInterface.php under \Scommerce\Custom\Api\Data\

namespace Scommerce\Custom\Api\Data;

/**
 * @api
 */
interface CategoryProductLinkInterface
{
    /**
     * @return string|null
     */
    public function getSku();

    /**
     * @param string $sku
     * @return $this
     */
    public function setSku($sku);

    /**
     * @return string|null
     */
    public function getName();

    /**
     * @param string $name
     * @return $this
     */
    public function setName($name);

    /**
     * @return float|null
     */
    public function getPrice();

    /**
     * @param float $price
     * @return $this
     */
    public function setPrice($price);

    /**
     * @return int|null
     */
    public function getPosition();

    /**
     * @param int $position
     * @return $this
     */
    public function setPosition($position);

    /**
     * @return string|null
     */
    public function getCategoryDescription();

    /**
     * @param string $description
     * @return $this
     */
    public function setCategoryDescription($description);
}

Step 4 – Now our interface files are created, let’s create our model classes where we can put the actual business logic, to do so we would need to specify this in our di.xml file under \Scommerce\Custom\etc\

<config ...>
    <preference for="Scommerce\Custom\Api\CategoryLinkManagementInterface" type="Scommerce\Custom\Model\CategoryLinkManagement" />
    <preference for="Scommerce\Custom\Api\Data\CategoryProductLinkInterface" type="Scommerce\Custom\Model\CategoryProductLink" />
</config>

Step 5 – Let’s create our first model class CategoryLinkManagement.php under Scommerce\Custom\Model\ as specified in di.xml

namespace Scommerce\Custom\Model;

/**
 * Class CategoryLinkManagement
 */
class CategoryLinkManagement implements \Scommerce\Custom\Api\CategoryLinkManagementInterface
{
    /**
     * @var \Magento\Catalog\Api\CategoryRepositoryInterface
     */
    protected $categoryRepository;

    /**
     * @var \Scommerce\Custom\Api\Data\CategoryProductLinkInterfaceFactory
     */
    protected $productLinkFactory;

    /**
     * CategoryLinkManagement constructor.
     *
     * @param \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository
     * @param \Scommerce\Custom\Api\Data\CategoryProductLinkInterfaceFactory $productLinkFactory
     */
    public function __construct(
        \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository,
        \Scommerce\Custom\Api\Data\CategoryProductLinkInterfaceFactory $productLinkFactory
    ) {
        $this->categoryRepository = $categoryRepository;
        $this->productLinkFactory = $productLinkFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function getAssignedProducts($categoryId)
    {
        $category = $this->categoryRepository->get($categoryId);
        if (!$category->getIsActive()) {
            return [[
                'error' => true,
                'error_desc' => 'Category is disabled'
            ]];
        }
        $categoryDesc = $category->getDescription();

        /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $products */
        $products = $category->getProductCollection()
            ->addFieldToSelect('position')
            ->addFieldToSelect('name')
            ->addFieldToSelect('price');

        /** @var \Scommerce\Custom\Api\Data\CategoryProductLinkInterface[] $links */
        $links = [];

        /** @var \Magento\Catalog\Model\Product $product */
        foreach ($products->getItems() as $product) {
            /** @var \Scommerce\Custom\Api\Data\CategoryProductLinkInterface $link */
            $link = $this->productLinkFactory->create();
            $link->setSku($product->getSku())
                ->setName($product->getName())
                ->setPrice($product->getFinalPrice())
                ->setPosition($product->getData('cat_index_position'))
                ->setCategoryDescription($categoryDesc);
            $links[] = $link;
        }

        return $links;
    }
}

Step 6 – Lets now create our second model class CategoryProductLink.php under Scommerce\Custom\Model\ as specified in di.xml

namespace Scommerce\Custom\Model;

/**
 * @codeCoverageIgnore
 */
class CategoryProductLink implements \Scommerce\Custom\Api\Data\CategoryProductLinkInterface
{
    /**#@+
     * Constant for confirmation status
     */
    const KEY_SKU                   = 'sku';
    const KEY_NAME                  = 'name';
    const KEY_PRICE                 = 'price';
    const KEY_CATEGORY_DESC         = 'category_description';
    const KEY_POSITION              = 'position';
    /**#@-*/

    /**
     * {@inheritdoc}
     */
    public function getSku()
    {
        return $this->_get(self::KEY_SKU);
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return $this->_get(self::KEY_NAME);
    }

    /**
     * {@inheritdoc}
     */
    public function getPosition()
    {
        return $this->_get(self::KEY_POSITION);
    }

    /**
     * {@inheritdoc}
     */
    public function getPrice()
    {
        return $this->_get(self::KEY_PRICE);
    }

    /**
     * {@inheritdoc}
     */
    public function getCategoryDescription()
    {
        return $this->_get(self::KEY_CATEGORY_DESC);
    }

    /**
     * @param string $sku
     * @return $this
     */
    public function setSku($sku)
    {
        return $this->setData(self::KEY_SKU, $sku);
    }

    /**
     * @param string $name
     * @return $this
     */
    public function setName($name)
    {
        return $this->setData(self::KEY_NAME, $name);
    }

    /**
     * @param int $position
     * @return $this
     */
    public function setPosition($position)
    {
        return $this->setData(self::KEY_POSITION, $position);
    }

    /**
     * @param float $price
     * @return $this
     */
    public function setPrice($price)
    {
        return $this->setData(self::KEY_PRICE, $price);
    }

    /**
     * @param string $description
     * @return $this
     */
    public function setCategoryDescription($description)
    {
        return $this->setData(self::KEY_CATEGORY_DESC, $description);
    }

}

The above will allow us to call our first Magento 2 web API using the customer token. To retrieve admin or custom token, please have a look at Magento official token retrieval documentation

source: https://www.scommerce-mage.com/blog/magento-2-how-to-create-custom-api.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top