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