# /expense - Mapeamento de Categorias e Dados Técnicos ## Categorias Activas (consolidacao 12-02-2026) | ID | Nome | Fornecedores típicos | |----|------|---------------------| | 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 | Existem ~30 categorias na BD mas apenas 8 são usadas regularmente. SEMPRE usar `get_expense_categories()` para lista completa. --- ## Mapeamento Fornecedor → Categoria | 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 | > `moloni.com` NAO incluido - é plataforma de facturação. --- ## Mapeamento Padrão PDF → Categoria | Padrão no PDF | Fornecedor | Categoria ID | |---------------|-----------|--------------| | `Gondooffice`, `Cubic Choices` | Gondooffice | 21 Contabilidade | | `Autoridade Tributaria`, `emiteDoc`, `AT -` | AT | 15 Planos Prestacionais | | `Staples`, `STP_ECOFACTURA` | Staples | 3 Material Escritorio | | `MEO`, `meoempresas` | MEO | 1 Telecomunicacoes | | `TOConline`, `Recibo de Vencimento` | Salario | 22 Salarios | | `Seguranca Social` | SS | 25 Contribuicoes SS | | `Cursor`, `Anysphere` | Cursor | 28 Licencas Software | | `Anthropic` | Anthropic | 38 Servicos IA e APIs | | `Hetzner` | Hetzner | 4 Alojamento web | | `ElasticEmail` | ElasticEmail | 30 Servicos Cloud | --- ## Campos create_expense | Campo | Tipo | Obrigatório | Descrição | |-------|------|-------------|-----------| | category_id | number | Sim | ID da categoria | | amount | number | Sim | Valor da despesa | | date | string | Sim | Data (YYYY-MM-DD) | | note | string | Sim | Descrição (incluir ticket ID) | | reference | string | Sim | Número fatura/recibo | | tax | number | Sim | ID da taxa (1 = IVA 23%) | | currency | number | Sim | EUR = **3**, USD = 2 | | send_invoice_to_customer | number | Sim | Sempre **0** | | client_id | number | Não | Cliente associado | | project_id | number | Não | Projecto associado | | billable | boolean | Não | Facturável (default: false) | --- ## Moedas | ID | Nome | Símbolo | Default | |----|------|---------|---------| | 2 | USD | $ | Não | | 3 | EUR | € | Sim | > **CRITICO:** EUR = **3**, USD = **2**. `currency = 1` não existe e causa despesas invisíveis nos relatórios. --- ## Taxas de Imposto | ID | Nome | Taxa | |----|------|------| | 1 | IVA Tx Normal | 23% | --- ## 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 (obrigatorio apos criar) 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, contact_id, dateadded) VALUES ({expense_id}, 'expense', '{filename}', 'application/pdf', 0, 1, 0, NOW()) ``` --- ## 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 ``` Retorna JSON com: vendor, cat_id, total, date, invoice, currency, text **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 ``` --- ## Paths de Ficheiros - Anexos ticket: `/uploads/ticket_attachments/{ticketid}/` - Anexos despesa: `/uploads/expenses/{expenseid}/` - Arquivo mensal: `/media/ealmeida/Dados/GDrive/Cloud/ADM_Descomplicar/Financeiro/Contabilidade/YYYY/NN-NomeMes/` - Credenciais BD: `/home/ealmeida/desk.descomplicar.pt/application/config/app-config.php` --- ## Tickets a Saltar | Tipo | Descrição | Acção | |------|-----------|-------| | Payment Receipt | Recibo de pagamento (não é fatura) | SALTAR | | Duplicado | Mesmo nº fatura já processado | SALTAR | | Sem anexo PDF | Apenas notificação por email | SALTAR | --- ## 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)` |