Mejoras en Facturacion
This commit is contained in:
@ -17,4 +17,7 @@ $app->group('/proyecto/{proyecto_id}', function($app) {
|
|||||||
$app->get('/disponibles[/]', [Proyectos::class, 'disponibles']);
|
$app->get('/disponibles[/]', [Proyectos::class, 'disponibles']);
|
||||||
$app->get('[/]', [Proyectos::class, 'unidades']);
|
$app->get('[/]', [Proyectos::class, 'unidades']);
|
||||||
});
|
});
|
||||||
|
$app->group('/terreno', function($app) {
|
||||||
|
$app->post('/edit[/]', [Proyectos::class, 'terreno']);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -4,3 +4,8 @@ use Incoviba\Controller\API\Ventas\Unidades;
|
|||||||
$app->group('/unidades', function($app) {
|
$app->group('/unidades', function($app) {
|
||||||
$app->post('/disponibles', [Unidades::class, 'disponibles']);
|
$app->post('/disponibles', [Unidades::class, 'disponibles']);
|
||||||
});
|
});
|
||||||
|
$app->group('/unidad/{unidad_id}', function($app) {
|
||||||
|
$app->group('/prorrateo', function($app) {
|
||||||
|
$app->post('[/]', [Unidades::class, 'prorrateo']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -42,6 +42,26 @@
|
|||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Terreno</td>
|
||||||
|
<td>
|
||||||
|
<table class="ui very basic striped table">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{$format->number($proyecto->terreno->superficie, 2)}}m²
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{$format->pesos($proyecto->terreno->valor)}} ({{$proyecto->terreno->fecha?->format('d-m-Y')}})
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="{{$urls->base}}/proyecto/{{$proyecto->id}}/terreno">
|
||||||
|
<i class="edit icon"></i>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Superficies</td>
|
<td>Superficies</td>
|
||||||
<td>
|
<td>
|
||||||
|
5
app/resources/views/proyectos/terreno/edit.blade.php
Normal file
5
app/resources/views/proyectos/terreno/edit.blade.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@extends('layout.base')
|
||||||
|
|
||||||
|
@push('page_content')
|
||||||
|
|
||||||
|
@endpush
|
@ -13,6 +13,9 @@
|
|||||||
{{$venta->propiedad()->summary()}}
|
{{$venta->propiedad()->summary()}}
|
||||||
</a>
|
</a>
|
||||||
</h2>
|
</h2>
|
||||||
|
<div class="ui very basic segment">
|
||||||
|
Valor Venta: {{$format->ufs($venta->valor)}}
|
||||||
|
</div>
|
||||||
<form id="venta_form" class="ui form">
|
<form id="venta_form" class="ui form">
|
||||||
<div class="two wide field">
|
<div class="two wide field">
|
||||||
<label for="proporcion">Proporción Factura</label>
|
<label for="proporcion">Proporción Factura</label>
|
||||||
@ -27,13 +30,37 @@
|
|||||||
@foreach ($venta->propiedad()->unidades as $unidad)
|
@foreach ($venta->propiedad()->unidades as $unidad)
|
||||||
<div class="three wide field">
|
<div class="three wide field">
|
||||||
<label for="precio{{$unidad->pu_id}}">Precio {{ucwords($unidad->proyectoTipoUnidad->tipoUnidad->descripcion)}} {{$unidad->descripcion}}</label>
|
<label for="precio{{$unidad->pu_id}}">Precio {{ucwords($unidad->proyectoTipoUnidad->tipoUnidad->descripcion)}} {{$unidad->descripcion}}</label>
|
||||||
<div class="ui right labeled input">
|
<div class="ui right labeled input" id="input{{$unidad->pu_id}}">
|
||||||
<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}}" />
|
<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 class="ui basic label">UF</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
|
<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
|
||||||
</form>
|
</form>
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
<div id="factura">
|
<div id="factura">
|
||||||
@ -44,7 +71,7 @@
|
|||||||
{{mb_strtoupper($venta->proyecto()->inmobiliaria()->nombreCompleto())}}
|
{{mb_strtoupper($venta->proyecto()->inmobiliaria()->nombreCompleto())}}
|
||||||
</strong><br/>
|
</strong><br/>
|
||||||
GIRO: <br/>
|
GIRO: <br/>
|
||||||
Dirección:
|
Dirección: {{$venta->proyecto()->direccion()->simple()}}
|
||||||
</div>
|
</div>
|
||||||
<div class="four wide column">
|
<div class="four wide column">
|
||||||
<div class="ui center aligned red segment">
|
<div class="ui center aligned red segment">
|
||||||
@ -148,12 +175,14 @@
|
|||||||
totales: {},
|
totales: {},
|
||||||
proporcion: 1,
|
proporcion: 1,
|
||||||
precio: {{$UF->transform($venta->currentEstado()->fecha, $venta->valor)}},
|
precio: {{$UF->transform($venta->currentEstado()->fecha, $venta->valor)}},
|
||||||
terreno: {{$IPC->readjust($venta->proyecto()->terreno->valor, $venta->proyecto()->terreno->date, $venta->currentEstado()->fecha)}},
|
terreno: {{(isset($venta->proyecto()->terreno->fecha) and $venta->proyecto()->terreno->fecha > $lastDic) ?
|
||||||
|
$IPC->readjust($venta->proyecto()->terreno->valor, $venta->proyecto()->terreno->fecha, $venta->currentEstado()->fecha) : 0}},
|
||||||
uf: {{$UF->get($venta->currentEstado()->fecha)}},
|
uf: {{$UF->get($venta->currentEstado()->fecha)}},
|
||||||
unidades: JSON.parse('{!! json_encode(array_map(function(Incoviba\Model\Venta\PropiedadUnidad $unidad) use ($venta, $UF, $format) {
|
unidades: JSON.parse('{!! json_encode(array_map(function(Incoviba\Model\Venta\PropiedadUnidad $unidad) use ($venta, $UF, $format) {
|
||||||
$precio = ($unidad->valor > 0) ? $unidad->valor : $unidad->precio($venta->currentEstado()->fecha)->valor;
|
$precio = ($unidad->valor > 0) ? $unidad->valor : $unidad->precio($venta->currentEstado()->fecha)->valor;
|
||||||
return [
|
return [
|
||||||
'pu_id' => $unidad->pu_id,
|
'id' => $unidad->id,
|
||||||
|
'pid' => $unidad->pu_id,
|
||||||
'descripcion' => ucwords($unidad->proyectoTipoUnidad->tipoUnidad->descripcion) . ' ' . $unidad->descripcion,
|
'descripcion' => ucwords($unidad->proyectoTipoUnidad->tipoUnidad->descripcion) . ' ' . $unidad->descripcion,
|
||||||
'precio' => $precio,
|
'precio' => $precio,
|
||||||
'base' => $UF->transform($venta->currentEstado()->fecha, $precio),
|
'base' => $UF->transform($venta->currentEstado()->fecha, $precio),
|
||||||
@ -168,6 +197,8 @@
|
|||||||
const percentFormatter = new Intl.NumberFormat('es-CL', {maximumFractionDigits: 5, minimumFractionDigits: 5})
|
const percentFormatter = new Intl.NumberFormat('es-CL', {maximumFractionDigits: 5, minimumFractionDigits: 5})
|
||||||
let terreno = 0
|
let terreno = 0
|
||||||
let prorrateo = 0
|
let prorrateo = 0
|
||||||
|
let totalUnidades = 0
|
||||||
|
let precioUnidades = 0
|
||||||
let c = 1
|
let c = 1
|
||||||
const classes = [
|
const classes = [
|
||||||
'',
|
'',
|
||||||
@ -178,6 +209,8 @@
|
|||||||
'right aligned'
|
'right aligned'
|
||||||
]
|
]
|
||||||
this.unidades.forEach(unidad => {
|
this.unidades.forEach(unidad => {
|
||||||
|
totalUnidades += unidad.base
|
||||||
|
precioUnidades += unidad.precio
|
||||||
const descuento = this.terreno * unidad.prorrateo
|
const descuento = this.terreno * unidad.prorrateo
|
||||||
terreno += descuento
|
terreno += descuento
|
||||||
prorrateo += unidad.prorrateo
|
prorrateo += unidad.prorrateo
|
||||||
@ -203,6 +236,13 @@
|
|||||||
})
|
})
|
||||||
tbody.append(row)
|
tbody.append(row)
|
||||||
})
|
})
|
||||||
|
$('#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()
|
||||||
|
}
|
||||||
const bruto = this.precio - terreno
|
const bruto = this.precio - terreno
|
||||||
const base = bruto / 1.19
|
const base = bruto / 1.19
|
||||||
const iva = base * .19
|
const iva = base * .19
|
||||||
@ -210,15 +250,16 @@
|
|||||||
const total = subtotal + terreno
|
const total = subtotal + terreno
|
||||||
const totalUF = total / this.uf
|
const totalUF = total / this.uf
|
||||||
|
|
||||||
|
const emptyTerreno = '<div class="ui tiny red horizontal circular label">0</div>'
|
||||||
const data = [
|
const data = [
|
||||||
c,
|
c,
|
||||||
'Valor con Terreno ' + pesoFormatter.format((base + terreno) * this.proporcion) + ' - Menos valor terreno ' + pesoFormatter.format(-terreno * this.proporcion) + '<br />' +
|
'Valor con Terreno ' + pesoFormatter.format((base + terreno) * this.proporcion) + ' - Menos valor terreno ' + ((terreno > 0) ? pesoFormatter.format(-terreno * this.proporcion) : emptyTerreno) + '<br />' +
|
||||||
'Base imponible ' + pesoFormatter.format(base * this.proporcion) + '<br />' +
|
'Base imponible ' + pesoFormatter.format(base * this.proporcion) + '<br />' +
|
||||||
'IVA ' + pesoFormatter.format(iva * this.proporcion) + '<br />' +
|
'IVA ' + pesoFormatter.format(iva * this.proporcion) + '<br />' +
|
||||||
'SUBTOTAL ' + pesoFormatter.format(subtotal * this.proporcion) + '<br />' +
|
'SUBTOTAL ' + pesoFormatter.format(subtotal * this.proporcion) + '<br />' +
|
||||||
'Mas valor terreno ' + pesoFormatter.format(terreno * this.proporcion) + '<br />' +
|
'Mas valor terreno ' + ((terreno > 0) ? pesoFormatter.format(terreno * this.proporcion) : emptyTerreno) + '<br />' +
|
||||||
'TOTAL ' + pesoFormatter.format(total * this.proporcion) + ';' + ufFormatter.format(totalUF * this.proporcion) + ' UF<br /><br />' +
|
'TOTAL ' + pesoFormatter.format(total * this.proporcion) + ';' + ufFormatter.format(totalUF * this.proporcion) + ' UF<br /><br />' +
|
||||||
'Descuento Terreno: ' + percentFormatter.format(prorrateo * 100) + '%<br /><br />' +
|
'Descuento Terreno: ' + ((terreno > 0) ? percentFormatter.format(prorrateo * 100) : emptyTerreno) + '%<br /><br />' +
|
||||||
'UF: ' + ufFormatter.format(this.uf),
|
'UF: ' + ufFormatter.format(this.uf),
|
||||||
'1 UNID',
|
'1 UNID',
|
||||||
pesoFormatter.format(terreno * this.proporcion),
|
pesoFormatter.format(terreno * this.proporcion),
|
||||||
@ -244,7 +285,8 @@
|
|||||||
update: function() {
|
update: function() {
|
||||||
return {
|
return {
|
||||||
price: (id, value) => {
|
price: (id, value) => {
|
||||||
const idx = this.unidades.findIndex(unidad => unidad.pu_id === id)
|
this.unhighlight()
|
||||||
|
const idx = this.unidades.findIndex(unidad => unidad.pid === id)
|
||||||
if (idx === -1) {
|
if (idx === -1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -263,11 +305,59 @@
|
|||||||
if (!json.edited) {
|
if (!json.edited) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const idx = this.unidades.findIndex(unidad => unidad.pu_id === json.propiedad_unidad_id)
|
const idx = this.unidades.findIndex(unidad => unidad.pid === json.propiedad_unidad_id)
|
||||||
this.unidades[idx].precio = parseInt(json.input.valor)
|
this.unidades[idx].precio = parseInt(json.input.valor)
|
||||||
this.unidades[idx].base = parseFloat(json.input.valor * this.unidades[idx].base / old_value)
|
this.unidades[idx].base = parseFloat(json.input.valor * this.unidades[idx].base / old_value)
|
||||||
this.build()
|
this.build()
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
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()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -283,16 +373,46 @@
|
|||||||
this.build()
|
this.build()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
prices: (class_name) => {
|
prices: class_name => {
|
||||||
$(class_name).change(event => {
|
$(class_name).change(event => {
|
||||||
const val = $(event.currentTarget).val()
|
const val = $(event.currentTarget).val()
|
||||||
const id = $(event.currentTarget).data('id')
|
const id = $(event.currentTarget).data('id')
|
||||||
this.update().price(id, val)
|
this.update().price(id, val)
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
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()
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup: function({form_id, tbody_id, input_id, prices_class, totales_ids}) {
|
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}) {
|
||||||
$(form_id).submit(event => {
|
$(form_id).submit(event => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
return false
|
return false
|
||||||
@ -302,12 +422,16 @@
|
|||||||
this.proporcion = $(input_id).val() / 100
|
this.proporcion = $(input_id).val() / 100
|
||||||
this.watch().proporcion(input_id)
|
this.watch().proporcion(input_id)
|
||||||
this.watch().prices(prices_class)
|
this.watch().prices(prices_class)
|
||||||
|
this.watch().prorrateo(prorrateo_class)
|
||||||
|
@if (!isset($venta->proyecto()->terreno->fecha) or $venta->proyecto()->terreno->fecha <= $lastDic)
|
||||||
|
this.watch().terreno(terreno_id)
|
||||||
|
@endif
|
||||||
this.build()
|
this.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$(document).ready(() => {
|
$(document).ready(() => {
|
||||||
factura.setup({form_id: '#venta_form', tbody_id: '#unidades', input_id: '#proporcion',
|
factura.setup({form_id: '#venta_form', tbody_id: '#unidades', input_id: '#proporcion',
|
||||||
prices_class: '.price', totales_ids: {
|
prices_class: '.price', prorrateo_class: '.prorrateo', terreno_id: '#terreno', totales_ids: {
|
||||||
afecto: '#neto',
|
afecto: '#neto',
|
||||||
exento: '#exento',
|
exento: '#exento',
|
||||||
iva: '#iva',
|
iva: '#iva',
|
||||||
|
@ -112,15 +112,15 @@
|
|||||||
}
|
}
|
||||||
}).then(data => {
|
}).then(data => {
|
||||||
if (data.total > 0) {
|
if (data.total > 0) {
|
||||||
|
const progress = this.draw().progress(data.ventas.length)
|
||||||
this.data.id = data.proyecto.id
|
this.data.id = data.proyecto.id
|
||||||
this.data.proyecto = data.proyecto.descripcion
|
this.data.proyecto = data.proyecto.descripcion
|
||||||
this.data.venta_ids = data.ventas
|
this.data.venta_ids = data.ventas
|
||||||
const promises = []
|
const promises = []
|
||||||
data.ventas.forEach(venta_id => {
|
data.ventas.forEach(venta_id => {
|
||||||
const promise = this.get().venta(venta_id)
|
const promise = this.get().venta(venta_id).then(() => {
|
||||||
/*promise.then(() => {
|
progress.progress('increment')
|
||||||
this.draw().ventas(true)
|
})
|
||||||
})*/
|
|
||||||
promises.push(promise)
|
promises.push(promise)
|
||||||
})
|
})
|
||||||
Promise.all(promises).then(() => {
|
Promise.all(promises).then(() => {
|
||||||
@ -185,6 +185,26 @@
|
|||||||
parent.show()
|
parent.show()
|
||||||
parent.find('.item.proyecto').click(this.actions().get)
|
parent.find('.item.proyecto').click(this.actions().get)
|
||||||
},
|
},
|
||||||
|
progress: cantidad => {
|
||||||
|
const parent = $(this.ids.proyectos)
|
||||||
|
parent.html('')
|
||||||
|
const progress = $('<div></div>').addClass('ui active progress').append(
|
||||||
|
$('<div></div>').addClass('bar').append(
|
||||||
|
$('<div></div>').addClass('centered progress')
|
||||||
|
)
|
||||||
|
).append(
|
||||||
|
$('<div></div>').addClass('label').html('Cargando datos')
|
||||||
|
)
|
||||||
|
progress.progress({
|
||||||
|
total: cantidad,
|
||||||
|
label: 'ratio',
|
||||||
|
text: {
|
||||||
|
ratio: '{value} de {total} ({percent}%)'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
parent.append(progress)
|
||||||
|
return progress
|
||||||
|
},
|
||||||
ventas: (loading = false) => {
|
ventas: (loading = false) => {
|
||||||
const title = $(this.ids.title)
|
const title = $(this.ids.title)
|
||||||
const parent = $(this.ids.proyectos)
|
const parent = $(this.ids.proyectos)
|
||||||
|
@ -12,6 +12,10 @@
|
|||||||
<a href="{{$urls->base}}/venta/{{$venta->id}}/escritura/firmar">
|
<a href="{{$urls->base}}/venta/{{$venta->id}}/escritura/firmar">
|
||||||
Firmar
|
Firmar
|
||||||
</a>
|
</a>
|
||||||
|
<br />
|
||||||
|
<a href="{{$urls->base}}/ventas/factura/{{$venta->id}}">
|
||||||
|
Factura
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
<div class="ui segment">
|
<div class="ui segment">
|
||||||
|
@ -140,4 +140,19 @@ class Proyectos
|
|||||||
}
|
}
|
||||||
return $this->withJson($response, $output);
|
return $this->withJson($response, $output);
|
||||||
}
|
}
|
||||||
|
public function terreno(ServerRequestInterface $request, ResponseInterface $response, Repository\Proyecto $proyectoRepository, int $proyecto_id): ResponseInterface
|
||||||
|
{
|
||||||
|
$body = $request->getParsedBody();
|
||||||
|
$output = [
|
||||||
|
'input' => $body,
|
||||||
|
'proyecto_id' => $proyecto_id,
|
||||||
|
'edited' => false
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$proyecto = $proyectoRepository->fetchById($proyecto_id);
|
||||||
|
$proyectoRepository->editTerreno($proyecto, $body);
|
||||||
|
$output['edited'] = true;
|
||||||
|
} catch (EmptyResult) {}
|
||||||
|
return $this->withJson($response, $output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,4 +83,19 @@ class Unidades
|
|||||||
}
|
}
|
||||||
return $this->withJson($response, $output);
|
return $this->withJson($response, $output);
|
||||||
}
|
}
|
||||||
|
public function prorrateo(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Unidad $unidadRepository, int $unidad_id): ResponseInterface
|
||||||
|
{
|
||||||
|
$body = $request->getParsedBody();
|
||||||
|
$output = [
|
||||||
|
'unidad_id' => $unidad_id,
|
||||||
|
'input' => $body,
|
||||||
|
'edited' => false
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$unidad = $unidadRepository->fetchById($unidad_id);
|
||||||
|
$unidadRepository->editProrrateo($unidad, $body);
|
||||||
|
$output['edited'] = true;
|
||||||
|
} catch (EmptyResult) {}
|
||||||
|
return $this->withJson($response, $output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ class Proyectos
|
|||||||
{
|
{
|
||||||
$redisKey = "proyecto:{$proyecto_id}";
|
$redisKey = "proyecto:{$proyecto_id}";
|
||||||
try {
|
try {
|
||||||
$proyecto = $proyectoService->getById($proyectoRepository->load((array) $this->fetchRedis($redisService, $redisKey)));
|
$proyecto = $proyectoService->getById($this->fetchRedis($redisService, $redisKey)->id);
|
||||||
} catch (EmptyRedis) {
|
} catch (EmptyRedis) {
|
||||||
$proyecto = $proyectoService->getById($proyecto_id);
|
$proyecto = $proyectoService->getById($proyecto_id);
|
||||||
$this->saveRedis($redisService, $redisKey, $proyecto);
|
$this->saveRedis($redisService, $redisKey, $proyecto);
|
||||||
|
@ -8,14 +8,14 @@ class Terreno implements JsonSerializable
|
|||||||
{
|
{
|
||||||
public float $superficie;
|
public float $superficie;
|
||||||
public float $valor;
|
public float $valor;
|
||||||
public ?DateTimeInterface $date;
|
public ?DateTimeInterface $fecha;
|
||||||
|
|
||||||
public function jsonSerialize(): mixed
|
public function jsonSerialize(): mixed
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'superficie' => $this->superficie,
|
'superficie' => $this->superficie,
|
||||||
'valor' => $this->valor,
|
'valor' => $this->valor,
|
||||||
'date' => $this->date?->format('Y-m-d')
|
'date' => $this->fecha?->format('Y-m-d')
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Incoviba\Repository;
|
namespace Incoviba\Repository;
|
||||||
|
|
||||||
|
use PDO;
|
||||||
|
use PDOException;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
use Incoviba\Common\Define;
|
use Incoviba\Common\Define;
|
||||||
use Incoviba\Common\Ideal;
|
use Incoviba\Common\Ideal;
|
||||||
@ -37,9 +39,9 @@ class Proyecto extends Ideal\Repository
|
|||||||
$terreno = new Model\Proyecto\Terreno();
|
$terreno = new Model\Proyecto\Terreno();
|
||||||
$terreno->superficie = $data['superficie_terreno'];
|
$terreno->superficie = $data['superficie_terreno'];
|
||||||
$terreno->valor = $data['valor_terreno'];
|
$terreno->valor = $data['valor_terreno'];
|
||||||
$terreno->date = null;
|
$terreno->fecha = null;
|
||||||
if (isset($data['fecha_terreno']) and $data['fecha_terreno'] !== '') {
|
if (isset($data['fecha_terreno']) and $data['fecha_terreno'] !== '') {
|
||||||
$terreno->date = new DateTimeImmutable($data['fecha_terreno']);
|
$terreno->fecha = new DateTimeImmutable($data['fecha_terreno']);
|
||||||
}
|
}
|
||||||
return $terreno;
|
return $terreno;
|
||||||
}))
|
}))
|
||||||
@ -71,7 +73,7 @@ class Proyecto extends Ideal\Repository
|
|||||||
'subterraneos'], $new_data);
|
'subterraneos'], $new_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fetchById(int $id): Define\Model
|
public function fetchById(int $id): Model\Proyecto
|
||||||
{
|
{
|
||||||
$query = $this->connection->getQueryBuilder()
|
$query = $this->connection->getQueryBuilder()
|
||||||
->select($this->columns())
|
->select($this->columns())
|
||||||
@ -81,7 +83,7 @@ class Proyecto extends Ideal\Repository
|
|||||||
return $this->fetchOne($query, [$id]);
|
return $this->fetchOne($query, [$id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fetchByName(string $name): Define\Model
|
public function fetchByName(string $name): Model\Proyecto
|
||||||
{
|
{
|
||||||
$query = $this->connection->getQueryBuilder()
|
$query = $this->connection->getQueryBuilder()
|
||||||
->select($this->columns())
|
->select($this->columns())
|
||||||
@ -116,6 +118,43 @@ class Proyecto extends Ideal\Repository
|
|||||||
->order('a.descripcion');
|
->order('a.descripcion');
|
||||||
return $this->fetchMany($query);
|
return $this->fetchMany($query);
|
||||||
}
|
}
|
||||||
|
public function editTerreno(Model\Proyecto $proyecto, array $data): Model\Proyecto
|
||||||
|
{
|
||||||
|
$fecha = new DateTimeImmutable($data['fecha']);
|
||||||
|
try {
|
||||||
|
$query = $this->connection->getQueryBuilder()
|
||||||
|
->select('valor')
|
||||||
|
->from('proyecto_terreno')
|
||||||
|
->where('proyecto_id = ? AND fecha = ?');
|
||||||
|
$result = $this->connection->execute($query, [$proyecto->id, $fecha->format('Y-m-d')])->fetch(PDO::FETCH_ASSOC);
|
||||||
|
if ($result === false) {
|
||||||
|
throw new Implement\Exception\EmptyResult($query);
|
||||||
|
}
|
||||||
|
if ($result['valor'] !== $data['valor']) {
|
||||||
|
$query = $this->connection->getQueryBuilder()
|
||||||
|
->update('proyecto_terreno')
|
||||||
|
->set('valor = ?')
|
||||||
|
->where('proyecto_id = ? AND fecha = ?');
|
||||||
|
$this->connection->execute($query, [$data['valor'], $proyecto->id, $fecha->format('Y-m-d')]);
|
||||||
|
$proyecto->terreno->valor = $data['valor'];
|
||||||
|
}
|
||||||
|
} catch (PDOException | Implement\Exception\EmptyResult) {
|
||||||
|
$query = $this->connection->getQueryBuilder()
|
||||||
|
->insert()
|
||||||
|
->into('proyecto_terreno')
|
||||||
|
->columns(['proyecto_id', 'fecha', 'valor', 'tipo_moneda_id'])
|
||||||
|
->values(['?', '?', '?', '1']);
|
||||||
|
try {
|
||||||
|
$this->connection->execute($query, [$proyecto->id, $fecha->format('Y-m-d'), $data['valor']]);
|
||||||
|
$proyecto->terreno->fecha = $fecha;
|
||||||
|
$proyecto->terreno->valor = $data['valor'];
|
||||||
|
} catch (PDOException $exception) {
|
||||||
|
error_log($exception);
|
||||||
|
throw new Implement\Exception\EmptyResult($query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $proyecto;
|
||||||
|
}
|
||||||
/*public function fetchSuperficieVendido(int $proyecto_id): float
|
/*public function fetchSuperficieVendido(int $proyecto_id): float
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
namespace Incoviba\Repository\Venta;
|
namespace Incoviba\Repository\Venta;
|
||||||
|
|
||||||
use PDO;
|
use PDO;
|
||||||
|
use PDOException;
|
||||||
use Incoviba\Common\Ideal;
|
use Incoviba\Common\Ideal;
|
||||||
use Incoviba\Common\Define;
|
use Incoviba\Common\Define;
|
||||||
use Incoviba\Common\Implement;
|
use Incoviba\Common\Implement;
|
||||||
@ -38,6 +39,40 @@ class Unidad extends Ideal\Repository
|
|||||||
{
|
{
|
||||||
return $this->update($model, ['subtipo', 'piso', 'descripcion', 'orientacion', 'pt'], $new_data);
|
return $this->update($model, ['subtipo', 'piso', 'descripcion', 'orientacion', 'pt'], $new_data);
|
||||||
}
|
}
|
||||||
|
public function editProrrateo(Model\Venta\Unidad $model, array $new_data): Model\Venta\Unidad
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$query = $this->connection->getQueryBuilder()
|
||||||
|
->select('prorrateo')
|
||||||
|
->from('unidad_prorrateo')
|
||||||
|
->where('unidad_id = ?');
|
||||||
|
$result = $this->connection->execute($query, [$model->id])->fetch(PDO::FETCH_ASSOC);
|
||||||
|
if ($result === false) {
|
||||||
|
throw new Implement\Exception\EmptyResult($query);
|
||||||
|
}
|
||||||
|
if ($new_data['prorrateo'] !== $result['prorrateo']) {
|
||||||
|
$query = $this->connection->getQueryBuilder()
|
||||||
|
->update('unidad_prorrateo')
|
||||||
|
->set('prorrateo = ?')
|
||||||
|
->where('unidad_id = ?');
|
||||||
|
$this->connection->execute($query, [$new_data['prorrateo'], $model->id]);
|
||||||
|
$model->prorrateo = $new_data['prorrateo'];
|
||||||
|
}
|
||||||
|
} catch (PDOException | Implement\Exception\EmptyResult) {
|
||||||
|
$query = $this->connection->getQueryBuilder()
|
||||||
|
->insert()
|
||||||
|
->into('unidad_prorrateo')
|
||||||
|
->columns(['unidad_id', 'prorrateo'])
|
||||||
|
->values(['?', '?']);
|
||||||
|
try {
|
||||||
|
$this->connection->execute($query, [$model->id, $new_data['prorrateo']]);
|
||||||
|
$model->prorrateo = $new_data['prorrateo'];
|
||||||
|
} catch (PDOException) {
|
||||||
|
throw new Implement\Exception\EmptyResult($query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
public function fetchById(int $id): Model\Venta\Unidad
|
public function fetchById(int $id): Model\Venta\Unidad
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,8 @@ class Proyecto
|
|||||||
{
|
{
|
||||||
return $this->process($this->proyectoRepository->fetchByName($name));
|
return $this->process($this->proyectoRepository->fetchByName($name));
|
||||||
}
|
}
|
||||||
public function process(Model\Proyecto $proyecto): Model\Proyecto
|
|
||||||
|
protected function process(Model\Proyecto $proyecto): Model\Proyecto
|
||||||
{
|
{
|
||||||
$proyecto->addFactory('estados', (new Implement\Repository\Factory())
|
$proyecto->addFactory('estados', (new Implement\Repository\Factory())
|
||||||
->setCallable([$this->estadoProyecto, 'fetchByProyecto'])
|
->setCallable([$this->estadoProyecto, 'fetchByProyecto'])
|
||||||
|
Reference in New Issue
Block a user