/*
<div vw class="enabled">
    <div vw-access-button class="active"></div>
    <div vw-plugin-wrapper>
        <div class="vw-plugin-top-wrapper"></div>
    </div>
</div>

<div class="minha-nova-aplicacao">
    <button>Meu Botão</button>
</div>

<script src="https://vlibras.gov.br/app/vlibras-plugin.js"></script>
<script>
    new window.VLibras.Widget('https://vlibras.gov.br/app');
</script>

.minha-nova-aplicacao {
    position: fixed;
    right: 10px;        /* Distância da borda direita */
    top: 40%;           /* Ajuste esse valor para subir ou descer */
    z-index: 99999;     /* Mesmo nível do VLibras para aparecer na frente */
}

.enabled.active {
    z-index: 99999 !important;
}

.minha-nova-aplicacao {
    position: fixed;
    right: 10px;
    top: 60%;           /* Valor maior que o do VLibras para ficar embaixo */
    z-index: 99999;
}

[vw-access-button] {
    top: 55% !important; /* Move o bonequinho do VLibras um pouco para baixo */
}

    public static function btnretornoconsulta($param = null) 
    {
        try
        {
            if (empty($param['id']))
            {
                throw new Exception('<br>ID do agendamento não foi fornecido.');
            }

            $id = $param['id'];
            TTransaction::open(self::$database);
            $agendamento = Agendamento::find($id);

            if (!$agendamento)
            {
                TTransaction::close();
                throw new Exception('<br>Agendamento ID ' . htmlspecialchars($id) . ' não encontrado.');
            }

            if ($agendamento->status !== '12')
            {
                TTransaction::close();
                throw new Exception('<br>O Agendamento deve estar <b>FINALIZADO</b> para agendar retorno.<br>Status atual: ' . self::getStatusLabel($agendamento->status));
            }

            if (empty($agendamento->profissional_id))
            {
                TTransaction::close();
                throw new Exception('<br>Profissional não vinculado ao agendamento.');
            }

            $profissional_usuario = SystemUsers::find($agendamento->profissional_id);
            if (!$profissional_usuario)
            {
                TTransaction::close();
                throw new Exception('<br>Profissional não encontrado.');
            }

            $profissional_pessoa = Pessoa::where('usuario_sistema', '=', $profissional_usuario->id)->first();
            if (!$profissional_pessoa)
            {
                TTransaction::close();
                throw new Exception('<br>Dados do profissional não encontrado.');
            }

            // Verificar autorização
            if (isset($profissional_pessoa->geraroutro_retorno) && $profissional_pessoa->geraroutro_retorno === 'N')
            {
                TTransaction::close();
                throw new Exception('<br>Profissional <b>' . htmlspecialchars($profissional_usuario->name) . '</b> não autorizou a geração do retorno.');
            }

            $dias_para_retorno = (int)($profissional_pessoa->dias_para_retorno ?? 0);
            if ($dias_para_retorno <= 0)
            {
                TTransaction::close();
                throw new Exception('<br>Dias para retorno não foi configurado para o profissional.');
            }

            $repository                                         = new TRepository('Agendamento');
            $criteria                                           = new TCriteria();
            $criteria->add(new TFilter('paciente_id',          '=', $agendamento->paciente_id));
            $criteria->add(new TFilter('profissional_id',      '=', $agendamento->profissional_id));
            $criteria->add(new TFilter('consulta_retorno',     '=', 'S'));
            $criteria->add(new TFilter('agendamento_anterior', '=', $agendamento->id));
            $criteria->add(new TFilter('status', 'IN', ['01', '02', '97']));

            if ($repository->count($criteria) > 0)
            {
                $retornos    = $repository->load($criteria, false);
                $ret         = $retornos[0];
                $msg_detalhe = '';

                if (!empty($ret->horario_inicial) && !empty($ret->horario_final))
                {
                    $dt_ini      = DateTime::createFromFormat('Y-m-d H:i:s', $ret->horario_inicial) ?: new DateTime($ret->horario_inicial);
                    $dt_fim      = DateTime::createFromFormat('Y-m-d H:i:s', $ret->horario_final)   ?: new DateTime($ret->horario_final);
                    $msg_detalhe =  "<br><br><b>Retorno agendado:</b><br>" .
                                    "Data e Hora: " . $dt_ini->format('d/m/Y H:i') . ' às ' . $dt_fim->format('H:i') . "<br>" .
                                    "Status: " . self::getStatusLabel($ret->status) . "<br>ID: " . $ret->id;
                }

                TTransaction::close();
                throw new Exception('<br>Já existe um retorno pendente para este paciente e profissional.' . $msg_detalhe);
            }

            $dados = new stdClass;

            // ID do agendamento atual
            $dados->vagendamento_id = $param['id'] ?? null;

            // Recupera contexto salvo na sessão
            $dados->empresa_id      = TSession::getValue('agendamento_filtro_empresa_id');
            $dados->profissional_id = TSession::getValue('agendamento_filtro_profissional_id');

            // Abre a lista mantendo o filtro
            TApplication::loadPage('AgendamentoList', 'onReload', (array) $dados);

            //</autoCode>
        }
        catch (Exception $e) 
        {
            TTransaction::rollback();
            new TMessage('error', '<b>' .TSession::getValue('username').  '</b>' . $e->getMessage());
        }
    }

        try
        {
            if (isset($param['key']))
            {
                $key                     = $param['key'];  // get the parameter $key
                self::$editando_registro = true;
                $isDuplicado             = (isset($param['duplicado']) && $param['duplicado'] == 'true');

                // Inicializar $object->modo_form para evitar erros
                $modo_form = 'edit'; // padrão
                if ($isDuplicado) 
                {
                    $modo_form = 'duplicado';
                }

                TTransaction::open(self::$database); // open a transaction

                $object                 = new Agendamento($key); // instantiates the Active Record
                self::$objeto_original  = clone $object;
                $object->modo_form      = $modo_form;

                // PRESERVAR VALORES ORIGINAIS ANTES DE QUALQUER PROCESSAMENTO
                $valor_taxaentregaexame_original         = $object->valor_taxaentregaexame;
                $valor_receber_original                  = $object->valor_receber;
                $valor_venda_original                    = $object->valor_venda;
                $percentual_desconto_maximo_original     = $object->percentual_desconto_maximo;
                $percentual_desconto_utilizado_original  = $object->percentual_desconto_utilizado;

                // Validação: Preenchimento do ambiente_id a partir do slot
                if (isset($param['from_slot']) && $param['from_slot'] == 'true' && !empty($param['ambiente_id']))
                {
                    $object->ambiente_id = $param['ambiente_id'];
                }

                // Preparaçăo de dados do paciente
                $paciente           = $object->paciente; 
                $paciente_id        = null;
                $titulo_paciente    = '[Paciente năo vinculado]';
                $js_script_coletado = "";                 // Inicializa a string que irá coletar todo o JavaScript

                if (is_object($paciente)) 
                {
                    $paciente_id     = $paciente->id; // Extrai o ID e o caminho da foto para uso posterior
                    $titulo_paciente = $paciente->get_nome_cnpjcpf_idade(); // Define o título formatado
                }

                // Define o Título da página (correçăo do erro 'null' incluída)
                parent::setTitle("AGENDAMENTO {$key} # {$titulo_paciente}");

                // Carregar foto do paciente
                $this->paciente_foto->src = $object->paciente->caminho_foto;

                // === CARREGAR PRODUTO_ID ANTES DE SETAR NO FORMULÁRIO ===
/*
                if (!empty($object->fornecedor_id) && !empty($object->produto_id)) 
                {
                    try 
                    {
                        $conn = TTransaction::get();

                        // Buscar o produto específico que está salvo
                        $sqlProduto = "SELECT 
                                        pfp.fornecedor_id,
                                        pfp.produto_id,
                                        p.descproduto,
                                        pfp.preco_venda,
                                        pfp.percentual_desconto_autorizado,
                                        pfp.valor_taxaentregaexame,
                                        pfp.consulta_retorno AS vconsultaretorno
                                    FROM produto_fornecedorpreco pfp
                                    INNER JOIN produto p ON p.id = pfp.produto_id
                                    WHERE pfp.produto_id = :produto_id
                                    AND pfp.fornecedor_id = :fornecedor_id
                                    AND pfp.status = 'A'
                                    ";

                        $stmt = $conn->prepare($sqlProduto);
                        $stmt->execute([
                            ':produto_id'    => $object->produto_id,
                            ':fornecedor_id' => $object->fornecedor_id
                        ]);
                        $row = $stmt->fetch(PDO::FETCH_ASSOC);

                        if ($row) 
                        {
                            $label = sprintf('%d %d %s | Valor: %.2f | Procedimento gera retorno: %s',
                                                $row['fornecedor_id'],
                                                $row['produto_id'],
                                                $row['descproduto'] ?? 'Sem nome',
                                                $row['preco_venda'] ?? 0,                                            
                                                $row['vconsultaretorno'] === 'S' ? 'Sim' : 'Năo'
                                                );

                            // Recarregar combo APENAS com este produto
                            TCombo::reload(self::$formName, 'produto_id', [$object->produto_id => $label]);
                        }
                    } 
                    catch (Exception $e) 
                    {
                        // Silenciosamente ignora erro e continua
                    }
                }
                else if (!empty($object->fornecedor_id))
                {
                    // Se tem fornecedor mas năo tem produto, carregar lista completa
                    try 
                    {
                        $conn = TTransaction::get();

                        $sqlProdutos = "SELECT 
                                            pfp.fornecedor_id,
                                            pfp.produto_id,
                                            p.descproduto,
                                            pfp.preco_venda,
                                            pfp.percentual_desconto_autorizado,
                                            pfp.valor_taxaentregaexame,
                                            pfp.consulta_retorno AS vconsultaretorno
                                        FROM produto_fornecedorpreco pfp
                                        INNER JOIN produto p ON p.id = pfp.produto_id
                                        WHERE pfp.fornecedor_id = :fornecedor_id
                                        AND pfp.status = 'A'
                                        ORDER BY p.descproduto
                                        ";

                        $stmt = $conn->prepare($sqlProdutos);
                        $stmt->execute([':fornecedor_id' => $object->fornecedor_id]);
                        $produtoOptions = [];

                        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) 
                        {
                            $label = sprintf('%d %d %s | Valor: %.2f | Procedimento gera retorno: %s',
                                                $row['fornecedor_id'],
                                                $row['produto_id'],
                                                $row['descproduto'] ?? 'Sem nome',
                                                $row['preco_venda'] ?? 0,                                            
                                                $row['vconsultaretorno'] === 'S' ? 'Sim' : 'Năo'
                                                );

                            $produtoOptions[$row['produto_id']] = $label;
                        }

                        TCombo::reload(self::$formName, 'produto_id', $produtoOptions);
                    } 
                    catch (Exception $e) 
                    {
                        // Silenciosamente ignora erro
                    }
                }
                else
                {
                    // Sem fornecedor, mostrar vazio
                    TCombo::reload(self::$formName, 'produto_id', ['' => 'Selecione um convęnio']);
                }
*/
            if (!empty($object->paciente_id) && !empty($object->fornecedor_id))
            {
                try
                {
                    // Buscar todos os convênios ativos do paciente
                    $criteria = TCriteria::create(['paciente_id' => $object->paciente_id]);
                    $criteria->add(new TFilter('status', '=', 'A'));

                    $repo      = new TRepository('PessoaConvenioparceria');
                    $convenios = $repo->load($criteria);

                    $options = ['' => ''];
                    $selected_label = '';

                    foreach ($convenios as $convenio)
                    {
                        $fornecedor = $convenio->fornecedor;
                        if ($fornecedor)
                        {
                            $label = $convenio->fornecedor_id . ' - ' . $fornecedor->nome . ' - Carteirinha: ' . ($convenio->numero_carteirinha ?? '');
                            $options[$convenio->fornecedor_id] = $label;

                            // Se for o fornecedor salvo, guardar o label
                            if ($convenio->fornecedor_id == $object->fornecedor_id)
                            {
                                $selected_label = $label;
                            }
                        }
                    }

                    // Recarregar o combo com TODAS as opções
                    TCombo::reload(self::$formName, 'fornecedor_id', $options);

                    // Forçar o valor selecionado via JavaScript
                    $fornecedor_escaped = addslashes($object->fornecedor_id);
                    TScript::create("
                        setTimeout(function() 
                        {
                            var combo = document.querySelector('[name=\"fornecedor_id\"]');
                            if (combo) 
                            {
                                combo.value = '{$fornecedor_escaped}';
                                $(combo).trigger('change');
                            }
                        }, 300);
                    ");

                    // Apenas marcação visual, não desabilita
                    TScript::create("
                        setTimeout(function() 
                        {
                            var el = document.querySelector('[name=\"fornecedor_id\"]');
                            if (el) 
                            {
                                el.style.backgroundColor = '#f9f9f9';
                                el.title = 'Campo preservado da edição. Pode ser alterado se necessário.';
                            }
                        }, 500);
                    ");

                }
                catch (Exception $e)
                {
                    // Continua silenciosamente
                }
            }

// ========================================
// CARREGAR FORNECEDOR_ID COM DADOS CORRETOS
// ========================================
if (!empty($object->fornecedor_id) && !empty($object->produto_id)) 
{
    try 
    {
        $conn = TTransaction::get();

        // Buscar o produto específico que está salvo
        $sqlProduto = "SELECT 
                        pfp.fornecedor_id,
                        pfp.produto_id,
                        p.descproduto,
                        pfp.preco_venda,
                        pfp.consulta_retorno AS vconsultaretorno
                    FROM produto_fornecedorpreco pfp
                    INNER JOIN produto p ON p.id = pfp.produto_id
                    WHERE pfp.produto_id = :produto_id
                    AND pfp.fornecedor_id = :fornecedor_id
                    AND pfp.status = 'A'
                    ";

        $stmt = $conn->prepare($sqlProduto);
        $stmt->execute([
            ':produto_id'    => $object->produto_id,
            ':fornecedor_id' => $object->fornecedor_id
        ]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($row) 
        {
            $label = sprintf('%d %d %s | Valor: %.2f | Procedimento gera retorno: %s',
                                $row['fornecedor_id'],
                                $row['produto_id'],
                                $row['descproduto'] ?? 'Sem nome',
                                $row['preco_venda'] ?? 0,                                            
                                $row['vconsultaretorno'] === 'S' ? 'Sim' : 'Não'
                                );

            // Recarregar combo APENAS com este produto
            TCombo::reload(self::$formName, 'produto_id', [$object->produto_id => $label]);
            
            // GARANTIR que o valor seja mantido no objeto
            $object->produto_id = $object->produto_id;
            
            // FORÇAR via JavaScript também
            TScript::create("
                setTimeout(function() {
                    var produtoField = document.querySelector('[name=\"produto_id\"]');
                    if (produtoField) {
                        produtoField.value = '{$object->produto_id}';
                        // Disparar evento para carregar dependências
                        $(produtoField).trigger('change');
                    }
                }, 400);
            ");
        }
        else
        {
            // Se não encontrou, carregar todos os produtos do fornecedor
            $sqlProdutos = "SELECT 
                                pfp.fornecedor_id,
                                pfp.produto_id,
                                p.descproduto,
                                pfp.preco_venda,
                                pfp.consulta_retorno AS vconsultaretorno
                            FROM produto_fornecedorpreco pfp
                            INNER JOIN produto p ON p.id = pfp.produto_id
                            WHERE pfp.fornecedor_id = :fornecedor_id
                            AND pfp.status = 'A'
                            ORDER BY p.descproduto";

            $stmt = $conn->prepare($sqlProdutos);
            $stmt->execute([':fornecedor_id' => $object->fornecedor_id]);
            $produtoOptions = [];

            while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) 
            {
                $label = sprintf('%d %d %s | Valor: %.2f | Procedimento gera retorno: %s',
                                    $row['fornecedor_id'],
                                    $row['produto_id'],
                                    $row['descproduto'] ?? 'Sem nome',
                                    $row['preco_venda'] ?? 0,
                                    $row['vconsultaretorno'] === 'S' ? 'Sim' : 'Não'
                                    );

                $produtoOptions[$row['produto_id']] = $label;
            }

            TCombo::reload(self::$formName, 'produto_id', $produtoOptions);
            
            // Forçar seleção
            TScript::create("
                setTimeout(function() {
                    var produtoField = document.querySelector('[name=\"produto_id\"]');
                    if (produtoField && '{$object->produto_id}') {
                        produtoField.value = '{$object->produto_id}';
                        $(produtoField).trigger('change');
                    }
                }, 400);
            ");
        }
    } 
    catch (Exception $e) 
    {
        // Em caso de erro, pelo menos manter o valor no formulário
        //TScript::create("console.warn('Erro ao carregar produto: " . addslashes($e->getMessage()) . "');");
    }
}
                // === FIM CARREGAMENTO PRODUTO_ID ===

                // CARREGAR GUIA PRINCIPAL AO EDITAR
                if (!empty($object->guia_conveniocab_id)) 
                {
                    try 
                    {
                        $guia = GuiasconvenioCab::find($object->guia_conveniocab_id);
                        if ($guia) 
                        {
                            // OBTER DADOS DA GUIA COM STATUS E COR
                            $label             = $guia->getLabelComFormatacao();
                            $status            = $guia->getStatusVencimento();
                            $color             = $guia->getCorStatus();
                            $colorEmoji        = ($color == 'red') ? '🔴' : (($color == 'orange') ? '🟠' : '🟢');
                            $labelComIndicador = $colorEmoji . ' ' . $label;

                            // RECARREGAR COMBO COM A GUIA ESPECÍFICA E INDICADOR VISUAL
                            $guiaOptions = [$object->guia_conveniocab_id => $labelComIndicador];
                            TCombo::reload(self::$formName, 'guia_conveniocab_id', $guiaOptions);

                            // FORÇAR SELEÇĂO DA GUIA
                            TScript::create("
                                setTimeout(function() 
                                {
                                    $('#guia_conveniocab_id').val('{$object->guia_conveniocab_id}').trigger('change');
                                }, 300);
                            ");
                        }
                    } 
                    catch (Exception $e) 
                    {
                        // Silenciosamente ignora erro
                    }
                }

                // Recarregar os combos com dados do banco
                //self::recarregarCombosEdicao($object);

//Alteração

// 1. RECARREGAR FORNECEDOR_ID COM CRITÉRIO DO PACIENTE
if (!empty($object->paciente_id)) 
{
    try 
    {
        $criteria = TCriteria::create(['paciente_id' => $object->paciente_id]);
        $criteria->add(new TFilter('status', '=', 'A'));

        TDBCombo::reloadFromModel(
            self::$formName, 
            'fornecedor_id', 
            'bdgestorweb', 
            'PessoaConvenioparceria', 
            'fornecedor_id', 
            '{fornecedor_id} - {fornecedor->nome} - Carteirinha: {numero_carteirinha}', 
            'fornecedor_id asc', 
            $criteria, 
            TRUE
        );
    } 
    catch (Exception $e) 
    {
        // continua silenciosamente
    }
}

// 2. RECARREGAR PRODUTO_ID COM CRITÉRIO DO FORNECEDOR
if (!empty($object->fornecedor_id)) 
{
    try 
    {
        $conn = TTransaction::get();

        $sqlProdutos = "SELECT 
                            pfp.fornecedor_id,
                            pfp.produto_id,
                            p.descproduto,
                            pfp.preco_venda,
                            pfp.consulta_retorno AS vconsultaretorno
                        FROM produto_fornecedorpreco pfp
                        INNER JOIN produto p ON p.id = pfp.produto_id
                        WHERE pfp.fornecedor_id = :fornecedor_id
                        AND pfp.status = 'A'
                        ORDER BY p.descproduto";

        $stmt = $conn->prepare($sqlProdutos);
        $stmt->execute([':fornecedor_id' => $object->fornecedor_id]);
        $produtoOptions = [];

        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) 
        {
            $label = sprintf('%d %d %s | Valor: %.2f | Procedimento gera retorno: %s',
                                $row['fornecedor_id'],
                                $row['produto_id'],
                                $row['descproduto'] ?? 'Sem nome',
                                $row['preco_venda'] ?? 0,                                            
                                $row['vconsultaretorno'] === 'S' ? 'Sim' : 'Não'
                                );

            $produtoOptions[$row['produto_id']] = $label;
        }

        TCombo::reload(self::$formName, 'produto_id', $produtoOptions);
    } 
    catch (Exception $e) 
    {
        // continua silenciosamente
    }
}

// 3. RECARREGAR ENTREGA_RESULTADO
if (!empty($object->entrega_resultado)) 
{
    try 
    {
        $items_entrega = [
            'NE' => 'Não tem Exame',
            'EN' => 'Entrega Normal',
            'EU' => 'Entrega Urgente'
        ];

        TCombo::reload(self::$formName, 'entrega_resultado', $items_entrega);
        TField::enableField(self::$formName, 'entrega_resultado');
    } 
    catch (Exception $e) 
    {
        // continua silenciosamente
    }
}

// 4. RECARREGAR GUIA_CONVENIOCAB_ID
if (!empty($object->paciente_id) && !empty($object->fornecedor_id)) 
{
    try 
    {
        $criteria_guia = new TCriteria();
        $criteria_guia->add(new TFilter('pessoa_id', '=', $object->paciente_id));
        $criteria_guia->add(new TFilter('fornecedor_id', '=', $object->fornecedor_id));
        $criteria_guia->add(new TFilter('status', '=', 'A'));

        $conn = TTransaction::get();
        $sql = "SELECT id, guia_convenio FROM guiasconvenio_cab 
                WHERE pessoa_id = :pessoa_id 
                AND fornecedor_id = :fornecedor_id 
                AND status = 'A'
                ORDER BY data_vencimento ASC";

        $stmt = $conn->prepare($sql);
        $stmt->execute([
            ':pessoa_id' => $object->paciente_id,
            ':fornecedor_id' => $object->fornecedor_id
        ]);

        $guiaOptions = [];
        while ($row = $stmt->fetch(PDO::FETCH_OBJ)) 
        {
            $guiaOptions[$row->id] = $row->guia_convenio;
        }

        TCombo::reload(self::$formName, 'guia_conveniocab_id', $guiaOptions);
    } 
    catch (Exception $e) 
    {
        // continua silenciosamente
    }
}

// 5. RECARREGAR GUIA_AUXILIAR_ID se tiver guia principal
if (!empty($object->guia_conveniocab_id)) 
{
    try 
    {
        $conn = TTransaction::get();
        $sql = "SELECT id, guia_codigovalidacao, utilizado 
                FROM guiasconvenio_item 
                WHERE guia_conveniocab_id = :guia_conveniocab_id
                ORDER BY id ASC";

        $stmt = $conn->prepare($sql);
        $stmt->execute([':guia_conveniocab_id' => $object->guia_conveniocab_id]);

        $guiaItemOptions = [];
        while ($row = $stmt->fetch(PDO::FETCH_OBJ)) 
        {
            $label = "{$row->id} - {$row->guia_codigovalidacao} - " . 
                    (($row->utilizado === 'S') ? 'Utilizado' : 'Disponível');
            $guiaItemOptions[$row->id] = $label;
        }

        TCombo::reload(self::$formName, 'guia_auxiliar_id', $guiaItemOptions);
    } 
    catch (Exception $e) 
    {
        // continua silenciosamente
    }
}

// GARANTIR que os IDs sejam mantidos como string/number
if (!empty($object->produto_id)) {
    $object->produto_id = (string) $object->produto_id;
}

if (!empty($object->fornecedor_id)) {
    $object->fornecedor_id = (string) $object->fornecedor_id;
}

if (!empty($object->guia_conveniocab_id)) {
    $object->guia_conveniocab_id = (string) $object->guia_conveniocab_id;
}

if (!empty($object->guia_auxiliar_id)) {
    $object->guia_auxiliar_id = (string) $object->guia_auxiliar_id;
}

// Preencher formulário com dados do objeto
$this->form->setData($object); // fill the form
//Fim alteração

               // Preencher formulário com dados do objeto
                $this->form->setData($object); // fill the form
// Alteração
// ========================================
// FORÇAR VALORES VIA JAVASCRIPT (após setData)
// ========================================
TScript::create("
    setTimeout(function() 
    {
        // Forçar valores dos combos após carregar
        var fornecedor = document.querySelector('[name=\"fornecedor_id\"]');
        if (fornecedor && '{$object->fornecedor_id}') 
        {
            fornecedor.value = '{$object->fornecedor_id}';
            fornecedor.dispatchEvent(new Event('change', { bubbles: true }));
        }

        var produto = document.querySelector('[name=\"produto_id\"]');
        if (produto && '{$object->produto_id}') 
        {
            produto.value = '{$object->produto_id}';
        }

        var guia = document.querySelector('[name=\"guia_conveniocab_id\"]');
        if (guia && '{$object->guia_conveniocab_id}') 
        {
            guia.value = '{$object->guia_conveniocab_id}';
        }

        var guiaItem = document.querySelector('[name=\"guia_auxiliar_id\"]');
        if (guiaItem && '{$object->guia_auxiliar_id}') 
        {
            guiaItem.value = '{$object->guia_auxiliar_id}';
        }

        var entrega = document.querySelector('[name=\"entrega_resultado\"]');
        if (entrega && '{$object->entrega_resultado}') 
        {
            entrega.value = '{$object->entrega_resultado}';
        }
    }, 500);
");

// ✅ Recarregar dados para edição
if (!empty($object->id)) 
{
    TTransaction::open(self::$database);

    // Recarregar combos com dados atualizados do banco
    if (!empty($object->paciente_id)) 
    {
        $criteria = TCriteria::create(['paciente_id' => $object->paciente_id]);
        $criteria->add(new TFilter('status', '=', 'A'));
        TDBCombo::reloadFromModel(
            self::$formName, 
            'fornecedor_id', 
            'bdgestorweb', 
            'PessoaConvenioparceria', 
            'fornecedor_id', 
            '{fornecedor_id} - {fornecedor->nome} - Carteirinha: {numero_carteirinha}', 
            'fornecedor_id asc', 
            $criteria, 
            TRUE
        );
    }

    // Recarregar produto
    if (!empty($object->fornecedor_id)) 
    {
        $criteria_produto = TCriteria::create(['fornecedor_id' => $object->fornecedor_id]);
        $criteria_produto->add(new TFilter('status', '=', 'A'));
        $criteria_produto->setProperty('order', 'descproduto');
        TDBCombo::reloadFromModel(
            self::$formName,
            'produto_id',
            self::$database,
            'ProdutoFornecedorpreco',
            'produto_id',
            '{fornecedor_id} {produto_id} - {produto->descproduto} Valor: {preco_venda}',
            null,
            $criteria_produto,
            TRUE
        );
    }

    // Recarregar entrega_resultado
    if (!empty($object->entrega_resultado)) 
    {
        $items_entrega = [
            'NE' => 'Não tem Exame',
            'EN' => 'Entrega Normal',
            'EU' => 'Entrega Urgente'
        ];
        TCombo::reload(self::$formName, 'entrega_resultado', $items_entrega);
        TField::enableField(self::$formName, 'entrega_resultado');
    }

    // Recarregar guia convênio
    if (!empty($object->paciente_id) && !empty($object->fornecedor_id)) 
    {
        $criteria_guia = new TCriteria();
        $criteria_guia->add(new TFilter('pessoa_id', '=', $object->paciente_id));
        $criteria_guia->add(new TFilter('fornecedor_id', '=', $object->fornecedor_id));
        $criteria_guia->add(new TFilter('status', '=', 'A'));
        $criteria_guia->setProperty('order', 'data_vencimento asc');
        TDBCombo::reloadFromModel(
            self::$formName,
            'guia_conveniocab_id',
            self::$database,
            'GuiasconvenioCab',
            'id',
            '{fornecedor_id} {id} - Guia do convênio: {guia_convenio}',
            'data_vencimento asc',
            $criteria_guia,
            TRUE
        );
    }

    // Recarregar guia auxiliar
    if (!empty($object->guia_conveniocab_id)) 
    {
        $criteria_auxiliar = new TCriteria();
        $criteria_auxiliar->add(new TFilter('guia_conveniocab_id', '=', $object->guia_conveniocab_id));
        TDBCombo::reloadFromModel(
            self::$formName,
            'guia_auxiliar_id',
            self::$database,
            'GuiasconvenioItem',
            'id',
            '{guia_conveniocab_id} - Guia: {guia_principal} - {id}',
            'id asc',
            $criteria_auxiliar,
            TRUE
        );
    }
}
//Fim alteração
                // === CORREÇÃO: Recarregar opções do fornecedor_id ao editar ===
                if (!empty($object->paciente_id) && !empty($object->fornecedor_id))
                {
                    try
                    {
                        TTransaction::open(self::$database);

                        // Buscar todos os convênios ativos do paciente
                        $criteria = TCriteria::create(['paciente_id' => $object->paciente_id]);
                        $criteria->add(new TFilter('status', '=', 'A'));

                        $repo      = new TRepository('PessoaConvenioparceria');
                        $convenios = $repo->load($criteria);

                        $options = ['' => ''];
                        foreach ($convenios as $convenio)
                        {
                            $fornecedor = $convenio->fornecedor;
                            if ($fornecedor)
                            {
                                $label                              = $convenio->fornecedor_id . ' - ' . $fornecedor->nome . ' - Carteirinha: ' . ($convenio->numero_carteirinha ?? '');
                                $options[$convenio->fornecedor_id]  = $label;

                                // Se for o fornecedor salvo, destacar ou garantir seleção
                                if ($convenio->fornecedor_id == $object->fornecedor_id)
                                {
                                    $selected_label = $label;
                                }
                            }
                        }

                        // Recarregar o combo com as opções corretas
                        TCombo::reload(self::$formName, 'fornecedor_id', $options);

                        // === CORREÇÃO: Recarregar opções do fornecedor_id ao editar ===
                        if (!empty($object->paciente_id) && !empty($object->fornecedor_id))
                        {
                            try
                            {
                                // Buscar todos os convênios ativos do paciente
                                $criteria = TCriteria::create(['paciente_id' => $object->paciente_id]);
                                $criteria->add(new TFilter('status', '=', 'A'));

                                $repo      = new TRepository('PessoaConvenioparceria');
                                $convenios = $repo->load($criteria);

                                $options = ['' => ''];
                                $selected_label = '';

                                foreach ($convenios as $convenio)
                                {
                                    $fornecedor = $convenio->fornecedor;
                                    if ($fornecedor)
                                    {
                                        $label                              = $convenio->fornecedor_id . ' - ' . $fornecedor->nome . ' - Carteirinha: ' . ($convenio->numero_carteirinha ?? '');
                                        $options[$convenio->fornecedor_id]  = $label;

                                        // Se for o fornecedor salvo, guardar o label
                                        if ($convenio->fornecedor_id == $object->fornecedor_id)
                                        {
                                            $selected_label = $label;
                                        }
                                    }
                                }

                                // Recarregar o combo com TODAS as opções
                                TCombo::reload(self::$formName, 'fornecedor_id', $options);

                                // ========================================
                                // NOVO: Forçar o valor selecionado via JavaScript ANTES de desabilitar
                                // ========================================
                                $fornecedor_escaped = addslashes($object->fornecedor_id);
                                TScript::create("
                                    setTimeout(function() 
                                    {
                                        var combo = document.querySelector('[name=\"fornecedor_id\"]');
                                        if (combo) 
                                        {
                                            combo.value = '{$fornecedor_escaped}';
                                            $(combo).trigger('change');
                                        }
                                    }, 300);
                                ");

                                // DEPOIS desabilitar o campo
                                TField::disableField(self::$formName, 'fornecedor_id');
/*
                                TScript::create("
                                    setTimeout(function() 
                                    {
                                        var el = document.querySelector('[name=\"fornecedor_id\"]');
                                        if (el) 
                                        {
                                            el.disabled = true;
                                            el.style.backgroundColor = '#f0f0f0';
                                            el.style.cursor = 'not-allowed';
                                            el.style.opacity = '0.7';
                                        }
                                    }, 500);
                                ");
*/
// SUBSTITUA por:
TScript::create("
    setTimeout(function() 
    {
        var el = document.querySelector('[name=\"fornecedor_id\"]');
        if (el) 
        {
            el.style.backgroundColor = '#f9f9f9';
            el.title = 'Valor preservado do registro original';
        }
    }, 500);
");
                                // Trava o botao onsave ate carregar os dados
                                $f_id = (int) $object->id;
                                TScript::create("
                                    $('#btn_salvar_agendamento').html('<i class=\"fa fa-spinner fa-spin\"></i> Aguarde carregando informações ....');
                                    $('[name=\"id\"]').val('{$f_id}').trigger('change');

                                    setTimeout(function() 
                                    {
                                        var b = $('#btn_salvar_agendamento');
                                        if (b.length > 0) 
                                        {
                                            b.prop('disabled', false);
                                            b.attr('style', 'pointer-events: auto; opacity: 1;');
                                            b.html('<i class=\"fas fa-save\" style=\"color:white\"></i> Aguarde atualizando informações ....');

                                            setTimeout(function() 
                                            { 
                                                b.html('<i class=\"fas fa-save\" style=\"color:white\"></i> Salvar'); 
                                            }, 2800);
                                        }
                                    }, 2800);
                                ");
                            }
                            catch (Exception $e)
                            {
                                new TMessage('error', 'Erro ao carregar convênios do paciente: ' . $e->getMessage());
                            }
                        }
// === FIM DA CORREÇÃO ===
/*
// Trava o botao onsave ate carregar os dados
TScript::create("
    setTimeout(function() 
    {
        var combo = document.querySelector('[name=\"fornecedor_id\"]');
        if (combo) 
        {
            combo.value = '{$object->fornecedor_id}';
            $(combo).trigger('change');
        }
    }, 700);
");
*/
                        // Trava o botao onsave ate carregar os dados
                        $f_id = (int) $object->id;
                        TScript::create("
                            $('#btn_salvar_agendamento').html('<i class=\"fa fa-spinner fa-spin\"></i> Aguarde carregando informações ....');
                            $('[name=\"id\"]').val('{$f_id}').trigger('change');

                            setTimeout(function() 
                            {
                                var b = $('#btn_salvar_agendamento');
                                if (b.length > 0) 
                                {
                                    b.prop('disabled', false);
                                    b.attr('style', 'pointer-events: auto; opacity: 1;');
                                    b.html('<i class=\"fas fa-save\" style=\"color:white\"></i> Aguarde atualizando informações ....');

                                    setTimeout(function() 
                                    { 
                                        b.html('<i class=\"fas fa-save\" style=\"color:white\"></i> Salvar'); 
                                    }, 2300);
                                }
                            }, 2300);
                        ");

                        TTransaction::close();
                    }
                    catch (Exception $e)
                    {
                        TTransaction::rollback();
                        new TMessage('error', 'Erro ao carregar convênios do paciente: ' . $e->getMessage());
                    }
                }
                // === FIM DA CORREÇÃO ===
                // CONFIGURAR STATUS DO AGENDAMENTO
                $this->configurarStatus($object, $isDuplicado);

                // ================= SOLUÇÃO DEFINITIVA: USAR JAVASCRIPT PARA DEFINIR VALORES =================
                // O TForm::sendData não está funcionando corretamente para valor_taxaentregaexame
                // Vamos usar JavaScript para injetar diretamente os valores formatados

                // Função auxiliar para formatar valores para campos TNumeric
                $formatarValor = function($valor) 
                {
                    if (empty($valor) && $valor !== '0' && $valor !== 0) 
                    {
                        return '';
                    }
                    // Converter para double e formatar com 2 decimais, vírgula como separador decimal
                    $valor_double = str_replace(',', '.', str_replace('.', '', $valor));
                    return  number_format($valor_double, 2, ',', '.');
                };

                // Preparar valores formatados
                $valores_js = 
                [
                    'valor_taxaentregaexame'            => $formatarValor($valor_taxaentregaexame_original),
                    'valor_venda'                       => $formatarValor($valor_venda_original),
                    'valor_receber'                     => $formatarValor($valor_receber_original),
                    'percentual_desconto_maximo'        => $formatarValor($percentual_desconto_maximo_original),
                    'percentual_desconto_utilizado'     => $formatarValor($percentual_desconto_utilizado_original)
                ];

                // Criar script JavaScript para injetar valores
                $js = "(function() {\n";
                $js .= "  function definirValor(campoNome, valor) {\n";
                $js .= "    var campo = document.querySelector('[name=\"' + campoNome + '\"]');\n";
                $js .= "    if (campo) {\n";
                $js .= "      campo.value = valor;\n";
                $js .= "      // IMPORTANTE: Não disparar eventos para evitar onexittemetregaresultado\n";
                $js .= "      // campo.dispatchEvent(new Event('change', { bubbles: true }));\n";
                $js .= "      // campo.dispatchEvent(new Event('input',  { bubbles: true }));\n";
                $js .= "    }\n";
                $js .= "    }\n";
                $js .= "  \n";
                $js .= "  // Tentar definir valores após 500ms\n";
                $js .= "  setTimeout(function() {\n";

                foreach ($valores_js as $campo => $valor) 
                {
                    $valor_escape = addslashes($valor);
                    $js .= "    definirValor('$campo', '$valor_escape');\n";
                }

                $js .= "  }, 500);\n";
                $js .= "  \n";
                $js .= "  // Tentar novamente após 1s para garantir\n";
                $js .= "  setTimeout(function() {\n";

                foreach ($valores_js as $campo => $valor) 
                {
                    $valor_escape = addslashes($valor);
                    $js .= "    definirValor('$campo', '$valor_escape');\n";
                }

                $js .= "  }, 1000);\n";
                $js .= "})();";

                TScript::create($js);
                // ================= FIM DA SOLUÇÃO =================

                // Verificar contas abertas
                if ($paciente_id) 
                {
                    $js_script_coletado .= self::verificarContasAbertas($paciente_id) . "\n";
                }

                if (!empty($js_script_coletado)) 
                {
                    TScript::create("
                        $(document).ready(function() 
                        {
                            " . $js_script_coletado . "
                        });
                    ");
                }

                // Garante que o botão tenha um ID para ser manipulado via JavaScript.
                $this->btn_onsave->{'id'} = 'btn-salvar-agendamento';
                // Injete o script com uma garantia de execução.
                TScript::create("
                    (function() 
                    {
                        var button = document.getElementById('btn-salvar-agendamento');
                        if (button) 
                        {
                            button.disabled = true;
                            setTimeout(function() 
                            {
                                button.disabled = false;
                            }, 3200);
                        }
                    })();
                ");

                // ATUALIZAR DIA DA SEMANA
                if (!empty($object->horario_inicial)) 
                {
                    $data_obj = self::parseDateTime($object->horario_inicial);
                    if ($data_obj) 
                    {
                        $dia_semana = self::getDiaSemanaFormatado($data_obj);

                        // USAR JAVASCRIPT PARA ATUALIZAR
                        $dia_semana_escaped = addslashes($dia_semana);
                        TScript::create("
                            setTimeout(function() 
                            {
                                \$('[name=\"vdiadasemana01\"]').val('{$dia_semana_escaped}');
                            }, 100);
                        ");
                    }
                }

                // Após fechar transação, disparar eventos para carregar dados dependentes
                TScript::create("
                    $(document).ready(function() 
                    {
                        // Disparar eventos para carregar dados dependentes
                        if ($('#fornecedor_id').val()) 
                        {
                            $('#fornecedor_id').trigger('change');
                        }

                        if ($('#guia_conveniocab_id').val()) 
                        {
                            setTimeout(function() 
                            {
                                $('#guia_conveniocab_id').trigger('change');
                            }, 800);
                        }

                        // Atualizar labels de obrigatoriedade das guias
                        setTimeout(function() 
                        {
                            if ($('#guia_conveniocab_id').val()) 
                            {
                                $('label:contains(\"GUIA DE ATENDIMENTO:\")').html('<font size=\"4\" class=\"bolded\" color=\"red\">*</font>GUIA DE ATENDIMENTO:');
                                $('label:contains(\"GUIA AUXILIAR:\")').html('<font size=\"4\" class=\"bolded\" color=\"red\">*</font>GUIA AUXILIAR:');
                            }
                        }, 1000);
                    });
                ");  

                TTransaction::close();
            }
            else
            {
                self::$editando_registro = false;
                self::$objeto_original   = null;
                $this->form->clear();
            }
        }
        catch (Exception $e) // in case of exception
        {
            self::$editando_registro = false;
            self::$objeto_original   = null;
            new TMessage('error', '<b>' . TSession::getValue('username') . '</b> - Erro ao carregar registro: ' . $e->getMessage());
            TTransaction::rollback(); // undo all pending operations
        }

framework utilizado adianti versão 7.4
refatorar para corrigir o erro que ao ter algum campo obrigatorio se estiver em modo de edição os campos e botoes estão ficando desabilitados apos o erro do campo
segue debug - DEBUG onSave - Campos recebidos: id: 1826 fornecedor_id: VAZIO produto_id: 152 guia_conveniocab_id: 84 guia_auxiliar_id: 287 entrega_resultado: EU paciente_id: 265 profissional_id: 4 cobranca_id: 10006
o campo fornecedor_id tem valor na tabela e nao esta sendo carregado

class AgendamentoCalendarForm02 extends TWindow
{
    protected BootstrapFormBuilder $form;
    private $formFields = [];
    private static $database = 'bdgestorweb';
    private static $activeRecord = 'Agendamento';
    private static $primaryKey = 'id';
    private static $formName = 'form_AgendamentoForm';

    //<classProperties>

//Aqui pode incluir---------------------------------------------------------------------
    private static $bloqueando_profissional     = false;
    private static $profissional_id_bloqueado   = null;
    private static $bloqueando_produto_id       = false;
    private static $produto_id_preservado       = null;
    private static $bloqueando_eventos_paciente = false;
    private static $editando_registro           = false;
    private static $objeto_original             = null;
    private static $bloqueando_todos_eventos    = false;  // NOVO: Flag global mais agressiva
    private static $valores_form_cache          = [];
    private static $processando_validacao       = false;

//--------------------------------------------------------------------------------------

    //</classProperties>

    /**
     * Form constructor
     * @param $param Request
     */
    public function __construct( $param )
    {
        parent::__construct();
        parent::setSize(0.80, null);
        parent::setTitle("Agendamento");
        parent::setProperty('class', 'window_modal');

        if(!empty($param['target_container']))
        {
            $this->adianti_target_container = $param['target_container'];
        }

        // creates the form
        $this->form = new BootstrapFormBuilder(self::$formName);
        // define the form title
        $this->form->setFormTitle("Agendamento");

        $criteria_empresa_id = new TCriteria();
        $criteria_paciente_id = new TCriteria();
        $criteria_profissional_id = new TCriteria();
        $criteria_ambiente_id = new TCriteria();
        $criteria_cobranca_id = new TCriteria();
        $criteria_usuario_inclusao = new TCriteria();
        $criteria_usuario_alteracao = new TCriteria();
        $criteria_usuario_cancelamento = new TCriteria();

        $filterVar = "F";
        $criteria_paciente_id->add(new TFilter('tipo_pessoa', '=', $filterVar)); 
        $filterVar = "S";
        $criteria_profissional_id->add(new TFilter('profissionaldesaude', '=', $filterVar)); 

        //<onBeginPageCreation>

//Aqui pode incluir---------------------------------------------------------------------
/*
        $close_action = new TAction([$this, 'onBeforeClose']);
        $close_action->setParameter('id', parent::getId());
        parent::setCloseAction($close_action);
*/
//--------------------------------------------------------------------------------------

        //</onBeginPageCreation>

        $paciente_foto = new TImage('app/images/');
        $btn_confirmar = new TButton('btn_confirmar');
        $btn_desmarcar = new TButton('btn_desmarcar');
        $btn_naocompareceu = new TButton('btn_naocompareceu');
        $btn_recepcao = new TButton('btn_recepcao');
        $btn_finalizar = new TButton('btn_finalizar');
        $btn_retorno = new TButton('btn_retorno');
        $btn_duplicar = new TButton('btn_duplicar');
        $btn_cancelar = new TButton('btn_cancelar');
        $btn_protocoloepreparo = new TButton('btn_protocoloepreparo');
        $id = new TEntry('id');
        $horario_inicial = new TDateTime('horario_inicial');
        $horario_final = new TDateTime('horario_final');
        $vdiadasemana01 = new TEntry('vdiadasemana01');
        $btn_calcularnovadataagendamento = new TButton('btn_calcularnovadataagendamento');
        $bhelper_calculanovadatadeagendamento = new BHelper();
        $empresa_id = new TDBUniqueSearch('empresa_id', 'bdgestorweb', 'SystemUnit', 'id', 'name','name asc' , $criteria_empresa_id );
        $btn_atualizardadospaciente = new TButton('btn_atualizardadospaciente');
        $btn_pacientenovo = new TButton('btn_pacientenovo');
        $btn_verificafinanceiro = new TButton('btn_verificafinanceiro');
        $label_msg01 = new TLabel(".", '#F44336', '12px', null);
        $paciente_id = new TDBUniqueSearch('paciente_id', 'bdgestorweb', 'Pessoa', 'id', 'nome','nome asc' , $criteria_paciente_id );
        $from_page = new THidden('from_page');
        $profissional_id = new TDBCombo('profissional_id', 'bdgestorweb', 'SystemUsers', 'id', '{name}','name asc' , $criteria_profissional_id );
        $encaminhamento = new TEntry('encaminhamento');
        $fornecedor_id = new TCombo('fornecedor_id');
        $btn_copiarnumeocarterinha = new TButton('btn_copiarnumeocarterinha');
        $bhelper_6908b4309ea28 = new BHelper();
        $produto_id = new TCombo('produto_id');
        $bhelper_entregaresultado = new BHelper();
        $entrega_resultado = new TCombo('entrega_resultado');
        $label_guia_atendimento = new TLabel("GUIA DE ATENDIMENTO:", null, '12px', null);
        $bhelper_guia = new BHelper();
        $guia_conveniocab_id = new TCombo('guia_conveniocab_id');
        $label_guia_auxiliar = new TLabel("GUIA AUXILIAR:", null, '12px', null);
        $guia_auxiliar_id = new TCombo('guia_auxiliar_id');
        $labelstatus = new TLabel("STATUS:", '#F44336', '12px', null, '100%');
        $status = new TCombo('status');
        $consulta_retorno = new TCombo('consulta_retorno');
        $geraroutro_retorno = new TCombo('geraroutro_retorno');
        $bhelper_69546025b5266 = new BHelper();
        $labelcancelado = new TLabel("CANCELADO:", '#F44336', '12px', null, '100%');
        $cancelado = new TCombo('cancelado');
        $labelagendamentoanterior = new TLabel("AGENDAMENTO NOVO / ANTERIOR:", '#F44336', '12px', null, '100%');
        $agendamento_novo = new TEntry('agendamento_novo');
        $agendamento_anterior = new TEntry('agendamento_anterior');
        $ordematendimento = new TSpinner('ordematendimento');
        $btn_atualizasaladeatendimento = new TButton('btn_atualizasaladeatendimento');
        $ambiente_id = new TDBCombo('ambiente_id', 'bdgestorweb', 'Ambiente', 'id', '{descambiente}','descambiente asc' , $criteria_ambiente_id );
        $bhelper_cobranca = new BHelper();
        $cobranca_id = new TDBCombo('cobranca_id', 'bdgestorweb', 'Cobranca', 'id', '{desccobranca}','desccobranca asc' , $criteria_cobranca_id );
        $valor_venda = new TNumeric('valor_venda', '2', '.', ',' );
        $vvalor_taxaentregaexame = new THidden('vvalor_taxaentregaexame');
        $vvalor_venda = new THidden('vvalor_venda');
        $valor_taxaentregaexame = new TNumeric('valor_taxaentregaexame', '2', '.', ',' );
        $percentual_desconto_maximo = new TNumeric('percentual_desconto_maximo', '2', '.', ',' );
        $percentual_desconto_utilizado = new TNumeric('percentual_desconto_utilizado', '2', '.', ',' );
        $valor_receber = new TNumeric('valor_receber', '2', '.', ',' );
        $btn_atualizavalores = new TButton('btn_atualizavalores');
        $observacao = new THtmlEditor('observacao');
        $data_inclusao = new TDate('data_inclusao');
        $hora_inclusao = new TTime('hora_inclusao');
        $usuario_inclusao = new TDBCombo('usuario_inclusao', 'bdgestorweb', 'SystemUsers', 'id', '{name}','name asc' , $criteria_usuario_inclusao );
        $data_alteracao = new TDate('data_alteracao');
        $hora_alteracao = new TTime('hora_alteracao');
        $usuario_alteracao = new TDBCombo('usuario_alteracao', 'bdgestorweb', 'SystemUsers', 'id', '{name}','name asc' , $criteria_usuario_alteracao );
        $data_cancelamento = new TDate('data_cancelamento');
        $hora_cancelamento = new TTime('hora_cancelamento');
        $usuario_cancelamento = new TDBCombo('usuario_cancelamento', 'bdgestorweb', 'SystemUsers', 'id', '{name}','name asc' , $criteria_usuario_cancelamento );
        $motivo_cancelamento = new TEntry('motivo_cancelamento');

        $paciente_id->setChangeAction(new TAction([$this,'onexitpaciente']));
        $profissional_id->setChangeAction(new TAction([$this,'onexitprofissional']));
        $fornecedor_id->setChangeAction(new TAction([$this,'onexitconvenioparceria']));
        $produto_id->setChangeAction(new TAction([$this,'onexitprocedimentorealizado']));
        $entrega_resultado->setChangeAction(new TAction([$this,'onexittemetregaresultado']));
        $guia_conveniocab_id->setChangeAction(new TAction([$this,'onexitguiaprincipal']));

        $horario_inicial->setExitAction(new TAction([$this,'onexithorarioinicial']));
        $horario_final->setExitAction(new TAction([$this,'onexithorariofinal']));

        $encaminhamento->forceUpperCase();
        $ordematendimento->setRange(0, 2000, 1);
        $empresa_id->setMinLength(0);
        $paciente_id->setMinLength(0);

        $empresa_id->setFilterColumns(["id","name"]);
        $paciente_id->setFilterColumns(["cnpj_cpf","fantasia_apelido","id","nome"]);

        $encaminhamento->setMaxLength(80);
        $motivo_cancelamento->setMaxLength(80);

        $status->setDefaultOption(false);
        $entrega_resultado->setDefaultOption(false);

        $label_msg01->setId("idlabel_msg01");
        $label_guia_auxiliar->setId("idlabel_guia_auxiliar");
        $label_guia_atendimento->setId("idlabel_guia_atendimento");

        $data_inclusao->setDatabaseMask('yyyy-mm-dd');
        $data_alteracao->setDatabaseMask('yyyy-mm-dd');
        $data_cancelamento->setDatabaseMask('yyyy-mm-dd');
        $horario_final->setDatabaseMask('yyyy-mm-dd hh:ii');
        $horario_inicial->setDatabaseMask('yyyy-mm-dd hh:ii');

        $cancelado->addItems(["S"=>"Sim","N"=>"Não"]);
        $consulta_retorno->addItems(["S"=>"Sim","N"=>"Não"]);
        $geraroutro_retorno->addItems(["S"=>"Sim","N"=>"Não"]);
        $entrega_resultado->addItems(["NE"=>"Não tem Exame","EN"=>"Entrega Normal","EU"=>"Entrega Urgente"]);
        $status->addItems(["01"=>"AGUARDANDO CONFIRMAÇÃO","02"=>"CONFIRMADO","03"=>"DESMARCOU","04"=>"NÃO COMPARECEU","12"=>"FINALIZADO","97"=>"RECEPÇÃO","98"=>"LISTA DE ESPERA"]);

        $valor_venda->setAllowNegative(false);
        $valor_receber->setAllowNegative(false);
        $valor_taxaentregaexame->setAllowNegative(false);
        $percentual_desconto_maximo->setAllowNegative(false);
        $percentual_desconto_utilizado->setAllowNegative(false);

        $bhelper_guia->enableHover();
        $bhelper_cobranca->enableHover();
        $bhelper_6908b4309ea28->enableHover();
        $bhelper_69546025b5266->enableHover();
        $bhelper_entregaresultado->enableHover();
        $bhelper_calculanovadatadeagendamento->enableHover();

        $bhelper_guia->setSide("auto");
        $bhelper_cobranca->setSide("auto");
        $bhelper_6908b4309ea28->setSide("auto");
        $bhelper_69546025b5266->setSide("left");
        $bhelper_entregaresultado->setSide("auto");
        $bhelper_calculanovadatadeagendamento->setSide("auto");

        $bhelper_guia->setIcon(new TImage("fas:question #fa931f"));
        $bhelper_cobranca->setIcon(new TImage("fas:question #fa931f"));
        $bhelper_6908b4309ea28->setIcon(new TImage("fas:question #fa931f"));
        $bhelper_69546025b5266->setIcon(new TImage("fas:question #fa931f"));
        $bhelper_entregaresultado->setIcon(new TImage("fas:question #fa931f"));
        $bhelper_calculanovadatadeagendamento->setIcon(new TImage("fas:question #fa931f"));

        $bhelper_guia->setTitle("Ajuda");
        $bhelper_cobranca->setTitle("Ajuda");
        $bhelper_6908b4309ea28->setTitle("Ajuda");
        $bhelper_69546025b5266->setTitle("Ajuda");
        $bhelper_entregaresultado->setTitle("Ajuda");
        $bhelper_calculanovadatadeagendamento->setTitle("Ajuda");

        $bhelper_69546025b5266->setContent("Havendo uma autorização do profissional de saúde, pode ser gerado um segundo retorno para o paciente.");
        $bhelper_entregaresultado->setContent("A entrega de resultado pode estar sujeito a cobrança de uma taxa, principalmente quando for classificado como Urgente, portanto verifique sempre esta questão com a sua Gerência antes de repassar alguma informação ao paciente. ");
        $bhelper_calculanovadatadeagendamento->setContent("Antes de utilizar este recurso, verifique o campo DATA E HORA INICIAL E DATA E HORA FINAL esteja preenchido de forma correta, depois informe a quantidade de dias para que o GestorWeb calcule a nova data para você:
<br>Exemplo: 30/08/2024 + 10 dias a nova data será 09/09/2024");
        $bhelper_6908b4309ea28->setContent("O GestorWeb, utiliza a seguinte regra para gerar o recebimento, primeiro ele verifica se o paciente em questão é de psicologia e se o mesmo é particular, se for particular o sistema assumi o valor que está cadastrado na aba 4) Sobre o paciente ->4.3) Serviços ->4.4.1) Psicologia campo “Valor de cada sessão”, se não será utilizado o valor definido no cadastrado do procedimento ligado ao convênio que for utilizado no processo do agendamento.");
        $bhelper_cobranca->setContent("Para facilitar o processo de cobrança de sua empresa, o GestorWeb criou um recurso onde o próprio usuário efetua o cadastro usando sua própria nomenclatura.
<br>Outro recurso é poder vincular uma cobrança no cadastro do paciente, para quando fizer um agendamento o sistema vai utilizar está cobrança como sugestão padrão, lembrando que pode ser trocada por qualquer outra cobrança.
<br>Exemplo: 
<br>Cartão de crédito empresa x 
<br>Cartão de débito empresa x");
        $bhelper_guia->setContent("O GestorWeb faz o controle das guias que são emitidas para o paciente, por exemplo se o atendimento for psicológico é comum o convênio emitir uma guia e nela conter a quantidade de sessões que foram liberadas para o atendimento. Para que este processo funcione corretamente, o primeiro passo é cadastrar a guia e depois gerar as sessões ou guias auxiliares como o GestoWeb chama e a cada agendamento realizado o sistema vai fazendo a utilização destas guias e deduzindo do saldo existente.
<br>Não esqueça de fazer a manutenção das guias.");

        $empresa_id->setMask('{id} - {name}');
        $data_inclusao->setMask('dd-mm-yyyy');
        $data_alteracao->setMask('dd-mm-yyyy');
        $data_cancelamento->setMask('dd-mm-yyyy');
        $horario_final->setMask('dd-mm-yyyy hh:ii');
        $horario_inicial->setMask('dd-mm-yyyy hh:ii');
        $paciente_id->setMask('{nome_cnpjcpf_idade_cor}');

        $cancelado->setValue('N');
        $consulta_retorno->setValue('N');
        $geraroutro_retorno->setValue('N');
        $hora_inclusao->setValue(date('H:i'));
        $data_inclusao->setValue(date('d-m-Y'));
        $empresa_id->setValue(TSession::getValue('userunitid'));
        $usuario_inclusao->setValue(TSession::getValue("userid"));

        $produto_id->enableSearch();
        $ambiente_id->enableSearch();
        $cobranca_id->enableSearch();
        $fornecedor_id->enableSearch();
        $profissional_id->enableSearch();
        $guia_auxiliar_id->enableSearch();
        $geraroutro_retorno->enableSearch();
        $guia_conveniocab_id->enableSearch();

        $valor_receber->setTip("Valor recebido");
        $percentual_desconto_maximo->setTip("Desconto autorizado");
        $percentual_desconto_utilizado->setTip("Desconto utilizado");
        $profissional_id->setTip("Selecione o profissional de saúde.");
        $horario_final->setTip("Selecione a data e hora final do atendimento");
        $ambiente_id->setTip("Informe a sala em que o paciente será atendido.");
        $horario_inicial->setTip("Selecione a data e hora inicial do atendimento");
        $fornecedor_id->setTip("Selecione o convênio que o paciente utilizará.");
        $empresa_id->setTip("Selecione em qual Empresa será feito o agendamento.");
        $produto_id->setTip("Selecione o procedimento que o paciente vai realizar.");
        $ordematendimento->setTip("Informe a ordem em que o paciente será atendido.");
        $encaminhamento->setTip("Informe aqui o nome do profissional que encaminhou o paciente.");
        $paciente_id->setTip("A pesquisa do paciente pode ser realizada por Nome, Apelido, CPF ou ID.");
        $guia_conveniocab_id->setTip("Selecione a guia de atendimento a ser utilizada no procedimento.");
        $guia_auxiliar_id->setTip("Ao selecionar uma guia de atendimento, o sistema lista as guias disponíveis para utilização, estas guias foram geradas de acordo com o saldo disponível na guia principal.");

        $btn_duplicar->setAction(new TAction([$this, 'btnduplicar']), "Duplicar");
        $btn_cancelar->setAction(new TAction([$this, 'btncancelar']), "Cancelar");
        $btn_recepcao->setAction(new TAction([$this, 'btnrecepcao']), "Recepção");
        $btn_confirmar->setAction(new TAction([$this, 'btnconfirmar']), "Confirmar");
        $btn_desmarcar->setAction(new TAction([$this, 'btndesmarcar']), "Desmarcar");
        $btn_finalizar->setAction(new TAction([$this, 'btnfinalizar']), "Finalizar");
        $btn_retorno->setAction(new TAction([$this, 'btnretornoconsulta']), "Retorno");
        $btn_atualizavalores->setAction(new TAction([$this, 'btnatualizavalores']), "");
        $btn_naocompareceu->setAction(new TAction([$this, 'btnnaocompareceu']), "Não compareceu");
        $btn_copiarnumeocarterinha->setAction(new TAction([$this, 'btncopiarnumeocarterinha']), "");
        $btn_protocoloepreparo->setAction(new TAction([$this, 'btnprotocoloepreparo']), "Preparo de exame");
        $btn_atualizasaladeatendimento->setAction(new TAction([$this, 'btnatualizasaladeatendimento']), "");
        $btn_verificafinanceiro->setAction(new TAction([$this, 'btnverificafinanceiro'],['static' => 1]), "");
        $btn_atualizardadospaciente->setAction(new TAction(['PessoaFormAtualizarDados01', 'onEditFromAgendamento']), "");
        $btn_calcularnovadataagendamento->setAction(new TAction([$this, 'btncalcularnovadataagendamento'],['campo_alterar' => 'horario_inicial']), "");
        $btn_pacientenovo->setAction(new TAction(['PessoaFormCadRapidoAgendamento01', 'onShow'],['campo' => 'paciente_id',"empresa_id" => "{empresa_id}"]), "");

        $btn_retorno->addStyleClass('btn-default');
        $btn_recepcao->addStyleClass('btn-default');
        $btn_duplicar->addStyleClass('btn-default');
        $btn_cancelar->addStyleClass('btn-default');
        $btn_confirmar->addStyleClass('btn-default');
        $btn_desmarcar->addStyleClass('btn-default');
        $btn_finalizar->addStyleClass('btn-default');
        $btn_pacientenovo->addStyleClass('btn-info');
        $btn_naocompareceu->addStyleClass('btn-default');
        $btn_atualizavalores->addStyleClass('btn-default');
        $btn_protocoloepreparo->addStyleClass('btn-default');
        $btn_verificafinanceiro->addStyleClass('btn-default');
        $btn_copiarnumeocarterinha->addStyleClass('btn-default');
        $btn_atualizardadospaciente->addStyleClass('btn-default');
        $btn_atualizasaladeatendimento->addStyleClass('btn-primary');
        $btn_calcularnovadataagendamento->addStyleClass('btn-default');

        $btn_desmarcar->setImage('fas:ban #FFFFFF');
        $btn_retorno->setImage('fas:times #FFFFFF');
        $btn_duplicar->setImage('far:clone #FFFFFF');
        $btn_finalizar->setImage('fas:check #FFFFFF');
        $btn_pacientenovo->setImage('fas:plus #FFFFFF');
        $btn_naocompareceu->setImage('fas:times #FFFFFF');
        $btn_cancelar->setImage('far:window-close #FFFFFF');
        $btn_confirmar->setImage('far:address-book #FFFFFF');
        $btn_protocoloepreparo->setImage('fas:print #FFFFFF');
        $btn_recepcao->setImage('fas:file-medical-alt #FFFFFF');
        $btn_copiarnumeocarterinha->setImage('far:copy #000000');
        $btn_atualizavalores->setImage('fas:calculator #2196F3');
        $btn_atualizardadospaciente->setImage('far:edit #000000');
        $btn_verificafinanceiro->setImage('far:money-bill-alt #F44336');
        $btn_atualizasaladeatendimento->setImage('fas:border-style #FFFFFF');
        $btn_calcularnovadataagendamento->setImage('fas:calendar-plus #03A9F4');

        $id->setEditable(false);
        $status->setEditable(false);
        $cancelado->setEditable(false);
        $valor_venda->setEditable(false);
        $data_inclusao->setEditable(false);
        $hora_inclusao->setEditable(false);
        $vdiadasemana01->setEditable(false);
        $data_alteracao->setEditable(false);
        $hora_alteracao->setEditable(false);
        $consulta_retorno->setEditable(false);
        $agendamento_novo->setEditable(false);
        $usuario_inclusao->setEditable(false);
        $usuario_alteracao->setEditable(false);
        $data_cancelamento->setEditable(false);
        $hora_cancelamento->setEditable(false);
        $geraroutro_retorno->setEditable(false);
        $motivo_cancelamento->setEditable(false);
        $agendamento_anterior->setEditable(false);
        $usuario_cancelamento->setEditable(false);
        $valor_taxaentregaexame->setEditable(false);
        $percentual_desconto_maximo->setEditable(false);

        $id->setSize('100%');
        $from_page->setSize(200);
        $status->setSize('100%');
        $empresa_id->setSize('98%');
        $cancelado->setSize('100%');
        $vvalor_venda->setSize(200);
        $paciente_id->setSize('99%');
        $produto_id->setSize('100%');
        $bhelper_guia->setSize('12');
        $valor_venda->setSize('80%');
        $data_inclusao->setSize(130);
        $hora_inclusao->setSize(130);
        $ambiente_id->setSize('100%');
        $cobranca_id->setSize('100%');
        $data_alteracao->setSize(130);
        $hora_alteracao->setSize(130);
        $horario_final->setSize('30%');
        $fornecedor_id->setSize('93%');
        $valor_receber->setSize('70%');
        $vdiadasemana01->setSize('35%');
        $horario_inicial->setSize('85%');
        $encaminhamento->setSize('100%');
        $bhelper_cobranca->setSize('12');
        $data_cancelamento->setSize(130);
        $hora_cancelamento->setSize(130);
        $profissional_id->setSize('100%');
        $consulta_retorno->setSize('40%');
        $agendamento_novo->setSize('45%');
        $ordematendimento->setSize('50%');
        $observacao->setSize('100%', 200);
        $guia_auxiliar_id->setSize('100%');
        $usuario_inclusao->setSize('100%');
        $entrega_resultado->setSize('100%');
        $geraroutro_retorno->setSize('40%');
        $usuario_alteracao->setSize('100%');
        $bhelper_6908b4309ea28->setSize('12');
        $guia_conveniocab_id->setSize('100%');
        $bhelper_69546025b5266->setSize('12');
        $agendamento_anterior->setSize('45%');
        $motivo_cancelamento->setSize('100%');
        $vvalor_taxaentregaexame->setSize(200);
        $usuario_cancelamento->setSize('100%');
        $valor_taxaentregaexame->setSize('78%');
        $bhelper_entregaresultado->setSize('12');
        $percentual_desconto_maximo->setSize('38%');
        $percentual_desconto_utilizado->setSize('38%');
        $bhelper_calculanovadatadeagendamento->setSize('12');

        $paciente_foto->width = '110px';
        $paciente_foto->height = '110px';
        $paciente_foto->id = 'foto-paciente';
        $btn_verificafinanceiro->id = 'idbtn_verificafinanceiro';
        $btn_copiarnumeocarterinha->id = 'idbtn_copiarnumeocarterinha';
        $btn_calcularnovadataagendamento->id = 'idbtn_calcularnovadata';
        $btn_atualizardadospaciente->id = 'idbtn_atualizardadospaciente';

        $this->paciente_foto = $paciente_foto;

        //<onBeforeAddFieldsToForm>

//Aqui pode incluir---------------------------------------------------------------------
        $modo_form = new THidden('modo_form');
        $this->form->addField($modo_form);
//--------------------------------------------------------------------------------------

        //</onBeforeAddFieldsToForm>

        $this->form->appendPage("Principal");

        $this->form->addFields([new THidden('current_tab')]);
        $this->form->setTabFunction("$('[name=current_tab]').val($(this).attr('data-current_page'));");

        $bcontainer_foto = new BContainer('bcontainer_foto');
        $this->bcontainer_foto = $bcontainer_foto;

        $bcontainer_foto->setTitle("FOTO", '#3F51B5', '12px', '', '#fff');
        $bcontainer_foto->setBorderColor('#c0c0c0');

        $row1 = $bcontainer_foto->addFields([$paciente_foto]);
        $row1->layout = [''];

        $bcontainer_acoes02 = new BContainer('bcontainer_acoes02');
        $this->bcontainer_acoes02 = $bcontainer_acoes02;

        $bcontainer_acoes02->setTitle("AÇÕES DO AGENDAMENTO", '#000000', '12px', '', '#fff');
        $bcontainer_acoes02->setBorderColor('#c0c0c0');

        $row2 = $bcontainer_acoes02->addFields([$btn_confirmar,$btn_desmarcar,$btn_naocompareceu,$btn_recepcao,$btn_finalizar,$btn_retorno,$btn_duplicar,$btn_cancelar,$btn_protocoloepreparo]);
        $row2->layout = [' col-sm-12  acoes'];

        $bcontainer_datagendamento = new BContainer('bcontainer_datagendamento');
        $this->bcontainer_datagendamento = $bcontainer_datagendamento;

        $bcontainer_datagendamento->setTitle("AGENDAMENTO", '#2196F3', '12px', '', '#fff');
        $bcontainer_datagendamento->setBorderColor('#c0c0c0');

        $row3 = $bcontainer_datagendamento->addFields([new TLabel("<font size=\"4\" class=\"bolded\" color=\"red\">*</font>ID:", '#2196F3', '12px', null, '100%'),$id],[new TLabel("<font size=\"4\" class=\"bolded\" color=\"red\">*</font>DATA E HORA INICIAL:", '#2196F3', '12px', null, '100%'),$horario_inicial],[new TLabel("<font size=\"4\" class=\"bolded\" color=\"red\">*</font>DATA E HORA FINAL:", '#2196F3', '12px', null, '100%'),$horario_final,$vdiadasemana01,$btn_calcularnovadataagendamento,$bhelper_calculanovadatadeagendamento]);
        $row3->layout = ['col-sm-3',' col-sm-3',' col-sm-6'];

        $row4 = $bcontainer_datagendamento->addFields([new TLabel("<font size=\"4\" class=\"bolded\" color=\"red\">*</font>EMPRESA:", '#2196F3', '12px', null, '100%'),$empresa_id]);
        $row4->layout = [' col-sm-12'];

        $row5 = $bcontainer_datagendamento->addFields([new TLabel("<font size=\"4\" class=\"bolded\" color=\"red\">*</font>PACIENTE:", '#2196F3', '12px', null),$btn_atualizardadospaciente,$btn_pacientenovo,$btn_verificafinanceiro,$label_msg01,$paciente_id,$from_page]);
        $row5->layout = [' col-sm-12'];

        $bcontainer_68f26d135ea90 = new BContainer('bcontainer_68f26d135ea90');
        $this->bcontainer_68f26d135ea90 = $bcontainer_68f26d135ea90;

        $bcontainer_68f26d135ea90->setTitle("PROFISSIONAL DE SAÚDE E ENCAMINHADO POR", '#3F51B5', '12px', '', '#fff');
        $bcontainer_68f26d135ea90->setBorderColor('#c0c0c0');

        $row6 = $bcontainer_68f26d135ea90->addFields([new TLabel("<font size=\"4\" class=\"bolded\" color=\"red\">*</font>PROFISSIONAL DE SAÚDE:", '#3F51B5', '12px', null, '100%'),$profissional_id]);
        $row6->layout = [' col-sm-12'];

        $row7 = $bcontainer_68f26d135ea90->addFields([new TLabel("ENCAMINHADO POR:", '#3F51B5', '12px', null, '100%'),$encaminhamento]);
        $row7->layout = [' col-sm-6 col-xl-12'];

        $bcontainer_procedimento = new BContainer('bcontainer_procedimento');
        $this->bcontainer_procedimento = $bcontainer_procedimento;

        $bcontainer_procedimento->setTitle("CONVÊNIO E GUIA DE ATENDIMENTO", '#333', '12px', '', '#fff');
        $bcontainer_procedimento->setBorderColor('#c0c0c0');

        $row8 = $bcontainer_procedimento->addFields([new TLabel("<font size=\"4\" class=\"bolded\" color=\"red\">*</font>CONVÊNIO:", null, '12px', null),$fornecedor_id,$btn_copiarnumeocarterinha],[new TLabel("<font size=\"4\" class=\"bolded\" color=\"red\">*</font>PROCEDIMENTO A SER REALIZADO:", null, '12px', null),$bhelper_6908b4309ea28,$produto_id],[new TLabel("<font size=\"4\" class=\"bolded\" color=\"red\">*</font>RESULTADO DE EXAME:", '#000000', '12px', null),$bhelper_entregaresultado,$entrega_resultado]);
        $row8->layout = ['col-sm-12',' col-sm-9',' col-sm-3'];

        $row9 = $bcontainer_procedimento->addFields([$label_guia_atendimento,$bhelper_guia,$guia_conveniocab_id],[$label_guia_auxiliar,$guia_auxiliar_id]);
        $row9->layout = [' col-sm-12',' col-sm-12'];

        $bcontainer_68f262140c722 = new BContainer('bcontainer_68f262140c722');
        $this->bcontainer_68f262140c722 = $bcontainer_68f262140c722;

        $bcontainer_68f262140c722->setTitle("OUTRAS INFORMAÇÕES", '#F44336', '12px', '', '#fff');
        $bcontainer_68f262140c722->setBorderColor('#c0c0c0');

        $row10 = $bcontainer_68f262140c722->addFields([$labelstatus,$status]);
        $row10->layout = [' col-sm-12'];

        $row11 = $bcontainer_68f262140c722->addFields([new TLabel("RETORNO / PERMITIR GERAR OUTRO RETORNO:", '#F44336', '12px', null, '100%'),$consulta_retorno,new TLabel("/", null, '14px', null),$geraroutro_retorno,$bhelper_69546025b5266]);
        $row11->layout = [' col-sm-12'];

        $row12 = $bcontainer_68f262140c722->addFields([$labelcancelado,$cancelado]);
        $row12->layout = [' col-sm-12'];

        $row13 = $bcontainer_68f262140c722->addFields([$labelagendamentoanterior,$agendamento_novo,new TLabel("/", null, '14px', null),$agendamento_anterior]);
        $row13->layout = [' col-sm-12'];

        $row14 = $bcontainer_68f262140c722->addFields([new TLabel("ORDEM E SALA DE ATENDIMENTO:", '#F44336', '12px', null, '100%'),$ordematendimento,$btn_atualizasaladeatendimento,$ambiente_id]);
        $row14->layout = [' col-sm-12'];

        $bcontainer_68c82038fc2d3 = new BContainer('bcontainer_68c82038fc2d3');
        $this->bcontainer_68c82038fc2d3 = $bcontainer_68c82038fc2d3;

        $bcontainer_68c82038fc2d3->setTitle("FINANCEIRO", '#228B22', '12px', '', '#fff');
        $bcontainer_68c82038fc2d3->setBorderColor('#c0c0c0');

        $row15 = $bcontainer_68c82038fc2d3->addFields([new TLabel("<font size=\"4\" class=\"bolded\" color=\"red\">*</font>COBRANÇA UTILIZADA:", '#228B22', '12px', null),$bhelper_cobranca,$cobranca_id],[new TLabel("VALOR DO PROCEDIMENTO:", '#228B22', '12px', null, '100%'),$valor_venda,$vvalor_taxaentregaexame,$vvalor_venda,new TLabel("RESULTADO DE EXAME - TAXA DE ENTREGA URGENTE:", '#228B22', '12px', null, '100%'),$valor_taxaentregaexame],[new TLabel("DESCONTO AUTORIZADO / UTILIZADO:", '#228B22', '12px', null, '100%'),$percentual_desconto_maximo,new TLabel("%", null, '14px', null),$percentual_desconto_utilizado,new TLabel("%", null, '14px', null),new TLabel("<font size=\"4\" class=\"bolded\" color=\"red\">*</font>VALOR A RECEBER:", '#228B22', '12px', null, '100%'),$valor_receber,$btn_atualizavalores]);
        $row15->layout = [' col-sm-12',' col-sm-12',' col-sm-12'];

        $row16 = $this->form->addFields([$bcontainer_foto,$bcontainer_acoes02],[$bcontainer_datagendamento,$bcontainer_68f26d135ea90,$bcontainer_procedimento],[$bcontainer_68f262140c722,$bcontainer_68c82038fc2d3]);
        $row16->layout = ['col-sm-2','col-sm-7','col-sm-3'];

        $this->form->appendPage("Observação");
        $row17 = $this->form->addFields([$observacao]);
        $row17->layout = [' col-sm-12'];

        $this->form->appendPage("Histórico");
        $row18 = $this->form->addFields([new TLabel("Inclusão:", null, '14px', null, '100%'),$data_inclusao,new TLabel("/", null, '14px', null),$hora_inclusao],[new TLabel(".", null, '2px', null, '100%'),$usuario_inclusao],[new TLabel("Alteração:", null, '14px', null, '100%'),$data_alteracao,new TLabel("/", null, '14px', null),$hora_alteracao],[new TLabel(".", null, '2px', null, '100%'),$usuario_alteracao],[new TLabel("Cancelamento:", null, '14px', null, '100%'),$data_cancelamento,new TLabel("/", null, '14px', null),$hora_cancelamento],[new TLabel(".", null, '2px', null, '100%'),$usuario_cancelamento],[new TLabel("Motivo do cancelamento:", null, '14px', null, '100%'),$motivo_cancelamento]);
        $row18->layout = [' col-sm-3',' col-sm-9',' col-sm-3',' col-sm-9',' col-sm-3',' col-sm-9',' col-sm-12'];

        //<onAfterFieldsCreation>

//Aqui pode incluir---------------------------------------------------------------------

//--------------------------------------------------------------------------------------

        //</onAfterFieldsCreation>

        // create the form actions
        $btn_salvaragendamento = $this->form->addAction("Salvar", new TAction([$this, 'onSave']), 'fas:save #ffffff');
        $this->btn_salvaragendamento = $btn_salvaragendamento;
        $btn_salvaragendamento->addStyleClass('btn-primary'); 

        //<onAfterPageCreation>

// ADICIONE ESTA LINHA ABAIXO:
        $btn_salvaragendamento->id    = 'btn_salvar_agendamento';
        $btn_salvaragendamento->style = "pointer-events: none; opacity: 0.6; cursor: not-allowed;";        

//Aqui pode incluir---------------------------------------------------------------------

        if (true)
        {
            $btn_desmarcar->style ='display: none';
        }

        $btn_atualizasaladeatendimento->popover            = 'true';
        $btn_atualizasaladeatendimento->popside            = 'top';
        $btn_atualizasaladeatendimento->poptitle           = 'Ajuda';
        $btn_atualizasaladeatendimento->popcontent         = 'Atualiza a sala de atendimento do profissional.';

        $btn_recepcao->popover                             = 'true';
        $btn_recepcao->popside                             = 'left';
        $btn_recepcao->poptitle                            = 'Ajuda';
        $btn_recepcao->popcontent                          = 'Confirma a presença na recpção.';

        $btn_copiarnumeocarterinha->popover                = 'true';
        $btn_copiarnumeocarterinha->popside                = 'left';
        $btn_copiarnumeocarterinha->poptitle               = 'Ajuda';
        $btn_copiarnumeocarterinha->popcontent             = 'Copia o número da carterinha do paciente.';

        $btn_retorno->popover                              = 'true';
        $btn_retorno->popside                              = 'left';
        $btn_retorno->poptitle                             = 'Ajuda';
        $btn_retorno->popcontent                           = 'Marcar retorno.';

        $btn_calcularnovadataagendamento->popover          = 'true';
        $btn_calcularnovadataagendamento->popside          = 'top';
        $btn_calcularnovadataagendamento->poptitle         = 'Ajuda';
        $btn_calcularnovadataagendamento->popcontent       = 'Calcula uma nova data para o agendamento.';

        $btn_atualizardadospaciente->popover               = 'true';
        $btn_atualizardadospaciente->popside               = 'top';
        $btn_atualizardadospaciente->poptitle              = 'Ajuda';
        $btn_atualizardadospaciente->popcontent            = 'Atualiza os dados do paciente.';

        $btn_verificafinanceiro->popover                   = 'true';
        $btn_verificafinanceiro->popside                   = 'top';
        $btn_verificafinanceiro->poptitle                  = 'Ajuda';
        $btn_verificafinanceiro->popcontent                = 'Verifica o financeiro do paciente.';

        $btn_confirmar->popover                            = 'true';
        $btn_confirmar->popside                            = 'left';
        $btn_confirmar->poptitle                           = 'Ajuda';
        $btn_confirmar->popcontent                         = 'Confirma o agendamento.';

        $btn_naocompareceu->popover          	           = 'true';
        $btn_naocompareceu->popside                        = 'left';
        $btn_naocompareceu->poptitle                       = 'Ajuda';
        $btn_naocompareceu->popcontent                     = 'Não compareceu ao agendamento.';

        $btn_protocoloepreparo->popover                    = 'true';
        $btn_protocoloepreparo->popside                    = 'left';
        $btn_protocoloepreparo->poptitle                   = 'Ajuda';
        $btn_protocoloepreparo->popcontent                 = 'Imprimir preparo do exame.';

        $btn_pacientenovo->popover          	           = 'true';
        $btn_pacientenovo->popside                         = 'left';
        $btn_pacientenovo->poptitle                        = 'Ajuda';
        $btn_pacientenovo->popcontent                      = 'Cadastro simplificado de paciente.';

        $btn_finalizar->popover                            = 'true';
        $btn_finalizar->popside                            = 'left';
        $btn_finalizar->poptitle                           = 'Ajuda';
        $btn_finalizar->popcontent                         = 'Finaliza o atendimento.';

        $btn_duplicar->popover                             = 'true';
        $btn_duplicar->popside                             = 'left';
        $btn_duplicar->poptitle                            = 'Ajuda';
        $btn_duplicar->popcontent                          = 'Duplica o agendamento.';

        $btn_cancelar->popover                             = 'true';
        $btn_cancelar->popside                             = 'left';
        $btn_cancelar->poptitle                            = 'Ajuda';
        $btn_cancelar->popcontent                          = 'Cancela o agendamento.';

        $btn_atualizavalores->popover                      = 'true';
        $btn_atualizavalores->popside                      = 'top';
        $btn_atualizavalores->poptitle                     = 'Ajuda';
        $btn_atualizavalores->popcontent                   = 'Atualiza o valor recebido.';
//--------------------------------------------------------------------------------------
        //</onAfterPageCreation>

        parent::add($this->form);
    }

    public static function onexithorarioinicial($param = null) 
    {
        try 
        {
            // ⭐️ VALIDAR ENTRADA
            $horario_inicial_input = isset($param['horario_inicial']) ? trim($param['horario_inicial']) : null;
            $object_feedback       = new stdClass(); 

            // Se vazio, sair
            if (empty($horario_inicial_input)) 
            {
                $object_feedback->vdiadasemana01 = '';
                TForm::sendData(self::$formName, $object_feedback, false, 0);
                return;
            }

            // --- Guarda 2: Datas Padrão Inválidas ---
            $invalid_defaults = 
            [   
                '31-12-1899 00:00', 
                '31-12-1899 00:00:00', 
                '00-00-0000 00:00', 
                '00/00/0000 00:00'
            ];

            if (in_array($horario_inicial_input, $invalid_defaults)) 
            {
                $object_feedback->horario_inicial = '';
                $object_feedback->vdiadasemana01  = '';
                TForm::sendData(self::$formName, $object_feedback, false, 0);
                new TMessage('warning', '<b>' .TSession::getValue('username').  '</b>' .  " - A data e hora digitada está inválida ou incompleta.");
                return;
            }

            // --- Normalização e Validação da Data ---
            $data_obj = self::parseDateTime($horario_inicial_input);

            if (!$data_obj) 
            {
                $object_feedback->horario_inicial = '';
                $object_feedback->vdiadasemana01  = '';
                TForm::sendData(self::$formName, $object_feedback, false, 0);
                $input_seguro = htmlspecialchars($horario_inicial_input);
                new TMessage('warning',  '<b>' .TSession::getValue('username').  '</b>' . " - A data e hora digitada está inválida: <b>'{$input_seguro}'</b>.");
                return;
            }

            // Se a data inicial foi apenas data (sem hora), corrige o campo
            $horario_inicial_corrigido = $data_obj->format('d-m-Y H:i');
            $object_feedback->horario_inicial = $horario_inicial_corrigido;

            // ⭐️ OBTER DIA DA SEMANA ANTES DE QUALQUER COISA
            $dia_semana                      = self::getDiaSemanaFormatado($data_obj);
            $object_feedback->vdiadasemana01 = $dia_semana;

            // ⭐️ ENVIAR IMEDIATAMENTE - ANTES DE ABRIR TRANSAÇÃO
            TForm::sendData(self::$formName, $object_feedback, false, 0);

            TTransaction::open(self::$database);

            // --- Busca o Feriado ---
            $data_para_consulta = $data_obj->format('Y-m-d');
            $feriado            = Feriados::where('dataferiado', '=', $data_para_consulta)->first();

            if ($feriado && $feriado->permitiragendamento == 'N') 
            {
                $perm_str = ($feriado->permitiragendamento == 'S') ? 'Sim' : 'Não';
                $tipo_map = 
                [
                    'E' => 'Feriado Estadual', 
                    'M' => 'Feriado Municipal',
                    'N' => 'Feriado Nacional', 
                    'O' => 'Outros'
                ];
                $tipo_str       = $tipo_map[$feriado->tipodeferiado] ?? $feriado->tipodeferiado;
                $data_formatada = TDateTime::convertToMask($feriado->dataferiado, 'yyyy-mm-dd', 'dd-mm-yyyy');
                $userName       = TSession::getValue('username');

                $mensagem  = "<b>{$userName}</b><br>";
                $mensagem .= "<b style='color: red;'>A data {$data_formatada} possui restrição, verifique antes de continuar!</b><br>";
                $mensagem .= "<b>Descrição:</b> {$feriado->descricaoferiado}<br>";
                $mensagem .= "<b>Tipo:</b> {$tipo_str}<br>";
                $mensagem .= "<b>Permite agendamento:</b> {$perm_str}<br>";

                new TMessage('info', $mensagem);
            }

            TTransaction::close();

            //</autoCode>
        }
        catch (Exception $e) 
        {
            TTransaction::rollback();
            new TMessage('error', '<b>' .TSession::getValue('username').  '</b>' . $e->getMessage());
        }
    }

    public static function onexithorariofinal($param = null) 
    {
        try 
        {
            // ⭐️ VALIDAR ENTRADA
            $horario_inicial_input = isset($param['horario_inicial']) ? trim($param['horario_inicial']) : null;
            $horario_final_input   = isset($param['horario_final']) ? trim($param['horario_final']) : null;

            // Se vazio, sair
            $object_feedback       = new stdClass(); 
            if (empty($horario_final_input)) 
            {
                $object_feedback->vdiadasemana01 = '';
                TForm::sendData(self::$formName, $object_feedback, false, 0);
                return;
            }

            // --- Guarda 2: Datas Padrão Inválidas ---
            $invalid_defaults = 
            [   
                '31-12-1899 00:00', 
                '31-12-1899 00:00:00', 
                '00-00-0000 00:00', 
                '00/00/0000 00:00'
            ];

            if (in_array($horario_final_input, $invalid_defaults)) 
            {
                $object_feedback->horario_final  = '';
                $object_feedback->vdiadasemana01 = '';
                TForm::sendData(self::$formName, $object_feedback, false, 0);
                new TMessage('warning',  '<b>' .TSession::getValue('username').  '</b>' . " - A data e hora digitada está inválida ou incompleta.");
                return;
            }

            // --- Normalização e Validação da Data Final ---
            $data_obj_final = self::parseDateTime($horario_final_input);

            if (!$data_obj_final) 
            {
                $object_feedback->horario_final  = '';
                $object_feedback->vdiadasemana01 = '';
                TForm::sendData(self::$formName, $object_feedback, false, 0);
                $input_seguro = htmlspecialchars($horario_final_input);
                new TMessage('warning',  '<b>' .TSession::getValue('username').  '</b>' . " - A data e hora final digitada está inválida: <b>'{$input_seguro}'</b>.");
                return;
            }

            // Se a data final foi apenas data (sem hora), corrige o campo
            $horario_final_corrigido        = $data_obj_final->format('d-m-Y H:i');
            $object_feedback->horario_final = $horario_final_corrigido;

            // --- VALIDAÇÃO DA DATA INICIAL ---
            $data_obj_inicial = self::parseDateTime($horario_inicial_input);

            if (!$data_obj_inicial) 
            {
                $object_feedback->vdiadasemana01 = '';
                TForm::sendData(self::$formName, $object_feedback, false, 0);
                new TMessage('error',  '<b>' .TSession::getValue('username').  '</b>' . " - A data e hora inicial <b>'{$horario_inicial_input}'</b> está em um formato inválido.");
                return;
            }

            $inicial_seguro = htmlspecialchars($data_obj_inicial->format('d-m-Y H:i'));
            $final_seguro   = htmlspecialchars($horario_final_corrigido);

            // --- REGRA 1: DATA (DIA/MÊS/ANO) DEVE SER IGUAL ---
            $data_inicial_str = $data_obj_inicial->format('Y-m-d');
            $data_final_str   = $data_obj_final->format('Y-m-d');

            if ($data_inicial_str != $data_final_str)
            {
                $object_feedback->vdiadasemana01 = '';
                TForm::sendData(self::$formName, $object_feedback, false, 0);
                $mensagem  = '<b>' . TSession::getValue('username') . '</b><br>';
                $mensagem .= "Atenção: A data final <b>deve</b> ser igual à data inicial.<br>";
                $mensagem .= "Inicial: <b>{$inicial_seguro}</b> | Final: <b>{$final_seguro}</b><br>";
                $mensagem .= "<b style='color: red;'>As datas são diferentes!</b>";
                new TMessage('warning', $mensagem);
                return;
            }

            // --- REGRA 2: HORA FINAL DEVE SER MAIOR QUE A HORA INICIAL ---
            if ($data_obj_final <= $data_obj_inicial)
            {
                $object_feedback->vdiadasemana01 = '';
                TForm::sendData(self::$formName, $object_feedback, false, 0);
                $mensagem  = '<b>' . TSession::getValue('username') . '</b><br>';
                $mensagem .= "Atenção: A hora final <b>deve</b> ser maior que a hora inicial.<br>";
                $mensagem .= "Inicial: <b>{$inicial_seguro}</b> | Final: <b>{$final_seguro}</b><br>";
                $mensagem .= "<b style='color: red;'>A hora final está incorreta!</b>";
                new TMessage('warning', $mensagem);
                return;
            }

            TTransaction::open(self::$database);

            // ⭐️ OBTER DIA DA SEMANA
            $dia_semana                      = self::getDiaSemanaFormatado($data_obj_final);
            $object_feedback->vdiadasemana01 = $dia_semana;

            // ⭐️ ENVIAR IMEDIATAMENTE - ANTES DE BUSCAR FERIADO
            TForm::sendData(self::$formName, $object_feedback, false, 0);

            // --- Busca o Feriado ---
            $data_para_consulta = $data_obj_final->format('Y-m-d');
            $feriado            = Feriados::where('dataferiado', '=', $data_para_consulta)->first();

            if ($feriado && $feriado->permitiragendamento == 'N') 
            {
                $perm_str = ($feriado->permitiragendamento == 'S') ? 'Sim' : 'Não';
                $tipo_map =
                [
                    'E' => 'Feriado Estadual', 
                    'M' => 'Feriado Municipal',
                    'N' => 'Feriado Nacional', 
                    'O' => 'Outros'
                ];

                $tipo_str       = $tipo_map[$feriado->tipodeferiado] ?? $feriado->tipodeferiado;
                $data_formatada = TDateTime::convertToMask($feriado->dataferiado, 'yyyy-mm-dd', 'dd-mm-yyyy');
                $userName       = TSession::getValue('username');

                $mensagem  = "<b>{$userName}</b><br>";
                $mensagem .= "<b style='color: red;'>A data {$data_formatada} possui restrição, verifique antes de continuar!</b><br>";
                $mensagem .= "<b>Descrição:</b> {$feriado->descricaoferiado}<br>";
                $mensagem .= "<b>Tipo:</b> {$tipo_str}<br>";
                $mensagem .= "<b>Permite agendamento:</b> {$perm_str}<br>";

                new TMessage('info', $mensagem);
            }

            TTransaction::close();

            //</autoCode>
        }
        catch (Exception $e) 
        {
            TTransaction::rollback();
            new TMessage('error', '<b>' .TSession::getValue('username').  '</b>' . $e->getMessage());
        }
    }

    public static function onexitpaciente($param = null) 
    {

try
    {
        // ✅ VERIFICAÇÃO CHAVE: Se está editando, NÃO LIMPAR NADA
        if (!empty($param['id'])) 
        {
            // Está em modo EDIÇÃO - preservar todos os dados
            return;
        }

        // ✅ ESTÁ EM MODO INCLUSÃO - Continuar com lógica original

        if (self::$bloqueando_eventos_paciente) 
        {
            return;
        }

        $formName            = $param['_form_name']  ?? 'form_AgendamentoForm';
        $paciente_id         = $param['paciente_id'] ?? null;
        $foto_nao_disponivel = 'app/images/semfoto.png';        

        TTransaction::open(self::$database);
        TScript::create("(function(){var el = document.getElementById('idlabel_msg01');if (el){el.style.display = 'none';el.innerHTML  = '';}})();");

        if (!$paciente_id) 
        {
            TCombo::clearField($formName, 'fornecedor_id');
            TCombo::clearField($formName, 'profissional_id');
            TCombo::clearField($formName, 'cobranca_id');
            TCombo::clearField($formName, 'guia_conveniocab_id');
            TCombo::clearField($formName, 'guia_auxiliar_id');

            $obj_clear                                  = new stdClass();
            $obj_clear->valor_venda                     = null;
            $obj_clear->valor_taxaentregaexame          = null;
            $obj_clear->percentual_desconto_autorizado  = null;
            $obj_clear->percentual_desconto_utilizado   = null;
            $obj_clear->valor_receber                   = null;

            TForm::sendData($formName, $obj_clear, false, false);
            TTransaction::close();
            return;
        }

        $pessoa = Pessoa::find($paciente_id);
        if (!$pessoa) 
        {
            TTransaction::close();
            return;
        }

        $caminho_foto = (!empty($pessoa->caminho_foto)) ? $pessoa->caminho_foto : $foto_nao_disponivel;
        TScript::create("document.getElementById('foto-paciente').src = '" . str_replace("'", "\\'", $caminho_foto) . "';");

        $conn = TTransaction::get();
        $sql  = "SELECT id, name FROM system_users WHERE profissionaldesaude = 'S' ORDER BY name ASC";
        $stmt = $conn->prepare($sql);
        $stmt->execute();

        $profissionaisOptions = array();
        $profissional_padrao  = null;

        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) 
        {
            if (!empty($pessoa->profissional_id) && $row['id'] == $pessoa->profissional_id) 
            {
                $profissional_padrao = $row['id'];
            }
            $profissionaisOptions[$row['id']] = $row['name'];
        }

        TCombo::reload($formName, 'profissional_id', $profissionaisOptions);

        $profissional_atualmente_selecionado = $param['profissional_id'] ?? null;

        if (!empty($profissional_atualmente_selecionado) && 
            $profissional_atualmente_selecionado != $profissional_padrao) 
        {
            $obj_prof                  = new stdClass();
            $obj_prof->profissional_id = $profissional_atualmente_selecionado;
            TForm::sendData($formName, $obj_prof, false, false);

            TScript::create("
                setTimeout(function() 
                {
                    var campo = document.querySelector('[name=\"profissional_id\"]');
                    if (campo) 
                    {
                        campo.value = '" . $profissional_atualmente_selecionado . "';
                    }
                }, 1000);
            ");

            TSession::setValue('profissional_id_inclusao', $profissional_atualmente_selecionado);
        }
        else if ($profissional_padrao)
        {
            $obj_prof                  = new stdClass();
            $obj_prof->profissional_id = $profissional_padrao;
            TForm::sendData($formName, $obj_prof, false, false);
            TSession::setValue('profissional_id_inclusao', $profissional_padrao);

            TScript::create("
                setTimeout(function() 
                {
                    var campo = document.querySelector('[name=\"profissional_id\"]');
                    if (campo) {
                        campo.value = '" . $profissional_padrao . "';
                    }
                }, 100);");
        }

        if ($pessoa->cobranca_id) 
        {
            $cob     = Cobranca::find($pessoa->cobranca_id);
            $cobNome = $cob ? $cob->desccobranca : $pessoa->cobranca_id;

            TCombo::reload($formName, 'cobranca_id', array($pessoa->cobranca_id => $cobNome));

            $obj_cob              = new stdClass();
            $obj_cob->cobranca_id = $pessoa->cobranca_id;
            TForm::sendData($formName, $obj_cob, false, false);
        }
        else
        {
            TCombo::reload($formName, 'cobranca_id', array('' => ''));
        }

        $criteria = TCriteria::create(array('paciente_id' => $paciente_id));
        $criteria->add(new TFilter('status', '=', 'A'));
        TDBCombo::reloadFromModel(
            $formName, 
            'fornecedor_id', 
            'bdgestorweb', 
            'PessoaConvenioparceria', 
            'fornecedor_id', 
            '{fornecedor_id} {fornecedor->nome} - Carteirinha: {numero_carteirinha}', 
            'fornecedor_id asc', 
            $criteria, 
            TRUE
        );

        TCombo::reload($formName, 'produto_id',             array('' => 'Selecione um convênio'));
        TCombo::reload($formName, 'entrega_resultado',      array('' => 'Selecione primeiro o procedimento'));
        TField::disableField($formName, 'entrega_resultado');
        TCombo::reload($formName, 'guia_conveniocab_id',    array('' => 'Selecione um convênio'));
        TCombo::reload($formName, 'guia_auxiliar_id',       array('' => 'Selecione primeiro uma guia'));

        $obj_clear                                  = new stdClass();
        $obj_clear->valor_venda                     = null;
        $obj_clear->valor_taxaentregaexame          = null;
        $obj_clear->percentual_desconto_autorizado  = null;
        $obj_clear->percentual_desconto_utilizado   = null;
        $obj_clear->valor_receber                   = null;
        TForm::sendData($formName, $obj_clear, false, false);

        if(empty($param['id']))
        {
            TButton::enableField(self::$formName,  'btn_atualizardadospaciente');
            TButton::enableField(self::$formName,  'btn_verificafinanceiro');
            TButton::disableField(self::$formName, 'btn_pacientenovo');
        }

        self::verificarContasAbertas($paciente_id);

        TTransaction::close();
    }
    catch (Exception $e)
    {
        TTransaction::rollback();
        new TMessage('error', '<b>' . TSession::getValue('username') . '</b> ' . $e->getMessage());
    }

    }

    public static function onexitprofissional($param = null) 
    {
        try 
        {
            $novo_profissional_id = $param['profissional_id'] ?? null;
            $isInclusao           = empty($param['id']);

            if (self::$bloqueando_profissional || !$isInclusao) 
            {
                return;
            }

            if (empty($novo_profissional_id)) 
            {
                TSession::setValue('profissional_id_inclusao', null);
                return;
            }

            $profissional_anterior = TSession::getValue('profissional_id_inclusao');

            // CORREÇÃO: Se for a primeira seleção ou se houver troca, limpa os campos
            if (empty($profissional_anterior) || $profissional_anterior != $novo_profissional_id) 
            {
                self::$bloqueando_profissional = true;
                TSession::setValue('profissional_id_inclusao', $novo_profissional_id); // Atualiza a sessão com o novo profissional
                self::limparCamposDependentesProfissional($param);
                self::$bloqueando_profissional = false;
            }

            //</autoCode>
        }
        catch (Exception $e) 
        {
            TSession::setValue('processando_alteracao_profissional', null);
            new TMessage('error', '<b>' . TSession::getValue('username') . '</b> ' . $e->getMessage());            
        }
    }

    public static function onexitconvenioparceria($param = null) 
    {
        try 
        {
                //Permitido fazer inclusao de codigo/////////////////////////////////
                $formName       = $param['_form_name']          ?? 'form_AgendamentoForm';
                $fornecedor_id  = $param['fornecedor_id']       ?? $param['key'] ?? null;
                $empresa_id     = $param['empresa_id']          ?? null;
                $paciente_id    = $param['paciente_id']         ?? null;
                $guia_id        = $param['guia_conveniocab_id'] ?? null;
                $produto_id     = $param['produto_id']          ?? null;
                $isEdit         = !empty($param['id']);

                // ⚠️ PROTEÇÃO TOTAL: Se estiver editando E produto_id estiver preenchido, BLOQUEAR tudo
                if ($isEdit && !empty($produto_id)) 
                {
                    self::$bloqueando_produto_id = true;
                    self::$produto_id_preservado = $produto_id;

                    TTransaction::open(self::$database);
                    $conn = TTransaction::get();

                    // Buscar dados do produto
                    $sqlProduto = "SELECT 
                                    pfp.fornecedor_id,
                                    pfp.produto_id,
                                    p.descproduto,
                                    pfp.preco_venda,
                                    pfp.consulta_retorno AS vconsultaretorno
                                FROM produto_fornecedorpreco pfp
                                INNER JOIN produto p ON p.id = pfp.produto_id
                                WHERE pfp.produto_id = :produto_id
                                AND pfp.status = 'A'";

                    $stmt = $conn->prepare($sqlProduto);
                    $stmt->execute([':produto_id' => $produto_id]);
                    $row = $stmt->fetch(PDO::FETCH_ASSOC);

                    if ($row) 
                    {
                        $label = sprintf('%d %d %s | Valor: %.2f | Procedimento gera retorno: %s',
                                            $row['fornecedor_id'],
                                            $row['produto_id'],
                                            $row['descproduto'] ?? 'Sem nome',
                                            $row['preco_venda'] ?? 0,                                            
                                            $row['vconsultaretorno'] === 'S' ? 'Sim' : 'Não'
                                            );

                        TCombo::reload($formName, 'produto_id', [$produto_id => $label]);

                        // FORÇAR valor via JavaScript também
                        TScript::create("
                            setTimeout(function() 
                            {
                                var el = document.querySelector('[name=\"produto_id\"]');
                                if (el)
                                {
                                    el.value = '{$produto_id}';
                                    el.dispatchEvent(new Event('change', { bubbles: true }));
                                }
                            }, 100);
                        ");
                    }

                    TTransaction::close();
                    return; // SAI AQUI - NÃO EXECUTA NADA MAIS
                }

                TTransaction::open(self::$database);
                $conn = TTransaction::get();

                // INCLUSÃO: Comportamento normal
                if (!empty($fornecedor_id)) 
                {
                    $sqlProdutos = "SELECT 
                                            pfp.fornecedor_id,
                                            pfp.produto_id,
                                            p.descproduto,
                                            pfp.preco_venda,
                                            pfp.consulta_retorno AS vconsultaretorno
                                    FROM produto_fornecedorpreco pfp
                                    INNER JOIN produto p ON p.id = pfp.produto_id
                                    WHERE pfp.fornecedor_id      = :fornecedor_id
                                    AND pfp.status               = 'A'
                                    ORDER BY p.descproduto";

                    $stmt = $conn->prepare($sqlProdutos);
                    $stmt->execute([':fornecedor_id' => $fornecedor_id]);
                    $produtoOptions = [];

                    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) 
                    {
                        $label = sprintf('%d %d %s | Valor: %.2f | Procedimento gera retorno: %s',
                                            $row['fornecedor_id'],
                                            $row['produto_id'],
                                            $row['descproduto'] ?? 'Sem nome',
                                            $row['preco_venda'] ?? 0,                                            
                                            $row['vconsultaretorno'] === 'S' ? 'Sim' : 'Não'
                                            );

                        $produtoOptions[$row['produto_id']] = $label;
                    }

                    $produtoOptionsComBranco = ['' => ''] + $produtoOptions;
                    TCombo::reload($formName, 'produto_id', $produtoOptionsComBranco);
                    TField::clearField($formName, 'produto_id');
                } 
                else 
                {
                    TCombo::reload($formName, 'produto_id', ['' => '']);
                }

                // ========================================
                // 2. RECARREGAR GUIA COM CORES NO LABEL
                // ========================================

                if ($isEdit && $guia_id) 
                {
                    $guia = GuiasconvenioCab::find($guia_id);

                    if ($guia) 
                    {
                        // ?? OBTER DADOS DA GUIA
                        $label  = $guia->getLabelComFormatacao();
                        $status = $guia->getStatusVencimento();
                        $color  = $guia->getCorStatus();

                        // ?? CRIAR EMOJI BASEADO NA COR
                        $colorEmoji             = ($color == 'red') ? '🔴' : (($color == 'orange') ? '🟠' : '🔵');
                        $labelComIndicador      = $colorEmoji . ' ' . $label;

                        // ?? RECARREGAR COMBO COM OPÇÃO ÚNICA (A GUIA SELECIONADA)
                        TCombo::reload($formName, 'guia_conveniocab_id', [$guia_id => $labelComIndicador]);

                        // ?? GARANTIR QUE A GUIA PERMANEÇA SELECIONADA
                        TScript::create("
                            setTimeout(function() 
                            {
                                $('#guia_conveniocab_id').val('{$guia_id}').trigger('change');
                            }, 300);
                        ");
                    } 
                    else
                    {
                        TCombo::reload($formName, 'guia_conveniocab_id', ['' => 'Guia não encontrada']);
                    }

                    TTransaction::close();
                    return;
                }

                // ========================================
                // 3. RECARREGAR GUIAS NA INCLUSÃO
                // ========================================
                if (!$isEdit) 
                {
                    if (empty($empresa_id) || empty($paciente_id) || empty($fornecedor_id)) 
                    {
                        TCombo::reload($formName, 'guia_conveniocab_id', ['' => '']);
                        // ⭐ SE NENHUM DADO DE FILTRO ESTIVER COMPLETO, DEIXA O LABEL ORIGINAL (SEM OBRIGATORIEDADE)
                        TScript::create("$('label:contains(\"GUIA DE ATENDIMENTO:\")').html('GUIA DE ATENDIMENTO:');");
                        TScript::create("$('label:contains(\"GUIA AUXILIAR:\")').html('GUIA AUXILIAR:');");
                    } 
                    else 
                    {
                        // ⭐️ BUSCAR GUIAS
                        $guias = GuiasconvenioCab::where('empresa_id',   '=', $empresa_id)
                                                ->where('pessoa_id',     '=', $paciente_id)
                                                ->where('fornecedor_id', '=', $fornecedor_id)
                                                ->where('status',        '=', 'A')
                                                ->where('guia_saldo',    '>', 0)
                                                ->orderBy('data_vencimento', 'asc')
                                                ->load();

                        $guiaOptions = ['' => ''];

                        foreach ($guias as $guia) 
                        {
                            $label  = $guia->getLabelComFormatacao();
                            $status = $guia->getStatusVencimento();
                            $color  = $guia->getCorStatus();

                            // ⭐️ ADICIONAR INDICADOR VISUAL DA COR NO LABEL
                            $colorEmoji             = ($color == 'red') ? '🔴' : (($color == 'orange') ? '🟠' : '🔵');
                            $labelComIndicador      = $colorEmoji . ' ' . $label;
                            $guiaOptions[$guia->id] = $labelComIndicador;
                        }

                        // ⭐️ RECARREGAR COMBO COM EMOJIS (VISUAL)
                        TCombo::reload($formName, 'guia_conveniocab_id', $guiaOptions);

                        // ========================================
                        // ⭐ LÓGICA DE ALTERAÇÃO DO LABEL
                        // ========================================
                        if (count($guias) > 0)
                        {
                        // Se houver guias disponíveis, troca para o label obrigatório
                        TScript::create("$('label:contains(\"GUIA DE ATENDIMENTO:\")').html('<font size=\"4\" class=\"bolded\" color=\"red\">*</font>GUIA DE ATENDIMENTO:');");
                        TScript::create("$('label:contains(\"GUIA AUXILIAR:\")').html('<font size=\"4\" class=\"bolded\" color=\"red\">*</font>GUIA AUXILIAR:');");
                        }
                        else
                        {
                        // Se não houver guias disponíveis, retorna ao label original (não obrigatório)
                        TScript::create("$('label:contains(\"GUIA DE ATENDIMENTO:\")').html('GUIA DE ATENDIMENTO:');");
                        TScript::create("$('label:contains(\"GUIA AUXILIAR:\")').html('GUIA AUXILIAR:');");
                        }

                    }
                }

                TTransaction::close();

            //</autoCode>
        }
        catch (Exception $e)
        {
            try 
            {
                TTransaction::rollback();
                new TMessage('error', '<b>' . TSession::getValue('username') . '</b> ' . $e->getMessage());            
            } 
            catch (Exception $ex) 
            {
                // Silenciar erro de rollback
            }
        }
    }

    public static function onexitprocedimentorealizado($param = null) 
    {
        $formName = self::$formName;

        try 
        {
            // ?? NOVO: Se estamos em EDIÇÃO (tem ID), NÃO limpar valores
            $isEdicao = !empty($param['id']);

            if ($isEdicao) 
            {
                // Em edição: preservar valores originais e sair
                return;
            }

            // Apenas em INCLUSÃO continuar com a lógica original

            $object                                 = new stdClass;
            $object->valor_custo                    = null;
            $object->valor_venda                    = null;
            $object->valor_receber                  = null;            
            $object->valor_contratado               = null;
            $object->percentual_desconto_autorizado = null;
            $object->valor_taxaentregaexame         = null; 

            $items_entrega = 
            [
                '' => 'Selecione primeiro um convênio'
            ];

            TField::disableField($formName, 'entrega_resultado'); 

            TTransaction::open(self::$database);

            $campos_essenciais_ok = (isset($param['produto_id'])      && !empty($param['produto_id']))    &&
                                    (isset($param['paciente_id'])     && !empty($param['paciente_id']))   &&
                                    (isset($param['fornecedor_id'])   && !empty($param['fornecedor_id'])) &&
                                    (isset($param['empresa_id'])      && !empty($param['empresa_id']))    &&
                                    (isset($param['profissional_id']) && !empty($param['profissional_id']));

            if ($campos_essenciais_ok)
            {
                $paciente            = new Pessoa($param['paciente_id']);
                $profissional_id     = $param['profissional_id'];
                $usarValorContratado = ($paciente->paciente_psicologia          == 'S' &&             // Verifica se é psicologia e se o profissional_id bate
                                        $paciente->profissional_id              == $profissional_id &&
                                        !empty($paciente->valor_contratado)     && 
                                        $paciente->valor_contratado != 0);

                if ($usarValorContratado)
                {
                    // Usa o valor contratado quando as condições são atendidas
                    $object->valor_custo                    = $paciente->valor_contratado;
                    $object->valor_venda                    = $paciente->valor_contratado;
                    $object->valor_receber                  = null;
                    $object->valor_contratado               = $paciente->valor_contratado;
                    $object->percentual_desconto_maximo     = null;
                    $object->valor_taxaentregaexame         = null;
                }
                else 
                {
                    // Busca o preço do procedimento/produto
                    $produtoPreco = ProdutoFornecedorpreco::where('empresa_id',  '=', $param['empresa_id'])
                                                        ->where('fornecedor_id', '=', $param['fornecedor_id'])
                                                        ->where('produto_id',    '=', $param['produto_id'])
                                                        ->first();

                    if ($produtoPreco)
                    {
                        $object->valor_venda                = $produtoPreco->preco_venda;
                        $object->percentual_desconto_maximo = $produtoPreco->percentual_desconto_maximo;
                    }
                }

                // Popula o combo com os valores reais e habilita o campo
                $items_entrega = 
                [
                    'NE' => 'Não tem Exame',                    
                    'EN' => 'Entrega Normal',
                    'EU' => 'Entrega Urgente'
                ];

                TField::enableField($formName, 'entrega_resultado');
            }

            TTransaction::close();

            TForm::sendData($formName, $object, false, false);
            TCombo::reload($formName, 'entrega_resultado', $items_entrega, true);

            //</autoCode>
            //</autoCode>
        }
        catch (Exception $e) 
        {
            TTransaction::rollback();
            new TMessage('error', '<b>' . TSession::getValue('username') . '</b>' . $e->getMessage());

            // Limpa todos os campos de valor e retorna o combo para o estado inicial em caso de erro
            $object_error                                 = new stdClass;
            $object_error->valor_custo                    = null;
            $object_error->valor_venda                    = null;
            $object_error->valor_receber                  = null;            
            $object_error->valor_contratado               = null;
            $object_error->percentual_desconto_autorizado = null;
            $object_error->valor_taxaentregaexame         = null;
            TForm::sendData($formName, $object_error, false, false);

            // Limpa e esvazia o combo (estado inicial de erro/vazio)
            TCombo::reload($formName,       'entrega_resultado', ['' => 'Erro ao carregar'], true);
            TField::disableField($formName, 'entrega_resultado');
        }

    }

    public static function onexittemetregaresultado($param = null) 
    {
        try 
        {
            if (!empty($param['modo_form']) && $param['modo_form'] === 'edit')
            {
                return;
            }

            if (!empty($param['entrega_resultado']))
            {
                $obj = new stdClass();
                $valor_calculo_taxa = 0; // Variável auxiliar para o cálculo imediato

                if ($param['entrega_resultado'] === 'EU' && !empty($param['fornecedor_id']) && !empty($param['produto_id']))
                {
                    TTransaction::open(self::$database);

                    $produtoPreco = ProdutoFornecedorpreco::where('fornecedor_id',  '=', $param['fornecedor_id'])
                                                        ->where('produto_id',      '=', $param['produto_id'])
                                                        ->first();

                    if ($produtoPreco && $produtoPreco->valor_taxaentregaexame > 0)
                    {
                        $valor_calculo_taxa = $produtoPreco->valor_taxaentregaexame;
                    }

                    TTransaction::close();
                }

                $obj->valor_taxaentregaexame = $valor_calculo_taxa;

                // 1. Envia para o formulário (visuável para o usuário)
                TForm::sendData(self::$formName, $obj, false, false);

                // 2. ATUALIZA O $PARAM MANUALMENTE (essencial para o btnatualizavalores enxergar)
                $param['valor_taxaentregaexame'] = $valor_calculo_taxa;

                // 3. Agora chama o cálculo com o valor atualizado no array
                self::btnatualizavalores($param);
            }

            //</autoCode>
        }
        catch (Exception $e) 
        {
            TTransaction::rollback();
            new TMessage('error', '<b>' .TSession::getValue('username').  '</b>' . $e->getMessage());
        }
    }

    public static function onexitguiaprincipal($param = null) 
    {
        try 
        {
            // ❌ edição: NÃO processa
            if (!empty($param['modo_form']) && $param['modo_form'] === 'edit')
            {
                return;
            }

            // novo ou duplicado: processa
            //if (!empty($param['guia_conveniocab_id']))
            //{

                // 1. Início da transação
                TTransaction::open(self::$database);

                // 2. Verifica modo de operação e IDs
                $is_editing             = !empty($param['id']);
                $agendamento_id         = !empty($param['id'])                  ? $param['id'] : null;
                $guia_conveniocab_id    = !empty($param['guia_conveniocab_id']) ? $param['guia_conveniocab_id'] : null;
                $guia_auxiliar_id_salva = !empty($param['guia_auxiliar_id'])    ? $param['guia_auxiliar_id'] : null;

                // 3. Resgate dos valores salvos do banco para edição
                if ($is_editing && $agendamento_id) 
                {
                    $repo            = new TRepository('Agendamento');
                    $criteria        = new TCriteria;
                    $criteria->add(new TFilter('id', '=', $agendamento_id));
                    $agendamentos    = $repo->load($criteria);

                    if ($agendamentos) 
                    {
                        $agendamento = $agendamentos[0];
                        if (!empty($agendamento->guia_conveniocab_id)) 
                        {
                            $guia_conveniocab_id = $agendamento->guia_conveniocab_id;
                            TScript::create("document.getElementById('guia_conveniocab_id').value = '$guia_conveniocab_id';");
                        }

                        if (!empty($agendamento->guia_auxiliar_id)) 
                        {
                            $guia_auxiliar_id_salva = $agendamento->guia_auxiliar_id;
                        }
                    } 
                    else
                    {
                        throw new Exception("<br>Agendamento com ID $agendamento_id não encontrado.");
                    }
                }

                // 4. Bloqueio se guia_conveniocab_id estiver vazio
                if (empty($guia_conveniocab_id)) 
                {
                    if (!$is_editing) 
                    {
                        TScript::create("document.getElementById('guia_auxiliar_id').value = '';");
                    }
                    TTransaction::close();
                    return;
                }

                // 5. Verificação de guia vencida
                $guia = new GuiasconvenioCab($guia_conveniocab_id);
                if (empty($guia->id)) 
                {
                    throw new Exception("<br>Guia com ID $guia_conveniocab_id não encontrada.");
                }

                $data_vencimento = $guia->data_vencimento;
                $data_atual      = date('Y-m-d');
                $guia_vencida    = ($data_vencimento && $data_atual > $data_vencimento);
                $guia_convenio   = $guia->guia_convenio;
                $fornecedor_id   = $guia->fornecedor_id;

                // 5.1 Se guia vencida detectada em INCLUSÃO, rejeita
                if ($guia_vencida && !$is_editing) 
                {
                    TScript::create("document.getElementById('guia_auxiliar_id').value = '';");
                    TCombo::clearField(self::$formName, 'guia_auxiliar_id');
                    TTransaction::close();
                    new TMessage('warning',  '<b>' . TSession::getValue('username') . '</b>' . "<br>A guia " . $guia_convenio . " venceu em " . date('d-m-Y', strtotime($data_vencimento)) . ", e não pode mais ser utilizada em novos agendamentos.<br>
                    Utilize o modulo de guias e inative a mesma.");
                    return;
                }

                // 6. Montagem dos critérios de filtragem para guia_auxiliar_id
                $conn = TTransaction::get();

                if ($is_editing && $guia_auxiliar_id_salva) 
                {
                    // Em edição: carregar EXATAMENTE a guia auxiliar que estava salva
                    $sql = "SELECT 
                                gci.id,
                                gci.fornecedor_id,
                                gci.guia_conveniocab_id,
                                gci.guia_codigovalidacao,
                                gci.utilizado,
                                gcc.guia_convenio
                            FROM guiasconvenio_item gci
                            INNER JOIN guiasconvenio_cab gcc ON gcc.id = gci.guia_conveniocab_id
                            WHERE gci.id = :guia_auxiliar_id
                            ";

                    $stmt = $conn->prepare($sql);
                    $stmt->bindValue(':guia_auxiliar_id', $guia_auxiliar_id_salva, PDO::PARAM_INT);
                    $stmt->execute();
                    $row = $stmt->fetch(PDO::FETCH_OBJ);

                    $items = [];
                    if ($row) 
                    {
                        $label = sprintf(
                            '%d %d %d %s Status: %s',
                            $row->fornecedor_id,
                            $row->guia_conveniocab_id,
                            $row->id,
                            htmlspecialchars($row->guia_codigovalidacao ?? '—'),
                            ($row->utilizado === 'S') ? 'Utilizado' : 'Disponível'
                        );
                        $items[$row->id] = $label;
                    }

                    if (!empty($items)) 
                    {
                        TCombo::reload(self::$formName, 'guia_auxiliar_id', $items);

                        TScript::create("
                            setTimeout(function()
                            {
                                var selectElement = document.getElementById('guia_auxiliar_id');
                                if (selectElement) 
                                {
                                    selectElement.value = '{$guia_auxiliar_id_salva}';
                                    selectElement.dispatchEvent(new Event('change', { bubbles: true }));
                                }
                            }, 300);
                        ");
                    } 
                    else 
                    {
                        TCombo::reload(self::$formName, 'guia_auxiliar_id', ['' => 'Guia auxiliar não encontrada']);
                    }
                } 
                else 
                {
                    // Em inclusão: carregar guias não utilizadas
                    $sql = "SELECT 
                                gci.id,
                                gci.fornecedor_id,
                                gci.guia_conveniocab_id,
                                gci.guia_codigovalidacao,
                                gci.utilizado,
                                gcc.guia_convenio
                            FROM guiasconvenio_item gci
                            INNER JOIN guiasconvenio_cab gcc ON gcc.id = gci.guia_conveniocab_id
                            WHERE gci.guia_conveniocab_id = :guia_conveniocab_id
                            AND gci.utilizado = 'N'
                            ORDER BY gci.id ASC
                            ";

                    $stmt = $conn->prepare($sql);
                    $stmt->bindValue(':guia_conveniocab_id', $guia_conveniocab_id, PDO::PARAM_INT);
                    $stmt->execute();

                    $items = [];
                    while ($row = $stmt->fetch(PDO::FETCH_OBJ)) 
                    { //'Fornecedor: %d | Item: %d | Guia: %d | Código: %s | Status: %s',
                        $label = sprintf(
                            '%d %d %d %s Status: %s',
                            $row->fornecedor_id,
                            $row->guia_conveniocab_id,                    
                            $row->id,
                            htmlspecialchars($row->guia_codigovalidacao ?? '—'),
                            ($row->utilizado === 'S') ? 'Utilizado' : 'Disponível'
                        );
                        $items[$row->id] = $label;
                    }

                    if (!empty($items)) 
                    {
                        TCombo::reload(self::$formName, 'guia_auxiliar_id', $items);
                    } 
                    else 
                    {
                        TCombo::reload(self::$formName, 'guia_auxiliar_id', ['' => 'Nenhuma guia disponível']);
                    }
                }

                TTransaction::close();
            //}            
        }
        catch (Exception $e) 
        {
            TTransaction::rollback();
            new TMessage('error', '<b>' .TSession::getValue('username').  '</b>' . $e->getMessage());
        }
    }

    public static function btnconfirmar($param = null) 
    {
        try 
        {
            if (empty($param['id']))
            {
                throw new Exception('<br>ID do agendamento não foi fornecido.');
            }

            $agendamentoId = $param['id'];
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';

            TTransaction::open(self::$database);

            $agendamento = Agendamento::find($agendamentoId);

            if (!$agendamento)
            {
                TTransaction::close();
                throw new Exception('<br>Agendamento com ID ' . htmlspecialchars($agendamentoId) . ' não encontrado.');
            }

            // Buscar dados do paciente relacionado
            $pacienteName = 'N/A';
            if (!empty($agendamento->paciente_id))
            {
                $paciente = Pessoa::find($agendamento->paciente_id);
                if ($paciente)
                {
                    $pacienteName = htmlspecialchars($paciente->nome ?? 'N/A');
                }
            }

            TTransaction::close();

            $mensagem  = "<b>{$usuarioLogado}</b><br><br>";
            $mensagem .= "Deseja confirmar este agendamento?<br>";
            $mensagem .= "<b>Agendamento:</b> " . htmlspecialchars($agendamentoId) . "<br>";
            $mensagem .= "<b>Paciente:</b> {$pacienteName}<br>";

            new TQuestion(
                $mensagem,
                new TAction([__CLASS__, 'onconfirmaragendamentoYes'], $param), 
                new TAction([__CLASS__, 'onconfirmaragendamentoNo'], $param)
            );

            //</autoCode>
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

    public static function btndesmarcar($param = null) 
    {
        try 
        {
            $userName = TSession::getValue('username');

            new TQuestion
            ("<b>{$userName}</b><br>Deseja desmarcar este agendamento?",
                 new TAction([__CLASS__, 'ondesmarcaragendamentoYes'], $param), 
                 new TAction([__CLASS__, 'ondesmarcaragendamentoNo'], $param)
            );

            //</autoCode>
        }
        catch (Exception $e) 
        {
            $userName = TSession::getValue('username');
            new TMessage('error', "<b>{$userName}</b> - {$e->getMessage()}");
        }
    }

    public static function btnnaocompareceu($param = null) 
    {
        try 
        {
            if (empty($param['id']))
            {
                throw new Exception('<br>ID do agendamento não foi fornecido.');
            }

            $agendamentoId = $param['id'];
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';

            TTransaction::open(self::$database);

            $agendamento = Agendamento::find($agendamentoId);

            if (!$agendamento)
            {
                TTransaction::close();
                throw new Exception('<br>Agendamento com ID ' . htmlspecialchars($agendamentoId) . ' não encontrado.');
            }

            // Buscar dados do paciente relacionado
            $pacienteName = 'N/A';
            if (!empty($agendamento->paciente_id))
            {
                $paciente = Pessoa::find($agendamento->paciente_id);
                if ($paciente)
                {
                    $pacienteName = htmlspecialchars($paciente->nome ?? 'N/A');
                }
            }

            TTransaction::close();

            $mensagem  = "<b>{$usuarioLogado}</b><br><br>";
            $mensagem .= "Deseja confirmar que o paciente não comparaceu?<br>";
            $mensagem .= "<b>Agendamento:</b> " . htmlspecialchars($agendamentoId) . "<br>";
            $mensagem .= "<b>Paciente:</b> {$pacienteName}<br>";

            new TQuestion(
                $mensagem,
                 new TAction([__CLASS__, 'onnaocompareceuYes'], $param), 
                 new TAction([__CLASS__, 'onnaocompareceuNo'], $param)
            );
            //</autoCode>
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

    public static function btnrecepcao($param = null) 
    {
        try 
        {
            if (empty($param['id']))
            {
                throw new Exception('<br>ID do agendamento não foi fornecido.');
            }

            $agendamentoId = $param['id'];
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';

            TTransaction::open(self::$database);

            $agendamento = Agendamento::find($agendamentoId);

            if (!$agendamento)
            {
                TTransaction::close();
                throw new Exception('<br>Agendamento com ID ' . htmlspecialchars($agendamentoId) . ' não encontrado.');
            }

            // Buscar dados do paciente relacionado
            $pacienteName = 'N/A';
            if (!empty($agendamento->paciente_id))
            {
                $paciente = Pessoa::find($agendamento->paciente_id);
                if ($paciente)
                {
                    $pacienteName = htmlspecialchars($paciente->nome ?? 'N/A');
                }
            }

            TTransaction::close();

            $mensagem  = "<b>{$usuarioLogado}</b><br><br>";
            $mensagem .= "Deseja confirmar que o paciente está aguardando na recepção?<br>";
            $mensagem .= "<b>Agendamento:</b> " . htmlspecialchars($agendamentoId) . "<br>";
            $mensagem .= "<b>Paciente:</b> {$pacienteName}<br>";

            new TQuestion(
                $mensagem,
                 new TAction([__CLASS__, 'onconfirmarrecepcaoYes'], $param), 
                 new TAction([__CLASS__, 'onconfirmarrecepcaoNo'], $param)
            );

            //</autoCode>
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

    public static function btnfinalizar($param = null) 
    {
        try 
        {
            if (empty($param['id']))
            {
                throw new Exception('<br>ID do agendamento não foi fornecido.');
            }

            $agendamentoId = $param['id'];
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';

            TTransaction::open(self::$database);

            $agendamento = Agendamento::find($agendamentoId);

            if (!$agendamento)
            {
                TTransaction::close();
                throw new Exception('<br>Agendamento com ID ' . htmlspecialchars($agendamentoId) . ' não encontrado.');
            }

            // Buscar dados do paciente relacionado
            $pacienteName = 'N/A';
            if (!empty($agendamento->paciente_id))
            {
                $paciente = Pessoa::find($agendamento->paciente_id);
                if ($paciente)
                {
                    $pacienteName = htmlspecialchars($paciente->nome ?? 'N/A');
                }
            }

            TTransaction::close();

            $mensagem  = "<b>{$usuarioLogado}</b><br><br>";
            $mensagem .= "Deseja finalizar este agendamento?<br>";
            $mensagem .= "<span style='color: red; font-weight: bold;'>Após a execução não será mais possível reverter o status.</span><br>";            
            $mensagem .= "<b>Agendamento:</b> " . htmlspecialchars($agendamentoId) . "<br>";
            $mensagem .= "<b>Paciente:</b> {$pacienteName}<br>";

            new TQuestion($mensagem,
                 new TAction([__CLASS__, 'onfinalizarYes'], $param), 
                 new TAction([__CLASS__, 'onfinalizarNo'], $param));

            //</autoCode>
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

    public static function btnretornoconsulta($param = null) 
    {
        try
        {
            // ========================================
            // PASSO 1: Validações Básicas
            // ========================================
            if (empty($param['id']))
            {
                throw new Exception('<br>ID do agendamento não foi fornecido.');
            }

            $id = $param['id'];
            TTransaction::open(self::$database);
            $agendamento = Agendamento::find($id);

            if (!$agendamento)
            {
                TTransaction::close();
                throw new Exception('<br>Agendamento ID ' . htmlspecialchars($id) . ' não encontrado.');
            }

            // ========================================
            // PASSO 2: Validar Status = '12' (FINALIZADO)
            // ========================================
            if ($agendamento->status !== '12')
            {
                TTransaction::close();
                throw new Exception('<br>O Agendamento deve estar <b>FINALIZADO</b> para agendar retorno.<br>Status atual: ' . self::getStatusLabel($agendamento->status));
            }

            // ========================================
            // PASSO 3: Validar Profissional
            // ========================================
            if (empty($agendamento->profissional_id))
            {
                TTransaction::close();
                throw new Exception('<br>Profissional não vinculado ao agendamento.');
            }

            $profissional_usuario = SystemUsers::find($agendamento->profissional_id);
            if (!$profissional_usuario)
            {
                TTransaction::close();
                throw new Exception('<br>Profissional não encontrado.');
            }

            $profissional_pessoa = Pessoa::where('usuario_sistema', '=', $profissional_usuario->id)->first();
            if (!$profissional_pessoa)
            {
                TTransaction::close();
                throw new Exception('<br>Dados do profissional não encontrado.');
            }

            // Verificar autorização
            if (isset($profissional_pessoa->geraroutro_retorno) && $profissional_pessoa->geraroutro_retorno === 'N')
            {
                TTransaction::close();
                throw new Exception('<br>Profissional <b>' . htmlspecialchars($profissional_usuario->name) . '</b> não autorizou a geração do retorno.');
            }

            $dias_para_retorno = (int)($profissional_pessoa->dias_para_retorno ?? 0);
            if ($dias_para_retorno <= 0)
            {
                TTransaction::close();
                throw new Exception('<br>Dias para retorno não foi configurado para o profissional.');
            }

            // ========================================
            // PASSO 4: Verificar Retornos Pendentes COM DETALHES
            // ========================================
            $repository = new TRepository('Agendamento');
            $criteria   = new TCriteria();
            $criteria->add(new TFilter('paciente_id',          '=', $agendamento->paciente_id));
            $criteria->add(new TFilter('profissional_id',      '=', $agendamento->profissional_id));
            $criteria->add(new TFilter('consulta_retorno',     '=', 'S'));
            $criteria->add(new TFilter('agendamento_anterior', '=', $agendamento->id));
            $criteria->add(new TFilter('status', 'IN', ['01', '02', '97']));

            if ($repository->count($criteria) > 0)
            {
                $retornos = $repository->load($criteria, false);
                $ret      = $retornos[0];

                $msg_detalhe = '';
                if (!empty($ret->horario_inicial) && !empty($ret->horario_final))
                {
                    $dt_ini = DateTime::createFromFormat('Y-m-d H:i:s', $ret->horario_inicial) ?: new DateTime($ret->horario_inicial);
                    $dt_fim = DateTime::createFromFormat('Y-m-d H:i:s', $ret->horario_final) ?: new DateTime($ret->horario_final);

                    $msg_detalhe = "<br><br><b>Retorno agendado:</b><br>" .
                        "Data e Hora: " . $dt_ini->format('d/m/Y H:i') . ' às ' . $dt_fim->format('H:i') . "<br>" .
                        "Status: " . self::getStatusLabel($ret->status) . "<br>ID: " . $ret->id;
                }

                TTransaction::close();
                throw new Exception('<br>Já existe um retorno pendente para este paciente e profissional.' . $msg_detalhe);
            }

            $dados = new stdClass;

            // ID do agendamento atual
            $dados->vagendamento_id = $param['id'] ?? null;

            // Recupera contexto salvo na sessão
            $dados->empresa_id      = TSession::getValue('agendamento_filtro_empresa_id');
            $dados->profissional_id = TSession::getValue('agendamento_filtro_profissional_id');

            // Abre a lista mantendo o filtro
            TApplication::loadPage('AgendamentoList02', 'onReload', (array) $dados);            

        }
        catch (Exception $e) 
        {
            TTransaction::rollback();
            new TMessage('error', '<b>' .TSession::getValue('username').  '</b>' . $e->getMessage());
        }
    }

    public static function btnduplicar($param = null) 
    {
        try 
        {
            if (empty($param['id']))
            {
                throw new Exception('<br>ID do agendamento não foi fornecido.');
            }

            $agendamentoId = $param['id'];
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';

            TTransaction::open(self::$database);

            $agendamento = Agendamento::find($agendamentoId);

            if (!$agendamento)
            {
                TTransaction::close();
                throw new Exception('<br>Agendamento com ID ' . htmlspecialchars($agendamentoId) . ' não encontrado.');
            }

            // Buscar dados do paciente relacionado
            $pacienteName = 'N/A';
            if (!empty($agendamento->paciente_id))
            {
                $paciente = Pessoa::find($agendamento->paciente_id);
                if ($paciente)
                {
                    $pacienteName = htmlspecialchars($paciente->nome ?? 'N/A');
                }
            }

            TTransaction::close();

            $mensagem  = "<b>{$usuarioLogado}</b><br><br>";
            $mensagem .= "Deseja duplicar este agendamento?<br>";
            $mensagem .= "<b>Agendamento:</b> " . htmlspecialchars($agendamentoId) . "<br>";
            $mensagem .= "<b>Paciente:</b> {$pacienteName}<br>";

            new TQuestion(
                $mensagem,
                 new TAction([__CLASS__, 'onduplicarYes'], $param), 
                 new TAction([__CLASS__, 'onduplicarNo'], $param)
            );
            //</autoCode>
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

    public static function btncancelar($param = null) 
    {
        try 
        {
            if (empty($param['id']))
            {
                throw new Exception('<br>ID do agendamento não foi fornecido.');
            }

            $agendamentoId = $param['id'];
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';

            TTransaction::open(self::$database);

            $agendamento = Agendamento::find($agendamentoId);

            if (!$agendamento)
            {
                TTransaction::close();
                throw new Exception('<br>Agendamento com ID ' . htmlspecialchars($agendamentoId) . ' não encontrado.');
            }

            // Buscar dados do paciente relacionado
            $pacienteName = 'N/A';
            if (!empty($agendamento->paciente_id))
            {
                $paciente = Pessoa::find($agendamento->paciente_id);
                if ($paciente)
                {
                    $pacienteName = htmlspecialchars($paciente->nome ?? 'N/A');
                }
            }

            TTransaction::close();

            $mensagem  = "<b>{$usuarioLogado}</b><br><br>";
            $mensagem .= "Deseja cancelar este agendamento?<br>";
            $mensagem .= "<b>Agendamento:</b> " . htmlspecialchars($agendamentoId) . "<br>";
            $mensagem .= "<b>Paciente:</b> {$pacienteName}<br>";

            new TQuestion(
                $mensagem,
                 new TAction([__CLASS__, 'oncancelarYes'], $param), 
                 new TAction([__CLASS__, 'oncancelarNo'], $param)
            );

            //</autoCode>
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

    public static function btnprotocoloepreparo($param = null) 
    {
        try 
        {

            //</autoCode>
        }
        catch (Exception $e) 
        {
            $userName = TSession::getValue('username');
            new TMessage('error', "<b>{$userName}</b> - {$e->getMessage()}");
        }
    }

    public static function btncalcularnovadataagendamento($param = null) 
    {
        try 
        {
            $userName = TSession::getValue('username');

            // Script que captura valor BRUTO do input sem processamento do Adianti
            $jsCapturar = "
            (function() 
            {
                // Capturar valor bruto do input
                var inputElement = document.querySelector('input[name=\"horario_inicial\"]');
                var valorBruto   = inputElement ? inputElement.value : '';

                // Armazenar globalmente para debug
                window.__valorBrutoHorario = valorBruto;

                // Validações básicas
                if (!valorBruto || valorBruto.length < 16) 
                {
                    alert('ERRO: Campo Data e Hora Inicial não está preenchido ou muito curto!\\n' +
                        'Valor recebido: [' + valorBruto + ']\\n' +
                        'Comprimento: ' + valorBruto.length);
                    return;
                }
            })();
            ";

            TScript::create($jsCapturar);

            // Criar formulário de entrada
            $form = new BootstrapFormBuilder('input_form_calcular_dias_v3');

            $dias = new TEntry('dias');
            $dias->setNumeric(true, 0, 999);
            $dias->setDefaultValue(1);
            $dias->setRequired(true);
            $dias->setTip('Quantos dias deseja adicionar?');

            // Campos ocultos
            $data_adicionar = new THidden('data_adicionar');
            $campo_alterar  = new THidden('campo_alterar');

            // Tentar obter valor de diferentes formas
            $horario_param = $param['horario_inicial'] ?? '';

            $data_adicionar->setValue($horario_param);
            $campo_alterar->setValue('horario_inicial');

            $form->addFields
            (
                [new TLabel('<b>Cálculo de Nova Data</b>')]
            );

            $form->addFields
            (
                [new TLabel('Quantos dias deseja adicionar?')],
                [$dias, $data_adicionar, $campo_alterar]
            );

            $form->addAction
            (
                'Calcular',
                new TAction([__CLASS__, 'adicionarDiasV3']),
                'fa:calculator green'
            );

            new TInputDialog('Cálculo de Nova Data de Agendamento', $form);
            echo "<style>.modal{z-index:9999 !important;}</style>";

            //</autoCode>
        }
        catch (Exception $e) 
        {
            $userName = TSession::getValue('username');
            new TMessage('error', "<b>{$userName}</b> - Erro: " . $e->getMessage());
        }
    }

    public static function btnverificafinanceiro($param = null) 
    {
        try 
        {
            $paciente_id = $param['paciente_id'] ?? null;

            if (empty($paciente_id))
            {
                throw new Exception('<br>Por favor, selecione um paciente.');
            }

            // Salva o paciente_id na sessão com chave fixa
            TSession::setValue('filtro_financeiro', $paciente_id);

            // Abre a página de contas a receber
            TApplication::loadPage("ContasReceberList03", "onShow");

            //</autoCode>
        }
        catch (Exception $e) 
        {
            $userName = TSession::getValue('username');
            new TMessage('error', "<b>{$userName}</b> - Erro: " . $e->getMessage());
        }
    }

    public static function btncopiarnumeocarterinha($param = null) 
    {
        try 
        {
            // Verifica se os parâmetros necessários estão presentes
            if (empty($param['paciente_id']) || empty($param['fornecedor_id'])) 
            {
                throw new Exception("<br>Os campos Paciente e Convênio precisam estar preenchidos.");
            }

            TTransaction::open(self::$database);

            // Uso de array na cláusula where para melhor legibilidade
            $pessoaConvenioparceria = PessoaConvenioparceria::where('paciente_id',   '=', $param['paciente_id'])
                                                            ->where('fornecedor_id', '=', $param['fornecedor_id'])
                                                            ->last();

            if($pessoaConvenioparceria)
            {
                $vcarteirinha    = $pessoaConvenioparceria->numero_carteirinha;
                $conteudo_seguro = addslashes($vcarteirinha); // IMPORTANTE: Adiciona barras invertidas antes de aspas simples para garantir que a string JavaScript não seja quebrada, permitindo a cópia correta.

                // Cria o script para copiar o conteúdo
                TScript::create("__adianti_copy_to_clipboard('{$conteudo_seguro}');");

                // Exibe a mensagem de sucesso
                new TMessage('info', '<b>' . TSession::getValue('username') . '</b> - Número da carteirinha <b>' . $vcarteirinha . '</b> copiado para a área de transferência.');
            } 
            else 
            {
                // Caso não encontre o registro, informa ao usuário
                new TMessage('info', '<b>' . TSession::getValue('username') . '</b> - Não foi encontrado um registro de convênio para copiar.');
            }

            TTransaction::close();
            //</autoCode>
        }
        catch (Exception $e) 
        {
            TTransaction::rollback();            
            $userName = TSession::getValue('username');
            new TMessage('error', "<b>{$userName}</b> - Erro: " . $e->getMessage());
        }
    }

    public static function btnatualizasaladeatendimento($param = null) 
    {
        try 
        {
            // 1. Em métodos estáticos, os dados vêm dentro de $param
            // Não use $this->form->getData() aqui.
            $horario_inicial = $param['horario_inicial'] ?? null;
            $horario_final   = $param['horario_final'] ?? null;
            $profissional_id = $param['profissional_id'] ?? null;

            if (empty($horario_inicial) || empty($profissional_id)) 
            {
                throw new Exception("<br>Os campos 'Data e hora inicial' / 'Data e hora final' e 'Profissional' são obrigatórios.");
            }

            // 2. Transação de Banco de Dados
            TTransaction::open(self::$database);

            // --- BUSCA O NOME DIRETAMENTE DA TABELA DE USUÁRIOS DO SISTEMA ---
            $usuario           = SystemUsers::find($profissional_id);
            $nome_profissional = ($usuario) ? $usuario->name : "ID: " . $profissional_id;

            // Limpeza básica manual para evitar depender de métodos externos que usem $this
            $data_limpa = str_replace(['/', ' '], ['-', ' '], $horario_inicial);
            $dt         = DateTime::createFromFormat('Y-m-d H:i', $data_limpa);

            if (!$dt) 
            {
                // Tenta formato brasileiro caso o campo envie DD/MM/YYYY
                $dt = DateTime::createFromFormat('d-m-Y H:i', $data_limpa);
            }

            if (!$dt) 
            {
                throw new Exception("Formato de data inválido: {$horario_inicial}");
            }

            // Lógica de dia da semana (0=Dom, 1=Seg...) -> Mapeado para Adianti (7=Dom, 1=Seg...)
            $dia_semana_n   = (int) $dt->format('w');
            $mapa           = [0 => 7, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6];
            $dia_adianti    = $mapa[$dia_semana_n];
            $hora_formatada = $dt->format('H:i');

            // 3. Busca o horário e o ambiente
            $pessoa_horario = PessoaHorarios::where('profissional_id', '=', $profissional_id)
                                            ->where('dia_da_semana', '=', $dia_adianti)
                                            ->where('hora_inicio', '<=', $hora_formatada)
                                            ->where('hora_fim', '>=', $hora_formatada)
                                            ->first();

            if (!$pessoa_horario)
            {
                throw new Exception("<br>O profissional <b>{$nome_profissional}</b> não tem agenda configurada para este dia e horário.");
            }

            $ambiente_id = $pessoa_horario->ambiente_id;

            // 4. Fechar transação
            TTransaction::close();

            // 5. Atualizar o formulário na tela
            $data              = new stdClass;
            $data->ambiente_id = $ambiente_id;

            // self::$formName deve estar definido na sua classe
            TForm::sendData(self::$formName, $data);

            TToast::show("success", "Sala de atendimento atualizada. " , "topRight", "fas:border-style");

            //</autoCode>
        }
        catch (Exception $e) 
        {
            TTransaction::rollback();
            new TMessage('error', '<b>' . TSession::getValue('username') . '</b>' . $e->getMessage());          
        }        
    }

    public static function btnatualizavalores($param = null) 
    {
        try 
        {        
            // ========================================
            // FUNÇÃO AUXILIAR PARA CONVERSÃO
            // ========================================
            $toFloat = function($val) 
            {
                if (empty($val) || $val === '') 
                {
                    return 0;
                }
                if (is_numeric($val)) 
                {
                    return (float) $val;
                }
                if (is_string($val)) 
                {
                    // Converte vírgula em ponto (padrão brasileiro)
                    $val = str_replace(',', '.', $val);
                    // Remove separador de milhares (mantém apenas último ponto = decimal)
                    if (substr_count($val, '.') > 1) 
                    {
                        $partes = explode('.', $val);
                        $val = implode('', array_slice($partes, 0, -1)) . '.' . end($partes);
                    }
                    return (float) $val;
                }
                return (float) $val;
            };

            // ========================================
            // 1. LER E CONVERTER OS VALORES PARA FLOAT
            // ========================================
            $valor_venda                    = $toFloat($param['valor_venda']                    ?? 0);
            $percentual_desconto_utilizado  = $toFloat($param['percentual_desconto_utilizado']  ?? 0);
            $percentual_desconto_maximo     = $toFloat($param['percentual_desconto_maximo']     ?? 0);
            $valor_taxaentregaexame         = $toFloat($param['valor_taxaentregaexame']         ?? 0);

            // ========================================
            // 2. VALIDAR DESCONTO
            // ========================================
            if ($percentual_desconto_utilizado > $percentual_desconto_maximo) 
            {
                throw new Exception("O desconto utilizado (" . number_format($percentual_desconto_utilizado, 2, ',', '.') . "%) não pode ser maior que o autorizado (" . number_format($percentual_desconto_maximo, 2, ',', '.') . "%).");
            }

            // ========================================
            // 3. CALCULAR VALORES (COM PRECISÃO)
            // ========================================
            $desconto      = (($valor_venda * $percentual_desconto_utilizado) / 100);
            $valor_receber = (($valor_venda - $desconto) + $valor_taxaentregaexame);

            // ========================================
            // 5. ENVIAR DADOS PARA O FORMULÁRIO
            // ========================================
            $obj                                    = new stdClass();
            $obj->valor_venda                       = $valor_venda_str;
            $obj->valor_taxaentregaexame            = $valor_taxa_str;
            $obj->valor_receber                     = $valor_receber_str;
            $obj->percentual_desconto_utilizado     = $desc_util_str;
            $obj->percentual_desconto_maximo        = $desc_max_str;

            TForm::sendData(self::$formName, $obj);
            //</autoCode>
        }
        catch (Exception $e) 
        {
            $userName = TSession::getValue('username');
            new TMessage('error', "<b>{$userName}</b> - {$e->getMessage()}");
        }
    }

    public function onSave($param = null) 
    {

    try
    {
        TTransaction::open(self::$database);
// DEBUG seguro - apenas valores escalares
//new TMessage('info', "DEBUG ONSAVE - VALOR_RECEBER NO PARAM: " . (is_scalar($param['valor_receber'] ?? null) ? $param['valor_receber'] : 'NÃO-ESCALAR'));

// DEBUG INICIAL
$debugFields = [
    'id' => $param['id'] ?? 'VAZIO',
    'fornecedor_id' => $param['fornecedor_id'] ?? 'VAZIO',
    'produto_id' => $param['produto_id'] ?? 'VAZIO',
    'guia_conveniocab_id' => $param['guia_conveniocab_id'] ?? 'VAZIO',
    'guia_auxiliar_id' => $param['guia_auxiliar_id'] ?? 'VAZIO',
    'entrega_resultado' => $param['entrega_resultado'] ?? 'VAZIO',
    'paciente_id' => $param['paciente_id'] ?? 'VAZIO',
    'profissional_id' => $param['profissional_id'] ?? 'VAZIO',
    'cobranca_id' => $param['cobranca_id'] ?? 'VAZIO',
];

$debugMsg = "DEBUG onSave - Campos recebidos:\n";
foreach ($debugFields as $campo => $valor) {
    $debugMsg .= "$campo: $valor\n";
}

new TMessage('info', $debugMsg);

        $preservar = 
        [
            'paciente_id'       => $param['paciente_id']     ?? null,
            'fornecedor_id'     => $param['fornecedor_id']   ?? null,
            'produto_id'        => $param['produto_id']      ?? null,
            'profissional_id'   => $param['profissional_id'] ?? null,
        ];
        self::$bloqueando_eventos_paciente = true;
        self::$bloqueando_profissional     = true;
        $data_raw                          = $this->form->getData();
        $is_editing                        = !empty($data_raw->id);
        $profissional_id_preservado        = $data_raw->profissional_id ?? null;
        $objeto_para_restaurar             = null;

        if ($is_editing) 
        {
            $objeto_para_restaurar = Agendamento::find($data_raw->id);
        }
        try 
        {
            $this->form->validate();
        } 
        catch (Exception $e) 
        {
            new TMessage('error', '<b>' . TSession::getValue('username') . '</b><br>' . $e->getMessage());
            self::$bloqueando_eventos_paciente = false;
            self::$bloqueando_profissional     = false;
            throw $e;
        }
        $data = $this->form->getData();
        // ========================================
        // FUNÇÃO AUXILIAR PARA EXTRAIR VALOR
        // ========================================
        $extrairValor = function($val) 
        {
            if (is_object($val)) 
            {
                if (property_exists($val, '__value')) 
                {
                    return $val->__value;
                }
                if (get_class($val) === 'stdClass') 
                {
                    $props = get_object_vars($val);
                    if (!empty($props)) 
                    {
                        return reset($props);
                    }
                }
                if (property_exists($val, 'value')) 
                {
                    return $val->value;
                } 
                elseif (property_exists($val, 'id')) 
                {
                    return $val->id;
                } 
                elseif (method_exists($val, '__toString')) 
                {
                    return (string) $val;
                }
                return null;
            }
            return $val;
        };
        // ========================================
        // FUNÇÃO PARA CONVERTER PARA FLOAT SEGURO
        // ========================================
        $toFloat = function($val) use ($extrairValor) 
        {
            $val = $extrairValor($val);
            if ($val === null || $val === '' || $val === false) 
            {
                return 0.0;
            }
            $val = trim((string)$val);
            $val = str_replace(' ', '', $val);
            if (strpos($val, ',') !== false && strpos($val, '.') !== false && strpos($val, '.') < strpos($val, ',')) 
            {
                $val = str_replace('.', '',  $val);
                $val = str_replace(',', '.', $val);
            } 
            else 
            {
                $val = str_replace(',', '', $val);
            }
            return (float) $val;
        };
        // ========================================
        // FUNÇÃO PARA FORMATAR COM EXATAMENTE 2 CASAS DECIMAIS COMO STRING
        // Essa é a chave: força "100.00", "1.00", "0.00", "81.50"
        // ========================================
        $format2Decimals = function($val) use ($toFloat) 
        {
            $float = $toFloat($val);
            return number_format($float, 2, '.', '');
        };
        // ========================================
        // CONVERSÃO INICIAL DOS VALORES MONETÁRIOS
        // ========================================
        $valor_venda_float          = isset($param['valor_venda']) ? $toFloat($param['valor_venda']) : 0.0;
        $valor_taxa_float           = isset($param['valor_taxaentregaexame']) ? $toFloat($param['valor_taxaentregaexame']) : 0.0;
        $percentual_desconto_util   = isset($param['percentual_desconto_utilizado']) ? $toFloat($param['percentual_desconto_utilizado']) : 0.0;
        $percentual_desconto_aut    = isset($param['percentual_desconto_autorizado']) ? $toFloat($param['percentual_desconto_autorizado']) : 0.0;
        $percentual_desconto_max    = isset($param['percentual_desconto_maximo']) ? $toFloat($param['percentual_desconto_maximo']) : 0.0;
        $desconto                   = (($valor_venda_float * $percentual_desconto_util) / 100);
        $valor_receber_float        = (($valor_venda_float - $desconto) + $valor_taxa_float);

        $this->form->setData($data);
        if ($profissional_id_preservado) 
        {
            $data->profissional_id = $profissional_id_preservado;
        }
        // ========================================
        // CORRIGIR VALORES MONETÁRIOS NO $data
        // ========================================
        $data->valor_venda                      = $valor_venda_float;
        $data->valor_taxaentregaexame           = $valor_taxa_float;
        $data->valor_receber                    = $valor_receber_float;
        $data->percentual_desconto_utilizado    = $percentual_desconto_util;
        $data->percentual_desconto_autorizado   = $percentual_desconto_aut;
        $data->percentual_desconto_maximo       = $percentual_desconto_max;

        $is_retorno = (!empty($data->consulta_retorno) && $data->consulta_retorno === 'S' && !empty($data->agendamento_anterior));
        if ($is_retorno) 
        {
            $data->valor_venda                      = null;
            $data->valor_custo                      = null;
            $data->valor_receber                    = null;
            $data->valor_contratado                 = null;
            $data->percentual_desconto_autorizado   = null;
            $data->percentual_desconto_utilizado    = null;
            $data->valor_taxaentregaexame           = null;

            $prof_bloqueado = TSession::getValue('RETORNO_PROFISSIONAL_BLOQUEADO');
            if ($prof_bloqueado) 
            {
                $data->profissional_id = $prof_bloqueado;
                TSession::delValue('RETORNO_PROFISSIONAL_BLOQUEADO');
            }
        }

        foreach (['horario_inicial', 'horario_final'] as $campo) 
        {
            if (!empty($data->$campo) && strpos($data->$campo, '-') !== false && !preg_match('/^\d{4}-\d{2}-\d{2}/', $data->$campo)) 
            {
                $data->$campo = preg_replace('/(\d{2})-(\d{2})-(\d{4})\s+(\d{2}):(\d{2})/', '$3-$2-$1 $4:$5:00', $data->$campo);
            }
        }
$isEdicao = !empty($data->id);
if ($isEdicao) 
{
    self::preservarDadosEdicao($data, $data->id);
}

        $erros = [];
        if (empty($data->horario_inicial))      $erros[] = "Data e hora inicial";
        if (empty($data->horario_final))        $erros[] = "Data e hora final";
        if (empty($data->empresa_id))           $erros[] = "Empresa";
        if (empty($data->paciente_id))          $erros[] = "Paciente";
        if (empty($data->profissional_id))      $erros[] = "Profissional de saúde";
        if (empty($data->fornecedor_id))        $erros[] = "Convênio";
        if (empty($data->produto_id))           $erros[] = "Procedimento a ser realizado";
        if (empty($data->entrega_resultado))    $erros[] = "Resultado de exame";
        if (empty($data->cobranca_id))          $erros[] = "Cobrança utilizada";

        if (!$is_retorno && empty($valor_receber_float)) 
        {
            $erros[] = "Valor a receber";
        }

/**
 * PROCURE POR ESTA VALIDAÇÃO NO onSave():
 * 
 * if (!empty($erros)) 
 * {
 *     $lista_erros = implode('<br>• ', $erros);
 *     throw new Exception("<b>Os seguintes campos são obrigatórios:</b><br>• {$lista_erros}");
 * }
 * 
 * SUBSTITUA POR:
 */
// ✅ VALIDAÇÃO CORRIGIDA - Permitir edição mesmo com campos vazios
if (!empty($erros)) 
{
    $isEdicao = !empty($data->id);

    // Em EDIÇÃO: se campos estão vazios, carregar do banco
    if ($isEdicao) 
    {
        TTransaction::open(self::$database);
        $agendamentoOriginal = Agendamento::find($data->id);
        TTransaction::close();

        if ($agendamentoOriginal) 
        {
            // Restaurar campos vazios com valores do banco
            if (empty($data->fornecedor_id) && !empty($agendamentoOriginal->fornecedor_id)) 
            {
                $data->fornecedor_id = $agendamentoOriginal->fornecedor_id;
            }
            if (empty($data->produto_id) && !empty($agendamentoOriginal->produto_id)) 
            {
                $data->produto_id = $agendamentoOriginal->produto_id;
            }
            if (empty($data->guia_conveniocab_id) && !empty($agendamentoOriginal->guia_conveniocab_id)) 
            {
                $data->guia_conveniocab_id = $agendamentoOriginal->guia_conveniocab_id;
            }
            if (empty($data->guia_auxiliar_id) && !empty($agendamentoOriginal->guia_auxiliar_id)) 
            {
                $data->guia_auxiliar_id = $agendamentoOriginal->guia_auxiliar_id;
            }
            if (empty($data->entrega_resultado) && !empty($agendamentoOriginal->entrega_resultado)) 
            {
                $data->entrega_resultado = $agendamentoOriginal->entrega_resultado;
            }
            if (empty($data->cobranca_id) && !empty($agendamentoOriginal->cobranca_id)) 
            {
                $data->cobranca_id = $agendamentoOriginal->cobranca_id;
            }
            if (empty($data->paciente_id) && !empty($agendamentoOriginal->paciente_id)) 
            {
                $data->paciente_id = $agendamentoOriginal->paciente_id;
            }
            if (empty($data->profissional_id) && !empty($agendamentoOriginal->profissional_id)) 
            {
                $data->profissional_id = $agendamentoOriginal->profissional_id;
            }

            // Recalcular erros após restaurar dados
            $erros = [];
            if (empty($data->horario_inicial))      $erros[] = "Data e hora inicial";
            if (empty($data->horario_final))        $erros[] = "Data e hora final";
            if (empty($data->empresa_id))           $erros[] = "Empresa";
            if (empty($data->paciente_id))          $erros[] = "Paciente";
            if (empty($data->profissional_id))      $erros[] = "Profissional de saúde";
            if (empty($data->fornecedor_id))        $erros[] = "Convênio";
            if (empty($data->produto_id))           $erros[] = "Procedimento a ser realizado";
            if (empty($data->entrega_resultado))    $erros[] = "Resultado de exame";
            if (empty($data->cobranca_id))          $erros[] = "Cobrança utilizada";
        }
    }

    // Se ainda houver erros, lançar exceção
    if (!empty($erros)) 
    {
        $lista_erros = implode('<br>• ', $erros);
        throw new Exception("<b>Os seguintes campos são obrigatórios:</b><br>• {$lista_erros}");
    }
}

        $object     = new Agendamento();
        $data_array = (array) $data;
        $object->fromArray($data_array);

        // VALIDAÇÃO DE HORÁRIOS DUPLICADOS
        if (empty($data->id)) 
        {
            if ($agendamento_existente = $object->checkDuplicate()) 
            {
                try 
                {
                    $dt_inicial                     = new DateTime($agendamento_existente->horario_inicial);
                    $dt_final                       = new DateTime($agendamento_existente->horario_final);
                    $data_hora_inicial_formatada    = $dt_inicial->format('d-m-Y H:i:s');
                    $hora_final_formatada           = $dt_final->format('H:i:s');
                } 
                catch (Exception $e) 
                {
                    $data_hora_inicial_formatada = '';
                    $hora_final_formatada        = '';
                }
                $mensagem_erro = " - Já existe um agendamento com estes mesmos dados:<br><br>"
                               . "<b>Agendamento:</b>   {$agendamento_existente->id}<br>"
                               . "<b>Paciente:</b>      {$agendamento_existente->paciente->nome}<br>"
                               . "<b>Profissional:</b>  {$agendamento_existente->profissional->name}<br>"
                               . "<b>Data e Horário:</b>{$data_hora_inicial_formatada} as {$hora_final_formatada}";
                throw new Exception($mensagem_erro);
            }
        }
        // VALIDAÇÃO DE HORÁRIOS
        if ($object->horario_final < $object->horario_inicial) 
        {
            throw new Exception('<br>A data e hora final não pode ser menor que a data e hora inicial');
        }
        // VALIDAÇÃO DE GUIAS E VALOR RECEBIDO (INCLUSÃO)
        if (empty($data->id)) 
        {
            $guia_convenio = GuiasconvenioCab::where('pessoa_id',       '=', $data->paciente_id)
                                            ->where('fornecedor_id',    '=', $data->fornecedor_id)
                                            ->where('data_vencimento', '>=', date('Y-m-d'))
                                            ->where('status', '=', 'A')
                                            ->first();
            if ($guia_convenio) 
            {
                if (!isset($data->guia_conveniocab_id) || empty($data->guia_conveniocab_id)) 
                {
                    throw new Exception("<br>Existe uma Guia de atendimento válida.<br>Consulte a guia {$guia_convenio->guia_convenio}");
                }
                if (!isset($data->guia_auxiliar_id) || empty($data->guia_auxiliar_id)) 
                {
                    throw new Exception("<br>O campo 'Guia Auxiliar' é obrigatório.");
                }
                $guia_para_abater             = new GuiasconvenioCab($guia_convenio->id);
                $guia_para_abater->guia_saldo = $guia_para_abater->guia_saldo - 1;
                $guia_para_abater->store();
                try 
                {
                    $guia_item_utilizado            = new GuiasconvenioItem($data->guia_auxiliar_id);
                    $guia_item_utilizado->status    = 'U';
                    $guia_item_utilizado->utilizado = 'S';
                    $guia_item_utilizado->store();
                } 
                catch (Exception $e) 
                {
                    throw new Exception("<br>ERRO: Não foi possível atualizar o Item de Guia Auxiliar (ID: {$data->guia_auxiliar_id}). Detalhe: " . $e->getMessage());
                }
            }
            if (empty($valor_receber_float) || $valor_receber_float <= 0.00) 
            {
                throw new Exception("<br>O campo 'Valor a receber' é obrigatório e deve ser maior que R$ 0,00. Valor atual: R$ " . number_format($valor_receber_float, 2, ',', '.'));
            }
        }
        // BUSCAR DADOS ADICIONAIS
        $object->rf_irrf = $object->rf_pis = $object->rf_cofins = $object->rf_csll = $object->rp_inss = $object->rm_iss = $object->re_icms = 0.00;
        $percentual_retencao_convenio   = 0.00;
        $percentual_retencao_particular = 0.00;

        if (!empty($object->profissional_id)) 
        {
            $systemUser = SystemUsers::find($object->profissional_id);
            if ($systemUser) 
            {
                $profissional = Pessoa::where('usuario_sistema', '=', $systemUser->id)->first();
                if ($profissional) 
                {
                    $percentual_retencao_convenio   = $toFloat($profissional->percentual_retencao_convenio   ?? 0);
                    $percentual_retencao_particular = $toFloat($profissional->percentual_retencao_particular ?? 0);
                }
            }
        }
        $object->percentual_retencao_convenio   = $percentual_retencao_convenio;
        $object->percentual_retencao_particular = $percentual_retencao_particular;
        $paciente_valor_contratado              = null;
        $produto_preco_custo                    = null;
        $produto_preco_venda                    = null;

        if (!empty($data->paciente_id)) 
        {
            $paciente_obj = Pessoa::find($data->paciente_id);
            if ($paciente_obj) 
            {
                $paciente_valor_contratado = $toFloat($paciente_obj->valor_contratado ?? 0);
            }
        }

        if (!empty($data->fornecedor_id) && !empty($data->produto_id)) 
        {
            $produto_preco = ProdutoFornecedorpreco::where('fornecedor_id', '=', $data->fornecedor_id)
                                                  ->where('produto_id',     '=', $data->produto_id)
                                                  ->first();
            if ($produto_preco) 
            {
                $produto_preco_custo = $toFloat($produto_preco->preco_custo ?? 0);
                $produto_preco_venda = $toFloat($produto_preco->preco_venda ?? 0);
            }
        }

        if (!empty($data->fornecedor_id)) 
        {
            $fornecedor_obj = Pessoa::find($data->fornecedor_id);
            if ($fornecedor_obj) 
            {
                $object->rf_irrf    = $toFloat($fornecedor_obj->rf_irrf     ?? 0);
                $object->rf_pis     = $toFloat($fornecedor_obj->rf_pis      ?? 0);
                $object->rf_cofins  = $toFloat($fornecedor_obj->rf_cofins   ?? 0);
                $object->rf_csll    = $toFloat($fornecedor_obj->rf_csll     ?? 0);
                $object->rp_inss    = $toFloat($fornecedor_obj->rp_inss     ?? 0);
                $object->rm_iss     = $toFloat($fornecedor_obj->rm_iss      ?? 0);
                $object->re_icms    = $toFloat($fornecedor_obj->re_icms     ?? 0);
            }
        }
        // LÓGICA DE VALOR CONTRATADO
        $valor_contratado_usar  = null;
        $usar_valor_contratado  = false;
        $paciente_obj_check     = Pessoa::find($data->paciente_id);

        if ($paciente_obj_check &&
            $paciente_obj_check->paciente_psicologia == 'S' &&
            $paciente_obj_check->profissional_id    == $data->profissional_id &&
            !empty($paciente_obj_check->valor_contratado) &&
            $paciente_obj_check->valor_contratado != 0) 
        {
            $usar_valor_contratado = true;
        }

        if ($usar_valor_contratado) 
        {
            $valor_contratado_usar = $paciente_valor_contratado;
        }

        if ($valor_contratado_usar !== null && $valor_contratado_usar != 0) 
        {
            if ($is_retorno) 
            {
                $object->valor_contratado = null;
                $object->valor_custo      = null;
                $object->valor_venda      = null;
            } 
            else 
            {
                $object->valor_contratado = $valor_contratado_usar;
                $object->valor_custo      = $valor_contratado_usar;
                $object->valor_venda      = $valor_contratado_usar;
            }
        } 
        else 
        {
            if ($is_retorno) 
            {
                $object->valor_custo = null;
                $object->valor_venda = null;
            } 
            else 
            {
                if ($produto_preco_custo !== null && $produto_preco_custo != 0) 
                {
                    $object->valor_custo = $produto_preco_custo;
                }
                if ($produto_preco_venda !== null && $produto_preco_venda != 0) 
                {
                    $object->valor_venda = $produto_preco_venda;
                }
            }
        }

        if (!$is_retorno) 
        {
            $object->valor_receber = $valor_receber_float;
        } 
        else 
        {
            $object->valor_receber = 0.00;
        }
        // ========================================
        // LISTA COMPLETA DOS CAMPOS QUE DEVEM SER 0.00 COM 2 CASAS
        // ========================================
        $campos_monetarios = 
        [
            'valor_custo',
            'valor_venda',
            'valor_receber',
            'valor_contratado',
            'valor_taxaentregaexame',
            'valor_original',
            'valor_liquido',
            'valor_quitado',
            'valor_retencao_particular',
            'valor_retencao_convenio',
            'rf_irrf',
            'rf_pis',
            'rf_cofins',
            'rf_csll',
            'rp_inss',
            'rm_iss',
            're_icms'
        ];
        $campos_percentuais = 
        [
            'percentual_desconto_autorizado',
            'percentual_desconto_utilizado',
            'percentual_desconto_maximo',
            'percentual_retencao_particular',
            'percentual_retencao_convenio'
        ];

        // ========================================
        // GARANTIA FINAL: FORÇA STRING COM 2 CASAS DECIMAIS
        // ========================================
        foreach ($campos_monetarios as $campo) 
        {
            $object->$campo = $format2Decimals($object->$campo ?? 0);
        }

        foreach ($campos_percentuais as $campo) 
        {
            $object->$campo = $format2Decimals($object->$campo ?? 0);
        }
        $object->valor_original = $format2Decimals($object->valor_original ?? 0);
        $object->valor_liquido  = $format2Decimals($object->valor_liquido  ?? 0);
        $object->valor_quitado  = $format2Decimals($object->valor_quitado  ?? 0);

        // SALVAR AGENDAMENTO
        if (empty($data->id)) 
        {
            $object->data_alteracao = date('Y/m/d');
            $object->hora_alteracao = date('H:i');
            $object->usuario_alteracao = TSession::getValue('userid');
        }

        if (!empty($data->agendamento_anterior) && empty($data->id)) 
        {
            $object->store();
            $agendamento_original = Agendamento::find($data->agendamento_anterior);
            if ($agendamento_original) 
            {
                $agendamento_original->agendamento_novo = $object->id;
                $agendamento_original->store();
            }
        } 
        else 
        {
            $object->store();
        }
        // ========================================
        // ENVIA VALORES FORMATADOS DE VOLTA AO FORMULÁRIO
        // ========================================
        TForm::sendData(self::$formName, (object)[
            'valor_venda'            => number_format($object->valor_venda ?? 0, 2, '.', ''),
            'valor_taxaentregaexame' => number_format($object->valor_taxaentregaexame ?? 0, 2, '.', ''),
            'valor_receber'          => number_format($object->valor_receber ?? 0, 2, '.', ''),
        ]);
        // RECARREGA COMBOS E FOTO
        $this->recarregarCombos($object);
        if (!empty($object->paciente_id)) 
        {
            $paciente = Pessoa::find($object->paciente_id);
            if ($paciente) 
            {
                $this->paciente_foto->src = $paciente->caminho_foto;
            }
        }

        $this->fireEvents($object);
        $data->id = $object->id;
        $this->form->setData($data);

        // GERAÇÃO DE CONTA A RECEBER
        $conta_existente = Conta::where('agendamento_id', '=', $object->id)->first();
        if (!$conta_existente && !$is_retorno) 
        {
            $produtofornecedorpreco = ProdutoFornecedorpreco::where('fornecedor_id', '=', $data->fornecedor_id)
                                                          ->where('produto_id',      '=', $data->produto_id)
                                                          ->first();
            $paciente          = Pessoa::find($object->paciente_id);

            $valor_custo_conta = null;
            $valor_venda_conta = null;

            $usar_valor_contratado_conta = false;
            if ($paciente &&
                $paciente->paciente_psicologia  == 'S' &&
                $paciente->profissional_id      == $object->profissional_id &&
                !empty($paciente->valor_contratado) &&
                $paciente->valor_contratado != 0) 
            {
                $usar_valor_contratado_conta = true;
            }
            if ($usar_valor_contratado_conta) 
            {
                $valor_contratado_usar  = $toFloat($paciente->valor_contratado);
                $valor_custo_conta      = $valor_contratado_usar;
                $valor_venda_conta      = $valor_contratado_usar;
            } 
            else if ($produtofornecedorpreco) 
            {
                $valor_custo_conta = $toFloat($produtofornecedorpreco->preco_custo ?? 0);
                $valor_venda_conta = $toFloat($produtofornecedorpreco->preco_venda ?? 0);
            }
            $contasareceber                                 = new Conta();
            $contasareceber->agendamento_id                 = $object->id;
            $contasareceber->empresa_id                     = $object->empresa_id;
            $contasareceber->cliente_id                     = $object->paciente_id;
            $contasareceber->tipo_conta_id                  = 1;
            $contasareceber->titulo                         = 'AG. - ' . $object->id;
            $contasareceber->parcela                        = 'PARCELA 1 DE 1';
            $contasareceber->profissional_id                = $object->profissional_id;
            $contasareceber->fornecedor_id                  = $object->fornecedor_id;
            $contasareceber->produto_id                     = $object->produto_id;
            $contasareceber->tipo_geracao                   = '2';
            $contasareceber->valor_custo                    = $format2Decimals($valor_custo_conta ?? 0);
            $contasareceber->valor_venda                    = $format2Decimals($valor_venda_conta ?? 0);
            $contasareceber->valor_receber                  = $format2Decimals($object->valor_receber ?? 0);
            $contasareceber->valor_contratado               = $format2Decimals($paciente ? $paciente->valor_contratado : 0);
            $contasareceber->valor_taxaentregaexame         = $format2Decimals($object->valor_taxaentregaexame ?? 0);
            $contasareceber->valor_original                 = '0.00';
            $contasareceber->valor_liquido                  = '0.00';
            $contasareceber->valor_quitado                  = '0.00';
            $contasareceber->desconto                       = '0.00';
            $contasareceber->juros                          = '0.00';
            $contasareceber->multa                          = '0.00';
            $contasareceber->valor_retencao_particular      = '0.00';
            $contasareceber->valor_retencao_convenio        = '0.00';
            $contasareceber->percentual_desconto_autorizado = $format2Decimals($object->percentual_desconto_autorizado ?? 0);
            $contasareceber->percentual_desconto_utilizado  = $format2Decimals($object->percentual_desconto_utilizado ?? 0);
            $contasareceber->percentual_desconto_maximo     = $format2Decimals($object->percentual_desconto_maximo ?? 0);
            $contasareceber->percentual_retencao_convenio   = $format2Decimals($percentual_retencao_convenio ?? 0);
            $contasareceber->percentual_retencao_particular = $format2Decimals($percentual_retencao_particular ?? 0);
            $contasareceber->rf_irrf                        = $format2Decimals($object->rf_irrf ?? 0);
            $contasareceber->rf_pis                         = $format2Decimals($object->rf_pis ?? 0);
            $contasareceber->rf_cofins                      = $format2Decimals($object->rf_cofins ?? 0);
            $contasareceber->rf_csll                        = $format2Decimals($object->rf_csll ?? 0);
            $contasareceber->rp_inss                        = $format2Decimals($object->rp_inss ?? 0);
            $contasareceber->rm_iss                         = $format2Decimals($object->rm_iss ?? 0);
            $contasareceber->re_icms                        = $format2Decimals($object->re_icms ?? 0);

            $id_produto      = $object->produto_id;
            $objeto_produto  = Produto::find($id_produto);
            if ($objeto_produto) 
            {
                $contasareceber->pla_codigo_id = $objeto_produto->pla_codigo_id;
            }
            $contasareceber->natureza_id                    = 2;
            $contasareceber->dt_emissao                     = date('Y-m-d');
            $contasareceber->dt_vencimento                  = $object->horario_inicial;
            $contasareceber->cobranca_id                    = $object->cobranca_id;
            $contasareceber->quitada                        = 'N';
            $contasareceber->data_quitacao                  = null;
            $contasareceber->data_inclusao                  = date('Y-m-d');
            $contasareceber->hora_inclusao                  = date('H:i:s');
            $contasareceber->usuario_inclusao               = TSession::getValue('userid');
            $contasareceber->geracaotitulo_id               = TSession::getValue('userid');
            $contasareceber->tipo_lancamento                = 'P';

            // GARANTIA FINAL NA CONTA (força string com 2 casas)
            foreach ($campos_monetarios as $campo) 
            {
                $contasareceber->$campo = $format2Decimals($contasareceber->$campo ?? 0);
            }

            foreach ($campos_percentuais as $campo) 
            {
                $contasareceber->$campo = $format2Decimals($contasareceber->$campo ?? 0);
            }
            $contasareceber->valor_original                 = '0.00';
            $contasareceber->valor_liquido                  = '0.00';
            $contasareceber->valor_quitado                  = '0.00';
            $contasareceber->desconto                       = '0.00';
            $contasareceber->juros                          = '0.00';
            $contasareceber->multa                          = '0.00';
            $contasareceber->store();
        }

        TTransaction::close();
        $messageAction = new TAction(['AgendamentoList', 'onShow']);
        if (!empty($param['target_container'])) 
        {
            $messageAction->setParameter('target_container', $param['target_container']);
        }

        new TMessage('info', '<b>' . TSession::getValue('username') . '</b> - Registro salvo com sucesso!', $messageAction);
        TWindow::closeWindow(parent::getId());
    }
    catch (Exception $e)
    {
        TTransaction::rollback();
        TTransaction::open(self::$database);
            $data = $this->form->getData();

            TCombo::reload(self::$formName, 'fornecedor_id', []);
            TForm::sendData(self::$formName, (object)['fornecedor_id' => null]);

            $criteria = new TCriteria;
            $criteria->add(new TFilter('paciente_id', '=', $data->paciente_id));
            $criteria->add(new TFilter('status', '=', 'A'));
            $criteria->setProperty('order', 'fornecedor_id');

            $repo               = new TRepository('PessoaConvenioparceria');
            $convenios          = $repo->load($criteria);
            $optionsFornecedor  = [];
            foreach ($convenios as $convenio) 
            {
                if ($convenio->fornecedor) 
                {
                    $optionsFornecedor[$convenio->fornecedor_id] = $convenio->fornecedor_id . ' - ' . $convenio->fornecedor->nome;
                }
            }
            TCombo::reload(self::$formName, 'fornecedor_id', $optionsFornecedor);
            $data->fornecedor_id = null;

            TCombo::reload(self::$formName, 'produto_id', []);
            $data->produto_id = null;

            $this->form->setData($data);
        TTransaction::close();
        new TMessage('error', '<b>' . TSession::getValue('username') . '</b><br>' . $e->getMessage());
    }

    }
    public function onEdit( $param )//</ini>
    {
        try
        {
            if (isset($param['key']))
            {
                $key                     = $param['key'];  // get the parameter $key
                self::$editando_registro = true;
                $isDuplicado             = (isset($param['duplicado']) && $param['duplicado'] == 'true');

                // Inicializar $object->modo_form para evitar erros
                $modo_form = 'edit'; // padrão
                if ($isDuplicado) 
                {
                    $modo_form = 'duplicado';
                }

                TTransaction::open(self::$database); // open a transaction

                $object                 = new Agendamento($key); // instantiates the Active Record
                self::$objeto_original  = clone $object;
                $object->modo_form      = $modo_form;

                // PRESERVAR VALORES ORIGINAIS ANTES DE QUALQUER PROCESSAMENTO
                // Usar valores do banco diretamente para evitar problemas de formatação
                $valor_taxaentregaexame_original         = $object->valor_taxaentregaexame;
                $valor_receber_original                  = $object->valor_receber;
                $valor_venda_original                    = $object->valor_venda;
                $percentual_desconto_maximo_original     = $object->percentual_desconto_maximo;
                $percentual_desconto_utilizado_original  = $object->percentual_desconto_utilizado;

                // Validação: Preenchimento do ambiente_id a partir do slot
                if (isset($param['from_slot']) && $param['from_slot'] == 'true' && !empty($param['ambiente_id']))
                {
                    $object->ambiente_id = $param['ambiente_id'];
                }

                // Preparaçăo de dados do paciente
                $paciente           = $object->paciente; 
                $paciente_id        = null;
                $titulo_paciente    = '[Paciente năo vinculado]';
                $js_script_coletado = "";                 // Inicializa a string que irá coletar todo o JavaScript

                if (is_object($paciente)) 
                {
                    $paciente_id     = $paciente->id; // Extrai o ID e o caminho da foto para uso posterior
                    $titulo_paciente = $paciente->get_nome_cnpjcpf_idade(); // Define o título formatado
                }

                // Define o Título da página (correçăo do erro 'null' incluída)
                parent::setTitle("AGENDAMENTO {$key} # {$titulo_paciente}");

                // Carregar foto do paciente
                $this->paciente_foto->src = $object->paciente->caminho_foto;

                // === CARREGAR PRODUTO_ID ANTES DE SETAR NO FORMULÁRIO ===
                if (!empty($object->fornecedor_id) && !empty($object->produto_id)) 
                {
                    try 
                    {
                        $conn = TTransaction::get();

                        // Buscar o produto específico que está salvo
                        $sqlProduto = "SELECT 
                                        pfp.fornecedor_id,
                                        pfp.produto_id,
                                        p.descproduto,
                                        pfp.preco_venda,
                                        pfp.percentual_desconto_autorizado,
                                        pfp.valor_taxaentregaexame,
                                        pfp.consulta_retorno AS vconsultaretorno
                                    FROM produto_fornecedorpreco pfp
                                    INNER JOIN produto p ON p.id = pfp.produto_id
                                    WHERE pfp.produto_id = :produto_id
                                    AND pfp.fornecedor_id = :fornecedor_id
                                    AND pfp.status = 'A'
                                    ";

                        $stmt = $conn->prepare($sqlProduto);
                        $stmt->execute([
                            ':produto_id'    => $object->produto_id,
                            ':fornecedor_id' => $object->fornecedor_id
                        ]);
                        $row = $stmt->fetch(PDO::FETCH_ASSOC);

                        if ($row) 
                        {
                            $label = sprintf('%d %d %s | Valor: %.2f | Procedimento gera retorno: %s',
                                                $row['fornecedor_id'],
                                                $row['produto_id'],
                                                $row['descproduto'] ?? 'Sem nome',
                                                $row['preco_venda'] ?? 0,                                            
                                                $row['vconsultaretorno'] === 'S' ? 'Sim' : 'Năo'
                                                );

                            // Recarregar combo APENAS com este produto
                            TCombo::reload(self::$formName, 'produto_id', [$object->produto_id => $label]);
                        }
                    } 
                    catch (Exception $e) 
                    {
                        // Silenciosamente ignora erro e continua
                    }
                }
                else if (!empty($object->fornecedor_id))
                {
                    // Se tem fornecedor mas năo tem produto, carregar lista completa
                    try 
                    {
                        $conn = TTransaction::get();

                        $sqlProdutos = "SELECT 
                                            pfp.fornecedor_id,
                                            pfp.produto_id,
                                            p.descproduto,
                                            pfp.preco_venda,
                                            pfp.percentual_desconto_autorizado,
                                            pfp.valor_taxaentregaexame,
                                            pfp.consulta_retorno AS vconsultaretorno
                                        FROM produto_fornecedorpreco pfp
                                        INNER JOIN produto p ON p.id = pfp.produto_id
                                        WHERE pfp.fornecedor_id = :fornecedor_id
                                        AND pfp.status = 'A'
                                        ORDER BY p.descproduto
                                        ";

                        $stmt = $conn->prepare($sqlProdutos);
                        $stmt->execute([':fornecedor_id' => $object->fornecedor_id]);
                        $produtoOptions = [];

                        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) 
                        {
                            $label = sprintf('%d %d %s | Valor: %.2f | Procedimento gera retorno: %s',
                                                $row['fornecedor_id'],
                                                $row['produto_id'],
                                                $row['descproduto'] ?? 'Sem nome',
                                                $row['preco_venda'] ?? 0,                                            
                                                $row['vconsultaretorno'] === 'S' ? 'Sim' : 'Năo'
                                                );

                            $produtoOptions[$row['produto_id']] = $label;
                        }

                        TCombo::reload(self::$formName, 'produto_id', $produtoOptions);
                    } 
                    catch (Exception $e) 
                    {
                        // Silenciosamente ignora erro
                    }
                }
                else
                {
                    // Sem fornecedor, mostrar vazio
                    TCombo::reload(self::$formName, 'produto_id', ['' => 'Selecione um convęnio']);
                }
                // === FIM CARREGAMENTO PRODUTO_ID ===

                // CARREGAR GUIA PRINCIPAL AO EDITAR
                if (!empty($object->guia_conveniocab_id)) 
                {
                    try 
                    {
                        $guia = GuiasconvenioCab::find($object->guia_conveniocab_id);
                        if ($guia) 
                        {
                            // OBTER DADOS DA GUIA COM STATUS E COR
                            $label             = $guia->getLabelComFormatacao();
                            $status            = $guia->getStatusVencimento();
                            $color             = $guia->getCorStatus();
                            $colorEmoji        = ($color == 'red') ? '🔴' : (($color == 'orange') ? '🟠' : '🟢');
                            $labelComIndicador = $colorEmoji . ' ' . $label;

                            // RECARREGAR COMBO COM A GUIA ESPECÍFICA E INDICADOR VISUAL
                            $guiaOptions = [$object->guia_conveniocab_id => $labelComIndicador];
                            TCombo::reload(self::$formName, 'guia_conveniocab_id', $guiaOptions);

                            // FORÇAR SELEÇĂO DA GUIA
                            TScript::create("
                                setTimeout(function() 
                                {
                                    $('#guia_conveniocab_id').val('{$object->guia_conveniocab_id}').trigger('change');
                                }, 300);
                            ");
                        }
                    } 
                    catch (Exception $e) 
                    {
                        // Silenciosamente ignora erro
                    }
                }

                // Recarregar os combos com dados do banco
                self::recarregarCombosEdicao($object);

//Alteração

// 1. RECARREGAR FORNECEDOR_ID COM CRITÉRIO DO PACIENTE
if (!empty($object->paciente_id)) 
{
    try 
    {
        $criteria = TCriteria::create(['paciente_id' => $object->paciente_id]);
        $criteria->add(new TFilter('status', '=', 'A'));

        TDBCombo::reloadFromModel(
            self::$formName, 
            'fornecedor_id', 
            'bdgestorweb', 
            'PessoaConvenioparceria', 
            'fornecedor_id', 
            '{fornecedor_id} - {fornecedor->nome} - Carteirinha: {numero_carteirinha}', 
            'fornecedor_id asc', 
            $criteria, 
            TRUE
        );
    } 
    catch (Exception $e) 
    {
        // continua silenciosamente
    }
}

// 2. RECARREGAR PRODUTO_ID COM CRITÉRIO DO FORNECEDOR
if (!empty($object->fornecedor_id)) 
{
    try 
    {
        $conn = TTransaction::get();

        $sqlProdutos = "SELECT 
                            pfp.fornecedor_id,
                            pfp.produto_id,
                            p.descproduto,
                            pfp.preco_venda,
                            pfp.consulta_retorno AS vconsultaretorno
                        FROM produto_fornecedorpreco pfp
                        INNER JOIN produto p ON p.id = pfp.produto_id
                        WHERE pfp.fornecedor_id = :fornecedor_id
                        AND pfp.status = 'A'
                        ORDER BY p.descproduto";

        $stmt = $conn->prepare($sqlProdutos);
        $stmt->execute([':fornecedor_id' => $object->fornecedor_id]);
        $produtoOptions = [];

        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) 
        {
            $label = sprintf('%d %d %s | Valor: %.2f | Procedimento gera retorno: %s',
                                $row['fornecedor_id'],
                                $row['produto_id'],
                                $row['descproduto'] ?? 'Sem nome',
                                $row['preco_venda'] ?? 0,                                            
                                $row['vconsultaretorno'] === 'S' ? 'Sim' : 'Não'
                                );

            $produtoOptions[$row['produto_id']] = $label;
        }

        TCombo::reload(self::$formName, 'produto_id', $produtoOptions);
    } 
    catch (Exception $e) 
    {
        // continua silenciosamente
    }
}

// 3. RECARREGAR ENTREGA_RESULTADO
if (!empty($object->entrega_resultado)) 
{
    try 
    {
        $items_entrega = [
            'NE' => 'Não tem Exame',
            'EN' => 'Entrega Normal',
            'EU' => 'Entrega Urgente'
        ];

        TCombo::reload(self::$formName, 'entrega_resultado', $items_entrega);
        TField::enableField(self::$formName, 'entrega_resultado');
    } 
    catch (Exception $e) 
    {
        // continua silenciosamente
    }
}

// 4. RECARREGAR GUIA_CONVENIOCAB_ID
if (!empty($object->paciente_id) && !empty($object->fornecedor_id)) 
{
    try 
    {
        $criteria_guia = new TCriteria();
        $criteria_guia->add(new TFilter('pessoa_id', '=', $object->paciente_id));
        $criteria_guia->add(new TFilter('fornecedor_id', '=', $object->fornecedor_id));
        $criteria_guia->add(new TFilter('status', '=', 'A'));

        $conn = TTransaction::get();
        $sql = "SELECT id, guia_convenio FROM guiasconvenio_cab 
                WHERE pessoa_id = :pessoa_id 
                AND fornecedor_id = :fornecedor_id 
                AND status = 'A'
                ORDER BY data_vencimento ASC";

        $stmt = $conn->prepare($sql);
        $stmt->execute([
            ':pessoa_id' => $object->paciente_id,
            ':fornecedor_id' => $object->fornecedor_id
        ]);

        $guiaOptions = [];
        while ($row = $stmt->fetch(PDO::FETCH_OBJ)) 
        {
            $guiaOptions[$row->id] = $row->guia_convenio;
        }

        TCombo::reload(self::$formName, 'guia_conveniocab_id', $guiaOptions);
    } 
    catch (Exception $e) 
    {
        // continua silenciosamente
    }
}

// 5. RECARREGAR GUIA_AUXILIAR_ID se tiver guia principal
if (!empty($object->guia_conveniocab_id)) 
{
    try 
    {
        $conn = TTransaction::get();
        $sql = "SELECT id, guia_codigovalidacao, utilizado 
                FROM guiasconvenio_item 
                WHERE guia_conveniocab_id = :guia_conveniocab_id
                ORDER BY id ASC";

        $stmt = $conn->prepare($sql);
        $stmt->execute([':guia_conveniocab_id' => $object->guia_conveniocab_id]);

        $guiaItemOptions = [];
        while ($row = $stmt->fetch(PDO::FETCH_OBJ)) 
        {
            $label = "{$row->id} - {$row->guia_codigovalidacao} - " . 
                    (($row->utilizado === 'S') ? 'Utilizado' : 'Disponível');
            $guiaItemOptions[$row->id] = $label;
        }

        TCombo::reload(self::$formName, 'guia_auxiliar_id', $guiaItemOptions);
    } 
    catch (Exception $e) 
    {
        // continua silenciosamente
    }
}
//Fim alteração

               // Preencher formulário com dados do objeto
                $this->form->setData($object); // fill the form
// Alteração
// ========================================
// FORÇAR VALORES VIA JAVASCRIPT (após setData)
// ========================================
TScript::create("
    setTimeout(function() 
    {
        // Forçar valores dos combos após carregar
        var fornecedor = document.querySelector('[name=\"fornecedor_id\"]');
        if (fornecedor && '{$object->fornecedor_id}') 
        {
            fornecedor.value = '{$object->fornecedor_id}';
            fornecedor.dispatchEvent(new Event('change', { bubbles: true }));
        }

        var produto = document.querySelector('[name=\"produto_id\"]');
        if (produto && '{$object->produto_id}') 
        {
            produto.value = '{$object->produto_id}';
        }

        var guia = document.querySelector('[name=\"guia_conveniocab_id\"]');
        if (guia && '{$object->guia_conveniocab_id}') 
        {
            guia.value = '{$object->guia_conveniocab_id}';
        }

        var guiaItem = document.querySelector('[name=\"guia_auxiliar_id\"]');
        if (guiaItem && '{$object->guia_auxiliar_id}') 
        {
            guiaItem.value = '{$object->guia_auxiliar_id}';
        }

        var entrega = document.querySelector('[name=\"entrega_resultado\"]');
        if (entrega && '{$object->entrega_resultado}') 
        {
            entrega.value = '{$object->entrega_resultado}';
        }
    }, 500);
");

// ✅ Recarregar dados para edição
if (!empty($object->id)) 
{
    TTransaction::open(self::$database);

    // Recarregar combos com dados atualizados do banco
    if (!empty($object->paciente_id)) 
    {
        $criteria = TCriteria::create(['paciente_id' => $object->paciente_id]);
        $criteria->add(new TFilter('status', '=', 'A'));
        TDBCombo::reloadFromModel(
            self::$formName, 
            'fornecedor_id', 
            'bdgestorweb', 
            'PessoaConvenioparceria', 
            'fornecedor_id', 
            '{fornecedor_id} - {fornecedor->nome} - Carteirinha: {numero_carteirinha}', 
            'fornecedor_id asc', 
            $criteria, 
            TRUE
        );
    }

    // Recarregar produto
    if (!empty($object->fornecedor_id)) 
    {
        $criteria_produto = TCriteria::create(['fornecedor_id' => $object->fornecedor_id]);
        $criteria_produto->add(new TFilter('status', '=', 'A'));
        $criteria_produto->setProperty('order', 'descproduto');
        TDBCombo::reloadFromModel(
            self::$formName,
            'produto_id',
            self::$database,
            'ProdutoFornecedorpreco',
            'produto_id',
            '{fornecedor_id} {produto_id} - {produto->descproduto} Valor: {preco_venda}',
            null,
            $criteria_produto,
            TRUE
        );
    }

    // Recarregar entrega_resultado
    if (!empty($object->entrega_resultado)) 
    {
        $items_entrega = [
            'NE' => 'Não tem Exame',
            'EN' => 'Entrega Normal',
            'EU' => 'Entrega Urgente'
        ];
        TCombo::reload(self::$formName, 'entrega_resultado', $items_entrega);
        TField::enableField(self::$formName, 'entrega_resultado');
    }

    // Recarregar guia convênio
    if (!empty($object->paciente_id) && !empty($object->fornecedor_id)) 
    {
        $criteria_guia = new TCriteria();
        $criteria_guia->add(new TFilter('pessoa_id', '=', $object->paciente_id));
        $criteria_guia->add(new TFilter('fornecedor_id', '=', $object->fornecedor_id));
        $criteria_guia->add(new TFilter('status', '=', 'A'));
        $criteria_guia->setProperty('order', 'data_vencimento asc');
        TDBCombo::reloadFromModel(
            self::$formName,
            'guia_conveniocab_id',
            self::$database,
            'GuiasconvenioCab',
            'id',
            '{fornecedor_id} {id} - Guia do convênio: {guia_convenio}',
            'data_vencimento asc',
            $criteria_guia,
            TRUE
        );
    }

    // Recarregar guia auxiliar
    if (!empty($object->guia_conveniocab_id)) 
    {
        $criteria_auxiliar = new TCriteria();
        $criteria_auxiliar->add(new TFilter('guia_conveniocab_id', '=', $object->guia_conveniocab_id));
        TDBCombo::reloadFromModel(
            self::$formName,
            'guia_auxiliar_id',
            self::$database,
            'GuiasconvenioItem',
            'id',
            '{guia_conveniocab_id} - Guia: {guia_principal} - {id}',
            'id asc',
            $criteria_auxiliar,
            TRUE
        );
    }
}
//Fim alteração
                // === CORREÇÃO: Recarregar opções do fornecedor_id ao editar ===
                if (!empty($object->paciente_id) && !empty($object->fornecedor_id))
                {
                    try
                    {
                        TTransaction::open(self::$database);

                        // Buscar todos os convênios ativos do paciente
                        $criteria = TCriteria::create(['paciente_id' => $object->paciente_id]);
                        $criteria->add(new TFilter('status', '=', 'A'));

                        $repo      = new TRepository('PessoaConvenioparceria');
                        $convenios = $repo->load($criteria);

                        $options = ['' => ''];
                        foreach ($convenios as $convenio)
                        {
                            $fornecedor = $convenio->fornecedor;
                            if ($fornecedor)
                            {
                                $label                              = $convenio->fornecedor_id . ' - ' . $fornecedor->nome . ' - Carteirinha: ' . ($convenio->numero_carteirinha ?? '');
                                $options[$convenio->fornecedor_id]  = $label;

                                // Se for o fornecedor salvo, destacar ou garantir seleção
                                if ($convenio->fornecedor_id == $object->fornecedor_id)
                                {
                                    $selected_label = $label;
                                }
                            }
                        }

                        // Recarregar o combo com as opções corretas
                        TCombo::reload(self::$formName, 'fornecedor_id', $options);

                        // === CORREÇÃO: Recarregar opções do fornecedor_id ao editar ===
                        if (!empty($object->paciente_id) && !empty($object->fornecedor_id))
                        {
                            try
                            {
                                // Buscar todos os convênios ativos do paciente
                                $criteria = TCriteria::create(['paciente_id' => $object->paciente_id]);
                                $criteria->add(new TFilter('status', '=', 'A'));

                                $repo      = new TRepository('PessoaConvenioparceria');
                                $convenios = $repo->load($criteria);

                                $options = ['' => ''];
                                $selected_label = '';

                                foreach ($convenios as $convenio)
                                {
                                    $fornecedor = $convenio->fornecedor;
                                    if ($fornecedor)
                                    {
                                        $label                              = $convenio->fornecedor_id . ' - ' . $fornecedor->nome . ' - Carteirinha: ' . ($convenio->numero_carteirinha ?? '');
                                        $options[$convenio->fornecedor_id]  = $label;

                                        // Se for o fornecedor salvo, guardar o label
                                        if ($convenio->fornecedor_id == $object->fornecedor_id)
                                        {
                                            $selected_label = $label;
                                        }
                                    }
                                }

                                // Recarregar o combo com TODAS as opções
                                TCombo::reload(self::$formName, 'fornecedor_id', $options);

                                // ========================================
                                // NOVO: Forçar o valor selecionado via JavaScript ANTES de desabilitar
                                // ========================================
                                $fornecedor_escaped = addslashes($object->fornecedor_id);
                                TScript::create("
                                    setTimeout(function() 
                                    {
                                        var combo = document.querySelector('[name=\"fornecedor_id\"]');
                                        if (combo) 
                                        {
                                            combo.value = '{$fornecedor_escaped}';
                                            $(combo).trigger('change');
                                        }
                                    }, 300);
                                ");

                                // DEPOIS desabilitar o campo
                                TField::disableField(self::$formName, 'fornecedor_id');

                                TScript::create("
                                    setTimeout(function() 
                                    {
                                        var el = document.querySelector('[name=\"fornecedor_id\"]');
                                        if (el) 
                                        {
                                            el.disabled = true;
                                            el.style.backgroundColor = '#f0f0f0';
                                            el.style.cursor = 'not-allowed';
                                            el.style.opacity = '0.7';
                                        }
                                    }, 500);
                                ");

                                // Trava o botao onsave ate carregar os dados
                                $f_id = (int) $object->id;
                                TScript::create("
                                    $('#btn_salvar_agendamento').html('<i class=\"fa fa-spinner fa-spin\"></i> Aguarde carregando informações ....');
                                    $('[name=\"id\"]').val('{$f_id}').trigger('change');

                                    setTimeout(function() 
                                    {
                                        var b = $('#btn_salvar_agendamento');
                                        if (b.length > 0) 
                                        {
                                            b.prop('disabled', false);
                                            b.attr('style', 'pointer-events: auto; opacity: 1;');
                                            b.html('<i class=\"fas fa-save\" style=\"color:white\"></i> Aguarde atualizando informações ....');

                                            setTimeout(function() 
                                            { 
                                                b.html('<i class=\"fas fa-save\" style=\"color:white\"></i> Salvar'); 
                                            }, 2800);
                                        }
                                    }, 2800);
                                ");
                            }
                            catch (Exception $e)
                            {
                                new TMessage('error', 'Erro ao carregar convênios do paciente: ' . $e->getMessage());
                            }
                        }
// === FIM DA CORREÇÃO ===
/*
// Trava o botao onsave ate carregar os dados
TScript::create("
    setTimeout(function() 
    {
        var combo = document.querySelector('[name=\"fornecedor_id\"]');
        if (combo) 
        {
            combo.value = '{$object->fornecedor_id}';
            $(combo).trigger('change');
        }
    }, 700);
");
*/
                        // Trava o botao onsave ate carregar os dados
                        $f_id = (int) $object->id;
                        TScript::create("
                            $('#btn_salvar_agendamento').html('<i class=\"fa fa-spinner fa-spin\"></i> Aguarde carregando informações ....');
                            $('[name=\"id\"]').val('{$f_id}').trigger('change');

                            setTimeout(function() 
                            {
                                var b = $('#btn_salvar_agendamento');
                                if (b.length > 0) 
                                {
                                    b.prop('disabled', false);
                                    b.attr('style', 'pointer-events: auto; opacity: 1;');
                                    b.html('<i class=\"fas fa-save\" style=\"color:white\"></i> Aguarde atualizando informações ....');

                                    setTimeout(function() 
                                    { 
                                        b.html('<i class=\"fas fa-save\" style=\"color:white\"></i> Salvar'); 
                                    }, 2800);
                                }
                            }, 2800);
                        ");

                        TTransaction::close();
                    }
                    catch (Exception $e)
                    {
                        TTransaction::rollback();
                        new TMessage('error', 'Erro ao carregar convênios do paciente: ' . $e->getMessage());
                    }
                }
                // === FIM DA CORREÇÃO ===
                // CONFIGURAR STATUS DO AGENDAMENTO
                $this->configurarStatus($object, $isDuplicado);

                // ================= SOLUÇÃO DEFINITIVA: USAR JAVASCRIPT PARA DEFINIR VALORES =================
                // O TForm::sendData não está funcionando corretamente para valor_taxaentregaexame
                // Vamos usar JavaScript para injetar diretamente os valores formatados

                // Função auxiliar para formatar valores para campos TNumeric
                $formatarValor = function($valor) 
                {
                    if (empty($valor) && $valor !== '0' && $valor !== 0) 
                    {
                        return '';
                    }
                    // Converter para double e formatar com 2 decimais, vírgula como separador decimal
                    $valor_double = str_replace(',', '.', str_replace('.', '', $valor));
                    return  number_format($valor_double, 2, ',', '.');
                };

                // Preparar valores formatados
                $valores_js = 
                [
                    'valor_taxaentregaexame'            => $formatarValor($valor_taxaentregaexame_original),
                    'valor_venda'                       => $formatarValor($valor_venda_original),
                    'valor_receber'                     => $formatarValor($valor_receber_original),
                    'percentual_desconto_maximo'        => $formatarValor($percentual_desconto_maximo_original),
                    'percentual_desconto_utilizado'     => $formatarValor($percentual_desconto_utilizado_original)
                ];

                // Criar script JavaScript para injetar valores
                $js = "(function() {\n";
                $js .= "  function definirValor(campoNome, valor) {\n";
                $js .= "    var campo = document.querySelector('[name=\"' + campoNome + '\"]');\n";
                $js .= "    if (campo) {\n";
                $js .= "      campo.value = valor;\n";
                $js .= "      // IMPORTANTE: Não disparar eventos para evitar onexittemetregaresultado\n";
                $js .= "      // campo.dispatchEvent(new Event('change', { bubbles: true }));\n";
                $js .= "      // campo.dispatchEvent(new Event('input',  { bubbles: true }));\n";
                $js .= "    }\n";
                $js .= "    }\n";
                $js .= "  \n";
                $js .= "  // Tentar definir valores após 500ms\n";
                $js .= "  setTimeout(function() {\n";

                foreach ($valores_js as $campo => $valor) 
                {
                    $valor_escape = addslashes($valor);
                    $js .= "    definirValor('$campo', '$valor_escape');\n";
                }

                $js .= "  }, 500);\n";
                $js .= "  \n";
                $js .= "  // Tentar novamente após 1s para garantir\n";
                $js .= "  setTimeout(function() {\n";

                foreach ($valores_js as $campo => $valor) 
                {
                    $valor_escape = addslashes($valor);
                    $js .= "    definirValor('$campo', '$valor_escape');\n";
                }

                $js .= "  }, 1000);\n";
                $js .= "})();";

                TScript::create($js);
                // ================= FIM DA SOLUÇÃO =================

                // Verificar contas abertas
                if ($paciente_id) 
                {
                    $js_script_coletado .= self::verificarContasAbertas($paciente_id) . "\n";
                }

                if (!empty($js_script_coletado)) 
                {
                    TScript::create("
                        $(document).ready(function() 
                        {
                            " . $js_script_coletado . "
                        });
                    ");
                }

                // Garante que o botão tenha um ID para ser manipulado via JavaScript.
                $this->btn_onsave->{'id'} = 'btn-salvar-agendamento';
                // Injete o script com uma garantia de execução.
                TScript::create("
                    (function() 
                    {
                        var button = document.getElementById('btn-salvar-agendamento');
                        if (button) 
                        {
                            button.disabled = true;
                            setTimeout(function() 
                            {
                                button.disabled = false;
                            }, 3200);
                        }
                    })();
                ");

                // ATUALIZAR DIA DA SEMANA
                if (!empty($object->horario_inicial)) 
                {
                    $data_obj = self::parseDateTime($object->horario_inicial);
                    if ($data_obj) 
                    {
                        $dia_semana = self::getDiaSemanaFormatado($data_obj);

                        // USAR JAVASCRIPT PARA ATUALIZAR
                        $dia_semana_escaped = addslashes($dia_semana);
                        TScript::create("
                            setTimeout(function() 
                            {
                                \$('[name=\"vdiadasemana01\"]').val('{$dia_semana_escaped}');
                            }, 100);
                        ");
                    }
                }

                // Após fechar transação, disparar eventos para carregar dados dependentes
                TScript::create("
                    $(document).ready(function() 
                    {
                        // Disparar eventos para carregar dados dependentes
                        if ($('#fornecedor_id').val()) 
                        {
                            $('#fornecedor_id').trigger('change');
                        }

                        if ($('#guia_conveniocab_id').val()) 
                        {
                            setTimeout(function() 
                            {
                                $('#guia_conveniocab_id').trigger('change');
                            }, 800);
                        }

                        // Atualizar labels de obrigatoriedade das guias
                        setTimeout(function() 
                        {
                            if ($('#guia_conveniocab_id').val()) 
                            {
                                $('label:contains(\"GUIA DE ATENDIMENTO:\")').html('<font size=\"4\" class=\"bolded\" color=\"red\">*</font>GUIA DE ATENDIMENTO:');
                                $('label:contains(\"GUIA AUXILIAR:\")').html('<font size=\"4\" class=\"bolded\" color=\"red\">*</font>GUIA AUXILIAR:');
                            }
                        }, 1000);
                    });
                ");  

                TTransaction::close();
            }
            else
            {
                self::$editando_registro = false;
                self::$objeto_original   = null;
                $this->form->clear();
            }
        }
        catch (Exception $e) // in case of exception
        {
            self::$editando_registro = false;
            self::$objeto_original   = null;
            new TMessage('error', '<b>' . TSession::getValue('username') . '</b> - Erro ao carregar registro: ' . $e->getMessage());
            TTransaction::rollback(); // undo all pending operations
        }

////////////////////////////////////////////////////////////////////        
    }//</end>

//</generated-onEdit>

    /**
     * Clear form data
     * @param $param Request
     */
    public function onClear( $param )
    {
        $this->form->clear(true);

        //<onFormClear>

        // Limpar sessão do profissional
        TSession::setValue('profissional_id_inclusao', null);

        //</onFormClear>

    }

    public function onShow($param = null)
    {

        //<onShow>

    // COMPORTAMENTO NORMAL
    $buttonsToDisable = 
    [
        'btn_atualizardadospaciente', 'btn_verificafinanceiro',
        'btn_copiarnumeocarterinha', 'btn_confirmar', 'btn_desmarcar',
        'btn_recepcao', 'btn_naocompareceu', 'btn_finalizar',
        'btn_retorno', 'btn_duplicar', 'btn_cancelar', 'btn_protocoloepreparo'
    ];

    foreach ($buttonsToDisable as $button) 
    {
        TButton::disableField(self::$formName, $button);
    }

    // Habilitar campo entrega_resultado apenas se necessário
    if (empty($param['key']))
    {
        $initial_items = ['' => 'Selecione primeiro o procedimento'];
        TCombo::reload(self::$formName, 'entrega_resultado', $initial_items, true);
        TField::disableField(self::$formName, 'entrega_resultado');
        TSession::setValue('profissional_id_inclusao', null);
    }

        //</onShow>
    } 

    public function fireEvents( $object )
    {
        $obj = new stdClass;
        if(is_object($object) && get_class($object) == 'stdClass')
        {
            if(isset($object->paciente_id))
            {
                $value = $object->paciente_id;

                $obj->paciente_id = $value;
            }
            if(isset($object->fornecedor_id))
            {
                $value = $object->fornecedor_id;

                $obj->fornecedor_id = $value;
            }
            if(isset($object->produto_id))
            {
                $value = $object->produto_id;

                $obj->produto_id = $value;
            }
            if(isset($object->guia_conveniocab_id))
            {
                $value = $object->guia_conveniocab_id;

                $obj->guia_conveniocab_id = $value;
            }
            if(isset($object->guia_auxiliar_id))
            {
                $value = $object->guia_auxiliar_id;

                $obj->guia_auxiliar_id = $value;
            }
            if(isset($object->produto_id))
            {
                $value = $object->produto_id;

                $obj->produto_id = $value;
            }
            if(isset($object->entrega_resultado))
            {
                $value = $object->entrega_resultado;

                $obj->entrega_resultado = $value;
            }
        }
        elseif(is_object($object))
        {
            if(isset($object->paciente_id))
            {
                $value = $object->paciente_id;

                $obj->paciente_id = $value;
            }
            if(isset($object->fornecedor_id))
            {
                $value = $object->fornecedor_id;

                $obj->fornecedor_id = $value;
            }
            if(isset($object->produto_id))
            {
                $value = $object->produto_id;

                $obj->produto_id = $value;
            }
            if(isset($object->guia_conveniocab_id))
            {
                $value = $object->guia_conveniocab_id;

                $obj->guia_conveniocab_id = $value;
            }
            if(isset($object->guia_auxiliar_id))
            {
                $value = $object->guia_auxiliar_id;

                $obj->guia_auxiliar_id = $value;
            }
            if(isset($object->produto_id))
            {
                $value = $object->produto_id;

                $obj->produto_id = $value;
            }
            if(isset($object->entrega_resultado))
            {
                $value = $object->entrega_resultado;

                $obj->entrega_resultado = $value;
            }
        }
        TForm::sendData(self::$formName, $obj);
    }  

    public static function getFormName()
    {
        return self::$formName;
    }

    //</hideLine> <addUserFunctionsCode/>

    //<userCustomFunctions>

/*
public function onClose()
{
    parent::onClose();

    // 🔁 Recarrega a lista após fechar o agendamento
    TApplication::loadPage(
        'AgendamentoList',
        'onReload'
    );
}
public static function onBeforeClose($param)
{
        $action = new TAction(['AgendamentoCalendarForm02', 'onClose']);
        $action->setParameters($param);
        $name = TSession::getValue('username');

        $url      = $action->serialize(FALSE);
        $formName = self::$formName;

        $action = "__adianti_post_data('{$formName}', '{$url}');";
        $action.= "return false;";

        TScript::create("__adianti_question('Questão', '<b> {$name} </b> - deseja realmente fechar está tela?', function(){ {$action} } , function(){ }, 'Sim', 'Não')");
}

public static function onClose($param)
{
    // A verificação agora depende do parâmetro 'id' que foi passado explicitamente
    if (empty($param['id']))
    {
        // Fecha a janela atual
        parent::closeWindow();

        // Abre a lista atualizada
        TApplication::loadPage('AgendamentoList', 'onReload', []);
    }
    else
    {
        // Salva os dados via postData no form
        AdiantiCoreApplication::postData(self::$formName, 'AgendamentoCalendarForm02', 'onSave', ['static' => 1]);
    }
}

*/
private static function recarregarCombosEdicao($agendamento)
{
    try 
    {
        $formName = self::$formName;

        // DEBUG
        TScript::create("console.log('DEBUG recarregarCombosEdicao: ' + JSON.stringify({
            fornecedor: '{$agendamento->fornecedor_id}',
            produto: '{$agendamento->produto_id}',
            guia: '{$agendamento->guia_conveniocab_id}',
            guia_item: '{$agendamento->guia_auxiliar_id}'
        }));");

        // ========================================
        // 1. RECARREGAR FORNECEDOR_ID
        // ========================================
        if (!empty($agendamento->paciente_id)) 
        {
            $criteria = TCriteria::create(['paciente_id' => $agendamento->paciente_id]);
            $criteria->add(new TFilter('status', '=', 'A'));

            TDBCombo::reloadFromModel(
                $formName, 
                'fornecedor_id', 
                'bdgestorweb', 
                'PessoaConvenioparceria', 
                'fornecedor_id', 
                '{fornecedor_id} - {fornecedor->nome} - Carteirinha: {numero_carteirinha}', 
                'fornecedor_id asc', 
                $criteria, 
                TRUE
            );

            // Forçar seleção do fornecedor via JavaScript
            if (!empty($agendamento->fornecedor_id)) 
            {
                TScript::create("
                    setTimeout(function() 
                    {
                        var select = document.querySelector('[name=\"fornecedor_id\"]');
                        if (select) 
                        {
                            select.value = '{$agendamento->fornecedor_id}';
                            select.dispatchEvent(new Event('change', { bubbles: true }));
                        }
                    }, 300);
                ");
            }
        }

        // ========================================
        // 2. RECARREGAR PRODUTO_ID
        // ========================================
        if (!empty($agendamento->fornecedor_id) && !empty($agendamento->produto_id)) 
        {
            $conn = TTransaction::get();

            $sqlProduto = "SELECT 
                            pfp.fornecedor_id,
                            pfp.produto_id,
                            p.descproduto,
                            pfp.preco_venda,
                            pfp.consulta_retorno AS vconsultaretorno
                        FROM produto_fornecedorpreco pfp
                        INNER JOIN produto p ON p.id = pfp.produto_id
                        WHERE pfp.produto_id = :produto_id
                        AND pfp.fornecedor_id = :fornecedor_id
                        AND pfp.status = 'A'";

            $stmt = $conn->prepare($sqlProduto);
            $stmt->execute([
                ':produto_id'    => $agendamento->produto_id,
                ':fornecedor_id' => $agendamento->fornecedor_id
            ]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);

            if ($row) 
            {
                $label = sprintf('%d %d %s | Valor: %.2f | Procedimento gera retorno: %s',
                                    $row['fornecedor_id'],
                                    $row['produto_id'],
                                    $row['descproduto'] ?? 'Sem nome',
                                    $row['preco_venda'] ?? 0,                                            
                                    $row['vconsultaretorno'] === 'S' ? 'Sim' : 'Não'
                                    );

                TCombo::reload($formName, 'produto_id', [$agendamento->produto_id => $label]);

                // Forçar seleção
                TScript::create("
                    setTimeout(function() 
                    {
                        var select = document.querySelector('[name=\"produto_id\"]');
                        if (select) 
                        {
                            select.value = '{$agendamento->produto_id}';
                            select.dispatchEvent(new Event('change', { bubbles: true }));
                        }
                    }, 400);
                ");
            }
        }

        // ========================================
        // 3. RECARREGAR ENTREGA_RESULTADO
        // ========================================
        if (!empty($agendamento->entrega_resultado)) 
        {
            $items_entrega = [
                'NE' => 'Não tem Exame',
                'EN' => 'Entrega Normal',
                'EU' => 'Entrega Urgente'
            ];

            TCombo::reload($formName, 'entrega_resultado', $items_entrega);
            TField::enableField($formName, 'entrega_resultado');

            // Forçar seleção
            TScript::create("
                setTimeout(function() 
                {
                    var select = document.querySelector('[name=\"entrega_resultado\"]');
                    if (select) 
                    {
                        select.value = '{$agendamento->entrega_resultado}';
                        select.dispatchEvent(new Event('change', { bubbles: true }));
                    }
                }, 500);
            ");
        }

        // ========================================
        // 4. RECARREGAR GUIA_CONVENIOCAB_ID
        // ========================================
        if (!empty($agendamento->guia_conveniocab_id)) 
        {
            $guia = GuiasconvenioCab::find($agendamento->guia_conveniocab_id);
            if ($guia) 
            {
                $label = $guia->getLabelComFormatacao();
                $status = $guia->getStatusVencimento();
                $color = $guia->getCorStatus();

                TCombo::reload($formName, 'guia_conveniocab_id', [$agendamento->guia_conveniocab_id => $label]);

                // Forçar seleção
                TScript::create("
                    setTimeout(function() 
                    {
                        var select = document.querySelector('[name=\"guia_conveniocab_id\"]');
                        if (select) 
                        {
                            select.value = '{$agendamento->guia_conveniocab_id}';
                            select.dispatchEvent(new Event('change', { bubbles: true }));
                        }
                    }, 600);
                ");
            }
        }

        // ========================================
        // 5. RECARREGAR GUIA_AUXILIAR_ID
        // ========================================
        if (!empty($agendamento->guia_auxiliar_id)) 
        {
            $guia_item = GuiasconvenioItem::find($agendamento->guia_auxiliar_id);
            if ($guia_item) 
            {
                $label = sprintf(
                    '%d %d %d %s Status: %s',
                    $guia_item->fornecedor_id,
                    $guia_item->guia_conveniocab_id,
                    $guia_item->id,
                    htmlspecialchars($guia_item->guia_codigovalidacao ?? '—'),
                    ($guia_item->utilizado === 'S') ? 'Utilizado' : 'Disponível'
                );

                TCombo::reload($formName, 'guia_auxiliar_id', [$agendamento->guia_auxiliar_id => $label]);

                // Forçar seleção
                TScript::create("
                    setTimeout(function() 
                    {
                        var select = document.querySelector('[name=\"guia_auxiliar_id\"]');
                        if (select) 
                        {
                            select.value = '{$agendamento->guia_auxiliar_id}';
                            select.dispatchEvent(new Event('change', { bubbles: true }));
                        }
                    }, 700);
                ");
            }
        }

    }
    catch (Exception $e) 
    {
        TScript::create("console.error('Erro em recarregarCombosEdicao: " . addslashes($e->getMessage()) . "');");
    }
}

    /**
    * NOVO MÉTODO: Carregar formulário com dados do retorno
    * Adicionar este método na classe
    */
    public function onShowRetorno($param = null)
    {
        try
        {
            // Recuperar dados da sessão
            $dados_retorno = TSession::getValue('dados_agendamento_retorno');

            if (empty($dados_retorno))
            {
                throw new Exception('<br>Dados do retorno não encontrados na sessão.');
            }

            // Limpar a sessão
            TSession::delValue('dados_agendamento_retorno');

            // Converter array para objeto
            $object = (object) $dados_retorno;

            // ✅ FORÇAR VALORES VAZIOS PARA CAMPOS FINANCEIROS
            $object->valor_venda                    = null;
            $object->valor_custo                    = null;
            $object->valor_receber                  = null;
            $object->valor_contratado               = null;
            $object->percentual_desconto_autorizado = null;
            $object->percentual_desconto_utilizado  = null;
            $object->valor_taxaentregaexame         = null;

            // Preencher o formulário
            $this->form->setData($object);

            // Configurar título
            parent::setTitle("NOVO AGENDAMENTO - RETORNO");

            // Disparar eventos para carregar dados dependentes
            $this->fireEvents($object);

            // ✅ DESABILITAR EDIÇÃO DO PROFISSIONAL
            TScript::create("
                $(document).ready(function() {
                    // Desabilitar campo profissional
                    $('[name=\"profissional_id\"]').prop('disabled', true);
                    $('[name=\"profissional_id\"]').css('background-color', '#f0f0f0');

                    // Limpar campos de valor
                    $('[name=\"valor_venda\"]').val('');
                    $('[name=\"valor_receber\"]').val('');
                    $('[name=\"percentual_desconto_autorizado\"]').val('');
                    $('[name=\"percentual_desconto_utilizado\"]').val('');
                    $('[name=\"valor_taxaentregaexame\"]').val('');

                    // Adicionar badge de retorno
                    $('h4.modal-title').append(' <span class=\"badge badge-warning\">RETORNO</span>');

                    // Destacar que é um retorno
                    $('[name=\"horario_inicial\"]').parent().parent().css('background-color', '#fff3cd');

                    // Mensagem de orientação
                    if (!$('.alert-retorno').length) {
                        $('form').prepend(
                            '<div class=\"alert alert-info alert-retorno\">' +
                            '<i class=\"fa fa-info-circle\"></i> ' +
                            '<strong>Atenção:</strong> Este é um agendamento de RETORNO. ' +
                            'Os valores financeiros devem permanecer zerados. ' +
                            'O profissional não pode ser alterado.' +
                            '</div>'
                        );
                    }
                });
            ");

            // Desabilitar botões de ação
            $buttonsToDisable = [
                'btn_confirmar', 'btn_desmarcar', 'btn_naocompareceu',
                'btn_recepcao', 'btn_finalizar', 'btn_retorno',
                'btn_duplicar', 'btn_cancelar', 'btn_protocoloepreparo'
            ];

            foreach ($buttonsToDisable as $button)
            {
                TButton::disableField(self::$formName, $button);
            }

            // Habilitar botões úteis
            TButton::enableField(self::$formName, 'btn_atualizardadospaciente');
            TButton::enableField(self::$formName, 'btn_verificafinanceiro');
            TButton::enableField(self::$formName, 'btn_copiarnumeocarterinha');
            TButton::enableField(self::$formName, 'btn_calcularnovadataagendamento');
        }
        catch (Exception $e)
        {
            new TMessage('error', '<b>' . TSession::getValue('username') . '</b> ' . $e->getMessage());
        }
    }

    /**
    * Método Auxiliar: Obter Label do Status
    */
    private static function getStatusLabel($status)
    {
        $statusMap = [
            '01' => 'Aguardando Confirmação',
            '02' => 'Confirmado',
            '03' => 'Desmarcou',
            '04' => 'Não Compareceu',
            '12' => 'Finalizado',
            '97' => 'Recepção',
            '98' => 'Lista de Espera',
            '99' => 'Horário Bloqueado'
        ];

        return $statusMap[$status] ?? "Desconhecido ({$status})";
    }

    public function onLoad($param)
    {
        TScript::create("$('#form_AgendamentoForm').data('formData', {});");
    }

    private static function verificarContasAbertas($paciente_id)
    {
        try 
        {
            TTransaction::open(self::$database);
            $conn = TTransaction::get();

            $stmt = $conn->prepare("
                SELECT COUNT(*) AS total
                FROM conta 
                WHERE cliente_id    = :cliente_id
                AND tipo_conta_id   = 1
                AND quitada         = 'N'
            ");

            $stmt->execute([':cliente_id' => $paciente_id]);
            $total = (int) $stmt->fetchColumn();
            TTransaction::close();

            if ($total > 0) 
            {
                $username = TSession::getValue('username') ?? 'USUÁRIO';
                $plural   = ($total > 1) ? 'S' : '';
                $msg      = strtoupper($username) . " - ATENÇÃO: EXISTE {$total} CONTA{$plural} A RECEBER EM ABERTO.";

                TScript::create("
                    (function() 
                    {
                        try 
                        {
                            window.__agendamentoDebug = window.__agendamentoDebug || {};
                            window.__agendamentoDebug.contasAbertas = {$total};

                            var el = document.getElementById('idlabel_msg01');
                            if (!el) 
                            {
                                el = document.createElement('div');
                                el.id = 'idlabel_msg01';
                                var form = document.querySelector('form');
                                if (form && form.parentNode) 
                                {
                                    form.parentNode.insertBefore(el, form);
                                }
                            }

                            if (el) 
                            {
                                el.textContent = " . json_encode($msg) . ";
                                el.style.color = '#d9534f';
                                el.style.backgroundColor = '#f2dede';
                                el.style.padding = '8px 12px';
                                el.style.borderLeft = '4px solid #d9534f';
                                el.style.borderRadius = '4px';
                                el.style.fontWeight = 'bold';
                                el.style.fontSize = '12px';
                                el.style.margin = '10px 0';
                                el.style.display = 'block';
                                el.style.animation = 'blink 2s linear infinite';
                            }

                            if (!document.getElementById('blink-style')) 
                            {
                                var style = document.createElement('style');
                                style.id = 'blink-style';
                                style.textContent = '@keyframes blink {0%,50%{opacity:1;}51%,100%{opacity:0.7;}}';
                                document.head.appendChild(style);
                            }
                        } 
                        catch(e) 
                        {
                            console.warn('Erro ao exibir contas abertas:', e.message);
                        }
                    })();
                ");
            } 
            else 
            {
                TScript::create("
                    (function() 
                    {
                        window.__agendamentoDebug = window.__agendamentoDebug || {};
                        window.__agendamentoDebug.contasAbertas = 0;
                        var el = document.getElementById('idlabel_msg01');
                        if (el) 
                        {
                            el.style.display = 'none';
                        }
                    })();
                ");
            }
        } 
        catch (Exception $e) 
        {
            TScript::create("console.warn('Erro ao verificar contas: " . addslashes($e->getMessage()) . "');");
        }
    }

    private function recarregarCombos($objeto)
    {
        if (!empty($objeto->paciente_id))
        {
            $criteria = TCriteria::create(['paciente_id' => $objeto->paciente_id]);
            $criteria->add(new TFilter('status', '=', 'A'));
            TDBCombo::reloadFromModel(
                self::$formName,
                'fornecedor_id',
                'bdgestorweb',
                'PessoaConvenioparceria',
                'fornecedor_id',
                '{fornecedor_id} - {fornecedor->nome} **Carteirinha: {numero_carteirinha}',
                'fornecedor_id asc',
                $criteria,
                TRUE  // FALSE
            );
        }

        if (!empty($objeto->fornecedor_id))
        {
            $criteria_produto = TCriteria::create(['fornecedor_id' => $objeto->fornecedor_id]);
            $criteria_produto->add(new TFilter('status', '=', 'A'));
            $criteria_produto->setProperty('order', 'descproduto');
            TDBCombo::reloadFromModel(
                self::$formName,
                'produto_id',
                self::$database,
                'ProdutoFornecedorpreco',
                'produto_id',
                '{fornecedor_id} {produto_id} - {produto->descproduto} Valor: {preco_venda} Desconto autorizao: {percentual_desconto_autorizado} Taxa de urgência: {valor_taxaentregaexame} Gera retorno: {vconsultaretorno}',
                null,
                $criteria_produto,
                TRUE
            );
        }

        if (!empty($objeto->paciente_id) && !empty($objeto->fornecedor_id))
        {
            $criteria_guia = new TCriteria();
            $criteria_guia->add(new TFilter('pessoa_id', '=', $objeto->paciente_id));
            $criteria_guia->add(new TFilter('fornecedor_id', '=', $objeto->fornecedor_id));
            $criteria_guia->add(new TFilter('status', '=', 'A'));
            $criteria_guia->setProperty('order', 'data_vencimento asc');
            TDBCombo::reloadFromModel(
                self::$formName,
                'guia_conveniocab_id',
                self::$database,
                'GuiasconvenioCab',
                'id',
                '{fornecedor_id} {id} - Guia do convênio: {guia_convenio} - Senha: {guia_senha} - Saldoxx: {guia_saldo} - Vencimento: {dtvencimento} {statusvencimento}',
                'data_vencimento asc',
                $criteria_guia,
                TRUE
            );
        }

        if (!empty($objeto->guia_conveniocab_id))
        {
            $criteria_auxiliar = new TCriteria();
            $criteria_auxiliar->add(new TFilter('guia_conveniocab_id', '=', $objeto->guia_conveniocab_id));

            if (!empty($objeto->guia_auxiliar_id))
            {
                $criteria_auxiliar->add(new TFilter('id', '=', $objeto->guia_auxiliar_id));
            }
            else
            {
                $criteria_auxiliar->add(new TFilter('utilizado', '=', 'N'));
            }

            TDBCombo::reloadFromModel(
                self::$formName,
                'guia_auxiliar_id',
                self::$database,
                'GuiasconvenioItem',
                'id',
                '{guia_conveniocab_id} - Guia: {guia_principal} - {id} {guia_codigovalidacao} {utilizado}',
                'id asc',
                $criteria_auxiliar,
                TRUE
            );
        }
    }

    public function onShow01($param = null)
    {
        try 
        {
            $buttonsToDisable = 
            [
                'btn_atualizardadospaciente', 'btn_verificafinanceiro', 'btn_copiarnumeocarterinha','btn_confirmar','btn_desmarcar','btn_recepcao','btn_naocompareceu',
                'btn_finalizar','btn_retorno','btn_duplicar','btn_cancelar','btn_protocoloepreparo'
            ];

            foreach ($buttonsToDisable as $button) 
            {
                TButton::disableField(self::$formName, $button);
            }

            // Recupera os dados da sessão
            $filtro = TSession::getValue('filtro_horariodisponivel');

            // Usa os dados de $param, com fallback para $filtro
            $data = (object) 
            [
                'empresa_id'      => $param['empresa_id']       ?? $filtro['empresa_id']        ?? null,
                'profissional_id' => $param['profissional_id']  ?? $filtro['profissional_id']   ?? null,
                'paciente_id'     => $param['paciente_id']      ?? $filtro['paciente_id']       ?? null,
                'horario_inicial' => $param['horario_inicial']  ?? $filtro['horario_inicial']   ?? null,
                'horario_final'   => $param['horario_final']    ?? $filtro['horario_final']     ?? null,
                'ambiente_id'     => $param['ambiente_id']      ?? $filtro['ambiente_id']       ?? null
            ];

            // ⭐️ PREENCHE O FORMULÁRIO COM OS DADOS
            $this->form->setData($data);

            // ⭐️ CRÍTICO: AGORA ATUALIZA O DIA DA SEMANA
            self::atualizarDiaSemanaFromHorario($data->horario_inicial);

            // ⭐️ FORÇAR RECARREGAMENTO DOS COMBOS DEPENDENTES
            if (!empty($data->paciente_id)) 
            {
                $param_onexitpaciente = 
                [
                    'paciente_id' => $data->paciente_id,
                    'key' => $data->paciente_id
                ];
                self::onexitpaciente($param_onexitpaciente);
            }

            if (!empty($data->fornecedor_id)) 
            {
                $param_onexit = 
                [
                    'fornecedor_id' => $data->fornecedor_id,
                    'key'           => $data->fornecedor_id,
                    'paciente_id'   => $data->paciente_id ?? null
                ];
                self::onexitconvenioparceria($param_onexit);
            }

        }
        catch (Exception $e)
        {
            new TMessage('error', '<b>' .TSession::getValue('username').  '</b>' . $e->getMessage());
        }
    } 

    private static function atualizarDiaSemanaFromHorario($horario_inicial)
    {
        try 
        {
            if (empty($horario_inicial)) 
            {
                return;
            }

            // Parsear a data/hora
            $data_obj = self::parseDateTime($horario_inicial);

            if (!$data_obj) 
            {
                return;
            }

            // Obter dia da semana formatado
            $dia_semana = self::getDiaSemanaFormatado($data_obj);

            // Enviar para o formulário
            $object_feedback = new stdClass();
            $object_feedback->vdiadasemana01 = $dia_semana;

            TForm::sendData(self::$formName, $object_feedback, false, 0);

        }
        catch (Exception $e) 
        {
            new TMessage('error', '<b>' . TSession::getValue('username') . '</b><br>❌ Erro ao atualizar dia da semana:<br>' . $e->getMessage());
        }

    }

    protected static function formatarDadosPaciente(object $paciente): string
    {
        // 1. Verificação de existência
        if (empty($paciente->id)) 
        {
            return '';
        }
        return $paciente->get_nome_cnpjcpf_idade();
    }

    //private function configurarStatus($object)
    private function configurarStatus($object, $isDuplicado = false) // <--- Adicionado parâmetro com default false    
    {
        /*
        01:Aguardando confirmação         02:Confirmado         03:Desmarcou         04:Não compareceu         12:Atendimento finalizado         97:Recepção         98:Lista de espera         99:Horário bloqueado
        */
        try 
        {
            // Validação básica
            if (empty($object) || empty($object->status)) 
            {
                return;
            }

            // SE for duplicação, garantimos que os campos fiquem ABERTOS e ignoramos o switch de bloqueio
            if ($isDuplicado)
            {
                    $this->safeSetEditable('horario_inicial', true);
                    $this->safeSetEditable('horario_final', true);
                    $this->safeSetEditable('empresa_id', false);
                    $this->safeSetEditable('paciente_id', false);
                    $this->safeSetEditable('profissional_id', false);
                    $this->safeSetEditable('encaminhamento', false);
                    $this->safeSetEditable('fornecedor_id', false);
                    $this->safeSetEditable('produto_id', false);
                    $this->safeSetEditable('entrega_resultado', true);
                    $this->safeSetEditable('guia_conveniocab_id', true);
                    $this->safeSetEditable('guia_auxiliar_id', true);
                    $this->safeSetEditable('cobranca_id', true);
                    $this->safeSetEditable('valor_receber', true);

                // Ajuste os botões para modo de edição
                    $this->ajustarBotoes(['btn_pacientenovo','btn_naocompareceu', 
                                        'btn_finalizar', 'btn_recepcao', 'btn_retorno','btn_duplicar', 'btn_desmarcar' ]);

                return; // Sai da função para não executar o switch abaixo
            }

            switch ($object->status) 
            {
                case '01': // Aguardando confirmação
                    $this->safeSetEditable('horario_inicial', false);
                    $this->safeSetEditable('horario_final', false);
                    $this->safeSetEditable('empresa_id', false);
                    $this->safeSetEditable('paciente_id', false);
                    $this->safeSetEditable('profissional_id', false);
                    $this->safeSetEditable('encaminhamento', false);
                    $this->safeSetEditable('fornecedor_id', false);
                    $this->safeSetEditable('produto_id', false);
                    $this->safeSetEditable('entrega_resultado', false);
                    $this->safeSetEditable('guia_conveniocab_id', false);
                    $this->safeSetEditable('guia_auxiliar_id', false);
                    $this->safeSetEditable('cobranca_id', false);
                    $this->safeSetEditable('valor_venda', false);
                    $this->safeSetEditable('percentual_desconto_autorizado', false);
                    $this->safeSetEditable('percentual_desconto_utilizado', false);
                    $this->safeSetEditable('valor_taxaentregaexame', false);
                    $this->safeSetEditable('valor_receber', false);
                    //$this->safeSetEditable('observacao', false);
                    //$this->safeSetEditable('ordematendimento', false);
                    //$this->safeSetEditable('ambiente_id', false);
                    //Desabilita botoes
                    $this->ajustarBotoes(['btn_calcularnovadataagendamento','btn_pacientenovo','btn_atualizavalores', 'btn_naocompareceu', 
                                        'btn_finalizar', 'btn_recepcao', 'btn_retorno','btn_duplicar', 'btn_desmarcar' ]);
                    break;

                case '02': // Confirmado
                    $this->safeSetEditable('horario_inicial', false);
                    $this->safeSetEditable('horario_final', false);
                    $this->safeSetEditable('empresa_id', false);
                    $this->safeSetEditable('paciente_id', false);
                    $this->safeSetEditable('profissional_id', false);
                    $this->safeSetEditable('encaminhamento', false);
                    $this->safeSetEditable('fornecedor_id', false);
                    $this->safeSetEditable('produto_id', false);
                    $this->safeSetEditable('entrega_resultado', false);
                    $this->safeSetEditable('guia_conveniocab_id', false);
                    $this->safeSetEditable('guia_auxiliar_id', false);
                    $this->safeSetEditable('cobranca_id', false);
                    $this->safeSetEditable('valor_venda', false);
                    $this->safeSetEditable('percentual_desconto_autorizado', false);
                    $this->safeSetEditable('percentual_desconto_utilizado', false);
                    $this->safeSetEditable('valor_taxaentregaexame', false);
                    $this->safeSetEditable('valor_receber', false);
                    //$this->safeSetEditable('observacao', false);
                    //$this->safeSetEditable('ordematendimento', false);
                    //$this->safeSetEditable('ambiente_id', false);
                    //Desabilita botoes
                    $this->ajustarBotoes(['btn_confirmar', 'btn_retorno', 'btn_calcularnovadataagendamento', 'btn_finalizar',
                                        'btn_pacientenovo','btn_atualizavalores','btn_duplicar']);
                    break;

                case '03': // Desmarcado
                    $this->safeSetEditable('horario_inicial', false);
                    $this->safeSetEditable('horario_final', false);
                    $this->safeSetEditable('empresa_id', false);
                    $this->safeSetEditable('paciente_id', false);
                    $this->safeSetEditable('profissional_id', false);
                    $this->safeSetEditable('encaminhamento', false);
                    $this->safeSetEditable('fornecedor_id', false);
                    $this->safeSetEditable('produto_id', false);
                    $this->safeSetEditable('entrega_resultado', false);
                    $this->safeSetEditable('guia_conveniocab_id', false);
                    $this->safeSetEditable('guia_auxiliar_id', false);
                    $this->safeSetEditable('cobranca_id', false);
                    $this->safeSetEditable('valor_venda', false);
                    $this->safeSetEditable('percentual_desconto_autorizado', false);
                    $this->safeSetEditable('percentual_desconto_utilizado', false);
                    $this->safeSetEditable('valor_taxaentregaexame', false);
                    $this->safeSetEditable('valor_receber', false);
                    $this->safeSetEditable('observacao', false);
                    $this->safeSetEditable('ordematendimento', false);
                    $this->safeSetEditable('ambiente_id', false);

                    $this->ajustarBotoes(['btn_confirmar','btn_desmarcar','btn_naocompareceu','btn_recepcao','btn_finalizar','btn_retorno','btn_duplicar',
                                        'btn_cancelar','btn_protocoloepreparo','btn_calcularnovadataagendamento','btn_atualizardadospaciente','btn_pacientenovo','btn_verificafinanceiro',
                                        'btn_copiarnumeocarterinha','btn_atualizasaladeatendimento','btn_atualizavalores']);

                    break;

                case '04': // Não compareceu
                    $this->safeSetEditable('horario_inicial', false);
                    $this->safeSetEditable('horario_final', false);
                    $this->safeSetEditable('empresa_id', false);
                    $this->safeSetEditable('paciente_id', false);
                    $this->safeSetEditable('profissional_id', false);
                    $this->safeSetEditable('encaminhamento', false);
                    $this->safeSetEditable('fornecedor_id', false);
                    $this->safeSetEditable('produto_id', false);
                    $this->safeSetEditable('entrega_resultado', false);
                    $this->safeSetEditable('guia_conveniocab_id', false);
                    $this->safeSetEditable('guia_auxiliar_id', false);
                    $this->safeSetEditable('cobranca_id', false);
                    $this->safeSetEditable('valor_venda', false);
                    $this->safeSetEditable('percentual_desconto_autorizado', false);
                    $this->safeSetEditable('percentual_desconto_utilizado', false);
                    $this->safeSetEditable('valor_taxaentregaexame', false);
                    $this->safeSetEditable('valor_receber', false);
                    $this->safeSetEditable('observacao', false);
                    $this->safeSetEditable('ordematendimento', false);
                    $this->safeSetEditable('ambiente_id', false);

                    $this->ajustarBotoes(['btn_confirmar','btn_desmarcar','btn_naocompareceu','btn_recepcao','btn_finalizar','btn_retorno',
                                        'btn_cancelar','btn_protocoloepreparo','btn_calcularnovadataagendamento','btn_atualizardadospaciente','btn_pacientenovo','btn_verificafinanceiro',
                                        'btn_copiarnumeocarterinha','btn_atualizasaladeatendimento','btn_atualizavalores']);
                    break;

                case '12': // Finalizado
                    try 
                    {
                    // ========================================
                    // PASSO 1: Desabilitar Campos Editáveis
                    // ========================================
                    $this->safeSetEditable('horario_inicial', false);
                    $this->safeSetEditable('horario_final', false);
                    $this->safeSetEditable('empresa_id', false);
                    $this->safeSetEditable('paciente_id', false);
                    $this->safeSetEditable('profissional_id', false);
                    $this->safeSetEditable('encaminhamento', false);
                    $this->safeSetEditable('fornecedor_id', false);
                    $this->safeSetEditable('produto_id', false);
                    $this->safeSetEditable('entrega_resultado', false);
                    $this->safeSetEditable('guia_conveniocab_id', false);
                    $this->safeSetEditable('guia_auxiliar_id', false);
                    $this->safeSetEditable('cobranca_id', false);
                    $this->safeSetEditable('valor_venda', false);
                    $this->safeSetEditable('percentual_desconto_autorizado', false);
                    $this->safeSetEditable('percentual_desconto_utilizado', false);
                    $this->safeSetEditable('valor_taxaentregaexame', false);
                    $this->safeSetEditable('valor_receber', false);
                    $this->safeSetEditable('observacao', false);
                    $this->safeSetEditable('ordematendimento', false);
                    $this->safeSetEditable('ambiente_id', false);

                    // ========================================
                    // PASSO 2: Desabilitar Botões
                    // ========================================
                    // Desabilitar botões que não são relevantes para agendamento finalizado
                    TButton::disableField(self::$formName, 'btn_confirmar');
                    TButton::disableField(self::$formName, 'btn_desmarcar');
                    TButton::disableField(self::$formName, 'btn_naocompareceu');
                    TButton::disableField(self::$formName, 'btn_recepcao');
                    TButton::disableField(self::$formName, 'btn_finalizar');
                    TButton::disableField(self::$formName, 'btn_cancelar');
                    TButton::disableField(self::$formName, 'btn_protocoloepreparo');
                    TButton::disableField(self::$formName, 'btn_calcularnovadataagendamento');
                    TButton::disableField(self::$formName, 'btn_atualizardadospaciente');
                    TButton::disableField(self::$formName, 'btn_pacientenovo');
                    TButton::disableField(self::$formName, 'btn_verificafinanceiro');
                    TButton::disableField(self::$formName, 'btn_copiarnumeocarterinha');
                    TButton::disableField(self::$formName, 'btn_atualizasaladeatendimento');
                    TButton::disableField(self::$formName, 'btn_atualizavalores');

                    // ========================================
                    // PASSO 3: Lógica Condicional (ProdutoFornecedorpreco)
                    // ========================================
                    // Assumindo que $object contém os dados do agendamento atual
                    $permitirRetorno = false;

                    TTransaction::open(self::$database); // Garante que a transação está aberta
                        // Busca o preço específico para o trio Empresa + Fornecedor + Produto
                        $precoVinculo = ProdutoFornecedorpreco::where('empresa_id',  '=', $object->empresa_id)
                                                            ->where('fornecedor_id', '=', $object->fornecedor_id)
                                                            ->where('produto_id',    '=', $object->produto_id)
                                                            ->first();

                        // Verifica se o registro existe e se o campo consulta_retorno é 'S'
                        if ($precoVinculo && $precoVinculo->consulta_retorno == 'S') 
                        {
                            $permitirRetorno = true;
                        }

                        if ($permitirRetorno) 
                        {
                            // HABILITA btn_retorno, DESABILITA btn_duplicar
                            TButton::enableField(self::$formName,  'btn_retorno');
                            TButton::disableField(self::$formName, 'btn_duplicar');
                        }
                        else 
                        {
                            // DESABILITA btn_retorno, HABILITA btn_duplicar
                            TButton::disableField(self::$formName, 'btn_retorno');
                            TButton::enableField(self::$formName,  'btn_duplicar');
                        }

                    TTransaction::close();
                }
                catch (Exception $e) 
                {
                    $userName = TSession::getValue('username');
                    new TMessage('error', "<b>{$userName}</b> - Erro ao configurar status finalizado: " . $e->getMessage());

                    TButton::disableField(self::$formName, 'btn_retorno');
                    TButton::disableField(self::$formName, 'btn_duplicar');
                }

                break;

                case '97': // Presença na recepção
                    $this->safeSetEditable('horario_inicial', false);
                    $this->safeSetEditable('horario_final', false);
                    $this->safeSetEditable('empresa_id', false);
                    $this->safeSetEditable('paciente_id', false);
                    $this->safeSetEditable('profissional_id', false);
                    $this->safeSetEditable('encaminhamento', false);
                    $this->safeSetEditable('fornecedor_id', false);
                    $this->safeSetEditable('produto_id', false);
                    $this->safeSetEditable('entrega_resultado', false);
                    $this->safeSetEditable('guia_conveniocab_id', false);
                    $this->safeSetEditable('guia_auxiliar_id', false);
                    $this->safeSetEditable('cobranca_id', false);
                    $this->safeSetEditable('valor_venda', false);
                    $this->safeSetEditable('percentual_desconto_autorizado', false);
                    $this->safeSetEditable('percentual_desconto_utilizado', false);
                    $this->safeSetEditable('valor_taxaentregaexame', false);
                    $this->safeSetEditable('valor_receber', false);
                    $this->safeSetEditable('observacao', false);
                    $this->safeSetEditable('ordematendimento', false);
                    $this->safeSetEditable('ambiente_id', false);

                    $this->ajustarBotoes(['btn_confirmar','btn_desmarcar','btn_naocompareceu','btn_recepcao','btn_retorno','btn_duplicar',
                                        'btn_cancelar','btn_protocoloepreparo','btn_calcularnovadataagendamento','btn_atualizardadospaciente','btn_pacientenovo','btn_verificafinanceiro',
                                        'btn_copiarnumeocarterinha','btn_atualizasaladeatendimento','btn_atualizavalores']);
                    break;

                case '98': // Lista de espera
                    $this->safeSetEditable('empresa_id', false);
                    $this->safeSetEditable('origemconsulta_id', false);
                    $this->safeSetEditable('cobranca_id', false);
                    $this->safeSetEditable('paciente_id', false);
                    $this->safeSetEditable('fornecedor_id', false);
                    $this->safeSetEditable('produto_id', false);
                    $this->safeSetEditable('profissional_id', false);
                    $this->safeSetEditable('solicitante', false);
                    $this->safeSetEditable('entrega_resultado', false);
                    $this->safeSetEditable('status', false);
                    $this->safeSetEditable('horario_inicial', false);
                    $this->safeSetEditable('horario_final', false);
                    $this->safeSetEditable('ordematendimento', false);
                    $this->safeSetEditable('ambiente_id', false);
                    $this->safeSetEditable('observacao', false);
                    $this->safeSetEditable('guia_conveniocab_id', false);
                    $this->safeSetEditable('guia_auxiliar_id', false);

                    $this->ajustarBotoes(['btn_confirmar','btn_desmarcar','btn_naocompareceu','btn_recepcao','btn_retorno','btn_duplicar',
                                        'btn_cancelar','btn_protocoloepreparo','btn_calcularnovadataagendamento','btn_atualizardadospaciente','btn_pacientenovo','btn_verificafinanceiro',
                                        'btn_copiarnumeocarterinha','btn_atualizasaladeatendimento','btn_atualizavalores']);
                    break;
            }
        } 
        catch (Exception $e) 
        {
            new TMessage('error', '<b>' . TSession::getValue('username') . '</b> - Erro ao configurar status: ' . $e->getMessage());
        }

    }

    private function ajustarBotoes(array $botoes, $enable = false)
    {
        $metodo = $enable ? 'enableField' : 'disableField';
        foreach ($botoes as $botao) 
        {
            TButton::$metodo(self::$formName, $botao);
        }
    }

    private function safeSetEditable($campo, $editable = true)
    {
        $field = $this->form->getField($campo);
        if ($field) 
        {
            $field->setEditable($editable);
        }
    }

    private static function updateFormDateTimeFields($object): void
    {
        try 
        {
            // Validar e formatar horario_inicial
            if (!empty($object->horario_inicial)) 
            {
                // Tentar múltiplos formatos
                $timestamp = false;

                // Primeiro tenta como DateTime completo
                $dt = DateTime::createFromFormat('Y-m-d H:i:s', $object->horario_inicial);
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('Y-m-d H:i', $object->horario_inicial);
                }
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y H:i:s', $object->horario_inicial);
                }
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y H:i', $object->horario_inicial);
                }

                // Se DateTime funcionou
                if ($dt !== false) 
                {
                    $object->horario_inicial = $dt->format('d-m-Y H:i');
                } 
                // Senão tenta strtotime com segurança
                else 
                {
                    $timestamp = @strtotime($object->horario_inicial);
                    if ($timestamp !== false) 
                    {
                        $object->horario_inicial = date('d-m-Y H:i', $timestamp);
                    }
                    // Se ainda falhar, deixa o valor como está
                }
            }

            // Validar e formatar horario_final
            if (!empty($object->horario_final)) 
            {
                $dt = DateTime::createFromFormat('Y-m-d H:i:s', $object->horario_final);
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('Y-m-d H:i', $object->horario_final);
                }
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y H:i:s', $object->horario_final);
                }
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y H:i', $object->horario_final);
                }

                if ($dt !== false) 
                {
                    $object->horario_final = $dt->format('d-m-Y H:i');
                } 
                else 
                {
                    $timestamp = @strtotime($object->horario_final);
                    if ($timestamp !== false) 
                    {
                        $object->horario_final = date('d-m-Y H:i', $timestamp);
                    }
                }
            }

            TForm::sendData(self::$formName, $object);
        }
        catch (Exception $e) 
        {
            new TMessage('error', '<b>' . TSession::getValue('username') . '</b> - Erro ao formatar datas: ' . $e->getMessage());
        }
    }

    private static function mostrarConfirmacaoRetorno($agendamento, $dias_para_retorno, $quantidade_atual, $quantidade_permitida)
    {
        try 
        {
            $usuario_logado = TSession::getValue('username') ?? 'Usuário';

            $mensagem  = "<b>{$usuario_logado}</b><br><br>";
            $mensagem .= "⚠️ <b>AVISO: Quantidade de retornos excedida!</b><br><br>";
            $mensagem .= "<b>Paciente:</b> " . htmlspecialchars($agendamento->paciente->nome ?? 'N/A') . "<br>";
            $mensagem .= "<b>Retornos já agendados:</b> {$quantidade_atual}<br>";
            $mensagem .= "<b>Permitidos por período:</b> {$quantidade_permitida}<br>";
            $mensagem .= "<b>Dias para o retorno:</b> {$dias_para_retorno} dias<br><br>";
            $mensagem .= "Deseja continuar e agendar este retorno mesmo assim?";

            $param_confirmacao = [
                'agendamento_id' => $agendamento->id,
                'dias_para_retorno' => $dias_para_retorno
            ];

            new TQuestion(
                $mensagem,
                new TAction([__CLASS__, 'onConfirmarRetorno'], $param_confirmacao),
                new TAction([__CLASS__, 'onCancelarRetorno'], [])
            );
        }
        catch (Exception $e) 
        {
            $userName = TSession::getValue('username');
            new TMessage('error', "<b>{$userName}</b> - Erro ao exibir confirmação: " . $e->getMessage());
        }
    }

    public static function onConfirmarRetorno($param = null)
    {
        try 
        {
            if (empty($param['agendamento_id'])) 
            {
                throw new Exception('<br>ID do agendamento não foi fornecido.');
            }

            TTransaction::open(self::$database);
            $agendamento = Agendamento::find($param['agendamento_id']);
            TTransaction::close();

            if (!$agendamento) 
            {
                throw new Exception('<br>Agendamento não encontrado.');
            }

            $dias_para_retorno = (int)($param['dias_para_retorno'] ?? 7);
            self::criarRetorno($agendamento, $dias_para_retorno);
        }
        catch (Exception $e) 
        {
            $userName = TSession::getValue('username');
            new TMessage('error', "<b>{$userName}</b>{$e->getMessage()}");
        }
    }

    public static function onCancelarRetorno($param = null)
    {
        // Apenas fecha o diálogo sem fazer nada
        return;
    }

    private static function criarRetorno($agendamento, $dias_para_retorno)
    {
        try 
        {
            if (empty($agendamento) || empty($agendamento->id)) 
            {
                throw new Exception('<br>Agendamento inválido para criar retorno.');
            }

            TTransaction::open(self::$database);

            // Calcular nova data (data do agendamento original + dias_para_retorno)
            $data_base = DateTime::createFromFormat('Y-m-d H:i:s', $agendamento->horario_inicial);

            if (!$data_base) 
            {
                $data_base = new DateTime($agendamento->horario_inicial);
            }

            $data_base->add(new DateInterval('P' . (int)$dias_para_retorno . 'D'));
            $nova_data_hora = $data_base->format('Y-m-d H:i:s');

            // Criar novo agendamento de retorno
            $retorno                                 = new Agendamento();
            $retorno->empresa_id                     = $agendamento->empresa_id;
            $retorno->paciente_id                    = $agendamento->paciente_id;
            $retorno->profissional_id                = $agendamento->profissional_id;
            $retorno->fornecedor_id                  = $agendamento->fornecedor_id;
            $retorno->produto_id                     = $agendamento->produto_id;
            $retorno->horario_inicial                = $nova_data_hora;
            $retorno->horario_final                  = date('Y-m-d H:i:s', strtotime('+1 hour', strtotime($nova_data_hora)));
            $retorno->status                         = '01'; // Aguardando confirmação
            $retorno->consulta_retorno               = 'S';
            $retorno->agendamento_anterior           = $agendamento->id;
            $retorno->cobranca_id                    = $agendamento->cobranca_id;
            $retorno->valor_venda                    = $agendamento->valor_venda;
            $retorno->valor_receber                  = $agendamento->valor_receber;
            $retorno->percentual_desconto_autorizado = $agendamento->percentual_desconto_autorizado;
            $retorno->percentual_desconto_utilizado  = $agendamento->percentual_desconto_utilizado;
            $retorno->valor_taxaentregaexame         = $agendamento->valor_taxaentregaexame;
            $retorno->entrega_resultado              = $agendamento->entrega_resultado;
            $retorno->ambiente_id                    = $agendamento->ambiente_id;
            $retorno->data_inclusao                  = date('Y-m-d');
            $retorno->hora_inclusao                  = date('H:i:s');
            $retorno->usuario_inclusao               = TSession::getValue('userid');
            $retorno->store();

            // Atualizar agendamento original marcando que tem retorno
            $agendamento->agendamento_retorno = $retorno->id;
            $agendamento->store();

            TTransaction::close();

            // Mensagem de sucesso
            $userName       = TSession::getValue('username');
            $data_formatada = $data_base->format('d/m/Y');
            $hora_formatada = $data_base->format('H:i');

            new TMessage('info', "<b>{$userName}</b><br><br>✅ Retorno agendado com sucesso!<br><br>" .
                "<b>Data:</b> {$data_formatada}<br>" .
                "<b>Horário:</b> {$hora_formatada}<br>" .
                "<b>Agendamento ID:</b> {$retorno->id}");
        }
        catch (Exception $e) 
        {
            if (TTransaction::isOpened()) 
            {
                TTransaction::rollback();
            }

            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

    private static function formatardatas($object): void
    {
        try 
        {
            // Formatar horario_inicial
            if (!empty($object->horario_inicial)) 
            {
                $dt = DateTime::createFromFormat('Y-m-d H:i:s', $object->horario_inicial);
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('Y-m-d H:i', $object->horario_inicial);
                }

                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y H:i:s', $object->horario_inicial);
                }

                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y H:i', $object->horario_inicial);
                }

                if ($dt !== false) 
                {
                    $object->horario_inicial = $dt->format('d-m-Y H:i');
                }
            }

            // Formatar horario_final
            if (!empty($object->horario_final)) 
            {
                $dt = DateTime::createFromFormat('Y-m-d H:i:s', $object->horario_final);
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('Y-m-d H:i', $object->horario_final);
                }

                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y H:i:s', $object->horario_final);
                }

                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y H:i', $object->horario_final);
                }

                if ($dt !== false) 
                {
                    $object->horario_final = $dt->format('d-m-Y H:i');
                }
            }

            // Formatar data_inclusao
            if (!empty($object->data_inclusao)) 
            {
                $dt = DateTime::createFromFormat('Y-m-d', $object->data_inclusao);
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y', $object->data_inclusao);
                }

                if ($dt !== false) 
                {
                    $object->data_inclusao = $dt->format('d-m-Y');
                }
            }

            // Formatar hora_inclusao
            if (!empty($object->hora_inclusao)) 
            {
                $dt = DateTime::createFromFormat('H:i:s', $object->hora_inclusao);
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('H:i', $object->hora_inclusao);
                }

                if ($dt !== false) 
                {
                    $object->hora_inclusao = $dt->format('H:i');
                }
            }

            // Formatar data_alteracao
            if (!empty($object->data_alteracao)) 
            {
                $dt = DateTime::createFromFormat('Y-m-d', $object->data_alteracao);
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y', $object->data_alteracao);
                }

                if ($dt !== false) 
                {
                    $object->data_alteracao = $dt->format('d-m-Y');
                }
            }

            // Formatar hora_alteracao
            if (!empty($object->hora_alteracao)) 
            {
                $dt = DateTime::createFromFormat('H:i:s', $object->hora_alteracao);
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('H:i', $object->hora_alteracao);
                }

                if ($dt !== false) 
                {
                    $object->hora_alteracao = $dt->format('H:i');
                }
            }

            // Formatar data_cancelamento
            if (!empty($object->data_cancelamento)) 
            {
                $dt = DateTime::createFromFormat('Y-m-d', $object->data_cancelamento);
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y', $object->data_cancelamento);
                }

                if ($dt !== false) 
                {
                    $object->data_cancelamento = $dt->format('d-m-Y');
                }
            }

            // Formatar hora_cancelamento
            if (!empty($object->hora_cancelamento)) 
            {
                $dt = DateTime::createFromFormat('H:i:s', $object->hora_cancelamento);
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('H:i', $object->hora_cancelamento);
                }

                if ($dt !== false) 
                {
                    $object->hora_cancelamento = $dt->format('H:i');
                }
            }

        } 
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }            
    }

    private static function parseDateTime($input_str)
    {
        if (empty($input_str)) 
        {
            return null;
        }

        $input_str = trim($input_str);

        // ⭐️ LISTA DE FORMATOS A TENTAR (DO MAIS ESPECÍFICO PARA O MAIS GERAL)
        $formatos = 
        [
            // Formato ISO do banco de dados (2025-10-15 08:00:00)
            'Y-m-d H:i:s',
            'Y-m-d H:i',

            // Formato brasileiro (24/10/2025 15:30)
            'd/m/Y H:i',
            'd/m/Y H:i:s',

            // Formato com hífen (24-10-2025 15:30)
            'd-m-Y H:i',
            'd-m-Y H:i:s',

            // Apenas data
            'd/m/Y',
            'd-m-Y',
            'Y-m-d'
        ];

        // ⭐️ TENTA CADA FORMATO
        foreach ($formatos as $formato) 
        {
            $data_obj = DateTime::createFromFormat($formato, $input_str);

            if ($data_obj !== false) 
            {
                return $data_obj;
            }
        }

        // ⭐️ SE NENHUM FORMATO FUNCIONOU, TENTA COM strtotime COMO ÚLTIMO RECURSO
        $timestamp = @strtotime($input_str);
        if ($timestamp !== false) 
        {
            $data_obj = new DateTime();
            $data_obj->setTimestamp($timestamp);
            return $data_obj;
        }

        return null;
    }

    private static function getDiaSemanaFormatado($data_obj)
    {
        if (!$data_obj) return '';

        $diaDaSemana = $data_obj->format('w');
        $diasDaSemanaEmPortugues = 
        [
            "Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", 
            "Quinta-feira", "Sexta-feira", "Sábado"
        ];
        return $diasDaSemanaEmPortugues[$diaDaSemana] ?? '';
    }

    private static function limparCamposDependentesProfissional($param = null)
    {
        try 
        {
            $formName      = self::$formName;
            $paciente_id   = $param['paciente_id'] ?? null;

            // Limpar campos
            $campos_limpar = 
            [
                'fornecedor_id',
                'produto_id',
                'entrega_resultado',
                'guia_conveniocab_id',
                'guia_auxiliar_id',
                'valor_venda',
                'valor_taxaentregaexame',
                'percentual_desconto_autorizado',
                'percentual_desconto_utilizado',
                'valor_receber'
            ];

            foreach ($campos_limpar as $campo) 
            {
                TField::clearField($formName, $campo);
            }

            // Limpar campos ocultos
            TField::clearField($formName, 'vvalor_venda');
            TField::clearField($formName, 'vvalor_taxaentregaexame');

            // Recarregar fornecedor_id se houver paciente
            if ($paciente_id) 
            {
                TTransaction::open(self::$database);

                $criteria = TCriteria::create(['paciente_id' => $paciente_id]);
                $criteria->add(new TFilter('status', '=', 'A'));

                TDBCombo::reloadFromModel(
                    $formName, 
                    'fornecedor_id', 
                    'bdgestorweb', 
                    'PessoaConvenioparceria', 
                    'fornecedor_id', 
                    '{fornecedor_id} - {fornecedor->nome} - Carteirinha: {numero_carteirinha}', 
                    'fornecedor_id asc', 
                    $criteria, 
                    TRUE
                );

                TTransaction::close();
            } 
            else 
            {
                TCombo::clearField($formName, 'fornecedor_id');
                TCombo::reload($formName,     'fornecedor_id', ['' => '']);
            }

            // Resetar combos
            TCombo::clearField($formName, 'produto_id');
            TCombo::reload($formName,     'produto_id', ['' => 'Selecione um convênio primeiro']);

            TCombo::clearField($formName,   'entrega_resultado');
            TCombo::reload($formName,       'entrega_resultado', ['' => 'Selecione primeiro o procedimento']);
            TField::disableField($formName, 'entrega_resultado');

            TCombo::clearField($formName, 'guia_conveniocab_id');
            TCombo::clearField($formName, 'guia_auxiliar_id');
            TCombo::reload($formName,     'guia_conveniocab_id', ['' => '']);
            TCombo::reload($formName,     'guia_auxiliar_id', ['' => '']);

            // Resetar valores financeiros
            $object_clear = new stdClass();
            $object_clear->valor_venda                    = '';
            $object_clear->valor_taxaentregaexame         = '';
            $object_clear->percentual_desconto_autorizado = '';
            $object_clear->percentual_desconto_utilizado  = '';
            $object_clear->valor_receber                  = '';

            TForm::sendData($formName, $object_clear, false, false);

        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

    public static function onProfissionalAlteradoNaoInclusao($param = null) 
    {
        try 
        {
            // Remover flag de processamento
            TSession::setValue('processando_alteracao_profissional', null);

            $formName              = self::$formName;
            $profissional_anterior = $param['profissional_anterior'] ?? null;

            if ($profissional_anterior) 
            {
                // Restaurar o profissional anterior
                $object_restore                  = new stdClass();
                $object_restore->profissional_id = $profissional_anterior;
                TForm::sendData($formName, $object_restore, false, false);

                // Manter a sessão com o profissional anterior
                TSession::setValue('profissional_id_inclusao', $profissional_anterior);
            }
            else
            {
                //new TMessage('info', '<b>DEBUG 6:</b> Nenhum profissional anterior para restaurar');
            }

        } 
        catch (Exception $e) 
        {
            // Remover flag em caso de erro
            TSession::setValue('processando_alteracao_profissional', null);
            //new TMessage('error', '<b>ERROR onProfissionalAlteradoNaoInclusao:</b> ' . TSession::getValue('username') . ' - ' . $e->getMessage());
        }
    }

    public function onOpenCalendarForm($param = null)
    {
        try
        {
            // Parâmetros recebidos do slot
            $horario_inicial  = $param['horario_inicial']  ?? null;
            $horario_final    = $param['horario_final']    ?? null;
            $profissional_id  = $param['profissional_id']  ?? null;
            $ambiente_id      = $param['ambiente_id']      ?? null;
            $empresa_id       = $param['empresa_id']       ?? TSession::getValue('userunitid');

            if (!$horario_inicial || !$profissional_id)
            {
                new TMessage('error', 'Parâmetros insuficientes para abrir o agendamento.');
                return;
            }

            // Verifica se o horário está bloqueado
            $esta_bloqueado = false;

            TTransaction::open(self::$database);

            // Busca o nome do profissional
            $profissional          = SystemUsers::find($profissional_id);
            $profissional_nome     = $profissional ? $profissional->name : 'Profissional não encontrado';
            $data_hora_inicio      = DateTime::createFromFormat('Y-m-d H:i:s', $horario_inicial);          // Formata as datas/horas para exibição
            $data_hora_fim         = DateTime::createFromFormat('Y-m-d H:i:s', $horario_final);            // Formata as datas/horas para exibição
            $data_formatada        = $data_hora_inicio ? $data_hora_inicio->format('d-m-Y') : $horario_inicial;            
            $hora_inicio_formatada = $data_hora_inicio ? $data_hora_inicio->format('H:i') : '';
            $hora_fim_formatada    = $data_hora_fim ? $data_hora_fim->format('H:i') : '';

            // Verifica no banco se está bloqueado
            if ($data_hora_inicio) 
            {
                $dia_semana     = $data_hora_inicio->format('w');
                $hora_inicio_db = $data_hora_inicio->format('H:i:s');

                // Busca na tabela pessoa_horarios
                $sql = "SELECT status FROM pessoa_horarios 
                    WHERE empresa_id    = :empresa_id 
                    AND profissional_id = :profissional_id 
                    AND dia_da_semana   = :dia_semana 
                    AND hora_inicio     = :hora_inicio";

                $conn = TTransaction::get();
                $stmt = $conn->prepare($sql);
                $stmt->bindValue(':empresa_id', $empresa_id, PDO::PARAM_INT);
                $stmt->bindValue(':profissional_id', $profissional_id, PDO::PARAM_INT);
                $stmt->bindValue(':dia_semana', $dia_semana, PDO::PARAM_INT);
                $stmt->bindValue(':hora_inicio', $hora_inicio_db, PDO::PARAM_STR);
                $stmt->execute();

                $result = $stmt->fetch(PDO::FETCH_OBJ);
                if ($result) 
                {
                    $esta_bloqueado = ($result->status === 'B');
                }
            }

            TTransaction::close();

            // Prepara os parâmetros que serão passados para o formulário
            $pass = 
            [
                'empresa_id'      => $empresa_id,
                'profissional_id' => $profissional_id,
                'paciente_id'     => $param['paciente_id'] ?? null,
                'horario_inicial' => $horario_inicial,
                'horario_final'   => $horario_final,
                'ambiente_id'     => $ambiente_id
            ];

            // Armazena na sessão para uso posterior
            TSession::setValue('filtro_horariodisponivel', $pass);

            if ($esta_bloqueado)
            {
                // Mensagem de confirmação para horário BLOQUEADO
                $mensagem  = "<b>ATENÇÃO: Este horário está BLOQUEADO!</b><br><br>";
                $mensagem .= "<b>Profissional:</b> {$profissional_nome}<br>";
                $mensagem .= "<b>Data:</b> {$data_formatada}<br>";
                $mensagem .= "<b>Horário:</b> {$hora_inicio_formatada} às {$hora_fim_formatada}<br><br>";
                $mensagem .= "Deseja agendar mesmo assim?";

                // Usa TQuestion padrão do Adianti com ações serializáveis
                new TQuestion(
                    $mensagem,
                    new TAction([__CLASS__, 'abrirFormularioAcaoSim'], $pass),
                    null // Não faz nada ao clicar em Não
                );
            }
            else
            {
                // Horário NÃO bloqueado - abre diretamente o formulário
                self::abrirFormularioAcaoSim($pass);
            }
        }
        catch (Exception $e)
        {
            //new TMessage('error', '<b>ERRO em onOpenCalendarForm:</b><br>' . $e->getMessage());
        }
    }

    public static function abrirFormularioAcaoSim($param = null)
    {
        try 
        {
            // Remove parâmetros extras que podem causar problemas
            $clean_params = [];
            $valid_keys   = ['empresa_id', 'profissional_id', 'paciente_id', 'horario_inicial', 'horario_final', 'ambiente_id'];

            foreach ($valid_keys as $key) 
            {
                if (isset($param[$key])) 
                {
                    $clean_params[$key] = $param[$key];
                }
            }

            // Usa o método padrão do Adianti para carregar páginas
            AdiantiCoreApplication::loadPage('AgendamentoCalendarForm02', 'onShow01', $clean_params);

        } 
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

   /**
     * Desabilita os campos de formulário
     */
    private static function disableFormFields(): void
    {
        // Usando um array para iteração para reduzir repetição de código
        $fieldsToDisable = ['horario_inicial',
                            'horario_final',
                            'empresa_id',
                            'paciente_id',
                            'profissional_id',
                            'encaminhamento',
                            'fornecedor_id',
                            'produto_id',
                            'entrega_resultado',
                            'guia_auxiliar_id',
                            'guia_conveniocab_id',
                            'guia_principal',
                            'cobranca_id',
                            'valor_venda',
                            'percentual_desconto_autorizado',
                            'percentual_desconto_utilizado',
                            'valor_taxaentregaexame',
                            'valor_receber',
                            ];

        foreach ($fieldsToDisable as $fieldName) 
        {
            // Verifica o tipo de campo para chamar a função correta
            if (in_array($fieldName, 
                            ['horario_inicial',
                             'horario_final',
                             'empresa_id',
                             'paciente_id',
                             'profissional_id',
                             'encaminhamento',
                             'fornecedor_id',
                             'produto_id',
                             'entrega_resultado',
                             'guia_auxiliar_id',
                             'guia_conveniocab_id',
                             'guia_principal',
                             'cobranca_id',
                             'valor_venda',
                             'percentual_desconto_autorizado',
                             'percentual_desconto_utilizado',
                             'valor_taxaentregaexame',
                             'valor_receber',
                            ])) 
            {
                TDBCombo::disableField(self::$formName, $fieldName);
            } 
            elseif (in_array($fieldName, ['horario_inicial', 'horario_final'])) 
            {
                TDateTime::disableField(self::$formName, $fieldName);
            } 
            else 
            {
                TCombo::disableField(self::$formName, $fieldName);
            }
        }
    }

//------------------------------------------------------------------------------------------------------------------//
    public static function onconfirmaragendamentoYes($param = null)
    {
        try 
        {
            // Validação: Garantir que o ID foi fornecido
            if (!isset($param['id'])) 
            {
                throw new Exception('<br>ID do agendamento não foi encontrado.');
            }

            $agendamentoId = $param['id'];

            // Inicia a transação
            TTransaction::open(self::$database);
                // Busca o agendamento
                $object = Agendamento::find($agendamentoId); 
                if (!$object) 
                {
                    TTransaction::rollback();
                    throw new Exception("<br>Agendamento com ID {$agendamentoId} não encontrado.");
                }

                // Atualizar os campos
                $object->status              = '02';  // Confirmado
                $object->data_confirmacao    = date('Y-m-d');
                $object->hora_confirmacao    = date('H:i:s');
                $object->usuario_confirmacao = TSession::getValue('userid');
                $object->store();
            TTransaction::close();

            // Recarregar o objeto para garantir valores atualizados do banco
            TTransaction::open(self::$database);
                $object = Agendamento::find($agendamentoId);
            TTransaction::close();

            // Preparar o objeto com formatações corretas para exibição
            self::formatardatas($object);

            TButton::disableField(self::$formName, 'btn_confirmar');
            TButton::enableField(self::$formName,  'btn_desmarcar');
            TButton::enableField(self::$formName,  'btn_naocompareceu');
            TButton::enableField(self::$formName,  'btn_recepcao');
            TButton::disableField(self::$formName, 'btn_finalizar');
            TButton::disableField(self::$formName, 'btn_retorno');
            TButton::disableField(self::$formName, 'btn_duplicar');
            TButton::enableField(self::$formName,  'btn_cancelar');
            TButton::enableField(self::$formName,  'btn_protocoloepreparo');
            TButton::disableField(self::$formName, 'btn_calcularnovadataagendamento');
            TButton::enableField(self::$formName,  'btn_atualizardadospaciente');
            TButton::disableField(self::$formName, 'btn_pacientenovo');
            TButton::disableField(self::$formName, 'btn_verificafinanceiro');
            TButton::enableField(self::$formName,  'btn_copiarnumeocarterinha');
            TButton::disableField(self::$formName, 'btn_atualizasaladeatendimento');
            TButton::disableField(self::$formName, 'btn_atualizavalores');

            // Enviar dados formatados para o formulário
            TForm::sendData(self::$formName, $object);

            // Forçar atualização do campo status (TCombo)
            TField::updateFieldValue('status', $object->status);

            // Forçar atualização via JavaScript como fallback
            $js = "document.getElementsByName('status')[0].value = '{$object->status}';";
            TPage::getPage()->onLoad($js);

            // Mensagem de sucesso
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('info', "<b>{$usuarioLogado}</b> - Agendamento confirmado com sucesso!");
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
            TTransaction::rollback(); // undo all pending operations
        }
    }

    public static function onconfirmaragendamentoNo($param = null) 
    {
        try 
        {
            //code here
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

    public static function oncancelarYes($param = null) 
    {
        try 
        {

            TButton::disableField(self::$formName, 'btn_confirmar');
            TButton::enableField(self::$formName,  'btn_desmarcar');
            TButton::enableField(self::$formName,  'btn_naocompareceu');
            TButton::enableField(self::$formName,  'btn_recepcao');
            TButton::disableField(self::$formName, 'btn_finalizar');
            TButton::disableField(self::$formName, 'btn_retorno');
            TButton::disableField(self::$formName, 'btn_duplicar');
            TButton::enableField(self::$formName,  'btn_cancelar');
            TButton::enableField(self::$formName,  'btn_protocoloepreparo');
            TButton::disableField(self::$formName, 'btn_calcularnovadataagendamento');
            TButton::enableField(self::$formName,  'btn_atualizardadospaciente');
            TButton::disableField(self::$formName, 'btn_pacientenovo');
            TButton::disableField(self::$formName, 'btn_verificafinanceiro');
            TButton::enableField(self::$formName,  'btn_copiarnumeocarterinha');
            TButton::disableField(self::$formName, 'btn_atualizasaladeatendimento');
            TButton::disableField(self::$formName, 'btn_atualizavalores');

        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

    public static function oncancelarNo($param = null) 
    {
        try 
        {
            //code here
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

    public static function onnaocompareceuYes($param = null)
    {
        try 
        {
            if (!isset($param['id'])) 
            {
                throw new Exception('<br>ID do agendamento não foi encontrado.');
            }

            $agendamentoId = $param['id'];

            // Inicia a transação
            TTransaction::open(self::$database);
                // Busca o agendamento
                $object = Agendamento::find($agendamentoId); 
                if (!$object) 
                {
                    TTransaction::rollback();
                    throw new Exception("<br>Agendamento com ID {$agendamentoId} não encontrado.");
                }

                // Atualizar os campos
                $object->status                = '04';  // NÃO COMPARECEU
                $object->data_naocompareceu    = date('Y-m-d');
                $object->hora_naocompareceu    = date('H:i:s');
                $object->usuario_naocompareceu = TSession::getValue('userid');
                $object->store();
            TTransaction::close();

            // Recarregar o objeto para garantir valores atualizados do banco
            TTransaction::open(self::$database);
                $object = Agendamento::find($agendamentoId);
            TTransaction::close();

            // Preparar o objeto com formatações corretas para exibição
            self::formatardatas($object);

            TButton::disableField(self::$formName, 'btn_confirmar');
            TButton::disableField(self::$formName, 'btn_desmarcar');
            TButton::disableField(self::$formName, 'btn_naocompareceu');
            TButton::disableField(self::$formName, 'btn_recepcao');
            TButton::disableField(self::$formName, 'btn_finalizar');
            TButton::disableField(self::$formName, 'btn_retorno');
            TButton::enableField(self::$formName, 'btn_duplicar');
            TButton::disableField(self::$formName, 'btn_cancelar');
            TButton::disableField(self::$formName, 'btn_protocoloepreparo');
            TButton::disableField(self::$formName, 'btn_calcularnovadataagendamento');
            TButton::disableField(self::$formName, 'btn_atualizardadospaciente');
            TButton::disableField(self::$formName, 'btn_pacientenovo');
            TButton::disableField(self::$formName, 'btn_verificafinanceiro');
            TButton::disableField(self::$formName, 'btn_copiarnumeocarterinha');
            TButton::disableField(self::$formName, 'btn_atualizasaladeatendimento');
            TButton::disableField(self::$formName, 'btn_atualizavalores');

            THtmlEditor::disableField(self::$formName, 'observacao');
            TSpinner::disableField(self::$formName, 'ordematendimento');
            TDBCombo::disableField(self::$formName, 'ambiente_id');

            // Enviar dados formatados para o formulário
            TForm::sendData(self::$formName, $object);

            // Forçar atualização do campo status (TCombo)
            TField::updateFieldValue('status', $object->status);

            // Forçar atualização via JavaScript como fallback
            $js = "document.getElementsByName('status')[0].value = '{$object->status}';";
            TPage::getPage()->onLoad($js);

            // Mensagem de sucesso
            $userName = TSession::getValue('username');
            new TMessage('info', "<b>{$userName}</b> - Status 'Não compareceu' confirmado com sucesso!");
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
            TTransaction::rollback(); // undo all pending operations
        }
    }

    public static function onnaocompareceuNo($param = null) 
    {
        try 
        {
            //code here
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

//Confirmar recepção--------------------------------------------------------------------------------------------
    public static function onconfirmarrecepcaoYes($param = null) 
    {
        try 
        {
            if (!isset($param['id'])) 
            {
                throw new Exception('<br>ID do agendamento não foi encontrado.');
            }

            $agendamentoId = $param['id'];

            // Inicia a transação
            TTransaction::open(self::$database);
                // Busca o agendamento
                $object = Agendamento::find($agendamentoId); 
                if (!$object) 
                {
                    TTransaction::rollback();
                    throw new Exception("<br>Agendamento com ID {$agendamentoId} não encontrado.");
                }

                // Atualizar os campos
                $object->status           = '97';  // RECEPÇÃO
                $object->data_recepcao    = date('Y-m-d');
                $object->hora_recepcao    = date('H:i:s');
                $object->usuario_recepcao = TSession::getValue('userid');
                $object->store();
            TTransaction::close();

            // Recarregar o objeto para garantir valores atualizados do banco
            TTransaction::open(self::$database);
                $object = Agendamento::find($agendamentoId);
            TTransaction::close();

            // Preparar o objeto com formatações corretas para exibição
            self::formatardatas($object);

            TButton::disableField(self::$formName, 'btn_confirmar');
            TButton::disableField(self::$formName, 'btn_desmarcar');
            TButton::disableField(self::$formName, 'btn_naocompareceu');
            TButton::disableField(self::$formName, 'btn_recepcao');
            TButton::enableField(self::$formName,  'btn_finalizar');
            TButton::disableField(self::$formName, 'btn_retorno');
            TButton::disableField(self::$formName, 'btn_duplicar');
            TButton::disableField(self::$formName, 'btn_cancelar');
            TButton::disableField(self::$formName, 'btn_protocoloepreparo');
            TButton::disableField(self::$formName, 'btn_calcularnovadataagendamento');
            TButton::disableField(self::$formName, 'btn_atualizardadospaciente');
            TButton::disableField(self::$formName, 'btn_pacientenovo');
            TButton::disableField(self::$formName, 'btn_verificafinanceiro');
            TButton::disableField(self::$formName, 'btn_copiarnumeocarterinha');
            TButton::disableField(self::$formName, 'btn_atualizasaladeatendimento');
            TButton::disableField(self::$formName, 'btn_atualizavalores');

            THtmlEditor::disableField(self::$formName, 'observacao');
            TSpinner::disableField(self::$formName, 'ordematendimento');
            TDBCombo::disableField(self::$formName, 'ambiente_id');

            // Enviar dados formatados para o formulário
            TForm::sendData(self::$formName, $object);

            // Forçar atualização do campo status (TCombo)
            TField::updateFieldValue('status', $object->status);

            // Forçar atualização via JavaScript como fallback
            $js = "document.getElementsByName('status')[0].value = '{$object->status}';";
            TPage::getPage()->onLoad($js);

            // Mensagem de sucesso
            $userName = TSession::getValue('username');
            new TMessage('info', "<b>{$userName}</b> - Status 'Recepção' confirmado!");
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
            TTransaction::rollback(); // undo all pending operations
        }
    }

    public static function onconfirmarrecepcaoNo($param = null) 
    {
        try 
        {
            //code here
        }
        catch (Exception $e) 
        {
            // Usando interpolação de strings para melhor legibilidade
            $userName = TSession::getValue('username');
            new TMessage('error', "<b>{$userName}</b> - {$e->getMessage()}");
        }
    }

//Fim Confirmar recepção------------------------------------------------------------------------------------

//Desmarcar-------------------------------------------------------------------------------------------------
    public static function ondesmarcaragendamentoYes($param = null) 
    {
        try 
        {
            // Inicia a transação
            TTransaction::open(self::$database);

            // 2. Otimização da Leitura: 
            // Garantir que $param['id'] exista antes de chamar find()
            $agendamentoId = $param['id'] ?? null;
            if (!$agendamentoId) 
            {
                throw new Exception('<br>ID do agendamento não fornecido.');
            }

            // Instancia o Active Record
            $object = Agendamento::find($agendamentoId); 

            if (!$object) 
            {
                throw new Exception("<br>Agendamento com ID {$agendamentoId} não encontrado.");
            }

            // 3. Otimização da Gravação (Minimizar as chamadas a funções de data):
            $currentDate               = date('Y-m-d');
            $currentTime               = date('H:i:s');
            $userId                    = TSession::getValue('userid');

            $object->status            = '03';  // DESMARCOU
            $object->data_desmarcou    = $currentDate; 
            $object->hora_desmarcou    = $currentTime;
            $object->usuario_desmarcou = $userId;
            $object->store();

            // Finaliza a transação
            TTransaction::close();

            // 4. Otimização da Manipulação de Campos (Lógica de UI fora da transação de BD):
            self::disableFormFields();
            self::toggleFormButtonsdesmarcar();
            self::updateFormDateTimeFields($object);

            TForm::sendData(self::$formName, $object);

            $userName = TSession::getValue('username');
            new TMessage('info', "<b>{$userName}</b> - Agendamento desmarcado.<br>Clique no botão salvar para continuar.");

        }
        catch (Exception $e) 
        {
            // Fecha a transação em caso de erro
            if (TTransaction::isOpened()) 
            {
                TTransaction::rollback();
            }
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

    public static function ondesmarcaragendamentoNo($param = null) 
    {
        try 
        {
            //code here
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

//Fim Desmarcar-------------------------------------------------------------------------------------------------
    public static function onfinalizarYes($param = null)
    {
        try 
        {
            if (!isset($param['id'])) 
            {
                throw new Exception('<br>ID do agendamento não foi encontrado.');
            }

            $agendamentoId = $param['id'];

            // Inicia a transação
            TTransaction::open(self::$database);
                // Busca o agendamento
                $object = Agendamento::find($agendamentoId); 
                if (!$object) 
                {
                    TTransaction::rollback();
                    throw new Exception("<br>Agendamento com ID {$agendamentoId} não encontrado.");
                }

                // Atualizar os campos
                $object->status              = '12'; //FINALIZADO
                $object->data_finalizacao    = date('Y-m-d');
                $object->hora_finalizacao    = date('H:i:s');
                $object->usuario_finalizacao = TSession::getValue('userid');
                $object->finalizado          = 'S';
                $object->store();

            TTransaction::close();

            // Recarregar o objeto para garantir valores atualizados do banco
            TTransaction::open(self::$database);
                $object = Agendamento::find($agendamentoId);
            TTransaction::close();

            // Preparar o objeto com formatações corretas para exibição
            self::formatardatas($object);

            TButton::disableField(self::$formName, 'btn_confirmar');
            TButton::disableField(self::$formName, 'btn_desmarcar');
            TButton::disableField(self::$formName, 'btn_naocompareceu');
            TButton::disableField(self::$formName, 'btn_recepcao');
            TButton::disableField(self::$formName, 'btn_finalizar');
            TButton::disableField(self::$formName, 'btn_retorno');
            TButton::enableField(self::$formName,  'btn_duplicar');
            TButton::disableField(self::$formName, 'btn_cancelar');
            TButton::disableField(self::$formName, 'btn_protocoloepreparo');
            TButton::disableField(self::$formName, 'btn_calcularnovadataagendamento');
            TButton::disableField(self::$formName, 'btn_atualizardadospaciente');
            TButton::disableField(self::$formName, 'btn_pacientenovo');
            TButton::disableField(self::$formName, 'btn_verificafinanceiro');
            TButton::disableField(self::$formName, 'btn_copiarnumeocarterinha');
            TButton::disableField(self::$formName, 'btn_atualizasaladeatendimento');
            TButton::disableField(self::$formName, 'btn_atualizavalores');

            // Enviar dados formatados para o formulário
            TForm::sendData(self::$formName, $object);

            // Forçar atualização do campo status (TCombo)
            TField::updateFieldValue('status', $object->status);

            // Forçar atualização via JavaScript como fallback
            $js = "document.getElementsByName('status')[0].value = '{$object->status}';";
            TPage::getPage()->onLoad($js);

            // Mensagem de sucesso
            $userName = TSession::getValue('username');
            new TMessage('info', "<b>{$userName}</b> - Status 'Finalizado' com sucesso!");
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
            TTransaction::rollback(); // undo all pending operations
        }
    }

    public static function onfinalizarNo($param = null) 
    {
        try 
        {
            //code here
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

    private static function prepararDuplicacao($param)
    {
        try 
        {
            TTransaction::open(self::$database);

            $agendamento = Agendamento::find($param['id']);

            if (!$agendamento) 
            {
                throw new Exception(TSession::getValue('username') . ' - Agendamento não encontrado para duplicar.');
            }

            $agendamentoClone = new Agendamento();             // Cria novo objeto ao invés de clonar diretamente
            $dados            = $agendamento->toArray();       // Copia os dados necessários (ajuste conforme sua estrutura de tabela)
            unset($dados['id']); // Remove o ID para gerar novo

            // Configura os novos valores
            $dados['agendamento_anterior']           = $agendamento->id;
            $dados['horario_inicial']                = null;
            $dados['horario_final']                  = null;
            $dados['guia_conveniocab_id']            = null;
            $dados['guia_auxiliar_id']               = null;
            $dados['observacao']                     = null;        
            $dados['status']                         = '01'; // Aguardando confirmação
            $dados['finalizado']                     = 'N';
            $dados['cancelado']                      = 'N';
            $dados['geroudesconto']                  = 'N';
            $dados['geroufinanceiro']                = 'N';
            $dados['geroudesconto_id']               = null;
            $dados['motivo_cancelamento']            = null;
            $dados['cobranca_id']                    = $agendamento->cobranca_id;
            $dados['entrega_resultado']              = null;
            $dados['valor_taxaentregaexame']         = null;
            $dados['valor_receber']                  = null;            
            $dados['data_inclusao']                  = date('Y-m-d');
            $dados['hora_inclusao']                  = date('H:i:s');
            $dados['usuario_inclusao']               = TSession::getValue('userid');

            // Atribui os dados ao clone
            $agendamentoClone->fromArray($dados);

            // Salva o clone
            $agendamentoClone->store();

            TTransaction::close();

            return $agendamentoClone;
        } 
        catch (Exception $e) 
        {
            if (TTransaction::getCurrentTransaction()) 
            {
                TTransaction::rollback();
            }
            throw $e;
        }
    }

    public static function onduplicarYes($param = null) 
    {
        try 
        {
            if (!isset($param['id']) || empty($param['id'])) 
            {
                throw new Exception(TSession::getValue('username') . ' - ID do agendamento não informado.');
            }

            // Prepara a duplicação
            $agendamentoClone = self::prepararDuplicacao($param);

            if ($agendamentoClone && $agendamentoClone->id) 
            {
                // Abre o formulário de calendário
                TApplication::loadPage('AgendamentoCalendarForm02', 'onEdit', 
                [
                    'key' => $agendamentoClone->id,
                    'duplicado' => 'true',
                    'agendamento_original' => $param['id']
                ]);
                new TMessage('info', '<b>' .TSession::getValue('username').  '</b>' . "<br>Agendamento {$param['id']} foi duplicado.<br> Faça as alterações necessárias e salve.");
            }

        } 
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }

    }

    public static function onduplicarNo($param = null) 
    {
        try 
        {
            //code here
        }
        catch (Exception $e) 
        {
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';
            new TMessage('error', "<b>{$usuarioLogado}</b> - {$e->getMessage()}");
        }
    }

    /**
     * CORREÇÃO 1: Novo método para restaurar valores originais
     */
    private function restaurarValoresOriginais(
        $taxa_original,
        $receber_original,
        $venda_original,
        $desconto_aut_original,
        $desconto_util_original) 
    {
        // Formatar valores com segurança
        $taxa_formatada          =  number_format($taxa_original, 2, ',', '.');
        $receber_formatada       =  number_format($receber_original, 2, ',', '.');
        $venda_formatada         =  number_format($venda_original, 2, ',', '.');
        $desconto_aut_formatada  =  number_format($desconto_aut_original, 2, ',', '.');
        $desconto_util_formatada =  number_format($desconto_util_original, 2, ',', '.');

        TScript::create("
            (function() 
            {
                setTimeout(function() 
                {
                    try 
                    {
                        var elTaxa = document.querySelector('[name=\"valor_taxaentregaexame\"]');
                        var elReceber = document.querySelector('[name=\"valor_receber\"]');
                        var elVenda = document.querySelector('[name=\"valor_venda\"]');
                        var elDescontoAut = document.querySelector('[name=\"percentual_desconto_autorizado\"]');
                        var elDescontoUtil = document.querySelector('[name=\"percentual_desconto_utilizado\"]');

                        if (elTaxa) 
                        {
                            elTaxa.value = '" . $taxa_formatada . "';
                            elTaxa.dispatchEvent(new Event('change', { bubbles: true }));
                            elTaxa.dispatchEvent(new Event('input', { bubbles: true }));
                        }
                        if (elReceber) 
                        {
                            elReceber.value = '" . $receber_formatada . "';
                            elReceber.dispatchEvent(new Event('change', { bubbles: true }));
                            elReceber.dispatchEvent(new Event('input', { bubbles: true }));
                        }
                        if (elVenda) 
                        {
                            elVenda.value = '" . $venda_formatada . "';
                            elVenda.dispatchEvent(new Event('change', { bubbles: true }));
                            elVenda.dispatchEvent(new Event('input', { bubbles: true }));
                        }
                        if (elDescontoAut) 
                        {
                            elDescontoAut.value = '" . $desconto_aut_formatada . "';
                            elDescontoAut.dispatchEvent(new Event('change', { bubbles: true }));
                            elDescontoAut.dispatchEvent(new Event('input', { bubbles: true }));
                        }
                        if (elDescontoUtil) 
                        {
                            elDescontoUtil.value = '" . $desconto_util_formatada . "';
                            elDescontoUtil.dispatchEvent(new Event('change', { bubbles: true }));
                            elDescontoUtil.dispatchEvent(new Event('input', { bubbles: true }));
                        }
                    } 
                    catch(e) 
                    {
                        //console.error('Erro ao restaurar valores:', e);
                    }
                }, 1000);
            })();
        ");
    }

public static function onProfissionalAlteradoSimInclusao($param = null) 
{
    try 
    {
        $formName = self::$formName;
        $novo_profissional_id = $param['profissional_id'] ?? null;

        // 1. Atualizar a sessão com o novo profissional
        if ($novo_profissional_id) 
        {
            TSession::setValue('profissional_id_inclusao', $novo_profissional_id);
        }

        // 2. Limpar os campos dependentes - usando métodos do Adianti SEM JavaScript
        $campos_limpar = [
            'fornecedor_id',
            'produto_id',
            'entrega_resultado',
            'guia_conveniocab_id',
            'guia_auxiliar_id',
            'valor_venda',
            'valor_taxaentregaexame',
            'percentual_desconto_autorizado',
            'percentual_desconto_utilizado',
            'valor_receber'
        ];

        // Usar TField::clearField que é nativo do Adianti
        foreach ($campos_limpar as $campo) 
        {
            TField::clearField($formName, $campo);
        }

        // Limpar campos ocultos
        TField::clearField($formName, 'vvalor_venda');
        TField::clearField($formName, 'vvalor_taxaentregaexame');

        // 3. Recarregar combos dependentes
        $paciente_id = $param['paciente_id'] ?? null;

        // Recarregar fornecedor_id se houver paciente
        if ($paciente_id) 
        {
            $criteria = TCriteria::create(['paciente_id' => $paciente_id]);
            $criteria->add(new TFilter('status', '=', 'A'));

            // Usar reloadFromModel mas tentar prevenir eventos
            TDBCombo::reloadFromModel(
                $formName, 
                'fornecedor_id', 
                'bdgestorweb', 
                'PessoaConvenioparceria', 
                'fornecedor_id', 
                '{fornecedor_id} - {fornecedor->nome} - Carteirinha: {numero_carteirinha}', 
                'fornecedor_id asc', 
                $criteria, 
                TRUE
            );
        } 
        else 
        {
            TCombo::clearField($formName, 'fornecedor_id');
        }

        // Limpar produto_id
        TCombo::clearField($formName, 'produto_id');
        TCombo::reload($formName, 'produto_id', ['' => 'Selecione um convênio primeiro']);

        // Limpar entrega_resultado
        TCombo::clearField($formName, 'entrega_resultado');
        TCombo::reload($formName, 'entrega_resultado', ['' => 'Selecione primeiro o procedimento']);
        TField::disableField($formName, 'entrega_resultado');

        // Limpar guias
        TCombo::clearField($formName, 'guia_conveniocab_id');
        TCombo::clearField($formName, 'guia_auxiliar_id');
        TCombo::reload($formName, 'guia_conveniocab_id', ['' => '']);
        TCombo::reload($formName, 'guia_auxiliar_id', ['' => '']);

        // Resetar labels de guias - usar método simples
        // Isso será feito no onShow ou similar, não aqui

        // Resetar valores financeiros
        $object_clear = new stdClass();
        $object_clear->valor_venda = null;
        $object_clear->valor_taxaentregaexame = null;
        $object_clear->percentual_desconto_autorizado = null;
        $object_clear->percentual_desconto_utilizado = null;
        $object_clear->valor_receber = null;

        TForm::sendData($formName, $object_clear, false, false);

        // Remover flag de processamento
        TSession::setValue('processando_alteracao_profissional', null);

        // Mostrar mensagem final
        $userName = TSession::getValue('username');       
    } 
    catch (Exception $e) 
    {
        // Remover flag em caso de erro
        TSession::setValue('processando_alteracao_profissional', null);
    }
}

/**
 * ADICIONE ESTE NOVO MÉTODO na classe:
 * No final da classe, antes do último fechamento
 */

private static function preservarDadosEdicao(&$data, $agendamento_id)
{
    if (empty($agendamento_id)) 
    {
        return; // Não é edição
    }

    try 
    {
        TTransaction::open(self::$database);
        $original = Agendamento::find($agendamento_id);
        TTransaction::close();

        if (!$original) 
        {
            return;
        }

        // Lista de campos que devem ser preservados se chegarem vazios
        $camposPreservados = [
            'fornecedor_id',
            'produto_id',
            'guia_conveniocab_id',
            'guia_auxiliar_id',
            'entrega_resultado',
            'cobranca_id',
            'paciente_id',
            'profissional_id',
            'empresa_id'
        ];

        foreach ($camposPreservados as $campo) 
        {
            if (empty($data->$campo) && !empty($original->$campo)) 
            {
                $data->$campo = $original->$campo;
            }
        }
    }
    catch (Exception $e) 
    {
        // Silenciosamente continua
    }
}

//---------------------------------------------------------

    //</userCustomFunctions>
/*
        try
        {
        TTransaction::open(self::$database);

        // Ativa bloqueio APENAS durante o save
        TSession::setValue('onexitpaciente_bloqueado', true);
        TSession::setValue('processando_save_agendamento', true);
        TSession::setValue('paciente_durante_erro', $data_raw->paciente_id ?? null);

        // BLOQUEIO DE EVENTOS PARA EVITAR SOBRESCRIÇÃO DO PROFISSIONAL
        self::$bloqueando_eventos_paciente = true;
        self::$bloqueando_profissional     = true;

        // CAPTURA INICIAL DOS DADOS
        $data_raw           = $this->form->getData();
        $is_editing         = !empty($data_raw->id);
        $produto_id_backup  = $data_raw->produto_id ?? null;

        // PRESERVA O PROFISSIONAL ESCOLHIDO PELO USUÁRIO (ESSENCIAL!)
        $profissional_id_preservado = $data_raw->profissional_id ?? null;

        // PRESERVA ESTADO ORIGINAL (EDIÇÃO)
        $objeto_para_restaurar = null;
        $valores_originais     = [];

        if ($is_editing)
        {
            $objeto_para_restaurar = Agendamento::find($data_raw->id);
            if ($objeto_para_restaurar)
            {
                $valores_originais = [
                    'valor_taxaentregaexame'         => $objeto_para_restaurar->valor_taxaentregaexame,
                    'valor_receber'                  => $objeto_para_restaurar->valor_receber,
                    'valor_venda'                    => $objeto_para_restaurar->valor_venda,
                    'percentual_desconto_autorizado' => $objeto_para_restaurar->percentual_desconto_autorizado,
                    'percentual_desconto_utilizado'  => $objeto_para_restaurar->percentual_desconto_utilizado
                ];
            }
        }

        // VALIDAÇÃO DO FORMULÁRIO (ADIANTI)
        try
        {
            $this->form->validate();
        }
        catch (Exception $e)
        {
            // Restaura profissional imediatamente (sem delay)
            if (!$is_editing && $profissional_id_preservado)
            {
                $obj_fix = new stdClass();
                $obj_fix->profissional_id = $profissional_id_preservado;
                TForm::sendData(self::$formName, $obj_fix, false, false);

                TScript::create("
                    (function() {
                        var select = document.querySelector('[name=\"profissional_id\"]');
                        if (select) {
                            select.value = '{$profissional_id_preservado}';
                            if (typeof __adianti_set_field_value === 'function') {
                                __adianti_set_field_value('profissional_id', '{$profissional_id_preservado}');
                            }
                            select.dispatchEvent(new Event('change', { bubbles: true }));
                        }
                    })();
                ");
            }

            new TMessage('error', '<b>' . TSession::getValue('username') . '</b><br>' . $e->getMessage());

            self::$bloqueando_eventos_paciente = false;
            self::$bloqueando_profissional     = false;
            throw $e;
        }

        // REOBTER DADOS APÓS VALIDAÇÃO
        $data = $this->form->getData();

        // FORÇA O PROFISSIONAL PRESERVADO DE VOLTA (EVITA QUE FIQUE VAZIO NAS VALIDAÇÕES MANUAIS)
        if ($profissional_id_preservado)
        {
            $data->profissional_id = $profissional_id_preservado;
        }

        // TRATAMENTO DE RETORNO
        $is_retorno = (!empty($data->consulta_retorno) && $data->consulta_retorno === 'S' && !empty($data->agendamento_anterior));
        if ($is_retorno)
        {
            $data->valor_venda                    = null;
            $data->valor_custo                    = null;
            $data->valor_receber                  = null;
            $data->valor_contratado               = null;
            $data->percentual_desconto_autorizado = null;
            $data->percentual_desconto_utilizado  = null;
            $data->valor_taxaentregaexame         = null;

            $prof_bloqueado = TSession::getValue('RETORNO_PROFISSIONAL_BLOQUEADO');
            if ($prof_bloqueado)
            {
                $data->profissional_id = $prof_bloqueado;
                TSession::delValue('RETORNO_PROFISSIONAL_BLOQUEADO');
            }
        }

        // CORREÇÃO DE FORMATO DE DATA/HORA
        foreach (['horario_inicial', 'horario_final'] as $campo)
        {
            if (!empty($data->$campo) && strpos($data->$campo, '-') !== false && !preg_match('/^\d{4}-\d{2}-\d{2}/', $data->$campo))
            {
                $data->$campo = preg_replace('/(\d{2})-(\d{2})-(\d{4})\s+(\d{2}):(\d{2})/', '$3-$2-$1 $4:$5:00', $data->$campo);
            }
        }

        // ========================================
        // VALIDAÇÕES MANUAIS COM CONTROLE TOTAL DE ERRO
        // ========================================
        $erros = [];

        // Campos obrigatórios
        if (empty($data->horario_inicial))      $erros[] = "Data e hora inicial";
        if (empty($data->horario_final))        $erros[] = "Data e hora final";
        if (empty($data->empresa_id))           $erros[] = "Empresa";
        if (empty($data->paciente_id))          $erros[] = "Paciente";
        if (empty($data->profissional_id))      $erros[] = "Profissional de saúde";
        if (empty($data->fornecedor_id))        $erros[] = "Convênio";
        if (empty($data->produto_id))           $erros[] = "Procedimento a ser realizado";
        if (empty($data->entrega_resultado))    $erros[] = "Resultado de exame";
        if (empty($data->cobranca_id))          $erros[] = "Cobrança utilizada";

        if (!$is_retorno && empty($data->valor_receber))
        {
            $erros[] = "Valor a receber";
        }

        // Se houver erros, restaura o profissional e mostra mensagem personalizada
        if (!empty($erros))
        {
            // FORÇA O PROFISSIONAL ESCOLHIDO PELO USUÁRIO IMEDIATAMENTE
            if ($profissional_id_preservado)
            {
                $obj_fix = new stdClass();
                $obj_fix->profissional_id = $profissional_id_preservado;
                TForm::sendData(self::$formName, $obj_fix, false, false);

                TScript::create("
                    (function() {
                        var select = document.querySelector('[name=\"profissional_id\"]');
                        if (select) {
                            select.value = '{$profissional_id_preservado}';
                            if (typeof __adianti_set_field_value === 'function') {
                                __adianti_set_field_value('profissional_id', '{$profissional_id_preservado}');
                            }
                            if (typeof __adianti_load_combo_options === 'function') {
                                __adianti_load_combo_options(select);
                            }
                            select.dispatchEvent(new Event('change', { bubbles: true }));
                        }
                    })();
                ");
            }

            // Monta mensagem amigável
            $lista_erros = implode('<br>• ', $erros);
            $mensagem = "<b>Os seguintes campos são obrigatórios:</b><br>• {$lista_erros}";

            new TMessage('error', '<b>' . TSession::getValue('username') . '</b><br>' . $mensagem);

            // Interrompe o save sem throw (evita recarregamento completo do form)
            TTransaction::rollback();
            self::$bloqueando_eventos_paciente = false;
            self::$bloqueando_profissional     = false;
            //$this->fireEvents($this->form->getData());
            return; // ← SAI AQUI E NÃO CONTINUA O SAVE
        }

        // CRIA OBJETO E APLICA DADOS
        $object = new Agendamento();
        $object->fromArray((array) $data);

        // Correção do valor_taxaentregaexame
        if (isset($data->valor_taxaentregaexame))
        {
            $valor_taxa = trim($data->valor_taxaentregaexame);
            if (empty($valor_taxa) || $valor_taxa === '0' || $valor_taxa === '0,00' || $valor_taxa === null)
            {
                $object->valor_taxaentregaexame = 0.00;
            }
            else
            {
                $valor_limpo = str_replace('.', '', $valor_taxa);
                $valor_limpo = str_replace(',', '.', $valor_limpo);
                $object->valor_taxaentregaexame = $valor_limpo;
            }
        }

        // VALIDAÇÃO DE HORÁRIOS DUPLICADOS
        if (empty($data->id))
        {
            if ($agendamento_existente = $object->checkDuplicate())
            {
                try
                {
                    $dt_inicial = new DateTime($agendamento_existente->horario_inicial);
                    $dt_final   = new DateTime($agendamento_existente->horario_final);
                    $data_hora_inicial_formatada = $dt_inicial->format('d-m-Y H:i:s');
                    $hora_final_formatada        = $dt_final->format('H:i:s');
                }
                catch (Exception $e)
                {
                    $data_hora_inicial_formatada = '';
                    $hora_final_formatada        = '';
                }

                $mensagem_erro = " - Já existe um agendamento com estes mesmos dados:<br><br>"
                               . "<b>Agendamento:</b> {$agendamento_existente->id}<br>"
                               . "<b>Paciente:</b> {$agendamento_existente->paciente->nome}<br>"
                               . "<b>Profissional:</b> {$agendamento_existente->profissional->name}<br>"
                               . "<b>Data e Horário:</b> {$data_hora_inicial_formatada} as {$hora_final_formatada}";
                throw new Exception($mensagem_erro);
            }
        }

        // VALIDAÇÃO DE HORÁRIOS
        if ($object->horario_final < $object->horario_inicial)
        {
            throw new Exception('<br>A data e hora final não pode ser menor que a data e hora inicial');
        }

        // VALIDAÇÃO DE GUIAS E VALOR RECEBIDO (SOMENTE INCLUSÃO)
        if (empty($data->id))
        {
            // GUIAS
            $guia_convenio = GuiasconvenioCab::where('pessoa_id', '=', $data->paciente_id)
                                            ->where('fornecedor_id', '=', $data->fornecedor_id)
                                            ->where('data_vencimento', '>=', date('Y-m-d'))
                                            ->where('status', '=', 'A')
                                            ->first();

            if ($guia_convenio)
            {
                if (!isset($data->guia_conveniocab_id) || empty($data->guia_conveniocab_id))
                {
                    throw new Exception("<br>Existe uma Guia de atendimento válida.<br>Consulte a guia {$guia_convenio->guia_convenio}");
                }

                if (!isset($data->guia_auxiliar_id) || empty($data->guia_auxiliar_id))
                {
                    throw new Exception("<br>O campo 'Guia Auxiliar' é obrigatório.");
                }

                $guia_para_abater             = new GuiasconvenioCab($guia_convenio->id);
                $guia_para_abater->guia_saldo = $guia_para_abater->guia_saldo - 1;
                $guia_para_abater->store();

                try
                {
                    $guia_item_utilizado            = new GuiasconvenioItem($data->guia_auxiliar_id);
                    $guia_item_utilizado->status    = 'U';
                    $guia_item_utilizado->utilizado = 'S';
                    $guia_item_utilizado->store();
                }
                catch (Exception $e)
                {
                    throw new Exception("<br>ERRO: Não foi possível atualizar o Item de Guia Auxiliar (ID: {$data->guia_auxiliar_id}). Detalhe: " . $e->getMessage());
                }
            }

            // VALOR RECEBIDO
            $valor_receber = str_replace(',', '.', str_replace('.', '', $data->valor_receber));
            if (empty($data->valor_receber) || $valor_receber <= 0.00)
            {
                throw new Exception("<br>O campo 'Valor a receber' é obrigatório e deve ser maior que R$ 0,00. Valor atual: R$ " . number_format($valor_receber, 2, ',', '.'));
            }
        }

        // BUSCAR DADOS ADICIONAIS
        $object->rf_irrf = null;
        $object->rf_pis  = null;
        $object->rf_cofins = null;
        $object->rf_csll = null;
        $object->rp_inss = null;
        $object->rm_iss  = null;
        $object->re_icms = null;

        $percentual_retencao_convenio   = 0;
        $percentual_retencao_particular = 0;

        if (!empty($object->profissional_id))
        {
            $systemUser = SystemUsers::find($object->profissional_id);
            if ($systemUser)
            {
                $profissional = Pessoa::where('usuario_sistema', '=', $systemUser->id)->first();
                if ($profissional)
                {
                    $percentual_retencao_convenio   = $profissional->percentual_retencao_convenio   ?? 0;
                    $percentual_retencao_particular = $profissional->percentual_retencao_particular ?? 0;
                }
            }
        }

        $object->percentual_retencao_convenio   = $percentual_retencao_convenio;
        $object->percentual_retencao_particular = $percentual_retencao_particular;

        $paciente_valor_contratado = null;
        $produto_preco_custo       = null;
        $produto_preco_venda       = null;

        if (!empty($data->paciente_id))
        {
            $paciente_obj = Pessoa::find($data->paciente_id);
            if ($paciente_obj)
            {
                $paciente_valor_contratado = $paciente_obj->valor_contratado;
            }
        }

        if (!empty($data->fornecedor_id) && !empty($data->produto_id))
        {
            $produto_preco = ProdutoFornecedorpreco::where('fornecedor_id', '=', $data->fornecedor_id)
                                                  ->where('produto_id', '=', $data->produto_id)
                                                  ->first();
            if ($produto_preco)
            {
                $produto_preco_custo = $produto_preco->preco_custo;
                $produto_preco_venda = $produto_preco->preco_venda;
            }
        }

        if (!empty($data->fornecedor_id))
        {
            $fornecedor_obj = Pessoa::find($data->fornecedor_id);
            if ($fornecedor_obj)
            {
                $object->rf_irrf   = $fornecedor_obj->rf_irrf;
                $object->rf_pis    = $fornecedor_obj->rf_pis;
                $object->rf_cofins = $fornecedor_obj->rf_cofins;
                $object->rf_csll   = $fornecedor_obj->rf_csll;
                $object->rp_inss   = $fornecedor_obj->rp_inss;
                $object->rm_iss    = $fornecedor_obj->rm_iss;
                $object->re_icms   = $fornecedor_obj->re_icms;
            }
        }

        // LÓGICA DE VALOR CONTRATADO
        $valor_contratado_usar = null;
        $usar_valor_contratado = false;

        $paciente_obj_check = Pessoa::find($data->paciente_id);
        if ($paciente_obj_check && 
            $paciente_obj_check->paciente_psicologia == 'S' && 
            $paciente_obj_check->profissional_id == $data->profissional_id && 
            !empty($paciente_obj_check->valor_contratado) && 
            $paciente_obj_check->valor_contratado != 0)
        {
            $usar_valor_contratado = true;
        }

        if ($usar_valor_contratado)
        {
            $valor_contratado_usar = $paciente_obj_check->valor_contratado;
        }

        if ($valor_contratado_usar !== null && $valor_contratado_usar != 0)
        {
            if ($is_retorno)
            {
                $object->valor_contratado = 0;
                $object->valor_custo      = 0;
                $object->valor_venda      = 0;
            }
            else
            {
                $object->valor_contratado = $valor_contratado_usar;
                $object->valor_custo      = $valor_contratado_usar;
                $object->valor_venda      = $valor_contratado_usar;
            }
        }
        else
        {
            if ($is_retorno)
            {
                $object->valor_custo = 0;
                $object->valor_venda = 0;
            }
            else
            {
                if ($produto_preco_custo !== null && $produto_preco_custo != 0)
                {
                    $object->valor_custo = $produto_preco_custo;
                }
                if ($produto_preco_venda !== null && $produto_preco_venda != 0)
                {
                    $object->valor_venda = $produto_preco_venda;
                }
            }
        }

        if (empty($data->id))
        {
            // SALVAR AGENDAMENTO
            $object->data_alteracao    = date('Y/m/d');
            $object->hora_alteracao    = date('H:i');
            $object->usuario_alteracao = TSession::getValue('userid');
        }

        if (!empty($data->agendamento_anterior) && empty($data->id))
        {
            $object->store();
            $agendamento_original = Agendamento::find($data->agendamento_anterior);
            if ($agendamento_original)
            {
                $agendamento_original->agendamento_novo = $object->id;
                $agendamento_original->store();
            }
        }
        else
        {
            $object->store();
        }

        // Pega os valores que foram salvos (do $data, que tem o formato original do usuário)
        $valor_taxa      = $data->valor_taxaentregaexame ?? '0,00';
        $valor_receber   = $data->valor_receber ?? '0,00';
        $valor_venda     = $data->valor_venda ?? '0,00';

        // Garante formatação brasileira correta (com vírgula decimal e ponto milhar)
        $valor_taxa      = number_format((float)str_replace(',', '.', str_replace('.', '', $valor_taxa)), 2, ',', '.');
        $valor_receber   = number_format((float)str_replace(',', '.', str_replace('.', '', $valor_receber)), 2, ',', '.');
        $valor_venda     = number_format((float)str_replace(',', '.', str_replace('.', '', $valor_venda)), 2, ',', '.');

        // Envia de volta ao formulário no formato que o usuário espera ver
        $obj_display = new stdClass();
        $obj_display->valor_taxaentregaexame = $valor_taxa;
        $obj_display->valor_receber          = $valor_receber;
        $obj_display->valor_venda            = $valor_venda;
        // Se precisar de outros campos, adicione aqui

        TForm::sendData(self::$formName, $obj_valores, false, false);

        // Recarrega combos e foto (mantém o que já tinha)
        $this->recarregarCombos($object);
        if (!empty($object->paciente_id))
        {
            $paciente = Pessoa::find($object->paciente_id);
            if ($paciente)
            {
                $this->paciente_foto->src = $paciente->caminho_foto;
            }
        }

        // Dispara eventos (agora seguro, pois já salvou)
        $this->fireEvents($object);
        $this->recarregarCombos($object);
        $this->paciente_foto->src = $object->paciente->caminho_foto;

        $messageAction = new TAction(['AgendamentoList', 'onShow']);
        if (!empty($param['target_container']))
        {
            $messageAction->setParameter('target_container', $param['target_container']);
        }

        $data->id = $object->id;
        $this->form->setData($data);

        // GERAÇÃO DE CONTA A RECEBER
        $conta_existente = Conta::where('agendamento_id', '=', $object->id)->first();

        if (!$conta_existente && !$is_retorno)
        {
            $agendamentotipo = AgendamentoTipo::find($param['tipo_agendamento_id'] ?? null);

            $produtofornecedorpreco = ProdutoFornecedorpreco::where('fornecedor_id', '=', $data->fornecedor_id)
                                                          ->where('produto_id', '=', $data->produto_id)
                                                          ->first();

            $paciente = Pessoa::find($object->paciente_id);

            $valor_custo_conta = null;
            $valor_venda_conta = null;

            $usar_valor_contratado_conta = false;
            if ($paciente && 
                $paciente->paciente_psicologia == 'S' && 
                $paciente->profissional_id == $object->profissional_id && 
                !empty($paciente->valor_contratado) && 
                $paciente->valor_contratado != 0)
            {
                $usar_valor_contratado_conta = true;
            }

            if ($usar_valor_contratado_conta)
            {
                $valor_contratado_usar = $paciente->valor_contratado;
                $valor_custo_conta     = $valor_contratado_usar;
                $valor_venda_conta     = $valor_contratado_usar;
            }
            else if ($produtofornecedorpreco)
            {
                $valor_custo_conta = $produtofornecedorpreco->preco_custo;
                $valor_venda_conta = $produtofornecedorpreco->preco_venda;
            }

            $valordecusto = $valor_custo_conta !== null ? number_format($valor_custo_conta, 2, ',', '.') : '0,00';
            $valordevenda = $valor_venda_conta !== null ? number_format($valor_venda_conta, 2, ',', '.') : '0,00';

            $contasareceber = new Conta();
            $contasareceber->agendamento_id                     = $object->id;
            $contasareceber->empresa_id                         = $object->empresa_id;
            $contasareceber->cliente_id                         = $object->paciente_id;
            $contasareceber->tipo_conta_id                      = 1;
            $contasareceber->titulo                             = 'AG. - ' . $object->id;
            $contasareceber->parcela                            = 'PARCELA 1 DE 1';
            $contasareceber->profissional_id                    = $object->profissional_id;
            $contasareceber->fornecedor_id                      = $object->fornecedor_id;
            $contasareceber->produto_id                         = $object->produto_id;
            $contasareceber->tipo_geracao                       = '2';
            $contasareceber->valor_custo                        = $valordecusto;
            $contasareceber->valor_venda                        = $valordevenda;
            $contasareceber->valor_receber                      = $object->valor_receber;
            $contasareceber->valor_contratado                   = $paciente ? $paciente->valor_contratado : null;
            $contasareceber->valor_taxaentregaexame             = $object->valor_taxaentregaexame;
            $contasareceber->percentual_desconto_autorizado     = $object->percentual_desconto_autorizado;
            $contasareceber->percentual_desconto_utilizado      = $object->percentual_desconto_utilizado;

            $id_produto = $object->produto_id;
            $objeto_produto = Produto::find($id_produto);
            if ($objeto_produto)
            {
                $contasareceber->pla_codigo_id = $objeto_produto->pla_codigo_id;
            }

            $contasareceber->percentual_retencao_convenio   = $percentual_retencao_convenio;
            $contasareceber->percentual_retencao_particular = $percentual_retencao_particular;

            $contasareceber->rf_irrf   = $object->rf_irrf;
            $contasareceber->rf_pis    = $object->rf_pis;
            $contasareceber->rf_cofins = $object->rf_cofins;
            $contasareceber->rf_csll   = $object->rf_csll;
            $contasareceber->rp_inss   = $object->rp_inss;
            $contasareceber->rm_iss    = $object->rm_iss;
            $contasareceber->re_icms   = $object->re_icms;

            $contasareceber->natureza_id   = 2;
            $contasareceber->dt_emissao    = date('Y-m-d');
            $contasareceber->dt_vencimento = $object->horario_inicial;
            $contasareceber->desconto      = null;
            $contasareceber->valor_original = null;
            $contasareceber->valor_liquido  = null;
            $contasareceber->valor_quitado  = null;
            $contasareceber->valor_retencao_particular = null;
            $contasareceber->valor_retencao_convenio   = null;
            $contasareceber->cobranca_id   = $object->cobranca_id;
            $contasareceber->juros         = null;
            $contasareceber->multa         = null;
            $contasareceber->quitada       = 'N';
            $contasareceber->data_quitacao = null;
            $contasareceber->data_inclusao = date('Y-m-d');
            $contasareceber->hora_inclusao = date('H:i:s');
            $contasareceber->usuario_inclusao = TSession::getValue('userid');
            $contasareceber->geracaotitulo_id = TSession::getValue('userid');
            $contasareceber->tipo_lancamento  = 'P';

            $contasareceber->store();
        }

        TTransaction::close();

        TSession::delValue('paciente_durante_erro');
        TSession::delValue('processando_save_agendamento');

        new TMessage('info', '<b>' . TSession::getValue('username') . '</b> - Registro salvo', $messageAction);
        TWindow::closeWindow(parent::getId());
    }
    catch (Exception $e)
    {

        TTransaction::rollback();

            // Usa o $param do onSave — ele SEMPRE tem os valores atuais do form, mesmo após erro de validação
            $paciente_id = $param['paciente_id'] ?? null;
            $prof_id     = $param['profissional_id'] ?? null;
            $forn_id     = $param['fornecedor_id'] ?? null;
            $prod_id     = $param['produto_id'] ?? null;

            // ========================================
            // RESTAURA PROFISSIONAL_ID (sem piscada)
            // ========================================
            if ($prof_id)
            {
                $obj_prof = new stdClass();
                $obj_prof->profissional_id = $prof_id;
                TForm::sendData(self::$formName, $obj_prof, false, false);

                TScript::create("
                    (function() {
                        var select = document.querySelector('[name=\"profissional_id\"]');
                        if (select) {
                            select.value = '';
                            if (typeof __adianti_load_combo_options === 'function') {
                                __adianti_load_combo_options(select);
                            }
                            select.value = '{$prof_id}';
                            if (typeof __adianti_set_field_value === 'function') {
                                __adianti_set_field_value('profissional_id', '{$prof_id}');
                            }
                            if (typeof __adianti_load_combo_options === 'function') {
                                __adianti_load_combo_options(select);
                            }
                            select.dispatchEvent(new Event('change', { bubbles: true }));
                        }
                    })();
                ");
            }

            // ========================================
            // RECARREGA FORNECEDOR_ID (convênio)
            // ========================================
            if ($paciente_id)
            {
                $criteria = TCriteria::create(['paciente_id' => $paciente_id]);
                $criteria->add(new TFilter('status', '=', 'A'));

                TDBCombo::reloadFromModel(
                    self::$formName,
                    'fornecedor_id',
                    'bdgestorweb',
                    'PessoaConvenioparceria',
                    'fornecedor_id',
                    '{fornecedor_id} {fornecedor->nome} - Carteirinha: {numero_carteirinha}',
                    'fornecedor_id asc',
                    $criteria,
                    TRUE
                );

                if ($forn_id)
                {
                    $obj_forn = new stdClass();
                    $obj_forn->fornecedor_id = $forn_id;
                    TForm::sendData(self::$formName, $obj_forn, false, false);

                    TScript::create("
                        (function() {
                            var select = document.querySelector('[name=\"fornecedor_id\"]');
                            if (select) {
                                select.value = '';
                                if (typeof __adianti_load_combo_options === 'function') {
                                    __adianti_load_combo_options(select);
                                }
                                select.value = '{$forn_id}';
                                if (typeof __adianti_set_field_value === 'function') {
                                    __adianti_set_field_value('fornecedor_id', '{$forn_id}');
                                }
                                if (typeof __adianti_load_combo_options === 'function') {
                                    __adianti_load_combo_options(select);
                                }
                                select.dispatchEvent(new Event('change', { bubbles: true }));
                            }
                        })();
                    ");
                }
            }
            // ========================================
            // RECARREGA PRODUTO_ID (procedimento) - CORREÇÃO PARA PERMITIR RE-SELEÇÃO
            // ========================================
            if ($forn_id)
            {
                $options = ['' => 'Selecione um procedimento'];

                try
                {
                    TTransaction::open(self::$database);
                    $conn = TTransaction::get();

                    $sql = "
                        SELECT 
                            pfp.produto_id AS id,
                            p.descproduto AS description
                        FROM produto_fornecedorpreco pfp
                        INNER JOIN produto p ON p.id = pfp.produto_id
                        WHERE pfp.fornecedor_id = :fornecedor_id
                        AND pfp.status = 'A'
                        ORDER BY p.descproduto ASC
                    ";

                    $stmt = $conn->prepare($sql);
                    $stmt->execute(['fornecedor_id' => $forn_id]);

                    while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
                    {
                        $options[$row['id']] = $row['description'];
                    }

                    TTransaction::close();
                }
                catch (Exception $ex)
                {
                    TTransaction::rollback();
                }

                // Recarrega o combo
                TCombo::reload(self::$formName, 'produto_id', $options);

                // FORÇA O VALUE CORRETO, MAS PERMITE RE-SELEÇÃO
                if ($prod_id)
                {
                    TScript::create("
                        (function() {
                            var select = document.querySelector('[name=\"produto_id\"]');
                            if (select) {
                                // Limpa primeiro (permite re-selecionar o mesmo item)
                                select.value = '';
                                if (typeof __adianti_load_combo_options === 'function') {
                                    __adianti_load_combo_options(select);
                                }
                                // Depois define o value correto
                                select.value = '{$prod_id}';
                                if (typeof __adianti_set_field_value === 'function') {
                                    __adianti_set_field_value('produto_id', '{$prod_id}');
                                }
                                if (typeof __adianti_load_combo_options === 'function') {
                                    __adianti_load_combo_options(select);
                                }
                                select.dispatchEvent(new Event('change', { bubbles: true }));
                            }
                        })();
                    ");
                }
            }
            else
            {
                TCombo::reload(self::$formName, 'produto_id', ['' => 'Selecione um convênio']);
            }

            // ========================================
            // RESTAURAÇÃO PARA EDIÇÃO (se existir)
            // ========================================
            if ($is_editing && $objeto_para_restaurar)
            {
                $this->form->setData($objeto_para_restaurar);
            }

            // Desbloqueia eventos
            self::$bloqueando_eventos_paciente = false;
            self::$bloqueando_profissional = false;

            new TMessage('error', '<b>' . TSession::getValue('username') . '</b><br>' . $e->getMessage());
        }
*/
//
/*
        try
        {
            TTransaction::open(self::$database);
    new TMessage('info', "DEBUG ONSAVE - VALOR_RECEBER NO PARAM: " . ($param['valor_receber'] ?? 'VAZIO'));        
    new TMessage('info', "PARAMS RECEBIDOS NO ONSAVE\n" . print_r($param, true));
            $preservar = 
            [
                'paciente_id'     => $param['paciente_id']     ?? null,
                'fornecedor_id'   => $param['fornecedor_id']   ?? null,
                'produto_id'      => $param['produto_id']      ?? null,
                'profissional_id' => $param['profissional_id'] ?? null,
            ];

            self::$bloqueando_eventos_paciente  = true;
            self::$bloqueando_profissional      = true;

            $data_raw                           = $this->form->getData();
            $is_editing                         = !empty($data_raw->id);
            $profissional_id_preservado         = $data_raw->profissional_id ?? null;

            $objeto_para_restaurar = null;
            if ($is_editing)
            {
                $objeto_para_restaurar = Agendamento::find($data_raw->id);
            }

            try
            {
    /*
    $data_debug_antes = $this->form->getData();
    new TMessage('info', "DEBUG 1 - ANTES DO VALIDATE\n".
        "Venda bruto: '" . ($data_debug_antes->valor_venda ?? 'vazio') . "'\n".
        "Taxa bruto: '" . ($data_debug_antes->valor_taxaentregaexame ?? 'vazio') . "'\n".
        "Receber bruto: '" . ($data_debug_antes->valor_receber ?? 'vazio') . "'");
    */
/*    
            $this->form->validate();
            }
            catch (Exception $e)
            {
                new TMessage('error', '<b>' . TSession::getValue('username') . '</b><br>' . $e->getMessage());
                self::$bloqueando_eventos_paciente = false;
                self::$bloqueando_profissional = false;
                throw $e;
            }

            $data = $this->form->getData();
    new TMessage('info', "DEBUG ONSAVE - VALOR_RECEBER NO DATA: " . ($data->valor_receber ?? 'VAZIO'));

    // Função para converter vírgula → ponto
    $toFloat = function($val) {
        if (is_string($val)) {
            return (float) str_replace(',', '.', str_replace('.', '', $val));
        }
        return (float) $val;
    };

    $object->valor_venda                    = ($param['valor_venda']);            // 15205
    $object->valor_taxaentregaexame         = ($param['valor_taxaentregaexame']); // 8150
    $object->percentual_desconto_utilizado  = ($param['percentual_desconto_utilizado']);
    $object->percentual_desconto_autorizado = ($param['percentual_desconto_autorizado']);

    $desconto      = (($param['valor_venda'] * $param['percentual_desconto_utilizado']) / 100);
    $valor_receber = (($param['valor_venda'] - $desconto) + $param['valor_taxaentregaexame']);
    $object->valor_receber                  = $valor_receber;

    // Outros campos
    $object->valor_custo = $object->valor_venda;
    $object->valor_contratado = $object->valor_venda;

    new TMessage('info', "DEBUG 2 - APÓS GETDATA (depois do validate)\n".
        "Venda: '"                . ($param['valor_venda'] ?? 'vazio') . "'\n".
        "Taxa entrega exame:'"    . ($param['valor_taxaentregaexame'] ?? 'vazio') . "'\n".
        "Desc utilizado:'"        . ($param['percentual_desconto_utilizado'] ?? 'vazio') . "'\n".
        "Desc autorizado:'"       . ($param['percentual_desconto_autorizado'] ?? 'vazio') . "'\n".        
        "Desc :'"                 . ($desconto ?? 'vazio') . "'\n".            
        "Receber : '"             . ($valor_receber ?? 'vazio') . "'");

            $this->form->setData($data);

            if ($profissional_id_preservado)
            {
                $data->profissional_id = $profissional_id_preservado;
            }

            $is_retorno = (!empty($data->consulta_retorno) && $data->consulta_retorno === 'S' && !empty($data->agendamento_anterior));
            if ($is_retorno)
            {
                $data->valor_venda                      = null;
                $data->valor_custo                      = null;
                $data->valor_receber                    = null;
                $data->valor_contratado                 = null;
                $data->percentual_desconto_autorizado   = null;
                $data->percentual_desconto_utilizado    = null;
                $data->valor_taxaentregaexame           = null;

                $prof_bloqueado = TSession::getValue('RETORNO_PROFISSIONAL_BLOQUEADO');
                if ($prof_bloqueado)
                {
                    $data->profissional_id = $prof_bloqueado;
                    TSession::delValue('RETORNO_PROFISSIONAL_BLOQUEADO');
                }
            }

            foreach (['horario_inicial', 'horario_final'] as $campo)
            {
                if (!empty($data->$campo) && strpos($data->$campo, '-') !== false && !preg_match('/^\d{4}-\d{2}-\d{2}/', $data->$campo))
                {
                    $data->$campo = preg_replace('/(\d{2})-(\d{2})-(\d{4})\s+(\d{2}):(\d{2})/', '$3-$2-$1 $4:$5:00', $data->$campo);
                }
            }

            $erros = [];
            if (empty($data->horario_inicial))      $erros[]       = "Data e hora inicial";
            if (empty($data->horario_final))        $erros[]       = "Data e hora final";
            if (empty($data->empresa_id))           $erros[]       = "Empresa";
            if (empty($data->paciente_id))          $erros[]       = "Paciente";
            if (empty($data->profissional_id))      $erros[]       = "Profissional de saúde";
            if (empty($data->fornecedor_id))        $erros[]       = "Convênio";
            if (empty($data->produto_id))           $erros[]       = "Procedimento a ser realizado";
            if (empty($data->entrega_resultado))    $erros[]       = "Resultado de exame";
            if (empty($data->cobranca_id))          $erros[]       = "Cobrança utilizada";

            if (!$is_retorno && empty($data->valor_receber))
            {
                $erros[] = "Valor a receber";
            }

            if (!empty($erros))
            {
                $lista_erros = implode('<br>• ', $erros);
                throw new Exception("<b>Os seguintes campos são obrigatórios:</b><br>• {$lista_erros}");
            }

            $object = new Agendamento();

    new TMessage('info', "DEBUG 3x - ANTES DA CONVERSÃO MANUAL\n".
        "Venda no $data: '" . ($data->valor_venda ?? 'vazio') . "'\n".
        "Taxa no $data: '" . ($data->valor_taxaentregaexame ?? 'vazio') . "'");

    // CONVERSÃO CORRETA DOS VALORES MONETÁRIOS USANDO $param (valor original com ponto decimal)
    $campos_monetarios = [
        'valor_venda',
        'valor_taxaentregaexame',
        'valor_receber',
        'valor_custo',
        'valor_contratado'
    ];

    foreach ($campos_monetarios as $campo)
    {
        if (isset($param[$campo]) && $param[$campo] !== '' && $param[$campo] !== null)
        {
            // $param tem o valor com ponto (ex: "152.05" ou "81.5")
            $valor_bruto = trim($param[$campo]);
            // Já está com ponto decimal (padrão do banco), só faz cast para float
            $object->$campo = (float) $valor_bruto;
        }
        else
        {
            $object->$campo = 0.00;
        }

    new TMessage('info', "DEBUG 4 - APÓS CONVERTER CAMPO {$campo}\n".
        "Valor bruto: '" . ($data->$campo ?? 'vazio') . "'\n".
        "Valor convertido no object: " . ($object->$campo ?? 'vazio'));    
    }

            $object->fromArray((array) $data);

            // VALIDAÇÃO DE HORÁRIOS DUPLICADOS
            if (empty($data->id))
            {
                if ($agendamento_existente = $object->checkDuplicate())
                {
                    try
                    {
                        $dt_inicial                         = new DateTime($agendamento_existente->horario_inicial);
                        $dt_final                           = new DateTime($agendamento_existente->horario_final);
                        $data_hora_inicial_formatada        = $dt_inicial->format('d-m-Y H:i:s');
                        $hora_final_formatada               = $dt_final->format('H:i:s');
                    }
                    catch (Exception $e)
                    {
                        $data_hora_inicial_formatada = '';
                        $hora_final_formatada        = '';
                    }
                    $mensagem_erro = " - Já existe um agendamento com estes mesmos dados:<br><br>"
                                . "<b>Agendamento:</b> {$agendamento_existente->id}<br>"
                                . "<b>Paciente:</b> {$agendamento_existente->paciente->nome}<br>"
                                . "<b>Profissional:</b> {$agendamento_existente->profissional->name}<br>"
                                . "<b>Data e Horário:</b> {$data_hora_inicial_formatada} as {$hora_final_formatada}";
                    throw new Exception($mensagem_erro);
                }
            }

            // VALIDAÇÃO DE HORÁRIOS
            if ($object->horario_final < $object->horario_inicial)
            {
                throw new Exception('<br>A data e hora final não pode ser menor que a data e hora inicial');
            }

            // VALIDAÇÃO DE GUIAS E VALOR RECEBIDO (INCLUSÃO)
            if (empty($data->id))
            {
                $guia_convenio = GuiasconvenioCab::where('pessoa_id',        '=', $data->paciente_id)
                                                ->where('fornecedor_id',     '=', $data->fornecedor_id)
                                                ->where('data_vencimento',  '>=', date('Y-m-d'))
                                                ->where('status', '=', 'A')
                                                ->first();

                if ($guia_convenio)
                {
                    if (!isset($data->guia_conveniocab_id) || empty($data->guia_conveniocab_id))
                    {
                        throw new Exception("<br>Existe uma Guia de atendimento válida.<br>Consulte a guia {$guia_convenio->guia_convenio}");
                    }
                    if (!isset($data->guia_auxiliar_id) || empty($data->guia_auxiliar_id))
                    {
                        throw new Exception("<br>O campo 'Guia Auxiliar' é obrigatório.");
                    }

                    $guia_para_abater               = new GuiasconvenioCab($guia_convenio->id);
                    $guia_para_abater->guia_saldo   = $guia_para_abater->guia_saldo - 1;
                    $guia_para_abater->store();

                    try
                    {
                        $guia_item_utilizado                = new GuiasconvenioItem($data->guia_auxiliar_id);
                        $guia_item_utilizado->status        = 'U';
                        $guia_item_utilizado->utilizado     = 'S';
                        $guia_item_utilizado->store();
                    }
                    catch (Exception $e)
                    {
                        throw new Exception("<br>ERRO: Não foi possível atualizar o Item de Guia Auxiliar (ID: {$data->guia_auxiliar_id}). Detalhe: " . $e->getMessage());
                    }
                }

                $valor_receber = str_replace(',', '.', str_replace('.', '', $data->valor_receber));
                if (empty($data->valor_receber) || $valor_receber <= 0.00)
                {
                    throw new Exception("<br>O campo 'Valor a receber' é obrigatório e deve ser maior que R$ 0,00. Valor atual: R$ " . number_format($valor_receber, 2, ',', '.'));
                }
            }

            // BUSCAR DADOS ADICIONAIS
            $object->rf_irrf                = null;
            $object->rf_pis                 = null;
            $object->rf_cofins              = null;
            $object->rf_csll                = null;
            $object->rp_inss                = null;
            $object->rm_iss                 = null;
            $object->re_icms                = null;
            $percentual_retencao_convenio   = null;
            $percentual_retencao_particular = null;

            if (!empty($object->profissional_id))
            {
                $systemUser = SystemUsers::find($object->profissional_id);
                if ($systemUser)
                {
                    $profissional = Pessoa::where('usuario_sistema', '=', $systemUser->id)->first();
                    if ($profissional)
                    {
                        $percentual_retencao_convenio   = $profissional->percentual_retencao_convenio    ?? 0;
                        $percentual_retencao_particular = $profissional->percentual_retencao_particular  ?? 0;
                    }
                }
            }
            $object->percentual_retencao_convenio   = $percentual_retencao_convenio;
            $object->percentual_retencao_particular = $percentual_retencao_particular;

            $paciente_valor_contratado  = null;
            $produto_preco_custo        = null;
            $produto_preco_venda        = null;

            if (!empty($data->paciente_id))
            {
                $paciente_obj = Pessoa::find($data->paciente_id);
                if ($paciente_obj)
                {
                    $paciente_valor_contratado = $paciente_obj->valor_contratado;
                }
            }

            if (!empty($data->fornecedor_id) && !empty($data->produto_id))
            {
                $produto_preco = ProdutoFornecedorpreco::where('fornecedor_id', '=', $data->fornecedor_id)
                                                    ->where('produto_id',     '=', $data->produto_id)
                                                    ->first();
                if ($produto_preco)
                {
                    $produto_preco_custo = $produto_preco->preco_custo;
                    $produto_preco_venda = $produto_preco->preco_venda;
                }
            }

            if (!empty($data->fornecedor_id))
            {
                $fornecedor_obj = Pessoa::find($data->fornecedor_id);
                if ($fornecedor_obj)
                {
                    $object->rf_irrf    = $fornecedor_obj->rf_irrf;
                    $object->rf_pis     = $fornecedor_obj->rf_pis;
                    $object->rf_cofins  = $fornecedor_obj->rf_cofins;
                    $object->rf_csll    = $fornecedor_obj->rf_csll;
                    $object->rp_inss    = $fornecedor_obj->rp_inss;
                    $object->rm_iss     = $fornecedor_obj->rm_iss;
                    $object->re_icms    = $fornecedor_obj->re_icms;
                }
            }

            // LÓGICA DE VALOR CONTRATADO
            $valor_contratado_usar = null;
            $usar_valor_contratado = false;

            $paciente_obj_check = Pessoa::find($data->paciente_id);
            if ($paciente_obj_check &&
                $paciente_obj_check->paciente_psicologia == 'S' &&
                $paciente_obj_check->profissional_id     == $data->profissional_id &&
                !empty($paciente_obj_check->valor_contratado) &&
                $paciente_obj_check->valor_contratado != 0)
            {
                $usar_valor_contratado = true;
            }

            if ($usar_valor_contratado)
            {
                $valor_contratado_usar = $paciente_obj_check->valor_contratado;
            }

            if ($valor_contratado_usar !== null && $valor_contratado_usar != 0)
            {
                if ($is_retorno)
                {
                    $object->valor_contratado   = null;
                    $object->valor_custo        = null;
                    $object->valor_venda        = null;
                }
                else
                {
                    $object->valor_contratado   = $valor_contratado_usar;
                    $object->valor_custo        = $valor_contratado_usar;
                    $object->valor_venda        = $valor_contratado_usar;
                }
            }
            else
            {
                if ($is_retorno)
                {
                    $object->valor_custo = null;
                    $object->valor_venda = null;
                }
                else
                {
                    if ($produto_preco_custo !== null && $produto_preco_custo != 0)
                    {
                        $object->valor_custo = $produto_preco_custo;
                    }
                    if ($produto_preco_venda !== null && $produto_preco_venda != 0)
                    {
                        $object->valor_venda = $produto_preco_venda;
                    }
                }
            }

    if (!$is_retorno)
    {
        $venda = isset($param['valor_venda']) ? (float)$param['valor_venda'] : 0;
        $taxa  = isset($param['valor_taxaentregaexame']) ? (float)$param['valor_taxaentregaexame'] : 0;
        $object->valor_receber = $venda + $taxa;
    }
    else
    {
        $object->valor_receber = 0.00;
    }
            // SALVAR
            if (empty($data->id))
            {
                $object->data_alteracao    = date('Y/m/d');
                $object->hora_alteracao    = date('H:i');
                $object->usuario_alteracao = TSession::getValue('userid');
            }

            if (!empty($data->agendamento_anterior) && empty($data->id))
            {
                $object->store();
                $agendamento_original = Agendamento::find($data->agendamento_anterior);
                if ($agendamento_original)
                {
                    $agendamento_original->agendamento_novo = $object->id;
                    $agendamento_original->store();
                }
            }
            else
            {
    new TMessage(
        'info',
        'SALVANDO NO OBJETO<br>' .
        'Venda: ' . $object->valor_venda . '<br>' .
        'Taxa: ' . $object->valor_taxaentregaexame . '<br>' .
        'Receber: ' . $object->valor_receber);
/*        
    // Multiplica venda e taxa por 100 para salvar como inteiro (ou float, como preferir)
            $object->valor_venda            = $valor_venda_float * 100;      // 15205
            $object->valor_taxaentregaexame = $valor_taxa_float * 100;       // 8150
            $object->valor_receber          = $valor_receber_float;          // 233.55 (ou *100 se quiser inteiro)
*/
/*
                $object->store();
            }

            // ========================================
            // ENVIA VALORES FORMATADOS DE VOLTA AO FORMULÁRIO
            // ========================================
    TForm::sendData(self::$formName, (object)[
        'valor_venda' => number_format($object->valor_venda ?? 0, 2, '.', ''),
        'valor_taxaentregaexame' => number_format($object->valor_taxaentregaexame ?? 0, 2, '.', ''),
        'valor_receber' => number_format($object->valor_receber ?? 0, 2, '.', ''),
    ]);
            // RECARREGA COMBOS E FOTO
            $this->recarregarCombos($object);

            if (!empty($object->paciente_id))
            {
                $paciente = Pessoa::find($object->paciente_id);
                if ($paciente)
                {
                    $this->paciente_foto->src = $paciente->caminho_foto;
                }
            }

            $this->fireEvents($object);

            $data->id = $object->id;
            $this->form->setData($data);

            // GERAÇÃO DE CONTA A RECEBER
            $conta_existente = Conta::where('agendamento_id', '=', $object->id)->first();
            if (!$conta_existente && !$is_retorno)
            {
                $agendamentotipo        = AgendamentoTipo::find($param['tipo_agendamento_id'] ?? null);
                $produtofornecedorpreco = ProdutoFornecedorpreco::where('fornecedor_id', '=', $data->fornecedor_id)
                                                            ->where('produto_id',      '=', $data->produto_id)
                                                            ->first();
                $paciente                    = Pessoa::find($object->paciente_id);
                $valor_custo_conta           = null;
                $valor_venda_conta           = null;
                $usar_valor_contratado_conta = false;
                if ($paciente &&
                    $paciente->paciente_psicologia  == 'S' &&
                    $paciente->profissional_id      == $object->profissional_id &&
                    !empty($paciente->valor_contratado) &&
                    $paciente->valor_contratado != 0)
                {
                    $usar_valor_contratado_conta = true;
                }
                if ($usar_valor_contratado_conta)
                {
                    $valor_contratado_usar = $paciente->valor_contratado;
                    $valor_custo_conta     = $valor_contratado_usar;
                    $valor_venda_conta     = $valor_contratado_usar;
                }
                else if ($produtofornecedorpreco)
                {
                    $valor_custo_conta = $produtofornecedorpreco->preco_custo;
                    $valor_venda_conta = $produtofornecedorpreco->preco_venda;
                }
                $valordecusto                                   = $valor_custo_conta !== null ? number_format($valor_custo_conta, 2, ',', '.') : '0,00';
                $valordevenda                                   = $valor_venda_conta !== null ? number_format($valor_venda_conta, 2, ',', '.') : '0,00';

                $contasareceber                                 = new Conta();
                $contasareceber->agendamento_id                 = $object->id;
                $contasareceber->empresa_id                     = $object->empresa_id;
                $contasareceber->cliente_id                     = $object->paciente_id;
                $contasareceber->tipo_conta_id                  = 1;
                $contasareceber->titulo                         = 'AG. - ' . $object->id;
                $contasareceber->parcela                        = 'PARCELA 1 DE 1';
                $contasareceber->profissional_id                = $object->profissional_id;
                $contasareceber->fornecedor_id                  = $object->fornecedor_id;
                $contasareceber->produto_id                     = $object->produto_id;
                $contasareceber->tipo_geracao                   = '2';
                $contasareceber->valor_custo                    = $valordecusto;
                $contasareceber->valor_venda                    = $valordevenda;
                $contasareceber->valor_receber                  = $object->valor_receber;
                $contasareceber->valor_contratado               = $paciente ? $paciente->valor_contratado : null;
                $contasareceber->valor_taxaentregaexame         = $object->valor_taxaentregaexame;
                $contasareceber->percentual_desconto_autorizado = $object->percentual_desconto_autorizado;
                $contasareceber->percentual_desconto_utilizado  = $object->percentual_desconto_utilizado;

                $id_produto     = $object->produto_id;
                $objeto_produto = Produto::find($id_produto);
                if ($objeto_produto)
                {
                    $contasareceber->pla_codigo_id              = $objeto_produto->pla_codigo_id;
                }

                $contasareceber->percentual_retencao_convenio   = $percentual_retencao_convenio;
                $contasareceber->percentual_retencao_particular = $percentual_retencao_particular;
                $contasareceber->rf_irrf                        = $object->rf_irrf;
                $contasareceber->rf_pis                         = $object->rf_pis;
                $contasareceber->rf_cofins                      = $object->rf_cofins;
                $contasareceber->rf_csll                        = $object->rf_csll;
                $contasareceber->rp_inss                        = $object->rp_inss;
                $contasareceber->rm_iss                         = $object->rm_iss;
                $contasareceber->re_icms                        = $object->re_icms;
                $contasareceber->natureza_id                    = 2;
                $contasareceber->dt_emissao                     = date('Y-m-d');
                $contasareceber->dt_vencimento                  = $object->horario_inicial;
                $contasareceber->desconto                       = null;
                $contasareceber->valor_original                 = null;
                $contasareceber->valor_liquido                  = null;
                $contasareceber->valor_quitado                  = null;
                $contasareceber->valor_retencao_particular      = null;
                $contasareceber->valor_retencao_convenio        = null;
                $contasareceber->cobranca_id                    = $object->cobranca_id;
                $contasareceber->juros                          = null;
                $contasareceber->multa                          = null;
                $contasareceber->quitada                        = 'N';
                $contasareceber->data_quitacao                  = null;
                $contasareceber->data_inclusao                  = date('Y-m-d');
                $contasareceber->hora_inclusao                  = date('H:i:s');
                $contasareceber->usuario_inclusao               = TSession::getValue('userid');
                $contasareceber->geracaotitulo_id               = TSession::getValue('userid');
                $contasareceber->tipo_lancamento                = 'P';
                $contasareceber->store();
            }

            TTransaction::close();

            $messageAction = new TAction(['AgendamentoList', 'onShow']);
            if (!empty($param['target_container']))
            {
                $messageAction->setParameter('target_container', $param['target_container']);
            }

            new TMessage('info', '<b>' . TSession::getValue('username') . '</b> - Registro salvo com sucesso!', $messageAction);
            TWindow::closeWindow(parent::getId());
        }
        catch (Exception $e)
        {
            TTransaction::rollback();
            TTransaction::open(self::$database);        

                $data = $this->form->getData();
                //$this->form->setData($this->form->getData());

                // 1) REMOVE TODAS AS OPTIONS (zera o Select2 de verdade)
                TCombo::reload(self::$formName, 'fornecedor_id', []);
                TForm::sendData(self::$formName, (object)[
                    'fornecedor_id' => null]);

                //2) CARREGA FORNECEDORES

                $criteria = new TCriteria;
                $criteria->add(new TFilter('paciente_id', '=', $data->paciente_id));
                $criteria->add(new TFilter('status', '=', 'A'));
                $criteria->setProperty('order', 'fornecedor_id');

                $repo       = new TRepository('PessoaConvenioparceria');
                $convenios  = $repo->load($criteria);

                $optionsFornecedor = [];
                foreach ($convenios as $convenio) 
                {
                    if ($convenio->fornecedor) 
                    {
                        $optionsFornecedor[$convenio->fornecedor_id] =$convenio->fornecedor_id . ' - ' .$convenio->fornecedor->nome;
                    }
                }

                // 3) RECRIA AS OPTIONS (sem seleção)
                TCombo::reload(self::$formName, 'fornecedor_id', $optionsFornecedor);

                // 4) BACKEND LIMPO
                $data->fornecedor_id = null;

                // 5) PRODUTOS SEMPRE VAZIOS
                TCombo::reload(self::$formName, 'produto_id', []);
                $data->produto_id = null;

                $this->form->setData($data);
                TTransaction::close();

                new TMessage('error','<b>' . TSession::getValue('username') . '</b><br>' . $e->getMessage());
            }    
*/

}


/*
    public static function onProfissionalAlteradoNaoInclusao($param = null) 
    {
        try 
        {
            // Remover flag de processamento
            TSession::setValue('processando_alteracao_profissional', null);

            $formName              = self::$formName;
            $profissional_anterior = $param['profissional_anterior'] ?? null;

            if ($profissional_anterior) 
            {
                // Restaurar o profissional anterior
                $object_restore                  = new stdClass();
                $object_restore->profissional_id = $profissional_anterior;
                TForm::sendData($formName, $object_restore, false, false);

                // Manter a sessão com o profissional anterior
                TSession::setValue('profissional_id_inclusao', $profissional_anterior);
            }
            else
            {

            }

        } 
        catch (Exception $e) 
        {
            // Remover flag em caso de erro
            TSession::setValue('processando_alteracao_profissional', null);
        }
    }



    private function restaurarValoresOriginais(
        $taxa_original,
        $receber_original,
        $venda_original,
        $desconto_aut_original,
        $desconto_util_original) 
    {
        // Formatar valores com segurança
        $taxa_formatada          =  number_format($taxa_original, 2, ',', '.');
        $receber_formatada       =  number_format($receber_original, 2, ',', '.');
        $venda_formatada         =  number_format($venda_original, 2, ',', '.');
        $desconto_aut_formatada  =  number_format($desconto_aut_original, 2, ',', '.');
        $desconto_util_formatada =  number_format($desconto_util_original, 2, ',', '.');

        TScript::create("
            (function() 
            {
                setTimeout(function() 
                {
                    try 
                    {
                        var elTaxa = document.querySelector('[name=\"valor_taxaentregaexame\"]');
                        var elReceber = document.querySelector('[name=\"valor_receber\"]');
                        var elVenda = document.querySelector('[name=\"valor_venda\"]');
                        var elDescontoAut = document.querySelector('[name=\"percentual_desconto_autorizado\"]');
                        var elDescontoUtil = document.querySelector('[name=\"percentual_desconto_utilizado\"]');

                        if (elTaxa) 
                        {
                            elTaxa.value = '" . $taxa_formatada . "';
                            elTaxa.dispatchEvent(new Event('change', { bubbles: true }));
                            elTaxa.dispatchEvent(new Event('input', { bubbles: true }));
                        }
                        if (elReceber) 
                        {
                            elReceber.value = '" . $receber_formatada . "';
                            elReceber.dispatchEvent(new Event('change', { bubbles: true }));
                            elReceber.dispatchEvent(new Event('input', { bubbles: true }));
                        }
                        if (elVenda) 
                        {
                            elVenda.value = '" . $venda_formatada . "';
                            elVenda.dispatchEvent(new Event('change', { bubbles: true }));
                            elVenda.dispatchEvent(new Event('input', { bubbles: true }));
                        }
                        if (elDescontoAut) 
                        {
                            elDescontoAut.value = '" . $desconto_aut_formatada . "';
                            elDescontoAut.dispatchEvent(new Event('change', { bubbles: true }));
                            elDescontoAut.dispatchEvent(new Event('input', { bubbles: true }));
                        }
                        if (elDescontoUtil) 
                        {
                            elDescontoUtil.value = '" . $desconto_util_formatada . "';
                            elDescontoUtil.dispatchEvent(new Event('change', { bubbles: true }));
                            elDescontoUtil.dispatchEvent(new Event('input', { bubbles: true }));
                        }
                    } 
                    catch(e) 
                    {
                        //console.error('Erro ao restaurar valores:', e);
                    }
                }, 1000);
            })();
        ");
    }

    public static function onProfissionalAlteradoSimInclusao($param = null) 
    {
        try 
        {
            $formName = self::$formName;
            $novo_profissional_id = $param['profissional_id'] ?? null;

            // 1. Atualizar a sessão com o novo profissional
            if ($novo_profissional_id) 
            {
                TSession::setValue('profissional_id_inclusao', $novo_profissional_id);
            }

            // 2. Limpar os campos dependentes - usando métodos do Adianti SEM JavaScript
            $campos_limpar = 
            [
                'fornecedor_id',
                'produto_id',
                'entrega_resultado',
                'guia_conveniocab_id',
                'guia_auxiliar_id',
                'valor_venda',
                'valor_taxaentregaexame',
                'percentual_desconto_autorizado',
                'percentual_desconto_utilizado',
                'valor_receber'
            ];

            // Usar TField::clearField que é nativo do Adianti
            foreach ($campos_limpar as $campo) 
            {
                TField::clearField($formName, $campo);
            }

            // Limpar campos ocultos
            TField::clearField($formName, 'vvalor_venda');
            TField::clearField($formName, 'vvalor_taxaentregaexame');

            // 3. Recarregar combos dependentes
            $paciente_id = $param['paciente_id'] ?? null;

            // Recarregar fornecedor_id se houver paciente
            if ($paciente_id) 
            {
                $criteria = TCriteria::create(['paciente_id' => $paciente_id]);
                $criteria->add(new TFilter('status', '=', 'A'));

                // Usar reloadFromModel mas tentar prevenir eventos
                TDBCombo::reloadFromModel(
                    $formName, 
                    'fornecedor_id', 
                    'bdgestorweb', 
                    'PessoaConvenioparceria', 
                    'fornecedor_id', 
                    '{fornecedor_id} - {fornecedor->nome} - Carteirinha: {numero_carteirinha}', 
                    'fornecedor_id asc', 
                    $criteria, 
                    TRUE
                );
            } 
            else 
            {
                TCombo::clearField($formName, 'fornecedor_id');
            }

            // Limpar produto_id
            TCombo::clearField($formName, 'produto_id');
            TCombo::reload($formName, 'produto_id', ['' => 'Selecione um convênio primeiro']);

            // Limpar entrega_resultado
            TCombo::clearField($formName, 'entrega_resultado');
            TCombo::reload($formName, 'entrega_resultado', ['' => 'Selecione primeiro o procedimento']);
            TField::disableField($formName, 'entrega_resultado');

            // Limpar guias
            TCombo::clearField($formName, 'guia_conveniocab_id');
            TCombo::clearField($formName, 'guia_auxiliar_id');
            TCombo::reload($formName, 'guia_conveniocab_id', ['' => '']);
            TCombo::reload($formName, 'guia_auxiliar_id', ['' => '']);

            // Resetar labels de guias - usar método simples
            // Isso será feito no onShow ou similar, não aqui

            // Resetar valores financeiros
            $object_clear = new stdClass();
            $object_clear->valor_venda = null;
            $object_clear->valor_taxaentregaexame = null;
            $object_clear->percentual_desconto_autorizado = null;
            $object_clear->percentual_desconto_utilizado = null;
            $object_clear->valor_receber = null;

            TForm::sendData($formName, $object_clear, false, false);

            // Remover flag de processamento
            TSession::setValue('processando_alteracao_profissional', null);

            // Mostrar mensagem final
            $userName = TSession::getValue('username');       
        } 
        catch (Exception $e) 
        {
            // Remover flag em caso de erro
            TSession::setValue('processando_alteracao_profissional', null);
        }
    }
    
*/    


/*
    private static function calcularProximoDiaSemana($horario_inicial_original, $horario_final_original, $dias)
    {
        if (!is_numeric($dias) || $dias <= 0) 
        {
            return null;
        }

        $inicio = self::parseDateTime($horario_inicial_original);
        if (!$inicio) 
        {
            return null;
        }

        $fim = self::parseDateTime($horario_final_original);

        // Se final inválido, assume 1 hora
        if (!$fim) 
        {
            $fim = clone $inicio;
            $fim->modify('+1 hour');
        }

        // Duração
        $duracao = $fim->getTimestamp() - $inicio->getTimestamp();
        if ($duracao <= 0) 
        {
            $duracao = 3600;
        }

        // Novo início conforme dias informados
        $novo_inicio = clone $inicio;
        $novo_inicio->modify("+{$dias} days");

        // Novo final preservando duração
        $novo_final = clone $novo_inicio;
        $novo_final->modify("+{$duracao} seconds");

        return ['inicio' => $novo_inicio->format('Y-m-d H:i'),'final'  => $novo_final->format('Y-m-d H:i')];
    }
*/
/*
        private static function prepararDuplicacao($param)
        {
            try 
            {
                TTransaction::open(self::$database);

                $agendamento = Agendamento::find($param['id']);

                if (!$agendamento) 
                {
                    throw new Exception(TSession::getValue('username') . ' - Agendamento não encontrado para duplicar.');
                }

                // ?? CALCULAR A NOVA DATA INICIAL (PRÓXIMO DIA DA SEMANA, MANTENDO HORÁRIO)
                $nova_horario_inicial = self::calcularProximoDiaSemana($agendamento->horario_inicial);

                if (!$nova_horario_inicial)
                {
                    throw new Exception('Não foi possível calcular a nova data do agendamento.');
                }

                // ?? CALCULAR A NOVA DATA FINAL (MANTENDO HORÁRIO E DURAÇÃO)
                $nova_horario_final = null;

                if (!empty($agendamento->horario_final))
                {
                    // Parsear datas iniciais para calcular duração
                    $data_inicial_obj = self::parseDateTime($agendamento->horario_inicial);
                    $data_final_obj   = self::parseDateTime($agendamento->horario_final);

                    if ($data_inicial_obj && $data_final_obj)
                    {
                        // Calcular a diferença entre inicial e final
                        $duracao = $data_final_obj->diff($data_inicial_obj);

                        // Parsear a nova data inicial
                        $nova_data_inicial_obj = self::parseDateTime($nova_horario_inicial);

                        if ($nova_data_inicial_obj)
                        {
                            // Adicionar a mesma duração na nova data inicial
                            $nova_data_inicial_obj->add($duracao);
                            $nova_horario_final = $nova_data_inicial_obj->format('d-m-Y H:i');
                        }
                        else
                        {
                            // Fallback: extrair hora do final original e aplicar na nova data
                            $hora_final = $data_final_obj->format('H:i');
                            $nova_horario_final = substr($nova_horario_inicial, 0, 10) . ' ' . $hora_final;
                        }
                    }
                    else
                    {
                        // Fallback: usar mesma hora que a final original
                        preg_match('/(\d{2}:\d{2})$/', $agendamento->horario_final, $matches);
                        if (!empty($matches[1]))
                        {
                            $hora_final = $matches[1];
                            $nova_horario_final = substr($nova_horario_inicial, 0, 10) . ' ' . $hora_final;
                        }
                        else
                        {
                            // Último fallback: adicionar 1 hora
                            $nova_data_obj = self::parseDateTime($nova_horario_inicial);
                            $nova_data_obj->add(new DateInterval('PT1H'));
                            $nova_horario_final = $nova_data_obj->format('d-m-Y H:i');
                        }
                    }
                }
                else
                {
                    // Se não houver horário final, criar um (1 hora após o inicial)
                    $nova_data_obj = self::parseDateTime($nova_horario_inicial);
                    $nova_data_obj->add(new DateInterval('PT1H'));
                    $nova_horario_final = $nova_data_obj->format('d-m-Y H:i');
                }

                // Criar novo agendamento (clone)
                $agendamentoClone = new Agendamento();
                $dados            = $agendamento->toArray();
                unset($dados['id']); // Remove o ID para gerar novo

                // Configura os novos valores
                $dados['agendamento_anterior']           = $agendamento->id;
                $dados['horario_inicial']                = $nova_horario_inicial;
                $dados['horario_final']                  = $nova_horario_final;
                $dados['guia_conveniocab_id']            = null;
                $dados['guia_auxiliar_id']               = null;
                $dados['ambiente_id']                    = null;            
                $dados['observacao']                     = null;
                $dados['ordematendimento']               = null;
                $dados['status']                         = '01'; // Aguardando confirmação
                $dados['finalizado']                     = 'N';
                $dados['cancelado']                      = 'N';
                $dados['geroudesconto']                  = 'N';
                $dados['geroufinanceiro']                = 'N';
                $dados['geroudesconto_id']               = null;
                $dados['motivo_cancelamento']            = null;
                $dados['cobranca_id']                    = $agendamento->cobranca_id;
                $dados['entrega_resultado']              = null;
                $dados['valor_taxaentregaexame']         = null;
                $dados['valor_receber']                  = null;            
                $dados['data_inclusao']                  = date('Y-m-d');
                $dados['hora_inclusao']                  = date('H:i:s');
                $dados['usuario_inclusao']               = TSession::getValue('userid');

                // Atribui os dados ao clone
                $agendamentoClone->fromArray($dados);
                $agendamentoClone->store();

                // AGORA atualizar o agendamento ORIGINAL com o ID do novo agendamento
                $agendamento->agendamento_novo = $agendamentoClone->id;
                $agendamento->store();

                TTransaction::close();

                return $agendamentoClone;
            } 
            catch (Exception $e) 
            {
                if (TTransaction::isOpened()) 
                {
                    TTransaction::rollback();
                }
                throw $e;
            }
        }
*/
/*
    private static function prepararDuplicacao($param)
    {
        try 
        {
            TTransaction::open(self::$database);

            $agendamento = Agendamento::find($param['id']);

            if (!$agendamento) 
            {
                throw new Exception(TSession::getValue('username') . ' - Agendamento não encontrado para duplicar.');
            }

            $agendamentoClone = new Agendamento();             // Cria novo objeto ao invés de clonar diretamente
            $dados            = $agendamento->toArray();       // Copia os dados necessários (ajuste conforme sua estrutura de tabela)
            unset($dados['id']); // Remove o ID para gerar novo

            // Configura os novos valores
            $dados['agendamento_anterior']           = $agendamento->id;
            $dados['horario_inicial']                = null;
            $dados['horario_final']                  = null;
            $dados['guia_conveniocab_id']            = null;
            $dados['guia_auxiliar_id']               = null;
            $dados['ambiente_id']                    = null;            
            $dados['observacao']                     = null;
            $dados['ordematendimento']               = null;
            $dados['status']                         = '01'; // Aguardando confirmação
            $dados['finalizado']                     = 'N';
            $dados['cancelado']                      = 'N';
            $dados['geroudesconto']                  = 'N';
            $dados['geroufinanceiro']                = 'N';
            $dados['geroudesconto_id']               = null;
            $dados['motivo_cancelamento']            = null;
            $dados['cobranca_id']                    = $agendamento->cobranca_id;
            $dados['entrega_resultado']              = null;
            $dados['valor_taxaentregaexame']         = null;
            $dados['valor_receber']                  = null;            
            $dados['data_inclusao']                  = date('Y-m-d');
            $dados['hora_inclusao']                  = date('H:i:s');
            $dados['usuario_inclusao']               = TSession::getValue('userid');

            // Atribui os dados ao clone
            $agendamentoClone->fromArray($dados);
            $agendamentoClone->store();

            // AGORA atualizar o agendamento ORIGINAL com o ID do novo agendamento
            $agendamento->agendamento_novo = $agendamentoClone->id;
            $agendamento->store();

            TTransaction::close();

            return $agendamentoClone;
        } 
        catch (Exception $e) 
        {
            if (TTransaction::getCurrentTransaction()) 
            {
                TTransaction::rollback();
            }
            throw $e;
        }
    }
*/

/*
            if (!isset($param['dias']))
            {
                // 1. Definição do Tamanho da Janela
                // TWindow::create(Título, Largura, Altura)
                // Use valores entre 0 e 1 para percentual (ex: 0.8 = 80%) ou pixels (ex: 800)
                $window = TWindow::create('DUPLICAR AGENDAMENTO', 0.3, null); 

                $form = new BootstrapFormBuilder('input_form');
                $form->setFormTitle(''); 

                // Estilo para o formulário não herdar bordas brancas
                $form->setProperty('style', 'border:none; box-shadow:none; background-color:transparent;');

                // ===== Campo dias =====
                $dias = new TEntry('dias');
                $dias->setValue(7);
                $dias->setSize('100%');

                $id = new THidden('id');
                $id->setValue($param['id'] ?? '');

                // ===== Label com formatação =====
                $label = new TLabel("AGENDAR DENTRO DE QUANTOS DIAS:");
                $label->setFontColor('#2196F3');
                $label->setFontStyle('b');
                // Força o display block para garantir que ocupe a linha toda
                $label->style = 'display: block; margin-bottom: 8px;';

                // ===== Organização do Layout (Label acima do campo) =====
                // Ao adicionar em addFields separados com layout vertical, o framework empilha os elementos
                $row1         = $form->addFields([$label]);
                $row1->layout = 'vertical';

                $row2 = $form->addFields([$dias, $id]);
                $row2->layout = 'vertical';

                // ===== Botões =====
                $form->addAction('Confirmar', new TAction([__CLASS__, 'onduplicarYes']), 'fa:check green');
                $form->addAction('Cancelar', new TAction([__CLASS__, 'onduplicarNo']), 'fa:times red');

                // ===== Estilização da Janela e Container =====
                $container = new TElement('div');
                $container->style = "background-color:#red; padding:40px; border-radius:5px; min-height:200px;";
                $container->add($form);

                $window->add($container);
                $window->show();

                return;
            }
*/

/*        
        try
        {
            if (empty($param['id']))
            {
                throw new Exception('<br>ID do agendamento não foi fornecido.');
            }

            $agendamentoId = $param['id'];
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';

            TTransaction::open(self::$database);

            $agendamento = Agendamento::find($agendamentoId);

            if (!$agendamento)
            {
                TTransaction::close();
                throw new Exception('<br>Agendamento com ID ' . htmlspecialchars($agendamentoId) . ' não encontrado.');
            }

            // Buscar dados do paciente relacionado
            $pacienteName = 'Sem informação';
            if (!empty($agendamento->paciente_id))
            {
                $paciente = Pessoa::find($agendamento->paciente_id);
                if ($paciente)
                {
                    $pacienteName = htmlspecialchars($paciente->nome ?? 'Sem informação');
                }
            }

            TTransaction::close();

            $mensagem  = "<b>{$usuarioLogado}</b><br><br>";
            $mensagem .= "Deseja duplicar este agendamento?<br>";
            $mensagem .= "<b>Agendamento:</b> " . htmlspecialchars($agendamentoId) . "<br>";
            $mensagem .= "<b>Paciente:</b> {$pacienteName}<br>";

            new TQuestion(
                $mensagem,
                 new TAction([__CLASS__, 'onduplicarYes'], $param), 
                 new TAction([__CLASS__, 'onduplicarNo'], $param)
            );
*/

/*            
            $userName = TSession::getValue('username');
            if (!isset($param['dias']))
            {

                // 1. Definimos uma largura maior para a janela (ex: 600px)
                $window = TWindow::create('CALCULAR NOVA DATA DE AGENDAMENTO', 600, null);
                $form   = new BootstrapFormBuilder('input_form_calcular_dias');
                $form->setFormTitle('');

                // Removemos sombras e bordas do formulário para o fundo branco ser limpo
                $form->setProperty('style', 'border:none; box-shadow:none; background-color:white;');

                // Criar formulário de entrada
                // $form = new BootstrapFormBuilder('input_form_calcular_dias');
                $dias = new TEntry('dias');
                $dias->setValue(7);            
                $dias->setTip('Quantos dias deseja?');
                $dias->setSize('100%');
                $dias->style = "max-width: 200px;"; // Mantém o campo com tamanho elegante

                // Campos ocultos
                $data_adicionar = new THidden('data_adicionar');
                $campo_alterar  = new THidden('campo_alterar');
                $horario_param  = $param['horario_inicial'] ?? '';             // Tentar obter valor de diferentes formas

                $data_adicionar->setValue($horario_param);
                $campo_alterar->setValue('horario_inicial');

                // ===== Label formatado =====
                $label01 = new TLabel("PARA CALCULAR A NOVA DATA DO AGENDAMENTO:");
                $label01->setFontColor('#F44336');
                $label01->setFontStyle('b');

                $label02 = new TLabel("INFORME A QUANTIDADE DE DIAS:");
                $label02->setFontColor('#F44336');
                $label02->setFontStyle('b');

                // --- O SEGREDO PARA FICAR ACIMA ---
                // Usamos addFields em linhas separadas e forçamos col-sm-12 (largura total)
                // Isso anula o comportamento de "coluna do lado da outra"
                $form->addFields([$label01])->layout    = 'vertical';    
                $form->addFields([$label02])->layout    = 'vertical';
                $form->addFields([$dias, $id])->layout  = 'vertical';

    /*
                $form->addFields
                (
                    [new TLabel('<b>Cálculo de Nova Data</b>')]
                );

                $form->addFields
                (
                    [new TLabel('Quantos dias deseja adicionar?')],
                    [$dias, $data_adicionar, $campo_alterar]
                );

                $form->addAction
                (
                    'Calcular',
                    new TAction([__CLASS__, 'adicionarDias']),
                    'fa:calculator green'
                );

                new TInputDialog('Cálculo de Nova Data de Agendamento', $form);
                echo "<style>.modal{z-index:9999 !important;}</style>";
*/
/*
                // ===== Botões =====
                $form->addAction('Confirmar', new TAction([__CLASS__, 'adicionarDias']),    'fa:check green');
                $form->addAction('Cancelar',  new TAction([__CLASS__, 'onduplicarNoDias']), 'fa:times red');

                // 2. Ajuste visual final: Fundo branco total e padding interno
                $container = new TElement('div');
                $container->style = "background-color:white; padding:25px; border-radius:5px;";
                $container->add($form);

                // CSS Adicional para garantir que o rodapé dos botões também seja branco
                // e que o label não tenha margem lateral esquerda (comum no Adianti)
                TScript::create("
                    $('.panel-footer').css('background-color', 'white').css('border-top', 'none');
                    $('.fb-field-container').css('padding-left', '0px');
                ");

                $window->add($container);
                $window->show();
            }
*/

    private static function updateFormDateTimeFields($object): void
    {
        try 
        {
            // Validar e formatar horario_inicial
            if (!empty($object->horario_inicial)) 
            {
                // Tentar múltiplos formatos
                $timestamp = false;

                // Primeiro tenta como DateTime completo
                $dt = DateTime::createFromFormat('Y-m-d H:i:s', $object->horario_inicial);
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('Y-m-d H:i', $object->horario_inicial);
                }
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y H:i:s', $object->horario_inicial);
                }
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y H:i', $object->horario_inicial);
                }

                // Se DateTime funcionou
                if ($dt !== false) 
                {
                    $object->horario_inicial = $dt->format('d-m-Y H:i');
                } 
                // Senão tenta strtotime com segurança
                else 
                {
                    $timestamp = @strtotime($object->horario_inicial);
                    if ($timestamp !== false) 
                    {
                        $object->horario_inicial = date('d-m-Y H:i', $timestamp);
                    }
                    // Se ainda falhar, deixa o valor como está
                }
            }

            // Validar e formatar horario_final
            if (!empty($object->horario_final)) 
            {
                $dt = DateTime::createFromFormat('Y-m-d H:i:s', $object->horario_final);
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('Y-m-d H:i', $object->horario_final);
                }
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y H:i:s', $object->horario_final);
                }
                if ($dt === false) 
                {
                    $dt = DateTime::createFromFormat('d-m-Y H:i', $object->horario_final);
                }

                if ($dt !== false) 
                {
                    $object->horario_final = $dt->format('d-m-Y H:i');
                } 
                else 
                {
                    $timestamp = @strtotime($object->horario_final);
                    if ($timestamp !== false) 
                    {
                        $object->horario_final = date('d-m-Y H:i', $timestamp);
                    }
                }
            }

            TForm::sendData(self::$formName, $object);
        }
        catch (Exception $e) 
        {
            new TMessage('error', '<b>' . TSession::getValue('username') . '</b> - Erro ao formatar datas: ' . $e->getMessage());
        }
    }

/*            
            if (empty($param['id']))
            {
                throw new Exception('<br>ID do agendamento não foi fornecido.');
            }

            $agendamentoId = $param['id'];
            $usuarioLogado = TSession::getValue('username') ?? 'Usuário';

            TTransaction::open(self::$database);

            $agendamento = Agendamento::find($agendamentoId);

            if (!$agendamento)
            {
                TTransaction::close();
                throw new Exception('<br>Agendamento com ID ' . htmlspecialchars($agendamentoId) . ' não encontrado.');
            }

            // Buscar dados do paciente relacionado
            $pacienteName = 'N/A';
            if (!empty($agendamento->paciente_id))
            {
                $paciente = Pessoa::find($agendamento->paciente_id);
                if ($paciente)
                {
                    $pacienteName = htmlspecialchars($paciente->nome ?? 'N/A');
                }
            }

            TTransaction::close();

            $mensagem  = "<b>{$usuarioLogado}</b><br><br>";
            $mensagem .= "Deseja cancelar este agendamento?<br>";
            $mensagem .= "<b>Agendamento:</b> " . htmlspecialchars($agendamentoId) . "<br>";
            $mensagem .= "<b>Paciente:</b> {$pacienteName}<br>";

            new TQuestion(
                $mensagem,
                 new TAction([__CLASS__, 'oncancelarYes'], $param), 
                 new TAction([__CLASS__, 'oncancelarNo'], $param)
            );
*/
