Files
oficial/app/resources/views/ventas/list.blade.php
2025-05-15 16:04:35 -04:00

343 lines
14 KiB
PHP

@extends('layout.base')
@section('page_title')
Ventas
@endsection
@section('page_content')
<div class="ui container">
<h2 class="ui header">Listado de Ventas</h2>
<h4 class="ui dividing header">
<div class="ui two column grid">
<div id="list_title" class="column">Proyectos</div>
<div class="right aligned column">
<div class="ui tiny icon buttons">
<button class="ui button" id="up_button">
<i class="up arrow icon"></i>
</button>
<button class="ui button" id="refresh_button">
<i class="refresh icon"></i>
</button>
</div>
</div>
</div>
</h4>
<div class="ui link selection list" id="proyectos"></div>
<table class="ui table" id="data"></table>
</div>
@endsection
@include('layout.head.styles.datatables')
@include('layout.body.scripts.datatables')
@push('page_scripts')
<script>
class Venta {
id
propiedad
propietario
valor
fecha
estado
constructor({id, propiedad, propietario, valor, fecha, estado}) {
this.id = id
this.propiedad = propiedad
this.propietario = propietario
this.valor = valor
this.fecha = fecha
this.estado = estado
}
draw(formatter, dateFormatter) {
const tipo = this.estado.tipo_estado_venta.descripcion
const date = new Date(this.fecha)
let unidad = this.propiedad.unidades[0]
if (this.propiedad.departamentos.length > 0) {
unidad = this.propiedad.departamentos[0]
}
return $('<tr></tr>').append(
$('<td></td>').attr('data-order', unidad.descripcion).append(
$('<a></a>').attr('href', '{{$urls->base}}/venta/' + this.id).html(this.propiedad.summary)
)
).append(
$('<td></td>').append(
$('<a></a>').attr('href', '{{$urls->base}}/search?tipo=propietario&query=' + encodeURIComponent(this.propietario.nombre_completo)).html(this.propietario.nombre_completo)
)
).append(
$('<td></td>').html(formatter.format(this.valor) + ' UF')
).append(
$('<td></td>').html(unidad.proyecto_tipo_unidad.abreviacion + ' (' + formatter.format(unidad.proyecto_tipo_unidad.vendible) + ' m²)')
).append(
$('<td></td>').html(formatter.format(this.valor / unidad.proyecto_tipo_unidad.vendible) + ' UF/m²')
).append(
$('<td></td>').attr('data-order', this.fecha).html(dateFormatter.format(date))
).append(
$('<td></td>').html(tipo.charAt(0).toUpperCase() + tipo.slice(1))
)
}
}
const ventas = {
ids: {
title: '',
proyectos: '',
table: '',
buttons: {
up: '',
refresh: ''
}
},
data: {
id: 0,
proyecto: '',
proyectos: JSON.parse('{!! json_encode($proyectos) !!}'),
venta_ids: [],
ventas: []
},
loading: {
ventas: false
},
formatters: {
number: new Intl.NumberFormat('es-CL', {minimumFractionDigits: 2, maximumFractionDigits: 2}),
date: new Intl.DateTimeFormat('es-CL')
},
table: null,
get: function() {
return {
ventas: proyecto_id => {
this.data.venta_ids = []
this.data.ventas = []
return fetchAPI('{{$urls->api}}/ventas',
{method: 'post', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({proyecto_id})}
).then(response => {
this.loading.precios = false
if (response.ok) {
return response.json()
}
}).then(data => {
if (data.total > 0) {
const progress = this.draw().progress(data.ventas.length)
this.data.id = data.proyecto.id
this.data.proyecto = data.proyecto.descripcion
this.data.venta_ids = data.ventas
const chunkSize = 50
const chunks = []
for (let i = 0; i < data.ventas.length; i += chunkSize) {
chunks.push(data.ventas.splice(i, i + chunkSize))
}
const promises = []
chunks.forEach(chunk => {
const promise = this.get().venta(chunk).then(count => {
progress.progress('increment', count)
})
promises.push(promise)
})
Promise.all(promises).then(() => {
this.draw().ventas()
})
}
})
},
venta: chunk => {
const body = new FormData()
body.set('ventas', chunk.join(','))
return fetchAPI('{{$urls->api}}/ventas/get', {method: 'post', body}).then(response => {
if (response.ok) {
return response.json()
}
}).then(data => {
if (data.ventas.length === 0) {
console.error(chunk, data.error)
return
}
data.ventas.forEach(venta_id => {
this.add().venta(venta_id)
})
return data.ventas.length
})
}
}
},
add: function() {
return {
venta: data => {
const venta = new Venta({
id: data.id,
propiedad: data.propiedad,
propietario: data.propietario,
valor: data.valor,
fecha: data.fecha,
estado: data.current_estado
})
this.data.ventas.push(venta)
}
}
},
draw: function() {
return {
proyectos: () => {
const title = $(this.ids.title)
const parent = $(this.ids.proyectos)
const table = $(this.ids.table)
table.hide()
parent.html('')
this.loading.ventas = false
if (this.table !== null) {
this.table.destroy()
this.table = null
}
title.html('Proyectos')
this.data.proyectos.forEach(proyecto => {
parent.append(
$('<div></div>').addClass('item proyecto').attr('data-proyecto', proyecto.id).html(proyecto.descripcion).css('cursor', 'pointer')
)
})
parent.show()
parent.find('.item.proyecto').click(this.actions().get)
},
progress: cantidad => {
const parent = $(this.ids.proyectos)
parent.html('')
const progress = $('<div></div>').addClass('ui active progress').append(
$('<div></div>').addClass('bar').append(
$('<div></div>').addClass('centered progress')
)
).append(
$('<div></div>').addClass('label').html('Cargando datos')
)
progress.progress({
total: cantidad,
label: 'ratio',
text: {
ratio: '{value} de {total} ({percent}%)'
}
})
parent.append(progress)
return progress
},
ventas: (loading = false) => {
const title = $(this.ids.title)
const parent = $(this.ids.proyectos)
const table = $(this.ids.table)
parent.hide()
table.html('')
this.loading.ventas = false
if (this.table !== null) {
this.table.destroy()
this.table = null
}
title.html('Ventas de ' + this.data.proyecto + ' [' + this.data.ventas.length + ']')
if (loading) {
title.append(
$('<span></span>').addClass('ui active inline loader')
)
}
const tbody = $('<tbody></tbody>')
this.data.ventas.forEach(venta => {
try {
tbody.append(venta.draw(this.formatters.number, this.formatters.date))
} catch (error) {
console.debug(venta)
console.error(error)
}
})
table.append(this.draw().header()).append(tbody)
table.show()
this.table = new DataTable(table, {
order: [[0, 'asc']],
pageLength: 50
})
},
table: () => {
const parent = $(this.ids.proyectos)
const table = $(this.ids.table)
if (table.length > 0) {
return
}
console.debug(parent.parent())
},
header: () => {
return $('<thead></thead>').append(
$('<tr></tr>').append(
$('<th></th>').html('Departamento')
).append(
$('<th></th>').html('Propietario')
).append(
$('<th></th>').html('Valor [UF]')
).append(
$('<th></th>').html('Tipologia')
).append(
$('<th></th>').html('UF/m²')
).append(
$('<th></th>').html('Fecha Venta')
).append(
$('<th></th>').html('Estado')
)
)
}
}
},
actions: function() {
return {
up: event => {
this.draw().proyectos()
},
refresh: event => {
const list = $(this.ids.proyectos)
if (list.is(':hidden')) {
const table = $(this.ids.table)
table.hide()
if (this.table !== null) {
this.table.destroy()
this.table = null
}
this.get().ventas(this.data.id)
} else {
this.draw().proyectos()
}
},
get: event => {
if (this.loading.ventas) {
return false
}
const element = $(event.currentTarget)
$(this.ids.proyectos + ' .item.proyecto').css('cursor', 'wait')
this.loading.ventas = true
const proyecto_id = element.data('proyecto')
this.get().ventas(proyecto_id)
}
}
},
setup: function({title, proyectos_id, table_id, up_button, refresh_button}) {
this.ids.title = title
this.ids.proyectos = proyectos_id
this.ids.table = table_id
this.ids.buttons.up = up_button
this.ids.buttons.refresh = refresh_button
$(this.ids.buttons.up).click(this.actions().up)
$(this.ids.buttons.refresh).click(this.actions().refresh)
this.draw().proyectos()
}
}
$(document).ready(() => {
ventas.setup({
title: '#list_title',
proyectos_id: '#proyectos',
table_id: '#data',
up_button: '#up_button',
refresh_button: '#refresh_button'
})
})
</script>
@endpush