Reservation to Venta add form

This commit is contained in:
Juan Pablo Vial
2025-11-25 17:59:21 -03:00
parent 5f348e954e
commit 9ed918ee03
3 changed files with 191 additions and 30 deletions

View File

@ -10,6 +10,7 @@ $app->group('/ventas', function($app) {
include_once $file->getRealPath(); include_once $file->getRealPath();
} }
$app->get('/add[/]', [Ventas::class, 'add']); $app->get('/add[/]', [Ventas::class, 'add']);
$app->post('/add[/]', [Ventas::class, 'add']);
$app->get('[/]', Ventas::class); $app->get('[/]', Ventas::class);
})->add($app->getContainer()->get(Incoviba\Middleware\Authentication::class)); })->add($app->getContainer()->get(Incoviba\Middleware\Authentication::class));
$app->group('/venta/{proyecto_nombre:[A-za-zÑñ\+\ %0-9]+}/{unidad_descripcion:[0-9]+}', function($app) { $app->group('/venta/{proyecto_nombre:[A-za-zÑñ\+\ %0-9]+}/{unidad_descripcion:[0-9]+}', function($app) {

View File

@ -255,14 +255,18 @@
} }
class Comuna { class Comuna {
id id
data data = {
region: 0,
provincias: []
}
propietario
promises = {
provincias: null,
comunas: {}
}
constructor(id) { constructor(id) {
this.id = id this.id = id
this.data = {
region: 0,
provincias: []
}
$(this.id).dropdown({ $(this.id).dropdown({
forceSelection: true forceSelection: true
@ -272,13 +276,23 @@
get() { get() {
return { return {
provincias: () => { provincias: () => {
if (this.data.region in this.propietario.data.comunas) {
this.promises.provincias = new Promise(resolve => resolve(this.propietario.data.comunas[this.data.region])).then(data => {
this.data.provincias = data.provincias
this.draw().comunas()
})
return this.promises.provincias
}
this.propietario.data.comunas[this.data.region] = {region: this.data.region, provincias: []}
const uri = '{{$urls->api}}/region/' + this.data.region + '/provincias' const uri = '{{$urls->api}}/region/' + this.data.region + '/provincias'
return fetchAPI(uri).then(response => { this.promises.provincias = APIClient.fetch(uri).then(response => {
this.promises.provincias = null
if (response.ok) { if (response.ok) {
return response.json() return response.json()
} }
}).then(data => { }).then(data => {
this.data.provincias = data.provincias this.data.provincias = data.provincias
this.propietario.data.comunas[this.data.region].provincias = data.provincias
const promises = [] const promises = []
this.data.provincias.forEach(provincia => { this.data.provincias.forEach(provincia => {
promises.push(this.get().comunas(provincia.id)) promises.push(this.get().comunas(provincia.id))
@ -287,17 +301,21 @@
this.draw().comunas() this.draw().comunas()
}) })
}) })
return this.data.provincias
}, },
comunas: provincia_id => { comunas: provincia_id => {
const uri = '{{$urls->api}}/provincia/' + provincia_id + '/comunas' const uri = '{{$urls->api}}/provincia/' + provincia_id + '/comunas'
return fetchAPI(uri).then(response => { this.promises.comunas[provincia_id] = fetchAPI(uri).then(response => {
if (response.ok) { if (response.ok) {
return response.json() return response.json()
} }
}).then(data => { }).then(data => {
this.promises.comunas[data.provincia_id] = null
const i = this.data.provincias.findIndex(provincia => provincia.id === data.provincia_id) const i = this.data.provincias.findIndex(provincia => provincia.id === data.provincia_id)
this.data.provincias[i].comunas = data.comunas this.data.provincias[i].comunas = data.comunas
this.propietario.data.comunas[this.data.region].provincias[i].comunas = data.comunas
}) })
return this.promises.comunas[provincia_id]
} }
} }
} }
@ -347,6 +365,11 @@
} }
class PersonaNatural { class PersonaNatural {
valid valid
parent
components = {
rut: null,
region: null
}
constructor({valid}) { constructor({valid}) {
this.valid = valid this.valid = valid
} }
@ -418,9 +441,10 @@
return lines.join("\n") return lines.join("\n")
} }
activate() { activate() {
new RutHandler({id: '#rut', alert_id: '#alert_rut', valid: this.valid}) this.components.rut = new RutHandler({id: '#rut', alert_id: '#alert_rut', valid: this.valid})
const comuna = new Comuna('#comuna') const comuna = new Comuna('#comuna')
new Region({id: '#region', comuna}) comuna.propietario = this.parent
this.components.region = new Region({id: '#region', comuna})
} }
} }
class PersonaTributaria { class PersonaTributaria {
@ -572,6 +596,15 @@
} }
class Propietario { class Propietario {
ids ids
components = {
persona: null
}
data = {
comunas: {}
}
promises = {
propietario: null
}
constructor({id, id_tipo, id_cantidad}) { constructor({id, id_tipo, id_cantidad}) {
this.ids = { this.ids = {
@ -591,8 +624,6 @@
document.getElementById(this.ids.cantidad).disabled = !document.getElementById(this.ids.tipo).checked document.getElementById(this.ids.cantidad).disabled = !document.getElementById(this.ids.tipo).checked
this.draw() this.draw()
$(this.ids.span).find('#rut')
} }
get tipo() { get tipo() {
return document.getElementById(this.ids.tipo).checked ? (document.getElementById(this.ids.cantidad).checked ? 2 : 0) : 1 return document.getElementById(this.ids.tipo).checked ? (document.getElementById(this.ids.cantidad).checked ? 2 : 0) : 1
@ -613,7 +644,8 @@
return { return {
propietario: rut => { propietario: rut => {
const uri = '{{$urls->api}}/ventas/propietario/' + rut.split('-')[0] const uri = '{{$urls->api}}/ventas/propietario/' + rut.split('-')[0]
return fetchAPI(uri).then(response => { this.promises.propietario = APIClient.fetch(uri).then(response => {
this.promises.propietario = null
if (response.ok) { if (response.ok) {
return response.json() return response.json()
} }
@ -627,7 +659,18 @@
parent.find("[name='numero']").val(data.propietario.direccion.numero) parent.find("[name='numero']").val(data.propietario.direccion.numero)
parent.find("[name='extra']").val(data.propietario.direccion.extra) parent.find("[name='extra']").val(data.propietario.direccion.extra)
parent.find('#region').dropdown('set selected', data.propietario.direccion.comuna.provincia.region.id) parent.find('#region').dropdown('set selected', data.propietario.direccion.comuna.provincia.region.id)
parent.find('#comuna').dropdown('set selected', data.propietario.direccion.comuna.id) let persona = this.components.persona
if (!('components' in persona)) {
persona = persona.persona
}
const promise = persona.components.region.comuna.promises.provincias
if (promise === null) {
parent.find('#comuna').dropdown('set selected', data.propietario.direccion.comuna.id)
} else {
promise.then(() => {
parent.find('#comuna').dropdown('set selected', data.propietario.direccion.comuna.id)
})
}
parent.find("[name='email']").val(data.propietario.email) parent.find("[name='email']").val(data.propietario.email)
parent.find("[name='telefono']").val(data.propietario.telefono) parent.find("[name='telefono']").val(data.propietario.telefono)
@ -645,6 +688,8 @@
} }
draw() { draw() {
const propietario = this.get().propietario(this.tipo) const propietario = this.get().propietario(this.tipo)
this.components.persona = propietario
propietario.parent = this
$(this.ids.span).html(propietario.draw()) $(this.ids.span).html(propietario.draw())
propietario.activate() propietario.activate()
} }
@ -655,6 +700,9 @@
data data
unidades unidades
added added
promises = {
unidades: null
}
constructor({unidades_id, proyecto_id}) { constructor({unidades_id, proyecto_id}) {
this.ids = { this.ids = {
@ -702,7 +750,8 @@
return { return {
unidades: () => { unidades: () => {
const uri = '{{$urls->api}}/proyecto/' + this.data.id + '/unidades' const uri = '{{$urls->api}}/proyecto/' + this.data.id + '/unidades'
return fetchAPI(uri).then(response => { this.promises.unidades = APIClient.fetch(uri).then(response => {
this.promises.unidades = null
if (response.ok) { if (response.ok) {
return response.json() return response.json()
} }
@ -712,6 +761,7 @@
} }
this.unidades = data.unidades this.unidades = data.unidades
}) })
return this.promises.unidades
} }
} }
} }
@ -733,6 +783,7 @@
) )
) )
) )
return unidad
} }
remove(number) { remove(number) {
number = parseInt(number) number = parseInt(number)
@ -750,6 +801,9 @@
} }
class Unidad{ class Unidad{
number number
components = {
dropdown: null
}
constructor({number}) { constructor({number}) {
this.number = number this.number = number
} }
@ -772,12 +826,16 @@
}) })
dropdown.append(menu) dropdown.append(menu)
dropdown.dropdown() dropdown.dropdown()
this.components.dropdown = dropdown
return dropdown return dropdown
} }
} }
class Payment { class Payment {
ids ids
components = {
checkbox: null
}
constructor({id, checkbox_id}) { constructor({id, checkbox_id}) {
this.ids = { this.ids = {
@ -785,7 +843,8 @@
checkbox: checkbox_id checkbox: checkbox_id
} }
document.getElementById(this.ids.checkbox).onchange = event => { this.components.checkbox = document.getElementById(this.ids.checkbox)
this.components.checkbox.onchange = event => {
this.toggle() this.toggle()
} }
this.toggle() this.toggle()
@ -812,12 +871,110 @@
form: '' form: ''
}, },
components: { components: {
date: null, $date: null,
project: null, project: null,
buyer: null, buyer: null,
payments: [], payments: {},
$form: null $form: null
}, },
fill: {
reservation: () => {
venta.fill.date()
venta.fill.buyer()
venta.fill.project()
venta.fill.payments()
},
date: () => {
const date = new Date('{{ $date?->format('Y-m-d') }}')
date.setDate(date.getDate() + 1)
venta.components.$date.calendar('set date', date)
},
buyer: () => {
const buyer = $(venta.ids.buyerId)
const rut = buyer.find('#rut')
rut.val('{{ $propietario['full'] }}')
let persona = venta.components.buyer.components.persona
if (!('components' in persona)) {
persona = persona.persona
}
const promise = persona.components.region.comuna.promises.provincias
if (promise === null) {
venta.fill.buyerRut(buyer, rut)
return;
}
promise.then(() => {
venta.fill.buyerRut(buyer, rut)
})
},
buyerRut: (buyer, rut) => {
rut.trigger('change')
const promise = venta.components.buyer.promises.propietario
if (promise === null) {
venta.fill.buyerData(buyer)
return;
}
promise.then(() => {
venta.fill.buyerData(buyer)
})
},
buyerData: buyer => {
const email = buyer.find('[name="email"]')
if (email.val() === '') {
email.val('{{ $propietario['email'] ?? '' }}')
}
const telefono = buyer.find('[name="telefono"]')
if (telefono.val() === '') {
telefono.val('{{ $propietario['telefono'] ?? '' }}')
}
},
project: () => {
$(venta.ids.projectId).dropdown('set selected', {{ $proyecto_id }})
const promise = venta.components.project.promises.unidades
if (promise === null) {
venta.fill.units()
return;
}
promise.then(() => {
venta.fill.units()
})
},
units: () => {
const unitTypes = JSON.parse('{!! json_encode($unidades) !!}')
Object.entries(unitTypes).forEach(([type, units]) => {
units.forEach(unit_id => {
const unit = venta.components.project.add(type)
unit.components.dropdown.dropdown('set selected', unit_id)
})
})
},
payments: () => {
const formaPago = JSON.parse('{!! json_encode($forma_pago) !!}')
Object.entries(formaPago).forEach(([key, value]) => {
const payment = venta.components.payments[key]
const event = new Event('change', {
view: window,
bubbles: true,
cancelable: true
})
payment.components.checkbox.dispatchEvent(event)
if (key in venta.fill.payment) {
venta.fill.payment[key](value)
return
}
console.debug(`No fill defined for payment ${key}`)
})
},
payment: {
pie: data => {
document.querySelector('[name="pie"]').value = data.valor
document.querySelector('[name="cuotas"]').value = data.cuotas
},
credito: data => {
document.querySelector('[name="credito"]').value = data
}
}
},
setup({dateId, buyerId, buyerTypeId, buyerNId, unitsId, projectId, fromReservation = false}) { setup({dateId, buyerId, buyerTypeId, buyerNId, unitsId, projectId, fromReservation = false}) {
this.ids = { this.ids = {
dateId, dateId,
@ -843,10 +1000,10 @@
'bono_pie' 'bono_pie'
] ]
payments.forEach(payment => { payments.forEach(payment => {
this.components.payments.push(new Payment({ this.components.payments[payment] = new Payment({
id: '#' + payment, id: '#' + payment,
checkbox_id: 'has_' + payment checkbox_id: 'has_' + payment
})) })
}) })
this.components.$form = $(this.ids.form) this.components.$form = $(this.ids.form)
@ -887,17 +1044,13 @@
}) })
if (fromReservation) { if (fromReservation) {
const date = new Date('{{ $date?->format('Y-m-d') }}') this.fill.reservation()
date.setDate(date.getDate() + 1)
this.components.$date.calendar('set date', date)
$(this.ids.projectId).dropdown('set selection', {{ $proyecto_id }})
} }
} }
} }
$(document).ready(() => { $(document).ready(() => {
const fromReservation = '{{ $fromReservation ?? false }}' const fromReservation = {{ $from_reservation ? 'true' : 'false' }};
venta.setup({ venta.setup({
dateId: '#fecha_venta_calendar', dateId: '#fecha_venta_calendar',
buyerId: '#propietario', buyerId: '#propietario',
@ -905,7 +1058,7 @@
buyerNId: 'cantidad_propietario', buyerNId: 'cantidad_propietario',
unitsId: '#unidades', unitsId: '#unidades',
projectId: '#proyecto', projectId: '#proyecto',
fromReservation: fromReservation === 'true' fromReservation: fromReservation
}) })
}) })
</script> </script>

View File

@ -115,14 +115,21 @@ class Ventas
if (isset($data['from_reservation']) && $data['from_reservation'] === 'true' && !empty($data['reservation_id'])) { if (isset($data['from_reservation']) && $data['from_reservation'] === 'true' && !empty($data['reservation_id'])) {
try { try {
$reservation = $reservaService->get((int)$data['reservation_id']); $reservation = $reservaService->get((int) $data['reservation_id']);
$viewData['from_reservation'] = true; $viewData['from_reservation'] = true;
$viewData['reservation_id'] = $reservation->id; $viewData['reservation_id'] = $reservation->id;
$viewData['date'] = $reservation->date; $viewData['date'] = $reservation->date;
$viewData['comments'] = explode("\n", $reservation->comments); $viewData['comments'] = explode("\n", $reservation->comments);
$viewData['propietario_rut'] = $reservation->buyer->rut; $viewData['propietario'] = [
'rut' => $reservation->buyer->rut,
'digito' => $reservation->buyer->digito,
'full' => $reservation->buyer->rutCompleto(),
'email' => $reservation->buyer->datos()?->email,
'telefono' => $reservation->buyer->datos()?->telefono,
'comuna_id' => $reservation->buyer->datos()?->direccion?->comuna?->id
];
// Add property data // Add property data
$viewData['proyecto_id'] = $reservation->project->id; $viewData['proyecto_id'] = $reservation->project->id;