Skip to content

Commit

Permalink
Send boletim and set empresa as partner routes
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel-Alvarenga committed Aug 3, 2024
1 parent 3f4043e commit 0e38353
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 123 deletions.
6 changes: 3 additions & 3 deletions ToDo.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
- [ ] conversa professor
- [ ] conversa empresa
- [ ] exportar currículo
- [ ] colocar o boletim
- [x] colocar o boletim

## Funcionário
- [ ] classificar empresa como parceira
- [ ] Ver empresas
- [x] classificar empresa como parceira
- [ ] Validar boletim

## Professor
- [ ] Mandar mensagem aluno
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-- CreateTable
CREATE TABLE `boletins` (
`id` VARCHAR(191) NOT NULL,
`alunoId` VARCHAR(191) NOT NULL,
`link` VARCHAR(191) NOT NULL,
`caminho` VARCHAR(191) NOT NULL,
`status` ENUM('EM_ANALISE', 'RECUSADO', 'APROVADO') NOT NULL DEFAULT 'EM_ANALISE',

PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- AddForeignKey
ALTER TABLE `boletins` ADD CONSTRAINT `boletins_alunoId_fkey` FOREIGN KEY (`alunoId`) REFERENCES `alunos`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
38 changes: 28 additions & 10 deletions server/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ model Aluno {
tentativasRestantes Int @default(5)
validated Boolean @default(false)
turmas AlunoTurma[]
boletins Boletim[]
atividades AlunoAtividade[]
cursosExtracurriculares Extracurricular[]
vinculosAluno Vinculo[] @relation("AlunoVinculo")
Expand Down Expand Up @@ -134,12 +135,29 @@ model AlunoTurma {
@@map("alunos_turmas")
}

model Boletim {
id String @id @default(uuid())
alunoId String @default(uuid())
link String
caminho String
status SituacaoBoletim @default(EM_ANALISE)
aluno Aluno @relation(fields: [alunoId], references: [id])
@@map("boletins")
}

enum SituacaoBoletim {
EM_ANALISE
RECUSADO
APROVADO
}

model AlunoAtividade {
alunoId String @default(uuid())
atividadeId String @default(uuid())
mencao Mencao
aluno Aluno @relation(fields: [alunoId], references: [id])
atividade Atividade @relation(fields: [atividadeId], references: [id])
alunoId String @default(uuid())
atividadeId String @default(uuid())
mencao Mencao
aluno Aluno @relation(fields: [alunoId], references: [id])
atividade Atividade @relation(fields: [atividadeId], references: [id])
@@id([alunoId, atividadeId])
@@map("alunos_atividades")
Expand Down Expand Up @@ -250,15 +268,15 @@ enum Cargo {
}

model Atividade {
id String @id @default(uuid())
id String @id @default(uuid())
title String
descricao String @db.VarChar(1000)
descricao String @db.VarChar(1000)
professorId String
imagem String?
alunos AlunoAtividade[]
professor Professor @relation(fields: [professorId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
professor Professor @relation(fields: [professorId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("atividades")
}
Expand Down
14 changes: 14 additions & 0 deletions server/src/modules/controllers/funcionarioControllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { RecoveryFuncionarioUseCase } from "../services/funcionario/RecoveryUseC
import { ValidateRecoveryUseCase } from "../services/funcionario/ValidateRecoveryUseCase";
import { RefreshTokenUseCase } from "../services/funcionario/RefreshTokenUseCase";
import { RegisterVagaUseCase } from "../services/funcionario/RegisterVagasUseCase";
import { SetEmpresaParceiraUseCase } from "../services/funcionario/SetAsParceiraUseCase";
import { SetEmpresaParceiraDTO } from "../interfaces/funcionarioDTOs";

export class InitFuncionarioController {
async handle(req: Request, res: Response) {
Expand Down Expand Up @@ -116,4 +118,16 @@ export class RegisterVagaController {

return res.status(201).json(result);
}
}

export class FuncionarioController {
async handle(req: Request, res: Response) {
const funcionarioId = req.body.funcionario.id;
const { emailEmpresa }: SetEmpresaParceiraDTO = req.body;

const setEmpresaParceiraUseCase = new SetEmpresaParceiraUseCase();

const result = await setEmpresaParceiraUseCase.execute({ funcionarioId, emailEmpresa });
return res.status(200).json(result);
}
}
5 changes: 5 additions & 0 deletions server/src/modules/interfaces/funcionarioDTOs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,9 @@ export interface RegisterVagaDTO {
status: string;
curso: string;
descricao: string;
}

export interface SetEmpresaParceiraDTO {
funcionarioId: string;
emailEmpresa: string;
}
163 changes: 56 additions & 107 deletions server/src/modules/services/aluno/SendBoletimUseCase.ts
Original file line number Diff line number Diff line change
@@ -1,119 +1,68 @@
// import puppeteerNormal from 'puppeteer';
// import puppeteer from 'puppeteer-extra';
// import RecaptchaPlugin from 'puppeteer-extra-plugin-recaptcha';
// import fs from 'fs';
// import path from 'path';
// import pdf from 'pdf-parse';
import axios from 'axios';
// import { getExecutablePath } from 'puppeteerNormal';

import fs from 'fs';
import path from 'path';
import pdf from 'pdf-parse';
import { prisma } from "../../../prisma/client";
import { SendNotasDTO } from "../../interfaces/alunoDTOs";
import { AppError } from "../../../errors/error";
import { clearUploads } from '../shared/helpers/helpers';

// Configure o plugin Recaptcha
// puppeteer.use(
// RecaptchaPlugin({
// provider: {
// id: '2captcha',
// token: process.env.CAPTCHA2_ID || '', // Certifique-se de que o token está definido
// },
// })
// );
import { uploadToMinio } from "../../../minioService";

export class SendBoletimUseCase {
async execute({ alunoId, boletim }: SendNotasDTO) {
if (!alunoId) {
throw new AppError('ID do aluno não fornecido.');
async execute({ alunoId, boletim }: SendNotasDTO) {
if (!alunoId) {
throw new AppError('ID do aluno não fornecido.');
}

if (!boletim || !boletim.path) {
throw new AppError('Arquivo do boletim não fornecido.');
}

const aluno = await prisma.aluno.findUnique({
where: {
id: alunoId,
},
});

if (!aluno) {
throw new AppError('Aluno não encontrado.');
}

const boletimPath = path.resolve(boletim.path);
const boletimBuffer = fs.readFileSync(boletimPath);

const link = await this.extractAuthUrlFromPdf(boletimBuffer);

const bucketName = 'boot';
const objectName = `aluno/${aluno.rm}/boletins/${path.basename(boletim.path)}`;

try {
await uploadToMinio(bucketName, objectName, boletimPath);

await prisma.boletim.create({
data: {
alunoId: aluno.id,
link: link,
caminho: objectName,
}
});

await clearUploads();

return { message: 'Boletim enviado e salvo com sucesso!' };
} catch (error) {
throw new AppError(`Erro ao salvar o boletim: ${error}`);
}
}

if (!boletim || !boletim.path) {
throw new AppError('Arquivo do boletim não fornecido.');
}
async extractAuthUrlFromPdf(buffer: Buffer): Promise<string> {
const data = await pdf(buffer);
const text = data.text;

const aluno = await prisma.aluno.findUnique({
where: {
id: alunoId,
},
});
const urlMatch = text.match(/https:\/\/nsa\.cps\.sp\.gov\.br\?a=[a-z0-9-]+/i);
if (!urlMatch) {
throw new AppError('URL de autenticação não encontrado no boletim.');
}

if (!aluno) {
throw new AppError('Aluno não encontrado.');
return urlMatch[0];
}

// const boletimPath = path.resolve(boletim.path);

// const boletimBuffer = fs.readFileSync(boletimPath);

// const authUrl = await this.extractAuthUrlFromPdf(boletimBuffer);

// const browser = await puppeteer.launch({
// headless: false,
// });


// const page = await browser.newPage();

// await page.goto(authUrl);

// setTimeout(async () => {
// const { solved, error } = await page.solveRecaptchas();
// console.log("Here2");

// if (!solved) {
// throw new AppError('Falha ao resolver CAPTCHA: ' + error);
// } else {
// console.log('Captcha resolvido com sucesso, url: ' + authUrl);
// }

// await page.waitForSelector('#btnValidar');
// await page.click('#btnValidar');
// }, 10000);

// const downloadUrl = await page.evaluate(() => {
// const linkElement = document.querySelector('a#downloadLink') as HTMLAnchorElement | null;
// return linkElement ? linkElement.href : '';
// });


// const response = await axios.get(downloadUrl, { responseType: 'arraybuffer' });
// const downloadedFilePath = path.join(__dirname, 'downloads', 'downloaded_boletim.pdf');
// fs.writeFileSync(downloadedFilePath, response.data);

// // Comparar os dois arquivos PDF
// const downloadedBoletimBuffer = fs.readFileSync(downloadedFilePath);

// if (!boletimBuffer.equals(downloadedBoletimBuffer)) {
// throw new AppError("Os arquivos enviados não coincidem.");
// }

// Extrair notas do boletim
// const notas = this.extractNotasFromBoletim(boletimBuffer);

// Fechar o navegador
// await browser.close();

await clearUploads();

}

// async extractAuthUrlFromPdf(buffer: Buffer): Promise<string> {
// const data = await pdf(buffer);
// const text = data.text;

// const urlMatch = text.match(/https:\/\/nsa\.cps\.sp\.gov\.br\?a=[a-z0-9-]+/i);
// if (!urlMatch) {
// throw new AppError('URL de autenticação não encontrado no boletim.');
// }

// return urlMatch[0];
// }

extractNotasFromBoletim(buffer: Buffer) {
return [
// { materia: 'Matemática', nota: 'MB' },
// { materia: 'Português', nota: 'MB' },
];
}
}
42 changes: 42 additions & 0 deletions server/src/modules/services/funcionario/SetAsParceiraUseCase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { prisma } from "../../../prisma/client";
import { SetEmpresaParceiraDTO } from "../../interfaces/funcionarioDTOs";
import { AppError } from "../../../errors/error";

export class SetEmpresaParceiraUseCase {
async execute({ funcionarioId, emailEmpresa }: SetEmpresaParceiraDTO) {
if (!funcionarioId || !emailEmpresa) {
throw new AppError("Parâmetros insuficientes ou inválidos.");
}

const funcionario = await prisma.funcionario.findUnique({
where: {
id: funcionarioId
}
});

if (!funcionario) {
throw new AppError("Funcionário não encontrado.");
}

const empresa = await prisma.empresa.findUnique({
where: {
email: emailEmpresa
}
});

if (!empresa) {
throw new AppError("Empresa não encontrada.");
}

const empresaParceira = await prisma.empresa.update({
where: {
id: emailEmpresa
},
data: {
patrocinador: true
}
});

return empresaParceira;
}
}
1 change: 1 addition & 0 deletions server/src/router/routes/funcionario.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ funcionarioRoutes.get("/init", controllers.initFuncionarioController.handle);

funcionarioRoutes.use(funcionarioAuthMiddleware);
funcionarioRoutes.post("/register/vaga", controllers.registerVagaController.handle);
funcionarioRoutes.post("/update/empresa", controllers.registerVagaController.handle);

funcionarioRoutes.get("/auth", (req, res) => {
res.status(200).send("Funcionário autenticado com sucesso.");
Expand Down
8 changes: 5 additions & 3 deletions server/src/router/routes/imports/funcionario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import {
RecoveryFuncionarioController,
ValidateRecoveryController,
RefreshTokenController,
RegisterVagaController
RegisterVagaController,
FuncionarioController,
} from "../../../modules/controllers/funcionarioControllers";
import {
GetCursosController,
GetEmpresasController
GetEmpresasController,
} from "../../../modules/controllers/sharedControllers";

export const createControllers = () => ({
Expand All @@ -21,5 +22,6 @@ export const createControllers = () => ({
refreshTokenController: new RefreshTokenController(),
registerVagaController: new RegisterVagaController(),
getCursosController: new GetCursosController(),
getEmpresasController: new GetEmpresasController()
getEmpresasController: new GetEmpresasController(),
funcionarioController: new FuncionarioController(),
});

0 comments on commit 0e38353

Please sign in to comment.