:::: MENU ::::

Nueva fila de total + impuestos en Magento

3.00 avg. rating (60% score) - 7 votes

Continuando con el post anterior (Añadiendo un recargo por pagar con PayPal en Magento) en el que comentábamos la idea de crear un nuevo total con sus correspondientes impuestos, comenzamos por mostrar la estructura de archivos necesaria.

Como veis a continuación, es una estructura muy simple, con apenas 4 archivos de los cuales uno es opcional. Lo iremos complicando, no os preocupéis…

Archivos de Paypalfee

A continuación, entrando en el archivo de configuración de nuestra extensión, podemos ver, que es necesario declarar los nuevos totales. Serán dos: un total «general» y un totalizador «de impuestos».

El primero de ellos hereda de la clase Mage_Sales_Model_Quote_Address_Total_Abstract y mostrará una nueva fila entre los totales.

El segundo hereda, por el contrario de Mage_Sales_Model_Quote_Address_Total_Tax y no mostrará una nueva fila, sino que sumará una cantidad a los impuestos calculados.

Archivo de configuración de la extensión Magento para recargo de PayPal

<global>  
    <sales>
        <quote>
            <totals>
                <paypalfee>
                    <class>paypalfee/quote_total</class>
                    <after>subtotal,discount,shipping</after>
                    <before>tax,grand_total</before>
                </paypalfee>
                <paypalfee_tax>
                    <class>paypalfee/quote_taxTotal</class>
                    <after>subtotal,discount,shipping,tax</after>
                    <before>grand_total</before>
                </paypalfee_tax>
            </totals>
        </quote>
    </sales>
</global>

Como se puede apreciar, entre los datos que indicamos, está el modelo a utilizar (class) y cuándo debe calcularse el total, en este caso elegimos que sea siempre antes del total general y de los impuestos.

Además, indicaremos dónde se debe mostrar el nuevo total. Para ello, en otro bloque del archivo, añadiremos lo siguiente.

<default>
    <sales>
        <totals_sort>
            <paypalfee>15</paypalfee>
        </totals_sort>
    </sales>
</default>

Con esto indicamos que el «peso» de este total es 15. En función de como hayamos configurado el «peso» de los otros totales existentes (se puede hacer en la configuración desde el admin), nuestro total se mostrará en una posición u otra.

Como se puede ver, en este caso solo indicamos una posición para el total general, ya que nuestro total de impuestos, no genera una nueva fila y por tanto no se necesita un orden.

Nuevo total en Magento

A continuación, la clase que calcula nuestro nuevo total, tiene en su versión más básica, solo dos funciones, que son las siguientes.

class NV_Paypalfee_Model_Quote_Total extends Mage_Sales_Model_Quote_Address_Total_Abstract {

    // Cantidad del recargo sin impuestos
    var $_amount;

    /**
     * Esta función es llamada cada vez que Magento requiere calcular los
     * totales por cualquier motivo: carrito actualizado, usuario se logea,
     * aplicar un cupón, selección de medios de envío, de pago, etc.
     * 
     * Se trata de calcular lo que queremos añadir de recargo y actualizar
     * el total del carrito (Magento itera sobre los totales y cada uno añade
     * su parte)
     */
    public function collect(Mage_Sales_Model_Quote_Address $address) {
        parent::collect($address);

        // Si no hay items, no hay nada que hacer
        $items = $this->_getAddressItems($address);
        if (!count($items)) {
            return $this;
        }

        // Calculamos
        $this->_amount = Mage::getSingleton('paypalfee/paypalfee')->getTotalWithoutTax($address->getQuote());

        // Apuntamos lo que hemos calculado para usarlo luego
        // Idealmente esto debería ir a parar a la base de datos a un campo 
        // creado a los efectos 
        $address->setPaypalfeeAmount($this->_amount);
        $address->setBasePaypalfeeAmount($this->_amount);

        // Actualizamos el total de la quote
        $address->setGrandTotal($address->getGrandTotal() + $address->getPaypalfeeAmount());
        $address->setBaseGrandTotal($address->getBaseGrandTotal() + $address->getBasePaypalfeeAmount());

        return $this;
    }

    /**
     * Esta función es llamada por Magento cuando quiere mostrar los totales en pantalla.
     * 
     * El cálculo ya se habrá hecho y deberíamos guardarlo en algún sitio para aquí,
     * simplemente retornar el valor formateado y que Magento lo muestre.
     */
    public function fetch(Mage_Sales_Model_Quote_Address $address) {
        parent::fetch($address);

        // Obtenemos la cantidad a mostrar.
        // Si es cero, evitamos que se pinte.
        $amount = $address->getPaypalfeeAmount();
        if ($amount < 0.01) {
          return $this;
        }

        // Retornamos el total con su título
        $address->addTotal(array(
                    'code'  => 'paypalfee',
                    'title' => 'PayPal Fee',
                    'value' => $amount
                ));

        return $this;
    }
}

Finalmente, necesitamos añadir la parte proporcional de los impuestos a la fila de impuestos generales. Para ello creamos una clase similar a la anterior, pero heredando de una clase diferente:

Nueva fila de impuestos en Magento

class NV_Paypalfee_Model_Quote_TaxTotal extends Mage_Sales_Model_Quote_Address_Total_Tax {

    var $_amount;
    var $_baseAmount;

    /**
     * Esta función es llamada cada vez que Magento requiere calcular los
     * totales por cualquier motivo: carrito actualizado, usuario se logea,
     * aplicar un cupón, selección de medios de envío, de pago, etc.
     * 
     * Se trata de calcular lo que queremos añadir de recargo y actualizar
     * el total del carrito (Magento itera sobre los totales y cada uno añade
     * su parte)
     */
    public function collect(Mage_Sales_Model_Quote_Address $address) {

        // Si no hay items, fin
        $items = $address->getAllItems();
        if (!count($items)) {
            return $this;
        }

        // Impuestos al cliente
        $custTaxClassId = $address->getQuote()->getCustomerTaxClassId();

        $taxCalculationModel = Mage::getSingleton('tax/calculation');
        /* @var $taxCalculationModel Mage_Tax_Model_Calculation */
        $request = $taxCalculationModel->getRateRequest(
            $address,
            $address->getQuote()->getBillingAddress(),
            $custTaxClassId,
            $store
        );

        $rate = 21; // Indicar la tasa correspondiente al impuesto aplicado
        $this->_amount = calculartotal * $rate / 100;
        $this->_baseAmount = calculartotal * $rate / 100;

        $address->setTaxAmount($address->getTaxAmount() + $this->_amount);
        $address->setBaseTaxAmount($address->getBaseTaxAmount() + $this->_baseAmount);

        $this->_saveAppliedTaxes(
            $address,
            $taxCalculationModel->getAppliedRates($request),
            $this->_amount,
            $this->_baseAmount,
            $rate
        );

        $address->setPaypalfeeTaxAmount($this->_amount);
        $address->setBasePaypalfeeTaxAmount($this->_baseAmount);

        $address->setGrandTotal($address->getGrandTotal() + $address->getPaypalfeeTaxAmount());
        $address->setBaseGrandTotal($address->getBaseGrandTotal() + $address->getBasePaypalfeeTaxAmount());

        return $this;
    }

    /**
     * Esta función es llamada por Magento cuando quiere mostrar los totales en pantalla.
     * 
     * En este caso, como los impuestos se muestran sumados a los impuestos generales, no
     * es necesario retornar una nueva fila... a no ser que queramos mostrar el desglose de
     * impuestos... eso será otro tutorial ;)
     */
    public function fetch(Mage_Sales_Model_Quote_Address $address) {

        return $this;
    }
}

Con esto, al llegar al carrito, deberíais ver una nueva fila en la que se muestra un recargo por PayPal, junto con los impuestos correspondientes, pero hay mucho trabajo por delante que os dejo como deberes.

Entre otras cosas es necesario limitar este recargo solo al medio de pago PayPal ya que ahora mismo se aplicará a cualquier medio de pago.

También será necesario guardar los importes calculados en la base de datos.




2 Comments

  • Responder Carlos Hernan |

    Buen día de ante mano gracias por este buen tutorial tengo una consulta la clase NV_Paypalfee_Model_Quote_TaxTotal esta sobre escribiendo la clase Mage_Sales_Model_Quote_Address_Total_Tax ?

    • Responder Daniel Navarro Murillo |

      NV_Paypalfee_Model_Quote_TaxTotal está extendiendo la clase Mage_Sales_Model_Quote_Address_Total_Tax.

      Sobreescribir una clase en magento tiene un significado un poco diferente. Al sobreescribir se utilizaría NV_Paypalfee_Model_Quote_TaxTotal en lugar de Mage_Sales_Model_Quote_Address_Total_Tax en todos los lugares donde se utilice la segunda, pero no es este caso.

      Aquí NV_Paypalfee_Model_Quote_TaxTotal amplia o extiende Mage_Sales_Model_Quote_Address_Total_Tax, pero para usarse solo en el módulo que estamos desarrollando, y no en el resto del sistema.

Hey! Qué opinas sobre el artículo?