358 lines
11 KiB
PHP
358 lines
11 KiB
PHP
<?php
|
|
namespace Incoviba\old\Venta;
|
|
|
|
use Carbon\Carbon;
|
|
use Incoviba\Common\Factory\Model as Factory;
|
|
use Incoviba\Common\Alias\OldModel as Model;
|
|
use Incoviba\old\Proyecto\Proyecto;
|
|
|
|
/**
|
|
* @property int $id
|
|
* @property Proyecto $proyecto
|
|
* @property float $precio
|
|
* @property \DateTime $fecha
|
|
* @property int $relacionado
|
|
* @property Propietario $propietario
|
|
*/
|
|
class Cierre extends Model
|
|
{
|
|
const VIGENTES = 1;
|
|
const NO_VIGENTES = -1;
|
|
public static function find(Proyecto $proyecto, Unidad $unidad, float $precio)
|
|
{
|
|
return model(Cierre::class)
|
|
->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, $this->container->get('settings')->app->timezone);//, 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();
|
|
}
|
|
}
|
|
public function abandonar(\DateTime $fecha) {
|
|
$tipo = model(TipoEstadoCierre::class)->where('descripcion', 'abandonado')->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->setContainer($this->container);
|
|
$estado->save();
|
|
}
|
|
}
|
|
protected $promesa;
|
|
public function promesa()
|
|
{
|
|
if (!$this->unidadPrincipal()) {
|
|
$this->promesa = false;
|
|
}
|
|
if ($this->promesa === null) {
|
|
$propiedad = model(Propiedad::class)->where('unidad_principal', $this->unidadPrincipal()->unidad)->findOne();
|
|
if (!$propiedad) {
|
|
$this->promesa = false;
|
|
return $this->promesa;
|
|
}
|
|
$this->promesa = model(Venta::class)->where('propiedad', $propiedad->id)->where('estado', 1)->findOne();
|
|
if (!$this->promesa) {
|
|
$this->promesa = false;
|
|
return $this->promesa;
|
|
}
|
|
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;
|
|
}
|
|
}
|