From df59d8af43f93d0f5ce262780e2973c96cae222b Mon Sep 17 00:00:00 2001 From: adriano Date: Mon, 18 Apr 2022 11:12:49 -0300 Subject: [PATCH] =?UTF-8?q?Cria=C3=A7=C3=A3o=20de=20op=C3=A7=C3=A3o=20de?= =?UTF-8?q?=20exportar=20para=20CSV=20relat=C3=B3rio=20detalhado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/controllers/ReportController.ts | 20 ++- backend/src/routes/reportRoutes.ts | 2 + .../MessageServices/ShowMessageReport.ts | 102 +++++++++++ .../src/components/Report/ExportCSV/index.js | 14 +- frontend/src/pages/Report/index.js | 160 +++++++++++++++++- frontend/src/pages/Settings/index.js | 2 +- 6 files changed, 279 insertions(+), 21 deletions(-) create mode 100644 backend/src/services/MessageServices/ShowMessageReport.ts diff --git a/backend/src/controllers/ReportController.ts b/backend/src/controllers/ReportController.ts index 83c2349..be4e5fb 100644 --- a/backend/src/controllers/ReportController.ts +++ b/backend/src/controllers/ReportController.ts @@ -3,6 +3,7 @@ import { Request, Response } from "express"; import AppError from "../errors/AppError"; import ShowTicketReport from "../services/TicketServices/ShowTicketReport"; +import ShowMessageReport from "../services/MessageServices/ShowMessageReport"; type IndexQuery = { @@ -20,12 +21,29 @@ export const reportUserByDateStartDateEnd = async (req: Request, res: Response): const { userId, startDate, endDate } = req.query as IndexQuery - const data_query = await ShowTicketReport(userId, startDate, endDate); + const data_query = await ShowTicketReport(userId, startDate, endDate); return res.status(200).json(data_query); }; + + +export const reportMessagesUserByDateStartDateEnd = async (req: Request, res: Response): Promise => { + + if (req.user.profile !== "master" && req.user.profile !== "admin") { + throw new AppError("ERR_NO_PERMISSION", 403); + } + + const { userId, startDate, endDate } = req.query as IndexQuery + + const data_query_messages = await ShowMessageReport(userId, startDate, endDate); + + return res.status(200).json(data_query_messages); + +}; + + diff --git a/backend/src/routes/reportRoutes.ts b/backend/src/routes/reportRoutes.ts index ba5366b..c3a751c 100644 --- a/backend/src/routes/reportRoutes.ts +++ b/backend/src/routes/reportRoutes.ts @@ -9,4 +9,6 @@ const reportRoutes = express.Router(); reportRoutes.get("/reports", isAuth, ReportController.reportUserByDateStartDateEnd); +reportRoutes.get("/reports/messages", isAuth, ReportController.reportMessagesUserByDateStartDateEnd); + export default reportRoutes; diff --git a/backend/src/services/MessageServices/ShowMessageReport.ts b/backend/src/services/MessageServices/ShowMessageReport.ts new file mode 100644 index 0000000..886258d --- /dev/null +++ b/backend/src/services/MessageServices/ShowMessageReport.ts @@ -0,0 +1,102 @@ +import Ticket from "../../models/Ticket"; +import AppError from "../../errors/AppError"; +import Contact from "../../models/Contact"; +import User from "../../models/User"; +import Queue from "../../models/Queue"; + +import Message from "../../models/Message"; +import { userInfo } from "os"; + +import { Op, where } from "sequelize"; + +import { Sequelize } from "sequelize"; +import moment from 'moment'; + +import { startOfDay, endOfDay, parseISO, getDate} from "date-fns"; +import { string } from "yup/lib/locale"; +import Whatsapp from "../../models/Whatsapp"; + +//Report by user, startDate, endDate +const ShowMessageReport = async (id: string | number, startDate: string, endDate: string): Promise => { + + let where_clause_user = {} + + let where_clause = { + createdAt: { + [Op.gte]: startDate+' 00:00:00.000000', + [Op.lte]: endDate +' 23:59:59.999999' + }, + } + + if(id=='0'){ + + // where_clause_user = { + // createdAt: { + // [Op.gte]: startDate+' 00:00:00.000000', + // [Op.lte]: endDate +' 23:59:59.999999' + // }, + // } + + } + else{ + where_clause_user = { + userid: id, + // createdAt: { + // [Op.gte]: startDate+' 00:00:00.000000', + // [Op.lte]: endDate +' 23:59:59.999999' + // }, + } + } + + const messages = await Message.findAll({ + + where: where_clause , + + attributes: ['id', 'body', 'read', 'mediaType','fromMe', 'mediaUrl', [Sequelize.fn("DATE_FORMAT",Sequelize.col("Message.createdAt"),"%d/%m/%Y %H:%i:%s"),"createdAt"]], + + include: [ + { + model: Ticket, + where: where_clause_user, + required:true, + + attributes: ['id', 'status'], + + include: [ + { + model: Contact, + attributes: ['name', 'number'] + }, + { + model: User, + attributes: ['name', 'email'] + }, + { + model: Queue, + attributes: ['name'] + }, + { + model: Whatsapp, + attributes: ['name'] + }, + ] + + }, + + ], + + order: [ + ['createdAt', 'ASC'] + ] + + }); + + + if (!messages) { + throw new AppError("ERR_NO_MESSAGES_FOUND", 404); + } + + return messages; +}; + +export default ShowMessageReport; diff --git a/frontend/src/components/Report/ExportCSV/index.js b/frontend/src/components/Report/ExportCSV/index.js index 79327f6..838fa47 100644 --- a/frontend/src/components/Report/ExportCSV/index.js +++ b/frontend/src/components/Report/ExportCSV/index.js @@ -3,19 +3,7 @@ import React, { useState, useRef} from "react"; import { CSVLink } from "react-csv"; import Button from '@mui/material/Button'; -/*const headers = [ - { label: "First Name", key: "firstname" }, - { label: "Last Name", key: "lastname" }, - { label: "Email", key: "email" } - ]; - -const data = [ - { firstname: "Ahmed", lastname: "Tomi", email: "ah@smthing.co.com" }, - { firstname: "Raed", lastname: "Labes", email: "rl@smthing.co.com" }, - { firstname: "Yezzi", lastname: "Min l3b", email: "ymin@cocococo.com" } - ];*/ - - + const ExportCSV = (props) => { diff --git a/frontend/src/pages/Report/index.js b/frontend/src/pages/Report/index.js index faf4598..5455af1 100644 --- a/frontend/src/pages/Report/index.js +++ b/frontend/src/pages/Report/index.js @@ -1,17 +1,81 @@ -import React, { useState, useEffect, useReducer, useContext} from "react"; +import React, { useState, useEffect, useReducer, useContext, useRef} from "react"; import MainContainer from "../../components/MainContainer"; import api from "../../services/api"; import SelectField from "../../components/Report/SelectField"; //import { data } from '../../components/Report/MTable/data'; import DatePicker1 from '../../components/Report/DatePicker' -import DatePicker2 from '../../components/Report/DatePicker' -//import { Button } from "@material-ui/core"; +import DatePicker2 from '../../components/Report/DatePicker' import MTable from "../../components/Report/MTable"; import PropTypes from 'prop-types'; import Box from '@mui/material/Box'; import { AuthContext } from "../../context/Auth/AuthContext"; import { Can } from "../../components/Can"; +import { Button } from "@material-ui/core"; + + +// test del + +// import ExportCSV from '../../components/Report/ExportCSV' + +import { CSVLink } from "react-csv"; + +let columns = [ + { + key: 'ticket.whatsapp.name', + label: 'Loja', + + }, + + { + key: 'id', + label: 'id Mensagem', + }, + + { + key: 'ticket.id', + label: 'id Conversa', + }, + + { + key: 'ticket.contact.name', + label: 'Cliente', + }, + + { + key: 'ticket.user.name', + label: 'Atendente', + }, + { + key: 'body', + label: 'Mensagem', + }, + { + key: 'fromMe', + label: 'Sentido', + }, + { + key: 'createdAt', + label: 'Criada', + }, + { + key: 'ticket.contact.number', + label: 'Telefone cliente', + }, + { + key: 'ticket.queue.name', + label: 'Fila', + }, + { + key: 'ticket.status', + label: 'Status', + }, + +] + +// + + const reducerQ = (state, action) =>{ @@ -106,7 +170,7 @@ Item.propTypes = { let columnsData = [ - { title: 'Whatsapp', field: 'whatsapp.name' }, + { title: 'Unidade', field: 'whatsapp.name' }, { title: 'Atendente', field: 'user.name' }, { title: 'Contato', field: 'contact.number' }, { title: 'Nome', field: 'contact.name' }, @@ -157,6 +221,8 @@ let columnsData = [ const Report = () => { + + const csvLink = useRef() const { user: userA } = useContext(AuthContext); @@ -172,6 +238,9 @@ const Report = () => { const [userId, setUser] = useState(null) const [query, dispatchQ] = useReducer(reducerQ, []) + const [dataCSV, setDataCSV] = useState([]) + const [isMount, setIsMount] = useState(true); + useEffect(() => { dispatch({ type: "RESET" }); dispatchQ({ type: "RESET" }) @@ -221,7 +290,9 @@ const Report = () => { //setLoading(false); - console.log('dataQuery: ', dataQuery.data) + // console.log('dataQuery: ', dataQuery.data) + + console.log() } catch (err) { console.log(err); @@ -253,8 +324,68 @@ const textFieldSelectUser = (data) => { setUser(data) } + + + + +// test del + +const handleCSVMessages = () =>{ + // setLoading(true); + + const fetchQueries = async () => { + + try { + + const dataQuery = await api.get("/reports/messages", {params: {userId, startDate, endDate },}); + + // console.log('dataQuery messages: ', dataQuery.data) + + if(dataQuery.data.length > 0){ + + let dataCSVFormat = dataQuery.data ; + + for(var i = 0; i { + + if(isMount){ + setIsMount(false); + return; + } + + csvLink.current.link.click() + +}, [dataCSV]); + + return ( @@ -274,7 +405,24 @@ const textFieldSelectUser = (data) => { - {/* */} + + + +
+ +
+
diff --git a/frontend/src/pages/Settings/index.js b/frontend/src/pages/Settings/index.js index fd6ecdc..91cf8d7 100644 --- a/frontend/src/pages/Settings/index.js +++ b/frontend/src/pages/Settings/index.js @@ -16,7 +16,7 @@ import toastError from "../../errors/toastError"; import { AuthContext } from "../../context/Auth/AuthContext"; import { Can } from "../../components/Can"; -import Button from "@material-ui/core/Button"; +// import Button from "@material-ui/core/Button"; const useStyles = makeStyles(theme => ({ root: {