mirror of
https://git.imnavajas.es/jjimenez/safekat.git
synced 2025-07-25 22:52:08 +00:00
falta terminar albaranes
This commit is contained in:
@ -511,6 +511,7 @@ $routes->group('albaranes', ['namespace' => 'App\Controllers\Albaranes'], functi
|
|||||||
$routes->get('datatablesAlbaranLinea', 'Albaran::datatablesLineasAlbaran');
|
$routes->get('datatablesAlbaranLinea', 'Albaran::datatablesLineasAlbaran');
|
||||||
$routes->post('updateAlbaran', 'Albaran::updateAlbaran');
|
$routes->post('updateAlbaran', 'Albaran::updateAlbaran');
|
||||||
$routes->post('borrarAlbaranLinea', 'Albaran::borrarLinea');
|
$routes->post('borrarAlbaranLinea', 'Albaran::borrarLinea');
|
||||||
|
$routes->post('borrarAlbaran', 'Albaran::borrarAlbaran');
|
||||||
});
|
});
|
||||||
$routes->resource('albaranes', ['namespace' => 'App\Controllers\Pedidos', 'controller' => 'Albaran', 'except' => 'show,new,create,update']);
|
$routes->resource('albaranes', ['namespace' => 'App\Controllers\Pedidos', 'controller' => 'Albaran', 'except' => 'show,new,create,update']);
|
||||||
|
|
||||||
@ -787,6 +788,7 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi
|
|||||||
$routes->post('deleteLineasEnvio', 'LogisticaController::deleteLineas');
|
$routes->post('deleteLineasEnvio', 'LogisticaController::deleteLineas');
|
||||||
$routes->post('updateLineaEnvio', 'LogisticaController::updateLineaEnvio');
|
$routes->post('updateLineaEnvio', 'LogisticaController::updateLineaEnvio');
|
||||||
$routes->post('updateComentariosEnvio', 'LogisticaController::saveComments');
|
$routes->post('updateComentariosEnvio', 'LogisticaController::saveComments');
|
||||||
|
$routes->post('updateCajasEnvio', 'LogisticaController::updateCajasEnvio');
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
419
ci4/app/Controllers/Albaranes/Albaran.php
Normal file
419
ci4/app/Controllers/Albaranes/Albaran.php
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controllers\Albaranes;
|
||||||
|
use App\Entities\Albaranes\AlbaranEntity;
|
||||||
|
use App\Models\Albaranes\AlbaranModel;
|
||||||
|
use Hermawan\DataTables\DataTable;
|
||||||
|
|
||||||
|
class Albaran extends \App\Controllers\BaseResourceController
|
||||||
|
{
|
||||||
|
protected $modelName = AlbaranModel::class;
|
||||||
|
protected $format = 'json';
|
||||||
|
|
||||||
|
protected static $singularObjectNameCc = 'albaran';
|
||||||
|
protected static $singularObjectName = 'Albaran';
|
||||||
|
protected static $pluralObjectName = 'Albaranes';
|
||||||
|
protected static $controllerSlug = 'albaran';
|
||||||
|
|
||||||
|
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||||
|
{
|
||||||
|
parent::initController($request, $response, $logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($id = null)
|
||||||
|
{
|
||||||
|
if ($this->request->isAJAX()) {
|
||||||
|
|
||||||
|
$newTokenHash = csrf_hash();
|
||||||
|
$csrfTokenName = csrf_token();
|
||||||
|
|
||||||
|
$model_linea = model('App\Models\Albaranes\AlbaranLineaModel');
|
||||||
|
$model_linea->where('albaran_id', $id)->delete();
|
||||||
|
|
||||||
|
$this->model->where('id', $id)->delete();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'error' => 0,
|
||||||
|
$csrfTokenName => $newTokenHash
|
||||||
|
];
|
||||||
|
return $this->respond($data);
|
||||||
|
} else {
|
||||||
|
return $this->failUnauthorized('Invalid request', 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addLinea($albaran_id)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($this->request->isAJAX()) {
|
||||||
|
|
||||||
|
$model_linea = model('App\Models\Albaranes\AlbaranLineaModel');
|
||||||
|
$newTokenHash = csrf_hash();
|
||||||
|
$csrfTokenName = csrf_token();
|
||||||
|
|
||||||
|
// si es un post, es el iva
|
||||||
|
if ($this->request->getPost()) {
|
||||||
|
$reqData = $this->request->getPost();
|
||||||
|
$albaran_id = $reqData['albaran_id'] ?? 0;
|
||||||
|
|
||||||
|
$albaran = $this->model->find($albaran_id);
|
||||||
|
if ($albaran == false) {
|
||||||
|
$data = [
|
||||||
|
'error' => 'Albaran no encontrado',
|
||||||
|
$csrfTokenName => $newTokenHash
|
||||||
|
];
|
||||||
|
return $this->respond($data);
|
||||||
|
}
|
||||||
|
$presupuesto_model = model('App\Models\Presupuestos\PresupuestoModel');
|
||||||
|
$presupuesto = $presupuesto_model->find($albaran->presupuesto_id);
|
||||||
|
if ($presupuesto == false) {
|
||||||
|
$data = [
|
||||||
|
'error' => 'Presupuesto no encontrado',
|
||||||
|
$csrfTokenName => $newTokenHash
|
||||||
|
];
|
||||||
|
return $this->respond($data);
|
||||||
|
}
|
||||||
|
$iva_reducido = $presupuesto->iva_reducido;
|
||||||
|
$lineas = $model_linea->where('albaran_id', $albaran_id)->findAll();
|
||||||
|
$total = 0;
|
||||||
|
foreach ($lineas as $linea) {
|
||||||
|
$total += $linea->total;
|
||||||
|
}
|
||||||
|
$iva = $iva_reducido ? $total * 4.0 / 100 : $total * 21.0 / 100;
|
||||||
|
$data_linea = [
|
||||||
|
'albaran_id' => $albaran_id,
|
||||||
|
'titulo' => $iva_reducido ? lang('Pedidos.iva4') : lang('Pedidos.iva21'),
|
||||||
|
'cantidad' => 1,
|
||||||
|
'precio_unidad' => round($iva, 2),
|
||||||
|
'total' => round($iva, 2),
|
||||||
|
'user_created_id' => auth()->user()->id,
|
||||||
|
'user_updated_id' => auth()->user()->id
|
||||||
|
];
|
||||||
|
$id_linea = $model_linea->insert($data_linea);
|
||||||
|
$linea = $model_linea->find($id_linea);
|
||||||
|
$data = [
|
||||||
|
'error' => 0,
|
||||||
|
'data' => $linea,
|
||||||
|
$csrfTokenName => $newTokenHash
|
||||||
|
];
|
||||||
|
return $this->respond($data);
|
||||||
|
} else {
|
||||||
|
$linea = [
|
||||||
|
'albaran_id' => $albaran_id,
|
||||||
|
'user_created_id' => auth()->user()->id,
|
||||||
|
'user_updated_id' => auth()->user()->id
|
||||||
|
];
|
||||||
|
$id_linea = $model_linea->insert($linea);
|
||||||
|
$data = $model_linea->find($id_linea);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'error' => 0,
|
||||||
|
'data' => $data,
|
||||||
|
$csrfTokenName => $newTokenHash
|
||||||
|
];
|
||||||
|
return $this->respond($data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return $this->failUnauthorized('Invalid request', 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
if ($this->request->isAJAX()) {
|
||||||
|
|
||||||
|
$user = auth()->user()->id;
|
||||||
|
|
||||||
|
$newTokenHash = csrf_hash();
|
||||||
|
$csrfTokenName = csrf_token();
|
||||||
|
|
||||||
|
$reqData = $this->request->getPost();
|
||||||
|
$pedido_id = $reqData['pedido_id'] ?? 0;
|
||||||
|
$presupuestos_id = $reqData['presupuestos_id'] ?? 0;
|
||||||
|
|
||||||
|
$return_data = $this->model->generarAlbaranes($pedido_id, $presupuestos_id, $user);
|
||||||
|
$data = [
|
||||||
|
'data' => $return_data,
|
||||||
|
$csrfTokenName => $newTokenHash
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->respond($data);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return $this->failUnauthorized('Invalid request', 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateAlbaran()
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($this->request->isAJAX()) {
|
||||||
|
|
||||||
|
$fieldName = $this->request->getPost('fieldName');
|
||||||
|
$fieldValue = $this->request->getPost('fieldValue');
|
||||||
|
$id = $this->request->getPost('albaranId');
|
||||||
|
|
||||||
|
if ($id == null) {
|
||||||
|
$data = [
|
||||||
|
'success' => false,
|
||||||
|
'message' => lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Pedidos.albaran')), $id]),
|
||||||
|
];
|
||||||
|
return $this->respond($data);
|
||||||
|
}
|
||||||
|
$albaranEntity = $this->model->find($id);
|
||||||
|
|
||||||
|
if ($albaranEntity == false) {
|
||||||
|
$data = [
|
||||||
|
'success' => false,
|
||||||
|
'message' => lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Pedidos.albaran')), $id]),
|
||||||
|
];
|
||||||
|
return $this->respond($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
$albaranEntity->fill([
|
||||||
|
$fieldName => $fieldValue,
|
||||||
|
'user_updated_id' => auth()->user()->id,
|
||||||
|
]);
|
||||||
|
$successfulResult = $this->model->skipValidation(true)->update($id, $albaranEntity);
|
||||||
|
if ($successfulResult) {
|
||||||
|
$data = [
|
||||||
|
'success' => true,
|
||||||
|
'message' => lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.',
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$data = [
|
||||||
|
'success' => false,
|
||||||
|
'message' => lang('Basic.global.updateError', [lang('Basic.global.record')]) . '.',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->respond($data);
|
||||||
|
} else {
|
||||||
|
return $this->failUnauthorized('Invalid request', 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function updateLinea($id = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($this->request->isAJAX()) {
|
||||||
|
|
||||||
|
$model_linea = model('App\Models\Albaranes\AlbaranLineaModel');
|
||||||
|
$newTokenHash = csrf_hash();
|
||||||
|
$csrfTokenName = csrf_token();
|
||||||
|
|
||||||
|
if ($id == null):
|
||||||
|
$data = [
|
||||||
|
'error' => 2,
|
||||||
|
$csrfTokenName => $newTokenHash
|
||||||
|
];
|
||||||
|
return $this->respond($data);
|
||||||
|
endif;
|
||||||
|
$id = filter_var($id, FILTER_SANITIZE_URL);
|
||||||
|
$albaranEntity = $model_linea->find($id);
|
||||||
|
|
||||||
|
if ($albaranEntity == false):
|
||||||
|
$message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Pedidos.albaran')), $id]);
|
||||||
|
$data = [
|
||||||
|
'error' => $message,
|
||||||
|
$csrfTokenName => $newTokenHash
|
||||||
|
];
|
||||||
|
return $this->respond($data);
|
||||||
|
endif;
|
||||||
|
|
||||||
|
if ($this->request->getPost()):
|
||||||
|
|
||||||
|
$nullIfEmpty = true; // !(phpversion() >= '8.1');
|
||||||
|
|
||||||
|
$postData = $this->request->getPost();
|
||||||
|
|
||||||
|
$sanitizedData = $this->sanitized($postData, $nullIfEmpty);
|
||||||
|
|
||||||
|
// JJO
|
||||||
|
$sanitizedData['user_updated_id'] = auth()->user()->id;
|
||||||
|
|
||||||
|
$noException = true;
|
||||||
|
if ($successfulResult = $this->canValidate()): // if ($successfulResult = $this->validate($this->formValidationRules) ) :
|
||||||
|
|
||||||
|
if ($this->canValidate()):
|
||||||
|
try {
|
||||||
|
$successfulResult = $model_linea->skipValidation(true)->update($id, $sanitizedData);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$noException = false;
|
||||||
|
$this->dealWithException($e);
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
$this->viewData['warningMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('Pedidos.albaran'))]);
|
||||||
|
$this->session->setFlashdata('formErrors', $model_linea->errors());
|
||||||
|
|
||||||
|
endif;
|
||||||
|
|
||||||
|
$albaranEntity->fill($sanitizedData);
|
||||||
|
|
||||||
|
endif;
|
||||||
|
if ($noException && $successfulResult):
|
||||||
|
$id = $albaranEntity->id ?? $id;
|
||||||
|
$message = lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.';
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'error' => 0,
|
||||||
|
$csrfTokenName => $newTokenHash
|
||||||
|
];
|
||||||
|
return $this->respond($data);
|
||||||
|
|
||||||
|
endif; // $noException && $successfulResult
|
||||||
|
endif; // ($requestMethod === 'post')
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'error' => 1,
|
||||||
|
$csrfTokenName => $newTokenHash
|
||||||
|
];
|
||||||
|
return $this->respond($data);
|
||||||
|
} else {
|
||||||
|
return $this->failUnauthorized('Invalid request', 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getAlbaranes()
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($this->request->isAJAX()) {
|
||||||
|
|
||||||
|
$envio_id = $this->request->getGet('envio_id');
|
||||||
|
$albaranes = $this->model->getAlbaranesEnvio($envio_id);
|
||||||
|
$data = [
|
||||||
|
'status' => true,
|
||||||
|
'data' => $albaranes,
|
||||||
|
];
|
||||||
|
return $this->respond($data);
|
||||||
|
} else {
|
||||||
|
return $this->failUnauthorized('Invalid request', 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateAlbaran()
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($this->request->isAJAX()) {
|
||||||
|
|
||||||
|
$reqData = $this->request->getPost();
|
||||||
|
$envio_id = $reqData['envio_id'] ?? 0;
|
||||||
|
$envio_lineas = $reqData['envio_lineas'] ?? [];
|
||||||
|
$cajas = $reqData['cajas'] ?? 0;
|
||||||
|
|
||||||
|
$response = $this->model->generarAlbaranes($envio_id, $envio_lineas, $cajas);
|
||||||
|
|
||||||
|
return $this->respond($response);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return $this->failUnauthorized('Invalid request', 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function datatablesLineasAlbaran()
|
||||||
|
{
|
||||||
|
|
||||||
|
$albaranId = $this->request->getGet('albaranId');
|
||||||
|
$model = model('App\Models\Albaranes\AlbaranLineaModel');
|
||||||
|
$q = $model->getDatatableQuery($albaranId);
|
||||||
|
|
||||||
|
$result = DataTable::of($q)
|
||||||
|
->add(
|
||||||
|
"action",
|
||||||
|
callback: function ($q) {
|
||||||
|
return '
|
||||||
|
<div class="btn-group btn-group-sm">
|
||||||
|
<a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete-albaran-lineas mx-2" data-id="' . $q->id . '"></i></a>
|
||||||
|
</div>
|
||||||
|
';
|
||||||
|
}
|
||||||
|
)
|
||||||
|
->edit('pedido', function ($q) {
|
||||||
|
return '<a href="' . base_url('pedidos/edit/' . $q->pedido) . '" target="_blank">' . $q->pedido . '</a>';
|
||||||
|
})
|
||||||
|
->edit('unidades', function ($q) {
|
||||||
|
return '<input type="number" class="form-control form-control-sm text-center" value="' . $q->unidades . '" data-id="' . $q->id . '" data-field="cantidad" />';
|
||||||
|
})
|
||||||
|
->edit('titulo', function ($q) {
|
||||||
|
return '<input type="text" class="form-control form-control-sm" value="' . $q->titulo . '" data-id="' . $q->id . '" data-field="titulo" />';
|
||||||
|
})
|
||||||
|
->edit('total', function ($q) {
|
||||||
|
return '<input class="form-control autonumeric-2 form-control-sm text-center" value="' . $q->total . '" data-id="' . $q->id . '" data-field="total" />';
|
||||||
|
})
|
||||||
|
->edit('precio_unidad', function ($q) {
|
||||||
|
return '<input class="form-control autonumeric-4 form-control-sm text-center" value="' .
|
||||||
|
number_format((float) $q->precio_unidad, 4, ',', '') .
|
||||||
|
'" data-id="' . $q->id . '" data-field="precio_unidad" />';
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return $result->toJson(returnAsObject: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function borrarLinea()
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($this->request->isAJAX()) {
|
||||||
|
|
||||||
|
$model_linea = model('App\Models\Albaranes\AlbaranLineaModel');
|
||||||
|
|
||||||
|
$reqData = $this->request->getPost();
|
||||||
|
$id = $reqData['linea'] ?? 0;
|
||||||
|
$id = filter_var($id, FILTER_SANITIZE_URL);
|
||||||
|
$albaranLineaEntity = $model_linea->find($id);
|
||||||
|
|
||||||
|
if ($albaranLineaEntity == false):
|
||||||
|
$message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Pedidos.albaran')), $id]);
|
||||||
|
$data = [
|
||||||
|
'success' => false,
|
||||||
|
'error' => $message,
|
||||||
|
];
|
||||||
|
return $this->respond($data);
|
||||||
|
endif;
|
||||||
|
|
||||||
|
$successfulResult = $model_linea->skipValidation(true)->update($id, ['deleted_at' => date('Y-m-d H:i:s')]);
|
||||||
|
|
||||||
|
if ($successfulResult):
|
||||||
|
$data = [
|
||||||
|
'success' => true,
|
||||||
|
];
|
||||||
|
else:
|
||||||
|
$data = [
|
||||||
|
'success' => false,
|
||||||
|
'error' => lang('Basic.global.deleteError', [lang('Basic.global.record')]) . '.',
|
||||||
|
];
|
||||||
|
endif;
|
||||||
|
return $this->respond($data);
|
||||||
|
} else {
|
||||||
|
return $this->failUnauthorized('Invalid request', 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function borrarAlbaran()
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($this->request->isAJAX()) {
|
||||||
|
|
||||||
|
$id = $this->request->getPost('albaranId');
|
||||||
|
$model_linea = model('App\Models\Albaranes\AlbaranLineaModel');
|
||||||
|
$model_linea->where('albaran_id', $id)->delete();
|
||||||
|
|
||||||
|
$this->model->where('id', $id)->delete();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'success' => true
|
||||||
|
];
|
||||||
|
return $this->respond($data);
|
||||||
|
} else {
|
||||||
|
return $this->failUnauthorized('Invalid request', 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -163,7 +163,6 @@ class LogisticaController extends BaseController
|
|||||||
if (empty($envioEntity)) {
|
if (empty($envioEntity)) {
|
||||||
return redirect()->to(base_url('logistica/selectEnvios/simple'))->with('error', lang('Logistica.errors.noEnvio'));
|
return redirect()->to(base_url('logistica/selectEnvios/simple'))->with('error', lang('Logistica.errors.noEnvio'));
|
||||||
}
|
}
|
||||||
$envioEntity->nextCaja = model('App\Models\Logistica\EnvioLineaModel')->getMaxCaja();
|
|
||||||
|
|
||||||
$viewData = [
|
$viewData = [
|
||||||
'currentModule' => static::$controllerSlug,
|
'currentModule' => static::$controllerSlug,
|
||||||
@ -177,6 +176,23 @@ class LogisticaController extends BaseController
|
|||||||
return view(static::$viewPath . 'viewEnvioEditForm', $viewData);
|
return view(static::$viewPath . 'viewEnvioEditForm', $viewData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateCajasEnvio()
|
||||||
|
{
|
||||||
|
if ($this->request->isAJAX()) {
|
||||||
|
$id = $this->request->getPost('id');
|
||||||
|
$cajas = $this->request->getPost('cajas');
|
||||||
|
$model = model('App\Models\Logistica\EnvioModel');
|
||||||
|
$result = $model->update($id, [
|
||||||
|
'cajas' => $cajas,
|
||||||
|
]);
|
||||||
|
return $this->response->setJSON([
|
||||||
|
"status" => $result,
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
return $this->failUnauthorized('Invalid request', 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function datatable_enviosEdit($idEnvio)
|
public function datatable_enviosEdit($idEnvio)
|
||||||
{
|
{
|
||||||
$model = model('App\Models\Logistica\EnvioLineaModel');
|
$model = model('App\Models\Logistica\EnvioLineaModel');
|
||||||
|
|||||||
@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Migrations;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Migration;
|
||||||
|
|
||||||
|
class ModifyAlbaranesAndAlbaranesLineas extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
// --- Tabla albaranes ---
|
||||||
|
$this->forge->dropColumn('albaranes', [
|
||||||
|
'pedido_id',
|
||||||
|
'presupuesto_id',
|
||||||
|
'presupuesto_direccion_id',
|
||||||
|
'total'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->forge->addColumn('albaranes', [
|
||||||
|
'fecha_albaran' => [
|
||||||
|
'type' => 'DATE',
|
||||||
|
'null' => true,
|
||||||
|
'after' => 'numero_albaran'
|
||||||
|
],
|
||||||
|
'envio_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 10,
|
||||||
|
'unsigned' => true,
|
||||||
|
'null' => true,
|
||||||
|
'after' => 'fecha_albaran'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Añadir foreign key a envios con ON DELETE SET NULL
|
||||||
|
$this->db->query('ALTER TABLE `albaranes`
|
||||||
|
ADD CONSTRAINT `fk_albaranes_envio_id` FOREIGN KEY (`envio_id`)
|
||||||
|
REFERENCES `envios`(`id`) ON DELETE SET NULL ON UPDATE CASCADE');
|
||||||
|
|
||||||
|
// --- Tabla albaranes_lineas ---
|
||||||
|
$this->forge->dropColumn('albaranes_lineas', ['cajas', 'ejemplares_por_caja']);
|
||||||
|
|
||||||
|
$this->forge->addColumn('albaranes_lineas', [
|
||||||
|
'iva_reducido' => [
|
||||||
|
'type' => 'TINYINT',
|
||||||
|
'constraint' => 1,
|
||||||
|
'default' => 0,
|
||||||
|
'null' => false,
|
||||||
|
'after' => 'precio_unidad'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
// Deshacer cambios tabla albaranes
|
||||||
|
$this->forge->dropForeignKey('albaranes', 'fk_albaranes_envio_id');
|
||||||
|
$this->forge->dropColumn('albaranes', ['envio_id', 'fecha_albaran']);
|
||||||
|
|
||||||
|
$this->forge->addColumn('albaranes', [
|
||||||
|
'pedido_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 10,
|
||||||
|
'unsigned' => true,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'presupuesto_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 10,
|
||||||
|
'unsigned' => true,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'presupuesto_direccion_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 10,
|
||||||
|
'unsigned' => true,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'total' => [
|
||||||
|
'type' => 'DOUBLE',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Deshacer cambios tabla albaranes_lineas
|
||||||
|
$this->forge->dropColumn('albaranes_lineas', ['iva_reducido']);
|
||||||
|
|
||||||
|
$this->forge->addColumn('albaranes_lineas', [
|
||||||
|
'cajas' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'ejemplares_por_caja' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Migrations;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Migration;
|
||||||
|
|
||||||
|
class AddClienteIdToEnvios extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$this->forge->addColumn('envios', [
|
||||||
|
'cliente_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 11,
|
||||||
|
'unsigned' => true, // IMPORTANTE
|
||||||
|
'null' => true,
|
||||||
|
'after' => 'id',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->db->query('ALTER TABLE envios ADD CONSTRAINT fk_envios_cliente FOREIGN KEY (cliente_id) REFERENCES clientes(id) ON DELETE SET NULL ON UPDATE CASCADE');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->db->query('ALTER TABLE envios DROP FOREIGN KEY fk_envios_cliente');
|
||||||
|
$this->forge->dropColumn('envios', 'cliente_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Migrations;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Migration;
|
||||||
|
|
||||||
|
class RenameCajasNullable extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$this->forge->modifyColumn('envios_lineas', [
|
||||||
|
'cajas' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 11,
|
||||||
|
'null' => true,
|
||||||
|
'default' => null,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->forge->modifyColumn('envios_lineas', [
|
||||||
|
'cajas' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 11,
|
||||||
|
'null' => false,
|
||||||
|
'default' => 0,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Migrations;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Migration;
|
||||||
|
|
||||||
|
class UpdateEnviosAlbaranes extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
// 1. Quitar columnas de envios_lineas
|
||||||
|
$this->forge->dropColumn('envios_lineas', ['cajas', 'unidades_cajas']);
|
||||||
|
|
||||||
|
// 2. Añadir columna 'cajas' en envios
|
||||||
|
$this->forge->addColumn('envios', [
|
||||||
|
'cajas' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 11,
|
||||||
|
'default' => 0,
|
||||||
|
'after' => 'comentarios'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 2. Quitar columna multienvio de envios
|
||||||
|
$this->forge->dropColumn('envios', 'multienvio');
|
||||||
|
|
||||||
|
// 3. Añadir columna 'cajas' en albaranes
|
||||||
|
$this->forge->addColumn('albaranes', [
|
||||||
|
'cajas' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 11,
|
||||||
|
'default' => 0,
|
||||||
|
'after' => 'envio_id'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 4. Añadir columna 'pedido_linea_id' a albaranes_lineas
|
||||||
|
$this->forge->addColumn('albaranes_lineas', [
|
||||||
|
'pedido_linea_id' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 11,
|
||||||
|
'unsigned' => true,
|
||||||
|
'null' => true,
|
||||||
|
'after' => 'albaran_id'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 5. Foreign key a pedidos_lineas
|
||||||
|
$this->db->query("
|
||||||
|
ALTER TABLE albaranes_lineas
|
||||||
|
ADD CONSTRAINT fk_albaranes_lineas_pedido_linea
|
||||||
|
FOREIGN KEY (pedido_linea_id) REFERENCES pedidos_linea(id)
|
||||||
|
ON DELETE SET NULL ON UPDATE CASCADE
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
// Revertir cajas en envios_lineas
|
||||||
|
$this->forge->addColumn('envios_lineas', [
|
||||||
|
'cajas' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 11,
|
||||||
|
'null' => true,
|
||||||
|
],
|
||||||
|
'unidades_cajas' => [
|
||||||
|
'type' => 'INT',
|
||||||
|
'constraint' => 11,
|
||||||
|
'null' => true,
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->forge->addColumn('envios', [
|
||||||
|
'multienvio' => [
|
||||||
|
'type' => 'TINYINT',
|
||||||
|
'constraint' => 3,
|
||||||
|
'unsigned' => true,
|
||||||
|
'default' => 0
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Quitar columnas añadidas
|
||||||
|
$this->forge->dropColumn('envios', 'cajas');
|
||||||
|
$this->forge->dropColumn('albaranes', 'cajas');
|
||||||
|
|
||||||
|
// Quitar foreign y columna pedido_linea_id
|
||||||
|
$this->db->query("ALTER TABLE albaranes_lineas DROP FOREIGN KEY fk_albaranes_lineas_pedido_linea");
|
||||||
|
$this->forge->dropColumn('albaranes_lineas', 'pedido_linea_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Migrations;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Migration;
|
||||||
|
|
||||||
|
class FixDeletedAtToDatetime extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
// Cambia los tipos de deleted_at a DATETIME NULL si existen
|
||||||
|
$tablas = ['albaranes', 'albaranes_lineas', 'envios', 'envios_lineas'];
|
||||||
|
|
||||||
|
foreach ($tablas as $tabla) {
|
||||||
|
$this->db->query("ALTER TABLE {$tabla} MODIFY COLUMN deleted_at DATETIME NULL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
// Opcional: puedes restaurar como TIMESTAMP NULL si lo deseas
|
||||||
|
$tablas = ['albaranes', 'albaranes_lineas', 'envios', 'envios_lineas'];
|
||||||
|
|
||||||
|
foreach ($tablas as $tabla) {
|
||||||
|
$this->db->query("ALTER TABLE {$tabla} MODIFY COLUMN deleted_at TIMESTAMP NULL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
44
ci4/app/Entities/Albaranes/AlbaranEntity.php
Normal file
44
ci4/app/Entities/Albaranes/AlbaranEntity.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Entities\Albaranes;
|
||||||
|
|
||||||
|
use CodeIgniter\Entity;
|
||||||
|
|
||||||
|
class AlbaranEntity extends \CodeIgniter\Entity\Entity
|
||||||
|
{
|
||||||
|
protected $attributes = [
|
||||||
|
'id' => null,
|
||||||
|
'envio_id' => null,
|
||||||
|
'cliente_id' => null,
|
||||||
|
'serie_id' => null,
|
||||||
|
'numero_albaran' => null,
|
||||||
|
'mostrar_precios' => null,
|
||||||
|
'direccion_albaran' => null,
|
||||||
|
'att_albaran' => null,
|
||||||
|
'user_created_id' => null,
|
||||||
|
'user_updated_id' => null,
|
||||||
|
'created_at' => null,
|
||||||
|
'updated_at' => null,
|
||||||
|
'deleted_at' => null,
|
||||||
|
'cajas' => null,
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'id' => 'integer',
|
||||||
|
'envio_id' => '?integer',
|
||||||
|
'presupuesto_id' => '?integer',
|
||||||
|
'presupuesto_direccion_id' => '?integer',
|
||||||
|
'cliente_id' => '?integer',
|
||||||
|
'serie_id' => '?integer',
|
||||||
|
'numero_albaran' => '?string',
|
||||||
|
'mostrar_precios' => '?boolean',
|
||||||
|
'total' => 'float',
|
||||||
|
'direccion_albaran' => '?string',
|
||||||
|
'att_albaran' => '?string',
|
||||||
|
'user_created_id' => 'integer',
|
||||||
|
'user_updated_id' => 'integer',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Agrega tus métodos personalizados aquí
|
||||||
|
}
|
||||||
40
ci4/app/Entities/Albaranes/AlbaranLineaEntity.php
Normal file
40
ci4/app/Entities/Albaranes/AlbaranLineaEntity.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Entities\Albaranes;
|
||||||
|
|
||||||
|
use CodeIgniter\Entity;
|
||||||
|
|
||||||
|
class AlbaranLineaEntity extends \CodeIgniter\Entity\Entity
|
||||||
|
{
|
||||||
|
protected $attributes = [
|
||||||
|
'id' => null,
|
||||||
|
'albaran_id' => null,
|
||||||
|
'pedido_linea_id' => null,
|
||||||
|
'titulo' => null,
|
||||||
|
'isbn' => null,
|
||||||
|
'ref_cliente' => null,
|
||||||
|
'cantidad' => null,
|
||||||
|
'precio_unidad' => null,
|
||||||
|
'total' => null,
|
||||||
|
'iva_reducido' => null,
|
||||||
|
'user_created_id' => null,
|
||||||
|
'user_updated_id' => null,
|
||||||
|
'created_at' => null,
|
||||||
|
'updated_at' => null,
|
||||||
|
'deleted_at' => null,
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'id' => 'integer',
|
||||||
|
'albaran_id' => '?integer',
|
||||||
|
'pedido_linea_id' => '?integer',
|
||||||
|
'titulo' => 'string',
|
||||||
|
'isbn' => '?string',
|
||||||
|
'ref_cliente' => '?string',
|
||||||
|
'cantidad' => '?integer',
|
||||||
|
'precio_unidad' => 'float',
|
||||||
|
'total' => 'float',
|
||||||
|
'iva_reducido' => '?boolean',
|
||||||
|
'user_created_id' => 'integer',
|
||||||
|
'user_updated_id' => 'integer',
|
||||||
|
];
|
||||||
|
}
|
||||||
@ -30,5 +30,6 @@ class EnvioEntity extends Entity
|
|||||||
'mostrar_iva' => 'boolean',
|
'mostrar_iva' => 'boolean',
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
|
'cajas' => 'int',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,8 +13,6 @@ class EnvioLineaEntity extends Entity
|
|||||||
'presupuesto_id' => 'int',
|
'presupuesto_id' => 'int',
|
||||||
'unidades_envio' => 'int',
|
'unidades_envio' => 'int',
|
||||||
'unidades_total' => 'int',
|
'unidades_total' => 'int',
|
||||||
'cajas' => 'int',
|
|
||||||
'unidades_cajas' => 'int',
|
|
||||||
'created_by' => 'int',
|
'created_by' => 'int',
|
||||||
'updated_by' => 'int',
|
'updated_by' => 'int',
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
|
|||||||
29
ci4/app/Language/es/Albaran.php
Normal file
29
ci4/app/Language/es/Albaran.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
return [
|
||||||
|
'fechaCreacion' => 'Fecha de creación',
|
||||||
|
"fechaAlbaran" => 'Fecha de albarán',
|
||||||
|
'numEnvio' => 'Número de envío',
|
||||||
|
'cliente' => 'Cliente',
|
||||||
|
'albaran' => 'Albarán',
|
||||||
|
'att' => 'Att',
|
||||||
|
'direccion' => 'Dirección',
|
||||||
|
'cajas' => 'Cajas',
|
||||||
|
|
||||||
|
'unidades' => 'Unidades',
|
||||||
|
'titulo' => 'Título',
|
||||||
|
'ISBN' => 'ISBN',
|
||||||
|
'refCliente' => 'Ref. cliente',
|
||||||
|
'precioU' => 'Precio/Unidad',
|
||||||
|
'subtotal' => 'Subtotal',
|
||||||
|
'pedido' => 'Pedido',
|
||||||
|
|
||||||
|
'mostrarPrecios' => 'Mostrar precios',
|
||||||
|
'addIva' => 'Añadir IVA',
|
||||||
|
'nuevaLinea' => 'Nueva línea',
|
||||||
|
'imprimirAlbaran' => 'Imprimir albarán',
|
||||||
|
'borrarAlbaran' => 'Borrar albarán',
|
||||||
|
'borrarAlbaranConfirm' => '¿Está seguro de que desea borrar el albarán?',
|
||||||
|
'borrar' => 'Borrar',
|
||||||
|
'cancelar' => 'Cancelar',
|
||||||
|
|
||||||
|
];
|
||||||
@ -39,6 +39,8 @@ return [
|
|||||||
'lineasEnvio' => 'Líneas del envío',
|
'lineasEnvio' => 'Líneas del envío',
|
||||||
'comentariosEnvio' => 'Comentarios del envío',
|
'comentariosEnvio' => 'Comentarios del envío',
|
||||||
'guardar' => 'Guardar',
|
'guardar' => 'Guardar',
|
||||||
|
'totales' => 'Totales',
|
||||||
|
'cajas' => 'Cajas',
|
||||||
|
|
||||||
'pedido' => 'Pedido',
|
'pedido' => 'Pedido',
|
||||||
'presupuesto' => 'Presupuesto',
|
'presupuesto' => 'Presupuesto',
|
||||||
@ -53,6 +55,8 @@ return [
|
|||||||
'addCaja' => 'Añadir caja',
|
'addCaja' => 'Añadir caja',
|
||||||
'numCaja' => 'Número de caja',
|
'numCaja' => 'Número de caja',
|
||||||
'selectAll' => 'Seleccionar todo',
|
'selectAll' => 'Seleccionar todo',
|
||||||
|
'peso' => 'Peso (kg): ',
|
||||||
|
'unidadesTotalesFooter' => 'Unidades:',
|
||||||
|
|
||||||
'errors' => [
|
'errors' => [
|
||||||
'noEnvio' => 'No se ha encontrado el envio',
|
'noEnvio' => 'No se ha encontrado el envio',
|
||||||
@ -60,4 +64,5 @@ return [
|
|||||||
'notFound' => 'No se encuentra el pedido o ISBN, el pedido aún no se ha finalizado o no tiene envíos pendientes',
|
'notFound' => 'No se encuentra el pedido o ISBN, el pedido aún no se ha finalizado o no tiene envíos pendientes',
|
||||||
'noAddresses' => 'El pedido no tiene direcciones de envío',
|
'noAddresses' => 'El pedido no tiene direcciones de envío',
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
85
ci4/app/Models/Albaranes/AlbaranLineaModel.php
Normal file
85
ci4/app/Models/Albaranes/AlbaranLineaModel.php
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models\Albaranes;
|
||||||
|
|
||||||
|
class AlbaranLineaModel extends \App\Models\BaseModel
|
||||||
|
{
|
||||||
|
protected $table = "albaranes_lineas";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether primary key uses auto increment.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $useAutoIncrement = true;
|
||||||
|
|
||||||
|
protected $primaryKey = 'id';
|
||||||
|
protected $returnType = 'App\Entities\Albaranes\AlbaranLineaEntity';
|
||||||
|
protected $allowedFields = [
|
||||||
|
'albaran_id',
|
||||||
|
'pedido_linea_id',
|
||||||
|
'titulo',
|
||||||
|
'isbn',
|
||||||
|
'ref_cliente',
|
||||||
|
'cantidad',
|
||||||
|
'precio_unidad',
|
||||||
|
'total',
|
||||||
|
'iva_reducido',
|
||||||
|
'user_created_id',
|
||||||
|
'user_updated_id',
|
||||||
|
'created_at',
|
||||||
|
'updated_at',
|
||||||
|
'deleted_at',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $useSoftDeletes = true;
|
||||||
|
protected $useTimestamps = true;
|
||||||
|
protected $createdField = 'created_at';
|
||||||
|
protected $updatedField = 'updated_at';
|
||||||
|
protected $deletedField = 'deleted_at';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get resource data for creating PDFs.
|
||||||
|
*
|
||||||
|
* @param string $search
|
||||||
|
*
|
||||||
|
* @return \CodeIgniter\Database\BaseBuilder
|
||||||
|
*/
|
||||||
|
public function getResourceForPdf($albaran_id = -1)
|
||||||
|
{
|
||||||
|
$builder = $this->db
|
||||||
|
|
||||||
|
->table($this->table . " t1")
|
||||||
|
->select(
|
||||||
|
"t1.id AS id, t1.albaran_id AS albaran_id, t1.titulo AS titulo, t1.isbn AS isbn,
|
||||||
|
t1.ref_cliente AS ref_cliente, t1.cantidad AS cantidad, t1.cajas AS cajas,
|
||||||
|
t1.ejemplares_por_caja AS ejemplares_por_caja, t1.precio_unidad AS precio_unidad,
|
||||||
|
t1.total AS total, pedidos.id AS pedido"
|
||||||
|
)
|
||||||
|
->join("pedidos_linea", "t1.pedido_linea_id = pedidos_linea.id", "left")
|
||||||
|
->join("pedidos", "pedidos_linea.pedido_id = pedidos.id", "left");
|
||||||
|
|
||||||
|
$builder->where("t1.deleted_at IS NULL");
|
||||||
|
$builder->where("t1.albaran_id", $albaran_id);
|
||||||
|
|
||||||
|
return $builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDatatableQuery($albaran_id = null){
|
||||||
|
$builder = $this->db
|
||||||
|
->table($this->table . " t1")
|
||||||
|
->select(
|
||||||
|
"t1.id, t1.titulo as titulo, t1.isbn as isbn, t1.ref_cliente as ref_cliente,
|
||||||
|
t1.cantidad as unidades, t1.precio_unidad as precio_unidad, t1.iva_reducido as iva_reducido,
|
||||||
|
t1.total as total, pedidos.id AS pedido"
|
||||||
|
)
|
||||||
|
->join("pedidos_linea", "t1.pedido_linea_id = pedidos_linea.id", "left")
|
||||||
|
->join("pedidos", "pedidos_linea.pedido_id = pedidos.id", "left");
|
||||||
|
|
||||||
|
$builder->where("t1.deleted_at IS NULL");
|
||||||
|
$builder->where("t1.albaran_id", $albaran_id);
|
||||||
|
|
||||||
|
return $builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
203
ci4/app/Models/Albaranes/AlbaranModel.php
Normal file
203
ci4/app/Models/Albaranes/AlbaranModel.php
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models\Albaranes;
|
||||||
|
|
||||||
|
class AlbaranModel extends \App\Models\BaseModel
|
||||||
|
{
|
||||||
|
protected $table = "albaranes";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether primary key uses auto increment.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $useAutoIncrement = true;
|
||||||
|
|
||||||
|
protected $primaryKey = 'id';
|
||||||
|
protected $returnType = 'App\Entities\Albaranes\AlbaranEntity';
|
||||||
|
protected $allowedFields = [
|
||||||
|
'envio_id',
|
||||||
|
'cliente_id',
|
||||||
|
'serie_id',
|
||||||
|
'numero_albaran',
|
||||||
|
'mostrar_precios',
|
||||||
|
'direccion_albaran',
|
||||||
|
'att_albaran',
|
||||||
|
'user_created_id',
|
||||||
|
'user_updated_id',
|
||||||
|
'created_at',
|
||||||
|
'updated_at',
|
||||||
|
'deleted_at',
|
||||||
|
'cajas',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $useSoftDeletes = true;
|
||||||
|
protected $useTimestamps = true;
|
||||||
|
protected $createdField = 'created_at';
|
||||||
|
protected $updatedField = 'updated_at';
|
||||||
|
protected $deletedField = 'deleted_at';
|
||||||
|
|
||||||
|
public function generarAlbaranes($envio_id, $envio_lineas, $cajas)
|
||||||
|
{
|
||||||
|
|
||||||
|
$user_id = auth()->user()->id;
|
||||||
|
|
||||||
|
if (!$envio_id || !$envio_lineas) {
|
||||||
|
return [
|
||||||
|
'status' => false
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// el albaran es para el mismo cliente, por lo que se obtiene el cliente_id de la primera_linea
|
||||||
|
$cliente_id = $this->db->table('envios_lineas')
|
||||||
|
->select('presupuestos.cliente_id')
|
||||||
|
->join('presupuestos', 'presupuestos.id = envios_lineas.presupuesto_id')
|
||||||
|
->where('envios_lineas.id', $envio_lineas[0])
|
||||||
|
->get()
|
||||||
|
->getRow()->cliente_id;
|
||||||
|
|
||||||
|
// se genera el numero de albaran
|
||||||
|
$model_series = model('App\Models\Configuracion\SeriesFacturasModel');
|
||||||
|
$serie = $model_series->find(11);
|
||||||
|
$numero_albaran = str_replace('{number}', $serie->next, $serie->formato);
|
||||||
|
$numero_albaran = str_replace('{year}', date("Y"), $numero_albaran);
|
||||||
|
$serie->next = $serie->next + 1;
|
||||||
|
$model_series->save($serie);
|
||||||
|
|
||||||
|
// Se genera el albaran con los datos del envio
|
||||||
|
$model_envio = model('App\Models\Logistica\EnvioModel');
|
||||||
|
$envio = $model_envio->find($envio_id);
|
||||||
|
$data = [
|
||||||
|
'envio_id' => $envio->id,
|
||||||
|
'cliente_id' => $cliente_id,
|
||||||
|
'serie_id' => 11, // Serie de albaranes
|
||||||
|
'numero_albaran' => $numero_albaran,
|
||||||
|
'mostrar_precios' => 0,
|
||||||
|
'direccion_albaran' => $envio->direccion,
|
||||||
|
'att_albaran' => $envio->att,
|
||||||
|
'user_created_id' => $user_id,
|
||||||
|
'cajas' => $cajas,
|
||||||
|
];
|
||||||
|
$id_albaran = $this->insert($data);
|
||||||
|
if(!$id_albaran) {
|
||||||
|
return [
|
||||||
|
'status' => false
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se generan las lineas del albaran
|
||||||
|
$model_albaran_linea = model('App\Models\Albaranes\AlbaranLineaModel');
|
||||||
|
$albaran_linea = [];
|
||||||
|
foreach ($envio_lineas as $linea) {
|
||||||
|
$modelLineaEnvio = model('App\Models\Logistica\EnvioLineaModel');
|
||||||
|
$datosLinea = $this->db->table('envios_lineas')
|
||||||
|
->select('presupuestos.titulo as titulo, presupuestos.isbn as isbn, presupuestos.referencia_cliente as ref_cliente,
|
||||||
|
envios_lineas.unidades_envio as cantidad, presupuestos.total_precio_unidad as precio_unidad, presupuestos.iva_reducido as iva_reducido,
|
||||||
|
ROUND(envios_lineas.unidades_envio * presupuestos.total_precio_unidad, 2) as total, pedidos_linea.id as pedido_linea_id')
|
||||||
|
->join('presupuestos', 'presupuestos.id = envios_lineas.presupuesto_id')
|
||||||
|
->join('pedidos', 'pedidos.id = envios_lineas.pedido_id')
|
||||||
|
->join('pedidos_linea', 'pedidos_linea.pedido_id = pedidos.id')
|
||||||
|
->where('envios_lineas.id', $linea)
|
||||||
|
->get()
|
||||||
|
->getRow();
|
||||||
|
$linea = $modelLineaEnvio->find($linea);
|
||||||
|
if (!$linea) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$albaran_linea = [
|
||||||
|
'albaran_id' => $id_albaran,
|
||||||
|
'titulo' => $datosLinea->titulo,
|
||||||
|
'isbn' => $datosLinea->isbn,
|
||||||
|
'ref_cliente' => $datosLinea->ref_cliente,
|
||||||
|
'cantidad' => $datosLinea->cantidad,
|
||||||
|
'precio_unidad' => $datosLinea->precio_unidad,
|
||||||
|
'iva_reducido' => $datosLinea->iva_reducido,
|
||||||
|
'total' => $datosLinea->total,
|
||||||
|
'user_created_id' => $user_id,
|
||||||
|
'user_updated_id' => $user_id,
|
||||||
|
'pedido_linea_id' => $datosLinea->pedido_linea_id,
|
||||||
|
|
||||||
|
];
|
||||||
|
$model_albaran_linea->insert($albaran_linea);
|
||||||
|
}
|
||||||
|
|
||||||
|
$albaran_data = $this->db->table('albaranes t1')
|
||||||
|
->select("
|
||||||
|
t1.id,
|
||||||
|
t1.att_albaran AS att,
|
||||||
|
t1.direccion_albaran AS direccion,
|
||||||
|
t1.envio_id,
|
||||||
|
t1.numero_albaran AS numero_albaran,
|
||||||
|
DATE_FORMAT(t1.created_at, '%d/%m/%Y') AS fecha_creacion,
|
||||||
|
DATE_FORMAT(t1.fecha_albaran, '%d/%m/%Y') AS fecha_albaran,
|
||||||
|
t1.mostrar_precios AS mostrar_precios,
|
||||||
|
t1.cajas AS cajas,
|
||||||
|
")
|
||||||
|
->where('t1.id', $id_albaran)
|
||||||
|
->get()
|
||||||
|
->getResultObject();
|
||||||
|
$modelCliente = model('App\Models\Clientes\ClienteModel');
|
||||||
|
$cliente = $modelCliente->find($cliente_id);
|
||||||
|
$albaran_data[0]->cliente = $cliente->nombre;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'status' => true,
|
||||||
|
'albaran' => $albaran_data[0],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAlbaranesEnvio($envio_id=null){
|
||||||
|
if (!$envio_id) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$albaran_data = $this->db->table('albaranes t1')
|
||||||
|
->select("
|
||||||
|
t1.id,
|
||||||
|
t1.att_albaran AS att,
|
||||||
|
t1.direccion_albaran AS direccion,
|
||||||
|
t1.envio_id,
|
||||||
|
t1.numero_albaran AS numero_albaran,
|
||||||
|
DATE_FORMAT(t1.created_at, '%d/%m/%Y') AS fecha_creacion,
|
||||||
|
DATE_FORMAT(t1.fecha_albaran, '%d/%m/%Y') AS fecha_albaran,
|
||||||
|
t1.mostrar_precios AS mostrar_precios,
|
||||||
|
t2.nombre AS cliente,
|
||||||
|
t1.cajas AS cajas
|
||||||
|
")
|
||||||
|
->join('clientes t2', 't1.cliente_id = t2.id', 'left')
|
||||||
|
->where('t1.envio_id', $envio_id)
|
||||||
|
->where('t1.deleted_at IS NULL')
|
||||||
|
->get()
|
||||||
|
->getResultObject();
|
||||||
|
return $albaran_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get resource data for creating PDFs.
|
||||||
|
*
|
||||||
|
* @param string $search
|
||||||
|
*
|
||||||
|
* @return \CodeIgniter\Database\BaseBuilder
|
||||||
|
*/
|
||||||
|
public function getResourceForPdf($albaran_id = -1)
|
||||||
|
{
|
||||||
|
$builder = $this->db
|
||||||
|
|
||||||
|
->table($this->table . " t1")
|
||||||
|
->select(
|
||||||
|
"t1.id AS id, t1.pedido_id AS pedido_id, t1.presupuesto_id AS presupuesto_id,
|
||||||
|
t1.presupuesto_direccion_id AS presupuesto_direccion_id, t1.cliente_id AS cliente_id,
|
||||||
|
t1.serie_id AS serie_id, t1.numero_albaran AS numero_albaran, t1.mostrar_precios AS mostrar_precios,
|
||||||
|
t1.total AS total, t1.direccion_albaran AS direccion_albaran, t1.att_albaran AS att_albaran,
|
||||||
|
t1.user_created_id AS user_created_id, t1.user_updated_id AS user_updated_id,
|
||||||
|
t1.created_at AS created_at, t1.updated_at AS updated_at,
|
||||||
|
t2.nombre AS cliente"
|
||||||
|
);
|
||||||
|
$builder->join("clientes t2", "t1.cliente_id = t2.id", "left");
|
||||||
|
|
||||||
|
$builder->where("t1.deleted_at IS NULL");
|
||||||
|
$builder->where("t1.id", $albaran_id);
|
||||||
|
|
||||||
|
return $builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -19,8 +19,6 @@ class EnvioLineaModel extends Model
|
|||||||
'pedido_id',
|
'pedido_id',
|
||||||
'unidades_envio',
|
'unidades_envio',
|
||||||
'unidades_total',
|
'unidades_total',
|
||||||
'cajas',
|
|
||||||
'unidades_cajas',
|
|
||||||
'created_at',
|
'created_at',
|
||||||
'updated_at',
|
'updated_at',
|
||||||
'created_by',
|
'created_by',
|
||||||
@ -37,7 +35,7 @@ class EnvioLineaModel extends Model
|
|||||||
$builder = $this->db
|
$builder = $this->db
|
||||||
->table($this->table . " t1")
|
->table($this->table . " t1")
|
||||||
->select(
|
->select(
|
||||||
"t1.id, t1.pedido_id as pedido, t3.id as presupuesto,t1.cajas, t1.cajas as cajasRaw,
|
"t1.id, t1.pedido_id as pedido, t3.id as presupuesto,
|
||||||
t3.titulo as titulo, t1.unidades_envio as unidadesEnvio, t1.unidades_envio as unidadesEnvioRaw,
|
t3.titulo as titulo, t1.unidades_envio as unidadesEnvio, t1.unidades_envio as unidadesEnvioRaw,
|
||||||
t1.unidades_total as unidadesTotal,
|
t1.unidades_total as unidadesTotal,
|
||||||
IFNULL((
|
IFNULL((
|
||||||
@ -62,17 +60,5 @@ class EnvioLineaModel extends Model
|
|||||||
return $builder;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,7 @@ class EnvioModel extends Model
|
|||||||
'mostrar_iva',
|
'mostrar_iva',
|
||||||
'created_at',
|
'created_at',
|
||||||
'updated_at',
|
'updated_at',
|
||||||
'multienvio',
|
'cajas',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $useTimestamps = true;
|
protected $useTimestamps = true;
|
||||||
|
|||||||
@ -190,14 +190,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</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>
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
|
|
||||||
@ -205,10 +197,6 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th></th>
|
|
||||||
<th class="text-center" style="width: 10%;">
|
|
||||||
<?= lang("Logistica.numCaja") ?>
|
|
||||||
</th>
|
|
||||||
<th><?= lang("Logistica.pedido") ?></th>
|
<th><?= lang("Logistica.pedido") ?></th>
|
||||||
<th><?= lang("Logistica.presupuesto") ?></th>
|
<th><?= lang("Logistica.presupuesto") ?></th>
|
||||||
<th><?= lang("Logistica.titulo") ?></th>
|
<th><?= lang("Logistica.titulo") ?></th>
|
||||||
@ -227,10 +215,35 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<th colspan="10">
|
||||||
|
<div class="text-end">
|
||||||
|
<?= lang("Logistica.unidadesTotalesFooter") ?>
|
||||||
|
<span id="footer-unidades-envio"></span>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th colspan="10">
|
||||||
|
<div class="text-end">
|
||||||
|
<?= lang("Logistica.peso") ?>
|
||||||
|
<span id="footer-peso"></span>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div class="col-sm-2 px-3">
|
||||||
|
<label for="cajas" class="form-label">
|
||||||
|
<?= lang("Logistica.cajas") ?>
|
||||||
|
</label>
|
||||||
|
<input type="number" id="cajas" name="cajas" tabindex="1" maxlength="50"
|
||||||
|
class="form-control" value="<?= old('cajas', $envioEntity->cajas) ?>">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
481
httpdocs/assets/js/safekat/components/albaranComponent.js
Normal file
481
httpdocs/assets/js/safekat/components/albaranComponent.js
Normal file
@ -0,0 +1,481 @@
|
|||||||
|
class AlbaranComponent {
|
||||||
|
|
||||||
|
constructor(item) {
|
||||||
|
this.item = item;
|
||||||
|
this.id = item.id;
|
||||||
|
this.numero = item.numero_albaran;
|
||||||
|
this.cliente = item.cliente;
|
||||||
|
this.att = item.att;
|
||||||
|
this.direccion = item.direccion;
|
||||||
|
this.envio_id = item.envio_id;
|
||||||
|
this.selectorTabla = `#tablaAlbaran${this.id}`;
|
||||||
|
|
||||||
|
this.table = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
mount(selector) {
|
||||||
|
const dom = this.render();
|
||||||
|
$(selector).append(dom);
|
||||||
|
requestAnimationFrame(() => this.init());
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { id, numero } = this;
|
||||||
|
|
||||||
|
const accordion = $('<div>', {
|
||||||
|
class: 'accordion accordion-bordered mt-3 accordion-albaran',
|
||||||
|
id: 'accordioAlbaran' + id,
|
||||||
|
albaran: id
|
||||||
|
});
|
||||||
|
|
||||||
|
const card = $('<div>', { class: 'card accordion-item active' });
|
||||||
|
|
||||||
|
const header = $('<h2>', {
|
||||||
|
class: 'accordion-header',
|
||||||
|
id: 'headingAlbaran' + id
|
||||||
|
});
|
||||||
|
|
||||||
|
const button = $('<button>', {
|
||||||
|
type: 'button',
|
||||||
|
class: 'accordion-button collapsed',
|
||||||
|
'data-bs-toggle': 'collapse',
|
||||||
|
'data-bs-target': '#accordionAlbaranTip' + id,
|
||||||
|
'aria-expanded': 'false',
|
||||||
|
'aria-controls': 'accordionAlbaranTip' + id,
|
||||||
|
'albaran': id,
|
||||||
|
}).css({ 'background-color': '#F0F8FF' }).append($('<h5>').html(numero));
|
||||||
|
|
||||||
|
const collapseDiv = $('<div>', {
|
||||||
|
id: 'accordionAlbaranTip' + id,
|
||||||
|
class: 'accordion-collapse collapse',
|
||||||
|
'data-bs-parent': '#accordioAlbaran' + id
|
||||||
|
});
|
||||||
|
|
||||||
|
const body = $('<div>', { class: 'accordion-body' });
|
||||||
|
|
||||||
|
// Cabecera HTML
|
||||||
|
const cabecera = this._buildCabecera();
|
||||||
|
const tableWrapper = $('<div>', {
|
||||||
|
class: 'table-responsive'
|
||||||
|
}).append(this._buildTable());
|
||||||
|
const botones = this._buildBotonera();
|
||||||
|
|
||||||
|
header.append(button);
|
||||||
|
card.append(header);
|
||||||
|
collapseDiv.append(body);
|
||||||
|
body.append(cabecera, tableWrapper, botones);
|
||||||
|
card.append(collapseDiv);
|
||||||
|
accordion.append(card);
|
||||||
|
|
||||||
|
return accordion;
|
||||||
|
}
|
||||||
|
|
||||||
|
_buildCabecera() {
|
||||||
|
|
||||||
|
return $(`
|
||||||
|
<div class="col-12 d-flex justify-content-between align-items-center my-3">
|
||||||
|
<!-- Fechas a la izquierda pegadas -->
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<div class="d-flex align-items-center me-3">
|
||||||
|
<label class="me-2 mb-0 white-space-nowrap">${window.language.Albaran.fechaCreacion}:</label>
|
||||||
|
<label class="mb-0">${this.item.fecha_creacion}</label>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-center ml-5">
|
||||||
|
<label class="me-2 mb-0 white-space-nowrap">${window.language.Albaran.fechaAlbaran}:</label>
|
||||||
|
<input id="fecha_albaran_${this.id}" class="cambios-albaran form-control form-control-sm"
|
||||||
|
style="max-width: 130px;" albaran_id=${this.id} value="${this.item.fecha_albaran == null ? '' : this.item.fecha_albaran}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Envío a la derecha -->
|
||||||
|
<div class="d-flex align-items-center ms-auto">
|
||||||
|
<label class="me-1 mb-0">${window.language.Albaran.numEnvio}:</label>
|
||||||
|
<label class="mb-0">${this.envio_id}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="col-12 d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<!-- Cliente a la izquierda -->
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<label class="me-2 mb-0">${window.language.Albaran.cliente}:</label>
|
||||||
|
<label class="mb-0 text-left">${this.cliente}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Nº Albarán a la derecha -->
|
||||||
|
<div class="d-flex align-items-center ms-auto">
|
||||||
|
<label class="me-2 mb-0">${window.language.Albaran.albaran}:</label>
|
||||||
|
<label class="mb-0 text-end">${this.item.numero_albaran}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12 d-flex justify-content-between mb-3">
|
||||||
|
<div class="col-1">
|
||||||
|
<label>${window.language.Albaran.att}:</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-11">
|
||||||
|
<input id="att_${this.item.id}" class="cambios-albaran form-control" data-albaranId=${this.item.id} value="${this.att}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 d-flex justify-content-between mb-3">
|
||||||
|
<div class="col-1">
|
||||||
|
<label>${window.language.Albaran.direccion}:</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-11">
|
||||||
|
<input id="direccion_${this.item.id}" class="cambios-albaran form-control" data-albaranId=${this.item.id} value="${this.direccion}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
_buildTable() {
|
||||||
|
return $('<table>', {
|
||||||
|
id: 'tablaAlbaran' + this.id,
|
||||||
|
width: '100%',
|
||||||
|
class: 'table table-responsive table-striped table-hover table-albaran'
|
||||||
|
}).append(
|
||||||
|
$('<thead>').append(
|
||||||
|
$('<tr>').append(
|
||||||
|
$('<th>').css({ 'max-width': '20px' }),
|
||||||
|
$('<th>'),
|
||||||
|
$('<th>', { class: 'lp-header', scope: 'col' }).css({ 'font-size': 'smaller', 'max-width':'8%' }).text(window.language.Albaran.pedido),
|
||||||
|
$('<th>', { class: 'lp-header', scope: 'col' }).css({ 'font-size': 'smaller', 'max-width':'8%' }).text(window.language.Albaran.unidades),
|
||||||
|
$('<th>', { class: 'lp-header', scope: 'col' }).css({ 'font-size': 'smaller' }).text(window.language.Albaran.titulo),
|
||||||
|
$('<th>', { class: 'lp-header', scope: 'col' }).css({ 'font-size': 'smaller', 'max-width':'15%' }).text(window.language.Albaran.ISBN),
|
||||||
|
$('<th>', { class: 'lp-header', scope: 'col' }).css({ 'font-size': 'smaller', 'max-width':'15%' }).text(window.language.Albaran.refCliente),
|
||||||
|
$('<th>', { class: 'lp-header', scope: 'col' }).css({ 'font-size': 'smaller', 'max-width':'8%' }).text(window.language.Albaran.precioU),
|
||||||
|
$('<th>', { class: 'lp-header', scope: 'col' }).css({ 'font-size': 'smaller', 'max-width':'8%' }).text(window.language.Albaran.subtotal),
|
||||||
|
$('<th>'),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
$('<tbody>')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_buildBotonera() {
|
||||||
|
const id = this.id;
|
||||||
|
const mostrarPreciosChecked = this.item.mostrar_precios == 1 ? 'checked' : '';
|
||||||
|
|
||||||
|
return $(`
|
||||||
|
<div class="row mt-5">
|
||||||
|
<div class="col-12 d-flex align-items-center">
|
||||||
|
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<label for="mostrar_precios_${id}" class="me-2 mb-0">${window.language.Albaran.mostrarPrecios}:</label>
|
||||||
|
<input type="checkbox" id="mostrar_precios_${id}" class="form-check-input mostrar-precios" albaran_id="${id}" ${mostrarPreciosChecked}>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-center mx-5">
|
||||||
|
<label for="cajas_albaran_${id}" class="me-2 mb-0">${window.language.Albaran.cajas}:</label>
|
||||||
|
<input type="number" id="cajas_albaran_${id}" class="form-control" albaran_id="${id}" value="${this.item.cajas}" min="0" max="200" step="1">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Botones alineados a la derecha -->
|
||||||
|
<div class="ms-auto d-flex gap-2 flex-wrap justify-content-end">
|
||||||
|
<button id="add_iva_albaran_${id}" class="add-iva-albaran btn btn-sm btn-light" type="button">
|
||||||
|
${window.language.Albaran.addIva} <i class="ti ti-plus"></i>
|
||||||
|
</button>
|
||||||
|
<button id="nueva_linea_albaran_${id}" class="nueva-linea-albaran btn btn-sm btn-light" type="button">
|
||||||
|
${window.language.Albaran.nuevaLinea} <i class="ti ti-plus"></i>
|
||||||
|
</button>
|
||||||
|
<button id="imprimir_albaran_${id}" class="imprimir-albaran btn btn-sm btn-light" type="button">
|
||||||
|
${window.language.Albaran.imprimirAlbaran} <i class="ti ti-printer"></i>
|
||||||
|
</button>
|
||||||
|
<button id="borrar_albaran_${id}" class="borrar-albaran btn btn-sm btn-danger" type="button">
|
||||||
|
${window.language.Albaran.borrarAlbaran} <i class="ti ti-trash"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
|
||||||
|
this.table = $('#tablaAlbaran' + this.id).DataTable({
|
||||||
|
processing: true,
|
||||||
|
serverSide: true,
|
||||||
|
autoWidth: true,
|
||||||
|
responsive: true,
|
||||||
|
scrollX: true,
|
||||||
|
order: [[1, 'asc']],
|
||||||
|
orderable: false,
|
||||||
|
lengthMenu: [5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500],
|
||||||
|
pageLength: 50,
|
||||||
|
dom: 'lrtip',
|
||||||
|
ajax: {
|
||||||
|
url: "/albaranes/datatablesAlbaranLinea?albaranId",
|
||||||
|
data: {
|
||||||
|
albaranId: this.id
|
||||||
|
},
|
||||||
|
type: 'GET',
|
||||||
|
},
|
||||||
|
language: {
|
||||||
|
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{ data: "action" },
|
||||||
|
{ data: "id", visible: false },
|
||||||
|
{ data: "pedido"},
|
||||||
|
{ data: "unidades" },
|
||||||
|
{ data: "titulo" },
|
||||||
|
{ data: "isbn" },
|
||||||
|
{ data: "ref_cliente" },
|
||||||
|
{ data: "precio_unidad" },
|
||||||
|
{ data: "total" },
|
||||||
|
{ data: "iva_reducido", visible: false },
|
||||||
|
],
|
||||||
|
columnDefs: [
|
||||||
|
{
|
||||||
|
orderable: false,
|
||||||
|
searchable: false,
|
||||||
|
targets: [0]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
drawCallback: (settings) => {
|
||||||
|
if ($('#mostrar_precios_' + this.id).is(':checked')) {
|
||||||
|
this.table
|
||||||
|
.column(7).visible(true)
|
||||||
|
.column(8).visible(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.table
|
||||||
|
.column(7).visible(false)
|
||||||
|
.column(8).visible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
this._initAutoNumericInputs();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#accordionAlbaranTip' + this.id).on('shown.bs.collapse', () => {
|
||||||
|
if (this.table) {
|
||||||
|
this.table.columns.adjust().draw(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#tablaAlbaran' + this.id).on('click', '.btn-delete-albaran-lineas', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const table = $('#tablaAlbaran' + this.id).DataTable();
|
||||||
|
const id = $(e.currentTarget).attr('data-id');
|
||||||
|
const url = `/albaranes/borrarAlbaranLinea`;
|
||||||
|
const data = { linea: id };
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: url,
|
||||||
|
type: 'POST',
|
||||||
|
data: data,
|
||||||
|
success: (response) => {
|
||||||
|
if (response.success) {
|
||||||
|
table.draw(false);
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Error',
|
||||||
|
text: 'No se ha podido borrar la línea del albarán',
|
||||||
|
icon: 'error',
|
||||||
|
showCancelButton: false,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
confirmButtonText: 'Ok',
|
||||||
|
customClass: {
|
||||||
|
confirmButton: 'btn btn-primary me-1',
|
||||||
|
},
|
||||||
|
buttonsStyling: false
|
||||||
|
});
|
||||||
|
table.draw(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: (xhr, status, error) => {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#mostrar_precios_' + this.id).on('change', (e) => {
|
||||||
|
const checked = $(e.currentTarget).is(':checked');
|
||||||
|
if (checked) {
|
||||||
|
this.table
|
||||||
|
.column(7).visible(true)
|
||||||
|
.column(8).visible(true);
|
||||||
|
} else {
|
||||||
|
this.table
|
||||||
|
.column(7).visible(false)
|
||||||
|
.column(8).visible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$.post('/albaranes/updateAlbaran', {
|
||||||
|
albaranId: this.id,
|
||||||
|
fieldName: 'mostrar_precios',
|
||||||
|
fieldValue: checked ? 1 : 0
|
||||||
|
}, (response) => {
|
||||||
|
if (response.success) {
|
||||||
|
this.table.ajax.reload(null, false);
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Error',
|
||||||
|
text: 'No se ha podido actualizar el albarán',
|
||||||
|
icon: 'error',
|
||||||
|
showCancelButton: false,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
confirmButtonText: 'Ok',
|
||||||
|
customClass: {
|
||||||
|
confirmButton: 'btn btn-primary me-1',
|
||||||
|
},
|
||||||
|
buttonsStyling: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#direccion_' + this.item.id).on('change', (e) => {
|
||||||
|
const value = $(e.currentTarget).val();
|
||||||
|
const albaranId = $(e.currentTarget).attr('data-albaranId');
|
||||||
|
|
||||||
|
$.post('/albaranes/updateAlbaran', {
|
||||||
|
albaranId: albaranId,
|
||||||
|
fieldName: 'direccion_albaran',
|
||||||
|
fieldValue: value
|
||||||
|
}, (response) => {
|
||||||
|
if (response.success) {
|
||||||
|
this.table.ajax.reload(null, false);
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Error',
|
||||||
|
text: 'No se ha podido actualizar el albarán',
|
||||||
|
icon: 'error',
|
||||||
|
showCancelButton: false,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
confirmButtonText: 'Ok',
|
||||||
|
customClass: {
|
||||||
|
confirmButton: 'btn btn-primary me-1',
|
||||||
|
},
|
||||||
|
buttonsStyling: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#att_' + this.item.id).on('change', (e) => {
|
||||||
|
const value = $(e.currentTarget).val();
|
||||||
|
const albaranId = $(e.currentTarget).attr('data-albaranId');
|
||||||
|
|
||||||
|
$.post('/albaranes/updateAlbaran', {
|
||||||
|
albaranId: albaranId,
|
||||||
|
fieldName: 'att_albaran',
|
||||||
|
fieldValue: value
|
||||||
|
}, (response) => {
|
||||||
|
if (response.success) {
|
||||||
|
this.table.ajax.reload(null, false);
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Error',
|
||||||
|
text: 'No se ha podido actualizar el albarán',
|
||||||
|
icon: 'error',
|
||||||
|
showCancelButton: false,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
confirmButtonText: 'Ok',
|
||||||
|
customClass: {
|
||||||
|
confirmButton: 'btn btn-primary me-1',
|
||||||
|
},
|
||||||
|
buttonsStyling: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$("#borrar_albaran_" + this.item.id).on('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const albaranId = this.id;
|
||||||
|
const url = `/albaranes/borrarAlbaran`;
|
||||||
|
const data = { albaranId: albaranId };
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
title: window.language.Albaran.borrarAlbaran,
|
||||||
|
text: window.language.Albaran.borrarAlbaranConfirm,
|
||||||
|
icon: 'warning',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
cancelButtonColor: '#d33',
|
||||||
|
confirmButtonText: window.language.Albaran.borrar,
|
||||||
|
cancelButtonText: window.language.Albaran.cancelar,
|
||||||
|
customClass: {
|
||||||
|
confirmButton: 'btn btn-primary me-1',
|
||||||
|
cancelButton: 'btn btn-outline-secondary'
|
||||||
|
},
|
||||||
|
buttonsStyling: false
|
||||||
|
}).then((result) => {
|
||||||
|
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: url,
|
||||||
|
type: 'POST',
|
||||||
|
data: data,
|
||||||
|
success: (response) => {
|
||||||
|
if (response.success) {
|
||||||
|
// quitar del dom el albarán
|
||||||
|
$(`#accordioAlbaran${albaranId}`).remove();
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Error',
|
||||||
|
text: 'No se ha podido borrar el albarán',
|
||||||
|
icon: 'error',
|
||||||
|
showCancelButton: false,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
confirmButtonText: 'Ok',
|
||||||
|
customClass: {
|
||||||
|
confirmButton: 'btn btn-primary me-1',
|
||||||
|
},
|
||||||
|
buttonsStyling: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: (xhr, status, error) => {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_initAutoNumericInputs() {
|
||||||
|
const config_2 = {
|
||||||
|
decimalPlaces: 2,
|
||||||
|
digitGroupSeparator: '.',
|
||||||
|
decimalCharacter: ',',
|
||||||
|
unformatOnSubmit: true,
|
||||||
|
decimalPlacesShownOnFocus: 2,
|
||||||
|
decimalPlacesShownOnBlur: 2,
|
||||||
|
watchExternalChanges: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const config_4 = {
|
||||||
|
decimalPlaces: 4,
|
||||||
|
digitGroupSeparator: '.',
|
||||||
|
decimalCharacter: ',',
|
||||||
|
unformatOnSubmit: true,
|
||||||
|
decimalPlacesShownOnFocus: 4,
|
||||||
|
decimalPlacesShownOnBlur: 4,
|
||||||
|
watchExternalChanges: true
|
||||||
|
};
|
||||||
|
|
||||||
|
// 🔥 Forzar limpieza completa de instancias anteriores
|
||||||
|
document.querySelectorAll('.autonumeric-2, .autonumeric-4').forEach(el => {
|
||||||
|
if (AutoNumeric.getAutoNumericElement(el)) {
|
||||||
|
AutoNumeric.getAutoNumericElement(el).remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Inicializar nuevos
|
||||||
|
AutoNumeric.multiple('.autonumeric-2', config_2);
|
||||||
|
AutoNumeric.multiple('.autonumeric-4', config_4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AlbaranComponent;
|
||||||
@ -4,13 +4,9 @@ import AlbaranComponent from '../../components/albaranComponent.js';
|
|||||||
|
|
||||||
class EnvioEdit {
|
class EnvioEdit {
|
||||||
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
||||||
this.tableCols = [
|
this.tableCols = [
|
||||||
{ data: "rowSelected" },
|
{ data: "rowSelected" },
|
||||||
{ data: "cajasRaw", defaultContent: "" },
|
|
||||||
{ data: "cajas", defaultContent: "" },
|
|
||||||
{ data: "pedido" },
|
{ data: "pedido" },
|
||||||
{ data: "presupuesto" },
|
{ data: "presupuesto" },
|
||||||
{ data: "titulo" },
|
{ data: "titulo" },
|
||||||
@ -26,17 +22,15 @@ class EnvioEdit {
|
|||||||
|
|
||||||
this.buscarPedidos = new ClassSelect($("#buscadorPedidos"), '/logistica/selectAddLinea', "", true, { 'envio': $("#id").val() });
|
this.buscarPedidos = new ClassSelect($("#buscadorPedidos"), '/logistica/selectAddLinea', "", true, { 'envio': $("#id").val() });
|
||||||
|
|
||||||
this.contadorCajas = parseInt($("#nextCaja").val()) || 1;
|
|
||||||
this.btnAddLinea = $("#btnAddLinea");
|
this.btnAddLinea = $("#btnAddLinea");
|
||||||
this.btnAddCaja = $("#btnAddCaja");
|
|
||||||
this.btnDeleteLinea = $("#btnEliminarLineas");
|
this.btnDeleteLinea = $("#btnEliminarLineas");
|
||||||
this.btnGuardarComentarios = $("#guardarComentarios");
|
this.btnGuardarComentarios = $("#guardarComentarios");
|
||||||
this.btnSelectAll = $("#btnSelectAll");
|
|
||||||
this.btnGenerarAlbaran = $("#btnGenerarAlbaran");
|
this.btnGenerarAlbaran = $("#btnGenerarAlbaran");
|
||||||
|
this.btnbtnSelectAll = $("#btnSelectAll");
|
||||||
|
this.cajas = $("#cajas");
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
|
||||||
this.table = $('#tableLineasEnvio').DataTable({
|
this.table = $('#tableLineasEnvio').DataTable({
|
||||||
processing: true,
|
processing: true,
|
||||||
serverSide: true,
|
serverSide: true,
|
||||||
@ -44,6 +38,8 @@ class EnvioEdit {
|
|||||||
responsive: true,
|
responsive: true,
|
||||||
scrollX: true,
|
scrollX: true,
|
||||||
orderCellsTop: true,
|
orderCellsTop: true,
|
||||||
|
orderable: false,
|
||||||
|
order: [[7, 'asc']],
|
||||||
lengthMenu: [5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500],
|
lengthMenu: [5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500],
|
||||||
pageLength: 50,
|
pageLength: 50,
|
||||||
"dom": 'lrtip',
|
"dom": 'lrtip',
|
||||||
@ -54,32 +50,20 @@ class EnvioEdit {
|
|||||||
"language": {
|
"language": {
|
||||||
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
|
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
|
||||||
},
|
},
|
||||||
rowGroup: {
|
footerCallback: function (row, data, start, end, display) {
|
||||||
dataSrc: 'cajasRaw',
|
let totalUnidades = 0;
|
||||||
startRender: function (rows, group) {
|
let totalPeso = 0;
|
||||||
// Forzar el grupo a string (DataTables puede pasarlo como undefined o null de forma interna)
|
|
||||||
const groupStr = group == null || group === 0 || group === '0' ? '__SIN__ASIGNAR__' : group.toString();
|
data.forEach(row => {
|
||||||
const nombreGrupo = groupStr === '__SIN__ASIGNAR__' ? 'SIN ASIGNAR' : groupStr;
|
const unidades = parseFloat(row.unidadesEnvioRaw) || 0;
|
||||||
|
const pesoUnidad = parseFloat(row.pesoUnidad) || 0;
|
||||||
let totalUnidades = 0;
|
totalUnidades += unidades;
|
||||||
let totalPeso = 0;
|
totalPeso += unidades * pesoUnidad;
|
||||||
rows.data().each(function (row) {
|
});
|
||||||
const unidades = parseInt(row.unidadesEnvioRaw) || 0;
|
|
||||||
totalUnidades += unidades;
|
// Mostrar en spans personalizados del <tfoot>
|
||||||
totalPeso += (parseFloat(row.pesoUnidad) || 0) * unidades;
|
$('#footer-unidades-envio').text(totalUnidades);
|
||||||
});
|
$('#footer-peso').text(totalPeso.toFixed(2));
|
||||||
|
|
||||||
return `
|
|
||||||
<label class="switch switch-square">
|
|
||||||
<input type="checkbox" class="switch-input switch-grupo" data-grupo="${groupStr}" id="switch-grupo-${groupStr}">
|
|
||||||
<span class="switch-toggle-slider"></span>
|
|
||||||
<span class="switch-label">
|
|
||||||
CAJA: ${nombreGrupo} [unidades: ${totalUnidades}, peso: <span class="peso-grupo" data-valor="${totalPeso}">${totalPeso.toFixed(1)}</span> kg]
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"columnDefs": [
|
"columnDefs": [
|
||||||
{
|
{
|
||||||
@ -89,105 +73,64 @@ class EnvioEdit {
|
|||||||
"searchable": false,
|
"searchable": false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"targets": [3, 4, 6, 7, 8],
|
"targets": [1, 2, 4, 5, 6],
|
||||||
"className": "text-center",
|
"className": "text-center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
targets: [1, 9, 10, 11],
|
targets: [7, 8, 9],
|
||||||
visible: false
|
visible: false
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"order": [[1, "asc"]],
|
|
||||||
"orderFixed": [[1, 'asc']],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#tableLineasEnvio').on('change', '.switch-grupo', function () {
|
this.cajas.on('change', (e) => {
|
||||||
const grupo = $(this).data('grupo');
|
const value = $(e.currentTarget).val();
|
||||||
const checked = $(this).is(':checked');
|
if (value < 0) {
|
||||||
|
Swal.fire({
|
||||||
const table = $('#tableLineasEnvio').DataTable();
|
title: 'Atención!',
|
||||||
|
text: 'El número de cajas no puede ser negativo.',
|
||||||
table.rows().every(function () {
|
icon: 'info',
|
||||||
const rowData = this.data();
|
confirmButtonColor: '#3085d6',
|
||||||
const node = $(this.node());
|
confirmButtonText: 'Ok',
|
||||||
|
customClass: {
|
||||||
const valorCaja = (rowData.cajasRaw === null || rowData.cajasRaw === '' ||
|
confirmButton: 'btn btn-primary me-1',
|
||||||
rowData.cajasRaw === 0 || rowData.cajasRaw === '0' || rowData.cajasRaw === undefined)
|
},
|
||||||
? '__SIN__ASIGNAR__'
|
buttonsStyling: false
|
||||||
: rowData.cajasRaw.toString();
|
});
|
||||||
|
$(e.currentTarget).val(0);
|
||||||
if (valorCaja == grupo) {
|
return;
|
||||||
node.find('.checkbox-linea-envio').prop('checked', checked);
|
}
|
||||||
}
|
$.post('/logistica/updateCajasEnvio', {
|
||||||
});
|
id: $('#id').val(),
|
||||||
});
|
cajas: value
|
||||||
|
}, function (response) {
|
||||||
$('#tableLineasEnvio').on('draw.dt', () => {
|
if (!response.status) {
|
||||||
const table = this.table;
|
Swal.fire({
|
||||||
|
title: 'Error',
|
||||||
this._aplicarDroppableEnGrupos(table);
|
text: response.message,
|
||||||
|
icon: 'error',
|
||||||
// Aplica draggable a filas si aún no lo tienen
|
confirmButtonColor: '#3085d6',
|
||||||
this.table.rows({ page: 'current' }).every(function () {
|
confirmButtonText: 'Ok',
|
||||||
const $row = $(this.node());
|
customClass: {
|
||||||
if (!$row.hasClass('draggable-applied')) {
|
confirmButton: 'btn btn-primary me-1',
|
||||||
$row.addClass('draggable-applied');
|
},
|
||||||
$row.draggable({
|
buttonsStyling: false
|
||||||
helper: 'clone',
|
|
||||||
revert: 'invalid',
|
|
||||||
start: () => $row.css('opacity', 0.5),
|
|
||||||
stop: () => $row.css('opacity', 1)
|
|
||||||
});
|
});
|
||||||
}
|
$(e.currentTarget).val(0);
|
||||||
});
|
}
|
||||||
|
}).fail(() => {
|
||||||
document.querySelectorAll('.peso-grupo').forEach(el => {
|
Swal.fire({
|
||||||
const valor = parseFloat(el.getAttribute('data-valor')) || 0;
|
title: 'Error',
|
||||||
|
text: 'No se pudo actualizar el número de cajas.',
|
||||||
new AutoNumeric(el, valor, {
|
icon: 'error',
|
||||||
decimalPlaces: 1,
|
confirmButtonColor: '#3085d6',
|
||||||
digitGroupSeparator: ',',
|
confirmButtonText: 'Ok',
|
||||||
decimalCharacter: '.',
|
customClass: {
|
||||||
minimumValue: '0',
|
confirmButton: 'btn btn-primary me-1',
|
||||||
suffixText: '',
|
},
|
||||||
modifyValueOnWheel: false
|
buttonsStyling: false
|
||||||
});
|
});
|
||||||
});
|
$(e.currentTarget).val(0);
|
||||||
|
|
||||||
$('#tableLineasEnvio').on('change', '.checkbox-linea-envio', function () {
|
|
||||||
const $row = $(this).closest('tr');
|
|
||||||
const table = $('#tableLineasEnvio').DataTable();
|
|
||||||
const rowData = table.row($row).data();
|
|
||||||
|
|
||||||
const valorCaja = (rowData.cajasRaw === null || rowData.cajasRaw === '' || rowData.cajasRaw === 0 || rowData.cajasRaw === '0')
|
|
||||||
? '__SIN__ASIGNAR__'
|
|
||||||
: rowData.cajasRaw;
|
|
||||||
|
|
||||||
// 1. Filtrar todas las filas del mismo grupo
|
|
||||||
let total = 0;
|
|
||||||
let seleccionadas = 0;
|
|
||||||
|
|
||||||
table.rows().every(function () {
|
|
||||||
const data = this.data();
|
|
||||||
const grupo = (data.cajasRaw === null || data.cajasRaw === '' || data.cajasRaw === 0 || data.cajasRaw === '0')
|
|
||||||
? 'SIN ASIGNAR'
|
|
||||||
: data.cajasRaw;
|
|
||||||
|
|
||||||
if (grupo == valorCaja) {
|
|
||||||
total++;
|
|
||||||
if ($(this.node()).find('.checkbox-linea-envio').is(':checked')) {
|
|
||||||
seleccionadas++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 2. Actualizar el checkbox del grupo
|
|
||||||
const checkGrupo = $(`.switch-grupo[data-grupo="${valorCaja}"]`);
|
|
||||||
if (seleccionadas === total) {
|
|
||||||
checkGrupo.prop('checked', true);
|
|
||||||
} else {
|
|
||||||
checkGrupo.prop('checked', false);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -210,7 +153,6 @@ class EnvioEdit {
|
|||||||
title: 'Error',
|
title: 'Error',
|
||||||
text: response.message,
|
text: response.message,
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
showCancelButton: false,
|
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
confirmButtonText: 'Ok',
|
confirmButtonText: 'Ok',
|
||||||
customClass: {
|
customClass: {
|
||||||
@ -225,7 +167,6 @@ class EnvioEdit {
|
|||||||
title: 'Error',
|
title: 'Error',
|
||||||
text: 'No se pudo actualizar el dato.',
|
text: 'No se pudo actualizar el dato.',
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
showCancelButton: false,
|
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
confirmButtonText: 'Ok',
|
confirmButtonText: 'Ok',
|
||||||
customClass: {
|
customClass: {
|
||||||
@ -239,39 +180,33 @@ class EnvioEdit {
|
|||||||
|
|
||||||
this.buscarPedidos.init();
|
this.buscarPedidos.init();
|
||||||
|
|
||||||
this.btnAddLinea.on('click', this._addEnvioLinea.bind(this));
|
if (this.btnAddLinea.length) this.btnAddLinea.on('click', this._addEnvioLinea.bind(this));
|
||||||
this.btnAddCaja.on('click', this._addCaja.bind(this));
|
if (this.btnDeleteLinea.length) this.btnDeleteLinea.on('click', this._deleteLineas.bind(this));
|
||||||
this.btnDeleteLinea.on('click', this._deleteLineas.bind(this));
|
if (this.btnGenerarAlbaran.length) this.btnGenerarAlbaran.on('click', this._generarAlbaran.bind(this));
|
||||||
this.btnGenerarAlbaran.on('click', this._generarAlbaran.bind(this));
|
|
||||||
|
|
||||||
this.btnGuardarComentarios.on('click', () => {
|
if (this.btnGuardarComentarios.length) {
|
||||||
|
this.btnGuardarComentarios.on('click', () => {
|
||||||
$.post('/logistica/updateComentariosEnvio', {
|
$.post('/logistica/updateComentariosEnvio', {
|
||||||
id: $('#id').val(),
|
id: $('#id').val(),
|
||||||
comentarios: $('#comentarios').val()
|
comentarios: $('#comentarios').val()
|
||||||
}, function (response) {
|
}, function (response) {
|
||||||
if (response.status) {
|
if (response.status) {
|
||||||
popSuccessAlert('Comentarios guardados correctamente');
|
popSuccessAlert('Comentarios guardados correctamente');
|
||||||
} else {
|
} else {
|
||||||
popErrorAlert(response.message);
|
popErrorAlert(response.message);
|
||||||
}
|
}
|
||||||
}).fail((error) => {
|
}).fail((error) => {
|
||||||
popErrorAlert(error.responseJSON.message);
|
popErrorAlert(error.responseJSON.message);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
this.btnbtnSelectAll.on('click', () => {
|
||||||
this.btnSelectAll.on('click', () => {
|
const checkboxes = this.table.$('input[type="checkbox"]');
|
||||||
$('.switch-grupo').each(function () {
|
const allChecked = checkboxes.length === checkboxes.filter(':checked').length;
|
||||||
const $switch = $(this);
|
checkboxes.prop('checked', !allChecked);
|
||||||
if (!$switch.is(':checked')) {
|
}
|
||||||
$switch.prop('checked', true).trigger('change');
|
);
|
||||||
} else {
|
|
||||||
// incluso si ya está marcado, forzamos el evento por seguridad
|
|
||||||
$switch.trigger('change');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
this._getAlbaranes();
|
this._getAlbaranes();
|
||||||
}
|
}
|
||||||
@ -281,7 +216,6 @@ class EnvioEdit {
|
|||||||
envio_id: $('#id').val(),
|
envio_id: $('#id').val(),
|
||||||
}, function (response) {
|
}, function (response) {
|
||||||
if (response.status && response.data) {
|
if (response.status && response.data) {
|
||||||
|
|
||||||
for (let i = 0; i < response.data.length; i++) {
|
for (let i = 0; i < response.data.length; i++) {
|
||||||
const albaran = response.data[i];
|
const albaran = response.data[i];
|
||||||
new AlbaranComponent(albaran).mount('#contenedorAlbaranes');
|
new AlbaranComponent(albaran).mount('#contenedorAlbaranes');
|
||||||
@ -291,7 +225,6 @@ class EnvioEdit {
|
|||||||
title: 'Error',
|
title: 'Error',
|
||||||
text: response.message,
|
text: response.message,
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
showCancelButton: false,
|
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
confirmButtonText: 'Ok',
|
confirmButtonText: 'Ok',
|
||||||
customClass: {
|
customClass: {
|
||||||
@ -305,7 +238,6 @@ class EnvioEdit {
|
|||||||
title: 'Error',
|
title: 'Error',
|
||||||
text: 'No se han podido obtener los albaranes.',
|
text: 'No se han podido obtener los albaranes.',
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
showCancelButton: false,
|
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
confirmButtonText: 'Ok',
|
confirmButtonText: 'Ok',
|
||||||
customClass: {
|
customClass: {
|
||||||
@ -317,8 +249,6 @@ class EnvioEdit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_generarAlbaran() {
|
_generarAlbaran() {
|
||||||
|
|
||||||
// se seleccionan los id de las lineas de envio con checkbox marcado
|
|
||||||
const table = this.table;
|
const table = this.table;
|
||||||
const selectedRows = table.rows({ page: 'current' }).nodes().filter((node) => {
|
const selectedRows = table.rows({ page: 'current' }).nodes().filter((node) => {
|
||||||
const checkbox = $(node).find('.checkbox-linea-envio');
|
const checkbox = $(node).find('.checkbox-linea-envio');
|
||||||
@ -327,14 +257,13 @@ class EnvioEdit {
|
|||||||
const ids = selectedRows.map((node) => {
|
const ids = selectedRows.map((node) => {
|
||||||
const rowData = table.row(node).data();
|
const rowData = table.row(node).data();
|
||||||
return rowData.id;
|
return rowData.id;
|
||||||
}
|
}).toArray();
|
||||||
).toArray();
|
|
||||||
if (ids.length <= 0) {
|
if (ids.length <= 0) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Atención!',
|
title: 'Atención!',
|
||||||
text: 'Debe seleccionar al menos una línea de envío para generar el albarán.',
|
text: 'Debe seleccionar al menos una línea de envío para generar el albarán.',
|
||||||
icon: 'info',
|
icon: 'info',
|
||||||
showCancelButton: false,
|
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
confirmButtonText: 'Ok',
|
confirmButtonText: 'Ok',
|
||||||
customClass: {
|
customClass: {
|
||||||
@ -344,20 +273,20 @@ class EnvioEdit {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const idEnvio = $('#id').val();
|
const idEnvio = $('#id').val();
|
||||||
$.post('/albaranes/generarAlbaran', {
|
$.post('/albaranes/generarAlbaran', {
|
||||||
envio_id: idEnvio,
|
envio_id: idEnvio,
|
||||||
envio_lineas: ids
|
envio_lineas: ids,
|
||||||
|
cajas: this.cajas.val()
|
||||||
}, function (response) {
|
}, function (response) {
|
||||||
if (response.status && response.albaran) {
|
if (response.status && response.albaran) {
|
||||||
|
|
||||||
new AlbaranComponent(response.albaran).mount('#contenedorAlbaranes');
|
new AlbaranComponent(response.albaran).mount('#contenedorAlbaranes');
|
||||||
} else {
|
} else {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Error',
|
title: 'Error',
|
||||||
text: response.message,
|
text: response.message,
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
showCancelButton: false,
|
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
confirmButtonText: 'Ok',
|
confirmButtonText: 'Ok',
|
||||||
customClass: {
|
customClass: {
|
||||||
@ -371,7 +300,6 @@ class EnvioEdit {
|
|||||||
title: 'Error',
|
title: 'Error',
|
||||||
text: 'No se pudo generar el albarán.',
|
text: 'No se pudo generar el albarán.',
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
showCancelButton: false,
|
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
confirmButtonText: 'Ok',
|
confirmButtonText: 'Ok',
|
||||||
customClass: {
|
customClass: {
|
||||||
@ -380,7 +308,6 @@ class EnvioEdit {
|
|||||||
buttonsStyling: false
|
buttonsStyling: false
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_deleteLineas() {
|
_deleteLineas() {
|
||||||
@ -392,11 +319,10 @@ class EnvioEdit {
|
|||||||
const ids = selectedRows.map((node) => {
|
const ids = selectedRows.map((node) => {
|
||||||
const rowData = table.row(node).data();
|
const rowData = table.row(node).data();
|
||||||
return rowData.id;
|
return rowData.id;
|
||||||
}
|
}).toArray();
|
||||||
).toArray();
|
|
||||||
if (ids.length > 0) {
|
if (ids.length > 0) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
|
|
||||||
title: 'Eliminar líneas de envío',
|
title: 'Eliminar líneas de envío',
|
||||||
text: '¿Está seguro de que desea eliminar las líneas seleccionadas?',
|
text: '¿Está seguro de que desea eliminar las líneas seleccionadas?',
|
||||||
icon: 'warning',
|
icon: 'warning',
|
||||||
@ -411,18 +337,15 @@ class EnvioEdit {
|
|||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
$.post('/logistica/deleteLineasEnvio', {
|
$.post('/logistica/deleteLineasEnvio', {
|
||||||
|
|
||||||
ids: ids
|
ids: ids
|
||||||
}, function (response) {
|
}, function (response) {
|
||||||
if (response.status) {
|
if (response.status) {
|
||||||
table.draw(false);
|
table.draw(false);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Error',
|
title: 'Error',
|
||||||
text: response.message,
|
text: response.message,
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
showCancelButton: false,
|
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
confirmButtonText: 'Ok',
|
confirmButtonText: 'Ok',
|
||||||
customClass: {
|
customClass: {
|
||||||
@ -437,7 +360,6 @@ class EnvioEdit {
|
|||||||
title: 'Error',
|
title: 'Error',
|
||||||
text: 'No se pudo eliminar la línea de envío.',
|
text: 'No se pudo eliminar la línea de envío.',
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
showCancelButton: false,
|
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
confirmButtonText: 'Ok',
|
confirmButtonText: 'Ok',
|
||||||
customClass: {
|
customClass: {
|
||||||
@ -454,7 +376,6 @@ class EnvioEdit {
|
|||||||
title: 'Sin filas seleccionadas',
|
title: 'Sin filas seleccionadas',
|
||||||
text: 'Marca al menos una línea para eliminarla.',
|
text: 'Marca al menos una línea para eliminarla.',
|
||||||
icon: 'info',
|
icon: 'info',
|
||||||
showCancelButton: false,
|
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
confirmButtonText: 'Ok',
|
confirmButtonText: 'Ok',
|
||||||
customClass: {
|
customClass: {
|
||||||
@ -465,160 +386,12 @@ class EnvioEdit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_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.includes('SIN ASIGNAR')) {
|
|
||||||
nombreGrupo = '__SIN__ASIGNAR__';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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() {
|
_addEnvioLinea() {
|
||||||
|
|
||||||
if (!this.buscarPedidos.getVal()) {
|
if (!this.buscarPedidos.getVal()) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Atención!',
|
title: 'Atención!',
|
||||||
text: 'Debe seleccionar un pedido antes de añadir una línea de envío.',
|
text: 'Debe seleccionar un pedido antes de añadir una línea de envío.',
|
||||||
icon: 'info',
|
icon: 'info',
|
||||||
showCancelButton: false,
|
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
confirmButtonText: 'Ok',
|
confirmButtonText: 'Ok',
|
||||||
customClass: {
|
customClass: {
|
||||||
@ -626,7 +399,6 @@ class EnvioEdit {
|
|||||||
},
|
},
|
||||||
buttonsStyling: false
|
buttonsStyling: false
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -637,35 +409,6 @@ class EnvioEdit {
|
|||||||
}, {},
|
}, {},
|
||||||
(response) => {
|
(response) => {
|
||||||
if (response.status) {
|
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.table.draw();
|
||||||
this.buscarPedidos.empty();
|
this.buscarPedidos.empty();
|
||||||
} else {
|
} else {
|
||||||
@ -673,7 +416,6 @@ class EnvioEdit {
|
|||||||
title: 'Atención!',
|
title: 'Atención!',
|
||||||
text: response.message,
|
text: response.message,
|
||||||
icon: 'info',
|
icon: 'info',
|
||||||
showCancelButton: false,
|
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
confirmButtonText: 'Ok',
|
confirmButtonText: 'Ok',
|
||||||
customClass: {
|
customClass: {
|
||||||
@ -686,79 +428,6 @@ class EnvioEdit {
|
|||||||
console.error(error);
|
console.error(error);
|
||||||
}).get();
|
}).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 () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
@ -778,7 +447,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
console.log("Error getting translations:", error);
|
console.log("Error getting translations:", error);
|
||||||
}
|
}
|
||||||
).post();
|
).post();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default EnvioEdit;
|
export default EnvioEdit;
|
||||||
Reference in New Issue
Block a user