Editar movimientos
This commit is contained in:
@ -0,0 +1,228 @@
|
||||
<script>
|
||||
class MovimientosTable {
|
||||
props
|
||||
columns
|
||||
constructor({ids, eventHandler}) {
|
||||
this.props = {
|
||||
ids,
|
||||
eventHandler,
|
||||
movimientos: [],
|
||||
formatters: {
|
||||
number: new Intl.NumberFormat('es-CL'),
|
||||
date: new Intl.DateTimeFormat('es-CL', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: 'numeric'
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
this.columns = [
|
||||
{title: 'Sigla', defs: {width: 'short', type: 'string'}, searchable: true, export: true}, //0
|
||||
{title: 'Banco', defs: {width: 'long', type: 'string'}, searchable: true, export: true},
|
||||
{title: 'Cuenta', defs: {width: 'short', type: 'string'}, searchable: true, export: true},
|
||||
{title: 'Fecha', defs: {width: 'long', type: 'string'}, searchable: true, export: true},
|
||||
{title: 'ISO Fecha', defs: {visible: false}},
|
||||
{title: 'Mes', defs: {width: 'short', type: 'string'}, searchable: true}, //5
|
||||
{title: 'Año', defs: {width: 'long', type: 'string'}, searchable: true},
|
||||
{title: 'Valor', defs: {className: 'dt-right', width: 'long', type: 'num'}, export: true},
|
||||
{title: 'ISO Valor', defs: {visible: false, type: 'num'}},
|
||||
{title: 'Glosa', defs: {width: 'short', type: 'string'}, export: true},
|
||||
{title: 'Centro de Costo', defs: {width: 'short', type: 'string'}, searchable: true, export: true}, //10
|
||||
{title: 'Categoria', defs: {width: 'short', type: 'string'}},
|
||||
{title: 'Detalle', defs: {width: 'long', type: 'string'}, export: true},
|
||||
{title: 'RUT', defs: {width: 'short', type: 'string'}, export: true},
|
||||
{title: 'Nombre', defs: {width: 'short', type: 'string'}, export: true},
|
||||
{title: 'Identificador', defs: {width: 'short', type: 'string'}, export: true}, //15
|
||||
{title: 'Editar', defs: {width: 'short', type: 'string'}},
|
||||
]
|
||||
const N = this.columns.filter(column => typeof column.defs.visible === 'undefined' || column.defs.visible).length
|
||||
const nShort = this.columns.filter(column => column.defs.width === 'short').length
|
||||
const nLong = this.columns.filter(column => column.defs.width === 'long').length
|
||||
const short = `${(nShort / N).toFixed(2)}%`
|
||||
const long = `${(nLong / N).toFixed(2)}%`
|
||||
|
||||
this.columns = this.columns.map(column => {
|
||||
if (typeof column.defs.width === 'undefined') {
|
||||
return column
|
||||
}
|
||||
switch (column.defs.width) {
|
||||
case 'short':
|
||||
column.defs.width = short
|
||||
break
|
||||
case 'long':
|
||||
column.defs.width = long
|
||||
break
|
||||
}
|
||||
return column
|
||||
})
|
||||
|
||||
const tr = $(this.props.ids.table).find('thead tr')
|
||||
tr.empty()
|
||||
this.columns.forEach(column => {
|
||||
if (typeof column.defs.className === 'undefined') {
|
||||
tr.append(`<th>${column.title}</th>`)
|
||||
return
|
||||
}
|
||||
switch (column.defs.className) {
|
||||
case 'dt-right':
|
||||
tr.append(`<th class="right aligned">${column.title}</th>`)
|
||||
break
|
||||
case 'dt-center':
|
||||
tr.append(`<th class="center aligned">${column.title}</th>`)
|
||||
break
|
||||
default:
|
||||
tr.append(`<th>${column.title}</th>`)
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
let dtD = structuredClone(datatables_defaults)
|
||||
const groupedColumns = Object.groupBy(this.columns, ({defs}) => Object.entries(defs).map((field, value) => `${field}: ${value}`).join(' - '))
|
||||
const columnDefs = Object.values(groupedColumns).map(group => {
|
||||
return {
|
||||
targets: group.map(({title}) => title).map(title => this.columns.map(column => column.title).indexOf(title)),
|
||||
...group[0].defs
|
||||
}
|
||||
})
|
||||
const searchBuilderColumns = this.columns.filter(column => column.searchable)
|
||||
.map(column => column.title).map(title => this.columns.map(column => column.title).indexOf(title))
|
||||
const exportColumns = this.columns.filter(column => column.export)
|
||||
.map(column => column.title).map(title => this.columns.map(column => column.title).indexOf(title))
|
||||
const order = ['Sigla', 'Banco', 'ISO Fecha'].map(title => {
|
||||
return [this.columns.map(column => column.title).indexOf(title), 'asc']
|
||||
})
|
||||
dtD = Object.assign(dtD, {
|
||||
columnDefs,
|
||||
order,
|
||||
language: Object.assign(dtD.language, {
|
||||
searchBuilder: {
|
||||
add: 'Filtrar',
|
||||
condition: 'Comparador',
|
||||
clearAll: 'Resetear',
|
||||
delete: 'Eliminar',
|
||||
deleteTitle: 'Eliminar Titulo',
|
||||
data: 'Columna',
|
||||
left: 'Izquierda',
|
||||
leftTitle: 'Titulo Izquierdo',
|
||||
logicAnd: 'Y',
|
||||
logicOr: 'O',
|
||||
right: 'Derecha',
|
||||
rightTitle: 'Titulo Derecho',
|
||||
title: {
|
||||
0: 'Filtros',
|
||||
_: 'Filtros (%d)'
|
||||
},
|
||||
value: 'Opciones',
|
||||
valueJoiner: 'y'
|
||||
}
|
||||
}),
|
||||
layout: {
|
||||
top1: {
|
||||
searchBuilder: {
|
||||
columns: searchBuilderColumns,
|
||||
}
|
||||
},
|
||||
top1End: {
|
||||
buttons: [
|
||||
{
|
||||
extend: 'excelHtml5',
|
||||
className: 'green',
|
||||
text: 'Exportar a Excel <i class="file excel icon"></i>',
|
||||
title: 'Movimientos Contables',
|
||||
download: 'open',
|
||||
exportOptions: {
|
||||
columns: exportColumns,
|
||||
format: {
|
||||
body: (data, row, column, node) => {
|
||||
if (column === this.columns.map(({title}) => title).indexOf('Fecha')) {
|
||||
return data.split('-').reverse().join('-')
|
||||
}
|
||||
if (column === this.columns.map(({title}) => title).indexOf('Valor')) {
|
||||
return data.replace(/\./g, '')
|
||||
}
|
||||
return data
|
||||
}
|
||||
}
|
||||
},
|
||||
customize: xlsx => {
|
||||
const sheet = xlsx.xl.worksheets['sheet1.xml']
|
||||
const columns = Object.values($('row[r="2"] t', sheet).map((idx, column) => column.textContent))
|
||||
const columnStylesMap = {
|
||||
Valor: '63',
|
||||
Fecha: '15'
|
||||
}
|
||||
Object.entries(columnStylesMap).forEach((column, style) => {
|
||||
const columnIndex = String.fromCharCode('A'.charCodeAt(0) + columns.indexOf(column))
|
||||
$(`c[r^="${columnIndex}"]`, sheet).attr('s', style)
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
data: this.props.movimientos,
|
||||
})
|
||||
this.props.table = new DataTable(this.props.ids.table, dtD)
|
||||
}
|
||||
draw() {
|
||||
return {
|
||||
table: (movimientos) => {
|
||||
this.props.table.clear().rows.add(this.draw().movimientos(movimientos)).draw()
|
||||
$(this.props.ids.buttons.edit).on('click', {handler: this.props.eventHandler}, this.props.eventHandler.edit().movimiento)
|
||||
$(this.props.ids.buttons.remove).on('click', {handler: this.props.eventHandler}, this.props.eventHandler.remove().movimiento)
|
||||
},
|
||||
movimientos: (movimientos) => {
|
||||
const output = []
|
||||
movimientos.forEach(movimiento => {
|
||||
this.draw().movimiento({movimiento, output})
|
||||
})
|
||||
return output
|
||||
},
|
||||
movimiento: ({movimiento, output}) => {
|
||||
const valor = movimiento.abono - movimiento.cargo
|
||||
const fecha = movimiento.fecha
|
||||
|
||||
const buttons = {
|
||||
edit: {
|
||||
icon: 'edit'
|
||||
},
|
||||
remove: {
|
||||
color: ' red',
|
||||
icon: 'trash'
|
||||
}
|
||||
}
|
||||
const buttonsHTML = Object.entries(buttons).map(([action, {color='', icon}]) => {
|
||||
const className = this.props.ids.buttons[action].replace('.', '')
|
||||
return `<button class="ui${color} icon button ${className}" data-id="${movimiento.id}" data-index="${movimiento.index}" data-type="movimiento"><i class="${icon} icon"></i></button>`
|
||||
}).join('')
|
||||
|
||||
const data = {
|
||||
Sigla: movimiento.cuenta.inmobiliaria.sigla,
|
||||
Banco: movimiento.cuenta.banco.nombre,
|
||||
Cuenta: movimiento.cuenta.cuenta,
|
||||
Fecha: this.props.formatters.date.format(fecha),
|
||||
'ISO Fecha': [fecha.getFullYear(), fecha.getMonth() + 1, fecha.getDate()].join('-'),
|
||||
Mes: fecha.getMonth() + 1,
|
||||
'Año': fecha.getFullYear(),
|
||||
Valor: this.props.formatters.number.format(valor),
|
||||
'ISO Valor': valor,
|
||||
Glosa: movimiento.glosa,
|
||||
'Centro de Costo': (movimiento.detalles) ? movimiento.detalles.centro_costo.id : '',
|
||||
Categoria: (movimiento.detalles) ? movimiento.detalles.categoria : '',
|
||||
Detalle: (movimiento.detalles) ? movimiento.detalles.detalle : '',
|
||||
RUT: (movimiento.detalles && movimiento.detalles.digito) ? `${this.props.formatters.number.format(movimiento.detalles.rut)}-${movimiento.detalles.digito}` : '',
|
||||
Nombre: (movimiento.detalles) ? movimiento.detalles.nombres : '',
|
||||
Identificador: (movimiento.detalles) ? movimiento.detalles.identificador : '',
|
||||
Editar: buttonsHTML,
|
||||
}
|
||||
const values = []
|
||||
this.columns.forEach(column => {
|
||||
values.push(data[column.title])
|
||||
})
|
||||
output.push(values)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
Reference in New Issue
Block a user