2023-11-22 19:08:19 -03:00
@ extends ( 'layout.base' )
@ section ( 'page_content' )
< div class = " ui container " >
2023-11-29 20:09:08 -03:00
< h2 class = " ui header " >
Facturación -
< a href = " { { $urls -> base } }/proyecto/ { { $venta -> proyecto () -> id } } " >
{{ $venta -> proyecto () -> descripcion }} < span class = " ui tiny text " >< sub >< i
class = " search icon " ></ i ></ sub ></ span >
</ a >
-
< a href = " { { $urls -> base } }/venta/ { { $venta -> id } } " >
{{ $venta -> propiedad () -> summary ()}}
</ a >
</ h2 >
2024-04-28 23:01:55 -04:00
< span id = " venta " ></ span >
2024-04-18 20:30:26 -04:00
< div id = " facturas " ></ div >
2024-04-28 23:01:55 -04:00
</ div >
2023-11-22 19:08:19 -03:00
@ endsection
2023-11-29 20:09:08 -03:00
2024-04-28 23:01:55 -04:00
@ include ( 'layout.body.scripts.luxon' )
2023-11-29 20:09:08 -03:00
@ push ( 'page_scripts' )
< script >
2024-04-28 23:01:55 -04:00
class BaseObject {
2024-04-18 20:30:26 -04:00
props
constructor ( props ) {
this . props = props
}
2024-04-28 23:01:55 -04:00
}
class Propietario extends BaseObject {
update () {
return {
proporcion : ( valor ) => {
this . props . proporcion = valor
facturas . draw () . facturas ()
},
rut : rut => {
this . props . rut = rut
facturas . draw () . facturas ()
},
nombre : nombre => {
this . props . nombre = nombre
facturas . draw () . facturas ()
},
direccion : direccion => {
this . props . direccion = direccion
facturas . draw () . facturas ()
},
comuna : comuna => {
this . props . comuna = comuna
facturas . draw () . facturas ()
},
fecha : fecha => {
this . props . fecha = fecha
this . update () . uf ( fecha ) . then (() => {
facturas . draw () . facturas ()
})
},
uf : fecha => {
const url = '{{$urls->api}}/money/uf'
const method = 'post'
const body = new FormData ()
body . set ( 'fecha' , [ fecha . getFullYear (), fecha . getMonth () + 1 , fecha . getDate ()] . join ( '-' ))
return fetchAPI ( url , { method , body }) . then ( response => {
if ( ! response ) {
return
}
return response . json () . then ( json => {
if ( typeof json . uf === 'undefined' ) {
return
}
this . props . uf = parseFloat ( json . uf )
})
})
}
}
}
watch () {
return {
propietario : () => {
this . watch () . proporcion ()
this . watch () . rut ()
this . watch () . nombre ()
this . watch () . direccion ()
this . watch () . comuna ()
this . watch () . fecha ()
},
proporcion : () => {
document . getElementById ( 'proporcion' + this . props . index ) . addEventListener ( 'input' , inputEvent => {
const newValue = inputEvent . currentTarget . value / 100
if ( newValue === this . props . proporcion ) {
return
}
const saldo = facturas . venta . props . propietarios . reduce (( sum , propietario ) => sum + propietario . props . proporcion , 0 ) - this . props . proporcion
if ( saldo + newValue > 1 ) {
return
}
this . update () . proporcion ( newValue )
})
},
rut : () => {},
nombre : () => {},
direccion : () => {},
comuna : () => {},
fecha : () => {
const cdo = structuredClone ( calendar_date_options )
cdo [ 'initialDate' ] = this . props . fecha
cdo [ 'onChange' ] = ( date , text , mode ) => {
this . update () . fecha ( date )
}
$ ( '#fecha_factura' + this . props . index ) . calendar ( cdo )
}
}
}
draw () {
return {
propietario : () => {
const output = [ '<div class="fields" data-index="' + this . props . index + '">' ]
output . push ( this . draw () . proporcion ())
output . push ( this . draw () . rut ())
output . push ( this . draw () . nombre ())
2024-04-30 20:27:05 -04:00
//output.push(this.draw().fecha())
2024-04-28 23:01:55 -04:00
output . push ( '</div>' )
output . push ( '<div class="fields" data-index="' + this . props . index + '">' )
output . push ( '<div class="three wide field"></div>' )
output . push ( this . draw () . direccion ())
output . push ( this . draw () . comuna ())
output . push ( '</div>' )
return output . join ( " \n " )
},
proporcion : () => {
return [
'<div class="two wide field">' ,
'<label for="proporcion' + this . props . index + '">Proporción Factura</label>' ,
'<div class="ui right labeled input">' ,
'<input type="number" name="proporcion' + this . props . index + '" id="proporcion' + this . props . index + '" value="' + ( this . props . proporcion * 100 ) + '" max="100" min="0" />' ,
'<div class="ui basic icon label">' ,
'<i class="percent icon"></i>' ,
'</div>' ,
'</div>' ,
'</div>' ,
] . join ( " \n " )
},
rut : () => {
return [
'<div class="three wide field">' ,
'<label for="rut' + this . props . index + '">RUT</label>' ,
'<div class="ui input">' ,
'<input type="text" name="rut' + this . props . index + '" id="rut' + this . props . index + '" value="' + this . props . rut . toUpperCase () + '" />' ,
'</div>' ,
'</div>' ,
] . join ( " \n " )
},
nombre : () => {
return [
'<div class="six wide field">' ,
'<label for="propietario' + this . props . index + '">Propietario</label>' ,
'<div class="ui input">' ,
'<input type="text" name="propietario' + this . props . index + '" id="propietario' + this . props . index + '" value="' + this . props . nombre + '" />' ,
'</div>' ,
'</div>' ,
] . join ( " \n " )
},
direccion : () => {
return [
'<div class="six wide field">' ,
'<label for="direccion_propietario' + this . props . index + '">Dirección</label>' ,
'<div class="ui input">' ,
'<input type="text" name="direccion_propietario' + this . props . index + '" id="direccion_propietario' + this . props . index + '" value="' + this . props . direccion + '" />' ,
'</div>' ,
'</div>' ,
] . join ( " \n " )
},
comuna : () => {
return [
'<div class="two wide field">' ,
'<label for="comuna_propietario' + this . props . index + '">Comuna</label>' ,
'<input type="text" name="comuna_propietario' + this . props . index + '" id="comuna_propietario' + this . props . index + '" value="' + this . props . comuna + '" />' ,
'</div>' ,
] . join ( " \n " )
},
fecha : () => {
return [
'<div class="three wide field">' +
'<label for="fecha_factura' + this . props . index + '">Fecha Factura</label>' +
'<div class="ui calendar" id="fecha_factura' + this . props . index + '">' +
'<div class="ui right icon input">' +
'<input type="text" name="fecha_factura' + this . props . index + '" />' +
'<i class="calendar icon"></i>' +
'</div>' +
'</div>' +
'</div>'
] . join ( " \n " )
}
}
}
}
class Unidad extends BaseObject {
update () {
return {
precio : newValue => {
const url = '{{$urls->api}}/ventas/propiedades/unidad/' + this . props . propiedad_unidad_id + '/edit'
const method = 'post'
const body = new FormData ()
body . set ( 'valor' , newValue )
return fetchAPI ( url , { method , body }) . then ( response => {
if ( ! response ) {
return
}
return response . json () . then ( json => {
if ( ! json . edited ) {
return
}
this . props . valor = parseFloat ( json . input . valor )
//document.getElementById('precio' + this.props.propiedad_unidad_id).value = json.input.valor
})
})
},
prorrateo : newValue => {
const url = '{{$urls->api}}/ventas/unidad/' + this . props . id + '/prorrateo'
const method = 'post'
const body = new FormData ()
body . set ( 'prorrateo' , newValue )
return fetchAPI ( url , { method , body }) . then ( response => {
if ( ! response ) {
return
}
return response . json () . then ( json => {
if ( ! json . edited ) {
return
}
this . props . prorrateo = json . input . prorrateo
document . getElementById ( 'prorrateo' + this . props . id ) . parentElement . parentElement . innerHTML = ''
})
})
}
}
}
watch () {
return {
unidad : () => {
this . watch () . precio ()
this . watch () . prorrateo ()
},
precio : () => {
document . getElementById ( 'precio' + this . props . propiedad_unidad_id ) . addEventListener ( 'change' , changeEvent => {
const newValue = changeEvent . currentTarget . value
if ( newValue === this . props . valor ) {
return
}
this . update () . precio ( newValue ) . then (() => {
facturas . venta . update () . totalUnidades ()
facturas . draw () . facturas ()
})
})
},
prorrateo : () => {
const input = document . getElementById ( 'prorrateo' + this . props . id )
if ( input === null ) {
return
}
input . addEventListener ( 'change' , changeEvent => {
const newValue = changeEvent . currentTarget . value
if ( newValue === this . props . prorrateo ) {
return
}
this . update () . prorrateo ( newValue )
facturas . draw () . facturas ()
})
}
}
}
draw () {
return {
precio : () => {
return [
'<div class="three wide field">' ,
'<label for="precio' + this . props . propiedad_unidad_id + '">Precio<br /> ' + this . props . tipo + ' ' + this . props . descripcion + '</label>' ,
'<div class="ui left labeled input" id="input' + this . props . propiedad_unidad_id + '">' ,
'<div class="ui basic label">UF</div>' ,
'<input class="price" type="text" name="precio' + this . props . propiedad_unidad_id + '" id="precio' + this . props . propiedad_unidad_id + '" data-id="' + this . props . propiedad_unidad_id + '" value="' + this . props . valor + '" />' ,
'</div>' ,
'</div>'
] . join ( " \n " )
},
prorrateo : () => {
const output = []
output . push ( '<div class="three wide field">' )
if ( this . props . prorrateo === 0 ) {
output . push ( ... [
'<label for="prorrateo' + this . props . id + '">Prorrateo<br /> ' + this . props . tipo + ' ' + this . props . descripcion + '</label>' ,
'<div class="ui right labeled input">' ,
'<input class="prorrateo" type="text" id="prorrateo' + this . props . id + '" value="' + this . props . prorrateo + '" />' ,
'<div class="ui basic label">%</div>' ,
'</div>'
])
}
output . push ( '</div>' )
return output . join ( " \n " )
}
}
}
}
class Venta extends BaseObject {
update () {
return {
propietarios : count => {
const diff = count - this . props . propietarios . length
if ( diff > 0 ) {
const m = this . props . propietarios . length / count
let p = 1
this . props . propietarios . forEach (( propietario , index ) => {
this . props . propietarios [ index ] . props . proporcion = parseFloat (( this . props . propietarios [ index ] . props . proporcion * m * 100 ) . toFixed ( 0 )) / 100
p -= this . props . propietarios [ index ] . props . proporcion
})
p /= diff
const watch = []
for ( let i = 0 ; i < diff ; i ++ ) {
const propietario = this . add () . propietario ({
rut : '' ,
nombre : '' ,
proporcion : ( p * 100 ) . toFixed ( 0 ) / 100 ,
direccion : '' ,
comuna : '' ,
fecha : this . props . estado . fecha ,
uf : this . props . uf
})
watch . push ( propietario )
}
document . getElementById ( 'propietarios' ) . innerHTML = this . draw () . propietarios ()
this . watch () . propietarios ()
return
}
for ( let i = this . props . propietarios . length - 1 ; i >= count ; i -- ) {
this . remove () . propietario ( i )
}
},
fecha : date => {
2024-04-29 10:45:19 -04:00
this . props . uf . fecha = date
2024-04-28 23:01:55 -04:00
const url = '{{$urls->api}}/money/uf'
const method = 'post'
const body = new FormData ()
body . set ( 'fecha' , [ date . getFullYear (), date . getMonth () + 1 , date . getDate ()] . join ( '-' ))
return fetchAPI ( url , { method , body }) . then ( response => {
if ( ! response ) {
return
}
return response . json () . then ( json => {
if ( typeof json . uf === 'undefined' ) {
return
}
2024-04-29 10:45:19 -04:00
this . props . uf . valor = json . uf
2024-04-28 23:01:55 -04:00
})
})
},
2024-04-30 20:27:05 -04:00
fechaFacturas : date => {
this . props . fechaFacturas = date
this . props . propietarios . forEach (( propietario , index ) => {
this . props . propietarios [ index ] . props . fecha = date
})
},
2024-04-28 23:01:55 -04:00
totalUnidades : () => {
const unidades = this . props . unidades . reduce (( sum , unidad ) => sum + unidad . props . valor , 0 )
const diff = parseFloat (( this . props . valor - unidades ) . toFixed ( 4 ))
const $total = $ ( '#total_unidades' )
if ( diff === 0 ) {
$total . html ( '' )
return
}
$total . html ( '<div class="ui error compact message">' +
'<div class="header">' +
'<i class="exclamation triangle icon"></i>' +
'Diferencia Promesa - Precio Unidades</div>' +
'UF ' + facturas . formatters . ufs . format ( diff ) +
'</div>' )
$total . find ( '.ui.message' ) . css ( 'display' , 'inline-block' )
},
terreno : newValue => {
const date = this . props . last . dicember
2024-04-18 20:30:26 -04:00
2024-04-28 23:01:55 -04:00
const url = '{{$urls->api}}/proyecto/{{$venta->proyecto()->id}}/terreno/edit'
const method = 'post'
const body = new FormData ()
body . set ( 'valor' , newValue )
body . set ( 'fecha' , [ date . getFullYear (), date . getMonth () + 1 , date . getDate ()] . join ( '-' ))
return fetchAPI ( url , { method , body }) . then ( response => {
if ( ! response ) {
return
}
return response . json () . then ( json => {
if ( ! json . edited ) {
return
}
this . props . terreno . fecha = this . props . last . dicember
this . props . terreno . valor = parseInt ( json . input . valor )
document . getElementById ( 'terreno' ) . parentElement . parentElement . remove ()
this . update () . ipc ()
})
})
},
ipc : () => {
const mesAnterior = DateTime . fromISO ( this . props . estado . fecha . toISOString ()) . minus ({ months : 1 })
const url = '{{$urls->api}}/money/ipc'
const method = 'post'
const body = new FormData ()
body . set ( 'start' , [ this . props . last . november . getFullYear (), this . props . last . november . getMonth () + 1 , this . props . last . november . getDate ()] . join ( '-' ))
body . set ( 'end' , [ mesAnterior . year , mesAnterior . month , mesAnterior . day ] . join ( '-' ))
return fetchAPI ( url , { method , body }) . then ( response => {
if ( ! response ) {
return
}
return response . json () . then ( json => {
this . props . terreno . reajustado *= ( 1 + parseFloat ( json . ipc ))
})
})
},
form : () => {
// fecha
// unidades
// valor total unidades
// terreno
// propietarios
// ipc no disponible
}
}
}
watch () {
return {
venta : () => {
this . watch () . fecha ()
2024-04-30 20:27:05 -04:00
this . watch () . fechaFacturas ()
2024-04-28 23:01:55 -04:00
this . watch () . unidades ()
this . watch () . terreno ()
this . watch () . cantidad ()
this . watch () . propietarios ()
this . update () . totalUnidades ()
},
fecha : () => {
const cdo = structuredClone ( calendar_date_options )
cdo [ 'initialDate' ] = this . props . estado . fecha
cdo [ 'onChange' ] = ( date , text , mode ) => {
2024-04-29 10:45:19 -04:00
this . update () . fecha ( date ) . then (() => {
facturas . draw () . facturas ()
})
2024-04-28 23:01:55 -04:00
}
$ ( '#fecha_uf' ) . calendar ( cdo )
},
2024-04-30 20:27:05 -04:00
fechaFacturas : () => {
const cdo = structuredClone ( calendar_date_options )
cdo [ 'initialDate' ] = this . props . estado . fecha
cdo [ 'onChange' ] = ( date , text , mode ) => {
this . update () . fechaFacturas ( date )
facturas . draw () . facturas ()
}
$ ( '#fecha_facturas' ) . calendar ( cdo )
},
2024-04-28 23:01:55 -04:00
unidades : () => {
this . props . unidades . forEach ( unidad => {
unidad . watch () . unidad ()
})
},
terreno : () => {
const terreno = document . getElementById ( 'terreno' )
if ( typeof terreno === 'undefined' || terreno === null ) {
return
}
terreno . addEventListener ( 'change' , changeEvent => {
const newValue = changeEvent . currentTarget . value
if ( newValue === this . props . terreno . valor ) {
return
}
this . update () . terreno ( newValue )
})
},
cantidad : () => {
document . getElementById ( 'cantidad_propietarios' ) . addEventListener ( 'change' , changeEvent => {
const count = changeEvent . currentTarget . value
const diff = count - this . props . propietarios . length
if ( diff === 0 ) {
return
}
this . update () . propietarios ( count )
facturas . draw () . facturas ()
})
},
propietarios : () => {
this . props . propietarios . forEach ( propietario => {
propietario . watch () . propietario ()
})
}
}
}
draw () {
return {
venta : ufFormatter => {
return [
this . draw () . value ( ufFormatter ),
this . draw () . form (),
this . draw () . ipc ()
] . join ( " \n " )
},
value : ufFormatter => {
return [
'<div class="ui grid">' ,
'<div class="three wide column">' ,
'<div class="ui very segment">' ,
'Valor Venta: UF ' + ufFormatter . format ( this . props . valor ),
'</div>' ,
'</div>' ,
'</div>'
] . join ( " \n " )
},
form : () => {
const output = []
output . push ( '<form id="venta_form" class="ui form">' )
output . push ( this . draw () . fecha ())
2024-04-30 20:27:05 -04:00
output . push ( this . draw () . fechaFactura ())
2024-04-28 23:01:55 -04:00
output . push ( this . draw () . precios ())
output . push ( this . draw () . prorrateos ())
output . push ( '<div class="ui very basic segment" id="total_unidades"></div>' )
output . push ( this . draw () . terreno ())
output . push ( ... [
'<div class="two wide field">' ,
'<label for="propietarios">Propietarios</label>' ,
'<input type="number" name="cantidad_propietarios" id="cantidad_propietarios" min="1" value="1" />' ,
'</div>' ,
])
output . push ( '<div id="propietarios">' )
output . push ( this . draw () . propietarios ())
output . push ( '</div>' )
output . push ( '</form>' )
return output . join ( " \n " )
},
fecha : () => {
return [
'<div class="three wide field">' ,
'<label for="fecha_uf">Fecha UF</label>' ,
'<div class="ui calendar" id="fecha_uf">' ,
'<div class="ui right icon input">' ,
'<input type="text" name="fecha_uf" />' ,
'<i class="calendar icon"></i>' ,
'</div>' ,
'</div>' ,
'</div>' ,
] . join ( " \n " )
},
2024-04-30 20:27:05 -04:00
fechaFactura : () => {
return [
'<div class="three wide field">' ,
'<label for="fecha_uf">Fecha Facturas</label>' ,
'<div class="ui calendar" id="fecha_facturas">' ,
'<div class="ui right icon input">' ,
'<input type="text" name="fecha_facturas" />' ,
'<i class="calendar icon"></i>' ,
'</div>' ,
'</div>' ,
'</div>' ,
] . join ( " \n " )
},
2024-04-28 23:01:55 -04:00
precios : () => {
const output = []
output . push ( '<div class="fields">' )
this . props . unidades . forEach ( unidad => {
output . push ( unidad . draw () . precio ())
})
output . push ( '</div>' )
return output . join ( " \n " )
},
prorrateos : () => {
const output = []
output . push ( '<div class="fields">' )
this . props . unidades . forEach ( unidad => {
output . push ( unidad . draw () . prorrateo ())
})
output . push ( '</div>' )
return output . join ( " \n " )
},
terreno : () => {
const output = []
if ( typeof this . props . terreno . fecha === 'undefined' || this . props . terreno . fecha === null || this . props . terreno . fecha . getTime () < 0 || this . props . terreno . fecha < this . props . last . dicember ) {
output . push ( ... [
'<div class="four wide field">' ,
'<label for="terreno">Valor Terreno al ' + this . props . last . dicember . toString () + '</label>' ,
'<div class="ui left labeled input">' ,
'<div class="ui basic label">$</div>' ,
'<input type="number" id="terreno" />' ,
'</div>' ,
'</div>'
])
}
return output . join ( " \n " )
},
propietarios : () => {
const output = []
this . props . propietarios . forEach ( propietario => {
output . push ( propietario . draw () . propietario ())
})
return output . join ( " \n " )
},
ipc : () => {
if ( ! ( this . props . fecha > this . props . terreno . fecha && this . props . terreno . valor === 0 )) {
return ''
}
return [
'<div class="ui compact icon error message">' ,
'<i class="exclamation triangle icon"></i>' ,
'<div class="content">' ,
'IPC no disponible para este mes.' ,
'</div>' ,
'</div>'
] . join ( " \n " )
},
facturas : formatters => {
const output = []
this . props . facturas . forEach (( factura , index ) => {
output . push ( factura . draw () . factura ({
proyecto : this . props . proyecto ,
propietario : this . props . propietarios [ index ],
unidades : this . props . unidades ,
terreno : this . props . terreno ,
2024-04-29 10:45:19 -04:00
venta : this . valores ( this . props . uf . valor ),
uf : this . props . uf ,
2024-04-28 23:01:55 -04:00
formatters
}))
})
return output . join ( " \n " )
}
}
}
valores ( uf ) {
const total = this . props . valor * uf
const prorrateo = this . props . unidades . reduce (( sum , unidad ) => sum + unidad . props . prorrateo , 0 )
const exento = this . props . terreno . reajustado * prorrateo
const bruto = total - exento
const neto = bruto / 1.19
const iva = neto * . 19
const base = neto + exento
return {
base ,
exento ,
neto ,
iva ,
bruto ,
descuento : prorrateo ,
total ,
totalUF : total / uf ,
}
}
add () {
return {
propietario : ({ rut , nombre , proporcion , direccion , comuna , fecha , uf }) => {
const index = this . props . propietarios . length + 1
const propietario = new Propietario ({ index , rut , nombre , proporcion , direccion , comuna , fecha , uf })
this . props . propietarios . push ( propietario )
this . add () . factura ( propietario )
return propietario
},
factura : propietario => {
const factura = new Factura ({ index : propietario . props . index })
this . props . facturas . push ( factura )
}
}
}
remove () {
return {
propietario : index => {
if ( index <= 0 ) {
return
}
const P1 = this . props . propietarios . reduce (( sum , propietario ) => sum + propietario . props . proporcion , 0 )
const propietario = this . props . propietarios . splice ( index , 1 )[ 0 ]
const P2 = this . props . propietarios . reduce (( sum , propietario ) => sum + propietario . props . proporcion , 0 )
document . querySelectorAll ( " [data-index=' " + propietario . props . index + " '] " ) . forEach ( field => {
field . remove ()
})
this . remove () . factura ( index )
},
factura : index => {
this . props . facturas . splice ( index , 1 )
document . getElementById ( 'facturas' ) . querySelectorAll ( " [data-index=' " + ( index + 1 ) + " '] " ) . forEach ( factura => {
factura . remove ()
})
}
}
}
}
class Factura extends BaseObject {
draw () {
return {
divider : index => {
return '<div class="ui divider" data-index="' + index + '"></div>'
},
2024-04-29 10:45:19 -04:00
factura : ({ proyecto , propietario , unidades , terreno , venta , uf , formatters = { date , pesos , ufs , percent }}) => {
2024-04-28 23:01:55 -04:00
return [
this . draw () . divider ( propietario . props . index ),
'<div class="factura" data-index="' + propietario . props . index + '">' ,
'<div class="ui compact grid">' ,
this . draw () . cabecera ( proyecto ),
this . draw () . propietario ({ propietario , formatters }),
2024-04-29 10:45:19 -04:00
this . draw () . table ({ venta , unidades , propietario , terreno , uf , formatters }),
this . draw () . totales ({ propietario , venta , uf , formatters }),
2024-04-28 23:01:55 -04:00
'</div>' ,
'</div>'
] . join ( " \n " )
},
cabecera : proyecto => {
return [
'<div class="two columns row">' ,
this . draw () . inmobiliaria ( proyecto ),
this . draw () . rut ( proyecto . inmobiliaria ),
'</div>'
] . join ( " \n " )
},
inmobiliaria : proyecto => {
return [
'<div class="twelve wide column">' ,
'<strong>' + proyecto . inmobiliaria . nombre . toUpperCase () + '</strong><br/>' ,
'GIRO: <br/>' ,
'Dirección: ' + proyecto . direccion ,
'</div>' ,
] . join ( " \n " )
},
rut : inmobiliaria => {
return [
'<div class="four wide column">' ,
'<div class="ui center aligned red segment">' ,
'<strong>' ,
'RUT:' + inmobiliaria . rut . toUpperCase () + '<br/>' ,
'FACTURA ELECTRÓNICA<br/>' ,
'N° #' ,
'</strong>' ,
'</div>' ,
'</div>'
] . join ( " \n " )
},
propietario : ({ propietario , formatters }) => {
return [
'<div class="row">' ,
'<table class="ui table">' ,
'<tr>' +
'<td class="grey"><strong>Señor(es)</strong></td>' ,
'<td>' + propietario . props . nombre + '</td>' ,
'<td class="grey"><strong>RUT</strong></td>' ,
'<td>' + propietario . props . rut . toUpperCase () + '</td>' ,
'</tr>' ,
'<tr>' ,
'<td class="grey"><strong>Giro</strong></td>' ,
'<td>Otras Actividades Profesionales</td>' ,
'<td class="grey"><strong>Fecha Emisión</strong></td>' ,
'<td>' + formatters . date . format ( propietario . props . fecha ) + '</td>' ,
'</tr>' ,
'<tr>' ,
'<td class="grey"><strong>Dirección</strong></td>' ,
'<td>' + propietario . props . direccion + '</td>' ,
'<td class="grey"><strong>Comuna</strong></td>' ,
'<td>' + propietario . props . comuna . toUpperCase () + '</td>' ,
'</tr>' ,
'</table>' ,
'</div>'
] . join ( " \n " )
},
2024-04-29 10:45:19 -04:00
table : ({ venta , unidades , propietario , terreno , uf , formatters }) => {
2024-04-28 23:01:55 -04:00
return [
'<div class="row">' ,
'<table class="ui celled table">' ,
'<thead>' ,
'<tr class="grey">' ,
'<th class="center aligned" colspan="6">DETALLES</th>' ,
'</tr>' ,
'<tr class="grey">' ,
'<th>N°</th>' ,
'<th class="center aligned">Descripción</th>' ,
'<th class="center aligned">Cant/Unidad</th>' ,
'<th class="center aligned">Prec. Unit.</th>' ,
'<th class="center aligned">Ind</th>' ,
'<th class="center aligned">Total</th>' ,
'</tr>' ,
'</thead>' ,
'<tbody>' ,
2024-04-29 10:45:19 -04:00
this . draw () . unidades ({ venta , unidades , propietario , terreno , uf , formatters }),
2024-04-28 23:01:55 -04:00
'</tbody>' ,
'<tfoot>' ,
'<tr>' ,
'<td colspan="6">' ,
'<br />' ,
'<br />' ,
'<br />' ,
'<br />' ,
'</td>' ,
'</tr>' ,
'</tfoot>' ,
'</table>' ,
'</div>'
] . join ( " \n " )
},
2024-04-29 10:45:19 -04:00
unidades : ({ venta , unidades , propietario , terreno , uf , formatters }) => {
2024-04-28 23:01:55 -04:00
const unidadesData = []
let no = 1
const classes = [
'' ,
'' ,
'center aligned' ,
'right aligned' ,
'center aligned' ,
'right aligned'
]
unidades . forEach ( unidad => {
unidadesData . push ( this . draw () . unidad ({
unidad ,
propietario ,
terreno ,
2024-04-29 10:45:19 -04:00
uf ,
2024-04-28 23:01:55 -04:00
no : no ++ ,
classes ,
formatters
}))
})
unidadesData . push ( this . draw () . resumen ({
propietario ,
venta ,
2024-04-29 10:45:19 -04:00
uf ,
2024-04-28 23:01:55 -04:00
no ,
classes ,
formatters
}))
return unidadesData . join ( " \n " )
},
2024-04-29 10:45:19 -04:00
unidad : ({ unidad , propietario , terreno , uf , no , classes , formatters }) => {
2024-04-28 23:01:55 -04:00
const descuento = terreno . reajustado * unidad . props . prorrateo
2024-04-29 10:45:19 -04:00
const bruto = unidad . props . valor * uf . valor - descuento
2024-04-28 23:01:55 -04:00
const neto = bruto / 1.19
const data = [
no ,
unidad . props . tipo + ' ' + unidad . props . descripcion + ' (UF ' + formatters . ufs . format ( unidad . props . valor * propietario . props . proporcion ) + ')' ,
'1 UNID' ,
formatters . pesos . format ( neto * propietario . props . proporcion ),
'AF' ,
formatters . pesos . format ( neto * propietario . props . proporcion )
]
const row = [ '<tr>' ]
data . forEach (( value , i ) => {
const cell = [ '<td' ]
if ( classes [ i ] !== '' ) {
cell . push ( ' class="' + classes [ i ] + '"' )
}
cell . push ( '>' + value + '</td>' )
row . push ( cell . join ( '' ))
})
row . push ( '</tr>' )
return row . join ( '' )
},
2024-04-29 10:45:19 -04:00
resumen : ({ propietario , venta , uf , no , classes , formatters }) => {
2024-04-28 23:01:55 -04:00
const emptyTerreno = '<div class="ui tiny red horizontal circular label">0</div>'
const data = [
no ,
'Valor con Terreno: $' + formatters . pesos . format ( venta . base * propietario . props . proporcion ) + ' - Menos valor terreno: $' + (( venta . exento > 0 ) ? formatters . pesos . format ( - venta . exento * propietario . props . proporcion ) : emptyTerreno ) + '<br />' +
'Base imponible (Neto): $' + formatters . pesos . format ( venta . neto * propietario . props . proporcion ) + '<br />' +
'IVA: $' + formatters . pesos . format ( venta . iva * propietario . props . proporcion ) + '<br />' +
'SUBTOTAL (Bruto): $' + formatters . pesos . format (( venta . neto + venta . iva ) * propietario . props . proporcion ) + '<br />' +
'Mas valor terreno: $' + (( venta . exento > 0 ) ? formatters . pesos . format ( venta . exento * propietario . props . proporcion ) : emptyTerreno ) + '<br />' +
'TOTAL (Escritura): $' + formatters . pesos . format ( venta . total * propietario . props . proporcion ) + '; ' + formatters . ufs . format ( venta . totalUF * propietario . props . proporcion ) + ' UF<br /><br />' +
'Descuento Terreno: ' + (( venta . exento > 0 ) ? formatters . percent . format ( venta . descuento * 100 ) : emptyTerreno ) + '%<br /><br />' +
2024-04-29 10:45:19 -04:00
'UF (' + formatters . date . format ( uf . fecha ) + '): $' + formatters . ufs . format ( uf . valor ),
2024-04-28 23:01:55 -04:00
'1 UNID' ,
formatters . pesos . format ( venta . exento * propietario . props . proporcion ),
'EX' ,
formatters . pesos . format ( venta . exento * propietario . props . proporcion )
]
const row = [ '<tr class="top aligned">' ]
data . forEach (( value , i ) => {
const cell = [ '<td' ]
if ( classes [ i ] !== '' ) {
cell . push ( ' class="' + classes [ i ] + '"' )
}
cell . push ( '>' + value + '</td>' )
row . push ( cell . join ( '' ))
})
return row . join ( '' )
},
totales : ({ propietario , venta , formatters }) => {
return [
'<div class="row">' ,
'<div class="ten wide column"></div>' ,
'<div class="six wide column">' ,
'<table class="ui celled very compact table">' ,
'<thead>' ,
'<tr>' ,
'<th class="center aligned grey" colspan="2">TOTALES</th>' ,
'</tr>' ,
'</thead>' ,
'<tbody>' ,
'<tr>' ,
'<td class="grey">Monto Neto</td>' ,
'<td class="right aligned" id="neto">' + formatters . pesos . format ( venta . neto * propietario . props . proporcion ) + '</td>' ,
'</tr>' ,
'<tr>' ,
'<td class="grey">Monto Exento</td>' ,
'<td class="right aligned" id="exento">' + formatters . pesos . format ( venta . exento * propietario . props . proporcion ) + '</td>' ,
'</tr>' ,
'<tr>' ,
'<td class="grey">19% IVA</td>' ,
'<td class="right aligned" id="iva">' + formatters . pesos . format ( venta . iva * propietario . props . proporcion ) + '</td>' ,
'</tr>' ,
'<tr>' ,
'<td class="grey">Monto Total</td>' ,
'<td class="right aligned"><strong id="total">' + formatters . pesos . format ( venta . bruto * propietario . props . proporcion ) + '</strong></td>' ,
'</tr>' ,
'</tbody>' ,
'</table>' ,
'</div>' ,
'</div>'
] . join ( " \n " )
}
}
2024-04-18 20:30:26 -04:00
}
}
2024-04-28 23:01:55 -04:00
const facturas = {
ids : {},
venta : null ,
formatters : {
date : new Intl . DateTimeFormat ( 'es-CL' , { year : 'numeric' , month : '2-digit' , day : '2-digit' }),
pesos : new Intl . NumberFormat ( 'es-CL' , { minimumFractionDigits : 0 , maximumFractionDigits : 0 }),
ufs : new Intl . NumberFormat ( 'es-CL' , { minimumFractionDigits : 2 , maximumFractionDigits : 2 }),
2024-06-10 21:41:11 -04:00
percent : new Intl . NumberFormat ( 'es-CL' , { minimumFractionDigits : 4 , maximumFractionDigits : 4 })
2024-04-18 20:30:26 -04:00
},
draw () {
return {
2024-04-28 23:01:55 -04:00
venta : () => {
document . getElementById ( this . ids . venta ) . innerHTML = this . venta . draw () . venta ( this . formatters . ufs )
this . venta . watch () . venta ()
2024-04-18 20:30:26 -04:00
},
facturas : () => {
2024-04-28 23:01:55 -04:00
document . getElementById ( this . ids . facturas ) . innerHTML = this . venta . draw () . facturas ( this . formatters )
2023-11-29 20:09:08 -03:00
}
}
},
2024-04-28 23:01:55 -04:00
setup ({ ids }) {
this . ids = ids
this . venta = new Venta ({
id : {{ $venta -> id }},
proyecto : {
id : {{ $venta -> proyecto () -> id }},
inmobiliaria : {
rut : '{{$venta->proyecto()->inmobiliaria()->rut()}}' ,
nombre : '{{$venta->proyecto()->inmobiliaria()->nombreCompleto()}}'
},
direccion : '{{$venta->proyecto()->direccion()->simple()}}'
2023-11-30 18:40:15 -03:00
},
2024-04-28 23:01:55 -04:00
valor : {{ $venta -> valor }},
2024-04-29 10:45:19 -04:00
uf : {
fecha : new Date ( '{{$venta->currentEstado()->fecha->add(new DateInterval(' P1D '))->format(' Y - m - d ')}}' ),
valor : {{ $uf }}
},
2024-04-30 20:27:05 -04:00
fechaFactura : new Date ( '{{$venta->currentEstado()->fecha->add(new DateInterval(' P1D '))->format(' Y - m - d ')}}' ),
2024-04-28 23:01:55 -04:00
estado : {
fecha : new Date ( '{{$venta->currentEstado()->fecha->add(new DateInterval(' P1D '))->format(' Y - m - d ')}}' )
2023-11-30 18:40:15 -03:00
},
2024-04-28 23:01:55 -04:00
terreno : {
fecha : new Date ( '{{$terreno->fecha->add(new DateInterval(' P1D '))->format(' Y - m - d ')}}' ),
valor : {{ $terreno -> valor }},
reajustado : {{ $terreno -> valor * ( 1 + $ipc )}}
2024-04-18 20:30:26 -04:00
},
2024-04-28 23:01:55 -04:00
last : {
dicember : new Date ( '{{(new DateTimeImmutable())->sub(new DateInterval(' P1Y '))->format(' Y - 11 - 31 ')}}' ),
november : new Date ( '{{(new DateTimeImmutable())->sub(new DateInterval(' P1Y '))->format(' Y - 11 - 30 ')}}' )
},
unidades : [
@ foreach ( $venta -> propiedad () -> unidades as $unidad )
new Unidad ({
id : {{ $unidad -> id }},
tipo : '{{ucwords($unidad->proyectoTipoUnidad->tipoUnidad->descripcion)}}' ,
descripcion : '{{$unidad->descripcion}}' ,
prorrateo : {{ $unidad -> prorrateo }},
propiedad_unidad_id : {{ $unidad -> pu_id }},
valor : {{( $unidad -> valor > 0 ) ? $unidad -> valor : $unidad -> precio ( $venta -> currentEstado () -> fecha ) -> valor }}
}),
@ endforeach
],
propietarios : [],
facturas : []
2023-11-29 20:09:08 -03:00
})
2024-04-28 23:01:55 -04:00
this . venta . add () . propietario ({
rut : '{{$venta->propietario()->rut()}}' ,
nombre : '{{$venta->propietario()->nombreCompleto()}}' ,
proporcion : 1 ,
direccion : '{{$venta->propietario()->datos->direccion->simple()}}' ,
comuna : '{{$venta->propietario()->datos->direccion->comuna->descripcion}}' ,
fecha : new Date ( '{{$venta->currentEstado()->fecha->add(new DateInterval(' P1D '))->format(' Y - m - d ')}}' ),
uf : {{ $uf }}
2024-04-18 20:30:26 -04:00
})
2024-04-28 23:01:55 -04:00
this . draw () . venta ()
this . draw () . facturas ()
2023-11-29 20:09:08 -03:00
}
}
$ ( document ) . ready (() => {
2024-04-28 23:01:55 -04:00
facturas . setup ({
ids : {
venta : 'venta' ,
facturas : 'facturas'
}
})
2023-11-29 20:09:08 -03:00
})
</ script >
@ endpush