diff --git a/src/app/(protected)/(cadastros)/cadastros/(t_servico_tipo)/servicos-tipo/page.tsx b/src/app/(protected)/(cadastros)/cadastros/(t_servico_tipo)/servicos-tipo/page.tsx index c216953..adb453a 100644 --- a/src/app/(protected)/(cadastros)/cadastros/(t_servico_tipo)/servicos-tipo/page.tsx +++ b/src/app/(protected)/(cadastros)/cadastros/(t_servico_tipo)/servicos-tipo/page.tsx @@ -13,6 +13,7 @@ import TServicoTipoForm from '../../_components/t_servico_tipo/TServicoTipoForm' import { useTServicoTipoReadHook } from '../../_hooks/t_servico_tipo/useTServicoTipoReadHook'; import { useTServicoTipoSaveHook } from '../../_hooks/t_servico_tipo/useTServicoTipoSaveHook'; import { useTServicoTipoRemoveHook } from '../../_hooks/t_servico_tipo/useTServicoTipoRemoveHook'; +import { useTServicoTipoEditHook } from '../../_hooks/t_servico_tipo/useTServicoTipoEditHook'; import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog'; import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog'; @@ -26,6 +27,7 @@ export default function TServicoTipoPage() { const { tServicoTipo, fetchTServicoTipo } = useTServicoTipoReadHook(); const { saveTServicoTipo } = useTServicoTipoSaveHook(); const { removeTServicoTipo } = useTServicoTipoRemoveHook(); + const { editTServicoTipo } = useTServicoTipoEditHook(); // Estados const [selectedServicoTipo, setSelectedServicoTipo] = useState(null); @@ -47,10 +49,31 @@ export default function TServicoTipoPage() { /** * Abre o formulário no modo de edição ou criação */ - const handleOpenForm = useCallback((data: TServicoTipoInterface | null) => { + const handleOpenForm = useCallback(async (data: TServicoTipoInterface | null) => { + + // Fecha o formulário antes de reabrir (garante reset limpo) + setIsFormOpen(false); + + // Se nenhum dado for passado, abre o formulário em modo de criação + if (!data) { + setSelectedServicoTipo(null); + setIsFormOpen(true); + return; + } + + // Define o item selecionado para edição setSelectedServicoTipo(data); + + // Aguarda carregar/editar o registro (o hook espera o objeto TServicoTipoInterface) + await editTServicoTipo(data); + + // Atualiza a lista de dados + await fetchTServicoTipo(); + setIsFormOpen(true); - }, []); + + }, [editTServicoTipo, fetchTServicoTipo]); + /** * Fecha o formulário e limpa o item selecionado @@ -65,15 +88,20 @@ export default function TServicoTipoPage() { */ const handleSave = useCallback(async (formData: TServicoTipoInterface) => { - // Aguarda salvar o registro - await saveTServicoTipo(formData); + // Aguarda salvar o registro + await saveTServicoTipo(formData); // Atualiza a lista de dados fetchTServicoTipo(); }, [saveTServicoTipo, fetchTServicoTipo], + + + ); + + /** * Quando o usuário clica em "remover" na tabela */ @@ -88,6 +116,7 @@ export default function TServicoTipoPage() { [openConfirmDialog], ); + /** * Executa a exclusão de fato quando o usuário confirma */ @@ -108,6 +137,8 @@ export default function TServicoTipoPage() { handleCancel(); }, [itemToDelete, removeTServicoTipo, fetchTServicoTipo, handleCancel]); + + /** * Busca inicial dos dados */ @@ -147,7 +178,7 @@ export default function TServicoTipoPage() { title="Confirmar exclusão" description="Atenção" // Adaptação da mensagem para a interface TServicoTipo - message={`Deseja realmente excluir o tipo de serviço "${itemToDelete?.stipo_nome}"?`} + message={`Deseja realmente excluir o tipo de serviço "${itemToDelete?.descricao}"?`} confirmText="Sim, excluir" cancelText="Cancelar" onConfirm={handleDelete} diff --git a/src/app/(protected)/(cadastros)/cadastros/_components/t_servico_tipo/TServicoTipoForm.tsx b/src/app/(protected)/(cadastros)/cadastros/_components/t_servico_tipo/TServicoTipoForm.tsx index ac60e84..fd274ee 100644 --- a/src/app/(protected)/(cadastros)/cadastros/_components/t_servico_tipo/TServicoTipoForm.tsx +++ b/src/app/(protected)/(cadastros)/cadastros/_components/t_servico_tipo/TServicoTipoForm.tsx @@ -52,6 +52,14 @@ import { GEmolumentoItemReadInterface } from "@/app/(protected)/(cadastros)/cada import CategoriaServicoSelect from "@/shared/components/categoriaServicoSelect/CategoriaServicoSelect"; import CCaixaServicoSelect from "@/packages/administrativo/components/CCaixaServico/CCaixaServicoSelect"; import { TServicoTipoSaveData } from "../../_data/TServicoTipo/TServicoTipoSaveData"; +import TTBReconhecimentoTipoSelect from "@/packages/administrativo/components/TTBReconhecimentoTipo/TTBReconhecimentoTipoSelect"; +import { ConfirmacaoCheckBox } from "@/shared/components/confirmacao/ConfirmacaoCheckBox"; +import ConfirmacaoSelect from "@/shared/components/confirmacao/ConfirmacaoSelect"; +import { TipoPessoaSelect } from "@/shared/components/tipoPessoa/tipoPessoaSelect"; +import { useTServicoEtiquetaReadHook } from "@/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaReadHook"; +import { useTServicoEtiquetaSaveHook } from "@/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaSaveHook"; +import { useTServicoEtiquetaRemoveHook } from "@/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaRemoveHook"; + // Propriedades esperadas pelo componente interface Props { @@ -64,35 +72,179 @@ interface Props { // Componente principal do formulário export default function TServicoTipoForm({ isOpen, data, onClose, onSave }: Props) { + // Inicializa o react-hook-form com validação via Zod + const form = useForm({ + resolver: zodResolver(TServicoTipoSchema), + defaultValues: { + servico_tipo_id: 0, + emolumento_id: 0, + emolumento_obrigatorio: 0, + descricao: "", + maximo_pessoa: 0, + tipo_item: "", + frenteverso: "N", + averbacao: "N", + transferencia_veiculo: "N", + usar_a4: "N", + etiqueta_unica: "N", + situacao: "A", + selar: "N", + valor_emolumento: 0, + valor_taxa_judiciaria: 0, + fundesp_valor: 0, + valor_total: 0, + tipo_pessoa: "F", // ou "J" + } as unknown as TServicoTipoFormValues, + }); + + + // Carrega o ID caso esteja informado no form + const servico_tipo_id = form.getValues('servico_tipo_id') || 0; + + // Hook responsável por buscar emolumentos no backend + const { tServicoEtiqueta, fetchTServicoEtiqueta } = useTServicoEtiquetaReadHook(); + + // Hook responsável em salvar o a etiqueta selecionada + const { tServicoEtiquetaSave, fetchTServicoEtiquetaSave } = useTServicoEtiquetaSaveHook(); + + // Hook responsável em excluir a etiqueta selecionada + const { fetchTServicoEtiquetaRemove } = useTServicoEtiquetaRemoveHook(); + // Estado para gerenciar os itens da tabela de etiquetas/carimbos - const [itensTabela, setItensTabela] = useState<{ marcacao_tipo_id: string; descricao: string }[]>([]); + const [itensTabela, setItensTabela] = useState<{ servico_etiqueta_id: string | number; descricao: string }[]>([]); + - // Função para adicionar um novo item à tabela - const handleAddEtiquetaCarimbo = () => { - const valorSelecionado = form.getValues('etiquetas_carimbos'); + // Carrega os dados de emolumentos apenas uma vez ao montar o componente + React.useEffect(() => { - if (!valorSelecionado) return; + // Função para consumir o endpoint da api + const loadData = async () => { - // Aqui você pode buscar o texto/descrição com base no seu componente GMarcacaoTipoSelect - // Exemplo: supondo que o valor seja um objeto { id, descricao } - const item = { - - marcacao_tipo_id: valorSelecionado.key ?? valorSelecionado, // ou ajusta conforme a estrutura do seu componente - descricao: valorSelecionado.value ?? 'Sem descrição', + // Verifica se o ID do serviço tipo foi informado + if(servico_tipo_id > 0){ + + // Consumo o endpoint da api + await fetchTServicoEtiqueta({servico_tipo_id}); + } }; - // Evita duplicatas - setItensTabela((prev) => { - if (prev.some((p) => p.marcacao_tipo_id === item.marcacao_tipo_id)) return prev; - return [...prev, item]; - }); - }; + // Chama a função para consumir o endpoint da api + loadData(); + + }, [servico_tipo_id]); - const handleRemoveItem = (marcacao_tipo_id: string) => { - setItensTabela((prev) => prev.filter((p) => p.marcacao_tipo_id !== marcacao_tipo_id)); + + // Atualiza itensTabela sempre que tServicoEtiqueta for carregado + React.useEffect(() => { + + // Verifica se a consulta retornou os dados como objeto + if (Array.isArray(tServicoEtiqueta) && tServicoEtiqueta.length > 0) { + + // Lista os itens + const mapped = tServicoEtiqueta.map((item) => ({ + servico_etiqueta_id: Number(item.servico_etiqueta_id ?? 0), + descricao: String(item.descricao ?? 'Sem descrição'), + })); + + setItensTabela(mapped); + + } else { + setItensTabela([]); + } + }, [tServicoEtiqueta]); + + + // Função para adicionar um novo item à tabela Etiquetas/Carimbos + const handleAddEtiquetaCarimbo = async () => { + + // Captura o valor selecionado do formulário + const valorSelecionado = form.getValues("etiquetas_carimbos"); + + // Se não houver valor selecionado, não faz nada + if (!valorSelecionado) return; + + // Verifica se o item já se encontra na tabela + const alreadyExists = itensTabela.some( + (p) => String(p.descricao).trim() === String(valorSelecionado.value).trim() + ); + + // Caso o item já esteja na tabela, para o procedimento + if (alreadyExists) { + return; + } + + // --- Envio opcional para API --- + try { + + // Verifica se o ID do serviço tipo foi informado + if(servico_tipo_id > 0){ + + // Monta o objeto do item selecionado + const data = { + etiqueta_modelo_id: valorSelecionado.key, + servico_tipo_id: servico_tipo_id, + }; + + // Consumo o endpoint da api + const response = await fetchTServicoEtiquetaSave(data); + + // Verifica se tServicoEtiquetaSave é um objeto válido (não null e não array) + if (response && typeof response === 'object' && !Array.isArray(response)) { + + // Monta o objeto com um único item para a tabela + const item = { + servico_etiqueta_id: Number(response.servico_etiqueta_id) ?? 0, + descricao: String(valorSelecionado.value) ?? "Sem descrição", + }; + + // Adiciona o item na tabela + setItensTabela((prev) => { + const idAtual = String(response.servico_etiqueta_id ?? ''); + const exists = prev.some((p) => String(p.servico_etiqueta_id ?? '') === idAtual); + return exists ? prev : [...prev, item]; + }); + + } + + } + + // Se ocorrer erros, informo + } catch (error) { + + console.log("Erro ao enviar o serviço para a API: " + error) + } }; + // Função para remover um item da tabela + const handleRemoveItem = async (servico_etiqueta_id: number) => { + + try{ + + // Verifica se o ID da etiqueta tipo foi informado + if(servico_etiqueta_id > 0){ + + // Monta o objeto do item selecionado + const data = { + servico_etiqueta_id: servico_etiqueta_id, + }; + + // Consumo o endpoint da api + await fetchTServicoEtiquetaRemove(data); + + } + + // Atualiza a tabela no form + setItensTabela((prev) => prev.filter((p) => Number(p.servico_etiqueta_id) !== servico_etiqueta_id)); + + // Se ocorrer erros, informo + } catch (error) { + + console.log("Erro ao enviar o serviço para a API: " + error) + } + }; + + // Parâmetros para o hook de leitura de emolumento_item // Inicializa com valores padrão (0) para evitar uso de propriedades não declaradas. const gEmolumentoItemReadParams: GEmolumentoItemReadInterface = { emolumento_id: 0, valor: 0 }; @@ -128,86 +280,109 @@ export default function TServicoTipoForm({ isOpen, data, onClose, onSave }: Prop }, [gEmolumentoItemReadParams.emolumento_id]); - // Inicializa o react-hook-form com validação via Zod -const form = useForm({ - resolver: zodResolver(TServicoTipoSchema), - defaultValues: { - servico_tipo_id: 0, - descricao: "", - categoria: "", - frenteverso: "N", - averbacao: "N", - transferencia_veiculo: "N", - usar_a4: "N", - etiqueta_unica: "N", - situacao: "A", - selar: "N", - valor_emolumento: 0, - valor_taxa_judiciaria: 0, - fundesp_valor: 0, - valor_total: 0, - }, -}); - // Captura o ID do serviço para uso local const servicoTipoId = Number(form.watch("servico_tipo_id") || data?.servico_tipo_id || 0); - // Atualiza os valores quando há dados para edição - useEffect(() => { - - if (data && Number(data.servico_tipo_id) > 0) { - - //Carrega os valores no form - form.reset(data); - } else { - - // Se não houver dados, reseta o - // formulário para os valores iniciais - // Modo novo cadastro → zera o ID manualmente - form.reset({ - ...form.getValues(), // mantém outros valores default - servico_tipo_id: 0, - descricao: '', - }); - } - }, [data, form]); - - // Função chamada ao clicar em "Salvar" const handleSave = async (formData: TServicoTipoFormValues) => { + try { - // Envia os dados para API - const response = await TServicoTipoSaveData(formData); - // Se a resposta contiver um ID válido + // Se o form não trouxe o ID, tenta puxar de `data` + const servico_tipo_id = formData.servico_tipo_id || data?.servico_tipo_id || form.getValues('servico_tipo_id') || 0; + + // Atualiza o valor dentro do formData + formData.servico_tipo_id = Number(servico_tipo_id); + + // Intercepta e trata o valor de emolumento_id + const emolumentoId = Number(formData.emolumento_id ?? 0); + formData.emolumento_id = emolumentoId === 0 ? null : emolumentoId; + + // Intercepta e trata o valor de emolumento_obrigatorio + const emolumentoObrigatorio = Number(formData.emolumento_obrigatorio ?? 0); + formData.emolumento_obrigatorio = + emolumentoObrigatorio === 0 ? null : emolumentoObrigatorio; + + + // Detecta automaticamente se é edição + const isEditing = !!formData.servico_tipo_id && Number(formData.servico_tipo_id) > 0; + + + // Envia os dados para o módulo com o método correto + const response = await TServicoTipoSaveData({ + ...formData, + metodo: isEditing ? 'PUT' : 'POST', // 💡 Definição explícita do método + }); + + + // Atualiza o formulário apenas se o retorno for válido if (response?.data?.servico_tipo_id) { - const novoId = response.data.servico_tipo_id; + const novoId = response.data.servico_tipo_id; + form.setValue('servico_tipo_id', novoId); // mantém o ID atualizado - // Atualiza o hidden input no formulário - form.setValue("servico_tipo_id", novoId); - // Atualiza todos os campos do formulário com o retorno da API - form.reset(response.data); + // Merge dos dados para preservar valores locais + form.reset({ ...form.getValues(), ...response.data }); - // Exibe mensagem de sucesso - console.log(`Serviço salvo com sucesso (ID: ${novoId})`); + console.log(`Serviço ${isEditing ? 'atualizado' : 'criado'} com sucesso (ID: ${novoId})`); } else { - console.log("Erro ao salvar o tipo de serviço."); + console.log('Erro ao salvar o tipo de serviço.'); } } catch (error) { - - console.log("Erro ao salvar:", error); + console.log('Erro ao salvar:', error); } - }; + }; + + + // Carrega os dados apenas quando o modal + // abrir e houver um registro para editar + useEffect(() => { + + // Remove as etiquetas selecionadas + setItensTabela([]); + + if (isOpen && data && Number(data.servico_tipo_id ?? 0) > 0) { + /** Carrega os dados no formulário */ + form.reset(data); // edição + + } else if (isOpen && !data) { + + /** Reseta os campos do formulário */ + form.reset({ + servico_tipo_id: 0, + emolumento_id: 0, + emolumento_obrigatorio: 0, + descricao: "", + maximo_pessoa: 0, + tipo_item: "", + frenteverso: "N", + averbacao: "N", + transferencia_veiculo: "N", + usar_a4: "N", + etiqueta_unica: "N", + situacao: "A", + selar: "N", + valor_emolumento: 0, + valor_taxa_judiciaria: 0, + fundesp_valor: 0, + valor_total: 0, + tipo_pessoa: "F", + }); + } + }, [isOpen, data]); + + function onError(errors: any) { + console.log('Erros de validação:', errors); + } return ( - { - if (!open) onClose(null, false); - }} - > + { + if (!open) onClose(null, false); + }} + > {/* Cabeçalho do diálogo */} @@ -216,8 +391,8 @@ const form = useForm({ {/* Estrutura do formulário */} -
- + + @@ -271,7 +446,7 @@ const form = useForm({
( Categoria @@ -292,20 +467,9 @@ const form = useForm({ render={({ field }) => ( Serviço Padrão - )} @@ -332,81 +496,37 @@ const form = useForm({ {/* Campo: Averbação (Checkbox) */}
- ( - - - field.onChange(checked ? "S" : "N")} // salva "S" ou "N" - /> - - Averbação - - )} + label="Averbação" + control={form.control} />
{/* Campo: Transferência de Veículo (Checkbox) */}
- ( - - - field.onChange(checked ? "S" : "N")} // salva "S" ou "N" - /> - - Transferência Veículo - - )} + label="Transferência de Veículo" + control={form.control} />
{/* Campo: Usar A4 (Checkbox) */}
- ( - - - field.onChange(checked ? "S" : "N")} // grava "S" ou "N" - /> - - Usar A4 - - )} + label="Usar A4" + control={form.control} />
{/* Campo: Etiqueta Única (Texto normal) */}
- ( - - - field.onChange(checked ? "S" : "N")} // grava "S" ou "N" - /> - - Etiqueta Única - - )} + label="Etiqueta Única" + control={form.control} />
@@ -417,7 +537,7 @@ const form = useForm({ control={form.control} name="frenteverso" render={({ field }) => { - const categoriaSelecionada = form.watch("categoria"); + const categoriaSelecionada = form.watch("tipo_item"); const isEnabled = categoriaSelecionada === "A"; return ( @@ -478,25 +598,13 @@ const form = useForm({
( Tipo - + )} @@ -506,30 +614,7 @@ const form = useForm({ {/* Campo: Pessoa (Select) */}
- ( - - Pessoa - - - - )} - /> +
@@ -537,37 +622,29 @@ const form = useForm({
( - - {/* Rótulo do campo */} + Quantidade de pessoas - - { - const apenasNumeros = e.target.value.replace(/[^0-9]/g, ''); - field.onChange(apenasNumeros); + // Converte para número se houver valor + const value = e.target.value === "" ? "" : Number(e.target.value); + field.onChange(value); }} /> - - {/* Exibe mensagens de erro do React Hook Form */} )} @@ -580,7 +657,7 @@ const form = useForm({
( Biometria @@ -588,10 +665,8 @@ const form = useForm({ value={field.value} onValueChange={field.onChange} > - - - - + + Sim @@ -608,7 +683,7 @@ const form = useForm({
( CPF/CNPJ @@ -616,10 +691,8 @@ const form = useForm({ value={field.value} onValueChange={field.onChange} > - - - - + + Sim @@ -637,7 +710,7 @@ const form = useForm({
( Autorização @@ -645,10 +718,8 @@ const form = useForm({ value={field.value} onValueChange={field.onChange} > - - - - + + Sim @@ -666,7 +737,7 @@ const form = useForm({
( Abonador @@ -674,10 +745,8 @@ const form = useForm({ value={field.value} onValueChange={field.onChange} > - - - - + + Sim @@ -740,7 +809,7 @@ const form = useForm({ {itensTabela.map((item, index) => ( - + {String(index + 1).padStart(3, '0')} @@ -750,7 +819,7 @@ const form = useForm({ variant="outline" className="w-full cursor-pointer" type="button" - onClick={() => handleRemoveItem(item.marcacao_tipo_id)} + onClick={() => handleRemoveItem(item.servico_etiqueta_id)} > Remover @@ -789,10 +858,8 @@ const form = useForm({ value={field.value} onValueChange={field.onChange} > - - - - + + Sim @@ -810,7 +877,7 @@ const form = useForm({
( Emolumento @@ -851,7 +918,7 @@ const form = useForm({ (item.valor_taxa_judiciaria ?? 0) + (item.valor_outra_taxa1 ?? 0); - form.setValue("valor_total", total); + form.setValue("valor", total); } } catch (error) { console.error("Erro ao buscar item de emolumento:", error); @@ -873,7 +940,7 @@ const form = useForm({
( Emolumento Adicional (Mesma etiqueta) @@ -953,7 +1020,7 @@ const form = useForm({
( Total R$ diff --git a/src/app/(protected)/(cadastros)/cadastros/_data/TServicoEtiqueta/TServicoEtiquetaReadData.ts b/src/app/(protected)/(cadastros)/cadastros/_data/TServicoEtiqueta/TServicoEtiquetaReadData.ts new file mode 100644 index 0000000..9d7fb3e --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_data/TServicoEtiqueta/TServicoEtiquetaReadData.ts @@ -0,0 +1,26 @@ +// Importa o serviço de API que será utilizado para realizar requisições HTTP +import API from '@/shared/services/api/Api'; // + +// Importa o enum que contém os métodos HTTP disponíveis (GET, POST, PUT, DELETE) +import { Methods } from '@/shared/services/api/enums/ApiMethodEnum'; // + +// Importa a interface tipada que define a estrutura dos dados do tipo de serviço +import { TServicoEtiquetaInterface } from '../../_interfaces/TServicoEtiquetaInterface'; + +// Importa função que encapsula chamadas assíncronas e trata erros automaticamente +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; // + +// Função assíncrona que implementa a lógica de localizar um tipo de serviço +async function executeTServicoEtiquetaService(data: TServicoEtiquetaInterface) { + // Instancia o cliente da API para enviar a requisição + const api = new API(); // + + // Executa a requisição para a API com o método apropriado e envia o ID no endpoint + return await api.send({ + method: Methods.GET, // Verbo GET para consulta + endpoint: `administrativo/t_servico_etiqueta/servico_tipo/${data.servico_tipo_id}`, // Endpoint e ID alterados + }); +} + +// Exporta a função de Readr tipo de serviço já encapsulada com tratamento de erros +export const TServicoEtiquetaReadData = withClientErrorHandler(executeTServicoEtiquetaService); // Nome da exportação alterado \ No newline at end of file diff --git a/src/app/(protected)/(cadastros)/cadastros/_data/TServicoEtiqueta/TServicoEtiquetaRemoveData.ts b/src/app/(protected)/(cadastros)/cadastros/_data/TServicoEtiqueta/TServicoEtiquetaRemoveData.ts new file mode 100644 index 0000000..1c6bdcf --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_data/TServicoEtiqueta/TServicoEtiquetaRemoveData.ts @@ -0,0 +1,27 @@ +// Importa o serviço de API que será utilizado para realizar requisições HTTP +import API from '@/shared/services/api/Api'; // + +// Importa o enum que contém os métodos HTTP disponíveis (GET, POST, PUT, DELETE) +import { Methods } from '@/shared/services/api/enums/ApiMethodEnum'; // + +// Importa a interface tipada que define a estrutura dos dados do tipo de serviço +import { TServicoEtiquetaInterface } from '../../_interfaces/TServicoEtiquetaInterface'; // Alterado de GCidadeInterface + +// Importa função que encapsula chamadas assíncronas e trata erros automaticamente +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; // + +// Função assíncrona que implementa a lógica de remover um tipo de serviço +async function executeTServicoEtiquetaRemoveData(data: TServicoEtiquetaInterface) { // Nome da função alterado + + // Instancia o cliente da API para enviar a requisição + const api = new API(); // + + // Executa a requisição para a API com o método apropriado e envia o ID no endpoint + return await api.send({ + method: Methods.DELETE, // Verbo DELETE para exclusão + endpoint: `administrativo/t_servico_etiqueta/${data.servico_etiqueta_id}`, // Endpoint e ID alterados + }); +} + +// Exporta a função de remover tipo de serviço já encapsulada com tratamento de erros +export const TServicoEtiquetaRemoveData = withClientErrorHandler(executeTServicoEtiquetaRemoveData); // Nome da exportação alterado \ No newline at end of file diff --git a/src/app/(protected)/(cadastros)/cadastros/_data/TServicoEtiqueta/TServicoEtiquetaSaveData.ts b/src/app/(protected)/(cadastros)/cadastros/_data/TServicoEtiqueta/TServicoEtiquetaSaveData.ts new file mode 100644 index 0000000..b56e5fb --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_data/TServicoEtiqueta/TServicoEtiquetaSaveData.ts @@ -0,0 +1,39 @@ +// Importa o serviço de API que será utilizado para realizar requisições HTTP +import API from '@/shared/services/api/Api'; // + +// Importa o esquema de validação de dados para tipos de serviço +import { TServicoEtiquetaFormValues } from '../../_schemas/TServicoEtiquetaSchema'; + +// Importa o enum que contém os métodos HTTP disponíveis (GET, POST, PUT, DELETE) +import { Methods } from '@/shared/services/api/enums/ApiMethodEnum'; // + +// Importa a interface tipada que define a estrutura dos dados do tipo de serviço +import { TServicoEtiquetaInterface } from '../../_interfaces/TServicoEtiquetaInterface'; // Interface alterada + +// Importa função que encapsula chamadas assíncronas e trata erros automaticamente +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; // + +// Função assíncrona que implementa a lógica de salvar (criar/atualizar) um tipo de serviço +async function executeTServicoEtiquetaSaveData(data: TServicoEtiquetaFormValues) { + + try{ + + // Instancia o cliente da API para enviar a requisição + const api = new API(); // + + // Executa a requisição para a API com o método apropriado e envia os dados no corpo + return await api.send({ + method: Methods.POST, // PUT se atualizar, POST se criar + endpoint: `administrativo/t_servico_etiqueta`, // Endpoint e ID alterados + body: data, // payload enviado para a API + }); + + } catch (error) { + + console.error('Erro no TServicoEtiquetaSaveData:', error); + throw error; // propaga erro para o form + } +} + +// Exporta a função de salvar tipo de serviço já encapsulada com tratamento de erros +export const TServicoEtiquetaSaveData = withClientErrorHandler(executeTServicoEtiquetaSaveData); // Nome da exportação alterado \ No newline at end of file diff --git a/src/app/(protected)/(cadastros)/cadastros/_data/TServicoTipo/TServicoTipoEditData.ts b/src/app/(protected)/(cadastros)/cadastros/_data/TServicoTipo/TServicoTipoEditData.ts new file mode 100644 index 0000000..a94106d --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_data/TServicoTipo/TServicoTipoEditData.ts @@ -0,0 +1,26 @@ +// Importa o serviço de API que será utilizado para realizar requisições HTTP +import API from '@/shared/services/api/Api'; // + +// Importa o enum que contém os métodos HTTP disponíveis (GET, POST, PUT, DELETE) +import { Methods } from '@/shared/services/api/enums/ApiMethodEnum'; // + +// Importa a interface tipada que define a estrutura dos dados do tipo de serviço +import TServicoTipoInterface from '../../_interfaces/TServicoTipoInterface'; // Alterado de GCidadeInterface + +// Importa função que encapsula chamadas assíncronas e trata erros automaticamente +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; // + +// Função assíncrona que implementa a lógica de localizar um tipo de serviço +async function executeTServicoTipoEditService(data: TServicoTipoInterface) { + // Instancia o cliente da API para enviar a requisição + const api = new API(); // + + // Executa a requisição para a API com o método apropriado e envia o ID no endpoint + return await api.send({ + method: Methods.GET, // Verbo GET para consulta + endpoint: `administrativo/t_servico_tipo/${data.servico_tipo_id}`, // Endpoint e ID alterados + }); +} + +// Exporta a função de Readr tipo de serviço já encapsulada com tratamento de erros +export const TServicoTipoEditData = withClientErrorHandler(executeTServicoTipoEditService); // Nome da exportação alterado \ No newline at end of file diff --git a/src/app/(protected)/(cadastros)/cadastros/_data/TServicoTipo/TServicoTipoRemoveData.ts b/src/app/(protected)/(cadastros)/cadastros/_data/TServicoTipo/TServicoTipoRemoveData.ts index 5b91bb5..0534182 100644 --- a/src/app/(protected)/(cadastros)/cadastros/_data/TServicoTipo/TServicoTipoRemoveData.ts +++ b/src/app/(protected)/(cadastros)/cadastros/_data/TServicoTipo/TServicoTipoRemoveData.ts @@ -19,7 +19,7 @@ async function executeTServicoTipoRemoveData(data: TServicoTipoInterface) { // N // Executa a requisição para a API com o método apropriado e envia o ID no endpoint return await api.send({ method: Methods.DELETE, // Verbo DELETE para exclusão - endpoint: `administrativo/t_servico_tipo/${data.servico_tipo_id}`, // Endpoint e ID alterados de g_cidade/cidade_id + endpoint: `administrativo/t_servico_tipo/${data.servico_tipo_id}`, // Endpoint e ID alterados }); } diff --git a/src/app/(protected)/(cadastros)/cadastros/_data/TServicoTipo/TServicoTipoSaveData.ts b/src/app/(protected)/(cadastros)/cadastros/_data/TServicoTipo/TServicoTipoSaveData.ts index 47942ce..18308b7 100644 --- a/src/app/(protected)/(cadastros)/cadastros/_data/TServicoTipo/TServicoTipoSaveData.ts +++ b/src/app/(protected)/(cadastros)/cadastros/_data/TServicoTipo/TServicoTipoSaveData.ts @@ -1,6 +1,9 @@ // Importa o serviço de API que será utilizado para realizar requisições HTTP import API from '@/shared/services/api/Api'; // +// Importa o esquema de validação de dados para tipos de serviço +import { TServicoTipoFormValues } from '../../_schemas/TServicoTipoSchema'; + // Importa o enum que contém os métodos HTTP disponíveis (GET, POST, PUT, DELETE) import { Methods } from '@/shared/services/api/enums/ApiMethodEnum'; // @@ -11,20 +14,33 @@ import TServicoTipoInterface from '../../_interfaces/TServicoTipoInterface'; // import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; // // Função assíncrona que implementa a lógica de salvar (criar/atualizar) um tipo de serviço -async function executeTServicoTipoSaveData(data: TServicoTipoInterface) { // Nome da função alterado +async function executeTServicoTipoSaveData(data: TServicoTipoFormValues & { metodo?: 'POST' | 'PUT' }) { // Verifica se existe ID do tipo de serviço para decidir se é atualização (PUT) ou criação (POST) - const isUpdate = Boolean(data.servico_tipo_id); // Campo de ID alterado de 'cidade_id' para 'servico_tipo_id' + const isEditing = !!data.servico_tipo_id && Number(data.servico_tipo_id) > 0; - // Instancia o cliente da API para enviar a requisição - const api = new API(); // + // Define método: prioridade para valor passado manualmente (metodo) + const method = data.metodo ?? (isEditing ? 'PUT' : 'POST'); - // Executa a requisição para a API com o método apropriado e envia os dados no corpo - return await api.send({ - method: isUpdate ? Methods.PUT : Methods.POST, // PUT se atualizar, POST se criar - endpoint: `administrativo/t_servico_tipo/${data.servico_tipo_id || ''}`, // Endpoint e ID alterados - body: data, // payload enviado para a API - }); + try{ + + console.log(data) + + // Instancia o cliente da API para enviar a requisição + const api = new API(); // + + // Executa a requisição para a API com o método apropriado e envia os dados no corpo + return await api.send({ + method: isEditing ? Methods.PUT : Methods.POST, // PUT se atualizar, POST se criar + endpoint: `administrativo/t_servico_tipo/${data.servico_tipo_id || ''}`, // Endpoint e ID alterados + body: data, // payload enviado para a API + }); + + } catch (error) { + + console.error('Erro no TServicoTipoSaveData:', error); + throw error; // propaga erro para o form + } } // Exporta a função de salvar tipo de serviço já encapsulada com tratamento de erros diff --git a/src/app/(protected)/(cadastros)/cadastros/_data/TTBReconhecimentoTipo/TTBReconhecimentoTipoIndexData.ts b/src/app/(protected)/(cadastros)/cadastros/_data/TTBReconhecimentoTipo/TTBReconhecimentoTipoIndexData.ts new file mode 100644 index 0000000..7e37517 --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_data/TTBReconhecimentoTipo/TTBReconhecimentoTipoIndexData.ts @@ -0,0 +1,27 @@ +// Importa o utilitário responsável por tratar erros de forma padronizada no cliente +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; + +// Importa a classe de serviço que gerencia requisições HTTP para a API +import API from '@/shared/services/api/Api'; + +// Importa o enum que define os métodos HTTP disponíveis (GET, POST, PUT, DELETE, etc.) +import { Methods } from '@/shared/services/api/enums/ApiMethodEnum'; +import { TTBReconhecimentoTipoReadInterface } from '../../_interfaces/TTBReconhecimentoTipoReadInterface'; + +// Função assíncrona responsável por executar a requisição para listar os tipos de marcação +async function executeTTBReconhecimentoTipoIndexData(data: TTBReconhecimentoTipoReadInterface) { + // Cria uma nova instância da classe API para enviar a requisição + const api = new API(); + + // Concatena o endpoint com a query string (caso existam parâmetros) + const endpoint = `administrativo/t_tb_reconhecimentotipo/`; + + // Envia uma requisição GET para o endpoint 'administrativo/g_marcacao_tipo/' + return await api.send({ + method: Methods.GET, + endpoint: endpoint, + }); +} + +// Exporta a função encapsulada pelo handler de erro, garantindo tratamento uniforme em caso de falhas +export const TTBReconhecimentoTipoIndexData = withClientErrorHandler(executeTTBReconhecimentoTipoIndexData); diff --git a/src/app/(protected)/(cadastros)/cadastros/_hooks/g_marcacao_tipo/useGMarcacaoTipoReadHook.ts b/src/app/(protected)/(cadastros)/cadastros/_hooks/g_marcacao_tipo/useGMarcacaoTipoReadHook.ts index 2f1cfb7..696eb74 100644 --- a/src/app/(protected)/(cadastros)/cadastros/_hooks/g_marcacao_tipo/useGMarcacaoTipoReadHook.ts +++ b/src/app/(protected)/(cadastros)/cadastros/_hooks/g_marcacao_tipo/useGMarcacaoTipoReadHook.ts @@ -6,14 +6,15 @@ import { useMemo, useState } from 'react'; // Importa a interface que define a estrutura dos dados de "GMarcacaoTipo" import { GMarcacaoTipoReadInterface } from '../../_interfaces/GMarcacaoTipoReadInterface'; +import { GMarcacaoTipoInterface } from '../../_interfaces/GMarcacaoTipoInterface'; // Importa o serviço responsável por buscar os dados de "GMarcacaoTipo" na API import { GMarcacaoTipoIndexService } from '../../_services/g_marcacao_tipo/GMarcacaoTipoIndexService'; -import { GMarcacaoTipoInterface } from '../../_interfaces/GMarcacaoTipoInterface'; // Hook personalizado para leitura (consulta) dos tipos de marcação export const useGMarcacaoTipoReadHook = () => { + // Obtém a função que atualiza a resposta global do sistema const { setResponse } = useResponse(); diff --git a/src/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaReadHook.ts b/src/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaReadHook.ts new file mode 100644 index 0000000..88b50ab --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaReadHook.ts @@ -0,0 +1,44 @@ +// Importa o hook responsável por gerenciar e exibir respostas globais (sucesso, erro, etc.) +import { useResponse } from '@/shared/components/response/ResponseContext'; + +// Importa hooks do React para gerenciamento de estado e memorização de valores +import { useCallback, useState } from 'react'; + +// Importa a interface que define a estrutura dos dados de "TServicoEtiqueta" +import { TServicoEtiquetaInterface } from '../../_interfaces/TServicoEtiquetaInterface'; + +// Importa o serviço responsável por buscar os dados de "TServicoEtiqueta" na API +import { TServicoEtiquetaServicoIdService } from '../../_services/t_servico_etiqueta/TServicoEtiquetaServicoIdService'; + +// Hook personalizado para leitura (consulta) dos tipos de marcação +export const useTServicoEtiquetaReadHook = () => { + + // Obtém a função que atualiza a resposta global do sistema + const { setResponse } = useResponse(); + + // Define o estado local que armazenará a lista de tipos de marcação + const [tServicoEtiqueta, setTServicoEtiqueta] = useState([]); + + // Função responsável por buscar os dados da API e atualizar o estado + const fetchTServicoEtiqueta = useCallback(async (data: TServicoEtiquetaInterface) => { + + try{ + + // Executa o serviço que faz a requisição à API + const response = await TServicoEtiquetaServicoIdService(data); + + // Atualiza o estado local com os dados retornados + setTServicoEtiqueta(response.data); + + // Atualiza o contexto global de resposta (ex: para exibir alertas ou mensagens) + setResponse(response); + + } catch (error) { + console.error('Erro ao buscar etiquetas:', error); + return { data: [] }; + } + }, [setResponse]); + + // Retorna os dados e a função de busca, memorizando o valor para evitar recriações desnecessárias + return { tServicoEtiqueta, fetchTServicoEtiqueta }; +}; diff --git a/src/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaRemoveHook.ts b/src/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaRemoveHook.ts new file mode 100644 index 0000000..8599229 --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaRemoveHook.ts @@ -0,0 +1,25 @@ +import { useResponse } from "@/shared/components/response/ResponseContext"; // Contexto global para gerenciar respostas da API + +// Interface tipada do tipo de serviço +import { TServicoEtiquetaInterface } from "../../_interfaces/TServicoEtiquetaInterface"; + +// Função que remove o tipo de serviço via API +import { TServicoEtiquetaRemoveData } from "../../_data/TServicoEtiqueta/TServicoEtiquetaRemoveData"; + +// Hook customizado para remoção de tipos de serviço +export const useTServicoEtiquetaRemoveHook = () => { + // Hook do contexto de resposta para feedback global (alertas, mensagens etc.) + const { setResponse } = useResponse(); + + // Função assíncrona que remove um tipo de serviço + const fetchTServicoEtiquetaRemove = async (data: TServicoEtiquetaInterface) => { + // Chama a função de remoção passando os dados do tipo de serviço + const response = await TServicoEtiquetaRemoveData(data); + + // Atualiza o contexto global com a resposta da API + setResponse(response); + }; + + // Retorna a função de remoção para ser usada no componente + return { fetchTServicoEtiquetaRemove }; +}; \ No newline at end of file diff --git a/src/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaSaveHook.ts b/src/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaSaveHook.ts new file mode 100644 index 0000000..25ebfcf --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_etiqueta/useTServicoEtiquetaSaveHook.ts @@ -0,0 +1,37 @@ +import { useState } from 'react'; +import { useResponse } from '@/shared/components/response/ResponseContext'; + +// Interface tipada do serviço etiqueta +import { TServicoEtiquetaInterface } from '../../_interfaces/TServicoEtiquetaInterface'; + +// Serviço que salva os dados do serviço etiqueta +import { TServicoEtiquetaSaveService } from '../../_services/t_servico_etiqueta/TServicoEtiquetaSaveService'; + +export const useTServicoEtiquetaSaveHook = () => { + const { setResponse } = useResponse(); + + // Estado local para armazenar os dados do serviço etiqueta salvos + const [tServicoEtiquetaSave, setTServicoEtiquetaSave] = useState(null); + + /** + * Função que executa o salvamento de um serviço etiqueta. + * @param data Os dados do serviço etiqueta a serem salvos. + */ + const fetchTServicoEtiquetaSave = async (data: TServicoEtiquetaInterface) => { + + // Chama o serviço de salvamento + const response = await TServicoEtiquetaSaveService(data); + + // Guardar os dados localizados + setTServicoEtiquetaSave(response.data); + + // Manda a resposta para o verificador de resposta global + ///setResponse(response); + + // Manda a resposta para o verificador de resposta global + return response.data; + } + + // Retorna o estado e a função de salvamento para uso no componente + return { tServicoEtiquetaSave, fetchTServicoEtiquetaSave }; +}; \ No newline at end of file diff --git a/src/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_tipo/useTServicoTipoEditHook.ts b/src/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_tipo/useTServicoTipoEditHook.ts new file mode 100644 index 0000000..67f927e --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_hooks/t_servico_tipo/useTServicoTipoEditHook.ts @@ -0,0 +1,26 @@ +import { useResponse } from "@/shared/components/response/ResponseContext"; // Contexto global para gerenciar respostas da API + +// Interface tipada do tipo de serviço +import TServicoTipoInterface from "../../_interfaces/TServicoTipoInterface"; + +// Função que Edit o tipo de serviço via API +import { TServicoTipoEditData } from "../../_data/TServicoTipo/TServicoTipoEditData"; + +// Hook customizado para remoção de tipos de serviço +export const useTServicoTipoEditHook = () => { + // Hook do contexto de resposta para feedback global (alertas, mensagens etc.) + const { setResponse } = useResponse(); + + // Função assíncrona que Edit um tipo de serviço + const editTServicoTipo = async (data: TServicoTipoInterface) => { + + // Chama a função de remoção passando os dados do tipo de serviço + const response = await TServicoTipoEditData(data); + + // Atualiza o contexto global com a resposta da API + setResponse(response); + }; + + // Retorna a função de remoção para ser usada no componente + return { editTServicoTipo }; +}; \ No newline at end of file diff --git a/src/app/(protected)/(cadastros)/cadastros/_hooks/t_tb_reconhecimentotipo/useTTBReconhecimentoTipoReadHook.ts b/src/app/(protected)/(cadastros)/cadastros/_hooks/t_tb_reconhecimentotipo/useTTBReconhecimentoTipoReadHook.ts new file mode 100644 index 0000000..88a8eaa --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_hooks/t_tb_reconhecimentotipo/useTTBReconhecimentoTipoReadHook.ts @@ -0,0 +1,37 @@ +// Importa o hook responsável por gerenciar e exibir respostas globais (sucesso, erro, etc.) +import { useResponse } from '@/shared/components/response/ResponseContext'; + +// Importa hooks do React para gerenciamento de estado e memorização de valores +import { useMemo, useState } from 'react'; + +// Importa a interface que define a estrutura dos dados de "TTBReconhecimentoTipo" +import { TTBReconhecimentoTipoReadInterface } from '../../_interfaces/TTBReconhecimentoTipoReadInterface'; +import { TTBReconhecimentoTipoInterface } from '../../_interfaces/TTBReconhecimentoTipoInterface'; + +// Importa o serviço responsável por buscar os dados de "TTBReconhecimentoTipo" na API +import { TTBReconhecimentoTipoIndexService } from '../../_services/t_tb_reconhecimentotipo/TTBReconhecimentoTipoIndexService'; + + +// Hook personalizado para leitura (consulta) dos tipos de marcação +export const useTTBReconhecimentoTipoReadHook = () => { + // Obtém a função que atualiza a resposta global do sistema + const { setResponse } = useResponse(); + + // Define o estado local que armazenará a lista de tipos de marcação + const [tTBReconhecimentoTipo, setTTBReconhecimentoTipo] = useState([]); + + // Função responsável por buscar os dados da API e atualizar o estado + const fetchTTBReconhecimentoTipo = async (data: TTBReconhecimentoTipoReadInterface) => { + // Executa o serviço que faz a requisição à API + const response = await TTBReconhecimentoTipoIndexService(data); + + // Atualiza o estado local com os dados retornados + setTTBReconhecimentoTipo(response.data); + + // Atualiza o contexto global de resposta (ex: para exibir alertas ou mensagens) + setResponse(response); + }; + + // Retorna os dados e a função de busca, memorizando o valor para evitar recriações desnecessárias + return useMemo(() => ({ tTBReconhecimentoTipo, fetchTTBReconhecimentoTipo }), [tTBReconhecimentoTipo, fetchTTBReconhecimentoTipo]); +}; diff --git a/src/app/(protected)/(cadastros)/cadastros/_interfaces/TServicoEtiquetaInterface.ts b/src/app/(protected)/(cadastros)/cadastros/_interfaces/TServicoEtiquetaInterface.ts new file mode 100644 index 0000000..9ab50d7 --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_interfaces/TServicoEtiquetaInterface.ts @@ -0,0 +1,7 @@ +// Interface que representa a tabela T_TB_RECONHECIMENTOTIPO +export interface TServicoEtiquetaInterface { + servico_etiqueta_id?: number; // NUMERIC(10,2) NOT NULL - Chave primária + etiqueta_modelo_id?: number; // NUMERIC(10,2) + servico_tipo_id?: number; // NUMERIC(10,2) + descricao?: string +} diff --git a/src/app/(protected)/(cadastros)/cadastros/_interfaces/TServicoEtiquetaServicoIdReadInterface.ts b/src/app/(protected)/(cadastros)/cadastros/_interfaces/TServicoEtiquetaServicoIdReadInterface.ts new file mode 100644 index 0000000..12ce5b0 --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_interfaces/TServicoEtiquetaServicoIdReadInterface.ts @@ -0,0 +1,3 @@ +export interface TServicoEtiquetaServicoIdReadInterface { + servico_tipo_id?: number +} \ No newline at end of file diff --git a/src/app/(protected)/(cadastros)/cadastros/_interfaces/TServicoTipoInterface.ts b/src/app/(protected)/(cadastros)/cadastros/_interfaces/TServicoTipoInterface.ts index 96a05f1..872097e 100644 --- a/src/app/(protected)/(cadastros)/cadastros/_interfaces/TServicoTipoInterface.ts +++ b/src/app/(protected)/(cadastros)/cadastros/_interfaces/TServicoTipoInterface.ts @@ -1,37 +1,27 @@ export default interface TServicoTipoInterface { - servico_tipo_id?: number; // SERVICO_TIPO_ID NUMERIC(10,2) NOT NULL (PK) - descricao: string; // DESCRICAO VARCHAR(60) - valor?: number; // VALOR NUMERIC(14,3) - tipo_item?: string; // TIPO_ITEM VARCHAR(1) - requer_autorizacao?: string; // REQUER_AUTORIZACAO VARCHAR(1) - requer_biometria?: string; // REQUER_BIOMETRIA VARCHAR(1) - tipo_pessoa?: string; // TIPO_PESSOA VARCHAR(1) - tb_reconhecimentotipo_id?: number; // TB_RECONHECIMENTOTIPO_ID NUMERIC(10,2) (FK) - tipo_permissao_cpf?: string; // TIPO_PERMISSAO_CPF VARCHAR(1) - requer_abonador?: string; // REQUER_ABONADOR VARCHAR(1) - requer_representante?: string; // REQUER_REPRESENTANTE VARCHAR(1) - situacao?: string; // SITUACAO VARCHAR(1) - requer_cpf?: string; // REQUER_CPF VARCHAR(1) - servico_padrao?: string; // SERVICO_PADRAO VARCHAR(1) - maximo_pessoa?: number; // MAXIMO_PESSOA NUMERIC(10,2) - alterar_valor?: string; // ALTERAR_VALOR VARCHAR(1) - servico_caixa_id?: number; // SERVICO_CAIXA_ID NUMERIC(10,2) - lancar_taxa?: string; // LANCAR_TAXA VARCHAR(1) - lancar_fundesp?: string; // LANCAR_FUNDESP VARCHAR(1) - liberar_desconto?: string; // LIBERAR_DESCONTO VARCHAR(1) - fundesp_automatica?: string; // FUNDESP_AUTOMATICA VARCHAR(1) - lancar_valor_documento?: string; // LANCAR_VALOR_DOCUMENTO VARCHAR(1) - valor_fixo?: string; // VALOR_FIXO VARCHAR(1) - emolumento_id?: number; // EMOLUMENTO_ID NUMERIC(10,2) (FK) - ato_praticado?: string; // ATO_PRATICADO VARCHAR(1) - selar?: string; // SELAR VARCHAR(1) - frenteverso?: string; // FRENTEVERSO VARCHAR(1) - pagina_acrescida?: string; // PAGINA_ACRESCIDA VARCHAR(1) - emolumento_obrigatorio?: number; // EMOLUMENTO_OBRIGATORIO NUMERIC(10,2) - apresentante_selo?: string; // APRESENTANTE_SELO VARCHAR(1) - renovacao_cartao?: string; // RENOVACAO_CARTAO VARCHAR(1) - etiqueta_unica?: string; // ETIQUETA_UNICA VARCHAR(1) - transferencia_veiculo?: string; // TRANSFERENCIA_VEICULO VARCHAR(1) - usar_a4?: string; // USAR_A4 VARCHAR(1) - averbacao?: string; // AVERBACAO VARCHAR(1) -} \ No newline at end of file + servico_tipo_id?: number; // SERVICO_TIPO_ID NUMERIC(10,2) NOT NULL (PK) + descricao: string; // DESCRICAO VARCHAR(60) + valor?: number; // VALOR NUMERIC(14,3) + requer_autorizacao?: string; // REQUER_AUTORIZACAO VARCHAR(1) + requer_biometria?: string; // REQUER_BIOMETRIA VARCHAR(1) + tipo_pessoa?: string; // TIPO_PESSOA VARCHAR(1) + tb_reconhecimentotipo_id?: number; // TB_RECONHECIMENTOTIPO_ID NUMERIC(10,2) (FK) + requer_abonador?: string; // REQUER_ABONADOR VARCHAR(1) + situacao?: string; // SITUACAO VARCHAR(1) + requer_cpf?: string; // REQUER_CPF VARCHAR(1) + servico_padrao?: string; // SERVICO_PADRAO VARCHAR(1) + maximo_pessoa?: number; // MAXIMO_PESSOA NUMERIC(10,2) + alterar_valor?: string; // ALTERAR_VALOR VARCHAR(1) + servico_caixa_id?: number; // SERVICO_CAIXA_ID NUMERIC(10,2) + caixa_servico_id?: number; // LIBERAR_DESCONTO VARCHAR(1) + valor_fixo?: string; // VALOR_FIXO VARCHAR(1) + emolumento_id?: number; // EMOLUMENTO_ID NUMERIC(10,2) (FK) + emolumento_obrigatorio?: number; // EMOLUMENTO_OBRIGATORIO NUMERIC(10,2) (FK) + ato_praticado?: string; // ATO_PRATICADO VARCHAR(1) + selar?: string; // SELAR VARCHAR(1) + frenteverso?: string; // FRENTEVERSO VARCHAR(1) + etiqueta_unica?: string; // ETIQUETA_UNICA VARCHAR(1) + transferencia_veiculo?: string; // TRANSFERENCIA_VEICULO VARCHAR(1) + usar_a4?: string; // USAR_A4 VARCHAR(1) + averbacao?: string; // AVERBACAO VARCHAR(1) +} diff --git a/src/app/(protected)/(cadastros)/cadastros/_interfaces/TTBReconhecimentoTipoInterface.ts b/src/app/(protected)/(cadastros)/cadastros/_interfaces/TTBReconhecimentoTipoInterface.ts new file mode 100644 index 0000000..8144ce6 --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_interfaces/TTBReconhecimentoTipoInterface.ts @@ -0,0 +1,6 @@ +// Interface que representa a tabela T_TB_RECONHECIMENTOTIPO +export interface TTbReconhecimentoTipoInterface { + tb_reconhecimentotipo_id: number; // NUMERIC(10,2) NOT NULL - Chave primária + descricao?: string; // VARCHAR(30) + situacao?: string; // VARCHAR(1) +} diff --git a/src/app/(protected)/(cadastros)/cadastros/_interfaces/TTBReconhecimentoTipoReadInterface.ts b/src/app/(protected)/(cadastros)/cadastros/_interfaces/TTBReconhecimentoTipoReadInterface.ts new file mode 100644 index 0000000..69948ee --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_interfaces/TTBReconhecimentoTipoReadInterface.ts @@ -0,0 +1,4 @@ +export interface TTBReconhecimentoTipoReadInterface { + tb_reconhecimentotipo_id?: number, + descricao?: string +} \ No newline at end of file diff --git a/src/app/(protected)/(cadastros)/cadastros/_schemas/TServicoEtiquetaSchema.ts b/src/app/(protected)/(cadastros)/cadastros/_schemas/TServicoEtiquetaSchema.ts new file mode 100644 index 0000000..11dc09e --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_schemas/TServicoEtiquetaSchema.ts @@ -0,0 +1,15 @@ +/** + * Interface principal baseada na DDL + * Tabela: T_SERVICO_ETIQUETA + */ +export interface TServicoEtiquetaFormValues { + /** Identificador principal (PK) */ + servico_etiqueta_id?: number; + + /** Relacionamento com o modelo de etiqueta (FK) */ + etiqueta_modelo_id?: number; + + /** Relacionamento com o tipo de serviço (FK) */ + servico_tipo_id?: number; + +} diff --git a/src/app/(protected)/(cadastros)/cadastros/_schemas/TServicoTipoSchema.ts b/src/app/(protected)/(cadastros)/cadastros/_schemas/TServicoTipoSchema.ts index 84a6ed1..3fae76f 100644 --- a/src/app/(protected)/(cadastros)/cadastros/_schemas/TServicoTipoSchema.ts +++ b/src/app/(protected)/(cadastros)/cadastros/_schemas/TServicoTipoSchema.ts @@ -29,15 +29,15 @@ export const TServicoTipoSchema = z.object({ etiqueta_unica: SN.optional(), selar: SN.optional(), servico_padrao: SN.optional(), - lancar_taxa: SN.optional(), - lancar_fundesp: SN.optional(), - liberar_desconto: SN.optional(), - fundesp_automatica: SN.optional(), - lancar_valor_documento: SN.optional(), + // lancar_taxa: SN.optional(), + // lancar_fundesp: SN.optional(), + // liberar_desconto: SN.optional(), + // fundesp_automatica: SN.optional(), + // lancar_valor_documento: SN.optional(), valor_fixo: SN.optional(), ato_praticado: SN.optional(), - apresentante_selo: SN.optional(), - renovacao_cartao: SN.optional(), + // apresentante_selo: SN.optional(), + // renovacao_cartao: SN.optional(), // Situação situacao: AI, @@ -46,8 +46,8 @@ export const TServicoTipoSchema = z.object({ valor: OptionalNumber, maximo_pessoa: OptionalNumber, servico_caixa_id: OptionalNumber, - emolumento_id: OptionalNumber, - emolumento_obrigatorio: OptionalNumber, + emolumento_id: z.number().nullable(), + emolumento_obrigatorio: z.number().nullable(), // Relacionamentos e permissões tipo_item: OneCharString, @@ -55,12 +55,12 @@ export const TServicoTipoSchema = z.object({ requer_biometria: OneCharString, tipo_pessoa: OneCharString, tb_reconhecimentotipo_id: OptionalNumber, - tipo_permissao_cpf: OneCharString, + // tipo_permissao_cpf: OneCharString, requer_abonador: OneCharString, - requer_representante: OneCharString, + // requer_representante: OneCharString, requer_cpf: OneCharString, - alterar_valor: OneCharString, - pagina_acrescida: OneCharString, + // alterar_valor: OneCharString, + // pagina_acrescida: OneCharString, // Campos auxiliares usados apenas no formulário (não persistidos) valor_emolumento: z.number().optional(), diff --git a/src/app/(protected)/(cadastros)/cadastros/_services/t_servico_etiqueta/TServicoEtiquetaSaveService.ts b/src/app/(protected)/(cadastros)/cadastros/_services/t_servico_etiqueta/TServicoEtiquetaSaveService.ts new file mode 100644 index 0000000..e6675ef --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_services/t_servico_etiqueta/TServicoEtiquetaSaveService.ts @@ -0,0 +1,21 @@ +// Função que envolve qualquer ação assíncrona para capturar e tratar erros do cliente +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; + +// Função que salva os dados do serviço etiqueta via API (ou mock) +import { TServicoEtiquetaSaveData } from '../../_data/TServicoEtiqueta/TServicoEtiquetaSaveData'; + +// Interface tipada do serviço etiqueta +import { TServicoEtiquetaInterface } from '../../_interfaces/TServicoEtiquetaInterface'; + +// Função assíncrona que executa o salvamento de um serviço etiqueta +async function executeTServicoEtiquetaSaveService(data: TServicoEtiquetaInterface) { + + // Chama a função que salva os dados do serviço etiqueta + const response = await TServicoEtiquetaSaveData(data); + + // Retorna a resposta do salvamento + return response; +} + +// Exporta o serviço de salvamento de serviço etiqueta já encapsulado com tratamento de erros +export const TServicoEtiquetaSaveService = withClientErrorHandler(executeTServicoEtiquetaSaveService); \ No newline at end of file diff --git a/src/app/(protected)/(cadastros)/cadastros/_services/t_servico_etiqueta/TServicoEtiquetaServicoIdService.ts b/src/app/(protected)/(cadastros)/cadastros/_services/t_servico_etiqueta/TServicoEtiquetaServicoIdService.ts new file mode 100644 index 0000000..1d56a87 --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_services/t_servico_etiqueta/TServicoEtiquetaServicoIdService.ts @@ -0,0 +1,20 @@ +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; +// Função que envolve qualquer ação assíncrona para capturar e tratar erros do cliente + +import { TServicoEtiquetaReadData } from '../../_data/TServicoEtiqueta/TServicoEtiquetaReadData'; + +import { TServicoEtiquetaInterface } from '../../_interfaces/TServicoEtiquetaInterface'; +// Interface tipada do tipo de serviço + +// Função assíncrona que executa a consulta de um tipo de serviço etiqueta +async function executeTServicoEtiquetaServicoIdService(data: TServicoEtiquetaInterface) { + + // Chama a função que consulta os dados do tipo de serviço etiqueta + const response = await TServicoEtiquetaReadData(data); + + // Retorna a resposta da remoção + return response; +} + +// Exporta o serviço de remoção de tipo de serviço já encapsulado com tratamento de erros +export const TServicoEtiquetaServicoIdService = withClientErrorHandler(executeTServicoEtiquetaServicoIdService); \ No newline at end of file diff --git a/src/app/(protected)/(cadastros)/cadastros/_services/t_servico_tipo/TServicoTipoEditService.ts b/src/app/(protected)/(cadastros)/cadastros/_services/t_servico_tipo/TServicoTipoEditService.ts new file mode 100644 index 0000000..873e321 --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_services/t_servico_tipo/TServicoTipoEditService.ts @@ -0,0 +1,20 @@ +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; +// Função que envolve qualquer ação assíncrona para capturar e tratar erros do cliente + +import { TServicoTipoEditData } from '../../_data/TServicoTipo/TServicoTipoEditData'; +// Função que remove os dados do tipo de serviço via API + +import TServicoTipoInterface from '../../_interfaces/TServicoTipoInterface'; +// Interface tipada do tipo de serviço + +// Função assíncrona que executa a remoção de um tipo de serviço +async function executeTServicoTipoEditService(data: TServicoTipoInterface) { + // Chama a função que remove os dados do tipo de serviço + const response = await TServicoTipoEditData(data); + + // Retorna a resposta da remoção + return response; +} + +// Exporta o serviço de remoção de tipo de serviço já encapsulado com tratamento de erros +export const TServicoTipoEditService = withClientErrorHandler(executeTServicoTipoEditService); \ No newline at end of file diff --git a/src/app/(protected)/(cadastros)/cadastros/_services/t_tb_reconhecimentotipo/TTBReconhecimentoTipoIndexService.ts b/src/app/(protected)/(cadastros)/cadastros/_services/t_tb_reconhecimentotipo/TTBReconhecimentoTipoIndexService.ts new file mode 100644 index 0000000..fece097 --- /dev/null +++ b/src/app/(protected)/(cadastros)/cadastros/_services/t_tb_reconhecimentotipo/TTBReconhecimentoTipoIndexService.ts @@ -0,0 +1,20 @@ +// Importa o utilitário responsável por lidar com erros de forma padronizada no cliente +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; + +// Importa a função que realiza a requisição de listagem dos tipos de marcação +import { TTBReconhecimentoTipoIndexData } from '../../_data/TTBReconhecimentoTipo/TTBReconhecimentoTipoIndexData'; +import { TTBReconhecimentoTipoReadInterface } from '../../_interfaces/TTBReconhecimentoTipoReadInterface'; + +// Função assíncrona responsável por executar o serviço de listagem de tipos de marcação +async function executeTTBReconhecimentoTipoIndexService(data: TTBReconhecimentoTipoReadInterface) { + // Chama a função que realiza a requisição à API e aguarda a resposta + const response = await TTBReconhecimentoTipoIndexData(data); + + // Retorna a resposta obtida da requisição + return response; +} + +// Exporta o serviço encapsulado pelo handler de erro, garantindo tratamento uniforme em caso de falhas +export const TTBReconhecimentoTipoIndexService = withClientErrorHandler( + executeTTBReconhecimentoTipoIndexService, +); diff --git a/src/packages/administrativo/components/CCaixaServico/CCaixaServicoSelect.tsx b/src/packages/administrativo/components/CCaixaServico/CCaixaServicoSelect.tsx index 83761bf..125a8aa 100644 --- a/src/packages/administrativo/components/CCaixaServico/CCaixaServicoSelect.tsx +++ b/src/packages/administrativo/components/CCaixaServico/CCaixaServicoSelect.tsx @@ -51,12 +51,10 @@ export default function CCaixaServicoSelect({ sistema_id, field }: any) { className="justify-between cursor-pointer" > {isLoading - ? "Carregando..." - : field.value && typeof field.value === 'object' && field.value.value - ? GetCapitalize(field.value.value) // Exibe a descrição do objeto - : field.value && typeof field.value !== 'object' - ? field.value // Se for um ID (valor antigo), exibe ele - : "Selecione o serviço"} + ? "Carregando..." + : selected + ? GetCapitalize(selected.descricao) + : "Selecione o serviço"} @@ -75,10 +73,7 @@ export default function CCaixaServicoSelect({ sistema_id, field }: any) { key={item.caixa_servico_id} value={item.descricao?.toLowerCase() ?? ""} onSelect={() => { - field.onChange({ - key: Number(item.caixa_servico_id), - value: item.descricao, - }); + field.onChange(Number(item.caixa_servico_id)); // envia apenas o número setOpen(false); }} > diff --git a/src/packages/administrativo/components/GEmolumento/GEmolumentoSelect.tsx b/src/packages/administrativo/components/GEmolumento/GEmolumentoSelect.tsx index c22efd6..0b3df97 100644 --- a/src/packages/administrativo/components/GEmolumento/GEmolumentoSelect.tsx +++ b/src/packages/administrativo/components/GEmolumento/GEmolumentoSelect.tsx @@ -56,7 +56,7 @@ export default function GEmolumentoSelect({ sistema_id, field, onSelectChange, c // Obtém o item selecionado com base no valor atual do campo const selected = gEmolumento?.find( - (item) => String(item.emolumento_id) === String(field.value?.key ?? field.value) + (item) => Number(item.emolumento_id) === Number(field.value ?? 0) ); @@ -112,6 +112,7 @@ export default function GEmolumentoSelect({ sistema_id, field, onSelectChange, c className="cursor-pointer w-full" key={item.emolumento_id} value={item.descricao?.toLowerCase() ?? ""} + // Quando o item é selecionado onSelect={() => { // Cria objeto com ID e descrição @@ -120,15 +121,20 @@ export default function GEmolumentoSelect({ sistema_id, field, onSelectChange, c value: item.descricao, }; - // Atualiza o valor no react-hook-form - field.onChange(selectedValue); + // Atualiza o valor no react-hook-form com o ID numérico + field.onChange(Number(item.emolumento_id ?? 0)); - // Dispara callback externo, se existir (ex: fetchGEmolumentoItem) - if (onSelectChange) onSelectChange(selectedValue); + // Dispara callback externo, se existir (mantém o objeto completo) + if (onSelectChange) + onSelectChange({ + key: Number(item.emolumento_id), + value: item.descricao, + }); // Fecha o popover setOpen(false); }} + > {/* Ícone de seleção (check) */} { + const loadData = async () => { + if (!tTBReconhecimentoTipo.length) { + setIsLoading(true); + await fetchTTBReconhecimentoTipo(); + setIsLoading(false); + } + }; + loadData(); + }, []); + const selected = tTBReconhecimentoTipo?.find( + (item) => Number(item.tb_reconhecimentotipo_id) === Number(field.value) + ); + return ( + + + + + + + + + + + + {isLoading ? "Carregando..." : "Nenhum resultado encontrado."} + + + {tTBReconhecimentoTipo?.map((item) => ( + { + field.onChange(Number(item.tb_reconhecimentotipo_id)); // envia apenas o número + setOpen(false); + }} + > + + {GetCapitalize(item.descricao)} + + ))} + + + + + + ); +} diff --git a/src/shared/components/confirmacao/ConfirmacaoCheckBox.tsx b/src/shared/components/confirmacao/ConfirmacaoCheckBox.tsx new file mode 100644 index 0000000..2b8255f --- /dev/null +++ b/src/shared/components/confirmacao/ConfirmacaoCheckBox.tsx @@ -0,0 +1,28 @@ +import { FormControl, FormField, FormItem, FormLabel } from "@/components/ui/form"; +import { Checkbox } from "@/components/ui/checkbox"; + +interface ConfirmacaoCheckBoxProps { + name: string; + label: string; + control: any; +} + +export function ConfirmacaoCheckBox({ name, label, control }: ConfirmacaoCheckBoxProps) { + return ( + ( + + + field.onChange(checked ? "S" : "N")} + /> + + {label} + + )} + /> + ); +} diff --git a/src/shared/components/confirmacao/ConfirmacaoSelect.tsx b/src/shared/components/confirmacao/ConfirmacaoSelect.tsx index 18c0511..363f07a 100644 --- a/src/shared/components/confirmacao/ConfirmacaoSelect.tsx +++ b/src/shared/components/confirmacao/ConfirmacaoSelect.tsx @@ -31,16 +31,16 @@ export default function ConfirmacaoSelect({ field }: any) { variant="outline" role="combobox" aria-expanded={open} - className="justify-between" + className="justify-between cursor-pointer" > {field.value ? options.find((item) => item.value === field.value)?.label : 'Selecione...'} - + - + @@ -48,6 +48,7 @@ export default function ConfirmacaoSelect({ field }: any) { {options.map((item) => ( { @@ -57,7 +58,7 @@ export default function ConfirmacaoSelect({ field }: any) { > diff --git a/src/shared/components/numericInputField/NumericInputField.tsx b/src/shared/components/numericInputField/NumericInputField.tsx new file mode 100644 index 0000000..b136ee4 --- /dev/null +++ b/src/shared/components/numericInputField/NumericInputField.tsx @@ -0,0 +1,68 @@ +"use client"; + +import React from "react"; +import { Control, FieldValues, Path } from "react-hook-form"; +import { + FormField, + FormItem, + FormLabel, + FormControl, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; + +interface NumericInputFieldProps { + control: Control; + name: Path; + label?: string; + placeholder?: string; + disabled?: boolean; + min?: number; + max?: number; +} + +export function NumericInputField({ + control, + name, + label = "Número", + placeholder = "Digite um número", + disabled = false, + min, + max, +}: NumericInputFieldProps) { + return ( + ( + + {label && {label}} + + + { + // Mantém apenas números + let value = e.target.value.replace(/[^0-9]/g, ""); + + // Limita faixa, se definido + if (min !== undefined && Number(value) < min) value = String(min); + if (max !== undefined && Number(value) > max) value = String(max); + + field.onChange(value); + }} + /> + + + + + )} + /> + ); +} diff --git a/src/shared/components/tipoPessoa/tipoPessoaSelect.tsx b/src/shared/components/tipoPessoa/tipoPessoaSelect.tsx new file mode 100644 index 0000000..dabe9fd --- /dev/null +++ b/src/shared/components/tipoPessoa/tipoPessoaSelect.tsx @@ -0,0 +1,66 @@ +"use client"; + +import React from "react"; +import { Control, FieldValues, Path } from "react-hook-form"; +import { + FormField, + FormItem, + FormLabel, + FormControl, + FormMessage, +} from "@/components/ui/form"; +import { + Select, + SelectTrigger, + SelectValue, + SelectContent, + SelectItem, +} from "@/components/ui/select"; + +interface PessoaTipoSelectProps { + control: Control; + name: Path; + label?: string; + disabled?: boolean; + placeholder?: string; +} + +export function TipoPessoaSelect({ + control, + name, + label = "Pessoa", + disabled = false, + placeholder = "Selecione uma opção", +}: PessoaTipoSelectProps) { + return ( + ( + + {label && {label}} + + + + )} + /> + ); +}