<?php

require_once 'odoo_auth.php';

class OdooOrdenVenta
{

    public static function getInvoices()
    {
        try {
            $models = OdooAuth::getOdoo();

            // Buscar IDs de facturas
            $invoice_ids = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'account.move',
                'search',
                array(
                    array(
                        array('move_type', '=', 'out_invoice'),
                        array('state', '!=', 'cancel')
                    )
                )
            );

            // Leer datos de las facturas
            $invoices = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'account.move',
                'read',
                array($invoice_ids),
                array()
            );

            return $invoices;
        } catch (Exception $e) {
            // Manejo del error
            error_log($e->getMessage());
            return false;
        }
    }

    public static function getAccountMoveFields()
    {
        try {
            $models = OdooAuth::getOdoo();

            // Obtener los campos del modelo account.move
            $fields = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'account.move',
                'fields_get',
                array(), // Array vacío para los argumentos
                array()  // Opcional: array de opciones (puede estar vacío)
            );

            return $fields;
        } catch (Exception $e) {
            // Manejo del error
            error_log($e->getMessage());
            return false;
        }
    }

    public static function confirmInvoice($invoice_id)
    {
        try {
            $models = OdooAuth::getOdoo();

            // Confirmar la factura
            $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'account.move',
                'action_post',
                array(array($invoice_id))
            );

            return true;
        } catch (Exception $e) {
            // Manejo del error
            error_log($e->getMessage());
            return false;
        }
    }

    public static function assignSalesTeamToSaleOrder($sale_order_id, $sales_team_id)
    {
        try {
            $models = OdooAuth::getOdoo();

            // Actualizar la orden de venta con el ID del equipo de ventas
            $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'sale.order',
                'write',
                array(array($sale_order_id), array('team_id' => $sales_team_id))
            );

            return true;
        } catch (Exception $e) {
            // Manejo del error
            error_log($e->getMessage());
            return false;
        }
    }

    public static function assignAnalyticAccountToSaleOrder($sale_order_id, $analytic_account_id)
    {
        try {
            $models = OdooAuth::getOdoo();

            // Actualizar la orden de venta con el ID de la cuenta analítica
            $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'sale.order',
                'write',
                array(array($sale_order_id), array('analytic_account_id' => $analytic_account_id))
            );

            return true;
        } catch (Exception $e) {
            // Manejo del error
            error_log($e->getMessage());
            return false;
        }
    }

    public static function addNewSaleOrder($partner_id, $warehouse_id, $analytic_account_id)
    {
        try {

            $models = OdooAuth::getOdoo();
            $sale_order_id = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'sale.order',
                'create',
                array(
                    array(
                        'partner_id' => $partner_id,
                        'warehouse_id' => $warehouse_id,
                        'partner_invoice_id' => $partner_id,
                        'partner_shipping_id' => $partner_id,
                        // Este campo de user_id es el usuario administrador, hay que reemplazar por el id del usuario
                        // que está creando la orden de venta
                        'user_id' => 15,
                        'analytic_account_id' => $analytic_account_id, // añadir la cuenta analítica
                        // añadir cualquier otro campo requerido
                    )
                )
            );
            return $sale_order_id;
        } catch (Exception $e) {
            // Manejar la excepción
            error_log($e->getMessage());
            return false;
        }
    }

    public static function addNewLineToSaleOrder($sale_order_id, $product_id, $qty)
    {
        try {
            $models = OdooAuth::getOdoo();
            $sale_order_line_id = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'sale.order.line',
                'create',
                array(
                    array(
                        'order_id' => $sale_order_id,
                        'product_id' => $product_id, // el ID del primer producto
                        'product_uom_qty' => $qty, // la cantidad vendida del primer producto
                        'name' => "Descripción de tu producto", // necesitas agregar esto
                    )
                )
            );
            return $sale_order_line_id;
        } catch (Exception $e) {
            // Manejar la excepción
            error_log($e->getMessage());
            return false;
        }
    }

    public static function updatePriceOfSaleOrderLine($sale_order_line_id, $new_price)
    {
        try {
            $models = OdooAuth::getOdoo();
            $result = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'sale.order.line',
                'write',
                array(
                    array($sale_order_line_id),
                    array('price_unit' => $new_price)
                )
            );

            return $result;
        } catch (Exception $e) {
            // Manejo del error
            error_log($e->getMessage());
            return false;
        }
    }

    public static function confirmSaleOrder($sale_order_id)
    {
        try {
            $models = OdooAuth::getOdoo();
            $confirm = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'sale.order',
                'action_confirm',
                array(array($sale_order_id))
            );

            return ($confirm) ? true : false;
        } catch (Exception $e) {
            // Manejar la excepción
            error_log($e->getMessage());
            return false;
        }
    }

    public static function validateSaleOrder($sale_order_id)
    {
        try {
            $models = OdooAuth::getOdoo();
            $confirm = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'sale.order',
                'validate_order',
                array(array($sale_order_id))
            );

            return ($confirm) ? true : false;
        } catch (Exception $e) {
            // Manejar la excepción
            error_log($e->getMessage());
            return false;
        }
    }

    public static function addNoteToOrder($sale_order_id, $note)
    {
        try {
            $models = OdooAuth::getOdoo();

            $sale_order_name = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'sale.order',
                'read',
                array(
                    array($sale_order_id),
                    array('name')
                )
            )[0]['name'];

            // Primero, obtén el picking asociado con la orden de venta
            $picking_ids = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'stock.picking',
                'search',
                array(array(array('origin', '=', $sale_order_name)))
            );

            // return;

            if (count($picking_ids) > 0) {
                $picking_id = $picking_ids[0];

                // Crear un nuevo mensaje de seguimiento
                $message_id = $models->execute_kw(
                    OdooAuth::$db,
                    OdooAuth::$uid,
                    OdooAuth::$password,
                    'mail.message',
                    'create',
                    array(
                        array(
                            'body' => $note, // contenido de la nota
                            'model' => 'stock.picking', // modelo al que se asocia la nota
                            'res_id' => $picking_id, // ID del registro al que se asocia la nota
                            'message_type' => 'comment', // tipo de mensaje ('comment' para notas internas)
                            'subtype_id' => 1, // ID del subtipo de mensaje (1 para notas internas)
                        )
                    )
                );

                return $message_id;
            }
        } catch (Exception $e) {
            // Manejar la excepción
            error_log($e->getMessage());
            return false;
        }
    }

    public static function confirmPicking($sale_order_id)
    {
        // try {
        //     $models = OdooAuth::getOdoo();

        //     $sale_order_name = $models->execute_kw(
        //         OdooAuth::$db,
        //         OdooAuth::$uid,
        //         OdooAuth::$password,
        //         'sale.order',
        //         'read',
        //         array(
        //             array($sale_order_id),
        //             array('name')
        //         )
        //     )[0]['name'];

        //     // Primero, obtén el picking asociado con la orden de venta
        //     $picking_ids = $models->execute_kw(
        //         OdooAuth::$db,
        //         OdooAuth::$uid,
        //         OdooAuth::$password,
        //         'stock.picking',
        //         'search',
        //         array(array(array('origin', '=', $sale_order_name)))
        //     );

        //     if (count($picking_ids) > 0) {
        //         $picking_id = $picking_ids[0];

        //         // Confirmar el picking
        //         $models->execute_kw(
        //             OdooAuth::$db,
        //             OdooAuth::$uid,
        //             OdooAuth::$password,
        //             'stock.picking',
        //             'button_validate',
        //             array($picking_id)
        //         );

        //         return true;
        //     }
        // } catch (Exception $e) {
        //     // Manejar la excepción
        //     error_log($e->getMessage());
        //     return false;
        // }
        try {
            $models = OdooAuth::getOdoo();

            // Obtener el nombre de la orden de venta
            $sale_order_name = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'sale.order',
                'read',
                array(
                    array($sale_order_id),
                    array('name')
                )
            )[0]['name'];

            // Obtener el picking asociado con la orden de venta
            $picking_ids = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'stock.picking',
                'search',
                array(array(array('origin', '=', $sale_order_name)))
            );

            if (count($picking_ids) > 0) {
                $picking_id = $picking_ids[0];

                // Verificar la disponibilidad de los productos en el picking
                $availability_result = $models->execute_kw(
                    OdooAuth::$db,
                    OdooAuth::$uid,
                    OdooAuth::$password,
                    'stock.picking',
                    'action_assign',
                    array($picking_id)
                );

                if (!$availability_result) {
                    // Si la disponibilidad no se puede confirmar, iterar sobre los move lines
                    $picking = $models->execute_kw(
                        OdooAuth::$db,
                        OdooAuth::$uid,
                        OdooAuth::$password,
                        'stock.picking',
                        'read',
                        array(array($picking_id), array('move_line_ids'))
                    );

                    $move_line_ids = $picking[0]['move_line_ids'];

                    // Iterar sobre los move lines para verificar disponibilidad
                    foreach ($move_line_ids as $move_line_id) {
                        $move_line = $models->execute_kw(
                            OdooAuth::$db,
                            OdooAuth::$uid,
                            OdooAuth::$password,
                            'stock.move.line',
                            'read',
                            array(array($move_line_id), array('product_id', 'qty_done', 'location_id', 'location_dest_id', 'product_uom_qty'))
                        )[0];

                        if ($move_line['qty_done'] < $move_line['product_uom_qty']) {
                            // Completar el movimiento de stock si no está disponible
                            $product_id = $move_line['product_id'][0];
                            $location_id = $move_line['location_id'][0];
                            $location_dest_id = $move_line['location_dest_id'][0];

                            // Buscar la ubicación con el stock disponible
                            $quant_ids = $models->execute_kw(
                                OdooAuth::$db,
                                OdooAuth::$uid,
                                OdooAuth::$password,
                                'stock.quant',
                                'search_read',
                                array(
                                    array(
                                        array('product_id', '=', $product_id),
                                        array('location_id', '=', $location_id)
                                    )
                                ),
                                array('fields' => array('quantity', 'reserved_quantity', 'location_id'))
                            );

                            // Asumimos que el stock está disponible en la ubicación de origen
                            foreach ($quant_ids as $quant) {
                                if ($quant['quantity'] > $quant['reserved_quantity']) {
                                    $available_qty = $quant['quantity'] - $quant['reserved_quantity'];
                                    $models->execute_kw(
                                        OdooAuth::$db,
                                        OdooAuth::$uid,
                                        OdooAuth::$password,
                                        'stock.move.line',
                                        'write',
                                        array(array($move_line_id), array('qty_done' => min($available_qty, $move_line['product_uom_qty'])))
                                    );
                                    break;
                                }
                            }
                        }
                    }

                    // Intentar de nuevo confirmar la disponibilidad después de completar los movimientos
                    $models->execute_kw(
                        OdooAuth::$db,
                        OdooAuth::$uid,
                        OdooAuth::$password,
                        'stock.picking',
                        'action_assign',
                        array($picking_id)
                    );
                }

                // Confirmar el picking
                $models->execute_kw(
                    OdooAuth::$db,
                    OdooAuth::$uid,
                    OdooAuth::$password,
                    'stock.picking',
                    'button_validate',
                    array($picking_id)
                );

                return true;
            } else {
                throw new Exception('No se encontró el picking asociado con la orden de venta.');
            }
        } catch (Exception $e) {
            // Manejar la excepción
            error_log($e->getMessage());
            return false;
        }
    }

    public static function moveStock($product_id, $quantity, $source_warehouse_id, $destination_warehouse_id)
    {
        try {
            $models = OdooAuth::getOdoo();
            // Create a new stock move
            $stock_move_id = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'stock.move',
                'create',
                array(
                    array(
                        'product_id' => $product_id,
                        'product_uom_qty' => $quantity,
                        'location_id' => $source_warehouse_id,
                        'location_dest_id' => $destination_warehouse_id,
                    )
                )
            );

            // Confirm the stock move
            $confirm = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'stock.move',
                'action_confirm',
                array(array($stock_move_id))
            );

            return ($confirm) ? true : false;
        } catch (Exception $e) {
            // Manejar la excepción
            error_log($e->getMessage());
            return false;
        }
    }

    public static function createInvoiceFromAdvancePayment($sale_order_id)
    {
        try {
            $models = OdooAuth::getOdoo();

            // Crear un registro en sale.advance.payment.inv
            $advance_payment_data = array(
                'advance_payment_method' => 'delivered',
                // Asumiendo que la lógica de tu Odoo espera un contexto con los IDs de pedido de venta
                // o necesita definir explícitamente los pedidos de venta para los cuales se crearán facturas.
            );

            // Establecer el contexto para la operación, asumiendo que el método `create_invoices`
            // utiliza el contexto para determinar para qué pedidos de venta crear facturas.
            $context = array('active_ids' => array($sale_order_id), 'active_id' => $sale_order_id);

            $advance_payment_id = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'sale.advance.payment.inv',
                'create',
                array($advance_payment_data),
                array('context' => $context)
            );

            $sale_order_name = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'sale.order',
                'read',
                array(
                    array($sale_order_id),
                    array('name')
                )
            )[0]['name'];

            // Llamar al método create_invoices en el registro creado, pasando el contexto
            $invoice_ids = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'sale.advance.payment.inv',
                'create_invoices',
                array(array($advance_payment_id)),
                array('context' => $context)
            );

            // print_r($invoice_ids);

            return $sale_order_name;
        } catch (Exception $e) {
            // Manejo del error
            error_log($e->getMessage());
            return false;
        }
    }

    public static function getInvoiceIDsAndConfirmBySaleOrderID($sale_order_id, $fg_periodicity, $fg_months, $fg_year)
    {

        try {
            $models = OdooAuth::getOdoo();

            $invoice_origin_format = $sale_order_id;

            $invoice_ids = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'account.move',
                'search',
                array(
                    array(
                        array('invoice_origin', '=', $invoice_origin_format),
                        array('state', '=', 'draft'), // Asumiendo que las facturas están en estado borrador
                    )
                )
            );

            if (empty($invoice_ids)) {
                return false;
            }

            // Confirmar cada factura encontrada
            foreach ($invoice_ids as $invoice_id) {

                if (!is_null($fg_periodicity) && !is_null($fg_months) && !is_null($fg_year)) {
                    $models->execute_kw(
                        OdooAuth::$db,
                        OdooAuth::$uid,
                        OdooAuth::$password,
                        'account.move',
                        'write',
                        array(array($invoice_id), array(
                            'global_invoice' => true,
                            'fg_periodicity' => $fg_periodicity,
                            'fg_months' => $fg_months,
                            'fg_year' => $fg_year
                        ))
                    );
                }

                $models->execute_kw(
                    OdooAuth::$db,
                    OdooAuth::$uid,
                    OdooAuth::$password,
                    'account.move',
                    'action_post',
                    array(array($invoice_id))
                );
            }

            return true;
        } catch (Exception $e) {
            // Manejo del error
            error_log($e->getMessage());
            return false;
        }
    }

    public static function verificarYObtenerLogFactura($sale_order_id)
    {
        try {
            $models = OdooAuth::getOdoo();

            $sale_order = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'sale.order',
                'read',
                array(array(intval($sale_order_id)), array('invoice_ids'))
            );

            if (empty($sale_order)) {
                throw new Exception("No se encontró la orden de venta: $sale_order_id");
            }

            $invoice_ids = $sale_order[0]['invoice_ids'][0];

            if (empty($invoice_ids)) {
                throw new Exception("No se encontraron facturas para la orden de venta: $sale_order_id");
            }

            // Leer los campos cfdi_folio_fiscal y cfdi_last_message de las facturas
            $facturas = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'account.move',
                'read',
                array($invoice_ids, array(
                    'id',
                    'access_url',
                    'name',
                    'partner_id',
                    'certificado',
                    'sello',
                    'cadena_original',
                    'cfdi_fecha_timbrado',
                    'cfdi_folio_fiscal',
                    'xml_file_signed_index',
                    'cfdi_last_message',
                    'cfdi_state',
                ))
            );

            $preview_url = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'account.move',
                'preview_invoice',  // Método que genera la vista previa
                array($invoice_ids)
            );
            $url_factura = OdooAuth::$url;
            $url_factura = $url_factura . $preview_url['url'];

            return array(
                'facturas' => $facturas,
                'url_factura' => $url_factura
            );
        } catch (Exception $e) {
            error_log($e->getMessage());
            return false;
        }
    }

    public static function mdlGetInformacionFactura($id_factura)
    {
        try {
            $models = OdooAuth::getOdoo();

            $factura = $models->execute_kw(
                OdooAuth::$db,
                OdooAuth::$uid,
                OdooAuth::$password,
                'account.move',
                'read',
                array($id_factura, array(
                    'id',
                    'access_url',
                    'name',
                    'partner_id',
                    'certificado',
                    'sello',
                    'cadena_original',
                    'cfdi_fecha_timbrado',
                    'cfdi_folio_fiscal',
                    'xml_file_signed_index',
                    'cfdi_last_message'
                ))
            );

            return $factura;
        } catch (Exception $e) {
            error_log($e->getMessage());
            return false;
        }
    }
}
