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