5.- Casos de uso PFI de ejemplo

5.- Casos de uso PFI de ejemplo

En este apartado se van a explicar diferentes casos de uso y cómo podría implementarlos una aplicación integradora.

 

Ejemplo 1: puesta a disposición de un documento para su firma, con un solo firmante 


Para que una aplicación pueda crear documentos y aparezcan en la aplicación  de PFI en pendientes de firma se necesitara llamar al createDocument de CCSV y integrarse con esa aplicación que están explicados en el apartado de la aplicación CCSV.  Pero para que se guarde en Pendientes de Firma en PFI debe haber una serie de meta-datos obligatorios como los de el firmante propuesto y el estado en pendiente de firma  para que se guarde automáticamente con este código de ejemplo se muestran los campos de como se debería guardar un documento para firmarlo en PFI: PASO 1: Envío del documento a CCSV
String idApp = "CCSV"; String filename = "prueba_CreateDocument.pdf"; CSVGenerator csvGenerator = new CSVGenerator(); String csv = csvGenerator.generateCSV("CCSV", "1"); Document doc = new Document(); doc.setApplicationCode(idApp); doc.setApplicationName(idApp); doc.setCsv(csv); doc.setExtension("PDF"); doc.setFormat(DocumentumConstants.Formato.PDF_A); doc.setName(filename); doc.setType(DocumentumConstants.TipoDocumental.DEA); ParamInitializeDocumentMetadata paramInitializeDocumentMetadata = new ParamInitializeDocumentMetadata(); paramInitializeDocumentMetadata.setDocument(doc); paramInitializeDocumentMetadata.setDocumentType(DocumentumConstants.TipoDocumento.DOCUMENTACION_JUSTIFICATIVA); paramInitializeDocumentMetadata.setProcedureCode("830"); paramInitializeDocumentMetadata.setApplicationId(idApp); ResultInitializeDocumentMetadata resultInitializeDocumentMetadata = ccsvClientDocumentMetadataSignatureService.initializeDocumentMetadata(paramInitializeDocumentMetadata); if (resultInitializeDocumentMetadata.getReturnCode().equals(ReturnCode.OK)) { try { InputStream documentInputStream = new FileInputStream("C:/Pruebas/CCSV_Tests/AST_EFIRMA_ManualIntegracion.pdf"); byte[] physicalDocumentByteArray = getBytesFromInputStream(documentInputStream); DataHandler docu = new DataHandler(new ByteArrayDataSource(physicalDocumentByteArray)); MessageDigest md = MessageDigest.getInstance("SHA"); byte[] hash = md.digest(physicalDocumentByteArray); Document document = resultInitializeDocumentMetadata.getDocument(); // Metadatos generales del documento // ------------------------------------------------------------------------------- HashMap<String, Object> metadatos = document.getMetadata(); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_CONTEXTO_GESTOR_COD_PROCEDIMIENTO, "830"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_CONTEXTO_GESTOR_NOMBRE_PROCEDIMIENTO, "PROCEDIMIENTO DE CONTRATACIÓN DEL SECTOR PÚBLICO"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_DESC_DESCRIPCION, "Pruebas CCSV-809"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_DESC_ESTADO, DocumentumConstants.Estado.PENDIENTE_DE_FIRMA); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_DESC_IDIOMA, DocumentumConstants.Idioma.CASTELLANO); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_DESC_NOMBRE, filename); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_DESC_TIPO_DOCUMENTO, DocumentumConstants.TipoDocumento.PUBLICACION_OFICIAL); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_CODIGO_CLASIFICACION, "0"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_DENOMINACION_CLASIFICACION, "Desconocido"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_CODIGO_APLICACION, "CCSV"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_CODIGO_REFERENCIA, "PRUEBA-LPL-20180905"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_CSV, csv); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_CSV_ESQUEMA, "CSV 1.0"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_FECHA_CAPTURA, "2018-09-05T09:00:00"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_NOMBRE_APLICACION, "CCSV"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_ORIGEN, DocumentumConstants.Origen.ADMINISTRACION); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_URL_VERIFICACION, "https://gobierno.aragon.es/verificadoc"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_VERSION_NTI_DGA, "http://www.aragon.es/NTI_2.0.0"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_NTI_TIPO_CATEGORIA, DocumentumConstants.Categoria.DOCUMENTO_SIMPLE); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_NTI_TIPO_ENTIDAD, DocumentumConstants.TipoEntidad.DOCUMENTO); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_SEGURIDAD_BLOQUEO, "N"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_SEGURIDAD_NIVEL_LOPD, DocumentumConstants.NivelLOPD.BASICO); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_SEG_VISIBLE_EXTERIOR, DocumentumConstants.Visible.VISIBLE); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_TECNICOS_FORMATO, DocumentumConstants.Formato.PDF_A); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_TECNICOS_SOPORTE_ORIGINAL, DocumentumConstants.SoporteOriginal.DIGITAL); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_VERIFICACION_ALGORITMO, "SHA-1"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_VERIFICACION_RESUMEN, BASE64Encoder.encode(hash).toString()); // FIRMANTE_PROPUESTO // ------------------------------------------------------------------------------- ParamInitializeStructuredMetadata paramInitializeStructuredMetadata = new ParamInitializeStructuredMetadata(DocumentumConstants.NombreMetadatos.PAEGA_FIRMANTE_PROPUESTO); paramInitializeStructuredMetadata.setApplicationId(idApp); ResultInitializeStructuredMetadata resultInitializeStructuredMetadata = ccsvClientDocumentMetadataSignatureService.initializeStructuredMetadata(paramInitializeStructuredMetadata); Document docfp = resultInitializeStructuredMetadata.getDocument(); HashMap<String, Object> firmante_propuesto = docfp.getMetadata(); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_DESCRIPCION_NOMBRE, "MANUELA BLANCO VIDAL"); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_FUNCIONARIO_CARGO, "ROL25248"); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_FUNCIONARIO_DESCRIPCION_CARGO, "Empleado"); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_FUNCIONARIO_ORGANISMO, "ORG07458"); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_IDENTIFICACION_IDENTIFICACION, "Q0100000I"); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_IDENTIFICACION_TIPO_IDENTIFICACION, "N"); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_NTI_TIPO_CATEGORIA, "Empleado Público"); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_NTI_TIPO_ENTIDAD, "Agente"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_FIRMANTE_PROPUESTO, docfp); // RELACIONES // ------------------------------------------------------------------------------- Object[] relaciones = (Object[]) metadatos.get(DocumentumConstants.NombreMetadatos.PAEGA_RELACION); for (Object ob : relaciones) { Document documentRelation = (Document) ob; if (documentRelation.getMetadata().get(DocumentumConstants.NombreMetadatos.PAEGA_RELACION_ROL).equals(DocumentumConstants.RolRelacion.APORTADOR)) { // Aportador Agent aportador = AgentRelationshipUtils.documentToAgent((Document) documentRelation.getMetadata().get(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE)); aportador.setCategory(DocumentumConstants.CategoriaAgente.FUNCIONARIO); aportador.setIdentificationType(DocumentumConstants.TipoIdentificacion.NIF); aportador.setIdentificationNumber("00000000T"); aportador.setName("PRUEBASPF APELLIDOUNOPF APELLIDODOSPF"); documentRelation.getMetadata().put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE, AgentRelationshipUtils.agentToDocument(aportador)); } else if (documentRelation.getMetadata().get(DocumentumConstants.NombreMetadatos.PAEGA_RELACION_ROL).equals(DocumentumConstants.RolRelacion.ORGANISMO_PRODUCTOR)) { // Organismo productor Agent productor = AgentRelationshipUtils.documentToAgent((Document) documentRelation.getMetadata().get(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE)); productor.setCategory(DocumentumConstants.CategoriaAgente.ORGANISMO); productor.setIdentificationType(DocumentumConstants.TipoIdentificacion.CODIGO_ORGANISMO_SIU); productor.setIdentificationNumber("ORG07458"); productor.setName("VICEPRESIDENCIA"); productor.setOrganismResponsible("96666666N"); documentRelation.getMetadata().put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE, AgentRelationshipUtils.agentToDocument(productor)); } else { System.out.println("Relaci?n no identificada: " + ((Document) ob).getMetadata().get(DocumentumConstants.NombreMetadatos.PAEGA_RELACION_ROL)); } } document.setContent(docu); ParamCreateDocument paramCreateDocument = new ParamCreateDocument(); paramCreateDocument.setApplicationId(idApp); paramCreateDocument.setDocument(document); paramCreateDocument.setNif("00000000T"); ResultCreateDocument result = ccsvClientDocumentMetadataSignatureService.createDocument(paramCreateDocument); if (result.getReturnCode().equals(ReturnCode.ERROR)) { System.out.println(result.getErrorCode()); System.out.println(result.getErrorMessage()); } else { System.out.println("Documento " + csv + " creado y pendiente de firma."); } } catch (Exception ex) { System.out.println(ex.getMessage()); } }
PASO 2: Notificar al firmante propuesto
String nif = "12345678X"; String csv = "csv_generado_en_punto_anterior"; IAdviceService.sendAdvice(PFICoreConstants.NOTE_TYPE_PROPOSEDSIGNER, csv, null, nif);
PASO 3: Capturar el cambio de estado de un documento
public class StateDocumentPFIImpl extends HttpServlet { private static final long serialVersionUID = 5954532668702585433L; private static final Logger LOG = CoreConfig.getLog(StateDocumentPFIImpl.class); private static final String INVALID_PARAMETERS = "Alguno de los parámetros necesarios está vacío"; private static final String INVALID_STATE = "Estado del documento no es válido"; private static final String UPDATESTATE_METHOD = "updateStateByPFI"; private static final String APPID_PARAM = "appId"; private static final String CSV_PARAM = "csv"; private static final String STATE_PARAM = "state"; private String appId; private IInfoService infoServicesPAUWS; private IDocumentManager documentManager; private ICCSVDocument ccsvManager; public void init() { WebApplicationContext applicationContext =ContextLoader.getCurrentWebApplicationContext(); appId = "ID_APLICACION_INTEGRADORA"; infoServicesPAUWS = (IInfoService) applicationContext.getBean("infoServicesPAUWS"); documentManager = (IDocumentManager) applicationContext.getBean("documentManager"); ccsvManager = (ICCSVDocument) applicationContext.getBean("ccsvManager"); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String applicationId = (String) request.getParameter(APPID_PARAM); String csv = (String) request.getParameter(CSV_PARAM); String state = (String) request.getParameter(STATE_PARAM); String ip = request.getRemoteAddr(); try { validateParameters(applicationId, csv, state, ip); authorizeRequest(applicationId, ip, UPDATESTATE_METHOD); updateStateByPFI(csv, state); } catch (InternalCoreException e) { throw new ServletException(e.getMsg(), e); } response.setStatus(HttpServletResponse.SC_OK); } private void validateParameters(String applicationId, String csv, String state, String ip) throws ServletException { if (applicationId == null || applicationId.equals("")) { throw new ServletException(INVALID_PARAMETERS); } if (csv == null || csv.equals("")) { throw new ServletException(INVALID_PARAMETERS); } if (state == null || state.equals("")) { throw new ServletException(INVALID_PARAMETERS); } if (ip == null || ip.equals("")) { throw new ServletException(INVALID_PARAMETERS); } } private void authorizeRequest(String remoteApplicationId, String ip, String methodName) throws InternalCoreException { LOG.info("BEGIN authorizeRequest " + remoteApplicationId + "-" + appId + "-" + ip); ResultAuthorizeApplication resultAuthorizeApplication = new ResultAuthorizeApplication(); try { // Obtenemos el código del método String methodCode = ""; ParamMethodApplicationList paramMethodApplicationList = new ParamMethodApplicationList(); paramMethodApplicationList.setApplicationAlias(appId); paramMethodApplicationList.setApplicationId(appId); ResultMethodApplicationList resultMethodApplicationList = infoServicesPAUWS.methodApplicationList(paramMethodApplicationList); es.aragon.pau.core.ws.data.Method[] methods = resultMethodApplicationList.getMethods(); for (es.aragon.pau.core.ws.data.Method m : methods) { if (m.getName().equals(methodName)) { methodCode = m.getMethodCode(); break; } } // Solicitamos autorización ParamAuthorizeApplication paramAuthorizeApplication = new ParamAuthorizeApplication(); paramAuthorizeApplication.setApplicationId(appId); paramAuthorizeApplication.setApplicationAliasA(remoteApplicationId); paramAuthorizeApplication.setApplicationAliasB(appId); paramAuthorizeApplication.setIp(ip); paramAuthorizeApplication.setMethodCode(methodCode); resultAuthorizeApplication = infoServicesPAUWS.authorizeApplication(paramAuthorizeApplication); LOG.info("Servicio PFI-SCE: Aplicación Llamante" + remoteApplicationId + " IP:" + ip); } catch (Exception e) { throw new InternalCoreException(SCECoreConstants.ERROR_APPLICATION_AUTHORIZATION, e); } // Si tiene errores pongo el mensaje de autorización if (resultAuthorizeApplication.isErrors()) { throw new InternalCoreException(SCECoreConstants.ERROR_APPLICATION_AUTHORIZATION, "La IP " + ip + " no está autorizada"); } LOG.info("END authorizeRequest " + remoteApplicationId + "-" + appId + "-" + ip); } private void updateStateByPFI(String csv, String ccsvState) throws InternalCoreException { LOG.info("BEGIN updateStateByPFI " + csv); if (DocumentumConstants.Estado.ORIGINAL.equals(ccsvState)){ //Este estado se recibirá cuando todos los firmantes hayan firmado correctamente el documento. //TODO: Realizar acciones necesarias en la Aplicación una vez que se conoce que el documento se ha firmado correctamente. } else if (DocumentumConstants.Estado.ANULADO.equals(ccsvState)) { //Este estado se recibirá cuando se haya rechazado la firma de un documento en Portafirmas por alguno de los firmantes. //TODO: Realizar acciones necesarias en la Aplicación una vez que se conoce que el documento ha sido rechazado por el firmante. } else if (DocumentumConstants.Estado.BORRADOR.equals(ccsvState)) { // Este estado se recibirá cuando por ejemplo el documento se ha propuesto para firmar por varios firmantes y haya transcurrido el periodo máximo fijado // por el preparador para realizar la firma sin que todos los firmantes hayan firmado el documento. //TODO: Realizar acciones necesarias en la Aplicación una vez que se conoce que el plazo trancurrido para la firma del documento por múltiples firmantes ha finalizado sin que todos ellos hayan firmado el documento. } else { // Se ha producido el cambio a un estado no esperado. //TODO: Realizar acciones necesarias en la aplicación para controlar el error. } LOG.info("END updateStateByPFI " + csv); } ... }

 

Ejemplo 2: puesta a disposición de documento con varios firmantes no siendo obligatorio la firma de todos para estar firmado.


 

Aunque el Portafirmas establece por defecto el quorum de un documento para que se ajuste a la cantidad de firmantes propuestos elegidos durante su preparación,  las aplicaciones integradoras tienen la posibilidad de alterar tanto el quorum del documento, como la fecha límite para completar el proceso de firma. El concepto de quorum en portafirmas representa la cantidad de firmas mínima que requiere un documento para pasar a firmado Tomando  como punto de partida un documento con 2 firmantes propuestos, podríamos alterar la puesta a disposición del documento para que no fuera obligatoria la firma de todos sus participantes, y aumentar el plazo para realizar su firma. Para ello deberíamos establecer el nuevo quorum del documento y su nueva fecha límite. PASO 1: Envío del documento a CCSV
String idApp = "CCSV"; String filename = "prueba_CreateDocument.pdf"; CSVGenerator csvGenerator = new CSVGenerator(); String csv = csvGenerator.generateCSV("CCSV", "1"); Document doc = new Document(); doc.setApplicationCode(idApp); doc.setApplicationName(idApp); doc.setCsv(csv); doc.setExtension("PDF"); doc.setFormat(DocumentumConstants.Formato.PDF_A); doc.setName(filename); doc.setType(DocumentumConstants.TipoDocumental.DEA); ParamInitializeDocumentMetadata paramInitializeDocumentMetadata = new ParamInitializeDocumentMetadata(); paramInitializeDocumentMetadata.setDocument(doc); paramInitializeDocumentMetadata.setDocumentType(DocumentumConstants.TipoDocumento.DOCUMENTACION_JUSTIFICATIVA); paramInitializeDocumentMetadata.setProcedureCode("830"); paramInitializeDocumentMetadata.setApplicationId(idApp); ResultInitializeDocumentMetadata resultInitializeDocumentMetadata = ccsvClientDocumentMetadataSignatureService.initializeDocumentMetadata(paramInitializeDocumentMetadata); if (resultInitializeDocumentMetadata.getReturnCode().equals(ReturnCode.OK)) { try { InputStream documentInputStream = new FileInputStream("C:/Pruebas/CCSV_Tests/AST_EFIRMA_ManualIntegracion.pdf"); byte[] physicalDocumentByteArray = getBytesFromInputStream(documentInputStream); DataHandler docu = new DataHandler(new ByteArrayDataSource(physicalDocumentByteArray)); MessageDigest md = MessageDigest.getInstance("SHA"); byte[] hash = md.digest(physicalDocumentByteArray); Document document = resultInitializeDocumentMetadata.getDocument(); // Metadatos generales del documento // ------------------------------------------------------------------------------- HashMap<String, Object> metadatos = document.getMetadata(); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_CONTEXTO_GESTOR_COD_PROCEDIMIENTO, "830"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_CONTEXTO_GESTOR_NOMBRE_PROCEDIMIENTO, "PROCEDIMIENTO DE CONTRATACIÓN DEL SECTOR PÚBLICO"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_DESC_DESCRIPCION, "Pruebas CCSV-809"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_DESC_ESTADO, DocumentumConstants.Estado.PENDIENTE_DE_FIRMA); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_DESC_IDIOMA, DocumentumConstants.Idioma.CASTELLANO); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_DESC_NOMBRE, filename); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_DESC_TIPO_DOCUMENTO, DocumentumConstants.TipoDocumento.PUBLICACION_OFICIAL); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_CODIGO_CLASIFICACION, "0"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_DENOMINACION_CLASIFICACION, "Desconocido"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_CODIGO_APLICACION, "CCSV"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_CODIGO_REFERENCIA, "PRUEBA-LPL-20180905"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_CSV, csv); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_CSV_ESQUEMA, "CSV 1.0"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_FECHA_CAPTURA, "2018-09-05T09:00:00"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_NOMBRE_APLICACION, "CCSV"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_ORIGEN, DocumentumConstants.Origen.ADMINISTRACION); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_URL_VERIFICACION, "https://gobierno.aragon.es/verificadoc"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_IDENT_VERSION_NTI_DGA, "http://www.aragon.es/NTI_2.0.0"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_NTI_TIPO_CATEGORIA, DocumentumConstants.Categoria.DOCUMENTO_SIMPLE); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_NTI_TIPO_ENTIDAD, DocumentumConstants.TipoEntidad.DOCUMENTO); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_SEGURIDAD_BLOQUEO, "N"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_SEGURIDAD_NIVEL_LOPD, DocumentumConstants.NivelLOPD.BASICO); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_SEG_VISIBLE_EXTERIOR, DocumentumConstants.Visible.VISIBLE); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_TECNICOS_FORMATO, DocumentumConstants.Formato.PDF_A); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_TECNICOS_SOPORTE_ORIGINAL, DocumentumConstants.SoporteOriginal.DIGITAL); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_VERIFICACION_ALGORITMO, "SHA-1"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_VERIFICACION_RESUMEN, BASE64Encoder.encode(hash).toString()); // FIRMANTE_PROPUESTO 1 // ------------------------------------------------------------------------------- ParamInitializeStructuredMetadata paramInitializeStructuredMetadata = new ParamInitializeStructuredMetadata(DocumentumConstants.NombreMetadatos.PAEGA_FIRMANTE_PROPUESTO); paramInitializeStructuredMetadata.setApplicationId(idApp); ResultInitializeStructuredMetadata resultInitializeStructuredMetadata = ccsvClientDocumentMetadataSignatureService.initializeStructuredMetadata(paramInitializeStructuredMetadata); Document docfp = resultInitializeStructuredMetadata.getDocument(); HashMap<String, Object> firmante_propuesto = docfp.getMetadata(); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_DESCRIPCION_NOMBRE, "MANUELA BLANCO VIDAL"); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_FUNCIONARIO_CARGO, "ROL25248"); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_FUNCIONARIO_DESCRIPCION_CARGO, "Empleado"); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_FUNCIONARIO_ORGANISMO, "ORG07458"); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_IDENTIFICACION_IDENTIFICACION, "Q0100000I"); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_IDENTIFICACION_TIPO_IDENTIFICACION, "N"); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_NTI_TIPO_CATEGORIA, "Empleado Público"); firmante_propuesto.put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_NTI_TIPO_ENTIDAD, "Agente"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_FIRMANTE_PROPUESTO, docfp); // FIRMANTE_PROPUESTO 2 // ------------------------------------------------------------------------------- ParamInitializeStructuredMetadata paramInitializeStructuredMetadata2 = new ParamInitializeStructuredMetadata(DocumentumConstants.NombreMetadatos.PAEGA_FIRMANTE_PROPUESTO); paramInitializeStructuredMetadata2.setApplicationId(idApp); paramInitializeStructuredMetadata resultInitializeStructuredMetadata2 = ccsvClientDocumentMetadataSignatureService.initializeStructuredMetadata(paramInitializeStructuredMetadata); Document docfp2 = resultInitializeStructuredMetadata2.getDocument(); HashMap<String, Object> firmante_propuesto_2 = docfp2.getMetadata(); firmante_propuesto_2 .put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_DESCRIPCION_NOMBRE, "JUAN CARLOS BLANCO VIDAL"); firmante_propuesto_2 .put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_FUNCIONARIO_CARGO, "ROL25248"); firmante_propuesto_2 .put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_FUNCIONARIO_DESCRIPCION_CARGO, "Empleado"); firmante_propuesto_2 .put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_FUNCIONARIO_ORGANISMO, "ORG07458"); firmante_propuesto_2 .put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_IDENTIFICACION_IDENTIFICACION, "Q0200000X"); firmante_propuesto_2 .put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_IDENTIFICACION_TIPO_IDENTIFICACION, "N"); firmante_propuesto_2 .put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_NTI_TIPO_CATEGORIA, "Empleado Público"); firmante_propuesto_2 .put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE_NTI_TIPO_ENTIDAD, "Agente"); metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_FIRMANTE_PROPUESTO, docfp2); // RELACIONES // ------------------------------------------------------------------------------- Object[] relaciones = (Object[]) metadatos.get(DocumentumConstants.NombreMetadatos.PAEGA_RELACION); for (Object ob : relaciones) { Document documentRelation = (Document) ob; if (documentRelation.getMetadata().get(DocumentumConstants.NombreMetadatos.PAEGA_RELACION_ROL).equals(DocumentumConstants.RolRelacion.APORTADOR)) { // Aportador Agent aportador = AgentRelationshipUtils.documentToAgent((Document) documentRelation.getMetadata().get(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE)); aportador.setCategory(DocumentumConstants.CategoriaAgente.FUNCIONARIO); aportador.setIdentificationType(DocumentumConstants.TipoIdentificacion.NIF); aportador.setIdentificationNumber("00000000T"); aportador.setName("PRUEBASPF APELLIDOUNOPF APELLIDODOSPF"); documentRelation.getMetadata().put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE, AgentRelationshipUtils.agentToDocument(aportador)); } else if (documentRelation.getMetadata().get(DocumentumConstants.NombreMetadatos.PAEGA_RELACION_ROL).equals(DocumentumConstants.RolRelacion.ORGANISMO_PRODUCTOR)) { // Organismo productor Agent productor = AgentRelationshipUtils.documentToAgent((Document) documentRelation.getMetadata().get(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE)); productor.setCategory(DocumentumConstants.CategoriaAgente.ORGANISMO); productor.setIdentificationType(DocumentumConstants.TipoIdentificacion.CODIGO_ORGANISMO_SIU); productor.setIdentificationNumber("ORG07458"); productor.setName("VICEPRESIDENCIA"); productor.setOrganismResponsible("96666666N"); documentRelation.getMetadata().put(DocumentumConstants.NombreMetadatos.PAEGA_AGENTE, AgentRelationshipUtils.agentToDocument(productor)); } else { System.out.println("Relaci?n no identificada: " + ((Document) ob).getMetadata().get(DocumentumConstants.NombreMetadatos.PAEGA_RELACION_ROL)); } } document.setContent(docu); ParamCreateDocument paramCreateDocument = new ParamCreateDocument(); paramCreateDocument.setApplicationId(idApp); paramCreateDocument.setDocument(document); paramCreateDocument.setNif("00000000T"); ResultCreateDocument result = ccsvClientDocumentMetadataSignatureService.createDocument(paramCreateDocument); if (result.getReturnCode().equals(ReturnCode.ERROR)) { System.out.println(result.getErrorCode()); System.out.println(result.getErrorMessage()); } else { System.out.println("Documento " + csv + " creado y pendiente de firma."); } } catch (Exception ex) { System.out.println(ex.getMessage()); } }
PASO 2: Establecer los nuevos parámetros del documento
ParamUpdateQuorumAndLimitDate paramCheckQuorumAndDate = new ParamUpdateQuorumAndLimitDate(); // Se indica el código seguro de verificación del documento en CCSV generado en el paso anterior paramCheckQuorumAndDate.setCsv(csv); // Se establece la nueva cantidad de firmantes mínima paramCheckQuorumAndDate.setQuorum(1); // Se establece la nueva fecha límite para firmar el documento Calendar cal = Calendar.getInstance(); cal.setTime(new Date()); Integer deferedDate = 7; cal.add(Calendar.DATE, deferedDate); paramCheckQuorumAndDate.setDate(cal.getTime()); // Realizamos la llamada al método ResultUpdateQuorumAndLimitDate resultCheckQuorumAndDate = iDocumentIntegrationService.updateQuorumAndLimitDateDocument(paramCheckQuorumAndDate);
PASO 3: Capturar el cambio de estado de un documento La aplicación integradora implementaría su Servlet del mismo modo que en el ejemplo anterior.

 

Ejemplo 3: Documento estado original y documento en estado copia


Para crear un documento en estado original

Se debe rellenar el metadato dea_desc_estado con valor P. No se debe rellenar el metadato dea_desc_tipo_copia.

En los metadatos que se rellenan para invocar a createDocument de CCSV, el metadato dea_desc_estado se rellenaría de la siguiente forma:

metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_DESC_ESTADO, DocumentumConstants.Estado.PENDIENTE_DE_FIRMA);

Cuando el documento quede en estado firmado en PFI, el valor del metadato dea_desc_estado será 0 (Firmado).

 

Para crear un documento en estado copia

Se debe rellenar el metadato dea_desc_estado con valor P y el metadato dea_desc_tipo_copia con un valor que esté en el rango entre 0 y 5. 

En los metadatos que se rellenan para invocar a createDocument de CCSV, los metadatos quedarían de la siguiente forma:

metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_DESC_TIPO_COPIA, DocumentumConstants.Estado.PENDIENTE_DE_FIRMA); // en este caso se indica a modo de ejemplo copia simple metadatos.put(DocumentumConstants.NombreMetadatos.PAEGA_DESC_TIPO_COPIA, DocumentumConstants.TipoCopia.COPIA_SIMPLE);

Cuando el documento quede en estado firmado en PFI, el valor del metadato dea_desc_estado será 2 (Copia) y el valor del metadato dea_desc_tipo_copia será el valor (entre 0 y 5) que se había introducido anteriormente al crear el documento.

 

Ejemplo 4: Ejemplo de como crear un documento de firma secuencial invocando a CCSV 


PASO 1: Envío del documento a CCSV, se envía la petición al createDocument de CCSV { "0": { "aclName": "dga_acl_paega_web", "applicationCode": "DGA - Aplicacion PAEGA", "applicationId": "XFILES", "folderId": "0b06fca38caa0147", "folderType": "dga_carpeta", "ip": "172.27.47.17", "metadataRelationType": "dga_paea_relacion_datos", "repository": "ARAInt" }, "1": { "applicationCode": "XFILES", "applicationName": "XFILES", "csv": "CSVUB04XMD0K9180XFIL", "extension": "pdf", "format": "PDF", "metadata": { "dea_cont_codprocedimiento": 466, "dea_cont_nom_procedimiento": "PROCEDIMIENTO QUE REGULA LA ADMISIÓN DE ALUMNOS EN LOS CENTROS DOCENTES PÚBLICOS Y PRIVADOS CONCERTADOS", "dea_desc_descripcion": "prueba documentacion sendAdvice", "dea_desc_estado": "P", "dea_desc_idioma": "es", "dea_desc_nombre": "260KB.pdf", "dea_desc_tipo_documento": "ACEPTACION", "dea_ident_clasif_codigo": 0, "dea_ident_clasifdenominacio": "Desconocido", "dea_ident_codigo_aplicacion": "XFILES", "dea_ident_csv": "CSVUB04XMD0K9180XFIL", "dea_ident_csv_esquema": "CSV 1.0", "dea_ident_fecha_captura": "2026-05-26T17:22:20", "dea_ident_id_nti": "ES_A02002834_2026_0000000000CSVUB04XMD0K9180XFIL", "dea_ident_nombre_aplicacion": "XFILES", "dea_ident_origen": 0, "dea_ident_url_verificacion": "https://gobierno.aragon.es/verificadoc", "dea_ident_version_nt_dga": "http://www.aragon.es/NTI_2.0.0", "dea_nti_categoria": "Documento Simple", "dea_nti_tipo_entidad": "DOCUMENTO", "dea_seg_bloqueo": "N", "dea_seg_nivel_lopd": "NS", "dea_seg_visible_exterior": "P", "dea_tec_formato": "PDF", "dea_tec_num_paginas": 46, "dea_tec_soporte_original": 0, "dea_verificacion_algoritmo": "SHA-512", "dea_verificacion_resumen": "IDRDJDzBSB8i5lqJRI3msKVonaWk+d4M4krKfHu5bjs4hbOvfjcw+Y2huwEIbEnA1cGuoY4qceFwdyGlu58TEg==", "dimensiones": [ { "metadata": { "dimensiones_dim_fisica": "0", "dimensiones_tam_logico": "260.35", "dimensiones_unidades": "kB" }, "name": "dimensiones", "type": "dga_paega_dimensiones" } ], "firmante_propuesto": [ { "metadata": { "agente_desc_nombre": "Juan Antonio Maldonado Vazquez", "agente_func_cargo": "JOB27665", "agente_func_descrip_cargo": "PUESTO JAMV", "agente_func_organismo": "ORG07458", "agente_ident_identificacion": "74736630Q", "agente_ident_tipo_identif": "N", "agente_nti_categoria": "Empleado Público", "agente_nti_tipo_entidad": "AGENTE", "firmante_prop_orden": "1", "firmante_prop_pseudonimo": "N" }, "name": "firmante_propuesto", "type": "dga_paega_firmante_prop" }, { "metadata": { "agente_desc_nombre": "Adrián Urbano Artiaga", "agente_func_cargo": "JOB23903", "agente_func_descrip_cargo": "Pruebas", "agente_func_organismo": "ORG17679", "agente_ident_identificacion": "76919168S", "agente_ident_tipo_identif": "N", "agente_nti_categoria": "Empleado Público", "agente_nti_tipo_entidad": "AGENTE", "firmante_prop_orden": "2", "firmante_prop_pseudonimo": "N" }, "name": "firmante_propuesto", "type": "dga_paega_firmante_prop" } ], "relacion": [ { "metadata": { "agente": { "metadata": { "agente_desc_nombre": "JUAN ANTONIO MALDONADO VAZQUEZ", "agente_ident_identificacion": "74736630Q", "agente_ident_tipo_identif": "N", "agente_nti_categoria": "Empleado Público", "agente_nti_tipo_entidad": "AGENTE" }, "name": "agente", "type": "dga_paega_agente" }, "relacion_nti_categoria": "AGENTE", "relacion_nti_tipo_entidad": "RELACION", "relacion_rol": "APORTADOR" }, "name": "relacion", "type": "dga_paega_relacion" }, { "metadata": { "agente": { "metadata": { "agente_desc_nombre": "DIRECCIÓN GENERAL DE PLANIFICACIÓN, CENTROS Y FORMACIÓN PROFESIONAL", "agente_ident_identificacion": "ORG20146", "agente_ident_tipo_identif": "S", "agente_nti_categoria": "Organismo", "agente_nti_tipo_entidad": "AGENTE" }, "name": "agente", "type": "dga_paega_agente" }, "relacion_nti_categoria": "AGENTE", "relacion_nti_tipo_entidad": "RELACION", "relacion_rol": "ORGANISMO PRODUCTOR" }, "name": "relacion", "type": "dga_paega_relacion" } ] }, "name": "260KB.pdf", "type": "dga_paega_doc_dea" }, "2": "false" } PASO 2: Se crea el documento en PFI llamando al sendDocumentumDocument de PFI (Esta llamada se realiza desde CCSV tras invocar el método anterior) { "applicationId": "CCSV", "csv": "CSVUB04XMD0K9180XFIL" } PASO 3: Se envía la notificación invocando el método sendAdvice de PFI { "sendAdvice": { "arg0": 2, "arg1": "CSVVW346G22K71C0XFIL", "arg2": "Mensaje para la notificación de documento de PFI", "arg3": "99999999R" } }

 

Ejemplo 5: Ejemplo de como rechazar o recuperar un documento Pendiente de firma

 

Para recuperar o rechazar un documento en estado Pendiente de firma, se debe invocar al servicio reviseOrRejectDocument. A este servicio solo se debe invocar con documentos Pendientes de firma y la acción no la puede hacer (no se debe dejar) que la haga un ciudadano (firmante externo no existente en SIU). La invocación a este método devuelve el documento a Borrador en PFI, y lo anula en CCSV.

 

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.core.pfi.aragon.es/"> <soapenv:Header/> <soapenv:Body> <ws:reviseOrRejectDocument> <!-- SI ESTA ELIMINADO EN CCSV DARA ERROR PERO SE RECHAZA IGUALMENTE--> <arg0> <!--Optional:--> <applicationId>appInvocante</applicationId> <userNif>NifUsuario</userNif> <noteDate>2026-05-15T12:51:00</noteDate> <text>Motivo del rechazo o recuperación</text> <!--Optional: --> <type>0</type> <!--Optional:--> <userName>NombreUsuario</userName> <!--Optional:--> <userSurname1>Apellido1Usuario</userSurname1> <!--Optional:--> <userSurname2>Apellido2Usuario</userSurname2> </arg0> <!--Zero or more repetitions:--> <arg1>csvDocumentoARechazar</arg1> <!--Optional:--> <arg4>NifUsuario</arg4> </ws:reviseOrRejectDocument> </soapenv:Body> </soapenv:Envelope>

 

 

Ejemplo 6: Ejemplo de como anular un documento Firmado

 

Para anular un documento en estado Firmado, se debe invocar al servicio deleteDocument. A este servicio solo se debe invocar con documentos Firmados y la acción la debería hacer un firmante del documento a anular. La invocación a este método marca el documento como Eliminado en PFI, pero no lo anula en CCSV, por lo que es necesario invocar a CCSV para cambiar el estado.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.core.pfi.aragon.es/"> <soapenv:Header/> <soapenv:Body> <ws:deleteDocument> <!--Optional:--> <arg0> <!--Optional:--> <applicationId>appInvoca</applicationId> <!--Optional:--> <userNif>NifUsuario</userNif> <csv>csvDocumentoAnular</csv> </arg0> </ws:deleteDocument> </soapenv:Body> </soapenv:Envelope>

 

Una vez marcado el documento en PFI como Eliminado, será necesario invocar al servicio changeState de CCSV para marcar como Anulado el documento.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.core.ccsv.aragon.es/" xmlns:doc="http://documentmetadata.data.ws.core.ccsv.aragon.es" xmlns:data="http://data.util.core.ccsv.aragon.es"> <soapenv:Header/> <soapenv:Body> <ws:changeState> <!--Optional:--> <ws:arg0> <!--Optional:--> <doc:applicationId>appInvocante</doc:applicationId> <!--Optional:--> <doc:csv>csvDocumentoAnular</doc:csv> <!--Optional:--> <doc:ip>ipdesdelaqueseinvoca</doc:ip> <!--Optional:--> <doc:nif>NifUsuario</doc:nif> <!--Optional:--> <doc:state>A</doc:state> <!--Optional:--> <doc:traceData> <!--Optional:--> <data:reason>Motivo anulación</data:reason> </doc:traceData> </ws:arg0> </ws:changeState> </soapenv:Body> </soapenv:Envelope>