Revert "Feat many fixes"
This commit is contained in:
@@ -1,38 +1,39 @@
|
||||
import { v } from 'convex/values';
|
||||
import { query, mutation } from './_generated/server';
|
||||
import { internal } from './_generated/api';
|
||||
import { simboloTipo } from './schema';
|
||||
import { getCurrentUserFunction } from './auth';
|
||||
import { v } from "convex/values";
|
||||
import { query, mutation } from "./_generated/server";
|
||||
import { internal } from "./_generated/api";
|
||||
import { simboloTipo } from "./schema";
|
||||
|
||||
// Validadores para campos opcionais
|
||||
const sexoValidator = v.optional(
|
||||
v.union(v.literal('masculino'), v.literal('feminino'), v.literal('outro'))
|
||||
v.union(v.literal("masculino"), v.literal("feminino"), v.literal("outro"))
|
||||
);
|
||||
const estadoCivilValidator = v.optional(
|
||||
v.union(
|
||||
v.literal('solteiro'),
|
||||
v.literal('casado'),
|
||||
v.literal('divorciado'),
|
||||
v.literal('viuvo'),
|
||||
v.literal('uniao_estavel')
|
||||
)
|
||||
v.union(
|
||||
v.literal("solteiro"),
|
||||
v.literal("casado"),
|
||||
v.literal("divorciado"),
|
||||
v.literal("viuvo"),
|
||||
v.literal("uniao_estavel")
|
||||
)
|
||||
);
|
||||
const grauInstrucaoValidator = v.optional(
|
||||
v.union(
|
||||
v.literal('fundamental'),
|
||||
v.literal('medio'),
|
||||
v.literal('superior'),
|
||||
v.literal('pos_graduacao'),
|
||||
v.literal('mestrado'),
|
||||
v.literal('doutorado')
|
||||
)
|
||||
v.union(
|
||||
v.literal("fundamental"),
|
||||
v.literal("medio"),
|
||||
v.literal("superior"),
|
||||
v.literal("pos_graduacao"),
|
||||
v.literal("mestrado"),
|
||||
v.literal("doutorado")
|
||||
)
|
||||
);
|
||||
const grupoSanguineoValidator = v.optional(
|
||||
v.union(v.literal('A'), v.literal('B'), v.literal('AB'), v.literal('O'))
|
||||
v.union(v.literal("A"), v.literal("B"), v.literal("AB"), v.literal("O"))
|
||||
);
|
||||
const fatorRHValidator = v.optional(
|
||||
v.union(v.literal("positivo"), v.literal("negativo"))
|
||||
);
|
||||
const fatorRHValidator = v.optional(v.union(v.literal('positivo'), v.literal('negativo')));
|
||||
const aposentadoValidator = v.optional(
|
||||
v.union(v.literal('nao'), v.literal('funape_ipsep'), v.literal('inss'))
|
||||
v.union(v.literal("nao"), v.literal("funape_ipsep"), v.literal("inss"))
|
||||
);
|
||||
|
||||
const regimeTrabalhoValidator = v.optional(
|
||||
@@ -45,256 +46,245 @@ const regimeTrabalhoValidator = v.optional(
|
||||
);
|
||||
|
||||
export const getAll = query({
|
||||
args: {},
|
||||
handler: async (ctx) => {
|
||||
// Autorização: listar funcionários
|
||||
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||
recurso: 'funcionarios',
|
||||
acao: 'listar'
|
||||
});
|
||||
const funcionarios = await ctx.db.query('funcionarios').collect();
|
||||
// Retornar apenas os campos necessários para listagem
|
||||
return funcionarios.map((f) => ({
|
||||
_id: f._id,
|
||||
nome: f.nome,
|
||||
matricula: f.matricula,
|
||||
cpf: f.cpf,
|
||||
rg: f.rg,
|
||||
nascimento: f.nascimento,
|
||||
email: f.email,
|
||||
telefone: f.telefone,
|
||||
endereco: f.endereco,
|
||||
cep: f.cep,
|
||||
cidade: f.cidade,
|
||||
uf: f.uf,
|
||||
simboloId: f.simboloId,
|
||||
simboloTipo: f.simboloTipo,
|
||||
admissaoData: f.admissaoData,
|
||||
desligamentoData: f.desligamentoData,
|
||||
descricaoCargo: f.descricaoCargo
|
||||
}));
|
||||
}
|
||||
args: {},
|
||||
handler: async (ctx) => {
|
||||
// Autorização: listar funcionários
|
||||
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||
recurso: "funcionarios",
|
||||
acao: "listar",
|
||||
});
|
||||
const funcionarios = await ctx.db.query("funcionarios").collect();
|
||||
// Retornar apenas os campos necessários para listagem
|
||||
return funcionarios.map((f) => ({
|
||||
_id: f._id,
|
||||
nome: f.nome,
|
||||
matricula: f.matricula,
|
||||
cpf: f.cpf,
|
||||
rg: f.rg,
|
||||
nascimento: f.nascimento,
|
||||
email: f.email,
|
||||
telefone: f.telefone,
|
||||
endereco: f.endereco,
|
||||
cep: f.cep,
|
||||
cidade: f.cidade,
|
||||
uf: f.uf,
|
||||
simboloId: f.simboloId,
|
||||
simboloTipo: f.simboloTipo,
|
||||
admissaoData: f.admissaoData,
|
||||
desligamentoData: f.desligamentoData,
|
||||
descricaoCargo: f.descricaoCargo,
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
export const getById = query({
|
||||
args: { id: v.id('funcionarios') },
|
||||
// Tipo inferido automaticamente pelo Convex
|
||||
handler: async (ctx, args) => {
|
||||
// Autorização: ver funcionário
|
||||
// await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||
// recurso: "funcionarios",
|
||||
// acao: "ver",
|
||||
// });
|
||||
return await ctx.db.get(args.id);
|
||||
}
|
||||
});
|
||||
|
||||
export const getCurrent = query({
|
||||
args: {},
|
||||
handler: async (ctx) => {
|
||||
const usuarioAtual = await getCurrentUserFunction(ctx);
|
||||
if (!usuarioAtual) throw new Error('Usuário não encontrado');
|
||||
if (!usuarioAtual.funcionarioId) throw new Error('Usuário não é funcionário');
|
||||
|
||||
return await ctx.db.get(usuarioAtual.funcionarioId);
|
||||
}
|
||||
args: { id: v.id("funcionarios") },
|
||||
// Tipo inferido automaticamente pelo Convex
|
||||
handler: async (ctx, args) => {
|
||||
// Autorização: ver funcionário
|
||||
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||
recurso: "funcionarios",
|
||||
acao: "ver",
|
||||
});
|
||||
return await ctx.db.get(args.id);
|
||||
},
|
||||
});
|
||||
|
||||
export const create = mutation({
|
||||
args: {
|
||||
// Campos obrigatórios
|
||||
nome: v.string(),
|
||||
matricula: v.optional(v.string()),
|
||||
simboloId: v.id('simbolos'),
|
||||
nascimento: v.string(),
|
||||
rg: v.string(),
|
||||
cpf: v.string(),
|
||||
endereco: v.string(),
|
||||
cep: v.string(),
|
||||
cidade: v.string(),
|
||||
uf: v.string(),
|
||||
telefone: v.string(),
|
||||
email: v.string(),
|
||||
admissaoData: v.optional(v.string()),
|
||||
desligamentoData: v.optional(v.string()),
|
||||
simboloTipo: simboloTipo,
|
||||
args: {
|
||||
// Campos obrigatórios
|
||||
nome: v.string(),
|
||||
matricula: v.optional(v.string()),
|
||||
simboloId: v.id("simbolos"),
|
||||
nascimento: v.string(),
|
||||
rg: v.string(),
|
||||
cpf: v.string(),
|
||||
endereco: v.string(),
|
||||
cep: v.string(),
|
||||
cidade: v.string(),
|
||||
uf: v.string(),
|
||||
telefone: v.string(),
|
||||
email: v.string(),
|
||||
admissaoData: v.optional(v.string()),
|
||||
desligamentoData: v.optional(v.string()),
|
||||
simboloTipo: simboloTipo,
|
||||
|
||||
// Dados Pessoais Adicionais
|
||||
nomePai: v.optional(v.string()),
|
||||
nomeMae: v.optional(v.string()),
|
||||
naturalidade: v.optional(v.string()),
|
||||
naturalidadeUF: v.optional(v.string()),
|
||||
sexo: sexoValidator,
|
||||
estadoCivil: estadoCivilValidator,
|
||||
nacionalidade: v.optional(v.string()),
|
||||
// Dados Pessoais Adicionais
|
||||
nomePai: v.optional(v.string()),
|
||||
nomeMae: v.optional(v.string()),
|
||||
naturalidade: v.optional(v.string()),
|
||||
naturalidadeUF: v.optional(v.string()),
|
||||
sexo: sexoValidator,
|
||||
estadoCivil: estadoCivilValidator,
|
||||
nacionalidade: v.optional(v.string()),
|
||||
|
||||
// Documentos Pessoais
|
||||
rgOrgaoExpedidor: v.optional(v.string()),
|
||||
rgDataEmissao: v.optional(v.string()),
|
||||
carteiraProfissionalNumero: v.optional(v.string()),
|
||||
carteiraProfissionalSerie: v.optional(v.string()),
|
||||
carteiraProfissionalDataEmissao: v.optional(v.string()),
|
||||
reservistaNumero: v.optional(v.string()),
|
||||
reservistaSerie: v.optional(v.string()),
|
||||
tituloEleitorNumero: v.optional(v.string()),
|
||||
tituloEleitorZona: v.optional(v.string()),
|
||||
tituloEleitorSecao: v.optional(v.string()),
|
||||
pisNumero: v.optional(v.string()),
|
||||
// Documentos Pessoais
|
||||
rgOrgaoExpedidor: v.optional(v.string()),
|
||||
rgDataEmissao: v.optional(v.string()),
|
||||
carteiraProfissionalNumero: v.optional(v.string()),
|
||||
carteiraProfissionalSerie: v.optional(v.string()),
|
||||
carteiraProfissionalDataEmissao: v.optional(v.string()),
|
||||
reservistaNumero: v.optional(v.string()),
|
||||
reservistaSerie: v.optional(v.string()),
|
||||
tituloEleitorNumero: v.optional(v.string()),
|
||||
tituloEleitorZona: v.optional(v.string()),
|
||||
tituloEleitorSecao: v.optional(v.string()),
|
||||
pisNumero: v.optional(v.string()),
|
||||
|
||||
// Formação e Saúde
|
||||
grauInstrucao: grauInstrucaoValidator,
|
||||
formacao: v.optional(v.string()),
|
||||
formacaoRegistro: v.optional(v.string()),
|
||||
grupoSanguineo: grupoSanguineoValidator,
|
||||
fatorRH: fatorRHValidator,
|
||||
// Formação e Saúde
|
||||
grauInstrucao: grauInstrucaoValidator,
|
||||
formacao: v.optional(v.string()),
|
||||
formacaoRegistro: v.optional(v.string()),
|
||||
grupoSanguineo: grupoSanguineoValidator,
|
||||
fatorRH: fatorRHValidator,
|
||||
|
||||
// Cargo e Vínculo
|
||||
descricaoCargo: v.optional(v.string()),
|
||||
nomeacaoPortaria: v.optional(v.string()),
|
||||
nomeacaoData: v.optional(v.string()),
|
||||
nomeacaoDOE: v.optional(v.string()),
|
||||
pertenceOrgaoPublico: v.optional(v.boolean()),
|
||||
orgaoOrigem: v.optional(v.string()),
|
||||
aposentado: aposentadoValidator,
|
||||
// Cargo e Vínculo
|
||||
descricaoCargo: v.optional(v.string()),
|
||||
nomeacaoPortaria: v.optional(v.string()),
|
||||
nomeacaoData: v.optional(v.string()),
|
||||
nomeacaoDOE: v.optional(v.string()),
|
||||
pertenceOrgaoPublico: v.optional(v.boolean()),
|
||||
orgaoOrigem: v.optional(v.string()),
|
||||
aposentado: aposentadoValidator,
|
||||
|
||||
// Dados Bancários
|
||||
contaBradescoNumero: v.optional(v.string()),
|
||||
contaBradescoDV: v.optional(v.string()),
|
||||
contaBradescoAgencia: v.optional(v.string()),
|
||||
// Dados Bancários
|
||||
contaBradescoNumero: v.optional(v.string()),
|
||||
contaBradescoDV: v.optional(v.string()),
|
||||
contaBradescoAgencia: v.optional(v.string()),
|
||||
|
||||
// Documentos Anexos (Storage IDs)
|
||||
certidaoAntecedentesPF: v.optional(v.id('_storage')),
|
||||
certidaoAntecedentesJFPE: v.optional(v.id('_storage')),
|
||||
certidaoAntecedentesSDS: v.optional(v.id('_storage')),
|
||||
certidaoAntecedentesTJPE: v.optional(v.id('_storage')),
|
||||
certidaoImprobidade: v.optional(v.id('_storage')),
|
||||
rgFrente: v.optional(v.id('_storage')),
|
||||
rgVerso: v.optional(v.id('_storage')),
|
||||
cpfFrente: v.optional(v.id('_storage')),
|
||||
cpfVerso: v.optional(v.id('_storage')),
|
||||
situacaoCadastralCPF: v.optional(v.id('_storage')),
|
||||
tituloEleitorFrente: v.optional(v.id('_storage')),
|
||||
tituloEleitorVerso: v.optional(v.id('_storage')),
|
||||
comprovanteVotacao: v.optional(v.id('_storage')),
|
||||
carteiraProfissionalFrente: v.optional(v.id('_storage')),
|
||||
carteiraProfissionalVerso: v.optional(v.id('_storage')),
|
||||
comprovantePIS: v.optional(v.id('_storage')),
|
||||
certidaoRegistroCivil: v.optional(v.id('_storage')),
|
||||
certidaoNascimentoDependentes: v.optional(v.id('_storage')),
|
||||
cpfDependentes: v.optional(v.id('_storage')),
|
||||
reservistaDoc: v.optional(v.id('_storage')),
|
||||
comprovanteEscolaridade: v.optional(v.id('_storage')),
|
||||
comprovanteResidencia: v.optional(v.id('_storage')),
|
||||
comprovanteContaBradesco: v.optional(v.id('_storage')),
|
||||
// Documentos Anexos (Storage IDs)
|
||||
certidaoAntecedentesPF: v.optional(v.id("_storage")),
|
||||
certidaoAntecedentesJFPE: v.optional(v.id("_storage")),
|
||||
certidaoAntecedentesSDS: v.optional(v.id("_storage")),
|
||||
certidaoAntecedentesTJPE: v.optional(v.id("_storage")),
|
||||
certidaoImprobidade: v.optional(v.id("_storage")),
|
||||
rgFrente: v.optional(v.id("_storage")),
|
||||
rgVerso: v.optional(v.id("_storage")),
|
||||
cpfFrente: v.optional(v.id("_storage")),
|
||||
cpfVerso: v.optional(v.id("_storage")),
|
||||
situacaoCadastralCPF: v.optional(v.id("_storage")),
|
||||
tituloEleitorFrente: v.optional(v.id("_storage")),
|
||||
tituloEleitorVerso: v.optional(v.id("_storage")),
|
||||
comprovanteVotacao: v.optional(v.id("_storage")),
|
||||
carteiraProfissionalFrente: v.optional(v.id("_storage")),
|
||||
carteiraProfissionalVerso: v.optional(v.id("_storage")),
|
||||
comprovantePIS: v.optional(v.id("_storage")),
|
||||
certidaoRegistroCivil: v.optional(v.id("_storage")),
|
||||
certidaoNascimentoDependentes: v.optional(v.id("_storage")),
|
||||
cpfDependentes: v.optional(v.id("_storage")),
|
||||
reservistaDoc: v.optional(v.id("_storage")),
|
||||
comprovanteEscolaridade: v.optional(v.id("_storage")),
|
||||
comprovanteResidencia: v.optional(v.id("_storage")),
|
||||
comprovanteContaBradesco: v.optional(v.id("_storage")),
|
||||
|
||||
// Declarações (Storage IDs)
|
||||
declaracaoAcumulacaoCargo: v.optional(v.id('_storage')),
|
||||
declaracaoDependentesIR: v.optional(v.id('_storage')),
|
||||
declaracaoIdoneidade: v.optional(v.id('_storage')),
|
||||
termoNepotismo: v.optional(v.id('_storage')),
|
||||
termoOpcaoRemuneracao: v.optional(v.id('_storage')),
|
||||
// Dependentes (opcional)
|
||||
dependentes: v.optional(
|
||||
v.array(
|
||||
v.object({
|
||||
parentesco: v.union(
|
||||
v.literal('filho'),
|
||||
v.literal('filha'),
|
||||
v.literal('conjuge'),
|
||||
v.literal('outro')
|
||||
),
|
||||
nome: v.string(),
|
||||
cpf: v.string(),
|
||||
nascimento: v.string(),
|
||||
documentoId: v.optional(v.id('_storage')),
|
||||
salarioFamilia: v.optional(v.boolean()),
|
||||
impostoRenda: v.optional(v.boolean())
|
||||
})
|
||||
)
|
||||
)
|
||||
},
|
||||
returns: v.id('funcionarios'),
|
||||
handler: async (ctx, args) => {
|
||||
// Autorização: criar
|
||||
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||
recurso: 'funcionarios',
|
||||
acao: 'criar'
|
||||
});
|
||||
// Unicidade: CPF
|
||||
const cpfExists = await ctx.db
|
||||
.query('funcionarios')
|
||||
.withIndex('by_cpf', (q) => q.eq('cpf', args.cpf))
|
||||
.unique();
|
||||
if (cpfExists) {
|
||||
throw new Error('CPF já cadastrado');
|
||||
}
|
||||
// Declarações (Storage IDs)
|
||||
declaracaoAcumulacaoCargo: v.optional(v.id("_storage")),
|
||||
declaracaoDependentesIR: v.optional(v.id("_storage")),
|
||||
declaracaoIdoneidade: v.optional(v.id("_storage")),
|
||||
termoNepotismo: v.optional(v.id("_storage")),
|
||||
termoOpcaoRemuneracao: v.optional(v.id("_storage")),
|
||||
// Dependentes (opcional)
|
||||
dependentes: v.optional(
|
||||
v.array(
|
||||
v.object({
|
||||
parentesco: v.union(
|
||||
v.literal("filho"),
|
||||
v.literal("filha"),
|
||||
v.literal("conjuge"),
|
||||
v.literal("outro")
|
||||
),
|
||||
nome: v.string(),
|
||||
cpf: v.string(),
|
||||
nascimento: v.string(),
|
||||
documentoId: v.optional(v.id("_storage")),
|
||||
salarioFamilia: v.optional(v.boolean()),
|
||||
impostoRenda: v.optional(v.boolean()),
|
||||
})
|
||||
)
|
||||
),
|
||||
},
|
||||
returns: v.id("funcionarios"),
|
||||
handler: async (ctx, args) => {
|
||||
// Autorização: criar
|
||||
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||
recurso: "funcionarios",
|
||||
acao: "criar",
|
||||
});
|
||||
// Unicidade: CPF
|
||||
const cpfExists = await ctx.db
|
||||
.query("funcionarios")
|
||||
.withIndex("by_cpf", (q) => q.eq("cpf", args.cpf))
|
||||
.unique();
|
||||
if (cpfExists) {
|
||||
throw new Error("CPF já cadastrado");
|
||||
}
|
||||
|
||||
// Unicidade: Matrícula (apenas se fornecida)
|
||||
if (args.matricula) {
|
||||
const matriculaExists = await ctx.db
|
||||
.query('funcionarios')
|
||||
.withIndex('by_matricula', (q) => q.eq('matricula', args.matricula))
|
||||
.unique();
|
||||
if (matriculaExists) {
|
||||
throw new Error(
|
||||
'Já existe um funcionário com esta matrícula. Por favor, use outra ou deixe em branco.'
|
||||
);
|
||||
}
|
||||
}
|
||||
// Unicidade: Matrícula (apenas se fornecida)
|
||||
if (args.matricula) {
|
||||
const matriculaExists = await ctx.db
|
||||
.query("funcionarios")
|
||||
.withIndex("by_matricula", (q) => q.eq("matricula", args.matricula))
|
||||
.unique();
|
||||
if (matriculaExists) {
|
||||
throw new Error(
|
||||
"Já existe um funcionário com esta matrícula. Por favor, use outra ou deixe em branco."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const novoFuncionarioId = await ctx.db.insert('funcionarios', args);
|
||||
return novoFuncionarioId;
|
||||
}
|
||||
const novoFuncionarioId = await ctx.db.insert("funcionarios", args);
|
||||
return novoFuncionarioId;
|
||||
},
|
||||
});
|
||||
|
||||
export const update = mutation({
|
||||
args: {
|
||||
id: v.id('funcionarios'),
|
||||
// Campos obrigatórios
|
||||
nome: v.string(),
|
||||
matricula: v.optional(v.string()),
|
||||
simboloId: v.id('simbolos'),
|
||||
nascimento: v.string(),
|
||||
rg: v.string(),
|
||||
cpf: v.string(),
|
||||
endereco: v.string(),
|
||||
cep: v.string(),
|
||||
cidade: v.string(),
|
||||
uf: v.string(),
|
||||
telefone: v.string(),
|
||||
email: v.string(),
|
||||
admissaoData: v.optional(v.string()),
|
||||
desligamentoData: v.optional(v.string()),
|
||||
simboloTipo: simboloTipo,
|
||||
args: {
|
||||
id: v.id("funcionarios"),
|
||||
// Campos obrigatórios
|
||||
nome: v.string(),
|
||||
matricula: v.optional(v.string()),
|
||||
simboloId: v.id("simbolos"),
|
||||
nascimento: v.string(),
|
||||
rg: v.string(),
|
||||
cpf: v.string(),
|
||||
endereco: v.string(),
|
||||
cep: v.string(),
|
||||
cidade: v.string(),
|
||||
uf: v.string(),
|
||||
telefone: v.string(),
|
||||
email: v.string(),
|
||||
admissaoData: v.optional(v.string()),
|
||||
desligamentoData: v.optional(v.string()),
|
||||
simboloTipo: simboloTipo,
|
||||
|
||||
// Dados Pessoais Adicionais
|
||||
nomePai: v.optional(v.string()),
|
||||
nomeMae: v.optional(v.string()),
|
||||
naturalidade: v.optional(v.string()),
|
||||
naturalidadeUF: v.optional(v.string()),
|
||||
sexo: sexoValidator,
|
||||
estadoCivil: estadoCivilValidator,
|
||||
nacionalidade: v.optional(v.string()),
|
||||
// Dados Pessoais Adicionais
|
||||
nomePai: v.optional(v.string()),
|
||||
nomeMae: v.optional(v.string()),
|
||||
naturalidade: v.optional(v.string()),
|
||||
naturalidadeUF: v.optional(v.string()),
|
||||
sexo: sexoValidator,
|
||||
estadoCivil: estadoCivilValidator,
|
||||
nacionalidade: v.optional(v.string()),
|
||||
|
||||
// Documentos Pessoais
|
||||
rgOrgaoExpedidor: v.optional(v.string()),
|
||||
rgDataEmissao: v.optional(v.string()),
|
||||
carteiraProfissionalNumero: v.optional(v.string()),
|
||||
carteiraProfissionalSerie: v.optional(v.string()),
|
||||
carteiraProfissionalDataEmissao: v.optional(v.string()),
|
||||
reservistaNumero: v.optional(v.string()),
|
||||
reservistaSerie: v.optional(v.string()),
|
||||
tituloEleitorNumero: v.optional(v.string()),
|
||||
tituloEleitorZona: v.optional(v.string()),
|
||||
tituloEleitorSecao: v.optional(v.string()),
|
||||
pisNumero: v.optional(v.string()),
|
||||
// Documentos Pessoais
|
||||
rgOrgaoExpedidor: v.optional(v.string()),
|
||||
rgDataEmissao: v.optional(v.string()),
|
||||
carteiraProfissionalNumero: v.optional(v.string()),
|
||||
carteiraProfissionalSerie: v.optional(v.string()),
|
||||
carteiraProfissionalDataEmissao: v.optional(v.string()),
|
||||
reservistaNumero: v.optional(v.string()),
|
||||
reservistaSerie: v.optional(v.string()),
|
||||
tituloEleitorNumero: v.optional(v.string()),
|
||||
tituloEleitorZona: v.optional(v.string()),
|
||||
tituloEleitorSecao: v.optional(v.string()),
|
||||
pisNumero: v.optional(v.string()),
|
||||
|
||||
// Formação e Saúde
|
||||
grauInstrucao: grauInstrucaoValidator,
|
||||
formacao: v.optional(v.string()),
|
||||
formacaoRegistro: v.optional(v.string()),
|
||||
grupoSanguineo: grupoSanguineoValidator,
|
||||
fatorRH: fatorRHValidator,
|
||||
// Formação e Saúde
|
||||
grauInstrucao: grauInstrucaoValidator,
|
||||
formacao: v.optional(v.string()),
|
||||
formacaoRegistro: v.optional(v.string()),
|
||||
grupoSanguineo: grupoSanguineoValidator,
|
||||
fatorRH: fatorRHValidator,
|
||||
|
||||
// Cargo e Vínculo
|
||||
descricaoCargo: v.optional(v.string()),
|
||||
@@ -306,188 +296,188 @@ export const update = mutation({
|
||||
orgaoOrigem: v.optional(v.string()),
|
||||
aposentado: aposentadoValidator,
|
||||
|
||||
// Dados Bancários
|
||||
contaBradescoNumero: v.optional(v.string()),
|
||||
contaBradescoDV: v.optional(v.string()),
|
||||
contaBradescoAgencia: v.optional(v.string()),
|
||||
// Dados Bancários
|
||||
contaBradescoNumero: v.optional(v.string()),
|
||||
contaBradescoDV: v.optional(v.string()),
|
||||
contaBradescoAgencia: v.optional(v.string()),
|
||||
|
||||
// Documentos Anexos (Storage IDs)
|
||||
certidaoAntecedentesPF: v.optional(v.id('_storage')),
|
||||
certidaoAntecedentesJFPE: v.optional(v.id('_storage')),
|
||||
certidaoAntecedentesSDS: v.optional(v.id('_storage')),
|
||||
certidaoAntecedentesTJPE: v.optional(v.id('_storage')),
|
||||
certidaoImprobidade: v.optional(v.id('_storage')),
|
||||
rgFrente: v.optional(v.id('_storage')),
|
||||
rgVerso: v.optional(v.id('_storage')),
|
||||
cpfFrente: v.optional(v.id('_storage')),
|
||||
cpfVerso: v.optional(v.id('_storage')),
|
||||
situacaoCadastralCPF: v.optional(v.id('_storage')),
|
||||
tituloEleitorFrente: v.optional(v.id('_storage')),
|
||||
tituloEleitorVerso: v.optional(v.id('_storage')),
|
||||
comprovanteVotacao: v.optional(v.id('_storage')),
|
||||
carteiraProfissionalFrente: v.optional(v.id('_storage')),
|
||||
carteiraProfissionalVerso: v.optional(v.id('_storage')),
|
||||
comprovantePIS: v.optional(v.id('_storage')),
|
||||
certidaoRegistroCivil: v.optional(v.id('_storage')),
|
||||
certidaoNascimentoDependentes: v.optional(v.id('_storage')),
|
||||
cpfDependentes: v.optional(v.id('_storage')),
|
||||
reservistaDoc: v.optional(v.id('_storage')),
|
||||
comprovanteEscolaridade: v.optional(v.id('_storage')),
|
||||
comprovanteResidencia: v.optional(v.id('_storage')),
|
||||
comprovanteContaBradesco: v.optional(v.id('_storage')),
|
||||
// Documentos Anexos (Storage IDs)
|
||||
certidaoAntecedentesPF: v.optional(v.id("_storage")),
|
||||
certidaoAntecedentesJFPE: v.optional(v.id("_storage")),
|
||||
certidaoAntecedentesSDS: v.optional(v.id("_storage")),
|
||||
certidaoAntecedentesTJPE: v.optional(v.id("_storage")),
|
||||
certidaoImprobidade: v.optional(v.id("_storage")),
|
||||
rgFrente: v.optional(v.id("_storage")),
|
||||
rgVerso: v.optional(v.id("_storage")),
|
||||
cpfFrente: v.optional(v.id("_storage")),
|
||||
cpfVerso: v.optional(v.id("_storage")),
|
||||
situacaoCadastralCPF: v.optional(v.id("_storage")),
|
||||
tituloEleitorFrente: v.optional(v.id("_storage")),
|
||||
tituloEleitorVerso: v.optional(v.id("_storage")),
|
||||
comprovanteVotacao: v.optional(v.id("_storage")),
|
||||
carteiraProfissionalFrente: v.optional(v.id("_storage")),
|
||||
carteiraProfissionalVerso: v.optional(v.id("_storage")),
|
||||
comprovantePIS: v.optional(v.id("_storage")),
|
||||
certidaoRegistroCivil: v.optional(v.id("_storage")),
|
||||
certidaoNascimentoDependentes: v.optional(v.id("_storage")),
|
||||
cpfDependentes: v.optional(v.id("_storage")),
|
||||
reservistaDoc: v.optional(v.id("_storage")),
|
||||
comprovanteEscolaridade: v.optional(v.id("_storage")),
|
||||
comprovanteResidencia: v.optional(v.id("_storage")),
|
||||
comprovanteContaBradesco: v.optional(v.id("_storage")),
|
||||
|
||||
// Declarações (Storage IDs)
|
||||
declaracaoAcumulacaoCargo: v.optional(v.id('_storage')),
|
||||
declaracaoDependentesIR: v.optional(v.id('_storage')),
|
||||
declaracaoIdoneidade: v.optional(v.id('_storage')),
|
||||
termoNepotismo: v.optional(v.id('_storage')),
|
||||
termoOpcaoRemuneracao: v.optional(v.id('_storage')),
|
||||
// Dependentes (opcional)
|
||||
dependentes: v.optional(
|
||||
v.array(
|
||||
v.object({
|
||||
parentesco: v.union(
|
||||
v.literal('filho'),
|
||||
v.literal('filha'),
|
||||
v.literal('conjuge'),
|
||||
v.literal('outro')
|
||||
),
|
||||
nome: v.string(),
|
||||
cpf: v.string(),
|
||||
nascimento: v.string(),
|
||||
documentoId: v.optional(v.id('_storage')),
|
||||
salarioFamilia: v.optional(v.boolean()),
|
||||
impostoRenda: v.optional(v.boolean())
|
||||
})
|
||||
)
|
||||
)
|
||||
},
|
||||
returns: v.null(),
|
||||
handler: async (ctx, args) => {
|
||||
// Autorização: editar
|
||||
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||
recurso: 'funcionarios',
|
||||
acao: 'editar'
|
||||
});
|
||||
// Unicidade: CPF (excluindo o próprio registro)
|
||||
const cpfExists = await ctx.db
|
||||
.query('funcionarios')
|
||||
.withIndex('by_cpf', (q) => q.eq('cpf', args.cpf))
|
||||
.unique();
|
||||
if (cpfExists && cpfExists._id !== args.id) {
|
||||
throw new Error('CPF já cadastrado');
|
||||
}
|
||||
// Declarações (Storage IDs)
|
||||
declaracaoAcumulacaoCargo: v.optional(v.id("_storage")),
|
||||
declaracaoDependentesIR: v.optional(v.id("_storage")),
|
||||
declaracaoIdoneidade: v.optional(v.id("_storage")),
|
||||
termoNepotismo: v.optional(v.id("_storage")),
|
||||
termoOpcaoRemuneracao: v.optional(v.id("_storage")),
|
||||
// Dependentes (opcional)
|
||||
dependentes: v.optional(
|
||||
v.array(
|
||||
v.object({
|
||||
parentesco: v.union(
|
||||
v.literal("filho"),
|
||||
v.literal("filha"),
|
||||
v.literal("conjuge"),
|
||||
v.literal("outro")
|
||||
),
|
||||
nome: v.string(),
|
||||
cpf: v.string(),
|
||||
nascimento: v.string(),
|
||||
documentoId: v.optional(v.id("_storage")),
|
||||
salarioFamilia: v.optional(v.boolean()),
|
||||
impostoRenda: v.optional(v.boolean()),
|
||||
})
|
||||
)
|
||||
),
|
||||
},
|
||||
returns: v.null(),
|
||||
handler: async (ctx, args) => {
|
||||
// Autorização: editar
|
||||
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||
recurso: "funcionarios",
|
||||
acao: "editar",
|
||||
});
|
||||
// Unicidade: CPF (excluindo o próprio registro)
|
||||
const cpfExists = await ctx.db
|
||||
.query("funcionarios")
|
||||
.withIndex("by_cpf", (q) => q.eq("cpf", args.cpf))
|
||||
.unique();
|
||||
if (cpfExists && cpfExists._id !== args.id) {
|
||||
throw new Error("CPF já cadastrado");
|
||||
}
|
||||
|
||||
// Unicidade: Matrícula (apenas se fornecida, excluindo o próprio registro)
|
||||
if (args.matricula) {
|
||||
const matriculaExists = await ctx.db
|
||||
.query('funcionarios')
|
||||
.withIndex('by_matricula', (q) => q.eq('matricula', args.matricula))
|
||||
.unique();
|
||||
if (matriculaExists && matriculaExists._id !== args.id) {
|
||||
throw new Error(
|
||||
'Já existe um funcionário com esta matrícula. Por favor, use outra ou deixe em branco.'
|
||||
);
|
||||
}
|
||||
}
|
||||
// Unicidade: Matrícula (apenas se fornecida, excluindo o próprio registro)
|
||||
if (args.matricula) {
|
||||
const matriculaExists = await ctx.db
|
||||
.query("funcionarios")
|
||||
.withIndex("by_matricula", (q) => q.eq("matricula", args.matricula))
|
||||
.unique();
|
||||
if (matriculaExists && matriculaExists._id !== args.id) {
|
||||
throw new Error(
|
||||
"Já existe um funcionário com esta matrícula. Por favor, use outra ou deixe em branco."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const usuarioExists = await ctx.db
|
||||
.query('usuarios')
|
||||
.withIndex('by_funcionarioId', (q) => q.eq('funcionarioId', args.id))
|
||||
.unique();
|
||||
const usuarioExists = await ctx.db
|
||||
.query("usuarios")
|
||||
.withIndex("by_funcionarioId", (q) => q.eq("funcionarioId", args.id))
|
||||
.unique();
|
||||
|
||||
if (usuarioExists && usuarioExists.email !== args.email) {
|
||||
await ctx.db.patch(usuarioExists._id, {
|
||||
email: args.email
|
||||
});
|
||||
}
|
||||
if (usuarioExists && usuarioExists.email !== args.email) {
|
||||
await ctx.db.patch(usuarioExists._id, {
|
||||
email: args.email,
|
||||
});
|
||||
}
|
||||
|
||||
const { id, ...updateData } = args;
|
||||
await ctx.db.patch(id, updateData);
|
||||
return null;
|
||||
}
|
||||
const { id, ...updateData } = args;
|
||||
await ctx.db.patch(id, updateData);
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
export const remove = mutation({
|
||||
args: { id: v.id('funcionarios') },
|
||||
returns: v.null(),
|
||||
handler: async (ctx, args) => {
|
||||
// Autorização: excluir
|
||||
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||
recurso: 'funcionarios',
|
||||
acao: 'excluir'
|
||||
});
|
||||
// TODO: Talvez queiramos também remover os arquivos do storage
|
||||
await ctx.db.delete(args.id);
|
||||
return null;
|
||||
}
|
||||
args: { id: v.id("funcionarios") },
|
||||
returns: v.null(),
|
||||
handler: async (ctx, args) => {
|
||||
// Autorização: excluir
|
||||
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||
recurso: "funcionarios",
|
||||
acao: "excluir",
|
||||
});
|
||||
// TODO: Talvez queiramos também remover os arquivos do storage
|
||||
await ctx.db.delete(args.id);
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
// Query para obter ficha completa para impressão
|
||||
export const getFichaCompleta = query({
|
||||
args: { id: v.id('funcionarios') },
|
||||
// Tipo inferido automaticamente pelo Convex
|
||||
handler: async (ctx, args) => {
|
||||
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||
recurso: 'funcionarios',
|
||||
acao: 'ver'
|
||||
});
|
||||
const funcionario = await ctx.db.get(args.id);
|
||||
if (!funcionario) {
|
||||
return null;
|
||||
}
|
||||
args: { id: v.id("funcionarios") },
|
||||
// Tipo inferido automaticamente pelo Convex
|
||||
handler: async (ctx, args) => {
|
||||
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||
recurso: "funcionarios",
|
||||
acao: "ver",
|
||||
});
|
||||
const funcionario = await ctx.db.get(args.id);
|
||||
if (!funcionario) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Buscar informações do símbolo
|
||||
const simbolo = await ctx.db.get(funcionario.simboloId);
|
||||
// Buscar informações do símbolo
|
||||
const simbolo = await ctx.db.get(funcionario.simboloId);
|
||||
|
||||
// Buscar cursos do funcionário
|
||||
const cursos = await ctx.db
|
||||
.query('cursos')
|
||||
.withIndex('by_funcionario', (q) => q.eq('funcionarioId', args.id))
|
||||
.collect();
|
||||
// Buscar cursos do funcionário
|
||||
const cursos = await ctx.db
|
||||
.query("cursos")
|
||||
.withIndex("by_funcionario", (q) => q.eq("funcionarioId", args.id))
|
||||
.collect();
|
||||
|
||||
// Buscar URLs dos certificados
|
||||
const cursosComUrls = await Promise.all(
|
||||
cursos.map(async (curso) => {
|
||||
let certificadoUrl = null;
|
||||
if (curso.certificadoId) {
|
||||
certificadoUrl = await ctx.storage.getUrl(curso.certificadoId);
|
||||
}
|
||||
return {
|
||||
...curso,
|
||||
certificadoUrl
|
||||
};
|
||||
})
|
||||
);
|
||||
// Buscar URLs dos certificados
|
||||
const cursosComUrls = await Promise.all(
|
||||
cursos.map(async (curso) => {
|
||||
let certificadoUrl = null;
|
||||
if (curso.certificadoId) {
|
||||
certificadoUrl = await ctx.storage.getUrl(curso.certificadoId);
|
||||
}
|
||||
return {
|
||||
...curso,
|
||||
certificadoUrl,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
...funcionario,
|
||||
simbolo: simbolo
|
||||
? {
|
||||
nome: simbolo.nome,
|
||||
descricao: simbolo.descricao,
|
||||
tipo: simbolo.tipo,
|
||||
vencValor: simbolo.vencValor,
|
||||
repValor: simbolo.repValor,
|
||||
valor: simbolo.valor
|
||||
}
|
||||
: null,
|
||||
cursos: cursosComUrls
|
||||
};
|
||||
}
|
||||
return {
|
||||
...funcionario,
|
||||
simbolo: simbolo
|
||||
? {
|
||||
nome: simbolo.nome,
|
||||
descricao: simbolo.descricao,
|
||||
tipo: simbolo.tipo,
|
||||
vencValor: simbolo.vencValor,
|
||||
repValor: simbolo.repValor,
|
||||
valor: simbolo.valor,
|
||||
}
|
||||
: null,
|
||||
cursos: cursosComUrls,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
// Mutation: Configurar gestor (apenas para TI_MASTER)
|
||||
export const configurarGestor = mutation({
|
||||
args: {
|
||||
funcionarioId: v.id('funcionarios'),
|
||||
gestorId: v.optional(v.id('usuarios'))
|
||||
},
|
||||
returns: v.null(),
|
||||
handler: async (ctx, args) => {
|
||||
await ctx.db.patch(args.funcionarioId, {
|
||||
gestorId: args.gestorId
|
||||
});
|
||||
return null;
|
||||
}
|
||||
args: {
|
||||
funcionarioId: v.id("funcionarios"),
|
||||
gestorId: v.optional(v.id("usuarios")),
|
||||
},
|
||||
returns: v.null(),
|
||||
handler: async (ctx, args) => {
|
||||
await ctx.db.patch(args.funcionarioId, {
|
||||
gestorId: args.gestorId,
|
||||
});
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user