ahora se recibe un array de estados para la busqueda de recetas

This commit is contained in:
luc662 2025-08-20 22:01:22 +00:00
parent 8c89ee9bb6
commit df9e14e1bf
4 changed files with 26 additions and 59 deletions

View file

@ -37,18 +37,18 @@ type Receta struct {
} }
type Vacuna struct { type Vacuna struct {
ID string `json:"id"` // identificador único para el ledger ID string `json:"id"`
Identifier string `json:"identifier"` Identifier string `json:"identifier"`
Status string `json:"status"` // podés validarlo con enums si querés Status string `json:"status"`
StatusChange string `json:"statusChange"` // como string (ISO8601) StatusChange string `json:"statusChange"`
StatusReason string `json:"statusReason"` StatusReason string `json:"statusReason"`
VaccinateCode string `json:"vaccinateCode"` VaccinateCode string `json:"vaccinateCode"`
AdministradedProduct string `json:"administradedProduct"` AdministradedProduct string `json:"administradedProduct"`
Manufacturer string `json:"manufacturer"` Manufacturer string `json:"manufacturer"`
LotNumber string `json:"lotNumber"` LotNumber string `json:"lotNumber"`
ExpirationDate string `json:"expirationDate"` // como string ISO8601 ExpirationDate string `json:"expirationDate"`
PatientDocumentNumber string `json:"patientDocumentNumber"` PatientDocumentNumber string `json:"patientDocumentNumber"`
Reactions string `json:"reactions"` // puede ser un string o una estructura si querés después Reactions string `json:"reactions"`
Practitioner string `json:"practitioner"` Practitioner string `json:"practitioner"`
PractitionerDocumentNumber string `json:"practitionerDocumentNumber"` PractitionerDocumentNumber string `json:"practitionerDocumentNumber"`
Matricula string `json:"matricula"` Matricula string `json:"matricula"`
@ -138,12 +138,10 @@ func (s *SmartContract) CreateReceta(ctx contractapi.TransactionContextInterface
if exists { if exists {
return fmt.Errorf("la receta %s ya existe", receta.ID) return fmt.Errorf("la receta %s ya existe", receta.ID)
} }
recetaJSON, err := json.Marshal(receta) recetaJSON, err := json.Marshal(receta)
if err != nil { if err != nil {
return err return err
} }
return ctx.GetStub().PutState(receta.ID, recetaJSON) return ctx.GetStub().PutState(receta.ID, recetaJSON)
} }
@ -176,7 +174,6 @@ func (s *SmartContract) FirmarReceta(ctx contractapi.TransactionContextInterface
if err != nil { if err != nil {
return fmt.Errorf("error al serializar la receta firmada: %v", err) return fmt.Errorf("error al serializar la receta firmada: %v", err)
} }
return ctx.GetStub().PutState(recetaID, updatedRecetaJSON) return ctx.GetStub().PutState(recetaID, updatedRecetaJSON)
} }
@ -188,8 +185,6 @@ func (s *SmartContract) EntregarReceta(ctx contractapi.TransactionContextInterfa
if !exists { if !exists {
return fmt.Errorf("la receta %s no existe", recetaID) return fmt.Errorf("la receta %s no existe", recetaID)
} }
// Obtener la receta actual
recetaActualJSON, err := ctx.GetStub().GetState(recetaID) recetaActualJSON, err := ctx.GetStub().GetState(recetaID)
if err != nil { if err != nil {
return fmt.Errorf("error al obtener la receta actual: %v", err) return fmt.Errorf("error al obtener la receta actual: %v", err)
@ -197,25 +192,18 @@ func (s *SmartContract) EntregarReceta(ctx contractapi.TransactionContextInterfa
if recetaActualJSON == nil { if recetaActualJSON == nil {
return fmt.Errorf("la receta %s no fue encontrada en el ledger", recetaID) return fmt.Errorf("la receta %s no fue encontrada en el ledger", recetaID)
} }
var recetaActual Receta var recetaActual Receta
if err := json.Unmarshal(recetaActualJSON, &recetaActual); err != nil { if err := json.Unmarshal(recetaActualJSON, &recetaActual); err != nil {
return fmt.Errorf("error al parsear la receta actual: %v", err) return fmt.Errorf("error al parsear la receta actual: %v", err)
} }
if recetaActual.Status != string(EstadoActive) { if recetaActual.Status != string(EstadoActive) {
return fmt.Errorf("solo se puede entregar la receta si está en estado 'active'") return fmt.Errorf("solo se puede entregar la receta si está en estado 'active'")
} }
// Cambiar el estado a ENTREGADO
recetaActual.Status = string(EstadoCompleted) recetaActual.Status = string(EstadoCompleted)
// Guardar la receta modificada
updatedRecetaJSON, err := json.Marshal(recetaActual) updatedRecetaJSON, err := json.Marshal(recetaActual)
if err != nil { if err != nil {
return fmt.Errorf("error al serializar la receta modificada: %v", err) return fmt.Errorf("error al serializar la receta modificada: %v", err)
} }
return ctx.GetStub().PutState(recetaID, updatedRecetaJSON) return ctx.GetStub().PutState(recetaID, updatedRecetaJSON)
} }
@ -315,17 +303,17 @@ func (s *SmartContract) GetAllRecetas(ctx contractapi.TransactionContextInterfac
} }
if len(queryResponse.Value) == 0 { if len(queryResponse.Value) == 0 {
continue // Ignorar valores vacíos continue
} }
var receta Receta var receta Receta
err = json.Unmarshal(queryResponse.Value, &receta) err = json.Unmarshal(queryResponse.Value, &receta)
if err != nil { if err != nil {
continue // O podrías loggear el error si es útil continue
} }
if receta.Status == string(EstadoCancelled) { if receta.Status == string(EstadoCancelled) {
continue // Ignorar recetas canceladas continue
} }
recetas = append(recetas, &receta) recetas = append(recetas, &receta)
@ -353,7 +341,7 @@ func (s *SmartContract) GetMultipleRecetas(ctx contractapi.TransactionContextInt
status := strings.ToLower(strings.TrimSpace(receta.Status)) status := strings.ToLower(strings.TrimSpace(receta.Status))
if status == string(EstadoCancelled) { if status == string(EstadoCancelled) {
continue // Ignorar receta cancelada continue
} }
recetas = append(recetas, &receta) recetas = append(recetas, &receta)
@ -361,56 +349,48 @@ func (s *SmartContract) GetMultipleRecetas(ctx contractapi.TransactionContextInt
return recetas, nil return recetas, nil
} }
// TODO: adaptar los campos para que se tengan un identificar de usuarios ademas del DNI
type ResultadoPaginado struct { type ResultadoPaginado struct {
Recetas []*Receta `json:"recetas"` Recetas []*Receta `json:"componentes"`
Bookmark string `json:"bookmark"` Bookmark string `json:"bookmark"`
} }
func (s *SmartContract) GetRecetasPorDniYEstadoPaginado( func (s *SmartContract) GetRecetasPorDniYEstadosPaginado(
ctx contractapi.TransactionContextInterface, ctx contractapi.TransactionContextInterface,
dni string, dni string,
estado string, estados []string,
pageSize int32, pageSize int32,
bookmark string, bookmark string,
) (*ResultadoPaginado, error) { ) (*ResultadoPaginado, error) {
if dni == "" || len(estados) == 0 {
if dni == "" || estado == "" { return nil, fmt.Errorf("el dni y al menos un estado son obligatorios")
return nil, fmt.Errorf("el dni y el estado son obligatorios")
} }
// Creamos la query para CouchDB
query := map[string]interface{}{ query := map[string]interface{}{
"selector": map[string]interface{}{ "selector": map[string]interface{}{
"patientDocumentNumber": dni, "patientDocumentNumber": dni,
"status": estado, "status": map[string]interface{}{
"$in": estados,
},
}, },
"limit": pageSize, "limit": pageSize,
} }
// Si hay bookmark, lo agregamos
if bookmark != "" { if bookmark != "" {
query["bookmark"] = bookmark query["bookmark"] = bookmark
} }
queryBytes, err := json.Marshal(query) queryBytes, err := json.Marshal(query)
if err != nil { if err != nil {
return nil, fmt.Errorf("error al generar la query: %v", err) return nil, fmt.Errorf("error al generar la query: %v", err)
} }
resultsIterator, metadata, err := ctx.GetStub().GetQueryResultWithPagination(string(queryBytes), pageSize, bookmark) resultsIterator, metadata, err := ctx.GetStub().GetQueryResultWithPagination(string(queryBytes), pageSize, bookmark)
if err != nil { if err != nil {
return nil, fmt.Errorf("error al ejecutar la query: %v", err) return nil, fmt.Errorf("error al ejecutar la query: %v", err)
} }
defer resultsIterator.Close() defer resultsIterator.Close()
var recetas []*Receta var recetas []*Receta
for resultsIterator.HasNext() { for resultsIterator.HasNext() {
response, iterErr := resultsIterator.Next() response, iterErr := resultsIterator.Next()
if iterErr != nil { if iterErr != nil {
return nil, iterErr return nil, iterErr
} }
var receta Receta var receta Receta
if err := json.Unmarshal(response.Value, &receta); err != nil { if err := json.Unmarshal(response.Value, &receta); err != nil {
return nil, fmt.Errorf("error al parsear receta: %v", err) return nil, fmt.Errorf("error al parsear receta: %v", err)
@ -418,16 +398,13 @@ func (s *SmartContract) GetRecetasPorDniYEstadoPaginado(
recetas = append(recetas, &receta) recetas = append(recetas, &receta)
} }
if recetas == nil { if recetas == nil {
recetas = []*Receta{} recetas = []*Receta{}
} }
resultado := &ResultadoPaginado{ resultado := &ResultadoPaginado{
Recetas: recetas, Recetas: recetas,
Bookmark: metadata.Bookmark, Bookmark: metadata.Bookmark,
} }
return resultado, nil return resultado, nil
} }
@ -439,7 +416,6 @@ func (s *SmartContract) CreateVacuna(ctx contractapi.TransactionContextInterface
if exists { if exists {
return fmt.Errorf("la vacuna %s ya existe", vacuna.ID) return fmt.Errorf("la vacuna %s ya existe", vacuna.ID)
} }
vacunaJSON, err := json.Marshal(vacuna) vacunaJSON, err := json.Marshal(vacuna)
if err != nil { if err != nil {
return err return err
@ -464,7 +440,6 @@ func (s *SmartContract) ReadVacuna(ctx contractapi.TransactionContextInterface,
if vacunaJSON == nil { if vacunaJSON == nil {
return nil, fmt.Errorf("la vacuna %s no existe", id) return nil, fmt.Errorf("la vacuna %s no existe", id)
} }
var vacuna Vacuna var vacuna Vacuna
err = json.Unmarshal(vacunaJSON, &vacuna) err = json.Unmarshal(vacunaJSON, &vacuna)
if err != nil { if err != nil {
@ -484,7 +459,6 @@ func (s *SmartContract) GetMultipleVacunas(ctx contractapi.TransactionContextInt
if vacunaJSON == nil { if vacunaJSON == nil {
continue continue
} }
var vacuna Vacuna var vacuna Vacuna
err = json.Unmarshal(vacunaJSON, &vacuna) err = json.Unmarshal(vacunaJSON, &vacuna)
if err != nil { if err != nil {
@ -499,7 +473,6 @@ func (s *SmartContract) GetVacunasPorDniYEstado(ctx contractapi.TransactionConte
if dni == "" { if dni == "" {
return nil, fmt.Errorf("el dni es obligatorio") return nil, fmt.Errorf("el dni es obligatorio")
} }
resultsIterator, err := ctx.GetStub().GetStateByRange("", "") resultsIterator, err := ctx.GetStub().GetStateByRange("", "")
if err != nil { if err != nil {
return nil, fmt.Errorf("error al obtener datos del ledger: %v", err) return nil, fmt.Errorf("error al obtener datos del ledger: %v", err)
@ -512,23 +485,16 @@ func (s *SmartContract) GetVacunasPorDniYEstado(ctx contractapi.TransactionConte
if err != nil { if err != nil {
return nil, err return nil, err
} }
var vacuna Vacuna var vacuna Vacuna
// Solo deserializamos si es posible (podría fallar si no es una vacuna)
if err := json.Unmarshal(queryResponse.Value, &vacuna); err != nil { if err := json.Unmarshal(queryResponse.Value, &vacuna); err != nil {
continue continue
} }
// Validamos que tenga un DNI y coincida
if vacuna.PatientDocumentNumber != dni { if vacuna.PatientDocumentNumber != dni {
continue continue
} }
// Si se pasó un estado, lo filtramos
if estado != "" && vacuna.Status != estado { if estado != "" && vacuna.Status != estado {
continue continue
} }
vacunasFiltradas = append(vacunasFiltradas, &vacuna) vacunasFiltradas = append(vacunasFiltradas, &vacuna)
} }

View file

@ -230,13 +230,13 @@ public class RecetaController {
@GetMapping("/obtener/paginado") @GetMapping("/obtener/paginado")
public ResponseEntity<ResultadoPaginado<RecetaDto>> obtenerRecetasPaginado( public ResponseEntity<ResultadoPaginado<RecetaDto>> obtenerRecetasPaginado(
@RequestParam String dni, @RequestParam String dni,
@RequestParam String estado, @RequestParam List<String> estados,
@RequestParam(defaultValue = "10") int pageSize, @RequestParam(defaultValue = "10") int pageSize,
@RequestParam(defaultValue = "") String bookmark) { @RequestParam(defaultValue = "") String bookmark) {
System.out.println("Entro ");
try { try {
ResultadoPaginado<RecetaDto> recetas = recetaService ResultadoPaginado<RecetaDto> recetas = recetaService
.obtenerRecetasPorDniYEstadoPaginado(dni, estado, pageSize, bookmark); .obtenerRecetasPorDniYEstadoPaginado(dni, estados, pageSize, bookmark);
return new ResponseEntity<>(recetas, HttpStatus.OK); return new ResponseEntity<>(recetas, HttpStatus.OK);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();

View file

@ -10,6 +10,6 @@ import java.util.List;
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
public class ResultadoPaginado<T> { public class ResultadoPaginado<T> {
private List<T> recetas; private List<T> componentes;
private String bookmark; private String bookmark;
} }

View file

@ -150,12 +150,13 @@ public class RecetaService {
} }
public ResultadoPaginado<RecetaDto> obtenerRecetasPorDniYEstadoPaginado( public ResultadoPaginado<RecetaDto> obtenerRecetasPorDniYEstadoPaginado(
String dni, String estado, int pageSize, String bookmark) throws Exception { String dni, List<String> estados, int pageSize, String bookmark) throws Exception {
String estadosJson = new ObjectMapper().writeValueAsString(estados);
System.out.println("Estados " + estadosJson);
byte[] result = contract.evaluateTransaction( byte[] result = contract.evaluateTransaction(
"GetRecetasPorDniYEstadoPaginado", "GetRecetasPorDniYEstadosPaginado",
dni, dni,
estado, estadosJson,
String.valueOf(pageSize), String.valueOf(pageSize),
bookmark); bookmark);