From 9666cc05653163ac38ce38e3b8556efad1ad0fe3 Mon Sep 17 00:00:00 2001 From: Nicolas Felipe Date: Sun, 26 Apr 2026 14:28:26 -0300 Subject: [PATCH] 26/04/2026 - Criando dashboard financeiro --- .../Cadastros/NfeInutilizadasCadastroPanel.cs | 97 +++ .../Cadastros/NfeNumeroLoteCadastroPanel.cs | 79 ++ .../Cadastros/NfeUfCidadeCadastroPanel.cs | 89 +++ .../Cadastros/NotasCceCadastroPanel.cs | 93 +++ .../Financeiro/DashboardFinanceiroPanel.cs | 684 ++++++++++++++++++ .../Financeiro/DashboardFinanceiroPanel.resx | 120 +++ UI/Dashboards/Main/Dash_main.Designer.cs | 24 + UI/Dashboards/Main/Dash_main.cs | 36 + 8 files changed, 1222 insertions(+) create mode 100644 UI/Dashboards/Cadastros/NfeInutilizadasCadastroPanel.cs create mode 100644 UI/Dashboards/Cadastros/NfeNumeroLoteCadastroPanel.cs create mode 100644 UI/Dashboards/Cadastros/NfeUfCidadeCadastroPanel.cs create mode 100644 UI/Dashboards/Cadastros/NotasCceCadastroPanel.cs create mode 100644 UI/Dashboards/Financeiro/DashboardFinanceiroPanel.cs create mode 100644 UI/Dashboards/Financeiro/DashboardFinanceiroPanel.resx diff --git a/UI/Dashboards/Cadastros/NfeInutilizadasCadastroPanel.cs b/UI/Dashboards/Cadastros/NfeInutilizadasCadastroPanel.cs new file mode 100644 index 0000000..e963a49 --- /dev/null +++ b/UI/Dashboards/Cadastros/NfeInutilizadasCadastroPanel.cs @@ -0,0 +1,97 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class NfeInutilizadasCadastroPanel : FormularioModelo + { + private ModeloNFEInutilizadas _inutilizada = new ModeloNFEInutilizadas(); + + // Controles - Identificação e Fiscal + private LV_TEXTBOX1 txtId, txtCodigo, txtModelo, txtDia; + + // Controles - Faixa Numérica + private LV_TEXTBOX1 txtNumeroInicial, txtNumeroFinal; + + // Controles - Justificativa + private LV_TEXTBOX1 txtMotivo; + + public NfeInutilizadasCadastroPanel() + { + this.Titulo = "Inutilização de Numeração de NF-e"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Dados do Evento --- + content.Controls.Add(CreateSectionHeader("DADOS DO PROTOCOLO", 20)); + + txtId = AddInput(content, "ID", 20, 50, 70, 30, true); + txtCodigo = AddInput(content, "PROTOCOLO SEFAZ", 100, 50, 250, 30); + txtDia = AddInput(content, "DATA DO EVENTO", 360, 50, 150, 30); + txtModelo = AddInput(content, "MOD (EX: 55)", 520, 50, 80, 30); + + // --- SEÇÃO 2: Faixa de Números --- + content.Controls.Add(CreateSectionHeader("FAIXA DE NUMERAÇÃO INUTILIZADA", 115)); + + txtNumeroInicial = AddInput(content, "NÚMERO INICIAL", 20, 145, 180, 30); + txtNumeroFinal = AddInput(content, "NÚMERO FINAL", 210, 145, 180, 30); + + Label lblDica = new Label + { + Text = "* Se for apenas uma nota, repita o número no Inicial e Final.", + Location = new Point(400, 161), + AutoSize = true, + ForeColor = Color.DimGray, + Font = new Font("Segoe UI", 8, FontStyle.Italic) + }; + content.Controls.Add(lblDica); + + // --- SEÇÃO 3: Justificativa --- + content.Controls.Add(CreateSectionHeader("MOTIVO DA INUTILIZAÇÃO", 210)); + txtMotivo = AddInput(content, "JUSTIFICATIVA (MÍNIMO 15 CARACTERES)", 20, 240, 780, 60); + + content.Height = 330; + } + + private void PreencherModel() + { + _inutilizada.CODIGO = txtCodigo.Text; + _inutilizada.DIA = txtDia.Text; + _inutilizada.MODELO = txtModelo.Text; + _inutilizada.NUMERO_INICIAL = txtNumeroInicial.Text; + _inutilizada.NUMERO_FINAL = txtNumeroFinal.Text; + _inutilizada.MOTIVO = txtMotivo.Text; + } + + protected override void OnNovo() + { + _inutilizada = new ModeloNFEInutilizadas(); + txtDia.Text = DateTime.Now.ToString("dd/MM/yyyy HH:mm"); + txtModelo.Text = "55"; // Valor padrão para NF-e + txtNumeroInicial.Focus(); + } + + protected override void OnSalvar() + { + if (txtMotivo.Text.Length < 15) + { + MessageBox.Show("A SEFAZ exige uma justificativa com no mínimo 15 caracteres.", "Validação Fiscal"); + return; + } + + PreencherModel(); + MessageBox.Show("Inutilização registrada e vinculada ao histórico fiscal!", "LevelOS Fiscal"); + } + + protected override void OnAlterar() { } + protected override void OnExcluir() { } + protected override void OnLocalizar() { } + protected override void OnCancelar() { } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Cadastros/NfeNumeroLoteCadastroPanel.cs b/UI/Dashboards/Cadastros/NfeNumeroLoteCadastroPanel.cs new file mode 100644 index 0000000..5f24a23 --- /dev/null +++ b/UI/Dashboards/Cadastros/NfeNumeroLoteCadastroPanel.cs @@ -0,0 +1,79 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class NfeNumeroLoteCadastroPanel : FormularioModelo + { + private ModeloNFENumeroLote _lote = new ModeloNFENumeroLote(); + + // Controles - Identificação e Rastreio + private LV_TEXTBOX1 txtId, txtNumLote, txtNumNF, txtDataGerado; + + // Controles - Resposta da SEFAZ + private LV_TEXTBOX1 txtRetorno; + + public NfeNumeroLoteCadastroPanel() + { + this.Titulo = "Gerenciamento de Lotes de NF-e"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Dados de Transmissão --- + content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO DO LOTE", 20)); + + txtId = AddInput(content, "ID INTERNO", 20, 50, 90, 30, true); + txtNumLote = AddInput(content, "Nº DO LOTE (RECIBO)", 120, 50, 200, 30); + txtNumNF = AddInput(content, "Nº DA NOTA FISCAL", 330, 50, 150, 30); + txtDataGerado = AddInput(content, "DATA DE GERAÇÃO", 490, 50, 180, 30, true); + + // --- SEÇÃO 2: Resposta do Processamento --- + content.Controls.Add(CreateSectionHeader("RETORNO DO WEBSERVICE (XML/JSON)", 115)); + + txtRetorno = AddInput(content, "STATUS E MENSAGEM DE RETORNO", 20, 145, 780, 100, true); + txtRetorno.Multiline = true; + //txtRetorno.ScrollBars = ScrollBars.Vertical; + + // Ajuste visual para o campo de retorno + txtRetorno.Height = 120; + + content.Height = 300; + } + + public void CarregarDados(ModeloNFENumeroLote lote) + { + _lote = lote; + txtId.Text = _lote.ID_NFE_NUM_LOTE.ToString(); + txtNumLote.Text = _lote.CODIGO; + txtNumNF.Text = _lote.NUM_NF; + txtDataGerado.Text = _lote.DATA_GERADO; + txtRetorno.Text = _lote.RETORNO; + + // Destaque visual para o status de retorno + if (_lote.RETORNO.Contains("100")) // Autorizado + { + txtRetorno.BackColor = Color.FromArgb(230, 255, 230); + txtRetorno.ForeColor = Color.DarkGreen; + } + else if (_lote.RETORNO.Contains("Rejeição")) + { + txtRetorno.BackColor = Color.FromArgb(255, 230, 230); + txtRetorno.ForeColor = Color.Red; + } + } + + protected override void OnNovo() { } // Lotes são gerados automaticamente pelo motor fiscal + protected override void OnSalvar() { } // Logs de lote são imutáveis após o retorno + protected override void OnExcluir() { } // Lotes não podem ser excluídos para manter histórico + protected override void OnAlterar() { } + protected override void OnLocalizar() { } + protected override void OnCancelar() { } + + } +} \ No newline at end of file diff --git a/UI/Dashboards/Cadastros/NfeUfCidadeCadastroPanel.cs b/UI/Dashboards/Cadastros/NfeUfCidadeCadastroPanel.cs new file mode 100644 index 0000000..f94d176 --- /dev/null +++ b/UI/Dashboards/Cadastros/NfeUfCidadeCadastroPanel.cs @@ -0,0 +1,89 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class NfeUfCidadeCadastroPanel : FormularioModelo + { + private ModeloNFEUfCidade _localidade = new ModeloNFEUfCidade(); + + // Controles - UF + private LV_TEXTBOX1 txtId, txtUfCod, txtUfNome; + + // Controles - Cidade + private LV_TEXTBOX1 txtCidCod, txtCidNome; + + public NfeUfCidadeCadastroPanel() + { + this.Titulo = "Cadastro de Cidades e Estados (IBGE)"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Unidade Federativa (Estado) --- + content.Controls.Add(CreateSectionHeader("ESTADO (UF)", 20)); + + txtId = AddInput(content, "ID INTERNO", 20, 50, 90, 30, true); + txtUfCod = AddInput(content, "CÓD. UF (IBGE)", 120, 50, 100, 30); + txtUfNome = AddInput(content, "NOME DO ESTADO", 230, 50, 250, 30); + + // --- SEÇÃO 2: Município --- + content.Controls.Add(CreateSectionHeader("MUNICÍPIO", 115)); + + txtCidCod = AddInput(content, "CÓD. MUNICÍPIO (IBGE)", 20, 145, 180, 30); + txtCidNome = AddInput(content, "NOME DA CIDADE", 210, 145, 450, 30); + + // Dica visual para o desenvolvedor (você) + Label lblInfo = new Label + { + Text = "* Estes dados são essenciais para as Tags e do XML da NF-e.", + Location = new Point(20, 190), + AutoSize = true, + ForeColor = Color.Gray, + Font = new Font("Segoe UI", 8, FontStyle.Italic) + }; + content.Controls.Add(lblInfo); + + content.Height = 230; + } + + private void PreencherModel() + { + _localidade.UF_COD = txtUfCod.Text; + _localidade.UF_NOME = txtUfNome.Text; + _localidade.CID_COD = txtCidCod.Text; + _localidade.CID_NOME = txtCidNome.Text; + } + + protected override void OnNovo() + { + _localidade = new ModeloNFEUfCidade(); + txtUfCod.Focus(); + } + + protected override void OnSalvar() + { + if (txtCidCod.Text.Length != 7) + { + MessageBox.Show("O código de município do IBGE deve ter exatamente 7 dígitos.", "Validação Fiscal"); + return; + } + + PreencherModel(); + MessageBox.Show("Localidade registrada com sucesso!", "LevelOS Database"); + } + + protected override void OnCancelar() { } + protected override void OnExcluir() { } + protected override void OnAlterar() { } + protected override void OnLocalizar() + { + + } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Cadastros/NotasCceCadastroPanel.cs b/UI/Dashboards/Cadastros/NotasCceCadastroPanel.cs new file mode 100644 index 0000000..e1cd479 --- /dev/null +++ b/UI/Dashboards/Cadastros/NotasCceCadastroPanel.cs @@ -0,0 +1,93 @@ +using CPM; +using MLL; +using System; +using System.Drawing; +using System.Windows.Forms; +using UI; + +namespace UI +{ + public partial class NotasCceCadastroPanel : FormularioModelo + { + private ModeloNotasCCE _cce = new ModeloNotasCCE(); + + // Controles - Rastreio + private LV_TEXTBOX1 txtId, txtChaveNfe, txtProtocolo, txtDataHora, txtSequencia; + + // Controles - Conteúdo + private LV_TEXTBOX1 txtCorrecao, txtRetorno; + + public NotasCceCadastroPanel() + { + this.Titulo = "Carta de Correção Eletrônica (CC-e)"; + MontarInterface(); + } + + private void MontarInterface() + { + // --- SEÇÃO 1: Dados do Evento --- + content.Controls.Add(CreateSectionHeader("VÍNCULO COM A NF-e", 20)); + + txtId = AddInput(content, "ID INTERNO", 20, 50, 80, 30, true); + txtChaveNfe = AddInput(content, "CHAVE DE ACESSO NF-e", 110, 50, 380, 30); + txtProtocolo = AddInput(content, "PROTOCOLO EVENTO", 500, 50, 220, 30, true); + + txtDataHora = AddInput(content, "DATA/HORA ENVIO", 20, 105, 180, 30, true); + txtSequencia = AddInput(content, "Nº SEQUENCIAL (EVENTO)", 210, 105, 150, 30); + + // --- SEÇÃO 2: Texto da Correção --- + content.Controls.Add(CreateSectionHeader("DETALHAMENTO DA CORREÇÃO", 165)); + + txtCorrecao = AddInput(content, "TEXTO DA CORREÇÃO (MÍNIMO 15 CARACTERES)", 20, 195, 700, 100); + txtCorrecao.Multiline = true; + //txtCorrecao.ScrollBars = ScrollBars.Vertical; + txtCorrecao.Height = 120; + + // --- SEÇÃO 3: Retorno SEFAZ --- + content.Controls.Add(CreateSectionHeader("RETORNO DO PROCESSAMENTO", 325)); + txtRetorno = AddInput(content, "STATUS / MENSAGEM DA SEFAZ", 20, 355, 700, 60, true); + txtRetorno.Multiline = true; + + content.Height = 450; + } + + private void PreencherModel() + { + _cce.COD_NFE = txtChaveNfe.Text; + _cce.CORRECAO = txtCorrecao.Text; + _cce.EVENTO = txtSequencia.Text; + _cce.DATA_HORA = txtDataHora.Text; + // TZD (Time Zone Designator) geralmente é capturado automaticamente pelo motor fiscal + _cce.TZD = "-03:00"; + } + + protected override void OnNovo() + { + _cce = new ModeloNotasCCE(); + txtDataHora.Text = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss"); + txtSequencia.Text = "1"; // Se for a primeira correção para esta nota + txtChaveNfe.Focus(); + } + + protected override void OnSalvar() + { + if (txtCorrecao.Text.Length < 15) + { + MessageBox.Show("A carta de correção deve ter no mínimo 15 caracteres.", "Regra Fiscal"); + return; + } + + PreencherModel(); + MessageBox.Show("Solicitação de Carta de Correção gerada!", "LevelOS Fiscal"); + } + + protected override void OnCancelar() { } + protected override void OnExcluir() { } + protected override void OnAlterar() { } + + protected override void OnLocalizar() + { + + } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Financeiro/DashboardFinanceiroPanel.cs b/UI/Dashboards/Financeiro/DashboardFinanceiroPanel.cs new file mode 100644 index 0000000..b12ff9b --- /dev/null +++ b/UI/Dashboards/Financeiro/DashboardFinanceiroPanel.cs @@ -0,0 +1,684 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using System.Collections.Generic; + +namespace UI +{ + public partial class DashboardFinanceiroPanel : FormularioModelo + { + // ── Paleta ──────────────────────────────────────────────── + private readonly Color C_Verde = Color.FromArgb(22, 163, 74); + private readonly Color C_Vermelho = Color.FromArgb(220, 38, 38); + private readonly Color C_Azul = Color.FromArgb(37, 99, 235); + private readonly Color C_Laranja = Color.FromArgb(234, 88, 12); + private readonly Color C_Roxo = Color.FromArgb(124, 58, 237); + private readonly Color C_Fundo = Color.FromArgb(248, 250, 252); + private readonly Color C_Borda = Color.FromArgb(226, 232, 240); + private readonly Color C_Texto = Color.FromArgb(30, 41, 59); + private readonly Color C_Cinza = Color.FromArgb(100, 116, 139); + + // ── Helpers estáticos ───────────────────────────────────── + private static decimal R(decimal v) => v; + private static DateTime DH(int dias) => DateTime.Today.AddDays(dias); + + // ── Dados simulados: Financeiro ─────────────────────────── + private readonly decimal[] _vendasMes = { 48200, 53400, 41800, 62100, 57300, 68900, 72400, 65800, 71200, 84300, 79600, 91200 }; + private readonly string[] _meses = { "Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez" }; + + private readonly (string Cliente, decimal Valor, int DiasAtraso)[] _inadimplentes = + { + ("Comércio Silva Ltda", R(3200), 15), + ("Distribuidora ABC", R(8750), 32), + ("Mercado São João", R(1450), 8), + ("Atacado Norte S/A", R(12300), 47), + ("Loja Central ME", R(980), 3), + }; + + private readonly (string Descricao, decimal Valor, DateTime Venc, bool APagar)[] _lancamentos = + { + ("Fornecedor XYZ", R(4500), DH(3), true), + ("Aluguel Loja", R(3200), DH(5), true), + ("Receb. Cliente 001", R(7800), DH(2), false), + ("Energia Elétrica", R(890), DH(8), true), + ("Receb. Cliente 002", R(3200), DH(4), false), + ("Folha de Pagamento", R(18000), DH(10), true), + ("Receb. Cliente 003", R(5500), DH(1), false), + ("Manutenção Equipamentos", R(1200), DH(6), true), + }; + + // ── Dados simulados: Ordens de Serviço ─────────────────── + private readonly (string OS, string Cliente, string Responsavel, decimal Valor, string Status, DateTime Prazo)[] _ordensServico = + { + ("OS-0041", "Comércio Silva Ltda", "Carlos", R(1200), "Em andamento", DH(2)), + ("OS-0042", "Distribuidora ABC", "Marcos", R(3500), "Aberta", DH(0)), + ("OS-0043", "Mercado São João", "Carlos", R(800), "Atrasada", DH(-3)), + ("OS-0044", "Atacado Norte S/A", "Julia", R(5200), "Concluída", DH(-1)), + ("OS-0045", "Loja Central ME", "Marcos", R(950), "Atrasada", DH(-7)), + ("OS-0046", "Fornecedor XYZ", "Julia", R(2100), "Em andamento", DH(5)), + ("OS-0047", "Cliente Novo Ltda", "Carlos", R(1750), "Concluída", DH(-2)), + ("OS-0048", "Empresa Teste S/A", "Marcos", R(4300), "Aberta", DH(4)), + }; + + // ───────────────────────────────────────────────────────── + public DashboardFinanceiroPanel() + { + Titulo = "Dashboard Financeiro"; + MontarDashboard(); + } + + private void MontarDashboard() + { + content.Controls.Clear(); + content.BackColor = C_Fundo; + content.Width = 1100; + + int y = 16; + + y = AdicionarFiltro(y); + y = AdicionarKPIs(y + 10); + y = AdicionarGraficoEFluxo(y + 14); + y = AdicionarTabelasInferiores(y + 14); + y = AdicionarBlocoOS(y + 14); + + content.Height = y + 24; + } + + // ══════════════════════════════════════════════════════════ + // FILTRO + // ══════════════════════════════════════════════════════════ + private int AdicionarFiltro(int y) + { + var pnl = new Panel + { + Location = new Point(16, y), + Size = new Size(1068, 44), + BackColor = Color.White + }; + pnl.Paint += PaintCard; + + var lblDe = Lbl("Período:", 14, 14, bold: true); lblDe.ForeColor = C_Cinza; + var dtDe = new DateTimePicker { Location = new Point(74, 10), Width = 120, Format = DateTimePickerFormat.Short, Value = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1) }; + var lblAte = Lbl("até", 204, 14); lblAte.ForeColor = C_Cinza; + var dtAte = new DateTimePicker { Location = new Point(228, 10), Width = 120, Format = DateTimePickerFormat.Short, Value = DateTime.Today }; + + var btnAtualizar = new Button + { + Text = "⟳ Atualizar", + Location = new Point(368, 8), + Size = new Size(110, 28), + FlatStyle = FlatStyle.Flat, + BackColor = C_Azul, + ForeColor = Color.White, + Font = new Font("Segoe UI Semibold", 8.5f), + Cursor = Cursors.Hand + }; + btnAtualizar.FlatAppearance.BorderSize = 0; + + pnl.Controls.AddRange(new Control[] { lblDe, dtDe, lblAte, dtAte, btnAtualizar }); + + string[] periodos = { "Mês Atual", "Trimestre", "Ano" }; + int bx = 500; + foreach (var p in periodos) + { + var b = new Button + { + Text = p, + Location = new Point(bx, 8), + Size = new Size(88, 28), + FlatStyle = FlatStyle.Flat, + BackColor = C_Fundo, + ForeColor = C_Texto, + Font = new Font("Segoe UI", 8.5f), + Cursor = Cursors.Hand + }; + b.FlatAppearance.BorderColor = C_Borda; + b.FlatAppearance.BorderSize = 1; + pnl.Controls.Add(b); + bx += 96; + } + + content.Controls.Add(pnl); + return y + pnl.Height; + } + + // ══════════════════════════════════════════════════════════ + // KPI CARDS — FINANCEIRO + // ══════════════════════════════════════════════════════════ + private int AdicionarKPIs(int y) + { + var dados = new[] + { + ("Vendas do Dia", "R$ 4.250,00", "↑ 12% vs ontem", C_Verde), + ("Vendas do Mês", "R$ 91.200,00", "↑ 8% vs mês anterior", C_Azul), + ("Contas a Receber", "R$ 38.600,00", "12 títulos em aberto", C_Verde), + ("Contas a Pagar", "R$ 27.790,00", "8 vencimentos próximos", C_Vermelho), + ("Inadimplência", "R$ 26.680,00", "5 clientes em atraso", C_Laranja), + }; + + int cardW = 200, gap = 13, x = 16; + foreach (var (titulo, valor, sub, cor) in dados) + { + var card = new Panel { Location = new Point(x, y), Size = new Size(cardW, 90), BackColor = Color.White }; + card.Paint += PaintCard; + + var acento = new Panel { Dock = DockStyle.Top, Height = 4, BackColor = cor }; + var lblT = Lbl(titulo, 14, 14); lblT.ForeColor = C_Cinza; lblT.Font = new Font("Segoe UI", 8f); + var lblV = Lbl(valor, 14, 30); lblV.Font = new Font("Segoe UI", 13f, FontStyle.Bold); lblV.ForeColor = C_Texto; + var lblS = Lbl(sub, 14, 62); lblS.ForeColor = cor; lblS.Font = new Font("Segoe UI", 7.5f); + + card.Controls.AddRange(new Control[] { acento, lblT, lblV, lblS }); + content.Controls.Add(card); + x += cardW + gap; + } + + return y + 90; + } + + // ══════════════════════════════════════════════════════════ + // GRÁFICO DE BARRAS + FLUXO DE CAIXA + // ══════════════════════════════════════════════════════════ + private int AdicionarGraficoEFluxo(int y) + { + const int alturaBloco = 300; + + var pnlGrafico = new Panel { Location = new Point(16, y), Size = new Size(680, alturaBloco), BackColor = Color.White }; + pnlGrafico.Paint += (s, e) => { PaintCard(s, e); DesenharGraficoBarras(e.Graphics, pnlGrafico.ClientRectangle); }; + content.Controls.Add(pnlGrafico); + + var pnlFluxo = new Panel { Location = new Point(704, y), Size = new Size(380, alturaBloco), BackColor = Color.White }; + pnlFluxo.Paint += PaintCard; + PreencherFluxoCaixa(pnlFluxo); + content.Controls.Add(pnlFluxo); + + return y + alturaBloco; + } + + private void DesenharGraficoBarras(Graphics g, Rectangle area) + { + g.SmoothingMode = SmoothingMode.AntiAlias; + + var fTitulo = new Font("Segoe UI", 10f, FontStyle.Bold); + var fLabel = new Font("Segoe UI", 7f); + var fValor = new Font("Segoe UI", 6.5f); + + g.DrawString("Vendas por Mês (R$)", fTitulo, new SolidBrush(C_Texto), new Point(16, 14)); + + int padL = 50, padR = 16, padT = 44, padB = 40; + int chartW = area.Width - padL - padR; + int chartH = area.Height - padT - padB; + + decimal maxVal = 0; + foreach (var v in _vendasMes) if (v > maxVal) maxVal = v; + maxVal = Math.Ceiling(maxVal / 10000m) * 10000m; + + int linhas = 5; + using var penGrade = new Pen(Color.FromArgb(235, 239, 244), 1f); + for (int i = 0; i <= linhas; i++) + { + int gy = padT + (int)(chartH * i / linhas); + g.DrawLine(penGrade, padL, gy, padL + chartW, gy); + decimal rotulo = maxVal * (linhas - i) / linhas; + g.DrawString("R$" + (rotulo / 1000m).ToString("0k"), fLabel, new SolidBrush(C_Cinza), new PointF(2, gy - 7)); + } + + int n = _vendasMes.Length; + float barW = (float)chartW / n * 0.55f; + float slotW = (float)chartW / n; + + for (int i = 0; i < n; i++) + { + float barH = (float)(_vendasMes[i] / maxVal) * chartH; + float bx = padL + i * slotW + (slotW - barW) / 2f; + float by = padT + chartH - barH; + + var rect = new RectangleF(bx, by, barW, barH); + using var brush = new LinearGradientBrush(rect, Color.FromArgb(99, 132, 255), C_Azul, LinearGradientMode.Vertical); + g.FillRectangle(brush, rect); + + g.DrawString(_meses[i], fLabel, new SolidBrush(C_Cinza), new PointF(bx + barW / 2f - 8, padT + chartH + 6)); + string val = "R$" + (_vendasMes[i] / 1000m).ToString("0.0k"); + g.DrawString(val, fValor, new SolidBrush(C_Azul), new PointF(bx - 2, by - 14)); + } + + using var penEixo = new Pen(C_Borda, 1f); + g.DrawLine(penEixo, padL, padT, padL, padT + chartH); + } + + private void PreencherFluxoCaixa(Panel pnl) + { + pnl.Controls.Add(TituloSecao("Fluxo de Caixa — " + DateTime.Today.ToString("MMM/yyyy"), 16, 14)); + + var itens = new[] + { + ("Saldo Inicial", "R$ 45.000,00", C_Texto), + ("(+) Entradas", "R$ 38.600,00", C_Verde), + ("(-) Saídas", "R$ 27.790,00", C_Vermelho), + ("(=) Saldo Final", "R$ 55.810,00", C_Azul), + }; + + int yi = 50; + foreach (var (desc, val, cor) in itens) + { + bool isFinal = desc.StartsWith("(=)"); + var row = new Panel + { + Location = new Point(16, yi), + Size = new Size(348, isFinal ? 44 : 36), + BackColor = isFinal ? Color.FromArgb(239, 246, 255) : Color.Transparent + }; + if (isFinal) row.Paint += PaintCard; + + var lD = Lbl(desc, 10, isFinal ? 13 : 10); + lD.Font = new Font("Segoe UI", isFinal ? 9f : 8.5f, isFinal ? FontStyle.Bold : FontStyle.Regular); + lD.ForeColor = C_Texto; + + var lV = new Label + { + Text = val, + AutoSize = true, + Location = new Point(220, isFinal ? 13 : 10), + Font = new Font("Segoe UI", isFinal ? 9f : 8.5f, FontStyle.Bold), + ForeColor = cor + }; + + row.Controls.AddRange(new Control[] { lD, lV }); + pnl.Controls.Add(row); + yi += isFinal ? 50 : 38; + } + + var linha = new Panel { Location = new Point(16, yi - 55), Size = new Size(348, 1), BackColor = C_Borda }; + pnl.Controls.Add(linha); + + yi += 10; + pnl.Controls.Add(TituloSecao("Indicadores do Mês", 16, yi)); yi += 28; + + var indicadores = new[] + { + ("Ticket Médio", "R$ 354,17", C_Azul), + ("Margem Líquida", "23,4%", C_Verde), + ("Giro de Caixa", "8,2×", C_Roxo), + }; + + foreach (var (ind, vl, cor) in indicadores) + { + var chip = new Panel { Location = new Point(16, yi), Size = new Size(348, 32), BackColor = Color.Transparent }; + var lI = Lbl(ind, 0, 8); lI.ForeColor = C_Cinza; lI.Font = new Font("Segoe UI", 8f); + var lV2 = new Label { Text = vl, AutoSize = true, Location = new Point(240, 8), Font = new Font("Segoe UI Semibold", 8.5f), ForeColor = cor }; + chip.Controls.AddRange(new Control[] { lI, lV2 }); + pnl.Controls.Add(chip); + yi += 32; + } + } + + // ══════════════════════════════════════════════════════════ + // CONTAS A PAGAR/RECEBER + INADIMPLÊNCIA + // ══════════════════════════════════════════════════════════ + private int AdicionarTabelasInferiores(int y) + { + const int alturaBloco = 320; + + var pnlContas = new Panel { Location = new Point(16, y), Size = new Size(540, alturaBloco), BackColor = Color.White }; + pnlContas.Paint += PaintCard; + PreencherContas(pnlContas); + content.Controls.Add(pnlContas); + + var pnlInad = new Panel { Location = new Point(564, y), Size = new Size(520, alturaBloco), BackColor = Color.White }; + pnlInad.Paint += PaintCard; + PreencherInadimplencia(pnlInad); + content.Controls.Add(pnlInad); + + return y + alturaBloco; + } + + private void PreencherContas(Panel pnl) + { + pnl.Controls.Add(TituloSecao("Contas a Pagar / Receber — Próximos Vencimentos", 14, 14)); + + pnl.Controls.Add(CriarLinhaTabela( + ("Descrição", 180), ("Valor", 100), ("Venc.", 80), ("Tipo", 70), ("Status", 80), + isHeader: true, y: 44)); + + int yi = 72; + foreach (var (desc, valor, venc, aPagar) in _lancamentos) + { + int dias = (venc - DateTime.Today).Days; + string status = dias < 0 ? "Vencido" : dias == 0 ? "Hoje" : $"{dias}d"; + Color corStatus = dias < 0 ? C_Vermelho : dias <= 3 ? C_Laranja : C_Verde; + + pnl.Controls.Add(CriarLinhaTabela( + (desc, 180), + ("R$ " + valor.ToString("N2"), 100), + (venc.ToString("dd/MM"), 80), + (aPagar ? "Pagar" : "Receber", 70), + (status, 80), + isHeader: false, y: yi, + corColuna4: aPagar ? C_Vermelho : C_Verde, + corColuna5: corStatus)); + yi += 28; + } + } + + private void PreencherInadimplencia(Panel pnl) + { + pnl.Controls.Add(TituloSecao("Inadimplência — Clientes em Atraso", 14, 14)); + + pnl.Controls.Add(CriarLinhaTabela( + ("Cliente", 200), ("Valor", 100), ("Dias Atraso", 90), ("Situação", 100), + isHeader: true, y: 44)); + + int yi = 72; + foreach (var (cliente, valor, dias) in _inadimplentes) + { + string situacao = dias <= 15 ? "Em negociação" : dias <= 30 ? "Notificado" : "Jurídico"; + Color corSit = dias <= 15 ? C_Laranja : dias <= 30 ? C_Vermelho : Color.FromArgb(127, 29, 29); + + pnl.Controls.Add(CriarLinhaTabela( + (cliente, 200), + ("R$ " + valor.ToString("N2"), 100), + (dias + " dias", 90), + (situacao, 100), + isHeader: false, y: yi, + corColuna4: corSit)); + yi += 28; + } + + decimal totalInad = 0; + foreach (var i in _inadimplentes) totalInad += i.Valor; + + var tot = new Panel { Location = new Point(14, yi + 6), Size = new Size(490, 32), BackColor = Color.FromArgb(255, 241, 242) }; + tot.Paint += PaintCard; + var lT = Lbl("Total inadimplente:", 10, 8); lT.Font = new Font("Segoe UI Semibold", 8.5f); + var lV = new Label { Text = "R$ " + totalInad.ToString("N2"), AutoSize = true, Location = new Point(310, 8), Font = new Font("Segoe UI", 9f, FontStyle.Bold), ForeColor = C_Vermelho }; + tot.Controls.AddRange(new Control[] { lT, lV }); + pnl.Controls.Add(tot); + } + + // ══════════════════════════════════════════════════════════ + // ORDENS DE SERVIÇO + // ══════════════════════════════════════════════════════════ + private int AdicionarBlocoOS(int y) + { + const int alturaBloco = 370; + + y = AdicionarKPIsOS(y); + + var pnlTabela = new Panel { Location = new Point(16, y + 10), Size = new Size(690, alturaBloco), BackColor = Color.White }; + pnlTabela.Paint += PaintCard; + PreencherTabelaOS(pnlTabela); + content.Controls.Add(pnlTabela); + + var pnlRanking = new Panel { Location = new Point(714, y + 10), Size = new Size(370, alturaBloco), BackColor = Color.White }; + pnlRanking.Paint += PaintCard; + PreencherRankingTecnicos(pnlRanking); + content.Controls.Add(pnlRanking); + + return y + 10 + alturaBloco; + } + + private int AdicionarKPIsOS(int y) + { + int abertas = 0, andamento = 0, atrasadas = 0, concluidas = 0; + decimal totalValor = 0; + + foreach (var os in _ordensServico) + { + totalValor += os.Valor; + switch (os.Status) + { + case "Aberta": abertas++; break; + case "Em andamento": andamento++; break; + case "Atrasada": atrasadas++; break; + case "Concluída": concluidas++; break; + } + } + + var kpis = new[] + { + ("OS Abertas", abertas.ToString(), "Aguardando início", C_Azul), + ("Em Andamento", andamento.ToString(), "Em execução agora", C_Roxo), + ("Atrasadas", atrasadas.ToString(), "⚠ Requerem atenção", C_Vermelho), + ("Concluídas no Mês", concluidas.ToString(), "Finalizadas este mês", C_Verde), + ("Valor Total OS", "R$ " + totalValor.ToString("N2"), "Misto: cobrado + interno", C_Laranja), + }; + + int cardW = 200, gap = 13, x = 16; + foreach (var (titulo, valor, sub, cor) in kpis) + { + var card = new Panel { Location = new Point(x, y), Size = new Size(cardW, 80), BackColor = Color.White }; + card.Paint += PaintCard; + + var acento = new Panel { Dock = DockStyle.Top, Height = 4, BackColor = cor }; + var lblT = Lbl(titulo, 14, 12); lblT.ForeColor = C_Cinza; lblT.Font = new Font("Segoe UI", 8f); + var lblV = Lbl(valor, 14, 28); lblV.Font = new Font("Segoe UI", 13f, FontStyle.Bold); lblV.ForeColor = C_Texto; + var lblS = Lbl(sub, 14, 56); lblS.ForeColor = cor; lblS.Font = new Font("Segoe UI", 7.5f); + + card.Controls.AddRange(new Control[] { acento, lblT, lblV, lblS }); + content.Controls.Add(card); + x += cardW + gap; + } + + return y + 80; + } + + private void PreencherTabelaOS(Panel pnl) + { + pnl.Controls.Add(TituloSecao("Ordens de Serviço — Visão Geral", 14, 14)); + + pnl.Controls.Add(CriarLinhaOS( + ("Nº OS", 65), ("Cliente", 160), ("Responsável", 100), + ("Valor", 90), ("Prazo", 90), ("Status", 90), + isHeader: true, y: 44)); + + int yi = 72; + foreach (var (os, cliente, resp, valor, status, prazo) in _ordensServico) + { + int dias = (prazo - DateTime.Today).Days; + string prazoTxt = dias < 0 ? $"{Math.Abs(dias)}d atraso" : dias == 0 ? "Hoje" : $"{dias}d restantes"; + Color corPrazo = dias < 0 ? C_Vermelho : dias <= 2 ? C_Laranja : C_Verde; + Color corStatus = status switch + { + "Concluída" => C_Verde, + "Em andamento" => C_Azul, + "Atrasada" => C_Vermelho, + _ => C_Cinza + }; + + pnl.Controls.Add(CriarLinhaOS( + (os, 65), (cliente, 160), (resp, 100), + ("R$ " + valor.ToString("N2"), 90), (prazoTxt, 90), (status, 90), + isHeader: false, y: yi, + corColuna5: corPrazo, corColuna6: corStatus)); + yi += 28; + } + + decimal total = 0; + foreach (var o in _ordensServico) total += o.Valor; + + var tot = new Panel { Location = new Point(14, yi + 6), Size = new Size(660, 32), BackColor = Color.FromArgb(241, 245, 249) }; + tot.Paint += PaintCard; + var lT = Lbl("Total em OS:", 10, 8); lT.Font = new Font("Segoe UI Semibold", 8.5f); + var lV = new Label { Text = "R$ " + total.ToString("N2"), AutoSize = true, Location = new Point(540, 8), Font = new Font("Segoe UI", 9f, FontStyle.Bold), ForeColor = C_Azul }; + tot.Controls.AddRange(new Control[] { lT, lV }); + pnl.Controls.Add(tot); + } + + private void PreencherRankingTecnicos(Panel pnl) + { + pnl.Controls.Add(TituloSecao("Ranking de Responsáveis", 14, 14)); + + var dic = new Dictionary(); + foreach (var os in _ordensServico) + { + if (!dic.ContainsKey(os.Responsavel)) + dic[os.Responsavel] = (0, 0, 0, 0); + var cur = dic[os.Responsavel]; + dic[os.Responsavel] = ( + cur.total + 1, + cur.concluidas + (os.Status == "Concluída" ? 1 : 0), + cur.atrasadas + (os.Status == "Atrasada" ? 1 : 0), + cur.valor + os.Valor + ); + } + + int yi = 48, pos = 1; + foreach (var kv in dic) + { + var (total, conc, atras, valor) = kv.Value; + float pct = total > 0 ? (float)conc / total : 0f; + + var card = new Panel { Location = new Point(14, yi), Size = new Size(342, 88), BackColor = C_Fundo }; + card.Paint += PaintCard; + + var lblPos = new Label + { + Text = $"#{pos}", + Location = new Point(10, 10), + Size = new Size(30, 30), + Font = new Font("Segoe UI", 11f, FontStyle.Bold), + ForeColor = pos == 1 ? Color.FromArgb(202, 138, 4) : C_Cinza, + TextAlign = ContentAlignment.MiddleCenter + }; + + var lblNome = Lbl(kv.Key, 48, 10); lblNome.Font = new Font("Segoe UI Semibold", 9.5f); + var lblTotal = Lbl($"{total} OS • R$ {valor:N2}", 48, 28); lblTotal.ForeColor = C_Cinza; lblTotal.Font = new Font("Segoe UI", 8f); + var lblConc = Lbl($"✔ {conc} concluída(s)", 48, 46); lblConc.ForeColor = C_Verde; lblConc.Font = new Font("Segoe UI", 7.5f); + var lblAtras = Lbl($"⚠ {atras} atrasada(s)", 170, 46); lblAtras.ForeColor = C_Vermelho; lblAtras.Font = new Font("Segoe UI", 7.5f); + + var barBg = new Panel { Location = new Point(48, 66), Size = new Size(284, 8), BackColor = C_Borda }; + var barFill = new Panel { Location = new Point(0, 0), Size = new Size((int)(284 * pct), 8), BackColor = pct >= 0.7f ? C_Verde : pct >= 0.4f ? C_Laranja : C_Vermelho }; + barBg.Controls.Add(barFill); + + var lblPct = Lbl($"{pct:P0}", 336, 60); lblPct.Font = new Font("Segoe UI", 7f); lblPct.ForeColor = C_Cinza; + + card.Controls.AddRange(new Control[] { lblPos, lblNome, lblTotal, lblConc, lblAtras, barBg, lblPct }); + pnl.Controls.Add(card); + yi += 98; + pos++; + } + } + + // ══════════════════════════════════════════════════════════ + // HELPERS DE LAYOUT + // ══════════════════════════════════════════════════════════ + private Panel CriarLinhaTabela( + (string texto, int largura) c1, + (string texto, int largura) c2, + (string texto, int largura) c3, + (string texto, int largura) c4, + (string texto, int largura) c5 = default, + bool isHeader = false, int y = 0, + Color? corColuna4 = null, + Color? corColuna5 = null) + { + var row = new Panel + { + Location = new Point(14, y), + Size = new Size(510, isHeader ? 24 : 26), + BackColor = isHeader ? Color.FromArgb(241, 245, 249) : Color.Transparent + }; + + var cols = new[] { c1, c2, c3, c4, c5 }; + Color[] cores = { C_Texto, C_Texto, C_Texto, corColuna4 ?? C_Texto, corColuna5 ?? C_Texto }; + + int x = 0; + for (int i = 0; i < cols.Length; i++) + { + if (cols[i].largura == 0) continue; + var lbl = new Label + { + Text = cols[i].texto, + Location = new Point(x + 4, isHeader ? 5 : 6), + Size = new Size(cols[i].largura, 18), + Font = new Font("Segoe UI", isHeader ? 7.5f : 8f, isHeader ? FontStyle.Bold : FontStyle.Regular), + ForeColor = isHeader ? C_Cinza : cores[i] + }; + row.Controls.Add(lbl); + x += cols[i].largura; + } + + if (!isHeader) + row.Paint += (s, e) => e.Graphics.DrawLine(new Pen(Color.FromArgb(241, 245, 249)), 0, row.Height - 1, row.Width, row.Height - 1); + + return row; + } + + private Panel CriarLinhaOS( + (string texto, int largura) c1, + (string texto, int largura) c2, + (string texto, int largura) c3, + (string texto, int largura) c4, + (string texto, int largura) c5, + (string texto, int largura) c6, + bool isHeader = false, int y = 0, + Color? corColuna5 = null, + Color? corColuna6 = null) + { + var row = new Panel + { + Location = new Point(14, y), + Size = new Size(660, isHeader ? 24 : 26), + BackColor = isHeader ? Color.FromArgb(241, 245, 249) : Color.Transparent + }; + + var cols = new[] { c1, c2, c3, c4, c5, c6 }; + Color[] cores = { C_Texto, C_Texto, C_Texto, C_Texto, corColuna5 ?? C_Texto, corColuna6 ?? C_Texto }; + + int x = 0; + for (int i = 0; i < cols.Length; i++) + { + var lbl = new Label + { + Text = cols[i].texto, + Location = new Point(x + 4, isHeader ? 5 : 6), + Size = new Size(cols[i].largura, 18), + Font = new Font("Segoe UI", isHeader ? 7.5f : 8f, isHeader ? FontStyle.Bold : FontStyle.Regular), + ForeColor = isHeader ? C_Cinza : cores[i] + }; + row.Controls.Add(lbl); + x += cols[i].largura; + } + + if (!isHeader) + row.Paint += (s, e) => e.Graphics.DrawLine(new Pen(Color.FromArgb(241, 245, 249)), 0, row.Height - 1, row.Width, row.Height - 1); + + return row; + } + + private Label TituloSecao(string texto, int x, int y) => new Label + { + Text = texto, + Location = new Point(x, y), + AutoSize = true, + Font = new Font("Segoe UI Semibold", 9f), + ForeColor = C_Texto + }; + + private Label Lbl(string texto, int x, int y, bool bold = false) => new Label + { + Text = texto, + Location = new Point(x, y), + AutoSize = true, + Font = new Font("Segoe UI", 8.5f, bold ? FontStyle.Bold : FontStyle.Regular), + ForeColor = C_Texto + }; + + private void PaintCard(object? sender, PaintEventArgs e) + { + if (sender is not Control c) return; + using var pen = new Pen(C_Borda); + e.Graphics.DrawRectangle(pen, new Rectangle(0, 0, c.Width - 1, c.Height - 1)); + } + + // ══════════════════════════════════════════════════════════ + // MÉTODOS OBRIGATÓRIOS + // ══════════════════════════════════════════════════════════ + protected override void OnNovo() { } + protected override void OnSalvar() { } + protected override void OnAlterar() { } + protected override void OnCancelar() { } + protected override void OnLocalizar() { } + protected override void OnExcluir() { } + } +} \ No newline at end of file diff --git a/UI/Dashboards/Financeiro/DashboardFinanceiroPanel.resx b/UI/Dashboards/Financeiro/DashboardFinanceiroPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/UI/Dashboards/Financeiro/DashboardFinanceiroPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/UI/Dashboards/Main/Dash_main.Designer.cs b/UI/Dashboards/Main/Dash_main.Designer.cs index af35c5b..bc629f7 100644 --- a/UI/Dashboards/Main/Dash_main.Designer.cs +++ b/UI/Dashboards/Main/Dash_main.Designer.cs @@ -32,6 +32,7 @@ lV_button1 = new CPM.LV_BUTTON(); lV_button2 = new CPM.LV_BUTTON(); lV_button3 = new CPM.LV_BUTTON(); + lV_button4 = new CPM.LV_BUTTON(); SuspendLayout(); // // lbltest @@ -106,11 +107,33 @@ lV_button3.UseVisualStyleBackColor = false; lV_button3.Click += lV_button3_Click; // + // lV_button4 + // + lV_button4.BackColor = Color.MediumSlateBlue; + lV_button4.BackgroundColor = Color.MediumSlateBlue; + lV_button4.BorderColor = Color.PaleVioletRed; + lV_button4.BorderRadius = 0; + lV_button4.BorderSize = 0; + lV_button4.ClickColor = Color.DarkBlue; + lV_button4.FlatAppearance.BorderSize = 0; + lV_button4.FlatStyle = FlatStyle.Flat; + lV_button4.ForeColor = Color.White; + lV_button4.HoverColor = Color.LightBlue; + lV_button4.Location = new Point(734, 126); + lV_button4.Name = "lV_button4"; + lV_button4.Size = new Size(148, 32); + lV_button4.TabIndex = 4; + lV_button4.Text = "Dash - Financeiro"; + lV_button4.TextColor = Color.White; + lV_button4.UseVisualStyleBackColor = false; + lV_button4.Click += lV_button4_Click; + // // Form1 // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(894, 474); + Controls.Add(lV_button4); Controls.Add(lV_button3); Controls.Add(lV_button2); Controls.Add(lV_button1); @@ -128,5 +151,6 @@ private CPM.LV_BUTTON lV_button1; private CPM.LV_BUTTON lV_button2; private CPM.LV_BUTTON lV_button3; + private CPM.LV_BUTTON lV_button4; } } diff --git a/UI/Dashboards/Main/Dash_main.cs b/UI/Dashboards/Main/Dash_main.cs index a942080..25d805a 100644 --- a/UI/Dashboards/Main/Dash_main.cs +++ b/UI/Dashboards/Main/Dash_main.cs @@ -71,5 +71,41 @@ namespace UI NT_MessageBox.Show(conectionString); } + // Dentro do seu MainForm onde você gerencia a navegação + //private void AbrirModulo(Form painelFilho) + //{ + // // Limpa o que estiver no painel central (ex: pnlConteudo) + // if (this.pnlConteudo.Controls.Count > 0) + // this.pnlConteudo.Controls.RemoveAt(0); + + // painelFilho.TopLevel = false; + // painelFilho.FormBorderStyle = FormBorderStyle.None; + // painelFilho.Dock = DockStyle.Fill; + + // this.pnlConteudo.Controls.Add(painelFilho); + // this.pnlConteudo.Tag = painelFilho; + // painelFilho.Show(); + // painelFilho.BringToFront(); + //} + + //// No clique do menu: + //DashboardFinanceiroPanel dashboard = new DashboardFinanceiroPanel(); + //AbrirModulo(dashboard); + + private void lV_button4_Click(object sender, EventArgs e) + { + DashboardFinanceiroPanel dashboard = new DashboardFinanceiroPanel(); + dashboard.Dock = DockStyle.Fill; + + Form janela = new Form + { + Text = "Dashboard Financeiro", + Size = new Size(1100, 750), + StartPosition = FormStartPosition.CenterScreen + }; + + janela.Controls.Add(dashboard); + janela.Show(); + } } }