395 lines
17 KiB
PHP
395 lines
17 KiB
PHP
@extends('layout.base')
|
|
|
|
@section('page_content')
|
|
<div class="ui container">
|
|
<h1 class="ui header">
|
|
Importar Cartola Diaria
|
|
</h1>
|
|
<div class="ui grid">
|
|
<div class="right aligned sixteen wide column">
|
|
<button class="ui green icon button" id="add_button">
|
|
Agregar
|
|
<i class="plus icon"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<form class="ui form" id="cartola_form">
|
|
</form>
|
|
<div class="ui two columns grid">
|
|
<div class="column">
|
|
<button class="ui icon button" id="process_button">
|
|
<i class="file excel icon"></i>
|
|
Procesar
|
|
</button>
|
|
</div>
|
|
<div class="right aligned column">
|
|
<div class="ui inline active loader" id="loader"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table class="ui celled table" id="movimientos" style="display: none;">
|
|
<thead>
|
|
<tr>
|
|
<th>Sigla</th>
|
|
<th>Fecha</th>
|
|
<th>Glosa</th>
|
|
<th class="right aligned">Cargo</th>
|
|
<th class="right aligned">Abono</th>
|
|
<th class="right aligned">Saldo</th>
|
|
<th class="center aligned">Centro de Costo</th>
|
|
<th>Categoría</th>
|
|
<th>Detalle</th>
|
|
<th>RUT</th>
|
|
<th>Nombres</th>
|
|
<th class="center aligned">Identificador</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
</tbody>
|
|
</table>
|
|
@endsection
|
|
|
|
@push('page_scripts')
|
|
<script>
|
|
class Cartola {
|
|
props
|
|
ids
|
|
constructor({index, ids}) {
|
|
this.props = {
|
|
index
|
|
}
|
|
this.ids = ids
|
|
}
|
|
get sociedad() {
|
|
return $(`#${this.ids.sociedad}${this.props.index}`).dropdown('get value')
|
|
}
|
|
get banco() {
|
|
return $(`#${this.ids.banco}${this.props.index}`).dropdown('get value')
|
|
}
|
|
get mes() {
|
|
return $(`#${this.ids.mes}${this.props.index}`).calendar('get date')
|
|
}
|
|
get file() {
|
|
return $(`#archivo${this.props.index}`)[0].files[0]
|
|
}
|
|
get data() {
|
|
return {
|
|
sociedad_rut: this.sociedad,
|
|
cuenta_id: this.banco,
|
|
mes: [this.mes.getFullYear(), this.mes.getMonth() + 1, 1].join('-'),
|
|
file: this.file,
|
|
index: this.props.index
|
|
}
|
|
}
|
|
draw({sociedades}) {
|
|
const output = [
|
|
`<div class="fields" data-idx="${this.props.index}">`,
|
|
'<div class="five wide field">',
|
|
'<label>Sociedad</label>',
|
|
`<div class="ui search selection dropdown" id="${this.ids.sociedad}${this.props.index}">`,
|
|
`<input type="hidden" name="sociedad_rut${this.props.index}" />`,
|
|
'<i class="dropdown icon"></i>',
|
|
'<div class="default text">Sociedad</div>',
|
|
'<div class="menu">',
|
|
...sociedades.map(sociedad => {
|
|
return [
|
|
`<div class="item" data-value="${sociedad.rut}">${sociedad.razon}</div>`
|
|
].join("\n")
|
|
}),
|
|
'</div>',
|
|
'</div>',
|
|
'</div>',
|
|
'<div class="four wide field">',
|
|
'<label>Banco</label>',
|
|
`<div class="ui search selection dropdown" id="${this.ids.banco}${this.props.index}">`,
|
|
`<input type="hidden" name="banco_id${this.props.index}" />`,
|
|
'<i class="dropdown icon"></i>',
|
|
'<div class="default text">Banco</div>',
|
|
'<div class="menu"></div>',
|
|
'</div>',
|
|
'</div>',
|
|
'<div class="field">',
|
|
'<label>Mes</label>',
|
|
`<div class="ui calendar" id="${this.ids.mes}${this.props.index}">`,
|
|
'<div class="ui input left icon">',
|
|
'<i class="calendar icon"></i>',
|
|
`<input type="text" name="mes${this.props.index}" placeholder="Mes" />`,
|
|
'</div>',
|
|
'</div>',
|
|
'</div>',
|
|
'<div class="field">',
|
|
'<label>Archivo</label>',
|
|
`<input type="file" class="ui invisible file input" name="archivo${this.props.index}" id="archivo${this.props.index}" />`,
|
|
`<label for="archivo${this.props.index}" class="ui icon button" id="archivo_button">`,
|
|
'<i class="file icon"></i>',
|
|
'</label>',
|
|
'</div>',
|
|
]
|
|
if (this.props.index > 1) {
|
|
output.push(...[
|
|
'<div class="field">',
|
|
'<label> </label>',
|
|
`<button class="ui red icon button remove" data-idx="${this.props.index}">`,
|
|
'<i class="trash icon"></i>',
|
|
'</button>',
|
|
'</div>',
|
|
])
|
|
}
|
|
output.push('</div>')
|
|
return output.join("\n")
|
|
}
|
|
activate() {
|
|
$(`#${this.ids.sociedad}${this.props.index}`).dropdown({
|
|
onChange: (value, text, $choice) => {
|
|
cartolas.fetch().bancos(value).then(response => {
|
|
if (!response) {
|
|
return
|
|
}
|
|
return response.json().then(data => {
|
|
const dropdown = $(`#${this.ids.banco}${this.props.index}`)
|
|
dropdown.dropdown('clear')
|
|
dropdown.dropdown('change values', data.cuentas.map(cuenta => {
|
|
const desc = [cuenta.banco.nombre, cuenta.cuenta].join(' - ')
|
|
return {
|
|
name: desc,
|
|
value: cuenta.id,
|
|
text: desc
|
|
}
|
|
}))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
$(`#${this.ids.banco}${this.props.index}`).dropdown()
|
|
const cdo = structuredClone(calendar_date_options)
|
|
cdo.type = 'month'
|
|
$(`#${this.ids.mes}${this.props.index}`).calendar(cdo)
|
|
if (this.props.index > 1) {
|
|
$(`.${this.ids.buttons.remove}[data-idx="${this.props.index}"]`).click(clickEvent => {
|
|
const index = $(clickEvent.currentTarget).data('idx')
|
|
this.remove(index)
|
|
})
|
|
}
|
|
}
|
|
remove(idx) {
|
|
$(`.fields[data-idx=${idx}]`).remove()
|
|
cartolas.data.cartolas = cartolas.data.cartolas.filter(cartola => cartola.props.index !== idx)
|
|
cartolas.draw().form()
|
|
}
|
|
}
|
|
class Movimiento {
|
|
props
|
|
constructor({id, sociedad, fecha, glosa, cargo, abono, saldo, categoria, detalle, centro_costo, rut, nombres,
|
|
identificador, relacionado, relacionadoType, nuevo = false, obsoleto = false}) {
|
|
this.props = {
|
|
id,
|
|
sociedad,
|
|
fecha,
|
|
glosa,
|
|
cargo,
|
|
abono,
|
|
saldo,
|
|
categoria,
|
|
detalle,
|
|
centro_costo,
|
|
rut,
|
|
nombres,
|
|
identificador,
|
|
relacionado,
|
|
relacionadoType,
|
|
nuevo,
|
|
obsoleto
|
|
}
|
|
}
|
|
draw({formatters}) {
|
|
const fecha = new Date(this.props.fecha)
|
|
let nombre = ''
|
|
if (this.props.nombres) {
|
|
if (this.props.relacionado) {
|
|
let type = this.props.relacionadoType
|
|
type = type.charAt(0).toUpperCase() + type.slice(1)
|
|
nombre = `<span data-tooltip="${type}">${this.props.nombres}</span>`
|
|
} else {
|
|
nombre = this.props.nombres
|
|
}
|
|
}
|
|
let edit = ''
|
|
let color = ''
|
|
if (this.props.nuevo) {
|
|
color = ' class="green"'
|
|
}
|
|
if (this.props.obsoleto) {
|
|
color = ' class="red"'
|
|
edit = `<button class="ui tertiary red icon button remove_movimiento" data-id="${this.props.id}"><i class="remove icon"></i></button>`
|
|
}
|
|
return [
|
|
`<tr${color}>`,
|
|
`<td>${this.props.sociedad.sigla}</td>`,
|
|
`<td>${formatters.date.format(fecha)}</td>`,
|
|
`<td>${this.props.glosa}</td>`,
|
|
`<td class="right aligned">${formatters.number.format(this.props.cargo ?? 0)}</td>`,
|
|
`<td class="right aligned">${formatters.number.format(this.props.abono ?? 0)}</td>`,
|
|
`<td class="right aligned">${formatters.number.format(this.props.saldo)}</td>`,
|
|
`<td class="center aligned">${this.props.centro_costo ?? ''}</td>`,
|
|
`<td>${this.props.categoria ?? ''}</td>`,
|
|
`<td>${this.props.detalle ?? ''}</td>`,
|
|
`<td>${this.props.rut ?? ''}</td>`,
|
|
`<td>${nombre}</td>`,
|
|
`<td class="center aligned">${this.props.identificador ?? ''}</td>`,
|
|
`<td class="right aligned">${edit}</td>`,
|
|
'</tr>'
|
|
].join("\n")
|
|
}
|
|
}
|
|
const cartolas = {
|
|
ids: {},
|
|
data: {
|
|
sociedades: {!! json_encode($inmobiliarias) !!},
|
|
bancos: {!! json_encode($bancos) !!},
|
|
cartolas: [],
|
|
movimientos: [],
|
|
},
|
|
formatters: {
|
|
number: new Intl.NumberFormat('es-CL', {minimumFractionDigits: 0, maximumFractionDigits: 0}),
|
|
date: new Intl.DateTimeFormat('es-CL', {dateStyle: 'short', timeStyle: 'short'})
|
|
},
|
|
add() {
|
|
return {
|
|
cartola: () => {
|
|
const idx = cartolas.data.cartolas.length + 1
|
|
const cartola = new Cartola({index: idx, ids: cartolas.ids.cartolas})
|
|
cartolas.data.cartolas.push(cartola)
|
|
cartolas.draw().form()
|
|
}
|
|
}
|
|
},
|
|
remove() {
|
|
return {
|
|
movimiento: id => {
|
|
const url = `{{$urls->api}}/contabilidad/movimiento/${id}`
|
|
const method = 'delete'
|
|
APIClient.fetch(url, {method}).then(response => {
|
|
if (!response.status) {
|
|
return
|
|
}
|
|
const index = this.data.movimientos.findIndex(movimiento => movimiento.id === response.movimiento.id)
|
|
this.data.movimientos.splice(index, 1)
|
|
this.draw().movimientos()
|
|
})
|
|
}
|
|
}
|
|
},
|
|
draw() {
|
|
return {
|
|
form: () => {
|
|
const form = $(this.ids.form)
|
|
form.empty()
|
|
form.append(`<input type="hidden" name="cartolas" value="${this.data.cartolas.length}" />`)
|
|
this.data.cartolas.forEach(cartola => {
|
|
form.append(cartola.draw({sociedades: this.data.sociedades, bancos: this.data.bancos}))
|
|
cartola.activate()
|
|
})
|
|
},
|
|
movimientos: () => {
|
|
const table = $(this.ids.movimientos)
|
|
const tbody = table.find('tbody')
|
|
tbody.empty()
|
|
this.data.movimientos.forEach(movimiento => {
|
|
tbody.append(movimiento.draw({formatters: this.formatters}))
|
|
})
|
|
table.show()
|
|
Object.values(document.getElementsByClassName('remove_movimiento')).forEach(element => {
|
|
element.addEventListener('click', clickEvent => {
|
|
const id = clickEvent.currentTarget.dataset['id']
|
|
this.remove().movimiento(id)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
},
|
|
fetch() {
|
|
return {
|
|
bancos: sociedad_rut => {
|
|
const url = `{{$urls->api}}/inmobiliaria/${sociedad_rut}/cuentas`
|
|
return fetchAPI(url)
|
|
}
|
|
}
|
|
},
|
|
import() {
|
|
return {
|
|
cartolas: () => {
|
|
const url = '{{$urls->api}}/contabilidad/cartolas/importar'
|
|
const method = 'post'
|
|
const body = new FormData()
|
|
this.data.cartolas.forEach(cartola => {
|
|
Object.entries(cartola.data).forEach(([key, value]) => {
|
|
const name = `${key}[${cartola.props.index - 1}]`
|
|
body.append(name, value)
|
|
})
|
|
})
|
|
|
|
APIClient.fetch(url, {method, body}).then(response => {
|
|
if (!response) {
|
|
return
|
|
}
|
|
return response.json().then(data => {
|
|
if (data.errors.length > 0) {
|
|
data.errors.forEach(errorData => {
|
|
console.error(errorData)
|
|
})
|
|
}
|
|
this.data.movimientos = data.movimientos.map(movimiento => new Movimiento(movimiento))
|
|
this.draw().movimientos()
|
|
})
|
|
}).catch(error => {
|
|
const table = $(this.ids.movimientos)
|
|
const tbody = table.find('tbody')
|
|
tbody.empty()
|
|
table.hide()
|
|
}).finally(() => {
|
|
$(this.ids.loader).hide()
|
|
})
|
|
}
|
|
}
|
|
},
|
|
setup(ids) {
|
|
this.ids = ids
|
|
this.add().cartola()
|
|
$(this.ids.buttons.add).click(() => {
|
|
this.add().cartola()
|
|
})
|
|
$(this.ids.loader).hide()
|
|
$(this.ids.form).submit(submitEvent => {
|
|
submitEvent.preventDefault()
|
|
$(this.ids.loader).show()
|
|
this.import().cartolas()
|
|
return false
|
|
})
|
|
$(this.ids.buttons.process).click(() => {
|
|
$(this.ids.form).submit()
|
|
})
|
|
}
|
|
}
|
|
$(document).ready(() => {
|
|
cartolas.setup({
|
|
form: '#cartola_form',
|
|
buttons: {
|
|
add: '#add_button',
|
|
process: '#process_button'
|
|
},
|
|
movimientos: '#movimientos',
|
|
loader: '#loader',
|
|
cartolas: {
|
|
sociedad: 'sociedad',
|
|
banco: 'banco',
|
|
mes: 'mes',
|
|
buttons: {
|
|
remove: 'remove'
|
|
}
|
|
}
|
|
})
|
|
})
|
|
</script>
|
|
@endpush
|