Files
oficial/app/resources/views/home/alertas.blade.php
aldarien 307f2ac7d7 feature/cierres (#25)
Varios cambios

Co-authored-by: Juan Pablo Vial <jpvialb@incoviba.cl>
Reviewed-on: #25
2025-07-22 13:18:00 +00:00

177 lines
8.8 KiB
PHP

<h4 class="ui dividing header">Alertas Escrituras</h4>
<div class="ui divided list" id="alertas_escrituras"></div>
@push('page_scripts')
<script>
const alertas_escrituras = {
id: '#alertas_escrituras',
data: {
proyectos: []
},
get: function() {
return {
proyectos: () => {
this.draw().loading()
const url = '{{$urls->api}}/proyectos/escriturando'
return fetchAPI(url).then(response => {
if (response.ok) {
return response.json()
}
}).then(data => {
const promises = []
data.proyectos.forEach(proyecto => {
this.add().proyecto(proyecto)
promises.push(
this.get().unidades(proyecto.id)
)
promises.push(
this.get().promesas(proyecto.id)
)
promises.push(
this.get().escrituras(proyecto.id)
)
})
Promise.all(promises).then(() => {
this.draw().list()
})
})
},
unidades: proyecto_id => {
const url = '{{$urls->api}}/ventas/unidades/disponibles'
return fetchAPI(url, {method: 'post', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({proyecto_id})}).then(response => {
if (response.ok) {
return response.json()
}
}).then(data => {
const index = this.data.proyectos.findIndex(proyecto => proyecto.id === data.proyecto_id)
this.data.proyectos[index].unidades = data.unidades
})
},
promesas: proyecto_id => {
const url = '{{$urls->api}}/ventas/estados/firmar'
return fetchAPI(url, {method: 'post', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({proyecto_id})}).then(response => {
if (response.ok) {
return response.json()
}
}).then(data => {
const index = this.data.proyectos.findIndex(proyecto => proyecto.id === data.proyecto_id)
this.data.proyectos[index].promesas = data.promesas
})
},
escrituras: proyecto_id => {
const url = '{{$urls->api}}/ventas/escrituras/estados';
return fetchAPI(url, {method: 'post', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({proyecto_id})}).then(response => {
if (response.ok) {
return response.json()
}
}).then(data => {
const index = this.data.proyectos.findIndex(proyecto => proyecto.id === data.proyecto_id)
this.data.proyectos[index].escrituras = data.escrituras
})
}
}
},
draw: function() {
return {
reset: () => {
const list = $(this.id)
list.html('')
},
loading: () => {
this.draw().reset()
const list = $(this.id)
list.append(
$('<div><div>').addClass('ui inline active loader')
)
},
list: () => {
this.draw().reset()
const list = $(this.id)
this.data.proyectos.forEach(proyecto => {
const feed = $('<div></div>').addClass('ui feed').append(
$('<div></div>').addClass('date').append(
$('<strong></strong>').html(proyecto.descripcion)
)
)
function add(control, title, value = null) {
if (control > 0) {
return $('<div></div>').addClass('event').append(
$('<div></div>').addClass('content').html(title)
).append(
$('<div></div>').addClass('meta').html(value ?? control)
)
}
}
const total_unidades = Object.entries(proyecto.unidades)
.filter(([tipo, total]) => tipo !== 'total')
.map(([tipo, total]) => total)
.reduce((sum, total_tipo) => sum + total_tipo, 0)
const unidades = $('<div></div>').addClass('ui feed')
const formatter = new Intl.NumberFormat('es-CL', {minimumFractionDigits: 0, maximumFractionDigits: 0})
Object.entries(proyecto.unidades).filter(([tipo, total]) => tipo !== 'total').forEach(([tipo, total]) => {
const full = proyecto.unidades.total[tipo]
tipo = tipo.charAt(0).toUpperCase() + tipo.slice(1)
unidades.append(
$('<div></div>').addClass('event').append(
$('<div></div>').addClass('content').html(tipo)
).append(
$('<div></div>').addClass('meta').html(total + '/' + full + ' [' + formatter.format(Math.round(total / full * 10000) / 100).padStart(2, ' ') + '%]')
)
)
})
if (total_unidades > 0) {
feed.append(
$('<div></div>').addClass('event').append(
$('<div></div>').addClass('content').html('Unidades por Vender')
).append(
$('<div></div>').addClass('content').append(unidades)
)
)
}
feed.append(add(proyecto.promesas, 'Promesas por Escriturar'))
feed.append(add(proyecto.escrituras.firmar, 'Escrituras por Firmar'))
feed.append(add(proyecto.escrituras.pagar, 'Escrituras con Pagos Pendientes'))
feed.append(add(proyecto.escrituras.abonar, 'Escrituras con Pagos no Abonados'))
list.append(
$('<div></div>').addClass('item').append(feed)
)
})
}
}
},
add: function() {
return {
proyecto: proyecto => {
proyecto.unidades = {
total: 0,
departamentos: 0,
estacionamientos: 0,
bodegas: 0
}
proyecto.promesas = 0
proyecto.escrituras = {
firmar: 0,
pagar: 0,
abonar: 0
}
this.data.proyectos.push(proyecto)
}
}
}
}
$(document).ready(() => {
alertas_escrituras.get().proyectos()
})
/**
* Listar proyectos construidos no terminados con unidades no vendidas, promesas o escrituras pendientes
* Listar # unidades no vendidas
* Listar # promesas por escriturar
* Listar # escrituras por firmar
* Listar # escrituras con pagos pendientes
* Listar # escrituras con abonos pendientes
*/
</script>
@endpush