We sacrifice by not doing any other technology, so that you get the best of Magento.

We sacrifice by not doing any other technology, so that you get the best of Magento.

    How to add email cc field to customer account area in admin panel Magento 2

    If you want to send transnational emails for another cc mail to the customer, then follow below steps.

    Step 1: Create a registration file like Magemonkey/EmailCC/registration.php

    <?php
    MagentoFrameworkComponentComponentRegistrar::register(
        MagentoFrameworkComponentComponentRegistrar::MODULE,
        'Magemonkey_EmailCC',
        __DIR__
    );

    Step 2: Create di file like Magemonkey/EmailCC/etc/di.xml

    <?xml version="1.0" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
        <type name="MagentoFrameworkMailTemplateTransportBuilder">
            <plugin disabled="false" name="Magemonkey_EmailCC_Plugin_Magento_Framework_Mail_Template_TransportBuilder" sortOrder="10" type="MagemonkeyEmailCCPluginMagentoFrameworkMailTemplateTransportBuilder"/>
        </type>
    </config>

    Step 3: Create module file like Magemonkey/EmailCC/etc/module.xml

    <?xml version="1.0" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="Magemonkey_EmailCC" setup_version="1.1.0">
            <sequence>
                <module name="Magento_Customer"/>
                <module name="Magento_Framework"/>
            </sequence>
        </module>
    </config>

    Step 4: Create extension attributes file like Magemonkey/EmailCC/etc/extension_attributes.xml

    <?xml version="1.0" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
        <extension_attributes for="MagentoCustomerApiDataCustomerInterface">
            <attribute code="mm_emailcc" type="string"/>
        </extension_attributes>
    </config>

    Step 5: Create plugin file like Magemonkey/EmailCC/Plugin/Magento/Framework/Mail/Template/TransportBuilder.php

    <?php
    
    namespace MagemonkeyEmailCCPluginMagentoFrameworkMailTemplate;
    
    /**
     * Plugin to add customer email cc
     */
    class TransportBuilder
    {
        /**
         * @var MagentoCustomerApiCustomerRepositoryInterface
         */
        protected $customerRepositoryInterface;
    
        /**
         * @var MagentoCustomerModelSession
         */
        protected $customerSession;
    
        /**
         * @var PsrLogLoggerInterface
         */
        protected $logger;
    
        public function __construct(
            MagentoCustomerApiCustomerRepositoryInterface $customerRepositoryInterface,
            MagentoCustomerModelSession $customerSession,
            PsrLogLoggerInterface $logger
        ) {
            $this->customerRepositoryInterface = $customerRepositoryInterface;
            $this->customerSession = $customerSession;
            $this->logger = $logger;
        }
    
        public function beforeGetTransport(
            MagentoFrameworkMailTemplateTransportBuilder $subject
        ) {
            try {
                $ccEmailAddresses = $this->getEmailCopyTo();
                if (!empty($ccEmailAddresses)) {
                    foreach ($ccEmailAddresses as $ccEmailAddress) {
                        $subject->addCc(trim($ccEmailAddress));
                        $this->logger->debug((string) __('Added customer CC: %1', trim($ccEmailAddress)));
                    }
                }
            } catch (Exception $e) {
                $this->logger->error((string) __('Failure to add customer CC: %1', $e->getMessage()));
            }
            return [];
        }
    
        /**
         * Get customer id from session
         */
        public function getCustomerIdFromSession()
        {
            if ($customer = $this->customerSession->getCustomer()) {
                return $customer->getId();
            }
            return null;
        }
    
        /**
         * Return email copy_to list
         * @return array|bool
         */
        public function getEmailCopyTo()
        {
            $customerId = $this->getCustomerIdFromSession();
            if (!$customerId) {
                return false;
            }
    
            $customer = $this->getCustomerById($customerId);
            if (!$customer) {
                return false;
            }
    
            $emailCc = $customer->getCustomAttribute('mm_emailcc');
            $customerEmailCC = $emailCc ? $emailCc->getValue() : null;
    
            if (!empty($customerEmailCC)) {
                return explode(',', trim($customerEmailCC));
            }
    
            return false;
        }
    
        /**
         * Get customer by Id.
         * @param int $customerId
         * @return MagentoCustomerModelDataCustomer
         */
        public function getCustomerById($customerId)
        {
            try {
                return $this->customerRepositoryInterface->getById($customerId);
            } catch (Exception $e) {
                $this->logger->critical($e);
                return false;
            }
        }
    }

    Step 6: Create a setup file like Magemonkey/EmailCC/Setup/Patch/Data/AddEmailCcCustomerAttribute.php

    <?php
    
    declare(strict_types=1);
    
    namespace MagemonkeyEmailCCSetupPatchData;
    
    use MagentoCustomerModelCustomer;
    use MagentoCustomerSetupCustomerSetup;
    use MagentoCustomerSetupCustomerSetupFactory;
    use MagentoEavModelEntityAttributeSet;
    use MagentoEavModelEntityAttributeSetFactory;
    use MagentoFrameworkSetupModuleDataSetupInterface;
    use MagentoFrameworkSetupPatchDataPatchInterface;
    use MagentoFrameworkSetupPatchPatchRevertableInterface;
    
    class AddEmailCcCustomerAttribute implements DataPatchInterface, PatchRevertableInterface
    {
    
        /**
         * @var ModuleDataSetupInterface
         */
        private $moduleDataSetup;
        /**
         * @var CustomerSetup
         */
        private $customerSetupFactory;
        /**
         * @var SetFactory
         */
        private $attributeSetFactory;
    
        /**
         * Constructor
         *
         * @param ModuleDataSetupInterface $moduleDataSetup
         * @param CustomerSetupFactory $customerSetupFactory
         * @param SetFactory $attributeSetFactory
         */
        public function __construct(
            ModuleDataSetupInterface $moduleDataSetup,
            CustomerSetupFactory $customerSetupFactory,
            SetFactory $attributeSetFactory
        ) {
            $this->moduleDataSetup = $moduleDataSetup;
            $this->customerSetupFactory = $customerSetupFactory;
            $this->attributeSetFactory = $attributeSetFactory;
        }
    
        /**
         * {@inheritdoc}
         */
        public function apply()
        {
            $this->moduleDataSetup->getConnection()->startSetup();
            /** @var CustomerSetup $customerSetup */
            $customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
            $customerEntity = $customerSetup->getEavConfig()->getEntityType(Customer::ENTITY);
            $attributeSetId = $customerEntity->getDefaultAttributeSetId();
            
            /** @var $attributeSet Set */
            $attributeSet = $this->attributeSetFactory->create();
            $attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);
            
            $customerSetup->addAttribute(
                Customer::ENTITY,
                'mm_emailcc',
                [
                    'type' => 'varchar',
                    'label' => 'Email CC',
                    'input' => 'text',
                    'source' => '',
                    'required' => false,
                    'visible' => true,
                    'position' => 500,
                    'system' => false,
                    'backend' => '',
                    'is_used_in_grid' => true,
                    'is_visible_in_grid' => true,
                    'is_filterable_in_grid' => true,
                    'is_searchable_in_grid' => false,
                    'note' => __("Comma separated"),
                ]
            );
            
            $attribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'mm_emailcc');
            $attribute->addData([
                'used_in_forms' => [
                    'adminhtml_customer',
                    'adminhtml_checkout',
                    'customer_account_create',
                    'customer_account_edit'
                ]
            ]);
            $attribute->addData([
                'attribute_set_id' => $attributeSetId,
                'attribute_group_id' => $attributeGroupId
            
            ]);
            $attribute->save();
    
            $this->moduleDataSetup->getConnection()->endSetup();
        }
    
        public function revert()
        {
            $this->moduleDataSetup->getConnection()->startSetup();
            /** @var CustomerSetup $customerSetup */
            $customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
            $customerSetup->removeAttribute(Customer::ENTITY, 'mm_emailcc');
            $this->moduleDataSetup->getConnection()->endSetup();
        }
    
        /**
         * {@inheritdoc}
         */
        public function getAliases()
        {
            return [];
        }
    
        /**
         * {@inheritdoc}
         */
        public static function getDependencies()
        {
            return [];
        }
    }

    Step 7: Create layout file like Magemonkey/EmailCC/view/frontend/layout/customer_account_edit.xml

    <?xml version="1.0"?>
    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
        <update handle="customer_account"/>
        <body>
            <referenceContainer name="content">
                <block class="MagentoCustomerBlockFormEdit" name="customer_edit" template="Magento_Customer::form/edit.phtml" cacheable="false">
                    <container name="form.additional.info" as="form_additional_info">
                        <block class="MagentoCustomerBlockFormEdit" as="customer_edit_cc" name="customer.edit.css" template="Magemonkey_EmailCC::form/mm_emailcc.phtml"/>
                    </container>
                </block>
            </referenceContainer>
        </body>
    </page>

    Step 8 : Create template file like Magemonkey/EmailCC/view/frontend/templates/form/mm_emailcc.phtml

    <?php
    $emailCc = $block->getCustomer()->getCustomAttribute('mm_emailcc');
    $customerEmailCC = $emailCc ? $emailCc->getValue() : null;
    ?>
    <fieldset class="fieldset create account" >
        <legend class="legend">
            <span><?=$block->escapeHtmlAttr(__('Email Copy To'))?></span>
        </legend>
        <br>
        <div class="field mm_emailcc">
            <label for="mm_emailcc" class="label">
                <span><?=$block->escapeHtmlAttr(__('Email Address (Comma separated)'));?></span>
            </label>
            <div class="control">
                <input id="mm_emailcc" 
                       class="input-text" 
                       name="mm_emailcc" 
                       value="<?=$block->escapeHtmlAttr($customerEmailCC);?>" 
                       title="<?=$block->escapeHtmlAttr(__('Email Copy To'));?>" 
                       type="text" 
                       autocomplete="off" />
            </div>
        </div>
    </fieldset>

    Step 9: Then after run the below commands.

    php bin/magento setup:upgrade
    php bin/magento setup:static-content:deploy
    php bin/magento cache:flush

    That’s it…

    Now clean cache and check  “Admin > CUSTOMERS > Customers > All Customers > Edit any customer”. Your new email address cc field option should appear here in the last.

    How to add BCC or other email address field option to General & Contacts in Magento 2 admin panel?

    If, you want to send another contact mail copy to another email address as a BCC? Then follow the below steps.

    Step 1: Create a registration file like Magemonkeys/ContactCc/registration.php

    <?php
    MagentoFrameworkComponentComponentRegistrar::register(
        MagentoFrameworkComponentComponentRegistrar::MODULE,
        'Magemonkey_ContactCc',
        __DIR__
    );

    Step 2: Create di file like Magemonkeys/ContactCc/etc/di.xml

    <?xml version="1.0" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
        <preference for="MagentoContactControllerIndexPost" type="MagemonkeyContactCcRewriteMagentoContactControllerIndexPost"/>
    </config>

    Step 3: Create module file like Magemonkeys/ContactCc/etc/module.xml

    <?xml version="1.0" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="Magemonkey_ContactCc" setup_version="1.0.2"/>
    </config>

    Step 4: Create a system file like Magemonkeys/ContactCc/etc/adminhtml/system.xml

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
        <system>
            <section id="contact" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
                <tab>general</tab>
                <group id="email" translate="label" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Email Options</label>
                    <field id="copy_to" translate="label comment" type="text" sortOrder="200" showInDefault="1" showInWebsite="1" showInStore="1">
                        <label>Send Contact Us Email Copy To</label>
                        <comment>Comma-separated</comment>
                    </field>                
                </group>
            </section>
        </system>
    </config>

    Step 5: Create helper file like Magemonkeys/ContactCc/Helper/Email.php

    <?php
    
    namespace MagemonkeyContactCcHelper;
    
    use MagentoFrameworkAppHelperAbstractHelper;
    use MagentoFrameworkAppHelperContext;
    use MagentoStoreModelStoreManagerInterface;
    use MagentoFrameworkAppConfigScopeConfigInterface;
    
    /**
     * Class Email
     * @package MagemonkeyContactCcHelper
     */
    class Email extends AbstractHelper
    {
        const XML_PATH_EMAIL_COPY_METHOD = 'contact/email/copy_method';
        const XML_PATH_EMAIL_COPY_TO = 'contact/email/copy_to';
    
        /**
         * @var StoreManagerInterface
         */
        private $storeManager;
    
        /**
         * @var ScopeConfigInterface
         */
        protected $scopeConfig;
    
        /**
         * Email constructor.
         * @param Context $context
         * @param StoreManagerInterface $storeManager
         * @param ScopeConfigInterface $scopeConfig
         */
        public function __construct(
            Context $context,
            StoreManagerInterface $storeManager,
            ScopeConfigInterface $scopeConfig
        ) {
            $this->storeManager = $storeManager;
            $this->scopeConfig = $scopeConfig;
            parent::__construct($context);
        }
    
        /**
         * @return array|bool
         * @throws MagentoFrameworkExceptionNoSuchEntityException
         */
        public function getEmailCopyTo()
        {
            $data = $this->getConfigValue(self::XML_PATH_EMAIL_COPY_TO, $this->storeManager->getStore()->getId());
            if (!empty($data)) {
                return explode(',', $data);
            }
            return false;
        }
    
        /**
         * @return mixed
         * @throws MagentoFrameworkExceptionNoSuchEntityException
         */
        public function getCopyMethod()
        {
            return $this->getConfigValue(self::XML_PATH_EMAIL_COPY_METHOD, $this->storeManager->getStore()->getId());
        }
    
        /**
         * @param $xmlPath
         * @param null $storeId
         * @return mixed
         */
        public function getConfigValue($xmlPath, $storeId = null)
        {
            return $this->scopeConfig->getValue(
                $xmlPath,
                MagentoStoreModelScopeInterface::SCOPE_STORE,
                $storeId
            );
        }
    }

    Step 6: Create PHP file like Magemonkey/ContactCc/Rewrite/Magento/Contact/Controller/Index/Post.php

    <?php
    
    namespace MagemonkeyContactCcRewriteMagentoContactControllerIndex;
    
    use MagentoFrameworkAppArea;
    use MagentoContactModelConfigInterface;
    use MagentoFrameworkAppActionContext;
    use MagentoFrameworkDataObject;
    use MagentoFrameworkAppRequestDataPersistorInterface;
    use MagemonkeyContactCcHelperEmail;
    use PsrLogLoggerInterface;
    use MagentoFrameworkExceptionLocalizedException;
    use MagentoContactModelMailInterface;
    use MagentoFrameworkAppObjectManager;
    use MagentoFrameworkTranslateInlineStateInterface;
    use MagentoStoreModelStoreManagerInterface;
    use MagentoFrameworkMailTemplateTransportBuilder;
    
    /**
     * Class Post
     * @package MagemonkeyContactCcRewriteMagentoContactControllerIndex
     */
    class Post extends MagentoContactControllerIndexPost
    {
        /**
         * @var Context
         */
        private $context;
    
        /**
         * @var ConfigInterface
         */
        private $contactsConfig;
    
        /**
         * @var MailInterface
         */
        private $mail;
    
        /**
         * @var DataPersistorInterface
         */
        private $dataPersistor;
    
        /**
         * @var LoggerInterface
         */
        private $logger;
    
        /**
         * @var Email
         */
        private $helper;
    
        /**
         * @var StateInterface
         */
        private $inlineTranslation;
    
        /**
         * @var TransportBuilder
         */
        private $transportBuilder;
    
        /**
         * @var StoreManagerInterface
         */
        private $storeManager;
    
        /**
         * Post constructor.
         * @param Context $context
         * @param ConfigInterface $contactsConfig
         * @param MailInterface $mail
         * @param DataPersistorInterface $dataPersistor
         * @param Email $helper
         * @param LoggerInterface|null $logger
         * @param TransportBuilder $transportBuilder
         * @param StateInterface $inlineTranslation
         * @param StoreManagerInterface|null $storeManager
         */
        public function __construct(
            Context $context,
            ConfigInterface $contactsConfig,
            MailInterface $mail,
            DataPersistorInterface $dataPersistor,
            Email $helper,
            LoggerInterface $logger = null,
            TransportBuilder $transportBuilder,
            StateInterface $inlineTranslation,
            StoreManagerInterface $storeManager = null
        ) {
            $this->context = $context;
            $this->contactsConfig = $contactsConfig;
            $this->mail = $mail;
            $this->dataPersistor = $dataPersistor;
            $this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class);
            $this->helper = $helper;
            $this->transportBuilder = $transportBuilder;
            $this->inlineTranslation = $inlineTranslation;
            $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class);
            parent::__construct($context, $contactsConfig, $mail, $dataPersistor, $logger);
        }
    
        /**
         * Contact store
         * @return MagentoFrameworkControllerResultRedirect
         */
        public function execute()
        {
            if (!$this->getRequest()->isPost()) {
                return $this->resultRedirectFactory->create()->setPath('*/*/');
            }
            try {
                $this->sendEmail($this->validatedParams());
                $this->messageManager->addSuccessMessage(
                    __('Thanks for contacting us with your comments and questions. We'll respond to you very soon.')
                );
                $this->dataPersistor->clear('contact_us');
            } catch (LocalizedException $e) {
                $this->messageManager->addErrorMessage($e->getMessage());
                $this->dataPersistor->set('contact_us', $this->getRequest()->getParams());
            } catch (Exception $e) {
                $this->logger->critical($e);
                $this->messageManager->addErrorMessage(
                    __('An error occurred while processing your form. Please try again later.')
                );
                $this->dataPersistor->set('contact_us', $this->getRequest()->getParams());
            }
            return $this->resultRedirectFactory->create()->setPath('contact/index');
        }
    
        /**
         * Send email
         * @param array $post
         * @throws MagentoFrameworkExceptionMailException
         * @throws MagentoFrameworkExceptionNoSuchEntityException
         */
        public function sendEmail($post)
        {
            $this->send(
                $post['email'],
                ['data' => new DataObject($post)]
            );
        }
    
        /**
         * Send email
         * @param $replyTo
         * @param array $variables
         * @throws MagentoFrameworkExceptionMailException
         * @throws MagentoFrameworkExceptionNoSuchEntityException
         */
        public function send($replyTo, array $variables)
        {
            $replyToName = !empty($variables['data']['name']) ? $variables['data']['name'] : null;
    
            $this->inlineTranslation->suspend();
    
            try {
                $this->configureEmailTemplate($replyTo, $replyToName, $variables);
                $this->transportBuilder->addTo($this->contactsConfig->emailRecipient());
    
                $copyTo = $this->helper->getEmailCopyTo();
                if (!empty($copyTo) && $this->helper->getCopyMethod() == 'bcc') {
                    foreach ($copyTo as $email) {
                        $this->transportBuilder->addBcc($email);
                    }
                }
    
                $transport = $this->transportBuilder->getTransport();
                $transport->sendMessage();
    
                $this->sendCopyTo($replyTo, $replyToName, $variables);
            } catch (Exception $e) {
                $this->logger->error($e->getMessage());
            } finally {
                $this->inlineTranslation->resume();
            }
        }
    
        /**
         * Prepare and send copy email message
         * @param string $replyTo
         * @param string $replyToName
         * @param array $variables
         * @return void
         */
        public function sendCopyTo($replyTo, $replyToName, $variables)
        {
            $copyTo = $this->helper->getEmailCopyTo();
            if (!empty($copyTo) && $this->helper->getCopyMethod() == 'copy') {
                foreach ($copyTo as $email) {
                    $this->configureEmailTemplate($replyTo, $replyToName, $variables);
                    $this->transportBuilder->addTo($email);
                    $transport = $this->transportBuilder->getTransport();
                    $transport->sendMessage();
                }
            }
        }
    
        /**
         * Configure email template
         * @param string $replyTo
         * @param string $replyToName
         * @param array $variables
         * @return void
         */
        protected function configureEmailTemplate($replyTo, $replyToName, $variables)
        {
            $this->transportBuilder->setTemplateIdentifier($this->contactsConfig->emailTemplate());
            $this->transportBuilder->setTemplateOptions([
                'area' => Area::AREA_FRONTEND,
                'store' => $this->storeManager->getStore()->getId()
            ]);
            $this->transportBuilder->setTemplateVars($variables);
            $this->transportBuilder->setFrom($this->contactsConfig->emailSender());
            $this->transportBuilder->setReplyTo($replyTo, $replyToName);
        }
    
        /**
         * Validate form params
         * @return array
         * @throws Exception
         */
        private function validatedParams()
        {
            $request = $this->getRequest();
            if (trim($request->getParam('name')) === '') {
                throw new LocalizedException(__('Name is missing'));
            }
            if (trim($request->getParam('comment')) === '') {
                throw new LocalizedException(__('Comment is missing'));
            }
            if (false === strpos($request->getParam('email'), '@')) {
                throw new LocalizedException(__('Invalid email address'));
            }
            if (trim($request->getParam('hideit')) !== '') {
                throw new LocalizedException(__('Error'));
            }
            return $request->getParams();
        }
    }

    Step 7: Then after run the below commands.

    php bin/magento setup:upgrade
    php bin/magento setup:static-content:deploy
    php bin/magento cache:flush

    That’s it…

    Now clean cache and check in Admin > STORES > Settings > Configuration > GENERAL > Contacts. Your new email address field option appear here.

    Disable MSI module in magento 2.3.X and 2.4.X

    Run the below command to disable MSI in Magento 2.3.3 or Magento 2.3.4:

    php bin/magento module:disable -f 
    Magento_Inventory
    Magento_InventoryAdminUi
    Magento_InventoryApi
    Magento_InventoryBundleProduct
    Magento_InventoryBundleProductAdminUi
    Magento_InventoryCatalog
    Magento_InventorySales
    Magento_InventoryCatalogAdminUi
    Magento_InventoryCatalogApi
    Magento_InventoryCatalogSearch
    Magento_InventoryConfigurableProduct
    Magento_InventoryConfigurableProductAdminUi
    Magento_InventoryConfigurableProductIndexer
    Magento_InventoryConfiguration
    Magento_InventoryConfigurationApi
    Magento_InventoryGroupedProduct
    Magento_InventoryGroupedProductAdminUi
    Magento_InventoryGroupedProductIndexer
    Magento_InventoryImportExport
    Magento_InventoryIndexer
    Magento_InventoryLowQuantityNotification
    Magento_InventoryLowQuantityNotificationAdminUi
    Magento_InventoryLowQuantityNotificationApi
    Magento_InventoryMultiDimensionalIndexerApi
    Magento_InventoryProductAlert
    Magento_InventoryReservations
    Magento_InventoryReservationsApi
    Magento_InventoryCache
    Magento_InventorySalesAdminUi
    Magento_InventorySalesApi
    Magento_InventorySalesFrontendUi
    Magento_InventoryShipping
    Magento_InventorySourceDeductionApi
    Magento_InventorySourceSelection
    Magento_InventorySourceSelectionApi
    Magento_InventoryShippingAdminUi
    Magento_InventoryDistanceBasedSourceSelectionAdminUi
    Magento_InventoryDistanceBasedSourceSelectionApi
    Magento_InventoryElasticsearch
    Magento_InventoryExportStockApi
    Magento_InventoryReservationCli
    Magento_InventoryExportStock
    Magento_CatalogInventoryGraphQl
    Magento_InventorySetupFixtureGenerator
    Magento_InventoryAdvancedCheckout
    Magento_InventoryDistanceBasedSourceSelection
    Magento_InventoryRequisitionList
    Magento_InventoryGraphQl

    Run the below command to disable MSI in Magento 2.4.X:

    php bin/magento module:disable -f
    Magento_Inventory
    Magento_InventoryAdminUi
    Magento_InventoryAdvancedCheckout
    Magento_InventoryApi
    Magento_InventoryBundleProduct
    Magento_InventoryBundleProductAdminUi
    Magento_InventoryCatalog
    Magento_InventorySales
    Magento_InventoryCatalogAdminUi
    Magento_InventoryCatalogApi
    Magento_InventoryCatalogSearch
    Magento_InventoryConfigurableProduct
    Magento_InventoryConfigurableProductAdminUi
    Magento_InventoryConfigurableProductIndexer
    Magento_InventoryConfiguration
    Magento_InventoryConfigurationApi
    Magento_InventoryDistanceBasedSourceSelection
    Magento_InventoryDistanceBasedSourceSelectionAdminUi
    Magento_InventoryDistanceBasedSourceSelectionApi
    Magento_InventoryElasticsearch
    Magento_InventoryExportStockApi
    Magento_InventoryIndexer
    Magento_InventorySalesApi
    Magento_InventoryGroupedProduct
    Magento_InventoryGroupedProductAdminUi
    Magento_InventoryGroupedProductIndexer
    Magento_InventoryImportExport
    Magento_InventoryCache
    Magento_InventoryLowQuantityNotification
    Magento_InventoryLowQuantityNotificationApi
    Magento_InventoryMultiDimensionalIndexerApi
    Magento_InventoryProductAlert
    Magento_InventoryRequisitionList
    Magento_InventoryReservations
    Magento_InventoryReservationCli
    Magento_InventoryReservationsApi
    Magento_InventoryExportStock
    Magento_InventorySalesAdminUi
    Magento_InventorySalesFrontendUi
    Magento_InventorySetupFixtureGenerator
    Magento_InventoryShipping
    Magento_InventorySourceDeductionApi
    Magento_InventorySourceSelection
    Magento_InventorySourceSelectionApi
    Magento_InventoryLowQuantityNotificationAdminUi
    Magento_InventoryShippingAdminUi
    Magento_InventoryGraphQl

     

    How to get salable quantity in Magento 2?

    Today we are going to share that how to get the actual salable quantity on the product detail page?

    Let’s say our requirement is to show available qty on the site

    You can use the below code by using object manager directly use in your phtml file.

    <?php 
        $objectManager = MagentoFrameworkAppObjectManager::getInstance();
        echo __('Quantity available: '); 
        $StockState = $objectManager->get('MagentoInventorySalesAdminUiModelGetSalableQuantityDataBySku');
        $qty = $StockState->execute($_product->getSku());
        echo $qty[0]['qty'];
    ?>

    That’s it.

    Magento 2: How to add new body class on all pages in your theme?

    If your want to add body class in all page in your theme then follow below code.

    Create default.xml file in app/design/frontend/Vendername/Themename/Magento_Theme/layout folder and paste below code

    <?xml version="1.0"?>a
    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
    <attribute name="class" value="theme-tpb"/> 
    </body>

    How to Call Script in Magento 2 Root?

    For example, if you want to get the order data and print it, you can create a root script in Magento 2 by executing the below code.

    <?php
    use MagentoFrameworkAppBootstrap;
    require 'app/bootstrap.php';
    $bootstrap = Bootstrap::create(BP, $_SERVER);
    $objectManager = $bootstrap->getObjectManager();
    $state = $objectManager->get('MagentoFrameworkAppState');
    $state->setAreaCode('frontend');
    echo 'My Script';

     

    Magento 2: How to add store code to body class in multi store view?

    In some cases, you will need to add a class to the body tag of your Magento stores. To process it, you’ll need to set-up an event observer for the layout_render_before event.

    1. Create file events.xml on app/code/Magemonkeys/Addbodyclass/etc/frontend

    <?xml version="1.0" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
      <event name="layout_render_before">
         <observer instance="MagemonkeysAddbodyclassObserverFrontendLayoutLoadBefore" name="add_bodystorecode_class_observer"/>
      </event>
    </config>

    2. Create file LoadBefore.php on app/code/Magemonkeys/Addbodyclass/Observer/Frontend/Layout

    <?php
    namespace MagemonkeysAddbodyclassObserverFrontendLayout;
     
    use MagentoFrameworkEventObserver;
    use MagentoFrameworkViewPageConfig;
    use MagentoStoreModelStoreManagerInterface; 
    
    class LoadBefore implements MagentoFrameworkEventObserverInterface
    {
       protected $storeManager;
    
       public function __construct(
           Config $config,
           StoreManagerInterface $storeManager
       ) {
           $this->config = $config;
           $this->storeManager = $storeManager;
       }
     
       public function execute(Observer $observer)
       {
           $store = $this->storeManager->getStore();
           $storeCode = $store->getCode();
           $websiteCode = $store->getWebsite()->getCode();
           $this->config->addBodyClass($storeCode);
           $this->config->addBodyClass($websiteCode);
       }
    }

     

     

    Send shipment email programmaticaly through cronjob

    Let’s say I have this requirement to send the shipment email every 5 minutes or 10 minutes. To perform the task, I chose to create a custom cronjob and its file to achieve the functionality. Follow the below steps for more details.

    Step 1: Create a crontab.xml

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
        <group id="default">
            <job name="sendshipmentemail" instance="MagemonkeysShipmentemailsendCronSend" method="execute">
                <schedule>0,15,30,45 * * * *</schedule>
            </job>
        </group>
    </config>

    Step 2: Create a Send.php file. Please follow the below code

    <?php
    
    namespace MagemonkeysShipmentemailsendCron;
    
    use MagentoFrameworkApiSearchFilterGroupBuilder;
    use MagentoFrameworkApiSearchCriteriaBuilder;
    use MagentoFrameworkAppObjectManager;
    use MagentoSalesModelOrderShipmentRepository;
    use MagentoSalesModelOrderRepository;
    use MagentoFrameworkApiFilterBuilder;
    use PsrLogLoggerInterface;
    
    class Send
    {
    
        private $orderRepository;
        private $searchCriteriaBuilder;
    
        public function __construct(
    
            OrderRepository $orderRepository,
            SearchCriteriaBuilder $searchCriteriaBuilder,
            ShipmentRepository $shipmentRepository,
            FilterBuilder $filterBuilder,
            FilterGroupBuilder $filterGroupBuilder,
            LoggerInterface $logger
        )
        {
            $this->orderRepository = $orderRepository;
            $this->shipmentRepository = $shipmentRepository;
            $this->searchCriteriaBuilder = $searchCriteriaBuilder;
            $this->filterBuilder = $filterBuilder;
            $this->filterGroupBuilder = $filterGroupBuilder;
            $this->objectManager = ObjectManager::getInstance();
            $this->logger = $logger;
        }
    
    
        public function execute()
        {
    
            $filtergroup_date = $this->filterGroupBuilder
                ->addFilter(
                    $this->filterBuilder
                        ->setField('created_at')
                        ->setConditionType('gt')
                        ->setValue('2020-01-01')
                        ->create()
                )
                ->create();
    
    
            $filtergroup_email_sent = $this->filterGroupBuilder
                ->addFilter(
                    $this->filterBuilder
                        ->setField('email_sent')
                        ->setConditionType('null')
                        ->create()
                )
                ->create();
    
            $filtergroup_send_email = $this->filterGroupBuilder
                ->addFilter(
                    $this->filterBuilder
                        ->setField('send_email')
                        ->setConditionType('null')
                        ->create()
                )
                ->create();
    
            $searchCriteria = $this->searchCriteriaBuilder
                ->setFilterGroups([
                    $filtergroup_date,
                    $filtergroup_email_sent,
                    $filtergroup_send_email
                ])
                ->create();;
    
            $shipmentList = $this->shipmentRepository->getList($searchCriteria)->getItems();
    
            foreach ($shipmentList as $shipment) {
                if (count($shipment->getTracks()) > 0) {
                    $this->objectManager->create('MagentoShippingModelShipmentNotifier')->notify($shipment);
                    $shipment->setEmailSent("1");
                    $shipment->save();
                } else {
                    $this->logger->warning("Unable to send shipment email for order");
                }
            }
        }
    }

    Now, when the cron runs it will execute our code and if any shipment mail needs to send then it will be sent.

    Send email on order cancellation in Magento 2

    Magento 2 has many templates to send when the customer changes the order process like an invoice, shipment, credit memo, etc. But the same isn’t available on the cancellation process.

    Today, we’re going to show you how to set it up for the cancelation process.

    Module name: Magemonkeys_Cancelledorder

    Create events.xml at app/code/Magemonkeys/Cancelledorder/etc/

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
        <event name="sales_order_save_after">
            <observer name="sales_order_save_after"
                      instance="MagemonkeysCancelledorderObserverOrderSaveAfter"/>
        </event>
    </config>

    Then Create OrderSaveAfter.php at app/code/Magemonkeys/Cancelledorder/Observer/

    <?php
    namespace MagemonkeysCancelledorderObserver;
    
    use MagentoFrameworkEventObserverInterface;
    use MagentoSalesModelOrderEmailSenderOrderCommentSender;
    
    class OrderSaveAfter implements ObserverInterface
    {
    
        protected $orderCommentSender;
    
        public function __construct(
            OrderCommentSender $orderCommentSender
        )
        {
            $this->orderCommentSender = $orderCommentSender;
        }
    
        public function execute(MagentoFrameworkEventObserver $observer)
        {
            $order = $observer->getEvent()->getOrder();
            if ($order->getState() == 'canceled') {
                $this->orderCommentSender->send($order, true);
            }
        }
    }

    The mail will look something like the below.

    Hope that helps.

    Magento 1.x create customer after place order using order details

    Create app/code/local/Namespace/Module/etc/config.xml  file and add below code

    <events>
      <checkout_onepage_controller_success_action> <!-- identifier of the event we want to catch -->
        <observers>
          <checkout_onepage_controller_success_action_handler> <!-- identifier of the event handler -->
            <type>singleton</type> <!-- class method call type; valid are model, object and singleton -->
            <class>createcustomer/observer</class> <!-- observers class alias -->
            <method>Aftersuccess</method>  <!-- observer's method to be called -->
            <args></args> <!-- additional arguments passed to observer -->
          </checkout_onepage_controller_success_action_handler>
        </observers>
      </checkout_onepage_controller_success_action>
    </events>

    Create app/code/local/Namespace/Module/Model/Observer.php file and add the below code.

    <?php
    class Namespace_Module_Model_Observer
    {
    
    	public function Aftersuccess(Varien_Event_Observer $observer)
    	{
    		$orderIds = $observer->getData('order_ids');
         	        foreach($orderIds as $_orderId){
    			$order = Mage::getModel('sales/order')->load($_orderId);
    			$storeId = Mage::app()->getStore()->getId();
    			$store = Mage::getModel('core/store')->load($order->getData('store_id'));
    			$websiteId = $store->getWebsiteId();
    			$billingaddress = $order->getBillingAddress();
    			$customer = Mage::getModel('customer/customer')->setWebsiteId($websiteId);
    			$customer->loadByEmail($order->getCustomerEmail());
    
    			if(!$customer->getId()) {
    				$customer = Mage::getModel("customer/customer");
    				$customer   ->setWebsiteId($websiteId)
    				            ->setStore($store)
    				            ->setFirstname($billingaddress->getFirstname())
    				            ->setLastname($billingaddress->getLastname())
    				            ->setEmail($billingaddress->getEmail());
    				try{
    				    $customer->save();
    				}
    				catch (Exception $e) {
    				    Zend_Debug::dump($e->getMessage());
    				}
    
    				$address = Mage::getModel("customer/address");
    				$address->setCustomerId($customer->getId())
    				        ->setFirstname($customer->getFirstname())
    				        ->setMiddleName($customer->getMiddlename())
    				        ->setLastname($customer->getLastname())
    				        ->setCountryId($billingaddress->getCountryId())
    						->setRegionId($billingaddress->getRegionId()) //state/province, only needed if the country is USA
    				        ->setPostcode($billingaddress->getPostcode())
    				        ->setCity($billingaddress->getCity())
    				        ->setTelephone($billingaddress->getTelephone())
    				        ->setFax($billingaddress->getFax())
    				        ->setCompany($billingaddress->getCompany())
    				        ->setStreet($billingaddress->getStreet())
    				        ->setIsDefaultBilling('1')
    				        ->setIsDefaultShipping('1')
    				        ->setSaveInAddressBook('1');
    				 
    				try{
    				    $address->save();
    				}
    				catch (Exception $e) {
    				    Zend_Debug::dump($e->getMessage());
    				}
    			}
    		}
    	}	
    }