Optimizacion de queries a cargar de una sola vez
This commit is contained in:
@ -168,19 +168,11 @@ class Contracts
|
||||
if (is_string($unit_ids)) {
|
||||
$unit_ids = json_decode($input['unidad_ids'], true);
|
||||
}
|
||||
foreach ($unit_ids as $unit_id) {
|
||||
try {
|
||||
$unit = $unitRepository->fetchById($unit_id);
|
||||
$contractService->getById($contract_id);
|
||||
$promotions = $promotionRepository->fetchByContractAndUnit($contract_id, $unit->id);
|
||||
$output['unidades'] []= [
|
||||
'id' => $unit->id,
|
||||
'promotions' => $promotions
|
||||
];
|
||||
} catch (ServiceAction\Read | Implement\Exception\EmptyResult $exception) {
|
||||
$output['unidades'] = $promotionRepository->fetchByContractAndUnits($contract_id, $unit_ids);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
$logger->debug($exception);
|
||||
}
|
||||
}
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
}
|
||||
|
@ -34,14 +34,7 @@ class Unidades extends Ideal\Controller
|
||||
}
|
||||
try {
|
||||
$proyecto = $proyectoService->getById($proyecto_id);
|
||||
foreach ($unidad_ids as $unidad_id) {
|
||||
try {
|
||||
$output['precios'][] = [
|
||||
'id' => $unidad_id,
|
||||
'precio' => $precioRepository->fetchVigenteByUnidad((int) $unidad_id)
|
||||
];
|
||||
} catch (Implement\Exception\EmptyResult) {}
|
||||
}
|
||||
$output['precios'] = $precioRepository->fetchVigentesByUnidades($unidad_ids);
|
||||
} catch (Implement\Exception\EmptyResult) {}
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
@ -62,21 +55,7 @@ class Unidades extends Ideal\Controller
|
||||
}
|
||||
try {
|
||||
$proyecto = $proyectoService->getById($proyecto_id);
|
||||
foreach ($unidad_ids as $unidad_id) {
|
||||
$output['estados'][] = [
|
||||
'id' => $unidad_id,
|
||||
'sold' => false
|
||||
];
|
||||
try {
|
||||
$unidad = $unidadRepository->fetchById($unidad_id);
|
||||
try {
|
||||
$output['estados'][] = [
|
||||
'id' => $unidad_id,
|
||||
'sold' => $unidadRepository->fetchSoldByUnidad($unidad->id)
|
||||
];
|
||||
} catch (Implement\Exception\EmptyResult) {}
|
||||
} catch (Implement\Exception\EmptyResult) {}
|
||||
}
|
||||
$output['estados'] = $unidadRepository->fetchSoldByUnidades($unidad_ids);
|
||||
} catch (Implement\Exception\EmptyResult) {}
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
|
@ -377,15 +377,9 @@ class Ventas extends Controller
|
||||
'input' => $input,
|
||||
'ventas' => []
|
||||
];
|
||||
foreach ($input['unidad_ids'] as $unidad_id) {
|
||||
try {
|
||||
$venta = $ventaService->getByUnidadId($unidad_id);
|
||||
$output['ventas'][] = [
|
||||
'unidad_id' => $unidad_id,
|
||||
'venta' => $venta
|
||||
];
|
||||
$output['ventas'] = $ventaService->getActiveByUnidadIds($input['unidad_ids']);
|
||||
} catch (Read) {}
|
||||
}
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
}
|
||||
|
@ -296,16 +296,65 @@ class Venta extends Ideal\Repository
|
||||
* @return Model\Venta
|
||||
* @throws Implement\Exception\EmptyResult
|
||||
*/
|
||||
public function fetchByUnidadId(int $unidad_id): Model\Venta
|
||||
public function fetchActiveByUnidadId(int $unidad_id): Model\Venta
|
||||
{
|
||||
$subSubQuery = $this->connection->getQueryBuilder()
|
||||
->select('MAX(`id`) AS `id`, `venta`')
|
||||
->from('`estado_venta`')
|
||||
->group('`venta`');
|
||||
$subQuery = $this->connection->getQueryBuilder()
|
||||
->select('e1.*')
|
||||
->from('`estado_venta` e1')
|
||||
->joined("INNER JOIN ({$subSubQuery}) e0 ON e0.`id` = e1.`id`");
|
||||
$query = $this->connection->getQueryBuilder()
|
||||
->select('a.*')
|
||||
->from("{$this->getTable()} a")
|
||||
->joined('JOIN propiedad_unidad pu ON pu.propiedad = a.propiedad')
|
||||
->where('pu.unidad = ?');
|
||||
->joined('INNER JOIN propiedad_unidad pu ON pu.propiedad = a.propiedad')
|
||||
->joined("INNER JOIN ({$subQuery}) ev ON ev.`venta` = a.`id`")
|
||||
->joined('INNER JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`')
|
||||
->where('pu.unidad = ? AND tev.activa = 1');
|
||||
return $this->fetchOne($query, [$unidad_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $unidad_ids
|
||||
* @return array
|
||||
* @throws Implement\Exception\EmptyResult
|
||||
*/
|
||||
public function fetchActiveByUnidadIds(array $unidad_ids): array
|
||||
{
|
||||
$subSubQuery = $this->connection->getQueryBuilder()
|
||||
->select('MAX(`id`) AS `id`, `venta`')
|
||||
->from('`estado_venta`')
|
||||
->group('`venta`');
|
||||
$subQuery = $this->connection->getQueryBuilder()
|
||||
->select('e1.*')
|
||||
->from('`estado_venta` e1')
|
||||
->joined("INNER JOIN ({$subSubQuery}) e0 ON e0.`id` = e1.`id`");
|
||||
$interrogations = implode(',', array_fill(0, count($unidad_ids), '?'));
|
||||
$query = $this->connection->getQueryBuilder()
|
||||
->select('a.*, pu.unidad')
|
||||
->from("{$this->getTable()} a")
|
||||
->joined('INNER JOIN propiedad_unidad pu ON pu.propiedad = a.propiedad')
|
||||
->joined("INNER JOIN ({$subQuery}) ev ON ev.`venta` = a.`id`")
|
||||
->joined('INNER JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`')
|
||||
->where("pu.unidad IN ({$interrogations}) AND tev.activa = 1");
|
||||
try {
|
||||
$results = $this->connection->execute($query, $unidad_ids)->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (empty($results)) {
|
||||
throw new Implement\Exception\EmptyResult($query);
|
||||
}
|
||||
return array_map(function($result) {
|
||||
return [
|
||||
'unidad_id' => $result['unidad'],
|
||||
'venta' => $this->load($result)
|
||||
];
|
||||
}, $results);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Implement\Exception\EmptyResult($query, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $unidad
|
||||
* @param string $tipo
|
||||
|
@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace Incoviba\Repository\Venta;
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Define;
|
||||
use Incoviba\Common\Implement;
|
||||
@ -96,6 +98,36 @@ class Precio extends Ideal\Repository
|
||||
return $this->fetchOne($query, [$unidad_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $unidad_ids
|
||||
* @return array
|
||||
* @throws Implement\Exception\EmptyResult
|
||||
*/
|
||||
public function fetchVigentesByUnidades(array $unidad_ids): array
|
||||
{
|
||||
$interrogations = implode(',', array_fill(0, count($unidad_ids), '?'));
|
||||
$query = $this->connection->getQueryBuilder()
|
||||
->select('a.*, unidad')
|
||||
->from("{$this->getTable()} a")
|
||||
->joined($this->joinEstado())
|
||||
->joined('INNER JOIN tipo_estado_precio tep ON tep.`id` = ep.`estado`')
|
||||
->where("`unidad` IN ({$interrogations}) AND tep.`descripcion` = \"vigente\"");
|
||||
try {
|
||||
$results = $this->connection->execute($query, $unidad_ids)->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (empty($results)) {
|
||||
throw new Implement\Exception\EmptyResult($query);
|
||||
}
|
||||
return array_map(function($result) {
|
||||
return [
|
||||
'id' => $result['unidad'],
|
||||
'precio' => $this->load($result)
|
||||
];
|
||||
}, $results);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Implement\Exception\EmptyResult($query, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $unidad_id
|
||||
* @param string $date_time
|
||||
|
@ -243,6 +243,72 @@ class Promotion extends Common\Ideal\Repository
|
||||
return $this->fetchMany($query, ['contract_id' => $contract_id, 'unit_id' => $unit_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $contract_id
|
||||
* @param array $unit_ids
|
||||
* @return array
|
||||
* @throws Common\Implement\Exception\EmptyResult
|
||||
*/
|
||||
public function fetchByContractAndUnits(int $contract_id, array $unit_ids): array
|
||||
{
|
||||
$interrogations = implode(',', array_map(fn($k) => ":id{$k}", array_keys($unit_ids)));
|
||||
$query = $this->connection->getQueryBuilder()
|
||||
->select('DISTINCT a.*, GROUP_CONCAT(COALESCE(pu.unit_id, u1.id, u2.id, u3.id) SEPARATOR "|") as unit_id')
|
||||
->from("{$this->getTable()} a")
|
||||
->joined('LEFT OUTER JOIN promotion_brokers pb ON pb.promotion_id = a.id')
|
||||
->joined('LEFT OUTER JOIN broker_contracts bc ON bc.broker_rut = pb.broker_rut')
|
||||
->joined('LEFT OUTER JOIN promotion_units pu ON pu.promotion_id = a.id')
|
||||
->joined('LEFT OUTER JOIN promotion_projects pp ON pp.promotion_id = a.id')
|
||||
->joined('LEFT OUTER JOIN proyecto_tipo_unidad ptu1 ON ptu1.proyecto = pp.project_id')
|
||||
->joined('LEFT OUTER JOIN unidad u1 ON u1.pt = ptu1.id')
|
||||
->joined('LEFT OUTER JOIN promotion_unit_types put ON put.promotion_id = a.id')
|
||||
->joined('LEFT OUTER JOIN proyecto_tipo_unidad ptu2 ON ptu2.tipo = put.unit_type_id AND ptu2.proyecto = put.project_id')
|
||||
->joined('LEFT OUTER JOIN unidad u2 ON u2.pt = ptu2.id')
|
||||
->joined('LEFT OUTER JOIN promotion_unit_lines pul ON pul.promotion_id = a.id')
|
||||
->joined('LEFT OUTER JOIN proyecto_tipo_unidad ptu3 ON ptu3.id = pul.unit_line_id')
|
||||
->joined('LEFT OUTER JOIN unidad u3 ON u3.pt = ptu3.id')
|
||||
->where("bc.id = :contract_id OR pu.unit_id IN ({$interrogations}) OR u1.id IN ({$interrogations}) OR u2.id IN ({$interrogations}) OR u3.id IN ({$interrogations})")
|
||||
->group('a.id');
|
||||
$unitParams = array_combine(array_map(fn($k) => "id{$k}", array_keys($unit_ids)), $unit_ids);
|
||||
try {
|
||||
$results = $this->connection->execute($query, array_merge(['contract_id' => $contract_id], $unitParams))->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (empty($results)) {
|
||||
throw new Common\Implement\Exception\EmptyResult($query);
|
||||
}
|
||||
$temp = new class()
|
||||
{
|
||||
protected array $promotions = [];
|
||||
public function addItem(int $id, Model\Venta\Promotion $promotion): void
|
||||
{
|
||||
if (!array_key_exists($id, $this->promotions)) {
|
||||
$this->promotions[$id] = [
|
||||
'id' => $id,
|
||||
'promotions' => []
|
||||
];
|
||||
}
|
||||
$this->promotions[$id]['promotions'] []= $promotion;
|
||||
}
|
||||
public function toArray(): array
|
||||
{
|
||||
return array_values($this->promotions);
|
||||
}
|
||||
};
|
||||
foreach ($results as $result) {
|
||||
if (str_contains($result['unit_id'], '|')) {
|
||||
$ids = explode('|', $result['unit_id']);
|
||||
foreach ($ids as $id) {
|
||||
$temp->addItem((int) $id, $this->load($result));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$temp->addItem((int) $result['unit_id'], $this->load($result));
|
||||
}
|
||||
return $temp->toArray();
|
||||
} catch (PDOException $exception) {
|
||||
throw new Common\Implement\Exception\EmptyResult($query, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model\Venta\Promotion $promotion
|
||||
* @param int $project_id
|
||||
|
@ -204,6 +204,44 @@ class Unidad extends Ideal\Repository
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $unidad_ids
|
||||
* @return array
|
||||
* @throws Implement\Exception\EmptyResult
|
||||
*/
|
||||
public function fetchSoldByUnidades(array $unidad_ids): array
|
||||
{
|
||||
$interrogations = implode(',', array_fill(0, count($unidad_ids), '?'));
|
||||
$query = $this->connection->getQueryBuilder()
|
||||
->select('a.id')
|
||||
->from("{$this->getTable()} a")
|
||||
->joined('INNER JOIN `propiedad_unidad` pu ON pu.`unidad` = a.`id`')
|
||||
->joined('INNER JOIN `venta` ON `venta`.`propiedad` = `pu`.`propiedad`')
|
||||
->joined($this->joinEstadoVenta(true))
|
||||
->joined('INNER JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`')
|
||||
->where("a.id IN ({$interrogations}) AND tev.activa = 1");
|
||||
try {
|
||||
$results = $this->connection->execute($query, $unidad_ids)->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (empty($results)) {
|
||||
throw new Implement\Exception\EmptyResult($query);
|
||||
}
|
||||
$missing = array_diff(array_map(fn($id) => (int) $id, $unidad_ids), array_column($results, 'id'));
|
||||
return [...array_map(function($result) {
|
||||
return [
|
||||
'id' => $result['id'],
|
||||
'sold' => true
|
||||
];
|
||||
}, $results), ...array_map(function($id) {
|
||||
return [
|
||||
'id' => $id,
|
||||
'sold' => false
|
||||
];
|
||||
}, $missing)];
|
||||
} catch (PDOException $exception) {
|
||||
throw new Implement\Exception\EmptyResult($query, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $promotion_id
|
||||
* @return array
|
||||
@ -239,16 +277,17 @@ class Unidad extends Ideal\Repository
|
||||
{
|
||||
return "LEFT OUTER JOIN unidad_prorrateo up ON up.unidad_id = a.id";
|
||||
}
|
||||
protected function joinEstadoVenta(): string
|
||||
protected function joinEstadoVenta(bool $inner = false): string
|
||||
{
|
||||
$subSubQuery = $this->connection->getQueryBuilder()
|
||||
->select('MAX(id) AS id, venta')
|
||||
->from('estado_venta')
|
||||
->group('venta');
|
||||
$join = $inner ? 'INNER' : 'LEFT OUTER';
|
||||
$subQuery = $this->connection->getQueryBuilder()
|
||||
->select('ev1.*')
|
||||
->from('estado_venta ev1')
|
||||
->joined("LEFT OUTER JOIN ($subSubQuery) ev0 ON ev0.id = ev1.id");
|
||||
return "LEFT OUTER JOIN ({$subQuery}) ev ON ev.`venta` = `venta`.`id`";
|
||||
->joined("{$join} JOIN ($subSubQuery) ev0 ON ev0.id = ev1.id");
|
||||
return "{$join} JOIN ({$subQuery}) ev ON ev.`venta` = `venta`.`id`";
|
||||
}
|
||||
}
|
||||
|
@ -91,10 +91,30 @@ class Venta extends Service
|
||||
* @return Model\Venta
|
||||
* @throws Read
|
||||
*/
|
||||
public function getByUnidadId(int $unidad_id): Model\Venta
|
||||
public function getActiveByUnidadId(int $unidad_id): Model\Venta
|
||||
{
|
||||
try {
|
||||
return $this->process($this->ventaRepository->fetchByUnidadId($unidad_id));
|
||||
return $this->process($this->ventaRepository->fetchActiveByUnidadId($unidad_id));
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Read(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $unidad_ids
|
||||
* @return array
|
||||
* @throws Read
|
||||
*/
|
||||
public function getActiveByUnidadIds(array $unidad_ids): array
|
||||
{
|
||||
try {
|
||||
$ventas = $this->ventaRepository->fetchActiveByUnidadIds($unidad_ids);
|
||||
return array_map(function($data) {
|
||||
return [
|
||||
'unidad_id' => $data['unidad_id'],
|
||||
'venta' => $this->process($data['venta'])
|
||||
];
|
||||
}, $ventas);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Read(__CLASS__, $exception);
|
||||
}
|
||||
|
Reference in New Issue
Block a user