The Problem seems to be here:
https://github.com/magento/magento2/blob/2.2.6/app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php#L86
While the Interface defines int as return type (not strict, only per type hint), the actual model behind the interface also allows string and returns a string.
As a result $isGlobal is false (although it should be true) because of strict comparison.
This leads to the $old array being empty and finally to Magento trying to insert the values although they already exist in the db (which then causes the Unique Constraint Violation error).
An elegant workaround with a plugin on getWebsiteId (cast value to int) seems very risky if in some other place the system expects it to be a string.
Hi @davidverholen. Thank you for your report.
To help us process this issue please make sure that you provided the following information:
Please make sure that the issue is reproducible on the vanilla Magento instance following Steps to reproduce. To deploy vanilla Magento instance on our environment, please, add a comment to the issue:
@magento-engcom-team give me $VERSION instance
where $VERSION is version tags (starting from 2.2.0+) or develop branches (for example: 2.3-develop).
For more details, please, review the Magento Contributor Assistant documentation.
@davidverholen do you confirm that you was able to reproduce the issue on vanilla Magento instance following steps to reproduce?
@magento-engcom-team give me 2.2.6 instance
Hi @davidverholen. Thank you for your request. I'm working on Magento 2.2.6 instance for you
Hi @davidverholen, here is your Magento instance.
Admin access: https://i-18154-2-2-6.engcom.dev.magento.com/admin
Login: admin Password: 123123q
Instance will be terminated in up to 3 hours.
Hi @engcom-backlog-nazar. Thank you for working on this issue.
In order to make sure that issue has enough information and ready for development, please read and check the following instruction: :point_down:
G1 Passed will be added to the issue automatically. Please, edit issue description if needed, until label G1 Passed appears.[x] 2. Verify that issue has a meaningful description and provides enough information to reproduce the issue. If the report is valid, add G2 Passed label to the issue by yourself.
[x] 3. Add Component: XXXXX label(s) to the ticket, indicating the components it may be related to.
[ ] 4. Verify that the issue is reproducible on 2.3-develop branchDetails
- Add the comment @magento-engcom-team give me 2.3-develop instance to deploy test instance on Magento infrastructure.
- If the issue is reproducible on 2.3-develop branch, please, add the label Reproduced on 2.3.x.
- If the issue is not reproducible, add your comment that issue is not reproducible and close the issue and _stop verification process here_!
[x] 5. Verify that the issue is reproducible on 2.2-develop branch. Details
- Add the comment @magento-engcom-team give me 2.2-develop instance to deploy test instance on Magento infrastructure.
- If the issue is reproducible on 2.2-develop branch, please add the label Reproduced on 2.2.x
[x] 6. Add label acknowledged once verification is complete.
[x] 7. Make sure that automatic system confirms that report is acknowledged.
@engcom-backlog-nazar could not reproduce it on vanilla instance so far. investigating further
ok there is another precondition, added it to the issue:
the price scope in the store configuration has to be set to website
changed the config on https://i-18154-2-2-6.engcom.dev.magento.com/ and now could reproduce it there
@engcom-backlog-nazar Thank you for verifying the issue. Based on the provided information internal tickets MAGETWO-95127 were created
Just to add some further comments on this issue, we are getting the same issue on our end and we've noticed that if we have tier prices set for customer groups and specific websites on our multisite environment, then when the product is saved as a whole, it's creating an automatic entry on the Advanced Pricing for "All Websites" on the "General" customer group, even though we're not entering that information in, if this is deleted on the Advanced Pricing and re-saved it does appear to work, however it will re-generate the entry, so every time an edit is made on a product you need to delete this entry otherwise you get the Unique Constraint Violation error. See attached screenshot of the record in question.

@davidverholen Thank you for the hint with the plugin on getWebsiteId, so far this is working for me:
di.xml
<type name="\Magento\Store\Model\Store">
<plugin name="fix_tier_price_global_error" type="Vendor\Module\Plugin\FixTierPrice" sortOrder="1"/>
</type>
FixTierPrice.php
<?php
namespace Vendor\Module\Plugin;
class FixTierPrice {
public function afterGetWebsiteId(\Magento\Store\Model\Store $subject, $result) {
if (is_string($result)) {
return intval($result);
}
return $result;
}
}
I let you know, if I experience any problems. But since getWebsiteId allows int as type I don麓t think there should be any issues.
I am afraid the plugin is not enough to fix all the problems with tierpricing. Now it is not possible to create multiple tierprices for a specific website. You always get an Unique constraint violation. This is because of the following check in the vendor/magento/module-catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php class:
private function prepareOriginalDataToCompare($origPrices, $isGlobal = true): array
{
$old = [];
if (is_array($origPrices)) {
foreach ($origPrices as $data) {
if ($isGlobal === $this->isWebsiteGlobal((int)$data['website_id'])) {
$key = $this->getPriceKey($data);
$old[$key] = $data;
}
}
}
return $old;
}
It will causes the "old" array to be emtpy when you try to save or update website specific tierprices. We fixed this by overwriting the specific class.
Can anyone explain me why the check should be there?
I've updated SaveHandler.php and UpdateHandler.php as described in the previous comments. It's now possible to save the tier/group-prices at the global scope. When trying to save at the website scope, the unique constraint violation exception appears.
Does anybody have a workaround/fix? (I take also the dirty one)
I've backported SaveHandler.php and UpdateHandler.php from 2.3-develop into 2.2.6
Now I can save also at the website scope.
@magento-engcom-team give me 2.2.7 instance
Hi @agorbulin. Thank you for your request. I'm working on Magento 2.2.7 instance for you
Hi @agorbulin, here is your Magento instance.
Admin access: https://i-18154-2-2-7.instances.magento-community.engineering/admin
Login: admin Password: 123123q
Instance will be terminated in up to 3 hours.
any insight on this issue , especially on part @reijervano pointed out , why is this condition there and what does it affect. Pretty huge issue when your site can't save items
@Detzler can you make a pull request for that backport for 2.2?
@hostep searched this out for us and here's a commit that solves this https://github.com/magento/magento2/commit/9240974c8c7
@Detzler Thanks for your tip on using the SaveHandler.php and UpdateHandler.php from 2.3-develop. I converted the difference between those two files on 2.2.7 vs 2.3-develop and applied it to a Magento 2.2.7 install using composer-patches.
Here's the patch in case anyone's interested:
github-issue-18154.patch.zip
Hi @davidverholen. Thank you for your report.
The issue has been fixed in 2.2-develop branch
Related commit(s):
The fix will be available with the upcoming 2.2.8 release.
Most helpful comment
Hi @davidverholen. Thank you for your report.
The issue has been fixed in 2.2-develop branch
Related commit(s):
The fix will be available with the upcoming 2.2.8 release.