Magento: pedidos, stocks y su ciclo de vida

2016-11-14 - Categorías: General / Magento
Magento motor

Para mejorar la eficiencia de una empresa, debemos de darle especial atención a la cantidad de activos que tenemos disponibles. Los activos de una empresa son los productos que se venden. Saber cuántos hay exactamente, cuántos hay que pedir a proveedores, si permitimos ventas infinitas, si estamos en rotura de stock.. Todo esto es información muy importante para mejorar los procesos de una empresa. Si esto mejora, debería de mejorar también el trato con el cliente, la percepción que tiene de nosotros, la cantidad de incidencias que podamos tener. Podemos pensar que tenemos un producto en stock que luego hay que pedir a proveedores. O puede pasar que no se esté vendiendo un producto que tenemos en stock. O simplemente para minimizar la cantidad de stock en almacén también es interesante automatizar todo lo que se pueda. Aquí llegamos al ciclo de vida de los pedidos y stocks en Magento.

Todo esto es un tema muy grande, y a la par divertido. Ir viendo cómo con cada ajuste todo mejora. Ir viendo cómo con cada batida de inventario el catálogo va mejorando día a día. Los productos se crean, suben los stocks. Bajan hasta llegar a cero, se pone a fuera de existencia.. Pedidos por debajo de cero creando necesidades de compra al suministrador.. Limitando existencias dejando al cliente que sepa que se lo podemos pedir..

Todo este control es un clásico de un ERP. Un ERP es un programa muy muy complejo de poner en marcha. Las muy pequeñas y pequeñas empresas no los suelen tener porque necesita mucho esfuerzo para ponerlo en marcha y revisarlo. Pero una vez más, Magento trae parte de esta gestión incorporada en el sistema. Es decir, Magento no es un ERP, pero te trae parte de la gestión de existencias ya incorporada de casa.

Aquí traigo entonces unos pocos HOWTOs para revisar y mantener todo esto en Magento.

Primeras configuraciones a nivel global

Tenemos cuatro principales configuraciones globales en Magento para todo esto:

  • Configuración global de gestión de existencias (manage_stock): que se aplica cuando el producto tiene que coger la configuración global.
  • Configuración global de pedidos por debajo de cero (backorders): que igualmente se aplica cuando el producto tiene que coger la configuración global que haya.
  • Disminuir existencias cuando un pedido se cree (can_subtract).
  • Restablecer existencias cuando un pedido se cancele (can_back_in_stock).

Todo esto lo tenemos en Sistema > Configuración > Catálogo > Inventario. La idea es conseguir que todas las existencias se gestionen. Ya sea con una cantidad limitada o ilimitada permitiendo cantidades por debajo de cero. Pero si directamente hacemos esto en configuración global y no configuramos los productos individualmente, lo que conseguiremos es dejar de vender todos los productos. Porque los productos cogen por defecto la configuración global, y si gestionamos existencias globalmente, tendremos que ponerle un stock.

Otra opción es permitir pedidos por debajo de cero gestionando las existencias. Es interesante porque las unidades positivas significan productos que están en el almacén, mientras que las negativas significan necesidades de suministro. Esto lo permite Magento, hasta tal punto que también permite notificar al cliente si no hubiera existencias. También permite decirle al cliente si hay que pedir a proveedor las unidades que quiere.

Cuando restar y sumar existencias con los pedidos

El disminuir y restablecer las unidades de stock cuando se crean o se cancelan los pedidos lo considero indispensable. Pensemos que no restamos el stock cuando se hace el pedido, podemos tener varios pedidos de una misma unidad aunque sólo tengamos 1 unidad disponible. Esto sería un problema. Por otro lado, imaginemos que restamos pero no restablecemos las unidades cuando un pedido se cancela. Entonces restaremos y restaremos hasta quedarnos sin nada.

Otra cosa a tener en cuenta es que hay que cancelar los pedidos que finalmente no se hacen para que las unidades no se queden pilladas. Ya sea manualmente o automáticamente con un módulo, Magento no cancela automáticamente porque intervienen otros datos en este proceso. Así que toca revisarlos manualmente, o poner un módulo que vaya cancelándolos automáticamente. Cuidadín con esto, porque no todos los pedidos se pueden cancelar automáticamente así como así. Hay que revisar si tienen factura hecha porque habría que hacer un abono en tal caso. Quizá no es una cancelación de pedido lo que necesites en algunos pedidos, sino un cierre del mismo. También se pueden suspender, o finalmente, revisar manualmente los que no tengas claro.

Las configuraciones a nivel individual de cada producto

Dentro de cada producto, para la configuración de existencias, tenemos los siguientes elementos relacionados con esto:

  • Usar configuración global de gestión de existencias.
  • Gestión de existencias para este producto.
  • Cantidad.
  • Usar configuración global de pedidos por debajo de cero.
  • Pedidos por debajo de cero, aquí podemos no permitir, permitir o permitir y notificar al cliente.

Una cosa que puede marear a la hora de configurar esto es la disponibilidad que se pondrá en existencia o fuera de existencia automáticamente. Esto lo hace según el resto de configuraciones que hayas puesto. Por ejemplo, si ponemos gestión de existencias con cantidad 0, pero permitimos pedidos por debajo de cero, el producto se seguirá vendiendo y lo verás en existencia aunque tengamos 0 unidades. El producto automáticamente se pondrá en existencias y cuando baje de 0 creará una necesidad de suministro. Entonces verás cantidades negativas.

Listando el estado de todos los productos

Ahora vamos con algo de código. Para ver las configuraciones globales que tenemos podemos hacer lo siguiente:

$configManageStock = Mage::getStoreConfig('cataloginventory/item_options/manage_stock');
$configBackorders = Mage::getStoreConfig('cataloginventory/item_options/backorders');
$configBackInStock = Mage::getStoreConfig('cataloginventory/options/can_back_in_stock');
$configCanSubstractStock = Mage::getStoreConfig('cataloginventory/options/can_subtract');

Ahora bien, para saber la configuración de un producto podemos hacer lo siguiente:

$productId = 1;
$product = Mage::getModel('catalog/product')->setStoreId(0)->load($productId);
$stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product);
$manageStock = $stockItem->getData('manage_stock');
$useConfigManageStock = $stockItem->getData('use_config_manage_stock');
$backorders = $stockItem->getData('backorders');
$useConfigBackorders = $stockItem->getData('use_config_backorders');
$isInStock = $stockItem->getData('is_in_stock');
$qty = $stockItem->getData('qty');

Teniendo esto, es fácil recorrer todos los productos listando su estado de existencias. Me remito a este otro post para ver cómo recorrer los productos. Al final del post hay una pequeña consulta para obtener la colección de productos y luego podemos recorrerlos haciendo esto de aquí arriba. Vamos a ver el bucle mejor aquí:

<?php
require_once __DIR__.'/app/Mage.php';
Mage::app();
$productsCollection = Mage::getModel('catalog/product')->getCollection();
foreach ($productsCollection as $product) {
    $product = Mage::getModel('catalog/product')->setStoreId(0)->load($product->getId());
    $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product);
    $manageStock = $stockItem->getData('manage_stock');
    $useConfigManageStock = $stockItem->getData('use_config_manage_stock');
    $backorders = $stockItem->getData('backorders');
    $useConfigBackorders = $stockItem->getData('use_config_backorders');
    $isInStock = $stockItem->getData('is_in_stock');
    $qty = $stockItem->getData('qty');
    // .. aquí es donde hacemos algo con los datos, 
    // como escribir por pantalla, grabar a fichero o actualizarlos..
}

Luego, de la misma forma podemos actualizar el estado del stock de un producto así:

$stockItem->setData('manage_stock', $newManageStock);
$stockItem->setData('use_config_manage_stock', $newUseConfigManageStock);
$stockItem->setData('backorders', $newBackorders);
$stockItem->setData('use_config_backorders', $newUseConfigBackorders);
$stockItem->setData('qty', $newQty);
$stockItem->save();

De aquí en adelante, depende de lo que necesitemos, desarrollaremos. Con esto es sencillo hacer un script que cargue los datos de stock de productos desde un fichero CSV. Que cargue el fichero y los actualice en Magento masivamente ¿verdad? No hay que hacer complejas consultas a la base de datos. Aunque se podrían hacer, no es nada práctico ya que tenemos el framework de Magento que nos abstrae mediante PHP de todo lo que haya por debajo (el framework de Zend, componentes de Symfony, o incluso el tipo de la base de datos..).

Los pedidos pendientes

Ahora bien, nos queda tener en cuenta que tenemos que cancelar, completar o cerrar absolutamente todos los pedidos. Los pedidos que no están cancelados, completados o cerrados son pedidos que no han terminado su ciclo de vida. Están sin acabar y puede que tengan unidades pilladas porque hayan restado del stock. Si finalmente no se vende el producto, y no se cancela o se cierra el pedido, dicha unidad se habrá restado pero no devuelto a su stock para vender.

Así que una pequeña consulta para sacar todos estos pedidos nos puede facilitar la vida:

$orderModel = Mage::getModel('sales/order');
$ordersCollection = $orderModel->getCollection()
    ->addFieldToFilter('state', array('nin' => array('canceled', 'complete', 'closed')))
    ->addAttributeToSort('created_at', 'desc');
foreach ($ordersCollection as $order) {
    echo $order->getIncrementId().PHP_EOL;
}

Ahora habría que revisar si son pedidos muy antiguos para terminarlos cada uno según proceda.

Terminando

Rizando el rizo con todo esto, es interesante saber que Magento permite que el cliente se registre en el caso de que no queden unidades disponible. Así luego podemos notificarle si volvemos a tener unidades en almacén, o si el producto vuelve a estar disponible. Podemos permitir pedidos por debajo de cero (backorders) notificándole al cliente o no. Si a lo que ya nos trae Magento le vamos añadiendo extensiones, no haremos más que añadir más y más funcionalidades. Imagina pues una extensión que recoja todos los pedidos pendientes y te los prepare para que los sirvas. Imagina poder de una tacada imprimir todos los pedidos que tienes que preparar para ir a almacén. O imagina que quieres saber lo que tienes que pedir a proveedores para cubrir el stock mínimo, o para servir los pedidos que tienes ‘bajo pedido’ (backorders). Imagina que quieres saber qué productos te sirve cada proveedor, o qué proveedores tienes para cada producto. Todo esto y más, clásicos de un ERP, nos los estamos encontrando cada vez más integrados dentro de Magentos.

La verdad que lo engorroso que es comenzar a trabajar con Magento, lo suple después con una brutal capacidad y flexibilidad de configuraciones. Esta flexibilidad y robustez se la cobra con la cantidad de cosas que hay que aprender para usarlo. Pero el que algo quiere algo le cuesta no? 😉

Disfruto cada día más descubriendo los entresijos de Magento y tengo claro que no me lo voy a acabar. Ya con esto lo dejo, y otro día más..

2 respuestas a “Magento: pedidos, stocks y su ciclo de vida”

  1. Irene dice:

    Necesito saber como se saca el ciclo de ventas en magento

    • Jnj dice:

      ¡Hola Irene!

      Lo que necesitas es sacar los pedidos entre fechas que se hayan terminado correctamente. Aquí tienes cómo listar pedidos entre fechas:
      https://jnjsite.com/magento-el-problema-de-las-fechas/

      Para listar sólo los pedidos completados, que son los que contabilizan como ventas tienes que hacer algo así:

      $orderModel = Mage::getModel(‘sales/order’);
      $ordersCollection = $orderModel->getCollection()
      ->addFieldToFilter(‘created_at’, array(
      ‘from’ => $startDate,
      ‘to’ => $endDate,
      ))
      ->addFieldToFilter(‘state’, array(‘complete’))
      //->addFieldToFilter(‘state’, array(‘nin’ => array(‘canceled’, ‘complete’, ‘closed’))) // esto son los pedidos sin terminar
      ->addAttributeToSort(‘created_at’, ‘desc’);

      Con esto sólo te queda recorrer los pedidos que hay en $ordersCollection para ir sumando lo que se ha vendido. O para ir sumando las unidades de cada producto vendido. O lo que necesites..

      El monto total de un pedido se saca con $order->getGrandTotal();

      Espero que sirva.
      Saludos.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

 

© 2024 JnjSite.com - MIT license

Sitio hecho con WordPress, diseño y programación del tema por Jnj.