Merge branch 'main' into fix/importador_bubok

This commit is contained in:
imnavajas
2025-05-13 09:05:32 +02:00
15 changed files with 255 additions and 111 deletions

View File

@ -0,0 +1,13 @@
<?php
use CodeIgniter\Router\RouteCollection;
/** @var RouteCollection $routes */
/* Rutas para tarifas */
$routes->group('scripts', ['namespace' => 'App\Controllers\Scripts'], function ($routes) {
$routes->get('completar-identidades', 'UsersIntegrity::completarIdentidades');
});

View File

@ -833,9 +833,18 @@ class Facturas extends \App\Controllers\BaseResourceController
if ((strpos($numero, "REC ") === 0)) {
$data['estado_pago'] = 'pagada';
}
$this->model->update($factura_id, $data);
if ((strpos($numero, "REC ") === 0)) {
$this->model->where('numero', $factura->factura_rectificada_id)->set([
'factura_rectificativa_id' => $numero,
'user_updated_id' => auth()->user()->id,
])->update();
}
}

View File

@ -92,7 +92,7 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
Field::inst('id'),
Field::inst('base'),
Field::inst('total_iva'),
Field::inst('total'),
Field::inst('total')->set(Field::SET_BOTH),
Field::inst('cantidad')
->validator(
'Validate::numeric',
@ -126,19 +126,6 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
'message' => lang('Facturas.validation.requerido')
)
),
Field::inst('total')
->validator(
'Validate::numeric',
array(
'message' => lang('Facturas.validation.numerico')
)
)
->validator(
'Validate::notEmpty',
array(
'message' => lang('Facturas.validation.requerido')
)
),
Field::inst('pedido_linea_impresion_id')
->setFormatter(function ($val, $data, $opts) {
return $val === '' ? null : $val;
@ -157,7 +144,7 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
$values['total'],
$values['iva'],
$values['cantidad'],
$values['old_cantidad'],
$values['old_cantidad'],
$values['base']
);
$editor
@ -183,7 +170,7 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
$values['total'],
$values['iva'],
$values['cantidad'],
$values['old_cantidad'],
$values['old_cantidad'],
$values['base']
);
$editor
@ -256,14 +243,13 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
$values['base'] = $base;
$values['total_iva'] = $total_iva;
$values['total'] = $total;
}
else{
} else {
// se pasa la base y el iva
$total_iva = round($base_input * $iva / 100, 2);
$total = round($base_input + $total_iva, 2);
$values = [];
$values['base'] = $base_input;
$values['base'] = (float) $base_input;
$values['total_iva'] = $total_iva;
$values['total'] = $total;

View File

@ -371,7 +371,7 @@ class ImportadorBubok extends BaseResourceController
// confirmar y crear pedido y ot
$presupuestoModel->confirmarPresupuesto($response['sk_id']);
PresupuestoService::crearPedido($response['sk_id']);
PresupuestoService::crearPedido($response['sk_id'],isImported:true);
if (!isset($response['sk_id'])) {

View File

@ -359,7 +359,7 @@ class ImportadorCatalogo extends BaseResourceController
// confirmar y crear pedido y ot
model('App\Models\Presupuestos\PresupuestoModel')->confirmarPresupuesto($response['data']['sk_id']);
PresupuestoService::crearPedido($response['data']['sk_id']);
PresupuestoService::crearPedido($response['data']['sk_id'],isImported:true);
return $this->respond($response);

View File

@ -0,0 +1,76 @@
<?php
namespace App\Controllers\Scripts;
use App\Controllers\BaseController;
use App\Models\Usuarios\UserModel;
use App\Entities\Usuarios\UserEntity;
use CodeIgniter\Shield\Authentication\Passwords\IdentityModel;
class UsersIntegrity extends BaseController
{
public function completarIdentidades()
{
$userModel = new UserModel();
// Buscar usuarios safekat.com no eliminados
$usuarios = $userModel
->where('deleted_at', null)
//->like('username', '@safekat.com')
->findAll();
$resultados = [];
foreach ($usuarios as $usuario) {
$email = $usuario->username . "@safekat.com";
// 1. Verificar si el usuario ya tiene identidad tipo email_password
$tieneIdentidad = array_filter(
$usuario->getIdentities(),
fn($identity) => $identity->type === 'email_password'
);
if (!empty($tieneIdentidad)) {
$resultados[] = "✅ Ya tiene identidad: {$email}";
continue;
}
// 2. Verificar si ya existe una identidad globalmente con ese email
$db = db_connect();
$builder = $db->table('auth_identities');
$existeGlobal = $builder
->where('type', 'email_password')
->where('secret', $email)
->get()
->getFirstRow();
if ($existeGlobal) {
$resultados[] = "⚠️ Email ya registrado en otra identidad: {$email}";
continue;
}
// 3. Crear y guardar identidad
try {
$identity = $usuario->createEmailIdentity([
'email' => $email,
'password' => 'Temporal123!', // reemplazar por valor real si lo tenés
]);
//$userModel->saveEmailIdentity($identity);
$resultados[] = " Identidad creada: {$email}";
} catch (\Throwable $e) {
$resultados[] = "❌ Error con {$email}: " . $e->getMessage();
}
}
return $this->response->setJSON([
'status' => 'completado',
'procesados' => count($usuarios),
'resultados' => $resultados,
]);
}
}

View File

@ -27,9 +27,9 @@ class FacturaModel extends \App\Models\BaseModel
];
const SORTABLE_PEDIDOS = [
1 => "t1.numero",
2 => "t2.nombre",
3 => "t4.cantidad",
1 => "t1.id",
2 => "t1.numero",
3 => "t4.ejemplares",
4 => "t2.nombre",
5 => "t1.estado",
6 => "t1.fecha_factura_at",
@ -129,7 +129,7 @@ class FacturaModel extends \App\Models\BaseModel
$builder->join("clientes t2", "t2.id = t1.cliente_id", "left");
$builder->join("facturas_pagos t3", "t3.factura_id = t1.id", "left");
$builder->join("formas_pago t4", "t3.forma_pago_id = t4.id", "left");
$builder->where("t1.deleted_at", null);
if (auth()->user()->inGroup("cliente-admin") || auth()->user()->inGroup("cliente-editor")) {
@ -140,7 +140,7 @@ class FacturaModel extends \App\Models\BaseModel
$builder->where("t1.cliente_id", $cliente_id);
}
$builder->groupBy("t1.id");
$builder->groupBy("t1.id");
//$query = $builder->getCompiledSelect();
return $builder;
}
@ -166,9 +166,10 @@ class FacturaModel extends \App\Models\BaseModel
return !empty($result);
}
public function getSumatoriosFacturacionCliente($cliente_id = -1){
public function getSumatoriosFacturacionCliente($cliente_id = -1)
{
if($cliente_id == -1){
if ($cliente_id == -1) {
return [
'total_facturacion' => 0,
'total_pendiente' => 0
@ -183,7 +184,7 @@ class FacturaModel extends \App\Models\BaseModel
->where('f.estado', 'validada')
->get()
->getResultObject();
$result['total_facturacion'] =
$result['total_facturacion'] =
round(floatval(($data && $data[0]->total != null) ? $data[0]->total : 0), 2);
$data = $this->db->table('facturas f')
@ -253,7 +254,17 @@ class FacturaModel extends \App\Models\BaseModel
$builder->join("pedidos t6", "t5.pedido_id = t6.id", "left");
$builder->where("t1.deleted_at IS NULL");
$builder->where("t6.id", $pedido_id);
$builder->groupStart()
->where("t6.id", $pedido_id)
->orWhere("t1.factura_rectificada_id IN (
SELECT f.numero
FROM facturas f
JOIN facturas_pedidos_lineas fpl ON f.id = fpl.factura_id
JOIN pedidos_linea pl ON fpl.pedido_linea_id = pl.id
JOIN pedidos p ON pl.pedido_id = p.id
WHERE p.id = {$pedido_id}
)")
->groupEnd();
$builder->groupBy("t1.id"); // Agrupa por id de la factura

View File

@ -1867,7 +1867,7 @@ class PresupuestoService extends BaseService
public static function crearPedido($presupuesto_id)
public static function crearPedido($presupuesto_id,?bool $isImported = false)
{
$model_pedido = model('App\Models\Pedidos\PedidoModel');
$model_pedido_linea = model('App\Models\Pedidos\PedidoLineaModel');
@ -1911,7 +1911,7 @@ class PresupuestoService extends BaseService
$serviceProduction->setPedido($pedido);
if (!$pedido->orden_trabajo()) {
$r = $serviceProduction->createOrdenTrabajo(true);
$r = $serviceProduction->createOrdenTrabajo($isImported);
$modelPedido->set(['estado' => 'produccion'])->where('id', $pedido_id)->update();
}
}

View File

@ -4,7 +4,7 @@
<thead>
<tr>
<th></th>
<th><?= lang('Produccion.datatable.ot_id') ?></th>
<th class="w-10"><?= lang('Produccion.datatable.ot_id') ?></th>
<th><?= lang('Produccion.datatable.pedido_id') ?></th>
<th><?= lang('Produccion.datatable.fecha_encuadernacion') ?></th>
<th><?= lang('Produccion.datatable.cliente') ?></th>
@ -16,6 +16,20 @@
<th><?= lang('Produccion.datatable.progreso') ?></th>
<th class="text-nowrap"><?= lang('Basic.global.Action') ?></th>
</tr>
<tr>
<th></th>
<th><input type="text" class="form-control ot-filter" name="id"></th>
<th><input type="text" class="form-control ot-filter" name="pedido_id"></th>
<th><input type="text" class="form-control ot-filter" name="fecha_encuadernado_at"></th>
<th><input type="text" class="form-control ot-filter" name="cliente_nombre"></th>
<th><input type="text" class="form-control ot-filter" name="presupuesto_titulo"></th>
<th><input type="text" class="form-control ot-filter" name="ubicacion_nombre"></th>
<th><input type="text" class="form-control ot-filter" name="total_tirada"></th>
<th><input type="text" class="form-control ot-filter" name="tipo_presupuesto_impresion"></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>

View File

@ -96,13 +96,12 @@
<div class="row mb-2">
<div <?= ($facturaEntity->serie_id == 7 || $facturaEntity->serie_id == 9 || $facturaEntity->factura_rectificada_id != null) ? "":"style='display:none;'" ?> class="col-md-12 col-lg-2 px-4 factura-R">
<div <?= ($facturaEntity->serie_id == 7 || $facturaEntity->serie_id == 9 || $facturaEntity->factura_rectificativa_id != null) ? "":"style='display:none;'" ?> class="col-md-12 col-lg-2 px-4 factura-R">
<div class="mb-1">
<label for="facturaR" class="form-label factura-R">
<?= ($facturaEntity->factura_rectificada_id != null) ? lang('Facturas.facturaRectificada') : lang('Facturas.facturaRectificativa') ?>:
<?= ($facturaEntity->serie_id == 7 || $facturaEntity->serie_id == 9) ? lang('Facturas.facturaRectificada') : lang('Facturas.facturaRectificativa') ?>:
</label>
<input <?= ($facturaEntity->estado!='borrador')? "disabled":"" ?> id="facturaR" name="<?= ($facturaEntity->factura_rectificada_id != null) ? 'factura_rectificada_id' : 'factura_rectificativa_id' ?>" tabindex="" maxLength="25" class="form-control update-cabecera factura-R"
<input <?= ($facturaEntity->estado!='borrador')? "disabled":"" ?> id="facturaR" name="<?= ($facturaEntity->serie_id == 7 || $facturaEntity->serie_id == 9) ? 'factura_rectificada_id' : 'factura_rectificativa_id' ?>" tabindex="" maxLength="25" class="form-control update-cabecera factura-R"
<?php if($facturaEntity->factura_rectificada_id == null && $facturaEntity->factura_rectificativa_id == null): ?>
value=""
<?php else: ?>

View File

@ -211,7 +211,7 @@ var editor_lineas = new $.fn.dataTable.Editor( {
name: "base",
attr: {
type: "text",
name : "total",
name : "base",
class :"autonumeric"
}
}, {
@ -224,6 +224,10 @@ var editor_lineas = new $.fn.dataTable.Editor( {
name: "id",
type: "hidden"
},
{
name: "total",
type: "hidden"
}
]
} );
@ -279,7 +283,8 @@ editor_lineas.on( 'preEdit', function ( e, json, data, id ) {
editor_lineas.on( 'postSubmit', function ( e, json, data, action ) {
yeniden(json.<?= csrf_token() ?>);
tableLineas.clearPipeline();
tableLineas.draw();
});
editor_lineas.on( 'submitSuccess', function ( e, json, data, action ) {
@ -495,7 +500,7 @@ var tableLineas = $('#tableOfLineasFactura').DataTable({
$('#total-iva-sum-4').closest('tr').addClass('d-none');
}
else{
totalTotal += totalIVA_4;
//totalTotal += totalIVA_4;
$('#total-iva-sum-4').closest('tr').removeClass('d-none');
}
autoNumericIVA_21.set(totalIVA_21);
@ -503,17 +508,18 @@ var tableLineas = $('#tableOfLineasFactura').DataTable({
$('#total-iva-sum-21').closest('tr').addClass('d-none');
}
else{
totalTotal += totalIVA_21;
//totalTotal += totalIVA_21;
$('#total-iva-sum-21').closest('tr').removeClass('d-none');
}
autoNumericTotal.set(totalTotal);
var total_pagos = autoNumericTotalCobrado.getNumber();
var pendientePago = totalTotal - total_pagos;
if (isNaN(pendientePago)) pendientePago = 0;
autoNumericPendientePago.set(pendientePago);
if(!(<?= $facturaEntity->serie_id ?> == 7 || <?= $facturaEntity->serie_id ?> == 9)){
var total_pagos = autoNumericTotalCobrado.getNumber();
var pendientePago = totalTotal - total_pagos;
if (isNaN(pendientePago)) pendientePago = 0;
autoNumericPendientePago.set(pendientePago);
}
$.ajax({
url: '<?= route_to('updateFacturaTotales', $facturaEntity->id) ?>',

View File

@ -17,7 +17,7 @@
<?= !empty($validation->getErrors()) ? $validation->listErrors("bootstrap_style") : "" ?>
<?= view("themes/vuexy/form/facturas/_facturaCabeceraItems") ?>
<?php if($facturaEntity->estado =='borrador') : ?>
<?php if($facturaEntity->estado =='borrador' && !($facturaEntity->serie_id == 7 || $facturaEntity->serie_id == 9)) : ?>
<?= view("themes/vuexy/form/facturas/_addPedidosItems") ?>
<?php endif; ?>

View File

@ -28,7 +28,7 @@
</div>
<div class="col-md-4 mb-3 d-flex align-items-end">
<button type="button" id="importBtn" class="btn btn-success w-100">
<button type="button" id="importBtn" class="btn btn-success w-100" disabled>
<i class="fas fa-file-import me-2"></i> <?= lang('Importador.importar') ?? 'Importar' ?>
</button>
</div>

View File

@ -11,19 +11,18 @@ class OrdenTrabajoDatatable {
this.datatableWaiting = this.item.find("#ot-datatable-waiting")
this.datatableRevisionComerical = this.item.find("#ot-datatable-revision-com")
this.columnIdIndex = 1;
this.tableLayout = "lrtip"
this.datatableColumns = [
{ data: 'pdf_check', searchable: false, sortable: false, render: d => `<input class="form-check-input pdf-check" data-id="${d}" type="checkbox">` },
{ data: 'id', searchable: true, sortable: true },
{ data: 'id', searchable: true, sortable: true},
{ data: 'pedido_id', searchable: true, sortable: true },
{ data: 'fecha_encuadernado_at',name:"pedidos.fecha_encuadernado", searchable: true, sortable: true },
{ data: 'cliente_nombre', name:"clientes.nombre", searchable: true, sortable: false },
{ data: 'presupuesto_titulo', name:"presupuestos.titulo", searchable: true, sortable: true },
{ data: 'ubicacion_nombre', name:"ubicaciones.nombre", searchable: true, sortable: true },
{ data: 'total_tirada', name:"pedidos.total_tirada",searchable: true, sortable: true, render: (d) => `<span class="autonumeric">${d}</span>` },
{ data: 'tipo_presupuesto_impresion', name:"tipos_presupuestos.codigo", searchable: true, sortable: true },
{ data: 'fecha_encuadernado_at', name: "pedidos.fecha_encuadernado", searchable: true, sortable: true },
{ data: 'cliente_nombre', name: "clientes.nombre", searchable: true, sortable: false },
{ data: 'presupuesto_titulo', name: "presupuestos.titulo", searchable: true, sortable: true },
{ data: 'ubicacion_nombre', name: "ubicaciones.nombre", searchable: true, sortable: true },
{ data: 'total_tirada', name: "pedidos.total_tirada", searchable: true, sortable: true, render: (d) => `<span class="autonumeric">${d}</span>` },
{ data: 'tipo_presupuesto_impresion', name: "tipos_presupuestos.codigo", searchable: true, sortable: true },
{
data: 'logo', searchable: false, sortable: false, render: (d, t) => {
return `<div class="logo-container">
@ -33,7 +32,7 @@ class OrdenTrabajoDatatable {
}
},
{
data: 'progreso',name:"ordenes_trabajo.progreso", searchable: false, sortable: true, render: (d, t) => {
data: 'progreso', name: "ordenes_trabajo.progreso", searchable: false, sortable: true, render: (d, t) => {
return `<div class="progress border rounded-2" style="height: 1rem;">
<div id="ot-progress-bar" class="progress-bar" role="progressbar" style="width: ${parseInt(d)}%;" aria-valuenow="${d}" aria-valuemin="0" aria-valuemax="100">${d}%</div>
</div>
@ -57,7 +56,7 @@ class OrdenTrabajoDatatable {
console.log(order)
this.focusDatatable = this.datatableOrder[order]
}
events(){
events() {
this.datatableOrder = [
this.datatableN,
this.datatableP,
@ -74,12 +73,8 @@ class OrdenTrabajoDatatable {
init() {
this.datatable = this.datatableItem.DataTable({
processing: true,
layout: {
topStart: 'pageLength',
topEnd: 'search',
bottomStart: 'info',
bottomEnd: 'paging'
},
dom: this.tableLayout,
orderCellsTop: true,
order: [[this.columnIdIndex, 'desc']],
columnDefs: [
{ className: 'dt-center', targets: '_all' },
@ -97,16 +92,17 @@ class OrdenTrabajoDatatable {
$(row).css("border-right", `10px solid ${data.logo.color}`)
}
});
this.datatableItem.on("change", ".ot-filter", (event) => {
console.log(this.datatable.column($(event.currentTarget).attr("name")))
let columnIndex = this.datatableColumns.findIndex((element) => element.data == $(event.currentTarget).attr("name"))
this.datatable.column(columnIndex).search($(event.currentTarget).val()).draw()
})
}
initPendientes() {
this.datatableP = this.datatablePendientesItem.DataTable({
processing: true,
layout: {
topStart: 'pageLength',
topEnd: 'search',
bottomStart: 'info',
bottomEnd: 'paging'
},
dom: this.tableLayout,
orderCellsTop: true,
order: [[this.columnIdIndex, 'desc']],
columnDefs: [
{ className: 'dt-center', targets: '_all' },
@ -125,16 +121,17 @@ class OrdenTrabajoDatatable {
}
});
this.datatablePendientesItem.on("change", ".ot-filter", (event) => {
console.log(this.datatableP.column($(event.currentTarget).attr("name")))
let columnIndex = this.datatableColumns.findIndex((element) => element.data == $(event.currentTarget).attr("name"))
this.datatableP.column(columnIndex).search($(event.currentTarget).val()).draw()
})
}
initFerroPendiente() {
this.datatableFP = this.datatableFerroPendienteItem.DataTable({
processing: true,
layout: {
topStart: 'pageLength',
topEnd: 'search',
bottomStart: 'info',
bottomEnd: 'paging'
},
dom: this.tableLayout,
orderCellsTop: true,
serverSide: true,
pageLength: 25,
order: [[this.columnIdIndex, 'desc']],
@ -152,16 +149,17 @@ class OrdenTrabajoDatatable {
$(row).css("border-right", `20px solid ${data.logo.color}`)
}
});
this.datatableFerroPendienteItem.on("change", ".ot-filter", (event) => {
console.log(this.datatableFP.column($(event.currentTarget).attr("name")))
let columnIndex = this.datatableColumns.findIndex((element) => element.data == $(event.currentTarget).attr("name"))
this.datatableFP.column(columnIndex).search($(event.currentTarget).val()).draw()
})
}
initFerroOk() {
this.datatableFO = this.datatableFerroOkItem.DataTable({
processing: true,
layout: {
topStart: 'pageLength',
topEnd: 'search',
bottomStart: 'info',
bottomEnd: 'paging'
},
dom: this.tableLayout,
orderCellsTop: true,
serverSide: true,
order: [[this.columnIdIndex, 'desc']],
columnDefs: [
@ -179,16 +177,17 @@ class OrdenTrabajoDatatable {
$(row).css("border-right", `20px solid ${data.logo.color}`)
}
});
this.datatableFerroOkItem.on("change", ".ot-filter", (event) => {
console.log(this.datatableFO.column($(event.currentTarget).attr("name")))
let columnIndex = this.datatableColumns.findIndex((element) => element.data == $(event.currentTarget).attr("name"))
this.datatableFO.column(columnIndex).search($(event.currentTarget).val()).draw()
})
}
initNews() {
this.datatableN = this.datatableNews.DataTable({
processing: true,
layout: {
topStart: 'pageLength',
topEnd: 'search',
bottomStart: 'info',
bottomEnd: 'paging'
},
dom: this.tableLayout,
orderCellsTop: true,
serverSide: true,
order: [[this.columnIdIndex, 'desc']],
columnDefs: [
@ -207,17 +206,17 @@ class OrdenTrabajoDatatable {
}
});
this.focusDatatable = this.datatableN
this.datatableNews.on("change", ".ot-filter", (event) => {
console.log(this.datatableN.column($(event.currentTarget).attr("name")))
let columnIndex = this.datatableColumns.findIndex((element) => element.data == $(event.currentTarget).attr("name"))
this.datatableN.column(columnIndex).search($(event.currentTarget).val()).draw()
})
}
initWaiting() {
this.datatableW = this.datatableWaiting.DataTable({
processing: true,
layout: {
topStart: 'pageLength',
topEnd: 'search',
bottomStart: 'info',
bottomEnd: 'paging'
},
dom: this.tableLayout,
orderCellsTop: true,
serverSide: true,
order: [[this.columnIdIndex, 'desc']],
columnDefs: [
@ -235,16 +234,17 @@ class OrdenTrabajoDatatable {
$(row).css("border-right", `20px solid ${data.logo.color}`)
}
});
this.datatableWaiting.on("change", ".ot-filter", (event) => {
console.log(this.datatableW.column($(event.currentTarget).attr("name")))
let columnIndex = this.datatableColumns.findIndex((element) => element.data == $(event.currentTarget).attr("name"))
this.datatableW.column(columnIndex).search($(event.currentTarget).val()).draw()
})
}
initProd() {
this.datatableProduccion = this.datatableProd.DataTable({
processing: true,
layout: {
topStart: 'pageLength',
topEnd: 'search',
bottomStart: 'info',
bottomEnd: 'paging'
},
dom: this.tableLayout,
orderCellsTop: true,
serverSide: true,
order: [[this.columnIdIndex, 'desc']],
columnDefs: [
@ -262,16 +262,17 @@ class OrdenTrabajoDatatable {
$(row).css("border-right", `20px solid ${data.logo.color}`)
}
});
this.datatableProd.on("change", ".ot-filter", (event) => {
console.log(this.datatableProduccion.column($(event.currentTarget).attr("name")))
let columnIndex = this.datatableColumns.findIndex((element) => element.data == $(event.currentTarget).attr("name"))
this.datatableProduccion.column(columnIndex).search($(event.currentTarget).val()).draw()
})
}
initRevisionComercial() {
this.datatableRC = this.datatableRevisionComerical.DataTable({
processing: true,
layout: {
topStart: 'pageLength',
topEnd: 'search',
bottomStart: 'info',
bottomEnd: 'paging'
},
dom: this.tableLayout,
orderCellsTop: true,
serverSide: true,
order: [[this.columnIdIndex, 'desc']],
columnDefs: [
@ -289,6 +290,11 @@ class OrdenTrabajoDatatable {
$(row).css("border-right", `20px solid ${data.logo.color}`)
}
});
this.datatableRevisionComerical.on("change", ".ot-filter", (event) => {
console.log(this.datatableRC.column($(event.currentTarget).attr("name")))
let columnIndex = this.datatableColumns.findIndex((element) => element.data == $(event.currentTarget).attr("name"))
this.datatableRC.column(columnIndex).search($(event.currentTarget).val()).draw()
})
}
getSelectIDs() {
return this.focusDatatable.rows((idx, data, node) => {

View File

@ -2,6 +2,8 @@ import Ajax from '../../../components/ajax.js';
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('importBtn').disabled = true;
const TABLE_COLUMNS = ["input", "idlinea", "descripcion", "cnt_pedida", "precio_compra"];
let dataTable;
@ -35,6 +37,9 @@ document.addEventListener('DOMContentLoaded', function () {
const file = e.target.files[0];
if (!file) return;
// Deshabilitar botón importar al comenzar nuevo procesamiento
document.getElementById('importBtn').disabled = true;
const reader = new FileReader();
reader.onload = function (e) {
const data = new Uint8Array(e.target.result);
@ -51,6 +56,18 @@ document.addEventListener('DOMContentLoaded', function () {
async function validateAndLoadDataTable(data) {
if (data.length === 0) return;
// Mostrar loader (ajústalo según tu HTML)
Swal.fire({
title: 'Procesando...',
text: 'Cargando datos del Excel...',
allowOutsideClick: false,
showDenyButton: false,
cancelButtonText: 'Cancelar',
didOpen: () => {
Swal.showLoading();
}
});
const headers = data[0].map(h => h.toString().trim());
const headerMap = {};
headers.forEach((name, idx) => {
@ -60,6 +77,7 @@ document.addEventListener('DOMContentLoaded', function () {
const requiredColumns = ["idpedido", ...TABLE_COLUMNS];
const missing = requiredColumns.filter(col => !(col in headerMap));
if (missing.length > 0) {
Swal.close(); // Cierra el loader
Swal.fire({
title: 'Error',
text: 'Faltan las siguientes columnas: ' + missing.join(', '),
@ -127,6 +145,12 @@ document.addEventListener('DOMContentLoaded', function () {
dataTable.clear().rows.add(rows).draw();
setupEventListeners();
Swal.close(); // Ocultar loader
// Habilitar botón importar si hay filas válidas
const tieneFilas = rows.length > 0;
document.getElementById('importBtn').disabled = !tieneFilas;
}
async function validarFila(rowData) {
@ -176,7 +200,7 @@ document.addEventListener('DOMContentLoaded', function () {
const skId = result.data?.sk_id ?? '';
// Actualizar campo "Notas" con el enlace
if (skUrl) {
if (skUrl) {
const notasHtml = `<a href="${skUrl}" target="_blank" class="btn btn-sm btn-secondary">Ver presupuesto (${skId})</a>`;
// La columna de notas es la posición 6 (índice 6)
rowData[6] = notasHtml;