> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Exemple de traitement manuel

> Découvrez pas à pas un exemple d’API ABBYY FlexiCapture qui ajoute une étape de service personnalisée pour relire des tâches, accepter ou rejeter des documents, et joindre une signature numérique.

Cet exemple montre comment créer une étape supplémentaire de traitement manuel des données. Par exemple, le service de sécurité de votre entreprise peut utiliser cette étape pour vérifier et valider l’envoi des documents qui remplissent certaines conditions en vue d’un traitement ultérieur, et rejeter ceux qui ne les remplissent pas.

Chaque document validé est accompagné d’une séquence d’octets qui imite une signature numérique.

<div id="what-the-example-does">
  ## Ce que fait l’exemple
</div>

L’exemple effectue les étapes suivantes :

* Configure la connexion
* Commence à travailler sur le projet
* Récupère et traite la liste des tâches
* Traite chaque tâche à l’étape de service
* Téléverse le fichier sur le serveur
* Ferme la session

<div id="run-the-example">
  ## Exécuter l’exemple
</div>

<Steps>
  <Step title="Ouvrir la solution dans Visual Studio">
    Ouvrez `UserStageExample.sln` dans Visual Studio 2013 ou une version plus récente.
  </Step>

  <Step title="Saisir l’URL du serveur d’applications">
    Saisissez l’URL du serveur d’applications.
  </Step>

  <Step title="Sélectionner un type d’authentification">
    Sélectionnez un type d’authentification.
  </Step>

  <Step title="Se connecter">
    Cliquez sur **login**.
  </Step>
</Steps>

<div id="configure-the-connection">
  ## Configurer la connexion
</div>

```csharp theme={null}
private const string FlexiHandlerPath = "/FlexiCapture12/Server/{0}API/v1/Soap"; // Chemin vers l'API FlexiCapture
private const string FlexiCaptureAuthPart = "FCAuth/"; // Chemin pour l'authentification FlexiCapture
private const string UserStageProjectName = "UserStageExample"; // Le nom du projet utilisé dans cet exemple
private const string UserStageName = "Service"; // Le nom de l'étape de service
// Création d'une nouvelle liaison
var binding = new BasicHttpBinding();
// La taille des messages est trop petite pour FlexiCapture et doit être augmentée
binding.MaxReceivedMessageSize = MessageSize;
// Sélection du mode de sécurité de connexion en fonction du protocole
binding.Security.Mode = serverUri.Scheme == Uri.UriSchemeHttps
   ? BasicHttpSecurityMode.Transport
   : BasicHttpSecurityMode.TransportCredentialOnly;
// Sélection de la méthode d'authentification
binding.Security.Transport.ClientCredentialType = windowsAuth
   ? HttpClientCredentialType.Windows
   : HttpClientCredentialType.Basic;
// Sélection du chemin vers l'API en fonction de la méthode d'authentification
var externalSuffix = windowsAuth ? string.Empty : FlexiCaptureAuthPart;
var remoteAddress = new EndpointAddress(new Uri(serverUri, string.Format(FlexiHandlerPath, externalSuffix)));
// Création d'un client SOAP
_client = new FlexiCapture.FlexiCaptureWebServiceSoapClient(binding, remoteAddress);
// Pour l'authentification FlexiCapture, spécifiez un identifiant et un mot de passe
if (_client.ClientCredentials != null && !windowsAuth)
{
   _client.ClientCredentials.UserName.UserName = login;
   _client.ClientCredentials.UserName.Password = password;
}
```

<div id="start-working-with-the-project">
  ## Commencer à travailler sur le projet
</div>

```csharp theme={null}
// Ouverture de la session
_sessionId = _client.OpenSession(RoleType, WorkstationType);
var projectGuid = string.Empty;
// Recherche du projet requis
foreach (var project in _client.GetProjects())
{
   if (project.Name == UserStageProjectName)
   {
      projectGuid = project.Guid;
   }
}
if (string.IsNullOrEmpty(projectGuid))
{
   MessageBox.Show("The server does not contain the UserStageExample project which is needed for this example");
}
// Ouverture du projet
_projectId = _client.OpenProject(_sessionId, projectGuid);
// Recherche et enregistrement de l'identifiant de l'étape de service
var stages = _client.GetProcessingStages(_projectId, 0, 0, UserStageName);
if (stages.Count != 1) throw new Exception("Invalid project");
   _serviceStageId = stages[0].Id;
// Recherche et enregistrement de l'ID externe de l'étape des exceptions
stages = _client.GetProcessingStages(_projectId, 0, ExceptionStageType, string.Empty);
if (stages.Count != 1) throw new Exception("Invalid project");
   _exceptionsStageId = stages[0].ExternalId;
```

<div id="get-and-process-tasks-pending-at-the-service-stage">
  ## Récupération et traitement des tâches en attente à l’étape de service
</div>

```csharp theme={null}
// Récupération de la liste des tâches
var tasks = _client.GetAvailableTasksByStageId(_sessionId, _projectId,
new FlexiCapture.stageIds() { _serviceStageId }, false);
var result = new Dictionary<int, Task>();
if (tasks == null || tasks.Count == 0) return result;
foreach (var task in tasks)
{
   // Pour chaque tâche, un objet de type Task est créé
   var item = new Task
   {
      Id = task.Id,
      BatchId = task.BatchId
   };
   // Récupération de la liste des documents de la tâche
   var documents = _client.GetTaskDocuments(task.Id);
   if (documents == null || documents.Count == 0) continue;
   foreach (var document in documents)
   {
      // Chargement du XML de la tâche
      var file = _client.LoadDocumentResult(_sessionId, document.BatchId, document.Id, "DocumentBody"); // "DocumentBody" - le nom du fichier contenant les données reconnues
      if (file == null || file.Bytes == null) continue;
      // Analyse et décomposition du XML
      var doc = new Document(document.Id, XDocument.Load(new MemoryStream(file.Bytes)));
      // Enregistrement de la liste de documents décomposée
      item.Documents.Add(document.Id, doc);
   }
   result.Add(item.Id, item);
}
```

<div id="send-the-task-for-further-processing">
  ## Envoyer la tâche pour traitement ultérieur
</div>

```csharp theme={null}
var ids = new FlexiCapture.docIds();
foreach (var rejectedDocument in rejectedDocuments)
{
   ids.Add(rejectedDocument.Id);
}
if (ids.Count > 0)
{
   _client.CreateTask(_sessionId, batchId, _exceptionsStageId, 0, "Rejection reason", 0, ids, false);
}
_client.OpenBatch(_sessionId, batchId);
var hasDocuments = false;
try
{
   var uri = _client.Endpoint.Address.Uri.OriginalString.Replace("/API/v1/Soap", "/FileService/v1");
   foreach (var document in acceptedDocuments)
   {
      hasDocuments = true;
      var buffer = new byte[SignatureSize]; // La taille de la signature numérique ajoutée aux documents : 1024
      _rng.GetBytes(buffer);
      //DocumentAttachment: Le type de pièce jointe (9 - pièce jointe au document)
      _client.SaveAttachment(_sessionId, DocumentAttachment, document.Id, batchId, _projectId, new FlexiCapture.File
      {
         Bytes = buffer,
         Name = "Signature.dat"
      });
      document.CreateStamp();
      UploadTextFileToServer(new Uri(uri),
         _client.ClientCredentials.UserName.UserName,
         _client.ClientCredentials.UserName.Password,
         document.GetXml(), 0, _sessionId, _projectId,
         batchId, 0, document.Id, 0, "DocumentBody"
      ).Wait();
   }
};
```

<div id="upload-the-file-to-the-server">
  ## Téléverser le fichier sur le serveur
</div>

```csharp theme={null}
private static async Task<string> UploadTextFileToServer(Uri server, string login, string password,
        string stream, int objectType, int sessionId, int projectId, int batchId, int parentId,
        int objectId, int version, string streamName)
{
        var creds = CredentialCache.DefaultNetworkCredentials;
        if (!string.IsNullOrEmpty(login)) creds = new NetworkCredential(login, password);
        using (var handler = new HttpClientHandler { Credentials = creds })
        using (var client = new HttpClient(handler))
        {
                var encodedStreamName = Convert.ToBase64String(Encoding.Unicode.GetBytes(streamName));
                var content = new MultipartFormDataContent
                {
                        {new StringContent("Save"), "Action"},
                        {new StringContent(objectType.ToString()), "objectType"},
                        {new StringContent(sessionId.ToString()), "sessionId"},
                        {new StringContent(projectId.ToString()), "projectId"},
                        {new StringContent(batchId.ToString()), "batchId"},
                        {new StringContent(parentId.ToString()), "parentId"},
                        {new StringContent(objectId.ToString()), "objectId"},
                        {new StringContent(version.ToString()), "version"},
                        {new StringContent(encodedStreamName), "streamName"},
                        {new ByteArrayContent(Encoding.Unicode.GetBytes(stream)), "blob", "data.txt"}
                };
                var msg = client.PostAsync(server, content).Result;
                return await msg.Content.ReadAsStringAsync();
        }
}
```

<div id="close-the-session">
  ## Fermer la session
</div>

```csharp theme={null}
_client.CloseProject(_sessionId, _projectId);
   _client.CloseSession(_sessionId);
```
