2

---- EDIT #3 :

Please ignore the code in this question. The template tier.phtml is not used by Magento 2.2.x (see edit #2)

The working code can be found here: Extra column in catalog_product_entity_tier_price not saving/updating in observer

---- EDIT #2 :

The problem I have found is that the tier.phtml doesn't seem to be used to create the advanced prices. Probably due to the following fact:

In Magento version 2.1, the product creation form was completely refactored and implemented using the form UI component.

see: https://devdocs.magento.com/guides/v2.2/howdoi/customize_product.html

It is instead created via the /module-catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php, specifically the getTierPriceStructure method. This is the reason none of the below codes ever worked. No var_dump() or die()'s ever had any effect anywhere. I've not found out where the tier.phtml is ever used.

I'll post an answer once I was able to modify the form.

// ---- END EDIT #2 :

I'm trying to overwrite the following template in the adminhtml backend:

module-catalog/view/adminhtml/templates/catalog/product/edit/price/tier.phtml

I first tried overwriting the template in a single module, this however did not work as expected. I then found the following post: How to override adminhtml phtml in magento 2?

which claims a custom admin theme is required, hence my code is as follows:

What I've done is the following on a clean install of Magento 2.2.3

files view

  1. Create a custom module under app/code/Vendor/CustomModule/

app/code/Vendor/CustomModule/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_CustomModule',
    __DIR__
);

Make sure my module is loaded after the theme in

app/code/Vendor/CustomModule/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="Vendor_CustomModule" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Theme"/>
        </sequence>
    </module>
</config>

Overwrite the Tier.php to set my custom template path:

app/code/Vendor/CustomModule/Block/Adminhtml/Product/Edit/Tab/Price/Tier.php

<?php

namespace Vendor\CustomModule\Block\Adminhtml\Product\Edit\Tab\Price;


/**
 * Adminhtml tier price item renderer
 */
class Tier extends \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Price\Tier
{
    /**
     * @var string
     */
    protected $_template = 'Vendor_CustomModule::catalog/product/edit/price/tier.phtml';

}

Set preference in my di.xml and set my custom admin theme (created in point 2.)

app/code/Vendor/CustomModule/etc/adminhtml/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="Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Price\Tier"
                type="Vendor\CustomModule\Block\Adminhtml\Product\Edit\Tab\Price\Tier" />

    <!-- Admin theme. Start -->
    <type name="Magento\Theme\Model\View\Design">
        <arguments>
            <argument name="themes" xsi:type="array">
                <item name="adminhtml" xsi:type="string">Vendor/CustomAdminTheme</item>
            </argument>
        </arguments>
    </type>
    <!-- Admin theme. End -->
</config>
  1. Create a custom admin theme

app/design/adminhtml/Vendor/CustomAdminTheme/registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::THEME,
    'adminhtml/Vendor/CustomAdminTheme',
    __DIR__
);

app/design/adminhtml/Vendor/CustomAdminTheme/theme.xml

<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
    <title>Vendor Custom Admin Theme</title>
    <parent>Magento/backend</parent>
</theme>

and create my custom tier-price template for testing:

app/design/adminhtml/Vendor/CustomAdminTheme/Magento_Catalog/templates/catalog/product/edit/price/tier.phtml

<?php

// @codingStandardsIgnoreFile

/* @var $block \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Price\Tier */
$element = $block->getElement();
?>


// THIS IS A TEST TEMPLATE!!

I have set 'MAGE_MODE' => 'developer' and run setup:upgrade and setup:di:compile, yet my backend 'advanced pricing' template in Catalog -> new Product does not update.

Any ideas where I went wrong?

Official Documentation Used:

  1. http://devdocs.magento.com/guides/v2.2/frontend-dev-guide/themes/admin_theme_create.html
  2. http://devdocs.magento.com/guides/v2.2/frontend-dev-guide/themes/admin_theme_apply.html

---- EDIT ----

As per @murtuza-zabuawala I've removed the custom admin theme, created a Vendor\CustomModule\Block\Adminhtml\Product\Edit\Tab\Price.php,Vendor\CustomModule\Block\Adminhtml\Product\Edit\Tab\Attributes, Vendor\CustomModule\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes and overwritten the hardcoded class name to use mine instead:

Vendor/CustomModule/Block/Adminhtml/Product/Edit/Tab/Price.php

<?php

namespace Vendor\CustomModule\Block\Adminhtml\Product\Edit\Tab;


class Price extends \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Price
{
    /**
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    protected function _prepareForm()
    {
        $product = $this->_coreRegistry->registry('product');

        /** @var \Magento\Framework\Data\Form $form */
        $form = $this->_formFactory->create();
        $fieldset = $form->addFieldset('tiered_price', ['legend' => __('Tier Pricing')]);

        $fieldset->addField(
            'default_price',
            'label',
            [
                'label' => __('Default Price'),
                'title' => __('Default Price'),
                'name' => 'default_price',
                'bold' => true,
                'value' => $product->getPrice()
            ]
        );

        $fieldset->addField(
            'tier_price',
            'text',
            ['name' => 'tier_price', 'class' => 'requried-entry', 'value' => $product->getData('tier_price')]
        );

        $form->getElement(
            'tier_price'
        )->setRenderer(
            $this->getLayout()->createBlock(\Vendor\CustomModule\Block\Adminhtml\Product\Edit\Tab\Price\Tier::class)
        );

        $this->setForm($form);
    }

}

Vendor/CustomModule/Block/Adminhtml/Product/Edit/Tab/Attributes.php

<?php
namespace Vendor\CustomModule\Block\Adminhtml\Product\Edit\Tab;

/**
 * @SuppressWarnings(PHPMD.DepthOfInheritance)
 */
class Attributes extends \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes
{

    protected function _prepareForm()
    {
        /** @var $group \Magento\Eav\Model\Entity\Attribute\Group */
        $group = $this->getGroup();
        if ($group) {
            /** @var \Magento\Framework\Data\Form $form */
            $form = $this->_formFactory->create();
            $product = $this->_coreRegistry->registry('product');
            $isWrapped = $this->_coreRegistry->registry('use_wrapper');
            if (!isset($isWrapped)) {
                $isWrapped = true;
            }
            $isCollapsable = $isWrapped && $group->getAttributeGroupCode() == 'product-details';
            $legend = $isWrapped ? __($group->getAttributeGroupName()) : null;
            // Initialize product object as form property to use it during elements generation
            $form->setDataObject($product);

            $fieldset = $form->addFieldset(
                'group-fields-' . $group->getAttributeGroupCode(),
                ['class' => 'user-defined', 'legend' => $legend, 'collapsable' => $isCollapsable]
            );

            $attributes = $this->getGroupAttributes();

            $this->_setFieldset($attributes, $fieldset, ['gallery']);

            $tierPrice = $form->getElement('tier_price');
            if ($tierPrice) {
                $tierPrice->setRenderer(
                    $this->getLayout()->createBlock(\Vendor\CustomModule\Block\Adminhtml\Product\Edit\Tab\Price\Tier::class)
                );
            }

            // Add new attribute controls if it is not an image tab
            if (!$form->getElement(
                'media_gallery'
            ) && $this->_authorization->isAllowed(
                'Magento_Catalog::attributes_attributes'
            ) && $isWrapped
            ) {
                $attributeCreate = $this->getLayout()->createBlock(
                    \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes\Create::class
                );

                $attributeCreate->getConfig()->setAttributeGroupCode(
                    $group->getAttributeGroupCode()
                )->setTabId(
                    'group_' . $group->getId()
                )->setGroupId(
                    $group->getId()
                )->setStoreId(
                    $form->getDataObject()->getStoreId()
                )->setAttributeSetId(
                    $form->getDataObject()->getAttributeSetId()
                )->setTypeId(
                    $form->getDataObject()->getTypeId()
                )->setProductId(
                    $form->getDataObject()->getId()
                );

                $attributeSearch = $this->getLayout()->createBlock(
                    \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes\Search::class
                )->setGroupId(
                    $group->getId()
                )->setGroupCode(
                    $group->getAttributeGroupCode()
                );

                $attributeSearch->setAttributeCreate($attributeCreate->toHtml());

                $fieldset->setHeaderBar($attributeSearch->toHtml());
            }

            $values = $product->getData();

            // Set default attribute values for new product or on attribute set change
            if (!$product->getId() || $product->dataHasChangedFor('attribute_set_id')) {
                foreach ($attributes as $attribute) {
                    if (!isset($values[$attribute->getAttributeCode()])) {
                        $values[$attribute->getAttributeCode()] = $attribute->getDefaultValue();
                    }
                }
            }

            if ($product->hasLockedAttributes()) {
                foreach ($product->getLockedAttributes() as $attribute) {
                    $element = $form->getElement($attribute);
                    if ($element) {
                        $element->setReadonly(true, true);
                        $element->lock();
                    }
                }
            }

            $form->addValues($values);
            $form->setFieldNameSuffix('product');

            $this->_eventManager->dispatch(
                'adminhtml_catalog_product_edit_prepare_form',
                ['form' => $form, 'layout' => $this->getLayout()]
            );

            $this->setForm($form);
        }
    }

}

Vendor/CustomModule/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php

<?php

namespace Vendor\CustomModule\Block\Adminhtml\Catalog\Product\Edit\Tab;


class Attributes extends \Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes
{

    protected function _prepareForm()
    {
        parent::_prepareForm();

        $specialPrice = $this->getForm()->getElement('special_price');
        if ($specialPrice) {
            $specialPrice->setRenderer(
                $this->getLayout()->createBlock(
                    \Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes\Special::class
                )->setDisableChild(
                    false
                )
            );
            $specialPrice->addClass(
                implode(
                    ' ',
                    [
                        'validate-greater-than-zero',
                        'validate-number-range',
                        'number-range-0.00-100.00'
                    ]
                )
            );
        }

        $sku = $this->getForm()->getElement('sku');
        if ($sku) {
            $sku->setRenderer(
                $this->getLayout()->createBlock(
                    \Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes\Extend::class
                )->setDisableChild(
                    false
                )
            );
        }

        $price = $this->getForm()->getElement('price');
        if ($price) {
            $price->setRenderer(
                $this->getLayout()->createBlock(
                    \Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes\Extend::class,
                    'adminhtml.catalog.product.bundle.edit.tab.attributes.price'
                )->setDisableChild(
                    true
                )
            );
        }

        $tax = $this->getForm()->getElement('tax_class_id');
        if ($tax) {
            $tax->setAfterElementHtml(
                '<script>' .
                "
                require(['prototype'], function(){
                function changeTaxClassId() {
                    if ($('price_type').value == '" .
                \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC .
                "') {
                        $('tax_class_id').disabled = true;
                        $('tax_class_id').value = '0';
                        $('tax_class_id').removeClassName('required-entry');
                        if ($('advice-required-entry-tax_class_id')) {
                            $('advice-required-entry-tax_class_id').remove();
                        }
                    } else {
                        $('tax_class_id').disabled = false;
                        " .
                ($tax->getRequired() ? "$('tax_class_id').addClassName('required-entry');" : '') .
                "
                    }
                }

                if ($('price_type')) {
                    $('price_type').observe('change', changeTaxClassId);
                    changeTaxClassId();
                }
                });
                " .
                '</script>'
            );
        }

        $weight = $this->getForm()->getElement('weight');
        if ($weight) {
            $weight->setRenderer(
                $this->getLayout()->createBlock(
                    \Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes\Extend::class
                )->setDisableChild(
                    true
                )
            );
        }

        $tier_price = $this->getForm()->getElement('tier_price');
        if ($tier_price) {
            $tier_price->setRenderer(
                $this->getLayout()->createBlock(
                    \Vendor\CustomModule\Block\Adminhtml\Product\Edit\Tab\Price\Tier::class
                )->setPriceColumnHeader(
                    __('Percent Discount')
                )->setPriceValidation(
                    'validate-greater-than-zero validate-number-range number-range-0.00-100.00'
                )
            );
        }
    }

}

and I've added it to my di.xml:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <preference for="Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes"
                type="Vendor\CustomModule\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes" />

    <preference for="Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes"
                type="Vendor\CustomModule\Block\Adminhtml\Product\Edit\Tab\Attributes" />

    <preference for="Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Price"
                type="Vendor\CustomModule\Block\Adminhtml\Product\Edit\Tab\Price" />

    <preference for="Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Price\Tier"
                type="Vendor\CustomModule\Block\Adminhtml\Product\Edit\Tab\Price\Tier" />
</config>

This however still does not seem to work. The complete module file structure now looks like this:

enter image description here

9
  • Do you have the tier.phtml template file under app/code/Vendor/CustomModule. Some of the folder structure and naming may be missing in the above. Commented May 4, 2018 at 10:37
  • Did you try my answer? Did it help? Commented May 5, 2018 at 12:56
  • Thanks for your answers, I've edited my question as not using a custom admin theme was my first method, which did not work.
    – tecjam
    Commented May 8, 2018 at 9:40
  • @tecjam Have you tried my solution ?? Commented May 10, 2018 at 5:04
  • @murtuza-zabuawala: I've tried it (edited the code above) but it didn't work. Do you still require a custom admin theme, I tried it without?
    – tecjam
    Commented May 10, 2018 at 13:04

3 Answers 3

0

I think you've just place your phtml in wrong destination, please place your template file in app/code/Vendor/CustomModule/view/adminhtml/templates/catalog/product/edit/price/tier.phtml and it should reflect the changes.

Also there is no need to override the template in your own theme.

1
  • This was the first method I tried, i forgot to mention it in my post (i will edit this). It does not work unfortunately. I then found this post and answer, which claims an admin theme is required, hence my code above: magento.stackexchange.com/questions/183129/…
    – tecjam
    Commented May 8, 2018 at 9:33
0

I didn't tried but I think you need to override protected $_template = 'catalog/product/edit/price/tier.phtml'; by overriding vendor/magento/module-catalog/Block/Adminhtml/Product/Edit/Tab/Price/Tier.php

1
  • I am overwriting it, see my code above after Overwrite the Tier.php to set my custom template path:
    – tecjam
    Commented May 8, 2018 at 12:48
0

That issue happens because of following

in vendor/magento/module-catalog/Block/Adminhtml/Product/Edit/Tab/Price.php file's _prepareForm() method

magento has directly set child block in this method like below

   $form->getElement(
        'tier_price'
    )->setRenderer(
        $this->getLayout()->createBlock('Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Price\Tier')
    );

So for this you have to make prefrence of this class Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Price and need to put your block over here

for example

   $form->getElement(
        'tier_price'
    )->setRenderer(
        $this->getLayout()->createBlock('Vendor\CustomModule\Block\Adminhtml\Product\Edit\Tab\Price\Tier')
    );

and make sure your block extends the Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Price\Tier class

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.