mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-22 17:45:10 +00:00
se agregaron las firmas y los campos del practicante para adaptarse al estandar FHIR
This commit is contained in:
parent
fbbc996b82
commit
9f8addf510
8 changed files with 186 additions and 92 deletions
|
|
@ -29,6 +29,9 @@ type Receta struct {
|
||||||
FechaDeAutorizacion string `json:"fechaDeAutorizacion"`
|
FechaDeAutorizacion string `json:"fechaDeAutorizacion"`
|
||||||
Cantidad string `json:"cantidad"`
|
Cantidad string `json:"cantidad"`
|
||||||
ExpectedSupplyDuration string `json:"expectedSupplyDuration"`
|
ExpectedSupplyDuration string `json:"expectedSupplyDuration"`
|
||||||
|
Practitioner string `json:"practitioner"`
|
||||||
|
PractitionerDocumentNumber string `json:"practitionerDocumentNumber"`
|
||||||
|
Signature string `json:"signature"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Vacuna struct {
|
type Vacuna struct {
|
||||||
|
|
@ -44,9 +47,10 @@ type Vacuna struct {
|
||||||
ExpirationDate string `json:"expirationDate"` // como string ISO8601
|
ExpirationDate string `json:"expirationDate"` // como string ISO8601
|
||||||
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"` // puede ser un string o una estructura si querés después
|
||||||
|
Practitioner string `json:"practitioner"`
|
||||||
|
PractitionerDocumentNumber string `json:"practitionerDocumentNumber"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error {
|
func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error {
|
||||||
recetas := []Receta{
|
recetas := []Receta{
|
||||||
{
|
{
|
||||||
|
|
@ -67,6 +71,9 @@ func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface)
|
||||||
FechaDeAutorizacion: "2024-01-01T09:00:00Z",
|
FechaDeAutorizacion: "2024-01-01T09:00:00Z",
|
||||||
Cantidad: "5",
|
Cantidad: "5",
|
||||||
ExpectedSupplyDuration: "2024-02-01T09:00:00Z",
|
ExpectedSupplyDuration: "2024-02-01T09:00:00Z",
|
||||||
|
Practitioner: "practitioner",
|
||||||
|
PractitionerDocumentNumber: "123456789",
|
||||||
|
Signature: "signature",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "receta2",
|
ID: "receta2",
|
||||||
|
|
@ -86,6 +93,9 @@ func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface)
|
||||||
FechaDeAutorizacion: "2024-01-10T10:00:00Z",
|
FechaDeAutorizacion: "2024-01-10T10:00:00Z",
|
||||||
Cantidad: "10",
|
Cantidad: "10",
|
||||||
ExpectedSupplyDuration: "2024-04-10T10:00:00Z",
|
ExpectedSupplyDuration: "2024-04-10T10:00:00Z",
|
||||||
|
Practitioner: "practitioner",
|
||||||
|
PractitionerDocumentNumber: "123456789",
|
||||||
|
Signature: "signature",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,6 +131,39 @@ func (s *SmartContract) CreateReceta(ctx contractapi.TransactionContextInterface
|
||||||
return ctx.GetStub().PutState(receta.ID, recetaJSON)
|
return ctx.GetStub().PutState(receta.ID, recetaJSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SmartContract) FirmarReceta(ctx contractapi.TransactionContextInterface, recetaID string, firma string) error {
|
||||||
|
exists, err := s.RecetaExists(ctx, recetaID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return fmt.Errorf("la receta %s no existe", recetaID)
|
||||||
|
}
|
||||||
|
recetaJSON, err := ctx.GetStub().GetState(recetaID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error al obtener la receta: %v", err)
|
||||||
|
}
|
||||||
|
if recetaJSON == nil {
|
||||||
|
return fmt.Errorf("la receta %s no fue encontrada en el ledger", recetaID)
|
||||||
|
}
|
||||||
|
var receta Receta
|
||||||
|
if err := json.Unmarshal(recetaJSON, &receta); err != nil {
|
||||||
|
return fmt.Errorf("error al parsear la receta: %v", err)
|
||||||
|
}
|
||||||
|
if receta.Status != "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.StatusChange = "FIRMADA"
|
||||||
|
updatedRecetaJSON, err := json.Marshal(receta)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error al serializar la receta firmada: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.GetStub().PutState(recetaID, updatedRecetaJSON)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SmartContract) EntregarReceta(ctx contractapi.TransactionContextInterface, recetaID string) error {
|
func (s *SmartContract) EntregarReceta(ctx contractapi.TransactionContextInterface, recetaID string) error {
|
||||||
exists, err := s.RecetaExists(ctx, recetaID)
|
exists, err := s.RecetaExists(ctx, recetaID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -144,13 +187,12 @@ func (s *SmartContract) EntregarReceta(ctx contractapi.TransactionContextInterfa
|
||||||
return fmt.Errorf("error al parsear la receta actual: %v", err)
|
return fmt.Errorf("error al parsear la receta actual: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validar que el estado actual sea ACTIVO
|
if recetaActual.Status != "active" {
|
||||||
if recetaActual.Status != "ACTIVO" {
|
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 'ACTIVO'")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cambiar el estado a ENTREGADO
|
// Cambiar el estado a ENTREGADO
|
||||||
recetaActual.Status = "ENTREGADO"
|
recetaActual.Status = "completed"
|
||||||
|
|
||||||
// Guardar la receta modificada
|
// Guardar la receta modificada
|
||||||
updatedRecetaJSON, err := json.Marshal(recetaActual)
|
updatedRecetaJSON, err := json.Marshal(recetaActual)
|
||||||
|
|
@ -260,12 +302,13 @@ func (s *SmartContract) GetMultipleRecetas(ctx contractapi.TransactionContextInt
|
||||||
var receta Receta
|
var receta Receta
|
||||||
err = json.Unmarshal(recetaJSON, &receta)
|
err = json.Unmarshal(recetaJSON, &receta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("error al parsear la receta con ID %s: %v", id, err)
|
||||||
}
|
}
|
||||||
recetas = append(recetas, &receta)
|
recetas = append(recetas, &receta)
|
||||||
}
|
}
|
||||||
return recetas, nil
|
return recetas, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: adaptar los campos para que se tengan un identificar de usuarios ademas del DNI
|
// TODO: adaptar los campos para que se tengan un identificar de usuarios ademas del DNI
|
||||||
func (s *SmartContract) GetRecetasPorDniYEstado(ctx contractapi.TransactionContextInterface, dni string, estado string) ([]*Receta, error) {
|
func (s *SmartContract) GetRecetasPorDniYEstado(ctx contractapi.TransactionContextInterface, dni string, estado string) ([]*Receta, error) {
|
||||||
if dni == "" || estado == "" {
|
if dni == "" || estado == "" {
|
||||||
|
|
|
||||||
|
|
@ -92,13 +92,21 @@ public class RecetaController {
|
||||||
|
|
||||||
return new ResponseEntity<>(recetaDto, HttpStatus.OK);
|
return new ResponseEntity<>(recetaDto, HttpStatus.OK);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error("IOException occurred while obtaining receta with ID: {}", requestBody.getId(), e); // Log de excepción específica
|
logger.error("IOException occurred while obtaining receta with ID: {}", requestBody.getId(), e); // Log de
|
||||||
|
// excepción
|
||||||
|
// específica
|
||||||
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
|
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
|
||||||
} catch (GatewayException e) {
|
} catch (GatewayException e) {
|
||||||
logger.error("GatewayException occurred while obtaining receta with ID: {}", requestBody.getId(), e); // Log de excepción Gateway
|
logger.error("GatewayException occurred while obtaining receta with ID: {}", requestBody.getId(), e); // Log
|
||||||
|
// de
|
||||||
|
// excepción
|
||||||
|
// Gateway
|
||||||
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
|
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Unexpected error occurred while obtaining receta with ID: {}", requestBody.getId(), e); // Log de error inesperado
|
logger.error("Unexpected error occurred while obtaining receta with ID: {}", requestBody.getId(), e); // Log
|
||||||
|
// de
|
||||||
|
// error
|
||||||
|
// inesperado
|
||||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -147,6 +155,29 @@ public class RecetaController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PutMapping("/firmar")
|
||||||
|
public ResponseEntity<Void> firmarReceta(@RequestBody Map<String, String> requestBody) {
|
||||||
|
try {
|
||||||
|
String id = requestBody.get("id");
|
||||||
|
String signature = requestBody.get("signature");
|
||||||
|
|
||||||
|
if (id == null || id.isEmpty()) {
|
||||||
|
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("\n--> Submit Transaction: FirmarReceta");
|
||||||
|
|
||||||
|
recetaService.firmarReceta(id, signature);
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
|
} catch (EndorseException | SubmitException | CommitStatusException | CommitException e) {
|
||||||
|
e.printStackTrace(); // o algún log específico
|
||||||
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
} catch (GatewayException e) {
|
||||||
|
e.printStackTrace(); // este bloque rara vez se ejecutaría si ya atrapás las anteriores
|
||||||
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private RecetaDto mapToDto(Receta receta) {
|
private RecetaDto mapToDto(Receta receta) {
|
||||||
RecetaDto dto = new RecetaDto();
|
RecetaDto dto = new RecetaDto();
|
||||||
dto.setIdentifier(receta.getIdentifier());
|
dto.setIdentifier(receta.getIdentifier());
|
||||||
|
|
@ -165,6 +196,9 @@ public class RecetaController {
|
||||||
dto.setFechaDeAutorizacion(receta.getFechaDeAutorizacion());
|
dto.setFechaDeAutorizacion(receta.getFechaDeAutorizacion());
|
||||||
dto.setCantidad(receta.getCantidad());
|
dto.setCantidad(receta.getCantidad());
|
||||||
dto.setExpectedSupplyDuration(receta.getExpectedSupplyDuration());
|
dto.setExpectedSupplyDuration(receta.getExpectedSupplyDuration());
|
||||||
|
dto.setPractitioner(receta.getPractitioner());
|
||||||
|
dto.setPractitionerDocumentNumber(receta.getPractitionerDocumentNumber());
|
||||||
|
dto.setSignature(receta.setSignature());
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,8 @@ public class VacunaController {
|
||||||
dto.setExpirationDate(vacuna.getExpirationDate());
|
dto.setExpirationDate(vacuna.getExpirationDate());
|
||||||
dto.setPatientDocumentNumber(vacuna.getPatientDocumentNumber());
|
dto.setPatientDocumentNumber(vacuna.getPatientDocumentNumber());
|
||||||
dto.setReactions(vacuna.getReactions());
|
dto.setReactions(vacuna.getReactions());
|
||||||
|
dto.setPractitioner(receta.getPractitioner());
|
||||||
|
dto.setPractitionerDocumentNumber(receta.getPractitionerDocumentNumber());
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,4 +28,7 @@ public class Receta {
|
||||||
private String cantidad;
|
private String cantidad;
|
||||||
//@JsonFormat(pattern = "yyyy-MM-dd")
|
//@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
private String expectedSupplyDuration;
|
private String expectedSupplyDuration;
|
||||||
|
private String practitioner;
|
||||||
|
private String practitionerDocumentNumber;
|
||||||
|
private String signature;
|
||||||
}
|
}
|
||||||
|
|
@ -27,4 +27,7 @@ public class RecetaDto {
|
||||||
private String cantidad;
|
private String cantidad;
|
||||||
// @JsonFormat(pattern = "yyyy-MM-dd")
|
// @JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
private String expectedSupplyDuration;
|
private String expectedSupplyDuration;
|
||||||
|
private String practitioner;
|
||||||
|
private String practitionerDocumentNumber;
|
||||||
|
private String signature;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,5 +20,7 @@ public class Vacuna {
|
||||||
private String expirationDate;
|
private String expirationDate;
|
||||||
private String patientDocumentNumber;
|
private String patientDocumentNumber;
|
||||||
private String reactions;
|
private String reactions;
|
||||||
|
private String practitioner;
|
||||||
|
private String practitionerDocumentNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,4 +20,6 @@ public class VacunaDto {
|
||||||
private String expirationDate;
|
private String expirationDate;
|
||||||
private String patientDocumentNumber;
|
private String patientDocumentNumber;
|
||||||
private String reactions;
|
private String reactions;
|
||||||
|
private String practitioner;
|
||||||
|
private String practitionerDocumentNumber;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,11 @@ public class RecetaService {
|
||||||
contract.submitTransaction("EntregarReceta", recetaId);
|
contract.submitTransaction("EntregarReceta", recetaId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void firmarReceta(String recetaId, String signature)
|
||||||
|
throws CommitStatusException, EndorseException, CommitException, SubmitException {
|
||||||
|
contract.submitTransaction("FirmarReceta", recetaId, signature);
|
||||||
|
}
|
||||||
|
|
||||||
public List<Receta> obtenerRecetasPorDniYEstado(String dni, String estado) throws GatewayException, IOException {
|
public List<Receta> obtenerRecetasPorDniYEstado(String dni, String estado) throws GatewayException, IOException {
|
||||||
if (dni == null || dni.isBlank() || estado == null || estado.isBlank()) {
|
if (dni == null || dni.isBlank() || estado == null || estado.isBlank()) {
|
||||||
throw new IllegalArgumentException("DNI y estado son obligatorios");
|
throw new IllegalArgumentException("DNI y estado son obligatorios");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue