# Anexar ficheiros

## Anexar ficheiro a um documento

O processo é realizado em dois passos. No primeiro o ficheiro é transferido para o servidor de uploads para uma área temporária. No segundo passo a API é utilizada para estabelecer  a associação ao documento sendo então o ficheiro arquivado definitivamente.

A tabela apresenta os URL de API e UPLOAD em função do serviço:

| URL applicação                                             | API\_URL                                                    | API\_URL                                         |
| ---------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------ |
| app.cloudware.pt                                           | <p>\<a href="<https://api-cwb.cldware.com>                  |                                                  |
| "><https://api-cwb.cldware.com><br></a></p>                | <p>\<a href="<https://upload-cwb-opo.cldware.com/upload>    |                                                  |
| "><https://upload-cwb-opo.cldware.com/upload> <br></a></p> |                                                             |                                                  |
| app<1-6>.toconline.pt                                      | [https://api.toconline.pt](<https://api.toconline.pt&#xA;>) | <p>\<a href="<https://fsopo.toconline.pt/upload> |
| "><https://fsopo.toconline.pt/upload><br></a></p>          |                                                             |                                                  |
| app<7-12>.toconline.pt                                     | <p>\<a href="<https://api.toconline.pt>                     |                                                  |
| "><https://api.toconline.pt><br></a></p>                   | <p>\<a href="<https://fslis.toconline.pt/upload>            |                                                  |
| "><https://fslis.toconline.pt/upload><br></a></p>          |                                                             |                                                  |
|                                                            |                                                             |                                                  |

Para utilizar os exemplos deste guia sugerimos exportar a configuração para variáveis de shell, por exemplo para o serviço Cloudware Business, depois obter um token de acesso definir as seguintes  variáveis.

```
export API_URL="https://api-cwb.cldware.com"
export UPLOAD_URL="https://upload-cwb-opo.cldware.com/upload"
export ACCESS_TOKEN="1-42-104-e17d72a5254029bc41d9b3c65795008cdf00278f1151cf31527fe3d3548335dd"
```

### 1º Passo transferir ficheiro para o servidor de arquivo

Neste passo o ficheiro é transferido para uma área temporária no servidor de ficheiros, o método devolve o caminho para um ficheiro único temporário que será mantido durante sete dias.&#x20;

```
curl -X 'POST' ${UPLOAD_URL} \
-H "Content-Type: application/octet-stream" \
-H "Content-Disposition: attachment" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
--data-binary @teste.pdf
```

#### Resposta de sucesso

O servidor de ficheiros retorna no atributo `file` o identificador do ficheiro temporário que será utilizado no próximo passo.

{% hint style="success" %}
200 Ficheiro transferido com sucesso (Content-Type: application/json)

```bash
{
  "file": "2021-02-20/MekIAU.ul"
}
```

{% endhint %}

{% hint style="info" %}
Para usar este identificador no exemplo do passo 2 coloque-o na variavel TEMP\_FILE  &#x20;

```bash
export TEMP_FILE="2021-02-20/MekIAU.ul"
```

{% endhint %}

####

#### Respostas de erro

{% hint style="warning" %}
413 Ficheiro excede o limite de 50 MB, resposta (Content-Type: text/html)

```bash
curl -X 'POST' ${UPLOAD_URL} \
-H "Content-Type: application/octet-stream" \
-H "Content-Disposition: attachment" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-F "data=@lixo.pdf"
<html>
<head><title>413 Request Entity Too Large</title></head>
<body>
<center><h1>413 Request Entity Too Large</h1></center>
<hr><center>nginx/1.16.1</center>
</body>
</html>
```

{% endhint %}

{% hint style="warning" %}
401 Token de acesso não é válido (Content-Type: text/html)

```bash
curl -X 'POST' ${UPLOAD_URL} \
-H "Content-Type: application/octet-stream" \
-H "Content-Disposition: attachment" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-F "data=@teste.pdf"
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.16.1</center>
</body>
</html>
```

{% endhint %}

### 2º  Passo associar ficheiro ao documento

A API disponibiliza três rotas para associar anexos  documentos:

* `/api/attachments/purchases_documents/:document_id` - para associar a facturas de compra
* `/api/attachments/documents/:document_id` - para associar a facturas de venda
* `/api/attachments/receipts/:document_id` - para associar a recibos

Estas rotas aceitam pedidos POST com o seguinte body:

```bash
{
  "data": {
    "type": "attachment",
    "attributes": {
      "file": <nome do ficheiro temporário obtido no 1º passo>,
      "file_name": <nome com que o ficheiro será arquivado e exibido ao utilizador>,
      "file_type": <application/pdf ou image/jpeg ou image/png>
    }
  }
}
```

Exemplo de pedido para factura de compra, para executar definir `TEMP_FILE` com valor obtido no 1º passo e `DOCUMENT_ID` com o identificador de uma fatura de compra da empresa.

{% hint style="warning" %}
413 A empresa não tem espaço disponível, será  necessário comprar mais espaço arquivo (Content-Type: application/json)

```bash
{
  "errors": [
    {
      "status": "413",
      "code": "JA000",
      "detail": "Excedeu o limite de espaço do seu arquivo digital"
    }
  ]
}
```

{% endhint %}

{% hint style="warning" %}
401 A empresa não tem o módulo de arquivo digital activado ou utilizador da sessão não tem permissão para aceder (Content-Type: application/json)

```bash
{
  "errors": [
    {
      "code": "FORBIDDEN_BY_GATEKEEPER",
      "detail": "",
      "meta": {
        "internal-error": {
          "method": "POST",
          "path": "/attachments/purchases_documents/944306",
          "why": "Access denied by rule at index 120."
        }
      },
      "status": "401 - Access Denied"
    }
  ]
}
```

{% endhint %}

{% hint style="warning" %}
400 Pedido inválido (Content-Type: application/json)

```bash
{
  "errors": [
    {
      "status": "400",
      "code": "JA000",
      "detail": "mandatory 'file_name' attribute not supplied"
    }
  ]
}
```

{% endhint %}

## Remover anexo do documento

Para remover um anexo enviar um pedido DELETE para a rota

* /api/attachments/:documenttype/:documentid/:archiveid em que o `archive_id` é valor retornado no 2º passo&#x20;

Exemplo de comando para remover o anexo inserido no passo 2

```bash
curl -X 'DELETE' ${API_URL}/api/attachments/purchases_documents/${DOCUMENT_ID}/${ARCHIVE_ID} \
 -H "Content-Type: application/vnd.api+json" \
 -H "Authorization: bearer ${ACCESS_TOKEN}" 
```

{% hint style="success" %}
200 Resposta de sucesso

```bash
{
  "data": {
    "type": "attachment",
    "id": "0",
    "attributes": {
      "updated": true,
      "detach_response": {
        "data": {
          "type": "detach_from_entity",
          "id": "cQTLsWZCu"
        }
      }
    }
  }
}
```

{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://cloudware.gitbook.io/documentacao-api/api-v0/anexar-ficheiros.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
