I think I just found yet another Magento Bug (YAMB).

I had the problem, that in \Mage_Sales_Model_Order_Creditmemo_Total_Shipping::collect the shippingAmount was 0 (as expected) but the shippingIncludingTax is the complete shipping amount (and is printed on our credit memos).

The problem ends here right before the end of the method.

$creditmemo->setShippingAmount($shipping);
$creditmemo->setBaseShippingAmount($baseShipping);
$creditmemo->setShippingInclTax($shippingInclTax);
$creditmemo->setBaseShippingInclTax($baseShippingInclTax);


I think the bug is the following problem. In the beginning all shipping values are initialized with the values from the order:

$shipping =$order->getShippingAmount();
$baseShipping =$order->getBaseShippingAmount();
$shippingInclTax =$order->getShippingInclTax();
$baseShippingInclTax =$order->getBaseShippingInclTax();


Due to the fact, that we do it through the backend, the following comment helps us. In the beginning I ignored the comment, and assumed that the baseShippingAmount is 0 and therefore the if shouldn't be entered.

$isShippingInclTax = Mage::getSingleton('tax/config')->displaySalesShippingInclTax($order->getStoreId());

/**
* Check if shipping amount was specified (from invoice or another source).
* Using has magic method to allow setting 0 as shipping amount.
*/
if ($creditmemo->hasBaseShippingAmount()) {$baseShippingAmount = Mage::app()->getStore()->roundPrice($creditmemo->getBaseShippingAmount()); if ($isShippingInclTax && $baseShippingInclTax != 0) {$part = $baseShippingAmount/$baseShippingInclTax;
$shippingInclTax = Mage::app()->getStore()->roundPrice($shippingInclTax*$part);$baseShippingInclTax= $baseShippingAmount;$baseShippingAmount = Mage::app()->getStore()->roundPrice($baseShipping*$part);
}


What happens here? We get the current setting for displaySalesShippingInclTax, which should be including tax (but was excluding tax in my case).

So, if the tax setting is "wrong" (excluding tax), we don't enter the if block.

If we enter it, the part of the shipping would be calculated which is refunded (0) and everything is updated. But when the if block is not entered, the shippingInclTax is not updated and therefore the value of shippingInclTax is not consistent with shippingAmount

Images is from Pixabay and CC0
Thanks to 777546-777546

I want to add tabs to a custom form in the backend.

There are a couple of great tutorials how to add tabs, like from Inchoo or Erfan Imani.

But I wanted this:

And got this:

The problem is simple - if you know it (costs me an hour and a few hairs):

The tabs are rendered with JS. So they live originally in left, but they are shown in content, to be more specific in the node, defined by:

class My_Module_Block_Adminhtml_Project_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs {

public function __construct()
{
// ...
$this->setDestElementId('project_form'); } }  And this id needs to be the same as in class My_Module_Block_Adminhtml_Project_Edit_Form extends Mage_Adminhtml_Block_Widget_Form { protected function _prepareForm() {$form = new Varien_Data_Form(
[
'id'     => 'project_form',
]);
}
}


Hope this helps anyone.

Magento Cheat Sheet, how to add a magento admin user, directly thorugh SQL

Thanks to Atwix, i found the SQL which is needed to create a magento admin user.

Cheat sheet for me:

SET @fistname = 'Fabian';
SET @lastname = 'Blechschmidt';
SET @salt = 'Fl';

SELECT
NULL user_id,
@fistname firstname,
@lastname lastname,
@email email,
NOW( ) created,
NULL modified,
NULL logdate,
0 lognum,
1 is_active,
(SELECT MAX(extra) FROM admin_user WHERE extra IS NOT NULL) extra,
NULL rp_token,
NOW() rp_token_created_at;

SELECT
NULL role_id,
2 tree_level,
0 sort_order,
'U' role_type,


You have imported the sample data (which are based on EE)? Use this:

SET @fistname = 'Fabian';
SET @lastname = 'Blechschmidt';
SET @salt = 'Fl';

SELECT
NULL user_id,
@fistname firstname,
@lastname lastname,
@email email,
NOW( ) created,
NULL modified,
NULL logdate,
0 lognum,
1 is_active,
(SELECT MAX(extra) FROM admin_user WHERE extra IS NOT NULL) extra,
NULL rp_token,
NOW() rp_token_created_at,
NULL failures_num,
NULL first_failure,
NULL lock_expires;

SELECT
NULL role_id,
2 tree_level,
0 sort_order,
'U' role_type,
1 gws_is_all,
1 gws_websites,
1 gws_store_groups;


In Magento version < 1.7.0.0-alpha1 it is not possible to empty a multiselect.

In the adminbackend in Magento is a bug, which prevents a multiselect to become empty.

# <select>

A <select> element is not submited, if no option is selected. To submit a value you need to render a <input type="hidden" /> element before it. This way, the variable is set in $_GET or $_POST and may be overwritten by the <select>.

# Bug in magento

This <input type="hidden" /> is not rendered before Version 1.7.0.0-alpha1.

# Fix

Thanks to this thread I found a quick, good fix (as magento fixed it in versions > 1.7.0.0-alpha1):

// app/code/core/Mage/Adminhtml/Block/Widget/Form.php:203
} else if ($inputType == 'multiselect') {$element->setValues($attribute->getSource()->getAllOptions(false, true));$element->setCanBeEmpty(true); // add this line


The line number is from version 1.7.0.2