File: /var/www/gestion-formularios.bdfschool/app/Imports/ProcessUploadStudentPaymentsImport.php
<?php
namespace App\Imports;
use App\Models\ConceptJournal;
use App\Models\UploadStudentPayment;
use App\Models\UploadStudentPaymentDetail;
use Carbon\Carbon;
use Maatwebsite\Excel\Facades\Excel;
class ProcessUploadStudentPaymentsImport {
private $first_file;
private $second_file;
public $errorMessage;
public $successMessage;
public $register_id;
private $partners;
public function __construct($first_file, $second_file, $partners)
{
$this->first_file = $first_file;
$this->second_file = $second_file;
$this->partners = $partners;
}
public function import()
{
$first_file_data = Excel::toCollection(new UploadStudentPaymentsImport, $this->first_file);
$second_file_data = Excel::toCollection(new UploadStudentPaymentsImport, $this->second_file);
if ($first_file_data[0]->isEmpty() || $second_file_data[0]->isEmpty()) {
$this->errorMessage = 'Uno de los archivos está vacío.';
return;
}
$first_headers = $first_file_data[0]->first()->keys()->toArray();
$second_headers = $second_file_data[0]->first()->keys()->toArray();
$first_file_array = $first_file_data->toArray()[0];
$second_file_array = $second_file_data->toArray()[0];
//ENCABEZADOS REQUERIDOS EN CADA TABLA
$payment_detail_columns = [
'n',
'apoderado',
'rut_apoderado',
'id_apoderado',
'fecha_de_pago',
'monto_del_pago',
'forma_de_pago',
'tarjeta_de_debito_o_credito',
'nro_operacion_orden_compra_o_cheque',
'n_boleta',
'tipo_documento',
'estado',
'fecha_emision',
'monto_total'
];
$items_detail_columns = [
'boleta',
'fecha_pago',
'forma_de_pago',
'cod_autorizacion',
'item_de_cargo',
'alumnoa',
'rut',
'curso',
'septiembre',
];
//VALIDACIÓN DE ARCHIVOS POR ENCABEZADOS REQUERIDOS
$detail_file = null;
$items_file = null;
if ($this->validateHeaders($first_headers, $payment_detail_columns)) {
$detail_file = $first_file_array;
$items_file = $second_file_array;
if(!$this->validateHeaders($second_headers, $items_detail_columns)) {
$this->errorMessage = 'Ninguno de los archivos tiene los encabezados requeridos de detalle de items.';
return;
}
} elseif ($this->validateHeaders($second_headers, $payment_detail_columns)) {
$detail_file = $second_file_array;
$items_file = $first_file_array;
if(!$this->validateHeaders($first_headers, $items_detail_columns)) {
$this->errorMessage = 'Ninguno de los archivos tiene los encabezados requeridos de detalle de items.';
return;
}
} else {
$this->errorMessage = 'Ninguno de los archivos tiene los encabezados requeridos de detalle de pagos.';
return;
}
//BUSCAR COINCIDENCIAS POR NÚMERO DE BOLETA, SI NO LAS HAY NO SE GENERA REGISTRO
// 1. Obtener números de boletas del archivo de items
$invoice_numbers = array_filter(
array_merge(...array_map(fn($value) => explode('-', $value),
array_filter(array_column($items_file, 'boleta'), fn($value) => $value && $value !== '0'))
));
//pre_die($items_file);
// 2. Buscar coincidencias por número de boletas en archivo de detalles de pago y almacenarlas en un array si las hay
$invoice_number_matches = [];
foreach($invoice_numbers as $invoice_number) {
foreach($detail_file as $payment_detail) {
if($invoice_number == $payment_detail['n_boleta']) {
// OBTENER DATA DE ITEM_DETAIL
$item_detail = array_values(array_filter($items_file, function($item) use ($invoice_number) {
return isset($item['boleta']) && in_array($invoice_number, explode('-', $item['boleta']));
}));
$item_detail = $item_detail[0];
// $odoo_parent_id = isset($this->partners[strUpper(str_replace('.', '', formateaRut($payment_detail['rut_apoderado'])))]) ? $this->partners[strUpper(str_replace('.', '', formateaRut($payment_detail['rut_apoderado'])))] : null;
// $odoo_student_id = isset($this->partners[str_replace('.', '', formateaRut($item_detail['rut']))]) ? $this->partners[str_replace('.', '', formateaRut($item_detail['rut']))] : null;
//FORMATEAR DATOS PARA INSERTAR
$upload_payment_detail_insertion = [
'invoice_number' => !empty($payment_detail['n_boleta']) ? $payment_detail['n_boleta'] : null,
'payment_number' => !empty($payment_detail['n']) ? $payment_detail['n'] : null,
'guardian' => !empty($payment_detail['apoderado']) ? $payment_detail['apoderado'] : null,
'guardian_id' => !empty($payment_detail['id_apoderado']) ? $payment_detail['id_apoderado'] : null,
'payment_date' => !empty($payment_detail['fecha_de_pago']) ? $payment_detail['fecha_de_pago'] : null,
'payment_amount' => !empty($payment_detail['monto_del_pago']) ? $payment_detail['monto_del_pago'] : null,
'payment_method' => !empty($payment_detail['forma_de_pago']) ? $payment_detail['forma_de_pago'] : null,
'operation_number' => !empty($payment_detail['nro_operacion_orden_compra_o_cheque']) ? $payment_detail['nro_operacion_orden_compra_o_cheque'] : null,
'document_type' => !empty($payment_detail['tipo_documento']) ? $payment_detail['tipo_documento'] : null,
'status' => !empty($payment_detail['estado']) ? $payment_detail['estado'] : null,
'emision_date' => !empty($payment_detail['fecha_emision']) ? $payment_detail['fecha_emision'] : null,
'total_amount' => !empty($payment_detail['monto_total']) ? $payment_detail['monto_total'] : null,
'user_created' => auth()->user()->id,
'created_at' => Carbon::now(),
'authorization_code' => !empty($item_detail['cod_autorizacion']) ? $item_detail['cod_autorizacion'] : null,
'charge_item' => !empty($item_detail['item_de_cargo']) ? $item_detail['item_de_cargo'] : null,
'student' => !empty($item_detail['alumnoa']) ? $item_detail['alumnoa'] : null,
'student_rut' => !empty($item_detail['rut']) ? $item_detail['rut'] : null,
'student_class' => !empty($item_detail['curso']) ? $item_detail['curso'] : null,
'upload_student_payment_id' => null,
'guardian_rut' => !empty($payment_detail['rut_apoderado']) ? $payment_detail['rut_apoderado'] : null,
'load_status' => 1,
'detail_integration_status_id' => 1,
'debit' => isset($payment_detail['debe']) ? $payment_detail['debe'] : '',
//'credit_account_id' => 21, //dato fijo: Cuenta única para apoderados
'credit' => isset($payment_detail['haber']) ? $payment_detail['haber'] : ''
];
array_push($invoice_number_matches, $upload_payment_detail_insertion);
}
}
}
//pre_die($invoice_number_matches);
if(empty($invoice_number_matches)) {
$this->errorMessage = 'No se han encontrado coincidencias por número de boleta en los archivos.';
return;
}
//ALMACENAR REGISTROS
//1.Crear cabecera
$quantity = count($invoice_number_matches);
$quantity_success = 0;
$quantity_error = 0;
$num_row = 1;
try {
$upload_student_payment = UploadStudentPayment::create([
'quantity' => $quantity,
'user_created' => auth()->user()->id,
'created_at' => Carbon::now()
]);
$this->register_id = $upload_student_payment->id;
} catch (\Throwable $th) {
$this->errorMessage = 'Ha ocurrido un error, por favor vuelve a intentarlo más tarde';
return;
}
//pre_die($upload_student_payment);
foreach($invoice_number_matches as $detail) {
$validation_errors = 0;
$validation_messages = '';
try {
// Validar los rut
$guardian_rut = strUpper(str_replace('.', '', formateaRut($detail['guardian_rut'])));
$student_rut = strUpper(str_replace('.', '', formateaRut($detail['student_rut'])));
// Rut apoderado
if (isset($this->partners[$guardian_rut])) {
$odoo_parent_id = $this->partners[$guardian_rut];
} else {
//registrar el error
$validation_errors++;
$validation_messages .= ($validation_errors + 1) . ': Rut de apoderado no encontrado. ';
$odoo_parent_id = null;
}
// Rut apoderado
if (isset($this->partners[$student_rut])) {
$odoo_student_id = $this->partners[$student_rut];
} else {
//registrar el error
$validation_errors++;
$validation_messages .= ($validation_errors + 1) . ': Rut de alumno no encontrado. ';
$odoo_student_id = null;
}
// Validar método de pago
$assignment = ConceptJournal::where('concept', strUpper(trim($detail['payment_method'])))->first();
if (!$assignment) {
$validation_messages .= ($validation_errors + 1) . ': Método de pago "' . $detail['payment_method'] . '" no encontrado.';
$validation_errors++;
$detail['payment_method'] = null;
}
//2.Formatear datos
$detail['invoice_number'] = intval($detail['invoice_number']);
$detail['payment_number'] = intval($detail['payment_number']);
$detail['operation_number'] = intval($detail['operation_number']);
$detail['guardian_rut'] = $guardian_rut;
$detail['student_rut'] = $student_rut;
$detail['payment_date'] = ordenar_fechaServidor($detail['payment_date']);
$detail['emision_date'] = ordenar_fechaServidor($detail['emision_date']);
$detail['payment_amount'] = floatval(str_replace(',', '.', $detail['payment_amount']));
$detail['total_amount'] = floatval(str_replace(',', '.', $detail['total_amount']));
$detail['upload_student_payment_id'] = $upload_student_payment->id;
$detail['num_row'] = $num_row;
$detail['odoo_parent_id'] = $odoo_parent_id;
$detail['odoo_student_id'] = $odoo_student_id;
//3.Guardar detalle
if ($validation_errors == 0) {
UploadStudentPaymentDetail::create($detail);
$quantity_success++;
} else {
$detail['load_status'] = 0;
$detail['error'] = $validation_messages;
UploadStudentPaymentDetail::create($detail);
$quantity_error++;
}
$num_row++;
} catch (\Exception $e) {
UploadStudentPaymentDetail::create([
'num_row' => $num_row,
'user_created' => auth()->user()->id,
'created_at' => Carbon::now(),
'load_status' => 0,
'upload_student_payment_id' => $upload_student_payment->id,
'detail_integration_status_id' => 1,
'error' => $e->getMessage()
]);
$quantity_error++;
$num_row++;
}
}
$upload_student_payment->update([
'quantity_success' => $quantity_success,
'quantity_error' => $quantity_error,
]);
$this->successMessage = 'Importación realizada correctamente. Registros exitosos: ' . $quantity_success . ', Errores: ' . $quantity_error;
}
private function validateHeaders($headers, $required_columns)
{
foreach ($required_columns as $column) {
if (!in_array($column, $headers)) {
return false;
}
}
return true;
}
}