Basket Sales Row Totals

Sales Row Totals are defined in config.xml in the nodes:

<sales>
    <quote>
        <totals>
            <shipping>
                <class>sales/quote_address_total_shipping</class>
                <after>subtotal,freeshipping,tax_subtotal</after>
                <before>grand_total</before>
            </shipping>
        </totals>
    </quote>
</sales>

The class node is instantiated by each total type, and then collect is called on each. The fetch method actually adds the total type to the address — up until this point the config.xml definition only declares the total types which should be queried for addition. Logic could exist in the fetch method to check whether the total type should be added at all. Additionally, the fetch method could add more than one type of total, as the Mage_Tax_Model_Sales_Total_Quote_Tax does.

<?php
  public function fetch(Mage_Sales_Model_Quote_Address $address)
    {
        $amount = $address->getShippingAmount();
       if ($amount != 0 || $address->getShippingDescription()) {
            $title = Mage::helper('sales')->__('Shipping & Handling');
            if ($address->getShippingDescription()) {
                $title .= ' (' . $address->getShippingDescription() . ')';
            }
            $address->addTotal(array(
                'code' => $this->getCode(),
                'title' => $title,
                'value' => $address->getShippingAmount()
            ));
        }
        return $this;
    }

These are rendered by the Mage_Checkout_Block_Cart_Totals‘ renderTotal method. A total can also have a block total renderer assigned to it instead of having to rely on the default output in the cart rows. The block is instantiated using the node names of the total config definition. The total node name is used (in the node) with _total_renderer appended to it. This is done in the Cart Totals’ _getTotalRenderer() method. In the example above, the renderer would be called *shipping_total_renderer*.

Fishpigs Total Renderer Example

Fish pigs add a cart total renderer to the cart. To achieve this, they add a shipping_total_renderer in their layout XML:

<layout>
	
	<checkout_cart_index>
		<reference name="checkout.cart.totals">
			<block type="basketshipping/total_shipping" name="shipping_total_renderer" />
		</reference>
	</checkout_cart_index>
	
</layout>

– This block will now be rendered for the shipping_total. Due to the way the fetch method works however, the row will only be added to the cart totals is not equal to zero or the address does not has a shipping description. This can be changed by overwriting the Mage_Sales_Model_Quote_Address_Total_Shipping model.

Notes on Magento’s Tax Module

Magento’s tax modules adds renderers to many of the sales/quote/total rows. This may often be overlooked when looking at the config file from Magento’s Sales module. This changes the renderers of the subtotal, shipping, discount, and grand total to renderer blocks within the tax module:

 <subtotal>
    <renderer>tax/checkout_subtotal</renderer>
    <admin_renderer>adminhtml/sales_order_create_totals_subtotal</admin_renderer>
</subtotal>
<shipping>
    <renderer>tax/checkout_shipping</renderer>
    <admin_renderer>adminhtml/sales_order_create_totals_shipping</admin_renderer>
</shipping>
<discount>
    <renderer>tax/checkout_discount</renderer>
    <admin_renderer>adminhtml/sales_order_create_totals_discount</admin_renderer>
</discount>
<grand_total>
    <renderer>tax/checkout_grandtotal</renderer>
    <admin_renderer>adminhtml/sales_order_create_totals_grandtotal</admin_renderer>
</grand_total>

Basket Row Total Areas

There are three main areas in the shipping row totals: footer, taxes, and null. Null is the default area any is output by default, other renderers require explicit output in a template, such as the taxes area. This area area is only created if tax/cart_display/grandtotal is set to Yes.

The position of taxes in Magento will render based on the tax/cart_display/grandtotal setting. If this setting is set to Yes, then the tax will not be output as part of the regular totals, and assigned to the taxes area, which by default is output as part of the grand total template (tax/checkout/grandtotal.phtml):

<?php echo $this->renderTotals('taxes', $this->getColspan()); ?>

The area is set in the fetch method of Mage_Tax_Model_Sales_Total_Quote_Tax:

$area = null;
if ($this->_config->displayCartTaxWithGrandTotal($store) && $address->getGrandTotal()) {
    $area = 'taxes';
}

if (($amount != 0) || ($this->_config->displayCartZeroTax($store))) {
    $address->addTotal(array(
        'code' => $this->getCode(),
        'title' => Mage::helper('tax')->__('Tax'),
        'full_info' => $applied ? $applied : array(),
        'value' => $amount,
        'area' => $area
    ));
}

If the tax/cart_display/grandtotal is set to “No”, then area doesn’t get assigned, and defaults to null, so the total will be output alongside all of the other totals.

Product Attributes

List of Parameters

Standard EAV Parameters

  • backend The backend model to use for saving values. These should extend Mage_Eav_Model_Entity_Attribute_Backend_Abstract
  • type default: varchar
  • frontend The frontend model to use for rendering values
  • input default: text
  • label The label to display in the admin
  • frontend_class
  • source The source model
  • required
  • user_defined
  • default The default value
  • unique
  • note Will be displayed under the input in the admin area

Catalog Product Specific
These are stored in the catalog_eav_attribute table, and the saving of them is catered for by the Mage_Catalog_Model_Resource_Setup class.

  • global The scope of the attributes. Default: Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL
  • visible default: 1
  • searchable default: 0
  • filterable default 0
  • comparable default 0
  • visible_on_front default 0
  • wysiwyg_enabled default 0
  • is_html_allowed_on_front default 0
  • visible_in_advanced_search default 0
  • filterable_in_search default 0
  • used_in_product_listing default 0
  • used_for_sort_by default 0
  • apply_to default 0
  • is_configurable default 1
  • used_for_promo_rules default 0

Attribute Sets and Groups

Attribute groups live in the eav_attribute_group table. They are assigned to attribute sets via their ID and have a default_id column to denote a default attribute group. Attribute sets can have multiple groups, and to change the order of the groups, use the sort_order column.

Getting All Attributes For An Entity (Raw SQL)

SELECT attribute_code, frontend_label
	FROM eav_attribute ea
	JOIN eav_entity_type eet 
		USING(entity_type_id)
	WHERE eet.entity_type_code = 'customer_address'

Running Setup Scripts

Adding product attributes need to be run through the Mage_Catalog_Model_Resource_Setup script. This extends Mage_Eav_Model_Entity_Setup and includes the code to deal with the extra options available in the catalog_eav_attribute table. If your setup scripts aren’t running as this and you can’t change it, if for example other setup scripts rely on a different class, you can directly instantiate it. This instantiates it with the core_setup resource which uses the default_setup connection.

$setup = new Mage_Catalog_Model_Resource_Setup('core_setup');

Adding A Product Attribute with Options

The following will add a dropdown field with the name ‘Product Overlay Logo’. It will have two options – Playline and Horse. Options added in this manner will have a blank option so that saving a product with one of these options is not required.

<?php
$installer = $this;

$installer->startSetup();

$setup = new Mage_Catalog_Model_Resource_Setup('core_setup');
$setup->addAttribute('catalog_product', 'product_overlay_logo', array(
    'attribute_set' => 'Default',
    'group'         => 'Hand Made Places',
    'input'         => 'select',
    'type'          => 'int',
    'label'         => 'Product Overlay Logo',
    'visible'       => true,
    'required'      => false,
    'visible_on_front' => true,
    'global'        => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
    'sort_order' => 10,
    'option' => array(
        'values' => array(
            0 => 'Playline',
            1 => 'Horse'
        )
    )
));
$installer->endSetup();

Adding Options with Translations

Use the Store IDs as the array keys for each language translation.

<?php
$installer = $this;

$installer->startSetup();

$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
$setup->addAttribute('catalog_product', 'product_overlay_logo', array(
    'attribute_set' => 'Default',
    'group'         => 'Hand Made Places',
    'input'         => 'select',
    'type'          => 'int',
    'label'         => 'Product Overlay Logo',
    'visible'       => true,
    'required'      => false,
    'visible_on_front' => true,
    'global'        => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
    'sort_order' => 10,
    'option' => array(
        'values' => array(
            0 => array(
                0 => 'Playline',
                1 => 'Playline French',
                2 => 'Playline German'
            ),
            1 => array(
                0 => 'Horse',
                1 => 'Horse French',
                2 => 'Horse German'
            )
        )
    )
));
$installer->endSetup();

Updating Attributes

It’s important to note that when using the EAV’s update attribute method that the attribute code is not converted to another code — the column should be referenced as it is in the database. E.g. visible_on_front should be is_visible_on_front:

<?php
$entityTypeId = $this->getEntityTypeId('catalog_product');
$this->updateAttribute($entityTypeId, 'is_visible_on_front', 'is_visible_on_front', 0);

Updating a Set of Product Attributes

$attrData = array(
    'attribute_code_here'=> 'Value Here',
);

$storeId = 0;

$productIds = Mage::getModel('catalog/product')->getCollection()->getAllIds();
Mage::getModel("catalog/product_action")->updateAttributes(
    $productIds, 
    $attrData, 
    $storeId
);

Mage_Eav_Model_Setup – Useful Methods

  • getEntityTypeId($entity_code); Gets the Database ID of the entity type with the given code (Eg. Customer)
  • getDefaultAttributeSetId($entityTypeId); Gets the default attribute set ID for the entity
  • getDefaultAttributeGroupId($entityTypeId, $attributeSetId = null); * Gets the default group for the entity‚Äôs attribute set. If no attribute set Id is passed in then the default set is used.
  • addAttribute($entity_code, $attribute_code, array)

Adding options to an existing attribute

Sometimes, options need to be added to existing attributes:


$eav = new Mage_Eav_Model_Entity_Setup('core_setup');
$attr = Mage::getSingleton('eav/config')->getAttribute($entityTypeId, $attributeCode);
 

$eav->addAttributeOption(array(
	'value' => array( 
		'small' => array(
			0 => 'Small'
		),
		'large' => array(
			0 => 'Large'
		)
	),
	'attribute_id' => $attr->getId(),
	'order' => array(
		'small' => 100,
		'large' => 200
	)
));

Adding Attribures to a Configurable Product’s Collection