Hello there,
Hope all is well. In the latest 7.x-1.x dev ( Feb 2015). An issue referred at there https://www.drupal.org/node/1853638
has been resolved by that implementing hook_commerce_cart_line_item_refresh. But it produces another very serious bug which is extremely hard to detect. It produces following error if line item refers to the disabled items.
PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'commerce_line_item-32-0-0-und' for key 'PRIMARY': INSERT INTO {field_data_commerce_unit_price} (entity_type, entity_id, revision_id, bundle, delta, language, commerce_unit_price_amount, commerce_unit_price_currency_code, commerce_unit_price_data) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8); Array ( [:db_insert_placeholder_0] => commerce_line_item [:db_insert_placeholder_1] => 32 [:db_insert_placeholder_2] => 32 [:db_insert_placeholder_3] => product [:db_insert_placeholder_4] => 0 [:db_insert_placeholder_5] => und [:db_insert_placeholder_6] => 1195 [:db_insert_placeholder_7] => USD [:db_insert_placeholder_8] => a:1:{s:10:"components";a:1:{i:0;a:3:{s:4:"name";s:10:"base_price";s:5:"price";a:3:{s:6:"amount";s:4:"1195";s:13:"currency_code";s:3:"USD";s:4:"data";a:1:{s:10:"components";a:0:{}}}s:8:"included";b:1;}}} ) in field_sql_storage_field_storage_write() (line 448 of /drupal/modules/field/modules/field_sql_storage/field_sql_storage.module).
TO mitigate this you should never ever save the line item as we just need torefresh the line item not to save the line item after customization as this is going to handle by the core. Since core is taking care for disabled items but your solution not. if you save the line item having disabled product then product pricing rules that has already emptied the unit price and currency conversion does still produce empty unit price. And unit price is required in the database schema and thus producing error. So to overcome this just remove from following
function commerce_multicurrency_commerce_cart_line_item_refresh($line_item, $order_wrapper) {
$line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
$currency_code = commerce_multicurrency_get_user_currency_code();
if ($line_item_wrapper->commerce_total->currency_code->value() != $currency_code) {
$amount = commerce_currency_convert(
$line_item_wrapper->commerce_total->amount->value(),
$line_item_wrapper->commerce_total->currency_code->value(),
$currency_code
);
$line_item_wrapper->commerce_total->amount = $amount;
$line_item_wrapper->commerce_total->currency_code = $currency_code;
}
// $line_item_wrapper->save(); // remove this line as drupal commerce will take care of it.
}
thanks
Comment | File | Size | Author |
---|---|---|---|
#3 | commerce_multicurrency-line_item_refresh_shouldnt_save_line_items-2479273-3.patch | 456 bytes | rossb89 |
Comments
Comment #1
rahu231086 CreditAttribution: rahu231086 commentedComment #2
das-peter CreditAttribution: das-peter commentedSet speaking title.
Set properly related ticket.
@rahu231086 Would you mind to provide a properly formatted patch? I guess test's would be great too but looks quite hard to create proper ones.
Comment #3
rossb89 CreditAttribution: rossb89 at ComputerMinds commentedI have encountered unintended behaviour due to this line of code being in place in this function.
On a highly customised commerce based site, some unwanted performance issues were caused by this line of code, as it triggered off an uneccessary entity save, with all the related hooks down the chain which were slowing down page load times slightly.
The first question I asked was, why does the code added in the patch in #1853638: Commerce Kickstart shopping cart (Commerce Order) block not converting currency until going to cart page save the line item wrapper NOT inside the
if ($line_item_wrapper->commerce_total->currency_code->value() != $currency_code) {}
statement.
If the currency code has not changed, then there is no need to *always* save the line item at this point in time.
I tested moving the
$line_item_wrapper->save()
line to inside the if statement, and this was then correctly only save the line item when the currency code had actually changed, not every single time the function was being called, regardless of if the currency code had changed or not.After some further searching I then came across this issue that @rahu231086 has raised, which raises a good point of saying the line item wrapper save is unnecessary, which I believe to be correct - as we should only be modifying the line item here, leaving the save to occur further down the chain.
I've tested removing the line entirely and everything still works as expected with the currency code being changed on the line item.
Comment #4
rossb89 CreditAttribution: rossb89 at ComputerMinds commentedComment #6
das-peter CreditAttribution: das-peter commented@rossb89 Thank you very much for the patch. Committed and pushed.
I've also decided to create a new version: https://www.drupal.org/project/commerce_multicurrency/releases/7.x-1.4 should be online soon.