feat: refactor 30+ skills to Anthropic progressive disclosure pattern
- All SKILL.md files now <500 lines (avg reduction 69%) - Detailed content extracted to references/ subdirectories - Frontmatter standardised: only name + description (Anthropic standard) - New skills: brand-guidelines, spec-coauthor, report-templates, skill-creator - Design skills: anti-slop guidelines, premium-proposals reference - Removed non-standard frontmatter fields (triggers, version, author, category) Plugins affected: infraestrutura, marketing, dev-tools, crm-ops, gestao, core-tools, negocio, perfex-dev, wordpress, design-media Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,117 +1,49 @@
|
||||
---
|
||||
name: expense
|
||||
description: >
|
||||
Gestão de despesas Desk CRM v2.0. Documento PDF obrigatório para cada despesa. Registar, categorizar e analisar despesas com verificação de categorias e duplicados. Upload SFTP + arquivo mensal automatico. NUNCA cria sem PDF (excepto bypass explicito). Use when "despesa", "expense", "gasto", "custo", "categoria despesa", "registar despesa", "expense report", "processar tickets contabilidade", "recibo", "factura fornecedor".
|
||||
author: Descomplicar® Crescimento Digital
|
||||
version: 2.0.0
|
||||
quality_score: 90
|
||||
user_invocable: true
|
||||
category: finance
|
||||
tags: [expense, despesas, finance, categories, desk-crm, costs, reporting, tickets, receipts, pdf, sftp]
|
||||
desk_task: 1710
|
||||
desk_project: 65
|
||||
allowed-tools: Read, mcp__desk-crm-v3, mcp__ssh-unified
|
||||
mcps: desk-crm-v3, ssh-unified
|
||||
dependencies:
|
||||
mcps: [desk-crm-v3, ssh-unified]
|
||||
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
|
||||
description: Gestao de despesas Desk CRM com PDF obrigatorio. Registar, categorizar e analisar despesas com verificacao de duplicados, upload SFTP e arquivo mensal automatico.
|
||||
---
|
||||
|
||||
# /expense - Gestão de Despesas
|
||||
# /expense - Gestao de Despesas
|
||||
|
||||
Skill para gestão de despesas com verificação obrigatória de categorias existentes.
|
||||
|
||||
## Metadata
|
||||
- **Version**: 2.0.0
|
||||
- **Author**: Descomplicar
|
||||
- **Date**: 2026-02-12
|
||||
- **Status**: Active
|
||||
|
||||
---
|
||||
Skill para gestao de despesas com verificacao obrigatoria de categorias existentes.
|
||||
|
||||
## Quando Usar
|
||||
|
||||
- Registar nova despesa
|
||||
- Criar/gerir categorias de despesas
|
||||
- Consultar despesas por período/categoria
|
||||
- Consultar despesas por periodo/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.)
|
||||
- Analise e relatorios de despesas
|
||||
- Processar despesas de tickets de contabilidade (departamento 3)
|
||||
- Importar recibos de servicos (Anthropic, Hetzner, etc.)
|
||||
|
||||
## Quando NÃO Usar
|
||||
## Quando NAO Usar
|
||||
|
||||
- Para facturas a clientes (usar /invoice)
|
||||
- Para orçamentos (usar /orcamento)
|
||||
- Para orcamentos (usar /orcamento)
|
||||
- Para pagamentos recebidos (usar /crm)
|
||||
|
||||
---
|
||||
|
||||
## REGRA CRÍTICA: CATEGORIAS
|
||||
## REGRA CRITICA: CATEGORIAS
|
||||
|
||||
> **PROIBIDO criar categoria sem verificar se já existe.**
|
||||
|
||||
Esta regra é INVIOLÁVEL. SEMPRE:
|
||||
> **PROIBIDO criar categoria sem verificar se ja existe.**
|
||||
|
||||
```
|
||||
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
|
||||
3. SE encontrar match ou similar: USAR a categoria existente
|
||||
4. SE realmente nao existe: PERGUNTAR "Nao encontrei categoria para X. Criar nova?"
|
||||
5. SO CRIAR apos confirmacao explicita
|
||||
```
|
||||
|
||||
**Violação desta regra causa duplicados que prejudicam relatórios financeiros.**
|
||||
**Violacao desta regra causa duplicados que prejudicam relatorios financeiros.**
|
||||
|
||||
Para mapeamento completo de fornecedores, emails e padroes PDF para categorias: ver `references/category-mapping.md`
|
||||
|
||||
---
|
||||
|
||||
## Categorias Activas (top 8 - consolidacao 12-02-2026)
|
||||
|
||||
| ID | Nome | Fornecedores tipicos |
|
||||
|----|------|---------------------|
|
||||
| 1 | Telecomunicacoes | MEO |
|
||||
| 4 | Alojamento web (Hosting) | Hetzner, CWP |
|
||||
| 6 | Servicos Externos | Make/Celonis, Gamma |
|
||||
| 14 | Subscricoes e Servicos Digitais | YouTube Premium, BdThemes |
|
||||
| 28 | Licencas Software | Canva, Cursor, Descript, GitHub, Softaculous |
|
||||
| 30 | Servicos Cloud e Infraestrutura | Google One, Google Workspace, ElasticEmail |
|
||||
| 37 | Dominios | PTisp, Namecheap |
|
||||
| 38 | Servicos IA e APIs | Anthropic, OpenRouter, CapSolver, Replicate |
|
||||
|
||||
**NOTA:** Existem ~30 categorias na BD mas apenas 8 sao usadas regularmente. SEMPRE usar `get_expense_categories()` para lista completa e actual.
|
||||
|
||||
---
|
||||
|
||||
## Protocolo
|
||||
|
||||
### 1. Registar Despesa
|
||||
## Protocolo: Registar Despesa
|
||||
|
||||
> **Gate PDF obrigatorio:** Sem documento, nao regista. Unica excepcao: bypass explicito do utilizador (AT/Salario sem recibo).
|
||||
|
||||
@@ -122,407 +54,101 @@ Esta regra é INVIOLÁVEL. SEMPRE:
|
||||
- SE nao tem e pede bypass: PERGUNTAR "Confirmas despesa sem documento?"
|
||||
- Bypass valido apenas para: AT, Salarios, transferencias bancarias
|
||||
2. LER O PDF: Extrair dados reais do documento
|
||||
- NUNCA copiar valor de um PDF para outro, mesmo com nomes semelhantes
|
||||
- Cada documento tem o seu valor proprio
|
||||
- NUNCA copiar valor de um PDF para outro
|
||||
3. OBRIGATORIO: get_expense_categories(with_stats=true)
|
||||
4. Identificar categoria correcta na lista
|
||||
- SE categoria nao existe: PERGUNTAR antes de criar
|
||||
5. VERIFICAR DUPLICADOS:
|
||||
- get_expenses(search: "<fornecedor>")
|
||||
- Mesmo fornecedor + valor + data = duplicado
|
||||
- Mesmo numero factura = duplicado
|
||||
6. Recolher dados:
|
||||
- category_id (obrigatorio)
|
||||
- amount (obrigatorio - valor REAL extraido do documento)
|
||||
- currency (obrigatorio - EUR=3, USD=2)
|
||||
- date (obrigatorio, YYYY-MM-DD)
|
||||
- note (obrigatorio, incluir numero factura)
|
||||
- send_invoice_to_customer = 0 (obrigatorio na BD)
|
||||
- client_id (opcional)
|
||||
- project_id (opcional)
|
||||
- billable (opcional, default false)
|
||||
- tax (opcional)
|
||||
- category_id, amount, currency (EUR=3, USD=2), date (YYYY-MM-DD)
|
||||
- note (incluir numero factura), send_invoice_to_customer = 0
|
||||
- Opcionais: client_id, project_id, billable, tax
|
||||
7. CONFIRMAR com utilizador (mostrar resumo)
|
||||
8. create_expense (ou SQL directo se MCP indisponivel)
|
||||
8. create_expense
|
||||
9. UPLOAD PDF ao Desk via SFTP:
|
||||
a. mkdir -p no servidor: /home/ealmeida/desk.descomplicar.pt/uploads/expenses/<id>
|
||||
b. mcp__ssh-unified__sftp_upload(server:"desk", local_path, remote_path)
|
||||
c. chown -R ealmeida:ealmeida
|
||||
d. INSERT INTO tblfiles (rel_id, rel_type='expense', file_name, filetype='application/pdf',
|
||||
visible_to_customer=0, staffid=1, contact_id=0, dateadded=NOW())
|
||||
10. ARQUIVO MENSAL: Mover PDF para pasta correspondente a data da factura:
|
||||
/media/ealmeida/Dados/GDrive/Cloud/ADM_Descomplicar/Financeiro/Contabilidade/YYYY/NN-NomeMes/
|
||||
(mkdir -p se pasta nao existir)
|
||||
d. INSERT INTO tblfiles (rel_id, rel_type='expense', ...)
|
||||
10. ARQUIVO MENSAL: Mover PDF para Contabilidade/YYYY/NN-NomeMes/
|
||||
11. Confirmar criacao ao utilizador
|
||||
```
|
||||
|
||||
### 2. Criar Categoria (APENAS se necessário)
|
||||
## Protocolo: Criar Categoria
|
||||
|
||||
```
|
||||
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. SE existe similar: USAR ESSA, nao criar
|
||||
4. SE nao existe: perguntar confirmacao ao utilizador
|
||||
5. SO APOS confirmacao: criar
|
||||
```
|
||||
|
||||
### 3. Consultar Despesas
|
||||
## Protocolo: 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)
|
||||
1. get_expenses com filtros: category, date_from/date_to, client_id, project_id, limit
|
||||
2. Apresentar resumo ao utilizador
|
||||
```
|
||||
|
||||
### 4. Análise de Despesas
|
||||
## Protocolo: Analise 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
|
||||
1. expense_analytics: period ("month"/"quarter"/"year"), breakdown_by ("category"/"client"/"project")
|
||||
2. Apresentar insights: total por categoria, tendencias, categorias mais usadas
|
||||
```
|
||||
|
||||
### 5. Processar Despesas de Tickets (Contabilidade)
|
||||
## Processar Despesas de Tickets
|
||||
|
||||
> **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).
|
||||
Para protocolo completo de processamento de tickets de contabilidade: ver `references/ticket-processing.md`
|
||||
|
||||
```
|
||||
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. Apos confirmacao:
|
||||
a. SQL: INSERT INTO tblexpenses (..., send_invoice_to_customer, ...) VALUES (..., 0, ...)
|
||||
OU create_expense via MCP (se disponivel)
|
||||
b. UPDATE tblexpenses SET expense_name = '{Fornecedor}' WHERE id = {id}
|
||||
c. mcp__ssh-unified__ssh_execute: mkdir -p uploads/expenses/{expenseid}
|
||||
d. mcp__ssh-unified__sftp_upload: PDF para uploads/expenses/{expenseid}/
|
||||
e. mcp__ssh-unified__ssh_execute: chown -R ealmeida:ealmeida uploads/expenses/{expenseid}
|
||||
f. SQL: INSERT INTO tblfiles (rel_id, rel_type, file_name, filetype,
|
||||
visible_to_customer, staffid, contact_id, dateadded)
|
||||
VALUES ({id}, 'expense', '{file}', 'application/pdf', 0, 1, 0, NOW())
|
||||
g. Mover PDF para arquivo mensal: Contabilidade/YYYY/NN-NomeMes/
|
||||
8. Confirmar ao utilizador e passar ao proximo
|
||||
```
|
||||
|
||||
#### 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
|
||||
|
||||
#### Moedas e Valores
|
||||
|
||||
> **Despesas em USD:** Manter valor original em USD com `currency = 2`. **Nao converter** manualmente.
|
||||
> **Despesas em EUR:** Usar `currency = 3`.
|
||||
|
||||
| Moeda | currency ID | Exemplo |
|
||||
|-------|------------|---------|
|
||||
| EUR | **3** | Anthropic 180.00 EUR |
|
||||
| USD | **2** | Cursor 20.00 USD |
|
||||
|
||||
> **CRITICO:** `currency = 1` nao existe e causa despesas invisiveis nos relatorios. SEMPRE usar 2 (USD) ou 3 (EUR).
|
||||
|
||||
#### 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 Fornecedor → Categoria (consolidado 12-02-2026)
|
||||
|
||||
| Fornecedor | Categoria ID | Nome |
|
||||
|-----------|-------------|------|
|
||||
| Anthropic, OpenRouter, CapSolver, Replicate | 38 | Servicos IA e APIs |
|
||||
| Canva, Cursor, Descript, GitHub, Softaculous, CWP | 28 | Licencas Software |
|
||||
| Google One, Google Workspace, ElasticEmail | 30 | Servicos Cloud e Infraestrutura |
|
||||
| Hetzner | 4 | Alojamento web (Hosting) |
|
||||
| MEO | 1 | Telecomunicacoes |
|
||||
| PTisp, Namecheap | 37 | Dominios |
|
||||
| Make/Celonis, Gamma | 6 | Servicos Externos |
|
||||
| YouTube Premium, BdThemes | 14 | Subscricoes e Servicos Digitais |
|
||||
|
||||
#### Mapeamento Email → Categoria
|
||||
|
||||
| Dominio Email | Categoria ID | Fornecedor |
|
||||
|---------------|--------------|------------|
|
||||
| anthropic.com | 38 | Anthropic |
|
||||
| openrouter.ai | 38 | OpenRouter |
|
||||
| payproglobal.com | 38 | CapSolver |
|
||||
| replicate.com | 38 | Replicate |
|
||||
| cursor.com, anysphere.dev | 28 | Cursor |
|
||||
| canva.com | 28 | Canva |
|
||||
| descript.com | 28 | Descript |
|
||||
| github.com | 28 | GitHub |
|
||||
| softaculous.com | 28 | Softaculous |
|
||||
| centos-webpanel.com | 28 | CWP |
|
||||
| elasticemail.com | 30 | ElasticEmail |
|
||||
| google.com (One/Workspace) | 30 | Google Cloud |
|
||||
| hetzner.com | 4 | Hetzner |
|
||||
| meoempresas.pt | 1 | MEO |
|
||||
| namecheap.com | 37 | Namecheap |
|
||||
| ptisp.pt | 37 | PTisp |
|
||||
| make.com, celonis.com | 6 | Make/Celonis |
|
||||
| gamma.app | 6 | Gamma |
|
||||
|
||||
> **NOTA:** `moloni.com` NAO incluido - e plataforma de facturacao, emails podem ser de qualquer fornecedor.
|
||||
|
||||
#### Mapeamento Padrao PDF → Categoria
|
||||
|
||||
Para documentos financeiros, identificar fornecedor pelo conteudo do PDF:
|
||||
|
||||
| Padrao no PDF | Fornecedor | Categoria ID | Nome |
|
||||
|---------------|-----------|--------------|------|
|
||||
| `Gondooffice`, `Cubic Choices` | Gondooffice | 21 | Contabilidade |
|
||||
| `Autoridade Tributaria`, `emiteDoc`, `AT -` | AT | 15 | Planos Prestacionais |
|
||||
| `Staples`, `STP_ECOFACTURA` | Staples | 3 | Material de Escritorio |
|
||||
| `MEO`, `meoempresas` | MEO | 1 | Telecomunicacoes |
|
||||
| `TOConline`, `Recibo de Vencimento` | Salario | 22 | Salarios e Vencimentos |
|
||||
| `Seguranca Social` | SS | 25 | Contribuicoes SS |
|
||||
| `Cursor`, `Anysphere` | Cursor | 28 | Licencas Software |
|
||||
| `Anthropic` | Anthropic | 38 | Servicos IA e APIs |
|
||||
| `Hetzner` | Hetzner | 4 | Alojamento web (Hosting) |
|
||||
| `ElasticEmail` | ElasticEmail | 30 | Servicos Cloud e Infraestrutura |
|
||||
|
||||
#### 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 (contact_id obrigatorio!)
|
||||
INSERT INTO tblfiles (rel_id, rel_type, file_name, filetype, visible_to_customer, staffid, contact_id, dateadded)
|
||||
VALUES ({expense_id}, 'expense', '{filename}', 'application/pdf', 0, 1, 0, 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}/`
|
||||
**Resumo:** Obter ticket -> verificar anexos -> verificar duplicados -> extrair dados -> confirmar -> criar despesa -> upload PDF -> arquivo mensal.
|
||||
|
||||
---
|
||||
|
||||
## Comandos
|
||||
|
||||
| Comando | Descrição |
|
||||
| Comando | Descricao |
|
||||
|---------|-----------|
|
||||
| `/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 categories` | Listar categorias disponiveis |
|
||||
| `/expense report [periodo]` | Relatorio 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 = 3**, USD = 2) |
|
||||
| payment_mode | string | - | Metodo pagamento (default: 'online') |
|
||||
| send_invoice_to_customer | number | ✓ | **Obrigatorio na BD** (sem default). Usar sempre **0** |
|
||||
|
||||
### 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 | USD | $ | Nao |
|
||||
| 3 | EUR | € | Sim |
|
||||
|
||||
> **CRITICO:** EUR = **3**, USD = **2**. Usar currency=1 causa despesas invisiveis nos relatorios. Para despesas em USD manter valor original com currency=2 (nao converter).
|
||||
**Despesas:** `get_expenses`, `create_expense`, `update_expense`, `delete_expense`, `bill_expense_to_customer`
|
||||
**Categorias:** `get_expense_categories` (usar with_stats=true)
|
||||
**Analise:** `expense_analytics`
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
**Categorias:**
|
||||
1. Criar categoria sem listar existentes primeiro
|
||||
2. Assumir que categoria nao existe
|
||||
3. Criar categoria com nome similar a existente
|
||||
|
||||
### Despesas
|
||||
**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
|
||||
5. Nao validar data (formato YYYY-MM-DD)
|
||||
6. Criar despesa sem verificar duplicados primeiro
|
||||
|
||||
### 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
|
||||
**Valores de PDFs:**
|
||||
7. Assumir que ficheiros com nomes semelhantes tem o mesmo valor
|
||||
8. SEMPRE ler CADA PDF individualmente para extrair o valor real
|
||||
|
||||
### Tickets
|
||||
13. Processar ticket sem verificar anexos PDF
|
||||
14. Assumir que ticket com recibo = despesa não lançada
|
||||
**Tickets:**
|
||||
9. Processar ticket sem verificar anexos PDF
|
||||
10. Assumir que ticket com recibo = despesa nao lancada
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
## Checklist Pre-Operacao
|
||||
|
||||
- [ ] Listar categorias existentes
|
||||
- [ ] Validar categoria correcta
|
||||
@@ -532,80 +158,12 @@ User: Registar 150€ de domínio para cliente TechStart
|
||||
|
||||
---
|
||||
|
||||
## Base de Dados
|
||||
## Referencias
|
||||
|
||||
- **Tabela categorias:** `tblexpenses_categories`
|
||||
- **Tabela despesas:** `tblexpenses`
|
||||
- **Campo categoria:** `category` (ID da categoria)
|
||||
- `references/category-mapping.md` - Mapeamento fornecedores, emails, padroes PDF, campos, moedas, SQL
|
||||
- `references/ticket-processing.md` - Protocolo completo de processamento de tickets
|
||||
- `references/changelog.md` - Historico de alteracoes
|
||||
|
||||
---
|
||||
|
||||
## Changelog
|
||||
|
||||
### v2.0.0 (2026-02-12) - Sistema Robusto 2026
|
||||
- **Gate PDF obrigatorio:** Despesa sem documento nao e registada (bypass explicito para AT/Salario)
|
||||
- **Upload SFTP:** Substituido `cp` local por `mcp__ssh-unified__sftp_upload` (Regra #41)
|
||||
- **Arquivo mensal:** PDF organizado em `Contabilidade/YYYY/NN-NomeMes/` automaticamente
|
||||
- **Campo `send_invoice_to_customer`:** Documentado como obrigatorio na BD (valor 0)
|
||||
- **Correccao currency:** EUR = **3** (nao 2), USD = **2**. Corrigido em toda a skill
|
||||
- **Categorias alinhadas com consolidacao:** 8 categorias activas com mapeamento correcto
|
||||
- Cursor/Canva/Descript/GitHub/Softaculous/CWP → 28 (Licencas Software)
|
||||
- Hetzner → 4 (Alojamento web)
|
||||
- ElasticEmail/Google → 30 (Servicos Cloud)
|
||||
- PTisp/Namecheap → 37 (Dominios)
|
||||
- YouTube/BdThemes → 14 (Subscricoes)
|
||||
- Make/Gamma → 6 (Servicos Externos)
|
||||
- **Verificacao duplicados reforçada:** Integrada no passo 5 do protocolo
|
||||
- **MCP ssh-unified adicionado** a dependencias
|
||||
- **Procedimento:** `06-Operacoes/Procedimentos/PROC-Skill-Expense.md`
|
||||
|
||||
### 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-12
|
||||
**Motivo:** Sistema robusto 2026 - PDF obrigatorio, SFTP, arquivo mensal, correccoes consolidacao
|
||||
**Criado:** 2026-02-05 | **Actualizado:** 2026-02-12
|
||||
|
||||
Reference in New Issue
Block a user