select('cierre.*') ->join('unidad_cierre', ['unidad_cierre.cierre', '=', 'cierre.id']) ->where('cierre.proyecto', $proyecto->id) ->where('unidad_cierre.unidad', $unidad->id) ->where('cierre.precio', $precio); } public static function vigentes() { return model(Cierre::class) ->select('cierre.*') ->join('estado_cierre', ['estado_cierre.cierre', '=', 'cierre.id']) ->join('tipo_estado_cierre', ['tipo_estado_cierre.id', '=', 'estado_cierre.tipo']) ->join('proyecto', ['proyecto.id', '=', 'cierre.proyecto']) ->where('tipo_estado_cierre.vigente', 1) ->orderByAsc('proyecto.descripcion') ->orderByAsc('cierre.fecha') ->groupBy('cierre.id') ->findMany(); } public static function proyectos() { return model(Proyecto::class) ->select('proyecto.*') ->join('cierre', ['proyecto.id', '=', 'cierre.proyecto']) ->join('estado_cierre', ['estado_cierre.cierre', '=', 'cierre.id']) ->join('tipo_estado_cierre', ['tipo_estado_cierre.id', '=', 'estado_cierre.tipo']) ->where('tipo_estado_cierre.vigente', 1) ->orderByAsc('proyecto.descripcion') ->orderByAsc('cierre.fecha') ->groupBy('proyecto.id') ->findMany(); } public function proyecto() { return $this->belongsTo(Proyecto::class, 'proyecto')->findOne(); } public function unidades() { return $this->hasMany(UnidadCierre::class, 'cierre')->where('principal', 0)->findMany(); } public function unidadPrincipal() { return $this->hasMany(UnidadCierre::class, 'cierre')->where('principal', 1)->findOne(); } public function fecha(\DateTime $fecha = null) { if ($fecha == null) { return Carbon::parse($this->fecha, config('app.timezone')); } $this->fecha = $fecha->format('Y-m-d'); } public function propietario() { $propietario = $this->belongsTo(Propietario::class, 'propietario'); if ($propietario) { return $propietario->findOne(); } return false; } public function uf_m2() { return $this->neto() / $this->unidadPrincipal()->unidad()->m2(); } public function neto() { $valor = $this->precio; foreach ($this->unidades() as $unidad) { $valor -= $unidad->unidad()->precio($this->fecha())->valor; } foreach ($this->valores() as $v) { if ($v->tipo()->descripcion == 'pie') { continue; } $valor -= $v->valor; } return $valor; } public function valores() { return $this->hasMany(ValorCierre::class, 'cierre')->findMany(); } public function valor($tipo = 'pie') { return $this->hasMany(ValorCierre::class, 'cierre') ->select('valor_cierre.*') ->join('tipo_valor_cierre', ['tipo_valor_cierre.id', '=', 'valor_cierre.tipo']) ->where('tipo_valor_cierre.descripcion', $tipo) ->findOne(); } public function estados() { return $this->hasMany(EstadoCierre::class, 'cierre')->findMany(); } public function estado(\DateTime $fecha = null) { if ($fecha == null) { $estado = $this->hasMany(EstadoCierre::class, 'cierre')->orderByDesc('id')->findOne(); if ($estado->tipo()->vigente == 1 and $this->oldest()) { if ($this->promesa() and $estado->tipo()->descripcion != 'promesado') { $tipo = model(TipoEstadoCierre::class)->where('descripcion', 'promesado')->findOne(); $data = [ 'cierre' => $this->id, 'tipo' => $tipo->id, 'fecha' => $this->promesa()->fecha ]; $estado = model(EstadoCierre::class)->create($data); $estado->save(); } } } else { $estado = $this->hasMany(EstadoCierre::class, 'cierre')->whereLte('fecha', $fecha->format('Y-m-d'))->orderByDesc('id')->findOne(); } return $estado; } public function new(\DateTime $fecha) { $this->save(); $tipo = model(TipoEstadoCierre::class)->where('descripcion', 'revisado')->findOne(); $data = [ 'cierre' => $this->id, 'tipo' => $tipo->id, 'fecha' => $fecha->format('Y-m-d') ]; $estado = model(EstadoCierre::class)->create($data); $estado->save(); if ($this->other()) { $this->replace($fecha); } } protected function cierresUnidad() { $up = $this->unidadPrincipal(); if (!$up) { return false; } $up = $up->id; $cierres = model(Cierre::class) ->select('cierre.*') ->join('unidad_cierre', ['unidad_cierre.cierre', '=', 'cierre.id']) ->where('unidad_cierre.unidad', $up) ->findMany(); $id = $this->id; $cierres = array_filter($cierres, function($item) use ($id) { return ($id != $item->id); }); return $cierres; } protected function other(): bool { $cierres = $this->cierresUnidad(); if ($cierres and count($cierres) > 0) { return true; } return false; } protected function oldest(): bool { if ($this->other()) { $last = $this->cierresUnidad()[count($this->cierresUnidad()) - 1]; if ($last->fecha < $this->fecha) { return true; } return false; } return true; } protected function replace(\DateTime $fecha) { $cierres = $this->cierresUnidad(); $tipo = model(TipoEstadoCierre::class)->where('descripcion', 'abandonado')->findOne(); array_walk($cierres, function($item) use ($tipo, $fecha) { $data = [ 'cierre' => $item->id, 'tipo' => $tipo->id, 'fecha' => $fecha->format('Y-m-d') ]; $estado = model(EstadoCierre::class)->create($data); $estado->save(); }); } public function addUnidad(array $data) { $data['cierre'] = $this->id; $unidad = model(UnidadCierre::class)->create($data); $unidad->save(); } public function addValor(array $data) { $data['cierre'] = $this->id; $tipo = model(TipoValorCierre::class)->where('descripcion', $data['tipo'])->findOne(); $data['tipo'] = $tipo->id; $valor = model(ValorCierre::class)->create($data); $valor->save(); } public static function evaluar($precio_neto, $unidad, $fecha, $relacionado = false) { $precio_oferta = round($precio_neto, 2); $precio_lista = round($unidad->precio($fecha)->valor * (($relacionado) ? (1 - 0.06) : 1), 2); if ($precio_oferta >= $precio_lista) { return true; } return false; } public function guardar(object $input) { $this->proyecto = $input->proyecto->id; $this->precio = $input->precio; $this->fecha = $input->fecha->format('Y-m-d'); $this->relacionado = 0; if (isset($input->relacionado) and $input->relacionado) { $this->relacionado = 1; } if (isset($input->subrelacionado) and $input->subrelacionado) { $this->relacionado = 2; } $fecha = Carbon::today(config('app.timezone')); $this->new($fecha); $data = [ 'unidad' => $input->departamento->id, 'principal' => 1 ]; $this->addUnidad($data); foreach ($input->unidades as $unidad) { $data = ['unidad' => $unidad->id]; $this->addUnidad($data); } if (isset($input->pie)) { $data = [ 'tipo' => 'pie', 'valor' => $input->pie ]; $this->addValor($data); } if (isset($input->bono)) { $data = [ 'tipo' => 'bono pie', 'valor' => $input->bono ]; $this->addValor($data); } if (isset($input->promocion)) { $data = [ 'tipo' => 'premio', 'valor' => $input->promocion ]; $this->addValor($data); } if (isset($input->operador)) { $data = [ 'tipo' => 'operador', 'valor' => $input->operador * $this->precio / 100 ]; $this->addValor($data); } } public function aprobar(\DateTime $fecha) { $tipo = model(TipoEstadoCierre::class)->where('descripcion', 'aprobado')->findOne(); $data = [ 'cierre' => $this->id, 'tipo' => $tipo->id ]; $estado = (new Factory(EstadoCierre::class))->where($data)->find(); if (!$estado) { $data['fecha'] = $fecha->format('Y-m-d'); $estado = model(EstadoCierre::class)->create($data); $estado->save(); } } public function rechazar(\DateTime $fecha) { $tipo = model(TipoEstadoCierre::class)->where('descripcion', 'rechazado')->findOne(); $data = [ 'cierre' => $this->id, 'tipo' => $tipo->id ]; $estado = (new Factory(EstadoCierre::class))->where($data)->find(); if (!$estado) { $data['fecha'] = $fecha->format('Y-m-d'); $estado = model(EstadoCierre::class)->create($data); $estado->save(); } } protected $promesa; public function promesa() { if ($this->promesa == null) { $propiedad = model(Propiedad::class)->where('unidad_principal', $this->unidadPrincipal()->unidad)->findOne(); if (!$propiedad) { return false; } $this->promesa = model(Venta::class)->where('propiedad', $propiedad->id)->where('estado', 1)->findOne(); if ($this->promesa != null and $this->propietario == 0) { $this->propietario = $this->promesa->propietario; $this->save(); } } return $this->promesa; } public function isRelacionado() { return ($this->relacionado == 1) ? true : false; } public function isSubrelacionado() { return ($this->relacionado == 2) ? true : false; } public function periodo() { $today = Carbon::today(config('app.timezone')); $dif = $today->diffInDays($this->fecha()); return $dif; } }