Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
María Hidalgo
/
carpooling-dae
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
bb34dd1b
authored
Oct 10, 2023
by
María Hidalgo
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Modificaciones realizadas
parent
cdf72f89
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
223 additions
and
143 deletions
pom.xml
src/main/java/es/ujaen/dae/carpoolingdae/entidades/Reserva.java
src/main/java/es/ujaen/dae/carpoolingdae/entidades/Usuario.java
src/main/java/es/ujaen/dae/carpoolingdae/entidades/Viaje.java
src/main/java/es/ujaen/dae/carpoolingdae/excepciones/NoAceptaConductor.java
src/main/java/es/ujaen/dae/carpoolingdae/servicios/SistemaCarpooling.java
src/test/java/es/ujaen/dae/carpoolingdae/entidades/ViajeTest.java
src/test/java/es/ujaen/dae/carpoolingdae/servicios/SistemaCarpoolingTest.java
pom.xml
View file @
bb34dd1b
...
...
@@ -29,11 +29,11 @@
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> -->
<dependency>
<!--
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.7.Final</version>
</dependency>
</dependency>
-->
<dependency>
<groupId>
mysql
</groupId>
<artifactId>
mysql-connector-java
</artifactId>
...
...
src/main/java/es/ujaen/dae/carpoolingdae/entidades/Reserva.java
deleted
100644 → 0
View file @
cdf72f89
package
es
.
ujaen
.
dae
.
carpoolingdae
.
entidades
;
/* import java.util.ArrayList;
import java.util.List; */
import
javax.persistence.Entity
;
import
javax.persistence.GeneratedValue
;
import
javax.persistence.GenerationType
;
import
javax.persistence.Id
;
@Entity
public
class
Reserva
{
@Id
@GeneratedValue
(
strategy
=
GenerationType
.
IDENTITY
)
int
id
;
// @OneToMany
// private List<Usuario> pasajerosConfirmados = new ArrayList<>();
// Constructor, getters y setters
}
src/main/java/es/ujaen/dae/carpoolingdae/entidades/Usuario.java
View file @
bb34dd1b
...
...
@@ -3,8 +3,6 @@ package es.ujaen.dae.carpoolingdae.entidades;
import
java.time.LocalDate
;
import
java.util.ArrayList
;
import
javax.persistence.Entity
;
import
javax.persistence.Id
;
import
javax.validation.constraints.Email
;
import
javax.validation.constraints.NotBlank
;
import
javax.validation.constraints.Past
;
...
...
@@ -13,6 +11,7 @@ import javax.validation.constraints.Size;
import
java.util.List
;
import
es.ujaen.dae.carpoolingdae.excepciones.PlazaNoDisponible
;
import
es.ujaen.dae.carpoolingdae.utils.CodificadorMd5
;
//import org.hibernate.mapping.List;
...
...
@@ -28,17 +27,16 @@ import lombok.NoArgsConstructor;
*/
@Data
@NoArgsConstructor
@Entity
public
class
Usuario
{
// Lista de viajes como conductor
private
List
<
Viaje
>
viajesComoConductor
;
List
<
Viaje
>
viajesComoConductor
;
// Lista de viajes como pasajero
private
List
<
Viaje
>
viajesComoPasajero
;
List
<
Viaje
>
viajesComoPasajero
;
@NotBlank
@Id
@Size
(
min
=
9
,
max
=
9
)
@Pattern
(
regexp
=
ExprReg
.
DNI
)
String
dni
;
...
...
@@ -100,9 +98,6 @@ public class Usuario {
return
email
;
}
public
List
<
Viaje
>
getviajesComoConductor
()
{
return
viajesComoConductor
;
}
/**
* Compara la clave con la del usuario, codificándola en Md5
...
...
@@ -114,5 +109,29 @@ public class Usuario {
public
boolean
claveValida
(
String
clave
)
{
return
clave
.
equals
(
clave
);
}
public
void
agregarViajeComoConductor
(
Viaje
viaje
)
{
// Agregar el viaje a la lista de viajes del usuario como conductor
viajesComoConductor
.
add
(
viaje
);
}
public
void
enviarSolicitudParaSerPasajero
(
Viaje
viaje
)
{
if
(!
viaje
.
usuariosSolicitantes
.
contains
(
this
)
&&
viaje
.
getPlazas
()
>
0
)
{
viaje
.
usuariosSolicitantes
.
add
(
this
);
}
else
{
throw
new
PlazaNoDisponible
();
}
}
/* public void confirmarPasajero(Viaje viaje) {
if (viajesComoConductor.contains(viaje) && viaje.usuariosSolicitantes.contains(this)) {
viaje.usuariosSolicitantes.remove(this);
viaje.usuariosConfirmados.add(this);
} else {
throw new NoAceptaConductor();
}
} */
}
src/main/java/es/ujaen/dae/carpoolingdae/entidades/Viaje.java
View file @
bb34dd1b
...
...
@@ -4,28 +4,24 @@ import java.time.LocalDateTime;
import
java.util.ArrayList
;
import
java.util.List
;
import
javax.persistence.GeneratedValue
;
import
javax.persistence.GenerationType
;
import
javax.persistence.Id
;
import
javax.persistence.ManyToOne
;
import
javax.validation.Valid
;
import
javax.validation.constraints.NotBlank
;
import
javax.validation.constraints.NotNull
;
import
javax.validation.constraints.Past
;
import
es.ujaen.dae.carpoolingdae.excepciones.PlazaNoDisponible
;
import
es.ujaen.dae.carpoolingdae.excepciones.NoAceptaConductor
;
public
class
Viaje
{
// Lista de usuarios que solicitan unirse a un viaje
private
List
<
Usuario
>
usuariosSolicitantes
=
new
ArrayList
<>();
List
<
Usuario
>
usuariosSolicitantes
=
new
ArrayList
<>();
// Lista de usuarios que son confirmados en un viaje
private
List
<
Usuario
>
usuariosConfirmados
=
new
ArrayList
<>();
@ManyToOne
private
Usuario
conductor
;
List
<
Usuario
>
usuariosConfirmados
=
new
ArrayList
<>();
@Id
@GeneratedValue
(
strategy
=
GenerationType
.
IDENTITY
)
//@GeneratedValue(strategy = GenerationType.IDENTITY)
int
id
;
@NotBlank
...
...
@@ -43,6 +39,8 @@ public class Viaje {
@NotBlank
Double
precioAsiento
;
private
Usuario
conductor
;
public
Viaje
(
int
id
,
String
destino
,
String
origen
,
LocalDateTime
fecha_hora
,
int
plazasDisponibles
,
Double
precioAsiento
)
{
this
.
id
=
id
;
...
...
@@ -78,19 +76,24 @@ public class Viaje {
return
precioAsiento
;
}
public
List
<
Usuario
>
getUsuariosSolicitantes
()
{
return
usuariosSolicitantes
;
}
public
List
<
Usuario
>
getusuariosConfirmados
()
{
return
usuariosConfirmados
;
// Método para obtener el conductor del viaje
public
Usuario
getConductor
()
{
return
conductor
;
}
public
void
setConductor
(
Usuario
conductor
)
{
this
.
conductor
=
conductor
;
}
public
void
addPasajero
(
Usuario
pasajero
)
{
public
List
<
Usuario
>
getUsuariosConfirmados
(){
return
usuariosConfirmados
;
}
public
List
<
Usuario
>
getUsuariosSolicitantes
(){
return
usuariosSolicitantes
;
}
/* public void addPasajero(Usuario pasajero) {
if (plazasDisponibles > 0) {
usuariosConfirmados.add(pasajero);
plazasDisponibles--;
...
...
@@ -98,6 +101,28 @@ public class Viaje {
throw new PlazaNoDisponible();
}
} */
public
void
reducePlazasDisponibles
(
@NotNull
@Valid
Viaje
viaje
)
{
if
(
plazasDisponibles
>
0
)
{
plazasDisponibles
--;
}
}
public
void
confirmarPasajero
(
@NotNull
@Valid
Usuario
pasajero
)
{
// Verificar si el usuario que acepta es el conductor del viaje
if
(!
this
.
getConductor
().
equals
(
conductor
))
{
throw
new
NoAceptaConductor
();
}
// Verificar si el pasajero está en la lista de solicitantes
if
(
usuariosSolicitantes
.
contains
(
pasajero
))
{
// Mover al pasajero de la lista de solicitantes a la lista de confirmados
usuariosSolicitantes
.
remove
(
pasajero
);
usuariosConfirmados
.
add
(
pasajero
);
}
}
}
src/main/java/es/ujaen/dae/carpoolingdae/excepciones/NoAceptaConductor.java
0 → 100644
View file @
bb34dd1b
package
es
.
ujaen
.
dae
.
carpoolingdae
.
excepciones
;
public
class
NoAceptaConductor
extends
RuntimeException
{
public
NoAceptaConductor
()
{
}
}
src/main/java/es/ujaen/dae/carpoolingdae/servicios/SistemaCarpooling.java
View file @
bb34dd1b
...
...
@@ -17,7 +17,7 @@ import org.springframework.validation.annotation.Validated;
import
es.ujaen.dae.carpoolingdae.entidades.Usuario
;
import
es.ujaen.dae.carpoolingdae.entidades.Viaje
;
import
es.ujaen.dae.carpoolingdae.excepciones.
PlazaNoDisponible
;
import
es.ujaen.dae.carpoolingdae.excepciones.
NoAceptaConductor
;
import
es.ujaen.dae.carpoolingdae.excepciones.UsuarioNoRegistrado
;
import
es.ujaen.dae.carpoolingdae.excepciones.UsuarioYaRegistrado
;
import
es.ujaen.dae.carpoolingdae.excepciones.ViajeNoExistente
;
...
...
@@ -59,8 +59,11 @@ public class SistemaCarpooling {
* @param clave la clave de acceso
* @return el objeto de la clase Viaje asociado
*/
public
Optional
<
Usuario
>
loginUsuario
(
@NotBlank
String
email
,
@NotBlank
String
clave
)
{
return
Optional
.
ofNullable
(
usuarios
.
get
(
email
)).
filter
((
cliente
)
->
cliente
.
claveValida
(
clave
));
public
Usuario
loginUsuario
(
@NotBlank
String
email
,
@NotBlank
String
clave
)
{
return
Optional
.
ofNullable
(
usuarios
.
get
(
email
))
.
filter
(
cliente
->
cliente
.
claveValida
(
clave
))
.
orElseThrow
(
UsuarioNoRegistrado:
:
new
);
}
/**
...
...
@@ -72,7 +75,7 @@ public class SistemaCarpooling {
* @return viajes encontrados con esos datos
*/
public
List
<
Viaje
>
buscarViajes
(
String
origen
,
String
destino
,
LocalDate
fecha
)
{
public
List
<
Viaje
>
buscarViajes
(
@NotBlank
String
origen
,
@NotBlank
String
destino
,
@NotBlank
LocalDate
fecha
)
{
List
<
Viaje
>
viajesEncontrados
=
new
ArrayList
<>();
for
(
Viaje
viaje
:
viajes
.
values
())
{
// Iterar sobre la colección de viajes
if
(
viaje
.
getOrigen
().
equals
(
origen
)
&&
viaje
.
getDestino
().
equals
(
destino
)
...
...
@@ -86,41 +89,30 @@ public class SistemaCarpooling {
}
public
void
agregarViaje
(
@NotBlank
String
dni
,
@NotNull
@Valid
Viaje
viaje
)
{
// Verificar si el usuario conductor existe en la base de datos
Usuario
conductor
=
usuarios
.
get
(
dni
);
if
(
conductor
==
null
)
{
throw
new
UsuarioNoRegistrado
();
}
public
void
agregarViaje
(
@NotNull
@Valid
Usuario
conductor
,
@NotNull
@Valid
Viaje
viaje
)
{
// Asignar el conductor al viaje
viaje
.
setConductor
(
conductor
);
//
Agregar el viaje a la lista de viajes del conductor (si es necesario)
conductor
.
getviajesComoConductor
().
add
(
viaje
);
//
Llamar a la función en Usuario para agregar el viaje como conductor
conductor
.
agregarViajeComoConductor
(
viaje
);
// Agregar el viaje al mapa de viajes
viajes
.
put
(
String
.
valueOf
(
viaje
.
getId
()),
viaje
);
}
/**
* Enviar solicitud para ser pasajero de un viaje
*
* @param viaje al que se envía la solicitud
*/
public
void
enviarSolicitudViaje
(
Viaje
viaje
,
Usuario
pasajero
)
{
if
(
viaje
!=
null
&&
!
viaje
.
getUsuariosSolicitantes
().
contains
(
pasajero
)
&&
viaje
.
getPlazas
()
>
0
)
{
// Envía la
// solicitud
// solo si
// hay
// plazas
// disponibles
viaje
.
getUsuariosSolicitantes
().
add
(
pasajero
);
// Agregar este usuario a la lista de solicitantes en el Viaje
}
else
{
throw
new
PlazaNoDisponible
();
}
public
void
enviarSolicitudViaje
(
@NotNull
@Valid
Viaje
viaje
,
@NotNull
@Valid
Usuario
pasajero
)
{
// Llamar a la función en Usuario para enviar la solicitud
pasajero
.
enviarSolicitudParaSerPasajero
(
viaje
);
}
/**
* Aceptar pasajero en un viaje
*
...
...
@@ -128,13 +120,24 @@ public class SistemaCarpooling {
* @param pasajero que es aceptado en el viaje
*/
public
void
aceptarPasajero
(
@NotNull
@Valid
Viaje
viaje
,
Usuario
pasajero
)
{
if
(
viaje
!=
null
&&
viaje
.
getUsuariosSolicitantes
().
contains
(
pasajero
)
&&
pasajero
.
getviajesComoConductor
().
contains
(
viaje
))
{
// SOLO PUEDE ACEPTAR EL
// CONDUCTOR
viaje
.
getUsuariosSolicitantes
().
remove
(
pasajero
);
viaje
.
getusuariosConfirmados
().
add
(
pasajero
);
/* public void aceptarPasajero(@NotNull @Valid Viaje viaje, @NotNull @Valid Usuario pasajero) {
// Llamar a la función en Usuario para confirmar al pasajero
viaje.confirmarPasajero(pasajero);
// Reducir el número de plazas disponibles en el viaje
viaje.reducePlazasDisponibles(viaje);
} */
public
void
aceptarPasajero
(
@NotNull
@Valid
Usuario
conductor
,
@NotNull
@Valid
Viaje
viaje
,
@NotNull
@Valid
Usuario
pasajero
)
{
// Verifica si el viaje está en la lista de viajes del conductor
if
(!
conductor
.
getViajesComoConductor
().
contains
(
viaje
))
{
throw
new
NoAceptaConductor
();
}
// Llamar a la función en Viaje para confirmar al pasajero
viaje
.
confirmarPasajero
(
pasajero
);
}
}
\ No newline at end of file
src/test/java/es/ujaen/dae/carpoolingdae/entidades/ViajeTest.java
View file @
bb34dd1b
package
es
.
ujaen
.
dae
.
carpoolingdae
.
entidades
;
import
java.util.List
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertFalse
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
org.assertj.core.api.Assertions
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.test.annotation.DirtiesContext
;
import
org.springframework.test.annotation.DirtiesContext.MethodMode
;
import
es.ujaen.dae.carpoolingdae.excepciones.NoAceptaConductor
;
import
es.ujaen.dae.carpoolingdae.servicios.SistemaCarpooling
;
public
class
ViajeTest
{
@Autowired
SistemaCarpooling
sistemaCarpooling
;
public
ViajeTest
()
{
}
private
Viaje
viaje
;
/* //
private Viaje viaje;
@Test
void testAddPasajero() {
Usuario
pasajero
=
new
Usuario
();
// Crea una instancia de Reserva adecuada para el test
Usuario pasajero = new Usuario("12345678A",
"Conductor",
"Apellido",
LocalDate.of(1990, 1, 1),
"123456789",
"conductor@example.com",
"clave");
Viaje viaje = new Viaje(
12345,
"Origen",
"Destino",
LocalDateTime.of(2023, 9, 30, 8, 0),
2,
50.0);
viaje.addPasajero(pasajero);
List
<
Usuario
>
usuariosConfirmados
=
viaje
.
getusuariosConfirmados
();
Assertions
.
assertThat
(
1
).
isEqualTo
(
usuariosConfirmados
.
size
());
Assertions
.
assertThat
(
pasajero
).
isEqualTo
(
usuariosConfirmados
.
get
(
0
));
assertTrue(viaje.getUsuariosConfirmados().contains(pasajero));
} */
@Test
@DirtiesContext
(
methodMode
=
MethodMode
.
AFTER_METHOD
)
public
void
testAceptarPasajero
()
{
// Crear un usuario conductor
Usuario
conductor
=
new
Usuario
(
"12345678A"
,
"Conductor"
,
"Apellido"
,
LocalDate
.
of
(
1990
,
1
,
1
),
"123456789"
,
"conductor@example.com"
,
"clave"
);
// Crear un usuario pasajero
Usuario
pasajero
=
new
Usuario
(
"87654321B"
,
"Pasajero"
,
"Apellido"
,
LocalDate
.
of
(
1995
,
5
,
5
),
"987654321"
,
"pasajero@example.com"
,
"clave"
);
// Crear un viaje
Viaje
viaje
=
new
Viaje
(
12345
,
"Origen"
,
"Destino"
,
LocalDateTime
.
of
(
2023
,
9
,
30
,
8
,
0
),
2
,
50.0
);
viaje
.
setConductor
(
conductor
);
// Agregar el viaje al sistema
sistemaCarpooling
.
agregarViaje
(
conductor
,
viaje
);
// Enviar solicitud de viaje
sistemaCarpooling
.
enviarSolicitudViaje
(
viaje
,
pasajero
);
// Aceptar al pasajero en el viaje llamando a la función en Viaje
try
{
viaje
.
confirmarPasajero
(
pasajero
);
}
catch
(
NoAceptaConductor
e
)
{
// Manejar la excepción si el conductor no es el correcto (opcional)
e
.
printStackTrace
();
}
// Verificar que el pasajero está en la lista de usuarios confirmados en el viaje
assertTrue
(
viaje
.
usuariosConfirmados
.
contains
(
pasajero
));
// Verificar que el pasajero ya no está en la lista de solicitantes del viaje
assertFalse
(
viaje
.
usuariosSolicitantes
.
contains
(
pasajero
));
}
}
src/test/java/es/ujaen/dae/carpoolingdae/servicios/SistemaCarpoolingTest.java
View file @
bb34dd1b
...
...
@@ -9,16 +9,19 @@ import java.time.LocalDateTime;
import
java.util.List
;
import
java.util.Optional
;
import
javax.validation.ConstraintViolationException
;
import
org.assertj.core.api.Assertions
;
import
java.util.Set
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
org.springframework.test.annotation.DirtiesContext
;
import
org.springframework.test.annotation.DirtiesContext.MethodMode
;
import
org.springframework.test.context.ActiveProfiles
;
import
javax.validation.ConstraintViolation
;
import
javax.validation.Validation
;
import
javax.validation.Validator
;
import
es.ujaen.dae.carpoolingdae.entidades.Usuario
;
//import es.ujaen.dae.carpoolingdae.utils.CodificadorMd5;
...
...
@@ -44,9 +47,9 @@ public class SistemaCarpoolingTest {
}
@Test
@DirtiesContext
(
methodMode
=
MethodMode
.
AFTER_METHOD
)
public
void
testAltaUsuarioInvalido
()
{
void
testValidacionUsuario
()
{
String
clave
=
"mariahm"
;
Usuario
usuario
=
new
Usuario
(
"22334455H"
,
"María"
,
...
...
@@ -56,13 +59,27 @@ public class SistemaCarpoolingTest {
"mhm@red.ujaen.es"
,
clave
);
Assertions
.
assertThatThrownBy
(()
->
{
sistemaCarpooling
.
altaUsuario
(
usuario
);
}).
isInstanceOf
(
ConstraintViolationException
.
class
);
Validator
validator
=
Validation
.
buildDefaultValidatorFactory
().
getValidator
();
Set
<
ConstraintViolation
<
Usuario
>>
violations
=
validator
.
validate
(
usuario
);
Assertions
.
assertThat
(
violations
).
isEmpty
();
}
// Damos de alta el usuario
@Test
void
testComprobacionClave
()
{
String
clave
=
"mariahm"
;
Usuario
usuario
=
new
Usuario
(
"22334455H"
,
"María"
,
"Hidalgo Morcillo"
,
LocalDate
.
of
(
1990
,
11
,
1
),
"189273810"
,
"mhm@red.ujaen.es"
,
clave
);
Assertions
.
assertThat
(
usuario
.
claveValida
(
clave
)).
isTrue
();
}
@Test
@DirtiesContext
(
methodMode
=
MethodMode
.
AFTER_METHOD
)
public
void
testAltaYLoginUsuario
()
{
...
...
@@ -77,7 +94,7 @@ public class SistemaCarpoolingTest {
clave
);
// Cuenta cuenta = servicioUjaCoin.altaCliente(cliente);
Optional
<
Usuario
>
usuarioLogin
=
sistemaCarpooling
.
loginUsuario
(
usuario
.
getEmail
(),
"clave"
);
List
<
Usuario
>
usuarioLogin
=
sistemaCarpooling
.
loginUsuario
(
usuario
.
getEmail
(),
"clave"
);
Assertions
.
assertThat
(
usuarioLogin
.
isPresent
()).
isTrue
();
Assertions
.
assertThat
(
usuarioLogin
.
get
()).
isEqualTo
(
usuario
);
...
...
@@ -199,53 +216,6 @@ public class SistemaCarpoolingTest {
assertTrue
(
viaje
.
getUsuariosSolicitantes
().
contains
(
pasajero
));
}
@Test
@DirtiesContext
(
methodMode
=
MethodMode
.
AFTER_METHOD
)
public
void
testAceptarPasajero
()
{
// Crear un usuario conductor
Usuario
conductor
=
new
Usuario
(
"12345678A"
,
"Conductor"
,
"Apellido"
,
LocalDate
.
of
(
1990
,
1
,
1
),
"123456789"
,
"conductor@example.com"
,
"clave"
);
// Crear un usuario pasajero
Usuario
pasajero
=
new
Usuario
(
"87654321B"
,
"Pasajero"
,
"Apellido"
,
LocalDate
.
of
(
1995
,
5
,
5
),
"987654321"
,
"pasajero@example.com"
,
"clave"
);
// Crear un viaje
Viaje
viaje
=
new
Viaje
(
12345
,
"Origen"
,
"Destino"
,
LocalDateTime
.
of
(
2023
,
9
,
30
,
8
,
0
),
2
,
50.0
);
viaje
.
setConductor
(
conductor
);
// Agregar el viaje al sistema
sistemaCarpooling
.
agregarViaje
(
conductor
.
getDni
(),
viaje
);
// Enviar solicitud de viaje
sistemaCarpooling
.
enviarSolicitudViaje
(
viaje
,
pasajero
);
// Aceptar al pasajero en el viaje
sistemaCarpooling
.
aceptarPasajero
(
viaje
,
pasajero
);
// Verificar que el pasajero está en la lista de usuarios confirmados en el
// viaje
assertTrue
(
viaje
.
getusuariosConfirmados
().
contains
(
pasajero
));
// Verificar que el pasajero ya no está en la lista de solicitantes del viaje
assertFalse
(
viaje
.
getUsuariosSolicitantes
().
contains
(
pasajero
));
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment