Magento order save error: violation of integrity constraints
I am getting the following error when I place an order with a credit / debit card in Magento:
Order saving error: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '282-189' for key 2
I couldn't get an accurate trace as I just didn't want to show it to me, but I traced it to app/code/core/Mage/Checkout/controllers/OnepageController.php
in line 501
(unedited). Exact line:
$this->getOnepage()->saveOrder();
Now the logic is telling me that these are just two orders having the same key when trying to add an order, or am I completely wrong?
Anyway, so outside of that, what's the best way to do this? I was thinking about exporting the orders, deleting them all and then republishing them, but I have a feeling that this won't work.
I am using Magento 1.6.2.0
EDIT: I just got it: if I find out which table won't check for consistency, I could potentially discredit that table (depending on which table it is) and would that fix it itself? Any ideas on how to find out which table is messed up?
EDIT2: So, after Oguz Chelikdemir's answer, it turns out that the culprit is:
2012-03-14T13:59:01+00:00 DEBUG (7): SQL: INSERT INTO `sales_order_tax_item` (`tax_id`, `item_id`, `tax_percent`) VALUES (?, ?, ?) (254, 8, 10)
2012-03-14T13:59:01+00:00 DEBUG (7): SQL: INSERT INTO `sales_order_tax_item` (`tax_id`, `item_id`, `tax_percent`) VALUES (?, ?, ?) (254, 8, 10)
Obviously, two identical tax_ids cannot be inserted. Does anyone know how to fix this?
source to share
I found a quick dirty hack. I'll try to post this as a developer bug. open the file app/code/core/Mmage/Tax/Model/Observer.php
and go to line 132. In this statement, the statement if($item)
wraps the code around this:
$define = 'FIX_'.$item->getId().'_'.$result->getTaxId();
if(!defined($define) || constant($define) != true) {
// code
define($define, true);
}
Example:
if (isset($ratesIdQuoteItemId[$id])) {
foreach ($ratesIdQuoteItemId[$id] as $quoteItemId) {
if ($quoteItemId['code'] == $tax['code']) {
$item = $order->getItemByQuoteItemId($quoteItemId['id']);
if ($item) {
$define = 'FIX_'.$item->getId().'_'.$result->getTaxId();
if(!defined($define) || constant($define) != true) {
$data = array(
'item_id' => $item->getId(),
'tax_id' => $result->getTaxId(),
'tax_percent' => $quoteItemId['percent']
);
Mage::getModel('tax/sales_order_tax_item')->setData($data)->save();
define($define, true);
}
}
}
}
}
source to share
Truncate the following tables log
. To protect yourself, make a backup from CONSOLE, not Magento.
TRUNCATE `log_customer`;
ALTER TABLE `log_customer` AUTO_INCREMENT=1;
TRUNCATE `log_quote`;
ALTER TABLE `log_quote` AUTO_INCREMENT=1;
TRUNCATE `log_summary`;
ALTER TABLE `log_summary` AUTO_INCREMENT=1;
TRUNCATE `log_visitor_info`;
ALTER TABLE `log_visitor_info` AUTO_INCREMENT=1;
TRUNCATE `log_url`;
ALTER TABLE `log_url` AUTO_INCREMENT=1;
TRUNCATE `log_url_info`;
ALTER TABLE `log_url_info` AUTO_INCREMENT=1;
TRUNCATE `log_visitor`;
ALTER TABLE `log_visitor` AUTO_INCREMENT=1;
TRUNCATE `report_event`;
ALTER TABLE `report_event` AUTO_INCREMENT=1;
TRUNCATE `log_summary_type`;
ALTER TABLE `log_summary_type` AUTO_INCREMENT=1;
EDIT:
For SQL debugging, open the file /lib/Varien/Db/Adapter/Pdo/Mysql.php
and find protected $_debug
. The default status should be false
, change to true
.
After that, the log file should be available at var/debug/sql.txt
Also, take this stackoverflow ansver How to print all requests in Magento?
EDIT 2:
So here are your files that handle sales tax.
app/code/core/Mage/Tax/Model/Observer/Observer.php
# Line 144 ( Magento 1.6 edition )
Mage::getModel('tax/sales_order_tax_item')->setData($data)->save();
which calls the sales_order_tax_item
model.
app/core/Mage/Tax/Model/Resource/Sales/Order/Tax/Itemp.php
# Line 51
public function getTaxItemsByItemId($item_id)
{
$adapter = $this->_getReadAdapter();
$select = $adapter->select()
->from(array('item' => $this->getTable('tax/sales_order_tax_item')), array('tax_id', 'tax_percent'))
->join(
array('tax' => $this->getTable('tax/sales_order_tax')),
'item.tax_id = tax.tax_id',
array('title', 'percent', 'base_amount')
)
->where('item_id = ?', $item_id);
return $adapter->fetchAll($select);
}
Here is a function calling from Observer. So what you can do now is just add a breakpoint on the Observer or Function and watch the debugger output. Why call this function twice!
source to share
Go to the section Sales -> Tax -> Manage Tax Rules
in the admin panel and check all entries there for duplicate zone-class relationships.
In my case, I got the same error on the Checkout page for products that had the tax class "Tax Products" and in the Tax Regulations I had two records for that class and each record was in the same tax area. Thus, the system tried to apply the same tax twice for a product.
source to share