Files
oficial/app/src/Service/Venta.php
Juan Pablo Vial 3141f1e7c4 Search
2023-09-28 21:05:16 -03:00

293 lines
9.6 KiB
PHP

<?php
namespace Incoviba\Service;
use DateTimeImmutable;
use Incoviba\Common\Implement;
use Incoviba\Repository;
use Incoviba\Model;
class Venta
{
public function __construct(
protected Repository\Venta $ventaRepository,
protected Repository\Venta\EstadoVenta $estadoVentaRepository,
protected Repository\Venta\TipoEstadoVenta $tipoEstadoVentaRepository,
protected Venta\Propietario $propietarioService,
protected Venta\Propiedad $propiedadService,
protected Venta\Pie $pieService,
protected Venta\Subsidio $subsidioService,
protected Venta\Credito $creditoService,
protected Venta\BonoPie $bonoPieService,
protected Money $moneyService
) {}
public function getById(int $venta_id): Model\Venta
{
return $this->process($this->ventaRepository->fetchById($venta_id));
}
public function getByProyecto(int $proyecto_id): array
{
$ventas = $this->ventaRepository->fetchByProyecto($proyecto_id);
foreach ($ventas as &$venta) {
$venta = $this->process($venta);
}
return $ventas;
}
public function getActivaByProyecto(int $proyecto_id): array
{
$ventas = $this->ventaRepository->fetchActivaByProyecto($proyecto_id);
foreach ($ventas as &$venta) {
$venta = $this->process($venta);
}
return $ventas;
}
public function getByProyectoAndUnidad(string $proyecto_nombre, int $unidad_descripcion): Model\Venta
{
$venta = $this->ventaRepository->fetchByProyectoAndUnidad($proyecto_nombre, $unidad_descripcion);
return $this->process($venta);
}
public function getByUnidad(string $unidad, string $tipo): array
{
$ventas = $this->ventaRepository->fetchByUnidad($unidad, $tipo);
foreach ($ventas as &$venta) {
$venta = $this->process($venta);
}
return $ventas;
}
public function getByPropietario(string $propietario): array
{
$ventas = $this->ventaRepository->fetchByPropietario($propietario);
foreach ($ventas as &$venta) {
$venta = $this->process($venta);
}
return $ventas;
}
public function getByPrecio(string $precio): array
{
$ventas = $this->ventaRepository->fetchByPrecio($precio);
foreach ($ventas as &$venta) {
$venta = $this->process($venta);
}
return $ventas;
}
protected function process(Model\Venta $venta): Model\Venta
{
$venta->addFactory('estados', (new Implement\Repository\Factory())->setCallable([$this->estadoVentaRepository, 'fetchByVenta'])->setArgs([$venta->id]));
$venta->addFactory('currentEstado', (new Implement\Repository\Factory())->setCallable([$this->estadoVentaRepository, 'fetchCurrentByVenta'])->setArgs([$venta->id]));
return $venta;
}
public function add(array $data): void
{
$fecha = new DateTimeImmutable($data['fecha_venta']);
$data['uf'] = $this->moneyService->getUF($fecha);
$propietario = $this->addPropietario($data);
$propiedad = $this->addPropiedad($data);
$forma_pago = $this->addFormaPago($data);
$venta_data = [
'propietario' => $propietario->rut,
'propiedad' => $propiedad->id,
'fecha' => $fecha->format('Y-m-d'),
'valor_uf' => $data['valor'],
'fecha_ingreso' => (new DateTimeImmutable())->format('Y-m-d'),
'uf' => $data['uf']
];
$map = ['pie', 'subsidio', 'credito', 'bono_pie'];
foreach ($map as $field) {
$name = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $field))));
if (isset($forma_pago->{$name})) {
$venta_data[$field] = $forma_pago->{$name}->id;
}
}
$venta = $this->ventaRepository->create($venta_data);
$venta = $this->ventaRepository->save($venta);
$tipoEstado = $this->tipoEstadoVentaRepository->fetchByDescripcion('vigente');
$estado = $this->estadoVentaRepository->create([
'venta' => $venta->id,
'estado' => $tipoEstado->id,
'fecha' => $venta->fecha->format('Y-m-d')
]);
$this->estadoVentaRepository->save($estado);
}
protected function addPropietario(array $data): Model\Venta\Propietario
{
if (isset($data['natural_uno'])) {
if (isset($data['natural_multiple'])) {
return $this->addDosPropietarios($data);
}
return $this->addUnPropietario($data);
}
return $this->addSociedad($data);
}
protected function addUnPropietario(array $data): Model\Venta\Propietario
{
$fields = array_fill_keys([
'rut',
'nombres',
'apellido_paterno',
'apellido_materno',
'calle',
'numero',
'extra',
'comuna'
], 0);
$filtered_data = array_intersect_key($data, $fields);
return $this->propietarioService->addPropietario($filtered_data);
}
protected function addDosPropietarios(array $data): Model\Venta\Propietario
{
$fields = array_fill_keys([
'rut_otro',
'nombres_otro',
'apellido_paterno_otro',
'apellido_materno_otro',
'calle_otro',
'numero_otro',
'extra_otro',
'comuna_otro'
], 0);
$filtered_data = array_intersect_key($data, $fields);
$mapped_data = array_combine([
'rut',
'nombres',
'apellido_paterno',
'apellido_materno',
'calle',
'numero',
'extra',
'comuna'
], $filtered_data);
$otro = $this->propietarioService->addPropietario($mapped_data);
$data['otro'] = $otro->rut;
$fields = array_fill_keys([
'rut',
'nombres',
'apellido_paterno',
'apellido_materno',
'calle',
'numero',
'extra',
'comuna',
'otro'
], 0);
$filtered_data = array_intersect_key($data, $fields);
return $this->propietarioService->addPropietario($filtered_data);
}
protected function addSociedad(array $data): Model\Venta\Propietario
{
$representante = $this->addUnPropietario($data);
$data['representante'] = $representante->rut;
$fields = array_fill_keys([
'rut_sociedad',
'razon_social',
'calle_comercial',
'numero_comercial',
'extra_comercial',
'comuna_comercial',
'representante'
], 0);
$filtered_data = array_intersect_key($data, $fields);
$mapped_data = array_combine([
'rut',
'razon_social',
'calle',
'numero',
'extra',
'comuna',
'representante'
], $filtered_data);
return $this->propietarioService->addSociedad($mapped_data);
}
protected function addPropiedad(array $data): Model\Venta\Propiedad
{
$ids = array_filter($data, function($key) {
return str_contains($key, 'unidad');
}, ARRAY_FILTER_USE_KEY);
return $this->propiedadService->addPropiedad($ids);
}
protected function addFormaPago(array $data): Model\Venta\FormaPago
{
$fields = [
'pie',
'subsidio',
'credito',
'bono_pie'
];
$forma_pago = new Model\Venta\FormaPago();
foreach ($fields as $name) {
if (isset($data["has_{$name}"])) {
$method = 'add' . str_replace(' ', '', ucwords(str_replace('_', ' ', $name)));
$obj = $this->{$method}($data);
$forma_pago->{$name} = $obj;
}
}
return $forma_pago;
}
protected function addPie(array $data): Model\Venta\Pie
{
$fields = array_fill_keys([
'fecha_venta',
'pie',
'cuotas',
'uf'
], 0);
$filtered_data = array_intersect_key($data, $fields);
$mapped_data = array_combine([
'fecha',
'valor',
'cuotas',
'uf'
], $filtered_data);
return $this->pieService->add($mapped_data);
}
protected function addSubsidio(array $data): Model\Venta\Subsidio
{
$fields = array_fill_keys([
'fecha_venta',
'ahorro',
'subsidio',
'uf'
], 0);
$filtered_data = array_intersect_key($data, $fields);
$mapped_data = array_combine([
'fecha',
'ahorro',
'subsidio',
'uf'
], $filtered_data);
return $this->subsidioService->add($mapped_data);
}
protected function addCredito(array $data): Model\Venta\Credito
{
$fields = array_fill_keys([
'fecha_venta',
'credito',
'uf'
], 0);
$filtered_data = array_intersect_key($data, $fields);
$mapped_data = array_combine([
'fecha',
'valor',
'uf'
], $filtered_data);
return $this->creditoService->add($mapped_data);
}
protected function addBonoPie(array $data): Model\Venta\BonoPie
{
$fields = array_fill_keys([
'fecha_venta',
'bono_pie'
], 0);
$filtered_data = array_intersect_key($data, $fields);
$mapped_data = array_combine([
'fecha',
'valor'
], $filtered_data);
return $this->bonoPieService->add($mapped_data);
}
}