mirror of
https://git.imnavajas.es/jjimenez/safekat.git
synced 2025-07-25 22:52:08 +00:00
terminada envio lineas
This commit is contained in:
@ -786,6 +786,10 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi
|
||||
$routes->get('envio/(:num)', 'LogisticaController::editEnvio/$1');
|
||||
$routes->get('selectAddLinea', 'LogisticaController::selectAddEnvioLinea');
|
||||
$routes->get('addLineaEnvio', 'LogisticaController::addEnvioLinea');
|
||||
$routes->post('updateCajaLinea', 'LogisticaController::setCajaLinea');
|
||||
$routes->post('deleteLineasEnvio', 'LogisticaController::deleteLineas');
|
||||
$routes->post('updateUnidadesEnvio', 'LogisticaController::updateUnidadesEnvio');
|
||||
$routes->post('updateComentariosEnvio', 'LogisticaController::saveComments');
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
@ -84,26 +84,29 @@ class LogisticaController extends BaseController
|
||||
return $this->response->setJSON($result);
|
||||
}
|
||||
|
||||
public function selectAddEnvioLinea(){
|
||||
public function selectAddEnvioLinea()
|
||||
{
|
||||
|
||||
if ($this->request->isAJAX()) {
|
||||
$query = LogisticaService::findLineaEnvioPorEnvio($this->request->getGet('envio'))->orderBy("name", "asc");
|
||||
$query = LogisticaService::findLineaEnvioPorEnvio($this->request->getGet('envio'));
|
||||
if ($this->request->getGet("q")) {
|
||||
$query->groupStart()
|
||||
->orLike("pedidos.id", $this->request->getGet("q"))
|
||||
->orLike("presupuestos.titulo", $this->request->getGet("q"))
|
||||
->orLike("p.id", $this->request->getGet("q"))
|
||||
->orLike("pr.titulo", $this->request->getGet("q"))
|
||||
->groupEnd();
|
||||
}
|
||||
|
||||
$result = $query->get()->getResultObject();
|
||||
|
||||
|
||||
$result = $query->orderBy("name", "asc")->get()->getResultObject();
|
||||
|
||||
return $this->response->setJSON($result);
|
||||
} else {
|
||||
return $this->failUnauthorized('Invalid request', 403);
|
||||
}
|
||||
}
|
||||
|
||||
public function addEnvioLinea(){
|
||||
public function addEnvioLinea()
|
||||
{
|
||||
|
||||
if ($this->request->isAJAX()) {
|
||||
$pedido_id = $this->request->getGet('pedido_id');
|
||||
@ -123,20 +126,20 @@ class LogisticaController extends BaseController
|
||||
$model = model('App\Models\Logistica\EnvioModel');
|
||||
$q = $model->getDatatableQuery();
|
||||
|
||||
|
||||
|
||||
$result = DataTable::of($q)
|
||||
->edit(
|
||||
"finalizado",
|
||||
function ($row, $meta) {
|
||||
if ($row->finalizado == 1)
|
||||
if ($row->finalizado == 1)
|
||||
return '<i class="ti ti-check"></i>';
|
||||
else
|
||||
return '<i class="ti ti-x"></i>';
|
||||
}
|
||||
)
|
||||
->add("action", callback: function ($q) {
|
||||
|
||||
return '
|
||||
|
||||
return '
|
||||
<div class="btn-group btn-group-sm">
|
||||
<a href="javascript:void(0);"><i class="ti ti-eye ti-sm btn-edit mx-2" data-id="' . $q->id . '"></i></a>
|
||||
</div>
|
||||
@ -146,7 +149,8 @@ class LogisticaController extends BaseController
|
||||
return $result->toJson(returnAsObject: true);
|
||||
}
|
||||
|
||||
public function editEnvio($id = null){
|
||||
public function editEnvio($id = null)
|
||||
{
|
||||
|
||||
if (empty($id)) {
|
||||
return redirect()->to(base_url('logistica/selectEnvios/simple'))->with('error', lang('Logistica.errors.noEnvio'));
|
||||
@ -159,10 +163,11 @@ class LogisticaController extends BaseController
|
||||
if (empty($envioEntity)) {
|
||||
return redirect()->to(base_url('logistica/selectEnvios/simple'))->with('error', lang('Logistica.errors.noEnvio'));
|
||||
}
|
||||
$envioEntity->nextCaja = model('App\Models\Logistica\EnvioLineaModel')->getMaxCaja();
|
||||
|
||||
$viewData = [
|
||||
'currentModule' => static::$controllerSlug,
|
||||
'boxTitle' => '<i class="ti ti-truck ti-xl"></i>' . ' '. lang('Logistica.envio') . ' [' . $envioEntity->id . ']: ' . $envioEntity->direccion,
|
||||
'boxTitle' => '<i class="ti ti-truck ti-xl"></i>' . ' ' . lang('Logistica.envio') . ' [' . $envioEntity->id . ']: ' . $envioEntity->direccion,
|
||||
'usingServerSideDataTable' => true,
|
||||
'envioEntity' => $envioEntity,
|
||||
];
|
||||
@ -177,15 +182,17 @@ class LogisticaController extends BaseController
|
||||
$model = model('App\Models\Logistica\EnvioLineaModel');
|
||||
$q = $model->getDatatableQuery($idEnvio);
|
||||
|
||||
|
||||
|
||||
$result = DataTable::of($q)
|
||||
->add("rowSelected",callback: function ($q) {
|
||||
return '<input type="checkbox" class="form-check-input" name="row_selected[]" value="' . $q->id . '">';
|
||||
->add(
|
||||
"rowSelected",
|
||||
callback: function ($q) {
|
||||
return '<input type="checkbox" class="form-check-input checkbox-linea-envio" name="row_selected[]" value="' . $q->id . '">';
|
||||
}
|
||||
)
|
||||
->add("action", callback: function ($q) {
|
||||
|
||||
return '
|
||||
|
||||
return '
|
||||
<div class="btn-group btn-group-sm">
|
||||
<a href="javascript:void(0);"><i class="ti ti-pencil ti-sm btn-edit mx-2" data-id="' . $q->id . '"></i></a>
|
||||
</div>
|
||||
@ -194,4 +201,85 @@ class LogisticaController extends BaseController
|
||||
|
||||
return $result->toJson(returnAsObject: true);
|
||||
}
|
||||
|
||||
public function setCajaLinea()
|
||||
{
|
||||
|
||||
if ($this->request->isAJAX()) {
|
||||
$id = $this->request->getPost('id');
|
||||
$caja = $this->request->getPost('caja');
|
||||
|
||||
|
||||
$model = model('App\Models\Logistica\EnvioLineaModel');
|
||||
$result = $model->update($id, [
|
||||
'cajas' => $caja,
|
||||
]);
|
||||
return $this->response->setJSON([
|
||||
"status" => $result,
|
||||
]);
|
||||
} else {
|
||||
return $this->failUnauthorized('Invalid request', 403);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteLineas()
|
||||
{
|
||||
if ($this->request->isAJAX()) {
|
||||
$ids = $this->request->getPost('ids');
|
||||
$model = model('App\Models\Logistica\EnvioLineaModel');
|
||||
$result = $model->delete($ids);
|
||||
return $this->response->setJSON([
|
||||
"status" => $result,
|
||||
]);
|
||||
} else {
|
||||
return $this->failUnauthorized('Invalid request', 403);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateUnidadesEnvio()
|
||||
{
|
||||
$id = $this->request->getPost('id');
|
||||
$unidades = $this->request->getPost('unidades_envio');
|
||||
|
||||
if (!$id || !$unidades || intval($unidades) <= 0) {
|
||||
return $this->response->setJSON([
|
||||
'status' => false,
|
||||
'message' => 'Datos inválidos'
|
||||
]);
|
||||
}
|
||||
|
||||
$model = model('App\Models\Logistica\EnvioLineaModel');
|
||||
$updated = $model->update($id, [
|
||||
'unidades_envio' => $unidades,
|
||||
]);
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => $updated,
|
||||
'message' => $updated ? 'Actualizado' : 'Error al actualizar'
|
||||
]);
|
||||
}
|
||||
|
||||
public function saveComments()
|
||||
{
|
||||
$id = $this->request->getPost('id');
|
||||
$comments = $this->request->getPost('comentarios');
|
||||
|
||||
if (!$id || !$comments) {
|
||||
return $this->response->setJSON([
|
||||
'status' => false,
|
||||
'message' => 'Datos inválidos'
|
||||
]);
|
||||
}
|
||||
|
||||
$model = model('App\Models\Logistica\EnvioModel');
|
||||
$updated = $model->update($id, [
|
||||
'comentarios' => $comments,
|
||||
]);
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => $updated,
|
||||
'message' => $updated ? 'Actualizado' : 'Error al actualizar'
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
use CodeIgniter\Database\RawSql;
|
||||
|
||||
class AddMEnvioColumns extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->forge->addColumn("envios",
|
||||
["multienvio" => [
|
||||
"type" => "TINYINT",
|
||||
"unsigned" => true,
|
||||
"null" => false,
|
||||
"default" => 0,
|
||||
]]
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->forge->dropColumn("envios", ['multienvio']);
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class AddEnviosLineas extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->forge->addField([
|
||||
'id' => ['type' => 'INT', 'auto_increment' => true],
|
||||
'envio_id' => ['type' => 'INT', 'unsigned' => true],
|
||||
'pedido_id' => ['type' => 'INT', 'unsigned' => true],
|
||||
'presupuesto_id' => ['type' => 'INT', 'unsigned' => true],
|
||||
'unidades_envio' => ['type' => 'INT', 'default' => 0],
|
||||
'unidades_total' => ['type' => 'INT', 'default' => 0],
|
||||
'cajas' => ['type' => 'INT', 'default' => 0],
|
||||
'unidades_cajas' => ['type' => 'INT', 'default' => 0],
|
||||
'created_at' => ['type' => 'DATETIME', 'null' => true],
|
||||
'updated_at' => ['type' => 'DATETIME', 'null' => true],
|
||||
'created_by' => ['type' => 'INT', 'unsigned' => true, 'null' => true],
|
||||
'updated_by' => ['type' => 'INT', 'unsigned' => true, 'null' => true],
|
||||
]);
|
||||
|
||||
$this->forge->addKey('id', true); // Primary Key
|
||||
|
||||
// Foreign Keys
|
||||
$this->forge->addForeignKey('presupuesto_id', 'presupuestos', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->forge->addForeignKey('pedido_id', 'pedidos', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->forge->addForeignKey('created_by', 'users', 'id', 'SET NULL', 'CASCADE');
|
||||
$this->forge->addForeignKey('updated_by', 'users', 'id', 'SET NULL', 'CASCADE');
|
||||
|
||||
$this->forge->createTable('envios_lineas');
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->forge->dropTable('envios_lineas');
|
||||
}
|
||||
}
|
||||
33
ci4/app/Entities/Logistica/EnvioEntity.php
Normal file
33
ci4/app/Entities/Logistica/EnvioEntity.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entities\Logistica;
|
||||
|
||||
use CodeIgniter\Entity\Entity;
|
||||
|
||||
class EnvioEntity extends Entity
|
||||
{
|
||||
protected $attributes = [
|
||||
'finalizado' => 0,
|
||||
'mostrar_precios' => 0,
|
||||
'mostrar_iva' => 0,
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'id' => 'int',
|
||||
'finalizado' => 'boolean',
|
||||
'codigo_seguimiento'=> 'string',
|
||||
'proveedor_id' => 'int',
|
||||
'comentarios' => 'string',
|
||||
'att' => 'string',
|
||||
'direccion' => 'string',
|
||||
'ciudad' => 'string',
|
||||
'cp' => 'string',
|
||||
'email' => 'string',
|
||||
'telefono' => 'string',
|
||||
'pais_id' => 'int',
|
||||
'mostrar_precios' => 'boolean',
|
||||
'mostrar_iva' => 'boolean',
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
23
ci4/app/Entities/Logistica/EnvioLineaEntity.php
Normal file
23
ci4/app/Entities/Logistica/EnvioLineaEntity.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entities\Logistica;
|
||||
|
||||
use CodeIgniter\Entity\Entity;
|
||||
|
||||
class EnvioLineaEntity extends Entity
|
||||
{
|
||||
protected $casts = [
|
||||
'id' => 'int',
|
||||
'envio_id' => 'int',
|
||||
'pedido_id' => 'int',
|
||||
'presupuesto_id' => 'int',
|
||||
'unidades_envio' => 'int',
|
||||
'unidades_total' => 'int',
|
||||
'cajas' => 'int',
|
||||
'unidades_cajas' => 'int',
|
||||
'created_by' => 'int',
|
||||
'updated_by' => 'int',
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
@ -50,6 +50,7 @@ return [
|
||||
'generarAlbaran' => 'Generar albarán',
|
||||
'imprimirEtiquetas' => 'Imprimir etiquetas',
|
||||
'buttonsActions' => 'Acciones sobre las filas seleccionadas',
|
||||
'addCaja' => 'Añadir caja',
|
||||
|
||||
'errors' => [
|
||||
'noEnvio' => 'No se ha encontrado el envio',
|
||||
|
||||
77
ci4/app/Models/Logistica/EnvioLineaModel.php
Normal file
77
ci4/app/Models/Logistica/EnvioLineaModel.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Logistica;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
use CodeIgniter\Database\BaseBuilder;
|
||||
|
||||
class EnvioLineaModel extends Model
|
||||
{
|
||||
protected $table = 'envios_lineas';
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
protected $useAutoIncrement = true;
|
||||
protected $returnType = \App\Entities\Logistica\EnvioLineaEntity::class;
|
||||
protected $useSoftDeletes = false;
|
||||
|
||||
protected $allowedFields = [
|
||||
'envio_id',
|
||||
'pedido_id',
|
||||
'unidades_envio',
|
||||
'unidades_total',
|
||||
'cajas',
|
||||
'unidades_cajas',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'presupuesto_id',
|
||||
];
|
||||
|
||||
protected $useTimestamps = true;
|
||||
protected $createdField = 'created_at';
|
||||
protected $updatedField = 'updated_at';
|
||||
|
||||
public function getDatatableQuery($envio_id = null): BaseBuilder
|
||||
{
|
||||
$builder = $this->db
|
||||
->table($this->table . " t1")
|
||||
->select(
|
||||
"t1.id, t1.pedido_id as pedido, t3.id as presupuesto,t1.cajas,
|
||||
t3.titulo as titulo, t1.unidades_envio as unidadesEnvio, t1.unidades_total as unidadesTotal,
|
||||
IFNULL((
|
||||
SELECT SUM(t_sub.unidades_envio)
|
||||
FROM " . $this->table . " t_sub
|
||||
JOIN envios e ON e.id = t_sub.envio_id
|
||||
JOIN presupuesto_direcciones d ON d.presupuesto_id = t_sub.presupuesto_id
|
||||
WHERE e.finalizado = 1
|
||||
AND t_sub.pedido_id = t1.pedido_id
|
||||
AND e.direccion = d.direccion COLLATE utf8mb3_general_ci
|
||||
), 0) as unidadesEnviadas,
|
||||
IFNULL((
|
||||
SELECT ROUND(SUM(peso) / 1000, 1)
|
||||
FROM presupuesto_linea
|
||||
WHERE presupuesto_id = t3.id
|
||||
), 0) AS pesoUnidad"
|
||||
);
|
||||
$builder->join("presupuestos t3", "t1.presupuesto_id = t3.id", "left");
|
||||
|
||||
$builder->where("t1.envio_id", $envio_id);
|
||||
|
||||
return $builder;
|
||||
}
|
||||
|
||||
public function getMaxCaja()
|
||||
{
|
||||
$builder = $this->db
|
||||
->table($this->table . " t1");
|
||||
$builder->selectMax('CAST(t1.cajas AS UNSIGNED)', 'max_caja');
|
||||
$builder->where('t1.cajas IS NOT NULL');
|
||||
$query = $builder->get();
|
||||
$row = $query->getRow();
|
||||
|
||||
$maxCaja = is_numeric($row->max_caja) ? (int) $row->max_caja : 0;
|
||||
|
||||
return $maxCaja + 1;
|
||||
}
|
||||
}
|
||||
55
ci4/app/Models/Logistica/EnvioModel.php
Normal file
55
ci4/app/Models/Logistica/EnvioModel.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Logistica;
|
||||
use CodeIgniter\Database\BaseBuilder;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class EnvioModel extends Model
|
||||
{
|
||||
protected $table = 'envios';
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
protected $useAutoIncrement = true;
|
||||
protected $returnType = \App\Entities\Logistica\EnvioEntity::class;
|
||||
protected $useSoftDeletes = false;
|
||||
|
||||
protected $allowedFields = [
|
||||
'finalizado',
|
||||
'codigo_seguimiento',
|
||||
'proveedor_id',
|
||||
'comentarios',
|
||||
'att',
|
||||
'direccion',
|
||||
'ciudad',
|
||||
'cp',
|
||||
'email',
|
||||
'telefono',
|
||||
'pais_id',
|
||||
'mostrar_precios',
|
||||
'mostrar_iva',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'multienvio',
|
||||
];
|
||||
|
||||
protected $useTimestamps = true;
|
||||
protected $createdField = 'created_at';
|
||||
protected $updatedField = 'updated_at';
|
||||
|
||||
public function getDatatableQuery(): BaseBuilder
|
||||
{
|
||||
$builder = $this->db
|
||||
->table($this->table . " t1")
|
||||
->select(
|
||||
"t1.id, GROUP_CONCAT(DISTINCT t2.pedido_id) AS pedidos,
|
||||
COUNT(t2.id) AS num_lineas,
|
||||
t1.att, t1.direccion, t1.ciudad, t3.nombre as pais, t1.cp, t1.email, t1.telefono, t1.finalizado"
|
||||
);
|
||||
$builder->join("envios_lineas t2", "t2.envio_id = t1.id", "left");
|
||||
$builder->join("lg_paises t3", "t3.id = t1.pais_id", "left");
|
||||
|
||||
$builder->groupBy("t1.id");
|
||||
return $builder;
|
||||
}
|
||||
}
|
||||
@ -170,7 +170,7 @@ class LogisticaService
|
||||
'pedido_id' => $result[0]->pedido_id,
|
||||
'unidades_envio' => $result[0]->unidades_envio,
|
||||
'unidades_total' => $result[0]->total_unidades,
|
||||
'cajas' => 1,
|
||||
'cajas' => null,
|
||||
'unidades_cajas' => 1,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
|
||||
243
ci4/app/Views/themes/vuexy/form/logistica/viewEnvioEditForm.php
Normal file
243
ci4/app/Views/themes/vuexy/form/logistica/viewEnvioEditForm.php
Normal file
@ -0,0 +1,243 @@
|
||||
<?= $this->include("themes/_commonPartialsBs/sweetalert") ?>
|
||||
<?= $this->include('themes/_commonPartialsBs/datatables') ?>
|
||||
<?= $this->include("themes/_commonPartialsBs/select2bs5") ?>
|
||||
<?= $this->extend('themes/vuexy/main/defaultlayout') ?>
|
||||
|
||||
|
||||
<?= $this->section('content'); ?>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4><?= $boxTitle ?></h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<?= view("themes/_commonPartialsBs/_alertBoxes") ?>
|
||||
|
||||
<input type="hidden" id="id" name="id" value="<?= $envioEntity->id ?>">
|
||||
<input type="hidden" id="nextCaja" name="next_caja" value="<?= $envioEntity->nextCaja ?>">
|
||||
|
||||
<div class="accordion accordion-bordered">
|
||||
<div class="card accordion-item active mb-5">
|
||||
<h4 class="accordion-header px-4 py-3">
|
||||
<?= lang("Logistica.datosEnvio") ?>
|
||||
</h4>
|
||||
|
||||
<div id="accordionDatosEnvioTip" class="accordion-collapse collapse show">
|
||||
<div class="accordion-body px-4 py-3">
|
||||
<div class="d-flex flex-row mb-3">
|
||||
|
||||
<div class="col-sm-4 px-3">
|
||||
<label for="att" class="form-label">
|
||||
<?= lang("Logistica.att") ?>
|
||||
</label>
|
||||
<input readonly id="att" name="att" tabindex="1" maxlength="50"
|
||||
class="form-control" value="<?= old('att', $envioEntity->att) ?>">
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 px-3">
|
||||
<label for="direccion" class="form-label">
|
||||
<?= lang("Logistica.direccion") ?>
|
||||
</label>
|
||||
<input readonly id="direccion" name="direccion" tabindex="1" maxlength="50"
|
||||
class="form-control" value="<?= old('direccion', $envioEntity->direccion) ?>">
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2 px-3">
|
||||
<label for="ciudad" class="form-label">
|
||||
<?= lang("Logistica.ciudad") ?>
|
||||
</label>
|
||||
<input readonly id="ciudad" name="ciudad" tabindex="1" maxlength="50"
|
||||
class="form-control" value="<?= old('ciudad', $envioEntity->ciudad) ?>">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-row mb-3">
|
||||
|
||||
<div class="col-sm-3 px-3">
|
||||
<label for="cp" class="form-label">
|
||||
<?= lang("Logistica.cp") ?>
|
||||
</label>
|
||||
<input readonly id="cp" name="cp" tabindex="1" maxlength="50"
|
||||
class="form-control" value="<?= old('cp', $envioEntity->cp) ?>">
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3 px-3">
|
||||
<label for="pais" class="form-label">
|
||||
<?= lang("Logistica.pais") ?>
|
||||
</label>
|
||||
<input readonly id="pais" name="pais" tabindex="1" maxlength="50"
|
||||
class="form-control" value="<?= old('pais', $envioEntity->pais) ?>">
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3 px-3">
|
||||
<label for="email" class="form-label">
|
||||
<?= lang("Logistica.email") ?>
|
||||
</label>
|
||||
<input readonly id="email" name="email" tabindex="1" maxlength="50"
|
||||
class="form-control" value="<?= old('email', $envioEntity->email) ?>">
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3 px-3">
|
||||
<label for="telefono" class="form-label">
|
||||
<?= lang("Logistica.telefono") ?>
|
||||
</label>
|
||||
<input readonly id="telefono" name="telefono" tabindex="1" maxlength="50"
|
||||
class="form-control" value="<?= old('telefono', $envioEntity->telefono) ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-row mb-3">
|
||||
<div class="col-sm-9 px-3">
|
||||
<label for="comentarios" class="form-label">
|
||||
<?= lang("Logistica.comentariosEnvio") ?>
|
||||
</label>
|
||||
<input id="comentarios" name="comentarios" tabindex="1" maxlength="50"
|
||||
class="form-control" value="<?= old('comentarios', $envioEntity->comentarios) ?>">
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3 px-3">
|
||||
<button id="guardarComentarios" name="guardar_comentarios" tabindex="1"
|
||||
class="btn btn-primary mt-4 w-100">
|
||||
<?= lang("Logistica.guardar") ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion accordion-bordered">
|
||||
<div class="card accordion-item active mb-5">
|
||||
<h4 class="accordion-header px-4 py-3">
|
||||
<?= lang("Logistica.addLineasEnvio") ?>
|
||||
</h4>
|
||||
|
||||
<div id="accordionaddLineasEnvioTip" class="accordion-collapse collapse show">
|
||||
|
||||
<div class="d-flex flex-row mb-3">
|
||||
<div class="col-sm-12 px-3">
|
||||
<p><?= lang('Logistica.addLineasText') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-row mb-3">
|
||||
<div class="col-sm-6 px-3">
|
||||
<label for="buscadorPedidos" class="form-label">
|
||||
<?= lang("Logistica.buscadorPedidosTitle2") ?>
|
||||
</label>
|
||||
<select id="buscadorPedidos" name="buscador_pedidos" tabindex="1" maxlength="50"
|
||||
class="form-control select2bs2" style="width: 100%;">
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm-2 px-3">
|
||||
<button id="btnAddLinea" name="btnBuscar" tabindex="1"
|
||||
class="btn btn-primary mt-4 w-100">
|
||||
<?= lang("Logistica.add") ?>
|
||||
<ti class="ti ti-circle-plus"></ti>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="accordion accordion-bordered">
|
||||
<div class="card accordion-item active mb-5">
|
||||
<h4 class="accordion-header px-4 py-3">
|
||||
<?= lang("Logistica.lineasEnvio") ?>
|
||||
</h4>
|
||||
|
||||
<div id="accordionDatosEnvioTip" class="accordion-collapse collapse show">
|
||||
<div class="accordion-body px-4 py-3">
|
||||
<div class="d-flex flex-row">
|
||||
<p><?= lang('Logistica.buttonsActions') ?></p>
|
||||
</div>
|
||||
<div class="d-flex flex-row mb-3">
|
||||
<div class="col-sm-2 px-3">
|
||||
<button id="btnEliminarLineas" name="btnEliminarLineas" tabindex="1"
|
||||
class="btn btn-danger w-100">
|
||||
<?= lang("Logistica.eliminar") ?>
|
||||
<i class="ti ti-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-sm-2 px-3">
|
||||
<button id="btnGenerarAlbaran" name="btnGenerarAlbaran" tabindex="1"
|
||||
class="btn btn-success w-100">
|
||||
<?= lang("Logistica.generarAlbaran") ?>
|
||||
<i class="ti ti-file-check"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-sm-2 px-3">
|
||||
<button id="btnImprimirEtiquetas" name="btnImprimirEtiquetas" tabindex="1"
|
||||
class="btn btn-primary w-100">
|
||||
<?= lang("Logistica.imprimirEtiquetas") ?>
|
||||
<i class="ti ti-printer"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2 px-3">
|
||||
<button id="btnAddCaja" name="btnAddCaja" tabindex="1"
|
||||
class="btn btn-secondary w-100">
|
||||
<?= lang("Logistica.addCaja") ?>
|
||||
<i class="ti ti-box"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
|
||||
<table id="tableLineasEnvio" class="table table-striped table-hover w-100">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th><?= lang("Logistica.pedido") ?></th>
|
||||
<th><?= lang("Logistica.presupuesto") ?></th>
|
||||
<th><?= lang("Logistica.titulo") ?></th>
|
||||
<th><?= lang("Logistica.unidadesEnvio") ?></th>
|
||||
<th><?= lang("Logistica.unidadesEnviadas") ?></th>
|
||||
<th><?= lang("Logistica.unidadesTotales") ?></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('css') ?>
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/libs/sweetalert2/sweetalert2.css') ?>" />
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/rowreorder/1.4.1/css/rowReorder.dataTables.min.css">
|
||||
<link rel="stylesheet" href="https://code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('additionalExternalJs') ?>
|
||||
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"></script>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/sweetalert2/sweetalert2.js') ?>"></script>
|
||||
<script src="https://cdn.datatables.net/rowgroup/1.3.1/js/dataTables.rowGroup.min.js"></script>
|
||||
|
||||
<script src="https://cdn.datatables.net/rowreorder/1.4.1/js/dataTables.rowReorder.min.js"></script>
|
||||
<script type="module" src="<?= site_url("assets/js/safekat/pages/logistica/envioEdit.js") ?>"></script>
|
||||
<?= $this->endSection() ?>
|
||||
97
ci4/app/Views/themes/vuexy/form/logistica/viewEnvioForm.php
Normal file
97
ci4/app/Views/themes/vuexy/form/logistica/viewEnvioForm.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?= $this->include("themes/_commonPartialsBs/sweetalert") ?>
|
||||
<?= $this->include('themes/_commonPartialsBs/datatables') ?>
|
||||
<?= $this->extend('themes/vuexy/main/defaultlayout') ?>
|
||||
|
||||
<?= $this->section('content'); ?>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4><?= $boxTitle ?></h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<?= view("themes/_commonPartialsBs/_alertBoxes") ?>
|
||||
|
||||
<div class="card accordion-item active mb-5">
|
||||
<h4 class="accordion-header px-4 py-3">
|
||||
<?= lang("Logistica.nuevoEnvio") ?>
|
||||
</h4>
|
||||
|
||||
<div id="accordionNuevoEnvioTip" class="accordion-collapse collapse show">
|
||||
<div class="accordion-body px-4 py-3">
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="mb-1 col-sm-4">
|
||||
<label for="buscadorPedidos" class="form-label">
|
||||
<?= lang("Logistica.buscadorPedidosTitle") ?>
|
||||
</label>
|
||||
<input id="buscadorPedidos" name="buscador_pedidos" tabindex="1" maxlength="50"
|
||||
class="form-control" value="">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card accordion-item active">
|
||||
<h4 class="accordion-header px-4 py-3">
|
||||
<?= lang("Logistica.listadoEnvios") ?>
|
||||
</h4>
|
||||
|
||||
<div id="accordionListadoEnviosTip" class="accordion-collapse collapse show">
|
||||
<div class="accordion-body px-4 py-3">
|
||||
|
||||
<div class="row">
|
||||
<table id="tableOfEnvios" class="table table-striped table-hover w-100">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= lang('Logistica.idEnvio') ?? 'ID Envío' ?></th>
|
||||
<th><?= lang('Logistica.numeroPedidos') ?? 'Nº Pedidos' ?></th>
|
||||
<th><?= lang('Logistica.numeroLineas') ?? 'Nº Líneas' ?></th>
|
||||
<th><?= lang('Logistica.att') ?? 'Att' ?></th>
|
||||
<th><?= lang('Logistica.direccion') ?? 'Dirección' ?></th>
|
||||
<th><?= lang('Logistica.ciudad') ?? 'Ciudad' ?></th>
|
||||
<th><?= lang('Logistica.pais') ?? 'País' ?></th>
|
||||
<th><?= lang('Logistica.cp') ?? 'CP' ?></th>
|
||||
<th><?= lang('Logistica.email') ?? 'Email' ?></th>
|
||||
<th><?= lang('Logistica.telefono') ?? 'Teléfono' ?></th>
|
||||
<th><?= lang('Logistica.finalizado') ?? 'Finalizado' ?></th>
|
||||
<th><?= lang('Logistica.acciones') ?? 'Acciones' ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<button type="button" class="btn btn-secondary" id="btnImprimirEtiquetas"
|
||||
onclick="window.location.href='<?= route_to('LogisticaPanel') ?>'">
|
||||
<?= lang('Logistica.backToPanel') ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
|
||||
<?= $this->section('css') ?>
|
||||
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/libs/sweetalert2/sweetalert2.css') ?>" />
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('additionalExternalJs') ?>
|
||||
<script src="<?= site_url('themes/vuexy/vendor/libs/sweetalert2/sweetalert2.js') ?>"></script>
|
||||
<script type="module" src="<?= site_url("assets/js/safekat/pages/logistica/envio.js") ?>"></script>
|
||||
<?= $this->endSection() ?>
|
||||
598
httpdocs/assets/js/safekat/pages/logistica/envioEdit.js
Normal file
598
httpdocs/assets/js/safekat/pages/logistica/envioEdit.js
Normal file
@ -0,0 +1,598 @@
|
||||
import ClassSelect from '../../components/select2.js';
|
||||
import Ajax from '../../components/ajax.js';
|
||||
|
||||
class EnvioEdit {
|
||||
|
||||
|
||||
constructor() {
|
||||
|
||||
this.tableCols = [
|
||||
{ data: "rowSelected" },
|
||||
{ data: "cajas", defaultContent: ""},
|
||||
{ data: "pedido" },
|
||||
{ data: "presupuesto" },
|
||||
{ data: "titulo" },
|
||||
{ data: "unidadesEnvio" },
|
||||
{ data: "unidadesEnviadas" },
|
||||
{ data: "unidadesTotal" },
|
||||
{ data: "action" },
|
||||
{ data: "id" },
|
||||
{ data: "pesoUnidad" }
|
||||
];
|
||||
|
||||
this.table = null;
|
||||
|
||||
this.buscarPedidos = new ClassSelect($("#buscadorPedidos"), '/logistica/selectAddLinea', "", true, { 'envio': $("#id").val() });
|
||||
|
||||
this.contadorCajas = parseInt($("#nextCaja").val()) || 1;
|
||||
this.btnAddLinea = $("#btnAddLinea");
|
||||
this.btnAddCaja = $("#btnAddCaja");
|
||||
this.btnDeleteLinea = $("#btnEliminarLineas");
|
||||
this.btnGuardarComentarios = $("#guardarComentarios");
|
||||
}
|
||||
|
||||
init() {
|
||||
|
||||
this.table = $('#tableLineasEnvio').DataTable({
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
autoWidth: true,
|
||||
responsive: true,
|
||||
scrollX: true,
|
||||
orderCellsTop: true,
|
||||
lengthMenu: [5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500],
|
||||
pageLength: 50,
|
||||
"dom": 'lrtip',
|
||||
"ajax": {
|
||||
"url": "/logistica/datatableLineasEnvios/" + $('#id').val(),
|
||||
},
|
||||
"columns": this.tableCols,
|
||||
"language": {
|
||||
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
|
||||
},
|
||||
rowGroup: {
|
||||
dataSrc: 'cajas',
|
||||
startRender: function (rows, group) {
|
||||
const nombreGrupo = group === null || group === '' || group === 'null' || group.toUpperCase() === 'NO GROUP'
|
||||
? 'SIN ASIGNAR'
|
||||
: group;
|
||||
let totalUnidades = 0;
|
||||
let totalPeso = 0;
|
||||
rows.data().each(function (row) {
|
||||
const unidades = parseInt(row.unidadesEnvio) || 0;
|
||||
totalUnidades += unidades;
|
||||
totalPeso += parseFloat(row.pesoUnidad) * unidades || 0;
|
||||
});
|
||||
|
||||
return `CAJA: ${nombreGrupo} [unidades: ${totalUnidades}, peso: <span class="peso-grupo" data-valor="${totalPeso}">${totalPeso.toFixed(1)}</span> kg]`;
|
||||
}
|
||||
},
|
||||
"columnDefs": [
|
||||
{
|
||||
"targets": [0, 8],
|
||||
"className": "text-center",
|
||||
"orderable": false,
|
||||
"searchable": false,
|
||||
},
|
||||
{
|
||||
"targets": [2, 3, 5, 6, 7],
|
||||
"className": "text-center",
|
||||
},
|
||||
{
|
||||
targets: [1, 9, 10],
|
||||
visible: false
|
||||
}
|
||||
],
|
||||
"order": [[1, "asc"]],
|
||||
"orderFixed": [ [1, 'asc'] ],
|
||||
});
|
||||
|
||||
|
||||
$('#tableLineasEnvio').on('draw.dt', () => {
|
||||
const table = this.table;
|
||||
|
||||
this._aplicarDroppableEnGrupos(table);
|
||||
|
||||
// Aplica draggable a filas si aún no lo tienen
|
||||
this.table.rows({ page: 'current' }).every(function () {
|
||||
const $row = $(this.node());
|
||||
if (!$row.hasClass('draggable-applied')) {
|
||||
$row.addClass('draggable-applied');
|
||||
$row.draggable({
|
||||
helper: 'clone',
|
||||
revert: 'invalid',
|
||||
start: () => $row.css('opacity', 0.5),
|
||||
stop: () => $row.css('opacity', 1)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelectorAll('.peso-grupo').forEach(el => {
|
||||
const valor = parseFloat(el.getAttribute('data-valor')) || 0;
|
||||
|
||||
new AutoNumeric(el, valor, {
|
||||
decimalPlaces: 1,
|
||||
digitGroupSeparator: ',',
|
||||
decimalCharacter: '.',
|
||||
minimumValue: '0',
|
||||
suffixText: '',
|
||||
modifyValueOnWheel: false
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.btn-edit', (e) => {
|
||||
const table = this.table;
|
||||
const id = $(e.currentTarget).data('id');
|
||||
const row = table.row($(e.currentTarget).closest('tr'));
|
||||
const rowData = row.data();
|
||||
|
||||
Swal.fire({
|
||||
title: 'Editar unidades a enviar',
|
||||
input: 'number',
|
||||
inputLabel: `Unidades actuales: ${rowData.unidadesEnvio}`,
|
||||
inputValue: rowData.unidadesEnvio,
|
||||
inputAttributes: {
|
||||
min: 1
|
||||
},
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Guardar',
|
||||
cancelButtonText: 'Cancelar',
|
||||
inputValidator: (value) => {
|
||||
if (!value || parseInt(value) <= 0) {
|
||||
return 'Debes ingresar un valor mayor a 0';
|
||||
}
|
||||
},
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
cancelButton: 'btn btn-secondary'
|
||||
},
|
||||
buttonsStyling: false
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
const nuevasUnidades = parseInt(result.value);
|
||||
|
||||
$.post('/logistica/updateUnidadesEnvio', {
|
||||
id: rowData.id,
|
||||
unidades_envio: nuevasUnidades
|
||||
}, function (response) {
|
||||
if (response.status) {
|
||||
table.draw(false);
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: response.message,
|
||||
icon: 'error',
|
||||
showCancelButton: false,
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
}
|
||||
}).fail(() => {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: 'No se pudo actualizar el dato.',
|
||||
icon: 'error',
|
||||
showCancelButton: false,
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.buscarPedidos.init();
|
||||
|
||||
this.btnAddLinea.on('click', this._addEnvioLinea.bind(this));
|
||||
this.btnAddCaja.on('click', this._addCaja.bind(this));
|
||||
this.btnDeleteLinea.on('click', this._deleteLineas.bind(this));
|
||||
this.btnGuardarComentarios.on('click', () => {
|
||||
|
||||
$.post('/logistica/updateComentariosEnvio', {
|
||||
id: $('#id').val(),
|
||||
comentarios: $('#comentarios').val()
|
||||
}, function (response) {
|
||||
if (response.status) {
|
||||
popSuccessAlert('Comentarios guardados correctamente');
|
||||
} else {
|
||||
popErrorAlert(response.message);
|
||||
}
|
||||
}).fail((error) => {
|
||||
popErrorAlert(error.responseJSON.message);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
_deleteLineas() {
|
||||
const table = this.table;
|
||||
const selectedRows = table.rows({ page: 'current' }).nodes().filter((node) => {
|
||||
const checkbox = $(node).find('.checkbox-linea-envio');
|
||||
return checkbox.is(':checked');
|
||||
});
|
||||
const ids = selectedRows.map((node) => {
|
||||
const rowData = table.row(node).data();
|
||||
return rowData.id;
|
||||
}
|
||||
).toArray();
|
||||
if (ids.length > 0) {
|
||||
Swal.fire({
|
||||
|
||||
title: 'Eliminar líneas de envío',
|
||||
text: '¿Está seguro de que desea eliminar las líneas seleccionadas?',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Sí',
|
||||
cancelButtonText: 'Cancelar',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-danger me-1',
|
||||
cancelButton: 'btn btn-secondary'
|
||||
},
|
||||
buttonsStyling: false
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post('/logistica/deleteLineasEnvio', {
|
||||
|
||||
ids: ids
|
||||
}, function (response) {
|
||||
if (response.status) {
|
||||
table.draw(false);
|
||||
}
|
||||
else {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: response.message,
|
||||
icon: 'error',
|
||||
showCancelButton: false,
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
table.ajax.reload();
|
||||
}
|
||||
}).fail(() => {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: 'No se pudo eliminar la línea de envío.',
|
||||
icon: 'error',
|
||||
showCancelButton: false,
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
table.ajax.reload();
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Sin filas seleccionadas',
|
||||
text: 'Marca al menos una línea para eliminarla.',
|
||||
icon: 'info',
|
||||
showCancelButton: false,
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_addCaja() {
|
||||
|
||||
const table = this.table;
|
||||
this.contadorCajas = this._calcularSiguienteNumeroCaja();
|
||||
const contadorCajas = this.contadorCajas;
|
||||
let moved = false;
|
||||
|
||||
// Recorremos todas las filas visibles
|
||||
table.rows({ page: 'current' }).every(function () {
|
||||
const $row = $(this.node());
|
||||
const checkbox = $row.find('.checkbox-linea-envio');
|
||||
|
||||
if (checkbox.is(':checked')) {
|
||||
const rowData = this.data();
|
||||
|
||||
$.post('/logistica/updateCajaLinea', {
|
||||
id: rowData.id,
|
||||
caja: contadorCajas
|
||||
}, function (response) {
|
||||
if (response.status) {
|
||||
table.draw(false);
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: response.message,
|
||||
icon: 'error',
|
||||
showCancelButton: false,
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
table.ajax.reload();
|
||||
}
|
||||
}).fail(() => {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: 'No se pudo actualizar el grupo.',
|
||||
icon: 'error',
|
||||
showCancelButton: false,
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
table.ajax.reload();
|
||||
});
|
||||
|
||||
moved = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (moved) {
|
||||
table.draw(false); // Redibuja sin cambiar de página
|
||||
this.contadorCajas++;
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Sin filas seleccionadas',
|
||||
text: 'Marca al menos una línea para moverla a una nueva caja.',
|
||||
icon: 'info',
|
||||
showCancelButton: false,
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_aplicarDroppableEnGrupos(table) {
|
||||
const self = this;
|
||||
setTimeout(() => {
|
||||
$('.dtrg-group').each(function () {
|
||||
const $grupo = $(this);
|
||||
let nombreGrupo = $grupo.text().toUpperCase().replace('CAJA:', '').trim();
|
||||
if (nombreGrupo === 'SIN ASIGNAR') {
|
||||
nombreGrupo = null;
|
||||
}
|
||||
|
||||
// Evitar aplicar múltiples veces
|
||||
if (!$grupo.hasClass('droppable-applied')) {
|
||||
$grupo.addClass('droppable-applied');
|
||||
|
||||
$grupo.droppable({
|
||||
accept: 'tr:not(.dtrg-group)',
|
||||
hoverClass: 'table-primary',
|
||||
drop: function (event, ui) {
|
||||
|
||||
const row = table.row(ui.draggable);
|
||||
const rowData = row.data();
|
||||
|
||||
rowData.cajas = nombreGrupo;
|
||||
row.data(rowData).invalidate();
|
||||
|
||||
$.post('/logistica/updateCajaLinea', {
|
||||
id: rowData.id,
|
||||
caja: nombreGrupo
|
||||
}, function (response) {
|
||||
if (response.status) {
|
||||
self._reordenarCajas();
|
||||
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: response.message,
|
||||
icon: 'error',
|
||||
showCancelButton: false,
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
table.ajax.reload();
|
||||
}
|
||||
}).fail(() => {
|
||||
Swal.fire({
|
||||
title: 'Error filas seleccionadas',
|
||||
text: 'No se pudo actualizar el grupo.',
|
||||
icon: 'error',
|
||||
showCancelButton: false,
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
table.ajax.reload();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}, 50); // pequeño delay para asegurar que el DOM esté listo
|
||||
}
|
||||
|
||||
_addEnvioLinea() {
|
||||
|
||||
if(!this.buscarPedidos.getVal()) {
|
||||
Swal.fire({
|
||||
title: 'Atención!',
|
||||
text: 'Debe seleccionar un pedido antes de añadir una línea de envío.',
|
||||
icon: 'info',
|
||||
showCancelButton: false,
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
new Ajax('/logistica/addLineaEnvio', {
|
||||
'envio_id': $('#id').val(),
|
||||
'pedido_id': this.buscarPedidos.getVal(),
|
||||
'direccion': $("#direccion").val()
|
||||
}, {},
|
||||
(response) => {
|
||||
if (response.status) {
|
||||
if (parseInt(response.data.total_unidades) > parseInt(response.data.unidades_envio)) {
|
||||
const text = `<div style="text-align: left;">
|
||||
Se ha añadido un nuevo envío parcial:\n
|
||||
<ul>
|
||||
<li>Unidades totales en pedido: {unidadesTotal}</li>
|
||||
<li>Unidades añadidos: {unidadesEnvio}</li>
|
||||
<li>Unidades enviadas: {unidadesEnviadas}</li>
|
||||
<li>Unidades en envíos no finalizados: {unidadesPendientes}</li>
|
||||
</ul>
|
||||
</div>`;
|
||||
const unidades_pendientes = parseInt(response.data.total_unidades) -
|
||||
parseInt(response.data.unidades_enviadas) - parseInt(response.data.unidades_envio);
|
||||
const textFinal = text.replace('{unidadesTotal}', response.data.total_unidades)
|
||||
.replace('{unidadesEnvio}', response.data.unidades_envio)
|
||||
.replace('{unidadesEnviadas}', response.data.unidades_enviadas)
|
||||
.replace('{unidadesPendientes}', unidades_pendientes);
|
||||
Swal.fire({
|
||||
title: 'Atención!',
|
||||
html: textFinal,
|
||||
icon: 'info',
|
||||
showCancelButton: false,
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
}
|
||||
this.table.draw();
|
||||
this.buscarPedidos.empty();
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Atención!',
|
||||
text: response.message,
|
||||
icon: 'info',
|
||||
showCancelButton: false,
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
}
|
||||
}, (error) => {
|
||||
console.error(error);
|
||||
}).get();
|
||||
}
|
||||
|
||||
|
||||
_calcularSiguienteNumeroCaja() {
|
||||
const cajasUsadas = new Set();
|
||||
|
||||
this.table.rows().every(function () {
|
||||
const data = this.data();
|
||||
const caja = data.cajas;
|
||||
|
||||
if (caja !== null && caja !== '' && !isNaN(parseInt(caja))) {
|
||||
cajasUsadas.add(parseInt(caja));
|
||||
}
|
||||
});
|
||||
|
||||
// Buscar el menor número libre empezando desde 1
|
||||
let i = 1;
|
||||
while (cajasUsadas.has(i)) {
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
_reordenarCajas() {
|
||||
const table = this.table;
|
||||
const mapaOriginalANuevo = {};
|
||||
const cajasDetectadas = [];
|
||||
|
||||
// 1. Recolectar cajas distintas en orden
|
||||
table.rows().every(function () {
|
||||
const data = this.data();
|
||||
const caja = data.cajas;
|
||||
|
||||
if (caja !== null && caja !== '' && !isNaN(parseInt(caja))) {
|
||||
const cajaNum = parseInt(caja);
|
||||
if (!cajasDetectadas.includes(cajaNum)) {
|
||||
cajasDetectadas.push(cajaNum);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cajasDetectadas.sort((a, b) => a - b);
|
||||
|
||||
// 2. Construir mapa de renumeración
|
||||
cajasDetectadas.forEach((valorOriginal, idx) => {
|
||||
mapaOriginalANuevo[valorOriginal] = idx + 1;
|
||||
});
|
||||
|
||||
// 3. Aplicar cambios si hace falta
|
||||
table.rows().every(function () {
|
||||
const data = this.data();
|
||||
const original = parseInt(data.cajas);
|
||||
const nuevo = mapaOriginalANuevo[original];
|
||||
|
||||
if (original !== nuevo) {
|
||||
data.cajas = nuevo;
|
||||
|
||||
// Persistir en backend
|
||||
$.post('/logistica/updateCajaLinea', {
|
||||
id: data.id,
|
||||
caja: nuevo
|
||||
});
|
||||
|
||||
this.data(data).invalidate();
|
||||
}
|
||||
});
|
||||
|
||||
// 4. Actualizar contador interno
|
||||
this.contadorCajas = cajasDetectadas.length + 1;
|
||||
|
||||
table.draw(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
new EnvioEdit().init();
|
||||
});
|
||||
|
||||
export default EnvioEdit;
|
||||
@ -130,4 +130,9 @@
|
||||
|
||||
.beta {
|
||||
color: orangered !important;
|
||||
}
|
||||
|
||||
.dtrg-group.ui-droppable-hover {
|
||||
background-color: #d1ecf1 !important;
|
||||
cursor: move;
|
||||
}
|
||||
Reference in New Issue
Block a user