diff --git a/src/controllers/locais-coleta-controller.js b/src/controllers/locais-coleta-controller.js index 771a7ef3..0467ed91 100644 --- a/src/controllers/locais-coleta-controller.js +++ b/src/controllers/locais-coleta-controller.js @@ -1,9 +1,10 @@ +import pick from '~/helpers/pick'; import BadRequestExeption from '../errors/bad-request-exception'; import models from '../models'; import codigos from '../resources/codigos-http'; const { - Relevo, Solo, Vegetacao, sequelize, + Relevo, Solo, Vegetacao, LocalColeta, Cidade, FaseSucessional, sequelize, } = models; export const cadastrarSolo = (request, response, next) => { @@ -120,4 +121,47 @@ export const buscarVegetacoes = (request, response, next) => { .catch(next); }; +export const cadastrarLocalColeta = async (request, response, next) => { + try { + const dados = pick(request.body, ['descricao', 'complemento', 'cidade_id', 'fase_sucessional_id']); + const localColeta = await LocalColeta.create(dados); + response.status(201).json(localColeta); + } catch (error) { + next(error); + } +}; + +export const buscarLocaisColeta = async (request, response, next) => { + try { + const { cidadeId } = request.query; + const { limite, pagina, offset } = request.paginacao; + + const where = {}; + if (cidadeId) { + where.cidade_id = cidadeId; + } + + const { count, rows } = await LocalColeta.findAndCountAll({ + where, + include: [ + { model: Cidade }, + { model: FaseSucessional }, + ], + limit: limite, + offset, + }); + + response.status(200).json({ + metadados: { + total: count, + pagina, + limite, + }, + resultado: rows, + }); + } catch (error) { + next(error); + } +}; + export default {}; diff --git a/src/controllers/tombos-controller.js b/src/controllers/tombos-controller.js index b1e50352..5b05f1e9 100644 --- a/src/controllers/tombos-controller.js +++ b/src/controllers/tombos-controller.js @@ -104,22 +104,21 @@ export const cadastro = (request, response, next) => { return undefined; }) .then(() => { - let json = {}; - // /////////CRIA LOCAL DE COLETA//////////// - if (paisagem) { - json = pick(paisagem, ['descricao', 'solo_id', 'relevo_id', 'vegetacao_id', 'fase_sucessional_id']); - } - if (localidade.complemento) { - json.complemento = localidade.complemento; + if(!localidade?.complemento){ + throw new BadRequestExeption(400); } - json.cidade_id = localidade.cidade_id; - return LocalColeta.create(json, { transaction }); + return LocalColeta.findOne({ + where: { + id: localidade.complemento, + }, + transaction, + }); }) .then(localColeta => { if (!localColeta) { - throw new BadRequestExeption(400); + throw new BadRequestExeption(533); } - principal.local_coleta_id = localColeta.id; + return undefined; }) // //////////////CRIA COLECOES ANEXAS/////////// .then(() => { @@ -271,11 +270,15 @@ export const cadastro = (request, response, next) => { data_coleta_mes: principal.data_coleta.mes, data_coleta_ano: principal.data_coleta.ano, numero_coleta: principal.numero_coleta, - local_coleta_id: principal.local_coleta_id, + local_coleta_id: localidade.complemento, cor: principal.cor, coletor_id: coletor, }; + if(paisagem.descricao) { + jsonTombo.descricao = paisagem.descricao; + } + if (observacoes) { jsonTombo.observacao = observacoes; } @@ -1022,8 +1025,6 @@ export const obterTombo = async (request, response, next) => { let resposta = {}; let dadosTombo = {}; - // eslint-disable-next-line - // console.error(id); Promise.resolve() .then(() => Tombo.findOne({ @@ -1052,6 +1053,7 @@ export const obterTombo = async (request, response, next) => { 'data_identificacao_dia', 'data_identificacao_mes', 'data_identificacao_ano', + 'descricao', ], include: [ { @@ -1187,22 +1189,12 @@ export const obterTombo = async (request, response, next) => { vegetacaoInicial: tombo.vegetaco !== null ? tombo.vegetaco?.nome : '', faseInicial: tombo.locais_coletum !== null && tombo.locais_coletum?.fase_sucessional !== null ? tombo.locais_coletum?.fase_sucessional?.numero : '', - // coletoresInicial: tombo.coletores.map((coletor) => ({ - // key: `${coletor.id}`, - // label: coletor.nome, - // })), coletor: tombo.coletore ? { id: tombo.coletore?.id, nome: tombo.coletore?.nome, } : null, - // coletorComplementar: tombo.coletorComplementar - // ? { - // hcf: tombo.coletorComplementar.hcf, - // complementares: tombo.coletorComplementar.complementares, - // } - // : '', colecaoInicial: tombo.colecoes_anexa !== null ? tombo.colecoes_anexa?.tipo : '', complementoInicial: tombo.localizacao !== null && tombo.localizacao !== undefined ? tombo.localizacao?.complemento : '', hcf: tombo.hcf, @@ -1211,6 +1203,7 @@ export const obterTombo = async (request, response, next) => { observacao: tombo.observacao !== null ? tombo.observacao : '', tipo: tombo.tipo !== null ? tombo.tipo?.nome : '', numero_coleta: tombo.numero_coleta, + descricao: tombo.descricao !== null ? tombo.descricao : '', herbario: tombo.herbario !== null ? `${tombo.herbario?.sigla} - ${tombo.herbario?.nome}` : '', localizacao: { latitude: tombo.latitude !== null ? tombo.latitude : '', @@ -1231,6 +1224,7 @@ export const obterTombo = async (request, response, next) => { complemento: tombo.locais_coletum?.complemento !== null ? tombo.locais_coletum?.complemento : '', }, local_coleta: { + id: tombo.locais_coletum !== null ? tombo.locais_coletum?.id : '', descricao: tombo.locais_coletum !== null && tombo.locais_coletum?.descricao !== null ? tombo.locais_coletum.descricao : '', solo: tombo.solo !== null ? tombo.solo?.nome : '', relevo: tombo.relevo !== null ? tombo.relevo?.nome : '', diff --git a/src/models/Tombo.js b/src/models/Tombo.js index 44ac13ad..0759eadb 100644 --- a/src/models/Tombo.js +++ b/src/models/Tombo.js @@ -261,6 +261,10 @@ export default (Sequelize, DataTypes) => { type: DataTypes.INTEGER, allowNull: true, }, + descricao: { + type: DataTypes.TEXT, + allowNull: true, + }, }; const options = { diff --git a/src/resources/errors/500-taxonomias.js b/src/resources/errors/500-taxonomias.js index 21df4ab2..9c5705bb 100644 --- a/src/resources/errors/500-taxonomias.js +++ b/src/resources/errors/500-taxonomias.js @@ -31,4 +31,5 @@ export default { 530: 'Vegetação não encontrada.', 531: 'Fase sucessional não encontrada.', 532: 'Autor não encontrado.', + 533: 'Local de coleta não encontrado.', }; diff --git a/src/routes/locais.js b/src/routes/locais.js index 0e5fa934..b095a036 100644 --- a/src/routes/locais.js +++ b/src/routes/locais.js @@ -1,5 +1,8 @@ +import listagensMiddleware from '../middlewares/listagens-middleware'; import tokensMiddleware, { TIPOS_USUARIOS } from '../middlewares/tokens-middleware'; import validacoesMiddleware from '../middlewares/validacoes-middleware'; +import localColetaCadastroEsquema from '../validators/localColeta-cadastro'; +import localColetaListagemEsquema from '../validators/localColeta-listagem'; import nomeEsquema from '../validators/nome-obrigatorio'; const controller = require('../controllers/locais-coleta-controller'); @@ -233,4 +236,104 @@ export default app => { .get([ controller.buscarVegetacoes, ]); + + /** + * @swagger + * /locais-coleta: + * post: + * summary: Cadastra um novo local de coleta + * tags: [Locais] + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * descricao: + * type: string + * complemento: + * type: string + * cidade_id: + * type: integer + * fase_sucessional_id: + * type: integer + * required: + * - descricao + * - cidade_id + * example: + * descricao: "Próximo ao rio" + * complemento: "Entrada pela fazenda" + * cidade_id: 1 + * fase_sucessional_id: 2 + * responses: + * 201: + * description: Local de coleta cadastrado com sucesso + * '400': + * $ref: '#/components/responses/BadRequest' + * '401': + * $ref: '#/components/responses/Unauthorized' + * '403': + * $ref: '#/components/responses/Forbidden' + */ + app.route('/locais-coleta') + .post([ + tokensMiddleware([ + TIPOS_USUARIOS.CURADOR, + TIPOS_USUARIOS.OPERADOR, + ]), + validacoesMiddleware(localColetaCadastroEsquema), + controller.cadastrarLocalColeta, + ]) + /** + * @swagger + * /locais-coleta: + * get: + * summary: Lista os locais de coleta + * tags: [Locais] + * parameters: + * - in: query + * name: cidadeId + * schema: + * type: integer + * description: Filtrar por ID da cidade + * - in: query + * name: pagina + * schema: + * type: integer + * description: Número da página + * - in: query + * name: limite + * schema: + * type: integer + * description: Quantidade de resultados por página + * responses: + * 200: + * description: Lista de locais de coleta + * content: + * application/json: + * schema: + * type: object + * properties: + * metadados: + * type: object + * locaisColeta: + * type: array + * items: + * type: object + * '401': + * $ref: '#/components/responses/Unauthorized' + * '403': + * $ref: '#/components/responses/Forbidden' + */ + .get([ + tokensMiddleware([ + TIPOS_USUARIOS.CURADOR, + TIPOS_USUARIOS.OPERADOR, + TIPOS_USUARIOS.IDENTIFICADOR, + ]), + listagensMiddleware, + validacoesMiddleware(localColetaListagemEsquema), + controller.buscarLocaisColeta, + ]); }; diff --git a/src/validators/localColeta-cadastro.js b/src/validators/localColeta-cadastro.js new file mode 100644 index 00000000..6f1c8530 --- /dev/null +++ b/src/validators/localColeta-cadastro.js @@ -0,0 +1,25 @@ +export default { + descricao: { + in: ['body'], + isString: true, + notEmpty: true, + errorMessage: 'Descrição é obrigatória.', + }, + complemento: { + in: ['body'], + isString: true, + optional: true, + }, + cidade_id: { + in: ['body'], + isInt: true, + notEmpty: true, + errorMessage: 'ID da cidade é obrigatório e deve ser um número inteiro.', + }, + fase_sucessional_id: { + in: ['body'], + isInt: true, + optional: true, + errorMessage: 'ID da fase sucessional deve ser um número inteiro.', + }, +}; diff --git a/src/validators/localColeta-listagem.js b/src/validators/localColeta-listagem.js new file mode 100644 index 00000000..9a19683e --- /dev/null +++ b/src/validators/localColeta-listagem.js @@ -0,0 +1,8 @@ +export default { + cidade_id: { + in: ['query'], + isInt: true, + optional: true, + errorMessage: 'ID da cidade deve ser um número inteiro.', + }, +}; diff --git a/src/validators/tombo-cadastro.js b/src/validators/tombo-cadastro.js index 487362b4..7b5e619e 100644 --- a/src/validators/tombo-cadastro.js +++ b/src/validators/tombo-cadastro.js @@ -108,11 +108,8 @@ export default { }, 'json.localidade.complemento': { in: 'body', - isString: true, - optional: true, - isLength: { - options: [{ min: 3 }], - }, + isInt: true, + isEmpty: false, }, 'json.paisagem.solo_id': { in: 'body',