Plugins: automacao, crm-ops, design-media, dev-tools, gestao, infraestrutura, marketing, negocio, perfex-dev, project-manager, wordpress + hello-plugin (existente). Totais: 83 skills, 44 agents, 12 datasets.json Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
574 lines
19 KiB
Markdown
574 lines
19 KiB
Markdown
---
|
|
name: expense
|
|
description: >
|
|
Gestão de despesas Desk CRM v1.3. Registar, categorizar e analisar despesas com verificação obrigatória de categorias existentes. Processa despesas de tickets de contabilidade com anexos PDF. Conversão USD→EUR automática. NUNCA cria categoria duplicada. Use when "despesa", "expense", "gasto", "custo", "categoria despesa", "registar despesa", "expense report", "processar tickets contabilidade".
|
|
author: Descomplicar® Crescimento Digital
|
|
version: 1.5.0
|
|
quality_score: 88
|
|
user_invocable: true
|
|
category: finance
|
|
tags: [expense, despesas, finance, categories, desk-crm, costs, reporting, tickets, receipts]
|
|
desk_task: null
|
|
desk_project: 65
|
|
allowed-tools: Read, mcp__desk-crm-v3
|
|
mcps: desk-crm-v3
|
|
dependencies:
|
|
mcps: [desk-crm-v3]
|
|
triggers:
|
|
- "User wants to create expense"
|
|
- "User mentions 'despesa', 'expense', 'gasto', 'custo'"
|
|
- "User wants to categorize expenses"
|
|
- "User asks about expense categories"
|
|
- "User needs expense report or analysis"
|
|
- "User wants to process expenses from tickets"
|
|
- "User mentions 'tickets contabilidade', 'recibos', 'receipts'"
|
|
anti_patterns:
|
|
critical:
|
|
- "NEVER create category without checking if exists"
|
|
- "NEVER assume category doesn't exist"
|
|
- "ALWAYS list categories before creating new one"
|
|
categories:
|
|
- "Creating duplicate categories"
|
|
- "Using similar name instead of existing category"
|
|
- "Not checking existing categories first"
|
|
technical:
|
|
- "Creating expense without category_id"
|
|
- "Using category name instead of ID"
|
|
performance:
|
|
baseline_duration_ms: 60000
|
|
target_duration_ms: 30000
|
|
last_run_duration_ms: null
|
|
success_rate: 0.95
|
|
---
|
|
|
|
# /expense - Gestão de Despesas
|
|
|
|
Skill para gestão de despesas com verificação obrigatória de categorias existentes.
|
|
|
|
## Metadata
|
|
- **Version**: 1.3.0
|
|
- **Author**: Descomplicar
|
|
- **Date**: 2026-02-05
|
|
- **Status**: Active
|
|
|
|
---
|
|
|
|
## Quando Usar
|
|
|
|
- Registar nova despesa
|
|
- Criar/gerir categorias de despesas
|
|
- Consultar despesas por período/categoria
|
|
- Associar despesas a projectos/clientes
|
|
- Análise e relatórios de despesas
|
|
- **Processar despesas de tickets de contabilidade (departamento 3)**
|
|
- Importar recibos de serviços (Anthropic, Hetzner, etc.)
|
|
|
|
## Quando NÃO Usar
|
|
|
|
- Para facturas a clientes (usar /invoice)
|
|
- Para orçamentos (usar /orcamento)
|
|
- Para pagamentos recebidos (usar /crm)
|
|
|
|
---
|
|
|
|
## REGRA CRÍTICA: CATEGORIAS
|
|
|
|
> **PROIBIDO criar categoria sem verificar se já existe.**
|
|
|
|
Esta regra é INVIOLÁVEL. SEMPRE:
|
|
|
|
```
|
|
1. Listar categorias: get_expense_categories(with_stats=true)
|
|
2. Pesquisar por nome similar na lista
|
|
3. SE encontrar match ou similar:
|
|
- USAR a categoria existente
|
|
- NÃO criar duplicado
|
|
4. SE realmente não existe:
|
|
- PERGUNTAR: "Não encontrei categoria para X. Criar nova?"
|
|
5. SÓ CRIAR após confirmação explícita
|
|
```
|
|
|
|
**Violação desta regra causa duplicados que prejudicam relatórios financeiros.**
|
|
|
|
---
|
|
|
|
## Categorias Existentes (Referência)
|
|
|
|
| ID | Nome | Uso |
|
|
|----|------|-----|
|
|
| 1 | Telecomunicações | Net+móvel |
|
|
| 2 | Serviços Bancários | Comissões, taxas |
|
|
| 3 | Material de Escritório | Consumíveis |
|
|
| 4 | FB e Google ADS | Publicidade |
|
|
| 5 | E-mail MKT | ElasticEmail |
|
|
| 6 | Seguros | Apólices |
|
|
| 7 | Equipamento Informático e Audiovisual | Hardware |
|
|
| 8 | Remunerações | Salários pagos |
|
|
| 9 | Plugins e Recursos de Design | FULL, Freepik, etc |
|
|
| 10 | Alojamento de Servidores | Hetzner |
|
|
| 11 | Software Faturação | Moloni |
|
|
| 12 | Softwares Gestão | Everhour |
|
|
| 13 | Registo de Domínios | Ptisp, NameCheap |
|
|
| 14 | Impostos | SS, IRS, IVA |
|
|
| 15 | Planos Prestacionais | Pagamentos acordados |
|
|
| 16 | Manutenção e Suporte | Serviços técnicos |
|
|
| 17 | Outras | Não classificadas |
|
|
| 18 | Ofertas a Clientes | Brindes |
|
|
| 19 | Plataformas Armazenamento | Vimeo, MyAirBridge |
|
|
| 21 | Contabilidade | GONDOOFFICE |
|
|
| 22 | Salários e Vencimentos | Recibos vencimento |
|
|
| 23 | IRC - Imposto sobre Rendimento | Pagamentos IRC |
|
|
| 24 | IRS - Imposto sobre Rendimento | Retenções IRS |
|
|
| 25 | Contribuições Segurança Social | SS mensal |
|
|
| 26 | Hosting e Servidores | Alojamento web |
|
|
| 28 | Licenças Software | Painéis controlo |
|
|
| 29 | Reembolsos e Créditos | Valores recebidos |
|
|
| 38 | Serviços IA e APIs | Anthropic, OpenAI, CapSolver |
|
|
|
|
**NOTA:** Esta lista pode estar desactualizada. SEMPRE usar `get_expense_categories()` para lista actual.
|
|
|
|
---
|
|
|
|
## Protocolo
|
|
|
|
### 1. Registar Despesa
|
|
|
|
```
|
|
1. OBRIGATÓRIO: get_expense_categories(with_stats=true)
|
|
2. Identificar categoria correcta na lista
|
|
3. SE categoria não existe: PERGUNTAR antes de criar
|
|
4. SE dados vêm de PDFs: ler CADA ficheiro individualmente com pdftotext
|
|
- NUNCA copiar valor de um PDF para outro, mesmo com nomes semelhantes
|
|
- Cada documento tem o seu valor próprio
|
|
5. Recolher dados:
|
|
- category_id (obrigatório)
|
|
- amount (obrigatório - valor REAL extraído do documento)
|
|
- date (obrigatório, YYYY-MM-DD)
|
|
- note (obrigatório, descrição)
|
|
- client_id (opcional)
|
|
- project_id (opcional)
|
|
- billable (opcional, default false)
|
|
- tax (opcional)
|
|
6. create_expense com dados validados
|
|
7. Confirmar criação ao utilizador
|
|
```
|
|
|
|
### 2. Criar Categoria (APENAS se necessário)
|
|
|
|
```
|
|
1. get_expense_categories() - listar todas
|
|
2. Verificar se existe categoria similar
|
|
3. SE existe similar: USAR ESSA, não criar
|
|
4. SE não existe nenhuma similar:
|
|
- Perguntar confirmação ao utilizador
|
|
- Aguardar resposta explícita
|
|
5. SÓ APÓS confirmação: criar via SQL ou interface
|
|
```
|
|
|
|
### 3. Consultar Despesas
|
|
|
|
```
|
|
1. get_expenses com filtros:
|
|
- category (ID da categoria)
|
|
- date_from / date_to (período)
|
|
- client_id (cliente específico)
|
|
- project_id (projecto específico)
|
|
- limit (número resultados)
|
|
2. Apresentar resumo ao utilizador
|
|
```
|
|
|
|
### 4. Análise de Despesas
|
|
|
|
```
|
|
1. expense_analytics com parâmetros:
|
|
- period: "month", "quarter", "year"
|
|
- breakdown_by: "category", "client", "project"
|
|
2. Apresentar insights:
|
|
- Total por categoria
|
|
- Tendências
|
|
- Categorias mais usadas
|
|
```
|
|
|
|
### 5. Processar Despesas de Tickets (Contabilidade)
|
|
|
|
> **REGRA 1:** Processar tickets UM A UM com confirmação do utilizador (ou em lote se solicitado).
|
|
> **REGRA 2:** Verificar SEMPRE se despesa já foi lançada (prevenir duplicados).
|
|
> **REGRA 3:** NÃO adicionar respostas aos tickets - apenas criar despesa e anexos.
|
|
> **REGRA 4:** Converter SEMPRE USD para EUR antes de criar despesa.
|
|
> **REGRA 5:** Saltar tickets que são apenas recibos de pagamento (não são facturas).
|
|
|
|
```
|
|
1. Obter ticket: get_ticket(ticket_id)
|
|
2. Verificar anexos: SELECT * FROM tblticket_attachments WHERE ticketid = X
|
|
3. SE não tem PDFs: SALTAR ticket (apenas notificação)
|
|
4. VERIFICAR DUPLICADOS (OBRIGATÓRIO):
|
|
SELECT id, amount, date, note FROM tblexpenses
|
|
WHERE reference_no LIKE '%{receipt_number}%' OR note LIKE '%ticket #{ticket_id}%'
|
|
SE encontrar: PARAR e informar "Despesa já existe: #ID"
|
|
5. Extrair dados:
|
|
- Do HTML do ticket (valor, data, referência)
|
|
- OU usar script Python: python3 /home/ealmeida/scripts/extract_invoice_data.py {pdf_path}
|
|
6. APRESENTAR resumo ao utilizador e AGUARDAR confirmação
|
|
7. Após confirmação:
|
|
a. create_expense(category_id, amount, date, note, tax=1, reference)
|
|
b. UPDATE tblexpenses SET expense_name = '{Fornecedor}' WHERE id = {id}
|
|
c. mkdir -p uploads/expenses/{expenseid}
|
|
d. cp uploads/ticket_attachments/{ticketid}/*.pdf uploads/expenses/{expenseid}/
|
|
e. chown -R ealmeida:ealmeida uploads/expenses/{expenseid}
|
|
f. INSERT INTO tblfiles (rel_id, rel_type, file_name, filetype, ...)
|
|
8. Confirmar ao utilizador e passar ao próximo
|
|
```
|
|
|
|
#### Script Python para Extracção de PDFs
|
|
|
|
Localização: `/home/ealmeida/scripts/extract_invoice_data.py`
|
|
|
|
```bash
|
|
python3 /home/ealmeida/scripts/extract_invoice_data.py /path/to/invoice.pdf
|
|
```
|
|
|
|
Retorna JSON com: vendor, cat_id, total, date, invoice, currency, text
|
|
|
|
#### Conversão USD → EUR
|
|
|
|
> **OBRIGATÓRIO:** Todas as despesas devem ser registadas em EUR.
|
|
|
|
Taxa aproximada: **1 USD ≈ 0.92 EUR** (verificar taxa actual se necessário)
|
|
|
|
Exemplos:
|
|
- $19.99 USD → €18.39 EUR
|
|
- $100.00 USD → €92.00 EUR
|
|
|
|
```sql
|
|
-- Após criar despesa em USD, actualizar para EUR
|
|
UPDATE tblexpenses SET amount = {valor_eur}, currency = 2 WHERE id = {expense_id};
|
|
```
|
|
|
|
> **CRÍTICO:** O ID da moeda EUR é **2** (não 1). Usar currency=1 faz despesas não aparecerem nos relatórios.
|
|
|
|
#### Tickets a Saltar
|
|
|
|
| Tipo | Descrição | Acção |
|
|
|------|-----------|-------|
|
|
| Payment Receipt | Recibo de pagamento (não é fatura) | SALTAR - não criar despesa |
|
|
| Duplicado | Mesmo nº fatura já processado | SALTAR - informar utilizador |
|
|
| Sem anexo PDF | Apenas notificação por email | SALTAR - dados insuficientes |
|
|
|
|
Exemplos de tickets a saltar:
|
|
- "Invoice Payment Confirmation" (é recibo, não fatura)
|
|
- Ticket com mesmo invoice_number de outro já processado
|
|
|
|
#### Credenciais Base de Dados
|
|
|
|
Localização: `/home/ealmeida/desk.descomplicar.pt/application/config/app-config.php`
|
|
|
|
```bash
|
|
grep -E "APP_DB" /home/ealmeida/desk.descomplicar.pt/application/config/app-config.php
|
|
```
|
|
|
|
#### Processamento em Lote
|
|
|
|
Se utilizador pedir "criar todas" ou "processar em lote":
|
|
1. Obter todos os tickets pendentes em paralelo
|
|
2. Identificar duplicados e tickets a saltar
|
|
3. Criar despesas em paralelo via `create_expense`
|
|
4. Actualizar `expense_name` e `reference_no` em batch via SQL
|
|
5. Copiar PDFs em batch
|
|
6. Registar ficheiros em batch via SQL INSERT múltiplo
|
|
|
|
#### Mapeamento Email → Categoria
|
|
|
|
| Domínio Email | Categoria ID | Nome |
|
|
|---------------|--------------|------|
|
|
| anthropic.com | 38 | Serviços IA e APIs |
|
|
| openai.com | 38 | Serviços IA e APIs |
|
|
| payproglobal.com | 38 | Serviços IA e APIs (CapSolver) |
|
|
| elasticemail.com | 5 | E-mail MKT |
|
|
| hetzner.com | 10 | Alojamento de Servidores |
|
|
| meoempresas.pt | 1 | Telecomunicações |
|
|
| centos-webpanel.com | 28 | Licenças Software |
|
|
| canva.com | 9 | Plugins e Recursos de Design |
|
|
| freepik.com | 9 | Plugins e Recursos de Design |
|
|
| namecheap.com | 13 | Registo de Domínios |
|
|
| ptisp.pt | 13 | Registo de Domínios |
|
|
| vimeo.com | 19 | Plataformas Armazenamento |
|
|
| everhour.com | 12 | Softwares Gestão |
|
|
| cursor.com | 38 | Serviços IA e APIs (Cursor) |
|
|
|
|
> **NOTA:** `moloni.com` NÃO incluído - é plataforma de facturação, emails podem ser de qualquer fornecedor. Verificar conteúdo do PDF para identificar o fornecedor real.
|
|
|
|
#### Mapeamento Fornecedor (PDF) → Categoria
|
|
|
|
Para documentos financeiros transferidos (não tickets), identificar fornecedor pelo conteúdo do PDF:
|
|
|
|
| Padrão no PDF | Fornecedor | Categoria ID | Nome |
|
|
|---------------|-----------|--------------|------|
|
|
| `Gondooffice`, `Cubic Choices`, `GONDOOFFICE` | Gondooffice (Cubic Choices) | 21 | Contabilidade |
|
|
| `Autoridade Tributária`, `emiteDoc`, `AT -` | AT - Autoridade Tributária | 15 | Planos Prestacionais |
|
|
| `Staples`, `STAPLES`, `STP_ECOFACTURA` | Staples | 3 | Material de Escritório |
|
|
| `MEO`, `Serviços _ Compras`, `meoempresas` | MEO Empresas | 1 | Telecomunicações |
|
|
| `TOConline`, `metta`, `Recibo de Vencimento` | Salário/Vencimento | 22 | Salários e Vencimentos |
|
|
| `NOS Comunicações`, `NOS ` | NOS | 1 | Telecomunicações |
|
|
| `Vodafone` | Vodafone | 1 | Telecomunicações |
|
|
| `EDP`, `E-REDES` | EDP | 17 | Outras |
|
|
| `Segurança Social`, `Seg. Social` | Segurança Social | 25 | Contribuições SS |
|
|
| `Cursor`, `Anysphere`, `cursor.com` | Cursor (Anysphere) | 38 | Serviços IA e APIs |
|
|
|
|
#### Extracção de Dados de PDFs
|
|
|
|
**Método 1: Script Python (recomendado)**
|
|
```bash
|
|
python3 /home/ealmeida/scripts/extract_invoice_data.py /path/to/invoice.pdf
|
|
```
|
|
|
|
**Método 2: pdfplumber directo**
|
|
```bash
|
|
python3 -c "
|
|
import pdfplumber
|
|
with pdfplumber.open('/path/to/file.pdf') as pdf:
|
|
for p in pdf.pages:
|
|
t = p.extract_text()
|
|
if t: print(t)
|
|
" | grep -iE "total|iva|€"
|
|
```
|
|
|
|
**Método 3: pdftotext (fallback)**
|
|
```bash
|
|
pdftotext /path/to/file.pdf - | head -80
|
|
```
|
|
|
|
> **NOTA:** Se PDF não extrair texto (imagem), usar dados do HTML do ticket email.
|
|
|
|
#### Comandos SQL
|
|
|
|
```sql
|
|
-- 1. VERIFICAR DUPLICADOS (EXECUTAR PRIMEIRO!)
|
|
SELECT id, amount, date, note, reference_no FROM tblexpenses
|
|
WHERE reference_no LIKE '%{receipt_number}%'
|
|
OR note LIKE '%ticket #{ticket_id}%'
|
|
|
|
-- 2. Verificar anexos do ticket
|
|
SELECT id, file_name, filetype FROM tblticket_attachments WHERE ticketid = {ID}
|
|
|
|
-- 3. Actualizar nome fornecedor
|
|
UPDATE tblexpenses SET expense_name = '{Fornecedor}' WHERE id = {expense_id}
|
|
|
|
-- 4. Registar anexo na despesa
|
|
INSERT INTO tblfiles (rel_id, rel_type, file_name, filetype, visible_to_customer, staffid, dateadded)
|
|
VALUES ({expense_id}, 'expense', '{filename}', 'application/pdf', 0, 1, NOW())
|
|
```
|
|
|
|
#### Campos para Rastreio de Duplicados
|
|
|
|
| Campo | Conteúdo | Exemplo |
|
|
|-------|----------|---------|
|
|
| reference | Número do recibo | `2810-3712-9577` |
|
|
| note | Incluir ticket ID | `Anthropic Max (ticket #9648)` |
|
|
|
|
#### Paths de Ficheiros
|
|
|
|
- Anexos ticket: `/uploads/ticket_attachments/{ticketid}/`
|
|
- Anexos despesa: `/uploads/expenses/{expenseid}/`
|
|
|
|
---
|
|
|
|
## Comandos
|
|
|
|
| Comando | Descrição |
|
|
|---------|-----------|
|
|
| `/expense create` | Registar nova despesa |
|
|
| `/expense list` | Listar despesas recentes |
|
|
| `/expense categories` | Listar categorias disponíveis |
|
|
| `/expense report [período]` | Relatório de despesas |
|
|
| `/expense search [termo]` | Pesquisar despesas |
|
|
|
|
---
|
|
|
|
## MCP Tools
|
|
|
|
### Despesas
|
|
- `get_expenses` - Listar despesas com filtros
|
|
- `create_expense` - Criar nova despesa
|
|
- `update_expense` - Actualizar despesa
|
|
- `delete_expense` - Eliminar despesa
|
|
- `bill_expense_to_customer` - Facturar ao cliente
|
|
|
|
### Categorias
|
|
- `get_expense_categories` - Listar categorias (usar with_stats=true)
|
|
|
|
### Análise
|
|
- `expense_analytics` - Métricas e análise
|
|
|
|
---
|
|
|
|
## Campos create_expense
|
|
|
|
| Campo | Tipo | Obrigatório | Descrição |
|
|
|-------|------|-------------|-----------|
|
|
| category_id | number | ✓ | ID da categoria |
|
|
| amount | number | ✓ | Valor da despesa |
|
|
| date | string | ✓ | Data (YYYY-MM-DD) |
|
|
| note | string | ✓ | Descrição (incluir ticket ID) |
|
|
| reference | string | ✓ | Número fatura/recibo (para duplicados) |
|
|
| tax | number | ✓ | **ID da taxa** (1 = IVA 23%) |
|
|
| client_id | number | - | Cliente associado |
|
|
| project_id | number | - | Projecto associado |
|
|
| billable | boolean | - | Facturável (default: false) |
|
|
| tax2 | number | - | Segunda taxa imposto |
|
|
| currency | number | - | ID moeda (**EUR = 2**) |
|
|
| payment_mode | string | - | Método pagamento |
|
|
|
|
### Campo expense_name (via SQL)
|
|
|
|
> **IMPORTANTE:** Após criar despesa, actualizar `expense_name` com nome do fornecedor.
|
|
|
|
```sql
|
|
UPDATE tblexpenses SET expense_name = '{Fornecedor}' WHERE id = {expense_id};
|
|
```
|
|
|
|
### Taxas de Imposto (tbltaxes)
|
|
|
|
| ID | Nome | Taxa |
|
|
|----|------|------|
|
|
| 1 | IVA Tx Normal | 23% |
|
|
|
|
### Moedas (tblcurrencies)
|
|
|
|
| ID | Nome | Símbolo | Default |
|
|
|----|------|---------|---------|
|
|
| 2 | EUR | € | Sim |
|
|
|
|
> **CRÍTICO:** Usar sempre `currency = 2` para EUR. O ID 1 não existe e causa despesas invisíveis nos relatórios.
|
|
|
|
---
|
|
|
|
## Anti-Patterns (NUNCA fazer)
|
|
|
|
### Categorias
|
|
1. **NUNCA** criar categoria sem listar existentes primeiro
|
|
2. **NUNCA** assumir que categoria não existe
|
|
3. **NUNCA** criar categoria com nome similar a existente
|
|
|
|
### Despesas
|
|
4. Criar despesa sem category_id
|
|
5. Usar nome da categoria em vez do ID
|
|
6. Não validar data (formato YYYY-MM-DD)
|
|
7. Criar despesa sem note/descrição
|
|
8. **NUNCA** criar despesa sem verificar duplicados primeiro
|
|
9. **NUNCA** processar ticket sem verificar se já foi lançado
|
|
|
|
### Valores de PDFs
|
|
10. **NUNCA** assumir que ficheiros com nomes semelhantes têm o mesmo valor
|
|
11. **SEMPRE** ler CADA PDF individualmente para extrair o valor real
|
|
12. Exemplo real: `emiteDoc.pdf` a `emiteDoc (12).pdf` tinham valores de 25,80€ a 100,53€ - todos diferentes
|
|
|
|
### Tickets
|
|
13. Processar ticket sem verificar anexos PDF
|
|
14. Assumir que ticket com recibo = despesa não lançada
|
|
|
|
---
|
|
|
|
## Exemplos
|
|
|
|
### Exemplo 1: Registar despesa com categoria existente
|
|
```
|
|
User: Registar despesa de 50€ de telecomunicações
|
|
→ get_expense_categories()
|
|
→ Encontra ID 1 = Telecomunicações
|
|
→ create_expense(category_id=1, amount=50, date="2026-02-05", note="Telecomunicações")
|
|
→ "Despesa #X criada: 50€ em Telecomunicações"
|
|
```
|
|
|
|
### Exemplo 2: Despesa com categoria a verificar
|
|
```
|
|
User: Registar despesa de formação 200€
|
|
→ get_expense_categories()
|
|
→ NÃO encontra "Formação"
|
|
→ "Não encontrei categoria 'Formação'. Usar 'Outras' (ID 17) ou criar nova categoria?"
|
|
→ User: Usar Outras
|
|
→ create_expense(category_id=17, amount=200, date="2026-02-05", note="Formação profissional")
|
|
```
|
|
|
|
### Exemplo 3: Despesa facturável a cliente
|
|
```
|
|
User: Registar 150€ de domínio para cliente TechStart
|
|
→ get_expense_categories() → ID 13 = Registo de Domínios
|
|
→ search_customers("TechStart") → client_id=42
|
|
→ create_expense(category_id=13, amount=150, date="2026-02-05",
|
|
note="Domínio techstart.pt", client_id=42, billable=true)
|
|
→ "Despesa facturável criada para TechStart"
|
|
```
|
|
|
|
---
|
|
|
|
## Checklist Pré-Operação
|
|
|
|
- [ ] Listar categorias existentes
|
|
- [ ] Validar categoria correcta
|
|
- [ ] Confirmar dados com utilizador
|
|
- [ ] Usar formato data YYYY-MM-DD
|
|
- [ ] Incluir nota descritiva
|
|
|
|
---
|
|
|
|
## Base de Dados
|
|
|
|
- **Tabela categorias:** `tblexpenses_categories`
|
|
- **Tabela despesas:** `tblexpenses`
|
|
- **Campo categoria:** `category` (ID da categoria)
|
|
|
|
---
|
|
|
|
## Changelog
|
|
|
|
### v1.5.0 (2026-02-05)
|
|
- Adicionado mapeamento **Cursor (Anysphere)** → categoria 38 (Serviços IA e APIs)
|
|
- Email: `cursor.com`
|
|
- PDF patterns: `Cursor`, `Anysphere`, `cursor.com`
|
|
|
|
### v1.4.0 (2026-02-05)
|
|
- **CORRECÇÃO CRÍTICA:** ID moeda EUR = **2** (não 1)
|
|
- Despesas com currency=1 não aparecem em relatórios
|
|
- Corrigidas 22 despesas existentes via `UPDATE tblexpenses SET currency = 2 WHERE currency = 1`
|
|
- Documentada tabela tblcurrencies com IDs correctos
|
|
|
|
### v1.3.0 (2026-02-05)
|
|
- **Conversão USD → EUR obrigatória** (taxa ~0.92, $19.99 → €18.39)
|
|
- **Processamento em lote** quando utilizador pede "criar todas"
|
|
- Tickets a saltar documentados (payment receipts, duplicados, sem PDF)
|
|
- Localização credenciais BD: `app-config.php`
|
|
- Regras 4 e 5 adicionadas ao protocolo de tickets
|
|
- 9 despesas processadas em sessão de teste: €857.73 total
|
|
|
|
### v1.2.0 (2026-02-05)
|
|
- Campo `expense_name` obrigatório com nome do fornecedor (via SQL UPDATE)
|
|
- Campo `tax` é ID da taxa de imposto (1 = IVA 23%), não percentagem
|
|
- Coluna BD é `reference_no`, não `reference`
|
|
- Script Python para extracção de PDFs: `/home/ealmeida/scripts/extract_invoice_data.py`
|
|
- 3 métodos de extracção PDF documentados (script, pdfplumber, pdftotext)
|
|
- Workflow actualizado: processar UM A UM com confirmação
|
|
- Removido: adicionar respostas aos tickets (apenas criar despesa + anexos)
|
|
- SQL commands actualizados com expense_name
|
|
|
|
### v1.1.0 (2026-02-05)
|
|
- Processamento de despesas a partir de tickets de contabilidade
|
|
- Mapeamento automático email domain → categoria
|
|
- Workflow completo com verificação de anexos PDF
|
|
- Cópia automática de anexos ticket → despesa
|
|
- Registo de ficheiros em tblfiles
|
|
|
|
### v1.0.0 (2026-02-05)
|
|
- Versão inicial
|
|
- Regra crítica de verificação de categorias
|
|
- Lista de categorias de referência
|
|
- Fluxos para criar/consultar despesas
|
|
- Integração com MCP desk-crm-v3
|
|
- Anti-patterns documentados
|
|
- Criada após limpeza de 9 categorias duplicadas
|
|
|
|
---
|
|
|
|
**Criado:** 2026-02-05
|
|
**Actualizado:** 2026-02-05
|
|
**Motivo:** Prevenção de categorias duplicadas + processamento de tickets
|