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

588 lines
25 KiB
C#

using CPM;
using DAL;
using MLL;
using BLL;
using System;
using System.Drawing;
using System.Windows.Forms;
namespace UI
{
public class ContaPagarCadastroPanel : FormularioModelo
{
// ── CAMPOS DO FORMULÁRIO ──────────────────────────────────────────────
private LV_TEXTBOX1 txtId = null!;
private LV_TEXTBOX1 txtDescricao = null!;
private LV_COMBOBOXCUSTOM cmbStatus = null!;
private CheckBox chkAtivo = null!;
// Fornecedor — busca
private LV_TEXTBOX1 txtFornecedorId = null!;
private LV_TEXTBOX1 txtFornecedorNome = null!;
private Button btnBuscarFornecedor = null!;
// Plano de Contas — busca
private LV_TEXTBOX1 txtPlanoContaId = null!;
private LV_TEXTBOX1 txtPlanoContaNome = null!;
private Button btnBuscarPlanoConta = null!;
// Valores
private LV_TEXTBOX1 txtValor = null!;
private LV_TEXTBOX1 txtValorPago = null!;
private LV_TEXTBOX1 txtJuros = null!;
private LV_TEXTBOX1 txtMulta = null!;
private LV_TEXTBOX1 txtDesconto = null!;
// Datas
private LV_TEXTBOX1 txtDataEmissao = null!;
private LV_TEXTBOX1 txtDataVencimento = null!;
private LV_TEXTBOX1 txtDataPagamento = null!;
// Auditoria
private LV_TEXTBOX1 txtCriadoEm = null!;
private LV_TEXTBOX1 txtAtualizadoEm = null!;
// Observações
private LV_TEXTBOX1 txtObservacoes = null!;
// ── ESTADO ────────────────────────────────────────────────────────────
private enum ModoFormulario { Visualizacao, Novo, Edicao }
private ModoFormulario _modo = ModoFormulario.Visualizacao;
private int _idAtual = 0;
private int _fornecedorId = 0;
private int _planoContaId = 0;
// ── BLL ───────────────────────────────────────────────────────────────
// private ContaPagarBLL _bll = null!;
// ── CONSTRUTOR ────────────────────────────────────────────────────────
public ContaPagarCadastroPanel()
{
Titulo = "Contas a Pagar";
BuildForm();
AplicarModo(ModoFormulario.Visualizacao);
}
// ── CONSTRUÇÃO DOS CAMPOS ─────────────────────────────────────────────
private void BuildForm()
{
// ── SEÇÃO: IDENTIFICAÇÃO ──────────────────────────────────────────
content.Controls.Add(CreateSectionHeader("Identificação", 20));
txtId = AddInput(content, "ID", 20, 58, 80, 32, readOnly: true);
txtDescricao = AddInput(content, "Descrição", 120, 58, 400, 32);
txtDescricao.MaxLength = 255;
// Status
var lblStatus = new Label
{
Text = "Status",
Location = new Point(540, 58),
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
ForeColor = TextDark,
AutoSize = true
};
cmbStatus = new LV_COMBOBOXCUSTOM
{
Location = new Point(540, 74),
Size = new Size(160, 32),
DropDownStyle = ComboBoxStyle.DropDownList,
BorderColor = BorderColor,
BackColor = Color.White,
ListBackColor = Color.White,
ListTextColor = TextDark,
IconColor = AccentBlue,
Font = new Font("Segoe UI", 9f)
};
cmbStatus.Items.Add("Pendente");
cmbStatus.Items.Add("Pago");
cmbStatus.Items.Add("Vencido");
cmbStatus.Items.Add("Cancelado");
cmbStatus.Items.Add("Parcial");
cmbStatus.SelectedIndex = 0;
content.Controls.Add(lblStatus);
content.Controls.Add(cmbStatus);
chkAtivo = CreateCheckBox("Ativo", 750, 82);
chkAtivo.Checked = true;
content.Controls.Add(chkAtivo);
// ── SEÇÃO: FORNECEDOR ─────────────────────────────────────────────
content.Controls.Add(CreateSectionHeader("Fornecedor", 128));
var lblFornecedor = new Label
{
Text = "Fornecedor",
Location = new Point(20, 166),
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
ForeColor = TextDark,
AutoSize = true
};
txtFornecedorId = new LV_TEXTBOX1
{
Location = new Point(20, 182),
Size = new Size(80, 32),
BorderColor = ReadOnlyBorder,
BorderFocusColor = AccentBlue,
ReadOnly = true,
BackColor = ReadOnlyBg
};
txtFornecedorNome = new LV_TEXTBOX1
{
Location = new Point(108, 182),
Size = new Size(300, 32),
BorderColor = ReadOnlyBorder,
BorderFocusColor = AccentBlue,
ReadOnly = true,
BackColor = ReadOnlyBg
};
btnBuscarFornecedor = new Button
{
Text = "🔍 Buscar",
Location = new Point(416, 182),
Size = new Size(90, 32),
BackColor = AccentBlue,
ForeColor = Color.White,
Font = new Font("Segoe UI Semibold", 8.5f),
Cursor = Cursors.Hand,
FlatStyle = FlatStyle.Flat,
Enabled = false
};
btnBuscarFornecedor.FlatAppearance.BorderSize = 0;
btnBuscarFornecedor.Click += BtnBuscarFornecedor_Click;
content.Controls.Add(lblFornecedor);
content.Controls.Add(txtFornecedorId);
content.Controls.Add(txtFornecedorNome);
content.Controls.Add(btnBuscarFornecedor);
// ── SEÇÃO: PLANO DE CONTAS ────────────────────────────────────────
content.Controls.Add(CreateSectionHeader("Plano de Contas", 234));
var lblPlanoConta = new Label
{
Text = "Plano de Contas",
Location = new Point(20, 272),
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
ForeColor = TextDark,
AutoSize = true
};
txtPlanoContaId = new LV_TEXTBOX1
{
Location = new Point(20, 288),
Size = new Size(80, 32),
BorderColor = ReadOnlyBorder,
BorderFocusColor = AccentBlue,
ReadOnly = true,
BackColor = ReadOnlyBg
};
txtPlanoContaNome = new LV_TEXTBOX1
{
Location = new Point(108, 288),
Size = new Size(300, 32),
BorderColor = ReadOnlyBorder,
BorderFocusColor = AccentBlue,
ReadOnly = true,
BackColor = ReadOnlyBg
};
btnBuscarPlanoConta = new Button
{
Text = "🔍 Buscar",
Location = new Point(416, 288),
Size = new Size(90, 32),
BackColor = AccentBlue,
ForeColor = Color.White,
Font = new Font("Segoe UI Semibold", 8.5f),
Cursor = Cursors.Hand,
FlatStyle = FlatStyle.Flat,
Enabled = false
};
btnBuscarPlanoConta.FlatAppearance.BorderSize = 0;
btnBuscarPlanoConta.Click += BtnBuscarPlanoConta_Click;
content.Controls.Add(lblPlanoConta);
content.Controls.Add(txtPlanoContaId);
content.Controls.Add(txtPlanoContaNome);
content.Controls.Add(btnBuscarPlanoConta);
// ── SEÇÃO: VALORES ────────────────────────────────────────────────
content.Controls.Add(CreateSectionHeader("Valores", 340));
txtValor = AddInput(content, "Valor (R$)", 20, 378, 150, 32);
txtValorPago = AddInput(content, "Valor Pago (R$)", 190, 378, 150, 32);
txtJuros = AddInput(content, "Juros (R$)", 360, 378, 130, 32);
txtMulta = AddInput(content, "Multa (R$)", 510, 378, 130, 32);
txtDesconto = AddInput(content, "Desconto (R$)", 660, 378, 130, 32);
// ── SEÇÃO: DATAS ──────────────────────────────────────────────────
content.Controls.Add(CreateSectionHeader("Datas", 440));
txtDataEmissao = AddInput(content, "Emissão", 20, 478, 180, 32);
txtDataVencimento = AddInput(content, "Vencimento", 220, 478, 180, 32);
txtDataPagamento = AddInput(content, "Pagamento", 420, 478, 180, 32);
// ── SEÇÃO: OBSERVAÇÕES ────────────────────────────────────────────
content.Controls.Add(CreateSectionHeader("Observações", 540));
var lblObs = new Label
{
Text = "Observações",
Location = new Point(20, 578),
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
ForeColor = TextDark,
AutoSize = true
};
txtObservacoes = new LV_TEXTBOX1
{
Location = new Point(20, 594),
Size = new Size(760, 70),
BorderColor = BorderColor,
BorderFocusColor = AccentBlue,
Multiline = true,
MaxLength = 500
};
content.Controls.Add(lblObs);
content.Controls.Add(txtObservacoes);
// ── SEÇÃO: AUDITORIA ──────────────────────────────────────────────
content.Controls.Add(CreateSectionHeader("Auditoria", 684));
txtCriadoEm = AddInput(content, "Criado em", 20, 722, 200, 32, readOnly: true);
txtAtualizadoEm = AddInput(content, "Atualizado em", 240, 722, 200, 32, readOnly: true);
content.Height = 790;
}
// ── CAMPOS EDITÁVEIS ──────────────────────────────────────────────────
private LV_TEXTBOX1[] CamposEditaveis() => new[]
{
txtDescricao, txtValor, txtValorPago, txtJuros,
txtMulta, txtDesconto, txtDataEmissao, txtDataVencimento,
txtDataPagamento, txtObservacoes
};
// ── MODOS DO FORMULÁRIO ───────────────────────────────────────────────
private void AplicarModo(ModoFormulario modo)
{
_modo = modo;
bool editando = modo == ModoFormulario.Novo || modo == ModoFormulario.Edicao;
foreach (var txt in CamposEditaveis())
{
txt.ReadOnly = !editando;
txt.BackColor = editando ? Color.White : ReadOnlyBg;
txt.BorderColor = editando ? BorderColor : ReadOnlyBorder;
}
cmbStatus.Enabled = editando;
cmbStatus.BorderColor = editando ? BorderColor : ReadOnlyBorder;
cmbStatus.BackColor = editando ? Color.White : ReadOnlyBg;
chkAtivo.Enabled = editando;
btnBuscarFornecedor.Enabled = editando;
btnBuscarPlanoConta.Enabled = editando;
btnNovo.Enabled = !editando;
btnAlterar.Enabled = !editando && _idAtual > 0;
btnExcluir.Enabled = !editando && _idAtual > 0;
btnLocalizar.Enabled = !editando;
btnSalvar.Enabled = editando;
btnCancelar.Enabled = editando;
if (modo == ModoFormulario.Novo) LimparCampos();
}
// ── BUSCA DE FORNECEDOR ───────────────────────────────────────────────
private void BtnBuscarFornecedor_Click(object? sender, EventArgs e)
{
// TODO: abrir formulário de busca de fornecedores
// var frm = new FormularioBuscarFornecedor();
// if (frm.ShowDialog() == DialogResult.OK)
// {
// _fornecedorId = frm.FornecedorSelecionado.Id;
// txtFornecedorId.Text = _fornecedorId.ToString();
// txtFornecedorNome.Text = frm.FornecedorSelecionado.Nome;
// }
MessageBox.Show("Implemente o formulário de busca de fornecedores.",
"Buscar Fornecedor", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
// ── BUSCA DE PLANO DE CONTAS ──────────────────────────────────────────
private void BtnBuscarPlanoConta_Click(object? sender, EventArgs e)
{
// TODO: abrir formulário de busca de plano de contas
// var frm = new FormularioBuscarPlanoConta();
// if (frm.ShowDialog() == DialogResult.OK)
// {
// _planoContaId = frm.PlanoContaSelecionado.Id;
// txtPlanoContaId.Text = _planoContaId.ToString();
// txtPlanoContaNome.Text = frm.PlanoContaSelecionado.Nome;
// }
MessageBox.Show("Implemente o formulário de busca de plano de contas.",
"Buscar Plano de Contas", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
// ── POPULAR / LIMPAR ──────────────────────────────────────────────────
private void PopularCampos(ModeloContaPagar m)
{
_idAtual = m.Id;
_fornecedorId = m.FornecedorId;
_planoContaId = m.PlanoContaId;
txtId.Text = m.Id.ToString();
txtDescricao.Text = m.Descricao;
txtFornecedorId.Text = m.FornecedorId.ToString();
txtPlanoContaId.Text = m.PlanoContaId.ToString();
txtValor.Text = m.Valor.ToString("F2");
txtValorPago.Text = m.ValorPago?.ToString("F2") ?? string.Empty;
txtJuros.Text = m.Juros.ToString("F2");
txtMulta.Text = m.Multa.ToString("F2");
txtDesconto.Text = m.Desconto.ToString("F2");
txtDataEmissao.Text = m.DataEmissao?.ToString("dd/MM/yyyy") ?? string.Empty;
txtDataVencimento.Text = m.DataVencimento.ToString("dd/MM/yyyy");
txtDataPagamento.Text = m.DataPagamento?.ToString("dd/MM/yyyy") ?? string.Empty;
txtObservacoes.Text = m.Observacoes;
chkAtivo.Checked = m.Ativo;
txtCriadoEm.Text = m.CriadoEm.ToString("dd/MM/yyyy HH:mm");
txtAtualizadoEm.Text = m.AtualizadoEm.ToString("dd/MM/yyyy HH:mm");
SelecionarCombo(cmbStatus, m.Status);
}
private void LimparCampos()
{
_idAtual = 0;
_fornecedorId = 0;
_planoContaId = 0;
txtId.Text = string.Empty;
txtDescricao.Text = string.Empty;
txtFornecedorId.Text = string.Empty;
txtFornecedorNome.Text = string.Empty;
txtPlanoContaId.Text = string.Empty;
txtPlanoContaNome.Text = string.Empty;
txtValor.Text = string.Empty;
txtValorPago.Text = string.Empty;
txtJuros.Text = string.Empty;
txtMulta.Text = string.Empty;
txtDesconto.Text = string.Empty;
txtDataEmissao.Text = string.Empty;
txtDataVencimento.Text = string.Empty;
txtDataPagamento.Text = string.Empty;
txtObservacoes.Text = string.Empty;
chkAtivo.Checked = true;
txtCriadoEm.Text = string.Empty;
txtAtualizadoEm.Text = string.Empty;
cmbStatus.SelectedIndex = 0;
}
// ── HELPER COMBOBOX ───────────────────────────────────────────────────
private static void SelecionarCombo(LV_COMBOBOXCUSTOM cmb, string valor)
{
for (int i = 0; i < cmb.Items.Count; i++)
{
if (cmb.Items[i]?.ToString() == valor)
{
cmb.SelectedIndex = i;
return;
}
}
cmb.SelectedIndex = 0;
}
// ── VALIDAÇÃO ─────────────────────────────────────────────────────────
private bool Validar()
{
if (string.IsNullOrWhiteSpace(txtDescricao.Text))
{
MessageBox.Show("Informe a descrição.", "Validação",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtDescricao.Focus();
return false;
}
if (_fornecedorId == 0)
{
MessageBox.Show("Selecione um fornecedor.", "Validação",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
btnBuscarFornecedor.Focus();
return false;
}
if (_planoContaId == 0)
{
MessageBox.Show("Selecione um plano de contas.", "Validação",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
btnBuscarPlanoConta.Focus();
return false;
}
if (!decimal.TryParse(txtValor.Text.Replace(",", "."),
System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out _))
{
MessageBox.Show("Informe um valor válido.", "Validação",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtValor.Focus();
return false;
}
if (string.IsNullOrWhiteSpace(txtDataVencimento.Text))
{
MessageBox.Show("Informe a data de vencimento.", "Validação",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtDataVencimento.Focus();
return false;
}
return true;
}
// ── MONTAR MODELO ─────────────────────────────────────────────────────
private ModeloContaPagar MontarModelo()
{
decimal.TryParse(txtValor.Text.Replace(",", "."),
System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out decimal valor);
decimal.TryParse(txtValorPago.Text.Replace(",", "."),
System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out decimal valorPago);
decimal.TryParse(txtJuros.Text.Replace(",", "."),
System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out decimal juros);
decimal.TryParse(txtMulta.Text.Replace(",", "."),
System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out decimal multa);
decimal.TryParse(txtDesconto.Text.Replace(",", "."),
System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out decimal desconto);
DateTime.TryParseExact(txtDataVencimento.Text, "dd/MM/yyyy",
null, System.Globalization.DateTimeStyles.None, out DateTime dataVenc);
DateTime.TryParseExact(txtDataEmissao.Text, "dd/MM/yyyy",
null, System.Globalization.DateTimeStyles.None, out DateTime dataEmissao);
DateTime? dataEmissaoNull = string.IsNullOrWhiteSpace(txtDataEmissao.Text) ? null : dataEmissao;
DateTime.TryParseExact(txtDataPagamento.Text, "dd/MM/yyyy",
null, System.Globalization.DateTimeStyles.None, out DateTime dataPag);
DateTime? dataPagNull = string.IsNullOrWhiteSpace(txtDataPagamento.Text) ? null : dataPag;
return new ModeloContaPagar(
_idAtual,
0, // EmpresaId — preenchido pela BLL via sessão
_fornecedorId,
_planoContaId,
txtDescricao.Text.Trim(),
valor,
string.IsNullOrWhiteSpace(txtValorPago.Text) ? null : valorPago,
juros,
multa,
desconto,
cmbStatus.SelectedItem?.ToString() ?? "Pendente",
dataEmissaoNull,
dataVenc,
dataPagNull,
txtObservacoes.Text.Trim(),
chkAtivo.Checked,
_modo == ModoFormulario.Novo ? DateTime.Now : DateTime.Parse(txtCriadoEm.Text),
DateTime.Now
);
}
// ── EVENTOS ABSTRATOS ─────────────────────────────────────────────────
protected override void OnNovo()
{
AplicarModo(ModoFormulario.Novo);
txtDescricao.Focus();
}
protected override void OnAlterar()
{
if (_idAtual == 0) return;
AplicarModo(ModoFormulario.Edicao);
txtDescricao.Focus();
}
protected override void OnExcluir()
{
if (_idAtual == 0) return;
var confirm = MessageBox.Show(
$"Deseja realmente excluir a conta \"{txtDescricao.Text}\"?",
"Confirmar exclusão",
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning);
if (confirm != DialogResult.Yes) return;
try
{
// TODO: _bll.Excluir(_idAtual);
MessageBox.Show("Conta a pagar excluída com sucesso.", "Sucesso",
MessageBoxButtons.OK, MessageBoxIcon.Information);
LimparCampos();
AplicarModo(ModoFormulario.Visualizacao);
}
catch (Exception ex)
{
MessageBox.Show($"Erro ao excluir:\n{ex.Message}", "Erro",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
protected override void OnLocalizar()
{
// TODO: abrir formulário de busca de contas a pagar
// var frm = new FormularioBuscarContaPagar();
// if (frm.ShowDialog() == DialogResult.OK)
// {
// PopularCampos(frm.ContaSelecionada);
// AplicarModo(ModoFormulario.Visualizacao);
// }
MessageBox.Show("Implemente o formulário de busca de contas a pagar.",
"Localizar", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
protected override void OnSalvar()
{
if (!Validar()) return;
var modelo = MontarModelo();
try
{
if (_modo == ModoFormulario.Novo)
{
// TODO: _bll.Criar(modelo);
MessageBox.Show("Conta a pagar cadastrada com sucesso!", "Sucesso",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
// TODO: _bll.Atualizar(modelo);
MessageBox.Show("Conta a pagar atualizada com sucesso!", "Sucesso",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
AplicarModo(ModoFormulario.Visualizacao);
}
catch (Exception ex)
{
MessageBox.Show($"Erro ao salvar:\n{ex.Message}", "Erro",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
protected override void OnCancelar()
{
if (_idAtual > 0)
{
// TODO: recarregar do banco se necessário
}
LimparCampos();
AplicarModo(ModoFormulario.Visualizacao);
}
}
}