mirror of
https://git.imnavajas.es/jjimenez/safekat.git
synced 2025-07-25 22:52:08 +00:00
Merge branch 'main' into fix/papel-impresion-routes
This commit is contained in:
632
httpdocs/assets/js/safekat/components/albaranComponent.js
Normal file
632
httpdocs/assets/js/safekat/components/albaranComponent.js
Normal file
@ -0,0 +1,632 @@
|
||||
import DatePicker from "./datepicker.js";
|
||||
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.fecha = null;
|
||||
if(this.item.fecha_albaran != null){
|
||||
const [dia, mes, anio] = item.fecha_albaran.split('/');
|
||||
this.fecha = `${anio}-${mes.padStart(2, '0')}-${dia.padStart(2, '0')}`;
|
||||
}
|
||||
this.selectorTabla = `#tablaAlbaran${this.id}`;
|
||||
|
||||
this.table = null;
|
||||
this.fechaAlbaran = 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);
|
||||
}
|
||||
});
|
||||
|
||||
const option = {
|
||||
altInput: true,
|
||||
altFormat: "d/m/Y",
|
||||
dateFormat: "Y-m-d",
|
||||
allowInput: true,
|
||||
}
|
||||
this.fechaAlbaran = new DatePicker($('#fecha_albaran_' + this.id), option);
|
||||
this.fechaAlbaran.setDate(this.fecha);
|
||||
|
||||
$('#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
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#fecha_albaran_' + this.item.id).on('change', (e) => {
|
||||
const value = $(e.currentTarget).val();
|
||||
const albaranId = this.id;
|
||||
|
||||
$.post('/albaranes/updateAlbaran', {
|
||||
albaranId: albaranId,
|
||||
fieldName: 'fecha_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);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$('#tablaAlbaran' + this.id).on('change', '.input-albaran-linea', (e) => {
|
||||
|
||||
const fieldName = $(e.currentTarget).attr('data-field');
|
||||
const fieldValue = $(e.currentTarget).val();
|
||||
const albaranId = this.id;
|
||||
const lineaId = $(e.currentTarget).attr('data-id');
|
||||
|
||||
$.post('/albaranes/updateAlbaranLinea', {
|
||||
fieldName: fieldName,
|
||||
fieldValue: fieldValue,
|
||||
lineaId: lineaId
|
||||
}, (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
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#add_iva_albaran_' + this.id).on('click', (e) => {
|
||||
|
||||
e.preventDefault();
|
||||
const albaranId = this.id;
|
||||
const url = `/albaranes/addIvaAlbaran`;
|
||||
const data = { albaranId: albaranId };
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
data: data,
|
||||
success: (response) => {
|
||||
if (response.success) {
|
||||
this.table.ajax.reload(null, false);
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: 'No se ha podido añadir el IVA al 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);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#nueva_linea_albaran_' + this.id).on('click', (e) => {
|
||||
|
||||
e.preventDefault();
|
||||
const albaranId = this.id;
|
||||
const url = `/albaranes/nuevaLineaAlbaran`;
|
||||
const data = { albaranId: albaranId };
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
data: data,
|
||||
success: (response) => {
|
||||
if (response.success) {
|
||||
this.table.ajax.reload(null, false);
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: 'No se ha podido añadir la línea al 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);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#imprimir_albaran_' + this.id).on('click', (e) => {
|
||||
|
||||
var albaran_id = this.id;
|
||||
window.open('/print-albaran/generar/'+ albaran_id , '_blank');
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
_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;
|
||||
82
httpdocs/assets/js/safekat/pages/logistica/envio.js
Normal file
82
httpdocs/assets/js/safekat/pages/logistica/envio.js
Normal file
@ -0,0 +1,82 @@
|
||||
import Ajax from '../../components/ajax.js';
|
||||
|
||||
$(()=>{
|
||||
|
||||
$('#buscadorPedidos').on('keydown', function(e) {
|
||||
if (e.key === 'Enter' || e.keyCode === 13) {
|
||||
e.preventDefault(); // Evita el submit si está dentro de un form
|
||||
let search = $(this).val().trim();
|
||||
new Ajax(
|
||||
'/logistica/buscar/'+search,
|
||||
{},
|
||||
{},
|
||||
function(response) {
|
||||
if(!response.status){
|
||||
popErrorAlert(response.message);
|
||||
}
|
||||
if(response.data){
|
||||
|
||||
window.open(`${window.location.origin}/logistica/envio/${response.data.id_envio}`);
|
||||
}
|
||||
|
||||
},
|
||||
function(xhr, status, error) {
|
||||
if(status == 'error' && typeof(error)== 'string')
|
||||
popErrorAlert(error);
|
||||
else
|
||||
popErrorAlert(error.responseJSON.message);
|
||||
}
|
||||
).get();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
const tableEnvios = $('#tableOfEnvios').DataTable({
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
autoWidth: true,
|
||||
responsive: true,
|
||||
scrollX: true,
|
||||
orderCellsTop: true,
|
||||
lengthMenu: [5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500],
|
||||
pageLength: 50,
|
||||
"dom": 'lBrtip',
|
||||
"ajax": {
|
||||
"url": "/logistica/datatableEnvios",
|
||||
},
|
||||
"columns": [
|
||||
{ "data": "id" },
|
||||
{ "data": "pedidos" },
|
||||
{ "data": "num_lineas" },
|
||||
{ "data": "att" },
|
||||
{ "data": "direccion" },
|
||||
{ "data": "ciudad" },
|
||||
{ "data": "pais" },
|
||||
{ "data": "cp" },
|
||||
{ "data": "email" },
|
||||
{ "data": "telefono" },
|
||||
{
|
||||
"data": "finalizado",
|
||||
"className": "text-center",
|
||||
},
|
||||
{ "data": "action" }
|
||||
|
||||
],
|
||||
"language": {
|
||||
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
|
||||
},
|
||||
"columnDefs": [
|
||||
{
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
targets: [11]
|
||||
},
|
||||
],
|
||||
"order": [[0, "desc"]],
|
||||
});
|
||||
|
||||
$(document).on('click', '.btn-edit', function (e) {
|
||||
window.location.href = '/logistica/envio/' + $(this).attr('data-id');
|
||||
});
|
||||
|
||||
});
|
||||
452
httpdocs/assets/js/safekat/pages/logistica/envioEdit.js
Normal file
452
httpdocs/assets/js/safekat/pages/logistica/envioEdit.js
Normal file
@ -0,0 +1,452 @@
|
||||
import ClassSelect from '../../components/select2.js';
|
||||
import Ajax from '../../components/ajax.js';
|
||||
import AlbaranComponent from '../../components/albaranComponent.js';
|
||||
|
||||
class EnvioEdit {
|
||||
|
||||
constructor() {
|
||||
this.tableCols = [
|
||||
{ data: "rowSelected" },
|
||||
{ data: "pedido" },
|
||||
{ data: "presupuesto" },
|
||||
{ data: "titulo" },
|
||||
{ data: "unidadesEnvio" },
|
||||
{ data: "unidadesEnviadas" },
|
||||
{ data: "unidadesTotal" },
|
||||
{ data: "id" },
|
||||
{ data: "pesoUnidad" },
|
||||
{ data: "unidadesEnvioRaw" }
|
||||
];
|
||||
|
||||
this.table = null;
|
||||
|
||||
this.buscarPedidos = new ClassSelect($("#buscadorPedidos"), '/logistica/selectAddLinea', "", true, { 'envio': $("#id").val() });
|
||||
|
||||
this.btnAddLinea = $("#btnAddLinea");
|
||||
this.btnDeleteLinea = $("#btnEliminarLineas");
|
||||
this.btnGuardarComentarios = $("#guardarComentarios");
|
||||
this.btnGenerarAlbaran = $("#btnGenerarAlbaran");
|
||||
this.btnbtnSelectAll = $("#btnSelectAll");
|
||||
this.cajas = $("#cajas");
|
||||
}
|
||||
|
||||
init() {
|
||||
this.table = $('#tableLineasEnvio').DataTable({
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
autoWidth: true,
|
||||
responsive: true,
|
||||
scrollX: true,
|
||||
orderCellsTop: true,
|
||||
orderable: false,
|
||||
order: [[7, 'asc']],
|
||||
lengthMenu: [5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500],
|
||||
pageLength: 50,
|
||||
"dom": 'lrtip',
|
||||
"ajax": {
|
||||
"url": "/logistica/datatableLineasEnvios/" + $('#id').val(),
|
||||
},
|
||||
"columns": this.tableCols,
|
||||
"language": {
|
||||
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
|
||||
},
|
||||
footerCallback: function (row, data, start, end, display) {
|
||||
let totalUnidades = 0;
|
||||
let totalPeso = 0;
|
||||
|
||||
data.forEach(row => {
|
||||
const unidades = parseFloat(row.unidadesEnvioRaw) || 0;
|
||||
const pesoUnidad = parseFloat(row.pesoUnidad) || 0;
|
||||
totalUnidades += unidades;
|
||||
totalPeso += unidades * pesoUnidad;
|
||||
});
|
||||
|
||||
// Mostrar en spans personalizados del <tfoot>
|
||||
$('#footer-unidades-envio').text(totalUnidades);
|
||||
$('#footer-peso').text(totalPeso.toFixed(2));
|
||||
},
|
||||
"columnDefs": [
|
||||
{
|
||||
"targets": [0],
|
||||
"className": "text-center",
|
||||
"orderable": false,
|
||||
"searchable": false,
|
||||
},
|
||||
{
|
||||
"targets": [1, 2, 4, 5, 6],
|
||||
"className": "text-center",
|
||||
},
|
||||
{
|
||||
targets: [7, 8, 9],
|
||||
visible: false
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
this.cajas.on('change', (e) => {
|
||||
const value = $(e.currentTarget).val();
|
||||
if (value < 0) {
|
||||
Swal.fire({
|
||||
title: 'Atención!',
|
||||
text: 'El número de cajas no puede ser negativo.',
|
||||
icon: 'info',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
$(e.currentTarget).val(0);
|
||||
return;
|
||||
}
|
||||
$.post('/logistica/updateCajasEnvio', {
|
||||
id: $('#id').val(),
|
||||
cajas: value
|
||||
}, function (response) {
|
||||
if (!response.status) {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: response.message,
|
||||
icon: 'error',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
$(e.currentTarget).val(0);
|
||||
}
|
||||
}).fail(() => {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: 'No se pudo actualizar el número de cajas.',
|
||||
icon: 'error',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
$(e.currentTarget).val(0);
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('change', '.input-lineas', (e) => {
|
||||
const table = this.table;
|
||||
const row = table.row($(e.currentTarget).closest('tr'));
|
||||
const rowData = row.data();
|
||||
const fieldName = $(e.currentTarget).data('name');
|
||||
const fieldValue = $(e.currentTarget).val();
|
||||
|
||||
$.post('/logistica/updateLineaEnvio', {
|
||||
id: rowData.id,
|
||||
"name": fieldName,
|
||||
'value': fieldValue
|
||||
}, function (response) {
|
||||
if (response.status) {
|
||||
table.draw(false);
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: response.message,
|
||||
icon: 'error',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
table.draw(false);
|
||||
}
|
||||
}).fail(() => {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: 'No se pudo actualizar el dato.',
|
||||
icon: 'error',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
table.draw(false);
|
||||
});
|
||||
});
|
||||
|
||||
this.buscarPedidos.init();
|
||||
|
||||
if (this.btnAddLinea.length) this.btnAddLinea.on('click', this._addEnvioLinea.bind(this));
|
||||
if (this.btnDeleteLinea.length) this.btnDeleteLinea.on('click', this._deleteLineas.bind(this));
|
||||
if (this.btnGenerarAlbaran.length) this.btnGenerarAlbaran.on('click', this._generarAlbaran.bind(this));
|
||||
|
||||
if (this.btnGuardarComentarios.length) {
|
||||
this.btnGuardarComentarios.on('click', () => {
|
||||
$.post('/logistica/updateComentariosEnvio', {
|
||||
id: $('#id').val(),
|
||||
comentarios: $('#comentarios').val()
|
||||
}, function (response) {
|
||||
if (response.status) {
|
||||
popSuccessAlert('Comentarios guardados correctamente');
|
||||
} else {
|
||||
popErrorAlert(response.message);
|
||||
}
|
||||
}).fail((error) => {
|
||||
popErrorAlert(error.responseJSON.message);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
this.btnbtnSelectAll.on('click', () => {
|
||||
const checkboxes = this.table.$('input[type="checkbox"]');
|
||||
const allChecked = checkboxes.length === checkboxes.filter(':checked').length;
|
||||
checkboxes.prop('checked', !allChecked);
|
||||
}
|
||||
);
|
||||
|
||||
this._getAlbaranes();
|
||||
}
|
||||
|
||||
_getAlbaranes() {
|
||||
$.get('/albaranes/albaranesEnvio', {
|
||||
envio_id: $('#id').val(),
|
||||
}, function (response) {
|
||||
if (response.status && response.data) {
|
||||
for (let i = 0; i < response.data.length; i++) {
|
||||
const albaran = response.data[i];
|
||||
new AlbaranComponent(albaran).mount('#contenedorAlbaranes');
|
||||
}
|
||||
} 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 han podido obtener los albaranes.',
|
||||
icon: 'error',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_generarAlbaran() {
|
||||
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 generar el albarán.',
|
||||
icon: 'info',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const idEnvio = $('#id').val();
|
||||
$.post('/albaranes/generarAlbaran', {
|
||||
envio_id: idEnvio,
|
||||
envio_lineas: ids,
|
||||
cajas: this.cajas.val()
|
||||
}, function (response) {
|
||||
if (response.status && response.albaran) {
|
||||
new AlbaranComponent(response.albaran).mount('#contenedorAlbaranes');
|
||||
} 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 el albarán.',
|
||||
icon: 'error',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_deleteLineas() {
|
||||
const table = this.table;
|
||||
const selectedRows = table.rows({ page: 'current' }).nodes().filter((node) => {
|
||||
const checkbox = $(node).find('.checkbox-linea-envio');
|
||||
return checkbox.is(':checked');
|
||||
});
|
||||
const ids = selectedRows.map((node) => {
|
||||
const rowData = table.row(node).data();
|
||||
return rowData.id;
|
||||
}).toArray();
|
||||
|
||||
if (ids.length > 0) {
|
||||
Swal.fire({
|
||||
title: 'Eliminar líneas de envío',
|
||||
text: '¿Está seguro de que desea eliminar las líneas seleccionadas?',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Sí',
|
||||
cancelButtonText: 'Cancelar',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-danger me-1',
|
||||
cancelButton: 'btn btn-secondary'
|
||||
},
|
||||
buttonsStyling: false
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post('/logistica/deleteLineasEnvio', {
|
||||
ids: ids
|
||||
}, function (response) {
|
||||
if (response.status) {
|
||||
table.draw(false);
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: response.message,
|
||||
icon: 'error',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
table.ajax.reload();
|
||||
}
|
||||
}).fail(() => {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: 'No se pudo eliminar la línea de envío.',
|
||||
icon: 'error',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
table.ajax.reload();
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Sin filas seleccionadas',
|
||||
text: 'Marca al menos una línea para eliminarla.',
|
||||
icon: 'info',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_addEnvioLinea() {
|
||||
if (!this.buscarPedidos.getVal()) {
|
||||
Swal.fire({
|
||||
title: 'Atención!',
|
||||
text: 'Debe seleccionar un pedido antes de añadir una línea de envío.',
|
||||
icon: 'info',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
new Ajax('/logistica/addLineaEnvio', {
|
||||
'envio_id': $('#id').val(),
|
||||
'pedido_id': this.buscarPedidos.getVal(),
|
||||
'direccion': $("#direccion").val()
|
||||
}, {},
|
||||
(response) => {
|
||||
if (response.status) {
|
||||
this.table.draw();
|
||||
this.buscarPedidos.empty();
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Atención!',
|
||||
text: response.message,
|
||||
icon: 'info',
|
||||
confirmButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Ok',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-1',
|
||||
},
|
||||
buttonsStyling: false
|
||||
});
|
||||
}
|
||||
}, (error) => {
|
||||
console.error(error);
|
||||
}).get();
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const dropdown = document.querySelector(".dropdown-language");
|
||||
const activeItem = dropdown.querySelector(".dropdown-menu .dropdown-item");
|
||||
let locale = 'es';
|
||||
if (activeItem) {
|
||||
locale = activeItem.getAttribute("data-language");
|
||||
}
|
||||
|
||||
new Ajax('/translate/getTranslation', { locale: locale, translationFile: ['Albaran'] }, {},
|
||||
function (translations) {
|
||||
window.language = JSON.parse(translations);
|
||||
new EnvioEdit().init();
|
||||
},
|
||||
function (error) {
|
||||
console.log("Error getting translations:", error);
|
||||
}
|
||||
).post();
|
||||
});
|
||||
|
||||
export default EnvioEdit;
|
||||
@ -129,8 +129,10 @@ class PresupuestoAdminEdit {
|
||||
let totalCostes = AutoNumeric.getAutoNumericElement($('#totalCostes')[0]);
|
||||
let envio_base = AutoNumeric.getAutoNumericElement($('#precioEnvios')[0]);
|
||||
let autoTotalAceptado = AutoNumeric.getAutoNumericElement($('#total_aceptado_revisado')[0]);
|
||||
let totalMargenes = AutoNumeric.getAutoNumericElement($('#totalMargenes')[0]);
|
||||
let total_aceptado_revisado = autoTotalAceptado.getNumber();
|
||||
|
||||
|
||||
if (total_aceptado_revisado && total_aceptado_revisado != 0) {
|
||||
const nuevoTotal = totalCostes.getNumber() + envio_base.getNumber();
|
||||
|
||||
@ -140,7 +142,7 @@ class PresupuestoAdminEdit {
|
||||
total_aceptado_revisado = nuevoTotal;
|
||||
}
|
||||
|
||||
totalMargenes = total_aceptado_revisado - nuevoTotal;
|
||||
totalMargenes.set(total_aceptado_revisado - nuevoTotal);
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user