resolvendo merge
This commit is contained in:
commit
407b4b4b17
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
.vs/
|
||||
<<<<<<< HEAD
|
||||
**/.vs/
|
||||
bin/
|
||||
obj/
|
||||
@ -8,3 +9,10 @@ obj/
|
||||
*.cache
|
||||
*.user
|
||||
*.suo
|
||||
=======
|
||||
bin/
|
||||
obj/
|
||||
*.user
|
||||
*.suo
|
||||
*.cache
|
||||
>>>>>>> 577e97245b8945b1bfd71ca7bb3971042d27d2a9
|
||||
|
||||
108
ArquivosAuxiliares/DadosAuxiliaresTabelaPermissoes.sql
Normal file
108
ArquivosAuxiliares/DadosAuxiliaresTabelaPermissoes.sql
Normal file
@ -0,0 +1,108 @@
|
||||
INSERT INTO Permissoes (Nome, Descricao)
|
||||
VALUES
|
||||
|
||||
-- ========================
|
||||
-- EMPRESA
|
||||
-- ========================
|
||||
('EMPRESA_VER', 'Visualizar dados da empresa'),
|
||||
('EMPRESA_EDITAR', 'Editar dados da empresa'),
|
||||
|
||||
-- ========================
|
||||
-- CLIENTES
|
||||
-- ========================
|
||||
('CLIENTE_VER', 'Visualizar clientes'),
|
||||
('CLIENTE_CADASTRAR', 'Cadastrar clientes'),
|
||||
('CLIENTE_EDITAR', 'Editar clientes'),
|
||||
('CLIENTE_EXCLUIR', 'Excluir clientes'),
|
||||
|
||||
-- ========================
|
||||
-- FORNECEDORES
|
||||
-- ========================
|
||||
('FORNECEDOR_VER', 'Visualizar fornecedores'),
|
||||
('FORNECEDOR_CADASTRAR', 'Cadastrar fornecedores'),
|
||||
('FORNECEDOR_EDITAR', 'Editar fornecedores'),
|
||||
('FORNECEDOR_EXCLUIR', 'Excluir fornecedores'),
|
||||
|
||||
-- ========================
|
||||
-- FUNCIONARIOS
|
||||
-- ========================
|
||||
('FUNCIONARIO_VER', 'Visualizar funcionários'),
|
||||
('FUNCIONARIO_CADASTRAR', 'Cadastrar funcionários'),
|
||||
('FUNCIONARIO_EDITAR', 'Editar funcionários'),
|
||||
('FUNCIONARIO_EXCLUIR', 'Excluir funcionários'),
|
||||
|
||||
-- ========================
|
||||
-- USUARIOS / SEGURANÇA
|
||||
-- ========================
|
||||
('USUARIO_VER', 'Visualizar usuários'),
|
||||
('USUARIO_CADASTRAR', 'Cadastrar usuários'),
|
||||
('USUARIO_EDITAR', 'Editar usuários'),
|
||||
('USUARIO_EXCLUIR', 'Excluir usuários'),
|
||||
('PERMISSAO_GERENCIAR', 'Gerenciar permissões'),
|
||||
|
||||
-- ========================
|
||||
-- SERVIÇOS
|
||||
-- ========================
|
||||
('SERVICO_VER', 'Visualizar serviços'),
|
||||
('SERVICO_CADASTRAR', 'Cadastrar serviços'),
|
||||
('SERVICO_EDITAR', 'Editar serviços'),
|
||||
('SERVICO_EXCLUIR', 'Excluir serviços'),
|
||||
|
||||
-- ========================
|
||||
-- CONTRATOS
|
||||
-- ========================
|
||||
('CONTRATO_VER', 'Visualizar contratos'),
|
||||
('CONTRATO_CADASTRAR', 'Cadastrar contratos'),
|
||||
('CONTRATO_EDITAR', 'Editar contratos'),
|
||||
('CONTRATO_EXCLUIR', 'Excluir contratos'),
|
||||
|
||||
-- ========================
|
||||
-- FINANCEIRO - RECEBER
|
||||
-- ========================
|
||||
('RECEBER_VER', 'Visualizar contas a receber'),
|
||||
('RECEBER_CADASTRAR', 'Cadastrar contas a receber'),
|
||||
('RECEBER_EDITAR', 'Editar contas a receber'),
|
||||
('RECEBER_BAIXAR', 'Dar baixa em contas a receber'),
|
||||
|
||||
-- ========================
|
||||
-- FINANCEIRO - PAGAR
|
||||
-- ========================
|
||||
('PAGAR_VER', 'Visualizar contas a pagar'),
|
||||
('PAGAR_CADASTRAR', 'Cadastrar contas a pagar'),
|
||||
('PAGAR_EDITAR', 'Editar contas a pagar'),
|
||||
('PAGAR_BAIXAR', 'Dar baixa em contas a pagar'),
|
||||
|
||||
-- ========================
|
||||
-- PLANO DE CONTAS
|
||||
-- ========================
|
||||
('PLANO_CONTAS_VER', 'Visualizar plano de contas'),
|
||||
('PLANO_CONTAS_CADASTRAR', 'Cadastrar plano de contas'),
|
||||
('PLANO_CONTAS_EDITAR', 'Editar plano de contas'),
|
||||
('PLANO_CONTAS_EXCLUIR', 'Excluir plano de contas'),
|
||||
|
||||
-- ========================
|
||||
-- TRANSPORTADORAS
|
||||
-- ========================
|
||||
('TRANSPORTADORA_VER', 'Visualizar transportadoras'),
|
||||
('TRANSPORTADORA_CADASTRAR', 'Cadastrar transportadoras'),
|
||||
('TRANSPORTADORA_EDITAR', 'Editar transportadoras'),
|
||||
('TRANSPORTADORA_EXCLUIR', 'Excluir transportadoras'),
|
||||
|
||||
-- ========================
|
||||
-- RELATORIOS
|
||||
-- ========================
|
||||
('RELATORIO_FINANCEIRO', 'Acessar relatórios financeiros'),
|
||||
('RELATORIO_CLIENTES', 'Acessar relatórios de clientes'),
|
||||
('RELATORIO_GERAL', 'Acessar relatórios gerais'),
|
||||
|
||||
-- ========================
|
||||
-- SISTEMA
|
||||
-- ========================
|
||||
('SISTEMA_CONFIG', 'Alterar configurações do sistema'),
|
||||
('SISTEMA_LOGS', 'Visualizar logs do sistema');
|
||||
|
||||
INSERT INTO Permissoes (Nome, Descricao)
|
||||
SELECT 'CLIENTE_VER', 'Visualizar clientes'
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM Permissoes WHERE Nome = 'CLIENTE_VER'
|
||||
);
|
||||
74
ArquivosAuxiliares/DadosSistema.sql
Normal file
74
ArquivosAuxiliares/DadosSistema.sql
Normal file
@ -0,0 +1,74 @@
|
||||
-- =========================
|
||||
-- PEGAR EMPRESA
|
||||
-- =========================
|
||||
DECLARE @EmpresaId INT;
|
||||
SELECT TOP 1 @EmpresaId = Id FROM Empresa;
|
||||
|
||||
-- =========================
|
||||
-- CRIAR USUARIO ADMIN
|
||||
-- =========================
|
||||
IF NOT EXISTS (SELECT 1 FROM Usuarios WHERE Usuario = 'admin' AND EmpresaId = @EmpresaId)
|
||||
BEGIN
|
||||
INSERT INTO Usuarios (
|
||||
EmpresaId, Nome, Email, Usuario, SenhaHash, Ativo, CriadoEm
|
||||
)
|
||||
VALUES (
|
||||
@EmpresaId,
|
||||
'Administrador do Sistema',
|
||||
'admin@levelcode.com.br',
|
||||
'admin',
|
||||
CONVERT(VARCHAR(255), HASHBYTES('SHA2_256', 'Nad310311*##'), 2),
|
||||
1,
|
||||
GETDATE()
|
||||
);
|
||||
END
|
||||
|
||||
-- =========================
|
||||
-- CRIAR PERFIL ADMIN
|
||||
-- =========================
|
||||
IF NOT EXISTS (SELECT 1 FROM Perfis WHERE Nome = 'Administrador' AND EmpresaId = @EmpresaId)
|
||||
BEGIN
|
||||
INSERT INTO Perfis (
|
||||
EmpresaId, Nome, Descricao, Ativo
|
||||
)
|
||||
VALUES (
|
||||
@EmpresaId,
|
||||
'Administrador',
|
||||
'Acesso total ao sistema',
|
||||
1
|
||||
);
|
||||
END
|
||||
|
||||
-- =========================
|
||||
-- PEGAR IDS
|
||||
-- =========================
|
||||
DECLARE @UsuarioId INT;
|
||||
DECLARE @PerfilId INT;
|
||||
|
||||
SELECT @UsuarioId = Id FROM Usuarios WHERE Usuario = 'admin' AND EmpresaId = @EmpresaId;
|
||||
SELECT @PerfilId = Id FROM Perfis WHERE Nome = 'Administrador' AND EmpresaId = @EmpresaId;
|
||||
|
||||
-- =========================
|
||||
-- VINCULAR USUARIO AO PERFIL
|
||||
-- =========================
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM UsuarioPerfis
|
||||
WHERE UsuarioId = @UsuarioId AND PerfilId = @PerfilId
|
||||
)
|
||||
BEGIN
|
||||
INSERT INTO UsuarioPerfis (UsuarioId, PerfilId)
|
||||
VALUES (@UsuarioId, @PerfilId);
|
||||
END
|
||||
|
||||
-- =========================
|
||||
-- DAR TODAS PERMISSÕES
|
||||
-- =========================
|
||||
INSERT INTO PerfilPermissoes (PerfilId, PermissaoId)
|
||||
SELECT
|
||||
@PerfilId,
|
||||
Id
|
||||
FROM Permissoes
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM PerfilPermissoes
|
||||
WHERE PerfilId = @PerfilId AND PermissaoId = Permissoes.Id
|
||||
);
|
||||
674
ArquivosAuxiliares/Database.sql
Normal file
674
ArquivosAuxiliares/Database.sql
Normal file
@ -0,0 +1,674 @@
|
||||
-- ================================
|
||||
-- CRIAR DATABASE
|
||||
-- ================================
|
||||
IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = 'LevelOS')
|
||||
BEGIN
|
||||
CREATE DATABASE LevelOS;
|
||||
END
|
||||
GO
|
||||
|
||||
USE LevelOS;
|
||||
GO
|
||||
|
||||
-- ================================
|
||||
-- TABELA EMPRESA
|
||||
-- ================================
|
||||
CREATE TABLE Empresa (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
|
||||
-- Dados básicos
|
||||
Nome VARCHAR(255) NOT NULL,
|
||||
CNPJ VARCHAR(20) NOT NULL UNIQUE,
|
||||
TipoEmpresa VARCHAR(20) NOT NULL,
|
||||
RegimeTributario VARCHAR(30) NOT NULL,
|
||||
CNAE VARCHAR(20) NOT NULL,
|
||||
|
||||
-- Endereço
|
||||
Cep VARCHAR(15) NOT NULL,
|
||||
Endereco VARCHAR(255) NOT NULL,
|
||||
Numero INT NOT NULL,
|
||||
Complemento VARCHAR(255),
|
||||
Bairro VARCHAR(255) NOT NULL,
|
||||
Cidade VARCHAR(255) NOT NULL,
|
||||
UF CHAR(2) NOT NULL,
|
||||
Pais VARCHAR(50),
|
||||
|
||||
-- Contatos
|
||||
Telefone1 VARCHAR(20),
|
||||
Telefone2 VARCHAR(20),
|
||||
Celular VARCHAR(20),
|
||||
Whatsapp VARCHAR(20),
|
||||
Email VARCHAR(150) NOT NULL,
|
||||
Site VARCHAR(255),
|
||||
|
||||
-- Fiscal
|
||||
InscricaoEstadual VARCHAR(20) UNIQUE,
|
||||
InscricaoMunicipal VARCHAR(20) UNIQUE,
|
||||
|
||||
-- Contador
|
||||
CNPJCPF_Contador VARCHAR(20),
|
||||
Nome_Contador VARCHAR(255),
|
||||
|
||||
-- Sistema
|
||||
TextoParaRecibo VARCHAR(MAX),
|
||||
|
||||
-- Controle
|
||||
Ativo BIT NOT NULL DEFAULT 1,
|
||||
CriadoEm DATETIME DEFAULT GETDATE(),
|
||||
AtualizadoEm DATETIME DEFAULT GETDATE()
|
||||
);
|
||||
GO
|
||||
|
||||
-- ================================
|
||||
-- CONFIGURAÇÕES
|
||||
-- ================================
|
||||
CREATE TABLE Empresa_config (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
EmpresaId INT NOT NULL,
|
||||
|
||||
-- Aparência
|
||||
NomeSistema VARCHAR(255),
|
||||
CorPrimaria VARCHAR(20),
|
||||
CorSecundaria VARCHAR(20),
|
||||
Logo VARCHAR(255),
|
||||
Favicon VARCHAR(255),
|
||||
|
||||
-- OS
|
||||
ExibirCPFCliente BIT DEFAULT 1,
|
||||
ExibirTelefoneCliente BIT DEFAULT 1,
|
||||
ExibirGarantia BIT DEFAULT 1,
|
||||
DiasGarantiaPadrao INT DEFAULT 90,
|
||||
|
||||
-- Financeiro
|
||||
GerarReciboAutomatico BIT DEFAULT 1,
|
||||
ExibirValoresOS BIT DEFAULT 1,
|
||||
|
||||
-- Comunicação
|
||||
EnviarEmailAutomatico BIT DEFAULT 0,
|
||||
EnviarWhatsappAutomatico BIT DEFAULT 0,
|
||||
|
||||
-- Sistema
|
||||
ModoEscuro BIT DEFAULT 0,
|
||||
PermitirEdicaoOSFinalizada BIT DEFAULT 0,
|
||||
|
||||
-- Auditoria
|
||||
CriadoEm DATETIME DEFAULT GETDATE(),
|
||||
AtualizadoEm DATETIME DEFAULT GETDATE(),
|
||||
|
||||
CONSTRAINT FK_ConfigEmpresa
|
||||
FOREIGN KEY (EmpresaId) REFERENCES Empresa(Id) ON DELETE CASCADE,
|
||||
|
||||
CONSTRAINT UQ_ConfigEmpresa UNIQUE (EmpresaId)
|
||||
);
|
||||
GO
|
||||
|
||||
-- ================================
|
||||
-- FUNCIONÁRIOS
|
||||
-- ================================
|
||||
CREATE TABLE Funcionarios (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
EmpresaId INT NOT NULL,
|
||||
|
||||
-- Dados pessoais
|
||||
Nome VARCHAR(255) NOT NULL,
|
||||
CPF VARCHAR(14),
|
||||
DataNascimento DATE,
|
||||
|
||||
-- Contato
|
||||
Telefone VARCHAR(20),
|
||||
Celular VARCHAR(20),
|
||||
Email VARCHAR(150) NOT NULL,
|
||||
|
||||
-- Login
|
||||
Usuario VARCHAR(50) NOT NULL,
|
||||
SenhaHash VARCHAR(255) NOT NULL,
|
||||
|
||||
-- Permissão
|
||||
TipoConta VARCHAR(20) NOT NULL DEFAULT 'Atendente',
|
||||
|
||||
-- Controle
|
||||
Ativo BIT NOT NULL DEFAULT 1,
|
||||
UltimoLogin DATETIME,
|
||||
|
||||
-- Auditoria
|
||||
CriadoEm DATETIME DEFAULT GETDATE(),
|
||||
AtualizadoEm DATETIME DEFAULT GETDATE(),
|
||||
|
||||
-- Constraints
|
||||
CONSTRAINT FK_FuncionarioEmpresa
|
||||
FOREIGN KEY (EmpresaId) REFERENCES Empresa(Id) ON DELETE CASCADE,
|
||||
|
||||
CONSTRAINT UQ_LoginEmpresa UNIQUE (EmpresaId, Usuario)
|
||||
);
|
||||
GO
|
||||
-- ================================
|
||||
-- FORNECEDORES
|
||||
-- ================================
|
||||
|
||||
CREATE TABLE Fornecedores (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
EmpresaId INT NOT NULL,
|
||||
|
||||
-- Dados básicos
|
||||
Nome VARCHAR(255) NOT NULL,
|
||||
TipoPessoa VARCHAR(2) NOT NULL, -- PF ou PJ
|
||||
Documento VARCHAR(20) NOT NULL, -- CPF ou CNPJ
|
||||
|
||||
-- Contato
|
||||
Telefone VARCHAR(20),
|
||||
Celular VARCHAR(20),
|
||||
Whatsapp VARCHAR(20),
|
||||
Email VARCHAR(150),
|
||||
|
||||
-- Endereço
|
||||
Cep VARCHAR(15),
|
||||
Endereco VARCHAR(255),
|
||||
Numero INT,
|
||||
Complemento VARCHAR(255),
|
||||
Bairro VARCHAR(255),
|
||||
Cidade VARCHAR(255),
|
||||
UF CHAR(2),
|
||||
|
||||
-- Dados adicionais
|
||||
NomeFantasia VARCHAR(255),
|
||||
InscricaoEstadual VARCHAR(20),
|
||||
Site VARCHAR(255),
|
||||
Observacoes VARCHAR(MAX),
|
||||
|
||||
-- Controle
|
||||
Ativo BIT NOT NULL DEFAULT 1,
|
||||
|
||||
-- Auditoria
|
||||
CriadoEm DATETIME DEFAULT GETDATE(),
|
||||
AtualizadoEm DATETIME DEFAULT GETDATE(),
|
||||
|
||||
-- Relacionamento
|
||||
CONSTRAINT FK_FornecedorEmpresa
|
||||
FOREIGN KEY (EmpresaId) REFERENCES Empresa(Id) ON DELETE CASCADE,
|
||||
|
||||
-- Evita duplicidade por empresa
|
||||
CONSTRAINT UQ_Fornecedor_Doc UNIQUE (EmpresaId, Documento)
|
||||
);
|
||||
GO
|
||||
|
||||
-- ================================
|
||||
-- TRANSPORTADORAS
|
||||
-- ================================
|
||||
CREATE TABLE Transportadoras (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
EmpresaId INT NOT NULL,
|
||||
|
||||
-- Dados básicos
|
||||
RazaoSocial VARCHAR(255) NOT NULL,
|
||||
NomeFantasia VARCHAR(255),
|
||||
CNPJ VARCHAR(20) NOT NULL,
|
||||
|
||||
-- Contato
|
||||
Telefone VARCHAR(20),
|
||||
Celular VARCHAR(20),
|
||||
Whatsapp VARCHAR(20),
|
||||
Email VARCHAR(150),
|
||||
|
||||
-- Endereço
|
||||
Cep VARCHAR(15),
|
||||
Endereco VARCHAR(255),
|
||||
Numero INT,
|
||||
Complemento VARCHAR(255),
|
||||
Bairro VARCHAR(255),
|
||||
Cidade VARCHAR(255),
|
||||
UF CHAR(2),
|
||||
|
||||
-- Dados de transporte
|
||||
TipoFrete VARCHAR(20), -- CIF / FOB / etc
|
||||
PrazoEntrega INT, -- em dias
|
||||
ValorFretePadrao DECIMAL(10,2),
|
||||
|
||||
-- Sistema
|
||||
Observacoes VARCHAR(MAX),
|
||||
|
||||
-- Controle
|
||||
Ativo BIT NOT NULL DEFAULT 1,
|
||||
|
||||
-- Auditoria
|
||||
CriadoEm DATETIME DEFAULT GETDATE(),
|
||||
AtualizadoEm DATETIME DEFAULT GETDATE(),
|
||||
|
||||
-- Relacionamento
|
||||
CONSTRAINT FK_TransportadoraEmpresa
|
||||
FOREIGN KEY (EmpresaId) REFERENCES Empresa(Id) ON DELETE CASCADE,
|
||||
|
||||
-- Evita duplicidade
|
||||
CONSTRAINT UQ_Transportadora_CNPJ UNIQUE (EmpresaId, CNPJ)
|
||||
);
|
||||
GO
|
||||
-- ================================
|
||||
-- CLIENTES
|
||||
-- ================================
|
||||
CREATE TABLE Clientes (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
EmpresaId INT NOT NULL,
|
||||
|
||||
-- Dados principais
|
||||
Nome VARCHAR(255) NOT NULL,
|
||||
NomeFantasia VARCHAR(255),
|
||||
TipoPessoa VARCHAR(2) NOT NULL, -- PF / PJ
|
||||
Documento VARCHAR(20) NOT NULL, -- CPF/CNPJ
|
||||
RG VARCHAR(20),
|
||||
InscricaoMunicipal VARCHAR(20),
|
||||
DataNascimento DATE,
|
||||
|
||||
-- Contato
|
||||
Contato VARCHAR(255),
|
||||
Telefone1 VARCHAR(20),
|
||||
Telefone2 VARCHAR(20),
|
||||
Celular VARCHAR(20),
|
||||
Whatsapp VARCHAR(20),
|
||||
Email VARCHAR(150),
|
||||
EmailNFe VARCHAR(150),
|
||||
Site VARCHAR(255),
|
||||
|
||||
-- Classificação
|
||||
Grupo VARCHAR(100),
|
||||
|
||||
-- Endereço
|
||||
Cep VARCHAR(15),
|
||||
Endereco VARCHAR(255),
|
||||
Numero INT,
|
||||
Complemento VARCHAR(255),
|
||||
Bairro VARCHAR(255),
|
||||
Cidade VARCHAR(255),
|
||||
UF CHAR(2),
|
||||
Pais VARCHAR(50),
|
||||
|
||||
-- Financeiro
|
||||
LimiteCredito DECIMAL(10,2) DEFAULT 0,
|
||||
Bloqueado BIT DEFAULT 0,
|
||||
ObservacoesCobranca VARCHAR(MAX),
|
||||
|
||||
-- Vendas / OS
|
||||
VendedorPadraoId INT NULL,
|
||||
TipoConsumidor VARCHAR(50), -- Consumidor final, revenda etc
|
||||
|
||||
-- Sistema
|
||||
Observacoes VARCHAR(MAX),
|
||||
|
||||
-- Extras (campos custom)
|
||||
CampoExtra1 VARCHAR(255),
|
||||
CampoExtra2 VARCHAR(255),
|
||||
CampoExtra3 VARCHAR(255),
|
||||
|
||||
-- Carteiras virtuais
|
||||
Bitcoin VARCHAR(255),
|
||||
Ethereum VARCHAR(255),
|
||||
Litecoin VARCHAR(255),
|
||||
|
||||
-- Controle
|
||||
Ativo BIT NOT NULL DEFAULT 1,
|
||||
UltimaCompra DATETIME,
|
||||
|
||||
-- Auditoria
|
||||
CriadoEm DATETIME DEFAULT GETDATE(),
|
||||
AtualizadoEm DATETIME DEFAULT GETDATE(),
|
||||
|
||||
-- Relacionamento
|
||||
CONSTRAINT FK_ClienteEmpresa
|
||||
FOREIGN KEY (EmpresaId) REFERENCES Empresa(Id) ON DELETE CASCADE,
|
||||
|
||||
-- Evita duplicidade
|
||||
CONSTRAINT UQ_Cliente_Doc UNIQUE (EmpresaId, Documento)
|
||||
);
|
||||
GO
|
||||
|
||||
-- ================================
|
||||
-- SERVIÇOS
|
||||
-- ================================
|
||||
CREATE TABLE Servicos (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
EmpresaId INT NOT NULL,
|
||||
|
||||
-- Dados básicos
|
||||
Nome VARCHAR(255) NOT NULL,
|
||||
Descricao VARCHAR(MAX),
|
||||
|
||||
-- Valores
|
||||
ValorPadrao DECIMAL(10,2) NOT NULL,
|
||||
Custo DECIMAL(10,2),
|
||||
|
||||
-- Comissão
|
||||
TipoComissao VARCHAR(10) NOT NULL DEFAULT 'Percentual', -- Percentual ou Fixo
|
||||
ValorComissao DECIMAL(10,2) NOT NULL DEFAULT 0,
|
||||
|
||||
-- Tempo
|
||||
TempoEstimado INT, -- em minutos
|
||||
|
||||
-- Controle
|
||||
Ativo BIT NOT NULL DEFAULT 1,
|
||||
|
||||
-- Auditoria
|
||||
CriadoEm DATETIME DEFAULT GETDATE(),
|
||||
AtualizadoEm DATETIME DEFAULT GETDATE(),
|
||||
|
||||
-- Relacionamento
|
||||
CONSTRAINT FK_ServicoEmpresa
|
||||
FOREIGN KEY (EmpresaId) REFERENCES Empresa(Id) ON DELETE CASCADE
|
||||
);
|
||||
GO
|
||||
-- ================================
|
||||
-- Situação OS
|
||||
-- ================================
|
||||
CREATE TABLE SituacoesOS (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
EmpresaId INT NOT NULL,
|
||||
|
||||
-- Identificação
|
||||
Descricao VARCHAR(255) NOT NULL,
|
||||
|
||||
-- Classificação (os 3 grupos da tela)
|
||||
Tipo VARCHAR(20) NOT NULL,
|
||||
-- Entrada | Oficina | Saida
|
||||
|
||||
-- Regras da OS
|
||||
ConsideraAberta BIT NOT NULL DEFAULT 1,
|
||||
ConsideraFechada BIT NOT NULL DEFAULT 0,
|
||||
MarcaComoPronto BIT NOT NULL DEFAULT 0,
|
||||
|
||||
-- Aparência (igual na tela)
|
||||
CorFundo VARCHAR(20),
|
||||
CorFonte VARCHAR(20),
|
||||
|
||||
-- Financeiro (opcional)
|
||||
PlanoContasId INT NULL,
|
||||
|
||||
-- Controle
|
||||
Ordem INT DEFAULT 0, -- ordem de exibição
|
||||
Ativo BIT NOT NULL DEFAULT 1,
|
||||
|
||||
-- Auditoria
|
||||
CriadoEm DATETIME DEFAULT GETDATE(),
|
||||
AtualizadoEm DATETIME DEFAULT GETDATE(),
|
||||
|
||||
-- Relacionamento
|
||||
CONSTRAINT FK_SituacaoEmpresa
|
||||
FOREIGN KEY (EmpresaId) REFERENCES Empresa(Id) ON DELETE CASCADE
|
||||
);
|
||||
GO
|
||||
-- ================================
|
||||
-- CONTRATOS
|
||||
-- ================================
|
||||
CREATE TABLE Contratos (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
EmpresaId INT NOT NULL,
|
||||
ClienteId INT NOT NULL,
|
||||
|
||||
-- Dados principais
|
||||
Descricao VARCHAR(255),
|
||||
Observacoes VARCHAR(MAX),
|
||||
|
||||
Valor DECIMAL(10,2) NOT NULL,
|
||||
DataInicio DATE,
|
||||
DataValidade DATE,
|
||||
|
||||
-- Controle de franquia (ex: horas inclusas)
|
||||
FranquiaTempo INT, -- minutos ou horas (você define padrão)
|
||||
|
||||
-- Controle
|
||||
Ativo BIT NOT NULL DEFAULT 1,
|
||||
|
||||
-- Auditoria
|
||||
CriadoEm DATETIME DEFAULT GETDATE(),
|
||||
AtualizadoEm DATETIME DEFAULT GETDATE(),
|
||||
|
||||
-- Relacionamentos
|
||||
CONSTRAINT FK_ContratoEmpresa
|
||||
FOREIGN KEY (EmpresaId) REFERENCES Empresa(Id) ON DELETE CASCADE,
|
||||
|
||||
CONSTRAINT FK_ContratoCliente
|
||||
FOREIGN KEY (ClienteId) REFERENCES Clientes(Id)
|
||||
);
|
||||
GO
|
||||
-- ================================
|
||||
-- CONTRATOS - EQUIPAMENTOS
|
||||
-- ================================
|
||||
CREATE TABLE ContratoEquipamentos (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
ContratoId INT NOT NULL,
|
||||
|
||||
-- Dados do equipamento
|
||||
Modelo VARCHAR(255),
|
||||
Marca VARCHAR(255),
|
||||
Operadora VARCHAR(100),
|
||||
Serial VARCHAR(100),
|
||||
NumeroPatrimonio VARCHAR(100),
|
||||
|
||||
Observacoes VARCHAR(MAX),
|
||||
|
||||
-- Relacionamento
|
||||
CONSTRAINT FK_ContratoEquipamento
|
||||
FOREIGN KEY (ContratoId) REFERENCES Contratos(Id) ON DELETE CASCADE
|
||||
);
|
||||
GO
|
||||
-- ================================
|
||||
-- PLANO DE CONTAS
|
||||
-- ================================
|
||||
CREATE TABLE PlanoDeContas (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
EmpresaId INT NOT NULL,
|
||||
|
||||
-- Hierarquia
|
||||
ContaPaiId INT NULL,
|
||||
|
||||
-- Identificação
|
||||
Nome VARCHAR(255) NOT NULL,
|
||||
Codigo VARCHAR(50), -- Ex: 1.01.02
|
||||
Tipo VARCHAR(20) NOT NULL, -- Receita / Despesa
|
||||
|
||||
-- Controle
|
||||
AceitaLancamento BIT NOT NULL DEFAULT 1, -- se pode lançar direto
|
||||
Ativo BIT NOT NULL DEFAULT 1,
|
||||
|
||||
-- Auditoria
|
||||
CriadoEm DATETIME DEFAULT GETDATE(),
|
||||
AtualizadoEm DATETIME DEFAULT GETDATE(),
|
||||
|
||||
-- Relacionamentos
|
||||
CONSTRAINT FK_PlanoContaEmpresa
|
||||
FOREIGN KEY (EmpresaId) REFERENCES Empresa(Id) ON DELETE CASCADE,
|
||||
|
||||
CONSTRAINT FK_PlanoContaPai
|
||||
FOREIGN KEY (ContaPaiId) REFERENCES PlanoDeContas(Id)
|
||||
);
|
||||
GO
|
||||
-- ================================
|
||||
-- CONTAS A PAGAR
|
||||
-- ================================
|
||||
CREATE TABLE ContasReceber (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
EmpresaId INT NOT NULL,
|
||||
ClienteId INT NOT NULL,
|
||||
|
||||
-- Classificação
|
||||
PlanoContaId INT NOT NULL,
|
||||
|
||||
-- Origem (contrato, venda futura, etc)
|
||||
ContratoId INT NULL,
|
||||
|
||||
-- Dados financeiros
|
||||
Descricao VARCHAR(255),
|
||||
Valor DECIMAL(10,2) NOT NULL,
|
||||
DataEmissao DATE,
|
||||
DataVencimento DATE NOT NULL,
|
||||
DataPagamento DATE,
|
||||
|
||||
-- Controle
|
||||
Status VARCHAR(20) NOT NULL DEFAULT 'Pendente',
|
||||
-- Pendente / Pago / Cancelado / Atrasado
|
||||
|
||||
ValorPago DECIMAL(10,2),
|
||||
Juros DECIMAL(10,2) DEFAULT 0,
|
||||
Multa DECIMAL(10,2) DEFAULT 0,
|
||||
Desconto DECIMAL(10,2) DEFAULT 0,
|
||||
|
||||
-- Observações
|
||||
Observacoes VARCHAR(MAX),
|
||||
|
||||
-- Controle sistema
|
||||
Ativo BIT NOT NULL DEFAULT 1,
|
||||
|
||||
-- Auditoria
|
||||
CriadoEm DATETIME DEFAULT GETDATE(),
|
||||
AtualizadoEm DATETIME DEFAULT GETDATE(),
|
||||
|
||||
-- Relacionamentos
|
||||
CONSTRAINT FK_ReceberEmpresa
|
||||
FOREIGN KEY (EmpresaId) REFERENCES Empresa(Id) ON DELETE CASCADE,
|
||||
|
||||
CONSTRAINT FK_ReceberCliente
|
||||
FOREIGN KEY (ClienteId) REFERENCES Clientes(Id),
|
||||
|
||||
CONSTRAINT FK_ReceberPlano
|
||||
FOREIGN KEY (PlanoContaId) REFERENCES PlanoDeContas(Id),
|
||||
|
||||
CONSTRAINT FK_ReceberContrato
|
||||
FOREIGN KEY (ContratoId) REFERENCES Contratos(Id)
|
||||
);
|
||||
GO
|
||||
-- ================================
|
||||
-- CONTAS A PAGAR
|
||||
-- ================================
|
||||
CREATE TABLE ContasPagar (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
EmpresaId INT NOT NULL,
|
||||
FornecedorId INT NOT NULL,
|
||||
|
||||
-- Classificação
|
||||
PlanoContaId INT NOT NULL,
|
||||
|
||||
-- Dados financeiros
|
||||
Descricao VARCHAR(255),
|
||||
Valor DECIMAL(10,2) NOT NULL,
|
||||
DataEmissao DATE,
|
||||
DataVencimento DATE NOT NULL,
|
||||
DataPagamento DATE,
|
||||
|
||||
-- Controle
|
||||
Status VARCHAR(20) NOT NULL DEFAULT 'Pendente',
|
||||
|
||||
ValorPago DECIMAL(10,2),
|
||||
Juros DECIMAL(10,2) DEFAULT 0,
|
||||
Multa DECIMAL(10,2) DEFAULT 0,
|
||||
Desconto DECIMAL(10,2) DEFAULT 0,
|
||||
|
||||
-- Observações
|
||||
Observacoes VARCHAR(MAX),
|
||||
|
||||
-- Controle sistema
|
||||
Ativo BIT NOT NULL DEFAULT 1,
|
||||
|
||||
-- Auditoria
|
||||
CriadoEm DATETIME DEFAULT GETDATE(),
|
||||
AtualizadoEm DATETIME DEFAULT GETDATE(),
|
||||
|
||||
-- Relacionamentos
|
||||
CONSTRAINT FK_PagarEmpresa
|
||||
FOREIGN KEY (EmpresaId) REFERENCES Empresa(Id) ON DELETE CASCADE,
|
||||
|
||||
CONSTRAINT FK_PagarFornecedor
|
||||
FOREIGN KEY (FornecedorId) REFERENCES Fornecedores(Id),
|
||||
|
||||
CONSTRAINT FK_PagarPlano
|
||||
FOREIGN KEY (PlanoContaId) REFERENCES PlanoDeContas(Id)
|
||||
);
|
||||
GO
|
||||
|
||||
-- ================================
|
||||
-- USUÁRIOS DO SISTEMA
|
||||
-- ================================
|
||||
CREATE TABLE Usuarios (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
EmpresaId INT NOT NULL,
|
||||
|
||||
Nome VARCHAR(255) NOT NULL,
|
||||
Email VARCHAR(150) NOT NULL,
|
||||
Usuario VARCHAR(50) NOT NULL,
|
||||
SenhaHash VARCHAR(255) NOT NULL,
|
||||
|
||||
-- Controle
|
||||
Ativo BIT NOT NULL DEFAULT 1,
|
||||
UltimoLogin DATETIME,
|
||||
|
||||
-- Auditoria
|
||||
CriadoEm DATETIME DEFAULT GETDATE(),
|
||||
AtualizadoEm DATETIME DEFAULT GETDATE(),
|
||||
|
||||
-- Relacionamento
|
||||
CONSTRAINT FK_UsuarioEmpresa
|
||||
FOREIGN KEY (EmpresaId) REFERENCES Empresa(Id) ON DELETE CASCADE,
|
||||
|
||||
-- Evita login duplicado por empresa
|
||||
CONSTRAINT UQ_Usuario_Login UNIQUE (EmpresaId, Usuario)
|
||||
);
|
||||
GO
|
||||
-- ================================
|
||||
-- PERFIS DE USUÁRIO
|
||||
-- ================================
|
||||
CREATE TABLE Perfis (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
EmpresaId INT NOT NULL,
|
||||
|
||||
Nome VARCHAR(100) NOT NULL, -- Admin, Técnico, etc
|
||||
Descricao VARCHAR(255),
|
||||
|
||||
Ativo BIT NOT NULL DEFAULT 1,
|
||||
|
||||
CONSTRAINT FK_PerfilEmpresa
|
||||
FOREIGN KEY (EmpresaId) REFERENCES Empresa(Id) ON DELETE CASCADE
|
||||
);
|
||||
GO
|
||||
-- ================================
|
||||
-- PERMISSÕES DE USUÁRIO
|
||||
-- ================================
|
||||
CREATE TABLE Permissoes (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
|
||||
Nome VARCHAR(100) NOT NULL, -- Ex: CLIENTE_CADASTRAR
|
||||
Descricao VARCHAR(255)
|
||||
);
|
||||
GO
|
||||
-- ================================
|
||||
-- PERFIL - PERMISSÕES
|
||||
-- ================================
|
||||
CREATE TABLE PerfilPermissoes (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
PerfilId INT NOT NULL,
|
||||
PermissaoId INT NOT NULL,
|
||||
|
||||
CONSTRAINT FK_PerfilPermissao_Perfil
|
||||
FOREIGN KEY (PerfilId) REFERENCES Perfis(Id) ON DELETE CASCADE,
|
||||
|
||||
CONSTRAINT FK_PerfilPermissao_Permissao
|
||||
FOREIGN KEY (PermissaoId) REFERENCES Permissoes(Id) ON DELETE CASCADE,
|
||||
|
||||
CONSTRAINT UQ_PerfilPermissao UNIQUE (PerfilId, PermissaoId)
|
||||
);
|
||||
GO
|
||||
-- ================================
|
||||
-- USUÁRIO - PERFIL
|
||||
-- ================================
|
||||
CREATE TABLE UsuarioPerfis (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
UsuarioId INT NOT NULL,
|
||||
PerfilId INT NOT NULL,
|
||||
|
||||
CONSTRAINT FK_UsuarioPerfil_Usuario
|
||||
FOREIGN KEY (UsuarioId)
|
||||
REFERENCES Usuarios(Id)
|
||||
ON DELETE CASCADE,
|
||||
|
||||
CONSTRAINT FK_UsuarioPerfil_Perfil
|
||||
FOREIGN KEY (PerfilId)
|
||||
REFERENCES Perfis(Id)
|
||||
ON DELETE NO ACTION,
|
||||
|
||||
CONSTRAINT UQ_UsuarioPerfil UNIQUE (UsuarioId, PerfilId)
|
||||
);
|
||||
GO
|
||||
95
ArquivosAuxiliares/ExemploUSO.txt
Normal file
95
ArquivosAuxiliares/ExemploUSO.txt
Normal file
@ -0,0 +1,95 @@
|
||||
using DALL;
|
||||
using System.Data;
|
||||
|
||||
// =============================================
|
||||
// Configuração da connection string
|
||||
// =============================================
|
||||
var connectionString = "Server=206.42.13.180;Database=Levelcode-LevelOS;User Id=sa;Password=suasenha;TrustServerCertificate=True;";
|
||||
|
||||
var backupService = new DALLBackupService(connectionString);
|
||||
|
||||
// =============================================
|
||||
// Backup FULL
|
||||
// =============================================
|
||||
var resultadoFull = backupService.ExecutarBackupFull();
|
||||
|
||||
if (resultadoFull.Sucesso)
|
||||
Console.WriteLine($"✅ Backup FULL concluído em {resultadoFull.Duracao.TotalSeconds:F1}s");
|
||||
else
|
||||
Console.WriteLine($"❌ Erro no Backup FULL: {resultadoFull.Erro}");
|
||||
|
||||
// =============================================
|
||||
// Backup DIFERENCIAL
|
||||
// =============================================
|
||||
var resultadoDiff = backupService.ExecutarBackupDiferencial();
|
||||
|
||||
if (resultadoDiff.Sucesso)
|
||||
Console.WriteLine($"✅ Backup DIFERENCIAL concluído em {resultadoDiff.Duracao.TotalSeconds:F1}s");
|
||||
else
|
||||
Console.WriteLine($"❌ Erro no Backup DIFERENCIAL: {resultadoDiff.Erro}");
|
||||
|
||||
// =============================================
|
||||
// Limpeza de backups antigos
|
||||
// =============================================
|
||||
var resultadoLimpeza = backupService.ExecutarLimpeza();
|
||||
|
||||
if (resultadoLimpeza.Sucesso)
|
||||
Console.WriteLine($"✅ Limpeza concluída em {resultadoLimpeza.Duracao.TotalSeconds:F1}s");
|
||||
else
|
||||
Console.WriteLine($"❌ Erro na Limpeza: {resultadoLimpeza.Erro}");
|
||||
|
||||
// =============================================
|
||||
// Listar histórico de backups
|
||||
// =============================================
|
||||
var historico = backupService.ListarHistoricoBackups();
|
||||
|
||||
Console.WriteLine("\n📋 Histórico de Backups:");
|
||||
Console.WriteLine($"{"Tipo",-15} {"TamanhoMB",-12} {"Inicio",-22} {"Arquivo"}");
|
||||
Console.WriteLine(new string('-', 90));
|
||||
|
||||
foreach (DataRow row in historico.Rows)
|
||||
{
|
||||
Console.WriteLine($"{row["Tipo"],-15} {row["TamanhoMB"],-12} {row["Inicio"],-22} {row["Arquivo"]}");
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// Restauração FULL + DIFERENCIAL
|
||||
// =============================================
|
||||
|
||||
// Pega o arquivo mais recente do histórico automaticamente
|
||||
string arquivoFull = "";
|
||||
string arquivoDiff = "";
|
||||
|
||||
foreach (DataRow row in historico.Rows)
|
||||
{
|
||||
if (row["Tipo"].ToString() == "FULL" && string.IsNullOrEmpty(arquivoFull))
|
||||
arquivoFull = row["Arquivo"].ToString()!;
|
||||
|
||||
if (row["Tipo"].ToString() == "DIFERENCIAL" && string.IsNullOrEmpty(arquivoDiff))
|
||||
arquivoDiff = row["Arquivo"].ToString()!;
|
||||
|
||||
if (!string.IsNullOrEmpty(arquivoFull) && !string.IsNullOrEmpty(arquivoDiff))
|
||||
break;
|
||||
}
|
||||
|
||||
// Restaura FULL
|
||||
Console.WriteLine($"\n🔁 Restaurando FULL: {arquivoFull}");
|
||||
var r1 = backupService.RestaurarBackup(arquivoFull, TipoRestauracao.Full);
|
||||
|
||||
if (r1.Sucesso)
|
||||
{
|
||||
Console.WriteLine($"✅ FULL restaurado em {r1.Duracao.TotalSeconds:F1}s");
|
||||
|
||||
// Aplica DIFERENCIAL após o FULL
|
||||
Console.WriteLine($"🔁 Aplicando DIFERENCIAL: {arquivoDiff}");
|
||||
var r2 = backupService.RestaurarBackup(arquivoDiff, TipoRestauracao.Diferencial);
|
||||
|
||||
if (r2.Sucesso)
|
||||
Console.WriteLine($"✅ DIFERENCIAL aplicado em {r2.Duracao.TotalSeconds:F1}s — Banco online!");
|
||||
else
|
||||
Console.WriteLine($"❌ Erro no DIFERENCIAL: {r2.Erro}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"❌ Erro no FULL: {r1.Erro}");
|
||||
}
|
||||
157
ArquivosAuxiliares/InsertsLotes.sql
Normal file
157
ArquivosAuxiliares/InsertsLotes.sql
Normal file
@ -0,0 +1,157 @@
|
||||
INSERT INTO Bancos (NUMERO, NOME) VALUES
|
||||
(1,'Banco do Brasil S/A'),
|
||||
(2,'Banco Central do Brasil'),
|
||||
(3,'Banco da Amazonia S/A'),
|
||||
(4,'Banco do Nordeste do Brasil S/A'),
|
||||
(8,'Banco Santander Meridional S/A'),
|
||||
(21,'BANESTES S/A - Banco Est.Esp.Santo'),
|
||||
(22,'CREDIREAL'),
|
||||
(24,'Banco de Pernambuco S/A - BANDEPE'),
|
||||
(25,'Banco Alfa S/A'),
|
||||
(27,'Banco Estado Santa Catarina S/A'),
|
||||
(28,'BANEB'),
|
||||
(29,'Banco BANERJ S/A'),
|
||||
(30,'PARAIBAN - Banco da Paraiba S/A'),
|
||||
(31,'Banco BEG S/A'),
|
||||
(33,'SANTANDER'),
|
||||
(34,'Banco BEA S/A'),
|
||||
(35,'Banco do Estado do Ceara S/A - BEC'),
|
||||
(36,'Banco do Estado do Maranhao S/A'),
|
||||
(37,'Banco do Estado do Para S/A'),
|
||||
(38,'Banco BANESTADO S/A'),
|
||||
(39,'Banco do Estado do Piaui S/A'),
|
||||
(40,'Banco Cargill S/A'),
|
||||
(41,'Banco Est. Rio Grande do Sul S/A'),
|
||||
(44,'Banco BVA S/A'),
|
||||
(45,'Banco OPPORTUNITY S/A'),
|
||||
(47,'Banco Est. de Sergipe S/A'),
|
||||
(48,'Banco BENGE S/A'),
|
||||
(63,'IBIBANK S/A - Banco Multiplo'),
|
||||
(65,'LEMON BANK Banco Multiplo S/A'),
|
||||
(66,'Banco MORGAN S. D. Witter S/A'),
|
||||
(67,'Banco BANEB S/A'),
|
||||
(68,'Banco BEA S/A'),
|
||||
(70,'BRB-Banco de Brasilia S/A'),
|
||||
(89,'CREDISAN'),
|
||||
(104,'Caixa Economica Federal'),
|
||||
(106,'Banco Itabanco S/A'),
|
||||
(107,'Banco BBM S/A'),
|
||||
(109,'CREDIBANCO S/A'),
|
||||
(116,'Banco BNL do Brasil S/A'),
|
||||
(148,'Bank Of America Brasil S/A'),
|
||||
(151,'Banco Nossa Caixa S/A'),
|
||||
(175,'Banco Finasa S/A'),
|
||||
(184,'Banco BBA Creditanstalt S/A'),
|
||||
(204,'BCO Inter American Express S/A'),
|
||||
(208,'Banco Pactual S/A'),
|
||||
(210,'DRESDNER Bank Lateinamerika A.'),
|
||||
(212,'Banco Matone S/A'),
|
||||
(213,'Banco ARBI S/A'),
|
||||
(214,'Banco DIBENS S/A'),
|
||||
(215,'Banco Com e Invest Sudameris'),
|
||||
(216,'Banco Regional MALCON S/A'),
|
||||
(217,'Banco JOHN DEERE S/A'),
|
||||
(218,'Banco Bonsucesso S/A'),
|
||||
(219,'Banco ZOGBI S/A'),
|
||||
(222,'BCO Credit Lyonnais Brasil S/A'),
|
||||
(224,'Banco Fibra S/A'),
|
||||
(225,'Banco Brascan S/A'),
|
||||
(229,'Banco Cruzeiro do Sul S/A'),
|
||||
(230,'Banco Bandeirantes S/A'),
|
||||
(231,'Banco Boavista interatlantico S/A'),
|
||||
(233,'Banco GE Capital S/A'),
|
||||
(237,'Banco Bradesco S/A'),
|
||||
(240,'Banco de Credito Real de M.G. S/A'),
|
||||
(241,'Banco Classico S/A'),
|
||||
(243,'Banco STOCK Maxima S/A'),
|
||||
(244,'Banco Cidade S/A'),
|
||||
(246,'Banco ABC-Brasil S/A'),
|
||||
(247,'UBS WARBURG S/A'),
|
||||
(249,'Banco Investcred UNIBANCO S/A'),
|
||||
(250,'Banco SCHAHIN S/A'),
|
||||
(252,'Banco FININVEST S/A'),
|
||||
(254,'PARANA Banco S/A'),
|
||||
(263,'Banco CACIQUE S/A'),
|
||||
(265,'Banco Fator S/A'),
|
||||
(266,'Banco Cedula S/A'),
|
||||
(275,'Banco ABN AMRO Real S/A'),
|
||||
(291,'Banco de Cred. Nacional S/A'),
|
||||
(294,'BCR'),
|
||||
(300,'Banco de LA Nacion Argentina'),
|
||||
(318,'Banco BMG S/A'),
|
||||
(320,'Banco Ind. e Com. S/A'),
|
||||
(341,'Banco Itau S/A'),
|
||||
(346,'Banco BFB'),
|
||||
(347,'Banco Sudameris Brasil S/A'),
|
||||
(351,'Banco Bozano Simonsen S/A'),
|
||||
(353,'Banco Santander S/A'),
|
||||
(356,'Banco ABN AMRO S/A'),
|
||||
(366,'Banco Societe Generale Bras. S/A'),
|
||||
(370,'Banco Westlb do Brasil S/A'),
|
||||
(376,'Banco CHASE Manhattan S/A'),
|
||||
(389,'Banco Mercantil do Brasil S/A'),
|
||||
(392,'Banco Mercantil de Sao Paulo S/A'),
|
||||
(394,'Banco BMC S/A'),
|
||||
(399,'HSBC Bank Brasil S/A'),
|
||||
(409,'Unibanco Uniao de Bancos Bras. S/A'),
|
||||
(412,'Banco Capital S/A'),
|
||||
(422,'Banco Safra S/A'),
|
||||
(424,'Banco Santander Nordeste S/A'),
|
||||
(453,'Banco Rural S/A'),
|
||||
(456,'Banco de Tokio Mitsubishi BR S/A'),
|
||||
(464,'Banco Sumitomo Mitsui Bras. S/A'),
|
||||
(472,'LLOYDS Bank PLC'),
|
||||
(473,'Banco Financial Portugues S/A'),
|
||||
(477,'Banco Citibank N/A'),
|
||||
(479,'Bankboston Banco Multiplo S/A'),
|
||||
(487,'Deutsche Bank S/A'),
|
||||
(488,'Morgan G. Trust Company of NY'),
|
||||
(492,'ING Bank N.V.'),
|
||||
(493,'Banco Union - Brasil S/A'),
|
||||
(494,'Banco de La Rep. Or.Del Uruguai'),
|
||||
(495,'Banco de La Provinc.Buenos Aires'),
|
||||
(496,'Banco Uno-E Brasil S/A'),
|
||||
(505,'Banco Credit S. F. Boston S/A'),
|
||||
(600,'Banco Luso Brasileiro S/A'),
|
||||
(604,'Banco Industrial Brasileiro S/A'),
|
||||
(610,'Banco VR S/A'),
|
||||
(611,'Banco Paulista S/A'),
|
||||
(612,'Banco Guanabara S/A'),
|
||||
(613,'Banco Pecunia S/A'),
|
||||
(623,'Banco Panamericano S/A'),
|
||||
(626,'Banco FICSA S/A'),
|
||||
(630,'Banco Intercap S/A'),
|
||||
(633,'Banco Rendimento S/A'),
|
||||
(634,'Banco Triangulo S/A'),
|
||||
(637,'Banco SOFISA S/A'),
|
||||
(638,'Banco Prosper S/A'),
|
||||
(641,'Banco Bilbao Vizcaya Argentaria Brasil S/A'),
|
||||
(643,'Banco Pine S/A'),
|
||||
(650,'Banco PEBB S/A'),
|
||||
(652,'Banco Frances e Brasileiro S/A'),
|
||||
(653,'Banco Indusval S/A'),
|
||||
(654,'Banco A. J. RENNER S/A'),
|
||||
(655,'Banco Votorantim S/A'),
|
||||
(702,'Banco Santos S/A'),
|
||||
(707,'Banco Daycoval S/A'),
|
||||
(719,'Banco Banif Primus S/A'),
|
||||
(721,'Banco Credibel S/A'),
|
||||
(733,'Banco das Nacoes S/A'),
|
||||
(734,'Banco Gerdau S/A'),
|
||||
(735,'Banco Pottencial S/A'),
|
||||
(738,'Banco Morada S/A'),
|
||||
(739,'Banco BGN S/A'),
|
||||
(740,'Banco BARCLAYS S/A'),
|
||||
(741,'Banco Ribeirao Preto S/A'),
|
||||
(743,'Banco Emblema S/A'),
|
||||
(744,'Bankboston N.A.'),
|
||||
(745,'Banco Citibank S/A'),
|
||||
(746,'Banco Modal S/A'),
|
||||
(747,'Banco Rabobank INT Brasil S/A'),
|
||||
(748,'Banco Coop. Sic. S/A BANSICREDI'),
|
||||
(749,'BR Banco Mercantil S/A'),
|
||||
(751,'DRESDNER Bank Brasil S/A'),
|
||||
(752,'Banco BNP Paribas Brasil S/A'),
|
||||
(753,'Banco Comercial Uruguai S/A'),
|
||||
(756,'Banco Cooperativo do Brasil S/A'),
|
||||
(757,'Banco KEB do Brasil S/A');
|
||||
44
ArquivosAuxiliares/ProcedureBKP-DIFF_AUTO.sql
Normal file
44
ArquivosAuxiliares/ProcedureBKP-DIFF_AUTO.sql
Normal file
@ -0,0 +1,44 @@
|
||||
USE [msdb]
|
||||
GO
|
||||
|
||||
-- =============================================
|
||||
-- Job: Backup DIFERENCIAL - a cada 6 horas
|
||||
-- =============================================
|
||||
EXEC sp_add_job @job_name = N'Backup DIFERENCIAL - Levelcode-LevelOS';
|
||||
|
||||
EXEC sp_add_jobstep
|
||||
@job_name = N'Backup DIFERENCIAL - Levelcode-LevelOS',
|
||||
@step_name = N'Executar Backup DIFERENCIAL',
|
||||
@command = N'EXEC [Levelcode-LevelOS].[dbo].[sp_BackupDiferencial]',
|
||||
@database_name = N'Levelcode-LevelOS';
|
||||
|
||||
EXEC sp_add_schedule
|
||||
@schedule_name = N'A cada 6 horas',
|
||||
@freq_type = 4, -- diário
|
||||
@freq_interval = 1,
|
||||
@freq_subday_type = 8, -- a cada X horas
|
||||
@freq_subday_interval = 6, -- 6 horas
|
||||
@active_start_time = 080000; -- começa às 08:00
|
||||
|
||||
EXEC sp_attach_schedule
|
||||
@job_name = N'Backup DIFERENCIAL - Levelcode-LevelOS',
|
||||
@schedule_name = N'A cada 6 horas';
|
||||
|
||||
EXEC sp_add_jobserver
|
||||
@job_name = N'Backup DIFERENCIAL - Levelcode-LevelOS';
|
||||
GO
|
||||
|
||||
-- Confirma os jobs criados
|
||||
SELECT
|
||||
j.name AS Job,
|
||||
s.name AS Schedule,
|
||||
s.active_start_time,
|
||||
CASE s.freq_subday_type
|
||||
WHEN 8 THEN CAST(s.freq_subday_interval AS VARCHAR) + 'h em ' + CAST(s.freq_subday_interval AS VARCHAR) + 'h'
|
||||
ELSE 'Diário fixo'
|
||||
END AS Frequencia
|
||||
FROM msdb.dbo.sysjobs j
|
||||
JOIN msdb.dbo.sysjobschedules js ON j.job_id = js.job_id
|
||||
JOIN msdb.dbo.sysschedules s ON js.schedule_id = s.schedule_id
|
||||
WHERE j.name LIKE '%Levelcode%'
|
||||
ORDER BY j.name;
|
||||
25
ArquivosAuxiliares/ProcedureBKP-FULL_AUTO.sql
Normal file
25
ArquivosAuxiliares/ProcedureBKP-FULL_AUTO.sql
Normal file
@ -0,0 +1,25 @@
|
||||
USE [msdb]
|
||||
GO
|
||||
|
||||
-- Job: Backup FULL - toda madrugada às 02:00
|
||||
EXEC sp_add_job @job_name = N'Backup FULL - Levelcode-LevelOS';
|
||||
|
||||
EXEC sp_add_jobstep
|
||||
@job_name = N'Backup FULL - Levelcode-LevelOS',
|
||||
@step_name = N'Executar Backup FULL',
|
||||
@command = N'EXEC [Levelcode-LevelOS].[dbo].[sp_BackupFull]',
|
||||
@database_name = N'Levelcode-LevelOS';
|
||||
|
||||
EXEC sp_add_schedule
|
||||
@schedule_name = N'Diario 02:00',
|
||||
@freq_type = 4, -- diário
|
||||
@freq_interval = 1,
|
||||
@active_start_time = 020000; -- 02:00:00
|
||||
|
||||
EXEC sp_attach_schedule
|
||||
@job_name = N'Backup FULL - Levelcode-LevelOS',
|
||||
@schedule_name = N'Diario 02:00';
|
||||
|
||||
EXEC sp_add_jobserver
|
||||
@job_name = N'Backup FULL - Levelcode-LevelOS';
|
||||
GO
|
||||
61
ArquivosAuxiliares/ProcedureBackups.sql
Normal file
61
ArquivosAuxiliares/ProcedureBackups.sql
Normal file
@ -0,0 +1,61 @@
|
||||
USE [Levelcode-LevelOS]
|
||||
GO
|
||||
|
||||
DROP PROCEDURE IF EXISTS [dbo].[sp_BackupFull]
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[sp_BackupFull]
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
DECLARE @Caminho NVARCHAR(500);
|
||||
|
||||
SET @Caminho = '/var/opt/mssql/backups/Levelcode-LevelOS_FULL_'
|
||||
+ FORMAT(GETDATE(), 'yyyyMMdd_HHmmss') + '.bak';
|
||||
|
||||
BACKUP DATABASE [Levelcode-LevelOS]
|
||||
TO DISK = @Caminho
|
||||
WITH FORMAT,
|
||||
INIT,
|
||||
NAME = 'Backup FULL - Levelcode-LevelOS',
|
||||
STATS = 10;
|
||||
END
|
||||
GO
|
||||
|
||||
-- Confirma criação
|
||||
SELECT name, create_date, modify_date
|
||||
FROM sys.procedures
|
||||
WHERE name = 'sp_BackupFull';
|
||||
|
||||
|
||||
USE [Levelcode-LevelOS]
|
||||
GO
|
||||
|
||||
DROP PROCEDURE IF EXISTS [dbo].[sp_BackupDiferencial]
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[sp_BackupDiferencial]
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
DECLARE @Caminho NVARCHAR(500);
|
||||
|
||||
SET @Caminho = '/var/opt/mssql/backups/Levelcode-LevelOS_DIFF_'
|
||||
+ FORMAT(GETDATE(), 'yyyyMMdd_HHmmss') + '.bak';
|
||||
|
||||
BACKUP DATABASE [Levelcode-LevelOS]
|
||||
TO DISK = @Caminho
|
||||
WITH DIFFERENTIAL,
|
||||
INIT,
|
||||
NAME = 'Backup DIFERENCIAL - Levelcode-LevelOS',
|
||||
STATS = 10;
|
||||
END
|
||||
GO
|
||||
|
||||
-- Confirma ambas criadas
|
||||
SELECT name, create_date, modify_date
|
||||
FROM sys.procedures
|
||||
WHERE name IN ('sp_BackupFull', 'sp_BackupDiferencial')
|
||||
ORDER BY name;
|
||||
128
ArquivosAuxiliares/ProcedureRestaurarBanco.sql
Normal file
128
ArquivosAuxiliares/ProcedureRestaurarBanco.sql
Normal file
@ -0,0 +1,128 @@
|
||||
USE [master]
|
||||
GO
|
||||
|
||||
DROP PROCEDURE IF EXISTS [dbo].[sp_RestaurarBackup]
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[sp_RestaurarBackup]
|
||||
@Arquivo NVARCHAR(500) = NULL,
|
||||
@Tipo CHAR(1) = 'F' -- 'F' = FULL | 'D' = DIFERENCIAL
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
-- =============================================
|
||||
-- Se não informar arquivo, lista os disponíveis
|
||||
-- =============================================
|
||||
IF @Arquivo IS NULL
|
||||
BEGIN
|
||||
PRINT '>>> Backups disponíveis no histórico:';
|
||||
|
||||
SELECT
|
||||
ROW_NUMBER() OVER (ORDER BY bs.backup_finish_date DESC) AS N,
|
||||
CASE bs.type
|
||||
WHEN 'D' THEN 'FULL'
|
||||
WHEN 'I' THEN 'DIFERENCIAL'
|
||||
END AS Tipo,
|
||||
bmf.physical_device_name AS Arquivo,
|
||||
bs.backup_start_date AS Inicio,
|
||||
bs.backup_finish_date AS Fim,
|
||||
CAST(bs.backup_size / 1024.0 / 1024.0 AS DECIMAL(10,2)) AS TamanhoMB
|
||||
FROM msdb.dbo.backupset bs
|
||||
JOIN msdb.dbo.backupmediafamily bmf
|
||||
ON bs.media_set_id = bmf.media_set_id
|
||||
WHERE bs.database_name = 'Levelcode-LevelOS'
|
||||
ORDER BY bs.backup_finish_date DESC;
|
||||
|
||||
PRINT '>>> Copie o caminho do arquivo desejado e execute:';
|
||||
PRINT '>>> EXEC sp_RestaurarBackup @Arquivo = ''caminho_aqui'', @Tipo = ''F''';
|
||||
RETURN;
|
||||
END
|
||||
|
||||
-- =============================================
|
||||
-- Verifica o arquivo com RESTORE HEADERONLY
|
||||
-- =============================================
|
||||
BEGIN TRY
|
||||
RESTORE HEADERONLY FROM DISK = @Arquivo;
|
||||
END TRY
|
||||
BEGIN CATCH
|
||||
RAISERROR('Arquivo não encontrado ou inválido: %s', 16, 1, @Arquivo);
|
||||
RETURN;
|
||||
END CATCH
|
||||
|
||||
-- =============================================
|
||||
-- Coloca o banco em SINGLE_USER
|
||||
-- =============================================
|
||||
PRINT '>>> Preparando banco para restauração...';
|
||||
|
||||
BEGIN TRY
|
||||
ALTER DATABASE [Levelcode-LevelOS]
|
||||
SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
|
||||
END TRY
|
||||
BEGIN CATCH
|
||||
PRINT '>>> Aviso: ' + ERROR_MESSAGE();
|
||||
END CATCH
|
||||
|
||||
-- =============================================
|
||||
-- Restauração FULL
|
||||
-- =============================================
|
||||
IF @Tipo = 'F'
|
||||
BEGIN
|
||||
PRINT '>>> Restaurando FULL: ' + @Arquivo;
|
||||
|
||||
RESTORE DATABASE [Levelcode-LevelOS]
|
||||
FROM DISK = @Arquivo
|
||||
WITH REPLACE,
|
||||
NORECOVERY,
|
||||
STATS = 10;
|
||||
|
||||
ALTER DATABASE [Levelcode-LevelOS] SET MULTI_USER;
|
||||
|
||||
PRINT '>>> FULL restaurado com sucesso!';
|
||||
PRINT '>>> Se tiver diferencial execute: EXEC sp_RestaurarBackup @Arquivo = ''caminho_diff'', @Tipo = ''D''';
|
||||
PRINT '>>> Se não tiver diferencial execute: RESTORE DATABASE [Levelcode-LevelOS] WITH RECOVERY;';
|
||||
END
|
||||
|
||||
-- =============================================
|
||||
-- Restauração DIFERENCIAL
|
||||
-- =============================================
|
||||
IF @Tipo = 'D'
|
||||
BEGIN
|
||||
PRINT '>>> Aplicando DIFERENCIAL: ' + @Arquivo;
|
||||
|
||||
RESTORE DATABASE [Levelcode-LevelOS]
|
||||
FROM DISK = @Arquivo
|
||||
WITH RECOVERY,
|
||||
STATS = 10;
|
||||
|
||||
ALTER DATABASE [Levelcode-LevelOS] SET MULTI_USER;
|
||||
|
||||
PRINT '>>> Banco restaurado e online!';
|
||||
END
|
||||
END
|
||||
GO
|
||||
|
||||
--Como usar --
|
||||
-- 1. Lista os backups disponíveis
|
||||
EXEC [master].[dbo].[sp_RestaurarBackup];
|
||||
|
||||
-- 2. Restaura apenas o FULL (sem diferencial)
|
||||
EXEC [master].[dbo].[sp_RestaurarBackup]
|
||||
@Arquivo = '/var/opt/mssql/backups/Levelcode-LevelOS_FULL_20260413_020000.bak',
|
||||
@Tipo = 'F';
|
||||
|
||||
-- Finaliza o banco após o FULL sem diferencial
|
||||
RESTORE DATABASE [Levelcode-LevelOS] WITH RECOVERY;
|
||||
|
||||
-- 3. Restaura FULL + DIFERENCIAL (sequência completa)
|
||||
EXEC [master].[dbo].[sp_RestaurarBackup]
|
||||
@Arquivo = '/var/opt/mssql/backups/Levelcode-LevelOS_FULL_20260413_020000.bak',
|
||||
@Tipo = 'F';
|
||||
|
||||
EXEC [master].[dbo].[sp_RestaurarBackup]
|
||||
@Arquivo = '/var/opt/mssql/backups/Levelcode-LevelOS_DIFF_20260413_080000.bak',
|
||||
@Tipo = 'D';
|
||||
|
||||
EXEC [master].[dbo].[sp_RestaurarBackup]
|
||||
@Arquivo = '/var/opt/mssql/backups/Levelcode-LevelOS_FULL_20260413_072013.bak',
|
||||
@Tipo = 'F';
|
||||
77
ArquivosAuxiliares/Procedure_LIMPEZA15DIAS.sql
Normal file
77
ArquivosAuxiliares/Procedure_LIMPEZA15DIAS.sql
Normal file
@ -0,0 +1,77 @@
|
||||
USE [Levelcode-LevelOS]
|
||||
GO
|
||||
|
||||
-- =============================================
|
||||
-- Procedure: Limpeza de backups antigos (+15 dias)
|
||||
-- =============================================
|
||||
DROP PROCEDURE IF EXISTS [dbo].[sp_LimpezaBackups]
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[sp_LimpezaBackups]
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
DECLARE @DataCorte DATETIME = DATEADD(DAY, -15, GETDATE());
|
||||
DECLARE @Comando NVARCHAR(500);
|
||||
DECLARE @Arquivo NVARCHAR(500);
|
||||
|
||||
-- Cursor nos backups com mais de 15 dias
|
||||
DECLARE cur CURSOR FOR
|
||||
SELECT DISTINCT bmf.physical_device_name
|
||||
FROM msdb.dbo.backupset bs
|
||||
JOIN msdb.dbo.backupmediafamily bmf
|
||||
ON bs.media_set_id = bmf.media_set_id
|
||||
WHERE bs.database_name = 'Levelcode-LevelOS'
|
||||
AND bs.backup_finish_date < @DataCorte
|
||||
AND bmf.physical_device_name LIKE '/var/opt/mssql/backups/%';
|
||||
|
||||
OPEN cur;
|
||||
FETCH NEXT FROM cur INTO @Arquivo;
|
||||
|
||||
WHILE @@FETCH_STATUS = 0
|
||||
BEGIN
|
||||
-- Deleta o arquivo físico no Linux
|
||||
SET @Comando = 'rm -f ' + @Arquivo;
|
||||
EXEC xp_cmdshell @Comando;
|
||||
|
||||
-- Remove o histórico do msdb
|
||||
PRINT 'Removido: ' + @Arquivo;
|
||||
|
||||
FETCH NEXT FROM cur INTO @Arquivo;
|
||||
END
|
||||
|
||||
CLOSE cur;
|
||||
DEALLOCATE cur;
|
||||
|
||||
-- Limpa o histórico do msdb também
|
||||
EXEC msdb.dbo.sp_delete_backuphistory @oldest_date = @DataCorte;
|
||||
|
||||
PRINT 'Limpeza concluída. Backups anteriores a '
|
||||
+ CONVERT(NVARCHAR(20), @DataCorte, 120) + ' removidos.';
|
||||
END
|
||||
GO
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
USE [Levelcode-LevelOS]
|
||||
GO
|
||||
|
||||
-- =============================================
|
||||
-- Procedure: Limpeza do HISTÓRICO (msdb) +15 dias
|
||||
-- =============================================
|
||||
DROP PROCEDURE IF EXISTS [dbo].[sp_LimpezaBackups]
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[sp_LimpezaBackups]
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
DECLARE @DataCorte DATETIME = DATEADD(DAY, -15, GETDATE());
|
||||
|
||||
-- Limpa apenas o histórico do msdb (não precisa de xp_cmdshell)
|
||||
EXEC msdb.dbo.sp_delete_backuphistory @oldest_date = @DataCorte;
|
||||
|
||||
PRINT 'Histórico de backups anteriores a '
|
||||
+ CONVERT(NVARCHAR(20), @DataCorte, 120) + ' removido do msdb.';
|
||||
END
|
||||
GO
|
||||
32
ArquivosAuxiliares/ScriptLimpezaServidor.sh
Normal file
32
ArquivosAuxiliares/ScriptLimpezaServidor.sh
Normal file
@ -0,0 +1,32 @@
|
||||
# Cria o script de limpeza
|
||||
cat > /var/opt/mssql/backups/limpar_backups.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# Deleta arquivos .bak com mais de 15 dias
|
||||
find /var/opt/mssql/backups/ -name "*.bak" -mtime +15 -delete
|
||||
echo "[$(date)] Limpeza concluída." >> /var/opt/mssql/backups/limpeza.log
|
||||
EOF
|
||||
|
||||
# Dá permissão de execução
|
||||
chmod +x /var/opt/mssql/backups/limpar_backups.sh
|
||||
|
||||
# Agenda no cron todo domingo às 03:00
|
||||
(crontab -l 2>/dev/null; echo "0 3 * * 0 /var/opt/mssql/backups/limpar_backups.sh") | crontab -
|
||||
|
||||
# Confirma o cron
|
||||
crontab -l
|
||||
|
||||
#-------------------------------------------------------------------------------------------------
|
||||
cat > /var/opt/mssql/backups/limpar_backups.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
find /var/opt/mssql/backups/ -name "*.bak" -mtime +15 -delete
|
||||
echo "[$(date)] Limpeza concluída." >> /var/opt/mssql/backups/limpeza.log
|
||||
EOF
|
||||
|
||||
#Dar permissão
|
||||
chmod +x /var/opt/mssql/backups/limpar_backups.sh
|
||||
# Executar script
|
||||
/var/opt/mssql/backups/limpar_backups.sh && cat /var/opt/mssql/backups/limpeza.log
|
||||
# Agendar JOB
|
||||
(crontab -l 2>/dev/null; echo "0 3 * * 0 /var/opt/mssql/backups/limpar_backups.sh") | crontab -
|
||||
# confirmar agendamento
|
||||
crontab -l
|
||||
14
ArquivosAuxiliares/TriggerFuncionarios.sql
Normal file
14
ArquivosAuxiliares/TriggerFuncionarios.sql
Normal file
@ -0,0 +1,14 @@
|
||||
--Gatilhos para a tabela funcionarios--
|
||||
CREATE OR ALTER TRIGGER TR_Funcionarios_GerarCodigo
|
||||
ON Funcionarios
|
||||
AFTER INSERT
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
UPDATE F
|
||||
SET CODIGO = CAST(100 + ((F.ID_FUNCIONARIO - 1) * 100) AS VARCHAR)
|
||||
FROM Funcionarios F
|
||||
INNER JOIN inserted I ON F.ID_FUNCIONARIO = I.ID_FUNCIONARIO;
|
||||
END
|
||||
GO
|
||||
13
ArquivosAuxiliares/Trigger_AgendaCodigoAuto.sql
Normal file
13
ArquivosAuxiliares/Trigger_AgendaCodigoAuto.sql
Normal file
@ -0,0 +1,13 @@
|
||||
CREATE OR ALTER TRIGGER TR_Agenda_GerarCodigo
|
||||
ON Agenda
|
||||
AFTER INSERT
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
UPDATE A
|
||||
SET CODIGO = 'AG' + RIGHT('0000' + CAST(A.ID_AGENDA AS VARCHAR), 4)
|
||||
FROM Agenda A
|
||||
INNER JOIN inserted I ON A.ID_AGENDA = I.ID_AGENDA;
|
||||
END
|
||||
GO
|
||||
151
ControlesCustom.cs
Normal file
151
ControlesCustom.cs
Normal file
@ -0,0 +1,151 @@
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class RoundTextBox : UserControl
|
||||
{
|
||||
private TextBox _textBox = null!;
|
||||
public int Radius { get; set; } = 4;
|
||||
public Color BorderColor { get; set; } = Color.LightGray;
|
||||
public Color FocusColor { get; set; } = Color.Blue;
|
||||
private bool _focused;
|
||||
|
||||
public bool ReadOnly
|
||||
{
|
||||
get => _textBox.ReadOnly;
|
||||
set => _textBox.ReadOnly = value;
|
||||
}
|
||||
public char PasswordChar
|
||||
{
|
||||
get => _textBox.PasswordChar;
|
||||
set => _textBox.PasswordChar = value;
|
||||
}
|
||||
|
||||
// ── Adiciona isso aqui ──
|
||||
public int SelectionStart
|
||||
{
|
||||
get => _textBox.SelectionStart;
|
||||
set => _textBox.SelectionStart = value;
|
||||
}
|
||||
public new event KeyEventHandler? KeyDown
|
||||
{
|
||||
add => _textBox.KeyDown += value;
|
||||
remove => _textBox.KeyDown -= value;
|
||||
}
|
||||
|
||||
public bool Multiline
|
||||
{
|
||||
get => _textBox.Multiline;
|
||||
set
|
||||
{
|
||||
_textBox.Multiline = value;
|
||||
_textBox.ScrollBars = value ? ScrollBars.Vertical : ScrollBars.None;
|
||||
AjustarTextBox();
|
||||
}
|
||||
}
|
||||
|
||||
public override string Text
|
||||
{
|
||||
get => _textBox.Text;
|
||||
set => _textBox.Text = value;
|
||||
}
|
||||
|
||||
public new Color BackColor
|
||||
{
|
||||
get => base.BackColor;
|
||||
set { base.BackColor = value; if (_textBox != null) _textBox.BackColor = value; }
|
||||
}
|
||||
|
||||
//public RoundTextBox()
|
||||
//{
|
||||
// DoubleBuffered = true;
|
||||
// base.BackColor = Color.White;
|
||||
// _textBox = new TextBox
|
||||
// {
|
||||
// BorderStyle = BorderStyle.None,
|
||||
// Font = new Font("Segoe UI", 9f),
|
||||
// Location = new Point(6, 6),
|
||||
// Width = Width - 12,
|
||||
// Height = Height - 12,
|
||||
// BackColor = Color.White
|
||||
// };
|
||||
// _textBox.GotFocus += (s, e) => { _focused = true; Invalidate(); };
|
||||
// _textBox.LostFocus += (s, e) => { _focused = false; Invalidate(); };
|
||||
// Controls.Add(_textBox);
|
||||
// SizeChanged += (s, e) => AjustarTextBox();
|
||||
//}
|
||||
public RoundTextBox()
|
||||
{
|
||||
DoubleBuffered = true;
|
||||
base.BackColor = Color.White;
|
||||
_textBox = new TextBox
|
||||
{
|
||||
BorderStyle = BorderStyle.None,
|
||||
Font = new Font("Segoe UI", 9f),
|
||||
Location = new Point(6, 6),
|
||||
Width = Width - 12,
|
||||
Height = Height - 12,
|
||||
BackColor = Color.White
|
||||
};
|
||||
|
||||
_textBox.GotFocus += (s, e) => { _focused = true; Invalidate(); };
|
||||
_textBox.LostFocus += (s, e) => { _focused = false; Invalidate(); };
|
||||
_textBox.TextChanged += (s, e) => OnTextChanged(e); // ← adiciona essa
|
||||
_textBox.Leave += (s, e) => OnLeave(e); // ← e essa
|
||||
|
||||
Controls.Add(_textBox);
|
||||
SizeChanged += (s, e) => AjustarTextBox();
|
||||
}
|
||||
|
||||
// Ajusta largura e altura do TextBox interno conforme Multiline
|
||||
private void AjustarTextBox()
|
||||
{
|
||||
_textBox.Width = Width - 12;
|
||||
_textBox.Height = _textBox.Multiline ? Height - 12 : _textBox.PreferredHeight;
|
||||
// Recentraliza verticalmente quando não é multiline
|
||||
if (!_textBox.Multiline)
|
||||
_textBox.Location = new Point(6, (Height - _textBox.PreferredHeight) / 2);
|
||||
else
|
||||
_textBox.Location = new Point(6, 6);
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
using var path = GetPath(new Rectangle(0, 0, Width - 1, Height - 1), Radius);
|
||||
using var brush = new SolidBrush(BackColor);
|
||||
e.Graphics.FillPath(brush, path);
|
||||
using var pen = new Pen(_focused ? FocusColor : BorderColor, _focused ? 1.5f : 1f);
|
||||
e.Graphics.DrawPath(pen, path);
|
||||
}
|
||||
|
||||
private static GraphicsPath GetPath(Rectangle r, int rad)
|
||||
{
|
||||
var path = new GraphicsPath();
|
||||
int d = rad * 2;
|
||||
path.AddArc(r.X, r.Y, d, d, 180, 90);
|
||||
path.AddArc(r.Right - d, r.Y, d, d, 270, 90);
|
||||
path.AddArc(r.Right - d, r.Bottom - d, d, d, 0, 90);
|
||||
path.AddArc(r.X, r.Bottom - d, d, d, 90, 90);
|
||||
path.CloseFigure();
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
public class RoundButton : Button
|
||||
{
|
||||
[DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
|
||||
private static extern IntPtr CreateRoundRectRgn(int nL, int nT, int nR, int nB, int nW, int nH);
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
base.OnPaint(e);
|
||||
Region = Region.FromHrgn(CreateRoundRectRgn(0, 0, Width, Height, 8, 8));
|
||||
FlatStyle = FlatStyle.Flat;
|
||||
FlatAppearance.BorderSize = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
120
ControlesCustom.resx
Normal file
120
ControlesCustom.resx
Normal 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>
|
||||
887
Dashboards/Cadastros/AgendaCadastroPanel.cs
Normal file
887
Dashboards/Cadastros/AgendaCadastroPanel.cs
Normal file
@ -0,0 +1,887 @@
|
||||
using BLL;
|
||||
using CustomMessageBox;
|
||||
using DAL;
|
||||
using MLL;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class AgendaCadastroPanel : UserControl
|
||||
{
|
||||
string _cx = DadosDaConexao.ObterConexao();
|
||||
// ── CORES ─────────────────────────────────────────────────────────────
|
||||
private readonly Color AccentBlue = Color.FromArgb(37, 99, 235);
|
||||
private readonly Color TextDark = Color.FromArgb(30, 41, 59);
|
||||
private readonly Color BorderColor = Color.FromArgb(226, 232, 240);
|
||||
private readonly Color GreenColor = Color.FromArgb(34, 197, 94);
|
||||
private readonly Color AmberColor = Color.FromArgb(245, 158, 11);
|
||||
private readonly Color RedColor = Color.FromArgb(239, 68, 68);
|
||||
private readonly Color MutedGray = Color.FromArgb(148, 163, 184);
|
||||
private readonly Color SurfaceColor = Color.FromArgb(248, 250, 252);
|
||||
private readonly Color DisabledBack = Color.FromArgb(241, 245, 249);
|
||||
|
||||
// ── LAYOUT ────────────────────────────────────────────────────────────
|
||||
private Panel pnlToolbar = null!;
|
||||
private Panel pnlLeft = null!;
|
||||
private Panel pnlRight = null!;
|
||||
private Panel pnlEventList = null!;
|
||||
private Panel pnlSplit = null!;
|
||||
private Panel pnlDias = null!;
|
||||
|
||||
// ── TOOLBAR ───────────────────────────────────────────────────────────
|
||||
private RoundButton btnNovo = null!;
|
||||
private RoundButton btnAlterar = null!;
|
||||
private RoundButton btnExcluir = null!;
|
||||
private RoundButton btnLocalizar = null!;
|
||||
private RoundButton btnSalvar = null!;
|
||||
private RoundButton btnCancelar = null!;
|
||||
|
||||
// ── CAMPOS DO FORMULÁRIO ──────────────────────────────────────────────
|
||||
private RoundTextBox txtId = null!;
|
||||
private RoundTextBox txtCodigo = null!;
|
||||
private RoundTextBox txtCompromisso = null!;
|
||||
private RoundTextBox txtData = null!;
|
||||
private RoundTextBox txtDia = null!;
|
||||
private RoundTextBox txtHora = null!;
|
||||
private RoundTextBox txtFunc = null!;
|
||||
private RoundTextBox txtAvisar = null!;
|
||||
private RoundTextBox txtOsVinc = null!;
|
||||
private CheckBox chkRealizado = null!;
|
||||
|
||||
// ── INFO (readonly) ───────────────────────────────────────────────────
|
||||
private RoundTextBox txtCriadoEm = null!;
|
||||
private RoundTextBox txtAtualizadoEm = null!;
|
||||
|
||||
// ── CALENDÁRIO ────────────────────────────────────────────────────────
|
||||
private Label lblMesAno = null!;
|
||||
private Button btnPrev = null!;
|
||||
private Button btnNext = null!;
|
||||
|
||||
// ── ESTADO ────────────────────────────────────────────────────────────
|
||||
private DateTime _currentMonth = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
|
||||
private DateTime? _selectedDate = null;
|
||||
private List<MLL.ModeloAgenda> _eventos = new();
|
||||
private int _nextId = 1;
|
||||
|
||||
// ── CONSTRUTOR ────────────────────────────────────────────────────────
|
||||
public AgendaCadastroPanel()
|
||||
{
|
||||
Dock = DockStyle.Fill;
|
||||
BackColor = Color.White;
|
||||
DoubleBuffered = true;
|
||||
|
||||
InitializeLayout();
|
||||
SetCampos(false);
|
||||
//CarregarDadosFake();
|
||||
CarregarDadosDoBanco();
|
||||
RenderCalendario();
|
||||
RenderListaEventos();
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════
|
||||
// LAYOUT
|
||||
// ══════════════════════════════════════════════════════════════════════
|
||||
private void InitializeLayout()
|
||||
{
|
||||
Controls.Clear();
|
||||
|
||||
// ── TOOLBAR ───────────────────────────────────────────────────────
|
||||
pnlToolbar = new Panel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
Height = 55,
|
||||
BackColor = SurfaceColor
|
||||
};
|
||||
|
||||
var flow = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Padding = new Padding(12, 10, 0, 0),
|
||||
BackColor = Color.Transparent
|
||||
};
|
||||
|
||||
btnNovo = CreateToolbarButton("Novo", GreenColor);
|
||||
btnAlterar = CreateToolbarButton("Alterar", AmberColor);
|
||||
btnExcluir = CreateToolbarButton("Excluir", RedColor);
|
||||
btnLocalizar = CreateToolbarButton("Localizar", AccentBlue);
|
||||
btnSalvar = CreateToolbarButton("Salvar", AccentBlue);
|
||||
btnCancelar = CreateToolbarButton("Cancelar", MutedGray);
|
||||
|
||||
btnNovo.Click += (_, _) => BtnNovo_Click();
|
||||
btnAlterar.Click += (_, _) => BtnAlterar_Click();
|
||||
btnExcluir.Click += (_, _) => BtnExcluir_Click();
|
||||
btnLocalizar.Click += (_, _) => BtnLocalizar_Click();
|
||||
btnSalvar.Click += (_, _) => BtnSalvar_Click();
|
||||
btnCancelar.Click += (_, _) => BtnCancelar_Click();
|
||||
|
||||
flow.Controls.AddRange(new Control[]
|
||||
{ btnNovo, btnAlterar, btnExcluir, btnLocalizar, btnSalvar, btnCancelar });
|
||||
|
||||
pnlToolbar.Controls.Add(flow);
|
||||
Controls.Add(pnlToolbar);
|
||||
|
||||
// ── SPLIT ─────────────────────────────────────────────────────────
|
||||
pnlSplit = new Panel { Dock = DockStyle.Fill, BackColor = Color.White };
|
||||
Controls.Add(pnlSplit);
|
||||
pnlSplit.BringToFront();
|
||||
|
||||
// RIGHT ─ calendário + lista
|
||||
pnlRight = new Panel
|
||||
{
|
||||
Dock = DockStyle.Right,
|
||||
Width = 340,
|
||||
BackColor = Color.White,
|
||||
Padding = new Padding(10, 10, 10, 10)
|
||||
};
|
||||
pnlSplit.Controls.Add(pnlRight);
|
||||
BuildCalendario(); // preenche pnlRight
|
||||
|
||||
// Divider
|
||||
var divider = new Panel
|
||||
{
|
||||
Dock = DockStyle.Right,
|
||||
Width = 1,
|
||||
BackColor = BorderColor
|
||||
};
|
||||
pnlSplit.Controls.Add(divider);
|
||||
|
||||
// LEFT ─ formulário
|
||||
pnlLeft = new Panel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
AutoScroll = true,
|
||||
BackColor = Color.White
|
||||
};
|
||||
pnlSplit.Controls.Add(pnlLeft);
|
||||
BuildFormulario();
|
||||
}
|
||||
|
||||
// ── FORMULÁRIO ────────────────────────────────────────────────────────
|
||||
private void BuildFormulario()
|
||||
{
|
||||
var content = new Panel { Width = 800, BackColor = Color.White };
|
||||
pnlLeft.Controls.Add(content);
|
||||
|
||||
const int rowH = 52;
|
||||
const int secH = 28;
|
||||
const int secGap = 10;
|
||||
const int inputH = 28;
|
||||
int y = 10;
|
||||
|
||||
// IDENTIFICAÇÃO
|
||||
content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtId = AddInput(content, "ID", 20, y, 60, inputH, readOnly: true);
|
||||
txtCodigo = AddInput(content, "Código", 90, y, 120, inputH);
|
||||
txtCompromisso = AddInput(content, "Compromisso", 220, y, 520, inputH);
|
||||
y += rowH;
|
||||
|
||||
// DATA E HORA
|
||||
y += secGap;
|
||||
content.Controls.Add(CreateSectionHeader("DATA E HORA", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtData = AddInput(content, "Data", 20, y, 130, inputH, readOnly: true);
|
||||
txtDia = AddInput(content, "Dia", 160, y, 150, inputH, readOnly: true);
|
||||
txtHora = AddInput(content, "Hora", 320, y, 100, inputH);
|
||||
y += rowH;
|
||||
|
||||
// RESPONSÁVEL E AVISO
|
||||
y += secGap;
|
||||
content.Controls.Add(CreateSectionHeader("RESPONSÁVEL E AVISO", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtFunc = AddInput(content, "Funcionário", 20, y, 280, inputH);
|
||||
txtAvisar = AddInput(content, "Avisar", 310, y, 180, inputH);
|
||||
txtOsVinc = AddInput(content, "OS Vinculada", 500, y, 140, inputH);
|
||||
y += rowH;
|
||||
|
||||
// SITUAÇÃO
|
||||
y += secGap;
|
||||
content.Controls.Add(CreateSectionHeader("SITUAÇÃO", y));
|
||||
y += secH + 4;
|
||||
|
||||
chkRealizado = new CheckBox
|
||||
{
|
||||
Text = "Realizado",
|
||||
Location = new Point(20, y + 4),
|
||||
Font = new Font("Segoe UI", 8.5f, FontStyle.Bold),
|
||||
ForeColor = TextDark,
|
||||
AutoSize = true
|
||||
};
|
||||
content.Controls.Add(chkRealizado);
|
||||
y += rowH;
|
||||
|
||||
// INFORMAÇÕES DO REGISTRO
|
||||
y += secGap;
|
||||
content.Controls.Add(CreateSectionHeader("INFORMAÇÕES DO REGISTRO", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtCriadoEm = AddInput(content, "Criado Em", 20, y, 175, inputH, readOnly: true);
|
||||
txtAtualizadoEm = AddInput(content, "Atualizado Em", 205, y, 175, inputH, readOnly: true);
|
||||
y += rowH;
|
||||
|
||||
content.Height = y + 10;
|
||||
}
|
||||
|
||||
// ── CALENDÁRIO ────────────────────────────────────────────────────────
|
||||
// ATENÇÃO: No WinForms, DockStyle.Fill deve ser adicionado ANTES dos
|
||||
// DockStyle.Top — a ordem de inserção em Controls é invertida visualmente.
|
||||
private void BuildCalendario()
|
||||
{
|
||||
// 1º — Lista de eventos (Fill) → adicionada PRIMEIRO
|
||||
pnlEventList = new Panel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
AutoScroll = true,
|
||||
BackColor = Color.White,
|
||||
Padding = new Padding(0, 4, 0, 0)
|
||||
};
|
||||
pnlRight.Controls.Add(pnlEventList); // ← PRIMEIRO
|
||||
|
||||
// 2º — Grid dos dias (Top) → adicionado DEPOIS do Fill
|
||||
pnlDias = new Panel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
Height = 215,
|
||||
BackColor = Color.White
|
||||
};
|
||||
pnlRight.Controls.Add(pnlDias); // ← SEGUNDO
|
||||
|
||||
// 3º — Cabeçalho mês/ano (Top) → adicionado POR ÚLTIMO (aparece no topo)
|
||||
var pnlCalHeader = new Panel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
Height = 38,
|
||||
BackColor = Color.White
|
||||
};
|
||||
|
||||
btnPrev = new Button
|
||||
{
|
||||
Text = "‹",
|
||||
Size = new Size(28, 26),
|
||||
Location = new Point(0, 6),
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
Font = new Font("Segoe UI", 13f),
|
||||
ForeColor = AccentBlue,
|
||||
BackColor = Color.White,
|
||||
Cursor = Cursors.Hand
|
||||
};
|
||||
btnPrev.FlatAppearance.BorderColor = BorderColor;
|
||||
btnPrev.Click += (_, _) =>
|
||||
{
|
||||
_currentMonth = _currentMonth.AddMonths(-1);
|
||||
RenderCalendario();
|
||||
RenderListaEventos();
|
||||
};
|
||||
|
||||
btnNext = new Button
|
||||
{
|
||||
Text = "›",
|
||||
Size = new Size(28, 26),
|
||||
Location = new Point(290, 6),
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
Font = new Font("Segoe UI", 13f),
|
||||
ForeColor = AccentBlue,
|
||||
BackColor = Color.White,
|
||||
Cursor = Cursors.Hand
|
||||
};
|
||||
btnNext.FlatAppearance.BorderColor = BorderColor;
|
||||
btnNext.Click += (_, _) =>
|
||||
{
|
||||
_currentMonth = _currentMonth.AddMonths(1);
|
||||
RenderCalendario();
|
||||
RenderListaEventos();
|
||||
};
|
||||
|
||||
lblMesAno = new Label
|
||||
{
|
||||
AutoSize = false,
|
||||
TextAlign = ContentAlignment.MiddleCenter,
|
||||
Font = new Font("Segoe UI", 10f, FontStyle.Bold),
|
||||
ForeColor = TextDark,
|
||||
Size = new Size(256, 26),
|
||||
Location = new Point(32, 6)
|
||||
};
|
||||
|
||||
pnlCalHeader.Controls.AddRange(new Control[] { btnPrev, lblMesAno, btnNext });
|
||||
pnlRight.Controls.Add(pnlCalHeader); // ← ÚLTIMO (fica no topo visualmente)
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════
|
||||
// RENDER CALENDÁRIO
|
||||
// ══════════════════════════════════════════════════════════════════════
|
||||
private void RenderCalendario()
|
||||
{
|
||||
pnlDias.Controls.Clear();
|
||||
|
||||
lblMesAno.Text = _currentMonth.ToString("MMMM yyyy",
|
||||
new System.Globalization.CultureInfo("pt-BR")).ToUpper();
|
||||
|
||||
string[] dowLabels = { "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb" };
|
||||
int cellW = 44;
|
||||
int cellH = 26;
|
||||
int startX = 2;
|
||||
|
||||
// Cabeçalho dias da semana
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
pnlDias.Controls.Add(new Label
|
||||
{
|
||||
Text = dowLabels[i],
|
||||
Size = new Size(cellW, 18),
|
||||
Location = new Point(startX + i * cellW, 0),
|
||||
TextAlign = ContentAlignment.MiddleCenter,
|
||||
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
|
||||
ForeColor = MutedGray
|
||||
});
|
||||
}
|
||||
|
||||
int firstDow = (int)new DateTime(_currentMonth.Year, _currentMonth.Month, 1).DayOfWeek;
|
||||
int daysInMonth = DateTime.DaysInMonth(_currentMonth.Year, _currentMonth.Month);
|
||||
var datesWithEvts = GetDatesWithEvents();
|
||||
DateTime today = DateTime.Today;
|
||||
int col = firstDow, row = 0;
|
||||
|
||||
for (int d = 1; d <= daysInMonth; d++)
|
||||
{
|
||||
var date = new DateTime(_currentMonth.Year, _currentMonth.Month, d);
|
||||
bool isToday = date == today;
|
||||
bool isSelected = _selectedDate.HasValue && date == _selectedDate.Value;
|
||||
bool hasEvent = datesWithEvts.Contains(date.Date);
|
||||
|
||||
var btn = new Button
|
||||
{
|
||||
Text = hasEvent ? $"{d} •" : d.ToString(),
|
||||
Size = new Size(cellW - 2, cellH),
|
||||
Location = new Point(startX + col * cellW, 22 + row * (cellH + 2)),
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
Font = new Font("Segoe UI", 8f,
|
||||
isToday || isSelected ? FontStyle.Bold : FontStyle.Regular),
|
||||
Cursor = Cursors.Hand,
|
||||
Tag = date
|
||||
};
|
||||
|
||||
if (isSelected)
|
||||
{
|
||||
btn.BackColor = AccentBlue;
|
||||
btn.ForeColor = Color.White;
|
||||
btn.FlatAppearance.BorderColor = AccentBlue;
|
||||
}
|
||||
else if (isToday)
|
||||
{
|
||||
btn.BackColor = Color.White;
|
||||
btn.ForeColor = AccentBlue;
|
||||
btn.FlatAppearance.BorderColor = AccentBlue;
|
||||
}
|
||||
else
|
||||
{
|
||||
btn.BackColor = Color.White;
|
||||
btn.ForeColor = TextDark;
|
||||
btn.FlatAppearance.BorderColor = BorderColor;
|
||||
}
|
||||
|
||||
btn.Click += (s, _) =>
|
||||
{
|
||||
if (s is Button b && b.Tag is DateTime dt)
|
||||
{
|
||||
_selectedDate = dt;
|
||||
if (txtData.Enabled)
|
||||
{
|
||||
txtData.Text = dt.ToString("dd/MM/yyyy");
|
||||
txtDia.Text = new System.Globalization.CultureInfo("pt-BR")
|
||||
.DateTimeFormat.GetDayName(dt.DayOfWeek);
|
||||
}
|
||||
RenderCalendario();
|
||||
RenderListaEventos();
|
||||
}
|
||||
};
|
||||
|
||||
pnlDias.Controls.Add(btn);
|
||||
|
||||
col++;
|
||||
if (col == 7) { col = 0; row++; }
|
||||
}
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════
|
||||
// RENDER LISTA DE EVENTOS
|
||||
// ══════════════════════════════════════════════════════════════════════
|
||||
private void RenderListaEventos()
|
||||
{
|
||||
pnlEventList.Controls.Clear();
|
||||
|
||||
var filtrados = _selectedDate.HasValue
|
||||
? _eventos.Where(e => ParseData(e.dDATA).Date == _selectedDate.Value.Date).ToList()
|
||||
: _eventos.Where(e => ParseData(e.dDATA).Month == _currentMonth.Month
|
||||
&& ParseData(e.dDATA).Year == _currentMonth.Year).ToList();
|
||||
|
||||
filtrados = filtrados.OrderBy(e => e.HORA).ToList();
|
||||
|
||||
// Largura real do painel (com fallback para evitar 0)
|
||||
int listW = pnlEventList.ClientSize.Width > 0
|
||||
? pnlEventList.ClientSize.Width
|
||||
: pnlRight.Width - pnlRight.Padding.Horizontal - 20;
|
||||
|
||||
int y = 0;
|
||||
|
||||
// ── Título ────────────────────────────────────────────────────────
|
||||
string titulo = _selectedDate.HasValue
|
||||
? $"COMPROMISSOS — {_selectedDate.Value:dd/MM/yyyy}"
|
||||
: $"COMPROMISSOS — {_currentMonth.ToString("MMMM/yyyy", new System.Globalization.CultureInfo("pt-BR")).ToUpper()}";
|
||||
|
||||
pnlEventList.Controls.Add(new Label
|
||||
{
|
||||
Text = titulo,
|
||||
AutoSize = false,
|
||||
Width = listW,
|
||||
Height = 18,
|
||||
Location = new Point(0, y),
|
||||
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
|
||||
ForeColor = MutedGray
|
||||
});
|
||||
y += 6;
|
||||
|
||||
// Linha separadora
|
||||
pnlEventList.Controls.Add(new Panel
|
||||
{
|
||||
Location = new Point(0, y + 14),
|
||||
Size = new Size(listW, 1),
|
||||
BackColor = BorderColor
|
||||
});
|
||||
y += 22;
|
||||
|
||||
// ── Vazio ─────────────────────────────────────────────────────────
|
||||
if (!filtrados.Any())
|
||||
{
|
||||
pnlEventList.Controls.Add(new Label
|
||||
{
|
||||
Text = "Nenhum compromisso encontrado.",
|
||||
Location = new Point(0, y + 8),
|
||||
AutoSize = true,
|
||||
Font = new Font("Segoe UI", 8.5f),
|
||||
ForeColor = MutedGray
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// ── Cards ─────────────────────────────────────────────────────────
|
||||
foreach (var ev in filtrados)
|
||||
{
|
||||
bool realizado = ev.REALIZADO?.ToUpper() == "S";
|
||||
|
||||
var card = new Panel
|
||||
{
|
||||
Location = new Point(0, y),
|
||||
Width = listW,
|
||||
Height = 72,
|
||||
BackColor = Color.White,
|
||||
BorderStyle = BorderStyle.None,
|
||||
Cursor = Cursors.Hand,
|
||||
Tag = ev
|
||||
};
|
||||
|
||||
// Borda esquerda colorida
|
||||
card.Controls.Add(new Panel
|
||||
{
|
||||
Location = new Point(0, 0),
|
||||
Size = new Size(3, 72),
|
||||
BackColor = realizado ? GreenColor : AmberColor
|
||||
});
|
||||
|
||||
card.Controls.Add(new Label
|
||||
{
|
||||
Text = $"{ev.HORA} — {ev.dDATA}",
|
||||
Location = new Point(10, 5),
|
||||
AutoSize = true,
|
||||
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
|
||||
ForeColor = AccentBlue
|
||||
});
|
||||
card.Controls.Add(new Label
|
||||
{
|
||||
Text = ev.COMPROMISSO,
|
||||
Location = new Point(10, 21),
|
||||
AutoSize = true,
|
||||
Font = new Font("Segoe UI", 8.5f, FontStyle.Bold),
|
||||
ForeColor = TextDark
|
||||
});
|
||||
card.Controls.Add(new Label
|
||||
{
|
||||
Text = string.IsNullOrWhiteSpace(ev.FUNC) ? "—" : ev.FUNC,
|
||||
Location = new Point(10, 39),
|
||||
AutoSize = true,
|
||||
Font = new Font("Segoe UI", 8f),
|
||||
ForeColor = MutedGray
|
||||
});
|
||||
card.Controls.Add(new Label
|
||||
{
|
||||
Text = realizado ? "✔ Realizado" : "⏳ Pendente",
|
||||
Location = new Point(10, 55),
|
||||
AutoSize = true,
|
||||
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
|
||||
ForeColor = realizado
|
||||
? Color.FromArgb(22, 101, 52)
|
||||
: Color.FromArgb(146, 64, 14)
|
||||
});
|
||||
|
||||
// Borda do card via Paint
|
||||
card.Paint += (_, pe) =>
|
||||
{
|
||||
using var pen = new Pen(BorderColor);
|
||||
pe.Graphics.DrawRectangle(pen, 0, 0, card.Width - 1, card.Height - 1);
|
||||
};
|
||||
|
||||
// Clique em qualquer parte do card (inclusive labels filhos)
|
||||
var evLocal = ev;
|
||||
EventHandler clickHandler = (_, _) => CarregarEvento(evLocal);
|
||||
card.Click += clickHandler;
|
||||
foreach (Control child in card.Controls)
|
||||
child.Click += clickHandler;
|
||||
|
||||
pnlEventList.Controls.Add(card);
|
||||
y += 78;
|
||||
}
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════
|
||||
// EVENTOS DOS BOTÕES
|
||||
// ══════════════════════════════════════════════════════════════════════
|
||||
private void BtnNovo_Click()
|
||||
{
|
||||
|
||||
LimparCampos();
|
||||
SetCampos(true);
|
||||
txtCriadoEm.Text = DateTime.Now.ToString("dd/MM/yyyy");
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void BtnAlterar_Click()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(txtId.Text))
|
||||
{
|
||||
MessageBox.Show("Nenhum registro selecionado para alterar.",
|
||||
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
SetCampos(true);
|
||||
}
|
||||
|
||||
private void BtnExcluir_Click()
|
||||
{
|
||||
BLLAgenda _agendaBLL = new BLLAgenda(this._cx);
|
||||
if (string.IsNullOrWhiteSpace(txtId.Text))
|
||||
{
|
||||
NT_MessageBox.Show("Nenhum registro selecionado para excluir.",
|
||||
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
var confirm = NT_MessageBox.Show("Confirma a exclusão deste registro?",
|
||||
"Confirmar Exclusão", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||
|
||||
if (confirm == DialogResult.Yes)
|
||||
{
|
||||
int id = int.Parse(txtId.Text);
|
||||
|
||||
bool sucesso = _agendaBLL.Excluir(id);
|
||||
|
||||
if (!sucesso)
|
||||
{
|
||||
NT_MessageBox.Show("Erro ao excluir o registro.",
|
||||
"Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
// 🔹 Atualiza lista do banco
|
||||
_eventos.Clear();
|
||||
_eventos.AddRange(_agendaBLL.Listar());
|
||||
|
||||
LimparCampos();
|
||||
SetCampos(false);
|
||||
RenderCalendario();
|
||||
RenderListaEventos();
|
||||
|
||||
NT_MessageBox.Show("Registro excluído com sucesso!",
|
||||
"Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
}//Excluir registro selecionado
|
||||
|
||||
private void BtnLocalizar_Click()
|
||||
{
|
||||
FormHelper.Show<AgendaConsultaPanel>("Agenda de Compromissos");
|
||||
}
|
||||
|
||||
private void BtnSalvar_Click()
|
||||
{
|
||||
//if (string.IsNullOrWhiteSpace(txtData.Text) ||
|
||||
// string.IsNullOrWhiteSpace(txtCompromisso.Text))
|
||||
//{
|
||||
// MessageBox.Show("Preencha ao menos Data e Compromisso.",
|
||||
// "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
// return;
|
||||
//}
|
||||
|
||||
//bool isNew = string.IsNullOrWhiteSpace(txtId.Text);
|
||||
//int id = isNew ? _nextId++ : int.Parse(txtId.Text);
|
||||
|
||||
//var agenda = new MLL.ModeloAgenda(
|
||||
// iD_AGENDA: id,
|
||||
// cODIGO: txtCodigo.Text,
|
||||
// cOMPROMISSO: txtCompromisso.Text,
|
||||
// dDATA: txtData.Text,
|
||||
// aVISAR: txtAvisar.Text,
|
||||
// fUNC: txtFunc.Text,
|
||||
// dIA: txtDia.Text,
|
||||
// hORA: txtHora.Text,
|
||||
// rEALIZADO: chkRealizado.Checked ? "S" : "N",
|
||||
// oS_VINC: txtOsVinc.Text
|
||||
//);
|
||||
|
||||
//if (isNew)
|
||||
//{
|
||||
// _eventos.Add(agenda);
|
||||
// txtId.Text = id.ToString();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// int idx = _eventos.FindIndex(e => e.ID_AGENDA == id);
|
||||
// if (idx >= 0) _eventos[idx] = agenda;
|
||||
//}
|
||||
|
||||
//txtAtualizadoEm.Text = DateTime.Now.ToString("dd/MM/yyyy");
|
||||
//SetCampos(false);
|
||||
//RenderCalendario();
|
||||
//RenderListaEventos();
|
||||
|
||||
//MessageBox.Show("Registro salvo com sucesso!", "Sucesso",
|
||||
// MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
BLLAgenda _agendaBLL = new BLLAgenda(_cx);
|
||||
if (string.IsNullOrWhiteSpace(txtData.Text) ||
|
||||
string.IsNullOrWhiteSpace(txtCompromisso.Text))
|
||||
{
|
||||
MessageBox.Show("Preencha ao menos Data e Compromisso.",
|
||||
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
bool isNew = string.IsNullOrWhiteSpace(txtId.Text);
|
||||
|
||||
var agenda = new MLL.ModeloAgenda(
|
||||
iD_AGENDA: isNew ? 0 : int.Parse(txtId.Text),
|
||||
cODIGO: txtCodigo.Text,
|
||||
cOMPROMISSO: txtCompromisso.Text,
|
||||
dDATA: txtData.Text,
|
||||
aVISAR: txtAvisar.Text,
|
||||
fUNC: txtFunc.Text,
|
||||
dIA: txtDia.Text,
|
||||
hORA: txtHora.Text,
|
||||
rEALIZADO: chkRealizado.Checked ? "S" : "N",
|
||||
oS_VINC: txtOsVinc.Text
|
||||
);
|
||||
|
||||
bool sucesso;
|
||||
|
||||
if (isNew)
|
||||
{
|
||||
sucesso = _agendaBLL.Inserir(agenda);
|
||||
}
|
||||
else
|
||||
{
|
||||
sucesso = _agendaBLL.Alterar(agenda);
|
||||
}
|
||||
|
||||
if (!sucesso)
|
||||
{
|
||||
MessageBox.Show("Erro ao salvar no banco de dados.",
|
||||
"Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
// 🔹 Recarrega dados do banco
|
||||
_eventos = _agendaBLL.Listar();
|
||||
|
||||
// 🔹 Atualiza UI
|
||||
txtAtualizadoEm.Text = DateTime.Now.ToString("dd/MM/yyyy");
|
||||
SetCampos(false);
|
||||
RenderCalendario();
|
||||
RenderListaEventos();
|
||||
|
||||
MessageBox.Show("Registro salvo com sucesso!", "Sucesso",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
private void BtnCancelar_Click()
|
||||
{
|
||||
LimparCampos();
|
||||
SetCampos(false);
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════
|
||||
// HELPERS
|
||||
// ══════════════════════════════════════════════════════════════════════
|
||||
private void SetCampos(bool enabled)
|
||||
{
|
||||
var campos = new[] { txtCodigo, txtCompromisso, txtHora, txtFunc, txtAvisar, txtOsVinc };
|
||||
foreach (var c in campos)
|
||||
{
|
||||
c.Enabled = enabled;
|
||||
c.BackColor = enabled ? Color.White : DisabledBack;
|
||||
}
|
||||
chkRealizado.Enabled = enabled;
|
||||
txtData.BackColor = enabled ? Color.FromArgb(239, 246, 255) : DisabledBack;
|
||||
}
|
||||
|
||||
private void LimparCampos()
|
||||
{
|
||||
txtId.Text = txtCodigo.Text = txtCompromisso.Text = string.Empty;
|
||||
txtData.Text = txtDia.Text = txtHora.Text = string.Empty;
|
||||
txtFunc.Text = txtAvisar.Text = txtOsVinc.Text = string.Empty;
|
||||
txtCriadoEm.Text = txtAtualizadoEm.Text = string.Empty;
|
||||
chkRealizado.Checked = false;
|
||||
_selectedDate = null;
|
||||
}
|
||||
|
||||
private void CarregarEvento(MLL.ModeloAgenda ev)
|
||||
{
|
||||
txtId.Text = ev.ID_AGENDA.ToString();
|
||||
txtCodigo.Text = ev.CODIGO;
|
||||
txtCompromisso.Text = ev.COMPROMISSO;
|
||||
txtData.Text = ev.dDATA;
|
||||
txtDia.Text = ev.DIA;
|
||||
txtHora.Text = ev.HORA;
|
||||
txtFunc.Text = ev.FUNC;
|
||||
txtAvisar.Text = ev.AVISAR;
|
||||
txtOsVinc.Text = ev.OS_VINC;
|
||||
txtCriadoEm.Text = ev.dDATA;
|
||||
txtAtualizadoEm.Text = DateTime.Now.ToString("dd/MM/yyyy");
|
||||
chkRealizado.Checked = ev.REALIZADO?.ToUpper() == "S";
|
||||
|
||||
var dt = ParseData(ev.dDATA);
|
||||
if (dt != DateTime.MinValue)
|
||||
{
|
||||
_selectedDate = dt;
|
||||
_currentMonth = new DateTime(dt.Year, dt.Month, 1);
|
||||
}
|
||||
|
||||
SetCampos(false);
|
||||
RenderCalendario();
|
||||
RenderListaEventos();
|
||||
}
|
||||
|
||||
private HashSet<DateTime> GetDatesWithEvents()
|
||||
{
|
||||
var set = new HashSet<DateTime>();
|
||||
foreach (var ev in _eventos)
|
||||
{
|
||||
var dt = ParseData(ev.dDATA);
|
||||
if (dt != DateTime.MinValue) set.Add(dt.Date);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
private static DateTime ParseData(string? value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value)) return DateTime.MinValue;
|
||||
if (DateTime.TryParseExact(value, "dd/MM/yyyy",
|
||||
System.Globalization.CultureInfo.InvariantCulture,
|
||||
System.Globalization.DateTimeStyles.None, out var dt))
|
||||
return dt;
|
||||
if (DateTime.TryParse(value, out dt)) return dt;
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
|
||||
private void CarregarDadosFake()
|
||||
{
|
||||
var hoje = DateTime.Today;
|
||||
_eventos.AddRange(new[]
|
||||
{
|
||||
new MLL.ModeloAgenda(1, "AG001", "Reunião com cliente",
|
||||
hoje.ToString("dd/MM/yyyy"), "30 minutos antes",
|
||||
"Carlos Silva", DiaSemana(hoje), "09:00", "S", "OS-1042"),
|
||||
|
||||
new MLL.ModeloAgenda(2, "AG002", "Visita técnica",
|
||||
hoje.ToString("dd/MM/yyyy"), "1 hora antes",
|
||||
"Ana Souza", DiaSemana(hoje), "14:00", "N", "OS-1055"),
|
||||
|
||||
new MLL.ModeloAgenda(3, "AG003", "Entrega de equipamento",
|
||||
hoje.AddDays(4).ToString("dd/MM/yyyy"), "1 dia antes",
|
||||
"Pedro Lima", DiaSemana(hoje.AddDays(4)), "10:30", "N", ""),
|
||||
});
|
||||
_nextId = 4;
|
||||
}//Carregar dados fake (Não usa mais)
|
||||
private void CarregarDadosDoBanco()
|
||||
{
|
||||
BLLAgenda _agendaBLL = new BLLAgenda(_cx);
|
||||
_eventos.Clear();
|
||||
_eventos.AddRange(_agendaBLL.Listar());
|
||||
}// Método auxiliar para obter os dados da agenda no banco de dados e preencher a lista de eventos.
|
||||
|
||||
private static string DiaSemana(DateTime d) =>
|
||||
new System.Globalization.CultureInfo("pt-BR").DateTimeFormat.GetDayName(d.DayOfWeek);
|
||||
|
||||
// ── UI HELPERS ────────────────────────────────────────────────────────
|
||||
private Panel CreateSectionHeader(string title, int y)
|
||||
{
|
||||
var pnl = new Panel { Location = new Point(20, y), Width = 760, Height = 26 };
|
||||
pnl.Controls.Add(new Label
|
||||
{
|
||||
Text = title,
|
||||
Font = new Font("Segoe UI", 8.5f, FontStyle.Bold),
|
||||
ForeColor = AccentBlue,
|
||||
AutoSize = true,
|
||||
Location = new Point(0, 0)
|
||||
});
|
||||
pnl.Controls.Add(new Panel
|
||||
{
|
||||
BackColor = BorderColor,
|
||||
Height = 1,
|
||||
Width = 740,
|
||||
Location = new Point(0, 20)
|
||||
});
|
||||
return pnl;
|
||||
}
|
||||
|
||||
private RoundTextBox AddInput(Control parent, string label,
|
||||
int x, int y, int width, int height,
|
||||
bool readOnly = false)
|
||||
{
|
||||
parent.Controls.Add(new Label
|
||||
{
|
||||
Text = label,
|
||||
Location = new Point(x, y),
|
||||
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
|
||||
ForeColor = readOnly ? Color.Gray : TextDark,
|
||||
AutoSize = true
|
||||
});
|
||||
var txt = new RoundTextBox
|
||||
{
|
||||
Location = new Point(x, y + 16),
|
||||
Size = new Size(width, height),
|
||||
Radius = 4,
|
||||
BorderColor = readOnly ? Color.FromArgb(203, 213, 225) : BorderColor,
|
||||
FocusColor = AccentBlue,
|
||||
ReadOnly = readOnly,
|
||||
BackColor = readOnly ? DisabledBack : Color.White
|
||||
};
|
||||
parent.Controls.Add(txt);
|
||||
return txt;
|
||||
}
|
||||
|
||||
private RoundButton CreateToolbarButton(string text, Color color) => new RoundButton
|
||||
{
|
||||
Text = text,
|
||||
Size = new Size(95, 32),
|
||||
BackColor = color,
|
||||
ForeColor = Color.White,
|
||||
Font = new Font("Segoe UI Semibold", 8.5f),
|
||||
Margin = new Padding(0, 0, 6, 0),
|
||||
Cursor = Cursors.Hand
|
||||
};
|
||||
}
|
||||
}
|
||||
120
Dashboards/Cadastros/AgendaCadastroPanel.resx
Normal file
120
Dashboards/Cadastros/AgendaCadastroPanel.resx
Normal 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>
|
||||
530
Dashboards/Cadastros/ClienteCadastroPanel.cs
Normal file
530
Dashboards/Cadastros/ClienteCadastroPanel.cs
Normal file
@ -0,0 +1,530 @@
|
||||
using BLL;
|
||||
using CustomMessageBox;
|
||||
using DAL;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class ClienteCadastroPanel : UserControl
|
||||
{
|
||||
private string _connectionString = DadosDaConexao.ObterConexao();
|
||||
private readonly Color AccentBlue = Color.FromArgb(37, 99, 235);
|
||||
private readonly Color TextDark = Color.FromArgb(30, 41, 59);
|
||||
private readonly Color BorderColor = Color.FromArgb(226, 232, 240);
|
||||
|
||||
private Panel pnlToolbar = null!;
|
||||
private Panel mainScroll = null!;
|
||||
private Panel content = null!;
|
||||
|
||||
// Identificação
|
||||
private RoundTextBox txtId = null!, txtEmpresaId = null!, txtNome = null!, txtNomeFantasia = null!;
|
||||
private RoundTextBox txtTipoPessoa = null!, txtDocumento = null!, txtRG = null!;
|
||||
private RoundTextBox txtInscricaoMunicipal = null!, txtDataNascimento = null!;
|
||||
private RoundTextBox txtGrupo = null!, txtTipoConsumidor = null!;
|
||||
|
||||
// Contatos
|
||||
private RoundTextBox txtContato = null!, txtTelefone1 = null!, txtTelefone2 = null!;
|
||||
private RoundTextBox txtCelular = null!, txtWhatsapp = null!, txtEmail = null!, txtEmailNFe = null!, txtSite = null!;
|
||||
|
||||
// Endereço
|
||||
private RoundTextBox txtCep = null!, txtEndereco = null!, txtNumero = null!, txtComplemento = null!;
|
||||
private RoundTextBox txtBairro = null!, txtCidade = null!, txtUF = null!, txtPais = null!;
|
||||
|
||||
// Financeiro
|
||||
private RoundTextBox txtLimiteCredito = null!, txtVendedorPadraoId = null!, txtObservacoesCobranca = null!;
|
||||
private CheckBox chkBloqueado = null!, chkAtivo = null!;
|
||||
|
||||
// Carteiras
|
||||
private RoundTextBox txtBitcoin = null!, txtEthereum = null!, txtLitecoin = null!;
|
||||
|
||||
// Extras
|
||||
private RoundTextBox txtObservacoes = null!;
|
||||
private RoundTextBox txtCampoExtra1 = null!, txtCampoExtra2 = null!, txtCampoExtra3 = null!;
|
||||
|
||||
// Info (readonly)
|
||||
private RoundTextBox txtUltimaCompra = null!, txtCriadoEm = null!, txtAtualizadoEm = null!;
|
||||
|
||||
//Funções Auxiliares
|
||||
private void CarregarConfiguracoesSistema()
|
||||
{
|
||||
BLLEmpresaConfig empresaConfig = new BLLEmpresaConfig(_connectionString);
|
||||
int codEmpresa = empresaConfig.ObterEmpresaAtivaId();
|
||||
|
||||
this.txtEmpresaId.Text = codEmpresa.ToString();
|
||||
}
|
||||
private DateTime? ConverterData(string texto)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(texto))
|
||||
return null;
|
||||
|
||||
if (DateTime.TryParse(texto, out DateTime data))
|
||||
return data;
|
||||
|
||||
return null;
|
||||
}
|
||||
private RoundTextBox[] TodosOsCampos() => new[]
|
||||
{
|
||||
txtId, txtEmpresaId, txtNome, txtNomeFantasia,
|
||||
txtTipoPessoa, txtDocumento, txtRG,
|
||||
txtInscricaoMunicipal, txtDataNascimento,
|
||||
txtGrupo, txtTipoConsumidor,
|
||||
txtContato, txtTelefone1, txtTelefone2,
|
||||
txtCelular, txtWhatsapp, txtEmail, txtEmailNFe, txtSite,
|
||||
txtCep, txtEndereco, txtNumero, txtComplemento,
|
||||
txtBairro, txtCidade, txtUF, txtPais,
|
||||
txtLimiteCredito, txtVendedorPadraoId, txtObservacoesCobranca,
|
||||
txtBitcoin, txtEthereum, txtLitecoin,
|
||||
txtObservacoes, txtCampoExtra1, txtCampoExtra2, txtCampoExtra3
|
||||
};
|
||||
|
||||
private void SetCampos(bool enabled)
|
||||
{
|
||||
foreach (var campo in TodosOsCampos())
|
||||
{
|
||||
campo.Enabled = enabled;
|
||||
campo.BackColor = enabled ? Color.White : Color.FromArgb(241, 245, 249);
|
||||
}
|
||||
chkBloqueado.Enabled = enabled;
|
||||
chkAtivo.Enabled = enabled;
|
||||
}
|
||||
|
||||
public ClienteCadastroPanel()
|
||||
{
|
||||
Dock = DockStyle.Fill;
|
||||
BackColor = Color.White;
|
||||
DoubleBuffered = true;
|
||||
InitializeLayout();
|
||||
SetCampos(false);
|
||||
}
|
||||
|
||||
private void InitializeLayout()
|
||||
{
|
||||
this.Controls.Clear();
|
||||
|
||||
// ── TOOLBAR ───────────────────────────────────────────────────────
|
||||
pnlToolbar = new Panel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
Height = 55,
|
||||
BackColor = Color.FromArgb(248, 250, 252),
|
||||
BorderStyle = BorderStyle.None
|
||||
};
|
||||
|
||||
var flowButtons = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Padding = new Padding(12, 10, 0, 0),
|
||||
BackColor = Color.Transparent
|
||||
};
|
||||
|
||||
var btnNovo = CreateToolbarButton("Novo", Color.FromArgb(34, 197, 94));
|
||||
var btnAlterar = CreateToolbarButton("Alterar", Color.FromArgb(245, 158, 11));
|
||||
var btnExcluir = CreateToolbarButton("Excluir", Color.FromArgb(239, 68, 68));
|
||||
var btnLocalizar = CreateToolbarButton("Localizar", AccentBlue);
|
||||
var btnSalvar = CreateToolbarButton("Salvar", AccentBlue);
|
||||
var btnCancelar = CreateToolbarButton("Cancelar", Color.FromArgb(148, 163, 184));
|
||||
|
||||
btnNovo.Click += (s, e) => BtnNovo_Click();
|
||||
btnAlterar.Click += (s, e) => BtnAlterar_Click();
|
||||
btnExcluir.Click += (s, e) => BtnExcluir_Click();
|
||||
btnLocalizar.Click += (s, e) => BtnLocalizar_Click();
|
||||
btnSalvar.Click += (s, e) => BtnSalvar_Click();
|
||||
btnCancelar.Click += (s, e) => BtnCancelar_Click();
|
||||
|
||||
flowButtons.Controls.AddRange(new Control[]
|
||||
{ btnNovo, btnAlterar, btnExcluir, btnLocalizar, btnSalvar, btnCancelar });
|
||||
pnlToolbar.Controls.Add(flowButtons);
|
||||
this.Controls.Add(pnlToolbar);
|
||||
|
||||
// ── SCROLL + CONTENT ──────────────────────────────────────────────
|
||||
mainScroll = new Panel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
AutoScroll = true,
|
||||
BackColor = Color.White
|
||||
};
|
||||
this.Controls.Add(mainScroll);
|
||||
mainScroll.BringToFront();
|
||||
|
||||
content = new Panel
|
||||
{
|
||||
Width = 1100,
|
||||
Height = 900,
|
||||
Location = new Point(0, 0),
|
||||
BackColor = Color.White
|
||||
};
|
||||
mainScroll.Controls.Add(content);
|
||||
|
||||
const int rowH = 52;
|
||||
const int secGap = 10;
|
||||
const int secH = 28;
|
||||
const int inputH = 28;
|
||||
|
||||
int y = 10;
|
||||
|
||||
// ── 1. IDENTIFICAÇÃO DO CLIENTE ───────────────────────────────────
|
||||
content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO DO CLIENTE", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtId = AddInput(content, "ID", 20, y, 60, inputH);
|
||||
txtEmpresaId = AddInput(content, "Empresa ID", 90, y, 80, inputH);
|
||||
txtNome = AddInput(content, "Nome / Razão Social", 180, y, 390, inputH);
|
||||
txtNomeFantasia = AddInput(content, "Nome Fantasia", 580, y, 360, inputH);
|
||||
y += rowH;
|
||||
|
||||
txtDocumento = AddInput(content, "CPF/CNPJ", 20, y, 170, inputH);
|
||||
DocumentoHelper.Registrar(txtDocumento);
|
||||
txtRG = AddInput(content, "RG / Insc. Estadual", 200, y, 170, inputH);
|
||||
txtInscricaoMunicipal = AddInput(content, "Insc. Municipal", 380, y, 130, inputH);
|
||||
txtDataNascimento = AddInput(content, "Dt. Nascimento", 520, y, 130, inputH);
|
||||
txtTipoPessoa = AddInput(content, "Tipo Pessoa", 660, y, 110, inputH);
|
||||
txtGrupo = AddInput(content, "Grupo", 780, y, 110, inputH);
|
||||
txtTipoConsumidor = AddInput(content, "Tipo Consumidor", 900, y, 140, inputH);
|
||||
y += rowH;
|
||||
|
||||
// ── 2. CONTATOS E COMUNICAÇÃO ─────────────────────────────────────
|
||||
y += secGap;
|
||||
content.Controls.Add(CreateSectionHeader("CONTATOS E COMUNICAÇÃO", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtContato = AddInput(content, "Contato", 20, y, 180, inputH);
|
||||
txtEmail = AddInput(content, "E-mail", 210, y, 230, inputH);
|
||||
txtEmailNFe = AddInput(content, "E-mail XML/NFe", 450, y, 230, inputH);
|
||||
txtSite = AddInput(content, "Site", 690, y, 250, inputH);
|
||||
y += rowH;
|
||||
|
||||
txtTelefone1 = AddInput(content, "Telefone 1", 20, y, 155, inputH);
|
||||
txtTelefone2 = AddInput(content, "Telefone 2", 185, y, 155, inputH);
|
||||
txtCelular = AddInput(content, "Celular", 350, y, 155, inputH);
|
||||
txtWhatsapp = AddInput(content, "WhatsApp", 515, y, 155, inputH);
|
||||
y += rowH;
|
||||
|
||||
// ── 3. ENDEREÇO COMPLETO ──────────────────────────────────────────
|
||||
y += secGap;
|
||||
content.Controls.Add(CreateSectionHeader("ENDEREÇO COMPLETO", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtCep = AddInput(content, "CEP", 20, y, 95, inputH);
|
||||
txtCep.Leave += (s, e) =>
|
||||
{
|
||||
string cep = txtCep.Text.Trim().Replace("-", "");
|
||||
|
||||
if (cep.Length != 8) return;
|
||||
|
||||
if (TLL.VerifyCep.verificaCEP(cep))
|
||||
{
|
||||
txtEndereco.Text = TLL.VerifyCep.endereco;
|
||||
txtBairro.Text = TLL.VerifyCep.bairro;
|
||||
txtCidade.Text = TLL.VerifyCep.cidade;
|
||||
txtUF.Text = TLL.VerifyCep.estado;
|
||||
|
||||
// Formata o CEP com hífen
|
||||
txtCep.Text = $"{cep[..5]}-{cep[5..]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
NT_MessageBox.Show("CEP não encontrado.", "CEP",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
};//cep
|
||||
txtEndereco = AddInput(content, "Logradouro", 125, y, 370, inputH);
|
||||
txtNumero = AddInput(content, "Nº", 505, y, 60, inputH);
|
||||
txtComplemento = AddInput(content, "Complemento", 575, y, 175, inputH);
|
||||
txtBairro = AddInput(content, "Bairro", 760, y, 180, inputH);
|
||||
y += rowH;
|
||||
|
||||
txtCidade = AddInput(content, "Cidade", 20, y, 280, inputH);
|
||||
txtUF = AddInput(content, "UF", 310, y, 55, inputH);
|
||||
txtPais = AddInput(content, "País", 375, y, 150, inputH);
|
||||
y += rowH;
|
||||
|
||||
// ── 4. FINANCEIRO ─────────────────────────────────────────────────
|
||||
y += secGap;
|
||||
content.Controls.Add(CreateSectionHeader("FINANCEIRO", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtLimiteCredito = AddInput(content, "Limite de Crédito", 20, y, 150, inputH);
|
||||
txtVendedorPadraoId = AddInput(content, "Vendedor Padrão ID", 180, y, 120, inputH);
|
||||
txtObservacoesCobranca = AddInput(content, "Obs. de Cobrança", 310, y, 380, inputH);
|
||||
|
||||
chkBloqueado = CreateCheckBox("Bloqueado", 705, y + 18);
|
||||
chkAtivo = CreateCheckBox("Ativo", 805, y + 18);
|
||||
content.Controls.Add(chkBloqueado);
|
||||
content.Controls.Add(chkAtivo);
|
||||
y += rowH;
|
||||
|
||||
// ── 5. CARTEIRAS DIGITAIS ─────────────────────────────────────────
|
||||
y += secGap;
|
||||
content.Controls.Add(CreateSectionHeader("CARTEIRAS DIGITAIS", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtBitcoin = AddInput(content, "Bitcoin (BTC)", 20, y, 290, inputH);
|
||||
txtEthereum = AddInput(content, "Ethereum (ETH)", 320, y, 290, inputH);
|
||||
txtLitecoin = AddInput(content, "Litecoin (LTC)", 620, y, 290, inputH);
|
||||
y += rowH;
|
||||
|
||||
// ── 6. CAMPOS EXTRAS ──────────────────────────────────────────────
|
||||
y += secGap;
|
||||
content.Controls.Add(CreateSectionHeader("CAMPOS EXTRAS", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtCampoExtra1 = AddInput(content, "Campo Extra 1", 20, y, 290, inputH);
|
||||
txtCampoExtra2 = AddInput(content, "Campo Extra 2", 320, y, 290, inputH);
|
||||
txtCampoExtra3 = AddInput(content, "Campo Extra 3", 620, y, 290, inputH);
|
||||
y += rowH;
|
||||
|
||||
// ── 7. OBSERVAÇÕES ────────────────────────────────────────────────
|
||||
y += secGap;
|
||||
content.Controls.Add(CreateSectionHeader("OBSERVAÇÕES", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtObservacoes = AddInput(content, "Observações Internas", 20, y, 920, inputH);
|
||||
y += rowH;
|
||||
|
||||
// ── 8. INFORMAÇÕES DO REGISTRO ────────────────────────────────────
|
||||
y += secGap;
|
||||
content.Controls.Add(CreateSectionHeader("INFORMAÇÕES DO REGISTRO", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtUltimaCompra = AddInput(content, "Última Compra", 20, y, 175, inputH, readOnly: true);
|
||||
txtCriadoEm = AddInput(content, "Criado Em", 205, y, 175, inputH, readOnly: true);
|
||||
txtAtualizadoEm = AddInput(content, "Atualizado Em", 390, y, 175, inputH, readOnly: true);
|
||||
y += rowH;
|
||||
|
||||
content.Height = y + 10;
|
||||
}
|
||||
|
||||
// ── EVENTOS ───────────────────────────────────────────────────────────
|
||||
|
||||
private void BtnNovo_Click()
|
||||
{
|
||||
foreach (var campo in TodosOsCampos())
|
||||
campo.Text = string.Empty;
|
||||
|
||||
chkBloqueado.Checked = false;
|
||||
chkAtivo.Checked = true;
|
||||
|
||||
SetCampos(true);
|
||||
txtId.Enabled = false;
|
||||
txtId.BackColor = Color.FromArgb(241, 245, 249);
|
||||
this.CarregarConfiguracoesSistema();
|
||||
txtEmpresaId.Enabled = false;
|
||||
txtEmpresaId.BackColor = Color.FromArgb(241, 245, 249);
|
||||
}
|
||||
|
||||
private void BtnAlterar_Click()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(txtId.Text))
|
||||
{
|
||||
MessageBox.Show(
|
||||
"Nenhum registro selecionado para alterar.",
|
||||
"Atenção",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
SetCampos(true);
|
||||
txtId.Enabled = false;
|
||||
txtId.BackColor = Color.FromArgb(241, 245, 249);
|
||||
txtEmpresaId.Enabled = false;
|
||||
txtEmpresaId.BackColor = Color.FromArgb(241, 245, 249);
|
||||
}
|
||||
|
||||
private void BtnExcluir_Click()
|
||||
{
|
||||
// Solicita confirmação e exclui o registro atual
|
||||
}
|
||||
|
||||
private void BtnLocalizar_Click()
|
||||
{
|
||||
// Abre tela/diálogo de busca e preenche os campos
|
||||
}
|
||||
|
||||
private void BtnSalvar_Click()
|
||||
{
|
||||
var bll = new BLLClientes(_connectionString);
|
||||
|
||||
// 🔒 validação básica front
|
||||
if (string.IsNullOrWhiteSpace(txtNome.Text) ||
|
||||
string.IsNullOrWhiteSpace(txtDocumento.Text))
|
||||
{
|
||||
NT_MessageBox.Show("Preencha ao menos Nome e Documento.",
|
||||
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
bool isNew = string.IsNullOrWhiteSpace(txtId.Text);
|
||||
|
||||
var cliente = new ModeloCliente
|
||||
{
|
||||
Id = isNew ? 0 : int.Parse(txtId.Text),
|
||||
EmpresaId = int.TryParse(txtEmpresaId.Text, out var emp) ? emp : 0,
|
||||
|
||||
Nome = txtNome.Text,
|
||||
NomeFantasia = txtNomeFantasia.Text,
|
||||
TipoPessoa = txtTipoPessoa.Text,
|
||||
Documento = txtDocumento.Text,
|
||||
|
||||
RG = txtRG.Text,
|
||||
InscricaoMunicipal = txtInscricaoMunicipal.Text,
|
||||
DataNascimento = ConverterData(txtDataNascimento.Text),
|
||||
|
||||
Contato = txtContato.Text,
|
||||
Telefone1 = txtTelefone1.Text,
|
||||
Telefone2 = txtTelefone2.Text,
|
||||
Celular = txtCelular.Text,
|
||||
Whatsapp = txtWhatsapp.Text,
|
||||
Email = txtEmail.Text,
|
||||
EmailNFe = txtEmailNFe.Text,
|
||||
Site = txtSite.Text,
|
||||
|
||||
Grupo = txtGrupo.Text,
|
||||
|
||||
Cep = txtCep.Text,
|
||||
Endereco = txtEndereco.Text,
|
||||
Numero = int.TryParse(txtNumero.Text, out var num) ? num : null,
|
||||
Complemento = txtComplemento.Text,
|
||||
Bairro = txtBairro.Text,
|
||||
Cidade = txtCidade.Text,
|
||||
UF = txtUF.Text,
|
||||
Pais = txtPais.Text,
|
||||
|
||||
LimiteCredito = decimal.TryParse(txtLimiteCredito.Text, out var lim) ? lim : 0,
|
||||
Bloqueado = chkBloqueado.Checked,
|
||||
ObservacoesCobranca = txtObservacoesCobranca.Text,
|
||||
|
||||
VendedorPadraoId = int.TryParse(txtVendedorPadraoId.Text, out var vend) ? vend : null,
|
||||
TipoConsumidor = txtTipoConsumidor.Text,
|
||||
|
||||
Observacoes = txtObservacoes.Text,
|
||||
|
||||
CampoExtra1 = txtCampoExtra1.Text,
|
||||
CampoExtra2 = txtCampoExtra2.Text,
|
||||
CampoExtra3 = txtCampoExtra3.Text,
|
||||
|
||||
Bitcoin = txtBitcoin.Text,
|
||||
Ethereum = txtEthereum.Text,
|
||||
Litecoin = txtLitecoin.Text,
|
||||
|
||||
Ativo = chkAtivo.Checked,
|
||||
UltimaCompra = ConverterData(txtUltimaCompra.Text),
|
||||
|
||||
// 🔥 esses o banco já gera, mas mantém compatível
|
||||
CriadoEm = DateTime.Now,
|
||||
AtualizadoEm = DateTime.Now
|
||||
};
|
||||
|
||||
bool sucesso = false;
|
||||
|
||||
try
|
||||
{
|
||||
sucesso = isNew
|
||||
? bll.Inserir(cliente)
|
||||
: bll.Alterar(cliente);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
NT_MessageBox.Show(ex.Message,
|
||||
"Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sucesso)
|
||||
{
|
||||
NT_MessageBox.Show("Erro ao salvar cliente.",
|
||||
"Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
SetCampos(false);
|
||||
|
||||
NT_MessageBox.Show("Cliente salvo com sucesso!",
|
||||
"Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
private void BtnCancelar_Click()
|
||||
{
|
||||
foreach (var campo in TodosOsCampos())
|
||||
campo.Text = string.Empty;
|
||||
|
||||
chkBloqueado.Checked = false;
|
||||
chkAtivo.Checked = false;
|
||||
|
||||
SetCampos(false);
|
||||
}
|
||||
|
||||
// ── HELPERS ───────────────────────────────────────────────────────────
|
||||
|
||||
private Panel CreateSectionHeader(string title, int y)
|
||||
{
|
||||
var pnl = new Panel { Location = new Point(20, y), Width = 1000, Height = 26 };
|
||||
var lbl = new Label
|
||||
{
|
||||
Text = title,
|
||||
Font = new Font("Segoe UI", 8.5f, FontStyle.Bold),
|
||||
ForeColor = AccentBlue,
|
||||
AutoSize = true,
|
||||
Location = new Point(0, 0)
|
||||
};
|
||||
var line = new Panel
|
||||
{
|
||||
BackColor = BorderColor,
|
||||
Height = 1,
|
||||
Width = 980,
|
||||
Location = new Point(0, 20)
|
||||
};
|
||||
pnl.Controls.Add(lbl);
|
||||
pnl.Controls.Add(line);
|
||||
return pnl;
|
||||
}
|
||||
|
||||
private RoundTextBox AddInput(Control parent, string label,
|
||||
int x, int y, int width, int height,
|
||||
bool readOnly = false)
|
||||
{
|
||||
var lbl = new Label
|
||||
{
|
||||
Text = label,
|
||||
Location = new Point(x, y),
|
||||
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
|
||||
ForeColor = readOnly ? Color.Gray : TextDark,
|
||||
AutoSize = true
|
||||
};
|
||||
var txt = new RoundTextBox
|
||||
{
|
||||
Location = new Point(x, y + 16),
|
||||
Size = new Size(width, height),
|
||||
Radius = 4,
|
||||
BorderColor = readOnly ? Color.FromArgb(203, 213, 225) : BorderColor,
|
||||
FocusColor = AccentBlue,
|
||||
ReadOnly = readOnly,
|
||||
BackColor = readOnly ? Color.FromArgb(241, 245, 249) : Color.White
|
||||
};
|
||||
parent.Controls.Add(lbl);
|
||||
parent.Controls.Add(txt);
|
||||
return txt;
|
||||
}
|
||||
|
||||
private CheckBox CreateCheckBox(string text, int x, int y) => new CheckBox
|
||||
{
|
||||
Text = text,
|
||||
Location = new Point(x, y),
|
||||
Font = new Font("Segoe UI", 8.5f, FontStyle.Bold),
|
||||
ForeColor = TextDark,
|
||||
AutoSize = true
|
||||
};
|
||||
|
||||
private RoundButton CreateToolbarButton(string text, Color color) => new RoundButton
|
||||
{
|
||||
Text = text,
|
||||
Size = new Size(95, 32),
|
||||
BackColor = color,
|
||||
ForeColor = Color.White,
|
||||
Font = new Font("Segoe UI Semibold", 8.5f),
|
||||
Margin = new Padding(0, 0, 6, 0),
|
||||
Cursor = Cursors.Hand
|
||||
};
|
||||
}
|
||||
}
|
||||
120
Dashboards/Cadastros/ClienteCadastroPanel.resx
Normal file
120
Dashboards/Cadastros/ClienteCadastroPanel.resx
Normal 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>
|
||||
526
Dashboards/Cadastros/EmpresaCadastroPanel.cs
Normal file
526
Dashboards/Cadastros/EmpresaCadastroPanel.cs
Normal file
@ -0,0 +1,526 @@
|
||||
using BLL;
|
||||
using CustomMessageBox;
|
||||
using DAL;
|
||||
using MLL;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class EmpresaCadastroPanel : UserControl
|
||||
{
|
||||
private string _cx = DadosDaConexao.ObterConexao();
|
||||
private readonly Color AccentBlue = Color.FromArgb(37, 99, 235);
|
||||
private readonly Color TextDark = Color.FromArgb(30, 41, 59);
|
||||
private readonly Color BorderColor = Color.FromArgb(226, 232, 240);
|
||||
|
||||
private Panel pnlToolbar = null!;
|
||||
private Panel mainScroll = null!;
|
||||
private Panel content = null!;
|
||||
|
||||
// Identificação
|
||||
private RoundTextBox txtId = null!, txtNome = null!, txtCNPJ = null!;
|
||||
private RoundTextBox txtTipoEmpresa = null!, txtRegimeTributario = null!, txtCNAE = null!;
|
||||
|
||||
// Endereço
|
||||
private RoundTextBox txtCep = null!, txtEndereco = null!, txtNumero = null!, txtComplemento = null!;
|
||||
private RoundTextBox txtBairro = null!, txtCidade = null!, txtUF = null!, txtPais = null!;
|
||||
|
||||
// Contatos
|
||||
private RoundTextBox txtTelefone1 = null!, txtTelefone2 = null!, txtCelular = null!, txtWhatsapp = null!;
|
||||
private RoundTextBox txtEmail = null!, txtSite = null!;
|
||||
|
||||
// Fiscal
|
||||
private RoundTextBox txtInscricaoEstadual = null!, txtInscricaoMunicipal = null!;
|
||||
|
||||
// Contador
|
||||
private RoundTextBox txtCNPJCPF_Contador = null!, txtNome_Contador = null!;
|
||||
|
||||
// Outros
|
||||
private RoundTextBox txtTextoParaRecibo = null!;
|
||||
private CheckBox chkAtivo = null!;
|
||||
|
||||
// Info (readonly)
|
||||
private RoundTextBox txtCriadoEm = null!, txtAtualizadoEm = null!;
|
||||
|
||||
//Carregar dados da empresa atual, se houver no banco de dados
|
||||
private void CarregarEmpresaAtiva()
|
||||
{
|
||||
var bll = new BLLEmpresa(_cx);
|
||||
var empresa = bll.CarregarEmpresaAtiva();
|
||||
|
||||
if (empresa == null)
|
||||
{
|
||||
MessageBox.Show("Nenhuma empresa ativa encontrada.",
|
||||
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// Preenche todos os campos do formulário
|
||||
txtId.Text = empresa.Id.ToString();
|
||||
txtNome.Text = empresa.Nome;
|
||||
txtCNPJ.Text = empresa.CNPJ;
|
||||
txtTipoEmpresa.Text = empresa.TipoEmpresa;
|
||||
txtRegimeTributario.Text = empresa.RegimeTributario;
|
||||
txtCNAE.Text = empresa.CNAE;
|
||||
txtInscricaoEstadual.Text = empresa.InscricaoEstadual;
|
||||
txtInscricaoMunicipal.Text = empresa.InscricaoMunicipal;
|
||||
txtCep.Text = empresa.Cep;
|
||||
txtEndereco.Text = empresa.Endereco;
|
||||
txtNumero.Text = empresa.Numero.ToString();
|
||||
txtComplemento.Text = empresa.Complemento;
|
||||
txtBairro.Text = empresa.Bairro;
|
||||
txtCidade.Text = empresa.Cidade;
|
||||
txtUF.Text = empresa.UF;
|
||||
txtPais.Text = empresa.Pais;
|
||||
txtTelefone1.Text = empresa.Telefone1;
|
||||
txtTelefone2.Text = empresa.Telefone2;
|
||||
txtCelular.Text = empresa.Celular;
|
||||
txtWhatsapp.Text = empresa.Whatsapp;
|
||||
txtEmail.Text = empresa.Email;
|
||||
txtSite.Text = empresa.Site;
|
||||
txtCNPJCPF_Contador.Text = empresa.CNPJCPF_Contador;
|
||||
txtNome_Contador.Text = empresa.Nome_Contador;
|
||||
txtTextoParaRecibo.Text = empresa.TextoParaRecibo;
|
||||
chkAtivo.Checked = empresa.Ativo;
|
||||
txtCriadoEm.Text = empresa.CriadoEm.ToString("dd/MM/yyyy");
|
||||
txtAtualizadoEm.Text = empresa.AtualizadoEm.ToString("dd/MM/yyyy");
|
||||
}
|
||||
public EmpresaCadastroPanel()
|
||||
{
|
||||
Dock = DockStyle.Fill;
|
||||
BackColor = Color.White;
|
||||
DoubleBuffered = true;
|
||||
InitializeLayout();
|
||||
// Carregar dados da empresa atual, se houver
|
||||
CarregarEmpresaAtiva();
|
||||
}
|
||||
|
||||
private void InitializeLayout()
|
||||
{
|
||||
this.Controls.Clear();
|
||||
|
||||
// ── TOOLBAR ───────────────────────────────────────────────────────
|
||||
pnlToolbar = new Panel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
Height = 55,
|
||||
BackColor = Color.FromArgb(248, 250, 252),
|
||||
BorderStyle = BorderStyle.None
|
||||
};
|
||||
|
||||
var flowButtons = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Padding = new Padding(12, 10, 0, 0),
|
||||
BackColor = Color.Transparent
|
||||
};
|
||||
|
||||
var btnNovo = CreateToolbarButton("Novo", Color.FromArgb(34, 197, 94));
|
||||
var btnAlterar = CreateToolbarButton("Alterar", Color.FromArgb(245, 158, 11));
|
||||
var btnExcluir = CreateToolbarButton("Excluir", Color.FromArgb(239, 68, 68));
|
||||
var btnLocalizar = CreateToolbarButton("Localizar", AccentBlue);
|
||||
var btnSalvar = CreateToolbarButton("Salvar", AccentBlue);
|
||||
var btnCancelar = CreateToolbarButton("Cancelar", Color.FromArgb(148, 163, 184));
|
||||
var btnCriarCert = CreateToolbarButton("Certificado", Color.FromArgb(148, 160, 184));
|
||||
var btnGerarFichaPDF = CreateToolbarButton("Ficha Tecnica", Color.FromArgb(255, 0, 0));
|
||||
|
||||
btnNovo.Click += (s, e) => BtnNovo_Click();
|
||||
btnAlterar.Click += (s, e) => BtnAlterar_Click();
|
||||
btnExcluir.Click += (s, e) => BtnExcluir_Click();
|
||||
btnLocalizar.Click += (s, e) => BtnLocalizar_Click();
|
||||
btnSalvar.Click += (s, e) => BtnSalvar_Click();
|
||||
btnCancelar.Click += (s, e) => BtnCancelar_Click();
|
||||
btnCriarCert.Click += (s, e) => BtnGerarCertificado_Click();
|
||||
btnGerarFichaPDF.Click += (s, e) => BtnFicha_Click();
|
||||
|
||||
flowButtons.Controls.AddRange(new Control[]
|
||||
{ btnNovo, btnAlterar, btnExcluir, btnLocalizar, btnSalvar, btnCancelar,btnCriarCert,btnGerarFichaPDF });
|
||||
pnlToolbar.Controls.Add(flowButtons);
|
||||
this.Controls.Add(pnlToolbar);
|
||||
|
||||
// ── SCROLL + CONTENT ──────────────────────────────────────────────
|
||||
mainScroll = new Panel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
AutoScroll = true,
|
||||
BackColor = Color.White
|
||||
};
|
||||
this.Controls.Add(mainScroll);
|
||||
mainScroll.BringToFront();
|
||||
|
||||
content = new Panel
|
||||
{
|
||||
Width = 1100,
|
||||
Height = 900,
|
||||
Location = new Point(0, 0),
|
||||
BackColor = Color.White
|
||||
};
|
||||
mainScroll.Controls.Add(content);
|
||||
|
||||
const int rowH = 52;
|
||||
const int secGap = 10;
|
||||
const int secH = 28;
|
||||
const int inputH = 28;
|
||||
|
||||
int y = 10;
|
||||
|
||||
// ── 1. IDENTIFICAÇÃO DA EMPRESA ───────────────────────────────────
|
||||
content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO DA EMPRESA", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtId = AddInput(content, "ID", 20, y, 60, inputH, readOnly: true);
|
||||
txtNome = AddInput(content, "Nome / Razão Social", 90, y, 450, inputH);
|
||||
txtCNPJ = AddInput(content, "CNPJ", 550, y, 180, inputH);
|
||||
DocumentoHelper.Registrar(txtCNPJ);
|
||||
txtTipoEmpresa = AddInput(content, "Tipo Empresa", 740, y, 200, inputH);
|
||||
y += rowH;
|
||||
|
||||
txtRegimeTributario = AddInput(content, "Regime Tributário", 20, y, 200, inputH);
|
||||
txtCNAE = AddInput(content, "CNAE", 230, y, 150, inputH);
|
||||
txtInscricaoEstadual = AddInput(content, "Inscrição Estadual", 390, y, 200, inputH);
|
||||
txtInscricaoMunicipal = AddInput(content, "Inscrição Municipal", 600, y, 200, inputH);
|
||||
|
||||
// ── 2. ENDEREÇO COMPLETO ──────────────────────────────────────────
|
||||
y += rowH + secGap;
|
||||
content.Controls.Add(CreateSectionHeader("ENDEREÇO COMPLETO", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtCep = AddInput(content, "CEP", 20, y, 95, inputH);
|
||||
// No InitializeLayout(), após criar o txtCep
|
||||
txtCep.Leave += (s, e) =>
|
||||
{
|
||||
string cep = txtCep.Text.Trim().Replace("-", "");
|
||||
|
||||
if (cep.Length != 8) return;
|
||||
|
||||
if (TLL.VerifyCep.verificaCEP(cep))
|
||||
{
|
||||
txtEndereco.Text = TLL.VerifyCep.endereco;
|
||||
txtBairro.Text = TLL.VerifyCep.bairro;
|
||||
txtCidade.Text = TLL.VerifyCep.cidade;
|
||||
txtUF.Text = TLL.VerifyCep.estado;
|
||||
txtPais.Text = "Brasil";
|
||||
|
||||
// Formata o CEP com hífen
|
||||
txtCep.Text = $"{cep[..5]}-{cep[5..]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
NT_MessageBox.Show("CEP não encontrado.", "CEP",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
};
|
||||
txtEndereco = AddInput(content, "Logradouro", 125, y, 370, inputH);
|
||||
txtNumero = AddInput(content, "Nº", 505, y, 60, inputH);
|
||||
txtComplemento = AddInput(content, "Complemento", 575, y, 175, inputH);
|
||||
txtBairro = AddInput(content, "Bairro", 760, y, 180, inputH);
|
||||
y += rowH;
|
||||
|
||||
txtCidade = AddInput(content, "Cidade", 20, y, 280, inputH);
|
||||
txtUF = AddInput(content, "UF", 310, y, 55, inputH);
|
||||
txtPais = AddInput(content, "País", 375, y, 150, inputH);
|
||||
|
||||
// ── 3. CONTATOS E COMUNICAÇÃO ─────────────────────────────────────
|
||||
y += rowH + secGap;
|
||||
content.Controls.Add(CreateSectionHeader("CONTATOS E COMUNICAÇÃO", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtTelefone1 = AddInput(content, "Telefone 1", 20, y, 155, inputH);
|
||||
txtTelefone2 = AddInput(content, "Telefone 2", 185, y, 155, inputH);
|
||||
txtCelular = AddInput(content, "Celular", 350, y, 155, inputH);
|
||||
txtWhatsapp = AddInput(content, "WhatsApp", 515, y, 155, inputH);
|
||||
y += rowH;
|
||||
|
||||
txtEmail = AddInput(content, "E-mail", 20, y, 350, inputH);
|
||||
txtSite = AddInput(content, "Site", 380, y, 290, inputH);
|
||||
|
||||
// ── 4. DADOS DO CONTADOR ──────────────────────────────────────────
|
||||
y += rowH + secGap;
|
||||
content.Controls.Add(CreateSectionHeader("DADOS DO CONTADOR", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtCNPJCPF_Contador = AddInput(content, "CPF/CNPJ do Contador", 20, y, 200, inputH);
|
||||
DocumentoHelper.Registrar(txtCNPJCPF_Contador);
|
||||
txtNome_Contador = AddInput(content, "Nome do Contador", 230, y, 400, inputH);
|
||||
|
||||
// ── 5. OUTROS ─────────────────────────────────────────────────────
|
||||
y += rowH + secGap;
|
||||
content.Controls.Add(CreateSectionHeader("OUTROS", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtTextoParaRecibo = AddInput(content, "Texto para Recibo", 20, y, 920, inputH);
|
||||
y += rowH;
|
||||
txtTextoParaRecibo.Multiline = true;
|
||||
|
||||
|
||||
chkAtivo = CreateCheckBox("Ativo", 20, y);
|
||||
content.Controls.Add(chkAtivo);
|
||||
|
||||
// ── 6. INFORMAÇÕES DO REGISTRO ────────────────────────────────────
|
||||
y += 35 + secGap;
|
||||
content.Controls.Add(CreateSectionHeader("INFORMAÇÕES DO REGISTRO", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtCriadoEm = AddInput(content, "Criado Em", 20, y, 175, inputH, readOnly: true);
|
||||
txtAtualizadoEm = AddInput(content, "Atualizado Em", 205, y, 175, inputH, readOnly: true);
|
||||
y += rowH;
|
||||
|
||||
content.Height = y + 10;
|
||||
|
||||
SetCampos(false);
|
||||
}
|
||||
|
||||
// ── CAMPOS ────────────────────────────────────────────────────────────
|
||||
|
||||
private RoundTextBox[] TodosOsCampos() => new[]
|
||||
{
|
||||
txtNome, txtCNPJ, txtTipoEmpresa, txtRegimeTributario, txtCNAE,
|
||||
txtInscricaoEstadual, txtInscricaoMunicipal,
|
||||
txtCep, txtEndereco, txtNumero, txtComplemento,
|
||||
txtBairro, txtCidade, txtUF, txtPais,
|
||||
txtTelefone1, txtTelefone2, txtCelular, txtWhatsapp,
|
||||
txtEmail, txtSite,
|
||||
txtCNPJCPF_Contador, txtNome_Contador,
|
||||
txtTextoParaRecibo
|
||||
};
|
||||
|
||||
private void SetCampos(bool enabled)
|
||||
{
|
||||
foreach (var campo in TodosOsCampos())
|
||||
{
|
||||
campo.Enabled = enabled;
|
||||
campo.BackColor = enabled ? Color.White : Color.FromArgb(241, 245, 249);
|
||||
}
|
||||
chkAtivo.Enabled = enabled;
|
||||
}
|
||||
|
||||
// ── EVENTOS ───────────────────────────────────────────────────────────
|
||||
|
||||
private void BtnNovo_Click()
|
||||
{
|
||||
foreach (var campo in TodosOsCampos())
|
||||
campo.Text = string.Empty;
|
||||
|
||||
chkAtivo.Checked = true;
|
||||
SetCampos(true);
|
||||
}
|
||||
|
||||
private void BtnAlterar_Click()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(txtId.Text))
|
||||
{
|
||||
MessageBox.Show(
|
||||
"Nenhum registro selecionado para alterar.",
|
||||
"Atenção",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
SetCampos(true);
|
||||
txtId.Enabled = false;
|
||||
txtId.BackColor = Color.FromArgb(241, 245, 249);
|
||||
}
|
||||
// Evento
|
||||
private void BtnFicha_Click()
|
||||
{
|
||||
var bll = new BLLEmpresa(_cx);
|
||||
var empresa = bll.CarregarEmpresaAtiva();
|
||||
|
||||
if (empresa == null)
|
||||
{
|
||||
MessageBox.Show("Nenhuma empresa ativa encontrada.");
|
||||
return;
|
||||
}
|
||||
|
||||
var resultado = TLL.FichaEmpresaPDF.GerarEAbrir(empresa);
|
||||
|
||||
if (!resultado.Sucesso)
|
||||
MessageBox.Show(resultado.Mensagem, "Erro",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
private void BtnExcluir_Click()
|
||||
{
|
||||
// Solicita confirmação e exclui o registro atual
|
||||
}
|
||||
|
||||
private void BtnLocalizar_Click()
|
||||
{
|
||||
// Abre tela/diálogo de busca e preenche os campos
|
||||
}
|
||||
private void BtnGerarCertificado_Click()
|
||||
{
|
||||
ModeloEmpresa empresa = new ModeloEmpresa();
|
||||
// Após salvar a empresa com sucesso...
|
||||
var resultado = TLL.CertificadoHelper.Gerar(empresa, "Nike12122020*##");
|
||||
|
||||
if (resultado.Sucesso)
|
||||
NT_MessageBox.Show(
|
||||
$"Certificado gerado!\nVálido até: {resultado.ValidoAte:dd/MM/yyyy}\n" +
|
||||
$"Thumbprint: {resultado.Thumbprint}",
|
||||
"Certificado", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
else
|
||||
NT_MessageBox.Show(resultado.Mensagem, "Erro",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
private void BtnVerificarCert_Click()
|
||||
{
|
||||
ModeloEmpresa empresa = new ModeloEmpresa();
|
||||
var status = TLL.CertificadoHelper.VerificarStatus(empresa.CNPJ, "Nike12122020*##");
|
||||
|
||||
if (!status.Valido)
|
||||
NT_MessageBox.Show("Certificado expirado! Gere um novo.",
|
||||
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
|
||||
private void BtnSalvar_Click()
|
||||
{
|
||||
BLLEmpresa _empresaBLL = new BLLEmpresa(_cx);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(txtNome.Text) ||
|
||||
string.IsNullOrWhiteSpace(txtCNPJ.Text) ||
|
||||
string.IsNullOrWhiteSpace(txtEmail.Text))
|
||||
{
|
||||
NT_MessageBox.Show("Preencha ao menos Nome, CNPJ e Email.",
|
||||
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
bool isNew = string.IsNullOrWhiteSpace(txtId.Text);
|
||||
|
||||
var empresa = new MLL.ModeloEmpresa(
|
||||
id: isNew ? 0 : int.Parse(txtId.Text),
|
||||
nome: txtNome.Text,
|
||||
cNPJ: txtCNPJ.Text,
|
||||
tipoEmpresa: txtTipoEmpresa.Text,
|
||||
regimeTributario: txtRegimeTributario.Text,
|
||||
cNAE: txtCNAE.Text,
|
||||
cep: txtCep.Text,
|
||||
endereco: txtEndereco.Text,
|
||||
numero: string.IsNullOrWhiteSpace(txtNumero.Text) ? 0 : int.Parse(txtNumero.Text),
|
||||
complemento: txtComplemento.Text,
|
||||
bairro: txtBairro.Text,
|
||||
cidade: txtCidade.Text,
|
||||
uF: txtUF.Text,
|
||||
pais: txtPais.Text,
|
||||
telefone1: txtTelefone1.Text,
|
||||
telefone2: txtTelefone2.Text,
|
||||
celular: txtCelular.Text,
|
||||
whatsapp: txtWhatsapp.Text,
|
||||
email: txtEmail.Text,
|
||||
site: txtSite.Text,
|
||||
inscricaoEstadual: txtInscricaoEstadual.Text,
|
||||
inscricaoMunicipal: txtInscricaoMunicipal.Text,
|
||||
cNPJCPF_Contador: txtCNPJCPF_Contador.Text,
|
||||
nome_Contador: txtNome_Contador.Text,
|
||||
textoParaRecibo: txtTextoParaRecibo.Text,
|
||||
ativo: chkAtivo.Checked,
|
||||
criadoEm: DateTime.Now,
|
||||
atualizadoEm: DateTime.Now
|
||||
);
|
||||
|
||||
bool sucesso;
|
||||
|
||||
if (isNew)
|
||||
sucesso = _empresaBLL.Inserir(empresa);
|
||||
else
|
||||
sucesso = _empresaBLL.Alterar(empresa);
|
||||
|
||||
if (!sucesso)
|
||||
{
|
||||
NT_MessageBox.Show("Erro ao salvar empresa.",
|
||||
"Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
// 🔹 Atualiza UI
|
||||
txtAtualizadoEm.Text = DateTime.Now.ToString("dd/MM/yyyy");
|
||||
SetCampos(false);
|
||||
|
||||
NT_MessageBox.Show("Empresa salva com sucesso!", "Sucesso",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
private void BtnCancelar_Click()
|
||||
{
|
||||
foreach (var campo in TodosOsCampos())
|
||||
campo.Text = string.Empty;
|
||||
|
||||
chkAtivo.Checked = false;
|
||||
SetCampos(false);
|
||||
}
|
||||
|
||||
// ── HELPERS ───────────────────────────────────────────────────────────
|
||||
|
||||
private Panel CreateSectionHeader(string title, int y)
|
||||
{
|
||||
var pnl = new Panel { Location = new Point(20, y), Width = 1000, Height = 26 };
|
||||
var lbl = new Label
|
||||
{
|
||||
Text = title,
|
||||
Font = new Font("Segoe UI", 8.5f, FontStyle.Bold),
|
||||
ForeColor = AccentBlue,
|
||||
AutoSize = true,
|
||||
Location = new Point(0, 0)
|
||||
};
|
||||
var line = new Panel
|
||||
{
|
||||
BackColor = BorderColor,
|
||||
Height = 1,
|
||||
Width = 980,
|
||||
Location = new Point(0, 20)
|
||||
};
|
||||
pnl.Controls.Add(lbl);
|
||||
pnl.Controls.Add(line);
|
||||
return pnl;
|
||||
}
|
||||
|
||||
private RoundTextBox AddInput(Control parent, string label,
|
||||
int x, int y, int width, int height,
|
||||
bool readOnly = false)
|
||||
{
|
||||
var lbl = new Label
|
||||
{
|
||||
Text = label,
|
||||
Location = new Point(x, y),
|
||||
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
|
||||
ForeColor = readOnly ? Color.Gray : TextDark,
|
||||
AutoSize = true
|
||||
};
|
||||
var txt = new RoundTextBox
|
||||
{
|
||||
Location = new Point(x, y + 16),
|
||||
Size = new Size(width, height),
|
||||
Radius = 4,
|
||||
BorderColor = readOnly ? Color.FromArgb(203, 213, 225) : BorderColor,
|
||||
FocusColor = AccentBlue,
|
||||
ReadOnly = readOnly,
|
||||
BackColor = readOnly ? Color.FromArgb(241, 245, 249) : Color.White
|
||||
};
|
||||
parent.Controls.Add(lbl);
|
||||
parent.Controls.Add(txt);
|
||||
return txt;
|
||||
}
|
||||
|
||||
private CheckBox CreateCheckBox(string text, int x, int y) => new CheckBox
|
||||
{
|
||||
Text = text,
|
||||
Location = new Point(x, y),
|
||||
Font = new Font("Segoe UI", 8.5f, FontStyle.Bold),
|
||||
ForeColor = TextDark,
|
||||
AutoSize = true
|
||||
};
|
||||
|
||||
private RoundButton CreateToolbarButton(string text, Color color) => new RoundButton
|
||||
{
|
||||
Text = text,
|
||||
Size = new Size(95, 32),
|
||||
BackColor = color,
|
||||
ForeColor = Color.White,
|
||||
Font = new Font("Segoe UI Semibold", 8.5f),
|
||||
Margin = new Padding(0, 0, 6, 0),
|
||||
Cursor = Cursors.Hand
|
||||
};
|
||||
}
|
||||
}
|
||||
120
Dashboards/Cadastros/EmpresaCadastroPanel.resx
Normal file
120
Dashboards/Cadastros/EmpresaCadastroPanel.resx
Normal 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>
|
||||
591
Dashboards/Cadastros/EmpresaConfiguracoesPanel.cs
Normal file
591
Dashboards/Cadastros/EmpresaConfiguracoesPanel.cs
Normal file
@ -0,0 +1,591 @@
|
||||
using BLL;
|
||||
using CCH;
|
||||
using CustomMessageBox;
|
||||
using DAL;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class EmpresaConfiguracoesPanel : UserControl
|
||||
{
|
||||
//Variaveis de ambiente
|
||||
private int _idEmpresa;
|
||||
private int _idConfig;
|
||||
private string _connectionString = DadosDaConexao.ObterConexao();
|
||||
|
||||
private readonly Color AccentBlue = Color.FromArgb(37, 99, 235);
|
||||
private readonly Color TextDark = Color.FromArgb(30, 41, 59);
|
||||
private readonly Color BorderColor = Color.FromArgb(226, 232, 240);
|
||||
|
||||
private Panel pnlToolbar = null!;
|
||||
private Panel mainScroll = null!;
|
||||
private Panel content = null!;
|
||||
|
||||
private RoundTextBox txtId = null!, txtEmpresaId = null!, txtNomeSistema = null!;
|
||||
private RoundTextBox txtCorPrimaria = null!, txtCorSecundaria = null!;
|
||||
private RoundTextBox txtLogo = null!, txtFavicon = null!;
|
||||
private RoundTextBox txtDiasGarantiaPadrao = null!;
|
||||
|
||||
private CheckBox chkExibirCPF = null!, chkExibirTelefone = null!, chkExibirGarantia = null!;
|
||||
private CheckBox chkGerarRecibo = null!, chkExibirValoresOS = null!;
|
||||
private CheckBox chkEmailAuto = null!, chkWhatsAuto = null!, chkModoEscuro = null!;
|
||||
private CheckBox chkPermitirEdicaoOS = null!;
|
||||
|
||||
private RoundTextBox txtCriadoEm = null!, txtAtualizadoEm = null!;
|
||||
|
||||
public EmpresaConfiguracoesPanel()
|
||||
{
|
||||
Dock = DockStyle.Fill;
|
||||
BackColor = Color.White;
|
||||
DoubleBuffered = true;
|
||||
InitializeLayout();
|
||||
this.CarregarConfig();
|
||||
|
||||
}
|
||||
|
||||
private void InitializeLayout()
|
||||
{
|
||||
this.Controls.Clear();
|
||||
|
||||
// ── TOOLBAR ───────────────────────────────────────────────────────
|
||||
pnlToolbar = new Panel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
Height = 55,
|
||||
BackColor = Color.FromArgb(248, 250, 252)
|
||||
};
|
||||
var flowButtons = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Padding = new Padding(12, 10, 0, 0)
|
||||
};
|
||||
|
||||
var btnNovo = CreateToolbarButton("Novo", Color.FromArgb(34, 197, 94));
|
||||
var btnAlterar = CreateToolbarButton("Alterar", Color.FromArgb(245, 158, 11));
|
||||
var btnExcluir = CreateToolbarButton("Excluir", Color.FromArgb(239, 68, 68));
|
||||
var btnLocalizar = CreateToolbarButton("Localizar", AccentBlue);
|
||||
var btnSalvar = CreateToolbarButton("Salvar", AccentBlue);
|
||||
var btnCancelar = CreateToolbarButton("Cancelar", Color.FromArgb(148, 163, 184));
|
||||
var btnConfigEmpresa = CreateToolbarButton("Gerar Config", Color.FromArgb(148, 163, 184));
|
||||
|
||||
btnNovo.Click += (s, e) => BtnNovo_Click();
|
||||
btnAlterar.Click += (s, e) => BtnAlterar_Click();
|
||||
btnExcluir.Click += (s, e) => BtnExcluir_Click();
|
||||
btnLocalizar.Click += (s, e) => BtnLocalizar_Click();
|
||||
btnSalvar.Click += (s, e) => BtnSalvar_Click();
|
||||
btnCancelar.Click += (s, e) => BtnCancelar_Click();
|
||||
btnConfigEmpresa.Click += (s, e) => BtnGerarConfig_Click();
|
||||
|
||||
flowButtons.Controls.AddRange(new Control[]
|
||||
{ btnNovo, btnAlterar, btnExcluir, btnLocalizar, btnSalvar,btnConfigEmpresa,btnCancelar });
|
||||
pnlToolbar.Controls.Add(flowButtons);
|
||||
this.Controls.Add(pnlToolbar);
|
||||
|
||||
// ── SCROLL + CONTENT ──────────────────────────────────────────────
|
||||
mainScroll = new Panel { Dock = DockStyle.Fill, AutoScroll = true };
|
||||
this.Controls.Add(mainScroll);
|
||||
mainScroll.BringToFront();
|
||||
|
||||
content = new Panel { Width = 1100, Height = 850, Location = new Point(0, 0) };
|
||||
mainScroll.Controls.Add(content);
|
||||
|
||||
int y = 10;
|
||||
const int rowH = 52;
|
||||
|
||||
// ── 1. IDENTIDADE DO SISTEMA ──────────────────────────────────────
|
||||
content.Controls.Add(CreateSectionHeader("IDENTIDADE DO SISTEMA", y));
|
||||
y += 32;
|
||||
|
||||
txtId = AddInput(content, "ID", 20, y, 60, 28, readOnly: true);
|
||||
txtEmpresaId = AddInput(content, "Empresa ID", 90, y, 80, 28);
|
||||
txtNomeSistema = AddInput(content, "Nome Personalizado do Sistema", 180, y, 350, 28);
|
||||
y += rowH;
|
||||
|
||||
txtCorPrimaria = AddInput(content, "Cor Primária (Hex)", 20, y, 150, 28);
|
||||
txtCorSecundaria = AddInput(content, "Cor Secundária (Hex)", 180, y, 150, 28);
|
||||
|
||||
// Logo com botão lupa
|
||||
txtLogo = AddInput(content, "Caminho da Logo", 340, y, 260, 28);
|
||||
var btnLogo = CreateIconButton("🔍", 608, y + 16);
|
||||
btnLogo.Click += (s, e) => SelecionarImagem(txtLogo, "Logo");
|
||||
content.Controls.Add(btnLogo);
|
||||
|
||||
// Favicon com botão lupa
|
||||
txtFavicon = AddInput(content, "Caminho do Favicon", 650, y, 240, 28);
|
||||
var btnFavicon = CreateIconButton("🔍", 898, y + 16);
|
||||
btnFavicon.Click += (s, e) => SelecionarImagem(txtFavicon, "Favicon");
|
||||
content.Controls.Add(btnFavicon);
|
||||
|
||||
// ── 2. REGRAS DE NEGÓCIO E EXIBIÇÃO ──────────────────────────────
|
||||
y += rowH + 15;
|
||||
content.Controls.Add(CreateSectionHeader("REGRAS DE NEGÓCIO E EXIBIÇÃO", y));
|
||||
y += 32;
|
||||
|
||||
chkExibirCPF = CreateCheckBox("Exibir CPF Cliente na OS", 20, y + 15);
|
||||
chkExibirTelefone = CreateCheckBox("Exibir Telefone na OS", 230, y + 15);
|
||||
chkExibirValoresOS = CreateCheckBox("Exibir Valores na OS", 460, y + 15);
|
||||
content.Controls.AddRange(new Control[] { chkExibirCPF, chkExibirTelefone, chkExibirValoresOS });
|
||||
y += rowH;
|
||||
|
||||
chkExibirGarantia = CreateCheckBox("Utilizar Garantia", 20, y + 15);
|
||||
txtDiasGarantiaPadrao = AddInput(content, "Dias Garantia (Padrão)", 180, y, 120, 28);
|
||||
content.Controls.Add(chkExibirGarantia);
|
||||
|
||||
// ── 3. AUTOMAÇÕES E COMUNICAÇÃO ───────────────────────────────────
|
||||
y += rowH + 15;
|
||||
content.Controls.Add(CreateSectionHeader("AUTOMAÇÕES E COMUNICAÇÃO", y));
|
||||
y += 32;
|
||||
|
||||
chkGerarRecibo = CreateCheckBox("Gerar Recibo Automático", 20, y + 15);
|
||||
chkEmailAuto = CreateCheckBox("Enviar E-mail Automático", 230, y + 15);
|
||||
chkWhatsAuto = CreateCheckBox("Enviar WhatsApp Automático", 460, y + 15);
|
||||
content.Controls.AddRange(new Control[] { chkGerarRecibo, chkEmailAuto, chkWhatsAuto });
|
||||
|
||||
// ── 4. PREFERÊNCIAS TÉCNICAS ──────────────────────────────────────
|
||||
y += rowH + 15;
|
||||
content.Controls.Add(CreateSectionHeader("PREFERÊNCIAS TÉCNICAS", y));
|
||||
y += 32;
|
||||
|
||||
chkModoEscuro = CreateCheckBox("Habilitar Modo Escuro", 20, y + 15);
|
||||
chkPermitirEdicaoOS = CreateCheckBox("Permitir Edição de OS Finalizada", 230, y + 15);
|
||||
content.Controls.AddRange(new Control[] { chkModoEscuro, chkPermitirEdicaoOS });
|
||||
|
||||
// ── 5. INFORMAÇÕES DO REGISTRO ────────────────────────────────────
|
||||
y += rowH + 15;
|
||||
content.Controls.Add(CreateSectionHeader("INFORMAÇÕES DO REGISTRO", y));
|
||||
y += 32;
|
||||
|
||||
txtCriadoEm = AddInput(content, "Criado Em", 20, y, 180, 28, readOnly: true);
|
||||
txtAtualizadoEm = AddInput(content, "Atualizado Em", 210, y, 180, 28, readOnly: true);
|
||||
y += rowH;
|
||||
|
||||
content.Height = y + 20;
|
||||
|
||||
SetCamposStatus(false);
|
||||
}
|
||||
|
||||
// ── SELEÇÃO DE IMAGEM ─────────────────────────────────────────────────
|
||||
|
||||
//private void SelecionarImagem(RoundTextBox destino, string tipo)
|
||||
//{
|
||||
// using var dlg = new OpenFileDialog
|
||||
// {
|
||||
// Title = $"Selecionar {tipo}",
|
||||
// Filter = "Imagens|*.png;*.jpg;*.jpeg;*.bmp;*.ico;*.gif|Todos os arquivos|*.*"
|
||||
// };
|
||||
|
||||
// if (dlg.ShowDialog() == DialogResult.OK)
|
||||
// {
|
||||
// var arquivo = dlg.FileName;
|
||||
// destino.Text = arquivo;
|
||||
|
||||
// // Valida tamanho máximo (2MB)
|
||||
// var info = new FileInfo(arquivo);
|
||||
// if (info.Length > 2 * 1024 * 1024)
|
||||
// {
|
||||
// MessageBox.Show(
|
||||
// $"O arquivo selecionado para {tipo} é maior que 2MB.\nRecomendamos imagens menores para melhor desempenho.",
|
||||
// "Atenção",
|
||||
// MessageBoxButtons.OK,
|
||||
// MessageBoxIcon.Warning);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
private void SelecionarImagem(RoundTextBox destino, string tipo)
|
||||
{
|
||||
using var dlg = new OpenFileDialog
|
||||
{
|
||||
Title = $"Selecionar {tipo}",
|
||||
Filter = "Imagens|*.png;*.jpg;*.jpeg;*.bmp;*.ico;*.gif|Todos os arquivos|*.*"
|
||||
};
|
||||
|
||||
if (dlg.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
try
|
||||
{
|
||||
var arquivoOriginal = dlg.FileName;
|
||||
|
||||
// 📁 Pasta destino fixa
|
||||
string pastaDestino = @"C:\Levelcode\LevelOS\Uploads\Images";
|
||||
|
||||
// Cria a pasta se não existir
|
||||
if (!Directory.Exists(pastaDestino))
|
||||
Directory.CreateDirectory(pastaDestino);
|
||||
|
||||
// 🔥 Gera nome único (evita sobrescrever)
|
||||
string extensao = Path.GetExtension(arquivoOriginal);
|
||||
string nomeNovo = $"{tipo}_{Guid.NewGuid()}{extensao}";
|
||||
string caminhoFinal = Path.Combine(pastaDestino, nomeNovo);
|
||||
|
||||
// Copia o arquivo
|
||||
File.Copy(arquivoOriginal, caminhoFinal, false);
|
||||
|
||||
// Atualiza o campo
|
||||
destino.Text = caminhoFinal;
|
||||
|
||||
// ⚠️ Valida tamanho (2MB)
|
||||
var info = new FileInfo(caminhoFinal);
|
||||
if (info.Length > 2 * 1024 * 1024)
|
||||
{
|
||||
MessageBox.Show(
|
||||
$"O arquivo selecionado para {tipo} é maior que 2MB.\nRecomendamos imagens menores para melhor desempenho.",
|
||||
"Atenção",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(
|
||||
"Erro ao copiar imagem: " + ex.Message,
|
||||
"Erro",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
}//Copiar com mais precisão
|
||||
|
||||
// ── EVENTOS DOS BOTÕES ────────────────────────────────────────────────
|
||||
|
||||
private void BtnNovo_Click()
|
||||
{
|
||||
LimparFormulario();
|
||||
SetCamposStatus(true);
|
||||
txtNomeSistema.Focus();
|
||||
BLLEmpresaConfig empresaConfig = new BLLEmpresaConfig(_connectionString);
|
||||
this.txtEmpresaId.Text = empresaConfig.ObterEmpresaAtivaId().ToString();
|
||||
}
|
||||
|
||||
private void BtnAlterar_Click()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(txtId.Text))
|
||||
{
|
||||
MessageBox.Show(
|
||||
"Nenhum registro selecionado para alterar.",
|
||||
"Atenção",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
SetCamposStatus(true);
|
||||
}
|
||||
|
||||
private void BtnExcluir_Click()
|
||||
{
|
||||
// Solicita confirmação e exclui o registro
|
||||
}
|
||||
|
||||
private void BtnLocalizar_Click()
|
||||
{
|
||||
// Abre tela de busca e preenche os campos
|
||||
}
|
||||
private void BtnGerarConfig_Click()
|
||||
{
|
||||
var config = new ModeloEmpresaConfig
|
||||
{
|
||||
IdEmpresaConfig = Convert.ToInt32(txtId.Text), // você precisa ter isso carregado
|
||||
IdEmpresa = Convert.ToInt32(txtEmpresaId.Text), // idem (empresa logada)
|
||||
|
||||
NomeSistema = txtNomeSistema.Text,
|
||||
CorPrimaria = txtCorPrimaria.Text,
|
||||
CorSecundaria = txtCorSecundaria.Text,
|
||||
Logo = txtLogo.Text,
|
||||
Favicon = txtFavicon.Text,
|
||||
|
||||
ExibirCPFCliente = chkExibirCPF.Checked,
|
||||
ExibirTelefoneCliente = chkExibirTelefone.Checked,
|
||||
ExibirGarantia = chkExibirGarantia.Checked,
|
||||
DiasGarantiaPadrao = Convert.ToInt32(txtDiasGarantiaPadrao.Text),
|
||||
|
||||
GerarReciboAutomatico = chkGerarRecibo.Checked,
|
||||
ExibirValoresOS = chkExibirValoresOS.Checked,
|
||||
|
||||
EnviarEmailAutomatico = chkEmailAuto.Checked,
|
||||
EnviarWhatsappAutomatico = chkWhatsAuto.Checked,
|
||||
|
||||
ModoEscuro = chkModoEscuro.Checked,
|
||||
PermitirEdicaoOSFinalizada = chkPermitirEdicaoOS.Checked
|
||||
};
|
||||
bool result = JsonHelper.SalvarBoolean(config, AppFileSystem.AppFileConfigEmpresa);
|
||||
if (result)
|
||||
{
|
||||
NT_MessageBox.Show("Arquivo de configuração gerado com sucesso.","Arquivo gerado",MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
else
|
||||
{
|
||||
NT_MessageBox.Show("Não foi possivel gerar o arquivo de configuração", "falha ao gerar arquivo", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void BtnSalvar_Click()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Valida campos obrigatórios
|
||||
if (string.IsNullOrWhiteSpace(txtNomeSistema.Text))
|
||||
{
|
||||
MessageBox.Show(
|
||||
"O campo 'Nome do Sistema' é obrigatório.",
|
||||
"Atenção",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Warning);
|
||||
txtNomeSistema.Focus();
|
||||
return;
|
||||
}
|
||||
|
||||
// Valida cores HEX
|
||||
if (!string.IsNullOrWhiteSpace(txtCorPrimaria.Text) && !ValidarHex(txtCorPrimaria.Text))
|
||||
{
|
||||
MessageBox.Show("Cor Primária inválida. Ex: #3B82F6", "Atenção");
|
||||
txtCorPrimaria.Focus();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(txtCorSecundaria.Text) && !ValidarHex(txtCorSecundaria.Text))
|
||||
{
|
||||
MessageBox.Show("Cor Secundária inválida. Ex: #64748B", "Atenção");
|
||||
txtCorSecundaria.Focus();
|
||||
return;
|
||||
}
|
||||
|
||||
// Valida arquivos
|
||||
if (!string.IsNullOrWhiteSpace(txtLogo.Text) && !File.Exists(txtLogo.Text))
|
||||
{
|
||||
MessageBox.Show("Logo não encontrada.", "Atenção");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(txtFavicon.Text) && !File.Exists(txtFavicon.Text))
|
||||
{
|
||||
MessageBox.Show("Favicon não encontrado.", "Atenção");
|
||||
return;
|
||||
}
|
||||
|
||||
// 🔥 Monta o modelo
|
||||
var config = new ModeloEmpresaConfig
|
||||
{
|
||||
IdEmpresaConfig = Convert.ToInt32(txtId.Text), // você precisa ter isso carregado
|
||||
IdEmpresa = Convert.ToInt32(txtEmpresaId.Text), // idem (empresa logada)
|
||||
|
||||
NomeSistema = txtNomeSistema.Text,
|
||||
CorPrimaria = txtCorPrimaria.Text,
|
||||
CorSecundaria = txtCorSecundaria.Text,
|
||||
Logo = txtLogo.Text,
|
||||
Favicon = txtFavicon.Text,
|
||||
|
||||
ExibirCPFCliente = chkExibirCPF.Checked,
|
||||
ExibirTelefoneCliente = chkExibirTelefone.Checked,
|
||||
ExibirGarantia = chkExibirGarantia.Checked,
|
||||
DiasGarantiaPadrao =Convert.ToInt32(txtDiasGarantiaPadrao.Text),
|
||||
|
||||
GerarReciboAutomatico = chkGerarRecibo.Checked,
|
||||
ExibirValoresOS = chkExibirValoresOS.Checked,
|
||||
|
||||
EnviarEmailAutomatico = chkEmailAuto.Checked,
|
||||
EnviarWhatsappAutomatico = chkWhatsAuto.Checked,
|
||||
|
||||
ModoEscuro = chkModoEscuro.Checked,
|
||||
PermitirEdicaoOSFinalizada = chkPermitirEdicaoOS.Checked
|
||||
};
|
||||
|
||||
var bll = new BLLEmpresaConfig(_connectionString);
|
||||
|
||||
// 🔥 Decide se cria ou atualiza
|
||||
_idConfig = Convert.ToInt32(txtId.Text);
|
||||
if (_idConfig == 0 || _idConfig == null)
|
||||
{
|
||||
bll.Inserir(config);
|
||||
JsonHelper.Salvar(config, AppFileSystem.AppFileConfigEmpresa);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
bll.Alterar(config);
|
||||
JsonHelper.Salvar(config, AppFileSystem.AppFileConfigEmpresa);
|
||||
}
|
||||
|
||||
MessageBox.Show(
|
||||
"Configurações salvas com sucesso!",
|
||||
"LevelOS",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Information);
|
||||
|
||||
SetCamposStatus(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(
|
||||
ex.Message,
|
||||
"Erro",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void BtnCancelar_Click()
|
||||
{
|
||||
LimparFormulario();
|
||||
SetCamposStatus(false);
|
||||
}
|
||||
|
||||
// ── HELPERS DE ESTADO ─────────────────────────────────────────────────
|
||||
|
||||
private void SetCamposStatus(bool active)
|
||||
{
|
||||
var campos = new Control[]
|
||||
{
|
||||
txtEmpresaId, txtNomeSistema, txtCorPrimaria, txtCorSecundaria,
|
||||
txtLogo, txtFavicon, txtDiasGarantiaPadrao,
|
||||
chkExibirCPF, chkExibirTelefone, chkExibirGarantia, chkGerarRecibo,
|
||||
chkExibirValoresOS, chkEmailAuto, chkWhatsAuto, chkModoEscuro, chkPermitirEdicaoOS
|
||||
};
|
||||
|
||||
foreach (var c in campos)
|
||||
{
|
||||
c.Enabled = active;
|
||||
if (c is RoundTextBox r)
|
||||
r.BackColor = active ? Color.White : Color.FromArgb(241, 245, 249);
|
||||
}
|
||||
|
||||
// ID e datas nunca editáveis
|
||||
txtId.Enabled = false;
|
||||
txtId.BackColor = Color.FromArgb(241, 245, 249);
|
||||
txtCriadoEm.Enabled = false;
|
||||
txtAtualizadoEm.Enabled = false;
|
||||
}
|
||||
|
||||
private void LimparFormulario()
|
||||
{
|
||||
var todos = new RoundTextBox[]
|
||||
{
|
||||
txtId, txtEmpresaId, txtNomeSistema, txtCorPrimaria, txtCorSecundaria,
|
||||
txtLogo, txtFavicon, txtDiasGarantiaPadrao, txtCriadoEm, txtAtualizadoEm
|
||||
};
|
||||
foreach (var t in todos) t.Text = string.Empty;
|
||||
|
||||
foreach (Control c in content.Controls)
|
||||
if (c is CheckBox chk) chk.Checked = false;
|
||||
}
|
||||
|
||||
private static bool ValidarHex(string valor)
|
||||
{
|
||||
var v = valor.TrimStart('#');
|
||||
return v.Length == 6 && System.Text.RegularExpressions.Regex.IsMatch(v, @"^[0-9A-Fa-f]{6}$");
|
||||
}
|
||||
|
||||
// ── HELPERS DE UI ─────────────────────────────────────────────────────
|
||||
|
||||
private Panel CreateSectionHeader(string title, int y)
|
||||
{
|
||||
var pnl = new Panel { Location = new Point(20, y), Width = 1000, Height = 26 };
|
||||
pnl.Controls.Add(new Label
|
||||
{
|
||||
Text = title,
|
||||
Font = new Font("Segoe UI", 8.5f, FontStyle.Bold),
|
||||
ForeColor = AccentBlue,
|
||||
AutoSize = true
|
||||
});
|
||||
pnl.Controls.Add(new Panel
|
||||
{
|
||||
BackColor = BorderColor,
|
||||
Height = 1,
|
||||
Width = 980,
|
||||
Location = new Point(0, 20)
|
||||
});
|
||||
return pnl;
|
||||
}
|
||||
|
||||
private RoundTextBox AddInput(Control parent, string label,
|
||||
int x, int y, int w, int h,
|
||||
bool readOnly = false)
|
||||
{
|
||||
parent.Controls.Add(new Label
|
||||
{
|
||||
Text = label,
|
||||
Location = new Point(x, y),
|
||||
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
|
||||
ForeColor = readOnly ? Color.Gray : TextDark,
|
||||
AutoSize = true
|
||||
});
|
||||
var txt = new RoundTextBox
|
||||
{
|
||||
Location = new Point(x, y + 16),
|
||||
Size = new Size(w, h),
|
||||
Radius = 4,
|
||||
BorderColor = readOnly ? Color.FromArgb(203, 213, 225) : BorderColor,
|
||||
FocusColor = AccentBlue,
|
||||
ReadOnly = readOnly,
|
||||
BackColor = readOnly ? Color.FromArgb(241, 245, 249) : Color.White
|
||||
};
|
||||
parent.Controls.Add(txt);
|
||||
return txt;
|
||||
}
|
||||
|
||||
private Button CreateIconButton(string icon, int x, int y) => new Button
|
||||
{
|
||||
Text = icon,
|
||||
Location = new Point(x, y),
|
||||
Size = new Size(28, 28),
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
Font = new Font("Segoe UI", 10f),
|
||||
Cursor = Cursors.Hand,
|
||||
FlatAppearance = { BorderColor = BorderColor, BorderSize = 1 },
|
||||
BackColor = Color.FromArgb(241, 245, 249)
|
||||
};
|
||||
|
||||
private CheckBox CreateCheckBox(string text, int x, int y) => new CheckBox
|
||||
{
|
||||
Text = text,
|
||||
Location = new Point(x, y),
|
||||
Font = new Font("Segoe UI", 8.25f, FontStyle.Bold),
|
||||
ForeColor = TextDark,
|
||||
AutoSize = true
|
||||
};
|
||||
|
||||
private RoundButton CreateToolbarButton(string text, Color color) => new RoundButton
|
||||
{
|
||||
Text = text,
|
||||
Size = new Size(95, 32),
|
||||
BackColor = color,
|
||||
ForeColor = Color.White,
|
||||
Font = new Font("Segoe UI Semibold", 8.5f),
|
||||
Margin = new Padding(0, 0, 6, 0),
|
||||
Cursor = Cursors.Hand
|
||||
};
|
||||
|
||||
private void CarregarConfig()
|
||||
{
|
||||
BLLEmpresaConfig empresaConfig = new BLLEmpresaConfig(_connectionString);
|
||||
int codEmpresa = empresaConfig.ObterEmpresaAtivaId();
|
||||
if (codEmpresa > 0)
|
||||
{
|
||||
ModeloEmpresaConfig modelo = empresaConfig.ObterPorEmpresa(codEmpresa);
|
||||
this.txtId.Text = modelo.IdEmpresaConfig.ToString();
|
||||
this.txtEmpresaId.Text = modelo.IdEmpresa.ToString();
|
||||
this.txtNomeSistema.Text = modelo.NomeSistema;
|
||||
this.txtCorPrimaria.Text = modelo.CorPrimaria;
|
||||
this.txtCorSecundaria.Text = modelo.CorSecundaria;
|
||||
this.txtLogo.Text = modelo.Logo;
|
||||
this.txtFavicon.Text = modelo.Favicon;
|
||||
this.txtDiasGarantiaPadrao.Text = modelo.DiasGarantiaPadrao.ToString();
|
||||
this.chkExibirCPF.Checked = modelo.ExibirCPFCliente;
|
||||
this.chkExibirTelefone.Checked = modelo.ExibirTelefoneCliente;
|
||||
this.chkExibirGarantia.Checked = modelo.ExibirGarantia;
|
||||
this.chkGerarRecibo.Checked = modelo.GerarReciboAutomatico;
|
||||
this.chkExibirValoresOS.Checked = modelo.ExibirValoresOS;
|
||||
this.chkEmailAuto.Checked = modelo.EnviarEmailAutomatico;
|
||||
this.chkWhatsAuto.Checked = modelo.EnviarWhatsappAutomatico;
|
||||
this.chkModoEscuro.Checked = modelo.ModoEscuro;
|
||||
this.chkPermitirEdicaoOS.Checked = modelo.PermitirEdicaoOSFinalizada;
|
||||
this.txtCriadoEm.Text = modelo.CriadoEm.ToString();
|
||||
this.txtAtualizadoEm.Text = modelo.AtualizadoEm.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
NT_MessageBox.Show("Erro ao recuperar configuração da empresa, por favor contacte o administrador do sistema","Erro",MessageBoxButtons.OK,MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
Dashboards/Cadastros/EmpresaConfiguracoesPanel.resx
Normal file
120
Dashboards/Cadastros/EmpresaConfiguracoesPanel.resx
Normal 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>
|
||||
947
Dashboards/Cadastros/FuncionariosCadastroPanel.cs
Normal file
947
Dashboards/Cadastros/FuncionariosCadastroPanel.cs
Normal file
@ -0,0 +1,947 @@
|
||||
using BLL;
|
||||
using CustomMessageBox;
|
||||
using DAL;
|
||||
using MLL;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using AForge.Video;
|
||||
using AForge.Video.DirectShow;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class FuncionariosCadastroPanel : UserControl
|
||||
{
|
||||
private int idBanco = 0;
|
||||
private string _cx = DadosDaConexao.ObterConexao();
|
||||
private readonly Color AccentBlue = Color.FromArgb(37, 99, 235);
|
||||
private readonly Color TextDark = Color.FromArgb(30, 41, 59);
|
||||
private readonly Color BorderColor = Color.FromArgb(226, 232, 240);
|
||||
|
||||
private Panel pnlToolbar = null!;
|
||||
private Panel mainScroll = null!;
|
||||
private Panel content = null!;
|
||||
|
||||
// Identificação
|
||||
private RoundTextBox txtId = null!, txtCodigo = null!, txtNome = null!;
|
||||
private RoundTextBox txtCPF = null!, txtCI = null!, txtCTPS = null!;
|
||||
private RoundTextBox txtCNH = null!, txtCatCNH = null!;
|
||||
private RoundTextBox txtECivil = null!, txtRegime = null!;
|
||||
|
||||
// Filiação
|
||||
private RoundTextBox txtPai = null!, txtMae = null!;
|
||||
|
||||
// Endereço
|
||||
private RoundTextBox txtcep=null!, txtEndereco = null!,txtEndNumero=null!, txtBairro = null!, txtCidade = null!, txtUF = null!;
|
||||
|
||||
// Dados Bancários
|
||||
private RoundTextBox txtBanco = null!, txtAgencia = null!, txtConta = null!;
|
||||
private RoundComboBox cbBanco = null!;
|
||||
|
||||
// Contato
|
||||
private RoundTextBox txtTelefone = null!;
|
||||
|
||||
// Acesso
|
||||
private RoundTextBox txtPass = null!;
|
||||
private CheckBox chkMasterUser = null!, chkVendedor = null!, chkTecnico = null!;
|
||||
private CheckBox chkDemitido = null!, chkContador = null!, chkOutros = null!;
|
||||
|
||||
// Outros
|
||||
private RoundTextBox txtFPath = null!, txtObserv = null!;
|
||||
|
||||
// Datas
|
||||
private RoundTextBox txtDataAdm = null!, txtDataDem = null!, txtAniver = null!;
|
||||
|
||||
// ── CARREGAR FUNCIONÁRIO ──────────────────────────────────────────────
|
||||
|
||||
private void CarregarFuncionario(int id)
|
||||
{
|
||||
//var bll = new BLLFuncionarios(_cx);
|
||||
//var f = bll.CarregarPorId(id);
|
||||
|
||||
//if (f == null)
|
||||
//{
|
||||
// NT_MessageBox.Show("Funcionário não encontrado.",
|
||||
// "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
// return;
|
||||
//}
|
||||
|
||||
//PreencherCampos(f);
|
||||
}
|
||||
|
||||
private void PreencherCampos(ModeloFuncionarios f)
|
||||
{
|
||||
txtId.Text = f.ID_FUNCIONARIO.ToString();
|
||||
txtCodigo.Text = f.CODIGO;
|
||||
txtNome.Text = f.NOME;
|
||||
txtPai.Text = f.PAI;
|
||||
txtMae.Text = f.MAE;
|
||||
txtCPF.Text = f.CPF;
|
||||
txtCI.Text = f.CI;
|
||||
txtCTPS.Text = f.CTPS;
|
||||
txtCNH.Text = f.CNH;
|
||||
txtCatCNH.Text = f.CAT_CNH;
|
||||
txtECivil.Text = f.ECIVIL;
|
||||
txtRegime.Text = f.REGIME;
|
||||
txtEndereco.Text = f.ENDERECO;
|
||||
txtBairro.Text = f.BAIRRO;
|
||||
txtCidade.Text = f.CIDADE;
|
||||
txtUF.Text = f.UF;
|
||||
txtBanco.Text = f.BANCO;
|
||||
txtAgencia.Text = f.AGENCIA;
|
||||
txtConta.Text = f.CONTA;
|
||||
txtTelefone.Text = f.TELEFONE;
|
||||
txtPass.Text = f.PASS;
|
||||
txtFPath.Text = f.FPATH;
|
||||
txtObserv.Text = f.OBSERV;
|
||||
//txtDataAdm.Text = f.DATA_ADM;
|
||||
//txtDataDem.Text = f.DATA_DEM;
|
||||
//txtAniver.Text = f.ANIVER;
|
||||
|
||||
//chkMasterUser.Checked = f.MASTERUSER == "S";
|
||||
//chkVendedor.Checked = f.VENDEDOR == "S";
|
||||
//chkTecnico.Checked = f.TECNICO == "S";
|
||||
//chkDemitido.Checked = f.DEMITIDO == "S";
|
||||
//chkContador.Checked = f.FTECNICO == "S";
|
||||
//chkOutros.Checked = f.FVENDEDOR == "S";
|
||||
}
|
||||
private Control[] TodosOsControles() => new Control[]{
|
||||
txtCodigo, txtNome,
|
||||
txtCPF, txtCI, txtCTPS, txtCNH, txtCatCNH,
|
||||
txtECivil, txtRegime,
|
||||
txtPai, txtMae,
|
||||
txtcep, txtEndereco, txtEndNumero, txtBairro, txtCidade, txtUF,
|
||||
|
||||
// 👇 ComboBox entra aqui
|
||||
cbBanco,
|
||||
|
||||
txtAgencia, txtConta,
|
||||
txtTelefone,
|
||||
txtPass,
|
||||
txtFPath, txtObserv,
|
||||
txtDataAdm, txtDataDem, txtAniver
|
||||
};//todos os controles
|
||||
private void SetCamposAtulizado(bool enabled)
|
||||
{
|
||||
foreach (var ctrl in TodosOsControles())
|
||||
{
|
||||
ctrl.Enabled = enabled;
|
||||
|
||||
// 🎨 Se for TextBox
|
||||
if (ctrl is RoundTextBox txt)
|
||||
{
|
||||
txt.BackColor = enabled
|
||||
? Color.White
|
||||
: Color.FromArgb(241, 245, 249);
|
||||
}
|
||||
|
||||
// 🎨 Se for ComboBox
|
||||
else if (ctrl is RoundComboBox cmb)
|
||||
{
|
||||
cmb.BackColor = enabled
|
||||
? Color.White
|
||||
: Color.FromArgb(241, 245, 249);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var chk in TodosOsChecks())
|
||||
chk.Enabled = enabled;
|
||||
}//SetCampos
|
||||
private void CarregarComboBoxAtualizada()
|
||||
{
|
||||
BLLBancos bLLBancos = new BLLBancos(_cx);
|
||||
|
||||
var tabela = bLLBancos.LocalizarTodos();
|
||||
|
||||
// 🔥 cria coluna personalizada
|
||||
tabela.Columns.Add("EXIBICAO", typeof(string), "NUMERO + ' - ' + NOME");
|
||||
|
||||
cbBanco.DataSource = tabela;
|
||||
cbBanco.DisplayMember = "EXIBICAO"; // 👈 aqui
|
||||
cbBanco.ValueMember = "ID_BANCOS";
|
||||
|
||||
if (cbBanco.SelectedValue != null)
|
||||
this.idBanco = Convert.ToInt32(cbBanco.SelectedValue);
|
||||
}//CarregarComboBoxAtualizada
|
||||
private DateTime? ConverterData(string texto)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(texto))
|
||||
return null;
|
||||
|
||||
if (DateTime.TryParse(texto, out DateTime data))
|
||||
return data;
|
||||
|
||||
return null;
|
||||
}//ConverterData
|
||||
|
||||
public FuncionariosCadastroPanel()
|
||||
{
|
||||
Dock = DockStyle.Fill;
|
||||
BackColor = Color.White;
|
||||
DoubleBuffered = true;
|
||||
InitializeLayout();
|
||||
this.CarregarComboBoxAtualizada();
|
||||
}
|
||||
|
||||
private void InitializeLayout()
|
||||
{
|
||||
this.Controls.Clear();
|
||||
|
||||
// ── TOOLBAR ───────────────────────────────────────────────────────
|
||||
pnlToolbar = new Panel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
Height = 55,
|
||||
BackColor = Color.FromArgb(248, 250, 252),
|
||||
BorderStyle = BorderStyle.None
|
||||
};
|
||||
|
||||
var flowButtons = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Padding = new Padding(12, 10, 0, 0),
|
||||
BackColor = Color.Transparent
|
||||
};
|
||||
|
||||
var btnNovo = CreateToolbarButton("Novo", Color.FromArgb(34, 197, 94));
|
||||
var btnAlterar = CreateToolbarButton("Alterar", Color.FromArgb(245, 158, 11));
|
||||
var btnExcluir = CreateToolbarButton("Excluir", Color.FromArgb(239, 68, 68));
|
||||
var btnLocalizar = CreateToolbarButton("Localizar", AccentBlue);
|
||||
var btnSalvar = CreateToolbarButton("Salvar", AccentBlue);
|
||||
var btnGerarFicha = CreateToolbarButton("Gerar Ficha", Color.FromArgb(255,0,0));
|
||||
var btnCancelar = CreateToolbarButton("Cancelar", Color.FromArgb(148, 163, 184));
|
||||
|
||||
btnNovo.Click += (s, e) => BtnNovo_Click();
|
||||
btnAlterar.Click += (s, e) => BtnAlterar_Click();
|
||||
btnExcluir.Click += (s, e) => BtnExcluir_Click();
|
||||
btnLocalizar.Click += (s, e) => BtnLocalizar_Click();
|
||||
btnSalvar.Click += (s, e) => BtnSalvar_Click();
|
||||
btnCancelar.Click += (s, e) => BtnCancelar_Click();
|
||||
btnGerarFicha.Click += (s, e) => BtnFichaFuncionario_Click();
|
||||
flowButtons.Controls.AddRange(new Control[]
|
||||
{ btnNovo, btnAlterar, btnExcluir, btnLocalizar, btnSalvar,btnGerarFicha,btnCancelar });
|
||||
pnlToolbar.Controls.Add(flowButtons);
|
||||
this.Controls.Add(pnlToolbar);
|
||||
|
||||
// ── SCROLL + CONTENT ──────────────────────────────────────────────
|
||||
mainScroll = new Panel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
AutoScroll = true,
|
||||
BackColor = Color.White
|
||||
};
|
||||
this.Controls.Add(mainScroll);
|
||||
mainScroll.BringToFront();
|
||||
|
||||
content = new Panel
|
||||
{
|
||||
Width = 1100,
|
||||
Height = 900,
|
||||
Location = new Point(0, 0),
|
||||
BackColor = Color.White
|
||||
};
|
||||
mainScroll.Controls.Add(content);
|
||||
|
||||
const int rowH = 52;
|
||||
const int secGap = 10;
|
||||
const int secH = 28;
|
||||
const int inputH = 28;
|
||||
|
||||
int y = 10;
|
||||
|
||||
// ── 1. IDENTIFICAÇÃO DO FUNCIONÁRIO ───────────────────────────────
|
||||
content.Controls.Add(CreateSectionHeader("IDENTIFICAÇÃO DO FUNCIONÁRIO", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtId = AddInput(content, "ID", 20, y, 60, inputH, readOnly: true);
|
||||
txtCodigo = AddInput(content, "Código", 90, y, 100, inputH, readOnly: true);
|
||||
txtNome = AddInput(content, "Nome", 200, y, 450, inputH);
|
||||
y += rowH;
|
||||
|
||||
txtCPF = AddInput(content, "CPF", 20, y, 160, inputH);
|
||||
DocumentoHelper.Registrar(txtCPF);
|
||||
txtCI = AddInput(content, "RG / CI", 190, y, 160, inputH);
|
||||
txtCTPS = AddInput(content, "CTPS", 360, y, 140, inputH);
|
||||
txtCNH = AddInput(content, "CNH", 510, y, 160, inputH);
|
||||
txtCatCNH = AddInput(content, "Cat. CNH", 680, y, 90, inputH);
|
||||
y += rowH;
|
||||
|
||||
txtECivil = AddInput(content, "Estado Civil", 20, y, 160, inputH);
|
||||
txtRegime = AddInput(content, "Regime", 190, y, 160, inputH);
|
||||
|
||||
// ── 2. FILIAÇÃO ───────────────────────────────────────────────────
|
||||
y += rowH + secGap;
|
||||
content.Controls.Add(CreateSectionHeader("FILIAÇÃO", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtPai = AddInput(content, "Nome do Pai", 20, y, 400, inputH);
|
||||
txtMae = AddInput(content, "Nome da Mãe", 430, y, 400, inputH);
|
||||
|
||||
|
||||
// ── 3. ENDEREÇO ─────────────────────────────────────────────
|
||||
y += rowH + secGap;
|
||||
content.Controls.Add(CreateSectionHeader("ENDEREÇO", y));
|
||||
y += secH + 4;
|
||||
|
||||
// LINHA ÚNICA
|
||||
txtcep = AddInput(content, "CEP", 20, y, 80, inputH);
|
||||
txtcep.Leave += (s, e) =>
|
||||
{
|
||||
string cep = txtcep.Text.Trim().Replace("-", "");
|
||||
|
||||
if (cep.Length != 8) return;
|
||||
|
||||
if (TLL.VerifyCep.verificaCEP(cep))
|
||||
{
|
||||
txtEndereco.Text = TLL.VerifyCep.endereco;
|
||||
txtBairro.Text = TLL.VerifyCep.bairro;
|
||||
txtCidade.Text = TLL.VerifyCep.cidade;
|
||||
txtUF.Text = TLL.VerifyCep.estado;
|
||||
|
||||
// Formata o CEP com hífen
|
||||
txtcep.Text = $"{cep[..5]}-{cep[5..]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
NT_MessageBox.Show("CEP não encontrado.", "CEP",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
};//cep
|
||||
txtEndereco = AddInput(content, "Logradouro", 110, y, 260, inputH);
|
||||
txtEndNumero = AddInput(content, "Nº", 380, y, 70, inputH);
|
||||
txtBairro = AddInput(content, "Bairro", 460, y, 150, inputH);
|
||||
txtCidade = AddInput(content, "Cidade", 620, y, 150, inputH);
|
||||
txtUF = AddInput(content, "UF", 780, y, 60, inputH);
|
||||
|
||||
// ── 4. DADOS BANCÁRIOS ────────────────────────────────────────────
|
||||
y += rowH + secGap;
|
||||
content.Controls.Add(CreateSectionHeader("DADOS BANCÁRIOS", y));
|
||||
y += secH + 4;
|
||||
|
||||
//txtBanco = AddInput(content, "Banco", 20, y, 280, inputH);
|
||||
cbBanco = AddComboBox(content, "Banco", 20, y, 200, inputH);
|
||||
txtAgencia = AddInput(content, "Agência", 310, y, 160, inputH);
|
||||
txtConta = AddInput(content, "Conta", 480, y, 160, inputH);
|
||||
|
||||
// ── 5. CONTATO ────────────────────────────────────────────────────
|
||||
y += rowH + secGap;
|
||||
content.Controls.Add(CreateSectionHeader("CONTATO", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtTelefone = AddInput(content, "Telefone", 20, y, 200, inputH);
|
||||
|
||||
// ── 6. ACESSO AO SISTEMA ──────────────────────────────────────────
|
||||
y += rowH + secGap;
|
||||
content.Controls.Add(CreateSectionHeader("ACESSO AO SISTEMA", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtPass = AddInput(content, "Senha", 20, y, 200, inputH);
|
||||
txtPass.PasswordChar = '*';
|
||||
y += rowH;
|
||||
|
||||
chkMasterUser = CreateCheckBox("Master User", 20, y);
|
||||
chkVendedor = CreateCheckBox("Vendedor", 160, y);
|
||||
chkTecnico = CreateCheckBox("Técnico", 290, y);
|
||||
chkOutros = CreateCheckBox("Outros", 420, y);
|
||||
chkContador = CreateCheckBox("Contador", 560, y);
|
||||
chkDemitido = CreateCheckBox("Demitido", 690, y);
|
||||
|
||||
content.Controls.AddRange(new Control[]
|
||||
{ chkMasterUser, chkVendedor, chkTecnico, chkOutros, chkContador, chkDemitido });
|
||||
|
||||
// ── 7. OUTROS ─────────────────────────────────────────────────────
|
||||
y += 35 + secGap;
|
||||
content.Controls.Add(CreateSectionHeader("OUTROS", y));
|
||||
y += secH + 4;
|
||||
|
||||
// Label da foto
|
||||
var lblFoto = new Label
|
||||
{
|
||||
Text = "Caminho da Foto (FPATH)",
|
||||
Location = new Point(20, y),
|
||||
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
|
||||
ForeColor = TextDark,
|
||||
AutoSize = true
|
||||
};
|
||||
content.Controls.Add(lblFoto);
|
||||
|
||||
// Campo de texto da foto (menor para dar espaço ao botão lupa)
|
||||
txtFPath = new RoundTextBox
|
||||
{
|
||||
Location = new Point(20, y + 16),
|
||||
Size = new Size(560, inputH),
|
||||
Radius = 4,
|
||||
BorderColor = BorderColor,
|
||||
FocusColor = AccentBlue,
|
||||
BackColor = Color.White
|
||||
};
|
||||
content.Controls.Add(txtFPath);
|
||||
|
||||
// Botão lupa 🔍
|
||||
var btnFoto = new Button
|
||||
{
|
||||
Text = "🔍",
|
||||
Location = new Point(588, y + 16),
|
||||
Size = new Size(36, inputH),
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
BackColor = Color.FromArgb(37, 99, 235),
|
||||
ForeColor = Color.White,
|
||||
Font = new Font("Segoe UI", 11f),
|
||||
Cursor = Cursors.Hand,
|
||||
TabStop = false
|
||||
};
|
||||
btnFoto.FlatAppearance.BorderSize = 0;
|
||||
btnFoto.Click += (s, e) => BtnFoto_Click();
|
||||
content.Controls.Add(btnFoto);
|
||||
|
||||
y += rowH;
|
||||
|
||||
txtObserv = AddInput(content, "Observações", 20, y, 920, inputH);
|
||||
txtObserv.Multiline = true;
|
||||
txtObserv.Height = 60;
|
||||
|
||||
// ── 8. DATAS ──────────────────────────────────────────────────────
|
||||
y += 70 + secGap;
|
||||
content.Controls.Add(CreateSectionHeader("DATAS", y));
|
||||
y += secH + 4;
|
||||
|
||||
txtDataAdm = AddInput(content, "Data de Admissão", 20, y, 175, inputH);
|
||||
txtDataDem = AddInput(content, "Data de Demissão", 205, y, 175, inputH);
|
||||
txtAniver = AddInput(content, "Aniversário", 390, y, 175, inputH);
|
||||
y += rowH;
|
||||
|
||||
content.Height = y + 10;
|
||||
|
||||
//SetCampos(false);
|
||||
SetCamposAtulizado(false);
|
||||
}
|
||||
|
||||
// ── FOTO: LUPA ────────────────────────────────────────────────────────
|
||||
|
||||
private void BtnFoto_Click()
|
||||
{
|
||||
using var dlg = new FotoOrigemDialog();
|
||||
if (dlg.ShowDialog() != DialogResult.OK) return;
|
||||
|
||||
string? caminhoSalvo = dlg.UsarWebcam
|
||||
? CapturarDaWebcam()
|
||||
: SelecionarDoComputador();
|
||||
|
||||
if (!string.IsNullOrEmpty(caminhoSalvo))
|
||||
txtFPath.Text = caminhoSalvo;
|
||||
}
|
||||
|
||||
private string? SelecionarDoComputador()
|
||||
{
|
||||
using var ofd = new OpenFileDialog
|
||||
{
|
||||
Title = "Selecionar Foto do Funcionário",
|
||||
Filter = "Imagens|*.jpg;*.jpeg;*.png;*.bmp|Todos os arquivos|*.*"
|
||||
};
|
||||
|
||||
if (ofd.ShowDialog() != DialogResult.OK) return null;
|
||||
|
||||
return SalvarFoto(ofd.FileName);
|
||||
}
|
||||
|
||||
private string? CapturarDaWebcam()
|
||||
{
|
||||
using var webcamForm = new WebcamCaptureForm();
|
||||
if (webcamForm.ShowDialog() != DialogResult.OK) return null;
|
||||
if (webcamForm.ImagemCapturada == null) return null;
|
||||
|
||||
string temp = Path.Combine(Path.GetTempPath(), $"webcam_{Guid.NewGuid()}.jpg");
|
||||
webcamForm.ImagemCapturada.Save(temp, ImageFormat.Jpeg);
|
||||
return SalvarFoto(temp);
|
||||
}
|
||||
|
||||
private string SalvarFoto(string origem)
|
||||
{
|
||||
const string pasta = @"C:\Levelcode\LevelOS\Uploads\Images\Funcionarios";
|
||||
Directory.CreateDirectory(pasta);
|
||||
|
||||
// Nome: NomeFuncionario_yyyyMMdd_HHmmss.jpg
|
||||
string nomeBase = string.IsNullOrWhiteSpace(txtNome.Text)
|
||||
? "Funcionario"
|
||||
: txtNome.Text.Trim().Replace(" ", "_");
|
||||
|
||||
string nomeArq = $"{nomeBase}_{DateTime.Now:yyyyMMdd_HHmmss}.jpg";
|
||||
string destino = Path.Combine(pasta, nomeArq);
|
||||
|
||||
File.Copy(origem, destino, overwrite: true);
|
||||
return destino;
|
||||
}
|
||||
|
||||
// ── CAMPOS ────────────────────────────────────────────────────────────
|
||||
|
||||
private RoundTextBox[] TodosOsCampos() => new[]
|
||||
{
|
||||
txtCodigo, txtNome,
|
||||
txtCPF, txtCI, txtCTPS, txtCNH, txtCatCNH,
|
||||
txtECivil, txtRegime,
|
||||
txtPai, txtMae,
|
||||
txtcep,txtEndereco,txtEndNumero, txtBairro, txtCidade, txtUF,
|
||||
/*txtBanco,*/ txtAgencia, txtConta,
|
||||
txtTelefone,
|
||||
txtPass,
|
||||
txtFPath, txtObserv,
|
||||
txtDataAdm, txtDataDem, txtAniver
|
||||
};
|
||||
|
||||
private CheckBox[] TodosOsChecks() => new[]
|
||||
{
|
||||
chkMasterUser, chkVendedor, chkTecnico,
|
||||
chkDemitido, chkContador, chkOutros
|
||||
};
|
||||
|
||||
private void SetCampos(bool enabled)
|
||||
{
|
||||
foreach (var campo in TodosOsCampos())
|
||||
{
|
||||
campo.Enabled = enabled;
|
||||
campo.BackColor = enabled ? Color.White : Color.FromArgb(241, 245, 249);
|
||||
}
|
||||
foreach (var chk in TodosOsChecks())
|
||||
chk.Enabled = enabled;
|
||||
}
|
||||
|
||||
// ── EVENTOS ───────────────────────────────────────────────────────────
|
||||
|
||||
private void BtnNovo_Click()
|
||||
{
|
||||
foreach (var campo in TodosOsCampos())
|
||||
campo.Text = string.Empty;
|
||||
|
||||
foreach (var chk in TodosOsChecks())
|
||||
chk.Checked = false;
|
||||
|
||||
//SetCampos(true);
|
||||
SetCamposAtulizado(true);
|
||||
}
|
||||
|
||||
private void BtnAlterar_Click()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(txtId.Text))
|
||||
{
|
||||
NT_MessageBox.Show(
|
||||
"Nenhum registro selecionado para alterar.",
|
||||
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
//SetCampos(true);
|
||||
SetCamposAtulizado(true);
|
||||
txtId.Enabled = false;
|
||||
txtId.BackColor = Color.FromArgb(241, 245, 249);
|
||||
}
|
||||
|
||||
private void BtnExcluir_Click()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void BtnLocalizar_Click()
|
||||
{
|
||||
// Abre tela/diálogo de busca e preenche os campos
|
||||
}
|
||||
|
||||
private void BtnSalvar_Click()
|
||||
{
|
||||
var bll = new BLLFuncionarios(_cx);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(txtNome.Text) ||
|
||||
string.IsNullOrWhiteSpace(txtCPF.Text))
|
||||
{
|
||||
NT_MessageBox.Show("Preencha ao menos Nome e CPF.",
|
||||
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
bool isNew = string.IsNullOrWhiteSpace(txtId.Text);
|
||||
|
||||
var funcionario = new ModeloFuncionarios
|
||||
{
|
||||
ID_FUNCIONARIO = isNew ? 0 : int.Parse(txtId.Text),
|
||||
|
||||
CODIGO = txtCodigo.Text,
|
||||
NOME = txtNome.Text,
|
||||
PAI = txtPai.Text,
|
||||
MAE = txtMae.Text,
|
||||
CPF = txtCPF.Text,
|
||||
CI = txtCI.Text,
|
||||
CTPS = txtCTPS.Text,
|
||||
CNH = txtCNH.Text,
|
||||
CAT_CNH = txtCatCNH.Text,
|
||||
ECIVIL = txtECivil.Text,
|
||||
REGIME = txtRegime.Text,
|
||||
|
||||
CEP = txtcep.Text,
|
||||
ENDERECO = txtEndereco.Text,
|
||||
ENDNUMERO = txtEndNumero.Text,
|
||||
BAIRRO = txtBairro.Text,
|
||||
CIDADE = txtCidade.Text,
|
||||
UF = txtUF.Text,
|
||||
|
||||
// 🔥 BANCO vindo do ComboBox
|
||||
BANCO = cbBanco.SelectedValue?.ToString(),
|
||||
|
||||
AGENCIA = txtAgencia.Text,
|
||||
CONTA = txtConta.Text,
|
||||
TELEFONE = txtTelefone.Text,
|
||||
PASS = txtPass.Text,
|
||||
|
||||
// 🔥 BOOL correto
|
||||
MASTERUSER = chkMasterUser.Checked,
|
||||
VENDEDOR = chkVendedor.Checked,
|
||||
TECNICO = chkTecnico.Checked,
|
||||
DEMITIDO = chkDemitido.Checked,
|
||||
|
||||
FTECNICO = chkContador.Checked ? "1" : null,
|
||||
FVENDEDOR = chkOutros.Checked ? "1" : null,
|
||||
|
||||
FPATH = txtFPath.Text,
|
||||
OBSERV = txtObserv.Text,
|
||||
|
||||
// 🔥 DATAS
|
||||
DATA_ADM = ConverterData(txtDataAdm.Text),
|
||||
DATA_DEM = ConverterData(txtDataDem.Text),
|
||||
ANIVER = ConverterData(txtAniver.Text)
|
||||
};
|
||||
|
||||
bool sucesso = isNew
|
||||
? bll.Inserir(funcionario)
|
||||
: bll.Alterar(funcionario);
|
||||
|
||||
if (!sucesso)
|
||||
{
|
||||
NT_MessageBox.Show("Erro ao salvar funcionário.",
|
||||
"Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
SetCampos(false);
|
||||
|
||||
NT_MessageBox.Show("Funcionário salvo com sucesso!", "Sucesso",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
private void BtnFichaFuncionario_Click()
|
||||
{
|
||||
var bll = new BLLFuncionarios(_cx);
|
||||
|
||||
var funcionario = bll.CarregarPorCodigo("100");
|
||||
|
||||
if (funcionario == null)
|
||||
{
|
||||
MessageBox.Show("Funcionário não encontrado.");
|
||||
return;
|
||||
}
|
||||
|
||||
var resultado = TLL.FichaFuncionarioPDF.GerarEAbrir(funcionario);
|
||||
|
||||
if (!resultado.Sucesso)
|
||||
MessageBox.Show(resultado.Mensagem, "Erro",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
private void BtnCancelar_Click()
|
||||
{
|
||||
foreach (var campo in TodosOsCampos())
|
||||
campo.Text = string.Empty;
|
||||
|
||||
foreach (var chk in TodosOsChecks())
|
||||
chk.Checked = false;
|
||||
|
||||
//SetCampos(false);
|
||||
SetCamposAtulizado(false);
|
||||
//this.cbBanco.Enabled = false;
|
||||
|
||||
}
|
||||
|
||||
// ── HELPERS ───────────────────────────────────────────────────────────
|
||||
|
||||
private Panel CreateSectionHeader(string title, int y)
|
||||
{
|
||||
var pnl = new Panel { Location = new Point(20, y), Width = 1000, Height = 26 };
|
||||
var lbl = new Label
|
||||
{
|
||||
Text = title,
|
||||
Font = new Font("Segoe UI", 8.5f, FontStyle.Bold),
|
||||
ForeColor = AccentBlue,
|
||||
AutoSize = true,
|
||||
Location = new Point(0, 0)
|
||||
};
|
||||
var line = new Panel
|
||||
{
|
||||
BackColor = BorderColor,
|
||||
Height = 1,
|
||||
Width = 980,
|
||||
Location = new Point(0, 20)
|
||||
};
|
||||
pnl.Controls.Add(lbl);
|
||||
pnl.Controls.Add(line);
|
||||
return pnl;
|
||||
}
|
||||
|
||||
private RoundTextBox AddInput(Control parent, string label,
|
||||
int x, int y, int width, int height,
|
||||
bool readOnly = false)
|
||||
{
|
||||
var lbl = new Label
|
||||
{
|
||||
Text = label,
|
||||
Location = new Point(x, y),
|
||||
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
|
||||
ForeColor = readOnly ? Color.Gray : TextDark,
|
||||
AutoSize = true
|
||||
};
|
||||
var txt = new RoundTextBox
|
||||
{
|
||||
Location = new Point(x, y + 16),
|
||||
Size = new Size(width, height),
|
||||
Radius = 4,
|
||||
BorderColor = readOnly ? Color.FromArgb(203, 213, 225) : BorderColor,
|
||||
FocusColor = AccentBlue,
|
||||
ReadOnly = readOnly,
|
||||
BackColor = readOnly ? Color.FromArgb(241, 245, 249) : Color.White
|
||||
};
|
||||
parent.Controls.Add(lbl);
|
||||
parent.Controls.Add(txt);
|
||||
return txt;
|
||||
}
|
||||
private RoundComboBox AddComboBox(Control parent, string label,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
var lbl = new Label
|
||||
{
|
||||
Text = label,
|
||||
Location = new Point(x, y),
|
||||
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
|
||||
ForeColor = TextDark,
|
||||
AutoSize = true
|
||||
};
|
||||
var cb = new RoundComboBox
|
||||
{
|
||||
Location = new Point(x, y + 16),
|
||||
Size = new Size(width, height),
|
||||
Radius = 4,
|
||||
BorderColor = BorderColor,
|
||||
FocusColor = AccentBlue,
|
||||
BackColor = Color.White
|
||||
};
|
||||
parent.Controls.Add(lbl);
|
||||
parent.Controls.Add(cb);
|
||||
return cb;
|
||||
}
|
||||
|
||||
private CheckBox CreateCheckBox(string text, int x, int y) => new CheckBox
|
||||
{
|
||||
Text = text,
|
||||
Location = new Point(x, y),
|
||||
Font = new Font("Segoe UI", 8.5f, FontStyle.Bold),
|
||||
ForeColor = TextDark,
|
||||
AutoSize = true
|
||||
};
|
||||
|
||||
private RoundButton CreateToolbarButton(string text, Color color) => new RoundButton
|
||||
{
|
||||
Text = text,
|
||||
Size = new Size(95, 32),
|
||||
BackColor = color,
|
||||
ForeColor = Color.White,
|
||||
Font = new Font("Segoe UI Semibold", 8.5f),
|
||||
Margin = new Padding(0, 0, 6, 0),
|
||||
Cursor = Cursors.Hand
|
||||
};
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
// DIALOG: Escolher origem da foto (Computador ou Webcam)
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
public class FotoOrigemDialog : Form
|
||||
{
|
||||
public bool UsarWebcam { get; private set; }
|
||||
|
||||
public FotoOrigemDialog()
|
||||
{
|
||||
Text = "Selecionar Foto";
|
||||
Size = new Size(340, 160);
|
||||
StartPosition = FormStartPosition.CenterParent;
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
BackColor = Color.White;
|
||||
|
||||
var lbl = new Label
|
||||
{
|
||||
Text = "Como deseja adicionar a foto?",
|
||||
Font = new Font("Segoe UI", 9.5f),
|
||||
Location = new Point(20, 18),
|
||||
AutoSize = true
|
||||
};
|
||||
|
||||
var btnComputador = new Button
|
||||
{
|
||||
Text = "📁 Do Computador",
|
||||
Location = new Point(20, 55),
|
||||
Size = new Size(140, 38),
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
BackColor = Color.FromArgb(37, 99, 235),
|
||||
ForeColor = Color.White,
|
||||
Font = new Font("Segoe UI", 9f),
|
||||
Cursor = Cursors.Hand
|
||||
};
|
||||
btnComputador.FlatAppearance.BorderSize = 0;
|
||||
btnComputador.Click += (s, e) =>
|
||||
{
|
||||
UsarWebcam = false;
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
};
|
||||
|
||||
var btnWebcam = new Button
|
||||
{
|
||||
Text = "📷 Webcam",
|
||||
Location = new Point(172, 55),
|
||||
Size = new Size(140, 38),
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
BackColor = Color.FromArgb(16, 185, 129),
|
||||
ForeColor = Color.White,
|
||||
Font = new Font("Segoe UI", 9f),
|
||||
Cursor = Cursors.Hand
|
||||
};
|
||||
btnWebcam.FlatAppearance.BorderSize = 0;
|
||||
btnWebcam.Click += (s, e) =>
|
||||
{
|
||||
UsarWebcam = true;
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
};
|
||||
|
||||
Controls.AddRange(new Control[] { lbl, btnComputador, btnWebcam });
|
||||
}
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
// FORM: Captura pela Webcam usando AForge
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
public class WebcamCaptureForm : Form
|
||||
{
|
||||
public Bitmap? ImagemCapturada { get; private set; }
|
||||
|
||||
private PictureBox picPreview = null!;
|
||||
private VideoCaptureDevice? _camera;
|
||||
private Bitmap? _frameAtual;
|
||||
|
||||
public WebcamCaptureForm()
|
||||
{
|
||||
Text = "Capturar Foto pela Webcam";
|
||||
Size = new Size(680, 560);
|
||||
StartPosition = FormStartPosition.CenterParent;
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
BackColor = Color.FromArgb(15, 23, 42);
|
||||
|
||||
picPreview = new PictureBox
|
||||
{
|
||||
Location = new Point(20, 20),
|
||||
Size = new Size(628, 440),
|
||||
SizeMode = PictureBoxSizeMode.Zoom,
|
||||
BackColor = Color.Black
|
||||
};
|
||||
Controls.Add(picPreview);
|
||||
|
||||
var btnCapturar = new Button
|
||||
{
|
||||
Text = "📷 Capturar",
|
||||
Location = new Point(20, 475),
|
||||
Size = new Size(200, 38),
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
BackColor = Color.FromArgb(37, 99, 235),
|
||||
ForeColor = Color.White,
|
||||
Font = new Font("Segoe UI", 9.5f),
|
||||
Cursor = Cursors.Hand
|
||||
};
|
||||
btnCapturar.FlatAppearance.BorderSize = 0;
|
||||
btnCapturar.Click += BtnCapturar_Click;
|
||||
Controls.Add(btnCapturar);
|
||||
|
||||
var btnCancelar = new Button
|
||||
{
|
||||
Text = "Cancelar",
|
||||
Location = new Point(234, 475),
|
||||
Size = new Size(120, 38),
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
BackColor = Color.FromArgb(100, 116, 139),
|
||||
ForeColor = Color.White,
|
||||
Font = new Font("Segoe UI", 9.5f),
|
||||
Cursor = Cursors.Hand
|
||||
};
|
||||
btnCancelar.FlatAppearance.BorderSize = 0;
|
||||
btnCancelar.Click += (s, e) => { PararCamera(); DialogResult = DialogResult.Cancel; Close(); };
|
||||
Controls.Add(btnCancelar);
|
||||
|
||||
FormClosing += (s, e) => PararCamera();
|
||||
|
||||
IniciarCamera();
|
||||
}
|
||||
|
||||
private void IniciarCamera()
|
||||
{
|
||||
var cameras = new FilterInfoCollection(FilterCategory.VideoInputDevice);
|
||||
|
||||
if (cameras.Count == 0)
|
||||
{
|
||||
MessageBox.Show("Nenhuma webcam encontrada.", "Webcam",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
_camera = new VideoCaptureDevice(cameras[0].MonikerString);
|
||||
_camera.NewFrame += Camera_NewFrame;
|
||||
_camera.Start();
|
||||
}
|
||||
|
||||
private void Camera_NewFrame(object sender, NewFrameEventArgs e)
|
||||
{
|
||||
_frameAtual?.Dispose();
|
||||
_frameAtual = (Bitmap)e.Frame.Clone();
|
||||
|
||||
picPreview.Invoke((MethodInvoker)(() =>
|
||||
{
|
||||
picPreview.Image?.Dispose();
|
||||
picPreview.Image = (Bitmap)_frameAtual.Clone();
|
||||
}));
|
||||
}
|
||||
|
||||
private void BtnCapturar_Click(object? sender, EventArgs e)
|
||||
{
|
||||
if (_frameAtual == null)
|
||||
{
|
||||
MessageBox.Show("Aguarde a câmera inicializar.", "Atenção",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
ImagemCapturada = (Bitmap)_frameAtual.Clone();
|
||||
PararCamera();
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void PararCamera()
|
||||
{
|
||||
if (_camera != null && _camera.IsRunning)
|
||||
{
|
||||
_camera.SignalToStop();
|
||||
_camera.WaitForStop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
Dashboards/Cadastros/FuncionariosCadastroPanel.resx
Normal file
120
Dashboards/Cadastros/FuncionariosCadastroPanel.resx
Normal 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>
|
||||
338
Dashboards/Configurações/Database/FrmConfigBanco.cs
Normal file
338
Dashboards/Configurações/Database/FrmConfigBanco.cs
Normal file
@ -0,0 +1,338 @@
|
||||
using CCH;
|
||||
using CustomMessageBox;
|
||||
using DAL;
|
||||
using Microsoft.Data.SqlClient; // Certifique-se de ter este pacote NuGet instalado
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Windows.Forms;
|
||||
using TLL;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class FrmConfigBanco : Form
|
||||
{
|
||||
// ── Cores LevelOS ──────────────────────────────────────────────────
|
||||
private static readonly Color Surface = Color.White;
|
||||
private static readonly Color Surface2 = Color.FromArgb(241, 245, 249);
|
||||
private static readonly Color BorderCol = Color.FromArgb(226, 232, 240);
|
||||
private static readonly Color TextPri = Color.FromArgb(15, 23, 42);
|
||||
private static readonly Color TextSec = Color.FromArgb(71, 85, 105);
|
||||
private static readonly Color TextMuted = Color.FromArgb(148, 163, 184);
|
||||
private static readonly Color Blue = Color.FromArgb(37, 99, 235);
|
||||
private static readonly Color Green = Color.FromArgb(22, 163, 74);
|
||||
private static readonly Color Red = Color.FromArgb(220, 38, 38);
|
||||
private static readonly Color NavyDark = Color.FromArgb(15, 30, 60);
|
||||
|
||||
// ── Controles ──────────────────────────────────────────────────────
|
||||
private readonly TextBox txtHost = new();
|
||||
private readonly TextBox txtPort = new();
|
||||
private readonly TextBox txtBanco = new();
|
||||
private readonly TextBox txtUsuario = new();
|
||||
private readonly TextBox txtSenha = new();
|
||||
private readonly TextBox txtTimeout = new();
|
||||
private readonly CheckBox chkEncrypt = new();
|
||||
private readonly CheckBox chkTrust = new();
|
||||
private readonly Button btnSalvar = new();
|
||||
private readonly Button btnTestar = new();
|
||||
private readonly Button btnCancelar = new();
|
||||
private readonly Label lblStatus = new();
|
||||
|
||||
public FrmConfigBanco()
|
||||
{
|
||||
Text = "LevelOS — Configuração do Banco de Dados";
|
||||
Size = new Size(660, 680);
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
BackColor = Surface2;
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
|
||||
BuildLayout();
|
||||
CarregarValores();
|
||||
|
||||
// ── Eventos ──────────────────────────────────────────────────
|
||||
btnSalvar.Click += BtnSalvar_Click;
|
||||
btnTestar.Click += BtnTestar_Click;
|
||||
btnCancelar.Click += (s, e) => Close();
|
||||
|
||||
//Carregar dados
|
||||
if (!File.Exists(AppFileSystem.AppFileDBSystem))
|
||||
{
|
||||
NT_MessageBox.Show("Arquivo de configuração do banco de dados ausente, por favor contacte o administrador do sistema para solucionar o problema", "Erro de SQL:101",
|
||||
MessageBoxButtons.OK,MessageBoxIcon.Error);
|
||||
}
|
||||
else
|
||||
{
|
||||
DatabaseHelper.Carregar(AppFileSystem.AppFileDBSystem, AppInfoSystem.AppKeyMasterCrip);
|
||||
this.txtHost.Text = DadosDaConexao.Host;
|
||||
this.txtPort.Text = DadosDaConexao.Port.ToString();
|
||||
this.txtBanco.Text = DadosDaConexao.Banco;
|
||||
this.txtUsuario.Text = DadosDaConexao.Usuario;
|
||||
this.txtSenha.Text = DadosDaConexao.Senha;
|
||||
this.chkEncrypt.Checked = DadosDaConexao.Encrypt;
|
||||
this.txtTimeout.Text = DadosDaConexao.ConnectTimeout.ToString();
|
||||
this.chkTrust.Checked = DadosDaConexao.TrustServerCertificate;
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildLayout()
|
||||
{
|
||||
// 1. TOPBAR
|
||||
var topbar = new Panel { Dock = DockStyle.Top, Height = 75, BackColor = NavyDark };
|
||||
topbar.Paint += DrawTopbar;
|
||||
Controls.Add(topbar);
|
||||
|
||||
// 2. RODAPÉ
|
||||
var footer = new Panel { Dock = DockStyle.Bottom, Height = 65, BackColor = Surface };
|
||||
footer.Paint += (s, e) => e.Graphics.DrawLine(new Pen(BorderCol), 0, 0, footer.Width, 0);
|
||||
Controls.Add(footer);
|
||||
|
||||
StyleButton(btnCancelar, "Cancelar", Surface, TextSec, BorderCol);
|
||||
btnCancelar.SetBounds(20, 15, 100, 35);
|
||||
btnCancelar.Anchor = AnchorStyles.Left;
|
||||
footer.Controls.Add(btnCancelar);
|
||||
|
||||
StyleButton(btnSalvar, "✔ Salvar", Blue, Color.White);
|
||||
btnSalvar.SetBounds(footer.Width - 120, 15, 100, 35);
|
||||
btnSalvar.Anchor = AnchorStyles.Right;
|
||||
footer.Controls.Add(btnSalvar);
|
||||
|
||||
StyleButton(btnTestar, "Testar conexão", Surface, TextPri, BorderCol);
|
||||
btnTestar.SetBounds(btnSalvar.Left - 145, 15, 135, 35);
|
||||
btnTestar.Anchor = AnchorStyles.Right;
|
||||
footer.Controls.Add(btnTestar);
|
||||
|
||||
lblStatus.SetBounds(130, 15, 250, 35);
|
||||
lblStatus.TextAlign = ContentAlignment.MiddleLeft;
|
||||
lblStatus.Font = new Font("Segoe UI", 9f);
|
||||
lblStatus.Anchor = AnchorStyles.Left | AnchorStyles.Right;
|
||||
footer.Controls.Add(lblStatus);
|
||||
|
||||
// 3. CONTAINER DE CONTEÚDO
|
||||
var pnlContainer = new Panel { Dock = DockStyle.Fill, AutoScroll = true, Padding = new Padding(0, 10, 0, 20) };
|
||||
Controls.Add(pnlContainer);
|
||||
pnlContainer.BringToFront();
|
||||
|
||||
// 4. CARD BRANCO
|
||||
var card = new Panel { BackColor = Surface, Width = 560, Left = 40, Top = 20 };
|
||||
pnlContainer.Controls.Add(card);
|
||||
|
||||
int cy = 30;
|
||||
|
||||
cy = AddSection(card, "SERVIDOR", cy);
|
||||
AddLabel(card, "Host / IP", 30, cy);
|
||||
AddLabel(card, "Porta", 430, cy);
|
||||
cy += 20;
|
||||
StyleInput(txtHost, "ex: localhost ou 192.168.0.1");
|
||||
txtHost.SetBounds(30, cy, 385, 30); card.Controls.Add(txtHost);
|
||||
StyleInput(txtPort, "1433");
|
||||
txtPort.SetBounds(430, cy, 100, 30); card.Controls.Add(txtPort);
|
||||
cy += 45;
|
||||
|
||||
cy = AddSection(card, "BANCO DE DADOS", cy);
|
||||
AddLabel(card, "Nome do Banco", 30, cy);
|
||||
cy += 20;
|
||||
StyleInput(txtBanco, "ex: LevelOS_DB");
|
||||
txtBanco.SetBounds(30, cy, 500, 30); card.Controls.Add(txtBanco);
|
||||
cy += 45;
|
||||
|
||||
cy = AddSection(card, "AUTENTICAÇÃO", cy);
|
||||
AddLabel(card, "Usuário", 30, cy);
|
||||
AddLabel(card, "Senha", 285, cy);
|
||||
cy += 20;
|
||||
StyleInput(txtUsuario, "sa");
|
||||
txtUsuario.SetBounds(30, cy, 245, 30); card.Controls.Add(txtUsuario);
|
||||
StyleInput(txtSenha, "••••••••");
|
||||
txtSenha.SetBounds(285, cy, 245, 30); txtSenha.PasswordChar = '●'; card.Controls.Add(txtSenha);
|
||||
cy += 45;
|
||||
|
||||
cy = AddSection(card, "AVANÇADO", cy);
|
||||
AddLabel(card, "Timeout de conexão (segundos)", 30, cy);
|
||||
cy += 20;
|
||||
StyleInput(txtTimeout, "3");
|
||||
txtTimeout.SetBounds(30, cy, 100, 30); card.Controls.Add(txtTimeout);
|
||||
cy += 40;
|
||||
|
||||
StyleCheckbox(chkEncrypt, "Encrypt Connection");
|
||||
chkEncrypt.SetBounds(30, cy, 250, 25); card.Controls.Add(chkEncrypt);
|
||||
cy += 30;
|
||||
StyleCheckbox(chkTrust, "Trust Server Certificate");
|
||||
chkTrust.SetBounds(30, cy, 250, 25); card.Controls.Add(chkTrust);
|
||||
cy += 40;
|
||||
|
||||
card.Height = cy;
|
||||
}
|
||||
|
||||
// ── Lógica de Negócio ──────────────────────────────────────────────
|
||||
|
||||
private void CarregarValores()
|
||||
{
|
||||
txtHost.Text = DbConfig.Host;
|
||||
txtPort.Text = DbConfig.Port.ToString();
|
||||
txtBanco.Text = DbConfig.Banco;
|
||||
txtUsuario.Text = DbConfig.Usuario;
|
||||
txtSenha.Text = DbConfig.Senha;
|
||||
txtTimeout.Text = DbConfig.ConnectTimeout.ToString();
|
||||
chkEncrypt.Checked = DbConfig.Encrypt;
|
||||
chkTrust.Checked = DbConfig.TrustServerCertificate;
|
||||
}
|
||||
|
||||
private void BtnSalvar_Click(object? sender, EventArgs e)
|
||||
{
|
||||
if (!Validar()) return;
|
||||
|
||||
DbConfig.Host = txtHost.Text.Trim();
|
||||
DbConfig.Port = int.TryParse(txtPort.Text, out int p) ? p : 1433;
|
||||
DbConfig.Banco = txtBanco.Text.Trim();
|
||||
DbConfig.Usuario = txtUsuario.Text.Trim();
|
||||
DbConfig.Senha = txtSenha.Text;
|
||||
DbConfig.ConnectTimeout = int.TryParse(txtTimeout.Text, out int t) ? t : 3;
|
||||
DbConfig.Encrypt = chkEncrypt.Checked;
|
||||
DbConfig.TrustServerCertificate = chkTrust.Checked;
|
||||
|
||||
//Preenchendo dados da conexao
|
||||
DadosDaConexao.Host = DbConfig.Host;
|
||||
DadosDaConexao.Port = DbConfig.Port;
|
||||
DadosDaConexao.Banco =DbConfig.Banco;
|
||||
DadosDaConexao.Usuario = DbConfig.Usuario;
|
||||
DadosDaConexao.Senha = DbConfig.Senha;
|
||||
DadosDaConexao.ConnectTimeout = DbConfig.ConnectTimeout;
|
||||
DadosDaConexao.Encrypt = chkEncrypt.Checked;
|
||||
DadosDaConexao.TrustServerCertificate = chkTrust.Checked;
|
||||
//salvar em arquivo criptografado
|
||||
DatabaseHelper.Salvar(AppFileSystem.AppFileDBSystem, AppInfoSystem.AppKeyMasterCrip);
|
||||
|
||||
|
||||
SetStatus("✔ Configurações salvas!", Green);
|
||||
}
|
||||
|
||||
private void BtnTestar_Click(object? sender, EventArgs e)
|
||||
{
|
||||
if (!Validar()) return;
|
||||
|
||||
SetStatus("⏳ Testando...", TextMuted);
|
||||
btnTestar.Enabled = false;
|
||||
Application.DoEvents(); // Força a interface a atualizar o status
|
||||
|
||||
try
|
||||
{
|
||||
using var conn = new SqlConnection(BuildConnStr());
|
||||
conn.Open();
|
||||
SetStatus($"✔ Conectado! SQL {conn.ServerVersion}", Green);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SetStatus($"✖ Erro: {ex.Message}", Red);
|
||||
}
|
||||
finally
|
||||
{
|
||||
btnTestar.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private string BuildConnStr()
|
||||
{
|
||||
SqlConnectionStringBuilder builder = new()
|
||||
{
|
||||
DataSource = $"{txtHost.Text.Trim()},{txtPort.Text.Trim()}",
|
||||
InitialCatalog = txtBanco.Text.Trim(),
|
||||
UserID = txtUsuario.Text.Trim(),
|
||||
Password = txtSenha.Text,
|
||||
ConnectTimeout = int.TryParse(txtTimeout.Text, out int t) ? t : 3,
|
||||
Encrypt = chkEncrypt.Checked,
|
||||
TrustServerCertificate = chkTrust.Checked
|
||||
};
|
||||
return builder.ConnectionString;
|
||||
}
|
||||
|
||||
private bool Validar()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(txtHost.Text)) { SetStatus("✖ Informe o Host.", Red); txtHost.Focus(); return false; }
|
||||
if (string.IsNullOrWhiteSpace(txtBanco.Text)) { SetStatus("✖ Informe o Banco.", Red); txtBanco.Focus(); return false; }
|
||||
if (string.IsNullOrWhiteSpace(txtUsuario.Text)) { SetStatus("✖ Informe o Usuário.", Red); txtUsuario.Focus(); return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SetStatus(string msg, Color color)
|
||||
{
|
||||
lblStatus.Text = msg;
|
||||
lblStatus.ForeColor = color;
|
||||
}
|
||||
|
||||
// ── Helpers de UI ──────────────────────────────────────────────────
|
||||
|
||||
private void DrawTopbar(object sender, PaintEventArgs e)
|
||||
{
|
||||
var g = e.Graphics;
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
var rect = new Rectangle(25, 20, 34, 34);
|
||||
using var path = RoundRectPath(rect, 8);
|
||||
g.FillPath(new SolidBrush(Blue), path);
|
||||
g.DrawString("S", new Font("Segoe UI", 14, FontStyle.Bold), Brushes.White, rect, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
|
||||
g.DrawString("Configuração do Banco", new Font("Segoe UI Semibold", 12.5f), Brushes.White, 70, 18);
|
||||
g.DrawString("Defina os parâmetros de conexão com o SQL Server", new Font("Segoe UI", 9), new SolidBrush(Color.FromArgb(148, 163, 184)), 70, 40);
|
||||
}
|
||||
|
||||
private int AddSection(Panel p, string title, int y)
|
||||
{
|
||||
var line = new Panel { BackColor = BorderCol, Height = 1, Width = p.Width - 60, Left = 30, Top = y };
|
||||
p.Controls.Add(line);
|
||||
var lbl = new Label { Text = title, Font = new Font("Segoe UI", 7, FontStyle.Bold), ForeColor = TextMuted, Top = y - 7, Left = 35, AutoSize = true, BackColor = Surface };
|
||||
p.Controls.Add(lbl);
|
||||
lbl.BringToFront();
|
||||
return y + 20;
|
||||
}
|
||||
|
||||
private void AddLabel(Panel p, string txt, int x, int y)
|
||||
{
|
||||
p.Controls.Add(new Label { Text = txt, Font = new Font("Segoe UI Semibold", 9), ForeColor = TextSec, Left = x, Top = y, AutoSize = true });
|
||||
}
|
||||
|
||||
private void StyleInput(TextBox t, string placeholder)
|
||||
{
|
||||
t.BorderStyle = BorderStyle.FixedSingle;
|
||||
t.Font = new Font("Segoe UI", 10);
|
||||
t.PlaceholderText = placeholder;
|
||||
t.BackColor = Color.FromArgb(250, 251, 253);
|
||||
}
|
||||
|
||||
private void StyleCheckbox(CheckBox chk, string text)
|
||||
{
|
||||
chk.Text = text; chk.Font = new Font("Segoe UI", 9.5f);
|
||||
chk.ForeColor = TextSec; chk.Cursor = Cursors.Hand;
|
||||
}
|
||||
|
||||
private void StyleButton(Button b, string txt, Color bg, Color fg, Color? borda = null)
|
||||
{
|
||||
b.Text = txt; b.FlatStyle = FlatStyle.Flat; b.BackColor = bg; b.ForeColor = fg; b.Cursor = Cursors.Hand;
|
||||
b.Font = new Font("Segoe UI Semibold", 9.5f);
|
||||
b.FlatAppearance.BorderSize = borda.HasValue ? 1 : 0;
|
||||
if (borda.HasValue) b.FlatAppearance.BorderColor = borda.Value;
|
||||
}
|
||||
|
||||
private static GraphicsPath RoundRectPath(Rectangle r, int radius)
|
||||
{
|
||||
var path = new GraphicsPath();
|
||||
int d = radius * 2;
|
||||
path.AddArc(r.X, r.Y, d, d, 180, 90);
|
||||
path.AddArc(r.Right - d, r.Y, d, d, 270, 90);
|
||||
path.AddArc(r.Right - d, r.Bottom - d, d, d, 0, 90);
|
||||
path.AddArc(r.X, r.Bottom - d, d, d, 90, 90);
|
||||
path.CloseFigure();
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Dados (DbConfig) ──────────────────────────────────────────────────
|
||||
public static class DbConfig
|
||||
{
|
||||
public static string Host { get; set; } = "localhost";
|
||||
public static int Port { get; set; } = 1433;
|
||||
public static string Banco { get; set; } = "";
|
||||
public static string Usuario { get; set; } = "sa";
|
||||
public static string Senha { get; set; } = "";
|
||||
public static int ConnectTimeout { get; set; } = 3;
|
||||
public static bool Encrypt { get; set; } = true;
|
||||
public static bool TrustServerCertificate { get; set; } = true;
|
||||
}
|
||||
}
|
||||
120
Dashboards/Configurações/Database/FrmConfigBanco.resx
Normal file
120
Dashboards/Configurações/Database/FrmConfigBanco.resx
Normal 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>
|
||||
431
Dashboards/Consultas/AgendaConsultaPanel.cs
Normal file
431
Dashboards/Consultas/AgendaConsultaPanel.cs
Normal file
@ -0,0 +1,431 @@
|
||||
using BLL;
|
||||
using DAL;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class AgendaConsultaPanel : UserControl
|
||||
{
|
||||
// ── CORES ─────────────────────────────────────────────────────────────
|
||||
private readonly Color AccentBlue = Color.FromArgb(37, 99, 235);
|
||||
private readonly Color TextDark = Color.FromArgb(30, 41, 59);
|
||||
private readonly Color BorderColor = Color.FromArgb(226, 232, 240);
|
||||
private readonly Color GreenColor = Color.FromArgb(34, 197, 94);
|
||||
private readonly Color MutedGray = Color.FromArgb(148, 163, 184);
|
||||
private readonly Color SurfaceColor = Color.FromArgb(248, 250, 252);
|
||||
|
||||
// ── CONTROLES ─────────────────────────────────────────────────────────
|
||||
private Panel pnlToolbar = null!;
|
||||
private Panel pnlFiltros = null!;
|
||||
private Panel pnlRodape = null!;
|
||||
private DataGridView dgvAgenda = null!;
|
||||
private Label lblTotal = null!;
|
||||
|
||||
// ── FILTROS ───────────────────────────────────────────────────────────
|
||||
private RoundTextBox txtFiltroCompromisso = null!;
|
||||
private RoundTextBox txtFiltroFunc = null!;
|
||||
private RoundTextBox txtFiltroOsVinc = null!;
|
||||
private RoundTextBox txtDataInicio = null!;
|
||||
private RoundTextBox txtDataFim = null!;
|
||||
private ComboBox cmbSituacao = null!;
|
||||
|
||||
// ── DADOS ─────────────────────────────────────────────────────────────
|
||||
private List<MLL.ModeloAgenda> _todos = new();
|
||||
private List<MLL.ModeloAgenda> _filtrados = new();
|
||||
|
||||
// ── EVENTO: abre cadastro com o registro selecionado ──────────────────
|
||||
public event Action<MLL.ModeloAgenda>? OnAbrirCadastro;
|
||||
|
||||
//Carrega a string conexao com o banco de dados, para ser usada no repositório
|
||||
private string _conexao = DadosDaConexao.ObterConexao();
|
||||
|
||||
// ── CONSTRUTOR ────────────────────────────────────────────────────────
|
||||
public AgendaConsultaPanel()
|
||||
{
|
||||
Dock = DockStyle.Fill;
|
||||
BackColor = Color.White;
|
||||
DoubleBuffered = true;
|
||||
|
||||
InitializeLayout();
|
||||
//CarregarDadosFake();
|
||||
CarregarDadosDoBanco();
|
||||
AplicarFiltros();
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════
|
||||
// LAYOUT
|
||||
//
|
||||
// REGRA WINFORMS — ordem de adição ao Controls é INVERSA à exibição:
|
||||
// 1º adicionar → Fill (ocupa o centro)
|
||||
// 2º adicionar → Bottom
|
||||
// 3º adicionar → Top (empurra o Fill para baixo; último = mais alto)
|
||||
//
|
||||
// ══════════════════════════════════════════════════════════════════════
|
||||
private void InitializeLayout()
|
||||
{
|
||||
Controls.Clear();
|
||||
|
||||
// ── 1º: GRID (Fill) ───────────────────────────────────────────────
|
||||
BuildGrid();
|
||||
Controls.Add(dgvAgenda);
|
||||
|
||||
// ── 2º: RODAPÉ (Bottom) ───────────────────────────────────────────
|
||||
pnlRodape = new Panel
|
||||
{
|
||||
Dock = DockStyle.Bottom,
|
||||
Height = 30,
|
||||
BackColor = SurfaceColor
|
||||
};
|
||||
lblTotal = new Label
|
||||
{
|
||||
AutoSize = true,
|
||||
Location = new Point(16, 7),
|
||||
Font = new Font("Segoe UI", 8.5f, FontStyle.Bold),
|
||||
ForeColor = MutedGray,
|
||||
Text = "0 registros encontrados"
|
||||
};
|
||||
pnlRodape.Controls.Add(lblTotal);
|
||||
Controls.Add(pnlRodape);
|
||||
|
||||
// ── 3º: FILTROS (Top) ─────────────────────────────────────────────
|
||||
pnlFiltros = new Panel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
Height = 95,
|
||||
BackColor = SurfaceColor,
|
||||
Padding = new Padding(16, 8, 16, 8)
|
||||
};
|
||||
BuildFiltros();
|
||||
Controls.Add(pnlFiltros);
|
||||
|
||||
// ── 4º: TOOLBAR (Top) — por último = fica acima dos filtros ───────
|
||||
pnlToolbar = new Panel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
Height = 55,
|
||||
BackColor = SurfaceColor
|
||||
};
|
||||
|
||||
var flow = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Padding = new Padding(12, 10, 0, 0),
|
||||
BackColor = Color.Transparent
|
||||
};
|
||||
|
||||
var btnPesquisar = CreateToolbarButton("Pesquisar", AccentBlue);
|
||||
var btnLimpar = CreateToolbarButton("Limpar", MutedGray);
|
||||
var btnAbrir = CreateToolbarButton("Abrir", GreenColor);
|
||||
var btnExportar = CreateToolbarButton("Exportar", Color.FromArgb(99, 102, 241));
|
||||
|
||||
btnPesquisar.Click += (_, _) => AplicarFiltros();
|
||||
btnLimpar.Click += (_, _) => LimparFiltros();
|
||||
btnAbrir.Click += (_, _) => AbrirRegistroSelecionado();
|
||||
btnExportar.Click += (_, _) => ExportarCSV();
|
||||
|
||||
flow.Controls.AddRange(new Control[] { btnPesquisar, btnLimpar, btnAbrir, btnExportar });
|
||||
pnlToolbar.Controls.Add(flow);
|
||||
Controls.Add(pnlToolbar); // ← último Top = aparece no topo
|
||||
}
|
||||
|
||||
// ── FILTROS ───────────────────────────────────────────────────────────
|
||||
private void BuildFiltros()
|
||||
{
|
||||
// Linha 1
|
||||
txtFiltroCompromisso = AddFiltroInput(pnlFiltros, "Compromisso", 0, 8, 260);
|
||||
txtFiltroFunc = AddFiltroInput(pnlFiltros, "Funcionário", 270, 8, 200);
|
||||
txtFiltroOsVinc = AddFiltroInput(pnlFiltros, "OS Vinculada", 480, 8, 130);
|
||||
|
||||
// Linha 2
|
||||
txtDataInicio = AddFiltroInput(pnlFiltros, "Data Início", 0, 50, 130);
|
||||
txtDataFim = AddFiltroInput(pnlFiltros, "Data Fim", 140, 50, 130);
|
||||
|
||||
pnlFiltros.Controls.Add(new Label
|
||||
{
|
||||
Text = "Situação",
|
||||
Location = new Point(280, 50),
|
||||
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
|
||||
ForeColor = TextDark,
|
||||
AutoSize = true
|
||||
});
|
||||
|
||||
cmbSituacao = new ComboBox
|
||||
{
|
||||
Location = new Point(280, 66),
|
||||
Size = new Size(160, 26),
|
||||
DropDownStyle = ComboBoxStyle.DropDownList,
|
||||
Font = new Font("Segoe UI", 8.5f),
|
||||
FlatStyle = FlatStyle.Flat
|
||||
};
|
||||
cmbSituacao.Items.AddRange(new object[] { "Todos", "Pendente", "Realizado" });
|
||||
cmbSituacao.SelectedIndex = 0;
|
||||
pnlFiltros.Controls.Add(cmbSituacao);
|
||||
|
||||
foreach (var txt in new[] { txtFiltroCompromisso, txtFiltroFunc, txtFiltroOsVinc, txtDataInicio, txtDataFim })
|
||||
txt.KeyDown += (_, e) => { if (e.KeyCode == Keys.Enter) AplicarFiltros(); };
|
||||
}
|
||||
|
||||
private RoundTextBox AddFiltroInput(Control parent, string label, int x, int y, int width)
|
||||
{
|
||||
parent.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 txt = new RoundTextBox
|
||||
{
|
||||
Location = new Point(x, y + 16),
|
||||
Size = new Size(width, 26),
|
||||
Radius = 4,
|
||||
BorderColor = BorderColor,
|
||||
FocusColor = AccentBlue,
|
||||
BackColor = Color.White
|
||||
};
|
||||
parent.Controls.Add(txt);
|
||||
return txt;
|
||||
}
|
||||
|
||||
// ── GRID ──────────────────────────────────────────────────────────────
|
||||
private void BuildGrid()
|
||||
{
|
||||
dgvAgenda = new DataGridView
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackgroundColor = Color.White,
|
||||
BorderStyle = BorderStyle.None,
|
||||
CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal,
|
||||
ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single,
|
||||
GridColor = BorderColor,
|
||||
RowHeadersVisible = false,
|
||||
AllowUserToAddRows = false,
|
||||
AllowUserToDeleteRows = false,
|
||||
ReadOnly = true,
|
||||
SelectionMode = DataGridViewSelectionMode.FullRowSelect,
|
||||
MultiSelect = false,
|
||||
Font = new Font("Segoe UI", 8.5f),
|
||||
AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill,
|
||||
ColumnHeadersHeight = 36,
|
||||
ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing,
|
||||
RowTemplate = { Height = 32 }
|
||||
};
|
||||
|
||||
dgvAgenda.ColumnHeadersDefaultCellStyle = new DataGridViewCellStyle
|
||||
{
|
||||
BackColor = SurfaceColor,
|
||||
ForeColor = TextDark,
|
||||
Font = new Font("Segoe UI", 8.5f, FontStyle.Bold),
|
||||
Alignment = DataGridViewContentAlignment.MiddleLeft,
|
||||
Padding = new Padding(8, 0, 0, 0),
|
||||
SelectionBackColor = SurfaceColor,
|
||||
SelectionForeColor = TextDark
|
||||
};
|
||||
|
||||
dgvAgenda.DefaultCellStyle = new DataGridViewCellStyle
|
||||
{
|
||||
ForeColor = TextDark,
|
||||
BackColor = Color.White,
|
||||
SelectionBackColor = Color.FromArgb(239, 246, 255),
|
||||
SelectionForeColor = AccentBlue,
|
||||
Padding = new Padding(8, 0, 0, 0)
|
||||
};
|
||||
|
||||
dgvAgenda.AlternatingRowsDefaultCellStyle = new DataGridViewCellStyle
|
||||
{
|
||||
BackColor = SurfaceColor,
|
||||
SelectionBackColor = Color.FromArgb(239, 246, 255),
|
||||
SelectionForeColor = AccentBlue
|
||||
};
|
||||
|
||||
dgvAgenda.Columns.AddRange(new DataGridViewColumn[]
|
||||
{
|
||||
new DataGridViewTextBoxColumn { Name = "colId", HeaderText = "ID", FillWeight = 5 },
|
||||
new DataGridViewTextBoxColumn { Name = "colCodigo", HeaderText = "Código", FillWeight = 8 },
|
||||
new DataGridViewTextBoxColumn { Name = "colCompromisso", HeaderText = "Compromisso", FillWeight = 26 },
|
||||
new DataGridViewTextBoxColumn { Name = "colData", HeaderText = "Data", FillWeight = 10 },
|
||||
new DataGridViewTextBoxColumn { Name = "colHora", HeaderText = "Hora", FillWeight = 7 },
|
||||
new DataGridViewTextBoxColumn { Name = "colDia", HeaderText = "Dia", FillWeight = 10 },
|
||||
new DataGridViewTextBoxColumn { Name = "colFunc", HeaderText = "Funcionário", FillWeight = 16 },
|
||||
new DataGridViewTextBoxColumn { Name = "colAvisar", HeaderText = "Avisar", FillWeight = 12 },
|
||||
new DataGridViewTextBoxColumn { Name = "colOs", HeaderText = "OS Vinc.", FillWeight = 8 },
|
||||
new DataGridViewTextBoxColumn { Name = "colSituacao", HeaderText = "Situação", FillWeight = 10 },
|
||||
});
|
||||
|
||||
dgvAgenda.CellDoubleClick += (_, e) =>
|
||||
{
|
||||
if (e.RowIndex >= 0) AbrirRegistroSelecionado();
|
||||
};
|
||||
|
||||
dgvAgenda.CellFormatting += (_, e) =>
|
||||
{
|
||||
if (e.RowIndex < 0 || e.ColumnIndex < 0) return;
|
||||
if (dgvAgenda.Columns[e.ColumnIndex].Name != "colSituacao") return;
|
||||
|
||||
bool realizado = e.Value?.ToString() == "Realizado";
|
||||
e.CellStyle.ForeColor = realizado ? Color.FromArgb(22, 101, 52) : Color.FromArgb(146, 64, 14);
|
||||
e.CellStyle.Font = new Font("Segoe UI", 8f, FontStyle.Bold);
|
||||
e.CellStyle.SelectionForeColor = e.CellStyle.ForeColor;
|
||||
e.FormattingApplied = true;
|
||||
};
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════
|
||||
// LÓGICA
|
||||
// ══════════════════════════════════════════════════════════════════════
|
||||
private void AplicarFiltros()
|
||||
{
|
||||
_filtrados = _todos.ToList();
|
||||
|
||||
var termComp = txtFiltroCompromisso.Text.Trim().ToLower();
|
||||
if (!string.IsNullOrEmpty(termComp))
|
||||
_filtrados = _filtrados.Where(e => e.COMPROMISSO?.ToLower().Contains(termComp) == true).ToList();
|
||||
|
||||
var termFunc = txtFiltroFunc.Text.Trim().ToLower();
|
||||
if (!string.IsNullOrEmpty(termFunc))
|
||||
_filtrados = _filtrados.Where(e => e.FUNC?.ToLower().Contains(termFunc) == true).ToList();
|
||||
|
||||
var termOs = txtFiltroOsVinc.Text.Trim().ToLower();
|
||||
if (!string.IsNullOrEmpty(termOs))
|
||||
_filtrados = _filtrados.Where(e => e.OS_VINC?.ToLower().Contains(termOs) == true).ToList();
|
||||
|
||||
if (DateTime.TryParseExact(txtDataInicio.Text.Trim(), "dd/MM/yyyy",
|
||||
System.Globalization.CultureInfo.InvariantCulture,
|
||||
System.Globalization.DateTimeStyles.None, out var dtIni))
|
||||
_filtrados = _filtrados.Where(e => ParseData(e.dDATA) >= dtIni).ToList();
|
||||
|
||||
if (DateTime.TryParseExact(txtDataFim.Text.Trim(), "dd/MM/yyyy",
|
||||
System.Globalization.CultureInfo.InvariantCulture,
|
||||
System.Globalization.DateTimeStyles.None, out var dtFim))
|
||||
_filtrados = _filtrados.Where(e => ParseData(e.dDATA) <= dtFim).ToList();
|
||||
|
||||
var sit = cmbSituacao.SelectedItem?.ToString();
|
||||
if (sit == "Realizado") _filtrados = _filtrados.Where(e => e.REALIZADO?.ToUpper() == "S").ToList();
|
||||
else if (sit == "Pendente") _filtrados = _filtrados.Where(e => e.REALIZADO?.ToUpper() != "S").ToList();
|
||||
|
||||
PreencherGrid();
|
||||
}
|
||||
|
||||
private void LimparFiltros()
|
||||
{
|
||||
txtFiltroCompromisso.Text = string.Empty;
|
||||
txtFiltroFunc.Text = string.Empty;
|
||||
txtFiltroOsVinc.Text = string.Empty;
|
||||
txtDataInicio.Text = string.Empty;
|
||||
txtDataFim.Text = string.Empty;
|
||||
cmbSituacao.SelectedIndex = 0;
|
||||
AplicarFiltros();
|
||||
}
|
||||
|
||||
private void PreencherGrid()
|
||||
{
|
||||
dgvAgenda.Rows.Clear();
|
||||
|
||||
foreach (var ev in _filtrados.OrderBy(e => ParseData(e.dDATA)).ThenBy(e => e.HORA))
|
||||
{
|
||||
dgvAgenda.Rows.Add(
|
||||
ev.ID_AGENDA, ev.CODIGO, ev.COMPROMISSO,
|
||||
ev.dDATA, ev.HORA, ev.DIA, ev.FUNC, ev.AVISAR, ev.OS_VINC,
|
||||
ev.REALIZADO?.ToUpper() == "S" ? "Realizado" : "Pendente"
|
||||
);
|
||||
}
|
||||
|
||||
int total = _filtrados.Count;
|
||||
lblTotal.Text = total == 1 ? "1 registro encontrado" : $"{total} registros encontrados";
|
||||
}
|
||||
|
||||
private void AbrirRegistroSelecionado()
|
||||
{
|
||||
if (dgvAgenda.SelectedRows.Count == 0)
|
||||
{
|
||||
MessageBox.Show("Selecione um registro na lista.",
|
||||
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
var row = dgvAgenda.SelectedRows[0];
|
||||
if (row.Cells["colId"].Value is int id)
|
||||
{
|
||||
var ev = _filtrados.FirstOrDefault(e => e.ID_AGENDA == id);
|
||||
if (ev != null) OnAbrirCadastro?.Invoke(ev);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExportarCSV()
|
||||
{
|
||||
if (!_filtrados.Any())
|
||||
{
|
||||
MessageBox.Show("Nenhum registro para exportar.",
|
||||
"Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
using var dlg = new SaveFileDialog
|
||||
{
|
||||
Filter = "CSV (*.csv)|*.csv",
|
||||
FileName = $"Agenda_{DateTime.Today:yyyyMMdd}.csv"
|
||||
};
|
||||
if (dlg.ShowDialog() != DialogResult.OK) return;
|
||||
|
||||
var sb = new System.Text.StringBuilder();
|
||||
sb.AppendLine("ID;Código;Compromisso;Data;Hora;Dia;Funcionário;Avisar;OS Vinculada;Situação");
|
||||
foreach (var ev in _filtrados.OrderBy(e => ParseData(e.dDATA)).ThenBy(e => e.HORA))
|
||||
sb.AppendLine($"{ev.ID_AGENDA};{ev.CODIGO};{ev.COMPROMISSO};{ev.dDATA};" +
|
||||
$"{ev.HORA};{ev.DIA};{ev.FUNC};{ev.AVISAR};{ev.OS_VINC};" +
|
||||
$"{(ev.REALIZADO?.ToUpper() == "S" ? "Realizado" : "Pendente")}");
|
||||
|
||||
System.IO.File.WriteAllText(dlg.FileName, sb.ToString(), System.Text.Encoding.UTF8);
|
||||
MessageBox.Show($"Exportado com sucesso!\n{dlg.FileName}", "Exportar",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
// ── DADOS FAKE — substituir pelo repositório ──────────────────────────
|
||||
private void CarregarDadosFake()
|
||||
{
|
||||
var hoje = DateTime.Today;
|
||||
_todos = new List<MLL.ModeloAgenda>
|
||||
{
|
||||
new(1, "AG001", "Reunião com cliente", hoje.ToString("dd/MM/yyyy"), "30 minutos antes", "Carlos Silva", DiaSemana(hoje), "09:00", "S", "OS-1042"),
|
||||
new(2, "AG002", "Visita técnica", hoje.ToString("dd/MM/yyyy"), "1 hora antes", "Ana Souza", DiaSemana(hoje), "14:00", "N", "OS-1055"),
|
||||
new(3, "AG003", "Entrega de equipamento", hoje.AddDays(4).ToString("dd/MM/yyyy"), "1 dia antes", "Pedro Lima", DiaSemana(hoje.AddDays(4)), "10:30", "N", ""),
|
||||
new(4, "AG004", "Manutenção preventiva", hoje.AddDays(-2).ToString("dd/MM/yyyy"), "30 minutos antes", "Carlos Silva", DiaSemana(hoje.AddDays(-2)), "08:00", "S", "OS-1030"),
|
||||
new(5, "AG005", "Treinamento equipe", hoje.AddDays(7).ToString("dd/MM/yyyy"), "1 dia antes", "Ana Souza", DiaSemana(hoje.AddDays(7)), "13:00", "N", ""),
|
||||
};
|
||||
}//Carregar dados fakes para ixibição
|
||||
private void CarregarDadosDoBanco()
|
||||
{
|
||||
BLLAgenda _agendaBLL = new BLLAgenda(_conexao);
|
||||
_todos.Clear();
|
||||
_todos.AddRange(_agendaBLL.Listar());
|
||||
}//Carregar dados reais do banco de dados usando o repositório
|
||||
|
||||
private static DateTime ParseData(string? value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value)) return DateTime.MinValue;
|
||||
if (DateTime.TryParseExact(value, "dd/MM/yyyy",
|
||||
System.Globalization.CultureInfo.InvariantCulture,
|
||||
System.Globalization.DateTimeStyles.None, out var dt)) return dt;
|
||||
if (DateTime.TryParse(value, out dt)) return dt;
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
|
||||
private static string DiaSemana(DateTime d) =>
|
||||
new System.Globalization.CultureInfo("pt-BR").DateTimeFormat.GetDayName(d.DayOfWeek);
|
||||
|
||||
private RoundButton CreateToolbarButton(string text, Color color) => new RoundButton
|
||||
{
|
||||
Text = text,
|
||||
Size = new Size(95, 32),
|
||||
BackColor = color,
|
||||
ForeColor = Color.White,
|
||||
Font = new Font("Segoe UI Semibold", 8.5f),
|
||||
Margin = new Padding(0, 0, 6, 0),
|
||||
Cursor = Cursors.Hand
|
||||
};
|
||||
}
|
||||
}
|
||||
120
Dashboards/Consultas/AgendaConsultaPanel.resx
Normal file
120
Dashboards/Consultas/AgendaConsultaPanel.resx
Normal 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>
|
||||
368
Dashboards/Dashmain/DashboardPanel.cs
Normal file
368
Dashboards/Dashmain/DashboardPanel.cs
Normal file
@ -0,0 +1,368 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Windows.Forms;
|
||||
using System.Globalization;
|
||||
namespace UI
|
||||
{
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
// DashboardPanel — painel principal com KPI cards + tabela de OS
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
public class DashboardPanel : UserControl
|
||||
{
|
||||
// ── Paleta ─────────────────────────────────────────────────────────
|
||||
private static readonly Color Surface = Color.FromArgb(255, 255, 255);
|
||||
private static readonly Color Surface2 = Color.FromArgb(248, 250, 252);
|
||||
private static readonly Color Border = Color.FromArgb(226, 232, 240);
|
||||
private static readonly Color TextPri = Color.FromArgb(15, 23, 42);
|
||||
private static readonly Color TextSec = Color.FromArgb(71, 85, 105);
|
||||
private static readonly Color TextMuted = Color.FromArgb(148, 163, 184);
|
||||
|
||||
private static readonly Color Blue = Color.FromArgb(37, 99, 235);
|
||||
private static readonly Color BlueLight = Color.FromArgb(219, 234, 254);
|
||||
private static readonly Color Green = Color.FromArgb(22, 163, 74);
|
||||
private static readonly Color GreenL = Color.FromArgb(220, 252, 231);
|
||||
private static readonly Color Amber = Color.FromArgb(217, 119, 6);
|
||||
private static readonly Color AmberL = Color.FromArgb(254, 243, 199);
|
||||
private static readonly Color Red = Color.FromArgb(220, 38, 38);
|
||||
private static readonly Color RedL = Color.FromArgb(254, 226, 226);
|
||||
private static readonly Color Orange = Color.FromArgb(234, 88, 12);
|
||||
private static readonly Color OrangeL = Color.FromArgb(255, 237, 213);
|
||||
|
||||
// ── Dados de OS ────────────────────────────────────────────────────
|
||||
private readonly List<OsRow> _ordens = new()
|
||||
{
|
||||
new OsRow("#0001", "João Silva", "Notebook Dell", OsStatus.EmAndamento, "07/04"),
|
||||
new OsRow("#0002", "Maria Souza", "PC Gamer", OsStatus.Concluida, "07/04"),
|
||||
new OsRow("#0003", "Carlos Mota", "Impressora HP", OsStatus.Aguardando, "08/04"),
|
||||
new OsRow("#0004", "Ana Lima", "iPhone 14", OsStatus.EmAndamento, "08/04"),
|
||||
new OsRow("#0005", "Pedro Rocha", "Monitor LG", OsStatus.Pendente, "09/04"),
|
||||
};
|
||||
|
||||
// ── KPI cards ──────────────────────────────────────────────────────
|
||||
// CORRIGIDO: instanciação posicional explícita (sem parâmetros nomeados)
|
||||
private readonly KpiCard[] _kpis;
|
||||
|
||||
// ── Layout ─────────────────────────────────────────────────────────
|
||||
private const int Pad = 24;
|
||||
private const int KpiH = 110;
|
||||
private const int KpiGap = 14;
|
||||
private const int CardRad = 10;
|
||||
private const int TopbarH = 56;
|
||||
private const int RowH = 38;
|
||||
|
||||
private readonly Font _fLabel;
|
||||
private readonly Font _fValue;
|
||||
private readonly Font _fDelta;
|
||||
private readonly Font _fHead;
|
||||
private readonly Font _fCell;
|
||||
private readonly Font _fColHead;
|
||||
private readonly Font _fMono;
|
||||
private readonly Font _fBtn;
|
||||
private readonly Font _fTopTitle;
|
||||
private readonly Font _fTopSub;
|
||||
|
||||
private Rectangle _btnNovaOS;
|
||||
private int _hoverRow = -1;
|
||||
|
||||
public DashboardPanel()
|
||||
{
|
||||
// CORRIGIDO: inicialização dos campos Font no construtor
|
||||
// (evita o aviso "campo não anulável precisa conter valor não nulo")
|
||||
_fLabel = new Font("Segoe UI", 8.5f);
|
||||
_fValue = new Font("Segoe UI Semibold", 18f);
|
||||
_fDelta = new Font("Segoe UI", 9f);
|
||||
_fHead = new Font("Segoe UI Semibold", 10.5f);
|
||||
_fCell = new Font("Segoe UI", 10f);
|
||||
_fColHead = new Font("Segoe UI", 8f);
|
||||
_fMono = new Font("Consolas", 9.5f);
|
||||
_fBtn = new Font("Segoe UI Semibold", 10f);
|
||||
_fTopTitle = new Font("Segoe UI Semibold", 13f);
|
||||
_fTopSub = new Font("Segoe UI", 9f);
|
||||
|
||||
// CORRIGIDO: KpiCard instanciado com construtor posicional explícito
|
||||
_kpis = new[]
|
||||
{
|
||||
new KpiCard("OS Abertas", "12", "↑ 4 essa semana", true, BlueLight, Blue),
|
||||
new KpiCard("OS Concluídas", "45", "↑ 12% vs mês", true, GreenL, Green),
|
||||
new KpiCard("Faturamento", "22.5k", "↑ R$ 2.100", true, AmberL, Amber),
|
||||
new KpiCard("Pendências", "3", "↓ aguardando", false, RedL, Red),
|
||||
};
|
||||
|
||||
BackColor = Surface2;
|
||||
DoubleBuffered = true;
|
||||
SetStyle(ControlStyles.AllPaintingInWmPaint |
|
||||
ControlStyles.OptimizedDoubleBuffer |
|
||||
ControlStyles.ResizeRedraw, true);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_fLabel.Dispose(); _fValue.Dispose(); _fDelta.Dispose();
|
||||
_fHead.Dispose(); _fCell.Dispose(); _fColHead.Dispose();
|
||||
_fMono.Dispose(); _fBtn.Dispose(); _fTopTitle.Dispose();
|
||||
_fTopSub.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
// ── Paint ──────────────────────────────────────────────────────────
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
var g = e.Graphics;
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
|
||||
|
||||
DrawTopbar(g);
|
||||
int y = TopbarH + Pad;
|
||||
DrawKpiRow(g, y);
|
||||
y += KpiH + 20;
|
||||
DrawOsCard(g, y);
|
||||
}
|
||||
|
||||
// ── Topbar ─────────────────────────────────────────────────────────
|
||||
private void DrawTopbar(Graphics g)
|
||||
{
|
||||
g.FillRectangle(new SolidBrush(Surface), 0, 0, Width, TopbarH);
|
||||
g.DrawLine(new Pen(Border, 1), 0, TopbarH, Width, TopbarH);
|
||||
|
||||
g.DrawString("Home", _fTopTitle, new SolidBrush(TextPri), Pad, 12);
|
||||
//g.DrawString("Quinta, 09 de abril de 2026", _fTopSub,
|
||||
g.DrawString(
|
||||
DateTime.Now.ToString("dd 'de' MMMM 'de' yyyy", new CultureInfo("pt-BR")), _fTopSub,
|
||||
new SolidBrush(TextMuted), Pad, 32);
|
||||
|
||||
int bw = 110, bh = 32;
|
||||
int bx = Width - Pad - bw;
|
||||
int by = (TopbarH - bh) / 2;
|
||||
_btnNovaOS = new Rectangle(bx, by, bw, bh);
|
||||
FillRoundRect(g, new SolidBrush(Blue), _btnNovaOS, 6);
|
||||
|
||||
var sf = new StringFormat
|
||||
{
|
||||
Alignment = StringAlignment.Center,
|
||||
LineAlignment = StringAlignment.Center
|
||||
};
|
||||
g.DrawString("+ Nova OS", _fBtn, new SolidBrush(Color.White), _btnNovaOS, sf);
|
||||
}
|
||||
|
||||
// ── KPI Row ────────────────────────────────────────────────────────
|
||||
private void DrawKpiRow(Graphics g, int y)
|
||||
{
|
||||
int totalGap = KpiGap * (_kpis.Length - 1);
|
||||
int kpiW = (Width - Pad * 2 - totalGap) / _kpis.Length;
|
||||
|
||||
for (int i = 0; i < _kpis.Length; i++)
|
||||
{
|
||||
int x = Pad + i * (kpiW + KpiGap);
|
||||
DrawKpiCard(g, _kpis[i], new Rectangle(x, y, kpiW, KpiH));
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawKpiCard(Graphics g, KpiCard kpi, Rectangle r)
|
||||
{
|
||||
FillRoundRect(g, new SolidBrush(Surface), r, CardRad);
|
||||
DrawRoundBorder(g, r, CardRad, Border);
|
||||
|
||||
int dotSize = 36;
|
||||
var dotRect = new Rectangle(r.Right - 16 - dotSize, r.Y + 16, dotSize, dotSize);
|
||||
FillRoundRect(g, new SolidBrush(kpi.DotBg), dotRect, 8);
|
||||
|
||||
g.DrawString(kpi.Label, _fLabel, new SolidBrush(TextMuted), r.X + 16, r.Y + 18);
|
||||
g.DrawString(kpi.Value, _fValue, new SolidBrush(TextPri), r.X + 14, r.Y + 36);
|
||||
|
||||
var deltaColor = kpi.DeltaUp ? Green : Red;
|
||||
g.DrawString(kpi.Delta, _fDelta, new SolidBrush(deltaColor), r.X + 16, r.Y + 76);
|
||||
}
|
||||
|
||||
// ── OS Card ────────────────────────────────────────────────────────
|
||||
private void DrawOsCard(Graphics g, int y)
|
||||
{
|
||||
string[] cols = { "OS", "Cliente", "Equipamento", "Status", "Data" };
|
||||
float[] colW = { 0.08f, 0.22f, 0.28f, 0.22f, 0.10f };
|
||||
|
||||
int cardH = 28 + RowH + RowH * _ordens.Count + 16;
|
||||
var card = new Rectangle(Pad, y, Width - Pad * 2, cardH);
|
||||
|
||||
FillRoundRect(g, new SolidBrush(Surface), card, CardRad);
|
||||
DrawRoundBorder(g, card, CardRad, Border);
|
||||
|
||||
g.DrawString("Ordens de Serviço Recentes", _fHead,
|
||||
new SolidBrush(TextPri), card.X + 18, card.Y + 16);
|
||||
|
||||
int tableY = card.Y + 44;
|
||||
g.DrawLine(new Pen(Border, 0.5f), card.X, tableY, card.Right, tableY);
|
||||
|
||||
int cx = card.X;
|
||||
for (int c = 0; c < cols.Length; c++)
|
||||
{
|
||||
int cw = (int)(card.Width * colW[c]);
|
||||
var sf = new StringFormat { LineAlignment = StringAlignment.Center };
|
||||
g.DrawString(cols[c].ToUpperInvariant(), _fColHead,
|
||||
new SolidBrush(TextMuted), cx + 10, tableY + 2, sf);
|
||||
cx += cw;
|
||||
}
|
||||
|
||||
for (int i = 0; i < _ordens.Count; i++)
|
||||
{
|
||||
int ry = tableY + RowH + i * RowH;
|
||||
var row = _ordens[i];
|
||||
|
||||
if (i == _hoverRow)
|
||||
g.FillRectangle(new SolidBrush(Surface2),
|
||||
card.X + 1, ry, card.Width - 2, RowH);
|
||||
|
||||
g.DrawLine(new Pen(Border, 0.5f), card.X, ry, card.Right, ry);
|
||||
|
||||
cx = card.X;
|
||||
int[] cws = GetColWidths(card.Width, colW);
|
||||
|
||||
g.DrawString(row.OS, _fMono,
|
||||
new SolidBrush(TextMuted), cx + 10, ry + (RowH - 14) / 2);
|
||||
cx += cws[0];
|
||||
|
||||
g.DrawString(row.Cliente, _fCell,
|
||||
new SolidBrush(TextPri), cx + 8, ry + (RowH - 14) / 2);
|
||||
cx += cws[1];
|
||||
|
||||
g.DrawString(row.Equipamento, _fCell,
|
||||
new SolidBrush(TextSec), cx + 8, ry + (RowH - 14) / 2);
|
||||
cx += cws[2];
|
||||
|
||||
DrawBadge(g, row.Status, cx + 8, ry + (RowH - 20) / 2);
|
||||
cx += cws[3];
|
||||
|
||||
g.DrawString(row.Data, _fCell,
|
||||
new SolidBrush(TextMuted), cx + 8, ry + (RowH - 14) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] GetColWidths(int total, float[] ratios)
|
||||
{
|
||||
var ws = new int[ratios.Length];
|
||||
for (int i = 0; i < ratios.Length; i++)
|
||||
ws[i] = (int)(total * ratios[i]);
|
||||
return ws;
|
||||
}
|
||||
|
||||
private void DrawBadge(Graphics g, OsStatus status, int x, int y)
|
||||
{
|
||||
var (label, bg, fg) = status switch
|
||||
{
|
||||
OsStatus.Concluida => ("Concluída", GreenL, Color.FromArgb(22, 101, 52)),
|
||||
OsStatus.EmAndamento => ("Em andamento", AmberL, Color.FromArgb(146, 64, 14)),
|
||||
OsStatus.Aguardando => ("Aguardando", BlueLight, Color.FromArgb(30, 64, 175)),
|
||||
OsStatus.Pendente => ("Pendente", RedL, Color.FromArgb(153, 27, 27)),
|
||||
_ => ("—", Border, TextMuted)
|
||||
};
|
||||
|
||||
var sz = g.MeasureString(label, _fDelta);
|
||||
int bw = (int)sz.Width + 16;
|
||||
int bh = 20;
|
||||
var badge = new Rectangle(x, y, bw, bh);
|
||||
FillRoundRect(g, new SolidBrush(bg), badge, 10);
|
||||
|
||||
var sf = new StringFormat
|
||||
{
|
||||
Alignment = StringAlignment.Center,
|
||||
LineAlignment = StringAlignment.Center
|
||||
};
|
||||
g.DrawString(label, _fDelta, new SolidBrush(fg), badge, sf);
|
||||
}
|
||||
|
||||
// ── Mouse ──────────────────────────────────────────────────────────
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
int row = HitTestRow(e.Y);
|
||||
if (row != _hoverRow) { _hoverRow = row; Invalidate(); }
|
||||
Cursor = _btnNovaOS.Contains(e.Location) ? Cursors.Hand : Cursors.Default;
|
||||
}
|
||||
|
||||
protected override void OnMouseLeave(EventArgs e)
|
||||
{
|
||||
_hoverRow = -1;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
private int HitTestRow(int mouseY)
|
||||
{
|
||||
int tableY = TopbarH + Pad + KpiH + 20 + 44 + RowH;
|
||||
for (int i = 0; i < _ordens.Count; i++)
|
||||
{
|
||||
int ry = tableY + i * RowH;
|
||||
if (mouseY >= ry && mouseY < ry + RowH) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ── GDI Helpers ────────────────────────────────────────────────────
|
||||
private static void FillRoundRect(Graphics g, Brush brush, Rectangle r, int radius)
|
||||
{
|
||||
using var path = RoundRectPath(r, radius);
|
||||
g.FillPath(brush, path);
|
||||
}
|
||||
|
||||
private static void DrawRoundBorder(Graphics g, Rectangle r, int radius, Color color)
|
||||
{
|
||||
using var path = RoundRectPath(r, radius);
|
||||
g.DrawPath(new Pen(color, 0.5f), path);
|
||||
}
|
||||
|
||||
private static GraphicsPath RoundRectPath(Rectangle r, int radius)
|
||||
{
|
||||
var path = new GraphicsPath();
|
||||
path.AddArc(r.X, r.Y, radius * 2, radius * 2, 180, 90);
|
||||
path.AddArc(r.Right - radius * 2, r.Y, radius * 2, radius * 2, 270, 90);
|
||||
path.AddArc(r.Right - radius * 2, r.Bottom - radius * 2, radius * 2, radius * 2, 0, 90);
|
||||
path.AddArc(r.X, r.Bottom - radius * 2, radius * 2, radius * 2, 90, 90);
|
||||
path.CloseFigure();
|
||||
return path;
|
||||
}
|
||||
|
||||
// ── Modelos ────────────────────────────────────────────────────────
|
||||
// CORRIGIDO: usando classes simples em vez de records posicionais
|
||||
// para compatibilidade com qualquer versão do compilador .NET 6+.
|
||||
private class OsRow
|
||||
{
|
||||
public string OS { get; }
|
||||
public string Cliente { get; }
|
||||
public string Equipamento { get; }
|
||||
public OsStatus Status { get; }
|
||||
public string Data { get; }
|
||||
|
||||
public OsRow(string os, string cliente, string equipamento, OsStatus status, string data)
|
||||
{
|
||||
OS = os;
|
||||
Cliente = cliente;
|
||||
Equipamento = equipamento;
|
||||
Status = status;
|
||||
Data = data;
|
||||
}
|
||||
}
|
||||
|
||||
private class KpiCard
|
||||
{
|
||||
public string Label { get; }
|
||||
public string Value { get; }
|
||||
public string Delta { get; }
|
||||
public bool DeltaUp { get; }
|
||||
public Color DotBg { get; }
|
||||
public Color DotFg { get; }
|
||||
|
||||
public KpiCard(string label, string value, string delta, bool deltaUp, Color dotBg, Color dotFg)
|
||||
{
|
||||
Label = label;
|
||||
Value = value;
|
||||
Delta = delta;
|
||||
DeltaUp = deltaUp;
|
||||
DotBg = dotBg;
|
||||
DotFg = dotFg;
|
||||
}
|
||||
}
|
||||
|
||||
private enum OsStatus { Concluida, EmAndamento, Aguardando, Pendente }
|
||||
}
|
||||
}
|
||||
120
Dashboards/Dashmain/DashboardPanel.resx
Normal file
120
Dashboards/Dashmain/DashboardPanel.resx
Normal 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>
|
||||
147
Dashboards/Dashmain/MainForm.cs
Normal file
147
Dashboards/Dashmain/MainForm.cs
Normal file
@ -0,0 +1,147 @@
|
||||
using CCH;
|
||||
using CustomMessageBox;
|
||||
using DAL;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using TLL;
|
||||
namespace UI
|
||||
{
|
||||
public class MainForm : Form
|
||||
{
|
||||
private readonly SidebarControl _sidebar;
|
||||
private readonly DashboardPanel _dashboard;
|
||||
|
||||
private readonly ClienteCadastroPanel _pClientes;
|
||||
private readonly EmpresaCadastroPanel _pEmpresa;
|
||||
private readonly EmpresaConfiguracoesPanel _pEmpresaConfig;
|
||||
private readonly AgendaCadastroPanel _pAgendaCadastro;
|
||||
private readonly AgendaConsultaPanel _pAgendaConsulta;
|
||||
private readonly FuncionariosCadastroPanel _pfuncionariosCadastro ;
|
||||
private readonly Panel _pOrdens;
|
||||
private readonly Panel _pProdutos;
|
||||
private readonly Panel _pEstoque;
|
||||
private readonly Panel _pFinanceiro;
|
||||
|
||||
public MainForm()
|
||||
{
|
||||
Text = "LevelOS — Sistema ERP";
|
||||
this.WindowState = FormWindowState.Maximized;
|
||||
this.MinimumSize = new Size(1100, 750);
|
||||
this.BackColor = Color.FromArgb(248, 250, 252);
|
||||
|
||||
_sidebar = new SidebarControl { Dock = DockStyle.Left };
|
||||
_sidebar.NavItemClicked += OnNavItemClicked;
|
||||
|
||||
_dashboard = new DashboardPanel { Dock = DockStyle.Fill };
|
||||
|
||||
_pClientes = new ClienteCadastroPanel { Dock = DockStyle.Fill, Visible = false };
|
||||
_pEmpresa = new EmpresaCadastroPanel { Dock = DockStyle.Fill, Visible = false };
|
||||
_pEmpresaConfig = new EmpresaConfiguracoesPanel { Dock = DockStyle.Fill, Visible = false };
|
||||
_pAgendaCadastro = new AgendaCadastroPanel { Dock = DockStyle.Fill, Visible = false };
|
||||
_pAgendaConsulta = new AgendaConsultaPanel { Dock = DockStyle.Fill, Visible = false };
|
||||
_pfuncionariosCadastro = new FuncionariosCadastroPanel { Dock = DockStyle.Fill, Visible = false };
|
||||
_pOrdens = PlaceholderPanel("Ordens de Serviço", Color.FromArgb(22, 163, 74));
|
||||
_pProdutos = PlaceholderPanel("Catálogo de Produtos", Color.FromArgb(217, 119, 6));
|
||||
_pEstoque = PlaceholderPanel("Controle de Estoque", Color.FromArgb(234, 88, 12));
|
||||
_pFinanceiro = PlaceholderPanel("Fluxo Financeiro", Color.FromArgb(124, 58, 237));
|
||||
|
||||
var mainContainer = new Panel { Dock = DockStyle.Fill };
|
||||
mainContainer.Controls.Add(_pFinanceiro);
|
||||
mainContainer.Controls.Add(_pAgendaCadastro);
|
||||
mainContainer.Controls.Add(_pAgendaConsulta);
|
||||
mainContainer.Controls.Add(_pEstoque);
|
||||
mainContainer.Controls.Add(_pProdutos);
|
||||
mainContainer.Controls.Add(_pOrdens);
|
||||
mainContainer.Controls.Add(_pEmpresa);
|
||||
mainContainer.Controls.Add(_pEmpresaConfig);
|
||||
mainContainer.Controls.Add(_pClientes);
|
||||
mainContainer.Controls.Add(_dashboard);
|
||||
mainContainer.Controls.Add(_pfuncionariosCadastro);
|
||||
|
||||
Controls.Add(mainContainer);
|
||||
Controls.Add(_sidebar);
|
||||
|
||||
ShowPanel(_dashboard);
|
||||
|
||||
}
|
||||
|
||||
private void OnNavItemClicked(object? sender, int index)
|
||||
{
|
||||
/* Índices:
|
||||
0 = Dashboard
|
||||
2 = Ordens de Serviço
|
||||
4 = Produtos
|
||||
5 = Estoque
|
||||
9 = Financeiro
|
||||
99 = Submenu → Clientes
|
||||
98 = Submenu → Empresa
|
||||
*/
|
||||
switch (index)
|
||||
{
|
||||
case 0: ShowPanel(_dashboard); break;
|
||||
case 2: ShowPanel(_pOrdens); break;
|
||||
case 4: ShowPanel(_pProdutos); break;
|
||||
case 5: ShowPanel(_pEstoque); break;
|
||||
case 9: ShowPanel(_pFinanceiro); break;
|
||||
case 99: ShowPanel(_pClientes); break;
|
||||
case 103: ShowPanel(_pfuncionariosCadastro); break;
|
||||
case 106: ShowPanel(_pEmpresa); break;
|
||||
|
||||
|
||||
case 202: ShowPanel(_pEmpresaConfig); break;
|
||||
case 300: ShowPanel(_pAgendaCadastro); break;
|
||||
case 301: ShowPanel(_pAgendaConsulta); break;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowPanel(Control panelToShow)
|
||||
{
|
||||
_dashboard.Visible = (panelToShow == _dashboard);
|
||||
_pClientes.Visible = (panelToShow == _pClientes);
|
||||
_pEmpresa.Visible = (panelToShow == _pEmpresa);
|
||||
_pEmpresaConfig.Visible = (panelToShow == _pEmpresaConfig);
|
||||
_pOrdens.Visible = (panelToShow == _pOrdens);
|
||||
_pProdutos.Visible = (panelToShow == _pProdutos);
|
||||
_pEstoque.Visible = (panelToShow == _pEstoque);
|
||||
_pFinanceiro.Visible = (panelToShow == _pFinanceiro);
|
||||
_pAgendaCadastro.Visible = (panelToShow == _pAgendaCadastro);
|
||||
_pAgendaConsulta.Visible = (panelToShow == _pAgendaConsulta);
|
||||
_pfuncionariosCadastro.Visible = (panelToShow == _pfuncionariosCadastro);
|
||||
|
||||
if (panelToShow.Visible)
|
||||
{
|
||||
panelToShow.BringToFront();
|
||||
panelToShow.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
private static Panel PlaceholderPanel(string titulo, Color cor)
|
||||
{
|
||||
var p = new Panel { Dock = DockStyle.Fill, Visible = false };
|
||||
p.Paint += (s, e) =>
|
||||
{
|
||||
var g = e.Graphics;
|
||||
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
|
||||
var r = p.ClientRectangle;
|
||||
g.Clear(Color.FromArgb(248, 250, 252));
|
||||
|
||||
var circle = new Rectangle(r.Width / 2 - 40, r.Height / 2 - 80, 80, 80);
|
||||
g.FillEllipse(new SolidBrush(Color.FromArgb(20, cor)), circle);
|
||||
|
||||
using var f1 = new Font("Segoe UI Semibold", 16f);
|
||||
using var f2 = new Font("Segoe UI", 10f);
|
||||
var sf = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
|
||||
|
||||
g.DrawString(titulo, f1, new SolidBrush(Color.FromArgb(30, 41, 59)),
|
||||
new RectangleF(0, r.Height / 2f - 10, r.Width, 40), sf);
|
||||
|
||||
g.DrawString("Este módulo está sendo integrado ao LevelOS", f2, new SolidBrush(Color.FromArgb(148, 163, 184)),
|
||||
new RectangleF(0, r.Height / 2f + 25, r.Width, 30), sf);
|
||||
};
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
120
Dashboards/Dashmain/MainForm.resx
Normal file
120
Dashboards/Dashmain/MainForm.resx
Normal 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>
|
||||
423
Dashboards/Dashmain/SidebarControl.cs
Normal file
423
Dashboards/Dashmain/SidebarControl.cs
Normal file
@ -0,0 +1,423 @@
|
||||
using CustomMessageBox;
|
||||
using DAL;
|
||||
using DALL;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class SidebarControl : UserControl
|
||||
{
|
||||
//Recebendo a conexao
|
||||
string _cx = DadosDaConexao.ObterConexao();
|
||||
|
||||
// ── Cores do Tema LevelOS ──────────────────────────────────────────
|
||||
private static readonly Color NavyDark = Color.FromArgb(15, 30, 60);
|
||||
private static readonly Color NavyMid = Color.FromArgb(26, 45, 80);
|
||||
private static readonly Color AccentBlue = Color.FromArgb(37, 99, 235);
|
||||
private static readonly Color TextLight = Color.FromArgb(255, 255, 255);
|
||||
private static readonly Color TextMuted = Color.FromArgb(148, 163, 184);
|
||||
private static readonly Color Divider = Color.FromArgb(40, 255, 255, 255);
|
||||
|
||||
// ── Estado e Escalonamento (DPI) ───────────────────────────────────
|
||||
private float _scale = 1.0f;
|
||||
private int _activeIndex = 0;
|
||||
private int _hoverIndex = -1;
|
||||
|
||||
// Propriedades Scaled (Ajustam-se ao monitor)
|
||||
private int ScaledWidth => (int)(220 * _scale);
|
||||
private int ScaledLogoH => (int)(55 * _scale);
|
||||
private int ScaledSectionH => (int)(32 * _scale);
|
||||
private int ScaledItemH => (int)(40 * _scale);
|
||||
private int ScaledItemPadX => (int)(12 * _scale);
|
||||
private int ScaledFooterH => (int)(50 * _scale);
|
||||
private int ScaledIconSize => (int)(16 * _scale);
|
||||
|
||||
// ── Submenus ───────────────────────────────────────────────────────
|
||||
private ContextMenuStrip _subMenuBanco, _subMenuConfiguracao,
|
||||
_subMenuAjuda, _subMenuOrdemServico, _subMenuFinanceiro,_subMenuCadastro, _subMenuAgenda;
|
||||
|
||||
public string UserName = "Levelcode", UserFunction = "Administrador";
|
||||
public event EventHandler<int>? NavItemClicked;
|
||||
|
||||
private readonly List<NavItem> _items = new()
|
||||
{
|
||||
new NavItem("Dashboard", SvgIcon.Grid, "Principal", null),
|
||||
new NavItem("Cadastro", SvgIcon.UserPlus, null, "3"),
|
||||
new NavItem("Ordens de Serviço", SvgIcon.FileText, null, "12"),
|
||||
new NavItem("Agenda", SvgIcon.Calendar, null, null),
|
||||
new NavItem("Produtos", SvgIcon.Package, "Gestão", null),
|
||||
new NavItem("Estoque", SvgIcon.Inventory, null, null),
|
||||
//new NavItem("Serviços", SvgIcon.Briefcase, null, null),
|
||||
//new NavItem("Transportadoras", SvgIcon.Truck, null, null),
|
||||
new NavItem("Financeiro", SvgIcon.DollarSign, null, null),
|
||||
new NavItem("Banco de Dados", SvgIcon.Database, "Sistema", null),
|
||||
new NavItem("Configurações", SvgIcon.Settings, null, null),
|
||||
new NavItem("Suporte Técnico", SvgIcon.Support, "Ajuda", null),
|
||||
};
|
||||
|
||||
public void backupFull(string conexao)
|
||||
{
|
||||
var backupService = new DALLBackupService(conexao);
|
||||
var resultadoFull = backupService.ExecutarBackupFull();
|
||||
|
||||
if (resultadoFull.Sucesso)
|
||||
NT_MessageBox.Show($"✅ Backup FULL concluído em {resultadoFull.Duracao.TotalSeconds:F1}s","Backup do banco de dados",MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
else
|
||||
NT_MessageBox.Show($"❌ Erro no Backup FULL: {resultadoFull.Erro}","Erro ao tentar executar backup do sistema.",MessageBoxButtons.OK,MessageBoxIcon.Error);
|
||||
}//Criar backup full
|
||||
|
||||
public void backupDifrencial(string conexao)
|
||||
{
|
||||
var backupService = new DALLBackupService(conexao);
|
||||
var resultadoDiff = backupService.ExecutarBackupDiferencial();
|
||||
|
||||
if (resultadoDiff.Sucesso)
|
||||
NT_MessageBox.Show($"✅ Backup DIFERENCIAL concluído em {resultadoDiff.Duracao.TotalSeconds:F1}s","Backup diferencial concluido", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
else
|
||||
NT_MessageBox.Show($"❌ Erro no Backup DIFERENCIAL: {resultadoDiff.Erro}","Erro ao tentar executar backup diferencial no sistema", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}//Criar backup diferencial
|
||||
|
||||
|
||||
|
||||
public SidebarControl()
|
||||
{
|
||||
BackColor = NavyDark;
|
||||
DoubleBuffered = true;
|
||||
this.SetStyle(ControlStyles.ResizeRedraw, true);
|
||||
}
|
||||
|
||||
protected override void OnHandleCreated(EventArgs e)
|
||||
{
|
||||
base.OnHandleCreated(e);
|
||||
using (Graphics g = this.CreateGraphics()) { _scale = g.DpiX / 96f; }
|
||||
this.Width = ScaledWidth;
|
||||
SetupSubMenus();
|
||||
}
|
||||
|
||||
private void SetupSubMenus()
|
||||
{
|
||||
//Submenu Cadastro
|
||||
_subMenuCadastro = CreateStyledMenu();
|
||||
_subMenuCadastro.Items.Add("👤 Clientes", null, (s, e) => {NavItemClicked?.Invoke(this, 99);});
|
||||
_subMenuCadastro.Items.Add("💻 Equipamentos", null, (s, e) => { NavItemClicked?.Invoke(this, 100); });
|
||||
_subMenuCadastro.Items.Add("📜 Contratos", null, (s, e) => { NavItemClicked?.Invoke(this, 101); });
|
||||
_subMenuCadastro.Items.Add("🏭 Fornecedores", null, (s, e) => { NavItemClicked?.Invoke(this, 102); });
|
||||
_subMenuCadastro.Items.Add("👔 Funcionários", null, (s, e) => { NavItemClicked?.Invoke(this, 103); });
|
||||
_subMenuCadastro.Items.Add("🚚 Transportadoras", null, (s, e) => { NavItemClicked?.Invoke(this, 104); });
|
||||
_subMenuCadastro.Items.Add("🛠️ Serviços", null, (s, e) => { NavItemClicked?.Invoke(this, 105); });
|
||||
_subMenuCadastro.Items.Add("🏢 Empresa", null, (s, e) => { NavItemClicked?.Invoke(this, 106); });
|
||||
_subMenuCadastro.Items.Add("🔑 Usuários do Sistema", null, (s, e) => { NavItemClicked?.Invoke(this, 107); });
|
||||
|
||||
_subMenuBanco = CreateStyledMenu();
|
||||
_subMenuBanco.Items.Add("⚙️ Configuração Database", null, (s, e) => showForms<Form>()); // Substitua pelo seu Form
|
||||
_subMenuBanco.Items.Add("💾 Backup de Dados (FULL)", null, (s, e) => backupFull(this._cx));
|
||||
_subMenuBanco.Items.Add("⚡ Backup de Dados (DIFF)", null, (s, e) => backupDifrencial(this._cx));
|
||||
_subMenuBanco.Items.Add("🔄 Restaurar Banco");
|
||||
|
||||
|
||||
//submenu Configurações
|
||||
_subMenuConfiguracao = CreateStyledMenu();
|
||||
_subMenuConfiguracao.Items.Add("🖼️ Personalização de OS");
|
||||
_subMenuConfiguracao.Items.Add("🖥️ Personalização de Sistema");
|
||||
_subMenuConfiguracao.Items.Add(" Configuração Empresa", null, (s, e) => { NavItemClicked?.Invoke(this, 202); });
|
||||
_subMenuConfiguracao.Items.Add(new ToolStripSeparator());
|
||||
_subMenuConfiguracao.Items.Add("📂 FTP-Cliente"); // Pasta para arquivos
|
||||
_subMenuConfiguracao.Items.Add("💬 Telegram-Cliente"); // Balão de conversa
|
||||
_subMenuConfiguracao.Items.Add("📩 SMTP-Cliente"); // Envelope de saída
|
||||
_subMenuConfiguracao.Items.Add(new ToolStripSeparator());
|
||||
// Automação
|
||||
_subMenuConfiguracao.Items.Add("⏰ Backups Automáticos"); // Relógio para agendamento
|
||||
_subMenuConfiguracao.Items.Add("☁️ Backup em Nuvem");
|
||||
|
||||
_subMenuAjuda = CreateStyledMenu();
|
||||
_subMenuAjuda.Items.Add("💬 Atendimento Online");
|
||||
_subMenuAjuda.Items.Add("📖 Manual do Sistema");
|
||||
|
||||
_subMenuOrdemServico = CreateStyledMenu();
|
||||
|
||||
_subMenuOrdemServico.Items.Add("✚ Abrir nova O.S", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuOrdemServico.Items.Add("✎ Alterar O.S", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuOrdemServico.Items.Add("🔒 Encerrar O.S", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuOrdemServico.Items.Add("🔍 Localizar O.S", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuOrdemServico.Items.Add("📋 Orçamento de O.S", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuOrdemServico.Items.Add("📜 Histórico de O.S", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuOrdemServico.Items.Add("📊 Relatório de O.S", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuOrdemServico.Items.Add("🖨 Imprimir", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuOrdemServico.Items.Add("⚠️ Chamado Técnico", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuOrdemServico.Items.Add("🌐 OS WEB", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuOrdemServico.Items.Add("🔓 Reabrir OS", null, (s, e) => { /* Lógica */ });
|
||||
|
||||
_subMenuFinanceiro = CreateStyledMenu();
|
||||
|
||||
_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 pagar", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuFinanceiro.Items.Add(new ToolStripSeparator()); // Linha divisória
|
||||
_subMenuFinanceiro.Items.Add("🛒 Compras", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuFinanceiro.Items.Add("💰 Vendas", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuFinanceiro.Items.Add("🧾 Notas Fiscais", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuFinanceiro.Items.Add(new ToolStripSeparator()); // Linha divisória
|
||||
_subMenuFinanceiro.Items.Add("📂 Arquivo Contador", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuFinanceiro.Items.Add("🏦 Dados Bancários", null, (s, e) => { /* Lógica */ });
|
||||
_subMenuFinanceiro.Items.Add("🕒 Histórico Financeiro", null, (s, e) => { /* Lógica */ });
|
||||
|
||||
|
||||
// private ContextMenuStrip _subMenuAgenda;
|
||||
_subMenuAgenda = CreateStyledMenu();
|
||||
//_subMenuAgenda.Items.Add("➕ Novo compromisso", null, (s, e) => {showForms<AgendaForm>();});
|
||||
_subMenuAgenda.Items.Add("➕ Novo compromisso", null, (s, e) => { NavItemClicked?.Invoke(this, 300); });
|
||||
_subMenuAgenda.Items.Add("🔍 Consultar compromissos", null, (s, e) => { NavItemClicked?.Invoke(this, 301); });
|
||||
_subMenuAgenda.Items.Add("✏️ Alterar compromisso", null, (s, e) => { /* Lógica de edição */ });
|
||||
_subMenuAgenda.Items.Add("🖨️ Imprimir", null, (s, e) => { /* Lógica de relatório */ });
|
||||
}
|
||||
|
||||
private ContextMenuStrip CreateStyledMenu()
|
||||
{
|
||||
return new ContextMenuStrip
|
||||
{
|
||||
BackColor = NavyMid,
|
||||
ForeColor = TextLight,
|
||||
ShowImageMargin = false,
|
||||
Font = new Font("Segoe UI", 10f * _scale),
|
||||
Renderer = new ToolStripProfessionalRenderer(new SubMenuColorTable())
|
||||
};
|
||||
}
|
||||
|
||||
private void showForms<T>() where T : Form, new()
|
||||
{
|
||||
using (T form = new T())
|
||||
{
|
||||
form.StartPosition = FormStartPosition.CenterScreen;
|
||||
form.ShowDialog();
|
||||
}
|
||||
}
|
||||
//Abrir agenda
|
||||
// AgendaForm.cs
|
||||
public class AgendaForm : Form
|
||||
{
|
||||
public AgendaForm()
|
||||
{
|
||||
Text = "Agenda de Compromissos";
|
||||
Size = new Size(1150, 780);
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
BackColor = Color.White;
|
||||
|
||||
var panel = new AgendaCadastroPanel();
|
||||
Controls.Add(panel);
|
||||
}
|
||||
}//abrir agenda de compromissos
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
var g = e.Graphics;
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
|
||||
|
||||
DrawLogo(g);
|
||||
DrawNavItems(g, ScaledLogoH + (int)(8 * _scale));
|
||||
DrawFooter(g);
|
||||
}
|
||||
|
||||
private void DrawNavItems(Graphics g, int startY)
|
||||
{
|
||||
int y = startY;
|
||||
using var fSection = new Font("Segoe UI", 8f * _scale, FontStyle.Bold);
|
||||
using var fItem = new Font("Segoe UI", 10f * _scale);
|
||||
using var fItemSel = new Font("Segoe UI Semibold", 10f * _scale);
|
||||
|
||||
for (int i = 0; i < _items.Count; i++)
|
||||
{
|
||||
var item = _items[i];
|
||||
if (item.Section != null)
|
||||
{
|
||||
y += (int)(10 * _scale);
|
||||
g.DrawString(item.Section.ToUpper(), fSection, new SolidBrush(Color.FromArgb(120, TextMuted)), ScaledItemPadX + (int)(8 * _scale), y);
|
||||
y += ScaledSectionH;
|
||||
}
|
||||
|
||||
bool isActive = (i == _activeIndex);
|
||||
bool isHover = (i == _hoverIndex && !isActive);
|
||||
var itemRect = new Rectangle(ScaledItemPadX, y, Width - ScaledItemPadX * 2, ScaledItemH);
|
||||
|
||||
if (isActive) FillRoundRect(g, new SolidBrush(AccentBlue), itemRect, (int)(6 * _scale));
|
||||
else if (isHover) FillRoundRect(g, new SolidBrush(Color.FromArgb(20, 255, 255, 255)), itemRect, (int)(6 * _scale));
|
||||
|
||||
var color = isActive ? TextLight : Color.FromArgb(200, TextLight);
|
||||
DrawIcon(g, item.Icon, ScaledItemPadX + (int)(10 * _scale), y + (ScaledItemH - ScaledIconSize) / 2, ScaledIconSize, color);
|
||||
g.DrawString(item.Label, isActive ? fItemSel : fItem, new SolidBrush(color), ScaledItemPadX + (int)(36 * _scale), y + (ScaledItemH - (int)(16 * _scale)) / 2);
|
||||
|
||||
if (HasSubMenu(item.Label))
|
||||
g.DrawString("›", fItem, new SolidBrush(Color.FromArgb(100, TextLight)), Width - (int)(30 * _scale), y + (ScaledItemH - (int)(18 * _scale)) / 2);
|
||||
|
||||
y += ScaledItemH + (int)(2 * _scale);
|
||||
}
|
||||
}
|
||||
|
||||
// Adicione "Cadastro" na verificação
|
||||
private bool HasSubMenu(string label) =>
|
||||
label == "Cadastro" || // <-- Adicionado aqui
|
||||
label == "Banco de Dados" ||
|
||||
label == "Financeiro" ||
|
||||
label == "Ordens de Serviço" ||
|
||||
label == "Configurações" ||
|
||||
label == "Suporte Técnico" ||
|
||||
label == "Agenda"
|
||||
;
|
||||
|
||||
protected override void OnMouseClick(MouseEventArgs e)
|
||||
{
|
||||
int hit = HitTest(e.Y);
|
||||
if (hit >= 0)
|
||||
{
|
||||
_activeIndex = hit; Invalidate();
|
||||
string label = _items[hit].Label;
|
||||
Point menuPos = new Point(Width + 2, e.Y - (int)(15 * _scale));
|
||||
|
||||
if (label == "Banco de Dados") _subMenuBanco.Show(this, menuPos);
|
||||
else if (label == "Financeiro") _subMenuFinanceiro.Show(this, menuPos);
|
||||
else if(label == "Agenda") _subMenuAgenda.Show(this, menuPos);
|
||||
else if (label == "Ordens de Serviço") _subMenuOrdemServico.Show(this, menuPos);
|
||||
else if (label == "Configurações") _subMenuConfiguracao.Show(this, menuPos);
|
||||
else if (label == "Suporte Técnico") _subMenuAjuda.Show(this, menuPos);
|
||||
else if (label == "Cadastro") _subMenuCadastro.Show(this, menuPos);
|
||||
else NavItemClicked?.Invoke(this, hit);
|
||||
}
|
||||
}
|
||||
|
||||
private int HitTest(int mouseY)
|
||||
{
|
||||
int y = ScaledLogoH + (int)(8 * _scale);
|
||||
for (int i = 0; i < _items.Count; i++)
|
||||
{
|
||||
if (_items[i].Section != null) y += (int)(10 * _scale) + ScaledSectionH;
|
||||
if (mouseY >= y && mouseY < y + ScaledItemH) return i;
|
||||
y += ScaledItemH + (int)(2 * _scale);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e) { int hit = HitTest(e.Y); if (hit != _hoverIndex) { _hoverIndex = hit; Invalidate(); } }
|
||||
protected override void OnMouseLeave(EventArgs e) { _hoverIndex = -1; Invalidate(); }
|
||||
|
||||
private void DrawLogo(Graphics g)
|
||||
{
|
||||
var iconRect = new Rectangle((int)(16 * _scale), (int)(18 * _scale), (int)(34 * _scale), (int)(34 * _scale));
|
||||
FillRoundRect(g, new SolidBrush(AccentBlue), iconRect, (int)(8 * _scale));
|
||||
using var fIcon = new Font("Segoe UI", 14f * _scale, FontStyle.Bold);
|
||||
DrawCenteredString(g, "S", fIcon, TextLight, iconRect);
|
||||
g.DrawString("LevelOS", new Font("Segoe UI Semibold", 13f * _scale), new SolidBrush(TextLight), 58 * _scale, 20 * _scale);
|
||||
g.DrawString("SISTEMA ERP", new Font("Segoe UI", 8f * _scale), new SolidBrush(TextMuted), 59 * _scale, 38 * _scale);
|
||||
g.DrawLine(new Pen(Divider), 0, ScaledLogoH, Width, ScaledLogoH);
|
||||
}
|
||||
|
||||
private void DrawFooter(Graphics g)
|
||||
{
|
||||
int fy = Height - ScaledFooterH;
|
||||
g.DrawLine(new Pen(Divider), 0, fy, Width, fy);
|
||||
var avRect = new Rectangle((int)(16 * _scale), fy + (int)(14 * _scale), (int)(32 * _scale), (int)(32 * _scale));
|
||||
g.FillEllipse(new SolidBrush(AccentBlue), avRect);
|
||||
DrawCenteredString(g, "AD", new Font("Segoe UI Semibold", 10f * _scale), TextLight, avRect);
|
||||
g.DrawString(UserName, new Font("Segoe UI Semibold", 11f * _scale), new SolidBrush(TextLight), 56 * _scale, fy + (14 * _scale));
|
||||
g.DrawString(UserFunction, new Font("Segoe UI", 9f * _scale), new SolidBrush(TextMuted), 57 * _scale, fy + (30 * _scale));
|
||||
}
|
||||
|
||||
// ── MOTOR DE ÍCONES COMPLETO (GDI+) ────────────────────────────────
|
||||
private void DrawIcon(Graphics g, SvgIcon icon, int x, int y, int size, Color color)
|
||||
{
|
||||
using var p = new Pen(color, 1.6f * _scale) { StartCap = LineCap.Round, EndCap = LineCap.Round, LineJoin = LineJoin.Round };
|
||||
float s = size / 24f;
|
||||
g.TranslateTransform(x, y); g.ScaleTransform(s, s);
|
||||
|
||||
switch (icon)
|
||||
{
|
||||
case SvgIcon.Grid:
|
||||
g.DrawRectangle(p, 3, 3, 7, 7); g.DrawRectangle(p, 14, 3, 7, 7); g.DrawRectangle(p, 3, 14, 7, 7); g.DrawRectangle(p, 14, 14, 7, 7); break;
|
||||
case SvgIcon.Users:
|
||||
g.DrawEllipse(p, 5, 3, 8, 8); g.DrawArc(p, 2, 13, 14, 8, 180, 180); g.DrawArc(p, 15, 8, 6, 6, 270, 180); break;
|
||||
case SvgIcon.FileText:
|
||||
g.DrawLines(p, new PointF[] { new(6, 2), new(6, 22), new(18, 22), new(18, 8), new(14, 2), new(6, 2) }); g.DrawLine(p, 14, 2, 14, 8); g.DrawLine(p, 14, 8, 18, 8); break;
|
||||
case SvgIcon.Package:
|
||||
g.DrawLines(p, new PointF[] { new(12, 2), new(2, 7), new(12, 12), new(22, 7), new(12, 2) }); g.DrawLine(p, 2, 7, 2, 17); g.DrawLine(p, 22, 7, 22, 17); g.DrawLine(p, 12, 12, 12, 22); break;
|
||||
case SvgIcon.DollarSign:
|
||||
g.DrawLine(p, 12, 2, 12, 22); g.DrawArc(p, 7, 5, 10, 7, 110, 250); g.DrawArc(p, 7, 12, 10, 7, 270, 250); break;
|
||||
case SvgIcon.Database:
|
||||
g.DrawEllipse(p, 4, 3, 16, 6); g.DrawLine(p, 4, 6, 4, 18); g.DrawLine(p, 20, 6, 20, 18); g.DrawArc(p, 4, 15, 16, 6, 0, 180); break;
|
||||
case SvgIcon.Calendar:
|
||||
g.DrawRectangle(p, 3, 4, 18, 17); g.DrawLine(p, 3, 9, 21, 9); g.DrawLine(p, 8, 2, 8, 6); g.DrawLine(p, 16, 2, 16, 6); break;
|
||||
case SvgIcon.Truck:
|
||||
g.DrawRectangle(p, 1, 5, 13, 11); g.DrawLines(p, new PointF[] { new(14, 16), new(14, 8), new(19, 8), new(23, 12), new(23, 16) });
|
||||
g.DrawEllipse(p, 3, 15, 4, 4); g.DrawEllipse(p, 17, 15, 4, 4); break;
|
||||
case SvgIcon.Factory:
|
||||
g.DrawRectangle(p, 2, 10, 20, 11); g.DrawLines(p, new PointF[] { new(2, 10), new(2, 5), new(8, 10), new(8, 5), new(14, 10) }); break;
|
||||
case SvgIcon.Briefcase:
|
||||
g.DrawRectangle(p, 3, 7, 18, 13); g.DrawArc(p, 9, 3, 6, 8, 180, 180); break;
|
||||
case SvgIcon.Support:
|
||||
g.DrawArc(p, 4, 4, 16, 16, 180, 180); g.DrawRectangle(p, 3, 13, 3, 5); g.DrawRectangle(p, 18, 13, 3, 5); break;
|
||||
case SvgIcon.Inventory:
|
||||
g.DrawRectangle(p, 3, 3, 18, 8); g.DrawRectangle(p, 3, 13, 18, 8); break;
|
||||
case SvgIcon.Settings:
|
||||
g.DrawEllipse(p, 9, 9, 6, 6);
|
||||
for (int a = 0; a < 360; a += 45)
|
||||
{
|
||||
float r = a * (float)Math.PI / 180f;
|
||||
g.DrawLine(p, 12 + (float)Math.Cos(r) * 8, 12 + (float)Math.Sin(r) * 8, 12 + (float)Math.Cos(r) * 11, 12 + (float)Math.Sin(r) * 11);
|
||||
}
|
||||
break;
|
||||
case SvgIcon.User: g.DrawEllipse(p, 8, 2, 8, 8); g.DrawArc(p, 3, 14, 18, 8, 180, 180); break;
|
||||
case SvgIcon.UserCheck: g.DrawEllipse(p, 8, 3, 8, 8); g.DrawArc(p, 3, 14, 18, 8, 180, 180); g.DrawRectangle(p, 10, 15, 4, 3); break;
|
||||
case SvgIcon.UserPlus:
|
||||
// Desenha o corpo do usuário (círculo e arco)
|
||||
g.DrawEllipse(p, 4, 4, 8, 8); // Cabeça
|
||||
g.DrawArc(p, 1, 14, 14, 8, 180, 180); // Ombros
|
||||
|
||||
// Desenha o sinal de "+" ao lado
|
||||
// Vertical
|
||||
g.DrawLine(p, 19, 7, 19, 15);
|
||||
// Horizontal
|
||||
g.DrawLine(p, 15, 11, 23, 11);
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
g.ResetTransform();
|
||||
}
|
||||
|
||||
// ── Helpers ──
|
||||
private static void FillRoundRect(Graphics g, Brush b, Rectangle r, int rad) { using var path = RoundRectPath(r, rad); g.FillPath(b, path); }
|
||||
private static GraphicsPath RoundRectPath(Rectangle r, int rad)
|
||||
{
|
||||
var path = new GraphicsPath(); int d = Math.Max(rad * 2, 1);
|
||||
path.AddArc(r.X, r.Y, d, d, 180, 90); path.AddArc(r.Right - d, r.Y, d, d, 270, 90);
|
||||
path.AddArc(r.Right - d, r.Bottom - d, d, d, 0, 90); path.AddArc(r.X, r.Bottom - d, d, d, 90, 90);
|
||||
path.CloseFigure(); return path;
|
||||
}
|
||||
private static void DrawCenteredString(Graphics g, string t, Font f, Color c, Rectangle r)
|
||||
{
|
||||
var sf = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
|
||||
g.DrawString(t, f, new SolidBrush(c), r, sf);
|
||||
}
|
||||
|
||||
private class NavItem
|
||||
{
|
||||
public string Label { get; }
|
||||
public SvgIcon Icon { get; }
|
||||
public string? Section { get; }
|
||||
public string? Badge { get; }
|
||||
public NavItem(string l, SvgIcon i, string? s, string? b) { Label = l; Icon = i; Section = s; Badge = b; }
|
||||
}
|
||||
private class SubMenuColorTable : ProfessionalColorTable
|
||||
{
|
||||
public override Color ToolStripDropDownBackground => NavyMid;
|
||||
public override Color MenuItemSelected => AccentBlue;
|
||||
public override Color MenuItemBorder => Color.Transparent;
|
||||
public override Color MenuItemSelectedGradientBegin => AccentBlue;
|
||||
public override Color MenuItemSelectedGradientEnd => AccentBlue;
|
||||
}
|
||||
}
|
||||
|
||||
public enum SvgIcon { Grid, Users, FileText, Package, DollarSign, User, Settings, Database, Truck, Factory, UserCheck, Briefcase, Support, Inventory, Wallet, ShoppingCart, ShoppingBag, Calendar , UserPlus}
|
||||
}
|
||||
120
Dashboards/Dashmain/SidebarControl.resx
Normal file
120
Dashboards/Dashmain/SidebarControl.resx
Normal 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>
|
||||
132
Dashboards/Main/Dash_main.Designer.cs
generated
Normal file
132
Dashboards/Main/Dash_main.Designer.cs
generated
Normal file
@ -0,0 +1,132 @@
|
||||
namespace UI
|
||||
{
|
||||
partial class Form1
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
lbltest = new Label();
|
||||
lV_button1 = new CPM.LV_BUTTON();
|
||||
lV_button2 = new CPM.LV_BUTTON();
|
||||
lV_button3 = new CPM.LV_BUTTON();
|
||||
SuspendLayout();
|
||||
//
|
||||
// lbltest
|
||||
//
|
||||
lbltest.AutoSize = true;
|
||||
lbltest.Location = new Point(12, 9);
|
||||
lbltest.Name = "lbltest";
|
||||
lbltest.Size = new Size(38, 15);
|
||||
lbltest.TabIndex = 0;
|
||||
lbltest.Text = "label1";
|
||||
//
|
||||
// lV_button1
|
||||
//
|
||||
lV_button1.BackColor = Color.MediumSlateBlue;
|
||||
lV_button1.BackgroundColor = Color.MediumSlateBlue;
|
||||
lV_button1.BorderColor = Color.PaleVioletRed;
|
||||
lV_button1.BorderRadius = 0;
|
||||
lV_button1.BorderSize = 0;
|
||||
lV_button1.ClickColor = Color.DarkBlue;
|
||||
lV_button1.FlatAppearance.BorderSize = 0;
|
||||
lV_button1.FlatStyle = FlatStyle.Flat;
|
||||
lV_button1.ForeColor = Color.White;
|
||||
lV_button1.HoverColor = Color.LightBlue;
|
||||
lV_button1.Location = new Point(734, 12);
|
||||
lV_button1.Name = "lV_button1";
|
||||
lV_button1.Size = new Size(148, 32);
|
||||
lV_button1.TabIndex = 1;
|
||||
lV_button1.Text = "FrmConfigDB";
|
||||
lV_button1.TextColor = Color.White;
|
||||
lV_button1.UseVisualStyleBackColor = false;
|
||||
lV_button1.Click += lV_button1_Click;
|
||||
//
|
||||
// lV_button2
|
||||
//
|
||||
lV_button2.BackColor = Color.MediumSlateBlue;
|
||||
lV_button2.BackgroundColor = Color.MediumSlateBlue;
|
||||
lV_button2.BorderColor = Color.PaleVioletRed;
|
||||
lV_button2.BorderRadius = 0;
|
||||
lV_button2.BorderSize = 0;
|
||||
lV_button2.ClickColor = Color.DarkBlue;
|
||||
lV_button2.FlatAppearance.BorderSize = 0;
|
||||
lV_button2.FlatStyle = FlatStyle.Flat;
|
||||
lV_button2.ForeColor = Color.White;
|
||||
lV_button2.HoverColor = Color.LightBlue;
|
||||
lV_button2.Location = new Point(734, 50);
|
||||
lV_button2.Name = "lV_button2";
|
||||
lV_button2.Size = new Size(148, 32);
|
||||
lV_button2.TabIndex = 2;
|
||||
lV_button2.Text = "Dashmain";
|
||||
lV_button2.TextColor = Color.White;
|
||||
lV_button2.UseVisualStyleBackColor = false;
|
||||
lV_button2.Click += lV_button2_Click;
|
||||
//
|
||||
// lV_button3
|
||||
//
|
||||
lV_button3.BackColor = Color.MediumSlateBlue;
|
||||
lV_button3.BackgroundColor = Color.MediumSlateBlue;
|
||||
lV_button3.BorderColor = Color.PaleVioletRed;
|
||||
lV_button3.BorderRadius = 0;
|
||||
lV_button3.BorderSize = 0;
|
||||
lV_button3.ClickColor = Color.DarkBlue;
|
||||
lV_button3.FlatAppearance.BorderSize = 0;
|
||||
lV_button3.FlatStyle = FlatStyle.Flat;
|
||||
lV_button3.ForeColor = Color.White;
|
||||
lV_button3.HoverColor = Color.LightBlue;
|
||||
lV_button3.Location = new Point(734, 88);
|
||||
lV_button3.Name = "lV_button3";
|
||||
lV_button3.Size = new Size(148, 32);
|
||||
lV_button3.TabIndex = 3;
|
||||
lV_button3.Text = "Arquivo Encryptado";
|
||||
lV_button3.TextColor = Color.White;
|
||||
lV_button3.UseVisualStyleBackColor = false;
|
||||
lV_button3.Click += lV_button3_Click;
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(894, 474);
|
||||
Controls.Add(lV_button3);
|
||||
Controls.Add(lV_button2);
|
||||
Controls.Add(lV_button1);
|
||||
Controls.Add(lbltest);
|
||||
Name = "Form1";
|
||||
Text = "Form1";
|
||||
Load += Form1_Load;
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Label lbltest;
|
||||
private CPM.LV_BUTTON lV_button1;
|
||||
private CPM.LV_BUTTON lV_button2;
|
||||
private CPM.LV_BUTTON lV_button3;
|
||||
}
|
||||
}
|
||||
75
Dashboards/Main/Dash_main.cs
Normal file
75
Dashboards/Main/Dash_main.cs
Normal file
@ -0,0 +1,75 @@
|
||||
using CAB;
|
||||
using CCH;
|
||||
using CPM;
|
||||
using CPT;
|
||||
using CustomMessageBox;
|
||||
using DAL;
|
||||
using TLL;
|
||||
using static CPT.SecurityManager;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public partial class Form1 : Form
|
||||
{
|
||||
public Form1()
|
||||
{
|
||||
InitializeComponent();
|
||||
string caminhoIcone = AppFileSystem.AppFileIconSystem;
|
||||
|
||||
if (File.Exists(caminhoIcone))
|
||||
{
|
||||
this.Icon = new Icon(caminhoIcone);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void Form1_Load(object sender, EventArgs e)
|
||||
{
|
||||
DadosDaConexao.Host = "206.42.13.180";
|
||||
DadosDaConexao.Port = 1433;
|
||||
DadosDaConexao.Banco = "Levelcode-LevelOS";
|
||||
DadosDaConexao.Usuario = "nicolas";
|
||||
DadosDaConexao.Senha = "Nike12122020*##";
|
||||
DadosDaConexao.ConnectTimeout = 1000;
|
||||
DadosDaConexao.Encrypt = false;
|
||||
DadosDaConexao.TrustServerCertificate = false;
|
||||
|
||||
DatabaseHelper.Salvar(AppFileSystem.AppFileDBSystem, AppInfoSystem.AppKeyMasterCrip);
|
||||
DatabaseHelper.Carregar(AppFileSystem.AppFileDBSystem, AppInfoSystem.AppKeyMasterCrip);
|
||||
this.lbltest.Text = DadosDaConexao.Host;
|
||||
if (DadosDaConexao.TestarConexao())
|
||||
{
|
||||
NT_MessageBox.Show("Conexão com o banco de dados concluida com sucesso!", "Teste de conexão");
|
||||
}
|
||||
}
|
||||
|
||||
private void lV_button1_Click(object sender, EventArgs e)
|
||||
{
|
||||
FrmConfigBanco f = new FrmConfigBanco();
|
||||
f.ShowDialog();
|
||||
}
|
||||
|
||||
private void lV_button2_Click(object sender, EventArgs e)
|
||||
{
|
||||
MainForm main = new MainForm();
|
||||
main.ShowDialog();
|
||||
}
|
||||
|
||||
private void lV_button3_Click(object sender, EventArgs e)
|
||||
{
|
||||
string caminhoKey = @"C:\Levelcode\LevelOS\Config\config.json";
|
||||
DadosDaConexao.Host = "206.42.13.180";
|
||||
DadosDaConexao.Port = 1433;
|
||||
DadosDaConexao.Banco = "Levelcode-LevelOS";
|
||||
DadosDaConexao.Usuario = "nicolas";
|
||||
DadosDaConexao.Senha = "Nike12122020*##";
|
||||
DadosDaConexao.ConnectTimeout = 1000;
|
||||
DadosDaConexao.Encrypt = false;
|
||||
DadosDaConexao.TrustServerCertificate = false;
|
||||
DatabaseHelperCPT.Salvar(caminhoKey);
|
||||
string conectionString = DatabaseHelperCPT.Carregar(caminhoKey);
|
||||
NT_MessageBox.Show(conectionString);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
120
Dashboards/Main/Dash_main.resx
Normal file
120
Dashboards/Main/Dash_main.resx
Normal 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>
|
||||
67
Documentohelper.cs
Normal file
67
Documentohelper.cs
Normal file
@ -0,0 +1,67 @@
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Formata CPF ou CNPJ automaticamente enquanto o usuário digita.
|
||||
/// Uso: DocumentoHelper.Registrar(txtDocumento);
|
||||
/// </summary>
|
||||
public static class DocumentoHelper
|
||||
{
|
||||
public static void Registrar(RoundTextBox txt)
|
||||
{
|
||||
bool formatando = false;
|
||||
|
||||
txt.TextChanged += (_, _) =>
|
||||
{
|
||||
// Evita loop: TextChanged → altera Text → TextChanged → ...
|
||||
if (formatando) return;
|
||||
formatando = true;
|
||||
|
||||
try
|
||||
{
|
||||
// 1. Extrai só os dígitos
|
||||
string digits = new string(txt.Text.Where(char.IsDigit).ToArray());
|
||||
|
||||
// 2. Limita ao tamanho máximo do CNPJ
|
||||
if (digits.Length > 14) digits = digits[..14];
|
||||
|
||||
// 3. Formata conforme o tamanho
|
||||
string formatado = digits.Length <= 11
|
||||
? FormatarCPF(digits)
|
||||
: FormatarCNPJ(digits);
|
||||
|
||||
// 4. Só atualiza se realmente mudou
|
||||
if (txt.Text != formatado)
|
||||
{
|
||||
txt.Text = formatado;
|
||||
txt.SelectionStart = formatado.Length; // cursor no final
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
formatando = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// CPF: 000.000.000-00
|
||||
private static string FormatarCPF(string d) => d.Length switch
|
||||
{
|
||||
<= 3 => d,
|
||||
<= 6 => $"{d[..3]}.{d[3..]}",
|
||||
<= 9 => $"{d[..3]}.{d[3..6]}.{d[6..]}",
|
||||
_ => $"{d[..3]}.{d[3..6]}.{d[6..9]}-{d[9..]}"
|
||||
};
|
||||
|
||||
// CNPJ: 00.000.000/0000-00
|
||||
private static string FormatarCNPJ(string d) => d.Length switch
|
||||
{
|
||||
<= 2 => d,
|
||||
<= 5 => $"{d[..2]}.{d[2..]}",
|
||||
<= 8 => $"{d[..2]}.{d[2..5]}.{d[5..]}",
|
||||
<= 12 => $"{d[..2]}.{d[2..5]}.{d[5..8]}/{d[8..]}",
|
||||
_ => $"{d[..2]}.{d[2..5]}.{d[5..8]}/{d[8..12]}-{d[12..]}"
|
||||
};
|
||||
}
|
||||
}
|
||||
20
Program.cs
Normal file
20
Program.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using CCH;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
// To customize application configuration such as set high DPI settings or default font,
|
||||
// see https://aka.ms/applicationconfiguration.
|
||||
ApplicationConfiguration.Initialize();
|
||||
AppFolderSystem.CriarEstruturaPastas();
|
||||
Application.Run(new Form1());
|
||||
}
|
||||
}
|
||||
}
|
||||
125
RoundComboBox.cs
Normal file
125
RoundComboBox.cs
Normal file
@ -0,0 +1,125 @@
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class RoundComboBox : UserControl
|
||||
{
|
||||
private ComboBox _comboBox = null!;
|
||||
public int Radius { get; set; } = 4;
|
||||
public Color BorderColor { get; set; } = Color.LightGray;
|
||||
public Color FocusColor { get; set; } = Color.Blue;
|
||||
private bool _focused;
|
||||
|
||||
public ComboBoxStyle DropDownStyle
|
||||
{
|
||||
get => _comboBox.DropDownStyle;
|
||||
set => _comboBox.DropDownStyle = value;
|
||||
}
|
||||
|
||||
public ComboBox.ObjectCollection Items => _comboBox.Items;
|
||||
|
||||
public object? SelectedItem
|
||||
{
|
||||
get => _comboBox.SelectedItem;
|
||||
set => _comboBox.SelectedItem = value;
|
||||
}
|
||||
|
||||
public int SelectedIndex
|
||||
{
|
||||
get => _comboBox.SelectedIndex;
|
||||
set => _comboBox.SelectedIndex = value;
|
||||
}
|
||||
|
||||
public override string Text
|
||||
{
|
||||
get => _comboBox.Text;
|
||||
set => _comboBox.Text = value;
|
||||
}
|
||||
|
||||
public new Color BackColor
|
||||
{
|
||||
get => base.BackColor;
|
||||
set { base.BackColor = value; if (_comboBox != null) _comboBox.BackColor = value; }
|
||||
}
|
||||
|
||||
public new event EventHandler? SelectedIndexChanged
|
||||
{
|
||||
add => _comboBox.SelectedIndexChanged += value;
|
||||
remove => _comboBox.SelectedIndexChanged -= value;
|
||||
}
|
||||
|
||||
public RoundComboBox()
|
||||
{
|
||||
DoubleBuffered = true;
|
||||
base.BackColor = Color.White;
|
||||
|
||||
_comboBox = new ComboBox
|
||||
{
|
||||
//BorderStyle = BorderStyle.None,
|
||||
Font = new Font("Segoe UI", 9f),
|
||||
BackColor = Color.White,
|
||||
DropDownStyle = ComboBoxStyle.DropDownList,
|
||||
FlatStyle = FlatStyle.Flat
|
||||
};
|
||||
|
||||
_comboBox.GotFocus += (s, e) => { _focused = true; Invalidate(); };
|
||||
_comboBox.LostFocus += (s, e) => { _focused = false; Invalidate(); };
|
||||
_comboBox.TextChanged += (s, e) => OnTextChanged(e);
|
||||
_comboBox.Leave += (s, e) => OnLeave(e);
|
||||
|
||||
Controls.Add(_comboBox);
|
||||
SizeChanged += (s, e) => AjustarComboBox();
|
||||
}
|
||||
|
||||
private void AjustarComboBox()
|
||||
{
|
||||
_comboBox.Width = Width - 12;
|
||||
_comboBox.Location = new Point(6, (Height - _comboBox.PreferredHeight) / 2);
|
||||
}
|
||||
public object? DataSource
|
||||
{
|
||||
get => _comboBox.DataSource;
|
||||
set => _comboBox.DataSource = value;
|
||||
}
|
||||
|
||||
public string DisplayMember
|
||||
{
|
||||
get => _comboBox.DisplayMember;
|
||||
set => _comboBox.DisplayMember = value;
|
||||
}
|
||||
|
||||
public string ValueMember
|
||||
{
|
||||
get => _comboBox.ValueMember;
|
||||
set => _comboBox.ValueMember = value;
|
||||
}
|
||||
|
||||
public object? SelectedValue
|
||||
{
|
||||
get => _comboBox.SelectedValue;
|
||||
set => _comboBox.SelectedValue = value;
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
using var path = GetPath(new Rectangle(0, 0, Width - 1, Height - 1), Radius);
|
||||
using var brush = new SolidBrush(BackColor);
|
||||
e.Graphics.FillPath(brush, path);
|
||||
using var pen = new Pen(_focused ? FocusColor : BorderColor, _focused ? 1.5f : 1f);
|
||||
e.Graphics.DrawPath(pen, path);
|
||||
}
|
||||
|
||||
private static GraphicsPath GetPath(Rectangle r, int rad)
|
||||
{
|
||||
var path = new GraphicsPath();
|
||||
int d = rad * 2;
|
||||
path.AddArc(r.X, r.Y, d, d, 180, 90);
|
||||
path.AddArc(r.Right - d, r.Y, d, d, 270, 90);
|
||||
path.AddArc(r.Right - d, r.Bottom - d, d, d, 0, 90);
|
||||
path.AddArc(r.X, r.Bottom - d, d, d, 90, 90);
|
||||
path.CloseFigure();
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
UI.csproj
Normal file
28
UI.csproj
Normal file
@ -0,0 +1,28 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BLL\BLL.csproj" />
|
||||
<ProjectReference Include="..\CAB\CAB.csproj" />
|
||||
<ProjectReference Include="..\CCH\CCH.csproj" />
|
||||
<ProjectReference Include="..\CMB\CMB.csproj" />
|
||||
<ProjectReference Include="..\CPM\CPM.csproj" />
|
||||
<ProjectReference Include="..\CPT\CPT.csproj" />
|
||||
<ProjectReference Include="..\DAL\DAL.csproj" />
|
||||
<ProjectReference Include="..\MLL\MLL.csproj" />
|
||||
<ProjectReference Include="..\TLL\TLL.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AForge.Video" Version="2.2.5" />
|
||||
<PackageReference Include="AForge.Video.DirectShow" Version="2.2.5" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
79
UI.sln
Normal file
79
UI.sln
Normal file
@ -0,0 +1,79 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 18
|
||||
VisualStudioVersion = 18.4.11626.88
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UI", "UI.csproj", "{344A1172-B978-A3CB-44BF-B15E6902C6C7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MLL", "..\MLL\MLL.csproj", "{BD112D2C-C31D-4DC4-A3C8-2C5808C17D53}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CCH", "..\CCH\CCH.csproj", "{AD6AD8F1-7AE1-4BFC-A7EB-5F5B37EFE4C0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TLL", "..\TLL\TLL.csproj", "{A5F3E468-7A97-4C71-8E75-CD2CAF8B477C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CPT", "..\CPT\CPT.csproj", "{970FFDEE-6F66-49FD-B41F-EBC8F50C547C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DAL", "..\DAL\DAL.csproj", "{9696C45A-97A2-445E-BE10-BB3EE320BFDF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLL", "..\BLL\BLL.csproj", "{68B73E29-9E25-4BCA-B077-400F6B2B450B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CPM", "..\CPM\CPM.csproj", "{20B46C82-119A-F5E9-8B57-A756A827F265}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CAB", "..\CAB\CAB.csproj", "{19039AC1-EE08-460B-821B-0277442D04D1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CMB", "..\CMB\CMB.csproj", "{766E76F2-BAFF-4352-B376-15F6DE8BE4D9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{344A1172-B978-A3CB-44BF-B15E6902C6C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{344A1172-B978-A3CB-44BF-B15E6902C6C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{344A1172-B978-A3CB-44BF-B15E6902C6C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{344A1172-B978-A3CB-44BF-B15E6902C6C7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BD112D2C-C31D-4DC4-A3C8-2C5808C17D53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BD112D2C-C31D-4DC4-A3C8-2C5808C17D53}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BD112D2C-C31D-4DC4-A3C8-2C5808C17D53}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BD112D2C-C31D-4DC4-A3C8-2C5808C17D53}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AD6AD8F1-7AE1-4BFC-A7EB-5F5B37EFE4C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AD6AD8F1-7AE1-4BFC-A7EB-5F5B37EFE4C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AD6AD8F1-7AE1-4BFC-A7EB-5F5B37EFE4C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AD6AD8F1-7AE1-4BFC-A7EB-5F5B37EFE4C0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A5F3E468-7A97-4C71-8E75-CD2CAF8B477C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A5F3E468-7A97-4C71-8E75-CD2CAF8B477C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A5F3E468-7A97-4C71-8E75-CD2CAF8B477C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A5F3E468-7A97-4C71-8E75-CD2CAF8B477C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{970FFDEE-6F66-49FD-B41F-EBC8F50C547C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{970FFDEE-6F66-49FD-B41F-EBC8F50C547C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{970FFDEE-6F66-49FD-B41F-EBC8F50C547C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{970FFDEE-6F66-49FD-B41F-EBC8F50C547C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9696C45A-97A2-445E-BE10-BB3EE320BFDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9696C45A-97A2-445E-BE10-BB3EE320BFDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9696C45A-97A2-445E-BE10-BB3EE320BFDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9696C45A-97A2-445E-BE10-BB3EE320BFDF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{68B73E29-9E25-4BCA-B077-400F6B2B450B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{68B73E29-9E25-4BCA-B077-400F6B2B450B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{68B73E29-9E25-4BCA-B077-400F6B2B450B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{68B73E29-9E25-4BCA-B077-400F6B2B450B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{20B46C82-119A-F5E9-8B57-A756A827F265}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{20B46C82-119A-F5E9-8B57-A756A827F265}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{20B46C82-119A-F5E9-8B57-A756A827F265}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{20B46C82-119A-F5E9-8B57-A756A827F265}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{19039AC1-EE08-460B-821B-0277442D04D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{19039AC1-EE08-460B-821B-0277442D04D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{19039AC1-EE08-460B-821B-0277442D04D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{19039AC1-EE08-460B-821B-0277442D04D1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{766E76F2-BAFF-4352-B376-15F6DE8BE4D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{766E76F2-BAFF-4352-B376-15F6DE8BE4D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{766E76F2-BAFF-4352-B376-15F6DE8BE4D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{766E76F2-BAFF-4352-B376-15F6DE8BE4D9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {15E7E724-DCEE-49C0-90C5-A55F1E2F06BD}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Loading…
Reference in New Issue
Block a user