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; } };