From 1ff27ec0b6b7215cd088aa003720551f623cd05c Mon Sep 17 00:00:00 2001 From: FrancoPandolfo Date: Thu, 5 Jun 2025 21:37:02 +0000 Subject: [PATCH] se agrega funcion para soft delete de una receta --- asset-transfer-basic/.gitignore | 1 + .../chaincode-go/chaincode/smartcontract.go | 57 +++++++++++++++-- .../controllers/RecetaController.java | 33 ++++++++++ .../hyperledger/services/RecetaService.java | 62 ++++++++++++++++--- 4 files changed, 140 insertions(+), 13 deletions(-) diff --git a/asset-transfer-basic/.gitignore b/asset-transfer-basic/.gitignore index 1ddbcb2f..8dea58b3 100755 --- a/asset-transfer-basic/.gitignore +++ b/asset-transfer-basic/.gitignore @@ -1,2 +1,3 @@ wallet !wallet/.gitkeep +bin/ diff --git a/asset-transfer-basic/chaincode-go/chaincode/smartcontract.go b/asset-transfer-basic/chaincode-go/chaincode/smartcontract.go index 6d0490dd..d5bcfc98 100644 --- a/asset-transfer-basic/chaincode-go/chaincode/smartcontract.go +++ b/asset-transfer-basic/chaincode-go/chaincode/smartcontract.go @@ -51,6 +51,16 @@ type Vacuna struct { PractitionerDocumentNumber string `json:"practitionerDocumentNumber"` } +type Estado string +const ( + EstadoDraft Estado = "draft" + EstadoActive Estado = "active" + EstadoOnHold Estado = "on_hold" + EstadoCancelled Estado = "cancelled" + EstadoCompleted Estado = "completed" + EstadoStoped Estado = "stoped" +) + func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error { recetas := []Receta{ { @@ -150,11 +160,11 @@ func (s *SmartContract) FirmarReceta(ctx contractapi.TransactionContextInterface if err := json.Unmarshal(recetaJSON, &receta); err != nil { return fmt.Errorf("error al parsear la receta: %v", err) } - if receta.Status != "draft" { + if receta.Status != Estado.Draft { return fmt.Errorf("la receta %s no puede ser firmada porque no está en estado 'draft'", recetaID) } receta.Signature = firma - receta.Status = "active" + receta.Status = Estado.Active receta.StatusChange = "FIRMADA" updatedRecetaJSON, err := json.Marshal(receta) if err != nil { @@ -187,12 +197,12 @@ func (s *SmartContract) EntregarReceta(ctx contractapi.TransactionContextInterfa return fmt.Errorf("error al parsear la receta actual: %v", err) } - if recetaActual.Status != "active" { + if recetaActual.Status != Estado.Active { return fmt.Errorf("solo se puede entregar la receta si está en estado 'active'") } // Cambiar el estado a ENTREGADO - recetaActual.Status = "completed" + recetaActual.Status = Estado.Completed // Guardar la receta modificada updatedRecetaJSON, err := json.Marshal(recetaActual) @@ -230,7 +240,33 @@ func (s *SmartContract) DeleteReceta(ctx contractapi.TransactionContextInterface return fmt.Errorf("la receta %s no existe", id) } - return ctx.GetStub().DelState(id) + // Obtener receta + recetaJSON, err := ctx.GetStub().GetState(id) + if err != nil { + return fmt.Errorf("error al obtener la receta: %v", err) + } + + var receta Receta + err = json.Unmarshal(recetaJSON, &receta) + if err != nil { + return fmt.Errorf("error al deserializar la receta: %v", err) + } + + // Cambiar el estado a "cancelled" + receta.Status = Estado.Cancelled + + // Volver a guardar la receta modificada + recetaActualizadaJSON, err := json.Marshal(receta) + if err != nil { + return fmt.Errorf("error al serializar la receta actualizada: %v", err) + } + + err = ctx.GetStub().PutState(id, recetaActualizadaJSON) + if err != nil { + return fmt.Errorf("error al guardar la receta actualizada: %v", err) + } + + return nil } func (s *SmartContract) RecetaExists(ctx contractapi.TransactionContextInterface, id string) (bool, error) { @@ -277,11 +313,20 @@ func (s *SmartContract) GetAllRecetas(ctx contractapi.TransactionContextInterfac return nil, err } + if len(queryResponse.Value) == 0 { + continue // Ignorar valores vacíos + } + var receta Receta err = json.Unmarshal(queryResponse.Value, &receta) if err != nil { - return nil, err + continue // O podrías loggear el error si es útil } + + if receta.Status == status.Cancelled { + continue // Ignorar recetas canceladas + } + recetas = append(recetas, &receta) } diff --git a/asset-transfer-basic/maven-API-SiMeDi/src/main/java/com/code/hyperledger/controllers/RecetaController.java b/asset-transfer-basic/maven-API-SiMeDi/src/main/java/com/code/hyperledger/controllers/RecetaController.java index 9ad82631..71480773 100644 --- a/asset-transfer-basic/maven-API-SiMeDi/src/main/java/com/code/hyperledger/controllers/RecetaController.java +++ b/asset-transfer-basic/maven-API-SiMeDi/src/main/java/com/code/hyperledger/controllers/RecetaController.java @@ -178,6 +178,39 @@ public class RecetaController { } } + + @PostMapping("/borrar") + public ResponseEntity delete(@RequestBody Map requestBody) { + logger.info("Received request to obtain receta with ID: {}", requestBody.get("id")); // Log de entrada + + try { + String id = requestBody.get("id"); + logger.debug("Searching for receta with ID: {}", id); // Log de búsqueda + + recetaService.borrarReceta(id); + logger.debug("Receta deleted: {}", id); // Log cuando se encuentra la receta + + return new ResponseEntity<>(HttpStatus.OK); + } catch (IOException e) { + logger.error("IOException occurred while deleting receta with ID: {}", requestBody.get("id"), e); // Log de + // excepción + // específica + return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); + } catch (GatewayException e) { + logger.error("GatewayException occurred while deleting receta with ID: {}", requestBody.get("id"), e); // Log + // de + // excepción + // Gateway + return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); + } catch (Exception e) { + logger.error("Unexpected error occurred while deleting receta with ID: {}", requestBody.get("id"), e); // Log + // de + // error + // inesperado + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } + private RecetaDto mapToDto(Receta receta) { RecetaDto dto = new RecetaDto(); dto.setIdentifier(receta.getIdentifier()); diff --git a/asset-transfer-basic/maven-API-SiMeDi/src/main/java/com/code/hyperledger/services/RecetaService.java b/asset-transfer-basic/maven-API-SiMeDi/src/main/java/com/code/hyperledger/services/RecetaService.java index f19282b3..c114166d 100644 --- a/asset-transfer-basic/maven-API-SiMeDi/src/main/java/com/code/hyperledger/services/RecetaService.java +++ b/asset-transfer-basic/maven-API-SiMeDi/src/main/java/com/code/hyperledger/services/RecetaService.java @@ -11,9 +11,6 @@ import lombok.SneakyThrows; import org.hyperledger.fabric.client.*; import org.hyperledger.fabric.client.identity.*; import org.springframework.stereotype.Service; -import org.hyperledger.fabric.client.identity.Identity; -import org.hyperledger.fabric.client.identity.Signer; - import javax.annotation.PostConstruct; import java.io.IOException; @@ -118,9 +115,31 @@ public class RecetaService { } public Receta obtenerReceta(String recetaId) throws GatewayException, IOException { - var evaluateResult = contract.evaluateTransaction("ReadReceta", recetaId); - ObjectMapper objectMapper = new ObjectMapper(); - return objectMapper.readValue(evaluateResult, Receta.class); + System.out.println("[INFO] Iniciando obtención de receta con ID: " + recetaId); + + try { + System.out.println("[DEBUG] Ejecutando transacción 'ReadReceta' con ID: " + recetaId); + var evaluateResult = contract.evaluateTransaction("ReadReceta", recetaId); + System.out.println("[DEBUG] Resultado de transacción recibido: " + new String(evaluateResult)); + + ObjectMapper objectMapper = new ObjectMapper(); + Receta receta = objectMapper.readValue(evaluateResult, Receta.class); + System.out.println("[INFO] Receta parseada exitosamente para ID: " + recetaId); + + return receta; + } catch (GatewayException e) { + System.err.println("[ERROR] GatewayException al obtener receta con ID: " + recetaId); + e.printStackTrace(System.err); + throw e; + } catch (IOException e) { + System.err.println("[ERROR] IOException al parsear receta con ID: " + recetaId); + e.printStackTrace(System.err); + throw e; + } catch (Exception e) { + System.err.println("[ERROR] Error inesperado al obtener receta con ID: " + recetaId); + e.printStackTrace(System.err); + throw new RuntimeException("Error inesperado al obtener la receta", e); + } } public List obtenerTodasLasRecetas() throws GatewayException, IOException { @@ -151,7 +170,36 @@ public class RecetaService { public void firmarReceta(String recetaId, String signature) throws CommitStatusException, EndorseException, CommitException, SubmitException { - contract.submitTransaction("FirmarReceta", recetaId, signature); + System.out.println("[INFO] Iniciando firma de receta con ID: " + recetaId); + try { + var evaluateResult = contract.submitTransaction("FirmarReceta", recetaId, signature); + System.out.println("[DEBUG] Resultado de transacción recibido: " + new String(evaluateResult)); + System.out.println("[INFO] Receta firmada exitosamente para ID: " + recetaId); + } catch (Exception e) { + System.err.println("[ERROR] Error al firmar receta: " + e.getMessage()); + e.printStackTrace(); + } + } + + public void borrarReceta(String recetaId) throws GatewayException, IOException { + System.out.println("[INFO] Iniciando borrado de receta con ID: " + recetaId); + + try { + System.out.println("[DEBUG] Ejecutando transacción 'DeleteReceta' con ID: " + recetaId); + var evaluateResult = contract.evaluateTransaction("DeleteReceta", recetaId); + System.out.println("[DEBUG] Resultado de transacción recibido: " + new String(evaluateResult)); + + System.out.println("[INFO] Receta borrada exitosamente para ID: " + recetaId); + + } catch (GatewayException e) { + System.err.println("[ERROR] GatewayException al borrar receta con ID: " + recetaId); + e.printStackTrace(System.err); + throw e; + } catch (Exception e) { + System.err.println("[ERROR] Error inesperado al borrar receta con ID: " + recetaId); + e.printStackTrace(System.err); + throw new RuntimeException("Error inesperado al borrar la receta", e); + } } public List obtenerRecetasPorDniYEstado(String dni, String estado) throws GatewayException, IOException {