877 lines
30 KiB
PHP
877 lines
30 KiB
PHP
<?php
|
|
namespace Incoviba\old\Proyecto;
|
|
|
|
use Carbon\Carbon;
|
|
use Incoviba\Common\Alias\OldModel as Model;
|
|
use Incoviba\old\Common\Direccion;
|
|
use Incoviba\old\Inmobiliaria\Inmobiliaria;
|
|
use Incoviba\old\Venta\Cierre;
|
|
use Incoviba\old\Venta\Cuota;
|
|
use Incoviba\old\Venta\Promocion;
|
|
use Incoviba\old\Venta\TipoUnidad;
|
|
use Incoviba\old\Venta\Unidad;
|
|
use Incoviba\old\Venta\Venta;
|
|
|
|
/**
|
|
*
|
|
* @author Aldarien
|
|
*
|
|
* @property int $id
|
|
* @property Inmobiliaria $inmobiliaria
|
|
* @property string $descripcion
|
|
* @property Direccion $direccion
|
|
* @property float $superficie_terreno
|
|
* @property float $valor_terreno
|
|
* @property float $corredor
|
|
* @property float $superficie_sobre_nivel
|
|
* @property float $superficie_bajo_nivel
|
|
* @property int $pisos
|
|
* @property int $subterraneos
|
|
*
|
|
*/
|
|
class Proyecto extends Model {
|
|
protected $unidades;
|
|
protected $valores;
|
|
protected $tipo_unidades;
|
|
protected $ventas;
|
|
protected $escrituras;
|
|
protected $entregas;
|
|
protected $estado;
|
|
protected $agentes;
|
|
protected $operadores;
|
|
protected $promociones;
|
|
protected $cuotas;
|
|
protected $superficies;
|
|
|
|
protected $inmobiliaria_obj;
|
|
public function inmobiliaria() {
|
|
if ($this->inmobiliaria_obj === null) {
|
|
$this->inmobiliaria_obj = $this->setRelationship(Inmobiliaria::class, 'rut', 'inmobiliaria')->one();
|
|
}
|
|
return $this->inmobiliaria_obj;
|
|
//return $this->belongs_to(Inmobiliaria::class, 'inmobiliaria', 'rut')->findOne();
|
|
}
|
|
protected $direccion_obj;
|
|
public function direccion() {
|
|
if ($this->direccion_obj === null) {
|
|
$this->direccion_obj = $this->setRelationship(Direccion::class, 'id', 'direccion')->one();
|
|
}
|
|
return $this->direccion_obj;
|
|
//return $this->belongs_to(Direccion::class, 'direccion')->findOne();
|
|
}
|
|
public function unidades($tipo = null) {
|
|
if ($tipo == null) {
|
|
if (!isset($this->unidades) or !isset($this->unidades->total)) {
|
|
$unidades = [];
|
|
if (isset($this->unidades)) {
|
|
$unidades = (array) $this->unidades;
|
|
}
|
|
$unidades['total'] = $this->has_many(Unidad::class, 'proyecto')->findMany();
|
|
$this->unidades = (object) $unidades;
|
|
}
|
|
return $this->unidades->total;
|
|
}
|
|
switch ($tipo) {
|
|
case 1:
|
|
case 'departamento':
|
|
case 'departamentos':
|
|
$tipo = 'departamento';
|
|
$id_tipo = 1;
|
|
break;
|
|
case 2:
|
|
case 'estacionamiento':
|
|
case 'estacionamientos':
|
|
$tipo = 'estacionamiento';
|
|
$id_tipo = 2;
|
|
break;
|
|
case 3:
|
|
case 'bodega':
|
|
case 'bodegas':
|
|
$tipo = 'bodega';
|
|
$id_tipo = 3;
|
|
break;
|
|
default:
|
|
return $this->unidades();
|
|
}
|
|
if (!isset($this->unidades) or !isset($this->unidades->{$tipo})) {
|
|
$unidades = [];
|
|
if (isset($this->unidades)) {
|
|
$unidades = (array) $this->unidades;
|
|
}
|
|
$unidades[$tipo] = $this->has_many(Unidad::class, 'proyecto')->where('tipo', $id_tipo)->findMany();
|
|
$this->unidades = (object) $unidades;
|
|
}
|
|
return $this->unidades->{$tipo};
|
|
}
|
|
public function unidadesDisponibles($tipo = null) {
|
|
switch ($tipo) {
|
|
case 1:
|
|
case 'departamento':
|
|
case 'departamentos':
|
|
$tipo = 'departamento';
|
|
$id_tipo = 1;
|
|
break;
|
|
case 2:
|
|
case 'estacionamiento':
|
|
case 'estacionamientos':
|
|
$tipo = 'estacionamiento';
|
|
$id_tipo = 2;
|
|
break;
|
|
case 3:
|
|
case 'bodega':
|
|
case 'bodegas':
|
|
$tipo = 'bodega';
|
|
$id_tipo = 3;
|
|
break;
|
|
default:
|
|
$tipo = 'total';
|
|
$id_tipo = null;
|
|
}
|
|
if (!isset($this->unidades) or !isset($this->unidades->disponibles) or !isset($this->unidades->disponibles->{$tipo})) {
|
|
$unidades = ['disponibles' => []];
|
|
if (isset($this->unidades)) {
|
|
$unidades = (array) $this->unidades;
|
|
$unidades['disponibles'] = [];
|
|
if (isset($this->unidades->disponibles)) {
|
|
$unidades['disponibles'] = (array) $this->unidades->disponibles;
|
|
}
|
|
}
|
|
$q_s = "SELECT u.*
|
|
FROM
|
|
(SELECT * FROM unidad WHERE proyecto = ? ORDER BY tipo) AS u
|
|
LEFT JOIN
|
|
(SELECT unidad.*
|
|
FROM venta
|
|
JOIN propiedad ON propiedad.id = venta.propiedad
|
|
JOIN unidad ON unidad.id = propiedad.unidad_principal
|
|
WHERE venta.estado = 1) AS v ON v.id = u.id
|
|
LEFT JOIN
|
|
(SELECT unidad.*
|
|
FROM venta
|
|
JOIN propiedad ON propiedad.id = venta.propiedad
|
|
JOIN unidad ON propiedad.estacionamientos LIKE unidad.id
|
|
OR propiedad.estacionamientos LIKE CONCAT(unidad.id, ';%')
|
|
OR propiedad.estacionamientos LIKE CONCAT('%;', unidad.id)
|
|
OR propiedad.estacionamientos LIKE CONCAT('%;', unidad.id, ';%')
|
|
WHERE venta.estado = 1) AS e ON e.id = u.id
|
|
LEFT JOIN
|
|
(SELECT unidad.*
|
|
FROM venta
|
|
JOIN propiedad ON propiedad.id = venta.propiedad
|
|
JOIN unidad ON propiedad.bodegas LIKE unidad.id
|
|
OR propiedad.bodegas LIKE CONCAT(unidad.id, ';%')
|
|
OR propiedad.bodegas LIKE CONCAT('%;', unidad.id)
|
|
OR propiedad.bodegas LIKE CONCAT('%;', unidad.id, ';%')
|
|
WHERE venta.estado = 1) AS b ON b.id = u.id
|
|
WHERE v.id IS NULL AND e.id IS NULL AND b.id IS NULL";
|
|
$q_p = " ORDER BY u.tipo, LPAD(u.descripcion, 4, '0')";
|
|
switch (strtolower($id_tipo)) {
|
|
case null:
|
|
default:
|
|
$q = $q_s . $q_p;
|
|
break;
|
|
case 1:
|
|
case 'departamento':
|
|
case 'departamentos':
|
|
$q = $q_s . ' AND u.tipo = 1' . $q_p;
|
|
break;
|
|
case 2:
|
|
case 'estacionamiento':
|
|
case 'estacionamientos':
|
|
$q = $q_s . ' AND u.tipo = 2' . $q_p;
|
|
break;
|
|
case 3:
|
|
case 'bodega':
|
|
case 'bodegas':
|
|
$q = $q_s . ' AND u.tipo = 3' . $q_p;
|
|
break;
|
|
}
|
|
$disponibles = model(Unidad::class)->rawQuery($q, [$this->id])->findMany();
|
|
$unidades['disponibles'][$tipo] = $disponibles;
|
|
$unidades['disponibles'] = (object) $unidades['disponibles'];
|
|
$this->unidades = (object) $unidades;
|
|
}
|
|
return $this->unidades->disponibles->{$tipo};
|
|
}
|
|
protected $ptus;
|
|
public function proyectoTipoUnidades() {
|
|
if ($this->ptus === null) {
|
|
$this->ptus = $this->setRelationship(ProyectoTipoUnidad::class, 'proyecto', 'id')->sort(['tipo', 'asc'])->many();
|
|
}
|
|
return $this->ptus;
|
|
//return $this->hasMany(ProyectoTipoUnidad::class, 'proyecto')->orderByAsc('tipo')->findMany();
|
|
}
|
|
public function tipoUnidades() {
|
|
if (!isset($this->tipos_unidades)) {
|
|
$tipos = \Model::factory(TipoUnidad::class)
|
|
->select('tipo_unidad.*')
|
|
->join('unidad', ['unidad.tipo', '=', 'tipo_unidad.id'])
|
|
->join('proyecto', ['proyecto.id', '=', 'unidad.proyecto'])
|
|
->where('proyecto.id', $this->id)
|
|
->order_by_asc('tipo_unidad.id')
|
|
->group_by('tipo_unidad.id')
|
|
->findMany();
|
|
$this->tipos_unidades = $tipos;
|
|
}
|
|
return $this->tipos_unidades;
|
|
}
|
|
public function ventas($order = 'departamento') {
|
|
if (!isset($this->ventas)) {
|
|
$ventas = model(Venta::class)
|
|
->select('venta.*')
|
|
->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
|
|
->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
|
|
->rawJoin('JOIN (SELECT `e1`.* FROM (SELECT `venta`, MAX(`id`) AS `id` FROM `estado_venta` GROUP BY `venta`) AS `e0` JOIN `estado_venta` AS `e1` ON `e1`.`id` = `e0`.`id`)', ['estado_venta.venta', '=', 'venta.id'], 'estado_venta')
|
|
->join('tipo_estado_venta', ['tipo_estado_venta.id', '=', 'estado_venta.estado'])
|
|
->where('unidad.proyecto', $this->id)
|
|
->where('unidad.tipo', 1)
|
|
->where('tipo_estado_venta.activa', 1);
|
|
switch (strtolower($order)) {
|
|
case 'fecha':
|
|
$ventas = $ventas->orderByAsc('venta.fecha');
|
|
case 'departamento':
|
|
default:
|
|
$ventas = $ventas->orderByExpr('LPAD(`unidad`.`descripcion`, 4, "0")');
|
|
break;
|
|
}
|
|
$ventas = $ventas->find_many();
|
|
$this->ventas = $ventas;
|
|
foreach ($this->ventas as &$venta) {
|
|
$venta->setContainer($this->container);
|
|
}
|
|
}
|
|
return $this->ventas;
|
|
}
|
|
protected $resciliaciones;
|
|
public function resciliaciones() {
|
|
if ($this->resciliaciones === null) {
|
|
$resciliaciones = model(Venta::class)
|
|
->select('venta.*')
|
|
->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
|
|
->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
|
|
->rawJoin('JOIN (SELECT `e1`.* FROM (SELECT `venta`, MAX(`id`) AS `id` FROM `estado_venta` GROUP BY `venta`) AS `e0` JOIN `estado_venta` AS `e1` ON `e1`.`id` = `e0`.`id`)', ['estado_venta.venta', '=', 'venta.id'], 'estado_venta')
|
|
->join('tipo_estado_venta', ['tipo_estado_venta.id', '=', 'estado_venta.estado'])
|
|
->where('unidad.proyecto', $this->id)
|
|
->where('unidad.tipo', 1)
|
|
->where('tipo_estado_venta.activa', 0)
|
|
->orderByExpr('LPAD(`unidad`.`descripcion`, 4, "0")')
|
|
->find_many()
|
|
;
|
|
$this->resciliaciones = $resciliaciones;
|
|
foreach ($this->resciliaciones as &$venta) {
|
|
$venta->setContainer($this->container);
|
|
}
|
|
}
|
|
return $this->resciliaciones;
|
|
}
|
|
public function escrituras() {
|
|
if (!isset($escrituras)) {
|
|
$ventas = model(Venta::class)
|
|
->select('venta.*')
|
|
->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
|
|
->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
|
|
->where('unidad.proyecto', $this->id)
|
|
->where('venta.estado', 1)
|
|
->where('unidad.tipo', 1)
|
|
->whereNotEqual('venta.escriturado', '0')
|
|
->orderByExpr('LPAD(unidad.descripcion, 4, "0")')
|
|
->find_many()
|
|
;
|
|
$this->escrituras = $ventas;
|
|
foreach ($this->escrituras as &$venta) {
|
|
$venta->setContainer($this->container);
|
|
}
|
|
}
|
|
return $this->escrituras;
|
|
}
|
|
public function entregas() {
|
|
if (!isset($this->entregas)) {
|
|
$entregas = [];
|
|
$escrituras = $this->escrituras();
|
|
foreach ($escrituras as $escritura) {
|
|
if ($escritura->entrega == '0') {
|
|
continue;
|
|
}
|
|
$entregas []= $escritura;
|
|
}
|
|
usort($entregas, function($a, $b) {
|
|
$fa = \Carbon\Carbon::parse($a->entrega()->find_one()->fecha);
|
|
$fb = \Carbon\Carbon::parse($b->entrega()->find_one()->fecha);
|
|
$dif = $fb->diffInDays($fa, false);
|
|
if ($dif == 0) {
|
|
return $a->unidad()->descripcion - $b->unidad()->descripcion;
|
|
}
|
|
return $dif;
|
|
});
|
|
$this->entregas = $entregas;
|
|
foreach ($this->entregas as &$venta) {
|
|
$venta->setContainer($this->container);
|
|
}
|
|
}
|
|
return $this->entregas;
|
|
}
|
|
protected $estados;
|
|
public function estados() {
|
|
if ($this->estados === null) {
|
|
$this->estados = $this->setRelationship(EstadoProyecto::class, 'proyecto', 'id')->sort(['fecha', 'asc'])->many();
|
|
}
|
|
return $this->estados;
|
|
//return $this->has_many(EstadoProyecto::class, 'proyecto')->orderByAsc('fecha')->findMany();
|
|
}
|
|
public function estado() {
|
|
if (!isset($this->estado)) {
|
|
$id = $this->has_many(EstadoProyecto::class, 'proyecto')->max('id');
|
|
$this->estado = $this->has_many(EstadoProyecto::class, 'proyecto')->findOne($id);
|
|
$this->estado->setContainer($this->container);
|
|
}
|
|
return $this->estado;
|
|
}
|
|
protected $avances;
|
|
public function avances() {
|
|
if ($this->avances === null) {
|
|
$this->avances = $this->setRelationship(AvanceConstruccion::class, 'proyecto', 'id')->sort(['fecha', 'asc'])->many();
|
|
}
|
|
return $this->avances;
|
|
//return $this->hasMany(AvanceConstruccion::class, 'proyecto')->orderByAsc('fecha')->findMany();
|
|
}
|
|
protected $avance;
|
|
public function avance() {
|
|
if ($this->avance == null and $this->avances()) {
|
|
$avance = array_reduce($this->avances(), function($carry, $item) {
|
|
return ($carry += $item->avance);
|
|
});
|
|
$this->avance = $avance;
|
|
}
|
|
return $this->avance;
|
|
}
|
|
protected $inicio;
|
|
public function inicio() {
|
|
if (!isset($this->inicio) or $this->inicio == null) {
|
|
$id = $this->has_many(EstadoProyecto::class, 'proyecto')->min('id');
|
|
$this->inicio = $this->has_many(EstadoProyecto::class, 'proyecto')->findOne($id);
|
|
$this->inicio->setContainer($this->container);
|
|
}
|
|
return $this->inicio;
|
|
}
|
|
public function valores() {
|
|
if (!isset($this->valores)) {
|
|
$ventas = $this->ventas();
|
|
|
|
/**
|
|
* vendidos
|
|
* departamentos
|
|
* cantidad
|
|
* ingreso
|
|
* neto
|
|
* bruto // suma estacionamientos, bodegas, comision y premios
|
|
* pagado
|
|
* abonado
|
|
* precio
|
|
* minimo
|
|
* promedio
|
|
* maximo
|
|
* mts
|
|
* minimo
|
|
* promedio // total dividido cantidad
|
|
* maximo
|
|
* total
|
|
* uf_m2
|
|
* minimo // minimo de precio dividido mts
|
|
* promedio // ingreso neto dividido mts total
|
|
* maximo // maximo de precio dividido mts
|
|
* estacionamientos // valor estacionamientos
|
|
* bodegas // valor bodegas
|
|
* comision // valor comisiones
|
|
* premios // valor total cada premio
|
|
* estimados // idem vendidos, pero valores estimados proporcional a mts
|
|
* totales // vendidos + estimados
|
|
*/
|
|
|
|
$premios = model(Promocion::class)->findMany();
|
|
$valores = (object) [
|
|
'vendidos' => new BaseValores(),
|
|
'estimados' => new BaseValores(),
|
|
'totales' => new BaseValores()
|
|
];
|
|
foreach ($valores as &$name) {
|
|
$name->basePremios($premios);
|
|
}
|
|
if ($ventas) {
|
|
$valores->vendidos->ingreso->neto = 0;
|
|
$valores->vendidos->ingreso->neto = array_reduce($ventas, function($sum, $item) {
|
|
return $sum + $item->valorFinal();
|
|
});
|
|
foreach ($ventas as $venta) {
|
|
//$valores->vendidos->ingreso->neto += $venta->valorFinal();
|
|
$valores->vendidos->ingreso->bruto += $venta->valor_uf;
|
|
$valores->vendidos->ingreso->pagado += $venta->valorPagado();
|
|
$valores->vendidos->ingreso->abonado += $venta->valorAbonado();
|
|
|
|
$valores->vendidos->departamentos->cantidad ++;
|
|
if ($venta->unidad()->precio($venta->fecha())) {
|
|
$valores->vendidos->departamentos->addPrecio($venta->unidad()->precio($venta->fecha())->valor);
|
|
}
|
|
$valores->vendidos->departamentos->addMts('totales', $venta->unidad()->m2('total'));
|
|
$valores->vendidos->departamentos->addMts('vendibles', $venta->unidad()->m2());
|
|
|
|
//$valores->vendidos->otros->cantidad += ($venta->estacionamientos() or $venta->bodegas()) :
|
|
$valores->vendidos->otros->valor += $venta->valorEstacionamientosYBodegas();
|
|
if ($venta->bono_pie) {
|
|
$valores->vendidos->bono->cantidad ++;
|
|
$valores->vendidos->bono->valor += $venta->bonoPie()->pago()->valor('ufs');
|
|
}
|
|
$valores->vendidos->comision += $venta->valorComision();
|
|
$ps = $venta->promociones();
|
|
if (count($ps) > 0) {
|
|
foreach ($ps as $promo) {
|
|
if ($promo->descripcion != '') {
|
|
$valores->vendidos->premios->{$promo->descripcion} += $promo->valor;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$valores->vendidos->departamentos->setPromedios();
|
|
}
|
|
|
|
$valores->estimados->departamentos->cantidad = count($this->unidades(1)) - count($this->ventas());
|
|
$valores->estimados->departamentos->mts->vendibles->total = 0;
|
|
$valores->estimados->departamentos->mts->vendibles->promedio = 0;
|
|
$valores->estimados->departamentos->precio->promedio = 0;
|
|
$valores->estimados->departamentos->uf_m2->promedio = 0;
|
|
if ($valores->estimados->departamentos->cantidad > 0) {
|
|
$valores->estimados->departamentos->mts->vendibles->total = array_reduce($this->unidadesDisponibles(1), function($sum, $item) {
|
|
return $sum + $item->m2();
|
|
});
|
|
$valores->estimados->departamentos->mts->vendibles->promedio = $valores->estimados->departamentos->mts->vendibles->total / $valores->estimados->departamentos->cantidad;
|
|
$valores->estimados->ingreso->neto = array_reduce($this->unidadesDisponibles(1), function($sum, $item) {
|
|
if (!$item->precio()) {
|
|
return $sum;
|
|
}
|
|
return $sum + $item->precio()->valor;
|
|
});
|
|
if ($valores->estimados->ingreso->neto == null) {
|
|
$valores->estimados->ingreso->neto = 0;
|
|
}
|
|
$valores->estimados->departamentos->precio->promedio = $valores->estimados->ingreso->neto / $valores->estimados->departamentos->cantidad;
|
|
$valores->estimados->departamentos->uf_m2->promedio = $valores->estimados->ingreso->neto / $valores->estimados->departamentos->mts->vendibles->total;
|
|
}
|
|
|
|
$valores->estimados->otros->cantidad = count($this->unidadesDisponibles(2)) + count($this->unidadesDisponibles(3));
|
|
$valores->estimados->otros->valor = count($this->unidadesDisponibles(2)) * 330 + count($this->unidadesDisponibles(3)) * 50;
|
|
foreach ($premios as $premio) {
|
|
$valores->estimados->premios->{$premio->descripcion} = 0;
|
|
if ($valores->vendidos->ingreso->neto > 0) {
|
|
$valores->estimados->premios->{$premio->descripcion} = $valores->vendidos->premios() * $valores->estimados->ingreso->neto / $valores->vendidos->ingreso->neto;
|
|
}
|
|
}
|
|
$valores->estimados->bono->valor = 0;
|
|
$valores->estimados->comision = 0;
|
|
if ($valores->vendidos->ingreso->neto > 0) {
|
|
$valores->estimados->bono->valor = $valores->vendidos->bono->valor * $valores->estimados->ingreso->neto / $valores->vendidos->ingreso->neto;
|
|
$valores->estimados->comision = $valores->vendidos->comision * $valores->estimados->ingreso->neto / $valores->vendidos->ingreso->neto;
|
|
}
|
|
$valores->estimados->ingreso->bruto = $valores->estimados->ingreso->neto
|
|
+ $valores->estimados->otros->valor
|
|
+ $valores->estimados->bono->valor
|
|
+ $valores->estimados->premios()
|
|
+ $valores->estimados->comision;
|
|
|
|
$this->valores = $valores;
|
|
}
|
|
|
|
return $this->valores;
|
|
}
|
|
public function agentes() {
|
|
if (!isset($this->agentes)) {
|
|
$this->agentes = \Model::factory(Agente::class)
|
|
->select('agente.*')
|
|
->join('proyecto_agente', ['proyecto_agente.agente', '=', 'agente.id'])
|
|
->where('proyecto_agente.proyecto', $this->id)
|
|
->orderByAsc('agente.abreviacion')
|
|
->findMany();
|
|
}
|
|
return $this->agentes;
|
|
}
|
|
public function operadores() {
|
|
if (!isset($this->operadores)) {
|
|
$this->operadores = \Model::factory(Agente::class)
|
|
->select('agente.*')
|
|
->select('agente_tipo.id', 'agente_tipo')
|
|
->join('agente_tipo', ['agente_tipo.agente', '=', 'agente.id'])
|
|
->join('proyecto_agente', ['proyecto_agente.agente', '=', 'agente_tipo.id'])
|
|
->where('agente_tipo.tipo', 19)
|
|
->where('proyecto_agente.proyecto', $this->id)
|
|
->orderByAsc('agente.abreviacion')
|
|
->groupBy('agente_tipo.id')
|
|
->findMany();
|
|
}
|
|
return $this->operadores;
|
|
}
|
|
public function operadoresVigentes() {
|
|
return $this->hasMany(ProyectoAgente::class, 'proyecto')
|
|
->select('proyecto_agente.*')
|
|
->join('agente_tipo', ['agente_tipo.id', '=', 'proyecto_agente.agente'])
|
|
->rawJoin('JOIN (SELECT e1.* FROM estado_proyecto_agente e1 JOIN (SELECT agente, MAX(id) AS id FROM estado_proyecto_agente GROUP BY agente) e0 ON e0.id = e1.id)', ['ep.agente', '=', 'proyecto_agente.id'], 'ep')
|
|
->where('agente_tipo.tipo', 19)
|
|
->where('ep.tipo', 1)
|
|
->findMany();
|
|
}
|
|
public function promociones() {
|
|
if (!isset($this->promociones)) {
|
|
$this->promociones = \Model::factory(Promocion::class)
|
|
->select('promocion.*')
|
|
->join('promocion_venta', ['promocion_venta.promocion', '=', 'promocion.id'])
|
|
->join('venta', ['venta.id', '=', 'promocion_venta.venta'])
|
|
->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
|
|
->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
|
|
->where('unidad.proyecto', $this->id)
|
|
->groupBy('promocion.id')
|
|
->orderByAsc('promocion.titulo')
|
|
->findMany();
|
|
}
|
|
return $this->promociones;
|
|
}
|
|
public function pisos() {
|
|
if ($this->pisos == 0) {
|
|
$pisos = $this->has_many(Unidad::class, 'proyecto')->where('tipo', 1)->max('piso');
|
|
if (!$pisos) {
|
|
return 0;
|
|
}
|
|
$this->pisos = $pisos;
|
|
$this->save();
|
|
}
|
|
return $this->pisos;
|
|
}
|
|
public function cuotasHoy() {
|
|
if (!isset($this->cuotas) or !isset($this->cuotas->hoy)) {
|
|
$cuotas = [];
|
|
if (isset($this->cuotas)) {
|
|
$cuotas = (array) $this->cuotas;
|
|
}
|
|
$f = Carbon::today($this->container->get('settings')->app->timezone);
|
|
$cuotas['hoy'] = model(Venta::class)
|
|
->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
|
|
->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
|
|
->join('cuota', ['cuota.pie', '=', 'venta.pie'])
|
|
->join('pago', ['pago.id', '=', 'cuota.pago'])
|
|
->raw_join('JOIN (SELECT e1.* FROM (SELECT pago, MAX(id) AS id FROM estado_pago GROUP BY pago) e0 JOIN estado_pago e1 ON e1.id = e0.id)', ['ep.pago', '=', 'pago.id'], 'ep')
|
|
->where('unidad.proyecto', $this->id)
|
|
->where('venta.estado', 1)
|
|
->where('pago.fecha', $f->format('Y-m-d'))
|
|
->whereLt('ep.estado', 1)
|
|
->whereGte('ep.estado', 0)
|
|
->count('cuota.id');
|
|
$this->cuotas = (object) $cuotas;
|
|
}
|
|
return $this->cuotas->hoy;
|
|
}
|
|
public function cuotasPendientes() {
|
|
if (!isset($this->cuotas) or !isset($this->cuotas->pendientes)) {
|
|
$cuotas = [];
|
|
if (isset($this->cuotas)) {
|
|
$cuotas = (array) $this->cuotas;
|
|
}
|
|
$f = Carbon::today($this->container->get('settings')->app->timezone);
|
|
$cuotas['pendientes'] = model(Cuota::class)
|
|
->join('venta', ['cuota.pie', '=', 'venta.pie'])
|
|
->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
|
|
->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
|
|
->join('pago', ['pago.id', '=', 'cuota.pago'])
|
|
->raw_join('JOIN (SELECT e1.* FROM (SELECT pago, MAX(id) AS id FROM estado_pago GROUP BY pago) e0 JOIN estado_pago e1 ON e1.id = e0.id)', ['ep.pago', '=', 'pago.id'], 'ep')
|
|
->where('unidad.proyecto', $this->id)
|
|
->where('venta.estado', 1)
|
|
->whereLt('pago.fecha', $f->format('Y-m-d'))
|
|
->whereLt('ep.estado', 1)
|
|
->whereGte('ep.estado', 0)
|
|
->count('cuota.id');
|
|
$this->cuotas = (object) $cuotas;
|
|
}
|
|
return $this->cuotas->pendientes;
|
|
}
|
|
public function cuotasMes() {
|
|
if (!isset($this->cuotas) or !isset($this->cuotas->mes)) {
|
|
$cuotas = [];
|
|
if (isset($this->cuotas)) {
|
|
$cuotas = (array) $this->cuotas;
|
|
}
|
|
$f = Carbon::today($this->container->get('settings')->app->timezone);
|
|
$cuotas['mes'] = model(Cuota::class)
|
|
->join('venta', ['cuota.pie', '=', 'venta.pie'])
|
|
->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
|
|
->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
|
|
->join('pago', ['pago.id', '=', 'cuota.pago'])
|
|
->raw_join('JOIN (SELECT e1.* FROM (SELECT pago, MAX(id) AS id FROM estado_pago GROUP BY pago) e0 JOIN estado_pago e1 ON e1.id = e0.id)', ['ep.pago', '=', 'pago.id'], 'ep')
|
|
->where('unidad.proyecto', $this->id)
|
|
->where('venta.estado', 1)
|
|
->whereGt('pago.fecha', $f->format('Y-m-d'))
|
|
->whereLte('pago.fecha', $f->copy()->addMonth(1)->format('Y-m-d'))
|
|
->where('ep.estado', 0)
|
|
->findMany();
|
|
$this->cuotas = (object) $cuotas;
|
|
}
|
|
return $this->cuotas->mes;
|
|
}
|
|
public function tiposMediciones() {
|
|
$tipos = $this->has_many_through(\Incoviba\nuevo\Venta\TipoMedicion::class, \Incoviba\nuevo\Venta\ProyectoTipoMedicion::class, 'proyecto_id', 'tipo_medicion_id');
|
|
if ($tipos) {
|
|
return $tipos->orderByAsc('descripcion')->findMany();
|
|
}
|
|
return null;
|
|
}
|
|
public function superficie($tipo = 'total') {
|
|
if (!isset($this->superficies) or !isset($this->superficies->{$tipo})) {
|
|
$superficies = [];
|
|
if (isset($this->superficies)) {
|
|
$superficies = (array) $this->superficies;
|
|
}
|
|
switch (strtolower($tipo)) {
|
|
case 'total':
|
|
$superficies['total'] = $this->superficie('snt') + $this->superficie('bnt');
|
|
break;
|
|
case 'terreno':
|
|
$superficies['terreno'] = $this->superficie_terreno;
|
|
break;
|
|
case 'sobre_nivel':
|
|
case 'snt':
|
|
$superficies['snt'] = $superficies['sobre_nivel'] = $this->superficie_sobre_nivel;
|
|
break;
|
|
case 'bajo_nivel':
|
|
case 'bnt':
|
|
$superficies['bnt'] = $superficies['bajo_nivel'] = $this->superficie_bajo_nivel;
|
|
break;
|
|
case 'vendible':
|
|
$superficies['vendible'] = 0;
|
|
if ($this->unidades()) {
|
|
$metros = $this->hasMany(Unidad::class, 'proyecto')->selectExpr('SUM(m2 + logia + terraza /2)', 'metros')->where('tipo', 1)->groupBy('proyecto')->findOne();
|
|
$superficies['vendible'] = $metros->metros;
|
|
}
|
|
break;
|
|
case 'vendida':
|
|
$superficies['vendida'] = 0;
|
|
if ($this->ventas()) {
|
|
$metros = model(Venta::class)
|
|
->selectExpr('SUM(unidad.m2 + unidad.logia + unidad.terraza / 2)', 'metros')
|
|
->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
|
|
->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
|
|
->where('unidad.proyecto', $this->id)
|
|
->where('venta.estado', 1)
|
|
->where('unidad.tipo', 1)
|
|
->groupBy('unidad.proyecto')
|
|
->findOne();
|
|
if ($metros) {
|
|
$superficies['vendida'] = $metros->metros;
|
|
}
|
|
}
|
|
break;
|
|
case 'por vender':
|
|
$superficies['por vender'] = $this->superficie('vendible') - $this->superficie('vendida');
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
$this->superficies = (object) $superficies;
|
|
}
|
|
return $this->superficies->{$tipo};
|
|
}
|
|
public function setDireccion(array $data) {
|
|
if (!is_numeric($data['comuna'])) {
|
|
$comuna = model(Comuna::class)->where('descripcion', $data['comuna'])->findOne();
|
|
$data['comuna'] = $comuna->id;
|
|
}
|
|
$direccion = model(Direccion::class)
|
|
->where('calle', $data['calle'])
|
|
->where('numero', $data['numero'])
|
|
->where('extra', $data['extra'])
|
|
->where('comuna', $data['comuna'])
|
|
->findOne();
|
|
$this->direccion = $direccion->id;
|
|
}
|
|
public function addAgente(array $data) {
|
|
$data = ['agente' => $data['agente'], 'tipo' => $data['tipo']];
|
|
$agente = (new Factory(AgenteTipo::class))->create($data);
|
|
$agente->save();
|
|
$this->agentes []= $agente;
|
|
}
|
|
protected $tipologias;
|
|
public function tipologias() {
|
|
if ($this->tipologias == null) {
|
|
$pts = $this->proyectoTipoUnidades();
|
|
$tipologias = [];
|
|
foreach ($pts as $pt) {
|
|
if ($pt->tipologia()) {
|
|
if (!isset($tipologias[$pt->tipologia()->tipologia->descripcion])) {
|
|
$tipologias[$pt->tipologia()->tipologia->descripcion] = (object) ['tipologia' => $pt->tipologia()->tipologia, 'tipos' => []];
|
|
}
|
|
$tipologias[$pt->tipologia()->tipologia->descripcion]->tipos []= $pt;
|
|
continue;
|
|
}
|
|
}
|
|
$this->tipologias = $tipologias;
|
|
}
|
|
return $this->tipologias;
|
|
}
|
|
protected $pagares;
|
|
public function pagares() {
|
|
if ($this->pagares === null) {
|
|
$this->pagares = $this->setRelationship(Pagare::class, 'proyecto', 'id')->many();
|
|
}
|
|
return $this->pagares;
|
|
//return $this->hasMany(Pagare::class, 'proyecto')->findMany();
|
|
}
|
|
protected $cierres;
|
|
public function cierres(int $vigentes = 0) {
|
|
if (!isset($this->cierres[$vigentes]) or $this->cierres[$vigentes] == null) {
|
|
$orm = model(Cierre::class)
|
|
->select('cierre.*')
|
|
->rawJoin('join (select e1.* from estado_cierre e1 join (select cierre, max(id) as id from estado_cierre group by cierre) e0 on e0.id = e1.id)', ['ec.cierre', '=', 'cierre.id'], 'ec')
|
|
->join('tipo_estado_cierre', ['tipo_estado_cierre.id', '=', 'ec.tipo'])
|
|
->join('proyecto', ['proyecto.id', '=', 'cierre.proyecto'])
|
|
->join('unidad_cierre', ['unidad_cierre.cierre', '=', 'cierre.id'])
|
|
->join('unidad', ['unidad.id', '=', 'unidad_cierre.unidad'])
|
|
->where('proyecto.id', $this->id)
|
|
->where('unidad_cierre.principal', 1)
|
|
->orderByAsc('proyecto.descripcion')
|
|
->orderByDesc('tipo_estado_cierre.vigente')
|
|
->orderByAsc('cierre.fecha')
|
|
->orderByExpr('LPAD(unidad.descripcion, 4, "0")')
|
|
->groupBy('cierre.id');
|
|
switch ($vigentes) {
|
|
case Cierre::VIGENTES:
|
|
$orm = $orm->where('tipo_estado_cierre.vigente', 1);
|
|
break;
|
|
case Cierre::NO_VIGENTES:
|
|
$orm = $orm->where('tipo_estado_cierre.vigente', 0);
|
|
break;
|
|
case Cierre::VIGENTES + 1:
|
|
$orm = $orm
|
|
->where('tipo_estado_cierre.vigente', 1)
|
|
->whereNotLike('tipo_estado_cierre.descripcion', 'promesado')
|
|
;
|
|
break;
|
|
case Cierre::VIGENTES + 2:
|
|
$orm = $orm
|
|
->where('tipo_estado_cierre.vigente', 1)
|
|
->whereLike('tipo_estado_cierre.descripcion', 'promesado')
|
|
;
|
|
break;
|
|
}
|
|
$this->cierres[$vigentes] = $orm->findMany();
|
|
}
|
|
return $this->cierres[$vigentes];
|
|
}
|
|
protected $tipos;
|
|
public function tipos() {
|
|
if ($this->tipos === null) {
|
|
$this->tipos = $this->setRelationship(ProyectoTipoUnidad::class, 'proyecto', 'id')->many();
|
|
}
|
|
return $this->tipos;
|
|
//return $this->hasMany(ProyectoTipoUnidad::class, 'proyecto')->findMany();
|
|
}
|
|
}
|
|
|
|
class Departamentos {
|
|
public $cantidad;
|
|
public $precio;
|
|
public $mts;
|
|
public $uf_m2;
|
|
public function __construct() {
|
|
$this->cantidad = 0;
|
|
$base = [
|
|
'minimo' => 1000000,
|
|
'promedio' => 0,
|
|
'maximo' => -1
|
|
];
|
|
$this->precio = (object) $base;
|
|
$this->mts = (object) [
|
|
'totales' => (object) array_merge($base, ['total' => 0]),
|
|
'vendibles' => (object) array_merge($base, ['total' => 0])
|
|
];
|
|
$this->uf_m2 = (object) $base;
|
|
}
|
|
protected function setMin(&$var, $val) {
|
|
if ($var > $val) {
|
|
$var = $val;
|
|
}
|
|
}
|
|
protected function setMax(&$var, $val) {
|
|
if ($var < $val) {
|
|
$var = $val;
|
|
}
|
|
}
|
|
public function addPrecio($val) {
|
|
$this->precio->promedio += $val;
|
|
$this->setMin($this->precio->minimo, $val);
|
|
$this->setMax($this->precio->maximo, $val);
|
|
$this->uf_m2->promedio += $val;
|
|
|
|
return $this;
|
|
}
|
|
public function addMts($name, $val) {
|
|
$this->mts->$name->total += $val;
|
|
$this->mts->$name->promedio += $val;
|
|
$this->setMin($this->mts->{$name}->minimo, $val);
|
|
$this->setMax($this->mts->{$name}->maximo, $val);
|
|
|
|
return $this;
|
|
}
|
|
public function addUfM2($val) {
|
|
$this->setMin($this->uf_m2->minimo, $val);
|
|
$this->setMax($this->uf_m2->maximo, $val);
|
|
|
|
return $this;
|
|
}
|
|
public function setPromedios() {
|
|
$this->precio->promedio /= $this->cantidad;
|
|
$this->mts->totales->promedio /= $this->cantidad;
|
|
$this->mts->vendibles->promedio /= $this->cantidad;
|
|
$this->uf_m2->promedio /= $this->mts->vendibles->total;
|
|
|
|
return $this;
|
|
}
|
|
};
|
|
class BaseValores {
|
|
public $ingreso;
|
|
public $departamentos;
|
|
public $otros;
|
|
public $bono;
|
|
public $comision;
|
|
public $premios;
|
|
|
|
public function __construct() {
|
|
$this->ingreso = (object) [
|
|
'neto' => 0,
|
|
'bruto' => 0,
|
|
'pagado' => 0,
|
|
'abonado' => 0
|
|
];
|
|
$this->departamentos = new Departamentos();
|
|
$this->otros = (object) [
|
|
'cantidad' => 0,
|
|
'valor' => 0
|
|
];
|
|
$this->bono = (object) [
|
|
'cantidad' => 0,
|
|
'valor' => 0
|
|
];
|
|
$this->comision = 0;
|
|
$this->premios = [];
|
|
}
|
|
public function basePremios(array $premios) {
|
|
foreach ($premios as $premio) {
|
|
$this->premios[$premio->descripcion] = 0;
|
|
}
|
|
$this->premios = (object) $this->premios;
|
|
|
|
return $this;
|
|
}
|
|
protected $total_premios;
|
|
public function premios() {
|
|
if ($this->total_premios == null) {
|
|
$this->total_premios = array_reduce((array) $this->premios, function($sum, $item) {
|
|
return $sum + $item;
|
|
});
|
|
}
|
|
return $this->total_premios;
|
|
}
|
|
};
|