Files
oficial/app/src/Service/Persona.php
Juan Pablo Vial e36281d924 Reservation Fixes
2025-09-09 16:24:48 -03:00

284 lines
10 KiB
PHP

<?php
namespace Incoviba\Service;
use PDOException;
use Psr\Log\LoggerInterface;
use Incoviba\Common\Ideal;
use Incoviba\Common\Implement;
use Incoviba\Exception\ServiceAction\Create;
use Incoviba\Exception\ServiceAction\Read;
use Incoviba\Model;
use Incoviba\Repository;
class Persona extends Ideal\Service
{
public function __construct(LoggerInterface $logger,
protected Repository\Persona $personaRepository,
protected Repository\Persona\Datos $datosPersonaRepository,
protected Repository\Venta\Propietario $propietarioRepository,
protected Direccion $direccionService)
{
parent::__construct($logger);
}
public function getAll(null|string|array $orderBy = null): array
{
try {
try {
$ruts = $this->personaRepository->fetchMissing();
$this->addMissingPropietarios($ruts);
} catch (Implement\Exception\EmptyResult | Read | Create) {}
return array_map([$this, 'process'], $this->personaRepository->fetchAll($orderBy));
} catch (Implement\Exception\EmptyResult) {
return [];
}
}
/**
* @param int $rut
* @return Model\Persona
* @throws Read
*/
public function getById(int $rut): Model\Persona
{
try {
return $this->process($this->personaRepository->fetchById($rut));
} catch (Implement\Exception\EmptyResult) {
try {
$this->propietarioRepository->fetchById($rut);
try {
return $this->add(compact('rut'));
} catch (Create $exception) {
throw new Read(__CLASS__, $exception);
}
} catch (Implement\Exception\EmptyResult $exception) {
throw new Read(__CLASS__, $exception);
}
}
}
/**
* @param array $data
* @return Model\Persona
* @throws Create
*/
public function add(array $data): Model\Persona
{
try {
$persona = $this->personaRepository->fetchById($data['rut']);
} catch (Implement\Exception\EmptyResult) {
try {
$propietario = $this->propietarioRepository->fetchById($data['rut']);
$persona = $this->addFromPropietario($propietario);
} catch (Implement\Exception\EmptyResult) {
$dataMap = [
'digit' => 'digito',
'name' => 'nombres',
'names' => 'nombres',
'last_name' => 'apellido_paterno',
'last_name2' => 'apellido_materno',
];
foreach ($data as $key => $value) {
if (array_key_exists($key, $dataMap)) {
$data[$dataMap[$key]] = $value;
unset($data[$key]);
}
}
$filteredData = $this->personaRepository->filterData($data);
try {
$persona = $this->personaRepository->create($filteredData);
$persona = $this->personaRepository->save($persona);
} catch (PDOException $exception) {
throw new Create(__CLASS__, $exception);
}
}
}
$this->addDatos($persona, $data);
return $this->process($persona);
}
/**
* @param array $ruts
* @param bool $load
* @return array|null
* @throws Create
* @throws Read
*/
public function addMissingPropietarios(array $ruts, bool $load = false): ?array
{
try {
$propietarios = $this->propietarioRepository->fetchByRuts($ruts);
} catch (Implement\Exception\EmptyResult $exception) {
throw new Read(__CLASS__, $exception);
}
$data = [];
$datos = [];
foreach ($propietarios as $propietario) {
$data []= [
'rut' => $propietario->rut,
'digito' => $propietario->dv,
'nombres' => $propietario->nombres,
'apellido_paterno' => $propietario->apellidos['paterno'],
'apellido_materno' => $propietario->apellidos['materno'] ?? '',
];
$datos []= [
'persona_rut' => $propietario->rut,
'direccion_id' => $propietario->datos?->direccion_id,
'email' => $propietario->datos?->email,
'telefono' => $propietario->datos?->telefono,
];
}
try {
$personas = $this->personaRepository->saveMissing($data);
} catch (PDOException|Implement\Exception\EmptyResult $exception) {
throw new Create(__CLASS__, $exception);
}
$personasRuts = array_map(function(Model\Persona $persona) {
return $persona->rut;
}, $personas);
$datos = array_filter($datos, function($row) use ($personasRuts) {
return in_array($row['persona_rut'], $personasRuts);
});
try {
$this->datosPersonaRepository->saveMissing($datos);
} catch (PDOException $exception) {
throw new Create(__CLASS__, $exception);
}
if ($load) {
return array_map([$this, 'process'], $personas);
}
return null;
}
public function edit(Model\Persona $persona, array $data): Model\Persona
{
$filteredData = $this->personaRepository->filterData($data);
try {
$datosData = $this->datosPersonaRepository->filterData($data);
$this->datosPersonaRepository->edit($persona->datos(), $datosData);
return $this->personaRepository->edit($persona, $filteredData);
} catch (Implement\Exception\EmptyResult) {
return $persona;
}
}
protected function process(Model\Persona $persona): Model\Persona
{
$persona->addFactory('datos', (new Implement\Repository\Factory())
->setCallable([$this->datosPersonaRepository, 'fetchByPersona'])
->setArgs(['persona_rut' => $persona->rut]));
return $persona;
}
/**
* @param Model\Venta\Propietario $propietario
* @return Model\Persona
* @throws Create
*/
protected function addFromPropietario(Model\Venta\Propietario $propietario): Model\Persona
{
$data = [
'rut' => $propietario->rut,
'digito' => $propietario->dv,
'nombres' => $propietario->nombres,
'apellido_paterno' => $propietario->apellidos['paterno'],
'apellido_materno' => $propietario->apellidos['materno'] ?? '',
];
try {
$persona = $this->personaRepository->create($data);
$persona = $this->personaRepository->save($persona);
} catch (PDOException $exception) {
throw new Create(__CLASS__, $exception);
}
$datosData = [];
if ($propietario->datos->direccion) {
$datosData['direccion_id'] = $propietario->datos?->direccion->id;
}
if ($propietario->datos->email) {
$datosData['email'] = $propietario->datos->email;
}
if ($propietario->datos->telefono) {
$datosData['telefono'] = $propietario->datos->telefono;
}
if ($propietario->datos->estado_civil) {
$datosData['estado_civil'] = $propietario->datos->estado_civil;
}
if ($propietario->datos->fecha_nacimiento) {
$datosData['fecha_nacimiento'] = $propietario->datos->fecha_nacimiento;
}
if ($propietario->datos->profesion) {
$datosData['ocupacion'] = $propietario->datos->profesion;
}
if ($propietario->datos->sexo) {
$datosData['sexo'] = $propietario->datos->sexo;
}
$this->addDatos($persona, $datosData);
return $persona;
}
/**
* @param Model\Persona $persona
* @param array $data
* @return Model\Persona
* @throws Create
*/
protected function addDatos(Model\Persona $persona, array $data): Model\Persona
{
$addressData = [];
foreach ($data as $key => $value) {
if (!str_starts_with($key, 'address_') and !str_starts_with($key, 'direccion_')) {
continue;
}
if (str_starts_with($key, 'direccion_')) {
$newKey = substr($key, strlen('direccion_'));
} else {
$newKey = substr($key, strlen('address_'));
}
$addressData[$newKey] = $value;
}
if (!empty($addressData)) {
$address = $this->direccionService->add($addressData);
foreach ($data as $key => $value) {
if (str_starts_with($key, 'address_') or str_starts_with($key, 'direccion_')) {
unset($data[$key]);
}
}
$data['direccion_id'] = $address->id;
}
$dataMap = [
'phone' => 'telefono',
'profession' => 'ocupacion',
'profesion' => 'ocupacion',
'sex' => 'sexo',
'marital_status' => 'estado_civil',
'birth_date' => 'fecha_nacimiento',
'birthdate' => 'fecha_nacimiento',
];
foreach ($data as $key => $value) {
if (array_key_exists($key, $dataMap)) {
$data[$dataMap[$key]] = $value;
unset($data[$key]);
}
}
try {
$datos = $this->datosPersonaRepository->fetchByPersona($persona->rut);
$this->datosPersonaRepository->edit($datos, $data);
} catch (Implement\Exception\EmptyResult $exception) {
$datosData = ['persona_rut' => $persona->rut, ...$data];
$datosData = $this->datosPersonaRepository->filterData($datosData);
$datos = $this->datosPersonaRepository->create($datosData);
try {
$this->datosPersonaRepository->save($datos);
} catch (PDOException $exception) {
throw new Create(__CLASS__, $exception);
}
}
return $persona;
}
}