mirror of
https://git.imnavajas.es/jjimenez/safekat.git
synced 2025-07-25 22:52:08 +00:00
Merge branch 'add/impresion_etiquetas_envios' into 'main'
Add/impresion etiquetas envios See merge request jjimenez/safekat!740
This commit is contained in:
@ -819,6 +819,7 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi
|
|||||||
$routes->post('generateEnvio', 'LogisticaController::generarEnvio');
|
$routes->post('generateEnvio', 'LogisticaController::generarEnvio');
|
||||||
$routes->get('selectForNewEnvio', 'LogisticaController::findForNewEnvio');
|
$routes->get('selectForNewEnvio', 'LogisticaController::findForNewEnvio');
|
||||||
$routes->get('selectDireccionForEnvio', 'LogisticaController::selectDireccionForEnvio');
|
$routes->get('selectDireccionForEnvio', 'LogisticaController::selectDireccionForEnvio');
|
||||||
|
$routes->post('imprimirEtiquetas', 'LogisticaController::imprimirEtiquetas');
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -122,6 +122,65 @@ class LogisticaController extends BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function imprimirEtiquetas()
|
||||||
|
{
|
||||||
|
if ($this->request->isAJAX()) {
|
||||||
|
$envio_id = $this->request->getPost('envio_id');
|
||||||
|
$ids = $this->request->getPost('envio_lineas');
|
||||||
|
$cajas = $this->request->getPost('cajas');
|
||||||
|
$printer_id = $this->request->getPost('printer_id');
|
||||||
|
|
||||||
|
if($cajas == null || $cajas == 0){
|
||||||
|
return $this->response->setJSON([
|
||||||
|
'status' => false,
|
||||||
|
'message' => 'Cajas no válidas'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$model = model('App\Models\Logistica\EnvioModel');
|
||||||
|
$envio = $model->select('envios.*, clientes.nombre as cliente')
|
||||||
|
->join('clientes', 'clientes.id = envios.cliente_id', 'left')
|
||||||
|
->where('envios.id', $envio_id)
|
||||||
|
->first();
|
||||||
|
if($envio == null){
|
||||||
|
return $this->response->setJSON([
|
||||||
|
'status' => false,
|
||||||
|
'message' => 'Envio no válido'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$model = model('App\Models\Logistica\EnvioLineaModel');
|
||||||
|
$lineas = $model->select('envios_lineas.*, presupuestos.titulo as titulo, presupuestos.referencia_cliente as referencia_cliente')
|
||||||
|
->join('presupuestos', 'presupuestos.id = envios_lineas.presupuesto_id', 'left')
|
||||||
|
->whereIn('envios_lineas.id', $ids)->findAll();
|
||||||
|
if($lineas == null){
|
||||||
|
return $this->response->setJSON([
|
||||||
|
'status' => false,
|
||||||
|
'message' => 'Lineas no válidas'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$modelImpresora = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
|
||||||
|
$impresora = $modelImpresora->select('id, name')
|
||||||
|
->where('deleted_at', null)
|
||||||
|
->where('id', $printer_id)
|
||||||
|
->orderBy('name', 'asc')
|
||||||
|
->first();
|
||||||
|
if($impresora == null){
|
||||||
|
return $this->response->setJSON([
|
||||||
|
'status' => false,
|
||||||
|
'message' => 'Impresora no válida'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = LogisticaService::generateEtiquetasTitulos($envio, $lineas, $impresora, $cajas);
|
||||||
|
return $this->response->setJSON($response);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return $this->failUnauthorized('Invalid request', 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function selectAddEnvioLinea()
|
public function selectAddEnvioLinea()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -221,6 +280,14 @@ class LogisticaController extends BaseController
|
|||||||
$envioEntity->proveedor_nombre = $proveedor->nombre;
|
$envioEntity->proveedor_nombre = $proveedor->nombre;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$modelImpresora = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
|
||||||
|
$impresoras = $modelImpresora->select('id, name')
|
||||||
|
->where('deleted_at', null)
|
||||||
|
->where('tipo', 1)
|
||||||
|
->orderBy('name', 'asc')
|
||||||
|
->findAll();
|
||||||
|
$envioEntity->impresoras = $impresoras;
|
||||||
|
|
||||||
$viewData = [
|
$viewData = [
|
||||||
'currentModule' => static::$controllerSlug,
|
'currentModule' => static::$controllerSlug,
|
||||||
'boxTitle' => '<i class="ti ti-truck ti-xl"></i>' . ' ' . lang('Logistica.envio') . ' [' . $envioEntity->id . ']: ' . $envioEntity->direccion,
|
'boxTitle' => '<i class="ti ti-truck ti-xl"></i>' . ' ' . lang('Logistica.envio') . ' [' . $envioEntity->id . ']: ' . $envioEntity->direccion,
|
||||||
|
|||||||
@ -30,6 +30,7 @@ return [
|
|||||||
'no' => 'No',
|
'no' => 'No',
|
||||||
'si' => 'Sí',
|
'si' => 'Sí',
|
||||||
'todos' => 'Todos',
|
'todos' => 'Todos',
|
||||||
|
'impresoraEtiquetas' => 'Impresora de etiquetas',
|
||||||
|
|
||||||
'envio' => 'Envío',
|
'envio' => 'Envío',
|
||||||
'addLineasEnvio' => 'Añadir líneas al envío',
|
'addLineasEnvio' => 'Añadir líneas al envío',
|
||||||
|
|||||||
@ -57,7 +57,7 @@ class ImpresoraEtiquetaService extends BaseService
|
|||||||
return ["impresora" => $impresora, "content" => $th->getMessage(), "status" => $status];
|
return ["impresora" => $impresora, "content" => $th->getMessage(), "status" => $status];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected function createEtiqueta(array $data_label = []): ?string
|
public function createEtiqueta(array $data_label = []): ?string
|
||||||
{
|
{
|
||||||
$xml = new DOMDocument('1.0', 'utf-8');
|
$xml = new DOMDocument('1.0', 'utf-8');
|
||||||
$labels = $xml->createElement("labels");
|
$labels = $xml->createElement("labels");
|
||||||
@ -76,7 +76,7 @@ class ImpresoraEtiquetaService extends BaseService
|
|||||||
$xml->appendChild($labels);
|
$xml->appendChild($labels);
|
||||||
return $xml->saveXML();
|
return $xml->saveXML();
|
||||||
}
|
}
|
||||||
protected function sendToImpresoraEtiqueta(string $name, string $content, ImpresoraEtiquetaEntity $impresoraEtiqueta): bool
|
public function sendToImpresoraEtiqueta(string $name, string $content, ImpresoraEtiquetaEntity $impresoraEtiqueta): bool
|
||||||
{
|
{
|
||||||
$tmpFile = tmpfile();
|
$tmpFile = tmpfile();
|
||||||
|
|
||||||
|
|||||||
@ -332,7 +332,6 @@ class LogisticaService
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static function finalizarEnvio($envio_id, $finalizar_ot = false)
|
public static function finalizarEnvio($envio_id, $finalizar_ot = false)
|
||||||
{
|
{
|
||||||
// hay que comprobar que para todas las lineas de envio de este envio
|
// hay que comprobar que para todas las lineas de envio de este envio
|
||||||
@ -419,4 +418,66 @@ class LogisticaService
|
|||||||
}
|
}
|
||||||
return $data_return;
|
return $data_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function generateEtiquetasTitulos($envio, $lineas, $printer, $cajas)
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
"printer" => $printer->name,
|
||||||
|
"header" => [
|
||||||
|
"_FORMAT" => "E:PEDIDO.ZPL",
|
||||||
|
"_QUANTITY" => 1,
|
||||||
|
"_PRINBTERNAME" => $printer->name,
|
||||||
|
"_JOBNAME" => "LBL101"
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($lineas as $linea) {
|
||||||
|
$data["labels"][] = [
|
||||||
|
"cliente" => $envio->cliente,
|
||||||
|
"titulo" => "[" . $linea->pedido_id . "] - " . $linea->titulo,
|
||||||
|
"cantidad" => $linea->unidades_envio,
|
||||||
|
"tirada" => $linea->unidades_total,
|
||||||
|
"cajas" => $cajas,
|
||||||
|
"ean" => null,
|
||||||
|
"nombre" => $envio->att,
|
||||||
|
"direccion" => $envio->direccion,
|
||||||
|
"notas" => "",
|
||||||
|
"refcliente" => $linea->refcliente,
|
||||||
|
"npedido" => $linea->pedido_id
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$servicioImpresora = new ImpresoraEtiquetaService();
|
||||||
|
$xml = $servicioImpresora->createEtiqueta($data);
|
||||||
|
if($xml == null){
|
||||||
|
return [
|
||||||
|
'status' => false,
|
||||||
|
'message' => lang('Logistica.errors.noEtiquetas'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$sk_environment = getenv('SK_ENVIRONMENT');
|
||||||
|
if($sk_environment == 'production'){
|
||||||
|
|
||||||
|
$status = $servicioImpresora->sendToImpresoraEtiqueta("ETIQUETA", $xml, $printer);
|
||||||
|
if ($status) {
|
||||||
|
return [
|
||||||
|
'status' => true,
|
||||||
|
'message' => lang('Logistica.success.imprimirEtiquetas'),
|
||||||
|
'data' => $xml
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
'status' => false,
|
||||||
|
'message' => lang('Logistica.errors.noEtiquetas'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
return [
|
||||||
|
'status' => true,
|
||||||
|
'message' => lang('Logistica.success.imprimirEtiquetas'),
|
||||||
|
'data' => $xml
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,9 @@
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h4><?= $boxTitle ?> <?= ($envioEntity->finalizado == 0)?'':'<span class="badge text-bg-success fw-lg">FINALIZADO</span>' ?></h4>
|
<h4><?= $boxTitle ?>
|
||||||
|
<?= ($envioEntity->finalizado == 0) ? '' : '<span class="badge text-bg-success fw-lg">FINALIZADO</span>' ?>
|
||||||
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|
||||||
@ -162,7 +164,7 @@
|
|||||||
<div class="d-flex flex-row">
|
<div class="d-flex flex-row">
|
||||||
<p><?= lang('Logistica.buttonsActions') ?></p>
|
<p><?= lang('Logistica.buttonsActions') ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex flex-row mb-3">
|
<div class="d-flex flex-row mb-3 align-items-end">
|
||||||
<div class="col-sm-2 px-3">
|
<div class="col-sm-2 px-3">
|
||||||
<button id="btnSelectAll" name="btnSelectAll" tabindex="1"
|
<button id="btnSelectAll" name="btnSelectAll" tabindex="1"
|
||||||
class="btn btn-primary w-100">
|
class="btn btn-primary w-100">
|
||||||
@ -194,6 +196,22 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-2 px-3 d-flex flex-column justify-content-end">
|
||||||
|
<div class="d-flex flex-column justify-content-end h-100">
|
||||||
|
<label for="impresoraEtiquetas" class="form-label">
|
||||||
|
<?= lang("Logistica.impresoraEtiquetas") ?>
|
||||||
|
</label>
|
||||||
|
<select id="impresoraEtiquetas" name="impresora_etiquetas" tabindex="1"
|
||||||
|
maxlength="50" class="form-control select2bs2" style="width: 100%;">
|
||||||
|
<?php foreach ($envioEntity->impresoras as $impresora): ?>
|
||||||
|
<option value="<?= $impresora->id ?>">
|
||||||
|
<?= $impresora->name ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
|
|
||||||
@ -288,9 +306,8 @@
|
|||||||
<?= lang("Logistica.codigoSeguimiento") ?>
|
<?= lang("Logistica.codigoSeguimiento") ?>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" id="codigoSeguimiento" name="codigo_seguimiento" tabindex="1"
|
<input type="text" id="codigoSeguimiento" name="codigo_seguimiento" tabindex="1"
|
||||||
maxlength="100" class="form-control"
|
maxlength="100" class="form-control" <?= ($envioEntity->finalizado == 0) ? '' : 'readonly' ?>
|
||||||
<?= ($envioEntity->finalizado == 0) ? "" : "readonly" ?>
|
value="<?= esc(old('codigo_seguimiento', $envioEntity->codigo_seguimiento)) ?>">
|
||||||
value="<?= old('codigo_seguimiento', $envioEntity->codigo_seguimiento) ?>">
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-3 px-3">
|
<div class="col-sm-3 px-3">
|
||||||
<label for="empresaMensajeria" class="form-label">
|
<label for="empresaMensajeria" class="form-label">
|
||||||
|
|||||||
@ -32,6 +32,8 @@ class EnvioEdit {
|
|||||||
if (!$("#empresaMensajeriaInput").length) {
|
if (!$("#empresaMensajeriaInput").length) {
|
||||||
this.proveedor = new ClassSelect($("#empresaMensajeria"), '/compras/proveedores/getProveedores', "", true, { 'tipo_id': 2 });
|
this.proveedor = new ClassSelect($("#empresaMensajeria"), '/compras/proveedores/getProveedores', "", true, { 'tipo_id': 2 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.impresoraEtiquetas = $("#impresoraEtiquetas");
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
@ -92,6 +94,63 @@ class EnvioEdit {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#btnImprimirEtiquetas').on('click', () => {
|
||||||
|
const table = this.table;
|
||||||
|
const selectedRows = table.rows({ page: 'current' }).nodes().filter((node) => {
|
||||||
|
const checkbox = $(node).find('.checkbox-linea-envio');
|
||||||
|
return checkbox.is(':checked');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const ids = selectedRows.map((node) => {
|
||||||
|
const rowData = table.row(node).data();
|
||||||
|
return rowData.id;
|
||||||
|
}).toArray();
|
||||||
|
if (ids.length <= 0) {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Atención!',
|
||||||
|
text: 'Debe seleccionar al menos una línea de envío para imprimir etiquetas.',
|
||||||
|
icon: 'info',
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
confirmButtonText: 'Ok',
|
||||||
|
customClass: {
|
||||||
|
confirmButton: 'btn btn-primary me-1',
|
||||||
|
},
|
||||||
|
buttonsStyling: false
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const idEnvio = $('#id').val();
|
||||||
|
let num_cajas = this.cajas.val();
|
||||||
|
if(ids.length != table.rows().count()){
|
||||||
|
// se preguntará el numero de cajas en un swal con un input para obtener el valor
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Atención!',
|
||||||
|
text: 'No se ha seleccionado todas las líneas de envío. Ingrese el número de cajas a imprimir.',
|
||||||
|
icon: 'info',
|
||||||
|
input: 'text',
|
||||||
|
inputLabel: 'Número de cajas',
|
||||||
|
inputValue: num_cajas,
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
confirmButtonText: 'Imprimir etiquetas',
|
||||||
|
cancelButtonText: 'Cancelar',
|
||||||
|
customClass: {
|
||||||
|
confirmButton: 'btn btn-primary me-1',
|
||||||
|
cancelButton: 'btn btn-secondary'
|
||||||
|
},
|
||||||
|
buttonsStyling: false
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
num_cajas = result.value;
|
||||||
|
this._imprimirEtiquetas(idEnvio, ids, num_cajas);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
this._imprimirEtiquetas(idEnvio, ids, num_cajas);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.cajas.on('change', (e) => {
|
this.cajas.on('change', (e) => {
|
||||||
const value = $(e.currentTarget).val();
|
const value = $(e.currentTarget).val();
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
@ -429,6 +488,71 @@ class EnvioEdit {
|
|||||||
this._getAlbaranes();
|
this._getAlbaranes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_imprimirEtiquetas(envio_id, ids, num_cajas) {
|
||||||
|
|
||||||
|
$.post('/logistica/imprimirEtiquetas', {
|
||||||
|
|
||||||
|
envio_id: envio_id,
|
||||||
|
envio_lineas: ids,
|
||||||
|
cajas: num_cajas,
|
||||||
|
printer_id: this.impresoraEtiquetas.val(),
|
||||||
|
|
||||||
|
}, function (response) {
|
||||||
|
if (response.status) {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Etiquetas generadas',
|
||||||
|
text: 'Las etiquetas se han generado correctamente.',
|
||||||
|
icon: 'success',
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
confirmButtonText: 'Ok',
|
||||||
|
customClass: {
|
||||||
|
confirmButton: 'btn btn-primary me-1',
|
||||||
|
},
|
||||||
|
buttonsStyling: false
|
||||||
|
}).then(() => {
|
||||||
|
if(response.data){
|
||||||
|
// show xml in a new tab
|
||||||
|
const blob = new Blob([response.data], { type: 'application/xml' });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'etiquetas.xml';
|
||||||
|
a.click();
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
a.remove();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Error',
|
||||||
|
text: response.message,
|
||||||
|
icon: 'error',
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
confirmButtonText: 'Ok',
|
||||||
|
customClass: {
|
||||||
|
confirmButton: 'btn btn-primary me-1',
|
||||||
|
},
|
||||||
|
buttonsStyling: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).fail(() => {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Error',
|
||||||
|
text: 'No se pudo generar las etiquetas.',
|
||||||
|
icon: 'error',
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
confirmButtonText: 'Ok',
|
||||||
|
customClass: {
|
||||||
|
confirmButton: 'btn btn-primary me-1',
|
||||||
|
},
|
||||||
|
buttonsStyling: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_checkDatosFinalizar() {
|
_checkDatosFinalizar() {
|
||||||
|
|
||||||
if (this.codigoSeguimiento.val().length <= 0 || this.proveedor.getVal() <= 0) {
|
if (this.codigoSeguimiento.val().length <= 0 || this.proveedor.getVal() <= 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user