Fecha de factura en Prestashop

Descripción del error de fecha de factura en Prestashop

Probablemente te has encontrado con esta situación en Prestashop más de una vez. Cuando has validado un pedido cuyo estado genera un albarán ("Generar PDF de la entrega"), éste se crea con la fecha de la generación pero cuando más adelante cambias el estado a uno que genera factura, la fecha de factura en Prestashop coincide con la del albarán y no con la fecha de generación de la factura.

Este error es muy habitual cuando se trabaja con el pago contrareembolso o simplemente cuando quieres generar un albarán cuyo pedido no ha sido pagado aún (por que por ejemplo se pagará por transferencia bancaria más adelante) y pasados unos días necesitas una factura con la fecha actual.

Este problema se debe a cómo Prestashop gestiona los albaranes y las facturas. Concretamente utiliza la tabla order_invoice para guardar una línea por cada albarán generado con la fecha actual de generación del albarán y reutiliza esta misma línea para obtener esta fecha en la generación de la factura, con lo que albarán y factura coinciden en fecha.

Cómo arreglarlo

Para arreglar este comportamiento basta con hacer un Override de la clase Order sobreescribiendo la función setInvoice como muestra el siguiente código. así que bastará con que coloques el siquiente código en un archivo llamado Order.php y éste lo sitúes en /override/classes/Order/. Para que este cambio surta efecto debes borrar el archivo cache de clases /cache/class_index.php.

Finalmente es conveniente que el estado posterior al que genera la factura (Por ejemplo Entregado), tenga desmarcado la generación de albarán para que la fecha del albarán no sea posterior a la de la factura.

Con esto conseguirás que la fecha de factura en Prestashop sea independiente de la del albarán.

 

<?php

class Order extends OrderCore
{

    /**
     * This method allows to generate first invoice of the current order
     */
    public function setInvoice($use_existing_payment = false)
    {
        if (!$this->hasInvoice()) {
            if ($id = (int)$this->getOrderInvoiceIdIfHasDelivery()) {
                $order_invoice = new OrderInvoice($id);
            } else {
                $order_invoice = new OrderInvoice();
            }
            $order_invoice->id_order = $this->id;
            if (!$id) {
                $order_invoice->number = 0;
            }

            // Save Order invoice

            $this->setInvoiceDetails($order_invoice);

            if (Configuration::get('PS_INVOICE')) {
                $this->setLastInvoiceNumber($order_invoice->id, $this->id_shop);
            }



            // Update order_carrier
            $id_order_carrier = Db::getInstance()->getValue('
				SELECT `id_order_carrier`
				FROM `'._DB_PREFIX_.'order_carrier`
				WHERE `id_order` = '.(int)$order_invoice->id_order.'
				AND (`id_order_invoice` IS NULL OR `id_order_invoice` = 0)');

            if ($id_order_carrier) {
                $order_carrier = new OrderCarrier($id_order_carrier);
                $order_carrier->id_order_invoice = (int)$order_invoice->id;
                $order_carrier->update();
            }

            // Update order detail
            Db::getInstance()->execute('
				UPDATE `'._DB_PREFIX_.'order_detail`
				SET `id_order_invoice` = '.(int)$order_invoice->id.'
				WHERE `id_order` = '.(int)$order_invoice->id_order);
            Cache::clean('objectmodel_OrderDetail_*');

            // Update order payment
            if ($use_existing_payment) {
                $id_order_payments = Db::getInstance()->executeS('
					SELECT DISTINCT op.id_order_payment
					FROM `'._DB_PREFIX_.'order_payment` op
					INNER JOIN `'._DB_PREFIX_.'orders` o ON (o.reference = op.order_reference)
					LEFT JOIN `'._DB_PREFIX_.'order_invoice_payment` oip ON (oip.id_order_payment = op.id_order_payment)
					WHERE (oip.id_order != '.(int)$order_invoice->id_order.' OR oip.id_order IS NULL) AND o.id_order = '.(int)$order_invoice->id_order);

                if (count($id_order_payments)) {
                    foreach ($id_order_payments as $order_payment) {
                        Db::getInstance()->execute('
							INSERT INTO `'._DB_PREFIX_.'order_invoice_payment`
							SET
								`id_order_invoice` = '.(int)$order_invoice->id.',
								`id_order_payment` = '.(int)$order_payment['id_order_payment'].',
								`id_order` = '.(int)$order_invoice->id_order);
                    }
                    // Clear cache
                    Cache::clean('order_invoice_paid_*');
                }
            }

            // Update order cart rule
            Db::getInstance()->execute('
				UPDATE `'._DB_PREFIX_.'order_cart_rule`
				SET `id_order_invoice` = '.(int)$order_invoice->id.'
				WHERE `id_order` = '.(int)$order_invoice->id_order);

            // Keep it for backward compatibility, to remove on 1.6 version
            $new_os = new OrderState((int)$this->current_state, $this->id_lang);
            if ($new_os->invoice && !$this->invoice_number) {
                $this->invoice_date = date('Y-m-d H:i:s');

                // Update order detail
                Db::getInstance()->execute('
                UPDATE `'._DB_PREFIX_.'order_invoice`
                SET `date_add` = NOW()
                WHERE `id_order_invoice` = '.(int)$order_invoice->id);
            } else {
                $this->invoice_date = $order_invoice->date_add;
            }
            

            if (Configuration::get('PS_INVOICE')) {
                $this->invoice_number = $this->getInvoiceNumber($order_invoice->id);
                $invoice_number = Hook::exec('actionSetInvoice', array(
                    get_class($this) => $this,
                    get_class($order_invoice) => $order_invoice,
                    'use_existing_payment' => (bool)$use_existing_payment
                ));

                if (is_numeric($invoice_number)) {
                    $this->invoice_number = (int)$invoice_number;
                } else {
                    $this->invoice_number = $this->getInvoiceNumber($order_invoice->id);
                }
            }

            $this->update();
        }
    }

}

Si necesitas ayuda con tu Prestashop o quieres crear una tienda online, no dudes en contactar conmigo y hablamos.

Hay numerosos pasos en el proceso de diseño y desarrollo de sitios web. Desde la recopilación de información inicial, a la creación de tu sitio web, y finalmente al mantenimiento para mantener tu sitio web actualizado y seguro, es importante conocerlos para conseguir unos buenos resultados.

La mayorías de las extensiones Joomla! aún utilizan un sistema de construcción basado en Phing, que hace su trabajo pero sin utilizar las últimas tecnologías. Gulp es un sistema de construcción moderno basado en Node.js increíblemente rápido y fácil de entender ya que usa código javascript.