LevelOS-Core/UI/Dashboards/Cadastros/BoletoCadastroPanel.cs

741 lines
31 KiB
C#

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;
}
}
}