Microservicios con colecciones dinámicas en jmoordbcore
Published: 2024-05-18 02:53:08

Las bases de datos dinámicas y colecciones solo aplican para entidades que no contengan documentos referenciados.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pwzlng9filtjxrc3fn5t.png)

Para implementarlo se permite entidades que contengan o no documentos embebidos.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lz6ejld6qw4xzjw05kg3.png)




En el Controller especifique la colección dinámica 

```java
  tarjetaRepository.setDynamicCollection(nameOfCollection + idproyecto);
```

Observe que el parámetro idproyecto lo recibe el endpoint y con el se genera la nueva colección.


```java

@Path("tarjeta")
@Tag(name = "Información del tarjeta", description = "End-point para entidad Tarjeta")
@RolesAllowed({"admin"})
@RequestScoped
public class TarjetaController implements Serializable{

    private String nameOfCollection = "tarjeta_";

    @Inject
    TarjetaRepository tarjetaRepository;
    @Inject
    HistoryRepository historyRepository;



    @GET
    @RolesAllowed({"admin"})
    @Path("idtarjetaidproyecto")
   
    public Tarjeta findByIdtarjetaIdproyecto(@QueryParam("idtarjeta") Long idtarjeta, @QueryParam("idproyecto") Long idproyecto) {
      
        tarjetaRepository.setDynamicCollection(nameOfCollection + idproyecto);
        return tarjetaRepository.findByPk(idtarjeta).orElseThrow(
                () -> new WebApplicationException("No hay tarjeta con idtarjeta " + idtarjeta, Response.Status.NOT_FOUND));

    }

    @POST
    @RolesAllowed({"admin"})
   
    public Response save(
            @RequestBody(description = "Crea un nuevo tarjeta.", content = @Content(mediaType = "application/json", schema = @Schema(implementation = Tarjeta.class))) Tarjeta tarjeta) {
     tarjetaRepository.setDynamicCollection(nameOfCollection + tarjeta.getIdproyecto());
        Optional<Tarjeta> tarjetaOptional = tarjetaRepository.save(tarjeta);
        if (tarjetaOptional.isPresent()) {
            saveHistory(tarjeta);

            return Response.status(201).entity(tarjetaOptional.get()).build();
        } else {
            return Response.status(400).entity("Error " + tarjetaRepository.getJmoordbException().getLocalizedMessage()).build();
        }

    }


    @PUT
    @RolesAllowed({"admin"})
    
    public Response update(
            @RequestBody(description = "Crea un nuevo tarjeta.", content = @Content(mediaType = "application/json", schema = @Schema(implementation = Tarjeta.class))) Tarjeta tarjeta) {
       tarjetaRepository.setDynamicCollection(nameOfCollection + tarjeta.getIdproyecto());
        if (tarjetaRepository.update(tarjeta)) {
            saveHistory(tarjeta);
            return Response.status(201).entity(tarjeta).build();
        } else {
            return Response.status(400).entity("Error " + tarjetaRepository.getJmoordbException().getLocalizedMessage()).build();
        }
    }


   
    @DELETE
    @RolesAllowed({"admin"})
    @Path("idtarjetaidproyecto")
    
    public Response delete(@QueryParam("idtarjeta") Long idtarjeta, @QueryParam("idproyecto") Long idproyecto) {
        tarjetaRepository.setDynamicCollection(nameOfCollection + idproyecto);
        if (tarjetaRepository.deleteByPk(idtarjeta) == 0L) {
            return Response.status(201).entity(Boolean.TRUE).build();
        } else {
            return Response.status(400).entity("Error " + tarjetaRepository.getJmoordbException().getLocalizedMessage()).build();
        }
    }

   
    @DELETE
    @Path("deletemany")
    @RolesAllowed({"admin"})
     public Response deleteMany(@QueryParam("filter") String filter, @QueryParam("idproyecto") Long idproyecto) {
        tarjetaRepository.setDynamicCollection(nameOfCollection + idproyecto);
        Search search = DocumentUtil.convertForLookup(filter, "", 0, 0);
        if (tarjetaRepository.deleteMany(search) == 0L) {
            return Response.status(201).entity(Boolean.TRUE).build();
        } else {
            return Response.status(400).entity("Error " + tarjetaRepository.getJmoordbException().getLocalizedMessage()).build();
        }
    }
    
    @GET
    @Path("lookup")
    @RolesAllowed({"admin"})
    
    public List<Tarjeta> lookup(@QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size, @QueryParam("idproyecto") Long idproyecto) {
        List<Tarjeta> suggestions = new ArrayList<>();
        try {
            tarjetaRepository.setDynamicCollection(nameOfCollection + idproyecto);
            Search search = DocumentUtil.convertForLookup(filter, sort, page, size);

            suggestions = tarjetaRepository.lookup(search);

        } catch (Exception e) {

            MessagesUtil.error(MessagesUtil.nameOfClassAndMethod() + "error: " + e.getLocalizedMessage());
        }

        return suggestions;
    }

    @GET
    @Path("count")
    @RolesAllowed({"admin"})
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})

    public Long count(@QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size, @QueryParam("idproyecto") Long idproyecto) {
        Long result = 0L;
        try {
            tarjetaRepository.setDynamicCollection(nameOfCollection + idproyecto);
            Search search = DocumentUtil.convertForLookup(filter, sort, page, size);
            result = tarjetaRepository.count(search);

        } catch (Exception e) {

            MessagesUtil.error(MessagesUtil.nameOfClassAndMethod() + "error: " + e.getLocalizedMessage());
        }

        return result;
    }

  
  
    @GET
    @Path("countlikebytarjeta")
    @RolesAllowed({"admin"})
     @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})

    public Long countLikeByTarjeta(@QueryParam("tarjeta") String tarjeta, @QueryParam("idproyecto") Long idproyecto) {
        Long result = 0L;
        try {
            tarjetaRepository.setDynamicCollection(nameOfCollection + idproyecto);
            result = tarjetaRepository.countLikeByTarjeta(tarjeta);

        } catch (Exception e) {

            MessagesUtil.error(MessagesUtil.nameOfClassAndMethod() + "error: " + e.getLocalizedMessage());
        }

        return result;
    }

  
    @GET
    @Path("countlikebydescripcion")
    @RolesAllowed({"admin"})
     @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})

    public Long countLikeByDescripcion(@QueryParam("descripcion") String descripcion, @QueryParam("idproyecto") Long idproyecto) {
        Long result = 0L;
        try {
            tarjetaRepository.setDynamicCollection(nameOfCollection + idproyecto);
            result = tarjetaRepository.countLikeByDescripcion(descripcion);

        } catch (Exception e) {

            MessagesUtil.error(MessagesUtil.nameOfClassAndMethod() + "error: " + e.getLocalizedMessage());
        }

        return result;
    }

   
    @GET
    @Path("likebytarjeta")
    @RolesAllowed({"admin"})
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})

    public List<Tarjeta> likeByName(@QueryParam("tarjeta") String tarjeta, @QueryParam("idproyecto") Long idproyecto) {
        List<Tarjeta> suggestions = new ArrayList<>();
        try {
            tarjetaRepository.setDynamicCollection(nameOfCollection + idproyecto);
            suggestions = tarjetaRepository.likeByTarjeta(tarjeta);

        } catch (Exception e) {

            MessagesUtil.error(MessagesUtil.nameOfClassAndMethod() + "error: " + e.getLocalizedMessage());
        }

        return suggestions;
    }

   
    @GET
    @Path("likebytarjetasearch")
    @RolesAllowed({"admin"})
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public List<Tarjeta> searchLikeByTarjeta(@QueryParam("tarjeta") String tarjeta, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size, @QueryParam("idproyecto") Long idproyecto) {
        List<Tarjeta> suggestions = new ArrayList<>();
        try {
            tarjetaRepository.setDynamicCollection(nameOfCollection + idproyecto);
            Search search = DocumentUtil.convertForLookup(filter, sort, page, size);
            suggestions = tarjetaRepository.searchLikeByTarjeta(tarjeta, search);
        } catch (Exception e) {
            MessagesUtil.error(MessagesUtil.nameOfClassAndMethod() + "error: " + e.getLocalizedMessage());
        }
        return suggestions;
    }

    
    @GET
    @Path("likebydescripcionsearch")
    @RolesAllowed({"admin"})
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public List<Tarjeta> searchLikeByDescripcion(@QueryParam("descripcion") String descripcion, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size, @QueryParam("idproyecto") Long idproyecto) {
        List<Tarjeta> suggestions = new ArrayList<>();
        try {
            tarjetaRepository.setDynamicCollection(nameOfCollection + idproyecto);
            Search search = DocumentUtil.convertForLookup(filter, sort, page, size);
            suggestions = tarjetaRepository.searchLikeByDescripcion(descripcion, search);
        } catch (Exception e) {
            MessagesUtil.error(MessagesUtil.nameOfClassAndMethod() + "error: " + e.getLocalizedMessage());
        }
        return suggestions;
    }

   
   
   
}

```


El repositorio tendría una estructura similar a 

```java
@Repository(database = "{mongodb.database1}", entity = Tarjeta.class)
public interface TarjetaRepository extends CrudRepository<Tarjeta, Long> {

    @Lookup
    public List<Tarjeta> lookup(Search search);

    @Count()
    public Long count(Search... search);
    
    @CountLikeBy(caseSensitive = CaseSensitive.NO, likeByType = LikeByType.ANYWHERE)
    public Long countLikeByTarjeta(String tarjeta);
       
    @CountLikeBy(caseSensitive = CaseSensitive.NO, likeByType = LikeByType.ANYWHERE)
    public Long countLikeByDescripcion(String descripcion);

    @SearchCountLikeBy(caseSensitive = CaseSensitive.NO, likeByType = LikeByType.ANYWHERE)
    public Long searchCountLikeByTarjeta(String tarjeta, Search search);
    
    @SearchCountLikeBy(caseSensitive = CaseSensitive.NO, likeByType = LikeByType.ANYWHERE)
    public Long searchCountLikeByDescripcion(String descripcion, Search search);
    
    @LikeBy(caseSensitive = CaseSensitive.NO, typeOrder = TypeOrder.ASC, likeByType = LikeByType.ANYWHERE)
    public List<Tarjeta> likeByTarjeta(String tarjeta);
    
    @LikeBy(caseSensitive = CaseSensitive.NO, typeOrder = TypeOrder.ASC, likeByType = LikeByType.ANYWHERE)
    public List<Tarjeta> likeByTarjetaPagination(String tarjeta, Pagination pagination);
    
   
    
    @LikeBy(caseSensitive = CaseSensitive.NO, typeOrder = TypeOrder.ASC, likeByType = LikeByType.ANYWHERE)
    public List<Tarjeta> likeByDescripcion(String descripcion);


   @SearchLikeBy(caseSensitive = CaseSensitive.NO, typeOrder = TypeOrder.ASC, likeByType = LikeByType.ANYWHERE)
    public List<Tarjeta> searchLikeByTarjeta(String tarjeta, Search search);

    @SearchLikeBy(caseSensitive = CaseSensitive.NO, typeOrder = TypeOrder.ASC, likeByType = LikeByType.ANYWHERE)
    public List<Tarjeta> searchLikeByDescripcion(String descripcion, Search search);

    @Find
    public List<Tarjeta> findByFechainicialGreaterThanEqualAndFechafinalLessThanEqual(@ExcludeTime Date start, @ExcludeTime Date end);
}

```


---

## En el cliente utilizamos Microprofile Rest-Client

En el archivo microprofile-config.properties

```
com.sft.restclient.TarjetaRestClient/mp-rest/url=http://localhost:9002/accreditation/api/
```


### Crear el RestClient

```java

 @RegisterRestClient()
@Path("/tarjeta")

//@ApplicationScoped
public interface TarjetaRestClient {

@GET
    @Path("idtarjetaidproyecto")
    public Tarjeta findByIdtarjetaproyecto(@QueryParam("idtarjeta") Long idtarjeta, @QueryParam("idproyecto") Long idproyecto);

 @GET
    @Path("tarjeta")
    public List<Tarjeta> findByTarjeta(@Parameter(description = "El tarjeta", required = true, example = "1", schema = @Schema(type = SchemaType.STRING)) @QueryParam("tarjeta") final String tarjeta,@QueryParam("idproyecto") Long idproyecto);
//// </editor-fold>

    

    // <editor-fold defaultstate="collapsed" desc="Response save">
    @POST

    public Response save(@RequestBody(description = "Crea un nuevo tarjeta.", content = @Content(mediaType = "application/json", schema = @Schema(implementation = Tarjeta.class))) Tarjeta tarjeta);
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Response update">

    @PUT

    public Response update(@RequestBody(description = "Actualiza la tarjeta.", content = @Content(mediaType = "application/json", schema = @Schema(implementation = Tarjeta.class))) Tarjeta tarjeta);

// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Response delete">
    @DELETE
//    @Path("{idtarjeta}")
    @Path("idtarjetaidproyecto")
//    public Response delete(@Parameter(description = "El elemento idtarjeta", required = true, example = "1", schema = @Schema(type = SchemaType.NUMBER)) @PathParam("idtarjeta") Long idtarjeta);
    public Response delete(@QueryParam("idtarjeta") Long idtarjeta, @QueryParam("idproyecto") Long idproyecto);
    // </editor-fold>
    
    
    // <editor-fold defaultstate="collapsed" desc="Response deleteMany(@QueryParam("filter") String filter ,@QueryParam("idproyecto") Long idproyecto)">
     @DELETE
     @Path("deletemany")
public Response deleteMany(@QueryParam("filter") String filter ,@QueryParam("idproyecto") Long idproyecto ) ;
  // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="List<Tarjeta> lookup(@QueryParam("filter") String filter, @QueryParam("sort") String sort,  @QueryParam("page") Integer page, @QueryParam("size") Integer size,@QueryParam("idproyecto") Long idproyecto)">
    @GET
    @Path("lookup")
    public List<Tarjeta> lookup(@QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size,@QueryParam("idproyecto") Long idproyecto);
    // </editor-fold>    
    
    
 // <editor-fold defaultstate="collapsed" desc="public Long count(@QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size,@QueryParam("idproyecto") Long idproyecto);">
    @GET
    @Path("count")
    public Long count(@QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size,@QueryParam("idproyecto") Long idproyecto);
    // </editor-fold>    

    // <editor-fold defaultstate="collapsed" desc="Long countLikeByTarjeta(@QueryParam("tarjeta") String tarjeta,@QueryParam("idproyecto") Long idproyecto)">
    @GET
   @Path("countlikebytarjeta")
     public Long countLikeByTarjeta(@QueryParam("tarjeta") String tarjeta,@QueryParam("idproyecto") Long idproyecto);
    // </editor-fold>    
 
    // <editor-fold defaultstate="collapsed" desc="Long countLikeByDescripcion(@QueryParam("descripcion") String descripcion,@QueryParam("idproyecto") Long idproyecto)">
    @GET
   @Path("countlikebydescripcion")
     public Long countLikeByDescripcion(@QueryParam("descripcion") String descripcion,@QueryParam("idproyecto") Long idproyecto);
    // </editor-fold>    
 

// <editor-fold defaultstate="collapsed" desc="public List<Tarjeta> likeByTarjeta(@QueryParam("tarjeta") String tarjeta,@QueryParam("idproyecto") Long idproyecto)">

    @GET
    @Path("likebytarjeta")
    public List<Tarjeta> likeByTarjeta(@QueryParam("tarjeta") String tarjeta,@QueryParam("idproyecto") Long idproyecto);
    // </editor-fold>
// <editor-fold defaultstate="collapsed" desc="public List<Tarjeta> likeByTarjetaPagination(@QueryParam("tarjeta") String tarjeta, @QueryParam("pagination") Pagination pagination,@QueryParam("idproyecto") Long idproyecto)">

    @GET
    @Path("likebytarjetapagination")
    public List<Tarjeta> likeByTarjetaPagination(@QueryParam("tarjeta") String tarjeta, @QueryParam("page") Integer page, @QueryParam("size") Integer siz,@QueryParam("idproyecto") Long idproyectoe);
    // </editor-fold>


// <editor-fold defaultstate="collapsed" desc="List<Tarjeta> likeByDescripcion(@QueryParam("descripcion") String descripcion,@QueryParam("idproyecto") Long idproyecto)">

    @GET
    @Path("likebydescripcion")
    public List<Tarjeta> likeByDescripcion(@QueryParam("descripcion") String descripcion,@QueryParam("idproyecto") Long idproyecto);
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="List<Tarjeta> betweenDate(@QueryParam("fechainicial") Date fechainicial, @QueryParam("fechafinal") Date fechafinal,@QueryParam("idproyecto") Long idproyecto)">
      @GET
    @Path("betweendate")
    public List<Tarjeta> betweenDate(@QueryParam("fechainicial") Date fechainicial, @QueryParam("fechafinal") Date fechafinal,@QueryParam("idproyecto") Long idproyecto) ;
    // </editor-fold>
    
    
    
    @GET
    @Path("likebytarjetasearch")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    List<Tarjeta> searchLikeByTarjeta(@QueryParam("tarjeta") String tarjeta, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size,@QueryParam("idproyecto") Long idproyecto);
    
   
    @GET
    @Path("searchcountlikebytarjeta")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
   public  Long searchCountLikeByTarjeta(@QueryParam("tarjeta") String tarjeta, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size,@QueryParam("idproyecto") Long idproyecto);

   
    @GET
    @Path("likebydescripcionsearch")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    List<Tarjeta> searchLikeByDescripcion(@QueryParam("descripcion") String descripcion, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size,@QueryParam("idproyecto") Long idproyecto);
    
    
    @GET
    @Path("searchcountlikebydescripcion")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
   public  Long searchCountLikeByDescripcion(@QueryParam("descripcion") String descripcion, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size,@QueryParam("idproyecto") Long idproyecto);
}

```


### Crear TarjetaServices

```java
public interface TarjetaServices {
//     public List<Tarjeta> findAll();
    public Optional<Tarjeta> save(Tarjeta tarjeta);

    public Boolean update(Tarjeta tarjeta);

    public Boolean deleteMany(Bson filter,Long idproyecto);

//    public Optional<Tarjeta> findByIdtarjeta(Long idtarjeta);
    public Optional<Tarjeta> findByIdtarjetaIdproyecto(Long idtarjeta, Long idproyecto);

    public List<Tarjeta> lookup(Bson filter, Document sort, Integer page, Integer size, Long idproyecto);

    public Boolean tarjetaExistInSprint(String tarjetaName, Long idproyecto, Long idsprint);

    public Boolean tarjetaExistInBacklog(String tarjetaName, Long idproyecto, Long idsprint);

    public Optional<Tarjeta> tarjetaConIgualNombreInSprint(String tarjetaName, Long idproyecto, Long idsprint);

    public Long count(Bson filter, Document sort, Integer page, Integer size, Long idproyecto);

    public Long totalPorColumna(Proyecto proyecto, String columna, Boolean storeInBacklog);

    public List<Comentario> ordenarComentarioPorFechaDescendente(Tarjeta tarjeta);

    public List<Tarea> ordenarTareaPorCompletadoDescendente(Tarjeta tarjeta);
    public List<Tarea> ordenarTareaPorOrden(Tarjeta tarjeta);

    public List<Impedimento> ordenarImpedimentoDescendente(Tarjeta tarjeta);

    public Boolean isMiembroAutorizedInTarjetaForanea(Tarjeta tarjeta, User userLogged, UserView userViewForaneo);

    public Boolean equalsExcludedNameOfTarjeta(Tarjeta tarjeta, Tarjeta other);

    public Boolean isEstimacionValida(Tarjeta tarjeta);

    public String colorTarjeta(Tarjeta tarjeta);

    public Long countLikeByTarjeta(String tarjeta, Long idproyecto);

    public Long countLikeByDescripcion(String descripcion, Long idproyecto);

    public List<Tarjeta> likeByTarjeta(String tarjeta, Long idproyecto);

    public List<Tarjeta> likeByTarjetaPagination(String tarjeta, Pagination pagination, Long idproyecto);

    public List<Tarjeta> likeByDescripcion(String descripcion, Long idproyecto);

    public List<Tarjeta> betweenDate(@QueryParam("fechainicial") Date fechainicial, @QueryParam("fechafinal") Date fechafinal, Long idproyecto);

    public List<Tarjeta> searchLikeByTarjeta(String tarjeta, Bson filter, Document sort, Integer page, Integer size, Long idproyecto);
    public Long searchCountLikeByTarjeta(String tarjeta, Bson filter, Document sort, Integer page, Integer size, Long idproyecto);
    
    public List<Tarjeta> searchLikeByDescripcion(String descripcion, Bson filter, Document sort, Integer page, Integer size, Long idproyecto);
        public Long searchCountLikeByDescripcion(String descripcion, Bson filter, Document sort, Integer page, Integer size, Long idproyecto);
    

    public List<Tarjeta> validarFechaFinalEsteSprintActual(List<Tarjeta> list, Sprint sprint);
    public List<Tarjeta> validarFechaFinalSprintPlanTrabajo(List<Tarjeta> list, Sprint sprint);
    
    public List<Tarjeta> orderListForIdTarjetaReserve(List<Tarjeta> list);
    
    public Integer positionOfTarjeta(Tarjeta tarjeta, List<Tarjeta> tarjetas);
    
    public TotalesTarjetasEstadistica calcularTotalesTarjetasEstadistica(Long iduser, Long idproyecto);
    
            
   
}

```

### Crear la implementación

```java
@ApplicationScoped
public class TarjetaServicesImpl implements TarjetaServices {
// <editor-fold defaultstate="collapsed" desc="@Inject">

    @Inject
    JmoordbResourcesFiles rf;
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Microprofile Rest Client">
    @Inject
    TarjetaRestClient tarjetaRestClient;
    @Inject
    TarjetaServices tarjetaServices;
// </editor-fold>

//    // <editor-fold defaultstate="collapsed" desc="List<Tarjeta> findAll()">
//    @Override
//    public List<Tarjeta> findAll() {
//        return tarjetaRestClient.findAll();
//    }
//// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Boolean update(Tarjeta tarjeta)">

    @Override
    public Boolean update(Tarjeta tarjeta) {
        Boolean result = Boolean.FALSE;
        try {

            Integer status = tarjetaRestClient.update(tarjeta).getStatus();

            if (status == 201) {
                result = Boolean.TRUE;
            }

        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }
// </editor-fold>

//    // <editor-fold defaultstate="collapsed" desc="Optional<Tarjeta> findByIdtarjeta(Long idtarjeta)">
//    @Override
//    public Optional<Tarjeta> findByIdtarjeta(Long idtarjeta) {
//
//        try {
//            Tarjeta result = tarjetaRestClient.findByIdtarjeta(idtarjeta);
//            if (result == null || result.getIdtarjeta() == null) {
//
//            } else {
//                return Optional.of(result);
//            }
//        } catch (Exception e) {
//            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
//        }
//        return Optional.empty();
//
//    }
//    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Optional<Tarjeta> findByIdtarjetaIdproyecto(Long idtarjeta, Long idproyecto)">
    @Override
    public Optional<Tarjeta> findByIdtarjetaIdproyecto(Long idtarjeta, Long idproyecto) {

        try {
            ConsoleUtil.test("\t >>>>>"+FacesUtil.nameOfClassAndMethod() + " <<<<<");
            ConsoleUtil.test("\t >>> idtarjeta "+idtarjeta + " idproyecto "+idproyecto);
            Tarjeta result = tarjetaRestClient.findByIdtarjetaproyecto(idtarjeta,idproyecto);
            ConsoleUtil.test("\t llego a 2");
            if (result == null || result.getIdtarjeta() == null) {

            } else {
                return Optional.of(result);
            }
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return Optional.empty();

    }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="List<Tarjeta> lookup(Bson filter, Document sort, Integer page, Integer size, Long idproyecto)">

    @Override
    public List<Tarjeta> lookup(Bson filter, Document sort, Integer page, Integer size, Long idproyecto) {
        List<Tarjeta> tarjetaList = new ArrayList<>();
        try {

            tarjetaList = tarjetaRestClient.lookup(
                    EncodeUtil.encodeBson(filter),
                    EncodeUtil.encodeBson(sort),
                    page, size, idproyecto);

        } catch (Exception e) {

            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }

        return tarjetaList;
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Boolean deleteMany(Bson filter, Long idproyecto) ">

    @Override
    public Boolean deleteMany(Bson filter, Long idproyecto) {
        Boolean result = Boolean.FALSE;
        try {
            Integer status = tarjetaRestClient.deleteMany(EncodeUtil.encodeBson(filter),idproyecto).getStatus();
            if (status == 201) {
                result = Boolean.TRUE;
            }
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }
// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Long count(Bson filter, Document sort, Integer page, Integer size, Long idproyecto)">
    @Override
    public Long count(Bson filter, Document sort, Integer page, Integer size, Long idproyecto) {
        Long result = 0L;
        try {
            result = tarjetaRestClient.count(
                    EncodeUtil.encodeBson(filter),
                    EncodeUtil.encodeBson(sort),
                    page, size,idproyecto);
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Optional<Tarjeta>(Tarjeta tarjeta)">
    @Override
    public Optional<Tarjeta> save(Tarjeta tarjeta) {
        try {

            Response response = tarjetaRestClient.save(tarjeta);

            if (response.getStatus() == 400) {

                String error = (response.readEntity(String.class));

                return Optional.empty();
            }

            Tarjeta result = (Tarjeta) (response.readEntity(Tarjeta.class));

            return Optional.of(result);

        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return Optional.empty();
    }
// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Boolean tarjetaExist(String tarjetaName, Long idproyecto, Long idsprint)">
    @Override
    public Boolean tarjetaExistInSprint(String tarjetaName, Long idproyecto, Long idsprint) {
        Boolean result = Boolean.FALSE;
        try {
            Integer page = 0;
            Integer size = 0;
            Bson filter = and(
                    eq("idproyecto", idproyecto),
                    eq("idsprint", idsprint),
                    eq("active", true),
                    eq("tarjeta", tarjetaName)
            );

            Document sort = new Document("idtarjeta", 1);
            if (count(filter, sort, page, size,idproyecto) > 0) {
                result = Boolean.TRUE;
            }

        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }

    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Boolean tarjetaExist(Bson filter, Document sort, Integer page, Integer size)">
    @Override
    public Boolean tarjetaExistInBacklog(String tarjetaName, Long idproyecto, Long idsprint) {
        Boolean result = Boolean.FALSE;
        try {
            Integer page = 0;
            Integer size = 0;
            Bson filter = and(
                    eq("idproyecto", idproyecto),
                    eq("idsprint", 0L),
                    eq("active", true),
                    eq("tarjeta", tarjetaName)
            );

            Document sort = new Document("idtarjeta", 1);
            if (count(filter, sort, page, size,idproyecto) > 0) {
                result = Boolean.TRUE;
            }

        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }

    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc=" List<Tarjeta> tarjetaConIgualNombreInSprint(String tarjetaName, Long idproyecto, Long idsprint)">
    @Override
    public Optional<Tarjeta> tarjetaConIgualNombreInSprint(String tarjetaName, Long idproyecto, Long idsprint) {
        Optional<Tarjeta> result = Optional.empty();
        try {
            Integer page = 0;
            Integer size = 0;
            Bson filter = and(
                    eq("idproyecto", idproyecto),
                    eq("idsprint", idsprint),
                    eq("active", true),
                    eq("tarjeta", tarjetaName)
            );

            Document sort = new Document("idtarjeta", 1);
            List<Tarjeta> list = lookup(filter, sort, page, size,idproyecto);
            if (list == null || list.isEmpty()) {
                return Optional.empty();
            }
            result = Optional.of(list.get(0));
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }

    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="List<Comentario> ordenarComentario(Tarjeta tarjeta) ">
    /**
     * Ordena los comentarios por fecha
     *
     * @param tarjeta
     * @return
     */
    @Override
    public List<Comentario> ordenarComentarioPorFechaDescendente(Tarjeta tarjeta) {
        List<Comentario> result = new ArrayList<>();
        try {

            if (tarjeta.getComentario() == null || tarjeta.getComentario().isEmpty()) {
                return result;
            }
            Comparator<Comentario> comparator
                    = (c1, c2) -> c1.getFecha().compareTo(c2.getFecha());

            tarjeta.getComentario().sort(comparator.reversed());

        } catch (Exception e) {
//            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return tarjeta.getComentario();
    }

    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Boolean isMiembroAutorizedInTarjetaForanea(Tarjeta tarjeta, User userLogged, UserView userViewForaneo)">
    @Override
    public Boolean isMiembroAutorizedInTarjetaForanea(Tarjeta tarjeta, User userLogged, UserView userViewForaneo) {
        Boolean result = Boolean.FALSE;
        try {
            if (tarjeta.getForeaneo()) {
                if (userViewForaneo.getIduser().equals(userLogged.getIduser())) {

                } else {
                    result = Boolean.TRUE;
                }
            } else {
                result = Boolean.TRUE;
            }
        } catch (Exception e) {
//            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="List<Comentario> ordenarTareaPorCompletadoDescendente(Tarjeta tarjeta) ">
    @Override
    public List<Tarea> ordenarTareaPorCompletadoDescendente(Tarjeta tarjeta) {
        List<Tarea> result = new ArrayList<>();
        try {

            if (tarjeta.getTarea() == null || tarjeta.getTarea().isEmpty()) {
                return result;
            }
            Comparator<Tarea> comparator
                    = (c1, c2) -> c1.getCompletado().compareTo(c2.getCompletado());

            tarjeta.getTarea().sort(comparator);
//           tarjeta.getTarea().sort(comparator.reversed());

        } catch (Exception e) {
//            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return tarjeta.getTarea();
    }

    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="List<Tarea> ordenarTareaPorOrden(Tarjeta tarjeta)">
    @Override
    public List<Tarea> ordenarTareaPorOrden(Tarjeta tarjeta) {
        List<Tarea> result = new ArrayList<>();
        try {
            if (tarjeta.getTarea() == null || tarjeta.getTarea().isEmpty()) {
                return result;
            }
            Comparator<Tarea> comparator
                    = (c1, c2) -> c1.getOrden().compareTo(c2.getOrden());

            tarjeta.getTarea().sort(comparator);

        } catch (Exception e) {
//            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return tarjeta.getTarea();
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="List<Impedimento> ordenarImpedimentoDescendente(Tarjeta tarjeta) ">
    @Override
    public List<Impedimento> ordenarImpedimentoDescendente(Tarjeta tarjeta) {
        List<Impedimento> result = new ArrayList<>();
        try {

            if (tarjeta.getImpedimento() == null || tarjeta.getImpedimento().isEmpty()) {
                return result;
            }
            Comparator<Impedimento> comparator
                    = (c1, c2) -> c1.getImpedimento().compareTo(c2.getImpedimento());

            tarjeta.getImpedimento().sort(comparator.reversed());

        } catch (Exception e) {
//            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return tarjeta.getImpedimento();
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Long totalPorColumna(Proyecto proyecto, String columna,Boolean storeInBacklog) ">
    /**
     * *
     *
     * @param proyecto
     * @param columna
     * @param storeInBacklog
     * @return devuelve el total de columnas
     */
    @Override
    public Long totalPorColumna(Proyecto proyecto, String columna, Boolean storeInBacklog) {
        Long result = 0L;

        try {
            Integer page = 0;
            Integer size = 0;
            Document sortTarjeta = new Document("idtarjeta", 1);
            /**
             * CargarTarjetas
             */

            if (!storeInBacklog) {
                Bson filter0 = eq("idproyecto", proyecto.getIdproyecto());
                Bson filter = and(filter0, eq("active", Boolean.TRUE),
                        eq("columna", columna));
                result = count(filter, sortTarjeta, page, size,proyecto.getIdproyecto());
            } else {
                Bson filter0 = eq("idproyecto", proyecto.getIdproyecto());
                Bson filter = and(filter0, eq("active", Boolean.TRUE),
                        eq("columna", columna),
                        eq("backlog", storeInBacklog));
                result = count(filter, sortTarjeta, page, size,proyecto.getIdproyecto());
            }

        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Boolean equalsExcludedNameOfTarjeta(Tarjeta tarjeta, Tarjeta other) ">
    @Override
    public Boolean equalsExcludedNameOfTarjeta(Tarjeta tarjeta, Tarjeta other) {
        Boolean result = Boolean.FALSE;
        try {
            if (tarjeta == null) {
                return false;
            }

            if (!Objects.equals(tarjeta.getDescripcion(), other.getDescripcion())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getPrioridad(), other.getPrioridad())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getEstimacion(), other.getEstimacion())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getColumna(), other.getColumna())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getIdtarjeta(), other.getIdtarjeta())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getUserView(), other.getUserView())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getFechainicial(), other.getFechainicial())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getFechafinal(), other.getFechafinal())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getIcono(), other.getIcono())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getTipotarjeta(), other.getTipotarjeta())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getIdsprint(), other.getIdsprint())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getIdproyecto(), other.getIdproyecto())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getBacklog(), other.getBacklog())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getActive(), other.getActive())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getTarea(), other.getTarea())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getComentario(), other.getComentario())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getEtiqueta(), other.getEtiqueta())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getArchivo(), other.getArchivo())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getImpedimento(), other.getImpedimento())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getForeaneo(), other.getForeaneo())) {
                return false;
            }
            if (!Objects.equals(tarjeta.getActionHistory(), other.getActionHistory())) {
                return false;
            }
            result = Boolean.TRUE;
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Boolean isEstimacionValida(Tarjeta tarjeta)">
    @Override
    public Boolean isEstimacionValida(Tarjeta tarjeta) {
        Boolean result = Boolean.TRUE;
        try {

            if (tarjeta.getEstimacion() == null || tarjeta.getEstimacion().equals("")) {
                FacesUtil.warningDialog(rf.fromCore("warning.warning"), rf.fromMessage("warning.ingreseestimacionformato"));
                return Boolean.FALSE;
            }

            if (tarjeta.getEstimacion().indexOf(":") == -1) {
                FacesUtil.warningDialog(rf.fromCore("warning.warning"), rf.fromMessage("warning.ingreseestimacionformato"));
                return Boolean.FALSE;
            }

            if (tarjeta.getEstimacion().indexOf("-") != -1) {
                FacesUtil.warningDialog(rf.fromCore("warning.warning"), rf.fromMessage("warning.ingreseestimacionformato"));
                return Boolean.FALSE;
            }

        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="String colorTarjeta(Tarjeta tarjeta)">
    /**
     * Listado de colores https://tailwindcss.com/docs/background-color
     *
     * @param tarjeta
     * @return
     */
    @Override
    public String colorTarjeta(Tarjeta tarjeta) {
        String color = "";
        try {
            switch (tarjeta.getPrioridad().toLowerCase()) {

                case "urgente":
                    color = "bg-orange-900";
                    break;

                case "alta":
                    color = "bg-purple-900";
                    break;
                case "baja":
////color ="bg-green-950";
//color ="bg-teal-600";
////color ="bg-green-600";
//                    color = "bg-indigo-900";
//                    color = "bg-indigo-700";
                    color = "bg-teal-900";
                    break;

                case "media":
                    color = "";
                    break;
            }
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return color;
    }
// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="public Long countLikeByTarjeta(@QueryParam("tarjeta") String tarjeta, Long idproyecto)">
    @Override
    public Long countLikeByTarjeta(String tarjeta, Long idproyecto) {
        Long result = 0L;
        try {
            result = tarjetaRestClient.countLikeByTarjeta(tarjeta,idproyecto);

        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }

    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Long countLikeByDescripcion( String descripcion, Long idproyecto)">
    @Override
    public Long countLikeByDescripcion(String descripcion, Long idproyecto) {
        Long result = 0L;
        try {
            result = tarjetaRestClient.countLikeByDescripcion(descripcion, idproyecto);

        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="public List<Tarjeta> likeByTarjeta(String tarjeta, Long idproyecto)">
    @Override
    public List<Tarjeta> likeByTarjeta(String tarjeta, Long idproyecto) {
        return tarjetaRestClient.likeByTarjeta(tarjeta,idproyecto);
    }
// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="public List<Tarjeta> likeByTarjetaPagination(String tarjeta, Pagination pagination, Long idproyecto)">
    @Override
    public List<Tarjeta> likeByTarjetaPagination(String tarjeta, Pagination pagination, Long idproyecto) {

        return tarjetaRestClient.likeByTarjetaPagination(tarjeta, pagination.getPage(), pagination.getSize(),idproyecto);

    }
// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="List<Tarjeta> likeByDescripcion(String descripcion, Long idproyecto)">
    @Override
    public List<Tarjeta> likeByDescripcion(String descripcion, Long idproyecto) {
        return tarjetaRestClient.likeByDescripcion(descripcion,idproyecto);
    }
// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="List<Tarjeta> betweenDate(@QueryParam("fechainicial") Date fechainicial, @QueryParam("fechafinal") Date fechafinal, Long idproyecto) ">
    public List<Tarjeta> betweenDate(@QueryParam("fechainicial") Date fechainicial, @QueryParam("fechafinal") Date fechafinal, Long idproyecto) {
        return tarjetaRestClient.betweenDate(fechainicial, fechafinal,idproyecto);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="List<Tarjeta> searchLikeByTarjeta(String tarjeta, Bson filter, Document sort, Integer page, Integer size, Long idproyecto)">
    @Override
    public List<Tarjeta> searchLikeByTarjeta(String tarjeta, Bson filter, Document sort, Integer page, Integer size, Long idproyecto) {
        List<Tarjeta> tarjetaList = new ArrayList<>();
        try {
            tarjetaList = tarjetaRestClient.searchLikeByTarjeta(tarjeta,
                    EncodeUtil.encodeBson(filter),
                    EncodeUtil.encodeBson(sort),
                    page, size,idproyecto);
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return tarjetaList;
    }
// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Long searchCountLikeByTarjeta(String tarjeta, Bson filter, Document sort, Integer page, Integer size,, Long idproyecto)">
    @Override
    public Long searchCountLikeByTarjeta(String tarjeta, Bson filter, Document sort, Integer page, Integer size, Long idproyecto) {
        Long result = 0L;
        try {
            result = tarjetaRestClient.searchCountLikeByTarjeta(tarjeta,
                    EncodeUtil.encodeBson(filter),
                    EncodeUtil.encodeBson(sort),
                    page, size,idproyecto);
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="List<Tarjeta> searchLikeByDescripcion(String descripcion, Bson filter, Document sort, Integer page, Integer size, Long idproyecto)">
    @Override
    public List<Tarjeta> searchLikeByDescripcion(String descripcion, Bson filter, Document sort, Integer page, Integer size, Long idproyecto) {
        List<Tarjeta> tarjetaList = new ArrayList<>();
        try {
            tarjetaList = tarjetaRestClient.searchLikeByDescripcion(descripcion,
                    EncodeUtil.encodeBson(filter),
                    EncodeUtil.encodeBson(sort),
                    page, size,idproyecto);
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return tarjetaList;
    }
// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Long searchCountLikeByDescripcion(String descripcion, Bson filter, Document sort, Integer page, Integer size, Long idproyecto)">
    @Override
    public Long searchCountLikeByDescripcion(String descripcion, Bson filter, Document sort, Integer page, Integer size, Long idproyecto) {
        Long result = 0L;
        try {
            result = tarjetaRestClient.searchCountLikeByDescripcion(descripcion,
                    EncodeUtil.encodeBson(filter),
                    EncodeUtil.encodeBson(sort),
                    page, size,idproyecto);
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="List<Tarjeta> validarFechaFinalEsteSprintActual(List<Tarjeta> list, Sprint sprint)">

    /**
     * Valida y garantiza que la ultima fecha de la tarjeta este en el sprint
     * actual
     *
     * @param list
     * @param sprint
     * @return
     */
    @Override
    public List<Tarjeta> validarFechaFinalEsteSprintActual(List<Tarjeta> list, Sprint sprint) {
        List<Tarjeta> result = new ArrayList<>();
        try {
            if (list == null || list.isEmpty()) {
                return result;
            } else {
                /**
                 * Verifica que la fecha final de la tarjeta no sea menor que la
                 * fecha inicial del sprint si ocurre actualiza con la fecha y
                 * hora actual
                 */
                Integer count = 0;
                for (Tarjeta t : list) {

                    if (DateUtil.fechaMenor(t.getFechafinal(), sprint.getFechainicial())) {
                        t.setFechafinal(sprint.getFechafinal());
                        update(t);
                        list.get(0).setFechafinal(t.getFechafinal());
                    }
                    count++;
                }
            }
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return list;
    }

    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="List<Tarjeta> validarFechaFinalSprintPlanTrabajo(List<Tarjeta> list, Sprint sprint)">
    /**
     * Valida y garantiza que la ultima fecha de la tarjeta en el sprint del
     * plan de trabajo actual
     *
     * @param list
     * @param sprint
     * @return
     */
    @Override
    public List<Tarjeta> validarFechaFinalSprintPlanTrabajo(List<Tarjeta> list, Sprint sprint) {
        List<Tarjeta> result = new ArrayList<>();
        try {
            if (list == null || list.isEmpty()) {
                return result;
            } else {
                /**
                 * Verifica que la fecha final de la tarjeta no sea menor que la
                 * fecha inicial del sprint si ocurre actualiza con la fecha y
                 * hora actual
                 */
                Integer count = 0;
                for (Tarjeta t : list) {
                    if (t.getIdproyecto().equals(sprint.getProyectoView().getIdproyecto())) {
                        if (DateUtil.fechaMenor(t.getFechafinal(), sprint.getFechainicial())) {
                            t.setFechafinal(sprint.getFechafinal());
                            t.setLastModification(t.getActionHistory().getLast().getFecha());
                            update(t);
                            list.get(count).setFechafinal(t.getFechafinal());
                        }else{
                          //  t.setLastModification(t.getActionHistory().getLast().getFecha());
                         //   list.get(count).setLastModification(t.getActionHistory().getLast().getFecha());
                        }

                    }
                    count++;
                }
            }
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return list;
    }

    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="List<Tarjeta> orderListForIdTarjetaReserve(List<Tarjeta> list)">
    /**
     *
     * @param list
     * @return lista de tarjeta ordenada por idtarjeta en orden inverso
     */
    @Override
    public List<Tarjeta> orderListForIdTarjetaReserve(List<Tarjeta> list) {
        try {
            list = list.stream().sorted(Comparator.comparing(Tarjeta::getIdtarjeta).reversed()).collect(Collectors.toList());

        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return list;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Integer positionOfTarjeta(Tarjeta tarjeta, List<Tarjeta> tarjetas)">
    @Override
    public Integer positionOfTarjeta(Tarjeta tarjeta, List<Tarjeta> tarjetas) {
        Integer result = -1;
        try {

            Integer c = 0;
            for (Tarjeta t : tarjetas) {
                if (t.getIdtarjeta().equals(tarjeta.getIdtarjeta())) {
                    result = c;
                    break;
                }
                c++;

            }
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc=" public TotalesTarjetasEstadistica calcularTotalesTarjetasEstadistica(Long iduser, Long idproyecto)">

    @Override
    public TotalesTarjetasEstadistica calcularTotalesTarjetasEstadistica(Long iduser, Long idproyecto) {
        TotalesTarjetasEstadistica result = new TotalesTarjetasEstadistica(0L, 0L, 0L,0L, iduser);
        try {
            Integer page = 0;
            Integer size = 0;
            Document sortTarjeta = new Document("idtarjeta", 1);
            Document sortSprint = new Document("idtarjeta", 1); 
            /**
             * CargarTarjetas
             */
            Bson filter0 = eq("user.iduser", iduser);
            Bson filter = and(filter0, eq("active", Boolean.TRUE),
                    eq("columna", "pendiente"),
                    ne("idsprint",0L));

            Long pendiente = tarjetaServices.count(filter, sortTarjeta, page, size,idproyecto);

            Bson filterProgreso = and(filter0, eq("active", Boolean.TRUE),
                    eq("columna", "progreso"));

            Long progreso = tarjetaServices.count(filterProgreso, sortTarjeta, page, size,idproyecto);

            Bson filterFinalizado = and(filter0, eq("active", Boolean.TRUE),
                    eq("columna", "finalizado"));

            Long finalizado = tarjetaServices.count(filterFinalizado, sortTarjeta, page, size,idproyecto);

            Bson filterBacklog = and(filter0, eq("active", Boolean.TRUE),
                    eq("backlog", true),
                            eq("idsprint",0L));

            Long backlog = tarjetaServices.count(filterBacklog, sortTarjeta, page, size,idproyecto);
            
          result.setTotalTarjetasBacklog(backlog);
          result.setTotalTarjetasFinalizado(finalizado);
          result.setTotalTarjetasPendiente(pendiente);
          result.setTotalTarjetasProgreso(progreso);

            
     } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }
    
    // </editor-fold>



    
     
}


```



### En una clase Faces

```java
@Named
@ViewScoped
@Data
public class TarjetasFaces implements Serializable, JmoordbCoreXHTMLUtil, IPaginator, SprintFacesServices, FacesServices {

    @Inject
    TarjetaServices tarjetaServices;

 public void save(Tarjeta tarjeta) {
   Optional<Tarjeta> tarjetaSaved = tarjetaServices.save(tarjeta);
            if (!tarjetaSaved.isPresent()) {

                FacesUtil.warningDialog(rf.fromCore("warning.warning"), rf.fromCore("warning.save"));

            } else {
                tarjeta.setIdtarjeta(tarjetaSaved.get().getIdtarjeta());
}
}

  public String nextProgreso(Tarjeta tarjeta) {
 Tarjeta tarjetaDB = tarjetaServices.findByIdtarjetaIdproyecto(tarjeta.getIdtarjeta(), proyectoSelected.getIdproyecto()).get();
}

```