Skip to content
Merged
117 changes: 114 additions & 3 deletions src/controllers/locais-coleta-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import models from '../models';
import codigos from '../resources/codigos-http';

const {
Relevo, Solo, Vegetacao, LocalColeta, Cidade, FaseSucessional, sequelize,
Relevo, Solo, Vegetacao, LocalColeta, Cidade, FaseSucessional, Estado, Pais, sequelize,
} = models;

export const cadastrarSolo = (request, response, next) => {
Expand Down Expand Up @@ -133,7 +133,7 @@ export const cadastrarLocalColeta = async (request, response, next) => {

export const buscarLocaisColeta = async (request, response, next) => {
try {
const { cidadeId } = request.query;
const { cidade_id: cidadeId } = request.query;
const { limite, pagina, offset } = request.paginacao;

const where = {};
Expand All @@ -144,7 +144,15 @@ export const buscarLocaisColeta = async (request, response, next) => {
const { count, rows } = await LocalColeta.findAndCountAll({
where,
include: [
{ model: Cidade },
{ model: Cidade,
include: [
{ model: Estado,
include: [
Pais,
],
},
],
},
{ model: FaseSucessional },
],
limit: limite,
Expand All @@ -164,4 +172,107 @@ export const buscarLocaisColeta = async (request, response, next) => {
}
};

export const buscarLocalColetaPorId = async (request, response, next) => {
try {
const { id } = request.params;

const localColeta = await LocalColeta.findOne({
where: { id },
include: [
{ model: Cidade,
include: [
{ model: Estado,
include: [
Pais,
],
},
],
},
{ model: FaseSucessional },
],
});

if (!localColeta) {
response.status(404).json({
mensagem: 'Local de coleta não encontrado.',
});
return;
}

response.status(200).json(localColeta);
} catch (error) {
next(error);
}
};

export const atualizarLocalColeta = async (request, response, next) => {
try {
const { id } = request.params;
const dados = pick(request.body, ['descricao', 'complemento', 'cidade_id', 'fase_sucessional_id']);

const [updated] = await LocalColeta.update(dados, {
where: { id },
});

if (updated === 0) {
response.status(404).json({
mensagem: 'Local de coleta não encontrado.',
});
return;
}

const localColetaAtualizado = await LocalColeta.findOne({
where: { id },
include: [
{ model: Cidade },
{ model: FaseSucessional },
],
});

response.status(200).json(localColetaAtualizado);
} catch (error) {
next(error);
}
};

export const deletarLocalColeta = async (request, response, next) => {
try {
const { id } = request.params;

const localColeta = await LocalColeta.findOne({
where: { id },
});

if (!localColeta) {
response.status(404).json({
mensagem: 'Local de coleta não encontrado.',
});
return;
}

const { Tombo } = models;
const tombosAssociados = await Tombo.count({
where: {
local_coleta_id: id,
ativo: true,
},
});

if (tombosAssociados > 0) {
response.status(400).json({
mensagem: `Não é possível excluir o local de coleta. Existem ${tombosAssociados} tombo(s) associado(s) a este local.`,
});
return;
}

await LocalColeta.destroy({
where: { id },
});

response.status(204).send();

} catch (error) {
next(error);
}
};
export default {};
4 changes: 2 additions & 2 deletions src/controllers/tombos-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export const cadastro = (request, response, next) => {
return undefined;
})
.then(() => {
if(!localidade?.complemento){
if (!localidade?.complemento) {
throw new BadRequestExeption(400);
}
return LocalColeta.findOne({
Expand Down Expand Up @@ -275,7 +275,7 @@ export const cadastro = (request, response, next) => {
coletor_id: coletor,
};

if(paisagem.descricao) {
if (paisagem.descricao) {
jsonTombo.descricao = paisagem.descricao;
}

Expand Down
185 changes: 185 additions & 0 deletions src/routes/locais.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,4 +336,189 @@ export default app => {
validacoesMiddleware(localColetaListagemEsquema),
controller.buscarLocaisColeta,
]);
/**
* @swagger
* /locais-coleta/{id}:
* get:
* summary: Busca um local de coleta pelo ID
* tags: [Locais]
* description: Retorna os dados de um local de coleta específico.
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: ID do local de coleta
* responses:
* 200:
* description: Dados do local de coleta encontrados
* content:
* application/json:
* schema:
* type: object
* properties:
* id:
* type: integer
* descricao:
* type: string
* complemento:
* type: string
* nullable: true
* cidade_id:
* type: integer
* fase_sucessional_id:
* type: integer
* nullable: true
* cidade:
* type: object
* properties:
* id:
* type: integer
* nome:
* type: string
* fase_sucessional:
* type: object
* nullable: true
* properties:
* id:
* type: integer
* nome:
* type: string
* '401':
* $ref: '#/components/responses/Unauthorized'
* '403':
* $ref: '#/components/responses/Forbidden'
* '404':
* $ref: '#/components/responses/NotFound'
* '500':
* $ref: '#/components/responses/InternalServerError'
* put:
* summary: Atualiza um local de coleta
* tags: [Locais]
* description: Atualiza os dados de um local de coleta existente.
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: ID do local de coleta
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* descricao:
* type: string
* description: Descrição do local de coleta
* complemento:
* type: string
* description: Complemento do local de coleta
* cidade_id:
* type: integer
* description: ID da cidade
* fase_sucessional_id:
* type: integer
* description: ID da fase sucessional
* required:
* - descricao
* - cidade_id
* example:
* descricao: "Próximo ao córrego"
* complemento: "Entrada pelo portão principal"
* cidade_id: 2
* fase_sucessional_id: 3
* responses:
* 200:
* description: Local de coleta atualizado com sucesso
* content:
* application/json:
* schema:
* type: object
* properties:
* id:
* type: integer
* descricao:
* type: string
* complemento:
* type: string
* cidade_id:
* type: integer
* fase_sucessional_id:
* type: integer
* '400':
* $ref: '#/components/responses/BadRequest'
* '401':
* $ref: '#/components/responses/Unauthorized'
* '403':
* $ref: '#/components/responses/Forbidden'
* '404':
* $ref: '#/components/responses/NotFound'
* '500':
* $ref: '#/components/responses/InternalServerError'
*/
app.route('/locais-coleta/:id')
.get([
tokensMiddleware([
TIPOS_USUARIOS.CURADOR,
TIPOS_USUARIOS.OPERADOR,
TIPOS_USUARIOS.IDENTIFICADOR,
]),
controller.buscarLocalColetaPorId,
])
.put([
tokensMiddleware([
TIPOS_USUARIOS.CURADOR,
TIPOS_USUARIOS.OPERADOR,
]),
validacoesMiddleware(localColetaCadastroEsquema),
controller.atualizarLocalColeta,
])
/**
* @swagger
* /locais-coleta/{id}:
* delete:
* summary: Remove um local de coleta
* tags: [Locais]
* description: Remove um local de coleta pelo ID. Verifica se não há tombos associados antes de remover.
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: ID do local de coleta
* responses:
* 204:
* description: Local de coleta removido com sucesso
* '400':
* description: Não é possível excluir - existem tombos associados
* content:
* application/json:
* schema:
* type: object
* properties:
* mensagem:
* type: string
* example:
* mensagem: "Não é possível excluir o local de coleta. Existem 5 tombo(s) associado(s) a este local."
* '401':
* $ref: '#/components/responses/Unauthorized'
* '403':
* $ref: '#/components/responses/Forbidden'
* '404':
* $ref: '#/components/responses/NotFound'
* '500':
* $ref: '#/components/responses/InternalServerError'
*/
.delete([
tokensMiddleware([
TIPOS_USUARIOS.CURADOR,
TIPOS_USUARIOS.OPERADOR,
]),
controller.deletarLocalColeta,
]);
};
Loading