Files
modelos/src/old/Venta/Cierre.php
2019-12-23 18:15:02 -03:00

336 lines
9.9 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, 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;
}
}