Files
oficial/app/src/Repository/Venta.php
Juan Pablo Vial 8f16f33a1e Cleanup
2025-03-03 14:57:22 -03:00

584 lines
25 KiB
PHP

<?php
namespace Incoviba\Repository;
use PDO;
use PDOException;
use Psr\Log\LoggerInterface;
use Incoviba\Common\Ideal;
use Incoviba\Common\Define;
use Incoviba\Common\Implement;
use Incoviba\Model;
use Incoviba\Service;
class Venta extends Ideal\Repository
{
public function __construct(
Define\Connection $connection,
protected LoggerInterface $logger,
protected Venta\Propietario $propietarioRepository,
protected Venta\Propiedad $propiedadRepository,
protected Service\Venta\Pie $pieService,
protected Venta\BonoPie $bonoPieRepository,
protected Venta\Credito $creditoRepository,
protected Venta\Escritura $escrituraRepository,
protected Venta\Subsidio $subsidioRepository,
protected Venta\Entrega $entregaRepository,
protected Service\Venta\Pago $pagoService
)
{
parent::__construct($connection);
$this->setTable('venta');
}
public function create(?array $data = null): Model\Venta
{
$map = (new Implement\Repository\MapperParser(['uf']))
->register('propietario', (new Implement\Repository\Mapper())
->setFactory((new Implement\Repository\Factory())
->setCallable([$this->propietarioRepository, 'fetchById'])
->setArgs([$data['propietario']])))
->register('propiedad', (new Implement\Repository\Mapper())
->setFactory((new Implement\Repository\Factory())
->setCallable([$this->propiedadRepository, 'fetchById'])
->setArgs([$data['propiedad']])))
/*->register('pie', (new Implement\Repository\Mapper())
->setProperty('formaPago')
->setFactory((new Implement\Repository\Factory())
->setCallable(function($repositories, $data) {
$fp = new Model\Venta\FormaPago();
$map = [
'pie' => [
'service' => $repositories->pieService
],
'bono_pie' => [
'property' => 'bonoPie',
'repository' => $repositories->bonoPieRepository
],
'credito' => [
'repository' => $repositories->creditoRepository
],
'escritura' => [
'repository' => $repositories->escrituraRepository
],
'subsidio' => [
'repository' => $repositories->subsidioRepository
],
'devolucion' => [
'service' => $repositories->pagoService
]
];
foreach ($map as $column => $settings) {
if (isset($data[$column]) and $data[$column] !== 0) {
if (isset($settings['repository'])) {
$fp->{$settings['property'] ?? $column} = $settings['repository']->fetchById($data[$column]);
continue;
}
$fp->{$settings['property'] ?? $column} = $settings['service']->getById($data[$column]);
continue;
}
$fp->{$settings['property'] ?? $column} = null;
}
return $fp;
})
->setArgs([(object) [
'pieService' => $this->pieService,
'bonoPieRepository' => $this->bonoPieRepository,
'creditoRepository' => $this->creditoRepository,
'escrituraRepository' => $this->escrituraRepository,
'subsidioRepository' => $this->subsidioRepository,
'pagoService' => $this->pagoService
], $data])))*/
/*->register('escriturado', (new Implement\Repository\Mapper())
->setFunction(function($data) {
return $data['escritura'] !== null;
}))*/
/*->register('entrega', (new Implement\Repository\Mapper())
->setFactory((new Implement\Repository\Factory())
->setCallable(function($entrega_id) {
if ($entrega_id !== null and $entrega_id !== 0) {
return $this->entregaRepository->fetchById($entrega_id);
}
return null;
})
->setArgs([$data['entrega']]))
->setDefault(null))*/
/*->register('entregado', (new Implement\Repository\Mapper())
->setFactory((new Implement\Repository\Factory())
->setCallable(function($entrega_id) {
if ($entrega_id !== null and $entrega_id !== 0) {
return $entrega_id != null;
}
return false;
})
->setArgs([$data['entrega']])))*/
->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'))
->register('valor_uf', (new Implement\Repository\Mapper())
->setProperty('valor'))
//->register('estado')
->register('fecha_ingreso', new Implement\Repository\Mapper\DateTime('fecha_ingreso', 'fechaIngreso'))
//->register('avalchile')
//->register('agente')
->register('relacionado', new Implement\Repository\Mapper\Boolean('relacionado'));
//->register('promocion')
//->register('devolucion');
if (array_key_exists('resciliacion', $data)) {
$map = $map->register('resciliacion', (new Implement\Repository\Mapper())
->setFactory((new Implement\Repository\Factory())
->setCallable([$this->pagoService, 'getById'])
->setArgs(['pago_id' => $data['resciliacion']])));
}
return $this->parseData(new Model\Venta(), $data, $map);
}
/**
* @param Define\Model $model
* @return Model\Venta
* @throws PDOException
*/
public function save(Define\Model $model): Model\Venta
{
$model->id = $this->saveNew(
['propietario', 'propiedad', 'pie', 'bono_pie', 'credito', 'escritura', 'subsidio', 'escriturado',
'entrega', 'entregado', 'fecha', 'valor_uf', 'estado', 'fecha_ingreso', 'avalchile', 'agente', 'uf',
'relacionado', 'promocion', 'resciliacion', 'devolucion'],
[$model->propietario()->rut, $model->propiedad()->id, $model->formaPago()?->pie?->id, $model->formaPago()?->bonoPie?->id,
$model->formaPago()?->credito?->id, $model->formaPago()?->escritura?->id, $model->formaPago()?->subsidio?->id,
$model->formaPago()?->escritura !== null ? $model->formaPago()?->escritura->pago->fecha->format('Y-m-d') : null,
null, null, $model->fecha->format('Y-m-d'), $model->valor, 1, $model->fechaIngreso->format('Y-m-d'),
null, null, $model->uf, $model->relacionado ? 1 : 0, null, null, null]
);
return $model;
}
/**
* @param Define\Model $model
* @param array $new_data
* @return Model\Venta
* @throws Implement\Exception\EmptyResult
*/
public function edit(Define\Model $model, array $new_data): Model\Venta
{
return $this->update($model, ['propietario', 'propiedad', 'pie', 'bono_pie', 'credito', 'escritura', 'subsidio', 'escriturado',
'entrega', 'entregado', 'fecha', 'valor_uf', 'estado', 'fecha_ingreso', 'avalchile', 'agente', 'uf',
'relacionado', 'promocion', 'resciliacion', 'devolucion'], $new_data);
}
/**
* @param int $proyecto_id
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchByProyecto(int $proyecto_id): array
{
$query = $this->connection->getQueryBuilder()
->select('a.*')
->from("{$this->getTable()} a")
->joined('JOIN propiedad_unidad pu ON pu.propiedad = a.propiedad')
->joined('JOIN unidad ON unidad.id = pu.unidad AND pu.principal = 1')
->joined('JOIN proyecto_tipo_unidad ptu ON ptu.id = unidad.pt')
->joined('JOIN (SELECT ev1.* FROM estado_venta ev1 JOIN (SELECT MAX(id) AS id, venta FROM estado_venta GROUP BY venta) ev0 ON ev0.id = ev1.id) ev ON ev.venta = a.id')
->joined('JOIN tipo_estado_venta tev ON tev.id = ev.estado')
->where('ptu.proyecto = ? AND tev.activa')
->group('a.id');
return $this->fetchMany($query, [$proyecto_id]);
}
/**
* @param int $proyecto_id
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchIdsByProyecto(int $proyecto_id): array
{
$query = $this->connection->getQueryBuilder()
->select('a.id')
->from("{$this->getTable()} a")
->joined('JOIN propiedad_unidad pu ON pu.propiedad = a.propiedad')
->joined('JOIN unidad ON unidad.id = pu.unidad AND unidad.pt')
->joined('JOIN proyecto_tipo_unidad ptu ON ptu.id = unidad.pt')
->joined('JOIN (SELECT ev1.* FROM estado_venta ev1 JOIN (SELECT MAX(id) AS id, venta FROM estado_venta GROUP BY venta) ev0 ON ev0.id = ev1.id) ev ON ev.venta = a.id')
->joined('JOIN tipo_estado_venta tev ON tev.id = ev.estado')
->where('ptu.proyecto = ? AND tev.activa = 1')
->group('a.id');
return $this->fetchIds($query, [$proyecto_id]);
}
/**
* @param int $proyecto_id
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchActivaByProyecto(int $proyecto_id): array
{
$query = $this->connection->getQueryBuilder()
->select('a.*')
->from("{$this->getTable()} a")
->joined('JOIN `propiedad_unidad` pu ON pu.`propiedad` = a.`propiedad`')
->joined('JOIN `unidad` ON `unidad`.`id` = pu.`unidad` AND pu.`principal` = 1')
->joined('JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`')
->joined("JOIN (SELECT e1.* FROM `estado_venta` e1 JOIN (SELECT MAX(`id`) AS 'id', `venta` FROM `estado_venta` GROUP BY `venta`) e0 ON e0.`id` = e1.`id`) ev ON ev.`venta` = a.`id`")
->joined('JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`')
->where('ptu.`proyecto` = ? AND tev.`activa` = 1')
->group('a.id');
return $this->fetchMany($query, [$proyecto_id]);
}
/**
* @param string $proyecto_nombre
* @param int $unidad_descripcion
* @return Model\Venta
* @throws Implement\Exception\EmptyResult
*/
public function fetchByProyectoAndUnidad(string $proyecto_nombre, int $unidad_descripcion): Model\Venta
{
$query = $this->connection->getQueryBuilder()
->select("a.*")
->from("`{$this->getTable()}` a")
->joined('JOIN `propiedad_unidad` pu ON pu.`propiedad` = a.`propiedad`')
->joined('JOIN `unidad` ON `unidad`.`id` = pu.`unidad` AND pu.`principal` = 1')
->joined('JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`')
->joined('JOIN `proyecto` ON `proyecto`.`id` = ptu.`proyecto`')
->joined("JOIN (SELECT e1.* FROM `estado_venta` e1 JOIN (SELECT MAX(`id`) AS 'id', `venta` FROM `estado_venta` GROUP BY `venta`) e0 ON e0.`id` = e1.`id`) ev ON ev.`venta` = a.`id`")
->joined('JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`')
->where('`proyecto`.`descripcion` = ? AND `unidad`.`descripcion` = ? AND tev.`activa`');
return $this->fetchOne($query, [$proyecto_nombre, $unidad_descripcion]);
}
/**
* @param int $pie_id
* @return Model\Venta
* @throws Implement\Exception\EmptyResult
*/
public function fetchByPie(int $pie_id): Model\Venta
{
$query = $this->connection->getQueryBuilder()
->select()
->from($this->getTable())
->where('pie = ?');
return $this->fetchOne($query, [$pie_id]);
}
/**
* @param int $pie_id
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchIdByPie(int $pie_id): array
{
$query = $this->connection->getQueryBuilder()
->select('id')
->from($this->getTable())
->where('pie = ?');
return $this->fetchId($query, [$pie_id]);
}
/**
* @param string $unidad
* @param string $tipo
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchByUnidad(string $unidad, string $tipo): array
{
$query = $this->connection->getQueryBuilder()
->select('a.*')
->from("{$this->getTable()} a")
->joined('JOIN `propiedad_unidad` pu ON pu.`propiedad` = a.`propiedad`')
->joined('JOIN `unidad` ON `unidad`.`id` = pu.`unidad`')
->joined('JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`')
->joined('JOIN `tipo_unidad` tu ON tu.`id` = ptu.`tipo`')
->where('`unidad`.`descripcion` LIKE ? AND tu.`descripcion` = ?');
return $this->fetchMany($query, [$unidad, $tipo]);
}
/**
* @param int $unidad_id
* @return Model\Venta
* @throws Implement\Exception\EmptyResult
*/
public function fetchByUnidadId(int $unidad_id): Model\Venta
{
$query = $this->connection->getQueryBuilder()
->select('a.*')
->from("{$this->getTable()} a")
->joined('JOIN propiedad_unidad pu ON pu.propiedad = a.propiedad')
->where('pu.unidad = ?');
return $this->fetchOne($query, [$unidad_id]);
}
/**
* @param string $unidad
* @param string $tipo
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchIdsByUnidad(string $unidad, string $tipo): array
{
$query = $this->connection->getQueryBuilder()
->select('a.id')
->from("{$this->getTable()} a")
->joined('JOIN `propiedad_unidad` pu ON pu.`propiedad` = a.`propiedad`')
->joined('JOIN `unidad` ON `unidad`.`id` = pu.`unidad`')
->joined('JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`')
->joined('JOIN `tipo_unidad` tu ON tu.`id` = ptu.`tipo`')
->where('`unidad`.`descripcion` LIKE ? AND tu.`descripcion` = ?');
return $this->fetchIds($query, [$unidad, $tipo]);
}
/**
* @param string $precio
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchByPrecio(string $precio): array
{
$query = $this->connection->getQueryBuilder()
->select()
->from($this->getTable())
->where('valor_uf = ?');
return $this->fetchMany($query, [$precio]);
}
/**
* @param string $precio
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchIdsByPrecio(string $precio): array
{
$query = $this->connection->getQueryBuilder()
->select('id')
->from($this->getTable())
->where('valor_uf = ?');
return $this->fetchIds($query, [$precio]);
}
/**
* @param int $propietario_rut
* @param int $propiedad_id
* @return Model\Venta
* @throws Implement\Exception\EmptyResult
*/
public function fetchByPropietarioAndPropiedad(int $propietario_rut, int $propiedad_id): Model\Venta
{
$query = $this->connection->getQueryBuilder()
->select()
->from($this->getTable())
->where('propietario = ? AND propiedad = ?');
return $this->fetchOne($query, [$propietario_rut, $propiedad_id]);
}
/**
* @param string $propietario
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchByPropietario(string $propietario): array
{
$query = $this->connection->getQueryBuilder()
->select('a.*')
->from("{$this->getTable()} a")
->joined('JOIN `propietario` ON `propietario`.`rut` = a.`propietario`')
->where("CONCAT_WS('-', `propietario`.`rut`, `propietario`.`dv`) LIKE :propietario OR `propietario`.`nombres` LIKE :propietario
OR `propietario`.`apellido_paterno` LIKE :propietario OR `propietario`.`apellido_materno` LIKE :propietario
OR CONCAT_WS(' ', `propietario`.`nombres`, `propietario`.`apellido_paterno`, `propietario`.`apellido_materno`) LIKE :propietario");
return $this->fetchMany($query, [':propietario' => "%{$propietario}%"]);
}
/**
* @param string $propietario
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchIdsByPropietario(string $propietario): array
{
$query = $this->connection->getQueryBuilder()
->select('a.id')
->from("{$this->getTable()} a")
->joined('JOIN `propietario` ON `propietario`.`rut` = a.`propietario`')
->where("CONCAT_WS('-', `propietario`.`rut`, `propietario`.`dv`) LIKE :propietario OR `propietario`.`nombres` LIKE :propietario
OR `propietario`.`apellido_paterno` LIKE :propietario OR `propietario`.`apellido_materno` LIKE :propietario
OR CONCAT_WS(' ', `propietario`.`nombres`, `propietario`.`apellido_paterno`, `propietario`.`apellido_materno`) LIKE :propietario
OR rut = :rut
OR CONCAT_WS('-', rut, dv) = :rut");
return $this->fetchIds($query, [':propietario' => "%{$propietario}%", ':rut' => $propietario]);
}
/**
* @param string $propietario
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchByPropietarioNombreCompleto(string $propietario): array
{
$query = $this->connection->getQueryBuilder()
->select('a.*')
->from("{$this->getTable()} a")
->joined('JOIN `propietario` ON `propietario`.`rut` = a.`propietario`')
->where("CONCAT_WS(' ', `propietario`.`nombres`, `propietario`.`apellido_paterno`, `propietario`.`apellido_materno`) LIKE ?");
return $this->fetchMany($query, [$propietario]);
}
/**
* @param int $proyecto_id
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchEscriturasByProyecto(int $proyecto_id): array
{
$query = $this->connection->getQueryBuilder()
->select('DISTINCT a.*')
->from("{$this->getTable()} a")
->joined('JOIN `propiedad_unidad` pu ON pu.`propiedad` = a.`propiedad`')
->joined('JOIN `unidad` ON `unidad`.`id` = pu.`unidad`')
->joined('JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`id`')
->joined("JOIN (SELECT e1.* FROM `estado_venta` e1 JOIN (SELECT MAX(`id`) AS 'id', `venta` FROM `estado_venta` GROUP BY `venta`) e0 ON e0.`id` = e1.`id`) ev ON ev.`venta` = a.`id`")
->joined('JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`')
->where("ptu.`proyecto` = ? AND tev.`descripcion` IN ('firmado por inmobiliaria', 'escriturando')")
->group('a.id');
return $this->fetchMany($query, [$proyecto_id]);
}
/**
* @param int $escritura_id
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchIdByEscritura(int $escritura_id): array
{
$query = $this->connection->getQueryBuilder()
->select('id')
->from($this->getTable())
->where('escritura = ?');
return $this->fetchId($query, [$escritura_id]);
}
/**
* @param int $subsidio_id
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchIdBySubsidio(int $subsidio_id): array
{
$query = $this->connection->getQueryBuilder()
->select('id')
->from($this->getTable())
->where('subsidio = ?');
return $this->fetchId($query, [$subsidio_id]);
}
/**
* @param int $credito_id
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchIdByCredito(int $credito_id): array
{
$query = $this->connection->getQueryBuilder()
->select('id')
->from($this->getTable())
->where('credito = ?');
return $this->fetchId($query, [$credito_id]);
}
/**
* @param int $bono_id
* @return array
* @throws Implement\Exception\EmptyResult
*/
public function fetchIdByBono(int $bono_id): array
{
$query = $this->connection->getQueryBuilder()
->select('id')
->from($this->getTable())
->where('bono_pie = ?');
return $this->fetchId($query, [$bono_id]);
}
/**
* @param int $venta_id
* @return array
*/
public function fetchByIdForSearch(int $venta_id): array
{
$query = $this->connection->getQueryBuilder()
->select('venta.id AS id, venta.fecha AS fecha, venta.valor_uf AS valor')
->columns('proyecto.id AS proyecto_id, proyecto.descripcion AS proyecto_descripcion')
->columns('CONCAT_WS(" ", propietario.nombres, propietario.apellido_paterno, propietario.apellido_materno) AS propietario')
->columns('unidad.descripcion AS unidad_descripcion, tu.descripcion AS tipo_unidad_descripcion, ptu.m2 + ptu.logia + ptu.terraza AS superficie')
->columns('GROUP_CONCAT(CONCAT(UPPER(LEFT(tu.descripcion, 1)), unidad.descripcion) SEPARATOR " - ") AS tipologia')
->columns('tev.activa')
->from($this->getTable())
->joined('JOIN propietario ON propietario.rut = venta.propietario')
->joined('JOIN propiedad_unidad pu ON pu.propiedad = venta.propiedad')
->joined('JOIN unidad ON unidad.id = pu.unidad')
->joined('JOIN proyecto_tipo_unidad ptu ON unidad.pt = ptu.id')
->joined('JOIN proyecto ON proyecto.id = ptu.proyecto')
->joined('JOIN tipo_unidad tu ON tu.id = ptu.tipo')
->joined('JOIN (SELECT ev1.* FROM estado_venta ev1 JOIN (SELECT MAX(id) AS id, venta FROM estado_venta GROUP BY venta) ev0 ON ev0.id = ev1.id) ev ON ev.venta = venta.id')
->joined('JOIN tipo_estado_venta tev ON ev.estado = tev.id')
->where('venta.id = ?')
->order('tu.orden')
->order('LPAD(unidad.descripcion, 4, "0")')
->group('venta.id')
->limit(1);
return $this->connection->execute($query, [$venta_id])->fetch(PDO::FETCH_ASSOC);
}
/**
* @param int $venta_id
* @return array
*/
public function fetchByIdForList(int $venta_id): array
{
$query = $this->connection->getQueryBuilder()
->select('venta.id AS id, venta.fecha AS fecha, venta.valor_uf AS valor')
->columns('proyecto.id AS proyecto_id, proyecto.descripcion AS proyecto_descripcion')
->columns('CONCAT_WS(" ", propietario.nombres, propietario.apellido_paterno, propietario.apellido_materno) AS propietario')
->columns("GROUP_CONCAT(unidad.descripcion SEPARATOR ' - ') AS unidad_descripcion, tu.descripcion AS tipo_unidad_descripcion, ptu.m2 + ptu.logia + ptu.terraza AS superficie")
->columns('tev.activa')
->from($this->getTable())
->joined('JOIN propietario ON propietario.rut = venta.propietario')
->joined('JOIN propiedad_unidad pu ON pu.propiedad = venta.propiedad')
->joined('JOIN unidad ON unidad.id = pu.unidad')
->joined('JOIN proyecto_tipo_unidad ptu ON unidad.pt = ptu.id')
->joined('JOIN proyecto ON proyecto.id = ptu.proyecto')
->joined('JOIN tipo_unidad tu ON tu.id = ptu.tipo')
->joined('JOIN (SELECT ev1.* FROM estado_venta ev1 JOIN (SELECT MAX(id) AS id, venta FROM estado_venta GROUP BY venta) ev0 ON ev0.id = ev1.id) ev ON ev.venta = venta.id')
->joined('JOIN tipo_estado_venta tev ON ev.estado = tev.id')
->where('venta.id = ?')
->group('venta.id');
return $this->connection->execute($query, [$venta_id])->fetch(PDO::FETCH_ASSOC);
}
/**
* @param string $query
* @param array|null $data
* @return array
* @throws Implement\Exception\EmptyResult
*/
protected function fetchIds(string $query, ?array $data = null): array
{
try {
return $this->connection->execute($query, $data)->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $exception) {
throw new Implement\Exception\EmptyResult($query, $exception);
}
}
/**
* @param string $query
* @param array|null $data
* @return array
* @throws Implement\Exception\EmptyResult
*/
protected function fetchId(string $query, ?array $data = null): array
{
try {
return $this->connection->execute($query, $data)->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $exception) {
throw new Implement\Exception\EmptyResult($query, $exception);
}
}
}