Facturacion
This commit is contained in:
@ -33,6 +33,7 @@
|
|||||||
</div>--}}
|
</div>--}}
|
||||||
{{--<a class="item" href="{{$urls->base}}/ventas/precios/importar">Importar Precios</a>--}}
|
{{--<a class="item" href="{{$urls->base}}/ventas/precios/importar">Importar Precios</a>--}}
|
||||||
{{--<a class="item" href="{{$urls->base}}/ventas/cierres/evaluar">Evaluar Cierre</a>--}}
|
{{--<a class="item" href="{{$urls->base}}/ventas/cierres/evaluar">Evaluar Cierre</a>--}}
|
||||||
|
<a class="item" href="{{$urls->base}}/ventas/facturacion">Facturación</a>
|
||||||
<a class="item" href="{{$urls->base}}/ventas/add">
|
<a class="item" href="{{$urls->base}}/ventas/add">
|
||||||
Nueva Venta
|
Nueva Venta
|
||||||
<i class="plus icon"></i>
|
<i class="plus icon"></i>
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<table class="ui table" id="data"></table>
|
<div id="data"></div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@include('layout.head.styles.datatables')
|
@include('layout.head.styles.datatables')
|
||||||
@ -226,49 +226,104 @@
|
|||||||
ids: {},
|
ids: {},
|
||||||
selected: 0,
|
selected: 0,
|
||||||
data: JSON.parse('{!! json_encode($proyectos) !!}'),
|
data: JSON.parse('{!! json_encode($proyectos) !!}'),
|
||||||
|
sent: false,
|
||||||
|
ufs: {},
|
||||||
|
ipcs: {},
|
||||||
table: null,
|
table: null,
|
||||||
get: function() {
|
get: function() {
|
||||||
return {
|
return {
|
||||||
ventas: () => {
|
ventas: () => {
|
||||||
|
if (this.sent) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.sent = true
|
||||||
const url = '{{$urls->api}}/ventas/facturacion/proyecto/' + this.selected
|
const url = '{{$urls->api}}/ventas/facturacion/proyecto/' + this.selected
|
||||||
|
this.draw().loading()
|
||||||
return fetchAPI(url).then(response => {
|
return fetchAPI(url).then(response => {
|
||||||
if (response.ok) {
|
if (!response) {
|
||||||
return response.json()
|
return
|
||||||
}
|
}
|
||||||
|
return response.json()
|
||||||
}).then(json => {
|
}).then(json => {
|
||||||
const idx = this.data.findIndex(proyecto => proyecto.id === json.proyecto_id)
|
const idx = this.data.findIndex(proyecto => proyecto.id === json.proyecto_id)
|
||||||
const fecha_terreno = new Date(this.data[idx].terreno.date)
|
const fecha_terreno = (typeof this.data[idx].terreno.date === 'undefined') ? new Date() : new Date(this.data[idx].terreno.date)
|
||||||
this.data[idx]['ventas'] = []
|
this.data[idx]['ventas'] = []
|
||||||
const ventas = []
|
const ventas = []
|
||||||
json.ventas.forEach(venta => {
|
const unidadesQueue = []
|
||||||
const data = {
|
const ufQueue = {}
|
||||||
id: venta.id,
|
const ipcQueue = {}
|
||||||
precio: venta.valor,
|
const chunkSize = 100
|
||||||
fecha: new Date(venta.fecha),
|
const url = '{{$urls->api}}/ventas/get'
|
||||||
escritura: null
|
for (let i = 0; i < json.ventas.length; i += chunkSize) {
|
||||||
}
|
const chunk = json.ventas.slice(i, i + chunkSize).map(venta => venta.id)
|
||||||
if (['escriturando'].includes(venta.current_estado.tipo_estado_venta.descripcion)) {
|
const body = new FormData()
|
||||||
data.escritura = new Date(venta.current_estado.fecha)
|
body.set('ventas', chunk)
|
||||||
}
|
const promise = fetchAPI(url, {method: 'post', body}).then(response => {
|
||||||
const v = new Venta(data)
|
if (!response) {
|
||||||
const promises = []
|
return response
|
||||||
if (v.escritura !== null) {
|
}
|
||||||
promises.push(money.get().uf(v.escritura).then(uf => {
|
return response.json().then(json => {
|
||||||
v.uf = uf
|
json.ventas.forEach(venta => {
|
||||||
}))
|
const data = {
|
||||||
promises.push(money.get().ipc(v.escritura, fecha_terreno).then(ipc => {
|
id: venta.id,
|
||||||
v.ipc = ipc
|
precio: venta.valor,
|
||||||
}))
|
fecha: new Date(venta.fecha),
|
||||||
}
|
escritura: new Date(venta.fecha)
|
||||||
promises.push(v.get().unidades())
|
}
|
||||||
const promise = Promise.all(promises).then(() => {
|
if (['escriturando'].includes(venta.current_estado.tipo_estado_venta.descripcion)) {
|
||||||
this.data[idx].ventas.push(v)
|
data.escritura = new Date(venta.current_estado.fecha)
|
||||||
|
}
|
||||||
|
const v = new Venta(data)
|
||||||
|
if (v.escritura !== null) {
|
||||||
|
const dateString = v.escritura.toString()
|
||||||
|
if (!Object.hasOwn(ufQueue, dateString)) {
|
||||||
|
ufQueue[dateString] = []
|
||||||
|
}
|
||||||
|
ufQueue[dateString].push(v.id)
|
||||||
|
if (!Object.hasOwn(ipcQueue, dateString)) {
|
||||||
|
ipcQueue[dateString] = []
|
||||||
|
}
|
||||||
|
ipcQueue[dateString].push(v.id)
|
||||||
|
}
|
||||||
|
unidadesQueue.push(v.id)
|
||||||
|
this.data[idx].ventas.push(v)
|
||||||
|
|
||||||
|
})
|
||||||
|
});
|
||||||
})
|
})
|
||||||
ventas.push(promise)
|
ventas.push(promise)
|
||||||
})
|
}
|
||||||
Promise.all(ventas).then(() => {
|
Promise.all(ventas).then(() => {
|
||||||
this.data[idx].ventas.sort((a, b) => parseInt(a.principal.descripcion) - parseInt(b.principal.descripcion))
|
const promises = []
|
||||||
this.draw().ventas(idx)
|
Object.entries(ufQueue).forEach(([dateString, ventas]) => {
|
||||||
|
const date = new Date(dateString)
|
||||||
|
promises.push(money.get().uf(date).then(uf => {
|
||||||
|
ventas.forEach(id => {
|
||||||
|
const vidx = this.data[idx].ventas.findIndex(venta => venta.id === id)
|
||||||
|
this.data[idx].ventas[vidx].uf = uf
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
Object.entries(ipcQueue).forEach(([dateString, ventas]) => {
|
||||||
|
const date = new Date(dateString)
|
||||||
|
promises.push(money.get().ipc(date, fecha_terreno).then(ipc => {
|
||||||
|
ventas.forEach(id => {
|
||||||
|
const vidx = this.data[idx].ventas.findIndex(venta => venta.id === id)
|
||||||
|
this.data[idx].ventas[vidx].ipc = ipc
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
for (let i = 0; i < unidadesQueue.length; i += chunkSize) {
|
||||||
|
const chunk = unidadesQueue.slice(i, i + chunkSize)
|
||||||
|
chunk.forEach(id => {
|
||||||
|
const vidx = this.data[idx].ventas.findIndex(venta => venta.id === id)
|
||||||
|
promises.push(this.data[idx].ventas[vidx].get().unidades())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Promise.all(promises).then(() => {
|
||||||
|
this.draw().ventas(idx)
|
||||||
|
this.sent = false
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -277,23 +332,37 @@
|
|||||||
draw: function() {
|
draw: function() {
|
||||||
return {
|
return {
|
||||||
proyectos: () => {
|
proyectos: () => {
|
||||||
|
$(this.ids.title).html('Proyectos')
|
||||||
if (this.table !== null) {
|
if (this.table !== null) {
|
||||||
this.table.clear()
|
this.table.clear()
|
||||||
|
this.table.destroy()
|
||||||
|
$(this.ids.data).html('')
|
||||||
}
|
}
|
||||||
$(this.ids.data).hide()
|
$(this.ids.data).hide()
|
||||||
|
$(this.ids.proyectos).find('.item').css('cursor', 'pointer')
|
||||||
$(this.ids.proyectos).show()
|
$(this.ids.proyectos).show()
|
||||||
},
|
},
|
||||||
ventas: proyecto_idx => {
|
ventas: proyecto_idx => {
|
||||||
const table = $(this.ids.data)
|
$(this.ids.title).html(this.data[proyecto_idx].descripcion)
|
||||||
|
const parent = $(this.ids.data)
|
||||||
if (this.table !== null) {
|
if (this.table !== null) {
|
||||||
this.table.clear().destroy()
|
this.table.clear()
|
||||||
|
this.table.destroy()
|
||||||
|
this.table = null
|
||||||
|
parent.html('')
|
||||||
}
|
}
|
||||||
|
const table = $('<table></table>').addClass('ui table')
|
||||||
table.append(this.draw().thead())
|
table.append(this.draw().thead())
|
||||||
table.append(this.draw().tbody(proyecto_idx))
|
table.append(this.draw().tbody(proyecto_idx))
|
||||||
table.show()
|
parent.show()
|
||||||
|
parent.html(table)
|
||||||
$(this.ids.proyectos).hide()
|
$(this.ids.proyectos).hide()
|
||||||
if (this.table === null) {
|
if (this.table === null) {
|
||||||
this.table = table.DataTable()
|
this.table = table.DataTable({
|
||||||
|
orders: [
|
||||||
|
[0, 'asc']
|
||||||
|
]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
thead: () => {
|
thead: () => {
|
||||||
@ -331,6 +400,9 @@
|
|||||||
venta.draw({tbody, valor_terreno: this.data[proyecto_idx].terreno.valor})
|
venta.draw({tbody, valor_terreno: this.data[proyecto_idx].terreno.valor})
|
||||||
})
|
})
|
||||||
return tbody
|
return tbody
|
||||||
|
},
|
||||||
|
loading: () => {
|
||||||
|
$(this.ids.proyectos).find('.item').css('cursor', 'wait')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -369,6 +441,7 @@
|
|||||||
}
|
}
|
||||||
$(document).ready(() => {
|
$(document).ready(() => {
|
||||||
proyectos.setup({ids: {
|
proyectos.setup({ids: {
|
||||||
|
title: '#list_title',
|
||||||
proyectos: '#proyectos',
|
proyectos: '#proyectos',
|
||||||
data: '#data',
|
data: '#data',
|
||||||
buttons: {
|
buttons: {
|
||||||
|
@ -97,8 +97,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="propietarios" class="fields"></div>
|
<div id="propietarios" class="fields"></div>
|
||||||
</form>
|
</form>
|
||||||
@if ($venta->currentEstado()->fecha->sub(new DateInterval('P1M')) > $venta->proyecto()->terreno->fecha
|
@if ($venta->currentEstado()->fecha->sub(new DateInterval('P1M')) > $terreno?->fecha
|
||||||
and $IPC->get($venta->proyecto()->terreno->fecha, $venta->currentEstado()->fecha->sub(new DateInterval('P1M'))) === 0.0)
|
and ($terreno?->valor ?? 0) === 0.0)
|
||||||
<div class="ui compact icon error message">
|
<div class="ui compact icon error message">
|
||||||
<i class="exclamation triangle icon"></i>
|
<i class="exclamation triangle icon"></i>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@ -409,8 +409,7 @@
|
|||||||
},
|
},
|
||||||
proyecto: {
|
proyecto: {
|
||||||
direccion: '{{$venta->proyecto()->direccion()->simple()}}',
|
direccion: '{{$venta->proyecto()->direccion()->simple()}}',
|
||||||
terreno: {{(isset($terreno->fecha) and $terreno->fecha >= $lastDic) ?
|
terreno: {{$terreno?->valor ?? 0}}
|
||||||
$IPC->readjust($terreno->valor, $terreno->fecha, $venta->currentEstado()->fecha) : 0}},
|
|
||||||
},
|
},
|
||||||
estadoVenta: {
|
estadoVenta: {
|
||||||
fecha: new Date('{{$venta->currentEstado()->fecha->format('Y-m-d')}}')
|
fecha: new Date('{{$venta->currentEstado()->fecha->format('Y-m-d')}}')
|
||||||
@ -758,7 +757,7 @@
|
|||||||
this.update().unidades()
|
this.update().unidades()
|
||||||
this.update().propietarios($(count_propietarios_id).val())
|
this.update().propietarios($(count_propietarios_id).val())
|
||||||
this.draw().propietarios()
|
this.draw().propietarios()
|
||||||
this.unidades.forEach((unidad, idx) => {
|
this.propietarios.forEach((unidad, idx) => {
|
||||||
this.update().proporciones(idx)
|
this.update().proporciones(idx)
|
||||||
})
|
})
|
||||||
this.update().facturas()
|
this.update().facturas()
|
||||||
|
@ -9,9 +9,12 @@ use Incoviba\Service;
|
|||||||
class Facturacion
|
class Facturacion
|
||||||
{
|
{
|
||||||
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, View $view,
|
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, View $view,
|
||||||
Service\Proyecto $proyectoService): ResponseInterface
|
Service\Proyecto $proyectoService, Service\Proyecto\Terreno $terrenoService): ResponseInterface
|
||||||
{
|
{
|
||||||
$proyectos = $proyectoService->getEscriturando();
|
$proyectos = $proyectoService->getEscriturando();
|
||||||
|
foreach ($proyectos as &$proyecto) {
|
||||||
|
$proyecto->terreno = $terrenoService->valor($proyecto->id) ?? $proyecto->terreno;
|
||||||
|
}
|
||||||
return $view->render($response, 'ventas.facturacion', compact('proyectos'));
|
return $view->render($response, 'ventas.facturacion', compact('proyectos'));
|
||||||
}
|
}
|
||||||
public function show(ServerRequestInterface $request, ResponseInterface $response, View $view,
|
public function show(ServerRequestInterface $request, ResponseInterface $response, View $view,
|
||||||
|
@ -171,7 +171,7 @@ class Venta extends Ideal\Repository
|
|||||||
->joined('JOIN proyecto_tipo_unidad ptu ON ptu.id = unidad.pt')
|
->joined('JOIN proyecto_tipo_unidad ptu ON ptu.id = unidad.pt')
|
||||||
->joined('JOIN (SELECT ev1.* FROM estado_venta ev1 JOIN (SELECT MAX(id) AS id, venta FROM estado_venta GROUP BY venta) ev0 ON ev0.id = ev1.id) ev ON ev.venta = a.id')
|
->joined('JOIN (SELECT ev1.* FROM estado_venta ev1 JOIN (SELECT MAX(id) AS id, venta FROM estado_venta GROUP BY venta) ev0 ON ev0.id = ev1.id) ev ON ev.venta = a.id')
|
||||||
->joined('JOIN tipo_estado_venta tev ON tev.id = ev.estado')
|
->joined('JOIN tipo_estado_venta tev ON tev.id = ev.estado')
|
||||||
->where('ptu.proyecto = ? AND tev.activa')
|
->where('ptu.proyecto = ? AND tev.activa = 1')
|
||||||
->group('a.id');
|
->group('a.id');
|
||||||
return $this->fetchIds($query, [$proyecto_id]);
|
return $this->fetchIds($query, [$proyecto_id]);
|
||||||
}
|
}
|
||||||
@ -185,7 +185,7 @@ class Venta extends Ideal\Repository
|
|||||||
->joined('JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`')
|
->joined('JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`')
|
||||||
->joined("JOIN (SELECT e1.* FROM `estado_venta` e1 JOIN (SELECT MAX(`id`) AS 'id', `venta` FROM `estado_venta` GROUP BY `venta`) e0 ON e0.`id` = e1.`id`) ev ON ev.`venta` = a.`id`")
|
->joined("JOIN (SELECT e1.* FROM `estado_venta` e1 JOIN (SELECT MAX(`id`) AS 'id', `venta` FROM `estado_venta` GROUP BY `venta`) e0 ON e0.`id` = e1.`id`) ev ON ev.`venta` = a.`id`")
|
||||||
->joined('JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`')
|
->joined('JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`')
|
||||||
->where('ptu.`proyecto` = ? AND tev.`activa`')
|
->where('ptu.`proyecto` = ? AND tev.`activa` = 1')
|
||||||
->group('a.id');
|
->group('a.id');
|
||||||
return $this->fetchMany($query, [$proyecto_id]);
|
return $this->fetchMany($query, [$proyecto_id]);
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,11 @@ class Terreno extends Ideal\Service
|
|||||||
try {
|
try {
|
||||||
return $this->getValorContable($proyecto, $lastDecember);
|
return $this->getValorContable($proyecto, $lastDecember);
|
||||||
} catch (Implement\Exception\EmptyResponse) {}
|
} catch (Implement\Exception\EmptyResponse) {}
|
||||||
|
if ($proyecto->terreno->fecha === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if ($proyecto->terreno->fecha->getTimestamp() > 0) {
|
if ($proyecto->terreno->fecha->getTimestamp() > 0) {
|
||||||
return $this->getValorReajustado($proyecto, $lastDecember);
|
return $this->getValorReajustado($proyecto);
|
||||||
}
|
}
|
||||||
$terreno = $proyecto->terreno;
|
$terreno = $proyecto->terreno;
|
||||||
} catch (Implement\Exception\EmptyResult) {}
|
} catch (Implement\Exception\EmptyResult) {}
|
||||||
|
@ -46,6 +46,10 @@ class Venta extends Service
|
|||||||
$ventas = $this->ventaRepository->fetchActivaByProyecto($proyecto_id);
|
$ventas = $this->ventaRepository->fetchActivaByProyecto($proyecto_id);
|
||||||
return array_map([$this, 'process'], $ventas);
|
return array_map([$this, 'process'], $ventas);
|
||||||
}
|
}
|
||||||
|
public function getIdsByProyecto(int $proyecto_id): array
|
||||||
|
{
|
||||||
|
return $this->ventaRepository->fetchIdsByProyecto($proyecto_id);
|
||||||
|
}
|
||||||
public function getByProyectoAndUnidad(string $proyecto_nombre, int $unidad_descripcion): Model\Venta
|
public function getByProyectoAndUnidad(string $proyecto_nombre, int $unidad_descripcion): Model\Venta
|
||||||
{
|
{
|
||||||
$venta = $this->ventaRepository->fetchByProyectoAndUnidad($proyecto_nombre, $unidad_descripcion);
|
$venta = $this->ventaRepository->fetchByProyectoAndUnidad($proyecto_nombre, $unidad_descripcion);
|
||||||
|
Reference in New Issue
Block a user