Files
safekat/httpdocs/assets/js/safekat/pages/plantillasTarifasCliente/edit.js
2025-01-03 16:03:54 +01:00

786 lines
30 KiB
JavaScript

import Table from '../../components/table.js';
import TableEditor from '../../components/tableEditor.js';
import ModalYesNo from '../../components/modalYesNo.js';
import Ajax from '../../components/ajax.js';
import { getToken } from '../../common/common.js';
class PlantillasTarifasClienteForm {
constructor() {
this.domItem = $('.card-body');
this.plantillaId = window.location.href.split("/").pop();
this.csrf_token = getToken();
this.csrf_hash = $('#mainContainer').find('input[name="' + this.csrf_token + '"]').val();
this.btnApply = $('#btnApply');
this.btnUndo = $('#btnUndo');
this.tablePlantilla = null;
this.modalYesNo = null;
this.localEditor = null;
this.ajaxEditor = null;
this.rows = [];
this.rowsDeleted = [];
this.rowsEdited = [];
this.rowsCreated = [];
}
init() {
const self = this;
this.headerSearcher();
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();
new Ajax(
'/clienteplantillaprecioslineas/getrows',
{
[this.csrf_token]: this.csrf_hash,
plantilla_id: this.plantillaId
},
{},
(response) => {
self.rows = response.data;
},
(error) => {
console.log(error);
}
).post();
// Editar en linea la fila
this.tablePlantilla.table.on('click', 'tbody span.edit', function (e) {
const row = $(this).closest('tr');
// Iniciar la edición en línea para todas las celdas de la fila
self.localEditor.editor.inline(
self.tablePlantilla.table.cells(row, '*').nodes(),
{
cancelHtml: '<a href="javascript:void(0);"><i class="ti ti-x"></i></a>',
submitHtml: '<a href="javascript:void(0);"><i class="ti ti-device-floppy"></i></a>',
cancelTrigger: row.find('span.cancel')[0],
submitTrigger: row.find('span.edit')[0],
submit: 'allIfChanged',
drawType: 'none'
}
);
});
this.tablePlantilla.table.on('draw.dt', function (e) {
self.tablePlantilla.table.rows().every(function (rowIdx, tableLoop, rowLoop) {
var row = this.data();
if (self.rowsDeleted.includes(row.id)) {
$('#' + row.id).css('background-color', '#ffcccc');
$('#' + row.id).addClass('row-deleted');
$('#' + row.id).find('span.edit').addClass('d-none');
$('#' + row.id).find('.btn-delete-' + self.tablePlantilla.getAlias()).addClass('d-none');
}
else if (self.rowsEdited.includes(row.id)) {
$('#' + row.id).css('background-color', '#E9DEAC');
$('#' + row.id).addClass('row-edited');
}
else if (row.id === '') {
self.tablePlantilla.table.row(rowIdx).nodes().to$().addClass('row-created');
self.tablePlantilla.table.row(rowIdx).nodes().to$().css('background-color', '#C9E2C7');
}
});
});
this.tablePlantilla.table.on('click', '.btn-delete-' + this.tablePlantilla.getAlias(), function (e) {
self.tablePlantilla.table.settings()[0].oFeatures.bServerSide = false;
if ($(this).closest('tr').hasClass('row-created')) {
$(this).closest('tr').remove();
}
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');
if (self.rowsDeleted.indexOf(row) == -1)
self.rowsDeleted.push(row);
});
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');
});
}
#initEditor() {
const self = this;
const tipo_linea = [
{ label: window.language.ClientePrecios.interior, value: 'interior' },
{ label: window.language.ClientePrecios.cubierta, value: 'cubierta' },
{ label: window.language.ClientePrecios.sobrecubierta, value: 'sobrecubierta' }
];
const tipo_maquina = [
{ label: window.language.ClientePrecios.toner, value: 'toner' },
{ label: window.language.ClientePrecios.inkjet, value: 'inkjet' },
];
const tipo_impresion = [
{ label: window.language.ClientePrecios.negro, value: 'negro' },
{ label: window.language.ClientePrecios.negrohq, value: 'negrohq' },
{ label: window.language.ClientePrecios.color, value: 'color' },
{ label: window.language.ClientePrecios.colorhq, value: 'colorhq' },
];
const editorFields = [
{
name: "id",
type: "readonly",
def: ''
}, {
name: "tipo",
type: "select",
options: tipo_linea
}, {
name: "tipo_maquina",
type: "select",
options: tipo_maquina
}, {
name: "tipo_impresion",
type: "select",
options: tipo_impresion
}, {
name: "tiempo_min"
}, {
name: "tiempo_max"
}, {
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'),
'',
{},
'id',
editorFields);
this.localEditor.init();
this.ajaxEditor = new TableEditor(
$('#tableOfPlantillasPreciosLineas'),
'/clienteplantillaprecioslineas/datatable_editor',
{ [this.csrf_token]: this.csrf_hash },
'id',
editorFields);
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);
if (json.data[0]) {
self.rowsCreated.push(json.data[0]);
}
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) {
// Actualizar los datos de la fila
self.tablePlantilla.table.row('#' + data.id).data({
id: data.id,
tipo: data.tipo,
tipo_maquina: data.tipo_maquina,
tipo_impresion: data.tipo_impresion,
tiempo_min: data.tiempo_min,
tiempo_max: data.tiempo_max,
precio_hora: data.precio_hora,
margen: data.margen,
user_updated_id: data.user_updated,
user_updated: data.user_updated,
updated_at: data.updated_at
});
self.btnApply.removeClass('d-none');
self.btnUndo.removeClass('d-none');
// modificar la fila en rows que tenga el mismo id
let index = self.rows.findIndex(r => r.id == data.id);
if (index != -1) {
self.rows[index] = data;
}
if (self.rowsEdited.indexOf(row.id) == -1)
self.rowsEdited.push(row.id);
}
});
this.ajaxEditor.editor.on('preEdit', function (e, d, type) {
self.tablePlantilla.table.settings()[0].oFeatures.bServerSide = true;
});
this.ajaxEditor.editor.on('preCreate', function (e, d, type) {
self.tablePlantilla.table.settings()[0].oFeatures.bServerSide = true;
});
}
#applyChanges() {
const self = this;
try {
self.modalYesNo.hide();
$('#loader').modal('show');
if (this.rowsEdited.length != 0) {
let error = self.#checkInterval(self.rowsEdited);
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 (this.rowsCreated.length != 0) {
let error = self.#checkInterval(self.rowsCreated);
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 (this.rowsDeleted.length != 0) {
let rowIds = self.rowsDeleted.map(row => '#' + row);
// 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 (this.rowsEdited.length != 0) {
let rowIds = this.rowsEdited.map(row => '#' + this.tablePlantilla.table.row(row).data().id);
let updatedFields = {};
// Iterar sobre las filas editadas y construir el objeto actualizado
this.rowsEdited.forEach(row2Edit => {
const row = this.tablePlantilla.table.row(row2Edit).data();
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 (this.rowsCreated.length != 0) {
let updatedFields = {};
let count = 0;
// Iterar sobre las filas editadas y construir el objeto actualizado
this.rowsCreated.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(self.rowsCreated.length, false).multiSet(updatedFields)
.submit()
}
new Ajax(
'/clienteprecios/update',
{
[self.csrf_token]: self.csrf_hash,
plantilla_id: self.plantillaId
},
{},
() => {
self.tablePlantilla.table.settings()[0].oFeatures.bServerSide = true;
new Ajax(
'/clienteplantillaprecioslineas/getrows',
{
[self.csrf_token]: self.csrf_hash,
plantilla_id: self.plantillaId
},
{},
(response) => {
self.rows = response.data;
self.rowsDeleted = [];
self.rowsEdited = [];
self.rowsCreated = [];
self.tablePlantilla.table.clearPipeline();
self.tablePlantilla.table.draw(true);
$('#loader').modal('hide');
},
(error) => {
console.log(error);
$('#loader').modal('hide');
}).post();
},
(error) => {
console.log(error);
$('#loader').modal('hide');
}
).post();
} catch (e) {
console.log(e);
$('#loader').modal('hide');
}
}
#checkInterval(rows) {
for (let row of this.rows) {
let rowData = this.tablePlantilla.table.row(row).data();
for (let row2Check of rows) {
let checkRow = this.tablePlantilla.table.row(row2Check).data();
if (checkRow.tiempo_min > checkRow.tiempo_max) {
return 1;
}
if (checkRow.id == rowData.id) continue;
if (rowData.tipo == checkRow.tipo && rowData.tipo_maquina == checkRow.tipo_maquina && rowData.tipo_impresion == checkRow.tipo_impresion) {
// check overlapping intervals
if (Math.max(checkRow.tiempo_max, rowData.tiempo_max) - Math.min(checkRow.tiempo_min, rowData.tiempo_min)
<= Math.min(checkRow.tiempo_max - checkRow.tiempo_min) + Math.min(rowData.tiempo_max - rowData.tiempo_min))
return 2;
}
}
}
return 0;
}
#initTable() {
const self = this;
const columns =
[
{ 'data': 'id' },
{
'data': 'tipo',
'render': function (data, type, row, meta) {
if (data == 'interior')
return window.language.ClientePrecios.interior;
else if (data == 'cubierta')
return window.language.ClientePrecios.cubierta;
else if (data == 'sobrecubierta')
return window.language.ClientePrecios.sobrecubierta;
}
},
{
'data': 'tipo_maquina',
'render': function (data, type, row, meta) {
if (data == 'toner')
return window.language.ClientePrecios.toner;
else if (data == 'inkjet')
return window.language.ClientePrecios.inkjet;
}
},
{
'data': 'tipo_impresion',
'render': function (data, type, row, meta) {
if (data == 'negro')
return window.language.ClientePrecios.negro;
else if (data == 'negrohq')
return window.language.ClientePrecios.negrohq;
else if (data == 'color')
return window.language.ClientePrecios.color;
else if (data == 'colorhq')
return window.language.ClientePrecios.colorhq;
}
},
{ 'data': 'tiempo_min' },
{ 'data': 'tiempo_max' },
{ 'data': 'precio_hora' },
{ 'data': 'margen' },
{ 'data': 'user_updated' },
{ 'data': 'updated_at' },
];
const actions = ['edit', 'delete', 'cancel'];
this.tablePlantilla = new Table(
$('#tableOfPlantillasPreciosLineas'),
'plantillaTarifasCliente',
'/clienteplantillaprecioslineas/datatable',
columns,
[
{ name: 'plantilla_id', value: this.plantillaId }
], 'id'
);
this.tablePlantilla.init({
actions: actions,
colVisibility: false,
buttonsExport: true,
buttonNewWithEditor: true,
editor: self.localEditor.editor,
});
this.tablePlantilla.table.on('init.dt', function () {
self.tablePlantilla.table.page.len(50).draw();
});
}
headerSearcher() {
const self = this;
$('#tableOfPlantillasPreciosLineas thead tr').clone(false).appendTo('#tableOfPlantillasPreciosLineas thead');
$('#tableOfPlantillasPreciosLineas thead tr:eq(1) th').each(function (i) {
if (!$(this).hasClass("noFilter")) {
if (i == 1) {
// Agregar un selector en la segunda columna
$(this).html('<select class="form-control" style="min-width:100px;max-width:120px;font-size:0.8rem !important;"></select>');
// Agregar opciones al selector
var selector = $('select', this);
selector.append('<option value="">Todos</option>'); // Opción vacía
selector.append('<option value="interior">Interior</option>');
selector.append('<option value="cubierta">Cubierta</option>');
selector.append('<option value="sobrecubierta">Sobrecubierta</option>');
selector.on('change', function () {
if (!self.tablePlantilla.table.settings()[0].oFeatures.bServerSide) {
var val = $(this).val(); // El valor seleccionado
var searchVal = "";
// Determinar el texto renderizado que debe buscarse
if (val === "interior") {
searchVal = window.language.ClientePrecios.interior;
} else if (val === "cubierta") {
searchVal = window.language.ClientePrecios.cubierta;
} else if (val === "sobrecubierta") {
searchVal = window.language.ClientePrecios.sobrecubierta;
}
const allRows = [...self.rows, ...self.rowsCreated.map(row => row.data())];
// Actualizar los datos de la tabla
self.tablePlantilla.table.clear().rows.add(allRows).draw();
// Aplicar el filtro sobre los valores renderizados
self.tablePlantilla.table.column(i).search(searchVal ? '^' + searchVal + '$' : '', true, false).draw();
}
else {
// Aplicar el filtro sobre los valores renderizados
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
self.tablePlantilla.table.column(i).search(val).draw();
}
});
}
else if (i == 2) {
// Agregar un selector en la tercera columna
$(this).html('<select class="form-control" style="min-width:100px;max-width:120px;font-size:0.8rem !important;"></select>');
// Agregar opciones al selector
var selector = $('select', this);
selector.append('<option value="">Todos</option>'); // Opción vacía
selector.append('<option value="toner">Toner</option>');
selector.append('<option value="inkjet">Inkjet</option>');
selector.on('change', function () {
if (!self.tablePlantilla.table.settings()[0].oFeatures.bServerSide) {
var val = $(this).val(); // El valor seleccionado
var searchVal = "";
// Determinar el texto renderizado que debe buscarse
if (val === "toner") {
searchVal = window.language.ClientePrecios.toner;
} else if (val === "inkjet") {
searchVal = window.language.ClientePrecios.inkjet;
}
const allRows = [...self.rows, ...self.rowsCreated.map(row => row.data())];
// Actualizar los datos de la tabla
self.tablePlantilla.table.clear().rows.add(allRows).draw();
// Aplicar el filtro sobre los valores renderizados
self.tablePlantilla.table.column(i).search(val).draw();
}
else {
// Aplicar el filtro sobre los valores renderizados
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
self.tablePlantilla.table.column(i).search(val).draw();
}
});
}
else if (i == 3) {
// Agregar un selector en la cuarta columna
$(this).html('<select class="form-control" style="min-width:100px;max-width:120px;font-size:0.8rem !important;"></select>');
// Agregar opciones al selector
var selector = $('select', this);
selector.append('<option value="">Todos</option>'); // Opción vacía
selector.append('<option value="negro">' + window.language.ClientePrecios.negro + '</option>');
selector.append('<option value="color">' + window.language.ClientePrecios.color + '</option>');
selector.append('<option value="negrohq">' + window.language.ClientePrecios.negrohq + '</option>');
selector.append('<option value="colorhq">' + window.language.ClientePrecios.colorhq + '</option>');
selector.on('change', function () {
if (!self.tablePlantilla.table.settings()[0].oFeatures.bServerSide) {
var val = $(this).val(); // El valor seleccionado
var searchVal = "";
// Determinar el texto renderizado que debe buscarse
if (val === "negro") {
searchVal = window.language.ClientePrecios.negro;
} else if (val === "negrohq") {
searchVal = window.language.ClientePrecios.negrohq;
} else if (val === "color") {
searchVal = window.language.ClientePrecios.color;
} else if (val === "colorhq") {
searchVal = window.language.ClientePrecios.colorhq;
}
const allRows = [...self.rows, ...self.rowsCreated.map(row => row.data())];
// Actualizar los datos de la tabla
self.tablePlantilla.table.clear().rows.add(allRows).draw();
self.tablePlantilla.table.column(i).search(searchVal ? '^' + searchVal + '$' : '', true, false).draw();
}
else {
// Aplicar el filtro sobre los valores renderizados
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
self.tablePlantilla.table.column(i).search(val).draw();
}
});
}
else {
$(this).html('<input type="text" class="form-control " style="min-width:100px;max-width:120px;font-size:0.8rem !important;" />');
$('input', this).on('change clear', function () {
if (self.tablePlantilla.table.column(i).search() !== this.value) {
if (!self.tablePlantilla.table.settings()[0].oFeatures.bServerSide) {
const allRows = [...self.rows, ...self.rowsCreated.map(row => row.data())];
// Actualizar los datos de la tabla
self.tablePlantilla.table.clear().rows.add(allRows).draw();
}
self.tablePlantilla.table
.column(i)
.search(this.value)
.draw();
}
});
}
}
else {
$(this).html('<span></span>');
}
});
}
}
document.addEventListener('DOMContentLoaded', function () {
const locale = document.querySelector('meta[name="locale"]').getAttribute('content');
new Ajax('/translate/getTranslation', { locale: locale, translationFile: ['ClientePrecios'] }, {},
function (translations) {
window.language = JSON.parse(translations);
new PlantillasTarifasClienteForm().init();
},
function (error) {
console.log("Error getting translations:", error);
}
).post();
});