This commit is contained in:
Juan Pablo Vial
2025-08-22 09:28:53 -04:00
parent 78222eb9f1
commit 454ba41d9c
26 changed files with 1036 additions and 135 deletions

View File

@ -26,7 +26,7 @@ abstract class Model implements Define\Model
public function jsonSerialize(): mixed
{
return [
'id' => $this->id,
'id' => $this->id ?? '',
...$this->jsonComplement()
];
}

View File

@ -10,6 +10,7 @@ $app->group('/reservations', function($app) {
});
$app->get('[/]', Reservations::class);
});
$app->post('/reservation/add[/]', [Reservations::class, 'addOne']);
$app->group('/reservation/{reservation_id}', function($app) {
$app->post('/edit[/]', [Reservations::class, 'edit']);
$app->delete('[/]', [Reservations::class, 'delete']);

View File

@ -24,6 +24,12 @@
rut.replace(/\D/g, '')
return rut.replace(/^(\d{1,2})(\d{3})(\d{3})$/, '$1.$2.$3')
}
static clean(rut) {
if (!(typeof rut === 'string' || rut instanceof String)) {
rut = rut.toString()
}
return rut.replace(/\D/g, '')
}
static validar(rut, digito) {
if (!(typeof digito === 'string' || digito instanceof String)) {
digito = digito.toString()

View File

@ -4,13 +4,13 @@
</div>
<div class="content">
<form class="ui form" id="add_reservation_form">
<input type="hidden" name="project_id" />
<input type="hidden" name="add_project_id" />
<div class="three wide required field">
<label>Fecha</label>
<div class="ui calendar" id="add_date">
<div class="ui icon input">
<i class="calendar icon"></i>
<input type="text" name="date" />
<input type="text" name="add_date" />
</div>
</div>
</div>
@ -18,7 +18,7 @@
<div class="three wide required field">
<label>RUT</label>
<div class="ui right labeled input" id="add_rut">
<input type="text" name="rut" placeholder="RUT" />
<input type="text" name="add_buyer_rut" placeholder="RUT" />
<div class="ui basic label">-<span id="add_digit"></span></div>
</div>
</div>
@ -30,29 +30,29 @@
<div class="fields">
<div class="three wide required field">
<label>Nombre</label>
<input type="text" name="name" placeholder="Nombre" />
<input type="text" name="add_buyer_name" placeholder="Nombre" />
</div>
<div class="six wide required field">
<label>Apellidos</label>
<input type="text" name="last_name" placeholder="Apellido Paterno" />
<input type="text" name="add_buyer_last_name" placeholder="Apellido Paterno" />
</div>
<div class="six wide field">
<label></label>
<input type="text" name="last_name2" placeholder="Apellido Materno" />
<input type="text" name="add_buyer_last_name2" placeholder="Apellido Materno" />
</div>
</div>
<div class="fields">
<div class="three wide field">
<label>Dirección</label>
<input type="text" name="calle" placeholder="Calle" />
<input type="text" name="add_buyer_address_street" placeholder="Calle" />
</div>
<div class="field">
<label></label>
<input type="text" name="numero" placeholder="" />
<input type="text" name="add_buyer_address_number" placeholder="" />
</div>
<div class="three wide field">
<label></label>
<input type="text" name="extra" placeholder="Otros Detalles" />
<input type="text" name="add_buyer_address_extra" placeholder="Otros Detalles" />
</div>
</div>
<div class="fields">
@ -82,25 +82,25 @@
<div class="fields">
<div class="field">
<label>Telefono</label>
<input type="text" name="phone" placeholder="Telefono" />
<input type="text" name="add_buyer_phone" placeholder="Telefono" />
</div>
<div class="field">
<label>Correo</label>
<div class="ui labeled input">
<input type="text" name="email_name" placeholder="Correo" />
<input type="text" name="add_buyer_email_name" placeholder="Correo" />
<div class="ui basic label">@</div>
<input type="text" name="email_domain" placeholder="Dominio" />
<input type="text" name="add_buyer_email_domain" placeholder="Dominio" />
</div>
</div>
</div>
<div class="fields">
<div class="field">
<label>Estado Civil</label>
<input type="text" name="civil_status" placeholder="Estado Civil" />
<input type="text" name="add_buyer_marital_status" placeholder="Estado Civil" />
</div>
<div class="field">
<label>Profesión</label>
<input type="text" name="profession" placeholder="Profesión" />
<input type="text" name="add_buyer_profession" placeholder="Profesión" />
</div>
<div class="field">
<label>Fecha de Nacimiento</label>
@ -115,7 +115,7 @@
<div class="six wide field">
<label>Operador *</label>
<div class="ui clearable search selection dropdown" id="add_broker">
<input type="hidden" name="broker" />
<input type="hidden" name="add_broker" />
<i class="dropdown icon"></i>
<div class="default text">Operador</div>
<div class="menu"></div>
@ -193,7 +193,7 @@
'<div class="three wide field">',
'<label>Promoción</label>',
`<div class="ui search selection dropdown">`,
'<input type="hidden" name="promotions[]" />',
'<input type="hidden" name="add_promotions[]" />',
'<i class="dropdown icon"></i>',
'<div class="default text">Promoción</div>',
`<div class="menu">${promotions.join('')}</div>`,
@ -298,7 +298,7 @@
'<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="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">',
@ -308,6 +308,13 @@
'</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>`,
@ -418,7 +425,7 @@
load(project_id) {
this.reset()
this.data.current_project = project_id
this.components.form.querySelector('input[name="project_id"]').value = project_id
this.components.form.querySelector('input[name="add_project_id"]').value = project_id
this.get.brokers(project_id)
this.get.promotions(project_id).then(promotions => {
@ -436,23 +443,27 @@
this.components.units.reset()
}
add() {
const url = '/api/ventas/reservations/add'
const url = '/api/ventas/reservation/add'
const form = document.getElementById(this.ids.form)
const body = new FormData(form)
const date = this.components.$date.calendar('get date')
console.debug(date)
body.set('date', [date.getFullYear(), date.getMonth() + 1, date.getDate()].join('-'))
body.set('comuna', this.components.$comuna.dropdown('get value'))
body.set('region', this.components.$region.dropdown('get value'))
body.set('broker_rut', this.components.$broker.dropdown('get value'))
/*body.set('promotions[]', '')
this.components.promotions.forEach(promotion => {
body.append('promotions[]', promotion.querySelector('promotion').value)
})*/
/*body.set('units[]', '')
this.components.units.forEach(unit => {
body.append('units[]', unit.querySelector('unit').value)
})*/
body.set('add_date', [date.getFullYear(), date.getMonth() + 1, date.getDate()].join('-'))
body.set('add_buyer_rut', Rut.clean(this.components.rut.querySelector('input').value))
body.set('add_buyer_digit', this.components.digit.textContent)
body.set('add_buyer_address_comuna_id', this.components.$comuna.dropdown('get value'))
body.set('add_broker_rut', Rut.clean(this.components.$broker.dropdown('get value')))
body.set('add_buyer_email', form.querySelector("input[name='add_buyer_email_name']").value + '@' + form.querySelector("input[name='add_buyer_email_domain']").value)
const birthdate = this.components.$birthdate.calendar('get date')
body.set('add_buyer_birthdate', [birthdate.getFullYear(), birthdate.getMonth() + 1, birthdate.getDate()].join('-'))
body.delete('comuna')
body.delete('region')
body.delete('broker')
body.delete('add_broker')
body.delete('birthdate')
body.delete('add_buyer_email_name')
body.delete('add_buyer_email_domain')
const method = 'post'
return APIClient.fetch(url, {method, body}).then(response => response.json()).then(json => {
if (json.success) {
@ -604,32 +615,32 @@
fill = {
user: user => {
const form = this.components.form
form.querySelector('input[name="name"]').value = user.nombres || ''
form.querySelector('input[name="last_name"]').value = user.apellidoPaterno || ''
form.querySelector('input[name="last_name2"]').value = user.apellidoMaterno || ''
form.querySelector('input[name="calle"]').value = user.datos?.direccion?.calle || ''
form.querySelector('input[name="numero"]').value = user.datos?.direccion?.numero || ''
form.querySelector('input[name="extra"]').value = user.datos?.direccion?.extra || ''
form.querySelector('input[name="add_buyer_name"]').value = user.nombres || ''
form.querySelector('input[name="add_buyer_last_name"]').value = user.apellidoPaterno || ''
form.querySelector('input[name="add_buyer_last_name2"]').value = user.apellidoMaterno || ''
form.querySelector('input[name="add_buyer_address_street"]').value = user.datos?.direccion?.calle || ''
form.querySelector('input[name="add_buyer_address_number"]').value = user.datos?.direccion?.numero || ''
form.querySelector('input[name="add_buyer_address_extra"]').value = user.datos?.direccion?.extra || ''
if (parseInt(this.components.$region.dropdown('get value')) !== user.datos?.direccion?.comuna?.provincia?.region?.id) {
this.components.$region.dropdown('set selected', user.datos?.direccion?.comuna?.provincia?.region?.id)
} else {
this.components.$comuna.dropdown('set selected', user.datos?.direccion?.comuna?.id)
}
form.querySelector('input[name="phone"]').value = user.datos?.telefono
const email_parts = user.datos?.email.split('@')
form.querySelector('input[name="email_name"]').value = email_parts[0]
form.querySelector('input[name="email_domain"]').value = email_parts[1]
if ('estadoCivil' in user.datos) {
form.querySelector('input[name="civil_status"]').value = user.datos?.estadoCivil.charAt(0).toUpperCase() + user.datos?.estadoCivil.slice(1)
form.querySelector('input[name="add_buyer_phone"]').value = user.datos?.telefono || ''
const email_parts = user.datos?.email?.split('@') || []
form.querySelector('input[name="add_buyer_email_name"]').value = email_parts[0] || ''
form.querySelector('input[name="add_buyer_email_domain"]').value = email_parts[1] || ''
if (user.datos !== null && 'estadoCivil' in user.datos) {
form.querySelector('input[name="add_buyer_marital_status"]').value = user.datos?.estadoCivil.charAt(0).toUpperCase() + user.datos?.estadoCivil.slice(1)
} else {
form.querySelector('input[name="civil_status"]').value = ''
form.querySelector('input[name="add_buyer_marital_status"]').value = ''
}
if ('ocupacion' in user.datos) {
form.querySelector('input[name="profession"]').value = user.datos?.ocupacion
if (user.datos !== null &&'ocupacion' in user.datos) {
form.querySelector('input[name="add_buyer_profession"]').value = user.datos?.ocupacion.charAt(0).toUpperCase() + user.datos?.ocupacion.slice(1).toLowerCase()
} else {
form.querySelector('input[name="profession"]').value = ''
form.querySelector('input[name="add_buyer_profession"]').value = ''
}
if ('fechaNacimiento' in user.datos) {
if (user.datos !== null &&'fechaNacimiento' in user.datos) {
this.components.$birthdate.calendar('set date', user.datos?.fechaNacimiento)
}
},

View File

@ -60,8 +60,8 @@ class Reservations
'partial' => false,
'errors' => [],
];
try {
var_dump($input);
/*try {
$output['reservations'] []= [
'reservation' => $reservationService->add($input),
'success' => true
@ -69,7 +69,7 @@ class Reservations
$output['partial'] = true;
} catch (ServiceAction\Create $exception) {
$output['errors'] []= $this->parseError($exception);
}
}*/
if (count($input['reservations']) === count($output['reservations'])) {
$output['success'] = true;
@ -77,6 +77,31 @@ class Reservations
return $this->withJson($response, $output);
}
public function addOne(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Reservation $reservationService): ResponseInterface
{
$input = $request->getParsedBody();
$output = [
'input' => $input,
'reservation' => null,
'success' => false,
'errors' => [],
];
$data = [];
foreach ($input as $key => $value) {
if (!str_starts_with($key, 'add_')) {
continue;
}
$data[substr($key, 4)] = $value;
}
try {
$output['reservation'] = $reservationService->add($data);
$output['success'] = true;
} catch (ServiceAction\Create $exception) {
$output['errors'] []= $this->parseError($exception);
}
return $this->withJson($response, $output);
}
public function edit(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Reservation $reservationService, int $reservation_id): ResponseInterface
{
$input = $request->getParsedBody();

View File

@ -1,6 +1,7 @@
<?php
namespace Incoviba\Model\Venta;
use DateTimeInterface;
use JsonSerializable;
use Incoviba\Model\Direccion;
@ -12,6 +13,7 @@ class Datos
public ?Direccion $direccion = null;
public ?int $telefono = null;
public ?string $email = null;
public ?DateTimeInterface $fecha_nacimiento = null;
public function jsonSerialize(): mixed
{
@ -21,7 +23,8 @@ class Datos
'profesion' => $this->profesion ?? '',
'direccion' => $this->direccion ?? '',
'telefono' => $this->telefono ?? '',
'email' => $this->email ?? ''
'email' => $this->email ?? '',
'fecha_nacimiento' => $this->fecha_nacimiento?->format('Y-m-d') ?? '',
];
}
}

View File

@ -68,7 +68,7 @@ class Reservation extends Common\Ideal\Model
public function addUnit(Model\Venta\Unidad $unit, float $value): self
{
if (($i = $this->findUnit($unit->id)) !== null) {
$this->units[$i]['value'] = $value;
$this->units[$i]->value = $value;
return $this;
}
$this->units[] = (object) [
@ -88,12 +88,7 @@ class Reservation extends Common\Ideal\Model
}
public function findUnit(int $unit_id): ?int
{
foreach ($this->units as $idx => $unit) {
if ($unit['unit']->id == $unit_id) {
return $idx;
}
}
return null;
return array_find_key($this->units, fn($unit) => $unit->unit->id == $unit_id);
}
public function hasUnit(int $unit_id): bool
{

View File

@ -3,8 +3,9 @@ namespace Incoviba\Model\Venta\Reservation\State;
enum Type: int
{
case ACTIVE = 1;
case INACTIVE = 0;
case ACTIVE = 1;
case PROMISED = 2;
case REJECTED = -1;
public function jsonSerialize(): array

View File

@ -93,7 +93,7 @@ class Contract extends Common\Ideal\Repository
->select('a.*')
->from("{$this->getTable()} a")
->joined($this->statusJoin())
->where('a.broker_rut = :broker_rut AND bcs.state = :state');
->where('a.broker_rut = :broker_rut AND bcs.type = :state');
return $this->fetchMany($query, ['broker_rut' => $brokerRut, 'state' => Model\Proyecto\Broker\Contract\Type::ACTIVE]);
}
@ -108,8 +108,8 @@ class Contract extends Common\Ideal\Repository
->select('a.*')
->from("{$this->getTable()} a")
->joined($this->statusJoin())
->where('a.proyecto_id = :proyecto_id AND bcs.state = :state');
return $this->fetchMany($query, ['proyecto_id' => $projectId, 'state' => Model\Proyecto\Broker\Contract\State\Type::ACTIVE->value]);
->where('a.project_id = :project_id AND bcs.type = :state');
return $this->fetchMany($query, ['project_id' => $projectId, 'state' => Model\Proyecto\Broker\Contract\State\Type::ACTIVE->value]);
}
/**

View File

@ -212,7 +212,7 @@ class Promotion extends Common\Ideal\Repository
->joined('LEFT OUTER JOIN proyecto_tipo_unidad ptu1 ON ptu.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) AND a.state = :state')
->group('a.id');
return $this->fetchMany($query, ['project_id' => $project_id, 'state' => Model\Venta\Promotion\State::ACTIVE]);
return $this->fetchMany($query, ['project_id' => $project_id, 'state' => Model\Venta\Promotion\State::ACTIVE->value]);
}
/**

View File

@ -45,15 +45,17 @@ class Reservation extends Common\Ideal\Repository
}
public function save(Common\Define\Model $model): Model\Venta\Reservation
{
$model->id = $this->saveNew([
'project_id',
'buyer_rut',
'date'
], [
$model->project->id,
$model->buyer->rut,
$model->date->format('Y-m-d')
]);
if (!isset($model->id)) {
$model->id = $this->saveNew([
'project_id',
'buyer_rut',
'date'
], [
$model->project->id,
$model->buyer->rut,
$model->date->format('Y-m-d')
]);
}
$this->saveUnits($model);
$this->savePromotions($model);
$this->saveBroker($model);
@ -440,10 +442,10 @@ class Reservation extends Common\Ideal\Repository
$query = $this->connection->getQueryBuilder()
->select()
->from('reservation_details')
->where('reservation_id = :id AND type = ?');
->where('reservation_id = :id AND type = :type');
$statement = $this->connection->execute($query, [
'id' => $reservation->id,
Model\Venta\Reservation\Detail\Type::Unit->value
'type' =>Model\Venta\Reservation\Detail\Type::Unit->value
]);
while ($result = $statement->fetch(PDO::FETCH_ASSOC)) {
@ -479,6 +481,13 @@ class Reservation extends Common\Ideal\Repository
}
return $reservation;
}
/**
* @param Model\Venta\Reservation $reservation
* @param array $new_data
* @return Model\Venta\Reservation
* @throws Common\Implement\Exception\EmptyResult
*/
protected function fetchBroker(Model\Venta\Reservation &$reservation, array $new_data): Model\Venta\Reservation
{
if (!array_key_exists('broker_id', $new_data)) {
@ -492,6 +501,9 @@ class Reservation extends Common\Ideal\Repository
'type' => Model\Venta\Reservation\Detail\Type::Broker->value
]);
$result = $statement->fetch(PDO::FETCH_ASSOC);
if ($result === false) {
throw new Common\Implement\Exception\EmptyResult($query);
}
$reservation->broker = $this->brokerRepository->fetchById($result['reference_id']);
} catch (PDOException) {}

View File

@ -19,12 +19,16 @@ class State extends Common\Ideal\Repository
public function create(?array $data = null): Model\Venta\Reservation\State
{
$map = (new Common\Implement\Repository\MapperParser(['type']))
$map = (new Common\Implement\Repository\MapperParser())
->register('reservation_id', (new Common\Implement\Repository\Mapper())
->setProperty('reservation')
->setFunction(function($data) {
return $this->reservationRepository->fetchById($data['reservation_id']);
}))
->register('type', (new Common\Implement\Repository\Mapper())
->setFunction(function($data) {
return Model\Venta\Reservation\State\Type::from($data['type']);
}))
->register('date', new Common\Implement\Repository\Mapper\DateTime('date'));
return $this->parseData(new Model\Venta\Reservation\State(), $data, $map);
}
@ -32,7 +36,7 @@ class State extends Common\Ideal\Repository
{
$model->id = $this->saveNew(
['reservation_id', 'date', 'type'],
[$model->reservation->id, $model->date->format('Y-m-d'), $model->type]
[$model->reservation->id, $model->date->format('Y-m-d'), $model->type->value]
);
return $model;
}

View File

@ -0,0 +1,49 @@
<?php
namespace Incoviba\Service;
use PDOException;
use Psr\Log\LoggerInterface;
use Incoviba\Common\Ideal;
use Incoviba\Common\Implement;
use Incoviba\Exception\ServiceAction;
use Incoviba\Model;
use Incoviba\Repository;
class Direccion extends Ideal\Service
{
public function __construct(LoggerInterface $logger, protected Repository\Direccion $direccionRepository)
{
parent::__construct($logger);
}
/**
* @param array $data
* @return Model\Direccion
* @throws ServiceAction\Create
*/
public function add(array $data): Model\Direccion
{
$dataMap = [
'street' => 'calle',
'number' => 'numero',
'comuna_id' => 'comuna',
];
foreach ($data as $key => $value) {
if (array_key_exists($key, $dataMap)) {
$data[$dataMap[$key]] = $value;
unset($data[$key]);
}
}
try {
return $this->direccionRepository->fetchByCalleAndNumeroAndExtraAndComuna($data['calle'], $data['numero'], $data['extra'], $data['comuna']);
} catch (Implement\Exception\EmptyResult) {
$filteredData = $this->direccionRepository->filterData($data);
$direccion = $this->direccionRepository->create($filteredData);
try {
return $this->direccionRepository->save($direccion);
} catch (PDOException $exception) {
throw new ServiceAction\Create(__CLASS__, $exception);
}
}
}
}

View File

@ -15,7 +15,8 @@ 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 Repository\Venta\Propietario $propietarioRepository,
protected Direccion $direccionService)
{
parent::__construct($logger);
}
@ -67,44 +68,34 @@ class Persona extends Ideal\Service
} catch (Implement\Exception\EmptyResult) {
try {
$propietario = $this->propietarioRepository->fetchById($data['rut']);
} catch (Implement\Exception\EmptyResult $exception) {
throw new Create(__CLASS__, $exception);
}
$data['rut'] = $propietario->rut;
$data['digito'] = $propietario->dv;
$data['nombres'] = $propietario->nombres;
$data['apellido_paterno'] = $propietario->apellidos['paterno'];
$data['apellido_materno'] = $propietario->apellidos['materno'] ?? '';
$persona = $this->personaRepository->create($data);
try {
$persona = $this->personaRepository->save($persona);
} catch (PDOException $exception) {
throw new Create(__CLASS__, $exception);
}
}
if (isset($data['direccion_id']) or isset($data['email']) or isset($data['telefono'])) {
$datosData = ['persona_rut' => $persona->rut];
if (isset($data['direccion_id'])) {
$datosData['direccion_id'] = $data['direccion_id'];
}
if (isset($data['email'])) {
$datosData['email'] = $data['email'];
}
if (isset($data['telefono'])) {
$datosData['telefono'] = $data['telefono'];
}
try {
$datos = $this->datosPersonaRepository->fetchByPersona($persona->rut);
$this->datosPersonaRepository->edit($datos, $data);
$persona = $this->addFromPropietario($propietario);
} catch (Implement\Exception\EmptyResult) {
$datos = $this->datosPersonaRepository->create($datosData);
$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 {
$this->datosPersonaRepository->save($datos);
$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);
}
@ -180,4 +171,129 @@ class Persona extends Ideal\Service
->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);
$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) {
$datosData = ['persona_rut' => $persona->rut];
/*if (isset($data['direccion_id'])) {
$datosData['direccion_id'] = $data['direccion_id'];
}
if (isset($data['email'])) {
$datosData['email'] = $data['email'];
}
if (isset($data['telefono'])) {
$datosData['telefono'] = $data['telefono'];
}
if (isset($data['estado_civil'])) {
$datosData['estado_civil'] = $data['estado_civil'];
}
if (isset($data['fecha_nacimiento'])) {
$datosData['fecha_nacimiento'] = $data['fecha_nacimiento'];
}
if (isset($data['ocupacion'])) {
$datosData['ocupacion'] = $data['ocupacion'];
}
if (isset($data['sexo'])) {
$datosData['sexo'] = $data['sexo'];
}*/
$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;
}
}

View File

@ -11,12 +11,16 @@ use Incoviba\Common\Implement;
use Incoviba\Exception\ServiceAction;
use Incoviba\Model;
use Incoviba\Repository;
use Incoviba\Service;
class Reservation extends Ideal\Service\API
{
public function __construct(LoggerInterface $logger,
protected Repository\Venta\Reservation $reservationRepository,
protected Repository\Venta\Reservation\State $stateRepository)
protected Repository\Venta\Reservation\State $stateRepository,
protected Service\Persona $personaService,
protected Service\Proyecto\Broker $brokerService,
protected Promotion $promotionService, protected Unidad $unitService)
{
parent::__construct($logger);
}
@ -91,22 +95,70 @@ class Reservation extends Ideal\Service\API
public function add(array $data): Model\Venta\Reservation
{
$date = new DateTimeImmutable();
try {
$date = new DateTimeImmutable();
try {
$date = new DateTimeImmutable($data['date']);
} catch (DateMalformedStringException) {}
return $this->process($this->reservationRepository->fetchByBuyerAndDate($data['buyer_rut'], $date));
} catch (Implement\Exception\EmptyResult) {}
$date = new DateTimeImmutable($data['date']);
} catch (DateMalformedStringException) {}
try {
$reservation = $this->reservationRepository->fetchByBuyerAndDate($data['buyer_rut'], $date);
try {
$reservationData = $this->reservationRepository->filterData($data);
$reservation = $this->reservationRepository->create($reservationData);
$this->reservationRepository->save($reservation);
return $this->process($reservation);
} catch (PDOException $exception) {
throw new ServiceAction\Create(__CLASS__, $exception);
if (array_key_exists('broker_rut', $data) and $data['broker_rut'] !== '') {
try {
$broker = $this->brokerService->get($data['broker_rut']);
$reservation = $this->reservationRepository->edit($reservation, ['broker_rut' => $broker->rut]);
} catch (ServiceAction\Read $exception) {}
}
} catch (Implement\Exception\EmptyResult) {
$buyerData = [];
foreach ($data as $key => $value) {
if (!str_starts_with($key, 'buyer_')) {
continue;
}
$buyerData[substr($key, 6)] = $value;
}
$this->personaService->add($buyerData);
if (array_key_exists('broker_rut', $data)) {
if (empty($data['broker_rut'])) {
unset($data['broker_rut']);
} else {
try {
$this->brokerService->get($data['broker_rut']);
} catch (ServiceAction\Read) {
unset($data['broker_rut']);
}
}
}
$data['date'] = $date->format('Y-m-d');
try {
$reservationData = $this->reservationRepository->filterData($data);
$reservation = $this->reservationRepository->create($reservationData);
$reservation = $this->reservationRepository->save($reservation);
try {
$stateType = Model\Venta\Reservation\State\Type::ACTIVE;
$stateData = [
'reservation_id' => $reservation->id,
'date' => $data['date'],
'type' => $stateType->value,
];
$state = $this->stateRepository->create($stateData);
$this->stateRepository->save($state);
} catch (PDOException $exception) {
$this->logger->warning($exception->getMessage(), ['reservation_id' => $reservation->id, 'exception' => $exception->getTraceAsString()]);
}
} catch (PDOException $exception) {
throw new ServiceAction\Create(__CLASS__, $exception);
}
}
$units = array_combine($data['units'], $data['units_value']);
$this->addUnits($reservation, $units);
if (isset($data['promotions'])) {
$this->addPromotions($reservation, $data['promotions']);
}
return $this->process($reservation);
}
public function edit(Define\Model $model, array $new_data): Model\Venta\Reservation
{
@ -136,4 +188,28 @@ class Reservation extends Ideal\Service\API
);
return $model;
}
protected function addUnits(Model\Venta\Reservation $reservation, array $units): void
{
foreach ($units as $unit_id => $value) {
try {
$unit = $this->unitService->getById($unit_id);
} catch (ServiceAction\Read) {
continue;
}
$reservation->addUnit($unit, $value);
}
$this->reservationRepository->save($reservation);
}
protected function addPromotions(Model\Venta\Reservation $reservation, array $promotions): void
{
foreach ($promotions as $promotion_id) {
try {
$promotion = $this->promotionService->getById($promotion_id);
} catch (ServiceAction\Read) {
continue;
}
$reservation->promotions []= $promotion;
}
$this->reservationRepository->save($reservation);
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace Tests\Extension;
use Psr\Container\ContainerInterface;
trait ContainerTrait
{
protected ContainerInterface $container;
protected function setUp(): void
{
parent::setUp();
require_once implode(DIRECTORY_SEPARATOR, [dirname(__DIR__, 2), 'setup', 'container.php']);
$this->container = buildContainer();
}
}

View File

@ -0,0 +1,117 @@
<?php
namespace Incoviba\Tests\Integration\API\Ventas;
use DateTimeImmutable;
use PHPUnit\Framework\TestCase;
use Faker;
use Incoviba\Common\Define;
use Incoviba\Common\Implement;
use Incoviba\Common\Ideal;
use Incoviba\Model;
use Incoviba\Service;
use Incoviba\Repository;
use Tests\Extension\AbstractIntegration;
use Tests\Extension\ContainerTrait;
use Tests\Extension\Faker\Provider\Rut;
class ReservationTest extends TestCase
{
use ContainerTrait;
public function testAdd(): void
{
$faker = Faker\Factory::create('es_CL');
$faker->addProvider(new Rut($faker));
$comunas = $this->container->get(Repository\Comuna::class)->fetchAll();
$projects = $this->container->get(Repository\Proyecto::class)->fetchAll();
$project = $faker->randomElement($projects);
$unitTypes = $this->container->get(Repository\Proyecto\TipoUnidad::class)->fetchAll();
$unitsRepository = $this->container->get(Repository\Venta\Unidad::class);
$units = [];
$unitsValue = [];
$unitsCount = $faker->numberBetween(1, 3);
for ($i = 0; $i < $unitsCount; $i++) {
$type = $faker->randomElement($unitTypes);
$units[] = $unitsRepository->fetchByProyectoAndTipo($project->id, $type->id);
$unitsValue[] = $faker->randomFloat(2, 1000, 10000);
}
$brokersCount = $faker->numberBetween(1, 3);
for ($i = 0; $i < $brokersCount; $i++) {
$rut = $faker->rut(false, false);
$brokerData = [
'rut' => $rut,
'digit' => $faker->digitoVerificador($rut),
'name' => $faker->firstName,
'legal_name' => $faker->company,
'contact' => $faker->name,
'email' => $faker->email,
'phone' => $faker->phoneNumber
];
$broker = $this->container->get(Repository\Proyecto\Broker::class)->create($brokerData);
$broker = $this->container->get(Repository\Proyecto\Broker::class)->save($broker);
$contractData = [
'project_id' => $project->id,
'broker_rut' => $broker->rut,
'commission' => $faker->randomFloat(4, 0, 1),
];
$contract = $this->container->get(Repository\Proyecto\Broker\Contract::class)->create($contractData);
$contract = $this->container->get(Repository\Proyecto\Broker\Contract::class)->save($contract);
$state = $this->container->get(Repository\Proyecto\Broker\Contract\State::class)->create([
'contract_id' => $contract->id,
'type' => Model\Proyecto\Broker\Contract\State\Type::ACTIVE->value,
'date' => $faker->dateTimeBetween('-2 months')->format('Y-m-d')
]);
$this->container->get(Repository\Proyecto\Broker\Contract\State::class)->save($state);
}
$contracts = $this->container->get(Repository\Proyecto\Broker\Contract::class)->fetchActiveByProject($project->id);
$broker = $faker->boolean(10) ? $faker->randomElement($contracts)->broker : null;
$activePromotions = $this->container->get(Repository\Venta\Promotion::class)->fetchActiveByProject($project->id);
$promotionsCount = $faker->numberBetween(0, 3);
$promotions = [];
for ($i = 0; $i < $promotionsCount; $i++) {
$promotions[] = $faker->randomElement($activePromotions)->id;
}
$rut = $faker->rut(false, false);
$data = [
'project_id' => $faker->randomElement($projects)->id,
'date' => $faker->dateTimeBetween('-2 years', 'now')->format('Y-m-d'),
'buyer_rut' => $rut,
'buyer_digit' => $faker->digitoVerificador($rut),
'buyer_names' => $faker->firstName,
'buyer_last_name' => $faker->lastName,
'buyer_last_name2' => $faker->lastName,
'buyer_email' => $faker->email,
'buyer_phone' => $faker->phoneNumber,
'buyer_address_street' => $faker->streetName,
'buyer_address_number' => $faker->buildingNumber,
'buyer_address_extra' => $faker->streetAddress,
'buyer_address_comuna_id' => $faker->randomElement($comunas)->id,
'units' => $units,
'units_value' => $unitsValue,
'broker_rut' => $broker ? $broker->rut : '',
];
if (count($promotions) > 0) {
$data['promotions'] = $promotions;
}
$reservation = $this->container->get(Service\Venta\Reservation::class)->add($data);
$this->assertInstanceOf(Model\Venta\Reservation::class, $reservation);
$this->assertEquals($data['date'], $reservation->date->format('Y-m-d'));
$this->assertEquals($data['project_id'], $reservation->project->id);
$this->assertEquals($data['buyer_rut'], $reservation->buyer->rut);
$this->assertEquals($data['buyer_digit'], $reservation->buyer->digito);
$this->assertEquals($data['buyer_names'], $reservation->buyer->nombres);
$this->assertEquals($data['buyer_last_name'], $reservation->buyer->apellido_paterno);
$this->assertEquals($data['buyer_last_name2'], $reservation->buyer->apellido_materno);
$this->assertEquals($data['buyer_email'], $reservation->buyer->datos->email);
$this->assertEquals($data['buyer_phone'], $reservation->buyer->datos->telefono);
$this->assertEquals($data['buyer_address_street'], $reservation->buyer->direccion->calle);
$this->assertEquals($data['buyer_address_number'], $reservation->buyer->direccion->numero);
$this->assertEquals($data['buyer_address_extra'], $reservation->buyer->direccion->extra);
$this->assertEquals($data['buyer_address_comuna_id'], $reservation->buyer->direccion->comuna->id);
$this->assertEquals($data['broker_rut'], $reservation->broker->rut);
}
}

View File

@ -11,17 +11,12 @@ use Incoviba\Common\Implement;
use Incoviba\Common\Ideal;
use Incoviba\Service;
use Incoviba\Repository;
use Tests\Extension\ContainerTrait;
use Tests\Extension\Faker\Provider\Rut;
class QueueTest extends TestCase
{
protected ContainerInterface $container;
protected function setUp(): void
{
require_once implode(DIRECTORY_SEPARATOR, [dirname(__DIR__, 2), 'setup', 'container.php']);
$this->container = buildContainer();
}
use ContainerTrait;
public function testServiceWorker(): void
{

View File

@ -13,7 +13,7 @@ class ReservationTest extends AbstractModel
protected function setUp(): void
{
$this->model = new Reservation();
$this->properties = ['buyer', 'date', 'units', 'promotions', 'broker'];
$this->properties = ['project', 'buyer', 'date', 'units', 'promotions', 'broker'];
$this->methods = ['states', 'currentState', 'addUnit', 'removeUnit', 'findUnit', 'hasUnit'];
}
}

View File

@ -0,0 +1,64 @@
<?php
namespace Incoviba\Test\Repository;
use PHPUnit\Framework\TestCase;
use Faker;
use Incoviba\Common\Define;
use Incoviba\Model;
use Incoviba\Repository;
class DireccionTest extends TestCase
{
protected Define\Connection $connection;
protected Repository\Comuna $comunaRepository;
protected function setUp(): void
{
$this->connection = $this->getMockBuilder(Define\Connection::class)
->disableOriginalConstructor()
->getMock();
$this->comunaRepository = $this->getMockBuilder(Repository\Comuna::class)
->disableOriginalConstructor()
->getMock();
$this->comunaRepository->method('fetchById')->willReturnCallback(function ($id) {
$comuna = new Model\Comuna();
$comuna->id = $id;
return $comuna;
});
}
public function testCreate(): void
{
$direccionRepository = new Repository\Direccion($this->connection, $this->comunaRepository);
$faker = Faker\Factory::create();
$data = [
'calle' => $faker->streetName,
'numero' => $faker->randomNumber(),
'extra' => $faker->streetSuffix,
'comuna' => $faker->randomNumber(),
];
$direccion = $direccionRepository->create($data);
$this->assertTrue(!isset($direccion->id));
$this->assertEquals($data['calle'], $direccion->calle);
$this->assertEquals($data['numero'], $direccion->numero);
$this->assertEquals($data['extra'], $direccion->extra);
$this->assertEquals($data['comuna'], $direccion->comuna->id);
}
public function testSave(): void
{
$direccionRepository = new Repository\Direccion($this->connection, $this->comunaRepository);
$faker = Faker\Factory::create();
$direccion = new Model\Direccion();
$direccion->calle = $faker->streetName;
$direccion->numero = $faker->randomNumber(3);
$direccion->extra = $faker->streetSuffix;
$direccion->comuna = $this->getMockBuilder(Model\Comuna::class)->getMock();
$direccion->comuna->id = $faker->numberBetween(10000, 18000);
$direccion = $direccionRepository->save($direccion);
$this->assertTrue(isset($direccion->id));
}
}

View File

@ -0,0 +1,62 @@
<?php
namespace Incoviba\Test\Repository;
use PHPUnit\Framework\TestCase;
use Faker;
use Incoviba\Common\Define;
use Incoviba\Model;
use Incoviba\Repository;
class PersonaTest extends TestCase
{
protected Define\Connection $connection;
protected function setUp(): void
{
$this->connection = $this->getMockBuilder(Define\Connection::class)
->disableOriginalConstructor()
->getMock();
}
public function testCreate(): void
{
$personaRepository = new Repository\Persona($this->connection);
$faker = Faker\Factory::create();
$data = [
'rut' => $faker->randomNumber(8),
'digito' => $faker->boolean(100 - round(1 / 11 * 100)) ? $faker->randomNumber(1) : 'K',
'nombres' => $faker->name(),
'apellido_paterno' => $faker->lastName(),
'apellido_materno' => $faker->lastName()
];
$persona = $personaRepository->create($data);
$this->assertEquals($data['rut'], $persona->rut);
$this->assertEquals($data['digito'], $persona->digito);
$this->assertEquals($data['nombres'], $persona->nombres);
$this->assertEquals($data['apellido_paterno'], $persona->apellidoPaterno);
$this->assertEquals($data['apellido_materno'], $persona->apellidoMaterno);
}
public function testSave(): void
{
$personaRepository = new Repository\Persona($this->connection);
$faker = Faker\Factory::create();
$data = [
'rut' => $faker->randomNumber(8),
'digito' => $faker->boolean(100 - round(1 / 11 * 100)) ? $faker->randomNumber(1) : 'K',
'nombres' => $faker->name(),
'apellido_paterno' => $faker->lastName(),
'apellido_materno' => $faker->lastName()
];
$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'];
$persona = $personaRepository->save($persona);
$this->assertEquals($data['rut'], $persona->rut);
}
}

View File

@ -0,0 +1,102 @@
<?php
namespace Incoviba\Test\Repository\Venta;
use DateTimeImmutable;
use PHPUnit\Framework\TestCase;
use Faker;
use Incoviba\Common\Define;
use Incoviba\Model;
use Incoviba\Repository;
class ReservationTest extends TestCase
{
protected Define\Connection $connection;
protected Repository\Proyecto $proyectoRepository;
protected Repository\Persona $personaRepository;
protected Repository\Proyecto\Broker $brokerRepository;
protected Repository\Venta\Unidad $unitRepository;
protected Repository\Venta\Promotion $promotionRepository;
protected function setUp(): void
{
$this->connection = $this->getMockBuilder(Define\Connection::class)
->disableOriginalConstructor()
->getMock();
$this->proyectoRepository = $this->getMockBuilder(Repository\Proyecto::class)
->disableOriginalConstructor()
->getMock();
$this->proyectoRepository->method('fetchById')->willReturnCallback(function ($id) {
$proyecto = new Model\Proyecto();
$proyecto->id = $id;
return $proyecto;
});
$this->personaRepository = $this->getMockBuilder(Repository\Persona::class)
->disableOriginalConstructor()
->getMock();
$this->personaRepository->method('fetchById')->willReturnCallback(function ($rut) {
$persona = new Model\Persona();
$persona->rut = $rut;
return $persona;
});
$this->brokerRepository = $this->getMockBuilder(Repository\Proyecto\Broker::class)
->disableOriginalConstructor()
->getMock();
$this->brokerRepository->method('fetchById')->willReturnCallback(function ($rut) {
$broker = new Model\Proyecto\Broker();
$broker->rut = $rut;
return $broker;
});
$this->unitRepository = $this->getMockBuilder(Repository\Venta\Unidad::class)
->disableOriginalConstructor()
->getMock();
$this->unitRepository->method('fetchById')->willReturnCallback(function ($id) {
$unidad = new Model\Venta\Unidad();
$unidad->id = $id;
return $unidad;
});
$this->promotionRepository = $this->getMockBuilder(Repository\Venta\Promotion::class)
->disableOriginalConstructor()
->getMock();
$this->promotionRepository->method('fetchById')->willReturnCallback(function ($id) {
$promotion = new Model\Venta\Promotion();
$promotion->id = $id;
return $promotion;
});
}
public function testCreate(): void
{
$reservationRepository = new Repository\Venta\Reservation($this->connection, $this->proyectoRepository,
$this->personaRepository, $this->brokerRepository, $this->unitRepository, $this->promotionRepository);
$faker = Faker\Factory::create();
$data = [
'project_id' => $faker->numberBetween(1, 10),
'buyer_rut' => $faker->randomNumber(8),
'date' => $faker->dateTimeBetween('-2 years', 'now')->format('Y-m-d'),
];
$reservation = $reservationRepository->create($data);
$this->assertTrue(!isset($reservation->id));
$this->assertEquals($data['project_id'], $reservation->project->id);
$this->assertEquals($data['buyer_rut'], $reservation->buyer->rut);
$this->assertEquals($data['date'], $reservation->date->format('Y-m-d'));
}
public function testSave(): void
{
$reservationRepository = new Repository\Venta\Reservation($this->connection, $this->proyectoRepository,
$this->personaRepository, $this->brokerRepository, $this->unitRepository, $this->promotionRepository);
$faker = Faker\Factory::create();
$data = [
'project_id' => $faker->numberBetween(1, 10),
'buyer_rut' => $faker->randomNumber(8),
'date' => $faker->dateTimeBetween('-2 years', 'now')->format('Y-m-d'),
];
$reservation = new Model\Venta\Reservation();
$reservation->project = $this->proyectoRepository->fetchById($data['project_id']);
$reservation->buyer = $this->personaRepository->fetchById($data['buyer_rut']);
$reservation->date = new DateTimeImmutable($data['date']);
$reservation = $reservationRepository->save($reservation);
$this->assertTrue(isset($reservation->id));
}
}

View File

@ -0,0 +1,64 @@
<?php
namespace Incoviba\Test\Service;
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;
class DireccionTest extends TestCase
{
protected LoggerInterface $logger;
protected Repository\Direccion $direccionRepository;
protected function setUp(): void
{
$this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
$this->direccionRepository = $this->getMockBuilder(Repository\Direccion::class)
->disableOriginalConstructor()
->getMock();
$this->direccionRepository->method('fetchByCalleAndNumeroAndExtraAndComuna')
->willThrowException(new Implement\Exception\EmptyResult(''));
$this->direccionRepository->method('filterData')->willReturnArgument(0);
$this->direccionRepository->method('create')->willReturnCallback(function($data) {
$direccion = new Model\Direccion();
$direccion->calle = $data['calle'];
$direccion->numero = $data['numero'];
$direccion->extra = $data['extra'];
$direccion->comuna = $this->getMockBuilder(Model\Comuna::class)
->disableOriginalConstructor()->getMock();
$direccion->comuna->id = $data['comuna'];
return $direccion;
});
$this->direccionRepository->method('save')->willReturnCallback(function($direccion) {
$direccion->id = 1;
return $direccion;
});
}
public function testAdd(): void
{
$direccionService = new Service\Direccion($this->logger, $this->direccionRepository);
$faker = Faker\Factory::create('es_ES');
$data = [
'street' => $faker->streetName,
'number' => $faker->randomNumber(3),
'extra' => $faker->word,
'comuna_id' => $faker->numberBetween(10000, 18000),
];
$direccion = $direccionService->add($data);
$this->assertEquals($data['street'], $direccion->calle);
$this->assertEquals($data['number'], $direccion->numero);
$this->assertEquals($data['extra'], $direccion->extra);
$this->assertEquals($data['comuna_id'], $direccion->comuna->id);
}
}

View File

@ -0,0 +1,65 @@
<?php
namespace Incoviba\Test\Service;
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;
class PersonaTest extends TestCase
{
protected LoggerInterface $logger;
protected Repository\Persona $personaRepository;
protected Repository\Persona\Datos $datosPersonaRepository;
protected Repository\Venta\Propietario $propietarioRepository;
protected Service\Direccion $direccionService;
protected function setUp(): void
{
$this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
$this->personaRepository = $this->getMockBuilder(Repository\Persona::class)
->disableOriginalConstructor()->getMock();
$this->personaRepository->method('fetchById')->willThrowException(new Implement\Exception\EmptyResult(''));
$this->personaRepository->method('filterData')->willReturnArgument(0);
$this->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;
});
$this->personaRepository->method('save')->willReturnArgument(0);
$this->datosPersonaRepository = $this->getMockBuilder(Repository\Persona\Datos::class)
->disableOriginalConstructor()->getMock();
$this->propietarioRepository = $this->getMockBuilder(Repository\Venta\Propietario::class)
->disableOriginalConstructor()->getMock();
$this->propietarioRepository->method('fetchById')->willThrowException(new Implement\Exception\EmptyResult(''));
$this->direccionService = $this->getMockBuilder(Service\Direccion::class)
->disableOriginalConstructor()->getMock();
}
public function testAdd(): void
{
$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';
$data = [
'rut' => $faker->randomNumber(8),
'digito' => $digit,
'nombres' => $faker->name(),
'apellido_paterno' => $faker->lastName(),
'apellido_materno' => $faker->lastName(),
];
$persona = $personaService->add($data);
$this->assertEquals($data['rut'], $persona->rut);
}
}

View File

@ -1,5 +1,5 @@
<?php
namespace Inventario\Service\Venta;
namespace Incoviba\Test\Service\Venta;
use DateTimeImmutable;
use PHPUnit\Framework\TestCase;
@ -70,4 +70,4 @@ class PagoTest extends TestCase
$this->assertTrue($status);
$this->assertEquals($pago->uf, $this->uf);
}
}
}

View File

@ -0,0 +1,118 @@
<?php
namespace Incoviba\Tests\Unit\Service\Venta;
use DateTimeImmutable;
use Psr\Log\LoggerInterface;
use PHPUnit\Framework\TestCase;
use Faker;
use Incoviba\Common\Implement;
use Incoviba\Model;
use Incoviba\Repository;
use Incoviba\Service;
class ReservationTest extends TestCase
{
protected LoggerInterface $logger;
protected Repository\Venta\Reservation $reservationRepository;
protected Repository\Venta\Reservation\State $stateRepository;
protected Service\Persona $personaService;
protected Service\Proyecto\Broker $brokerService;
protected Service\Venta\Promotion $promotionService;
protected Service\Venta\Unidad $unitService;
protected function setUp(): void
{
$this->logger = $this->getMockBuilder(LoggerInterface::class)
->disableOriginalConstructor()->getMock();
$this->reservationRepository = $this->getMockBuilder(Repository\Venta\Reservation::class)
->disableOriginalConstructor()->getMock();
$this->reservationRepository->method('fetchByBuyerAndDate')->willThrowException(new Implement\Exception\EmptyResult(''));
$this->reservationRepository->method('filterData')->willReturnArgument(0);
$this->reservationRepository->method('create')->willReturnCallback(function($data) {
$reservation = new Model\Venta\Reservation();
$reservation->buyer = $this->getMockBuilder(Model\Persona::class)->disableOriginalConstructor()->getMock();
$reservation->buyer->rut = $data['buyer_rut'];
$reservation->project = $this->getMockBuilder(Model\Proyecto::class)->disableOriginalConstructor()->getMock();
$reservation->project->id = $data['project_id'];
$reservation->date = new DateTimeImmutable($data['date']);
if (array_key_exists('broker_rut', $data)) {
$reservation->broker = $this->getMockBuilder(Model\Proyecto\Broker::class)->disableOriginalConstructor()->getMock();
$reservation->broker->rut = $data['broker_rut'];
}
return $reservation;
});
$this->reservationRepository->method('save')->willReturnCallback(function($reservation) {
$reservation->id = 1;
return $reservation;
});
$this->stateRepository = $this->getMockBuilder(Repository\Venta\Reservation\State::class)
->disableOriginalConstructor()->getMock();
$this->personaService = $this->getMockBuilder(Service\Persona::class)
->disableOriginalConstructor()->getMock();
$this->personaService->method('add')->willReturnCallback(function($data) {
$persona = new Model\Persona();
$persona->rut = $data['rut'];
return $persona;
});
$this->brokerService = $this->getMockBuilder(Service\Proyecto\Broker::class)
->disableOriginalConstructor()->getMock();
$this->promotionService = $this->getMockBuilder(Service\Venta\Promotion::class)
->disableOriginalConstructor()->getMock();
$this->unitService = $this->getMockBuilder(Service\Venta\Unidad::class)
->disableOriginalConstructor()->getMock();
$this->unitService->method('getById')->willReturnCallback(function($id) {
$unit = new Model\Venta\Unidad();
$unit->id = $id;
return $unit;
});
}
public function testAdd(): void
{
$faker = Faker\Factory::create();
$reservationService = new Service\Venta\Reservation($this->logger, $this->reservationRepository,
$this->stateRepository, $this->personaService, $this->brokerService, $this->promotionService,
$this->unitService);
$units = [];
$unitsValue = [];
$unitsCount = $faker->numberBetween(1, 10);
for ($i = 0; $i < $unitsCount; $i++) {
$units[] = $faker->numberBetween(1, 100);
$unitsValue[] = $faker->randomFloat(2, 1000, 10000);
}
$digit = $faker->boolean(100-round(1/11*100)) ? $faker->randomNumber(1) : 'K';
$broker = $faker->boolean(10) ? $faker->randomNumber(8, true) : '';
$promotions = [];
$promotionsCount = $faker->numberBetween(0, 10);
for ($i = 0; $i < $promotionsCount; $i++) {
$promotions[] = $faker->numberBetween(1, 100);
}
$data = [
'project_id' => $faker->numberBetween(1, 100),
'date' => $faker->dateTimeBetween('-1 year', 'now')->format('Y-m-d'),
'buyer_rut' => $faker->randomNumber(8, true),
'buyer_digit' => $digit,
'buyer_names' => $faker->firstName(),
'buyer_last_name' => $faker->lastName(),
'buyer_last_name2' => $faker->lastName(),
'buyer_address_street' => $faker->streetName(),
'buyer_address_number' => $faker->randomNumber(3),
'buyer_address_comuna' => $faker->numberBetween(10000, 18000),
'buyer_marital_status' => $faker->word(),
'buyer_email' => $faker->email(),
'buyer_phone' => $faker->randomNumber(9),
'buyer_profession' => $faker->word(),
'buyer_birthdate' => $faker->dateTimeBetween('-80 year', '-18 year')->format('Y-m-d'),
'units' => $units,
'units_value' => $unitsValue,
'broker_rut' => $broker,
'promotions' => $promotions
];
$reservation = $reservationService->add($data);
$this->assertEquals($data['project_id'], $reservation->project->id);
$this->assertEquals($data['buyer_rut'], $reservation->buyer->rut);
$this->assertCount($unitsCount, $reservation->units);
}
}