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 >
2023-11-30 18:40:15 -03:00
< div class = " ui very basic segment " >
Valor Venta : {{ $format -> ufs ( $venta -> valor )}}
</ div >
2023-11-29 20:09:08 -03:00
< form id = " venta_form " class = " ui form " >
< div class = " two wide field " >
< label for = " proporcion " > Proporción Factura </ label >
< div class = " ui right labeled input " >
< input type = " number " name = " proporcion " id = " proporcion " value = " 100 " max = " 100 " min = " 0 " />
< div class = " ui basic icon label " >
< i class = " percent icon " ></ i >
</ div >
</ div >
</ div >
< div class = " fields " >
@ foreach ( $venta -> propiedad () -> unidades as $unidad )
< div class = " three wide field " >
< label for = " precio { { $unidad -> pu_id } } " > Precio {{ ucwords ( $unidad -> proyectoTipoUnidad -> tipoUnidad -> descripcion )}} {{ $unidad -> descripcion }} </ label >
2023-11-30 18:40:15 -03:00
< div class = " ui right labeled input " id = " input { { $unidad -> pu_id } } " >
2023-11-29 20:09:08 -03:00
< input class = " price " type = " text " name = " precio { { $unidad -> pu_id } } " id = " precio { { $unidad -> pu_id } } " data - id = " { { $unidad -> pu_id } } " value = " { { ( $unidad->valor > 0) ? $unidad->valor : $unidad->precio ( $venta->currentEstado ()->fecha)->valor}} " />
< div class = " ui basic label " > UF </ div >
</ div >
</ div >
@ endforeach
2023-11-22 19:08:19 -03:00
</ div >
2023-11-30 18:40:15 -03:00
< div class = " fields " >
@ foreach ( $venta -> propiedad () -> unidades as $unidad )
< div class = " three wide field " >
@ if ( $unidad -> prorrateo === 0.0 )
< label for = " prorrateo { { $unidad -> id } } " > Prorrateo {{ ucwords ( $unidad -> proyectoTipoUnidad -> tipoUnidad -> descripcion )}} {{ $unidad -> descripcion }} </ label >
< div class = " ui right labeled input " id = " prorrateo { { $unidad -> id } } " >
< input class = " prorrateo " type = " text " data - id = " { { $unidad -> id } } " value = " { { $unidad -> prorrateo } } " />
< div class = " ui basic label " >%</ div >
</ div >
@ endif
</ div >
@ endforeach
</ div >
< div class = " ui very basic segment " id = " total_unidades " ></ div >
@ php $lastDic = new DateTimeImmutable (( new DateTimeImmutable ()) -> sub ( new DateInterval ( 'P1Y' )) -> format ( '31-12-Y' )); @ endphp
@ if ( ! isset ( $venta -> proyecto () -> terreno -> fecha ) or $venta -> proyecto () -> terreno -> fecha < $lastDic )
< div class = " four wide field " >
< label for = " terreno " > Valor Terreno al {{ $lastDic -> format ( 'd-m-Y' )}} </ label >
< div class = " ui left labeled input " >
< div class = " ui basic label " > $ </ div >
< input type = " number " id = " terreno " />
</ div >
</ div >
@ endif
2023-11-22 19:08:19 -03:00
</ form >
2024-01-18 13:15:26 -03:00
@ if ( $venta -> currentEstado () -> fecha -> sub ( new DateInterval ( 'P1M' )) > $venta -> proyecto () -> terreno -> fecha
and $IPC -> get ( $venta -> proyecto () -> terreno -> fecha , $venta -> currentEstado () -> fecha -> sub ( new DateInterval ( 'P1M' ))) === 0.0 )
2023-12-04 19:51:44 -03:00
< div class = " ui compact icon error message " >
< i class = " exclamation triangle icon " ></ i >
< div class = " content " >
IPC no disponible para este mes .
</ div >
</ div >
@ endif
2023-11-29 20:09:08 -03:00
< div class = " ui divider " ></ div >
< div id = " factura " >
< div class = " ui compact grid " >
< div class = " two columns row " >
< div class = " twelve wide column " >
< strong >
{{ mb_strtoupper ( $venta -> proyecto () -> inmobiliaria () -> nombreCompleto ())}}
</ strong >< br />
GIRO : < br />
2023-11-30 18:40:15 -03:00
Dirección : {{ $venta -> proyecto () -> direccion () -> simple ()}}
2023-11-29 20:09:08 -03:00
</ div >
< div class = " four wide column " >
< div class = " ui center aligned red segment " >
< strong >
RUT : {{ $venta -> proyecto () -> inmobiliaria () -> rut ()}} < br />
FACTURA ELECTRÓNICA < br />
N° #
</ strong >
</ div >
</ div >
</ div >
< div class = " row " >
< table class = " ui table " >
< tr >
< td class = " grey " >< strong > Señor ( es ) </ strong ></ td >
< td > {{ $venta -> propietario () -> nombreCompleto ()}} </ td >
< td class = " grey " >< strong > RUT </ strong ></ td >
< td > {{ $venta -> propietario () -> rut ()}} </ 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 > {{( new IntlDateFormatter ( 'es-CL' , IntlDateFormatter :: LONG , IntlDateFormatter :: NONE )) -> format ( $venta -> currentEstado () -> fecha )}} </ td >
</ tr >
< tr >
< td class = " grey " >< strong > Dirección </ strong ></ td >
< td > {{ $venta -> propietario () -> datos -> direccion -> simple ()}} </ td >
< td class = " grey " >< strong > Comuna </ strong ></ td >
< td > {{ mb_strtoupper ( $venta -> propietario () -> datos -> direccion -> comuna -> descripcion )}} </ td >
</ tr >
</ table >
</ div >
< 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 id = " unidades " ></ tbody >
< tfoot >
< tr >
< td colspan = " 6 " >
< br />
< br />
< br />
< br />
</ td >
</ tr >
</ tfoot >
</ table >
</ div >
< 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 " ></ td >
</ tr >
< tr >
< td class = " grey " > Monto Exento </ td >
< td class = " right aligned " id = " exento " ></ td >
</ tr >
< tr >
< td class = " grey " > 19 % IVA </ td >
< td class = " right aligned " id = " iva " ></ td >
</ tr >
< tr >
< td class = " grey " > Monto Total </ td >
< td class = " right aligned " >< strong id = " total " ></ strong ></ td >
</ tr >
</ tbody >
</ table >
</ div >
</ div >
</ div >
</ div >
2023-11-22 19:08:19 -03:00
</ div >
@ endsection
2023-11-29 20:09:08 -03:00
@ push ( 'page_scripts' )
< script >
const factura = {
id : '#unidades' ,
totales : {},
proporcion : 1 ,
precio : {{ $UF -> transform ( $venta -> currentEstado () -> fecha , $venta -> valor )}},
2024-04-15 20:13:15 -04:00
terreno : {{( isset ( $terreno -> fecha ) and $terreno -> fecha >= $lastDic ) ?
$IPC -> readjust ( $terreno -> valor , $terreno -> fecha , $venta -> currentEstado () -> fecha ) : 0 }},
2023-11-29 20:09:08 -03:00
uf : {{ $UF -> get ( $venta -> currentEstado () -> fecha )}},
unidades : JSON . parse ( ' { !! json_encode ( array_map ( function ( Incoviba\Model\Venta\PropiedadUnidad $unidad ) use ( $venta , $UF , $format ) {
2023-12-13 13:28:19 -03:00
$precio = ( $unidad -> valor > 0 ) ? $unidad -> valor : ( $unidad -> precio ( $venta -> currentEstado () -> fecha ) ? $unidad -> precio ( $venta -> currentEstado () -> fecha ) -> valor : 0 );
2023-11-29 20:09:08 -03:00
return [
2023-11-30 18:40:15 -03:00
'id' => $unidad -> id ,
'pid' => $unidad -> pu_id ,
2023-11-29 20:09:08 -03:00
'descripcion' => ucwords ( $unidad -> proyectoTipoUnidad -> tipoUnidad -> descripcion ) . ' ' . $unidad -> descripcion ,
'precio' => $precio ,
'base' => $UF -> transform ( $venta -> currentEstado () -> fecha , $precio ),
'prorrateo' => $unidad -> prorrateo ,
];
}, $venta -> propiedad () -> unidades )) !! } ' ),
build : function () {
const tbody = $ ( this . id )
tbody . html ( '' )
const pesoFormatter = new Intl . NumberFormat ( 'es-CL' , { maximumFractionDigits : 0 , minimumFractionDigits : 0 })
const ufFormatter = new Intl . NumberFormat ( 'es-CL' , { maximumFractionDigits : 2 , minimumFractionDigits : 2 })
const percentFormatter = new Intl . NumberFormat ( 'es-CL' , { maximumFractionDigits : 5 , minimumFractionDigits : 5 })
let terreno = 0
2023-11-29 21:21:51 -03:00
let prorrateo = 0
2023-11-30 18:40:15 -03:00
let totalUnidades = 0
let precioUnidades = 0
2023-11-29 20:09:08 -03:00
let c = 1
const classes = [
'' ,
'' ,
'center aligned' ,
'right aligned' ,
'center aligned' ,
'right aligned'
]
this . unidades . forEach ( unidad => {
2023-11-30 18:40:15 -03:00
totalUnidades += unidad . base
precioUnidades += unidad . precio
2023-11-29 20:09:08 -03:00
const descuento = this . terreno * unidad . prorrateo
terreno += descuento
2023-11-29 21:21:51 -03:00
prorrateo += unidad . prorrateo
2023-11-29 20:09:08 -03:00
const bruto = unidad . base - descuento
const neto = bruto / 1.19
const data = [
c ++ ,
unidad . descripcion + ' (UF ' + ufFormatter . format ( unidad . precio * this . proporcion ) + ')' ,
'1 UNID' ,
pesoFormatter . format ( neto * this . proporcion ),
'AF' ,
pesoFormatter . format ( neto * this . proporcion )
]
const row = $ ( '<tr></tr' )
data . forEach (( value , i ) => {
const cell = $ ( '<td></td>' )
if ( classes [ i ] !== '' ) {
cell . addClass ( classes [ i ])
}
cell . html ( value )
row . append ( cell )
})
tbody . append ( row )
})
2023-11-30 18:40:15 -03:00
$ ( '#total_unidades' )
. attr ( 'class' , 'ui compact segment ' + (( totalUnidades . toFixed ( 2 ) !== this . precio . toFixed ( 2 )) ? 'inverted red' : 'inverted green' ))
. html ( 'Total Unidades: ' + ufFormatter . format ( precioUnidades ) + ' UF' +
(( totalUnidades . toFixed ( 2 ) !== this . precio . toFixed ( 2 )) ? '; Diferencia: ' + ufFormatter . format ({{ $venta -> valor }} - precioUnidades ) + ' UF' : '' ))
if ( totalUnidades . toFixed ( 2 ) !== this . precio . toFixed ( 2 )) {
this . highlight ()
}
2023-11-29 20:09:08 -03:00
const bruto = this . precio - terreno
const base = bruto / 1.19
const iva = base * . 19
const subtotal = base + iva
const total = subtotal + terreno
const totalUF = total / this . uf
2023-11-30 18:40:15 -03:00
const emptyTerreno = '<div class="ui tiny red horizontal circular label">0</div>'
2023-11-29 20:09:08 -03:00
const data = [
c ,
2023-11-30 18:40:15 -03:00
'Valor con Terreno ' + pesoFormatter . format (( base + terreno ) * this . proporcion ) + ' - Menos valor terreno ' + (( terreno > 0 ) ? pesoFormatter . format ( - terreno * this . proporcion ) : emptyTerreno ) + '<br />' +
2023-11-29 20:09:08 -03:00
'Base imponible ' + pesoFormatter . format ( base * this . proporcion ) + '<br />' +
'IVA ' + pesoFormatter . format ( iva * this . proporcion ) + '<br />' +
'SUBTOTAL ' + pesoFormatter . format ( subtotal * this . proporcion ) + '<br />' +
2023-11-30 18:40:15 -03:00
'Mas valor terreno ' + (( terreno > 0 ) ? pesoFormatter . format ( terreno * this . proporcion ) : emptyTerreno ) + '<br />' +
2023-11-29 20:09:08 -03:00
'TOTAL ' + pesoFormatter . format ( total * this . proporcion ) + ';' + ufFormatter . format ( totalUF * this . proporcion ) + ' UF<br /><br />' +
2023-11-30 18:40:15 -03:00
'Descuento Terreno: ' + (( terreno > 0 ) ? percentFormatter . format ( prorrateo * 100 ) : emptyTerreno ) + '%<br /><br />' +
2023-11-29 20:09:08 -03:00
'UF: ' + ufFormatter . format ( this . uf ),
'1 UNID' ,
pesoFormatter . format ( terreno * this . proporcion ),
'EX' ,
pesoFormatter . format ( terreno * this . proporcion )
]
const row = $ ( '<tr></tr>' ) . addClass ( 'top aligned' )
data . forEach (( value , i ) => {
const cell = $ ( '<td></td>' )
if ( classes [ i ] !== '' ) {
cell . addClass ( classes [ i ])
}
cell . html ( value )
row . append ( cell )
})
tbody . append ( row )
$ ( this . totales . afecto ) . html ( pesoFormatter . format ( base * this . proporcion ))
$ ( this . totales . exento ) . html ( pesoFormatter . format ( terreno * this . proporcion ))
$ ( this . totales . iva ) . html ( pesoFormatter . format ( iva * this . proporcion ))
$ ( this . totales . total ) . html ( pesoFormatter . format ( total * this . proporcion ))
},
update : function () {
return {
price : ( id , value ) => {
2023-11-30 18:40:15 -03:00
this . unhighlight ()
const idx = this . unidades . findIndex ( unidad => unidad . pid === id )
2023-11-29 20:44:13 -03:00
if ( idx === - 1 ) {
return
}
2023-11-29 20:09:08 -03:00
const old_value = this . unidades [ idx ] . precio
if ( old_value === parseFloat ( value )) {
return
}
const url = '{{$urls->api}}/ventas/propiedades/unidad/' + id + '/edit'
const data = new FormData ()
data . set ( 'valor' , value )
return fetchAPI ( url , { method : 'post' , body : data }) . then ( response => {
if ( response . ok ) {
return response . json ()
}
}) . then ( json => {
if ( ! json . edited ) {
return
}
2023-11-30 18:40:15 -03:00
const idx = this . unidades . findIndex ( unidad => unidad . pid === json . propiedad_unidad_id )
2024-01-18 13:15:26 -03:00
this . unidades [ idx ] . precio = parseFloat ( json . input . valor )
2023-11-29 20:09:08 -03:00
this . unidades [ idx ] . base = parseFloat ( json . input . valor * this . unidades [ idx ] . base / old_value )
this . build ()
})
2023-11-30 18:40:15 -03:00
},
terreno : value => {
const url = '{{$urls->api}}/proyecto/{{$venta->proyecto()->id}}/terreno/edit'
const data = new FormData ()
data . set ( 'valor' , value )
data . set ( 'fecha' , '{{$lastDic->format(' Y - m - d ')}}' )
return fetchAPI ( url , { method : 'post' , body : data }) . then ( response => {
if ( response . ok ) {
return response . json ()
}
}) . then ( json => {
if ( ! json . edited ) {
return
}
this . terreno = parseInt ( json . input . valor )
const data = new FormData ()
data . set ( 'start' , '{{$lastDic->format(' Y - m - d ')}}' )
data . set ( 'end' , '{{$venta->currentEstado()->fecha->sub(new DateInterval(' P1M '))->format(' Y - m - d ')}}' )
const url = '{{$urls->api}}/money/ipc'
return fetchAPI ( url , { method : 'post' , body : data }) . then ( response => {
if ( response . ok ) {
return response . json ()
}
}) . then ( json => {
this . terreno *= ( 1 + parseFloat ( json . ipc ))
this . build ()
})
})
},
prorrateo : ( id , value ) => {
if ( parseFloat ( value ) === 0 ) {
return
}
const url = '{{$urls->api}}/ventas/unidad/' + id + '/prorrateo'
const data = new FormData ()
data . set ( 'prorrateo' , value )
return fetchAPI ( url , { method : 'post' , body : data }) . then ( response => {
if ( response . ok ) {
return response . json ()
}
}) . then ( json => {
if ( ! json . edited ) {
return
}
const idx = this . unidades . findIndex ( unidad => unidad . id === json . unidad_id )
this . unidades [ idx ] . prorrateo = parseFloat ( json . input . prorrateo )
this . build ()
})
2023-11-29 20:09:08 -03:00
}
}
},
watch : function () {
return {
proporcion : id => {
$ ( id ) . change ( event => {
const val = $ ( event . currentTarget ) . val ()
if ( val / 100 === this . proporcion ) {
return
}
this . proporcion = val / 100
this . build ()
})
},
2023-11-30 18:40:15 -03:00
prices : class_name => {
2023-11-29 20:09:08 -03:00
$ ( class_name ) . change ( event => {
const val = $ ( event . currentTarget ) . val ()
const id = $ ( event . currentTarget ) . data ( 'id' )
this . update () . price ( id , val )
})
2023-11-30 18:40:15 -03:00
},
prorrateo : class_name => {
$ ( class_name ) . change ( event => {
const val = $ ( event . currentTarget ) . val ()
const id = $ ( event . currentTarget ) . data ( 'id' )
this . update () . prorrateo ( id , val )
})
},
terreno : id => {
$ ( id ) . change ( event => {
const val = $ ( event . currentTarget ) . val ()
this . update () . terreno ( val ) . then (() => {
$ ( id ) . parent () . parent () . hide ()
})
})
2023-11-29 20:09:08 -03:00
}
}
},
2023-11-30 18:40:15 -03:00
highlight : function () {
const pid = this . unidades [ 0 ] . pid
const input = $ ( '#input' + pid )
input . addClass ( 'error' )
input . find ( '.label' ) . addClass ( 'red' )
input . attr ( 'data-content' , 'Valor total no es igual a valor de venta' )
input . popup ()
},
unhighlight : function () {
const pid = this . unidades [ 0 ] . pid
const input = $ ( '#input' + pid )
input . removeClass ( 'error' )
input . find ( '.label' ) . removeClass ( 'red' )
input . removeAttr ( 'data-content' )
},
setup : function ({ form_id , tbody_id , input_id , prices_class , prorrateo_class , terreno_id , totales_ids }) {
2023-11-29 20:09:08 -03:00
$ ( form_id ) . submit ( event => {
event . preventDefault ()
return false
})
this . id = tbody_id
this . totales = totales_ids
this . proporcion = $ ( input_id ) . val () / 100
this . watch () . proporcion ( input_id )
this . watch () . prices ( prices_class )
2023-11-30 18:40:15 -03:00
this . watch () . prorrateo ( prorrateo_class )
@ if ( ! isset ( $venta -> proyecto () -> terreno -> fecha ) or $venta -> proyecto () -> terreno -> fecha <= $lastDic )
this . watch () . terreno ( terreno_id )
@ endif
2023-11-29 20:09:08 -03:00
this . build ()
}
}
$ ( document ) . ready (() => {
factura . setup ({ form_id : '#venta_form' , tbody_id : '#unidades' , input_id : '#proporcion' ,
2023-11-30 18:40:15 -03:00
prices_class : '.price' , prorrateo_class : '.prorrateo' , terreno_id : '#terreno' , totales_ids : {
2023-11-29 20:09:08 -03:00
afecto : '#neto' ,
exento : '#exento' ,
iva : '#iva' ,
total : '#total'
}})
})
</ script >
@ endpush