2025-07-22 18:21:05 -04:00
|
|
|
@extends('layout.base')
|
|
|
|
|
|
|
|
@section('page_title')
|
|
|
|
Cierres -Reservas
|
|
|
|
@endsection
|
|
|
|
|
|
|
|
@section('page_content')
|
|
|
|
<div class="ui container">
|
|
|
|
<h2 class="ui header">Cierres - Reservas</h2>
|
|
|
|
|
|
|
|
<div class="ui compact segment" id="projects">
|
|
|
|
<div class="ui header">Proyectos</div>
|
|
|
|
@if (count($projects) == 0)
|
|
|
|
<div class="ui message">
|
|
|
|
No hay proyectos en venta.
|
|
|
|
</div>
|
|
|
|
@else
|
|
|
|
<div class="ui link list">
|
|
|
|
@foreach ($projects as $project)
|
|
|
|
<div class="item link" data-id="{{ $project->id }}">
|
|
|
|
{{ $project->descripcion }}
|
|
|
|
</div>
|
|
|
|
@endforeach
|
|
|
|
</div>
|
|
|
|
@endif
|
|
|
|
</div>
|
2025-08-05 18:18:05 -04:00
|
|
|
<h3 class="ui header" id="project"></h3>
|
2025-07-22 18:21:05 -04:00
|
|
|
<div class="ui right aligned top attached basic segment" id="controls">
|
|
|
|
<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>
|
2025-08-05 18:18:05 -04:00
|
|
|
<button class="ui green icon button" id="add_button">
|
|
|
|
<i class="plus icon"></i>
|
|
|
|
</button>
|
2025-07-22 18:21:05 -04:00
|
|
|
</div>
|
|
|
|
</div>
|
2025-08-05 18:18:05 -04:00
|
|
|
<div class="ui top attached tabular menu" id="tabs">
|
|
|
|
<div class="yellow active item" data-tab="pending">Pendientes</div>
|
|
|
|
<div class="green item" data-tab="active">Activas</div>
|
|
|
|
<div class="red item" data-tab="rejected">Rechazadas</div>
|
|
|
|
</div>
|
|
|
|
<div class="ui bottom attached tab fitted segment active" data-tab="pending">
|
|
|
|
<table class="ui yellow striped table" id="pending_reservations">
|
|
|
|
<thead>
|
2025-07-22 18:21:05 -04:00
|
|
|
<tr>
|
|
|
|
<th>Unidades</th>
|
|
|
|
<th>Cliente</th>
|
|
|
|
<th>Fecha</th>
|
|
|
|
<th>Oferta</th>
|
|
|
|
<th>¿Valida?</th>
|
|
|
|
<th>Operador</th>
|
2025-08-05 18:18:05 -04:00
|
|
|
<th></th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody></tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
<div class="ui bottom attached tab fitted segment" data-tab="active">
|
|
|
|
<table class="ui green striped table" id="active_reservations">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>Unidades</th>
|
|
|
|
<th>Cliente</th>
|
|
|
|
<th>Fecha</th>
|
|
|
|
<th>Oferta</th>
|
|
|
|
<th>Operador</th>
|
|
|
|
<th></th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody></tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
<div class="ui bottom attached tab fitted segment" data-tab="rejected">
|
|
|
|
<table class="ui red striped table" id="rejected_reservations">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>Unidades</th>
|
|
|
|
<th>Cliente</th>
|
|
|
|
<th>Fecha</th>
|
|
|
|
<th>Oferta</th>
|
|
|
|
<th>Estado</th>
|
|
|
|
<th>Operador</th>
|
|
|
|
<th>Comentarios</th>
|
2025-07-22 18:21:05 -04:00
|
|
|
</tr>
|
2025-08-05 18:18:05 -04:00
|
|
|
</thead>
|
|
|
|
<tbody></tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
2025-07-22 18:21:05 -04:00
|
|
|
</div>
|
|
|
|
@endsection
|
|
|
|
|
|
|
|
@push('page_styles')
|
|
|
|
<style>
|
|
|
|
.item.link {
|
|
|
|
cursor: pointer;
|
|
|
|
text-decoration: underline;
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
@endpush
|
|
|
|
|
|
|
|
@push('page_scripts')
|
|
|
|
<script>
|
|
|
|
class Projects {
|
|
|
|
display = {
|
|
|
|
projects: '',
|
|
|
|
project: ''
|
|
|
|
}
|
|
|
|
component_id = ''
|
|
|
|
component = null
|
|
|
|
current_project = null;
|
|
|
|
title_id = ''
|
|
|
|
title_component = null
|
|
|
|
|
|
|
|
constructor({component_id, title_id}) {
|
|
|
|
this.component_id = component_id
|
|
|
|
this.component = document.getElementById(this.component_id)
|
|
|
|
this.display.projects = this.component.style.display
|
|
|
|
this.title_id = title_id
|
|
|
|
this.title_component = document.getElementById(this.title_id)
|
|
|
|
this.display.project = this.title_component.style.display
|
|
|
|
|
|
|
|
this.show()
|
|
|
|
this.watch()
|
|
|
|
}
|
|
|
|
|
|
|
|
select(event) {
|
|
|
|
event.preventDefault()
|
|
|
|
|
|
|
|
const project_id = event.currentTarget.dataset.id
|
2025-08-05 18:18:05 -04:00
|
|
|
if (project_id === this.current_project) {
|
2025-07-22 18:21:05 -04:00
|
|
|
this.hide()
|
|
|
|
this.title_component.innerHTML = event.currentTarget.innerHTML
|
|
|
|
|
|
|
|
reservations.action().reservations()
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
2025-08-05 18:18:05 -04:00
|
|
|
this.current_project = project_id
|
2025-07-22 18:21:05 -04:00
|
|
|
reservations.get().reservations(project_id)
|
|
|
|
|
|
|
|
this.hide()
|
|
|
|
this.title_component.innerHTML = event.currentTarget.innerHTML
|
|
|
|
}
|
|
|
|
watch() {
|
|
|
|
this.component.querySelectorAll('.item.link').forEach(item => {
|
|
|
|
item.addEventListener('click', this.select.bind(this))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
show() {
|
|
|
|
this.component.style.display = this.display.projects
|
|
|
|
this.title_component.style.display = 'none'
|
|
|
|
}
|
|
|
|
hide() {
|
|
|
|
this.component.style.display = 'none'
|
|
|
|
this.title_component.style.display = this.display.project
|
|
|
|
}
|
|
|
|
}
|
2025-08-05 18:18:05 -04:00
|
|
|
class Controls {
|
|
|
|
display = {
|
|
|
|
up: '',
|
|
|
|
reset: '',
|
|
|
|
}
|
|
|
|
component_id = ''
|
|
|
|
component = null
|
|
|
|
|
|
|
|
buttons = {
|
|
|
|
up: null,
|
|
|
|
reset: null,
|
|
|
|
add: null
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor({component_id}) {
|
|
|
|
this.component_id = component_id
|
|
|
|
this.component = document.getElementById(this.component_id)
|
|
|
|
const buttons = this.component.querySelectorAll('button')
|
|
|
|
this.buttons.up = buttons[0]
|
|
|
|
this.buttons.reset = buttons[1]
|
|
|
|
this.buttons.add = buttons[2]
|
|
|
|
this.display.up = buttons[0].style.display
|
|
|
|
this.display.reset = buttons[1].style.display
|
|
|
|
|
|
|
|
this.watch()
|
|
|
|
this.hide()
|
|
|
|
}
|
|
|
|
|
|
|
|
watch() {
|
|
|
|
Object.entries(this.buttons).forEach(([key, value]) => {
|
|
|
|
const name = key.replace('_button', '')
|
|
|
|
value.addEventListener('click', reservations.action()[name].bind(reservations))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
hide() {
|
|
|
|
this.buttons.up.style.display = this.display.up
|
|
|
|
this.buttons.reset.style.display = this.display.reset
|
|
|
|
}
|
|
|
|
show() {
|
|
|
|
this.buttons.up.style.display = 'none'
|
|
|
|
this.buttons.reset.style.display = 'none'
|
|
|
|
}
|
|
|
|
}
|
2025-07-22 18:21:05 -04:00
|
|
|
class Reservations {
|
|
|
|
display = {
|
|
|
|
reservations: '',
|
|
|
|
}
|
|
|
|
component_id = ''
|
|
|
|
component = null
|
|
|
|
formatters = {
|
|
|
|
date: null,
|
|
|
|
ufs: null
|
|
|
|
}
|
|
|
|
|
2025-08-05 18:18:05 -04:00
|
|
|
columnNames = []
|
2025-07-22 18:21:05 -04:00
|
|
|
reservations = []
|
|
|
|
|
2025-08-05 18:18:05 -04:00
|
|
|
constructor({component_id, formatters = {date, ufs}}) {
|
2025-07-22 18:21:05 -04:00
|
|
|
this.component_id = component_id
|
|
|
|
this.component = document.getElementById(this.component_id)
|
|
|
|
this.display.reservations = this.component.style.display
|
2025-08-05 18:18:05 -04:00
|
|
|
|
2025-07-22 18:21:05 -04:00
|
|
|
this.formatters = formatters
|
|
|
|
|
2025-08-05 18:18:05 -04:00
|
|
|
this.set().columnNames()
|
2025-07-22 18:21:05 -04:00
|
|
|
|
2025-08-05 18:18:05 -04:00
|
|
|
this.hide()
|
2025-07-22 18:21:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
set() {
|
|
|
|
return {
|
|
|
|
reservations: reservations => {
|
|
|
|
this.reservations = reservations
|
|
|
|
return this
|
2025-08-05 18:18:05 -04:00
|
|
|
},
|
|
|
|
columnNames: () => {
|
|
|
|
const tds = this.component.querySelector('thead tr').querySelectorAll('th')
|
|
|
|
this.columnNames = []
|
|
|
|
tds.forEach(td => {
|
|
|
|
let name = td.innerHTML.toLowerCase()
|
|
|
|
if (name === '') {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if (name.includes('?')) {
|
|
|
|
name = name.replaceAll(/[¿?]/g, '')
|
|
|
|
}
|
|
|
|
this.columnNames.push(name)
|
|
|
|
})
|
|
|
|
return this
|
2025-07-22 18:21:05 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2025-08-05 18:18:05 -04:00
|
|
|
columnsData() {
|
|
|
|
return this.reservations.map(reservation => {
|
|
|
|
const date = new Date(Date.parse(reservation.fecha) + 24 * 60 * 60 * 1000)
|
|
|
|
return {
|
|
|
|
id: reservation.id,
|
|
|
|
unidades: reservation.summary,
|
|
|
|
cliente: reservation.buyer.nombreCompleto,
|
|
|
|
fecha: this.formatters.date.format(date),
|
|
|
|
oferta: `${this.formatters.ufs.format(reservation.offer)} UF`,
|
|
|
|
valida: reservation.valid ? '<span class="ui green text">Si</span>' : '<span class="ui red text">No</span>',
|
|
|
|
operador: reservation.broker?.name ?? '',
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2025-07-22 18:21:05 -04:00
|
|
|
draw() {
|
|
|
|
const tbody = this.component.querySelector('tbody')
|
|
|
|
tbody.innerHTML = ''
|
2025-08-05 18:18:05 -04:00
|
|
|
this.columnsData().forEach(column => {
|
2025-07-22 18:21:05 -04:00
|
|
|
const tr = document.createElement('tr')
|
2025-08-05 18:18:05 -04:00
|
|
|
const contents = []
|
|
|
|
const id = column.id
|
|
|
|
this.columnNames.forEach(name => {
|
|
|
|
contents.push(`<td>${column[name]}</td>`)
|
|
|
|
})
|
|
|
|
const actions = this.drawActions(id)
|
|
|
|
if (actions !== '') {
|
|
|
|
contents.push(actions)
|
|
|
|
}
|
|
|
|
tr.innerHTML = contents.join("\n")
|
2025-07-22 18:21:05 -04:00
|
|
|
tbody.appendChild(tr)
|
|
|
|
})
|
|
|
|
this.show()
|
|
|
|
}
|
2025-08-05 18:18:05 -04:00
|
|
|
drawActions(id) {
|
|
|
|
return `
|
|
|
|
<td class="right aligned">
|
|
|
|
<button class="ui green mini icon button approve" data-id="${id}" title="Aprobar">
|
|
|
|
<i class="check icon"></i>
|
|
|
|
</button>
|
|
|
|
<button class="ui red mini icon button reject" data-id="${id}" title="Rechazar">
|
|
|
|
<i class="trash icon"></i>
|
|
|
|
</button>
|
|
|
|
</td>`
|
|
|
|
}
|
2025-07-22 18:21:05 -04:00
|
|
|
|
|
|
|
show() {
|
|
|
|
this.component.style.display = this.display.reservations
|
|
|
|
}
|
|
|
|
hide() {
|
|
|
|
this.component.style.display = 'none'
|
2025-08-05 18:18:05 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
class ActiveReservations extends Reservations {
|
|
|
|
constructor({component_id, formatters = {date, ufs}}) {
|
|
|
|
super({component_id, formatters})
|
|
|
|
}
|
|
|
|
columnsData() {
|
|
|
|
const data = super.columnsData();
|
|
|
|
return data.map(row => {
|
|
|
|
delete(row['valida'])
|
|
|
|
return row
|
|
|
|
})
|
|
|
|
}
|
|
|
|
drawActions(id) {
|
|
|
|
return `
|
|
|
|
<td class="right aligned">
|
|
|
|
<button class="ui green mini icon button edit" data-id="${id}" title="Promesar">
|
|
|
|
<i class="right chevron icon"></i>
|
|
|
|
</button>
|
|
|
|
<button class="ui red mini icon button remove" data-id="${id}" title="Abandonar">
|
|
|
|
<i class="trash icon"></i>
|
|
|
|
</button>
|
|
|
|
</td>`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
class PendingReservations extends Reservations {
|
|
|
|
constructor({component_id, formatters = {date, ufs}}) {
|
|
|
|
super({component_id, formatters})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
class RejectedReservations extends Reservations {
|
|
|
|
constructor({component_id, formatters = {date, ufs}}) {
|
|
|
|
super({component_id, formatters})
|
|
|
|
}
|
|
|
|
|
|
|
|
columnsData() {
|
|
|
|
const data = super.columnsData()
|
|
|
|
return this.reservations.map((reservation, idx) => {
|
|
|
|
data[idx]['estado'] = reservation.state.charAt(0).toUpperCase() + reservation.state.slice(1)
|
|
|
|
data[idx]['comentarios'] = reservation.comments?.join('<br />\n') ?? ''
|
|
|
|
return data[idx]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
drawActions(id) {
|
|
|
|
return ''
|
2025-07-22 18:21:05 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
const reservations = {
|
|
|
|
components: {
|
|
|
|
projects: null,
|
2025-08-05 18:18:05 -04:00
|
|
|
controls: null,
|
|
|
|
reservations: {
|
|
|
|
active: null,
|
|
|
|
pending: null,
|
|
|
|
rejected: null
|
|
|
|
}
|
2025-07-22 18:21:05 -04:00
|
|
|
},
|
|
|
|
get() {
|
|
|
|
return {
|
2025-08-05 18:18:05 -04:00
|
|
|
active: project_id => {
|
2025-07-22 18:21:05 -04:00
|
|
|
const reservations = [
|
|
|
|
{
|
|
|
|
id: 1,
|
|
|
|
summary: 'D1',
|
|
|
|
buyer: {
|
|
|
|
rut: '12345678-9',
|
|
|
|
nombreCompleto: 'Juan Perez'
|
|
|
|
},
|
|
|
|
fecha: '2021-01-01',
|
2025-08-05 18:18:05 -04:00
|
|
|
offer: 3000,
|
|
|
|
valid: true,
|
2025-07-22 18:21:05 -04:00
|
|
|
broker: {
|
|
|
|
name: 'Operador 1'
|
|
|
|
}
|
2025-08-05 18:18:05 -04:00
|
|
|
}
|
|
|
|
]
|
|
|
|
this.components.reservations.active.set().reservations(reservations).draw()
|
|
|
|
},
|
|
|
|
pending: project_id => {
|
|
|
|
const reservations = [
|
2025-07-22 18:21:05 -04:00
|
|
|
{
|
|
|
|
id: 2,
|
|
|
|
summary: 'D2',
|
|
|
|
buyer: {
|
|
|
|
rut: '12345678-9',
|
2025-08-05 18:18:05 -04:00
|
|
|
nombreCompleto: 'Pedro Jimenez'
|
2025-07-22 18:21:05 -04:00
|
|
|
},
|
|
|
|
fecha: '2021-10-01',
|
2025-08-05 18:18:05 -04:00
|
|
|
offer: 1000,
|
|
|
|
valid: false,
|
|
|
|
broker: {
|
|
|
|
name: 'Operador 2'
|
|
|
|
}
|
2025-07-22 18:21:05 -04:00
|
|
|
}
|
|
|
|
]
|
2025-08-05 18:18:05 -04:00
|
|
|
this.components.reservations.pending.set().reservations(reservations).draw()
|
|
|
|
},
|
|
|
|
rejected: project_id => {
|
|
|
|
const reservations = [
|
|
|
|
{
|
|
|
|
id: 3,
|
|
|
|
summary: 'D3',
|
|
|
|
buyer: {
|
|
|
|
rut: '12345678-9',
|
|
|
|
nombreCompleto: 'Fernando Dominguez'
|
|
|
|
},
|
|
|
|
fecha: '2021-01-10',
|
|
|
|
offer: 1000,
|
|
|
|
valid: false,
|
|
|
|
state: 'rechazado',
|
|
|
|
broker: {
|
|
|
|
name: 'Operador 3'
|
|
|
|
},
|
|
|
|
comments: ['Comentarios']
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 4,
|
|
|
|
summary: 'D4',
|
|
|
|
buyer: {
|
|
|
|
rut: '12345678-9',
|
|
|
|
nombreCompleto: 'Domingo Gomez'
|
|
|
|
},
|
|
|
|
fecha: '2021-02-01',
|
|
|
|
offer: 1000,
|
|
|
|
valid: false,
|
|
|
|
state: 'abandonado',
|
|
|
|
broker: {
|
|
|
|
name: 'Operador 4'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
this.components.reservations.rejected.set().reservations(reservations).draw()
|
|
|
|
},
|
|
|
|
reservations: project_id => {
|
|
|
|
this.get().active(project_id)
|
|
|
|
this.get().pending(project_id)
|
|
|
|
this.get().rejected(project_id)
|
2025-07-22 18:21:05 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
action() {
|
|
|
|
return {
|
|
|
|
reset: event => {
|
|
|
|
event.preventDefault()
|
|
|
|
this.components.projects.current_project = null
|
2025-08-05 18:18:05 -04:00
|
|
|
Object.entries(this.components.reservations).forEach(([key, value]) => {
|
|
|
|
this.components.reservations[key].reservations = []
|
|
|
|
this.components.reservations[key].hide()
|
|
|
|
})
|
2025-07-22 18:21:05 -04:00
|
|
|
this.components.projects.show()
|
|
|
|
return false
|
|
|
|
},
|
|
|
|
up: event => {
|
|
|
|
event.preventDefault()
|
2025-08-05 18:18:05 -04:00
|
|
|
Object.values(this.components.reservations).forEach(reservations => reservations.hide())
|
2025-07-22 18:21:05 -04:00
|
|
|
this.components.projects.show()
|
|
|
|
return false
|
|
|
|
},
|
2025-08-05 18:18:05 -04:00
|
|
|
add: event => {
|
|
|
|
event.preventDefault()
|
|
|
|
console.debug('Add')
|
|
|
|
return false
|
|
|
|
},
|
2025-07-22 18:21:05 -04:00
|
|
|
reservations: () => {
|
2025-08-05 18:18:05 -04:00
|
|
|
Object.values(this.components.reservations).forEach(reservations => {
|
|
|
|
reservations.draw()
|
|
|
|
})
|
2025-07-22 18:21:05 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setup(configuration) {
|
|
|
|
const formatters = {
|
|
|
|
date: new Intl.DateTimeFormat('es-CL', {year: 'numeric', month: 'long', day: 'numeric'}),
|
|
|
|
ufs: new Intl.NumberFormat('es-CL', {minimumFractionDigits: 2, maximumFractionDigits: 2})
|
|
|
|
}
|
|
|
|
this.components.projects = new Projects({component_id: configuration.ids.projects, title_id: configuration.ids.project})
|
2025-08-05 18:18:05 -04:00
|
|
|
this.components.controls = new Controls({component_id: configuration.ids.controls})
|
|
|
|
this.components.reservations.active = new ActiveReservations({component_id: configuration.ids.active, formatters})
|
|
|
|
this.components.reservations.pending = new PendingReservations({component_id: configuration.ids.pending, formatters})
|
|
|
|
this.components.reservations.rejected = new RejectedReservations({component_id: configuration.ids.rejected, formatters})
|
|
|
|
|
|
|
|
$(`#${configuration.ids.tabs} .item`).tab()
|
2025-07-22 18:21:05 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
$(document).ready(() => {
|
|
|
|
reservations.setup({
|
|
|
|
ids: {
|
|
|
|
projects: 'projects',
|
|
|
|
project: 'project',
|
|
|
|
controls: 'controls',
|
2025-08-05 18:18:05 -04:00
|
|
|
tabs: 'tabs',
|
|
|
|
active: 'active_reservations',
|
|
|
|
pending: 'pending_reservations',
|
|
|
|
rejected: 'rejected_reservations',
|
2025-07-22 18:21:05 -04:00
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
</script>
|
|
|
|
@endpush
|