File: /var/www/middleware-citas-dev/app/Services/OdooService.php
<?php
namespace App\Services;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class OdooService
{
private $url;
private $db;
private $username;
private $apiKey;
private $uid;
public function __construct()
{
$this->url = rtrim(env('ODOO_URL', ''), '/');
$this->db = env('ODOO_DB', '');
$this->username = env('ODOO_USERNAME', '');
$this->apiKey = env('ODOO_API_KEY', '');
}
/**
* Autenticarse con Odoo via JSON-RPC y obtener el uid.
*/
public function authenticate()
{
if ($this->uid) {
return $this->uid;
}
$response = $this->jsonRpc('common', 'authenticate', [
$this->db,
$this->username,
$this->apiKey,
[],
]);
if (!$response || isset($response['error'])) {
Log::error('[OdooService] Error de autenticacion', [
'error' => $response['error'] ?? 'uid vacĂo',
]);
throw new \Exception('Error al autenticarse con Odoo');
}
$this->uid = $response['result'];
Log::info('[OdooService] Autenticacion exitosa', ['uid' => $this->uid]);
return $this->uid;
}
/**
* Ejecutar un metodo en un modelo de Odoo (execute_kw).
*/
public function executeKw($model, $method, $args = [], $kwargs = [])
{
$this->authenticate();
$params = [
$this->db,
$this->uid,
$this->apiKey,
$model,
$method,
$args,
];
if (!empty($kwargs)) {
$params[] = $kwargs;
}
$response = $this->jsonRpc('object', 'execute_kw', $params);
if (isset($response['error'])) {
Log::error("[OdooService] Error en execute_kw", [
'model' => $model,
'method' => $method,
'error' => $response['error'],
]);
throw new \Exception('Error Odoo: ' . ($response['error']['data']['message'] ?? $response['error']['message'] ?? 'Error desconocido'));
}
return $response['result'];
}
/**
* Buscar y leer registros de un modelo.
*/
public function searchRead($model, $domain = [], $fields = [], $limit = 0)
{
$kwargs = ['fields' => $fields];
if ($limit > 0) {
$kwargs['limit'] = $limit;
}
return $this->executeKw($model, 'search_read', [$domain], $kwargs);
}
/**
* Crear un registro en un modelo.
*/
public function create($model, $data)
{
return $this->executeKw($model, 'create', [$data]);
}
/**
* Verificar si un partner existe en Odoo por su ID.
*/
public function partnerExists($partnerId)
{
$result = $this->searchRead(
'res.partner',
[['id', '=', (int) $partnerId]],
['id', 'name', 'email', 'vat', 'phone', 'mobile'],
1
);
return !empty($result) ? $result[0] : null;
}
/**
* Verificar si un usuario existe en Odoo por su ID.
*/
public function userExists($userId)
{
$result = $this->searchRead(
'res.users',
[['id', '=', (int) $userId]],
['id', 'name', 'login'],
1
);
return !empty($result) ? $result[0] : null;
}
/**
* Crear un pago de cliente (account.payment) en Odoo.
*/
public function createAccountPayment($data)
{
return $this->create('account.payment', $data);
}
/**
* Llamada JSON-RPC generica a Odoo.
*/
private function jsonRpc($service, $method, $args)
{
$payload = [
'jsonrpc' => '2.0',
'method' => 'call',
'params' => [
'service' => $service,
'method' => $method,
'args' => $args,
],
'id' => rand(1, 999999),
];
$response = Http::timeout(30)->post($this->url . '/jsonrpc', $payload);
if (!$response->successful()) {
Log::error('[OdooService] HTTP error', [
'status' => $response->status(),
'body' => $response->body(),
]);
throw new \Exception('Error HTTP al conectar con Odoo: ' . $response->status());
}
return $response->json();
}
}