Criação de opção de exportar para CSV relatório detalhado

pull/1/head
adriano 2022-04-18 11:12:49 -03:00
parent 7baed2a7da
commit df59d8af43
6 changed files with 279 additions and 21 deletions

View File

@ -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<Response> => {
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);
};

View File

@ -9,4 +9,6 @@ const reportRoutes = express.Router();
reportRoutes.get("/reports", isAuth, ReportController.reportUserByDateStartDateEnd);
reportRoutes.get("/reports/messages", isAuth, ReportController.reportMessagesUserByDateStartDateEnd);
export default reportRoutes;

View File

@ -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<Message[]> => {
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;

View File

@ -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) => {

View File

@ -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<dataCSVFormat.length; i++){
if(dataCSVFormat[i].fromMe){
dataCSVFormat[i].fromMe = 'Atendente'
}
else{
dataCSVFormat[i].fromMe = 'Cliente'
}
}
// console.log('dataCSVFormat: ', dataCSVFormat)
setDataCSV(dataCSVFormat)
// setDataCSV(dataQuery.data)
}
// setLoading(false);
} catch (err) {
console.log(err);
}
};
fetchQueries();
}
useEffect(() => {
if(isMount){
setIsMount(false);
return;
}
csvLink.current.link.click()
}, [dataCSV]);
return (
@ -274,7 +405,24 @@ const textFieldSelectUser = (data) => {
<Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={false} title={'Data fim'}/></Item>
<Item sx={{ gridColumn: '4 / 5' }}>
{/* <Button size="small" variant="contained" onClick={()=>{handleQuery()}}>GO</Button>*/}
<Button
variant="contained"
color="primary"
onClick={(e) => handleCSVMessages()}
>
{"CSV ALL"}
</Button>
<div>
<CSVLink
data={dataCSV}
headers={columns}
filename= {'Relatorio_detalhado_atendimento_atendentes.csv'}
target={'_blank'}
ref={csvLink}/>
</div>
</Item>
</Box>

View File

@ -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: {