diff --git a/src/controllers/fichas-tombos-controller.js b/src/controllers/fichas-tombos-controller.js index 9a08b35..1e91d98 100644 --- a/src/controllers/fichas-tombos-controller.js +++ b/src/controllers/fichas-tombos-controller.js @@ -42,22 +42,34 @@ function formataDataSaida(data) { } function formataDataIdentificacao(dia, mes, ano, arrayRomanos) { - // Se não tiver ano, não mostra nada if (!ano) { return ''; } - // Se tiver mês e ano mas não tiver dia, mostra mês/ano if (!dia && mes && ano) { return `${arrayRomanos[mes - 1]}/${ano}`; } - // Se não tiver mês mas tiver ano, mostra só o ano if (!mes && ano) { return `${ano}`; } - // Se tiver dia, mês e ano, mostra tudo + return `${dia}/${arrayRomanos[mes - 1]}/${ano}`; +} + +function formataDataColeta(dia, mes, ano, arrayRomanos) { + if (!ano) { + return ''; + } + + if (!dia && mes && ano) { + return `${arrayRomanos[mes - 1]}/${ano}`; + } + + if (!mes && ano) { + return `${ano}`; + } + return `${dia}/${arrayRomanos[mes - 1]}/${ano}`; } @@ -254,7 +266,12 @@ export default function fichaTomboController(request, response, next) { romanos, ); - const romanoDataColeta = (`${tombo.data_coleta_dia}/${romanos[tombo.data_coleta_mes - 1]}/${tombo.data_coleta_ano}`); + const romanoDataColeta = formataDataColeta( + tombo?.data_coleta_dia, + tombo?.data_coleta_mes, + tombo?.data_coleta_ano, + romanos, + ); const parametros = { // Se não tem fotos, cria um array de 1 posição com um objeto vazio diff --git a/src/controllers/tombos-controller.js b/src/controllers/tombos-controller.js index 552831c..601a3d1 100644 --- a/src/controllers/tombos-controller.js +++ b/src/controllers/tombos-controller.js @@ -1294,15 +1294,17 @@ export const obterTombo = async (request, response, next) => { const [tomboIdentificador] = tombo.identificadores; if (tombo.data_identificacao_dia !== null) { - dataIdent = `${tombo.data_identificacao_dia}/`; + dataIdent = tombo.data_identificacao_dia; resposta.data_identificacao_dia = tombo.data_identificacao_dia; } if (tombo.data_identificacao_mes !== null) { - dataIdent += `${converteInteiroParaRomano(tombo.data_identificacao_mes)}/`; + if (dataIdent) dataIdent += '/'; + dataIdent += converteInteiroParaRomano(tombo.data_identificacao_mes); resposta.data_identificacao_mes = tombo.data_identificacao_mes; } if (tombo.data_identificacao_ano !== null) { - dataIdent += `${tombo.data_identificacao_ano}`; + if (dataIdent) dataIdent += '/'; + dataIdent += tombo.data_identificacao_ano; resposta.data_identificacao_ano = tombo.data_identificacao_ano; } @@ -1318,11 +1320,13 @@ export const obterTombo = async (request, response, next) => { resposta.data_coleta_dia = tombo.data_coleta_dia; } if (tombo.data_coleta_mes !== null) { - dataCol += `/${converteInteiroParaRomano(tombo.data_coleta_mes)}`; + if (dataCol) dataCol += '/'; + dataCol += converteInteiroParaRomano(tombo.data_coleta_mes); resposta.data_coleta_mes = tombo.data_coleta_mes; } if (tombo.data_coleta_ano !== null) { - dataCol += `/${tombo.data_coleta_ano}`; + if (dataCol) dataCol += '/'; + dataCol += tombo.data_coleta_ano; resposta.data_coleta_ano = tombo.data_coleta_ano; } diff --git a/src/helpers/formata-dados-relatorio.js b/src/helpers/formata-dados-relatorio.js index da688bf..ed9e7e8 100644 --- a/src/helpers/formata-dados-relatorio.js +++ b/src/helpers/formata-dados-relatorio.js @@ -57,15 +57,29 @@ const defineNomeCientifico = dado => { export const formatarDadosParaRelatorioDeColetaPorLocalEIntervaloDeData = dados => { const romanos = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII']; - const dadosFormatados = dados.map(dado => ({ - local: dado.locais_coletum?.descricao, - data: `${String(dado.data_coleta_dia).padStart(2, '0')}/${romanos[dado.data_coleta_mes - 1]}/${dado.data_coleta_ano}`, - tombo: dado?.hcf, - numeroColeta: dado.numero_coleta || '-', - especie: defineNomeCientifico(dado), - familia: dado?.familia?.nome || 'Não Informada', - autor: dado.especy?.autor?.nome || 'Não Informado', - })); + const dadosFormatados = dados.map(dado => { + let data = ''; + if (dado.data_coleta_dia !== null) { + data = String(dado.data_coleta_dia).padStart(2, '0'); + } + if (dado.data_coleta_mes !== null) { + if (data) data += '/'; + data += romanos[dado.data_coleta_mes - 1]; + } + if (dado.data_coleta_ano !== null) { + if (data) data += '/'; + data += dado.data_coleta_ano; + } + return { + local: dado.locais_coletum?.descricao, + data, + tombo: dado?.hcf, + numeroColeta: dado.numero_coleta || '-', + especie: defineNomeCientifico(dado), + familia: dado?.familia?.nome || 'Não Informada', + autor: dado.especy?.autor?.nome || 'Não Informado', + }; + }); dadosFormatados.sort((a, b) => a.familia.localeCompare(b.familia)); @@ -76,8 +90,20 @@ export const formatarDadosParaRelatorioDeColetaPorColetorEIntervaloDeData = dado const romanos = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII']; const dadosFormatados = dados.map(dado => { if (dado?.numero_coleta && dado?.numero_coleta !== null) { + let data = ''; + if (dado.data_coleta_dia !== null) { + data = String(dado.data_coleta_dia).padStart(2, '0'); + } + if (dado.data_coleta_mes !== null) { + if (data) data += '/'; + data += romanos[dado.data_coleta_mes - 1]; + } + if (dado.data_coleta_ano !== null) { + if (data) data += '/'; + data += dado.data_coleta_ano; + } return { - data: `${String(dado.data_coleta_dia).padStart(2, '0')}/${romanos[dado.data_coleta_mes - 1]}/${dado.data_coleta_ano}`, + data, tombo: dado?.hcf, numeroColeta: dado.numero_coleta || '-', especie: defineNomeCientifico(dado), diff --git a/src/helpers/tombo.js b/src/helpers/tombo.js index 7339d23..a04d66b 100644 --- a/src/helpers/tombo.js +++ b/src/helpers/tombo.js @@ -59,13 +59,13 @@ export function converteRequisicaoParaTombo(requisicao) { longitude: converteParaDecimal(localidade.longitude), altitude: localidade.altitude, - data_coleta_dia: dataColeta.dia, - data_coleta_mes: dataColeta.mes, - data_coleta_ano: dataColeta.ano, + data_coleta_dia: dataColeta?.dia, + data_coleta_mes: dataColeta?.mes, + data_coleta_ano: dataColeta?.ano, - data_identificacao_dia: dataIdentificacao.dia, - data_identificacao_mes: dataIdentificacao.mes, - data_identificacao_ano: dataIdentificacao.ano, + data_identificacao_dia: dataIdentificacao?.dia, + data_identificacao_mes: dataIdentificacao?.mes, + data_identificacao_ano: dataIdentificacao?.ano, tipo: { id: principal.tipo_id, diff --git a/src/reports/templates/LocaisColeta.tsx b/src/reports/templates/LocaisColeta.tsx index dcf0421..7ed88c5 100644 --- a/src/reports/templates/LocaisColeta.tsx +++ b/src/reports/templates/LocaisColeta.tsx @@ -60,7 +60,19 @@ function RelacaoLocaisColeta({ dados, total, textoFiltro, showCoord = false }: R 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII' ]; - return `${data_coleta_dia}/${romanoMeses[data_coleta_mes - 1]}/${data_coleta_ano}`; + let data = ''; + if (data_coleta_dia !== null && data_coleta_dia !== undefined) { + data = String(data_coleta_dia).padStart(2, '0'); + } + if (data_coleta_mes !== null && data_coleta_mes !== undefined) { + if (data) data += '/'; + data += romanoMeses[data_coleta_mes - 1]; + } + if (data_coleta_ano !== null && data_coleta_ano !== undefined) { + if (data) data += '/'; + data += data_coleta_ano; + } + return data; } const converteDecimalParaDMS = (decimal: number | null, isLatitude = true) => { diff --git a/src/routes/tombos.js b/src/routes/tombos.js index 114938d..ca3de4c 100644 --- a/src/routes/tombos.js +++ b/src/routes/tombos.js @@ -393,7 +393,6 @@ export default app => { * required: * - numero * - coletor - * - data_coleta * - local * example: * numero: "12345" diff --git a/src/validators/tombo-alteracao.js b/src/validators/tombo-alteracao.js index d8906b8..bfe084e 100644 --- a/src/validators/tombo-alteracao.js +++ b/src/validators/tombo-alteracao.js @@ -42,6 +42,9 @@ export default { }, 'json.principal.data_coleta': { in: 'body', + optional: { + options: { nullable: true }, + }, custom: { options: validaData, }, diff --git a/src/validators/tombo-cadastro.js b/src/validators/tombo-cadastro.js index c19d986..9e63d22 100644 --- a/src/validators/tombo-cadastro.js +++ b/src/validators/tombo-cadastro.js @@ -31,26 +31,65 @@ export default { options: validaDataTombo, }, }, - 'json.principal.data_coleta.dia': { + 'json.principal.data_coleta': { in: 'body', optional: { options: { nullable: true }, }, - isInt: true, + custom: { + options: validaData, + }, + }, + 'json.principal.data_coleta.dia': { + in: 'body', + optional: { + options: { nullable: true, checkFalsy: false }, + }, + custom: { + options: value => { + if (value === null || value === undefined) { + return true; + } + if (Number.isInteger(value)) { + return true; + } + throw new Error('dia must be an integer'); + }, + }, }, 'json.principal.data_coleta.mes': { in: 'body', optional: { - options: { nullable: true }, + options: { nullable: true, checkFalsy: false }, + }, + custom: { + options: value => { + if (value === null || value === undefined) { + return true; + } + if (Number.isInteger(value)) { + return true; + } + throw new Error('mes must be an integer'); + }, }, - isInt: true, }, 'json.principal.data_coleta.ano': { in: 'body', optional: { - options: { nullable: true }, + options: { nullable: true, checkFalsy: false }, + }, + custom: { + options: value => { + if (value === null || value === undefined) { + return true; + } + if (Number.isInteger(value)) { + return true; + } + throw new Error('ano must be an integer'); + }, }, - isInt: true, }, 'json.principal.tipo_id': { in: 'body', diff --git a/src/validators/tombo-data.js b/src/validators/tombo-data.js index 2d90b1f..b5781a4 100644 --- a/src/validators/tombo-data.js +++ b/src/validators/tombo-data.js @@ -1,8 +1,25 @@ -export default ({ dia, mes, ano }) => { +export default value => { + if (!value) { + return true; + } - if (dia || mes || ano) { + const { dia, mes, ano } = value; + + // Tudo vazio é válido + if (!dia && !mes && !ano) { return true; } - return false; + // Se tiver dia, PRECISA ter mês e ano + if (dia && (!mes || !ano)) { + return false; + } + + // Se tiver mês, PRECISA ter ano + if (mes && !ano) { + return false; + } + + // Resto é válido: só ano, mês+ano, dia+mês+ano + return true; };