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();
}
$app->get('/add[/]', [Ventas::class, 'add']);
$app->post('/add[/]', [Ventas::class, 'add']);
$app->get('[/]', Ventas::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) {

View File

@ -255,14 +255,18 @@
}
class Comuna {
id
data
data = {
region: 0,
provincias: []
}
propietario
promises = {
provincias: null,
comunas: {}
}
constructor(id) {
this.id = id
this.data = {
region: 0,
provincias: []
}
$(this.id).dropdown({
forceSelection: true
@ -272,13 +276,23 @@
get() {
return {
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'
return fetchAPI(uri).then(response => {
this.promises.provincias = APIClient.fetch(uri).then(response => {
this.promises.provincias = null
if (response.ok) {
return response.json()
}
}).then(data => {
this.data.provincias = data.provincias
this.propietario.data.comunas[this.data.region].provincias = data.provincias
const promises = []
this.data.provincias.forEach(provincia => {
promises.push(this.get().comunas(provincia.id))
@ -287,17 +301,21 @@
this.draw().comunas()
})
})
return this.data.provincias
},
comunas: provincia_id => {
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) {
return response.json()
}
}).then(data => {
this.promises.comunas[data.provincia_id] = null
const i = this.data.provincias.findIndex(provincia => provincia.id === data.provincia_id)
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 {
valid
parent
components = {
rut: null,
region: null
}
constructor({valid}) {
this.valid = valid
}
@ -418,9 +441,10 @@
return lines.join("\n")
}
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')
new Region({id: '#region', comuna})
comuna.propietario = this.parent
this.components.region = new Region({id: '#region', comuna})
}
}
class PersonaTributaria {
@ -572,6 +596,15 @@
}
class Propietario {
ids
components = {
persona: null
}
data = {
comunas: {}
}
promises = {
propietario: null
}
constructor({id, id_tipo, id_cantidad}) {
this.ids = {
@ -591,8 +624,6 @@
document.getElementById(this.ids.cantidad).disabled = !document.getElementById(this.ids.tipo).checked
this.draw()
$(this.ids.span).find('#rut')
}
get tipo() {
return document.getElementById(this.ids.tipo).checked ? (document.getElementById(this.ids.cantidad).checked ? 2 : 0) : 1
@ -613,7 +644,8 @@
return {
propietario: rut => {
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) {
return response.json()
}
@ -627,7 +659,18 @@
parent.find("[name='numero']").val(data.propietario.direccion.numero)
parent.find("[name='extra']").val(data.propietario.direccion.extra)
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='telefono']").val(data.propietario.telefono)
@ -645,6 +688,8 @@
}
draw() {
const propietario = this.get().propietario(this.tipo)
this.components.persona = propietario
propietario.parent = this
$(this.ids.span).html(propietario.draw())
propietario.activate()
}
@ -655,6 +700,9 @@
data
unidades
added
promises = {
unidades: null
}
constructor({unidades_id, proyecto_id}) {
this.ids = {
@ -702,7 +750,8 @@
return {
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) {
return response.json()
}
@ -712,6 +761,7 @@
}
this.unidades = data.unidades
})
return this.promises.unidades
}
}
}
@ -733,6 +783,7 @@
)
)
)
return unidad
}
remove(number) {
number = parseInt(number)
@ -750,6 +801,9 @@
}
class Unidad{
number
components = {
dropdown: null
}
constructor({number}) {
this.number = number
}
@ -772,12 +826,16 @@
})
dropdown.append(menu)
dropdown.dropdown()
this.components.dropdown = dropdown
return dropdown
}
}
class Payment {
ids
components = {
checkbox: null
}
constructor({id, checkbox_id}) {
this.ids = {
@ -785,7 +843,8 @@
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()
@ -812,12 +871,110 @@
form: ''
},
components: {
date: null,
$date: null,
project: null,
buyer: null,
payments: [],
payments: {},
$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}) {
this.ids = {
dateId,
@ -843,10 +1000,10 @@
'bono_pie'
]
payments.forEach(payment => {
this.components.payments.push(new Payment({
this.components.payments[payment] = new Payment({
id: '#' + payment,
checkbox_id: 'has_' + payment
}))
})
})
this.components.$form = $(this.ids.form)
@ -887,17 +1044,13 @@
})
if (fromReservation) {
const date = new Date('{{ $date?->format('Y-m-d') }}')
date.setDate(date.getDate() + 1)
this.components.$date.calendar('set date', date)
$(this.ids.projectId).dropdown('set selection', {{ $proyecto_id }})
this.fill.reservation()
}
}
}
$(document).ready(() => {
const fromReservation = '{{ $fromReservation ?? false }}'
const fromReservation = {{ $from_reservation ? 'true' : 'false' }};
venta.setup({
dateId: '#fecha_venta_calendar',
buyerId: '#propietario',
@ -905,7 +1058,7 @@
buyerNId: 'cantidad_propietario',
unitsId: '#unidades',
projectId: '#proyecto',
fromReservation: fromReservation === 'true'
fromReservation: fromReservation
})
})
</script>