terminado

This commit is contained in:
2024-12-05 00:15:08 +01:00
parent 73821603b4
commit 9fa31c5d8e
9 changed files with 383 additions and 63 deletions

View File

@ -0,0 +1,69 @@
class ModalYesNo {
constructor(text= "", alias = "") {
this.modalId = alias !== "" ? `yesNoModal-${alias}`: 'yesNoModal';
this.btnCancelId = alias !== "" ? `btnCancelModal-${alias}` : 'btnCancelModal';
this.btnConfirmId = alias !== "" ? `btnYesModal-${alias}` : 'btnYesModal';
this.modalHtml = `
<div class="modal fade" id="${this.modalId}" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="${this.modalId}Label" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="${this.modalId}Label">Aplicar cambios</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
${text}
</div>
<div class="modal-footer">
<button id=${this.btnCancelId} type="button" class="btn btn-default" data-bs-dismiss="modal">Cancelar</button>
<a id=${this.btnConfirmId} href="javascript:void(0);" class="btn btn-danger ">Si</a>
</div><!--//.modal-footer -->
</div><!--//.modal-content -->
</div><!--//.modal-dialog -->
</div><!--//.modal -->
`;
}
init() {
// Insertar el modal en el body del documento si no existe
if (!document.getElementById(this.modalId)) {
document.body.insertAdjacentHTML('beforeend', this.modalHtml);
}
document.getElementById(this.btnCancelId).addEventListener('click', () => {
const modal = new bootstrap.Modal(document.getElementById(this.modalId));
modal.hide();
});
}
getModalId() {
return '#' + this.modalId;
}
// Método para mostrar el modal
show(callback) {
// Mostrar el modal usando Bootstrap
const modal = new bootstrap.Modal(document.getElementById(this.modalId));
modal.show();
// Configurar el evento de confirmación de eliminación
document.getElementById(this.btnConfirmId).addEventListener('click', () => {
callback(); // Llamar al callback que el usuario haya proporcionado
modal.hide(); // Cerrar el modal
});
}
// Método para ocultar el modal si es necesario
hide() {
const modal = new bootstrap.Modal(document.getElementById(this.modalId));
modal.hide();
}
}
export default ModalYesNo;

View File

@ -49,6 +49,7 @@ let Table = function (
columns.push(
{
'data': self.actionBtns.bind(self), // Vincular correctamente el contexto
'defaultContent': '<span class="edit"><a href="javascript:void(0);"><i class="ti ti-pencil ti-sm btn-edit mx-2"></i></a></span><span class="cancel"></span><a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete mx-2"></i></a>',
'className': 'row-edit dt-center',
}
);
@ -92,7 +93,7 @@ let Table = function (
autoWidth: true,
responsive: true,
scrollX: true,
stateSave: false,
stateSave: true,
lengthMenu: [5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500],
order: order,
orderCellsTop: true,

View File

@ -1,6 +1,6 @@
import Table from '../../components/table.js';
import TableEditor from '../../components/tableEditor.js';
import ConfirmDeleteModal from '../../components/ConfirmDeleteModal.js';
import ModalYesNo from '../../components/modalYesNo.js';
import Ajax from '../../components/ajax.js';
import { getToken } from '../../common/common.js';
@ -16,15 +16,13 @@ class PlantillasTarifasClienteForm {
this.csrf_hash = $('#mainContainer').find('input[name="' + this.csrf_token + '"]').val();
this.btnApply = $('#btnApply');
this.btnUndo = $('#btnUndo');
this.tablePlantilla = null;
this.deleteModal = null;
this.modalYesNo = null;
this.localEditor = null;
this.ajaxEditor = null;
this.changedRows = [];
this.deletedRows = [];
}
init() {
@ -33,12 +31,17 @@ class PlantillasTarifasClienteForm {
this.headerSearcher();
this.deleteModal = new ConfirmDeleteModal('plantillasTarifasCliente');
this.deleteModal.init();
this.modalYesNo = new ModalYesNo(
"Aplicar los cambios afectarán a <b>TODOS</b> los clientes que tengan asociada esta plantilla de precios.<br>" +
"¿Esta seguro de que deseas aplicar los cambios?",
);
this.modalYesNo.init();
this.#initEditor();
this.#initTable();
this.#initEditor();
// Editar en linea la fila
this.tablePlantilla.table.on('click', 'tbody span.edit', function (e) {
@ -58,6 +61,37 @@ class PlantillasTarifasClienteForm {
}
);
});
this.tablePlantilla.table.on('click', '.btn-delete-' + this.tablePlantilla.getAlias(), function (e) {
self.tablePlantilla.table.settings()[0].oFeatures.bServerSide = false;
const row = $(this).attr('data-id');
self.btnApply.removeClass('d-none');
self.btnUndo.removeClass('d-none');
$('#' + row).css('background-color', '#ffcccc');
$('#' + row).addClass('row-deleted');
// find closest span.edit
$('#' + row).find('span.edit').addClass('d-none');
$('#' + row).find('.btn-delete-' + self.tablePlantilla.getAlias()).addClass('d-none');
});
this.btnApply.on('click', function (e) {
self.modalYesNo.show(self.#applyChanges.bind(self));
});
this.btnUndo.on('click', function (e) {
self.tablePlantilla.table.settings()[0].oFeatures.bServerSide = true;
self.tablePlantilla.table.clearPipeline();
self.tablePlantilla.table.draw();
self.btnApply.addClass('d-none');
self.btnUndo.addClass('d-none');
});
}
@ -86,7 +120,8 @@ class PlantillasTarifasClienteForm {
const editorFields = [
{
name: "id",
type: "readonly"
type: "readonly",
def: new Date().toISOString().slice(0, 19).replace('T', ' ')
}, {
name: "tipo",
type: "select",
@ -107,7 +142,26 @@ class PlantillasTarifasClienteForm {
name: "precio_hora"
}, {
name: "margen"
},
}, {
name: "user_updated",
type: "hidden",
def: ''
}, {
name: "updated_at",
type: "hidden",
def: ''
}, {
name: "deleted_at",
type: "hidden",
}, {
name: "is_deleted",
type: "hidden",
}, {
name: "plantilla_id",
type: "hidden",
def: this.plantillaId
}
];
this.localEditor = new TableEditor(
$('#tableOfPlantillasPreciosLineas'),
@ -127,14 +181,42 @@ class PlantillasTarifasClienteForm {
this.ajaxEditor.init();
this.localEditor.editor.on('preCreate', function (e, d, type) {
self.tablePlantilla.table.settings()[0].oFeatures.bServerSide = false;
});
// add class and change background color of row in postCreate
this.localEditor.editor.on('postCreate', function (e, json, data) {
const row = self.tablePlantilla.table.row('#' + json.data[0].id);
let rowNode = row.node();
$(rowNode).addClass('row-created');
$(rowNode).css('background-color', '#C9E2C7');
self.btnApply.removeClass('d-none');
self.btnUndo.removeClass('d-none');
});
this.localEditor.editor.on('postEdit', function (e, json, data) {
self.tablePlantilla.table.settings()[0].oFeatures.bServerSide = false;
let row = self.tablePlantilla.table.row('#' + data.id);
let rowNode = row.node();
// Añadir una clase usando jQuery
if (!$(rowNode).hasClass('row-created')) {
$(rowNode).addClass('row-edited');
$(rowNode).css('background-color', '#E9DEAC');
}
if (row.length) {
let rowData = row.data();
// Actualizar los datos de la fila
self.tablePlantilla.table.row('#' + data.id).data({
id: data.id,
@ -144,56 +226,199 @@ class PlantillasTarifasClienteForm {
tiempo_min: data.tiempo_min,
tiempo_max: data.tiempo_max,
precio_hora: data.precio_hora,
margen: "150",
margen: data.margen,
user_updated_id: data.user_updated,
user_updated: data.user_updated,
updated_at: data.updated_at
});
});
// check if this id exists
if (!self.changedRows.includes(data.id))
self.changedRows.push(data.id);
self.btnApply.removeClass('d-none');
self.btnUndo.removeClass('d-none');
}
});
/*
this.editorTarifas.editor.on('preSubmit', function (e, d, type) {
if (type === 'create') {
d.data[0]['cliente_id'] = self.clienteId;
}
this.ajaxEditor.editor.on('preEdit', function (e, d, type) {
self.tablePlantilla.table.settings()[0].oFeatures.bServerSide = true;
});
this.editorTarifas.editor.on('submitSuccess', function (e, json, data, action) {
self.tablePlantilla.table.clearPipeline();
self.tablePlantilla.table.draw();
this.ajaxEditor.editor.on('preCreate', function (e, d, type) {
self.tablePlantilla.table.settings()[0].oFeatures.bServerSide = true;
});
this.editorTarifas.editor.on('postEdit', function (e, json, data, action) {
self.#borrarPlantillaTarifa(self.clienteId);
self.selectorPlantilla.offChange();
self.selectorPlantilla.setOption(0, 'Personalizado');
self.selectorPlantilla.onChange(self.#changePlantilla.bind(this));
})
this.editorTarifas.editor.on('postCreate', function (e, json, data, action) {
self.#borrarPlantillaTarifa(self.clienteId);
self.selectorPlantilla.offChange();
self.selectorPlantilla.setOption(0, 'Personalizado');
self.selectorPlantilla.onChange(self.#changePlantilla.bind(this));
})
this.editorTarifas.editor.on('postCancel', function (e, json, data) {
// Restaurar botones de acción por fila
self.tablePlantilla.table.rows().nodes().each(function (node) {
$(node).find('span.edit').removeClass('d-none');
$(node).find('span.cancel, span.submit').addClass('d-none');
});
});*/
}
#applyChanges() {
const self = this;
const deletedRows = self.tablePlantilla.table.rows('.row-deleted').data().toArray();
const editedRows = self.tablePlantilla.table.rows('.row-edited').data().toArray();
const createdRows = self.tablePlantilla.table.rows('.row-created').data().toArray();
if (editedRows.length != 0) {
let error = self.#checkInterval(editedRows);
if (error) {
if (error == 1) {
popErrorAlert('Hay filas EDITADAS con el tiempo mínimo mayor que el tiempo máximo');
}
else if (error == 2) {
popErrorAlert('Hay filas EDITADAS con intervalos [Tiempo min., Tiempo max] solapados');
}
return;
}
}
if (createdRows.length != 0) {
let error = self.#checkInterval(editedRows);
if (error) {
if (error == 1) {
popErrorAlert('Hay filas CREADAS con el tiempo mínimo mayor que el tiempo máximo');
}
else if (error == 2) {
popErrorAlert('Hay filas CREADAS con intervalos [Tiempo min., Tiempo max] solapados');
}
return;
}
}
if (deletedRows.length != 0) {
let rowIds = deletedRows.map(row => '#' + row.id);
// Iterar sobre cada fila y actualizar los campos necesarios
self.ajaxEditor.editor
.edit(rowIds, false) // Editar múltiples filas (acepta un array)
.multiSet({
deleted_at: new Date().toISOString().slice(0, 19).replace('T', ' '),
is_deleted: 1
}) // Establecer valores comunes para todas las filas
.submit();
}
if (editedRows.length != 0) {
let rowIds = editedRows.map(row => '#' + row.id);
let updatedFields = {};
// Iterar sobre las filas editadas y construir el objeto actualizado
editedRows.forEach(row => {
updatedFields['tipo'] = updatedFields['tipo'] || {};
updatedFields['tipo'][row.id] = row.tipo;
updatedFields['tipo_maquina'] = updatedFields['tipo_maquina'] || {};
updatedFields['tipo_maquina'][row.id] = row.tipo_maquina;
updatedFields['tipo_impresion'] = updatedFields['tipo_impresion'] || {};
updatedFields['tipo_impresion'][row.id] = row.tipo_impresion;
updatedFields['tiempo_min'] = updatedFields['tiempo_min'] || {};
updatedFields['tiempo_min'][row.id] = row.tiempo_min;
updatedFields['tiempo_max'] = updatedFields['tiempo_max'] || {};
updatedFields['tiempo_max'][row.id] = row.tiempo_max;
updatedFields['precio_hora'] = updatedFields['precio_hora'] || {};
updatedFields['precio_hora'][row.id] = row.precio_hora;
updatedFields['margen'] = updatedFields['margen'] || {};
updatedFields['margen'][row.id] = row.margen;
});
self.ajaxEditor.editor.edit(rowIds, false).multiSet(updatedFields)
.submit()
}
if (createdRows.length != 0) {
let updatedFields = {};
let count = 0;
// Iterar sobre las filas editadas y construir el objeto actualizado
createdRows.forEach(row => {
updatedFields['id'] = updatedFields['id'] || {};
updatedFields['id'][row.id] = count;
updatedFields['tipo'] = updatedFields['tipo'] || {};
updatedFields['tipo'][count] = row.tipo;
updatedFields['tipo_maquina'] = updatedFields['tipo_maquina'] || {};
updatedFields['tipo_maquina'][count] = row.tipo_maquina;
updatedFields['tipo_impresion'] = updatedFields['tipo_impresion'] || {};
updatedFields['tipo_impresion'][count] = row.tipo_impresion;
updatedFields['tiempo_min'] = updatedFields['tiempo_min'] || {};
updatedFields['tiempo_min'][count] = row.tiempo_min;
updatedFields['tiempo_max'] = updatedFields['tiempo_max'] || {};
updatedFields['tiempo_max'][count] = row.tiempo_max;
updatedFields['precio_hora'] = updatedFields['precio_hora'] || {};
updatedFields['precio_hora'][count] = row.precio_hora;
updatedFields['margen'] = updatedFields['margen'] || {};
updatedFields['margen'][count] = row.margen;
updatedFields['plantilla_id'] = updatedFields['plantilla_id'] || {};
updatedFields['plantilla_id'][count] = self.plantillaId;
count++;
});
self.ajaxEditor.editor.create(createdRows.length, false).multiSet(updatedFields)
.submit()
}
if (deletedRows.length != 0 || editedRows.length != 0 || createdRows.length != 0) {
new Ajax(
'/clienteprecios/update',
{
[self.csrf_token]: self.csrf_hash,
plantilla_id: self.plantillaId
},
{},
() => {
window.location.reload();
},
(error) => {
console.log(error);
}
).post();
}
}
#checkInterval(rows) {
// obtener todas las filas de la tabla que no tengan la clase row-deleted
let rowsNotDeletedDT = this.tablePlantilla.table.rows(':not(.row-deleted)').nodes().toArray();
for (let row of rowsNotDeletedDT) {
let rowData = this.tablePlantilla.table.row(row).data();
for (let rowEdited of rows) {
if (rowEdited.tiempo_min > rowEdited.tiempo_max) {
return 1;
}
if (rowData.tipo == rowEdited.tipo && rowData.tipo_maquina == rowEdited.tipo_maquina && rowData.tipo_impresion == rowEdited.tipo_impresion) {
// check overlapping intervals
if (rowEdited.tiempo_min >= rowData.tiempo_min || rowEdited.tiempo_min <= rowData.tiempo_max) {
return 2;
}
}
}
}
return 0;
}
#initTable() {
const self = this;
@ -252,7 +477,7 @@ class PlantillasTarifasClienteForm {
columns,
[
{ name: 'plantilla_id', value: this.plantillaId }
],'id'
], 'id'
);
@ -260,6 +485,8 @@ class PlantillasTarifasClienteForm {
actions: actions,
colVisibility: false,
buttonsExport: true,
buttonNewWithEditor: true,
editor: self.localEditor.editor,
});