# Sistema de Tickets - OfficeGest

## Visão Geral

O sistema de tickets do OfficeGest é um módulo completo de suporte e atendimento ao cliente integrado ao ERP. Este documento explica sua arquitetura, funcionamento e principalmente **a integração com Ordens de Serviço (OS)**.

## Arquitetura do Sistema

### Estrutura de Arquivos
```
_ajax/
├── tickets.php              # Endpoints AJAX para todas as operações
_views/
├── tickets/tickets/new.php   # Formulário de criação de tickets  
├── entidades/includes/tabs/  
    └── tickets.php          # Tab de tickets em entidades e documentos
_files/
├── modules/tickets/         # Classes do módulo legacy
```

### Componentes Principais

#### 1. Módulo Tickets (`$m['tickets']`)
- **Localização**: `_files/modules/tickets/`
- **Função**: Classe principal com métodos para CRUD de tickets
- **Acesso**: Via global `$m['tickets']` após bootstrap

#### 2. Sistema de Privilégios
```php
$u->checkPriv("tickets:tickets")     // Ver/criar tickets
$u->checkPriv("tickets:admin")       // Administrar tickets
```

#### 3. Estados de Tickets
- **normal**: Ticket ativo
- **hold**: Em espera
- **resolved**: Resolvido
- **closed**: Fechado

## Integração OS ↔ Tickets

### Como Funciona a Integração

#### 1. Detecção de Contexto OS
O sistema detecta quando está numa OS através de:
```php
// Em _views/entidades/includes/tabs/tickets.php linha 40-42
if($u->checkPriv("tickets:tickets") && !empty($doc) && $doc['tipoop'] == 'OS'){
    // Mostra botão "Novo" 
}
```

**Condições necessárias:**
- ✅ Usuário tem privilégio `tickets:tickets`  
- ✅ Variável `$doc` existe e não está vazia
- ✅ Tipo do documento é 'OS' (`$doc['tipoop'] == 'OS'`)

#### 2. Botão "Novo Ticket"
```php
$ticketBtn = '<button type="button" id="new_osv_ticket" class="btn btn-small btn-secondary pull-right mr-2" data-toggle="modal">
    <i class="fa fa-plus mr-2"></i>'.$l->r('n17567').'
</button>';
```

#### 3. Abertura do Formulário
Quando clicado, o botão executa JavaScript que:
```javascript
// Linhas 113-123 de tickets.php
$('#new_osv_ticket').on('click',function(){
    const codtercOsv = $('#doc_CodTerc').val();
    var html = '<input type="hidden" name="tipoop" value="<?= $doc['tipoop'] ?>"/>
               <input type="hidden" name="num" value="<?= $doc['num'] ?>" />
               <input type="hidden" name="documentnumber" value="<?= $doc['DocumentNumber'] ?>" />
               <input type="hidden" name="codterc" value="'+codtercOsv+'" />
               <input type="hidden" name="typeterc" value="C" />';
    // Cria form POST e submete
});
```

**Dados enviados automaticamente:**
- `tipoop`: Tipo do documento (sempre 'OS')
- `num`: Número interno da OS  
- `documentnumber`: Número do documento (ex: OS2025/001)
- `codterc`: Código do cliente
- `typeterc`: Tipo de terceiro (sempre 'C' = Cliente)

#### 4. Processamento no Formulário
O formulário `new.php` recebe os dados:
```php
// Linhas 43-48
if(isset($_REQUEST['num']) && isset($_REQUEST['tipoop'])) {
    $source = 'phone';                    // Define source automático
    $documNum = $_REQUEST['num'];         // Número da OS
    $documTipoop = $_REQUEST['tipoop'];   // Tipo = 'OS'  
    $depId = $u->getDepartamento();       // Departamento do usuário
}
```

#### 5. Título Automático
```php
// Linha 40-41
if(isset($_REQUEST['documentnumber'])) {
    $description = $_REQUEST['documentnumber']; // Base do título = DocumentNumber
}
```

O título final será: **"DocumentNumber + descrição inserida pelo operador"**

#### 6. Pré-seleção de Email
Se há dados da OS (`codterc`, `documNum`, `documTipoop`), executa AJAX:
```javascript
// Linhas 1322+
$.ajax({
    url: AjaxURL,
    data: {
        action: 'Sel2_Select_Entity_Mails',
        codterc: <?= $codterc ?>,
        // ...
    },
    success: function(data) {
        // Seleciona primeiro email automaticamente
    }
});
```

### Fluxo Completo de Criação

```mermaid
graph TD
    A[Usuário na OS] --> B[Clica botão Novo Ticket]
    B --> C[JavaScript coleta dados da OS]
    C --> D[Form POST para /tickets/tickets/new]
    D --> E[Formulário recebe dados da OS]
    E --> F[Pré-popula campos automaticamente]
    F --> G[AJAX busca emails do cliente]
    G --> H[Usuário preenche descrição]
    H --> I[Submete formulário]
    I --> J[AJAX postNewTicket cria ticket]
    J --> K[Ticket associado à OS]
```

## Listagem de Tickets na OS

### Tab de Tickets
A tab mostra todos os tickets relacionados:
- **Entidades**: Tickets por cliente/fornecedor
- **Documentos OS**: Tickets específicos do documento

### Configuração da Consulta
```php
// Para documentos (como OS)
if ($modrewrite[0] != 'entidades') {
    $doc_type = $modrewrite[1] != 'ordservico' ? $modrewrite[1] : 'OS';
    $doc_num = base64_decode($modrewrite[3] ?? '');
    $paramsDt = [
        'option' => 'DT_List_Tik_Documents', 
        'where[tik.document_number]' => $doc_num,
        'where[tik.document_type]' => $doc_type,
        'where_in[stat.type]' => 'normal,hold'  // Apenas em aberto
    ];
}
```

### Filtros Disponíveis
- **Em Aberto**: `normal,hold` (padrão)
- **Fechados**: `resolved,closed`  
- **Todos**: `normal,hold,resolved,closed`

## Para Desenvolvedores

### Globals Importantes
```php
global $u;    // Usuário atual - privilégios, departamento
global $m;    // Módulos carregados - $m['tickets'] 
global $l;    // Localização - $l->r('código') para textos
global $doc;  // Dados do documento atual (quando aplicável)
```

### Principais Métodos do Módulo
```php
$m['tickets']->postNewEmpregTicket()     // Criar ticket
$m['tickets']->listDepartments()         // Listar departamentos  
$m['tickets']->countTickets()            // Contar tickets
$m['tickets']->get_permission_departments() // Departamentos com permissão
```

### Endpoints AJAX Relevantes
- `tickets.php?option=postNewTicket` - Criar novo ticket
- `tickets.php?option=DT_List_Tik_Documents` - Listar tickets de documento
- `counters.php?option=tickets_abertos` - Contar tickets em aberto

### Variáveis JavaScript Globais
```javascript
var status_tickets = 'normal,hold';  // Filtro atual de status
var oTable_list_tick_userhistory;   // DataTable da listagem
```

## Troubleshooting

### Botão "Novo" não aparece
**Verifique:**
1. ✅ Privilégio `tickets:tickets` 
2. ✅ Variável `$doc` existe
3. ✅ `$doc['tipoop'] == 'OS'`
4. ✅ Módulo tickets está ativo

### Dados não são pré-populados
**Verifique:**
1. ✅ Form POST envia `num` e `tipoop`
2. ✅ `$_REQUEST` recebe os dados
3. ✅ JavaScript coleta `#doc_CodTerc`

### Email não é pré-selecionado
**Verifique:**
1. ✅ `codterc`, `documNum`, `documTipoop` estão definidos
2. ✅ AJAX `Sel2_Select_Entity_Mails` responde 
3. ✅ Cliente tem emails cadastrados

## Glossário

- **OS**: Ordem de Serviço - documento de oficina
- **TK/Ticket**: Chamado de suporte
- **codterc**: Código do terceiro (cliente/fornecedor)
- **tipoop**: Tipo de operação do documento
- **DocumentNumber**: Número formatado do documento (ex: OS2025/001)
- **source**: Origem do ticket (phone, email, web, etc.)