Criação de opção de exportar para CSV relatório detalhado
parent
7baed2a7da
commit
df59d8af43
|
@ -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 = {
|
||||
|
@ -28,5 +29,22 @@ export const reportUserByDateStartDateEnd = async (req: Request, res: Response):
|
|||
|
||||
|
||||
|
||||
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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -9,4 +9,6 @@ const reportRoutes = express.Router();
|
|||
|
||||
reportRoutes.get("/reports", isAuth, ReportController.reportUserByDateStartDateEnd);
|
||||
|
||||
reportRoutes.get("/reports/messages", isAuth, ReportController.reportMessagesUserByDateStartDateEnd);
|
||||
|
||||
export default reportRoutes;
|
||||
|
|
|
@ -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;
|
|
@ -3,18 +3,6 @@ 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) => {
|
||||
|
|
|
@ -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 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' },
|
||||
|
@ -158,6 +222,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);
|
||||
|
@ -256,6 +327,66 @@ const textFieldSelectUser = (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 (
|
||||
|
||||
<Can
|
||||
|
@ -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>
|
||||
|
|
|
@ -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: {
|
||||
|
|
Loading…
Reference in New Issue