Compare commits

34 Commits

Author SHA1 Message Date
fc65ee581a Promotions by unit 2025-09-15 20:18:29 -03:00
b750f80eb7 FIX: unidades port tipo 2025-09-15 20:16:44 -03:00
2d5a526b43 Merge branch 'develop' into feature/cierres 2025-09-15 18:49:56 -03:00
b2e0031422 Cleanup 2025-09-15 18:45:37 -03:00
a478c61563 Merge pull request 'FIX: invoice product_id = venta_id' (#41) from fix/toku-invoice-product-id into develop
Reviewed-on: #41
2025-09-15 18:22:51 -03:00
be7f5b26f1 FIX: invoice product_id = venta_id 2025-09-15 18:22:07 -03:00
880113fe86 Merge pull request 'FIX: mapRequest was not returning request' (#40) from fix/toku-map-request into develop
Reviewed-on: #40
2025-09-15 18:08:02 -03:00
14938f42ac FIX: mapRequest was not returning request 2025-09-15 18:07:40 -03:00
e7a86e37e0 Merge branch 'develop' into feature/cierres 2025-09-15 18:04:56 -03:00
6b9a923715 Merge pull request 'FIX: mapResponse not working' (#39) from fix/toku-response-client-log into develop
Reviewed-on: #39
2025-09-15 17:58:21 -03:00
7c0807b478 FIX: mapResponse not working 2025-09-15 17:54:28 -03:00
45c70ec055 Merge pull request 'fix/details-incorrectly-sent-to-toku' (#38) from fix/details-incorrectly-sent-to-toku into develop
Reviewed-on: #38
2025-09-15 17:28:58 -03:00
03c05611b0 FIX: number with country code without + 2025-09-15 17:26:56 -03:00
ae1b985b35 Test get 2025-09-15 16:45:42 -03:00
c0f56f02e9 Cleanup 2025-09-15 16:45:26 -03:00
d0074a6988 FIX: single quote 2025-09-15 16:44:40 -03:00
d94a064915 Cleanup 2025-09-15 14:45:53 -03:00
4d24548f49 Merge pull request 'Log more from exception.' (#37) from feature/better-logging-in-queue into develop
Reviewed-on: #37
2025-09-15 14:41:21 -03:00
0be244f4fa Log more from exception. 2025-09-15 14:32:03 -03:00
096ed618ae Merge pull request 'Redis max log size' (#36) from feature/redis-log-max-entries into develop
Reviewed-on: #36
2025-09-15 14:26:18 -03:00
1a94759f9d Configurable 2025-09-15 14:25:10 -03:00
ebdc53eb80 Redis max log size 2025-09-15 14:22:47 -03:00
22195dae8b Redis max log size 2025-09-15 14:21:46 -03:00
c2cb8f91ad Merge branch 'develop' into feature/cierres 2025-09-15 14:10:07 -03:00
4599d22bd0 Merge pull request 'Log response data' (#35) from feature/log-toku-response into develop
Reviewed-on: #35
2025-09-15 14:09:21 -03:00
ed0b17ef88 Log response data 2025-09-15 14:08:14 -03:00
600773a270 Unit promotions 2025-09-15 14:07:52 -03:00
121f88103f Merge pull request 'Reorganization' (#34) from feature/skip-deprecated into develop
Reviewed-on: #34
2025-09-15 13:03:38 -03:00
a0723201aa Reorganization 2025-09-15 13:02:44 -03:00
5d73c8372b Merge pull request 'FIX: check missing table' (#33) from feature/skip-deprecated into develop
Reviewed-on: #33
2025-09-11 17:52:10 -03:00
1945c5728a FIX: check missing table 2025-09-11 17:50:58 -03:00
27c19ee087 Merge pull request 'Deprecated log table' (#32) from feature/skip-deprecated into develop
Reviewed-on: #32
2025-09-11 17:36:54 -03:00
7badba17c3 Deprecated log table 2025-09-11 17:35:02 -03:00
951888636a Merge pull request 'feature/cierres' (#31) from feature/cierres into develop
Reviewed-on: #31
2025-09-11 17:05:15 -03:00
14 changed files with 325 additions and 106 deletions

View File

@ -5,27 +5,53 @@ use Incoviba\Common\Define\Connection;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Level;
use Monolog\LogRecord;
use PDOException;
use PDOStatement;
class MySQL extends AbstractProcessingHandler
{
private bool $initialized = false;
private PDOStatement $statement;
private array $tables = [
'default' => 'monolog',
'deprecated' => 'monolog_deprecated'
];
private array $statements = [
'default' => null,
'deprecated' => null
];
private array $baseQueries = [
'check' => "SHOW TABLES LIKE '%s'",
'create' => "CREATE TABLE IF NOT EXISTS %s (channel VARCHAR(255), level VARCHAR(100), message LONGTEXT, time DATETIME, context LONGTEXT, extra LONGTEXT)",
'insert' => "INSERT INTO %s (channel, level, message, time, context, extra) VALUES (:channel, :level, :message, :time, :context, :extra)",
'delete' => "DELETE FROM %s WHERE time < DATE_SUB(CURDATE(), INTERVAL %d DAY)"
];
public function __construct(protected Connection $connection, protected int $retainDays = 90, int|string|Level $level = Level::Debug, bool $bubble = true)
public function __construct(protected Connection $connection, protected int $retainDays = 90,
int|string|Level $level = Level::Debug, bool $bubble = true)
{
parent::__construct($level, $bubble);
}
public function write(LogRecord $record): void
{
if (!$this->initialized) {
if (!$this->checkTableExists()) {
$this->createTable();
if (!$this->checkTablesExist()) {
$this->createTables();
}
$this->cleanup();
$this->initialized();
}
$this->statement->execute([
if (str_contains(strtolower($record->message), 'deprecated:')) {
$this->statements['deprecated']->execute([
'channel' => $record->channel,
'level' => $record->level->getName(),
'message' => $record->formatted,
'time' => $record->datetime->format('Y-m-d H:i:s.u'),
'context' => (count($record->context) > 0) ? json_encode($record->context, JSON_UNESCAPED_SLASHES) : '',
'extra' => (count($record->extra) > 0) ? json_encode($record->extra, JSON_UNESCAPED_SLASHES) : ''
]);
return;
}
$this->statements['default']->execute([
'channel' => $record->channel,
'level' => $record->level->getName(),
'message' => $record->formatted,
@ -37,36 +63,54 @@ class MySQL extends AbstractProcessingHandler
private function initialized(): void
{
$query = <<<QUERY
INSERT INTO monolog (channel, level, message, time, context, extra)
VALUES (:channel, :level, :message, :time, :context, :extra)
QUERY;
$this->statement = $this->connection->getPDO()->prepare($query);
foreach ($this->tables as $type => $table) {
$query = sprintf($this->baseQueries['insert'], $table);
$this->statements[$type] = $this->connection->getPDO()->prepare($query);
}
$this->initialized = true;
}
private function checkTableExists(): bool
private function checkTablesExist(): bool
{
$query = "SHOW TABLES LIKE 'monolog'";
$result = $this->connection->query($query);
return array_all($this->tables, fn($table) => $this->checkTableExists($table));
}
private function checkTableExists(string $table): bool
{
$query = sprintf($this->baseQueries['check'], $table);
try {
$result = $this->connection->query($query);
} catch (PDOException) {
return false;
}
return $result->rowCount() > 0;
}
private function createTable(): void
private function createTables(): void
{
$query = <<<QUERY
CREATE TABLE IF NOT EXISTS monolog (
channel VARCHAR(255),
level VARCHAR(100),
message LONGTEXT,
time DATETIME,
context LONGTEXT,
extra LONGTEXT
)
QUERY;
$this->connection->getPDO()->exec($query);
foreach ($this->tables as $table) {
if (!$this->checkTableExists($table)) {
$this->createTable($table);
}
}
}
private function createTable(string $table): void
{
$query = sprintf($this->baseQueries['create'], $table);
try {
$result = $this->connection->getPDO()->exec($query);
if ($result === false) {
throw new PDOException('Failed to create table: ' . $table);
}
} catch (PDOException) {}
}
private function cleanup(): void
{
$query = "DELETE FROM monolog WHERE time < DATE_SUB(CURDATE(), INTERVAL {$this->retainDays} DAY)";
$this->connection->query($query);
foreach ($this->tables as $table) {
$query = sprintf($this->baseQueries['delete'], $table, $this->retainDays);
try {
$result = $this->connection->getPDO()->query($query);
if ($result === false) {
throw new PDOException('Failed to delete from table: ' . $table);
}
} catch (PDOException) {}
}
}
}

View File

@ -60,7 +60,8 @@ class ArrayBuilder
try {
$params = [
$this->container->get(Predis\ClientInterface::class),
"logs:{$handlerData['name']}"
"logs:{$handlerData['name']}",
'capSize' => $handlerData['capSize'] ?? 100
];
} catch (NotFoundExceptionInterface | ContainerExceptionInterface $exception) {
$this->log($exception, ['handlerData' => $handlerData]);

View File

@ -33,7 +33,7 @@ Editar Propietario
<div class="fields">
<div class="field">
<label for="calle">Dirección</label>
<input type="text" name="calle" id="calle" value="{'{$propietario->datos->direccion->calle}}" />
<input type="text" name="calle" id="calle" value="{{$propietario->datos->direccion->calle}}" />
</div>
<div class="field">
<label for="numero">Número</label>

View File

@ -238,6 +238,7 @@
}
}
class AddModalUnits {
parent = null
ids = {
buttons_holder: '',
units: ''
@ -252,7 +253,8 @@
units: null,
}
constructor() {
constructor(parent) {
this.parent = parent
this.ids = {
buttons_holder: 'add_unit_buttons',
units: 'add_units'
@ -265,6 +267,9 @@
}
this.setup()
}
get promotions() {
return this.parent.data.promotions[this.parent.data.current_project]
}
draw = {
button: type => {
return [
@ -293,36 +298,26 @@
return
}
this.components.units.innerHTML = this.data.units.map(unit => {
return [
'<div class="fields">',
'<div class="four wide field">',
`<label>${unit.type.charAt(0).toUpperCase() + unit.type.slice(1)}</label>`,
`<div class="ui search selection dropdown">`,
'<input type="hidden" name="add_units[]" />',
'<i class="dropdown icon"></i>',
`<div class="default text">${unit.type.charAt(0).toUpperCase() + unit.type.slice(1)}</div>`,
'<div class="menu">',
this.data.types[unit.type].map(unit => {
return `<div class="item" data-value="${unit.value}">${unit.name}</div>`
}).join(''),
'</div>',
'</div>',
'</div>',
'<div class="three wide field">',
'<label>Valor</label>',
'<div class="ui right labeled input">',
'<input type="number" name="add_units_value[]" placeholder="Valor" />',
'<div class="ui basic label">UF</div>',
'</div>',
'</div>',
'<div class="field">',
'<label></label>',
`<button class="ui red tiny icon button remove_unit" type="button" data-id="${unit.idx}"><i class="trash icon"></i></button>`,
'</div>',
'</div>',
].join('')
return this.draw.unit(unit)
}).join('')
this.components.units.querySelectorAll('.dropdown').forEach(dropdown => {
this.components.units.querySelectorAll('.dropdown.add_units').forEach(dropdown => {
$(dropdown).dropdown({
onChange: (value, text, $selectedItem) => {
const unitPromotions = this.promotions.filter(promotion => promotion.units.length > 0)
const promotions = unitPromotions.filter(promotion => promotion.units.filter(unit => unit.id === parseInt(value)).length > 0)
console.debug($selectedItem.parent().parent().parent().parent().find('.add_promotions_unit'))
$selectedItem.parent().parent().parent().parent().find('.add_promotions_unit')
.dropdown('change values', promotions.map(promotion => {
return {
value: promotion.id,
name: promotion.description,
text: promotion.description,
}
}))
}
})
})
this.components.units.querySelectorAll('.dropdown.add_promotions_unit').forEach(dropdown => {
$(dropdown).dropdown()
})
this.components.units.querySelectorAll('.remove_unit').forEach(button => {
@ -331,6 +326,54 @@
this.remove(idx)
})
})
},
unit: unit => {
let promotions = ''
if (unit.type === 'departamento') {
if (this.promotions.filter(promotion => promotion.units.length > 0).length > 0) {
promotions = [
'<div class="three wide field">',
'<label>Promociones</label>',
'<div class="ui multiple search selection dropdown add_promotions_unit">',
'<input type="hidden" name="add_units_promotions[]" />',
'<i class="dropdown icon"></i>',
'<div class="default text">Promociones</div>',
'<div class="menu">',
'</div>',
'</div>',
'</div>'
].join('')
}
}
return [
'<div class="fields">',
'<div class="four wide field">',
`<label>${unit.type.charAt(0).toUpperCase() + unit.type.slice(1)}</label>`,
`<div class="ui search selection dropdown add_units">`,
'<input type="hidden" name="add_units[]" />',
'<i class="dropdown icon"></i>',
`<div class="default text">${unit.type.charAt(0).toUpperCase() + unit.type.slice(1)}</div>`,
'<div class="menu">',
this.data.types[unit.type].map(unit => {
return `<div class="item" data-value="${unit.value}">${unit.name}</div>`
}).join(''),
'</div>',
'</div>',
'</div>',
'<div class="three wide field">',
'<label>Valor</label>',
'<div class="ui right labeled input">',
'<input type="number" name="add_units_value[]" placeholder="Valor" />',
'<div class="ui basic label">UF</div>',
'</div>',
'</div>',
promotions,
'<div class="field">',
'<label></label>',
`<button class="ui red tiny icon button remove_unit" type="button" data-id="${unit.idx}"><i class="trash icon"></i></button>`,
'</div>',
'</div>',
].join('')
}
}
reset() {
@ -436,11 +479,30 @@
this.get.brokers(project_id)
this.get.promotions(project_id).then(promotions => {
this.components.promotions.data.promotions = promotions
this.components.promotions.data.promotions = promotions.map(promotion => {
return {
text: promotion.name,
name: promotion.name,
value: promotion.id
}
})
this.components.promotions.draw.promotions()
})
this.get.units(project_id).then(units => {
this.components.units.data.types = units
this.get.units(project_id).then(unitTypes => {
Object.entries(unitTypes).map(([type, units]) => {
units = units.map(unit => {
return {
text: unit.descripcion,
name: unit.descripcion,
value: unit.id
}
})
units.sort((a, b) => {
return parseInt(a.text) - parseInt(b.text)
})
unitTypes[type] = units
})
this.components.units.data.types = unitTypes
this.components.units.draw.buttons()
})
}
@ -564,13 +626,7 @@
if (json.promotions.length === 0) {
return this.data.promotions[project_id] = []
}
return this.data.promotions[project_id] = json.promotions.map(promotion => {
return {
text: promotion.name,
name: promotion.name,
value: promotion.id
}
})
return this.data.promotions[project_id] = json.promotions
})
},
units: project_id => {
@ -593,18 +649,9 @@
if (!(type in this.data.units[project_id])) {
this.data.units[project_id][type] = []
}
this.data.units[project_id][type].push({
text: unit.descripcion,
name: unit.descripcion,
value: unit.id
})
})
Object.entries(this.data.units[project_id]).forEach(([type, units]) => {
units.sort((a, b) => {
return parseInt(a.text) - parseInt(b.text)
})
this.data.units[project_id][type] = units
this.data.units[project_id][type].push(unit)
})
return this.data.units[project_id]
})
},
@ -706,7 +753,7 @@
this.components.promotions = new AddModalPromotions()
this.components.projects = document.getElementById(this.ids.projects)
this.components.project_name = document.getElementById(this.ids.project_name)
this.components.units = new AddModalUnits()
this.components.units = new AddModalUnits(this)
this.components.$modal.modal({
onApprove: () => {

View File

@ -125,6 +125,7 @@ return [
'headers' => $request->getHeaders(),
'body' => $request->getBody()->getContents(),
]);
return $request;
}));
return new GuzzleHttp\Client([
'handler' => $stack,

View File

@ -187,7 +187,7 @@ class Promotion extends Common\Ideal\Repository
->joined('LEFT OUTER JOIN proyecto_tipo_unidad ptu ON ptu.id = pul.unit_line_id')
->joined('LEFT OUTER JOIN promotion_units pu ON pu.promotion_id = a.id')
->joined('LEFT OUTER JOIN unidad ON unidad.id = pu.unit_id')
->joined('LEFT OUTER JOIN proyecto_tipo_unidad ptu1 ON ptu.id = unidad.pt')
->joined('LEFT OUTER JOIN proyecto_tipo_unidad ptu1 ON ptu1.id = unidad.pt')
->where('pp.project_id = :project_id OR put.project_id = :project_id OR ptu.proyecto = :project_id OR ptu1.proyecto = :project_id')
->group('a.id');
return $this->fetchMany($query, ['project_id' => $project_id]);

View File

@ -92,7 +92,6 @@ class Persona extends Ideal\Service
throw new Create(__CLASS__, $exception);
}
}
}
$this->addDatos($persona, $data);

View File

@ -68,12 +68,24 @@ class Queue extends Ideal\Service
return false;
}
} catch (Exception $exception) {
$this->logger->warning("Could not run job {$job->id}", ['exception' => $exception]);
$this->logger->warning("Could not run job {$job->id}", ['exception' => [
'code' => $exception->getCode(),
'message' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'trace' => $exception->getTraceAsString(),
]]);
$job->retries++;
try {
$this->jobService->update($job);
} catch (Update $exception) {
$this->logger->error($exception->getMessage(), ['job' => $job, 'exception' => $exception]);
$this->logger->error($exception->getMessage(), ['job' => $job, 'exception' => [
'code' => $exception->getCode(),
'message' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'trace' => $exception->getTraceAsString(),
]]);
}
return false;
}

View File

@ -103,7 +103,11 @@ class Customer extends AbstractEndPoint
continue;
}
if (!str_starts_with($value, '+')) {
$value = "+56{$value}";
if (str_starts_with($value, '56')) {
$value = "+{$value}";
} else {
$value = "+56{$value}";
}
}
$params[$key] = $value;
continue;

View File

@ -251,7 +251,7 @@ class Invoice extends AbstractEndPoint
{
$paramsMap = [
'customer' => 'customer',
'product_id' => 'cuota_id',
'product_id' => 'venta_id',
'due_date' => 'fecha',
'subscription' => 'subscription',
'amount' => 'valor',
@ -266,8 +266,6 @@ class Invoice extends AbstractEndPoint
'invoice_external_id' => 'cuota_id'
];
$today = new DateTimeImmutable('now', new DateTimeZone('America/Santiago'));
$params = [];
foreach ($paramsMap as $key => $ref) {
if ($ref === null) {
@ -278,14 +276,6 @@ class Invoice extends AbstractEndPoint
continue;
}
if ($ref === 'valor') {
/*$valor = 0;
if ($data['cuota']->pago->fecha <= $today) {
$valor = $data['cuota']->pago->valor();
}
if ($valor === 0) {
$valor = $data['cuota']->pago->valor / $data['venta']->uf;
}
$params[$key] = $valor;*/
$params[$key] = $data['cuota']->pago->valor;
continue;
}
@ -303,6 +293,10 @@ class Invoice extends AbstractEndPoint
$params[$key] = $data['cuota']->id;
continue;
}
if ($ref === 'product_id') {
$params[$key] = $data['venta']->id;
continue;
}
if (array_key_exists($ref, $data) and $data[$ref] !== '' and $data[$ref] !== null) {
$params[$key] = $data[$ref];
}

View File

@ -99,13 +99,13 @@ class Subscription extends AbstractEndPoint
public function queue(int $venta_id): bool
{
try {
$venta = $this->ventaService->getById($venta_id);
$this->ventaService->getById($venta_id);
} catch (Read $exception) {
$this->logger->warning($exception);
return false;
}
try {
$subscription = $this->subscriptionRepsitory->fetchByVenta($venta_id);
$this->subscriptionRepsitory->fetchByVenta($venta_id);
return false;
} catch (EmptyResult) {
return true;

View File

@ -104,7 +104,6 @@ class Propietario extends Service
} catch (EmptyResult) {
try {
$propietario = $this->propietarioRepository->create($filtered_data);
$this->logger->info('Propietario', ['propietario' => $propietario]);
$propietario = $this->propietarioRepository->save($propietario);
} catch (PDOException $exception) {
throw new Create(__CLASS__, $exception);

View File

@ -0,0 +1,59 @@
<?php
namespace Tests\Unit\Common\Implement\Log\Handler;
use DateTimeImmutable;
use PDO;
use PDOStatement;
use PHPUnit\Framework\TestCase;
use Monolog;
use Faker\Factory;
use Incoviba\Common\Implement\Log\Handler\MySQL;
use Incoviba\Common\Define;
class MySQLTest extends TestCase
{
protected Define\Connection $connection;
protected function setUp(): void
{
$pdo = $this->getMockBuilder(PDO::class)
->disableOriginalConstructor()
->getMock();
$pdo->method('prepare')->willReturn($this->getMockBuilder(PDOStatement::class)->getMock());
$this->connection = $this->getMockBuilder(Define\Connection::class)
->disableOriginalConstructor()
->getMock();
$this->connection->method('getPDO')->willReturn($pdo);
}
public function testWrite(): void
{
$faker = Factory::create();
$context = [];
$extra = [];
for ($i = 0; $i < 5; $i++) {
$context[$faker->word] = $faker->word;
$extra[$faker->word] = $faker->word;
}
$recordArray = [
'message' => 'Test message',
'context' => $context,
'level' => 100,
'level_name' => 'DEBUG',
'channel' => $faker->word,
'datetime' => DateTimeImmutable::createFromMutable($faker->dateTime()),
'extra' => $extra,
];
$record = new Monolog\LogRecord(
$recordArray['datetime'],
$recordArray['channel'],
Monolog\Level::fromName($recordArray['level_name']),
$recordArray['message'],
$recordArray['context'],
$recordArray['extra']);
$handler = new MySQL($this->connection);
$handler->write($record);
$this->assertTrue(true);
}
}

View File

@ -5,12 +5,10 @@ use Psr\Log\LoggerInterface;
use PHPUnit\Framework\TestCase;
use Faker;
use Incoviba\Common\Implement;
use Incoviba\Exception\ServiceAction;
use Incoviba\Model;
use Incoviba\Repository;
use Incoviba\Service;
use Incoviba\Common\Define;
use Incoviba\Common\Ideal;
use Tests\Extension\Faker\Provider\Rut;
class PersonaTest extends TestCase
{
@ -51,10 +49,11 @@ class PersonaTest extends TestCase
$personaService = new Service\Persona($this->logger, $this->personaRepository, $this->datosPersonaRepository,
$this->propietarioRepository, $this->direccionService);
$faker = Faker\Factory::create('es_ES');
$digit = $faker->boolean(100-round(1/11*100)) ? $faker->randomNumber(1) : 'K';
$faker->addProvider(new Rut($faker));
$rut = $faker->rut(false, false);
$data = [
'rut' => $faker->randomNumber(8),
'digito' => $digit,
'rut' => $rut,
'digito' => $faker->digitoVerificador($rut),
'nombres' => $faker->name(),
'apellido_paterno' => $faker->lastName(),
'apellido_materno' => $faker->lastName(),
@ -62,4 +61,64 @@ class PersonaTest extends TestCase
$persona = $personaService->add($data);
$this->assertEquals($data['rut'], $persona->rut);
}
public function testGetById(): void
{
$faker = Faker\Factory::create('es_ES');
$faker->addProvider(new Rut($faker));
$direccion = $this->getMockBuilder(Model\Direccion::class)
->disableOriginalConstructor()->getMock();
$direccion->id = $faker->randomNumber(2);
$datos = new Model\Venta\Datos();
$datos->direccion = $direccion;
$datos->telefono = $faker->randomNumber(8);
$datos->email = $faker->email();
$datos->sexo = $faker->randomElement(['M', 'F']);
$rut = $faker->rut(false, false);
$propietario = new Model\Venta\Propietario();
$propietario->rut = $rut;
$propietario->dv = $faker->digitoVerificador($rut);
$propietario->nombres = $faker->name();
$propietario->apellidos['paterno'] = $faker->lastName();
$propietario->apellidos['materno'] = $faker->lastName();
$propietario->datos = $datos;
$propietarioRepository = $this->getMockBuilder(Repository\Venta\Propietario::class)
->disableOriginalConstructor()->getMock();
$personaRepository = $this->getMockBuilder(Repository\Persona::class)
->disableOriginalConstructor()->getMock();
$personaRepository->method('fetchById')->willThrowException(new Implement\Exception\EmptyResult(''));
$personaRepository->method('create')->willReturnCallback(function($data) {
$persona = new Model\Persona();
$persona->rut = $data['rut'];
$persona->digito = $data['digito'];
$persona->nombres = $data['nombres'];
$persona->apellidoPaterno = $data['apellido_paterno'];
$persona->apellidoMaterno = $data['apellido_materno'];
return $persona;
});
$personaRepository->method('save')->willReturnArgument(0);
$datosPersona = new Model\Persona\Datos();
$datosPersona->direccion = $direccion;
$datosPersona->telefono = $datos->telefono;
$datosPersona->email = $datos->email;
$datosPersona->sexo = $datos->sexo;
$datosPersonaRepository = $this->getMockBuilder(Repository\Persona\Datos::class)
->disableOriginalConstructor()->getMock();
$datosPersonaRepository->method('fetchByPersona')->willReturn($datosPersona);
$propietarioRepository->method('fetchById')->willReturn($propietario);
$direccionService = $this->getMockBuilder(Service\Direccion::class)
->disableOriginalConstructor()->getMock();
$direccionService->method('add')->willReturn($direccion);
$personaService = new Service\Persona($this->logger, $personaRepository, $datosPersonaRepository,
$propietarioRepository, $direccionService);
$persona = $personaService->getById($rut);
$this->assertEquals($rut, $persona->rut);
$this->assertEquals($propietario->dv, $persona->digito);
$this->assertEquals($propietario->nombres, $persona->nombres);
$this->assertEquals($propietario->apellidos['paterno'], $persona->apellidoPaterno);
$this->assertEquals($propietario->apellidos['materno'], $persona->apellidoMaterno);
$this->assertEquals($datos->direccion, $persona->datos->direccion);
$this->assertEquals($datos->telefono, $persona->datos->telefono);
$this->assertEquals($datos->email, $persona->datos->email);
$this->assertEquals($datos->sexo, $persona->datos->sexo);
}
}