File: /var/www/gestion-formularios.bdfschool/app/Classes/Odoo/Client/OdooSentPayment.php
<?php
namespace App\Classes\Odoo\Client;
use App\Models\ConceptJournal;
use App\Models\IntegrationOdooResult;
use DOMDocument;
use Exception;
class OdooSentPayment {
private $data;
private $uid;
private $models;
private $odooDb;
private $odooApiKey;
private $ref_year;
private $resource_name;
public $result = false;
public $line_ids = [];
public $success_ids = [];
public $errorMessage = '';
public function __construct($data, $uid, $models, $ref_year, $resource_name, $odooDb, $odooApiKey)
{
$this->data = $data;
$this->uid = $uid;
$this->models = $models;
$this->odooApiKey = $odooApiKey;
$this->odooDb = $odooDb;
$this->ref_year = $ref_year;
$this->resource_name = $resource_name;
}
public function sent()
{
$moves_data = [];
$resource_ids = [];
$index = 1;
foreach ($this->data as $detail) {
try {
//Asignación de diario contable
$concept = strUpper(trim($detail->payment_method));
$assignment = ConceptJournal::where('concept', $concept)->first();
if (empty($assignment)) {
$this->errorMessage = 'No hay un registro de asignación para concepto ' . $concept;
return;
}
$journal = $assignment->journal;
if (empty($journal)) {
$this->errorMessage = 'No hay un diario contable asignado a concepto ' . $assignment->concept;
return;
}
//Formatear Ref
$ref = isset($detail->guardian_rut) ? explode('-', $detail->guardian_rut)[0] . '/' . $this->ref_year : '(S/I)/' . $this->ref_year;
// Datos del pago
$move_data_line = [
'ref' => $ref, // Referencia del asiento
'journal_id' => $journal->odoo_id, // ID del diario contable en Odoo
//'x_studio_alumnoa' => $detail->odoo_student_id ? intval($detail->odoo_student_id) : null, //ID del alumno
'x_local_id' => $detail->id,
'partner_id' => $detail->odoo_parent_id ? intval($detail->odoo_parent_id) : null,//ID del cliente
'payment_method_id' => 1, // Método de pago: manual
'amount' => (float) $detail->payment_amount,
'currency_id' => 45,
'payment_type' => 'inbound',
'date' => date('Y-m-d', strtotime($detail->payment_date))
];
$moves_data[] = $move_data_line;
$resource_ids[] = $detail->id;
$index++;
} catch (\Exception $e) {
$this->errorMessage = 'Error al formatear detalle #' . $detail->id . ' para envío: ' . $e->getMessage();
return;
}
}
if (empty($moves_data)) {
return;
}
//dd($moves_data);
if ($this->resource_name == 'UPLOAD STUDENT PAYMENTS') {
$resource_id = $this->data[0]->upload_student_payment_id;
$multiple_record = 1;
} else {
$resource_id = $this->data[0]->id;
$multiple_record = 0;
}
$integration_result = new IntegrationOdooResult;
$integration_result->create_body = json_encode($moves_data);
$integration_result->status = 'PENDING';
$integration_result->user_created = auth()->user()->id;
$integration_result->created_at = ahoraServidor();
$integration_result->resource_name = $this->resource_name;
$integration_result->multiple_record = $multiple_record;
$integration_result->resource_id = $resource_id;
try {
// Insertar los registros en odoo
$new_move_ids = $this->models->execute_kw($this->odooDb, $this->uid, $this->odooApiKey, 'account.payment', 'create', array($moves_data));
if (!isset($new_move_ids['faultCode'])) {
$this->result = true;
if ($multiple_record == 1) {
$odoo_id = null;
$odoo_ids = json_encode(array_values($new_move_ids));
} else {
$odoo_id = $new_move_ids[0];
$odoo_ids = null;
}
// Crear registro
$integration_result->status = 'COMPLETED';
$integration_result->integration_at = ahoraServidor();
$integration_result->request_body = base64_encode(gzcompress(htmlspecialchars($this->formatXml($this->models->_request))));
$integration_result->code = '200';
$integration_result->odoo_id = $odoo_id;
$integration_result->odoo_ids = $odoo_ids;
// Publicar asientos: en el caso de los pagos, action_post devuelve 'none' lo cual provoca error de interpretación en cliente de ripcord. por eso se usa write para pagos, el efecto es el mismo
$action_post = $this->models->execute_kw($this->odooDb, $this->uid, $this->odooApiKey, 'account.payment', 'write', [$new_move_ids, ['state' => 'posted']]);
if (!isset($action_post['faultCode'])) {
$integration_result->message = 'Asientos contables de deudas enviados y publicados correctamente';
$integration_result->response = htmlspecialchars($this->formatXml($this->models->_response));
} else {
$integration_result->message = 'Asientos contables de deudas enviados correctamente, error al publicar';
$integration_result->response = htmlspecialchars($this->formatXml($this->models->_response));
}
$integration_result->save();
} else {
$integration_result->status = 'FAILED';
$integration_result->integration_at = ahoraServidor();
$integration_result->request_body = base64_encode(gzcompress(htmlspecialchars($this->formatXml($this->models->_request))));
$integration_result->code = '400/500';
$integration_result->message = 'Error al enviar asientos contables de pagos';
$integration_result->response = htmlspecialchars($this->formatXml($this->models->_response));
$integration_result->save();
$this->errorMessage = $new_move_ids['faultString'];
return;
}
$formated_odoo_ids = array_values($new_move_ids);
// Obtener los ids locales que fueron insertados
$local_ids = $this->models->execute_kw($this->odooDb, $this->uid, $this->odooApiKey, 'account.payment', 'search_read', array(
array(['id', 'in', $formated_odoo_ids])
), array('fields' => array('x_local_id')));
$formated_local_ids = array_column($local_ids, 'x_local_id');
// Enviar array con los ids que fueron enviados exitosamente a odoo
$this->success_ids = $formated_local_ids;
} catch (\Exception $e) {
$integration_result->status = 'FAILED';
$integration_result->integration_at = ahoraServidor();
$integration_result->code = '400/500';
$integration_result->message = 'Error al enviar asientos contables de pagos: ' . $e->getMessage();
$integration_result->save();
$this->errorMessage = 'Error al enviar asientos contables de pagos: ' . $e->getMessage();
return;
}
}
private function formatXml($xml)
{
// Crear un nuevo objeto DOMDocument
$dom = new DOMDocument();
// Cargar el XML
$dom->loadXML($xml);
// Establecer la opción para formato
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->formatOutput = true;
$dom->loadXML($xml);
return $dom->saveXML();
}
}