20/04/2026 - Criando interfaces

This commit is contained in:
levelcode developed 2026-04-20 02:58:10 -03:00
parent 7882311e7b
commit 35171ffde0
15 changed files with 2339 additions and 57 deletions

242
CPM/ComboBox/LV_COMBOBOX.cs Normal file
View File

@ -0,0 +1,242 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace CPM
{
/// <summary>
/// ComboBox customizado do sistema LevelOS.
/// Segue o mesmo padrão visual do LV_TEXTBOX1.
/// </summary>
public class LV_COMBOBOX : UserControl
{
// ── CAMPOS INTERNOS ───────────────────────────────────────────────────
private ComboBox _combo;
private bool _isFocused = false;
// ── PROPRIEDADES VISUAIS ──────────────────────────────────────────────
private Color _borderColor = Color.FromArgb(226, 232, 240);
private Color _borderFocusColor = Color.FromArgb(37, 99, 235);
private Color _arrowColor = Color.FromArgb(100, 116, 139);
private int _borderRadius = 6;
private int _borderSize = 1;
public Color BorderColor
{
get => _borderColor;
set { _borderColor = value; Invalidate(); }
}
public Color BorderFocusColor
{
get => _borderFocusColor;
set { _borderFocusColor = value; Invalidate(); }
}
public Color ArrowColor
{
get => _arrowColor;
set { _arrowColor = value; Invalidate(); }
}
public int BorderRadius
{
get => _borderRadius;
set { _borderRadius = value; Invalidate(); }
}
public int BorderSize
{
get => _borderSize;
set { _borderSize = value; Invalidate(); }
}
// ── PROPRIEDADES DO COMBOBOX ──────────────────────────────────────────
public ComboBoxStyle DropDownStyle
{
get => _combo.DropDownStyle;
set => _combo.DropDownStyle = value;
}
public System.Windows.Forms.ComboBox.ObjectCollection Items => _combo.Items;
public object? SelectedItem
{
get => _combo.SelectedItem;
set => _combo.SelectedItem = value;
}
public int SelectedIndex
{
get => _combo.SelectedIndex;
set => _combo.SelectedIndex = value;
}
public string Text
{
get => _combo.Text;
set => _combo.Text = value;
}
public override Font Font
{
get => base.Font;
set
{
base.Font = value;
_combo.Font = value;
AjustarAltura();
}
}
public new bool Enabled
{
get => base.Enabled;
set
{
base.Enabled = value;
_combo.Enabled = value;
BackColor = value ? Color.White : Color.FromArgb(241, 245, 249);
Invalidate();
}
}
// ── EVENTOS REPASSADOS ────────────────────────────────────────────────
public event EventHandler? SelectedIndexChanged
{
add => _combo.SelectedIndexChanged += value;
remove => _combo.SelectedIndexChanged -= value;
}
public new event EventHandler? TextChanged
{
add => _combo.TextChanged += value;
remove => _combo.TextChanged -= value;
}
// ── CONSTRUTOR ────────────────────────────────────────────────────────
public LV_COMBOBOX()
{
_combo = new ComboBox
{
DropDownStyle = ComboBoxStyle.DropDownList,
FlatStyle = FlatStyle.Flat,
Font = new Font("Segoe UI", 9f),
BackColor = Color.White,
ForeColor = Color.FromArgb(30, 41, 59),
Dock = DockStyle.None,
IntegralHeight = false
};
// Configura o controle pai
Padding = new Padding(8, 0, 30, 0); // espaço para seta customizada
BackColor = Color.White;
ForeColor = Color.FromArgb(30, 41, 59);
Font = new Font("Segoe UI", 9f);
Size = new Size(200, 36);
DoubleBuffered = true;
Controls.Add(_combo);
AjustarAltura();
// Eventos de foco
_combo.GotFocus += (s, e) => { _isFocused = true; Invalidate(); };
_combo.LostFocus += (s, e) => { _isFocused = false; Invalidate(); };
// Propaga clique na área do controle para o combo
this.Click += (s, e) => _combo.Focus();
_combo.DropDown += (s, e) => Invalidate();
_combo.DropDownClosed += (s, e) => Invalidate();
}
// ── AJUSTE DE ALTURA ──────────────────────────────────────────────────
private void AjustarAltura()
{
int altura = _combo.PreferredHeight;
this.Height = altura + 10;
_combo.Width = this.Width - 38; // reserva espaço para seta
_combo.Left = 8;
_combo.Top = (this.Height - _combo.Height) / 2;
}
// ── RESIZE ────────────────────────────────────────────────────────────
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
_combo.Width = this.Width - 38;
_combo.Left = 8;
_combo.Top = (this.Height - _combo.Height) / 2;
Invalidate();
}
// ── PAINT ─────────────────────────────────────────────────────────────
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
var cor = _isFocused ? _borderFocusColor : _borderColor;
var rect = new Rectangle(0, 0, Width - 1, Height - 1);
var bgRect = new Rectangle(1, 1, Width - 2, Height - 2);
// Fundo
using var bgBrush = new SolidBrush(Enabled ? BackColor : Color.FromArgb(241, 245, 249));
g.FillRoundedRectangle(bgBrush, bgRect, _borderRadius);
// Borda
using var pen = new Pen(cor, _borderSize);
g.DrawRoundedRectangle(pen, rect, _borderRadius);
// Seta customizada
DesenharSeta(g);
}
private void DesenharSeta(Graphics g)
{
int arrowX = Width - 22;
int arrowY = Height / 2;
using var brush = new SolidBrush(_isFocused ? _borderFocusColor : _arrowColor);
var pontos = new Point[]
{
new Point(arrowX - 5, arrowY - 3),
new Point(arrowX + 5, arrowY - 3),
new Point(arrowX, arrowY + 4)
};
g.FillPolygon(brush, pontos);
}
}
// ── EXTENSÕES DE GRAPHICS PARA ROUNDED RECT ───────────────────────────────
internal static class GraphicsExtensions
{
public static void FillRoundedRectangle(this Graphics g, Brush brush, Rectangle rect, int radius)
{
using var path = GetRoundedPath(rect, radius);
g.FillPath(brush, path);
}
public static void DrawRoundedRectangle(this Graphics g, Pen pen, Rectangle rect, int radius)
{
using var path = GetRoundedPath(rect, radius);
g.DrawPath(pen, path);
}
private static GraphicsPath GetRoundedPath(Rectangle rect, int radius)
{
int r = Math.Min(radius, Math.Min(rect.Width, rect.Height) / 2);
var d = r * 2;
var path = new GraphicsPath();
path.AddArc(rect.X, rect.Y, d, d, 180, 90);
path.AddArc(rect.Right - d, rect.Y, d, d, 270, 90);
path.AddArc(rect.Right - d, rect.Bottom - d, d, d, 0, 90);
path.AddArc(rect.X, rect.Bottom - d, d, d, 90, 90);
path.CloseFigure();
return path;
}
}
}

View File

@ -4,71 +4,122 @@ namespace MLL
{ {
public class ModeloBoletos public class ModeloBoletos
{ {
// ── CONSTRUTOR VAZIO ──────────────────────────────────────────────────
public ModeloBoletos() public ModeloBoletos()
{ {
this.ID_BOLETO = 0; ID_BOLETO = 0;
this.CODIGO = string.Empty; CODIGO = string.Empty;
this.EMITIDO = string.Empty; NUMERO = string.Empty;
this.VENCE = string.Empty; NOSSO_NUMERO = string.Empty;
this.VALOR = string.Empty; CHAVE_BOLETO = string.Empty;
this.NUMERO = string.Empty; LINHA_DIGITAVEL = string.Empty;
this.PG = string.Empty; EMITIDO = null;
this.SACADO = string.Empty; VENCE = null;
this.CONTA = string.Empty; DT_PAGAMENTO = null;
this.OBSERVACAO = string.Empty; VALOR = 0m;
this.COD_CONTA = string.Empty; VL_PAGO = null;
this.NOSSO_NUMERO = string.Empty; VL_MULTA = null;
this.ACEITE = string.Empty; VL_DESCONTO = null;
this.IMPRESSO = string.Empty; STATUS = "ABERTO";
this.IMPORTACAO = string.Empty; PG = false;
} SACADO = string.Empty;
public ModeloBoletos(int iD_BOLETO, string cODIGO, string eMITIDO, string vENCE, string vALOR, string nUMERO, string pG, string sACADO, string cONTA, string oBSERVACAO, string cOD_CONTA, string nOSSO_NUMERO, string aCEITE, string iMPRESSO, string iMPORTACAO) CONTA = string.Empty;
{ COD_CONTA = string.Empty;
ID_BOLETO = iD_BOLETO; ACEITE = false;
CODIGO = cODIGO; IMPRESSO = false;
EMITIDO = eMITIDO; IMPORTACAO = false;
VENCE = vENCE; ARQUIVO_NOME = string.Empty;
VALOR = vALOR; ARQUIVO_TIPO = string.Empty;
NUMERO = nUMERO; ARQUIVO_CAMINHO = string.Empty;
PG = pG; ARQUIVO_DADOS = null;
SACADO = sACADO; OBSERVACAO = string.Empty;
CONTA = cONTA; DT_CADASTRO = DateTime.Now;
OBSERVACAO = oBSERVACAO; DT_ALTERACAO = null;
COD_CONTA = cOD_CONTA; ID_USUARIO = null;
NOSSO_NUMERO = nOSSO_NUMERO;
ACEITE = aCEITE;
IMPRESSO = iMPRESSO;
IMPORTACAO = iMPORTACAO;
} }
// ── IDENTIFICAÇÃO ─────────────────────────────────────────────────────
public int ID_BOLETO { get; set; } public int ID_BOLETO { get; set; }
public string CODIGO { get; set; } public string CODIGO { get; set; }
public string EMITIDO { get; set; }
public string VENCE { get; set; }
public string VALOR { get; set; }
public string NUMERO { get; set; } public string NUMERO { get; set; }
public string PG { get; set; }
public string SACADO { get; set; }
public string CONTA { get; set; }
public string OBSERVACAO { get; set; }
public string COD_CONTA { get; set; }
public string NOSSO_NUMERO { get; set; } public string NOSSO_NUMERO { get; set; }
public string ACEITE { get; set; } /// <summary>Chave única para baixa/integração bancária.</summary>
public string CHAVE_BOLETO { get; set; }
public string IMPRESSO { get; set; } /// <summary>Código de barras / linha digitável (47 ou 48 dígitos).</summary>
public string LINHA_DIGITAVEL { get; set; }
public string IMPORTACAO { get; set; } // ── DATAS ─────────────────────────────────────────────────────────────
public DateTime? EMITIDO { get; set; }
public DateTime? VENCE { get; set; }
/// <summary>Data efetiva em que o boleto foi pago.</summary>
public DateTime? DT_PAGAMENTO { get; set; }
// ── VALORES ───────────────────────────────────────────────────────────
public decimal VALOR { get; set; }
/// <summary>Valor efetivamente pago (pode diferir de VALOR por multa/desconto).</summary>
public decimal? VL_PAGO { get; set; }
/// <summary>Multa por atraso aplicada no pagamento.</summary>
public decimal? VL_MULTA { get; set; }
/// <summary>Desconto concedido no pagamento.</summary>
public decimal? VL_DESCONTO { get; set; }
// ── STATUS ────────────────────────────────────────────────────────────
/// <summary>
/// Status do boleto.
/// Valores: ABERTO | PAGO | VENCIDO | CANCELADO | BAIXADO
/// </summary>
public string STATUS { get; set; }
// ── FLAGS ─────────────────────────────────────────────────────────────
public bool PG { get; set; }
public bool ACEITE { get; set; }
public bool IMPRESSO { get; set; }
public bool IMPORTACAO { get; set; }
// ── SACADO E CONTA ────────────────────────────────────────────────────
public string SACADO { get; set; }
public string CONTA { get; set; }
public string COD_CONTA { get; set; }
// ── ARQUIVO (XML / PDF) ───────────────────────────────────────────────
/// <summary>Nome original do arquivo anexado.</summary>
public string ARQUIVO_NOME { get; set; }
/// <summary>Tipo do arquivo: "XML" ou "PDF".</summary>
public string ARQUIVO_TIPO { get; set; }
/// <summary>Caminho completo do arquivo em disco.</summary>
public string ARQUIVO_CAMINHO { get; set; }
/// <summary>Conteúdo binário do arquivo (para armazenamento no banco).</summary>
public byte[]? ARQUIVO_DADOS { get; set; }
// ── OBSERVAÇÃO ────────────────────────────────────────────────────────
public string OBSERVACAO { get; set; }
// ── RASTREABILIDADE ───────────────────────────────────────────────────
public DateTime DT_CADASTRO { get; set; }
public DateTime? DT_ALTERACAO { get; set; }
public int? ID_USUARIO { get; set; }
// ── HELPERS ───────────────────────────────────────────────────────────
/// <summary>Retorna true se o boleto está vencido e ainda não foi pago.</summary>
public bool EstaVencido =>
!PG && VENCE.HasValue && VENCE.Value.Date < DateTime.Today;
/// <summary>Retorna true se há arquivo anexado (caminho ou binário).</summary>
public bool TemArquivo =>
!string.IsNullOrEmpty(ARQUIVO_CAMINHO) || ARQUIVO_DADOS != null;
/// <summary>Valor com multa e desconto aplicados.</summary>
public decimal ValorFinal =>
VALOR + (VL_MULTA ?? 0m) - (VL_DESCONTO ?? 0m);
} }
} }

View File

@ -0,0 +1,189 @@
USE [Levelcode-LevelOS]
GO
-- ============================================================
-- MIGRAÇÃO DA TABELA [dbo].[Boletos]
-- Gerado em: 20/04/2026
-- Descrição: Melhoria de tipos, rastreabilidade,
-- suporte a arquivo (XML/PDF) e baixa bancária
-- ============================================================
-- ── PASSO 1: Corrigir tipos das colunas existentes ──────────
-- Datas
ALTER TABLE [dbo].[Boletos]
ALTER COLUMN [EMITIDO] DATE NULL;
GO
ALTER TABLE [dbo].[Boletos]
ALTER COLUMN [VENCE] DATE NULL;
GO
-- Valor
ALTER TABLE [dbo].[Boletos]
ALTER COLUMN [VALOR] DECIMAL(10,2) NULL;
GO
-- Flags booleanas (S/N → BIT)
-- Precisa converter os dados antes de mudar o tipo
UPDATE [dbo].[Boletos] SET [PG] = CASE WHEN [PG] = 'S' THEN '1' ELSE '0' END;
UPDATE [dbo].[Boletos] SET [ACEITE] = CASE WHEN [ACEITE] = 'S' THEN '1' ELSE '0' END;
UPDATE [dbo].[Boletos] SET [IMPRESSO] = CASE WHEN [IMPRESSO] = 'S' THEN '1' ELSE '0' END;
UPDATE [dbo].[Boletos] SET [IMPORTACAO]= CASE WHEN [IMPORTACAO]= 'S' THEN '1' ELSE '0' END;
GO
ALTER TABLE [dbo].[Boletos] ALTER COLUMN [PG] BIT NOT NULL;
ALTER TABLE [dbo].[Boletos] ALTER COLUMN [ACEITE] BIT NOT NULL;
ALTER TABLE [dbo].[Boletos] ALTER COLUMN [IMPRESSO] BIT NOT NULL;
ALTER TABLE [dbo].[Boletos] ALTER COLUMN [IMPORTACAO] BIT NOT NULL;
GO
-- Campos de texto: limitar tamanho adequado
ALTER TABLE [dbo].[Boletos] ALTER COLUMN [CODIGO] VARCHAR(50) NULL;
ALTER TABLE [dbo].[Boletos] ALTER COLUMN [NUMERO] VARCHAR(50) NULL;
ALTER TABLE [dbo].[Boletos] ALTER COLUMN [NOSSO_NUMERO] VARCHAR(50) NULL;
ALTER TABLE [dbo].[Boletos] ALTER COLUMN [SACADO] VARCHAR(200) NULL;
ALTER TABLE [dbo].[Boletos] ALTER COLUMN [CONTA] VARCHAR(100) NULL;
ALTER TABLE [dbo].[Boletos] ALTER COLUMN [COD_CONTA] VARCHAR(30) NULL;
ALTER TABLE [dbo].[Boletos] ALTER COLUMN [OBSERVACAO] VARCHAR(500) NULL;
GO
-- ── PASSO 2: Adicionar colunas novas ────────────────────────
-- Baixa bancária / integração
ALTER TABLE [dbo].[Boletos]
ADD [CHAVE_BOLETO] VARCHAR(100) NULL; -- Chave única para baixa/integração bancária
GO
ALTER TABLE [dbo].[Boletos]
ADD [LINHA_DIGITAVEL] VARCHAR(60) NULL; -- Código de barras / linha digitável
GO
-- Pagamento
ALTER TABLE [dbo].[Boletos]
ADD [DT_PAGAMENTO] DATE NULL; -- Data efetiva do pagamento
GO
ALTER TABLE [dbo].[Boletos]
ADD [VL_PAGO] DECIMAL(10,2) NULL; -- Valor pago (pode ter multa/desconto)
GO
ALTER TABLE [dbo].[Boletos]
ADD [VL_MULTA] DECIMAL(10,2) NULL; -- Multa por atraso
GO
ALTER TABLE [dbo].[Boletos]
ADD [VL_DESCONTO] DECIMAL(10,2) NULL; -- Desconto concedido
GO
-- Arquivo (XML ou PDF) — caminho em disco
ALTER TABLE [dbo].[Boletos]
ADD [ARQUIVO_NOME] VARCHAR(255) NULL; -- Nome original do arquivo
GO
ALTER TABLE [dbo].[Boletos]
ADD [ARQUIVO_TIPO] VARCHAR(10) NULL; -- 'XML' ou 'PDF'
GO
ALTER TABLE [dbo].[Boletos]
ADD [ARQUIVO_CAMINHO] VARCHAR(500) NULL; -- Caminho completo em disco
GO
-- Arquivo — binário no banco
ALTER TABLE [dbo].[Boletos]
ADD [ARQUIVO_DADOS] VARBINARY(MAX) NULL; -- Conteúdo binário do arquivo
GO
-- Rastreabilidade
ALTER TABLE [dbo].[Boletos]
ADD [DT_CADASTRO] DATETIME NOT NULL DEFAULT GETDATE(); -- Data de criação
GO
ALTER TABLE [dbo].[Boletos]
ADD [DT_ALTERACAO] DATETIME NULL; -- Última alteração
GO
ALTER TABLE [dbo].[Boletos]
ADD [ID_USUARIO] INT NULL; -- Usuário responsável
GO
ALTER TABLE [dbo].[Boletos]
ADD [STATUS] VARCHAR(20) NOT NULL DEFAULT 'ABERTO';
-- Valores possíveis: 'ABERTO', 'PAGO', 'VENCIDO', 'CANCELADO', 'BAIXADO'
GO
-- ── PASSO 3: Índices para performance ───────────────────────
-- Busca por número do boleto
CREATE NONCLUSTERED INDEX [IX_Boletos_Numero]
ON [dbo].[Boletos] ([NUMERO] ASC)
WHERE [NUMERO] IS NOT NULL;
GO
-- Busca por chave bancária
CREATE NONCLUSTERED INDEX [IX_Boletos_Chave]
ON [dbo].[Boletos] ([CHAVE_BOLETO] ASC)
WHERE [CHAVE_BOLETO] IS NOT NULL;
GO
-- Busca por vencimento (relatórios de inadimplência)
CREATE NONCLUSTERED INDEX [IX_Boletos_Vence]
ON [dbo].[Boletos] ([VENCE] ASC);
GO
-- Busca por status
CREATE NONCLUSTERED INDEX [IX_Boletos_Status]
ON [dbo].[Boletos] ([STATUS] ASC);
GO
-- ── PASSO 4: Constraint de validação de status ──────────────
ALTER TABLE [dbo].[Boletos]
ADD CONSTRAINT [CK_Boletos_Status]
CHECK ([STATUS] IN ('ABERTO', 'PAGO', 'VENCIDO', 'CANCELADO', 'BAIXADO'));
GO
ALTER TABLE [dbo].[Boletos]
ADD CONSTRAINT [CK_Boletos_ArquivoTipo]
CHECK ([ARQUIVO_TIPO] IN ('XML', 'PDF') OR [ARQUIVO_TIPO] IS NULL);
GO
-- ── PASSO 5: FK para usuário (se a tabela existir) ──────────
-- Descomente quando a tabela de usuários estiver criada:
-- ALTER TABLE [dbo].[Boletos]
-- ADD CONSTRAINT [FK_Boletos_Usuario]
-- FOREIGN KEY ([ID_USUARIO]) REFERENCES [dbo].[Usuarios]([ID_USUARIO]);
-- GO
-- ── RESULTADO FINAL ──────────────────────────────────────────
-- Tabela com a estrutura completa após migração:
--
-- ID_BOLETO INT IDENTITY PK
-- CODIGO VARCHAR(50)
-- NUMERO VARCHAR(50)
-- NOSSO_NUMERO VARCHAR(50)
-- CHAVE_BOLETO VARCHAR(100) ← novo
-- LINHA_DIGITAVEL VARCHAR(60) ← novo
-- EMITIDO DATE ← tipo corrigido
-- VENCE DATE ← tipo corrigido
-- DT_PAGAMENTO DATE ← novo
-- VALOR DECIMAL(10,2) ← tipo corrigido
-- VL_PAGO DECIMAL(10,2) ← novo
-- VL_MULTA DECIMAL(10,2) ← novo
-- VL_DESCONTO DECIMAL(10,2) ← novo
-- STATUS VARCHAR(20) ← novo
-- PG BIT ← tipo corrigido
-- SACADO VARCHAR(200) ← tipo corrigido
-- CONTA VARCHAR(100) ← tipo corrigido
-- COD_CONTA VARCHAR(30) ← tipo corrigido
-- ACEITE BIT ← tipo corrigido
-- IMPRESSO BIT ← tipo corrigido
-- IMPORTACAO BIT ← tipo corrigido
-- ARQUIVO_NOME VARCHAR(255) ← novo
-- ARQUIVO_TIPO VARCHAR(10) ← novo
-- ARQUIVO_CAMINHO VARCHAR(500) ← novo
-- ARQUIVO_DADOS VARBINARY(MAX) ← novo
-- OBSERVACAO VARCHAR(500) ← tipo corrigido
-- DT_CADASTRO DATETIME ← novo
-- DT_ALTERACAO DATETIME ← novo
-- ID_USUARIO INT ← novo

View File

@ -0,0 +1,741 @@
using CPM;
using DAL;
using MLL;
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
namespace UI
{
public class BoletoCadastroPanel : FormularioModelo
{
// ── MODELO ────────────────────────────────────────────────────────────
private ModeloBoletos _modelo = new ModeloBoletos();
// ── SEÇÃO 1: Identificação ────────────────────────────────────────────
private LV_TEXTBOX1 txtCodigo = null!;
private LV_TEXTBOX1 txtNumero = null!;
private LV_TEXTBOX1 txtNossoNumero = null!;
private LV_TEXTBOX1 txtChaveBoleto = null!;
private LV_TEXTBOX1 txtLinhaDigitavel = null!;
// ── SEÇÃO 2: Datas e Valores ──────────────────────────────────────────
private DateTimePicker dtpEmitido = null!;
private DateTimePicker dtpVence = null!;
private DateTimePicker dtpPagamento = null!;
private LV_TEXTBOX1 txtValor = null!;
private LV_TEXTBOX1 txtVlPago = null!;
private LV_TEXTBOX1 txtVlMulta = null!;
private LV_TEXTBOX1 txtVlDesconto = null!;
// ── SEÇÃO 3: Sacado e Conta ───────────────────────────────────────────
private LV_TEXTBOX1 txtSacado = null!;
private LV_COMBOBOX cmbConta = null!;
private LV_COMBOBOX cmbCodConta = null!;
// ── SEÇÃO 4: Status e Flags ───────────────────────────────────────────
private LV_COMBOBOX cmbStatus = null!;
private CheckBox chkPago = null!;
private CheckBox chkAceite = null!;
private CheckBox chkImpresso = null!;
private CheckBox chkImportado = null!;
// ── SEÇÃO 5: Arquivo ──────────────────────────────────────────────────
private LV_TEXTBOX1 txtArquivoNome = null!;
private LV_TEXTBOX1 txtArquivoCaminho = null!;
private LV_COMBOBOX cmbArquivoTipo = null!;
private Button btnAnexar = null!;
private Button btnVisualizarArq = null!;
private Label lblArquivoInfo = null!;
// ── SEÇÃO 6: Observação ───────────────────────────────────────────────
private LV_TEXTBOX1 txtObservacao = null!;
// ── BOTÃO EXTRA DA TOOLBAR ────────────────────────────────────────────
private Button btnBaixar = null!;
// ── CONSTRUTOR ────────────────────────────────────────────────────────
public BoletoCadastroPanel()
{
Titulo = "Cadastro de Boletos";
BuildToolbarExtra();
BuildForm();
SetEstadoInicial();
}
// ── TOOLBAR EXTRA ─────────────────────────────────────────────────────
private void BuildToolbarExtra()
{
btnBaixar = CreateToolbarButton("Baixar", Color.FromArgb(99, 102, 241));
btnBaixar.Click += (s, e) => OnBaixarBoleto();
AddToolbarButton(btnBaixar);
}
// ── CONSTRUÇÃO DO FORMULÁRIO ──────────────────────────────────────────
private void BuildForm()
{
content.Height = 1050;
// ── SEÇÃO 1: Identificação ─────────────────────────────────────
content.Controls.Add(CreateSectionHeader("Identificação", 20));
txtCodigo = AddInput(content, "Código", 20, 55, 120, 32, readOnly: true);
txtNumero = AddInput(content, "Número do Boleto", 155, 55, 200, 32);
txtNossoNumero = AddInput(content, "Nosso Número", 370, 55, 200, 32);
txtChaveBoleto = AddInput(content, "Chave do Boleto", 585, 55, 235, 32);
txtLinhaDigitavel = AddInput(content, "Linha Digitável / Código de Barras", 20, 110, 800, 32);
// ── SEÇÃO 2: Datas e Valores ───────────────────────────────────
content.Controls.Add(CreateSectionHeader("Datas e Valores", 165));
dtpEmitido = BuildDatePicker("Data de Emissão", 20, 200);
dtpVence = BuildDatePicker("Data de Vencimento", 210, 200);
dtpPagamento = BuildDatePicker("Data de Pagamento", 400, 200);
dtpPagamento.Enabled = false;
txtValor = AddInput(content, "Valor (R$)", 600, 200, 140, 32);
txtVlPago = AddInput(content, "Valor Pago (R$)", 20, 260, 140, 32);
txtVlMulta = AddInput(content, "Multa (R$)", 175, 260, 140, 32);
txtVlDesconto = AddInput(content, "Desconto (R$)", 330, 260, 140, 32);
var lblVFLabel = new Label
{
Text = "Valor Final (R$)",
Location = new Point(490, 260),
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
ForeColor = AccentBlue,
AutoSize = true
};
var lblVFValor = new Label
{
Name = "lblValorFinal",
Text = "R$ 0,00",
Location = new Point(490, 276),
Font = new Font("Segoe UI", 10f, FontStyle.Bold),
ForeColor = AccentBlue,
AutoSize = true
};
content.Controls.AddRange(new Control[] { lblVFLabel, lblVFValor });
txtValor.Leave += (s, e) => AtualizarValorFinal();
txtVlMulta.Leave += (s, e) => AtualizarValorFinal();
txtVlDesconto.Leave += (s, e) => AtualizarValorFinal();
// ── SEÇÃO 3: Sacado e Conta ────────────────────────────────────
content.Controls.Add(CreateSectionHeader("Sacado e Conta", 315));
txtSacado = AddInput(content, "Sacado", 20, 350, 430, 32);
content.Controls.Add(new Label
{
Text = "Conta",
Location = new Point(465, 350),
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
ForeColor = TextDark,
AutoSize = true
});
cmbConta = new LV_COMBOBOX
{
Location = new Point(465, 366),
Size = new Size(200, 32),
Font = new Font("Segoe UI", 9f),
DropDownStyle = ComboBoxStyle.DropDownList,
BackColor = Color.White,
};
content.Controls.Add(new Label
{
Text = "Cód. Conta",
Location = new Point(680, 350),
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
ForeColor = TextDark,
AutoSize = true
});
cmbCodConta = new LV_COMBOBOX
{
Location = new Point(680, 366),
Size = new Size(150, 32),
Font = new Font("Segoe UI", 9f),
DropDownStyle = ComboBoxStyle.DropDownList,
BackColor = Color.White,
};
content.Controls.AddRange(new Control[] { cmbConta, cmbCodConta });
// ── SEÇÃO 4: Status e Flags ────────────────────────────────────
content.Controls.Add(CreateSectionHeader("Status e Flags", 415));
content.Controls.Add(new Label
{
Text = "Status",
Location = new Point(20, 450),
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
ForeColor = TextDark,
AutoSize = true
});
cmbStatus = new LV_COMBOBOX
{
Location = new Point(20, 466),
Size = new Size(160, 32),
Font = new Font("Segoe UI", 9f),
DropDownStyle = ComboBoxStyle.DropDownList,
BackColor = Color.White,
};
cmbStatus.Items.AddRange(new object[] { "ABERTO", "PAGO", "VENCIDO", "CANCELADO", "BAIXADO" });
cmbStatus.SelectedIndex = 0;
cmbStatus.SelectedIndexChanged += (s, e) => OnStatusChanged();
content.Controls.Add(cmbStatus);
chkPago = CreateCheckBox("Pago", 200, 470);
chkAceite = CreateCheckBox("Aceite", 300, 470);
chkImpresso = CreateCheckBox("Impresso", 400, 470);
chkImportado = CreateCheckBox("Importado", 510, 470);
chkPago.CheckedChanged += (s, e) =>
{
dtpPagamento.Enabled = chkPago.Checked;
if (chkPago.Checked && cmbStatus.SelectedItem?.ToString() != "PAGO")
cmbStatus.SelectedItem = "PAGO";
};
content.Controls.AddRange(new Control[]
{ chkPago, chkAceite, chkImpresso, chkImportado });
// ── SEÇÃO 5: Arquivo ───────────────────────────────────────────
content.Controls.Add(CreateSectionHeader("Arquivo Anexo (XML / PDF)", 510));
content.Controls.Add(new Label
{
Text = "Tipo",
Location = new Point(20, 545),
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
ForeColor = TextDark,
AutoSize = true
});
cmbArquivoTipo = new LV_COMBOBOX
{
Location = new Point(20, 561),
Size = new Size(80, 32),
Font = new Font("Segoe UI", 9f),
DropDownStyle = ComboBoxStyle.DropDownList,
BackColor = Color.White,
};
cmbArquivoTipo.Items.AddRange(new object[] { "", "XML", "PDF" });
cmbArquivoTipo.SelectedIndex = 0;
content.Controls.Add(cmbArquivoTipo);
txtArquivoNome = AddInput(content, "Nome do Arquivo", 115, 545, 220, 32, readOnly: true);
txtArquivoCaminho = AddInput(content, "Caminho em Disco", 350, 545, 340, 32, readOnly: true);
btnAnexar = new Button
{
Text = "📎 Anexar",
Location = new Point(705, 561),
Size = new Size(95, 32),
BackColor = Color.FromArgb(100, 116, 139),
ForeColor = Color.White,
Font = new Font("Segoe UI Semibold", 8.5f),
Cursor = Cursors.Hand,
};
btnAnexar.FlatAppearance.BorderSize = 0;
btnAnexar.Click += (s, e) => OnAnexarArquivo();
btnVisualizarArq = new Button
{
Text = "👁 Abrir",
Location = new Point(705, 599),
Size = new Size(95, 28),
BackColor = AccentBlue,
ForeColor = Color.White,
Font = new Font("Segoe UI Semibold", 8f),
Cursor = Cursors.Hand,
Enabled = false
};
btnVisualizarArq.FlatAppearance.BorderSize = 0;
btnVisualizarArq.Click += (s, e) => OnAbrirArquivo();
lblArquivoInfo = new Label
{
Text = "Nenhum arquivo anexado.",
Location = new Point(20, 603),
Font = new Font("Segoe UI", 8f, FontStyle.Italic),
ForeColor = Color.Gray,
AutoSize = true
};
content.Controls.AddRange(new Control[]
{ btnAnexar, btnVisualizarArq, lblArquivoInfo });
// ── SEÇÃO 6: Observação ────────────────────────────────────────
content.Controls.Add(CreateSectionHeader("Observação", 640));
content.Controls.Add(new Label
{
Text = "Observação",
Location = new Point(20, 675),
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
ForeColor = TextDark,
AutoSize = true
});
txtObservacao = new LV_TEXTBOX1
{
Location = new Point(20, 691),
Size = new Size(830, 80),
BorderColor = BorderColor,
BorderFocusColor = AccentBlue,
Multiline = true
};
content.Controls.Add(txtObservacao);
}
// ── HELPER: DateTimePicker padronizado ────────────────────────────────
private DateTimePicker BuildDatePicker(string label, int x, int y)
{
content.Controls.Add(new Label
{
Text = label,
Location = new Point(x, y),
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
ForeColor = TextDark,
AutoSize = true
});
var dtp = new DateTimePicker
{
Location = new Point(x, y + 16),
Size = new Size(175, 32),
Format = DateTimePickerFormat.Short,
Font = new Font("Segoe UI", 9f)
};
content.Controls.Add(dtp);
return dtp;
}
// ── VALOR FINAL ───────────────────────────────────────────────────────
private void AtualizarValorFinal()
{
decimal valor = ParseDecimal(txtValor.Text);
decimal multa = ParseDecimal(txtVlMulta.Text);
decimal desconto = ParseDecimal(txtVlDesconto.Text);
decimal final = valor + multa - desconto;
var lbl = content.Controls["lblValorFinal"] as Label;
if (lbl != null)
{
lbl.Text = final.ToString("C2");
lbl.ForeColor = final < 0 ? Color.FromArgb(239, 68, 68) : AccentBlue;
}
}
private static decimal ParseDecimal(string text)
{
text = text.Replace("R$", "").Replace(".", "").Replace(",", ".").Trim();
return decimal.TryParse(text,
System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture,
out var v) ? v : 0m;
}
// ── STATUS CHANGED ────────────────────────────────────────────────────
private void OnStatusChanged()
{
var status = cmbStatus.SelectedItem?.ToString();
if (status == "PAGO" && !chkPago.Checked)
chkPago.Checked = true;
dtpPagamento.Enabled = status == "PAGO";
}
// ── ARQUIVO ───────────────────────────────────────────────────────────
private void OnAnexarArquivo()
{
using var dlg = new OpenFileDialog
{
Title = "Selecionar Arquivo do Boleto",
Filter = "Arquivos Suportados (*.xml;*.pdf)|*.xml;*.pdf|XML|*.xml|PDF|*.pdf"
};
if (dlg.ShowDialog() != DialogResult.OK) return;
var caminho = dlg.FileName;
var nome = Path.GetFileName(caminho);
var ext = Path.GetExtension(caminho).TrimStart('.').ToUpper();
txtArquivoNome.Text = nome;
txtArquivoCaminho.Text = caminho;
cmbArquivoTipo.Text = ext;
_modelo.ARQUIVO_DADOS = File.ReadAllBytes(caminho);
lblArquivoInfo.Text = $"✔ {nome} ({new FileInfo(caminho).Length / 1024} KB)";
lblArquivoInfo.ForeColor = Color.FromArgb(34, 197, 94);
btnVisualizarArq.Enabled = true;
}
private void OnAbrirArquivo()
{
var caminho = txtArquivoCaminho.Text;
if (!string.IsNullOrEmpty(caminho) && File.Exists(caminho))
{
System.Diagnostics.Process.Start(
new System.Diagnostics.ProcessStartInfo { FileName = caminho, UseShellExecute = true });
return;
}
// Sem caminho em disco — reconstrói do binário para temp
if (_modelo.ARQUIVO_DADOS != null && _modelo.ARQUIVO_DADOS.Length > 0)
{
var ext = string.IsNullOrEmpty(cmbArquivoTipo.Text) ? "tmp" : cmbArquivoTipo.Text.ToLower();
var temp = Path.Combine(Path.GetTempPath(), $"boleto_{_modelo.ID_BOLETO}.{ext}");
File.WriteAllBytes(temp, _modelo.ARQUIVO_DADOS);
System.Diagnostics.Process.Start(
new System.Diagnostics.ProcessStartInfo { FileName = temp, UseShellExecute = true });
}
else
{
MessageBox.Show("Nenhum arquivo disponível para visualização.",
"Aviso", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
// ── BAIXAR BOLETO ─────────────────────────────────────────────────────
private void OnBaixarBoleto()
{
var chave = txtChaveBoleto.Text.Trim();
var linha = txtLinhaDigitavel.Text.Trim();
var numero = txtNumero.Text.Trim();
if (string.IsNullOrEmpty(chave) && string.IsNullOrEmpty(linha) && string.IsNullOrEmpty(numero))
{
MessageBox.Show(
"Informe a Chave do Boleto, a Linha Digitável ou o Número para realizar a baixa.",
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// TODO: implementar integração bancária
// Fluxo sugerido:
// 1. BLLBoletos.BaixarBoleto(chave / linha / numero, _cx)
// 2. BLL aciona API do banco escolhido
// 3. Retorna status: BAIXADO | PAGO | ERRO
// 4. Atualiza _modelo e recarrega tela
MessageBox.Show(
$"Baixa bancária ainda não implementada.\n\n" +
$"Dados disponíveis:\n" +
$"• Chave: {chave}\n" +
$"• Linha Digitável: {linha}\n" +
$"• Número: {numero}",
"Baixar Boleto", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
// ── MÁQUINA DE ESTADOS ────────────────────────────────────────────────
private void SetEstadoInicial()
{
SetCamposEnabled(false);
btnSalvar.Enabled = false;
btnCancelar.Enabled = false;
btnAlterar.Enabled = false;
btnExcluir.Enabled = false;
btnBaixar.Enabled = false;
}
private void SetCamposEnabled(bool enabled)
{
txtNumero.ReadOnly = !enabled;
txtNossoNumero.ReadOnly = !enabled;
txtChaveBoleto.ReadOnly = !enabled;
txtLinhaDigitavel.ReadOnly = !enabled;
txtValor.ReadOnly = !enabled;
txtVlPago.ReadOnly = !enabled;
txtVlMulta.ReadOnly = !enabled;
txtVlDesconto.ReadOnly = !enabled;
txtSacado.ReadOnly = !enabled;
txtObservacao.ReadOnly = !enabled;
dtpEmitido.Enabled = enabled;
dtpVence.Enabled = enabled;
dtpPagamento.Enabled = enabled && chkPago.Checked;
cmbConta.Enabled = enabled;
cmbCodConta.Enabled = enabled;
cmbStatus.Enabled = enabled;
cmbArquivoTipo.Enabled = enabled;
chkPago.Enabled = enabled;
chkAceite.Enabled = enabled;
chkImpresso.Enabled = enabled;
chkImportado.Enabled = enabled;
btnAnexar.Enabled = enabled;
}
private void SetEstadoEdicao()
{
SetCamposEnabled(true);
btnSalvar.Enabled = true;
btnCancelar.Enabled = true;
btnNovo.Enabled = false;
btnAlterar.Enabled = false;
btnExcluir.Enabled = false;
btnLocalizar.Enabled = false;
btnBaixar.Enabled = false;
}
private void SetEstadoConsulta()
{
SetCamposEnabled(false);
btnSalvar.Enabled = false;
btnCancelar.Enabled = false;
btnNovo.Enabled = true;
btnAlterar.Enabled = true;
btnExcluir.Enabled = true;
btnLocalizar.Enabled = true;
btnBaixar.Enabled = _modelo.ID_BOLETO > 0;
}
// ── CARGA / LIMPEZA / COLETA ──────────────────────────────────────────
private void CarregarModelo()
{
txtCodigo.Text = _modelo.ID_BOLETO == 0 ? "" : _modelo.ID_BOLETO.ToString();
txtNumero.Text = _modelo.NUMERO;
txtNossoNumero.Text = _modelo.NOSSO_NUMERO;
txtChaveBoleto.Text = _modelo.CHAVE_BOLETO;
txtLinhaDigitavel.Text = _modelo.LINHA_DIGITAVEL;
txtSacado.Text = _modelo.SACADO;
txtValor.Text = _modelo.VALOR.ToString("N2");
txtVlPago.Text = _modelo.VL_PAGO?.ToString("N2") ?? "";
txtVlMulta.Text = _modelo.VL_MULTA?.ToString("N2") ?? "";
txtVlDesconto.Text = _modelo.VL_DESCONTO?.ToString("N2") ?? "";
txtObservacao.Text = _modelo.OBSERVACAO;
dtpEmitido.Value = _modelo.EMITIDO ?? DateTime.Today;
dtpVence.Value = _modelo.VENCE ?? DateTime.Today;
dtpPagamento.Value = _modelo.DT_PAGAMENTO ?? DateTime.Today;
cmbStatus.SelectedItem = _modelo.STATUS ?? "ABERTO";
chkPago.Checked = _modelo.PG;
chkAceite.Checked = _modelo.ACEITE;
chkImpresso.Checked = _modelo.IMPRESSO;
chkImportado.Checked = _modelo.IMPORTACAO;
if (!string.IsNullOrEmpty(_modelo.CONTA)) cmbConta.Text = _modelo.CONTA;
if (!string.IsNullOrEmpty(_modelo.COD_CONTA)) cmbCodConta.Text = _modelo.COD_CONTA;
txtArquivoNome.Text = _modelo.ARQUIVO_NOME;
txtArquivoCaminho.Text = _modelo.ARQUIVO_CAMINHO;
cmbArquivoTipo.Text = _modelo.ARQUIVO_TIPO;
bool temArquivo = _modelo.TemArquivo;
btnVisualizarArq.Enabled = temArquivo;
lblArquivoInfo.Text = temArquivo ? $"✔ {_modelo.ARQUIVO_NOME}" : "Nenhum arquivo anexado.";
lblArquivoInfo.ForeColor = temArquivo ? Color.FromArgb(34, 197, 94) : Color.Gray;
AtualizarValorFinal();
}
private void LimparCampos()
{
_modelo = new ModeloBoletos();
txtCodigo.Text = "";
txtNumero.Text = "";
txtNossoNumero.Text = "";
txtChaveBoleto.Text = "";
txtLinhaDigitavel.Text = "";
txtSacado.Text = "";
txtValor.Text = "";
txtVlPago.Text = "";
txtVlMulta.Text = "";
txtVlDesconto.Text = "";
txtObservacao.Text = "";
txtArquivoNome.Text = "";
txtArquivoCaminho.Text = "";
dtpEmitido.Value = DateTime.Today;
dtpVence.Value = DateTime.Today;
dtpPagamento.Value = DateTime.Today;
cmbStatus.SelectedIndex = 0;
cmbConta.SelectedIndex = -1;
cmbCodConta.SelectedIndex = -1;
cmbArquivoTipo.SelectedIndex = 0;
chkPago.Checked = false;
chkAceite.Checked = false;
chkImpresso.Checked = false;
chkImportado.Checked = false;
btnVisualizarArq.Enabled = false;
lblArquivoInfo.Text = "Nenhum arquivo anexado.";
lblArquivoInfo.ForeColor = Color.Gray;
AtualizarValorFinal();
}
private ModeloBoletos ColetarModelo() => new ModeloBoletos
{
ID_BOLETO = _modelo.ID_BOLETO,
NUMERO = txtNumero.Text.Trim(),
NOSSO_NUMERO = txtNossoNumero.Text.Trim(),
CHAVE_BOLETO = txtChaveBoleto.Text.Trim(),
LINHA_DIGITAVEL = txtLinhaDigitavel.Text.Trim(),
EMITIDO = dtpEmitido.Value.Date,
VENCE = dtpVence.Value.Date,
DT_PAGAMENTO = chkPago.Checked ? dtpPagamento.Value.Date : (DateTime?)null,
VALOR = ParseDecimal(txtValor.Text),
VL_PAGO = string.IsNullOrWhiteSpace(txtVlPago.Text) ? null : ParseDecimal(txtVlPago.Text),
VL_MULTA = string.IsNullOrWhiteSpace(txtVlMulta.Text) ? null : ParseDecimal(txtVlMulta.Text),
VL_DESCONTO = string.IsNullOrWhiteSpace(txtVlDesconto.Text) ? null : ParseDecimal(txtVlDesconto.Text),
STATUS = cmbStatus.SelectedItem?.ToString() ?? "ABERTO",
PG = chkPago.Checked,
ACEITE = chkAceite.Checked,
IMPRESSO = chkImpresso.Checked,
IMPORTACAO = chkImportado.Checked,
SACADO = txtSacado.Text.Trim(),
CONTA = cmbConta.Text,
COD_CONTA = cmbCodConta.Text,
ARQUIVO_NOME = txtArquivoNome.Text.Trim(),
ARQUIVO_TIPO = cmbArquivoTipo.Text,
ARQUIVO_CAMINHO = txtArquivoCaminho.Text.Trim(),
ARQUIVO_DADOS = _modelo.ARQUIVO_DADOS,
OBSERVACAO = txtObservacao.Text.Trim(),
DT_CADASTRO = _modelo.DT_CADASTRO == default ? DateTime.Now : _modelo.DT_CADASTRO,
DT_ALTERACAO = _modelo.ID_BOLETO > 0 ? DateTime.Now : (DateTime?)null,
ID_USUARIO = _modelo.ID_USUARIO
};
// ── EVENTOS ABSTRATOS ─────────────────────────────────────────────────
protected override void OnNovo()
{
LimparCampos();
SetEstadoEdicao();
txtNumero.Focus();
}
protected override void OnAlterar()
{
if (_modelo.ID_BOLETO == 0)
{
MessageBox.Show("Localize um boleto antes de alterar.",
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
SetEstadoEdicao();
txtNumero.Focus();
}
protected override void OnExcluir()
{
if (_modelo.ID_BOLETO == 0)
{
MessageBox.Show("Localize um boleto antes de excluir.",
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
var confirm = MessageBox.Show(
$"Deseja excluir o boleto Nº {_modelo.NUMERO}?",
"Confirmar Exclusão", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (confirm == DialogResult.Yes)
{
// TODO: DALBoletos.Excluir(_modelo.ID_BOLETO, _cx);
LimparCampos();
SetEstadoInicial();
MessageBox.Show("Boleto excluído com sucesso.",
"Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
protected override void OnLocalizar()
{
// TODO: abrir form de pesquisa
// var frm = new FormLocalizarBoleto();
// if (frm.ShowDialog() == DialogResult.OK)
// {
// _modelo = frm.ModeloSelecionado;
// CarregarModelo();
// SetEstadoConsulta();
// }
}
protected override void OnSalvar()
{
if (!Validar()) return;
var modelo = ColetarModelo();
try
{
if (modelo.ID_BOLETO == 0)
{
// TODO: DALBoletos.Inserir(modelo, _cx);
MessageBox.Show("Boleto cadastrado com sucesso.",
"Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
// TODO: DALBoletos.Atualizar(modelo, _cx);
MessageBox.Show("Boleto atualizado com sucesso.",
"Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
_modelo = modelo;
SetEstadoConsulta();
}
catch (Exception ex)
{
MessageBox.Show($"Erro ao salvar boleto:\n{ex.Message}",
"Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
protected override void OnCancelar()
{
if (_modelo.ID_BOLETO == 0)
LimparCampos();
else
CarregarModelo();
SetEstadoConsulta();
}
// ── VALIDAÇÃO ─────────────────────────────────────────────────────────
private bool Validar()
{
if (string.IsNullOrWhiteSpace(txtNumero.Text))
{
MessageBox.Show("Informe o número do boleto.",
"Validação", MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtNumero.Focus(); return false;
}
if (ParseDecimal(txtValor.Text) <= 0)
{
MessageBox.Show("Informe um valor válido para o boleto.",
"Validação", MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtValor.Focus(); return false;
}
if (dtpVence.Value.Date < dtpEmitido.Value.Date)
{
MessageBox.Show("A data de vencimento não pode ser anterior à data de emissão.",
"Validação", MessageBoxButtons.OK, MessageBoxIcon.Warning);
dtpVence.Focus(); return false;
}
if (string.IsNullOrWhiteSpace(txtSacado.Text))
{
MessageBox.Show("Informe o sacado.",
"Validação", MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtSacado.Focus(); return false;
}
if (cmbConta.SelectedIndex < 0)
{
MessageBox.Show("Selecione a conta.",
"Validação", MessageBoxButtons.OK, MessageBoxIcon.Warning);
cmbConta.Focus(); return false;
}
return true;
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,176 @@
using CPM;
using MLL; // Namespace da sua model
using System;
using System.Drawing;
using System.Windows.Forms;
using UI; // Namespace do seu FormularioModelo
namespace UI
{
public partial class ContratosCadastroPanel : FormularioModelo
{
private ModeloContrato _contrato = new ModeloContrato();
// Controles específicos
private LV_TEXTBOX1 txtId, txtEmpresaId, txtClienteId, txtDescricao;
private LV_TEXTBOX1 txtValor, txtDataInicio, txtDataValidade, txtFranquia;
private LV_TEXTBOX1 txtObservacoes;
private CheckBox chkAtivo;
private LV_TEXTBOX1 txtNomeCliente; // Novo campo para o nome
private Button btnBuscaCliente; // Botão da lupa
public ContratosCadastroPanel()
{
this.Titulo = "Gestão de Contratos";
MontarInterface();
}
//private void MontarInterface()
//{
// // --- SEÇÃO 1: Vínculos e Descrição ---
// content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO DO CONTRATO", 20));
// txtId = AddInput(content, "ID", 20, 50, 80, 30, true);
// txtEmpresaId = AddInput(content, "ID EMPRESA", 110, 50, 100, 30);
// txtClienteId = AddInput(content, "ID CLIENTE", 220, 50, 100, 30);
// txtDescricao = AddInput(content, "DESCRIÇÃO DO CONTRATO", 330, 50, 550, 30);
// // --- SEÇÃO 2: Valores e Prazos ---
// content.Controls.Add(CreateSectionHeader("FINANCEIRO E VIGÊNCIA", 110));
// txtValor = AddInput(content, "VALOR MENSAL (R$)", 20, 140, 150, 30);
// txtDataInicio = AddInput(content, "DATA INÍCIO", 180, 140, 150, 30);
// txtDataValidade = AddInput(content, "VALIDADE/TÉRMINO", 340, 140, 150, 30);
// txtFranquia = AddInput(content, "FRANQUIA (HORAS/MIN)", 500, 140, 180, 30);
// chkAtivo = CreateCheckBox("CONTRATO ATIVO", 700, 158);
// content.Controls.Add(chkAtivo);
// // --- SEÇÃO 3: Observações ---
// content.Controls.Add(CreateSectionHeader("DETALHES E OBSERVAÇÕES", 200));
// txtObservacoes = AddInput(content, "OBSERVAÇÕES INTERNAS", 20, 230, 860, 80);
// // Ajuste para o campo de observações ser maior (se o seu LV_TEXTBOX1 permitir)
// txtObservacoes.Height = 80;
//}
private void MontarInterface()
{
// --- SEÇÃO 1: Identificação e Vínculos ---
content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO DO CONTRATO", 20));
// Linha 1: IDs e Busca
txtId = AddInput(content, "ID CONTRATO", 20, 50, 90, 30, true);
txtClienteId = AddInput(content, "ID CLIENTE", 120, 50, 80, 30);
// Botão Lupa
btnBuscaCliente = new Button
{
Text = "🔍",
Location = new Point(205, 66), // Alinhado ao topo do textbox (50 + 16)
Size = new Size(32, 30),
BackColor = AccentBlue,
ForeColor = Color.White,
FlatStyle = FlatStyle.Flat,
Cursor = Cursors.Hand
};
btnBuscaCliente.FlatAppearance.BorderSize = 0;
btnBuscaCliente.Click += (s, e) => OnLocalizarCliente();
content.Controls.Add(btnBuscaCliente);
txtNomeCliente = AddInput(content, "NOME DO CLIENTE / RAZÃO SOCIAL", 247, 50, 410, 30, true);
txtEmpresaId = AddInput(content, "ID EMPRESA", 667, 50, 80, 30);
// Linha 2: Descrição (abaixo dos IDs)
txtDescricao = AddInput(content, "DESCRIÇÃO DO CONTRATO", 20, 105, 727, 30);
// --- SEÇÃO 2: Valores e Prazos ---
// Aumentei o Y para 170 para dar espaço à descrição acima
content.Controls.Add(CreateSectionHeader("FINANCEIRO E VIGÊNCIA", 175));
txtValor = AddInput(content, "VALOR MENSAL (R$)", 20, 205, 150, 30);
txtDataInicio = AddInput(content, "DATA INÍCIO", 185, 205, 150, 30);
txtDataValidade = AddInput(content, "VALIDADE/TÉRMINO", 350, 205, 150, 30);
txtFranquia = AddInput(content, "FRANQUIA (HORAS/MIN)", 515, 205, 170, 30);
// Checkbox Alinhado com os inputs
chkAtivo = CreateCheckBox("CONTRATO ATIVO", 700, 223); // Y do input (205) + ~18px
content.Controls.Add(chkAtivo);
// --- SEÇÃO 3: Detalhes e Notas ---
content.Controls.Add(CreateSectionHeader("DETALHES E OBSERVAÇÕES", 275));
txtObservacoes = AddInput(content, "OBSERVAÇÕES INTERNAS", 20, 305, 860, 100);
// Forçar a altura maior para o campo de observações
txtObservacoes.Height = 100;
// Se o seu LV_TEXTBOX1 tiver a propriedade Multiline, ative-a aqui:
// txtObservacoes.Multiline = true;
}
// Método que você precisará implementar para a busca
private void OnLocalizarCliente()
{
//Logica para abrir o form de busca e retornar os dados
//Exemplo:
// var busca = new FormBuscaCliente();
//if (busca.ShowDialog() == DialogResult.OK)
//{
// txtClienteId.Text = busca.IdSelecionado;
// txtNomeCliente.Text = busca.NomeSelecionado;
//}
}
private void PreencherModel()
{
_contrato.Descricao = txtDescricao.Text;
_contrato.Observacoes = txtObservacoes.Text;
_contrato.Ativo = chkAtivo.Checked;
// Conversões seguras
if (decimal.TryParse(txtValor.Text, out decimal v)) _contrato.Valor = v;
if (int.TryParse(txtEmpresaId.Text, out int emp)) _contrato.EmpresaId = emp;
if (int.TryParse(txtClienteId.Text, out int cli)) _contrato.ClienteId = cli;
if (int.TryParse(txtFranquia.Text, out int fra)) _contrato.FranquiaTempo = fra;
if (DateTime.TryParse(txtDataInicio.Text, out DateTime dtIn)) _contrato.DataInicio = dtIn;
if (DateTime.TryParse(txtDataValidade.Text, out DateTime dtVal)) _contrato.DataValidade = dtVal;
}
// --- MÉTODOS OBRIGATÓRIOS DA BASE ---
protected override void OnNovo()
{
_contrato = new ModeloContrato();
// Limpar campos...
txtDescricao.Focus();
}
protected override void OnSalvar()
{
try
{
PreencherModel();
// Chamar BLL.Salvar(_contrato);
MessageBox.Show("Contrato processado com sucesso!", "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show("Erro ao salvar contrato: " + ex.Message);
}
}
protected override void OnAlterar() { /* Implementar busca/edição */ }
protected override void OnExcluir()
{
if (MessageBox.Show("Deseja rescindir/excluir este contrato?", "Confirmação", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
// Lógica de exclusão
}
}
protected override void OnLocalizar() { /* Abrir grid de contratos */ }
protected override void OnCancelar() { OnNovo(); }
}
}

View File

@ -0,0 +1,123 @@
using CPM;
using MLL; // Namespace da sua model
using System;
using System.Drawing;
using System.Windows.Forms;
using UI; // Namespace do seu FormularioModelo
namespace UI
{
public partial class EquipamentosCadastroPanel : FormularioModelo
{
// Instância da model para controle de dados
private ModeloEquipamentos _equipamento = new ModeloEquipamentos();
// Controles do formulário
private LV_TEXTBOX1 txtId, txtCodigo, txtDescricao, txtMarca, txtModelo;
private LV_TEXTBOX1 txtSerie, txtPatrimonio, txtDataCompra, txtRevenda;
private LV_TEXTBOX1 txtNF, txtCertificado, txtObservacoes;
public EquipamentosCadastroPanel()
{
this.Titulo = "Cadastro de Equipamentos";
MontarInterface();
LimparTela();
}
private void MontarInterface()
{
// --- SEÇÃO 1: Identificação ---
content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO E DESCRIÇÃO", 20));
txtId = AddInput(content, "ID", 20, 50, 80, 30, true); // Somente leitura
txtCodigo = AddInput(content, "CÓDIGO INTERNO", 110, 50, 150, 30);
txtDescricao = AddInput(content, "DESCRIÇÃO DO EQUIPAMENTO", 270, 50, 450, 30);
// --- SEÇÃO 2: Detalhes Técnicos ---
content.Controls.Add(CreateSectionHeader("ESPECIFICAÇÕES TÉCNICAS", 110));
txtMarca = AddInput(content, "MARCA", 20, 140, 240, 30);
txtModelo = AddInput(content, "MODELO", 270, 140, 240, 30);
txtSerie = AddInput(content, "Nº DE SÉRIE", 520, 140, 200, 30);
txtPatrimonio = AddInput(content, "PATRIMÔNIO (PAT)", 730, 140, 150, 30);
// --- SEÇÃO 3: Compra e Garantia ---
content.Controls.Add(CreateSectionHeader("DADOS DE AQUISIÇÃO E GARANTIA", 200));
txtDataCompra = AddInput(content, "DATA DA COMPRA", 20, 230, 150, 30);
txtRevenda = AddInput(content, "REVENDA / FORNECEDOR", 180, 230, 330, 30);
txtNF = AddInput(content, "NOTA FISCAL", 520, 230, 150, 30);
txtCertificado = AddInput(content, "Nº CERT. GARANTIA", 680, 230, 200, 30);
// --- SEÇÃO 4: Observações ---
content.Controls.Add(CreateSectionHeader("OBSERVAÇÕES ADICIONAIS", 290));
txtObservacoes = AddInput(content, "NOTAS GERAIS", 20, 320, 860, 60);
// Se o seu LV_TEXTBOX1 suportar Multiline, você pode ajustar aqui
}
private void LimparTela()
{
_equipamento = new ModeloEquipamentos();
// Lógica para limpar todos os campos txtId.Text = "", etc.
// Dica: Você pode criar um método auxiliar na base para limpar o 'content'
}
// --- IMPLEMENTAÇÃO DOS MÉTODOS DA BASE ---
protected override void OnNovo()
{
LimparTela();
txtCodigo.Focus();
}
protected override void OnSalvar()
{
try
{
// Mapeia a tela para a model
_equipamento.CODIGO = txtCodigo.Text;
_equipamento.DESCRICAO = txtDescricao.Text;
_equipamento.MARCA = txtMarca.Text;
_equipamento.MODELO = txtModelo.Text;
_equipamento.SERIE = txtSerie.Text;
_equipamento.PAT = txtPatrimonio.Text;
_equipamento.DATA_COMPRA = txtDataCompra.Text;
_equipamento.REVENDA = txtRevenda.Text;
_equipamento.NUM_NF = txtNF.Text;
_equipamento.NUM_CERTGAR = txtCertificado.Text;
_equipamento.OBSERVACOES = txtObservacoes.Text;
// Aqui você chamaria sua BLL ou DAL passando o _equipamento
MessageBox.Show("Equipamento salvo com sucesso!", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show("Erro ao salvar: " + ex.Message);
}
}
protected override void OnAlterar()
{
// Lógica para habilitar campos ou mudar estado
}
protected override void OnExcluir()
{
if (MessageBox.Show("Deseja excluir este equipamento?", "Confirmar", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
// Lógica de exclusão
}
}
protected override void OnLocalizar()
{
// Aqui você abriria um formulário de busca
}
protected override void OnCancelar()
{
LimparTela();
}
}
}

View File

@ -0,0 +1,133 @@
using CPM;
using MLL;
using System;
using System.Drawing;
using System.Windows.Forms;
using UI;
namespace UI
{
public partial class FornecedoresCadastroPanel : FormularioModelo
{
private ModeloFornecedores _fornecedor = new ModeloFornecedores();
// Controles - Identificação
private LV_TEXTBOX1 txtId, txtEmpresaId, txtNome, txtNomeFantasia, txtDocumento, txtIE, txtTipoPessoa;
// Controles - Localização
private LV_TEXTBOX1 txtCep, txtEndereco, txtNumero, txtBairro, txtCidade, txtUF, txtComplemento;
// Controles - Contato e Extras
private LV_TEXTBOX1 txtTelefone, txtCelular, txtWhatsapp, txtEmail, txtSite, txtObservacoes;
private CheckBox chkAtivo;
public FornecedoresCadastroPanel()
{
this.Titulo = "Cadastro de Fornecedores";
MontarInterface();
}
private void MontarInterface()
{
// --- SEÇÃO 1: Identificação ---
content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO DO FORNECEDOR", 20));
txtId = AddInput(content, "ID", 20, 50, 70, 30, true);
txtEmpresaId = AddInput(content, "ID EMPRESA", 100, 50, 80, 30);
txtTipoPessoa = AddInput(content, "TIPO (PF/PJ)", 190, 50, 100, 30);
txtDocumento = AddInput(content, "CPF / CNPJ", 300, 50, 180, 30);
txtIE = AddInput(content, "INSC. ESTADUAL", 490, 50, 180, 30);
txtNome = AddInput(content, "RAZÃO SOCIAL / NOME", 20, 105, 430, 30);
txtNomeFantasia = AddInput(content, "NOME FANTASIA", 460, 105, 420, 30);
// --- SEÇÃO 2: Localização ---
content.Controls.Add(CreateSectionHeader("ENDEREÇO E LOCALIZAÇÃO", 175));
txtCep = AddInput(content, "CEP", 20, 205, 100, 30);
txtEndereco = AddInput(content, "LOGRADOURO", 130, 205, 350, 30);
txtNumero = AddInput(content, "Nº", 490, 205, 70, 30);
txtBairro = AddInput(content, "BAIRRO", 570, 205, 190, 30);
txtUF = AddInput(content, "UF", 770, 205, 50, 30);
txtCidade = AddInput(content, "CIDADE", 20, 260, 300, 30);
txtComplemento = AddInput(content, "COMPLEMENTO", 330, 260, 550, 30);
// --- SEÇÃO 3: Contato e Comunicação ---
content.Controls.Add(CreateSectionHeader("CONTATOS E DIGITAL", 330));
txtTelefone = AddInput(content, "TELEFONE", 20, 360, 150, 30);
txtCelular = AddInput(content, "CELULAR", 180, 360, 150, 30);
txtWhatsapp = AddInput(content, "WHATSAPP", 340, 360, 150, 30);
txtEmail = AddInput(content, "E-MAIL", 500, 360, 380, 30);
txtSite = AddInput(content, "WEBSITE / PORTAL", 20, 415, 430, 30);
chkAtivo = CreateCheckBox("FORNECEDOR ATIVO", 460, 433);
content.Controls.Add(chkAtivo);
// --- SEÇÃO 4: Observações ---
content.Controls.Add(CreateSectionHeader("OBSERVAÇÕES GERAIS", 485));
txtObservacoes = AddInput(content, "NOTAS INTERNAS", 20, 515, 860, 100);
txtObservacoes.Height = 100;
// Ajuste automático da área de scroll para o conteúdo caber
content.Height = 650;
}
private void PreencherModel()
{
_fornecedor.Nome = txtNome.Text;
_fornecedor.NomeFantasia = txtNomeFantasia.Text;
_fornecedor.TipoPessoa = txtTipoPessoa.Text;
_fornecedor.Documento = txtDocumento.Text;
_fornecedor.InscricaoEstadual = txtIE.Text;
_fornecedor.Cep = txtCep.Text;
_fornecedor.Endereco = txtEndereco.Text;
_fornecedor.Bairro = txtBairro.Text;
_fornecedor.Cidade = txtCidade.Text;
_fornecedor.UF = txtUF.Text;
_fornecedor.Complemento = txtComplemento.Text;
if (int.TryParse(txtNumero.Text, out int n)) _fornecedor.Numero = n;
if (int.TryParse(txtEmpresaId.Text, out int emp)) _fornecedor.EmpresaId = emp;
_fornecedor.Telefone = txtTelefone.Text;
_fornecedor.Celular = txtCelular.Text;
_fornecedor.Whatsapp = txtWhatsapp.Text;
_fornecedor.Email = txtEmail.Text;
_fornecedor.Site = txtSite.Text;
_fornecedor.Observacoes = txtObservacoes.Text;
_fornecedor.Ativo = chkAtivo.Checked;
}
// --- MÉTODOS OBRIGATÓRIOS ---
protected override void OnNovo()
{
_fornecedor = new ModeloFornecedores();
// Implementar lógica de limpar campos se necessário
txtNome.Focus();
}
protected override void OnSalvar()
{
try
{
PreencherModel();
// BLLFornecedor.Salvar(_fornecedor);
MessageBox.Show("Fornecedor salvo com sucesso!", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show("Erro ao salvar: " + ex.Message);
}
}
protected override void OnAlterar() { }
protected override void OnExcluir() { }
protected override void OnLocalizar() { }
protected override void OnCancelar() { OnNovo(); }
}
}

View File

@ -0,0 +1,104 @@
using CPM;
using MLL;
using System;
using System.Drawing;
using System.Windows.Forms;
using UI;
namespace UI
{
public partial class ServicosCadastroPanel : FormularioModelo
{
private ModeloServicos _servico = new ModeloServicos();
// Controles - Identificação
private LV_TEXTBOX1 txtId, txtEmpresaId, txtNome, txtDescricao;
// Controles - Financeiro e Comissão
private LV_TEXTBOX1 txtValorVenda, txtCusto, txtTipoComissao, txtValorComissao;
// Controles - Operacional
private LV_TEXTBOX1 txtTempoEstimado;
private CheckBox chkAtivo;
public ServicosCadastroPanel()
{
this.Titulo = "Cadastro de Serviços";
MontarInterface();
}
private void MontarInterface()
{
// --- SEÇÃO 1: Definição do Serviço ---
content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO DO SERVIÇO", 20));
txtId = AddInput(content, "ID", 20, 50, 70, 30, true);
txtEmpresaId = AddInput(content, "ID EMPRESA", 100, 50, 80, 30);
txtNome = AddInput(content, "NOME DO SERVIÇO", 190, 50, 690, 30);
txtDescricao = AddInput(content, "DESCRIÇÃO DETALHADA / ESCOPO", 20, 105, 860, 50);
txtDescricao.Multiline = true;
// --- SEÇÃO 2: Financeiro e Precificação ---
content.Controls.Add(CreateSectionHeader("VALORES E CUSTOS", 175));
txtValorVenda = AddInput(content, "VALOR DE VENDA (R$)", 20, 205, 180, 30);
txtCusto = AddInput(content, "CUSTO ESTIMADO (R$)", 210, 205, 180, 30);
// --- SEÇÃO 3: Regras de Comissão e Tempo ---
content.Controls.Add(CreateSectionHeader("COMISSIONAMENTO E OPERAÇÃO", 270));
txtTipoComissao = AddInput(content, "TIPO COMISSÃO (FIXO/%)", 20, 300, 180, 30);
txtValorComissao = AddInput(content, "VALOR DA COMISSÃO", 210, 300, 180, 30);
txtTempoEstimado = AddInput(content, "TEMPO ESTIMADO (MIN)", 400, 300, 180, 30);
chkAtivo = CreateCheckBox("SERVIÇO ATIVO PARA VENDA", 600, 318);
content.Controls.Add(chkAtivo);
// Ajuste da altura do conteúdo (Serviços costumam ser telas mais curtas)
content.Height = 450;
}
private void PreencherModel()
{
_servico.Nome = txtNome.Text;
_servico.Descricao = txtDescricao.Text;
_servico.TipoComissao = txtTipoComissao.Text;
_servico.Ativo = chkAtivo.Checked;
// Conversões Numéricas
if (int.TryParse(txtEmpresaId.Text, out int emp)) _servico.EmpresaId = emp;
if (int.TryParse(txtTempoEstimado.Text, out int tempo)) _servico.TempoEstimado = tempo;
if (decimal.TryParse(txtValorVenda.Text, out decimal valor)) _servico.ValorPadrao = valor;
if (decimal.TryParse(txtCusto.Text, out decimal custo)) _servico.Custo = custo;
if (decimal.TryParse(txtValorComissao.Text, out decimal comissao)) _servico.ValorComissao = comissao;
}
protected override void OnNovo()
{
_servico = new ModeloServicos();
txtNome.Focus();
}
protected override void OnSalvar()
{
try
{
PreencherModel();
// BLLServicos.Salvar(_servico);
MessageBox.Show("Serviço cadastrado com sucesso!", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show("Erro ao salvar serviço: " + ex.Message);
}
}
protected override void OnAlterar() { }
protected override void OnExcluir() { }
protected override void OnLocalizar() { }
protected override void OnCancelar() { OnNovo(); }
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,126 @@
using CPM;
using MLL;
using System;
using System.Drawing;
using System.Windows.Forms;
using UI;
namespace UI
{
public partial class TransportadorasCadastroPanel : FormularioModelo
{
private ModeloTransportadoras _transportadora = new ModeloTransportadoras();
// Controles - Identificação
private LV_TEXTBOX1 txtId, txtEmpresaId, txtRazaoSocial, txtNomeFantasia, txtCNPJ;
// Controles - Localização
private LV_TEXTBOX1 txtCep, txtEndereco, txtNumero, txtBairro, txtCidade, txtUF, txtComplemento;
// Controles - Logística e Contato
private LV_TEXTBOX1 txtTelefone, txtEmail, txtTipoFrete, txtPrazo, txtValorFrete, txtObservacoes;
private CheckBox chkAtivo;
public TransportadorasCadastroPanel()
{
this.Titulo = "Cadastro de Transportadoras";
MontarInterface();
}
private void MontarInterface()
{
// --- SEÇÃO 1: Identificação ---
content.Controls.Add(CreateSectionHeader("DADOS DA TRANSPORTADORA", 20));
txtId = AddInput(content, "ID", 20, 50, 70, 30, true);
txtEmpresaId = AddInput(content, "ID EMPRESA", 100, 50, 80, 30);
txtCNPJ = AddInput(content, "CNPJ", 190, 50, 200, 30);
txtRazaoSocial = AddInput(content, "RAZÃO SOCIAL", 20, 105, 430, 30);
txtNomeFantasia = AddInput(content, "NOME FANTASIA", 460, 105, 420, 30);
// --- SEÇÃO 2: Localização ---
content.Controls.Add(CreateSectionHeader("ENDEREÇO SEDE", 175));
txtCep = AddInput(content, "CEP", 20, 205, 100, 30);
txtEndereco = AddInput(content, "LOGRADOURO", 130, 205, 350, 30);
txtNumero = AddInput(content, "Nº", 490, 205, 70, 30);
txtBairro = AddInput(content, "BAIRRO", 570, 205, 190, 30);
txtUF = AddInput(content, "UF", 770, 205, 50, 30);
txtCidade = AddInput(content, "CIDADE", 20, 260, 300, 30);
txtComplemento = AddInput(content, "COMPLEMENTO", 330, 260, 550, 30);
// --- SEÇÃO 3: Regras de Logística e Contato ---
content.Controls.Add(CreateSectionHeader("CONFIGURAÇÕES DE FRETE E CONTATO", 330));
txtTipoFrete = AddInput(content, "TIPO DE FRETE (CIF/FOB)", 20, 360, 180, 30);
txtPrazo = AddInput(content, "PRAZO MÉDIO (DIAS)", 210, 360, 150, 30);
txtValorFrete = AddInput(content, "VALOR PADRÃO (R$)", 370, 360, 150, 30);
chkAtivo = CreateCheckBox("TRANSPORTADORA ATIVA", 540, 378);
content.Controls.Add(chkAtivo);
txtTelefone = AddInput(content, "TELEFONE", 20, 415, 180, 30);
txtEmail = AddInput(content, "E-MAIL PARA COTAÇÃO", 210, 415, 670, 30);
// --- SEÇÃO 4: Observações ---
content.Controls.Add(CreateSectionHeader("OBSERVAÇÕES ADICIONAIS", 485));
txtObservacoes = AddInput(content, "NOTAS DE LOGÍSTICA", 20, 515, 860, 80);
txtObservacoes.Height = 80;
content.Height = 630;
}
private void PreencherModel()
{
_transportadora.RazaoSocial = txtRazaoSocial.Text;
_transportadora.NomeFantasia = txtNomeFantasia.Text;
_transportadora.CNPJ = txtCNPJ.Text;
_transportadora.Cep = txtCep.Text;
_transportadora.Endereco = txtEndereco.Text;
_transportadora.Bairro = txtBairro.Text;
_transportadora.Cidade = txtCidade.Text;
_transportadora.UF = txtUF.Text;
_transportadora.Complemento = txtComplemento.Text;
// Conversões numéricas
if (int.TryParse(txtNumero.Text, out int num)) _transportadora.Numero = num;
if (int.TryParse(txtEmpresaId.Text, out int emp)) _transportadora.EmpresaId = emp;
if (int.TryParse(txtPrazo.Text, out int prazo)) _transportadora.PrazoEntrega = prazo;
if (decimal.TryParse(txtValorFrete.Text, out decimal valor)) _transportadora.ValorFretePadrao = valor;
_transportadora.TipoFrete = txtTipoFrete.Text;
_transportadora.Telefone = txtTelefone.Text;
_transportadora.Email = txtEmail.Text;
_transportadora.Observacoes = txtObservacoes.Text;
_transportadora.Ativo = chkAtivo.Checked;
}
protected override void OnNovo()
{
_transportadora = new ModeloTransportadoras();
txtCNPJ.Focus();
}
protected override void OnSalvar()
{
try
{
PreencherModel();
// BLLTransportadora.Salvar(_transportadora);
MessageBox.Show("Transportadora registrada com sucesso!", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show("Erro ao processar dados: " + ex.Message);
}
}
protected override void OnAlterar() { }
protected override void OnExcluir() { }
protected override void OnLocalizar() { }
protected override void OnCancelar() { OnNovo(); }
}
}

View File

@ -1,6 +1,7 @@
using CCH; using CCH;
using CustomMessageBox; using CustomMessageBox;
using DAL; using DAL;
using LevelOS;
using System; using System;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
@ -18,6 +19,15 @@ namespace UI
private readonly AgendaCadastroPanel _pAgendaCadastro; private readonly AgendaCadastroPanel _pAgendaCadastro;
private readonly AgendaConsultaPanel _pAgendaConsulta; private readonly AgendaConsultaPanel _pAgendaConsulta;
private readonly FuncionariosCadastroPanel _pfuncionariosCadastro ; private readonly FuncionariosCadastroPanel _pfuncionariosCadastro ;
private readonly EquipamentosCadastroPanel _pequipamentosCadastroPanel;
private readonly ContratosCadastroPanel _pcontratosCadastroPanel;
private readonly FornecedoresCadastroPanel _pfornecedoresCadastroPanel;
private readonly TransportadorasCadastroPanel _ptransportadorasCadastroPanel;
private readonly ServicosCadastroPanel _pservicosCadastroPanel;
//Painel financeiro
private readonly BoletoCadastroPanel _pboletoCadastroPanel;
private readonly Panel _pOrdens; private readonly Panel _pOrdens;
private readonly Panel _pProdutos; private readonly Panel _pProdutos;
private readonly Panel _pEstoque; private readonly Panel _pEstoque;
@ -41,6 +51,12 @@ namespace UI
_pAgendaCadastro = new AgendaCadastroPanel { Dock = DockStyle.Fill, Visible = false }; _pAgendaCadastro = new AgendaCadastroPanel { Dock = DockStyle.Fill, Visible = false };
_pAgendaConsulta = new AgendaConsultaPanel { Dock = DockStyle.Fill, Visible = false }; _pAgendaConsulta = new AgendaConsultaPanel { Dock = DockStyle.Fill, Visible = false };
_pfuncionariosCadastro = new FuncionariosCadastroPanel { Dock = DockStyle.Fill, Visible = false }; _pfuncionariosCadastro = new FuncionariosCadastroPanel { Dock = DockStyle.Fill, Visible = false };
_pboletoCadastroPanel = new BoletoCadastroPanel { Dock = DockStyle.Fill, Visible = false };
_pequipamentosCadastroPanel = new EquipamentosCadastroPanel { Dock = DockStyle.Fill, Visible = false };
_pcontratosCadastroPanel = new ContratosCadastroPanel { Dock = DockStyle.Fill, Visible = false };
_pfornecedoresCadastroPanel = new FornecedoresCadastroPanel { Dock = DockStyle.Fill, Visible = false };
_ptransportadorasCadastroPanel = new TransportadorasCadastroPanel { Dock = DockStyle.Fill, Visible = false };
_pservicosCadastroPanel = new ServicosCadastroPanel { Dock = DockStyle.Fill, Visible = false };
_pOrdens = PlaceholderPanel("Ordens de Serviço", Color.FromArgb(22, 163, 74)); _pOrdens = PlaceholderPanel("Ordens de Serviço", Color.FromArgb(22, 163, 74));
_pProdutos = PlaceholderPanel("Catálogo de Produtos", Color.FromArgb(217, 119, 6)); _pProdutos = PlaceholderPanel("Catálogo de Produtos", Color.FromArgb(217, 119, 6));
_pEstoque = PlaceholderPanel("Controle de Estoque", Color.FromArgb(234, 88, 12)); _pEstoque = PlaceholderPanel("Controle de Estoque", Color.FromArgb(234, 88, 12));
@ -50,6 +66,12 @@ namespace UI
mainContainer.Controls.Add(_pFinanceiro); mainContainer.Controls.Add(_pFinanceiro);
mainContainer.Controls.Add(_pAgendaCadastro); mainContainer.Controls.Add(_pAgendaCadastro);
mainContainer.Controls.Add(_pAgendaConsulta); mainContainer.Controls.Add(_pAgendaConsulta);
mainContainer.Controls.Add(_pboletoCadastroPanel);
mainContainer.Controls.Add(_pequipamentosCadastroPanel);
mainContainer.Controls.Add(_pcontratosCadastroPanel);
mainContainer.Controls.Add(_pfornecedoresCadastroPanel);
mainContainer.Controls.Add(_ptransportadorasCadastroPanel);
mainContainer.Controls.Add(_pservicosCadastroPanel);
mainContainer.Controls.Add(_pEstoque); mainContainer.Controls.Add(_pEstoque);
mainContainer.Controls.Add(_pProdutos); mainContainer.Controls.Add(_pProdutos);
mainContainer.Controls.Add(_pOrdens); mainContainer.Controls.Add(_pOrdens);
@ -85,7 +107,12 @@ namespace UI
case 5: ShowPanel(_pEstoque); break; case 5: ShowPanel(_pEstoque); break;
case 9: ShowPanel(_pFinanceiro); break; case 9: ShowPanel(_pFinanceiro); break;
case 99: ShowPanel(_pClientes); break; case 99: ShowPanel(_pClientes); break;
case 100: ShowPanel(_pequipamentosCadastroPanel); break;
case 101: ShowPanel(_pcontratosCadastroPanel); break;
case 102: ShowPanel(_pfornecedoresCadastroPanel); break;
case 103: ShowPanel(_pfuncionariosCadastro); break; case 103: ShowPanel(_pfuncionariosCadastro); break;
case 104: ShowPanel(_ptransportadorasCadastroPanel); break;
case 105: ShowPanel(_pservicosCadastroPanel); break;
case 106: ShowPanel(_pEmpresa); break; case 106: ShowPanel(_pEmpresa); break;
@ -94,6 +121,10 @@ namespace UI
case 301: ShowPanel(_pAgendaConsulta); break; case 301: ShowPanel(_pAgendaConsulta); break;
case 500: ShowPanel(_pboletoCadastroPanel); break;
} }
} }
@ -110,7 +141,12 @@ namespace UI
_pAgendaCadastro.Visible = (panelToShow == _pAgendaCadastro); _pAgendaCadastro.Visible = (panelToShow == _pAgendaCadastro);
_pAgendaConsulta.Visible = (panelToShow == _pAgendaConsulta); _pAgendaConsulta.Visible = (panelToShow == _pAgendaConsulta);
_pfuncionariosCadastro.Visible = (panelToShow == _pfuncionariosCadastro); _pfuncionariosCadastro.Visible = (panelToShow == _pfuncionariosCadastro);
_pboletoCadastroPanel.Visible = (panelToShow == _pboletoCadastroPanel);
_pequipamentosCadastroPanel.Visible = (panelToShow == _pequipamentosCadastroPanel);
_pcontratosCadastroPanel.Visible = (panelToShow == _pcontratosCadastroPanel);
_pfornecedoresCadastroPanel.Visible = (panelToShow == _pfornecedoresCadastroPanel);
_ptransportadorasCadastroPanel.Visible = (panelToShow == _ptransportadorasCadastroPanel);
_pservicosCadastroPanel.Visible = (panelToShow == _pservicosCadastroPanel);
if (panelToShow.Visible) if (panelToShow.Visible)
{ {
panelToShow.BringToFront(); panelToShow.BringToFront();

View File

@ -156,6 +156,7 @@ namespace UI
_subMenuFinanceiro.Items.Add("💳 Contas", null, (s, e) => { /* Lógica */ }); _subMenuFinanceiro.Items.Add("💳 Contas", null, (s, e) => { /* Lógica */ });
_subMenuFinanceiro.Items.Add("📈 Contas a receber", null, (s, e) => { /* Lógica */ }); _subMenuFinanceiro.Items.Add("📈 Contas a receber", null, (s, e) => { /* Lógica */ });
_subMenuFinanceiro.Items.Add("📉 Contas a pagar", null, (s, e) => { /* Lógica */ }); _subMenuFinanceiro.Items.Add("📉 Contas a pagar", null, (s, e) => { /* Lógica */ });
_subMenuFinanceiro.Items.Add("📉 Boletos/Duplicatas", null, (s, e) => { NavItemClicked?.Invoke(this, 500); });
_subMenuFinanceiro.Items.Add(new ToolStripSeparator()); // Linha divisória _subMenuFinanceiro.Items.Add(new ToolStripSeparator()); // Linha divisória
_subMenuFinanceiro.Items.Add("🛒 Compras", null, (s, e) => { /* Lógica */ }); _subMenuFinanceiro.Items.Add("🛒 Compras", null, (s, e) => { /* Lógica */ });
_subMenuFinanceiro.Items.Add("💰 Vendas", null, (s, e) => { /* Lógica */ }); _subMenuFinanceiro.Items.Add("💰 Vendas", null, (s, e) => { /* Lógica */ });

View File

@ -4,7 +4,7 @@ using System;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
namespace LevelOS namespace UI
{ {
/// <summary> /// <summary>
/// Modelo base para todos os formulários do sistema. /// Modelo base para todos os formulários do sistema.

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>