QUESTION & ANSWER:

 

I have found a bug in the Magento 2 Multiple Store View Pricing module for Magento version 2.2.9. (module v2.2.1)

When compiling multiple error are shown:

  1. The param $groupManagement in the class app/code/Bss/MultiStoreViewPricingTierPrice/Model/Product/Attribute/Backend/Tierprice/UpdateHandler.php must be protected or not initialized in that class since the parent does it. 
  2. In the constructor, the parent's constructor is not being called.
  3. The method getAdditionalFields() must be protected. As it is the same as the parent method, it can be removed.
  4. The method getPercentage() must be protected. As it is the same as the parent method, it can be removed.
  5. The method prepareTierPrice() must be protected. As it is the same as the parent method, it can be removed.


Finally, I think that the file app/code/Bss/MultiStoreViewPricingTierPrice/Model/Product/Attribute/Backend/Tierprice/UpdateHandler.php 

should be should look like this:


storeManager = $storeManager;        $this->attributeRepository = $attributeRepository;        $this->metadataPoll = $metadataPool;        $this->tierPriceResource = $tierPriceResource;        parent::__construct(            $storeManager,            $attributeRepository,            $groupManagement,            $metadataPool,            $tierPriceResource        );    }

    /**
     * @param \Magento\Catalog\Api\Data\ProductInterface|object $entity
     * @param array $arguments
     * @return \Magento\Catalog\Api\Data\ProductInterface|object
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     * @throws \Magento\Framework\Exception\LocalizedException
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function execute($entity, $arguments = [])
    {        $attribute = $this->attributeRepository->get('tier_price');        $priceRows = $entity->getData($attribute->getName());        if (null !== $priceRows) {            if (!is_array($priceRows)) {                throw new \Magento\Framework\Exception\InputException(                    __('Tier prices data should be array, but actually other type is received')                );            }
            $identifierField = $this->metadataPoll->getMetadata(ProductInterface::class)->getLinkField();
            $productId = $entity->getData($identifierField);

            // prepare original data to compare
            $old = $entity->getOrigData($attribute->getName());

            if (!is_array($old)) {                throw new \Magento\Framework\Exception\InputException(                    __('Tier prices data should be array, but actually other type is received')                );            }

            // prepare data for save
            $new = $this->prepareNewDataForSave($priceRows, 1);

            $delete = array_diff_key($old, $new);
            $insert = array_diff_key($new, $old);
            $update = array_intersect_key($new, $old);

            $isAttributeChanged = $this->deleteValues($productId, $delete);
            $isAttributeChanged |= $this->insertValues($productId, $insert);
            $isAttributeChanged |= $this->updateValues($update, $old);

            if ($isAttributeChanged) {                $valueChangedKey = $attribute->getName() . '_changed';                $entity->setData($valueChangedKey, 1);            }        }        return $entity;    }

    /**
     * Update existing tier prices for processed product
     *
     * @param array $valuesToUpdate
     * @param array $oldValues
     * @return boolean
     */
    private function updateValues(array $valuesToUpdate, array $oldValues): bool
    {        $isChanged = false;        foreach ($valuesToUpdate as $key => $value) {            if ((!empty($value['value']) && (float)$oldValues[$key]['price'] !== (float)$value['value'])                || $this->getPercentage($oldValues[$key]) !== $this->getPercentage($value)            ) {                $price = new \Magento\Framework\DataObject(                    [                        'value_id'         => $oldValues[$key]['price_id'],                        'value'            => $value['value'],                        'percentage_value' => $this->getPercentage($value)                    ]                );                $this->tierPriceResource->savePriceData($price);                $isChanged = true;            }        }        return $isChanged;    }

    /**
     * Insert new tier prices for processed product
     *
     * @param int $productId
     * @param array $valuesToInsert
     * @return bool
     */
    private function insertValues(int $productId, array $valuesToInsert): bool
    {        $isChanged = false;        $identifierField = $this->metadataPoll->getMetadata(ProductInterface::class)->getLinkField();        foreach ($valuesToInsert as $data) {            $price = new \Magento\Framework\DataObject($data);            $price->setData(                $identifierField,                $productId            );            $this->tierPriceResource->savePriceData($price);            $isChanged = true;        }        return $isChanged;    }

    /**
     * Delete tier price values for processed product
     *
     * @param int $productId
     * @param array $valuesToDelete
     * @return bool
     */
    private function deleteValues(int $productId, array $valuesToDelete): bool
    {        $isChanged = false;        foreach ($valuesToDelete as $data) {            $this->tierPriceResource->deletePriceData($productId, null, $data['price_id']);            $isChanged = true;        }        return $isChanged;    }

    /**
     * @param array $priceRows
     * @param bool $isGlobal
     * @return array
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    private function prepareNewDataForSave($priceRows, $isGlobal = true): array
    {        $new = [];        $priceRows = array_filter($priceRows);        foreach ($priceRows as $data) {            if (empty($data['delete'])                && (!empty($data['price_qty'])                    || isset($data['cust_group'])                    || $isGlobal)            ) {                $key = $this->getPriceKey($data);                $new[$key] = $this->prepareTierPrice($data);            }        }        return $new;    }

    /**
     * Get generated price key based on price data
     *
     * @param array $priceData
     * @return string
     */
    private function getPriceKey(array $priceData): string
    {        $key = implode(            '-',            array_merge([$priceData['website_id'], $priceData['cust_group']], [(int)$priceData['price_qty']])        );        return $key;    }}


Thank Mr Raul Mateos - a valued customer of BSS Commerce Store who contributed this solution.



If you need further assistance, please don't hesitate to contact us.