diff --git a/frontend/src/assets/styles/_colors.scss b/frontend/src/assets/styles/_colors.scss
index 70d90f086..23b7040c1 100644
--- a/frontend/src/assets/styles/_colors.scss
+++ b/frontend/src/assets/styles/_colors.scss
@@ -103,6 +103,18 @@ Background colors
/*
Background colors hover
*/
+
+.rangepicker{
+ color: $blue-grey;
+ border:thin solid $grey-light
+}
+.rangepicker input {
+ color:$blue-grey
+}
+.rangepicker button {
+ fill: $red;
+}
+
.hover-bg-red:hover,
.hover-bg-red:focus {
background-color: $red;
diff --git a/frontend/src/components/teamsAndOrgs/teams.js b/frontend/src/components/teamsAndOrgs/teams.js
index e04ee49e1..dc237d394 100644
--- a/frontend/src/components/teamsAndOrgs/teams.js
+++ b/frontend/src/components/teamsAndOrgs/teams.js
@@ -1,10 +1,10 @@
-import React, { useState } from 'react';
+import React, { useState, useEffect } from 'react';
import { useSelector } from 'react-redux';
import { Link } from '@reach/router';
import { FormattedMessage } from 'react-intl';
import ReactPlaceholder from 'react-placeholder';
import { Form, Field } from 'react-final-form';
-
+import { fetchLocalJSONAPI } from '../../network/genericJSONRequest';
import messages from './messages';
import { useEditTeamAllowed } from '../../hooks/UsePermissions';
import { UserAvatar, UserAvatarList } from '../user/avatar';
@@ -12,6 +12,13 @@ import { AddButton, ViewAllLink, Management, VisibilityBox, InviteOnlyBox } from
import { SwitchToggle, RadioField, OrganisationSelect } from '../formInputs';
import { EditModeControl } from './editMode';
import { Button, EditButton } from '../button';
+import { Tabs, TabList, Tab, TabPanel } from 'react-tabs';
+import 'react-tabs/style/react-tabs.css';
+import DataTable from 'react-data-table-component';
+import DateRangePicker from '@wojtekmaj/react-daterange-picker';
+import 'react-calendar/dist/Calendar.css';
+import Select from 'react-select';
+import moment from 'moment';
export function TeamsManagement({
teams,
@@ -371,6 +378,442 @@ export function TeamsBoxList({ teams }: Object) {
>
);
}
+export function TeamsStats() {
+ // const mappingTeams = teams.filter((team) => team.role === 'MAPPER');
+ // const validationTeams = teams.filter((team) => team.role === 'VALIDATOR');
+ const token = useSelector((state) => state.auth.get('token'));
+ const userDetails = useSelector((state) => state.auth.get('userDetails'));
+ const userName = userDetails.username;
+ const userId = userDetails.id;
+ const [selectedOption, setSelectedOption] = useState(null);
+ const [selectedUser, setSelectedUser] = useState({});
+ const maxDateApp = new Date();
+ var dateObj = new Date();
+ dateObj.setDate(dateObj.getDate() - 7);
+
+ const [value, onChange] = useState([dateObj, new Date()]);
+ const [teamMetricsStats, setTeamMetricsStats] = useState({});
+ const [teamNames, setTeamNames] = useState({});
+
+ const startDate = moment(value[0]).format('YYYY-MM -DD');
+
+ const endDate = moment(value[1]).format('YYYY-MM -DD');
+
+ useEffect(() => {
+ getTeamMetricsStats();
+ getTeamNames();
+ }, []);
+
+ const getTeamNames = async () => {
+ const response = await fetchLocalJSONAPI(`teams/?member=${userId}`, token);
+
+ const jsonData = await response.teams;
+ //const jsonDataForDays = await response.day;
+ setTeamNames(jsonData);
+
+ console.log('team names are ***', jsonData);
+ };
+
+ let selectItems = [{ value: 'All', label: 'All' }];
+ //selectItems
+ for (var i = 0; i < teamNames.length; i++) {
+ var obj = {};
+ obj.value = teamNames[i].teamId;
+ obj.label = teamNames[i].name;
+ selectItems.push(obj);
+ }
+ const getTeamMetricsStats = async () => {
+ const response = await fetchLocalJSONAPI(
+ `users/${userName}/usersteamstats/?start_date=${startDate}&end_date=${endDate}`,
+ token,
+ );
+
+ const jsonData = await response.team;
+ //const jsonDataForDays = await response.day;
+ setTeamMetricsStats(jsonData);
+
+ console.log('user metrics stats are ***', jsonData);
+ };
+ console.log('team metrics stats are ***', teamMetricsStats);
+ var convertSeconds = (sec) => {
+ var hrs = Math.floor(sec / 3600);
+ var min = Math.floor((sec - hrs * 3600) / 60);
+ var seconds = sec - hrs * 3600 - min * 60;
+ seconds = Math.round(seconds * 100) / 100;
+
+ var result = hrs < 10 ? '0' + hrs : hrs;
+ result += ':' + (min < 10 ? '0' + min : min);
+ result += ':' + (seconds < 10 ? '0' + seconds : seconds);
+ return result;
+ };
+
+ let dataSummaryResponse = [];
+ //totaltime, mappingTotal, ValidationTotal;
+
+ for (let i = 0; i < teamMetricsStats.length; i++) {
+ let obj = {};
+
+ obj.userid = teamMetricsStats[i].user_id;
+ obj.UserName = teamMetricsStats[i].user_name;
+ obj.TimeinOSMTM = convertSeconds(teamMetricsStats[i].time_spent_mapping);
+ obj.MappingTotal = teamMetricsStats[i].tasks_mapped;
+ obj.ValidationTotal = teamMetricsStats[i].tasks_validated;
+
+ dataSummaryResponse.push(obj);
+ }
+ let dataMappedResponse = [];
+ for (let i = 0; i < teamMetricsStats.length; i++) {
+ let obj = {};
+
+ obj.UserName = teamMetricsStats[i].user_name;
+ obj.TasksDone = teamMetricsStats[i].tasks_mapped;
+ obj.TotalTaskstime = convertSeconds(teamMetricsStats[i].time_spent_mapping);
+ obj.AverageTimePerTask = convertSeconds(teamMetricsStats[i].average_time_spent_mapping);
+
+ dataMappedResponse.push(obj);
+ }
+ let dataValidatedResponse = [];
+ for (let i = 0; i < teamMetricsStats.length; i++) {
+ let obj = {};
+ obj.UserName = teamMetricsStats[i].user_name;
+ obj.TasksDone = teamMetricsStats[i].tasks_validated;
+ obj.TotalTaskstime = convertSeconds(teamMetricsStats[i].time_spent_validating);
+ obj.AverageTimePerTask = convertSeconds(teamMetricsStats[i].average_time_spent_validating);
+
+ dataValidatedResponse.push(obj);
+ }
+
+ const columnsSummary = [
+ {
+ name: 'User Name',
+ selector: 'UserName',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ cell: (row) => (
+
+ {' '}
+ {row.UserName}{' '}
+
+ ),
+ },
+
+ {
+ name: 'Total Time (hh:mm:ss) ',
+ selector: 'TimeinOSMTM',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ },
+ {
+ name: 'Mapping Total',
+ selector: 'MappingTotal',
+ sortable: true,
+ grow: 2,
+
+ minWidth: '100px',
+ },
+ {
+ name: 'Validation Total',
+ selector: 'ValidationTotal',
+ sortable: true,
+ grow: 2,
+
+ minWidth: '200px',
+ },
+ ];
+
+ function submitSelected(Values) {
+ console.log('param sent is', Values.value);
+ console.log('start time is', value[0]);
+ console.log('end time is', value[1]);
+
+ generateTeamMetricsStats(Values.value, value[0], value[1]);
+ }
+ var generateTeamMetricsStats = (teamId, startDate, endDate) => {
+ // console.log('select box value inside api call is', selectBoxValue.value);
+ var startDateFormatted = moment(startDate).format('YYYY-MM -DD');
+
+ var endDateFormatted = moment(endDate).format('YYYY-MM -DD');
+
+ // const response = await fetchLocalJSONAPI(
+ // `users/${userName}/userstaskmapped/ ?project_id=6&start_date=${startDateFormatted}&end_date=${endDateFormatted}`,
+ // token,
+ // );
+
+ // const jsonData = await response.task;
+ //const response = await fetchLocalJSONAPI(`users/HanumanthMapper/usersteamstats/`, token);
+
+ let url = '';
+ if (teamId === 'All') {
+ url = `users/${userName}/usersteamstats/?start_date=${startDateFormatted}&end_date=${endDateFormatted}`;
+ //url = `users/${userName}/userstaskmapped/?start_date=${startDateFormatted}&end_date=${endDateFormatted}`;
+ } else {
+ url = `users/${userName}/usersteamstats/?team_id=${teamId}&start_date=${startDateFormatted}&end_date=${endDateFormatted}`;
+ }
+ fetchLocalJSONAPI(url, token)
+ .then((res) => {
+ // setUserMetricsStats(res.team);
+ setTeamMetricsStats(res.team);
+ //setUserMetricsGraphData(res.day);
+ })
+ .catch((e) => console.log('call back failed in task index file' + e));
+ };
+ const columnsForValidated = [
+ {
+ name: 'User Name',
+ selector: 'UserName',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ cell: (row) => (
+
+ {row.UserName}
+
+ ),
+ },
+
+ {
+ name: 'Tasks Done ',
+ selector: 'TasksDone',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ },
+ {
+ name: 'Total Tasks time (hh:mm:ss)',
+ selector: 'TotalTaskstime',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ },
+ {
+ name: 'Average time per task(hh:mm:ss)',
+ selector: 'AverageTimePerTask',
+ sortable: true,
+ grow: 2,
+ minWidth: '200px',
+ },
+ ];
+ const columnsForMapped = [
+ {
+ name: 'User Name',
+ selector: 'UserName',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ cell: (row) => (
+
+ {row.UserName}
+
+ ),
+ },
+
+ {
+ name: 'Tasks Done ',
+ selector: 'TasksDone',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ },
+ {
+ name: 'Total Tasks time (hh:mm:ss)',
+ selector: 'TotalTaskstime',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ },
+ {
+ name: 'Average time per task(hh:mm:ss)',
+ selector: 'AverageTimePerTask',
+ sortable: true,
+ grow: 2,
+ minWidth: '200px',
+ },
+ ];
+ const exporttoCsv = (dataArray, fileName) => {
+ console.log('array data', dataArray);
+ console.log('afile name is', fileName);
+ console.log('Start Date', value[0]);
+ console.log('End Date is', value[1]);
+ const link = document.createElement('a');
+ let csv = convertArrayOfObjectsToCSV(dataArray);
+ if (csv == null) return;
+
+ const filename = fileName + 'export.csv';
+
+ if (!csv.match(/^data:text\/csv/i)) {
+ csv = `data:text/csv;charset=utf-8,${csv}`;
+ }
+
+ link.setAttribute('href', encodeURI(csv));
+ link.setAttribute('download', filename);
+ link.click();
+ };
+ function convertArrayOfObjectsToCSV(array) {
+ let result;
+
+ const columnDelimiter = ',';
+ const lineDelimiter = '\n';
+ const keys = Object.keys(array[0]);
+
+ result = '';
+ result += keys.join(columnDelimiter);
+ result += lineDelimiter;
+
+ array.forEach((item) => {
+ let ctr = 0;
+ keys.forEach((key) => {
+ if (ctr > 0) result += columnDelimiter;
+
+ result += item[key];
+
+ ctr++;
+ });
+ result += lineDelimiter;
+ });
+
+ return result;
+ }
+
+ function handleRowClick(row, event) {
+ console.log('row event clicked', row.UserName);
+ setSelectedUser(row.UserName);
+ console.log('inside handle Row click for popup 1112', selectedUser);
+ }
+
+ const customStyles = {
+ headCells: {
+ style: {
+ fontSize: '15px',
+ fontWeight: 'bold',
+ },
+ },
+
+ cells: {
+ style: {
+ fontSize: '14px',
+ },
+ },
+ };
+ return (
+
+
+
+
+
Team Metrics
+
+
+
+
+
+ |
+
+
+ |
+
+
+
+ |
+
+ |
+
+
+
+
+
+
+ Summary
+
+ Mapped
+ Validated
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
export const TeamBox = ({ team, className }: Object) => (
diff --git a/frontend/src/components/userDetail/elementsMapped.js b/frontend/src/components/userDetail/elementsMapped.js
index 7fd34fa15..af1849d1e 100644
--- a/frontend/src/components/userDetail/elementsMapped.js
+++ b/frontend/src/components/userDetail/elementsMapped.js
@@ -2,8 +2,16 @@ import React from 'react';
import humanizeDuration from 'humanize-duration';
import ReactTooltip from 'react-tooltip';
import { FormattedMessage } from 'react-intl';
-
+import { Tabs, TabList, Tab, TabPanel } from 'react-tabs';
+import 'react-tabs/style/react-tabs.css';
import messages from './messages';
+import { useState, useEffect } from 'react';
+import { fetchLocalJSONAPI } from '../../network/genericJSONRequest';
+import { useSelector } from 'react-redux';
+import { Button } from '../button';
+import { Line } from 'react-chartjs-2';
+import Select from 'react-select';
+import moment from 'moment';
import {
ClockIcon,
RoadIcon,
@@ -15,6 +23,9 @@ import {
ValidatedIcon,
} from '../svgIcons';
import { StatsCardContent } from '../statsCardContent';
+import DataTable from 'react-data-table-component';
+import 'react-data-table-component-extensions/dist/index.css';
+import DateRangePicker from '@wojtekmaj/react-daterange-picker';
const getFieldData = (field) => {
const iconClass = 'h-50 w-50';
@@ -72,6 +83,281 @@ const Element = ({ field, value }) => {
};
export const TaskStats = ({ userStats, username }) => {
+ const [selectedOption, setSelectedOption] = useState(null);
+ const [userMetricsStats, setUserMetricsStats] = useState({});
+ const [userMetricsGraphData, setUserMetricsGraphData] = useState({});
+ const token = useSelector((state) => state.auth.get('token'));
+ const [projectNames, setProjectNames] = useState({});
+ const userDetails = useSelector((state) => state.auth.get('userDetails'));
+ const userName = userDetails.username;
+
+ useEffect(() => {
+ getUserMetricsStats();
+ getProjectNames();
+ }, []);
+
+ var convertSeconds = (sec) => {
+ var hrs = Math.floor(sec / 3600);
+ var min = Math.floor((sec - hrs * 3600) / 60);
+ var seconds = sec - hrs * 3600 - min * 60;
+ seconds = Math.round(seconds * 100) / 100;
+
+ var result = hrs < 10 ? '0' + hrs : hrs;
+ result += ':' + (min < 10 ? '0' + min : min);
+ result += ':' + (seconds < 10 ? '0' + seconds : seconds);
+ return result;
+ };
+
+ const maxDateApp = new Date();
+
+ var dateObj = new Date();
+
+ // subtract seven days from current time
+ dateObj.setDate(dateObj.getDate() - 7);
+
+ const [value, onChange] = useState([dateObj, new Date()]);
+ const startDate = moment(value[0]).format('YYYY-MM -DD');
+ const endDate = moment(value[1]).format('YYYY-MM -DD');
+ const getProjectNames = async () => {
+ const response = await fetchLocalJSONAPI(`projects/`, token);
+ const jsonData = await response.results;
+ setProjectNames(jsonData);
+ };
+ let selectItems = [{ value: 'All', label: 'All' }];
+ for (var i = 0; i < projectNames.length; i++) {
+ var obj = {};
+ obj.value = projectNames[i].projectId;
+ obj.label = projectNames[i].name;
+ selectItems.push(obj);
+ }
+
+ const getUserMetricsStats = async () => {
+ const response = await fetchLocalJSONAPI(
+ `users/${userName}/userstaskmapped/?start_date=${startDate}&end_date=${endDate}`,
+ token,
+ );
+ const jsonData = await response.task;
+ const jsonDataForDays = await response.day;
+ setUserMetricsStats(jsonData);
+ setUserMetricsGraphData(jsonDataForDays);
+ };
+
+ const columnsSummary = [
+ {
+ name: 'Project Name',
+ selector: 'ProjectName',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ },
+
+ {
+ name: 'Total Time (hh:mm:ss) ',
+ selector: 'TimeinOSMTM',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ },
+ {
+ name: 'Mapping Total',
+ selector: 'MappingTotal',
+ sortable: true,
+ grow: 2,
+
+ minWidth: '100px',
+ },
+ {
+ name: 'Validation Total',
+ selector: 'ValidationTotal',
+ sortable: true,
+ grow: 2,
+
+ minWidth: '200px',
+ },
+ ];
+
+ let graphDays = [];
+ let graphMappedValues = [];
+ let graphValidationValues = [];
+
+ for (let i = 0; i < userMetricsGraphData.length; i++) {
+ let date = '';
+ let mapped = '';
+ let validated = '';
+ date = moment(userMetricsGraphData[i].date).format('DD-MMM');
+
+ mapped = userMetricsGraphData[i].tasks_mapped;
+ validated = userMetricsGraphData[i].tasks_validated;
+ graphDays.push(date);
+ graphMappedValues.push(mapped);
+ graphValidationValues.push(validated);
+ }
+
+ let dataSummaryResponse = [];
+ for (let i = 0; i < userMetricsStats.length; i++) {
+ let obj = {};
+ obj.id = i + 1;
+ obj.ProjectName = userMetricsStats[i].project_name;
+ obj.TimeinOSMTM = convertSeconds(userMetricsStats[i].time_spent_mapping);
+ obj.MappingTotal = userMetricsStats[i].tasks_mapped;
+ obj.ValidationTotal = userMetricsStats[i].tasks_validated;
+
+ dataSummaryResponse.push(obj);
+ }
+ let dataMappedResponse = [];
+ for (let i = 0; i < userMetricsStats.length; i++) {
+ let obj = {};
+ obj.id = i + 1;
+ obj.ProjectName = userMetricsStats[i].project_name;
+ obj.TasksDone = userMetricsStats[i].tasks_mapped;
+ obj.TotalTaskstime = convertSeconds(userMetricsStats[i].time_spent_mapping);
+ obj.AverageTimePerTask = convertSeconds(userMetricsStats[i].average_time_spent_mapping);
+
+ dataMappedResponse.push(obj);
+ }
+ let dataValidatedResponse = [];
+ for (let i = 0; i < userMetricsStats.length; i++) {
+ let obj = {};
+ obj.id = i + 1;
+ obj.ProjectName = userMetricsStats[i].project_name;
+ obj.TasksDone = userMetricsStats[i].tasks_validated;
+ obj.TotalTaskstime = convertSeconds(userMetricsStats[i].time_spent_validating);
+ obj.AverageTimePerTask = convertSeconds(userMetricsStats[i].average_time_spent_validating);
+
+ dataValidatedResponse.push(obj);
+ }
+
+ const columnsForMapped = [
+ {
+ name: 'Project Name',
+ selector: 'ProjectName',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ },
+
+ {
+ name: 'Tasks Done ',
+ selector: 'TasksDone',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ },
+ {
+ name: 'Total Tasks time (hh:mm:ss)',
+ selector: 'TotalTaskstime',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ },
+ {
+ name: 'Average time per task(hh:mm:ss)',
+ selector: 'AverageTimePerTask',
+ sortable: true,
+ grow: 2,
+ minWidth: '200px',
+ },
+ ];
+
+ function convertArrayOfObjectsToCSV(array) {
+ let result;
+
+ const columnDelimiter = ',';
+ const lineDelimiter = '\n';
+ const keys = Object.keys(array[0]);
+
+ result = '';
+ result += keys.join(columnDelimiter);
+ result += lineDelimiter;
+
+ array.forEach((item) => {
+ let ctr = 0;
+ keys.forEach((key) => {
+ if (ctr > 0) result += columnDelimiter;
+
+ result += item[key];
+
+ ctr++;
+ });
+ result += lineDelimiter;
+ });
+
+ return result;
+ }
+ const state = {
+ labels: graphDays,
+ datasets: [
+ {
+ label: 'Mapped',
+ fill: false,
+ lineTension: 0.5,
+
+ borderWidth: 2,
+ data: graphMappedValues,
+ },
+ {
+ label: 'Validated',
+ fill: false,
+ lineTension: 0.5,
+ backgroundColor: 'rgb(173, 230, 239)',
+ borderColor: 'rgb(173, 230, 239)',
+ borderWidth: 2,
+ data: graphValidationValues,
+ },
+ ],
+ };
+
+ const exporttoCsv = (dataArray, fileName) => {
+ const link = document.createElement('a');
+ let csv = convertArrayOfObjectsToCSV(dataArray);
+ if (csv == null) return;
+
+ const filename = userName + '-' + fileName + 'export.csv';
+
+ if (!csv.match(/^data:text\/csv/i)) {
+ csv = `data:text/csv;charset=utf-8,${csv}`;
+ }
+
+ link.setAttribute('href', encodeURI(csv));
+ link.setAttribute('download', filename);
+ link.click();
+ };
+
+ function submitSelected(Values) {
+ generateUserMetricsStats(Values.value, value[0], value[1]);
+ }
+ var generateUserMetricsStats = (projId, startDate, endDate) => {
+ var startDateFormatted = moment(startDate).format('YYYY-MM -DD');
+ var endDateFormatted = moment(endDate).format('YYYY-MM -DD');
+
+ let url = '';
+ if (projId === 'All') {
+ url = `users/${userName}/userstaskmapped/?start_date=${startDateFormatted}&end_date=${endDateFormatted}`;
+ } else {
+ url = `users/${userName}/userstaskmapped/?project_id=${projId}&start_date=${startDateFormatted}&end_date=${endDateFormatted}`;
+ }
+ fetchLocalJSONAPI(url, token)
+ .then((res) => {
+ setUserMetricsStats(res.task);
+ setUserMetricsGraphData(res.day);
+ })
+ .catch((e) => console.log('call back failed in task index file' + e));
+ };
+
+ const customStyles = {
+ headCells: {
+ style: {
+ fontSize: '15px',
+ fontWeight: 'bold',
+ },
+ },
+
+ cells: {
+ style: {
+ fontSize: '14px',
+ },
+ },
+ };
return (
@@ -154,6 +440,137 @@ export const TaskStats = ({ userStats, username }) => {
+
+
+
+
+
+
Your Metrics
+
+
+
+
+
+ |
+
+
+ |
+
+
+
+ |
+
+ |
+
+
+
+
+
+
+ Summary
+
+ Mapped
+ Validated
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
};
diff --git a/frontend/src/views/teams.js b/frontend/src/views/teams.js
index db5fadd73..18e1939c7 100644
--- a/frontend/src/views/teams.js
+++ b/frontend/src/views/teams.js
@@ -5,12 +5,15 @@ import ReactPlaceholder from 'react-placeholder';
import { TextBlock, RectShape } from 'react-placeholder/lib/placeholders';
import { FormattedMessage } from 'react-intl';
import { Form } from 'react-final-form';
-
+import Select from 'react-select';
import messages from './messages';
import { useFetch } from '../hooks/UseFetch';
import { useEditTeamAllowed } from '../hooks/UsePermissions';
import { useSetTitleTag } from '../hooks/UseMetaTags';
import { fetchLocalJSONAPI, pushToLocalJSONAPI } from '../network/genericJSONRequest';
+import DataTable from 'react-data-table-component';
+import { Button } from '../components/button';
+import moment from 'moment';
import {
getMembersDiff,
filterActiveMembers,
@@ -24,18 +27,339 @@ import {
TeamForm,
TeamsManagement,
TeamSideBar,
+ TeamsStats,
} from '../components/teamsAndOrgs/teams';
import { MessageMembers } from '../components/teamsAndOrgs/messageMembers';
import { Projects } from '../components/teamsAndOrgs/projects';
import { FormSubmitButton, CustomButton } from '../components/button';
import { DeleteModal } from '../components/deleteModal';
import { NotFound } from './notFound';
+import { useLocation } from '@reach/router';
+import DateRangePicker from '@wojtekmaj/react-daterange-picker';
+import { isObject } from '@turf/helpers';
export function ManageTeams() {
useSetTitleTag('Manage teams');
return ;
}
+export function MyTeamsUserSatsIndetailed() {
+ useSetTitleTag('My teams MyTeamsUserSatsIndetailed ');
+
+ useEffect(() => {
+ getUserNameBasedStats();
+ getUserNames();
+ }, []);
+
+ const token = useSelector((state) => state.auth.get('token'));
+
+ const [userNames, setUserNames] = useState({});
+
+ const getUserNames = async () => {
+ const response = await fetchLocalJSONAPI(`users/`, token);
+
+ const jsonData = await response.users;
+ //const jsonDataForDays = await response.day;
+ setUserNames(jsonData);
+ };
+
+ const location = useLocation();
+ let selectUserStats = [];
+ for (var i = 0; i < userNames.length; i++) {
+ var obj = {};
+ obj.value = userNames[i].username;
+ obj.label = userNames[i].username;
+ selectUserStats.push(obj);
+ }
+
+ let selectTaskSatus = [
+ { value: 'MAPPED', label: 'MAPPED' },
+ { value: 'VALIDATED', label: 'VALIDATED' },
+ ];
+ const maxDateApp = new Date();
+ const customStyles = {
+ headCells: {
+ style: {
+ fontSize: '15px',
+ fontWeight: 'bold',
+ },
+ },
+
+ cells: {
+ style: {
+ fontSize: '14px',
+ },
+ },
+ };
+
+ const popUpTableColumns = [
+ {
+ name: 'Task Url',
+ selector: 'TaskUrl',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ cell: (row) => (
+
+ Project {row.TaskUrl} - Task {row.TaskId}
+
+ ),
+ },
+ {
+ name: 'Task',
+ selector: 'TaskId',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ omit: 'yes',
+ },
+ {
+ name: 'Current State',
+ selector: 'CurrentState',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ },
+
+ {
+ name: ' Task Finish time ',
+ selector: 'TaskFinishTime',
+ sortable: true,
+ grow: 2,
+ minWidth: '100px',
+ },
+ {
+ name: 'Time spent on task (hh:mm:ss)',
+ selector: 'TimeSpentOnTask',
+ sortable: true,
+ grow: 2,
+
+ minWidth: '100px',
+ },
+ {
+ name: 'Validator',
+ selector: 'Reviewer',
+ sortable: true,
+ grow: 2,
+ minWidth: '200px',
+ },
+ ];
+ var dateObj = new Date();
+
+ // subtract one day from current time
+ dateObj.setDate(dateObj.getDate() - 7);
+ // const [value, onChange] = useState([new Date(), new Date()]);
+ let [value, onChange] = useState([dateObj, new Date()]);
+ let [selectedUserName, setSelectedUserName] = useState(null);
+ let [selectedTaskStatus, setSelectedTaskStatus] = useState(null);
+ const [teamMetricsStats, setTeamMetricsStats] = useState({});
+
+ const params = new URLSearchParams(location.search);
+
+ // You can access specific parameters:
+ let selectedStringName = params.get('name');
+ let selectedStatus = params.get('status');
+
+ let varSelectedUser = { value: selectedStringName, label: selectedStringName };
+ let defaultelectedStatus = { value: selectedStatus, label: selectedStatus };
+ let userNameSelected = varSelectedUser.value;
+
+ var convertSeconds = (sec) => {
+ var hrs = Math.floor(sec / 3600);
+ var min = Math.floor((sec - hrs * 3600) / 60);
+ var seconds = sec - hrs * 3600 - min * 60;
+ seconds = Math.round(seconds * 100) / 100;
+
+ var result = hrs < 10 ? '0' + hrs : hrs;
+ result += ':' + (min < 10 ? '0' + min : min);
+ result += ':' + (seconds < 10 ? '0' + seconds : seconds);
+ return result;
+ };
+ const getUserNameBasedStats = async () => {
+ var startDateFormatted = moment(value[0]).format('YYYY-MM -DD');
+
+ var endDateFormatted = moment(value[1]).format('YYYY-MM -DD');
+
+ const response = await fetchLocalJSONAPI(
+ `users/${userNameSelected}/tasks/?status=${selectedStatus}&start_date=${startDateFormatted}&end_date=${endDateFormatted}`,
+ token,
+ );
+ //const response = await fetchLocalJSONAPI(`users/${userName}/tasks/?status=MAPPED`, token);
+
+ const jsonData = await response.tasks;
+ //const jsonDataForDays = await response.day;
+ setTeamMetricsStats(jsonData);
+ };
+ let dataUserBasedStats = [];
+ //totaltime, mappingTotal, ValidationTotal;
+
+ for (let i = 0; i < teamMetricsStats.length; i++) {
+ let obj = {};
+
+ obj.TaskUrl = teamMetricsStats[i].project_id;
+ obj.TaskId = teamMetricsStats[i].tasks_id;
+ // obj.TimeinOSMTM = convertSeconds(teamMetricsStats[i].time_spent_mapping);
+ obj.CurrentState = teamMetricsStats[i].task_status;
+ obj.TaskFinishTime = moment(teamMetricsStats[i].action_date).format('DD-MM-YYYY HH:mm:ss');
+
+ obj.TimeSpentOnTask = convertSeconds(teamMetricsStats[i].total_time_spent);
+ obj.Reviewer = teamMetricsStats[i].reviewer;
+
+ dataUserBasedStats.push(obj);
+ }
+ const exporttoCsv = (dataArray, fileName) => {
+ const link = document.createElement('a');
+ let csv = convertArrayOfObjectsToCSV(dataArray);
+ if (csv == null) return;
+
+ const filename = fileName + 'export.csv';
+
+ if (!csv.match(/^data:text\/csv/i)) {
+ csv = `data:text/csv;charset=utf-8,${csv}`;
+ }
+
+ link.setAttribute('href', encodeURI(csv));
+ link.setAttribute('download', filename);
+ link.click();
+ };
+ function convertArrayOfObjectsToCSV(array) {
+ let result;
+
+ const columnDelimiter = ',';
+ const lineDelimiter = '\n';
+ const keys = Object.keys(array[0]);
+
+ result = '';
+ result += keys.join(columnDelimiter);
+ result += lineDelimiter;
+
+ array.forEach((item) => {
+ let ctr = 0;
+ keys.forEach((key) => {
+ if (ctr > 0) result += columnDelimiter;
+
+ result += item[key];
+
+ ctr++;
+ });
+ result += lineDelimiter;
+ });
+
+ return result;
+ }
+
+ function submitUserSelected(Values) {
+ selectedUserName = Values.value;
+ let taskStatus = '';
+ if (selectedTaskStatus) {
+ if (isObject(selectedTaskStatus)) {
+ taskStatus = selectedTaskStatus.value;
+ } else {
+ taskStatus = selectedTaskStatus;
+ }
+ } else {
+ taskStatus = 'MAPPED';
+ }
+ generateUserBasedMetricsStats(selectedUserName, taskStatus, value[0], value[1]);
+ //generateUserBasedMetricsStats();
+ }
+ function submitTaskSelected(Values) {
+ selectedTaskStatus = Values.value;
+ let userNameselected = '';
+ if (selectedUserName) {
+ userNameselected = selectedUserName.value;
+ } else {
+ userNameselected = userNameSelected;
+ }
+
+ generateUserBasedMetricsStats(userNameselected, selectedTaskStatus, value[0], value[1]);
+ }
+ var generateUserBasedMetricsStats = (userName, taskStatus, startDate, endDate) => {
+ var startDateFormatted = moment(startDate).format('YYYY-MM -DD');
+
+ var endDateFormatted = moment(endDate).format('YYYY-MM -DD');
+
+ let url = `users/${userName}/tasks/?status=${taskStatus}&start_date=${startDateFormatted}&end_date=${endDateFormatted}`;
+ fetchLocalJSONAPI(url, token)
+ .then((res) => {
+ // setTeamMetricsStats(res.team);
+ const responseData = res.tasks;
+ setTeamMetricsStats(responseData);
+ })
+ .catch((e) => console.log('call back failed in task index file' + e));
+ };
+
+ return (
+
+
+
+
+
+
+ |
+
+ |
+
+
+ |
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+
+
+ );
+}
+
export function MyTeams() {
useSetTitleTag('My teams');
return (
@@ -88,6 +412,7 @@ export function ListTeams({ managementView = false }: Object) {
userTeamsOnly={userTeamsOnly}
setUserTeamsOnly={setUserTeamsOnly}
/>
+
);
}
From 644ed8a5eb0a1b0b7edb340a854a5d7ee643ce7b Mon Sep 17 00:00:00 2001
From: hc00364289 <71371046+hc00364289@users.noreply.github.com>
Date: Mon, 14 Dec 2020 17:59:56 +0530
Subject: [PATCH 2/8] removed unnecessary code
---
frontend/src/components/teamsAndOrgs/teams.js | 29 -------------------
frontend/src/views/teams.js | 16 ++--------
2 files changed, 2 insertions(+), 43 deletions(-)
diff --git a/frontend/src/components/teamsAndOrgs/teams.js b/frontend/src/components/teamsAndOrgs/teams.js
index dc237d394..c6acde633 100644
--- a/frontend/src/components/teamsAndOrgs/teams.js
+++ b/frontend/src/components/teamsAndOrgs/teams.js
@@ -408,10 +408,7 @@ export function TeamsStats() {
const response = await fetchLocalJSONAPI(`teams/?member=${userId}`, token);
const jsonData = await response.teams;
- //const jsonDataForDays = await response.day;
setTeamNames(jsonData);
-
- console.log('team names are ***', jsonData);
};
let selectItems = [{ value: 'All', label: 'All' }];
@@ -431,10 +428,7 @@ export function TeamsStats() {
const jsonData = await response.team;
//const jsonDataForDays = await response.day;
setTeamMetricsStats(jsonData);
-
- console.log('user metrics stats are ***', jsonData);
};
- console.log('team metrics stats are ***', teamMetricsStats);
var convertSeconds = (sec) => {
var hrs = Math.floor(sec / 3600);
var min = Math.floor((sec - hrs * 3600) / 60);
@@ -448,7 +442,6 @@ export function TeamsStats() {
};
let dataSummaryResponse = [];
- //totaltime, mappingTotal, ValidationTotal;
for (let i = 0; i < teamMetricsStats.length; i++) {
let obj = {};
@@ -524,38 +517,22 @@ export function TeamsStats() {
];
function submitSelected(Values) {
- console.log('param sent is', Values.value);
- console.log('start time is', value[0]);
- console.log('end time is', value[1]);
-
generateTeamMetricsStats(Values.value, value[0], value[1]);
}
var generateTeamMetricsStats = (teamId, startDate, endDate) => {
- // console.log('select box value inside api call is', selectBoxValue.value);
var startDateFormatted = moment(startDate).format('YYYY-MM -DD');
var endDateFormatted = moment(endDate).format('YYYY-MM -DD');
- // const response = await fetchLocalJSONAPI(
- // `users/${userName}/userstaskmapped/ ?project_id=6&start_date=${startDateFormatted}&end_date=${endDateFormatted}`,
- // token,
- // );
-
- // const jsonData = await response.task;
- //const response = await fetchLocalJSONAPI(`users/HanumanthMapper/usersteamstats/`, token);
-
let url = '';
if (teamId === 'All') {
url = `users/${userName}/usersteamstats/?start_date=${startDateFormatted}&end_date=${endDateFormatted}`;
- //url = `users/${userName}/userstaskmapped/?start_date=${startDateFormatted}&end_date=${endDateFormatted}`;
} else {
url = `users/${userName}/usersteamstats/?team_id=${teamId}&start_date=${startDateFormatted}&end_date=${endDateFormatted}`;
}
fetchLocalJSONAPI(url, token)
.then((res) => {
- // setUserMetricsStats(res.team);
setTeamMetricsStats(res.team);
- //setUserMetricsGraphData(res.day);
})
.catch((e) => console.log('call back failed in task index file' + e));
};
@@ -632,10 +609,6 @@ export function TeamsStats() {
},
];
const exporttoCsv = (dataArray, fileName) => {
- console.log('array data', dataArray);
- console.log('afile name is', fileName);
- console.log('Start Date', value[0]);
- console.log('End Date is', value[1]);
const link = document.createElement('a');
let csv = convertArrayOfObjectsToCSV(dataArray);
if (csv == null) return;
@@ -677,9 +650,7 @@ export function TeamsStats() {
}
function handleRowClick(row, event) {
- console.log('row event clicked', row.UserName);
setSelectedUser(row.UserName);
- console.log('inside handle Row click for popup 1112', selectedUser);
}
const customStyles = {
diff --git a/frontend/src/views/teams.js b/frontend/src/views/teams.js
index 18e1939c7..6fc5e8ffe 100644
--- a/frontend/src/views/teams.js
+++ b/frontend/src/views/teams.js
@@ -52,14 +52,12 @@ export function MyTeamsUserSatsIndetailed() {
}, []);
const token = useSelector((state) => state.auth.get('token'));
-
const [userNames, setUserNames] = useState({});
-
const getUserNames = async () => {
const response = await fetchLocalJSONAPI(`users/`, token);
const jsonData = await response.users;
- //const jsonDataForDays = await response.day;
+
setUserNames(jsonData);
};
@@ -146,9 +144,8 @@ export function MyTeamsUserSatsIndetailed() {
];
var dateObj = new Date();
- // subtract one day from current time
+ // subtract seven day from current time
dateObj.setDate(dateObj.getDate() - 7);
- // const [value, onChange] = useState([new Date(), new Date()]);
let [value, onChange] = useState([dateObj, new Date()]);
let [selectedUserName, setSelectedUserName] = useState(null);
let [selectedTaskStatus, setSelectedTaskStatus] = useState(null);
@@ -184,24 +181,16 @@ export function MyTeamsUserSatsIndetailed() {
`users/${userNameSelected}/tasks/?status=${selectedStatus}&start_date=${startDateFormatted}&end_date=${endDateFormatted}`,
token,
);
- //const response = await fetchLocalJSONAPI(`users/${userName}/tasks/?status=MAPPED`, token);
-
const jsonData = await response.tasks;
- //const jsonDataForDays = await response.day;
setTeamMetricsStats(jsonData);
};
let dataUserBasedStats = [];
- //totaltime, mappingTotal, ValidationTotal;
-
for (let i = 0; i < teamMetricsStats.length; i++) {
let obj = {};
-
obj.TaskUrl = teamMetricsStats[i].project_id;
obj.TaskId = teamMetricsStats[i].tasks_id;
- // obj.TimeinOSMTM = convertSeconds(teamMetricsStats[i].time_spent_mapping);
obj.CurrentState = teamMetricsStats[i].task_status;
obj.TaskFinishTime = moment(teamMetricsStats[i].action_date).format('DD-MM-YYYY HH:mm:ss');
-
obj.TimeSpentOnTask = convertSeconds(teamMetricsStats[i].total_time_spent);
obj.Reviewer = teamMetricsStats[i].reviewer;
@@ -282,7 +271,6 @@ export function MyTeamsUserSatsIndetailed() {
let url = `users/${userName}/tasks/?status=${taskStatus}&start_date=${startDateFormatted}&end_date=${endDateFormatted}`;
fetchLocalJSONAPI(url, token)
.then((res) => {
- // setTeamMetricsStats(res.team);
const responseData = res.tasks;
setTeamMetricsStats(responseData);
})
From 15f3e1589dbdb1ce7614b8f1f674705a2e02b105 Mon Sep 17 00:00:00 2001
From: hc00364289 <71371046+hc00364289@users.noreply.github.com>
Date: Mon, 14 Dec 2020 21:24:05 +0530
Subject: [PATCH 3/8] code formating for csv export
---
frontend/src/components/teamsAndOrgs/teams.js | 47 ++----------------
.../components/userDetail/elementsMapped.js | 48 ++-----------------
frontend/src/network/genericCSVExport.js | 40 ++++++++++++++++
frontend/src/views/teams.js | 43 +----------------
4 files changed, 50 insertions(+), 128 deletions(-)
create mode 100644 frontend/src/network/genericCSVExport.js
diff --git a/frontend/src/components/teamsAndOrgs/teams.js b/frontend/src/components/teamsAndOrgs/teams.js
index c6acde633..aae8e657c 100644
--- a/frontend/src/components/teamsAndOrgs/teams.js
+++ b/frontend/src/components/teamsAndOrgs/teams.js
@@ -5,6 +5,7 @@ import { FormattedMessage } from 'react-intl';
import ReactPlaceholder from 'react-placeholder';
import { Form, Field } from 'react-final-form';
import { fetchLocalJSONAPI } from '../../network/genericJSONRequest';
+import { exporttoCSVFile } from '../../network/genericCSVExport';
import messages from './messages';
import { useEditTeamAllowed } from '../../hooks/UsePermissions';
import { UserAvatar, UserAvatarList } from '../user/avatar';
@@ -608,46 +609,6 @@ export function TeamsStats() {
minWidth: '200px',
},
];
- const exporttoCsv = (dataArray, fileName) => {
- const link = document.createElement('a');
- let csv = convertArrayOfObjectsToCSV(dataArray);
- if (csv == null) return;
-
- const filename = fileName + 'export.csv';
-
- if (!csv.match(/^data:text\/csv/i)) {
- csv = `data:text/csv;charset=utf-8,${csv}`;
- }
-
- link.setAttribute('href', encodeURI(csv));
- link.setAttribute('download', filename);
- link.click();
- };
- function convertArrayOfObjectsToCSV(array) {
- let result;
-
- const columnDelimiter = ',';
- const lineDelimiter = '\n';
- const keys = Object.keys(array[0]);
-
- result = '';
- result += keys.join(columnDelimiter);
- result += lineDelimiter;
-
- array.forEach((item) => {
- let ctr = 0;
- keys.forEach((key) => {
- if (ctr > 0) result += columnDelimiter;
-
- result += item[key];
-
- ctr++;
- });
- result += lineDelimiter;
- });
-
- return result;
- }
function handleRowClick(row, event) {
setSelectedUser(row.UserName);
@@ -720,7 +681,7 @@ export function TeamsStats() {
@@ -743,7 +704,7 @@ export function TeamsStats() {
@@ -763,7 +724,7 @@ export function TeamsStats() {
diff --git a/frontend/src/components/userDetail/elementsMapped.js b/frontend/src/components/userDetail/elementsMapped.js
index af1849d1e..35fd3a35a 100644
--- a/frontend/src/components/userDetail/elementsMapped.js
+++ b/frontend/src/components/userDetail/elementsMapped.js
@@ -12,6 +12,7 @@ import { Button } from '../button';
import { Line } from 'react-chartjs-2';
import Select from 'react-select';
import moment from 'moment';
+import { exporttoCSVFile } from '../../network/genericCSVExport';
import {
ClockIcon,
RoadIcon,
@@ -259,31 +260,6 @@ export const TaskStats = ({ userStats, username }) => {
},
];
- function convertArrayOfObjectsToCSV(array) {
- let result;
-
- const columnDelimiter = ',';
- const lineDelimiter = '\n';
- const keys = Object.keys(array[0]);
-
- result = '';
- result += keys.join(columnDelimiter);
- result += lineDelimiter;
-
- array.forEach((item) => {
- let ctr = 0;
- keys.forEach((key) => {
- if (ctr > 0) result += columnDelimiter;
-
- result += item[key];
-
- ctr++;
- });
- result += lineDelimiter;
- });
-
- return result;
- }
const state = {
labels: graphDays,
datasets: [
@@ -307,22 +283,6 @@ export const TaskStats = ({ userStats, username }) => {
],
};
- const exporttoCsv = (dataArray, fileName) => {
- const link = document.createElement('a');
- let csv = convertArrayOfObjectsToCSV(dataArray);
- if (csv == null) return;
-
- const filename = userName + '-' + fileName + 'export.csv';
-
- if (!csv.match(/^data:text\/csv/i)) {
- csv = `data:text/csv;charset=utf-8,${csv}`;
- }
-
- link.setAttribute('href', encodeURI(csv));
- link.setAttribute('download', filename);
- link.click();
- };
-
function submitSelected(Values) {
generateUserMetricsStats(Values.value, value[0], value[1]);
}
@@ -493,7 +453,7 @@ export const TaskStats = ({ userStats, username }) => {
@@ -531,7 +491,7 @@ export const TaskStats = ({ userStats, username }) => {
@@ -551,7 +511,7 @@ export const TaskStats = ({ userStats, username }) => {
diff --git a/frontend/src/network/genericCSVExport.js b/frontend/src/network/genericCSVExport.js
new file mode 100644
index 000000000..5e6dd538f
--- /dev/null
+++ b/frontend/src/network/genericCSVExport.js
@@ -0,0 +1,40 @@
+export function exporttoCSVFile(dataArray, fileName) {
+ const link = document.createElement('a');
+ let csv = convertArrayOfObjectsToCSV(dataArray);
+ if (csv == null) return;
+
+ const filename = fileName + 'export.csv';
+
+ if (!csv.match(/^data:text\/csv/i)) {
+ csv = `data:text/csv;charset=utf-8,${csv}`;
+ }
+
+ link.setAttribute('href', encodeURI(csv));
+ link.setAttribute('download', filename);
+ link.click();
+}
+function convertArrayOfObjectsToCSV(array) {
+ let result;
+
+ const columnDelimiter = ',';
+ const lineDelimiter = '\n';
+ const keys = Object.keys(array[0]);
+
+ result = '';
+ result += keys.join(columnDelimiter);
+ result += lineDelimiter;
+
+ array.forEach((item) => {
+ let ctr = 0;
+ keys.forEach((key) => {
+ if (ctr > 0) result += columnDelimiter;
+
+ result += item[key];
+
+ ctr++;
+ });
+ result += lineDelimiter;
+ });
+
+ return result;
+}
diff --git a/frontend/src/views/teams.js b/frontend/src/views/teams.js
index 6fc5e8ffe..e950e043a 100644
--- a/frontend/src/views/teams.js
+++ b/frontend/src/views/teams.js
@@ -11,6 +11,7 @@ import { useFetch } from '../hooks/UseFetch';
import { useEditTeamAllowed } from '../hooks/UsePermissions';
import { useSetTitleTag } from '../hooks/UseMetaTags';
import { fetchLocalJSONAPI, pushToLocalJSONAPI } from '../network/genericJSONRequest';
+import { exporttoCSVFile } from '../network/genericCSVExport';
import DataTable from 'react-data-table-component';
import { Button } from '../components/button';
import moment from 'moment';
@@ -196,46 +197,6 @@ export function MyTeamsUserSatsIndetailed() {
dataUserBasedStats.push(obj);
}
- const exporttoCsv = (dataArray, fileName) => {
- const link = document.createElement('a');
- let csv = convertArrayOfObjectsToCSV(dataArray);
- if (csv == null) return;
-
- const filename = fileName + 'export.csv';
-
- if (!csv.match(/^data:text\/csv/i)) {
- csv = `data:text/csv;charset=utf-8,${csv}`;
- }
-
- link.setAttribute('href', encodeURI(csv));
- link.setAttribute('download', filename);
- link.click();
- };
- function convertArrayOfObjectsToCSV(array) {
- let result;
-
- const columnDelimiter = ',';
- const lineDelimiter = '\n';
- const keys = Object.keys(array[0]);
-
- result = '';
- result += keys.join(columnDelimiter);
- result += lineDelimiter;
-
- array.forEach((item) => {
- let ctr = 0;
- keys.forEach((key) => {
- if (ctr > 0) result += columnDelimiter;
-
- result += item[key];
-
- ctr++;
- });
- result += lineDelimiter;
- });
-
- return result;
- }
function submitUserSelected(Values) {
selectedUserName = Values.value;
@@ -328,7 +289,7 @@ export function MyTeamsUserSatsIndetailed() {
From 463bfb668bcec36ab81110e2f8cc78690cd01d40 Mon Sep 17 00:00:00 2001
From: hc00364289 <71371046+hc00364289@users.noreply.github.com>
Date: Mon, 21 Dec 2020 16:25:20 +0530
Subject: [PATCH 4/8] Date format changes in metrics
---
frontend/src/components/teamsAndOrgs/teams.js | 46 ++++++++++---------
.../components/userDetail/elementsMapped.js | 15 +++---
frontend/src/network/genericCSVExport.js | 41 +++++++++++++----
frontend/src/views/teams.js | 38 +++++++++------
4 files changed, 89 insertions(+), 51 deletions(-)
diff --git a/frontend/src/components/teamsAndOrgs/teams.js b/frontend/src/components/teamsAndOrgs/teams.js
index aae8e657c..0e73b732f 100644
--- a/frontend/src/components/teamsAndOrgs/teams.js
+++ b/frontend/src/components/teamsAndOrgs/teams.js
@@ -5,7 +5,11 @@ import { FormattedMessage } from 'react-intl';
import ReactPlaceholder from 'react-placeholder';
import { Form, Field } from 'react-final-form';
import { fetchLocalJSONAPI } from '../../network/genericJSONRequest';
-import { exporttoCSVFile } from '../../network/genericCSVExport';
+import {
+ exporttoCSVFile,
+ convertStartDateTime,
+ convertEndDateTime,
+} from '../../network/genericCSVExport';
import messages from './messages';
import { useEditTeamAllowed } from '../../hooks/UsePermissions';
import { UserAvatar, UserAvatarList } from '../user/avatar';
@@ -19,7 +23,6 @@ import DataTable from 'react-data-table-component';
import DateRangePicker from '@wojtekmaj/react-daterange-picker';
import 'react-calendar/dist/Calendar.css';
import Select from 'react-select';
-import moment from 'moment';
export function TeamsManagement({
teams,
@@ -396,15 +399,17 @@ export function TeamsStats() {
const [teamMetricsStats, setTeamMetricsStats] = useState({});
const [teamNames, setTeamNames] = useState({});
- const startDate = moment(value[0]).format('YYYY-MM -DD');
-
- const endDate = moment(value[1]).format('YYYY-MM -DD');
-
- useEffect(() => {
- getTeamMetricsStats();
- getTeamNames();
- }, []);
+ let startDateTime = convertStartDateTime(value[0]);
+ let endDateTime = convertEndDateTime(value[1]);
+ const getTeamMetricsStats = async () => {
+ const response = await fetchLocalJSONAPI(
+ `users/${userName}/usersteamstats/?start_date=${startDateTime}&end_date=${endDateTime}`,
+ token,
+ );
+ const jsonData = await response.team;
+ setTeamMetricsStats(jsonData);
+ };
const getTeamNames = async () => {
const response = await fetchLocalJSONAPI(`teams/?member=${userId}`, token);
@@ -412,6 +417,11 @@ export function TeamsStats() {
setTeamNames(jsonData);
};
+ useEffect(() => {
+ getTeamMetricsStats();
+ getTeamNames();
+ }, []);
+
let selectItems = [{ value: 'All', label: 'All' }];
//selectItems
for (var i = 0; i < teamNames.length; i++) {
@@ -420,16 +430,7 @@ export function TeamsStats() {
obj.label = teamNames[i].name;
selectItems.push(obj);
}
- const getTeamMetricsStats = async () => {
- const response = await fetchLocalJSONAPI(
- `users/${userName}/usersteamstats/?start_date=${startDate}&end_date=${endDate}`,
- token,
- );
- const jsonData = await response.team;
- //const jsonDataForDays = await response.day;
- setTeamMetricsStats(jsonData);
- };
var convertSeconds = (sec) => {
var hrs = Math.floor(sec / 3600);
var min = Math.floor((sec - hrs * 3600) / 60);
@@ -521,9 +522,12 @@ export function TeamsStats() {
generateTeamMetricsStats(Values.value, value[0], value[1]);
}
var generateTeamMetricsStats = (teamId, startDate, endDate) => {
- var startDateFormatted = moment(startDate).format('YYYY-MM -DD');
+ // var startDateFormatted = moment(startDate).format('YYYY-MM -DD');
+
+ // var endDateFormatted = moment(endDate).format('YYYY-MM -DD');
+ var startDateFormatted = convertStartDateTime(startDate);
- var endDateFormatted = moment(endDate).format('YYYY-MM -DD');
+ var endDateFormatted = convertEndDateTime(endDate);
let url = '';
if (teamId === 'All') {
diff --git a/frontend/src/components/userDetail/elementsMapped.js b/frontend/src/components/userDetail/elementsMapped.js
index 35fd3a35a..8ea823d3d 100644
--- a/frontend/src/components/userDetail/elementsMapped.js
+++ b/frontend/src/components/userDetail/elementsMapped.js
@@ -12,7 +12,11 @@ import { Button } from '../button';
import { Line } from 'react-chartjs-2';
import Select from 'react-select';
import moment from 'moment';
-import { exporttoCSVFile } from '../../network/genericCSVExport';
+import {
+ exporttoCSVFile,
+ convertStartDateTime,
+ convertEndDateTime,
+} from '../../network/genericCSVExport';
import {
ClockIcon,
RoadIcon,
@@ -117,8 +121,6 @@ export const TaskStats = ({ userStats, username }) => {
dateObj.setDate(dateObj.getDate() - 7);
const [value, onChange] = useState([dateObj, new Date()]);
- const startDate = moment(value[0]).format('YYYY-MM -DD');
- const endDate = moment(value[1]).format('YYYY-MM -DD');
const getProjectNames = async () => {
const response = await fetchLocalJSONAPI(`projects/`, token);
const jsonData = await response.results;
@@ -131,6 +133,8 @@ export const TaskStats = ({ userStats, username }) => {
obj.label = projectNames[i].name;
selectItems.push(obj);
}
+ const startDate = convertStartDateTime(value[0]);
+ const endDate = convertEndDateTime(value[1]);
const getUserMetricsStats = async () => {
const response = await fetchLocalJSONAPI(
@@ -287,9 +291,8 @@ export const TaskStats = ({ userStats, username }) => {
generateUserMetricsStats(Values.value, value[0], value[1]);
}
var generateUserMetricsStats = (projId, startDate, endDate) => {
- var startDateFormatted = moment(startDate).format('YYYY-MM -DD');
- var endDateFormatted = moment(endDate).format('YYYY-MM -DD');
-
+ var startDateFormatted = convertStartDateTime(startDate);
+ var endDateFormatted = convertEndDateTime(endDate);
let url = '';
if (projId === 'All') {
url = `users/${userName}/userstaskmapped/?start_date=${startDateFormatted}&end_date=${endDateFormatted}`;
diff --git a/frontend/src/network/genericCSVExport.js b/frontend/src/network/genericCSVExport.js
index 5e6dd538f..1607c4ca1 100644
--- a/frontend/src/network/genericCSVExport.js
+++ b/frontend/src/network/genericCSVExport.js
@@ -1,17 +1,20 @@
+import moment from 'moment';
export function exporttoCSVFile(dataArray, fileName) {
- const link = document.createElement('a');
- let csv = convertArrayOfObjectsToCSV(dataArray);
- if (csv == null) return;
+ if (dataArray && dataArray.length > 0) {
+ const link = document.createElement('a');
+ let csv = convertArrayOfObjectsToCSV(dataArray);
+ if (csv == null) return;
- const filename = fileName + 'export.csv';
+ const filename = fileName + 'export.csv';
- if (!csv.match(/^data:text\/csv/i)) {
- csv = `data:text/csv;charset=utf-8,${csv}`;
- }
+ if (!csv.match(/^data:text\/csv/i)) {
+ csv = `data:text/csv;charset=utf-8,${csv}`;
+ }
- link.setAttribute('href', encodeURI(csv));
- link.setAttribute('download', filename);
- link.click();
+ link.setAttribute('href', encodeURI(csv));
+ link.setAttribute('download', filename);
+ link.click();
+ }
}
function convertArrayOfObjectsToCSV(array) {
let result;
@@ -38,3 +41,21 @@ function convertArrayOfObjectsToCSV(array) {
return result;
}
+
+export function convertStartDateTime(value) {
+ let dateTime = new Date(value);
+ dateTime.setHours(0);
+ dateTime.setMinutes(0);
+ dateTime.setSeconds(0);
+ let result = moment(dateTime).format('YYYY-MM-DD HH:mm:ss');
+ return result;
+}
+export function convertEndDateTime(value) {
+ let dateTime = new Date(value);
+ dateTime.setHours(11);
+ dateTime.setMinutes(59);
+ dateTime.setSeconds(59);
+
+ let result = moment(dateTime).format('YYYY-MM-DD HH:mm:ss');
+ return result;
+}
diff --git a/frontend/src/views/teams.js b/frontend/src/views/teams.js
index e950e043a..1541c705e 100644
--- a/frontend/src/views/teams.js
+++ b/frontend/src/views/teams.js
@@ -11,7 +11,11 @@ import { useFetch } from '../hooks/UseFetch';
import { useEditTeamAllowed } from '../hooks/UsePermissions';
import { useSetTitleTag } from '../hooks/UseMetaTags';
import { fetchLocalJSONAPI, pushToLocalJSONAPI } from '../network/genericJSONRequest';
-import { exporttoCSVFile } from '../network/genericCSVExport';
+import {
+ exporttoCSVFile,
+ convertStartDateTime,
+ convertEndDateTime,
+} from '../network/genericCSVExport';
import DataTable from 'react-data-table-component';
import { Button } from '../components/button';
import moment from 'moment';
@@ -72,8 +76,12 @@ export function MyTeamsUserSatsIndetailed() {
}
let selectTaskSatus = [
- { value: 'MAPPED', label: 'MAPPED' },
- { value: 'VALIDATED', label: 'VALIDATED' },
+ { value: 'MAPPED', label: 'Mapped' },
+ { value: 'LOCKED_FOR_MAPPING', label: 'Locked For Mapping ' },
+ { value: 'VALIDATED', label: 'Validated' },
+ { value: 'LOCKED_FOR_VALIDATION', label: 'Locked For Validation ' },
+ { value: 'INVALIDATED', label: 'In Validated' },
+ { value: 'BADIMAGERY', label: 'BadImagery' },
];
const maxDateApp = new Date();
const customStyles = {
@@ -121,8 +129,8 @@ export function MyTeamsUserSatsIndetailed() {
},
{
- name: ' Task Finish time ',
- selector: 'TaskFinishTime',
+ name: ' Status Change Time',
+ selector: 'StatusChangeTime',
sortable: true,
grow: 2,
minWidth: '100px',
@@ -174,9 +182,12 @@ export function MyTeamsUserSatsIndetailed() {
return result;
};
const getUserNameBasedStats = async () => {
- var startDateFormatted = moment(value[0]).format('YYYY-MM -DD');
+ // var startDateFormatted = moment(value[0]).format('YYYY-MM -DD');
+
+ // var endDateFormatted = moment(value[1]).format('YYYY-MM -DD');
+ var startDateFormatted = convertStartDateTime(value[0]);
- var endDateFormatted = moment(value[1]).format('YYYY-MM -DD');
+ var endDateFormatted = convertEndDateTime(value[1]);
const response = await fetchLocalJSONAPI(
`users/${userNameSelected}/tasks/?status=${selectedStatus}&start_date=${startDateFormatted}&end_date=${endDateFormatted}`,
@@ -191,7 +202,8 @@ export function MyTeamsUserSatsIndetailed() {
obj.TaskUrl = teamMetricsStats[i].project_id;
obj.TaskId = teamMetricsStats[i].tasks_id;
obj.CurrentState = teamMetricsStats[i].task_status;
- obj.TaskFinishTime = moment(teamMetricsStats[i].action_date).format('DD-MM-YYYY HH:mm:ss');
+
+ obj.StatusChangeTime = moment(teamMetricsStats[i].action_date).format('DD-MM-YYYY HH:mm:ss');
obj.TimeSpentOnTask = convertSeconds(teamMetricsStats[i].total_time_spent);
obj.Reviewer = teamMetricsStats[i].reviewer;
@@ -225,10 +237,8 @@ export function MyTeamsUserSatsIndetailed() {
generateUserBasedMetricsStats(userNameselected, selectedTaskStatus, value[0], value[1]);
}
var generateUserBasedMetricsStats = (userName, taskStatus, startDate, endDate) => {
- var startDateFormatted = moment(startDate).format('YYYY-MM -DD');
-
- var endDateFormatted = moment(endDate).format('YYYY-MM -DD');
-
+ var startDateFormatted = convertStartDateTime(startDate);
+ var endDateFormatted = convertEndDateTime(endDate);
let url = `users/${userName}/tasks/?status=${taskStatus}&start_date=${startDateFormatted}&end_date=${endDateFormatted}`;
fetchLocalJSONAPI(url, token)
.then((res) => {
@@ -259,7 +269,7 @@ export function MyTeamsUserSatsIndetailed() {
/>
|
-
+
|
|
- |
From d9c838e667df4eeb4e32fa0e1730d8fe9fa1a2d2 Mon Sep 17 00:00:00 2001
From: hc00364289 <71371046+hc00364289@users.noreply.github.com>
Date: Mon, 21 Dec 2020 19:40:26 +0530
Subject: [PATCH 5/8] API files for Metrics
---
backend/__init__.py | 16 +-
backend/api/users/statistics.py | 225 +++-
backend/models/dtos/user_dto.py | 21 +-
backend/services/users/user_service.py | 1537 +++++++++++++++++++++++-
4 files changed, 1792 insertions(+), 7 deletions(-)
diff --git a/backend/__init__.py b/backend/__init__.py
index ecd298df7..ef709428d 100644
--- a/backend/__init__.py
+++ b/backend/__init__.py
@@ -250,6 +250,9 @@ def add_api_endpoints(app):
from backend.api.users.statistics import (
UsersStatisticsAPI,
UsersStatisticsInterestsAPI,
+ UsersTaskMappedAPI,
+ UsersTeamStatsAPI,
+ UserSpecificAPI,
)
# System API endpoint
@@ -518,7 +521,6 @@ def add_api_endpoints(app):
TasksActionsSplitAPI,
format_url("projects//tasks/actions/split//"),
)
-
# Comments REST endoints
api.add_resource(
CommentsProjectsRestAPI,
@@ -677,6 +679,7 @@ def add_api_endpoints(app):
# Users REST endpoint
api.add_resource(UsersAllAPI, format_url("users/"))
api.add_resource(UsersRestAPI, format_url("users//"))
+
api.add_resource(
UsersQueriesUsernameFilterAPI,
format_url("users/queries/filter//"),
@@ -712,6 +715,7 @@ def add_api_endpoints(app):
)
api.add_resource(UsersTasksAPI, format_url("users//tasks/"))
+
api.add_resource(
UsersActionsVerifyEmailAPI, format_url("users/me/actions/verify-email/")
)
@@ -724,6 +728,16 @@ def add_api_endpoints(app):
UsersStatisticsAPI, format_url("users//statistics/")
)
+ api.add_resource(
+ UsersTaskMappedAPI, format_url("users//userstaskmapped/")
+ )
+
+ api.add_resource(
+ UsersTeamStatsAPI, format_url("users//usersteamstats/")
+ )
+
+ api.add_resource(UserSpecificAPI, format_url("users//tasks/"))
+
# User RecommendedProjects endpoint
api.add_resource(
UsersRecommendedProjectsAPI,
diff --git a/backend/api/users/statistics.py b/backend/api/users/statistics.py
index bd5d4eeb8..4abb9a60d 100644
--- a/backend/api/users/statistics.py
+++ b/backend/api/users/statistics.py
@@ -1,7 +1,8 @@
-from flask_restful import Resource, current_app
+from flask_restful import Resource, current_app, request
from backend.services.users.user_service import UserService, NotFound
from backend.services.interests_service import InterestService
from backend.services.users.authentication_service import token_auth
+from dateutil.parser import parse as date_parse
class UsersStatisticsAPI(Resource):
@@ -27,6 +28,7 @@ def get(self, username):
required: true
type: string
default: Thinkwhere
+
responses:
200:
description: User found
@@ -87,3 +89,224 @@ def get(self, user_id):
error_msg = f"Interest GET - unhandled error: {str(e)}"
current_app.logger.critical(error_msg)
return {"Error": error_msg}, 500
+
+
+class UsersTaskMappedAPI(Resource):
+ @token_auth.login_required
+ def get(self, username):
+ """
+ Get detailed stats about a user by OpenStreetMap username
+ ---
+ tags:
+ - users
+ produces:
+ - application/json
+ parameters:
+ - in: header
+ name: Authorization
+ description: Base64 encoded session token
+ required: true
+ type: string
+ default: Token sessionTokenHere==
+ - name: username
+ in: path
+ description: Mapper's OpenStreetMap username
+ required: true
+ type: string
+ default: Thinkwhere
+ - in: query
+ name: project_id
+ description: Project id
+ required: false
+ type: integer
+ default: null
+ - in: query
+ name: start_date
+ description: Date to filter as minimum
+ required: false
+ type: string
+ default: null
+ - in: query
+ name: end_date
+ description: Date to filter as maximum
+ required: false
+ type: string
+ default: null
+
+ responses:
+ 200:
+ description: User found
+ 401:
+ description: Unauthorized - Invalid credentials
+ 404:
+ description: User not found
+ 500:
+ description: Internal Server Error
+ """
+ try:
+ project_id = int(request.args.get("project_id", 0))
+ start_date = (
+ date_parse(request.args.get("start_date"))
+ if request.args.get("start_date")
+ else None
+ )
+ end_date = (
+ date_parse(request.args.get("end_date"))
+ if request.args.get("end_date")
+ else None
+ )
+ tasks_dto = UserService.get_tasks_mapped(username, start_date=start_date, end_date=end_date, project_id=project_id,)
+
+ return tasks_dto.to_primitive(), 200
+ except NotFound:
+ return {"Error": "User not found"}, 404
+ except Exception as e:
+ error_msg = f"User GET - unhandled error: {str(e)}"
+ current_app.logger.critical(error_msg)
+ return {"Error": "Unable to fetch user statistics"}, 500
+
+
+class UsersTeamStatsAPI(Resource):
+ @token_auth.login_required
+ def get(self, username):
+ """
+ Get detailed stats about a user by OpenStreetMap username
+ ---
+ tags:
+ - users
+ produces:
+ - application/json
+ parameters:
+ - in: header
+ name: Authorization
+ description: Base64 encoded session token
+ required: true
+ type: string
+ default: Token sessionTokenHere==
+ - name: username
+ in: path
+ description: Mapper's OpenStreetMap username
+ required: true
+ type: string
+ default: Thinkwhere
+ - in: query
+ name: team_id
+ description: Team Id
+ required: false
+ type: integer
+ default: null
+ - in: query
+ name: start_date
+ description: Date to filter as minimum
+ required: false
+ type: string
+ default: null
+ - in: query
+ name: end_date
+ description: Date to filter as maximum
+ required: false
+ type: string
+ default: null
+
+ responses:
+ 200:
+ description: User found
+ 401:
+ description: Unauthorized - Invalid credentials
+ 404:
+ description: User not found
+ 500:
+ description: Internal Server Error
+ """
+ try:
+ team_id = int(request.args.get("team_id", 0))
+ start_date = (
+ date_parse(request.args.get("start_date"))
+ if request.args.get("start_date")
+ else None
+ )
+ end_date = (
+ date_parse(request.args.get("end_date"))
+ if request.args.get("end_date")
+ else None
+ )
+ teams_dto = UserService.get_teams_stats(username, start_date=start_date, end_date=end_date, team_id=team_id,)
+
+ return teams_dto.to_primitive(), 200
+ except NotFound:
+ return {"Error": "User not found"}, 404
+ except Exception as e:
+ error_msg = f"User GET - unhandled error: {str(e)}"
+ current_app.logger.critical(error_msg)
+ return {"Error": "Unable to fetch user statistics"}, 500
+
+
+class UserSpecificAPI(Resource):
+ @token_auth.login_required
+ def get(self, username):
+ """
+ Get a list of tasks a user has interacted with
+ ---
+ tags:
+ - users
+ produces:
+ - application/json
+ parameters:
+ - in: header
+ name: Authorization
+ description: Base64 encoded session token
+ required: true
+ type: string
+ default: Token sessionTokenHere==
+ - name: username
+ in: path
+ description: Mapper's OpenStreetMap username
+ required: true
+ type: string
+ default: Thinkwhere
+ - in: query
+ name: status
+ description: Task Status filter mapped/validated
+ required: false
+ type: string
+ default: null
+ - in: query
+ name: start_date
+ description: Date to filter as minimum
+ required: false
+ type: string
+ default: null
+ - in: query
+ name: end_date
+ description: Date to filter as maximum
+ required: false
+ type: string
+ default: null
+ responses:
+ 200:
+ description: Mapped projects found
+ 404:
+ description: No mapped projects found
+ 500:
+ description: Internal Server Error
+ """
+ try:
+ status = request.args.get("status")
+ start_date = (
+ date_parse(request.args.get("start_date"))
+ if request.args.get("start_date")
+ else None
+ )
+ end_date = (
+ date_parse(request.args.get("end_date"))
+ if request.args.get("end_date")
+ else None
+ )
+ tasks = UserService.get_user_specific_task(username, task_status=status, start_date=start_date, end_date=end_date,)
+ return tasks.to_primitive(), 200
+ except NotFound:
+ return {"Error": "User or tasks not found"}, 404
+ except Exception as e:
+ error_msg = f"User GET - unhandled error: {str(e)}"
+ current_app.logger.critical(error_msg)
+ return {"error": error_msg}, 500
diff --git a/backend/models/dtos/user_dto.py b/backend/models/dtos/user_dto.py
index d08cf16f8..2ff1a6a98 100644
--- a/backend/models/dtos/user_dto.py
+++ b/backend/models/dtos/user_dto.py
@@ -58,6 +58,7 @@ class UserDTO(Model):
is_email_verified = EmailType(
serialized_name="isEmailVerified", serialize_when_none=False
)
+
is_expert = BooleanType(serialized_name="isExpert", serialize_when_none=False)
twitter_id = StringType(serialized_name="twitterId")
facebook_id = StringType(serialized_name="facebookId")
@@ -125,7 +126,7 @@ class UserContributionDTO(Model):
class UserStatsDTO(Model):
""" DTO containing statistics about the user """
-
+
total_time_spent = IntType(serialized_name="totalTimeSpent")
time_spent_mapping = IntType(serialized_name="timeSpentMapping")
time_spent_validating = IntType(serialized_name="timeSpentValidating")
@@ -145,7 +146,6 @@ class UserStatsDTO(Model):
ModelType(InterestDTO), serialized_name="ContributionsByInterest"
)
-
class UserOSMDTO(Model):
""" DTO containing OSM details for the user """
@@ -252,3 +252,20 @@ def __init__(self):
user_tasks = ListType(ModelType(TaskDTO), serialized_name="tasks")
pagination = ModelType(Pagination)
+
+class UserMappedDTO(Model):
+ """ DTO containing statistics about the user """
+
+ task = ListType(IntType(serialized_name="task"))
+ day = ListType(IntType(serialized_name="day"))
+
+class UserTeamStatsDTO(Model):
+ """ DTO containing statistics about the teams """
+
+ team = ListType(IntType(serialized_name="team"))
+
+
+class UserSpecificDTO(Model):
+ """ DTO containing stats about the user """
+
+ tasks = ListType(IntType(serialized_name="tasks"))
\ No newline at end of file
diff --git a/backend/services/users/user_service.py b/backend/services/users/user_service.py
index 78a0f4773..b4dc1ef91 100644
--- a/backend/services/users/user_service.py
+++ b/backend/services/users/user_service.py
@@ -1,6 +1,8 @@
from cachetools import TTLCache, cached
from flask import current_app
import datetime
+from functools import reduce
+import dateutil.parser
from sqlalchemy.sql.expression import literal
from sqlalchemy import func, or_, desc, and_, distinct, cast, Time
from backend import db
@@ -16,11 +18,16 @@
UserRegisterEmailDTO,
UserCountryContributed,
UserCountriesContributed,
+ UserMappedDTO,
+ UserTeamStatsDTO,
+ UserSpecificDTO,
+
)
from backend.models.dtos.interests_dto import InterestsListDTO, InterestDTO
from backend.models.postgis.interests import Interest, project_interests
from backend.models.postgis.message import Message
from backend.models.postgis.project import Project
+from backend.models.postgis.project_info import ProjectInfo
from backend.models.postgis.user import User, UserRole, MappingLevel, UserEmail
from backend.models.postgis.task import TaskHistory, TaskAction, Task
from backend.models.dtos.user_dto import UserTaskDTOs
@@ -33,7 +40,9 @@
get_template,
template_var_replacing,
)
-
+from backend.models.postgis.team import TeamMembers, Team
+from backend.models.postgis.user import User
+from datetime import timedelta
user_filter_cache = TTLCache(maxsize=1024, ttl=600)
@@ -139,6 +148,8 @@ def get_projects_mapped(user_id: int):
return projects_mapped
+
+
@staticmethod
def register_user(osm_id, username, changeset_count, picture_url, email):
"""
@@ -263,7 +274,6 @@ def get_tasks_dto(
user_task_dtos = UserTaskDTOs()
task_id_list = base_query.subquery()
-
tasks = Task.query.join(
task_id_list,
and_(
@@ -283,7 +293,6 @@ def get_tasks_dto(
tasks = tasks.filter_by(project_id=project_id)
results = tasks.paginate(page, page_size, True)
-
task_list = []
for task, action_date in results.items:
@@ -798,3 +807,1525 @@ def get_interests(user: User) -> InterestsListDTO:
dto.interests.append(int_dto)
return dto
+
+ @staticmethod
+ def get_tasks_mapped(
+ username,
+ start_date: datetime.datetime = None,
+ end_date: datetime.datetime = None,
+ project_id: int = None,
+ ):
+ user = UserService.get_user_by_username(username)
+ tasks_dto = UserMappedDTO()
+
+ actions = [
+ TaskStatus.VALIDATED.name,
+ TaskStatus.INVALIDATED.name,
+ TaskStatus.MAPPED.name,
+ ]
+
+ actions_table = (
+ db.session.query(literal(TaskStatus.VALIDATED.name).label("action_text"))
+ .union(
+ db.session.query(
+ literal(TaskStatus.INVALIDATED.name).label("action_text")
+ ),
+ db.session.query(literal(TaskStatus.MAPPED.name).label("action_text")),
+ )
+ .subquery()
+ .alias("actions_table")
+ )
+
+ days_list = []
+
+ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=None, project_id: int=None):
+ days = []
+
+ for i in range((end_date-start_date).days):
+ days.append(start_date)
+ start_date += datetime.timedelta(days=1)
+
+ if ((start_date and end_date)and not project_id):
+ for i in range(len(days)):
+
+ for j in range(len(days)):
+ proj_ids = (TaskHistory.query.with_entities(TaskHistory.project_id).filter(TaskHistory.action_date>=days[i])
+ .filter(TaskHistory.action_date<=days[i]+datetime.timedelta(days=1)).group_by(TaskHistory.project_id)).all()
+ projid=[lis[0] for lis in proj_ids]
+
+ avg_time_spent_mapping = 0
+ avg_time_spent_validating = 0
+ total_time_spent = 0
+ time_spent_mapping = 0
+ time_spent_validating = 0
+ total_mapping_time = 0
+ total_validation_time = 0
+
+ filtered_actions = (
+ TaskHistory.query.with_entities(
+ TaskHistory.user_id,
+ TaskHistory.project_id,
+ TaskHistory.task_id,
+ TaskHistory.action_text,
+ TaskHistory.action_date,
+ )
+ .filter(TaskHistory.action_text.in_(actions))
+ .filter(TaskHistory.user_id==user.id)
+ .filter(TaskHistory.action_date>=days[i])
+ .filter(TaskHistory.action_date<=days[i]+datetime.timedelta(days=1))
+
+ .subquery()
+ .alias("filtered_actions")
+
+ )
+
+ user_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id == user.id)
+ .subquery()
+ .alias("user_tasks")
+ )
+
+ others_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id != user.id)
+ .filter(filtered_actions.c.task_id == user_tasks.c.task_id)
+ .filter(filtered_actions.c.project_id == user_tasks.c.project_id)
+ .filter(filtered_actions.c.action_text != TaskStatus.MAPPED.name)
+
+ .subquery()
+ .alias("others_tasks")
+ )
+
+ user_stats = (
+ db.session.query(
+ actions_table.c.action_text, func.count(user_tasks.c.action_text)
+ )
+ .outerjoin(
+ user_tasks, actions_table.c.action_text == user_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+
+ )
+
+ others_stats = (
+ db.session.query(
+ func.concat(actions_table.c.action_text, "_BY_OTHERS"),
+ func.count(others_tasks.c.action_text),
+ )
+ .outerjoin(
+ others_tasks, actions_table.c.action_text == others_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+ )
+
+ res = user_stats.union(others_stats).all()
+ results = {key: value for key, value in res}
+
+ query = (
+ TaskHistory.query.with_entities(
+ func.date_trunc("minute", TaskHistory.action_date).label("trn"),
+ func.max(TaskHistory.action_text).label("tm"),
+ )
+ .filter(TaskHistory.user_id == user.id)
+ .filter(TaskHistory.action == "LOCKED_FOR_VALIDATION")
+ .filter(TaskHistory.action_date>=days[i])
+ .filter(TaskHistory.action_date<=days[i]+datetime.timedelta(days=1))
+ .group_by("trn", TaskHistory.project_id)
+ .subquery()
+ )
+ total_validation_time = db.session.query(
+ func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
+ ).scalar()
+
+
+
+ if total_validation_time:
+ time_spent_validating = total_validation_time.total_seconds()
+ avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
+ total_time_spent += time_spent_validating
+
+ total_mapping_time = (
+ db.session.query(
+ func.sum(
+ cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
+ )
+ )
+
+ .filter(
+ or_(
+ TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
+ TaskHistory.action == TaskAction.AUTO_UNLOCKED_FOR_MAPPING.name,
+ )
+ )
+ .filter(TaskHistory.user_id == user.id)
+ .filter(TaskHistory.action_date>=days[i])
+ .filter(TaskHistory.action_date<=days[i]+datetime.timedelta(days=1))
+
+ .scalar()
+
+ )
+ if total_mapping_time:
+ time_spent_mapping = total_mapping_time.total_seconds()
+ avg_time_spent_mapping += (time_spent_mapping/int(results["MAPPED"])) if int(results["MAPPED"]) != 0 else 0
+ total_time_spent += time_spent_mapping
+
+ days_list.append({"date":str(days[i]),
+ "project_id":projid,
+ "tasks_mapped":(results["MAPPED"]),
+ "tasks_validated":(results["VALIDATED"]),
+ "tasks_invalidated":(results["INVALIDATED"]),
+ "tasks_validated_by_others":(results["VALIDATED_BY_OTHERS"]),
+ "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
+ "total_time_spent":total_time_spent,
+ "time_spent_mapping":time_spent_mapping,
+ "average_time_spent_mapping":avg_time_spent_mapping,
+ "time_spent_validating":time_spent_validating,
+ "average_time_spent_validating":avg_time_spent_validating})
+ break
+
+ elif((start_date and end_date)and project_id):
+ for i in range(len(days)):
+
+ for j in range(len(days)):
+
+ avg_time_spent_mapping = 0
+ avg_time_spent_validating = 0
+ total_time_spent = 0
+ time_spent_mapping = 0
+ time_spent_validating = 0
+ total_mapping_time = 0
+ total_validation_time = 0
+
+ filtered_actions = (
+ TaskHistory.query.with_entities(
+ TaskHistory.user_id,
+ TaskHistory.project_id,
+ TaskHistory.task_id,
+ TaskHistory.action_text,
+ TaskHistory.action_date,
+ )
+ .filter(TaskHistory.action_text.in_(actions))
+ .filter(TaskHistory.project_id == project_id)
+ .filter(TaskHistory.user_id==user.id)
+ .filter(TaskHistory.action_date>=days[i])
+ .filter(TaskHistory.action_date<=days[i]+datetime.timedelta(days=1))
+
+ .subquery()
+ .alias("filtered_actions")
+
+ )
+
+ user_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id == user.id)
+ .subquery()
+ .alias("user_tasks")
+ )
+
+ others_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id != user.id)
+ .filter(filtered_actions.c.task_id == user_tasks.c.task_id)
+ .filter(filtered_actions.c.project_id == user_tasks.c.project_id)
+ .filter(filtered_actions.c.action_text != TaskStatus.MAPPED.name)
+
+ .subquery()
+ .alias("others_tasks")
+ )
+
+ user_stats = (
+ db.session.query(
+ actions_table.c.action_text, func.count(user_tasks.c.action_text)
+ )
+ .outerjoin(
+ user_tasks, actions_table.c.action_text == user_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+
+ )
+
+ others_stats = (
+ db.session.query(
+ func.concat(actions_table.c.action_text, "_BY_OTHERS"),
+ func.count(others_tasks.c.action_text),
+ )
+ .outerjoin(
+ others_tasks, actions_table.c.action_text == others_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+ )
+
+ res = user_stats.union(others_stats).all()
+ results = {key: value for key, value in res}
+
+ query = (
+ TaskHistory.query.with_entities(
+ func.date_trunc("minute", TaskHistory.action_date).label("trn"),
+ func.max(TaskHistory.action_text).label("tm"),
+ )
+ .filter(TaskHistory.user_id == user.id)
+ .filter(TaskHistory.action == "LOCKED_FOR_VALIDATION")
+ .filter(TaskHistory.project_id==project_id)
+ .filter(TaskHistory.action_date>=days[i])
+ .filter(TaskHistory.action_date<=days[i]+datetime.timedelta(days=1))
+ .group_by("trn", TaskHistory.project_id)
+ .subquery()
+ )
+ total_validation_time = db.session.query(
+ func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
+ ).scalar()
+
+
+
+ if total_validation_time:
+ time_spent_validating = total_validation_time.total_seconds()
+ avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
+ total_time_spent += time_spent_validating
+
+ total_mapping_time = (
+ db.session.query(
+ func.sum(
+ cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
+ )
+ )
+
+ .filter(
+ or_(
+ TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
+ TaskHistory.action == TaskAction.AUTO_UNLOCKED_FOR_MAPPING.name,
+ )
+ )
+ .filter(TaskHistory.user_id == user.id)
+ .filter(TaskHistory.action_date>=days[i])
+ .filter(TaskHistory.action_date<=days[i]+datetime.timedelta(days=1))
+ .filter(TaskHistory.project_id == project_id)
+
+ .scalar()
+
+ )
+ if total_mapping_time:
+ time_spent_mapping = total_mapping_time.total_seconds()
+ avg_time_spent_mapping += (time_spent_mapping/int(results["MAPPED"])) if int(results["MAPPED"]) != 0 else 0
+ total_time_spent += time_spent_mapping
+
+
+ days_list.append({"date":str(days[i]),
+ "project_id":project_id,
+ "tasks_mapped":(results["MAPPED"]),
+ "tasks_validated":(results["VALIDATED"]),
+ "tasks_invalidated":(results["INVALIDATED"]),
+ "tasks_validated_by_others":(results["VALIDATED_BY_OTHERS"]),
+ "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
+ "total_time_spent":total_time_spent,
+ "time_spent_mapping":time_spent_mapping,
+ "average_time_spent_mapping":avg_time_spent_mapping,
+ "time_spent_validating":time_spent_validating,
+ "average_time_spent_validating":avg_time_spent_validating})
+ break
+ return days_list
+
+
+ task_list=[]
+
+ if (project_id and (start_date and end_date)):
+ date_function(start_date, end_date, project_id)
+
+ proj_query = ProjectInfo.query.with_entities(ProjectInfo.name).filter(ProjectInfo.project_id==project_id)
+ proj_name=[lis[0] for lis in proj_query]
+
+ avg_time_spent_mapping = 0
+ avg_time_spent_validating = 0
+ total_time_spent = 0
+ time_spent_mapping = 0
+ time_spent_validating = 0
+ total_mapping_time = 0
+ total_validation_time = 0
+
+ filtered_actions = (
+ TaskHistory.query.with_entities(
+ TaskHistory.user_id,
+ TaskHistory.project_id,
+ TaskHistory.task_id,
+ TaskHistory.action_text,
+ TaskHistory.action_date,
+ )
+ .filter(TaskHistory.action_text.in_(actions))
+ .filter(TaskHistory.project_id == project_id)
+ .filter(TaskHistory.action_date>=start_date)
+ .filter(TaskHistory.action_date<=end_date)
+ .subquery()
+ .alias("filtered_actions")
+
+ )
+ user_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id == user.id)
+ .subquery()
+ .alias("user_tasks")
+ )
+
+ others_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id != user.id)
+ .filter(filtered_actions.c.task_id == user_tasks.c.task_id)
+ .filter(filtered_actions.c.project_id == user_tasks.c.project_id)
+ .filter(filtered_actions.c.action_text != TaskStatus.MAPPED.name)
+
+ .subquery()
+ .alias("others_tasks")
+ )
+
+ user_stats = (
+ db.session.query(
+ actions_table.c.action_text, func.count(user_tasks.c.action_text)
+ )
+ .outerjoin(
+ user_tasks, actions_table.c.action_text == user_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+
+ )
+
+ others_stats = (
+ db.session.query(
+ func.concat(actions_table.c.action_text, "_BY_OTHERS"),
+ func.count(others_tasks.c.action_text),
+ )
+ .outerjoin(
+ others_tasks, actions_table.c.action_text == others_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+ )
+
+ res = user_stats.union(others_stats).all()
+ results = {key: value for key, value in res}
+
+ query = (
+ TaskHistory.query.with_entities(
+ func.date_trunc("minute", TaskHistory.action_date).label("trn"),
+ func.max(TaskHistory.action_text).label("tm"),
+ )
+ .filter(TaskHistory.user_id == user.id)
+ .filter(TaskHistory.action == "LOCKED_FOR_VALIDATION")
+ .filter(TaskHistory.project_id == project_id)
+ .filter(TaskHistory.action_date>=start_date)
+ .filter(TaskHistory.action_date<=end_date)
+ .group_by("trn")
+ .subquery()
+ )
+
+ total_validation_time = db.session.query(
+ func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
+ ).scalar()
+
+ if total_validation_time:
+ time_spent_validating = total_validation_time.total_seconds()
+ avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
+ total_time_spent += time_spent_validating
+
+ total_mapping_time = (
+ db.session.query(
+ func.sum(
+ cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
+ )
+ )
+
+ .filter(
+ or_(
+ TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
+ TaskHistory.action == TaskAction.AUTO_UNLOCKED_FOR_MAPPING.name,
+ )
+ )
+ .filter(TaskHistory.user_id == user.id)
+ .filter(TaskHistory.project_id==project_id)
+ .filter(TaskHistory.action_date>=start_date)
+ .filter(TaskHistory.action_date<=end_date)
+
+ .scalar()
+
+ )
+ if total_mapping_time:
+ time_spent_mapping = total_mapping_time.total_seconds()
+ avg_time_spent_mapping += (time_spent_mapping/int(results["MAPPED"])) if int(results["MAPPED"]) != 0 else 0
+ total_time_spent += time_spent_mapping
+
+ task_list.append({"project_id":project_id,
+ "project_name":proj_name[0],
+ "tasks_mapped":(results["MAPPED"]),
+ "tasks_validated":(results["VALIDATED"]),
+ "tasks_invalidated":(results["INVALIDATED"]),
+ "tasks_validated_by_others":(results["VALIDATED_BY_OTHERS"]),
+ "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
+ "total_time_spent":total_time_spent,
+ "time_spent_mapping":time_spent_mapping,
+ "average_time_spent_mapping":avg_time_spent_mapping,
+ "time_spent_validating":time_spent_validating,
+ "average_time_spent_validating":avg_time_spent_validating})
+
+ elif(project_id and not (start_date and end_date)):
+ proj_query = ProjectInfo.query.with_entities(ProjectInfo.name).filter(ProjectInfo.project_id==project_id)
+ proj_name=[lis[0] for lis in proj_query]
+
+ avg_time_spent_mapping = 0
+ avg_time_spent_validating = 0
+ total_time_spent = 0
+ time_spent_mapping = 0
+ time_spent_validating = 0
+ total_mapping_time = 0
+ total_validation_time = 0
+
+ filtered_actions = (
+ TaskHistory.query.with_entities(
+ TaskHistory.user_id,
+ TaskHistory.project_id,
+ TaskHistory.task_id,
+ TaskHistory.action_text,
+ )
+
+ .filter(TaskHistory.action_text.in_(actions))
+ .filter(TaskHistory.project_id == project_id)
+ .subquery()
+ .alias("filtered_actions")
+
+ )
+
+ user_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id == user.id)
+ .subquery()
+ .alias("user_tasks")
+ )
+
+ others_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id != user.id)
+ .filter(filtered_actions.c.task_id == user_tasks.c.task_id)
+ .filter(filtered_actions.c.project_id == user_tasks.c.project_id)
+ .filter(filtered_actions.c.action_text != TaskStatus.MAPPED.name)
+
+ .subquery()
+ .alias("others_tasks")
+ )
+
+ user_stats = (
+ db.session.query(
+ actions_table.c.action_text, func.count(user_tasks.c.action_text)
+ )
+ .outerjoin(
+ user_tasks, actions_table.c.action_text == user_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+
+ )
+
+ others_stats = (
+ db.session.query(
+ func.concat(actions_table.c.action_text, "_BY_OTHERS"),
+ func.count(others_tasks.c.action_text),
+ )
+ .outerjoin(
+ others_tasks, actions_table.c.action_text == others_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+ )
+
+ res = user_stats.union(others_stats).all()
+ results = {key: value for key, value in res}
+
+ query = (
+ TaskHistory.query.with_entities(
+ func.date_trunc("minute", TaskHistory.action_date).label("trn"),
+ func.max(TaskHistory.action_text).label("tm"),
+ )
+ .filter(TaskHistory.user_id == user.id)
+ .filter(TaskHistory.action == "LOCKED_FOR_VALIDATION")
+ .filter(TaskHistory.project_id == project_id)
+ .group_by("trn")
+ .subquery()
+ )
+
+ total_validation_time = db.session.query(
+ func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
+ ).scalar()
+
+ if total_validation_time:
+ time_spent_validating = total_validation_time.total_seconds()
+ avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
+ total_time_spent += time_spent_validating
+
+ total_mapping_time = (
+ db.session.query(
+ func.sum(
+ cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
+ )
+ )
+
+ .filter(
+ or_(
+ TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
+ TaskHistory.action == TaskAction.AUTO_UNLOCKED_FOR_MAPPING.name,
+ )
+ )
+ .filter(TaskHistory.user_id == user.id)
+ .filter(TaskHistory.project_id==project_id)
+ .scalar()
+ )
+ if total_mapping_time:
+ time_spent_mapping = total_mapping_time.total_seconds()
+ avg_time_spent_mapping += (time_spent_mapping/int(results["MAPPED"])) if int(results["MAPPED"]) != 0 else 0
+ total_time_spent += time_spent_mapping
+
+ task_list.append({"project_id":project_id,
+ "project_name":proj_name[0],
+ "tasks_mapped":(results["MAPPED"]),
+ "tasks_validated":(results["VALIDATED"]),
+ "tasks_invalidated":(results["INVALIDATED"]),
+ "tasks_validated_by_others":(results["VALIDATED_BY_OTHERS"]),
+ "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
+ "total_time_spent":total_time_spent,
+ "time_spent_mapping":time_spent_mapping,
+ "average_time_spent_mapping":avg_time_spent_mapping,
+ "time_spent_validating":time_spent_validating,
+ "average_time_spent_validating":avg_time_spent_validating})
+
+ if((start_date and end_date)and not project_id):
+ date_function(start_date, end_date, project_id)
+
+ proj_ids = (TaskHistory.query.with_entities(TaskHistory.project_id).filter(TaskHistory.action_date>=start_date)
+ .filter(TaskHistory.action_date<=end_date).group_by(TaskHistory.project_id)).all()
+ proj_id = [lis[0] for lis in proj_ids]
+
+ for j in range(len(proj_id)):
+ proj_query = ProjectInfo.query.with_entities(ProjectInfo.name).filter(ProjectInfo.project_id==proj_id[j])
+ proj_name=[lis[0] for lis in proj_query]
+
+ for i in range(len(proj_id)):
+ avg_time_spent_mapping = 0
+ avg_time_spent_validating = 0
+ total_time_spent = 0
+ time_spent_mapping = 0
+ time_spent_validating = 0
+ total_mapping_time = 0
+ total_validation_time = 0
+ filtered_actions = (
+ TaskHistory.query.with_entities(
+ TaskHistory.user_id,
+ TaskHistory.project_id,
+ TaskHistory.task_id,
+ TaskHistory.action_text,
+ TaskHistory.action_date,
+ )
+ .filter(TaskHistory.action_text.in_(actions))
+ .filter(TaskHistory.project_id == proj_id[j])
+ .filter(TaskHistory.user_id==user.id)
+ .filter(TaskHistory.action_date>=start_date)
+ .filter(TaskHistory.action_date<=end_date)
+
+ .subquery()
+ .alias("filtered_actions")
+
+ )
+
+ user_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id == user.id)
+ .subquery()
+ .alias("user_tasks")
+ )
+
+ others_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id != user.id)
+ .filter(filtered_actions.c.task_id == user_tasks.c.task_id)
+ .filter(filtered_actions.c.project_id == user_tasks.c.project_id)
+ .filter(filtered_actions.c.action_text != TaskStatus.MAPPED.name)
+
+ .subquery()
+ .alias("others_tasks")
+ )
+
+ user_stats = (
+ db.session.query(
+ actions_table.c.action_text, func.count(user_tasks.c.action_text)
+ )
+ .outerjoin(
+ user_tasks, actions_table.c.action_text == user_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+
+ )
+
+ others_stats = (
+ db.session.query(
+ func.concat(actions_table.c.action_text, "_BY_OTHERS"),
+ func.count(others_tasks.c.action_text),
+ )
+ .outerjoin(
+ others_tasks, actions_table.c.action_text == others_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+ )
+
+ res = user_stats.union(others_stats).all()
+ results = {key: value for key, value in res}
+
+ query = (
+ TaskHistory.query.with_entities(
+ func.date_trunc("minute", TaskHistory.action_date).label("trn"),
+ func.max(TaskHistory.action_text).label("tm"),
+ )
+ .filter(TaskHistory.user_id == user.id)
+ .filter(TaskHistory.project_id==proj_id[j])
+ .filter(TaskHistory.action == "LOCKED_FOR_VALIDATION")
+ .filter(TaskHistory.action_date>=start_date)
+ .filter(TaskHistory.action_date<=end_date)
+ .group_by("trn", TaskHistory.project_id)
+ .subquery()
+ )
+ total_validation_time = db.session.query(
+ func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
+ ).scalar()
+
+
+
+ if total_validation_time:
+ time_spent_validating = total_validation_time.total_seconds()
+ avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
+ total_time_spent += time_spent_validating
+
+ total_mapping_time = (
+ db.session.query(
+ func.sum(
+ cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
+ )
+ )
+
+ .filter(
+ or_(
+ TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
+ TaskHistory.action == TaskAction.AUTO_UNLOCKED_FOR_MAPPING.name,
+ )
+ )
+ .filter(TaskHistory.user_id == user.id)
+ .filter(TaskHistory.action_date>=start_date)
+ .filter(TaskHistory.action_date<=end_date)
+ .filter(TaskHistory.project_id == proj_id[j])
+
+ .scalar()
+
+ )
+ if total_mapping_time:
+ time_spent_mapping = total_mapping_time.total_seconds()
+ avg_time_spent_mapping += (time_spent_mapping/int(results["MAPPED"])) if int(results["MAPPED"]) != 0 else 0
+ total_time_spent += time_spent_mapping
+
+ task_list.append({"project_id":(proj_id[j]),
+ "project_name":proj_name[0],
+ "tasks_mapped":(results["MAPPED"]),
+ "tasks_validated":(results["VALIDATED"]),
+ "tasks_invalidated":(results["INVALIDATED"]),
+ "tasks_validated_by_others":(results["VALIDATED_BY_OTHERS"]),
+ "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
+ "total_time_spent":total_time_spent,
+ "time_spent_mapping":time_spent_mapping,
+ "average_time_spent_mapping":avg_time_spent_mapping,
+ "time_spent_validating":time_spent_validating,
+ "average_time_spent_validating":avg_time_spent_validating})
+ break
+
+
+ elif(not (start_date and end_date) and not project_id):
+ project_query = TaskHistory.query.with_entities(TaskHistory.project_id).group_by(TaskHistory.project_id).all()
+ proj_id = [lis[0] for lis in project_query]
+
+ for j in range(len(proj_id)):
+ proj_query = ProjectInfo.query.with_entities(ProjectInfo.name).filter(ProjectInfo.project_id==proj_id[j])
+ proj_name=[lis[0] for lis in proj_query]
+
+ for i in range(len(proj_id)):
+ avg_time_spent_mapping = 0
+ avg_time_spent_validating = 0
+ total_time_spent = 0
+ time_spent_mapping = 0
+ time_spent_validating = 0
+ total_mapping_time = 0
+ total_validation_time = 0
+
+ filtered_actions = (
+ TaskHistory.query.with_entities(
+ TaskHistory.user_id,
+ TaskHistory.project_id,
+ TaskHistory.task_id,
+ TaskHistory.action_text,
+ )
+ .filter(TaskHistory.action_text.in_(actions))
+ .filter(TaskHistory.project_id == proj_id[j])
+ .subquery()
+ .alias("filtered_actions")
+ )
+
+ user_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id == user.id)
+ .subquery()
+ .alias("user_tasks")
+ )
+
+ others_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id != user.id)
+ .filter(filtered_actions.c.task_id == user_tasks.c.task_id)
+ .filter(filtered_actions.c.project_id == user_tasks.c.project_id)
+ .filter(filtered_actions.c.action_text != TaskStatus.MAPPED.name)
+
+ .subquery()
+ .alias("others_tasks")
+ )
+
+ user_stats = (
+ db.session.query(
+ actions_table.c.action_text, func.count(user_tasks.c.action_text)
+ )
+ .outerjoin(
+ user_tasks, actions_table.c.action_text == user_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+
+ )
+
+ others_stats = (
+ db.session.query(
+ func.concat(actions_table.c.action_text, "_BY_OTHERS"),
+ func.count(others_tasks.c.action_text),
+ )
+ .outerjoin(
+ others_tasks, actions_table.c.action_text == others_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+ )
+
+ res = user_stats.union(others_stats).all()
+ results = {key: value for key, value in res}
+
+ query = (
+ TaskHistory.query.with_entities(
+ func.date_trunc("minute", TaskHistory.action_date).label("trn"),
+ func.max(TaskHistory.action_text).label("tm"),
+ )
+ .filter(TaskHistory.user_id == user.id)
+ .filter(TaskHistory.project_id==proj_id[j])
+ .filter(TaskHistory.action == "LOCKED_FOR_VALIDATION")
+ .group_by("trn")
+ .subquery()
+ )
+
+ total_validation_time = db.session.query(
+ func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
+ ).scalar()
+
+
+
+ if total_validation_time:
+ time_spent_validating = total_validation_time.total_seconds()
+ avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
+ total_time_spent += time_spent_validating
+
+ total_mapping_time = (
+ db.session.query(
+ func.sum(
+ cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
+ )
+ )
+
+ .filter(
+ or_(
+ TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
+ TaskHistory.action == TaskAction.AUTO_UNLOCKED_FOR_MAPPING.name,
+ )
+ )
+ .filter(TaskHistory.user_id == user.id)
+ .filter(TaskHistory.project_id==proj_id[j])
+
+ .scalar()
+
+ )
+
+ if total_mapping_time:
+ time_spent_mapping = total_mapping_time.total_seconds()
+ avg_time_spent_mapping += (time_spent_mapping/results["MAPPED"]) if int(results["MAPPED"]) != 0 else 0
+ total_time_spent += time_spent_mapping
+
+ task_list.append({"project_id":(proj_id[j]),
+ "project_name":proj_name[0],
+ "tasks_mapped":(results["MAPPED"]),
+ "tasks_validated":(results["VALIDATED"]),
+ "tasks_invalidated":(results["INVALIDATED"]),
+ "tasks_validated_by_others":(results["VALIDATED_BY_OTHERS"]),
+ "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
+ "total_time_spent":total_time_spent,
+ "time_spent_mapping":time_spent_mapping,
+ "average_time_spent_mapping":avg_time_spent_mapping,
+ "time_spent_validating":time_spent_validating,
+ "average_time_spent_validating":avg_time_spent_validating})
+ break
+
+ tasks_dto.task = task_list
+ tasks_dto.day = days_list
+
+ return tasks_dto
+
+
+ @staticmethod
+ def get_teams_stats(
+ username,
+ start_date: datetime.datetime = None,
+ end_date: datetime.datetime = None,
+ team_id: int = None,
+ ):
+ user = UserService.get_user_by_username(username)
+ teams_dto = UserTeamStatsDTO()
+
+ actions = [
+ TaskStatus.VALIDATED.name,
+ TaskStatus.MAPPED.name,
+ ]
+
+
+ actions_table = (
+ db.session.query(literal(TaskStatus.VALIDATED.name).label("action_text"))
+ .union(
+ db.session.query(literal(TaskStatus.MAPPED.name).label("action_text")),
+ )
+ .subquery()
+ .alias("actions_table")
+ )
+ team_list=[]
+
+
+ UserQuery = TeamMembers.query.with_entities(TeamMembers.user_id).filter(TeamMembers.team_id==team_id).group_by(TeamMembers.user_id).all()
+ UserList = [lis[0] for lis in UserQuery]
+
+ if (team_id and (start_date and end_date)):
+
+ for j in range(len(UserList)):
+ teamname_query=Team.query.with_entities(Team.name).filter(Team.id==team_id)
+ teamname=[lis[0] for lis in teamname_query]
+
+ username_query=User.query.with_entities(User.username).filter(User.id==UserList[j])
+ username=[lis[0] for lis in username_query]
+
+ for i in range(len(UserList)):
+
+ avg_time_spent_mapping = 0
+ avg_time_spent_validating = 0
+ total_time_spent = 0
+ time_spent_mapping = 0
+ time_spent_validating = 0
+ total_mapping_time = 0
+ total_validation_time = 0
+
+ filtered_actions = (
+ TaskHistory.query.with_entities(
+ TaskHistory.user_id,
+ TaskHistory.project_id,
+ TaskHistory.task_id,
+ TaskHistory.action_text,
+ TaskHistory.action_date,
+ )
+ .filter(TaskHistory.action_text.in_(actions))
+ .filter(TaskHistory.user_id==UserList[j])
+ .filter(TaskHistory.action_date>=start_date)
+ .filter(TaskHistory.action_date<=end_date)
+ .subquery()
+ .alias("filtered_actions")
+
+ )
+ user_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id == UserList[j])
+ .subquery()
+ .alias("user_tasks")
+ )
+
+ user_stats = (
+ db.session.query(
+ actions_table.c.action_text, func.count(user_tasks.c.action_text)
+ )
+ .outerjoin(
+ user_tasks, actions_table.c.action_text == user_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+ )
+
+ res = user_stats.all()
+ results = {key: value for key, value in res}
+
+ query = (
+ TaskHistory.query.with_entities(
+ func.date_trunc("minute", TaskHistory.action_date).label("trn"),
+ func.max(TaskHistory.action_text).label("tm"),
+ )
+ .filter(TaskHistory.user_id == UserList[j])
+ .filter(TaskHistory.action == "LOCKED_FOR_VALIDATION")
+ .filter(TaskHistory.action_date>=start_date)
+ .filter(TaskHistory.action_date<=end_date)
+ .group_by("trn")
+ .subquery()
+ )
+
+ total_validation_time = db.session.query(
+ func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
+ ).scalar()
+
+ if total_validation_time:
+ time_spent_validating = total_validation_time.total_seconds()
+ avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
+ total_time_spent += time_spent_validating
+
+ total_mapping_time = (
+ db.session.query(
+ func.sum(
+ cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
+ )
+ )
+
+ .filter(
+ or_(
+ TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
+ TaskHistory.action == TaskAction.AUTO_UNLOCKED_FOR_MAPPING.name,
+ )
+ )
+ .filter(TaskHistory.user_id == UserList[j])
+ .filter(TaskHistory.action_date>=start_date)
+ .filter(TaskHistory.action_date<=end_date)
+ .scalar()
+ )
+
+ if total_mapping_time:
+ time_spent_mapping = total_mapping_time.total_seconds()
+ avg_time_spent_mapping += (time_spent_mapping/int(results["MAPPED"])) if int(results["MAPPED"]) != 0 else 0
+ total_time_spent += time_spent_mapping
+
+ team_list.append({"team_id":team_id,
+ "team_name":teamname[0],
+ "user_id":UserList[j],
+ "user_name":username[0],
+ "tasks_mapped":(results["MAPPED"]),
+ "tasks_validated":(results["VALIDATED"]),
+ "total_time_spent":total_time_spent,
+ "time_spent_mapping":time_spent_mapping,
+ "average_time_spent_mapping":avg_time_spent_mapping,
+ "time_spent_validating":time_spent_validating,
+ "average_time_spent_validating":avg_time_spent_validating})
+ break
+
+ elif(team_id and not (start_date and end_date)):
+
+ for j in range(len(UserList)):
+ teamname_query=Team.query.with_entities(Team.name).filter(Team.id==team_id)
+ teamname=[lis[0] for lis in teamname_query]
+
+ username_query=User.query.with_entities(User.username).filter(User.id==UserList[j])
+ username=[lis[0] for lis in username_query]
+
+ for i in range(len(UserList)):
+
+ avg_time_spent_mapping = 0
+ avg_time_spent_validating = 0
+ total_time_spent = 0
+ time_spent_mapping = 0
+ time_spent_validating = 0
+ total_mapping_time = 0
+ total_validation_time = 0
+
+ filtered_actions = (
+ TaskHistory.query.with_entities(
+ TaskHistory.user_id,
+ TaskHistory.project_id,
+ TaskHistory.task_id,
+ TaskHistory.action_text,
+ )
+
+ .filter(TaskHistory.action_text.in_(actions))
+ .filter(TaskHistory.user_id==UserList[j])
+ .subquery()
+ .alias("filtered_actions")
+
+ )
+
+ user_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id == UserList[j])
+ .subquery()
+ .alias("user_tasks")
+ )
+
+ user_stats = (
+ db.session.query(
+ actions_table.c.action_text, func.count(user_tasks.c.action_text)
+ )
+ .outerjoin(
+ user_tasks, actions_table.c.action_text == user_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+
+ )
+
+ res = user_stats.all()
+ results = {key: value for key, value in res}
+
+ query = (
+ TaskHistory.query.with_entities(
+ func.date_trunc("minute", TaskHistory.action_date).label("trn"),
+ func.max(TaskHistory.action_text).label("tm"),
+ )
+ .filter(TaskHistory.user_id == UserList[j])
+ .filter(TaskHistory.action == "LOCKED_FOR_VALIDATION")
+ .group_by("trn")
+ .subquery()
+ )
+
+ total_validation_time = db.session.query(
+ func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
+ ).scalar()
+
+ if total_validation_time:
+ time_spent_validating = total_validation_time.total_seconds()
+ avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
+ total_time_spent += time_spent_validating
+
+ total_mapping_time = (
+ db.session.query(
+ func.sum(
+ cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
+ )
+ )
+
+ .filter(
+ or_(
+ TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
+ TaskHistory.action == TaskAction.AUTO_UNLOCKED_FOR_MAPPING.name,
+ )
+ )
+ .filter(TaskHistory.user_id == UserList[j])
+ .scalar()
+ )
+ if total_mapping_time:
+ time_spent_mapping = total_mapping_time.total_seconds()
+ avg_time_spent_mapping += (time_spent_mapping/int(results["MAPPED"])) if int(results["MAPPED"]) != 0 else 0
+ total_time_spent += time_spent_mapping
+
+ team_list.append({"team_id":team_id,
+ "team_name":teamname[0],
+ "user_id":UserList[j],
+ "user_name":username[0],
+ "tasks_mapped":(results["MAPPED"]),
+ "tasks_validated":(results["VALIDATED"]),
+ "total_time_spent":total_time_spent,
+ "time_spent_mapping":time_spent_mapping,
+ "average_time_spent_mapping":avg_time_spent_mapping,
+ "time_spent_validating":time_spent_validating,
+ "average_time_spent_validating":avg_time_spent_validating})
+ break
+
+ user_query = TeamMembers.query.with_entities(TeamMembers.user_id).group_by(TeamMembers.user_id).all()
+ user_list = [lis[0] for lis in user_query]
+
+ if((start_date and end_date)and not team_id):
+
+ for j in range(len(user_list)):
+ username_query=User.query.with_entities(User.username).filter(User.id==user_list[j])
+ username=[lis[0] for lis in username_query]
+
+ for i in range(len(user_list)):
+ team_query = TeamMembers.query.with_entities(TeamMembers.team_id).filter(TeamMembers.user_id==user_list[j]).group_by(TeamMembers.team_id).all()
+ t_id = [lis[0] for lis in team_query]
+
+ teamname=[]
+ for var in t_id:
+ teamname_query=Team.query.with_entities(Team.name).filter(Team.id==var).all()
+ teamname.append(teamname_query)
+ teamname=[lis[0] for lis in teamname]
+ teamname=[lis[0] for lis in teamname]
+
+ avg_time_spent_mapping = 0
+ avg_time_spent_validating = 0
+ total_time_spent = 0
+ time_spent_mapping = 0
+ time_spent_validating = 0
+ total_mapping_time = 0
+ total_validation_time = 0
+
+ filtered_actions = (
+ TaskHistory.query.with_entities(
+ TaskHistory.user_id,
+ TaskHistory.project_id,
+ TaskHistory.task_id,
+ TaskHistory.action_text,
+ TaskHistory.action_date,
+ )
+ .filter(TaskHistory.action_text.in_(actions))
+ .filter(TaskHistory.user_id==user_list[j])
+ .filter(TaskHistory.action_date>=start_date)
+ .filter(TaskHistory.action_date<=end_date)
+ .subquery()
+ .alias("filtered_actions")
+ )
+
+ user_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id == user_list[j])
+ .subquery()
+ .alias("user_tasks")
+ )
+
+ user_stats = (
+ db.session.query(
+ actions_table.c.action_text, func.count(user_tasks.c.action_text)
+ )
+ .outerjoin(
+ user_tasks, actions_table.c.action_text == user_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+
+ )
+
+ res = user_stats.all()
+ results = {key: value for key, value in res}
+
+ query = (
+ TaskHistory.query.with_entities(
+ func.date_trunc("minute", TaskHistory.action_date).label("trn"),
+ func.max(TaskHistory.action_text).label("tm"),
+ )
+ .filter(TaskHistory.user_id == user_list[j])
+ .filter(TaskHistory.action == "LOCKED_FOR_VALIDATION")
+ .filter(TaskHistory.action_date>=start_date)
+ .filter(TaskHistory.action_date<=end_date)
+ .group_by("trn", TaskHistory.project_id)
+ .subquery()
+ )
+ total_validation_time = db.session.query(
+ func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
+ ).scalar()
+
+
+
+ if total_validation_time:
+ time_spent_validating = total_validation_time.total_seconds()
+ avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
+ total_time_spent += time_spent_validating
+
+ total_mapping_time = (
+ db.session.query(
+ func.sum(
+ cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
+ )
+ )
+
+ .filter(
+ or_(
+ TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
+ TaskHistory.action == TaskAction.AUTO_UNLOCKED_FOR_MAPPING.name,
+ )
+ )
+ .filter(TaskHistory.user_id == user_list[j])
+ .filter(TaskHistory.action_date>=start_date)
+ .filter(TaskHistory.action_date<=end_date)
+
+ .scalar()
+
+ )
+ if total_mapping_time:
+ time_spent_mapping = total_mapping_time.total_seconds()
+ avg_time_spent_mapping += (time_spent_mapping/int(results["MAPPED"])) if int(results["MAPPED"]) != 0 else 0
+ total_time_spent += time_spent_mapping
+
+ team_list.append({"team_id":t_id,
+ "team_name":teamname,
+ "user_id":user_list[j],
+ "user_name":username[0],
+ "tasks_mapped":(results["MAPPED"]),
+ "tasks_validated":(results["VALIDATED"]),
+ "total_time_spent":total_time_spent,
+ "time_spent_mapping":time_spent_mapping,
+ "average_time_spent_mapping":avg_time_spent_mapping,
+ "time_spent_validating":time_spent_validating,
+ "average_time_spent_validating":avg_time_spent_validating})
+ break
+
+
+ elif(not (start_date and end_date) and not team_id):
+
+ for j in range(len(user_list)):
+ username_query=User.query.with_entities(User.username).filter(User.id==user_list[j])
+ username=[lis[0] for lis in username_query]
+
+ for i in range(len(user_list)):
+ team_query = TeamMembers.query.with_entities(TeamMembers.team_id).filter(TeamMembers.user_id==user_list[j]).group_by(TeamMembers.team_id).all()
+ t_id = [lis[0] for lis in team_query]
+
+ teamname=[]
+ for var in t_id:
+ teamname_query=Team.query.with_entities(Team.name).filter(Team.id==var).all()
+ teamname.append(teamname_query)
+
+ teamname=[lis[0] for lis in teamname]
+ teamname=[lis[0] for lis in teamname]
+
+ avg_time_spent_mapping = 0
+ avg_time_spent_validating = 0
+ total_time_spent = 0
+ time_spent_mapping = 0
+ time_spent_validating = 0
+ total_mapping_time = 0
+ total_validation_time = 0
+
+ filtered_actions = (
+ TaskHistory.query.with_entities(
+ TaskHistory.user_id,
+ TaskHistory.project_id,
+ TaskHistory.task_id,
+ TaskHistory.action_text,
+ )
+ .filter(TaskHistory.action_text.in_(actions))
+ .filter(TaskHistory.user_id == user_list[j])
+ .subquery()
+ .alias("filtered_actions")
+ )
+
+ user_tasks = (
+ db.session.query(filtered_actions)
+ .filter(filtered_actions.c.user_id == user_list[j])
+ .subquery()
+ .alias("user_tasks")
+ )
+
+ user_stats = (
+ db.session.query(
+ actions_table.c.action_text, func.count(user_tasks.c.action_text)
+ )
+ .outerjoin(
+ user_tasks, actions_table.c.action_text == user_tasks.c.action_text
+ )
+ .group_by(actions_table.c.action_text)
+
+ )
+
+ res = user_stats.all()
+ results = {key: value for key, value in res}
+
+ query = (
+ TaskHistory.query.with_entities(
+ func.date_trunc("minute", TaskHistory.action_date).label("trn"),
+ func.max(TaskHistory.action_text).label("tm"),
+ )
+ .filter(TaskHistory.user_id == user.id)
+ .filter(TaskHistory.user_id == user_list[j])
+ .filter(TaskHistory.action == "LOCKED_FOR_VALIDATION")
+ .group_by("trn")
+ .subquery()
+ )
+
+ total_validation_time = db.session.query(
+ func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
+ ).scalar()
+
+
+
+ if total_validation_time:
+ time_spent_validating = total_validation_time.total_seconds()
+ avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
+ total_time_spent += time_spent_validating
+
+ total_mapping_time = (
+ db.session.query(
+ func.sum(
+ cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
+ )
+ )
+
+ .filter(
+ or_(
+ TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
+ TaskHistory.action == TaskAction.AUTO_UNLOCKED_FOR_MAPPING.name,
+ )
+ )
+ .filter(TaskHistory.user_id == user_list[j])
+ .scalar()
+ )
+
+ if total_mapping_time:
+ time_spent_mapping = total_mapping_time.total_seconds()
+ avg_time_spent_mapping += (time_spent_mapping/results["MAPPED"]) if int(results["MAPPED"]) != 0 else 0
+ total_time_spent += time_spent_mapping
+
+ team_list.append({"team_id":t_id,
+ "team_name":teamname,
+ "user_id":user_list[j],
+ "user_name":username[0],
+ "tasks_mapped":(results["MAPPED"]),
+ "tasks_validated":(results["VALIDATED"]),
+ "total_time_spent":total_time_spent,
+ "time_spent_mapping":time_spent_mapping,
+ "average_time_spent_mapping":avg_time_spent_mapping,
+ "time_spent_validating":time_spent_validating,
+ "average_time_spent_validating":avg_time_spent_validating})
+ break
+
+ teams_dto.team = team_list
+
+ return teams_dto
+
+ @staticmethod
+ def get_user_specific_task(
+ username: str,
+ start_date: datetime.datetime = None,
+ end_date: datetime.datetime = None,
+ task_status: str = None,
+ ):
+
+ user = UserService.get_user_by_username(username)
+ task_dto = UserSpecificDTO()
+ task_list=[]
+
+ actions = [
+ TaskStatus.VALIDATED.name,
+ TaskStatus.MAPPED.name,
+ TaskStatus.INVALIDATED.name,
+ TaskStatus.BADIMAGERY.name
+ ]
+ action_list=[
+ TaskStatus.LOCKED_FOR_MAPPING.name,
+ TaskStatus.LOCKED_FOR_VALIDATION.name,
+ ]
+
+ task_query = (TaskHistory.query.with_entities(TaskHistory.task_id)
+ .filter(TaskHistory.user_id==user.id)
+ .group_by(TaskHistory.task_id)
+ ).all()
+
+ pro_query=(TaskHistory.query.with_entities(TaskHistory.project_id)
+ .filter(TaskHistory.user_id==user.id)
+ .group_by(TaskHistory.project_id)
+ ).all()
+
+ pro_list=[lis[0] for lis in pro_query]
+ taskid_list=[var[0] for var in task_query]
+
+ for j in range(len(pro_list)):
+ for i in range(len(taskid_list)):
+ review_query=Task.query.with_entities(Task.validated_by).filter(Task.project_id==pro_list[j]).filter(Task.id==taskid_list[i]).all()
+ review_list=[lis[0] for lis in review_query]
+
+ date_query=(TaskHistory.query.with_entities(TaskHistory.action_date).filter(TaskHistory.project_id==pro_list[j])
+ .filter(TaskHistory.task_id==taskid_list[i])
+ .filter(TaskHistory.user_id==user.id)
+ .filter(TaskHistory.action_text.in_(actions))
+ ).all()
+ date_list=[lis[0] for lis in date_query]
+
+ time_spent_mapping=0
+ time_spent_validating=0
+ total_time_spent=0
+
+ base_query=(TaskHistory.query.with_entities(
+ TaskHistory.task_id,
+ TaskHistory.project_id,
+ TaskHistory.action_text,
+ )
+ .filter(TaskHistory.project_id==pro_list[j])
+ .filter(TaskHistory.task_id==taskid_list[i])
+ .filter(TaskHistory.user_id==user.id)
+ .filter(TaskHistory.action_text.in_(actions))
+ )
+
+ if task_status:
+ if task_status.upper() in actions:
+ base_query = base_query.filter(TaskHistory.action_text == TaskStatus[task_status.upper()].name)
+ if (start_date and end_date):
+ base_query = base_query.filter(TaskHistory.action_date >= start_date).filter(TaskHistory.action_date <= end_date)
+ elif task_status.upper() in action_list:
+ date_query=(TaskHistory.query.with_entities(TaskHistory.action_date).filter(TaskHistory.project_id==pro_list[j])
+ .filter(TaskHistory.task_id==taskid_list[i])
+ .filter(TaskHistory.user_id==user.id)
+ .filter(TaskHistory.action.in_(action_list))
+ ).all()
+ date_list=[lis[0] for lis in date_query]
+ base_query=(TaskHistory.query.with_entities(
+ TaskHistory.task_id,
+ TaskHistory.project_id,
+ TaskHistory.action,
+ )
+ .filter(TaskHistory.project_id==pro_list[j])
+ .filter(TaskHistory.task_id==taskid_list[i])
+ .filter(TaskHistory.user_id==user.id)
+ .filter(TaskHistory.action.in_(action_list))
+ )
+ base_query=base_query.filter(TaskHistory.action==TaskStatus[task_status.upper()].name)
+ if (start_date and end_date):
+ base_query = base_query.filter(TaskHistory.action_date >= start_date).filter(TaskHistory.action_date <= end_date)
+ if (start_date and end_date):
+ base_query = base_query.filter(TaskHistory.action_date >= start_date).filter(TaskHistory.action_date <= end_date)
+
+ base_query=base_query.all()
+
+ query = (
+ TaskHistory.query.with_entities(
+ func.date_trunc("minute", TaskHistory.action_date).label("trn"),
+ func.max(TaskHistory.action_text).label("tm"),
+ )
+ .filter(TaskHistory.project_id==pro_list[j])
+ .filter(TaskHistory.task_id==taskid_list[i])
+ .filter(TaskHistory.user_id == user.id)
+ .filter(TaskHistory.action == "LOCKED_FOR_VALIDATION")
+ .group_by("trn")
+ .subquery()
+ )
+
+ total_validation_time = db.session.query(
+ func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
+ ).scalar()
+
+ if total_validation_time:
+ time_spent_validating = total_validation_time.total_seconds()
+ total_time_spent += time_spent_validating
+
+ total_mapping_time = (
+ db.session.query(
+ func.sum(
+ cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
+ )
+ )
+ .filter(
+ or_(
+ TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
+ TaskHistory.action == TaskAction.AUTO_UNLOCKED_FOR_MAPPING.name,
+ )
+ )
+ .filter(TaskHistory.project_id==pro_list[j])
+ .filter(TaskHistory.task_id==taskid_list[i])
+ .filter(TaskHistory.user_id == user.id)
+ .scalar()
+ )
+ if total_mapping_time:
+ time_spent_mapping = total_mapping_time.total_seconds()
+ total_time_spent += time_spent_mapping
+
+ task_status_list=[lis[2] for lis in base_query]
+
+ if len(base_query):
+ task_list.append({"user_name":username,
+ "project_id":pro_list[j],
+ "tasks_id":taskid_list[i],
+ "task_status":task_status_list[0],
+ "action_date":str(date_list[0]),
+ "total_time_spent":total_time_spent,
+ "time_spent_mapping":time_spent_mapping,
+ "time_spent_validating":time_spent_validating,
+ "reviewer":review_list[0]})
+
+ task_dto.tasks = task_list
+
+ return task_dto
\ No newline at end of file
From b5b168b310aa5e32f2828c1eccc8486c311b9262 Mon Sep 17 00:00:00 2001
From: hc00364289 <71371046+hc00364289@users.noreply.github.com>
Date: Wed, 23 Dec 2020 19:08:45 +0530
Subject: [PATCH 6/8] Date fromat TZ UTC to local conversion and some
refactoring for Secs to HH:MM:SS conversion
---
frontend/src/components/teamsAndOrgs/teams.js | 13 +-----------
.../components/userDetail/elementsMapped.js | 13 +-----------
frontend/src/network/genericCSVExport.js | 21 +++++++++++++++++++
frontend/src/views/teams.js | 18 ++++------------
4 files changed, 27 insertions(+), 38 deletions(-)
diff --git a/frontend/src/components/teamsAndOrgs/teams.js b/frontend/src/components/teamsAndOrgs/teams.js
index 0e73b732f..2da4b8e4c 100644
--- a/frontend/src/components/teamsAndOrgs/teams.js
+++ b/frontend/src/components/teamsAndOrgs/teams.js
@@ -9,6 +9,7 @@ import {
exporttoCSVFile,
convertStartDateTime,
convertEndDateTime,
+ convertSeconds,
} from '../../network/genericCSVExport';
import messages from './messages';
import { useEditTeamAllowed } from '../../hooks/UsePermissions';
@@ -431,18 +432,6 @@ export function TeamsStats() {
selectItems.push(obj);
}
- var convertSeconds = (sec) => {
- var hrs = Math.floor(sec / 3600);
- var min = Math.floor((sec - hrs * 3600) / 60);
- var seconds = sec - hrs * 3600 - min * 60;
- seconds = Math.round(seconds * 100) / 100;
-
- var result = hrs < 10 ? '0' + hrs : hrs;
- result += ':' + (min < 10 ? '0' + min : min);
- result += ':' + (seconds < 10 ? '0' + seconds : seconds);
- return result;
- };
-
let dataSummaryResponse = [];
for (let i = 0; i < teamMetricsStats.length; i++) {
diff --git a/frontend/src/components/userDetail/elementsMapped.js b/frontend/src/components/userDetail/elementsMapped.js
index 8ea823d3d..ba0cb0a88 100644
--- a/frontend/src/components/userDetail/elementsMapped.js
+++ b/frontend/src/components/userDetail/elementsMapped.js
@@ -16,6 +16,7 @@ import {
exporttoCSVFile,
convertStartDateTime,
convertEndDateTime,
+ convertSeconds,
} from '../../network/genericCSVExport';
import {
ClockIcon,
@@ -101,18 +102,6 @@ export const TaskStats = ({ userStats, username }) => {
getProjectNames();
}, []);
- var convertSeconds = (sec) => {
- var hrs = Math.floor(sec / 3600);
- var min = Math.floor((sec - hrs * 3600) / 60);
- var seconds = sec - hrs * 3600 - min * 60;
- seconds = Math.round(seconds * 100) / 100;
-
- var result = hrs < 10 ? '0' + hrs : hrs;
- result += ':' + (min < 10 ? '0' + min : min);
- result += ':' + (seconds < 10 ? '0' + seconds : seconds);
- return result;
- };
-
const maxDateApp = new Date();
var dateObj = new Date();
diff --git a/frontend/src/network/genericCSVExport.js b/frontend/src/network/genericCSVExport.js
index 1607c4ca1..43c26711a 100644
--- a/frontend/src/network/genericCSVExport.js
+++ b/frontend/src/network/genericCSVExport.js
@@ -59,3 +59,24 @@ export function convertEndDateTime(value) {
let result = moment(dateTime).format('YYYY-MM-DD HH:mm:ss');
return result;
}
+
+export function convertUtcToLocal(dateTime) {
+ var date = moment.utc(dateTime).format('YYYY-MM-DD HH:mm:ss');
+ var localTime = moment.utc(date).toDate();
+ localTime = moment(localTime).format('YYYY-MM-DD HH:mm:ss');
+ console.log('moment: ' + localTime);
+
+ return localTime;
+}
+
+export function convertSeconds(sec) {
+ var hrs = Math.floor(sec / 3600);
+ var min = Math.floor((sec - hrs * 3600) / 60);
+ var seconds = sec - hrs * 3600 - min * 60;
+ seconds = Math.round(seconds * 100) / 100;
+
+ var result = hrs < 10 ? '0' + hrs : hrs;
+ result += ':' + (min < 10 ? '0' + min : min);
+ result += ':' + (seconds < 10 ? '0' + seconds : seconds);
+ return result;
+}
diff --git a/frontend/src/views/teams.js b/frontend/src/views/teams.js
index 1541c705e..7a3414535 100644
--- a/frontend/src/views/teams.js
+++ b/frontend/src/views/teams.js
@@ -15,6 +15,8 @@ import {
exporttoCSVFile,
convertStartDateTime,
convertEndDateTime,
+ convertUtcToLocal,
+ convertSeconds,
} from '../network/genericCSVExport';
import DataTable from 'react-data-table-component';
import { Button } from '../components/button';
@@ -170,17 +172,6 @@ export function MyTeamsUserSatsIndetailed() {
let defaultelectedStatus = { value: selectedStatus, label: selectedStatus };
let userNameSelected = varSelectedUser.value;
- var convertSeconds = (sec) => {
- var hrs = Math.floor(sec / 3600);
- var min = Math.floor((sec - hrs * 3600) / 60);
- var seconds = sec - hrs * 3600 - min * 60;
- seconds = Math.round(seconds * 100) / 100;
-
- var result = hrs < 10 ? '0' + hrs : hrs;
- result += ':' + (min < 10 ? '0' + min : min);
- result += ':' + (seconds < 10 ? '0' + seconds : seconds);
- return result;
- };
const getUserNameBasedStats = async () => {
// var startDateFormatted = moment(value[0]).format('YYYY-MM -DD');
@@ -202,8 +193,7 @@ export function MyTeamsUserSatsIndetailed() {
obj.TaskUrl = teamMetricsStats[i].project_id;
obj.TaskId = teamMetricsStats[i].tasks_id;
obj.CurrentState = teamMetricsStats[i].task_status;
-
- obj.StatusChangeTime = moment(teamMetricsStats[i].action_date).format('DD-MM-YYYY HH:mm:ss');
+ obj.StatusChangeTime = convertUtcToLocal(teamMetricsStats[i].action_date);
obj.TimeSpentOnTask = convertSeconds(teamMetricsStats[i].total_time_spent);
obj.Reviewer = teamMetricsStats[i].reviewer;
@@ -284,7 +274,7 @@ export function MyTeamsUserSatsIndetailed() {
/>
-
+
Date Range :
|
From a950183c1bb6a6c6c060ea6a62ef00505164e868 Mon Sep 17 00:00:00 2001
From: hc00364289 <71371046+hc00364289@users.noreply.github.com>
Date: Wed, 23 Dec 2020 19:14:42 +0530
Subject: [PATCH 7/8] removed console statement
---
frontend/src/network/genericCSVExport.js | 2 --
1 file changed, 2 deletions(-)
diff --git a/frontend/src/network/genericCSVExport.js b/frontend/src/network/genericCSVExport.js
index 43c26711a..9a3f1212d 100644
--- a/frontend/src/network/genericCSVExport.js
+++ b/frontend/src/network/genericCSVExport.js
@@ -64,8 +64,6 @@ export function convertUtcToLocal(dateTime) {
var date = moment.utc(dateTime).format('YYYY-MM-DD HH:mm:ss');
var localTime = moment.utc(date).toDate();
localTime = moment(localTime).format('YYYY-MM-DD HH:mm:ss');
- console.log('moment: ' + localTime);
-
return localTime;
}
From 09ba9e34262f43c798595dc19bc2628991007b3d Mon Sep 17 00:00:00 2001
From: Zack LaVergne
Date: Mon, 18 Apr 2022 11:52:45 -0600
Subject: [PATCH 8/8] address review feedback
---
backend/api/users/statistics.py | 22 +-
backend/services/users/user_service.py | 490 +++++++++---------
frontend/src/components/teamsAndOrgs/teams.js | 2 -
3 files changed, 256 insertions(+), 258 deletions(-)
diff --git a/backend/api/users/statistics.py b/backend/api/users/statistics.py
index 4abb9a60d..d21d02185 100644
--- a/backend/api/users/statistics.py
+++ b/backend/api/users/statistics.py
@@ -28,7 +28,7 @@ def get(self, username):
required: true
type: string
default: Thinkwhere
-
+
responses:
200:
description: User found
@@ -108,12 +108,12 @@ def get(self, username):
required: true
type: string
default: Token sessionTokenHere==
- - name: username
- in: path
+ - in: path
+ name: username
description: Mapper's OpenStreetMap username
required: true
type: string
- default: Thinkwhere
+ default: null
- in: query
name: project_id
description: Project id
@@ -155,13 +155,13 @@ def get(self, username):
if request.args.get("end_date")
else None
)
- tasks_dto = UserService.get_tasks_mapped(username, start_date=start_date, end_date=end_date, project_id=project_id,)
-
+ tasks_dto = UserService.get_tasks_mapped(username, start_date=start_date, end_date=end_date, project_id=project_id)
+
return tasks_dto.to_primitive(), 200
except NotFound:
- return {"Error": "User not found"}, 404
+ return {"Error": "UsersTaskMapped not found"}, 404
except Exception as e:
- error_msg = f"User GET - unhandled error: {str(e)}"
+ error_msg = f"UsersTaskMapped GET - unhandled error: {str(e)}"
current_app.logger.critical(error_msg)
return {"Error": "Unable to fetch user statistics"}, 500
@@ -183,8 +183,8 @@ def get(self, username):
required: true
type: string
default: Token sessionTokenHere==
- - name: username
- in: path
+ - in: path
+ name: username
description: Mapper's OpenStreetMap username
required: true
type: string
@@ -231,7 +231,7 @@ def get(self, username):
else None
)
teams_dto = UserService.get_teams_stats(username, start_date=start_date, end_date=end_date, team_id=team_id,)
-
+
return teams_dto.to_primitive(), 200
except NotFound:
return {"Error": "User not found"}, 404
diff --git a/backend/services/users/user_service.py b/backend/services/users/user_service.py
index b4dc1ef91..5c72bf000 100644
--- a/backend/services/users/user_service.py
+++ b/backend/services/users/user_service.py
@@ -21,7 +21,7 @@
UserMappedDTO,
UserTeamStatsDTO,
UserSpecificDTO,
-
+
)
from backend.models.dtos.interests_dto import InterestsListDTO, InterestDTO
from backend.models.postgis.interests import Interest, project_interests
@@ -822,8 +822,8 @@ def get_tasks_mapped(
TaskStatus.VALIDATED.name,
TaskStatus.INVALIDATED.name,
TaskStatus.MAPPED.name,
- ]
-
+ ]
+
actions_table = (
db.session.query(literal(TaskStatus.VALIDATED.name).label("action_text"))
.union(
@@ -837,22 +837,22 @@ def get_tasks_mapped(
)
days_list = []
-
+
def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=None, project_id: int=None):
days = []
-
+
for i in range((end_date-start_date).days):
days.append(start_date)
start_date += datetime.timedelta(days=1)
-
+
if ((start_date and end_date)and not project_id):
for i in range(len(days)):
-
+
for j in range(len(days)):
proj_ids = (TaskHistory.query.with_entities(TaskHistory.project_id).filter(TaskHistory.action_date>=days[i])
.filter(TaskHistory.action_date<=days[i]+datetime.timedelta(days=1)).group_by(TaskHistory.project_id)).all()
projid=[lis[0] for lis in proj_ids]
-
+
avg_time_spent_mapping = 0
avg_time_spent_validating = 0
total_time_spent = 0
@@ -860,7 +860,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
time_spent_validating = 0
total_mapping_time = 0
total_validation_time = 0
-
+
filtered_actions = (
TaskHistory.query.with_entities(
TaskHistory.user_id,
@@ -873,15 +873,15 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.filter(TaskHistory.user_id==user.id)
.filter(TaskHistory.action_date>=days[i])
.filter(TaskHistory.action_date<=days[i]+datetime.timedelta(days=1))
-
+
.subquery()
.alias("filtered_actions")
-
+
)
-
+
user_tasks = (
db.session.query(filtered_actions)
- .filter(filtered_actions.c.user_id == user.id)
+ .filter(filtered_actions.c.user_id == user.id)
.subquery()
.alias("user_tasks")
)
@@ -892,11 +892,11 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.filter(filtered_actions.c.task_id == user_tasks.c.task_id)
.filter(filtered_actions.c.project_id == user_tasks.c.project_id)
.filter(filtered_actions.c.action_text != TaskStatus.MAPPED.name)
-
+
.subquery()
.alias("others_tasks")
)
-
+
user_stats = (
db.session.query(
actions_table.c.action_text, func.count(user_tasks.c.action_text)
@@ -905,7 +905,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
user_tasks, actions_table.c.action_text == user_tasks.c.action_text
)
.group_by(actions_table.c.action_text)
-
+
)
others_stats = (
@@ -918,10 +918,10 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
)
.group_by(actions_table.c.action_text)
)
-
+
res = user_stats.union(others_stats).all()
- results = {key: value for key, value in res}
-
+ results = {key: value for key, value in res}
+
query = (
TaskHistory.query.with_entities(
func.date_trunc("minute", TaskHistory.action_date).label("trn"),
@@ -937,9 +937,9 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
total_validation_time = db.session.query(
func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
).scalar()
-
-
+
+
if total_validation_time:
time_spent_validating = total_validation_time.total_seconds()
avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
@@ -951,7 +951,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
)
)
-
+
.filter(
or_(
TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
@@ -960,10 +960,10 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
)
.filter(TaskHistory.user_id == user.id)
.filter(TaskHistory.action_date>=days[i])
- .filter(TaskHistory.action_date<=days[i]+datetime.timedelta(days=1))
-
+ .filter(TaskHistory.action_date<=days[i]+datetime.timedelta(days=1))
+
.scalar()
-
+
)
if total_mapping_time:
time_spent_mapping = total_mapping_time.total_seconds()
@@ -971,22 +971,22 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
total_time_spent += time_spent_mapping
days_list.append({"date":str(days[i]),
- "project_id":projid,
- "tasks_mapped":(results["MAPPED"]),
+ "project_id":projid,
+ "tasks_mapped":(results["MAPPED"]),
"tasks_validated":(results["VALIDATED"]),
- "tasks_invalidated":(results["INVALIDATED"]),
+ "tasks_invalidated":(results["INVALIDATED"]),
"tasks_validated_by_others":(results["VALIDATED_BY_OTHERS"]),
- "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
+ "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
"total_time_spent":total_time_spent,
- "time_spent_mapping":time_spent_mapping,
+ "time_spent_mapping":time_spent_mapping,
"average_time_spent_mapping":avg_time_spent_mapping,
- "time_spent_validating":time_spent_validating,
+ "time_spent_validating":time_spent_validating,
"average_time_spent_validating":avg_time_spent_validating})
break
elif((start_date and end_date)and project_id):
for i in range(len(days)):
-
+
for j in range(len(days)):
avg_time_spent_mapping = 0
@@ -996,7 +996,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
time_spent_validating = 0
total_mapping_time = 0
total_validation_time = 0
-
+
filtered_actions = (
TaskHistory.query.with_entities(
TaskHistory.user_id,
@@ -1010,15 +1010,15 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.filter(TaskHistory.user_id==user.id)
.filter(TaskHistory.action_date>=days[i])
.filter(TaskHistory.action_date<=days[i]+datetime.timedelta(days=1))
-
+
.subquery()
.alias("filtered_actions")
-
+
)
-
+
user_tasks = (
db.session.query(filtered_actions)
- .filter(filtered_actions.c.user_id == user.id)
+ .filter(filtered_actions.c.user_id == user.id)
.subquery()
.alias("user_tasks")
)
@@ -1029,11 +1029,11 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.filter(filtered_actions.c.task_id == user_tasks.c.task_id)
.filter(filtered_actions.c.project_id == user_tasks.c.project_id)
.filter(filtered_actions.c.action_text != TaskStatus.MAPPED.name)
-
+
.subquery()
.alias("others_tasks")
)
-
+
user_stats = (
db.session.query(
actions_table.c.action_text, func.count(user_tasks.c.action_text)
@@ -1042,7 +1042,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
user_tasks, actions_table.c.action_text == user_tasks.c.action_text
)
.group_by(actions_table.c.action_text)
-
+
)
others_stats = (
@@ -1055,10 +1055,10 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
)
.group_by(actions_table.c.action_text)
)
-
+
res = user_stats.union(others_stats).all()
- results = {key: value for key, value in res}
-
+ results = {key: value for key, value in res}
+
query = (
TaskHistory.query.with_entities(
func.date_trunc("minute", TaskHistory.action_date).label("trn"),
@@ -1075,9 +1075,9 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
total_validation_time = db.session.query(
func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
).scalar()
-
-
+
+
if total_validation_time:
time_spent_validating = total_validation_time.total_seconds()
avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
@@ -1089,7 +1089,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
)
)
-
+
.filter(
or_(
TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
@@ -1099,38 +1099,38 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.filter(TaskHistory.user_id == user.id)
.filter(TaskHistory.action_date>=days[i])
.filter(TaskHistory.action_date<=days[i]+datetime.timedelta(days=1))
- .filter(TaskHistory.project_id == project_id)
-
+ .filter(TaskHistory.project_id == project_id)
+
.scalar()
-
+
)
if total_mapping_time:
time_spent_mapping = total_mapping_time.total_seconds()
avg_time_spent_mapping += (time_spent_mapping/int(results["MAPPED"])) if int(results["MAPPED"]) != 0 else 0
total_time_spent += time_spent_mapping
-
+
days_list.append({"date":str(days[i]),
- "project_id":project_id,
- "tasks_mapped":(results["MAPPED"]),
+ "project_id":project_id,
+ "tasks_mapped":(results["MAPPED"]),
"tasks_validated":(results["VALIDATED"]),
- "tasks_invalidated":(results["INVALIDATED"]),
+ "tasks_invalidated":(results["INVALIDATED"]),
"tasks_validated_by_others":(results["VALIDATED_BY_OTHERS"]),
- "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
+ "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
"total_time_spent":total_time_spent,
- "time_spent_mapping":time_spent_mapping,
+ "time_spent_mapping":time_spent_mapping,
"average_time_spent_mapping":avg_time_spent_mapping,
- "time_spent_validating":time_spent_validating,
+ "time_spent_validating":time_spent_validating,
"average_time_spent_validating":avg_time_spent_validating})
- break
- return days_list
+ break
+ return days_list
+
-
task_list=[]
-
+
if (project_id and (start_date and end_date)):
date_function(start_date, end_date, project_id)
-
+
proj_query = ProjectInfo.query.with_entities(ProjectInfo.name).filter(ProjectInfo.project_id==project_id)
proj_name=[lis[0] for lis in proj_query]
@@ -1156,11 +1156,11 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.filter(TaskHistory.action_date<=end_date)
.subquery()
.alias("filtered_actions")
-
+
)
user_tasks = (
db.session.query(filtered_actions)
- .filter(filtered_actions.c.user_id == user.id)
+ .filter(filtered_actions.c.user_id == user.id)
.subquery()
.alias("user_tasks")
)
@@ -1171,11 +1171,11 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.filter(filtered_actions.c.task_id == user_tasks.c.task_id)
.filter(filtered_actions.c.project_id == user_tasks.c.project_id)
.filter(filtered_actions.c.action_text != TaskStatus.MAPPED.name)
-
+
.subquery()
.alias("others_tasks")
)
-
+
user_stats = (
db.session.query(
actions_table.c.action_text, func.count(user_tasks.c.action_text)
@@ -1184,7 +1184,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
user_tasks, actions_table.c.action_text == user_tasks.c.action_text
)
.group_by(actions_table.c.action_text)
-
+
)
others_stats = (
@@ -1197,7 +1197,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
)
.group_by(actions_table.c.action_text)
)
-
+
res = user_stats.union(others_stats).all()
results = {key: value for key, value in res}
@@ -1218,7 +1218,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
total_validation_time = db.session.query(
func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
).scalar()
-
+
if total_validation_time:
time_spent_validating = total_validation_time.total_seconds()
avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
@@ -1230,7 +1230,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
)
)
-
+
.filter(
or_(
TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
@@ -1241,26 +1241,26 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.filter(TaskHistory.project_id==project_id)
.filter(TaskHistory.action_date>=start_date)
.filter(TaskHistory.action_date<=end_date)
-
+
.scalar()
-
+
)
if total_mapping_time:
time_spent_mapping = total_mapping_time.total_seconds()
avg_time_spent_mapping += (time_spent_mapping/int(results["MAPPED"])) if int(results["MAPPED"]) != 0 else 0
total_time_spent += time_spent_mapping
- task_list.append({"project_id":project_id,
+ task_list.append({"project_id":project_id,
"project_name":proj_name[0],
- "tasks_mapped":(results["MAPPED"]),
+ "tasks_mapped":(results["MAPPED"]),
"tasks_validated":(results["VALIDATED"]),
- "tasks_invalidated":(results["INVALIDATED"]),
+ "tasks_invalidated":(results["INVALIDATED"]),
"tasks_validated_by_others":(results["VALIDATED_BY_OTHERS"]),
- "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
+ "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
"total_time_spent":total_time_spent,
- "time_spent_mapping":time_spent_mapping,
+ "time_spent_mapping":time_spent_mapping,
"average_time_spent_mapping":avg_time_spent_mapping,
- "time_spent_validating":time_spent_validating,
+ "time_spent_validating":time_spent_validating,
"average_time_spent_validating":avg_time_spent_validating})
elif(project_id and not (start_date and end_date)):
@@ -1282,17 +1282,17 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
TaskHistory.task_id,
TaskHistory.action_text,
)
-
+
.filter(TaskHistory.action_text.in_(actions))
.filter(TaskHistory.project_id == project_id)
.subquery()
.alias("filtered_actions")
-
+
)
user_tasks = (
db.session.query(filtered_actions)
- .filter(filtered_actions.c.user_id == user.id)
+ .filter(filtered_actions.c.user_id == user.id)
.subquery()
.alias("user_tasks")
)
@@ -1303,11 +1303,11 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.filter(filtered_actions.c.task_id == user_tasks.c.task_id)
.filter(filtered_actions.c.project_id == user_tasks.c.project_id)
.filter(filtered_actions.c.action_text != TaskStatus.MAPPED.name)
-
+
.subquery()
.alias("others_tasks")
)
-
+
user_stats = (
db.session.query(
actions_table.c.action_text, func.count(user_tasks.c.action_text)
@@ -1316,7 +1316,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
user_tasks, actions_table.c.action_text == user_tasks.c.action_text
)
.group_by(actions_table.c.action_text)
-
+
)
others_stats = (
@@ -1329,7 +1329,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
)
.group_by(actions_table.c.action_text)
)
-
+
res = user_stats.union(others_stats).all()
results = {key: value for key, value in res}
@@ -1344,23 +1344,23 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.group_by("trn")
.subquery()
)
-
+
total_validation_time = db.session.query(
func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
).scalar()
-
+
if total_validation_time:
time_spent_validating = total_validation_time.total_seconds()
avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
total_time_spent += time_spent_validating
-
+
total_mapping_time = (
db.session.query(
func.sum(
cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
)
)
-
+
.filter(
or_(
TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
@@ -1376,22 +1376,22 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
avg_time_spent_mapping += (time_spent_mapping/int(results["MAPPED"])) if int(results["MAPPED"]) != 0 else 0
total_time_spent += time_spent_mapping
- task_list.append({"project_id":project_id,
+ task_list.append({"project_id":project_id,
"project_name":proj_name[0],
- "tasks_mapped":(results["MAPPED"]),
+ "tasks_mapped":(results["MAPPED"]),
"tasks_validated":(results["VALIDATED"]),
- "tasks_invalidated":(results["INVALIDATED"]),
+ "tasks_invalidated":(results["INVALIDATED"]),
"tasks_validated_by_others":(results["VALIDATED_BY_OTHERS"]),
- "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
+ "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
"total_time_spent":total_time_spent,
- "time_spent_mapping":time_spent_mapping,
+ "time_spent_mapping":time_spent_mapping,
"average_time_spent_mapping":avg_time_spent_mapping,
- "time_spent_validating":time_spent_validating,
+ "time_spent_validating":time_spent_validating,
"average_time_spent_validating":avg_time_spent_validating})
-
+
if((start_date and end_date)and not project_id):
date_function(start_date, end_date, project_id)
-
+
proj_ids = (TaskHistory.query.with_entities(TaskHistory.project_id).filter(TaskHistory.action_date>=start_date)
.filter(TaskHistory.action_date<=end_date).group_by(TaskHistory.project_id)).all()
proj_id = [lis[0] for lis in proj_ids]
@@ -1421,15 +1421,15 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.filter(TaskHistory.user_id==user.id)
.filter(TaskHistory.action_date>=start_date)
.filter(TaskHistory.action_date<=end_date)
-
+
.subquery()
.alias("filtered_actions")
-
+
)
-
+
user_tasks = (
db.session.query(filtered_actions)
- .filter(filtered_actions.c.user_id == user.id)
+ .filter(filtered_actions.c.user_id == user.id)
.subquery()
.alias("user_tasks")
)
@@ -1440,11 +1440,11 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.filter(filtered_actions.c.task_id == user_tasks.c.task_id)
.filter(filtered_actions.c.project_id == user_tasks.c.project_id)
.filter(filtered_actions.c.action_text != TaskStatus.MAPPED.name)
-
+
.subquery()
.alias("others_tasks")
)
-
+
user_stats = (
db.session.query(
actions_table.c.action_text, func.count(user_tasks.c.action_text)
@@ -1453,7 +1453,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
user_tasks, actions_table.c.action_text == user_tasks.c.action_text
)
.group_by(actions_table.c.action_text)
-
+
)
others_stats = (
@@ -1466,10 +1466,10 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
)
.group_by(actions_table.c.action_text)
)
-
+
res = user_stats.union(others_stats).all()
- results = {key: value for key, value in res}
-
+ results = {key: value for key, value in res}
+
query = (
TaskHistory.query.with_entities(
func.date_trunc("minute", TaskHistory.action_date).label("trn"),
@@ -1486,9 +1486,9 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
total_validation_time = db.session.query(
func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
).scalar()
-
-
+
+
if total_validation_time:
time_spent_validating = total_validation_time.total_seconds()
avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
@@ -1500,7 +1500,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
)
)
-
+
.filter(
or_(
TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
@@ -1510,10 +1510,10 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.filter(TaskHistory.user_id == user.id)
.filter(TaskHistory.action_date>=start_date)
.filter(TaskHistory.action_date<=end_date)
- .filter(TaskHistory.project_id == proj_id[j])
-
+ .filter(TaskHistory.project_id == proj_id[j])
+
.scalar()
-
+
)
if total_mapping_time:
time_spent_mapping = total_mapping_time.total_seconds()
@@ -1521,28 +1521,28 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
total_time_spent += time_spent_mapping
task_list.append({"project_id":(proj_id[j]),
- "project_name":proj_name[0],
- "tasks_mapped":(results["MAPPED"]),
+ "project_name":proj_name[0],
+ "tasks_mapped":(results["MAPPED"]),
"tasks_validated":(results["VALIDATED"]),
- "tasks_invalidated":(results["INVALIDATED"]),
+ "tasks_invalidated":(results["INVALIDATED"]),
"tasks_validated_by_others":(results["VALIDATED_BY_OTHERS"]),
- "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
+ "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
"total_time_spent":total_time_spent,
- "time_spent_mapping":time_spent_mapping,
+ "time_spent_mapping":time_spent_mapping,
"average_time_spent_mapping":avg_time_spent_mapping,
- "time_spent_validating":time_spent_validating,
+ "time_spent_validating":time_spent_validating,
"average_time_spent_validating":avg_time_spent_validating})
break
-
+
elif(not (start_date and end_date) and not project_id):
project_query = TaskHistory.query.with_entities(TaskHistory.project_id).group_by(TaskHistory.project_id).all()
proj_id = [lis[0] for lis in project_query]
-
+
for j in range(len(proj_id)):
proj_query = ProjectInfo.query.with_entities(ProjectInfo.name).filter(ProjectInfo.project_id==proj_id[j])
proj_name=[lis[0] for lis in proj_query]
-
+
for i in range(len(proj_id)):
avg_time_spent_mapping = 0
avg_time_spent_validating = 0
@@ -1564,10 +1564,10 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.subquery()
.alias("filtered_actions")
)
-
+
user_tasks = (
db.session.query(filtered_actions)
- .filter(filtered_actions.c.user_id == user.id)
+ .filter(filtered_actions.c.user_id == user.id)
.subquery()
.alias("user_tasks")
)
@@ -1578,11 +1578,11 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.filter(filtered_actions.c.task_id == user_tasks.c.task_id)
.filter(filtered_actions.c.project_id == user_tasks.c.project_id)
.filter(filtered_actions.c.action_text != TaskStatus.MAPPED.name)
-
+
.subquery()
.alias("others_tasks")
)
-
+
user_stats = (
db.session.query(
actions_table.c.action_text, func.count(user_tasks.c.action_text)
@@ -1591,7 +1591,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
user_tasks, actions_table.c.action_text == user_tasks.c.action_text
)
.group_by(actions_table.c.action_text)
-
+
)
others_stats = (
@@ -1604,7 +1604,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
)
.group_by(actions_table.c.action_text)
)
-
+
res = user_stats.union(others_stats).all()
results = {key: value for key, value in res}
@@ -1619,17 +1619,17 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
.group_by("trn")
.subquery()
)
-
+
total_validation_time = db.session.query(
func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
).scalar()
-
-
+
+
if total_validation_time:
time_spent_validating = total_validation_time.total_seconds()
avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
- total_time_spent += time_spent_validating
+ total_time_spent += time_spent_validating
total_mapping_time = (
db.session.query(
@@ -1637,7 +1637,7 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
)
)
-
+
.filter(
or_(
TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
@@ -1646,9 +1646,9 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
)
.filter(TaskHistory.user_id == user.id)
.filter(TaskHistory.project_id==proj_id[j])
-
+
.scalar()
-
+
)
if total_mapping_time:
@@ -1657,19 +1657,19 @@ def date_function(start_date:datetime.datetime=None, end_date:datetime.datetime=
total_time_spent += time_spent_mapping
task_list.append({"project_id":(proj_id[j]),
- "project_name":proj_name[0],
- "tasks_mapped":(results["MAPPED"]),
+ "project_name":proj_name[0],
+ "tasks_mapped":(results["MAPPED"]),
"tasks_validated":(results["VALIDATED"]),
- "tasks_invalidated":(results["INVALIDATED"]),
+ "tasks_invalidated":(results["INVALIDATED"]),
"tasks_validated_by_others":(results["VALIDATED_BY_OTHERS"]),
- "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
+ "tasks_invalidated_by_others":(results["INVALIDATED_BY_OTHERS"]),
"total_time_spent":total_time_spent,
- "time_spent_mapping":time_spent_mapping,
+ "time_spent_mapping":time_spent_mapping,
"average_time_spent_mapping":avg_time_spent_mapping,
- "time_spent_validating":time_spent_validating,
+ "time_spent_validating":time_spent_validating,
"average_time_spent_validating":avg_time_spent_validating})
break
-
+
tasks_dto.task = task_list
tasks_dto.day = days_list
@@ -1689,9 +1689,9 @@ def get_teams_stats(
actions = [
TaskStatus.VALIDATED.name,
TaskStatus.MAPPED.name,
- ]
-
-
+ ]
+
+
actions_table = (
db.session.query(literal(TaskStatus.VALIDATED.name).label("action_text"))
.union(
@@ -1701,13 +1701,13 @@ def get_teams_stats(
.alias("actions_table")
)
team_list=[]
-
-
+
+
UserQuery = TeamMembers.query.with_entities(TeamMembers.user_id).filter(TeamMembers.team_id==team_id).group_by(TeamMembers.user_id).all()
UserList = [lis[0] for lis in UserQuery]
-
+
if (team_id and (start_date and end_date)):
-
+
for j in range(len(UserList)):
teamname_query=Team.query.with_entities(Team.name).filter(Team.id==team_id)
teamname=[lis[0] for lis in teamname_query]
@@ -1716,7 +1716,7 @@ def get_teams_stats(
username=[lis[0] for lis in username_query]
for i in range(len(UserList)):
-
+
avg_time_spent_mapping = 0
avg_time_spent_validating = 0
total_time_spent = 0
@@ -1739,11 +1739,11 @@ def get_teams_stats(
.filter(TaskHistory.action_date<=end_date)
.subquery()
.alias("filtered_actions")
-
+
)
user_tasks = (
db.session.query(filtered_actions)
- .filter(filtered_actions.c.user_id == UserList[j])
+ .filter(filtered_actions.c.user_id == UserList[j])
.subquery()
.alias("user_tasks")
)
@@ -1777,7 +1777,7 @@ def get_teams_stats(
total_validation_time = db.session.query(
func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
).scalar()
-
+
if total_validation_time:
time_spent_validating = total_validation_time.total_seconds()
avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
@@ -1789,7 +1789,7 @@ def get_teams_stats(
cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
)
)
-
+
.filter(
or_(
TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
@@ -1811,12 +1811,12 @@ def get_teams_stats(
"team_name":teamname[0],
"user_id":UserList[j],
"user_name":username[0],
- "tasks_mapped":(results["MAPPED"]),
+ "tasks_mapped":(results["MAPPED"]),
"tasks_validated":(results["VALIDATED"]),
"total_time_spent":total_time_spent,
- "time_spent_mapping":time_spent_mapping,
+ "time_spent_mapping":time_spent_mapping,
"average_time_spent_mapping":avg_time_spent_mapping,
- "time_spent_validating":time_spent_validating,
+ "time_spent_validating":time_spent_validating,
"average_time_spent_validating":avg_time_spent_validating})
break
@@ -1830,7 +1830,7 @@ def get_teams_stats(
username=[lis[0] for lis in username_query]
for i in range(len(UserList)):
-
+
avg_time_spent_mapping = 0
avg_time_spent_validating = 0
total_time_spent = 0
@@ -1846,17 +1846,17 @@ def get_teams_stats(
TaskHistory.task_id,
TaskHistory.action_text,
)
-
+
.filter(TaskHistory.action_text.in_(actions))
.filter(TaskHistory.user_id==UserList[j])
.subquery()
.alias("filtered_actions")
-
+
)
user_tasks = (
db.session.query(filtered_actions)
- .filter(filtered_actions.c.user_id == UserList[j])
+ .filter(filtered_actions.c.user_id == UserList[j])
.subquery()
.alias("user_tasks")
)
@@ -1869,7 +1869,7 @@ def get_teams_stats(
user_tasks, actions_table.c.action_text == user_tasks.c.action_text
)
.group_by(actions_table.c.action_text)
-
+
)
res = user_stats.all()
@@ -1885,23 +1885,23 @@ def get_teams_stats(
.group_by("trn")
.subquery()
)
-
+
total_validation_time = db.session.query(
func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
).scalar()
-
+
if total_validation_time:
time_spent_validating = total_validation_time.total_seconds()
avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
total_time_spent += time_spent_validating
-
+
total_mapping_time = (
db.session.query(
func.sum(
cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
)
)
-
+
.filter(
or_(
TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
@@ -1919,21 +1919,21 @@ def get_teams_stats(
team_list.append({"team_id":team_id,
"team_name":teamname[0],
"user_id":UserList[j],
- "user_name":username[0],
- "tasks_mapped":(results["MAPPED"]),
+ "user_name":username[0],
+ "tasks_mapped":(results["MAPPED"]),
"tasks_validated":(results["VALIDATED"]),
"total_time_spent":total_time_spent,
- "time_spent_mapping":time_spent_mapping,
+ "time_spent_mapping":time_spent_mapping,
"average_time_spent_mapping":avg_time_spent_mapping,
- "time_spent_validating":time_spent_validating,
+ "time_spent_validating":time_spent_validating,
"average_time_spent_validating":avg_time_spent_validating})
break
-
+
user_query = TeamMembers.query.with_entities(TeamMembers.user_id).group_by(TeamMembers.user_id).all()
user_list = [lis[0] for lis in user_query]
-
- if((start_date and end_date)and not team_id):
-
+
+ if((start_date and end_date)and not team_id):
+
for j in range(len(user_list)):
username_query=User.query.with_entities(User.username).filter(User.id==user_list[j])
username=[lis[0] for lis in username_query]
@@ -1941,9 +1941,9 @@ def get_teams_stats(
for i in range(len(user_list)):
team_query = TeamMembers.query.with_entities(TeamMembers.team_id).filter(TeamMembers.user_id==user_list[j]).group_by(TeamMembers.team_id).all()
t_id = [lis[0] for lis in team_query]
-
+
teamname=[]
- for var in t_id:
+ for var in t_id:
teamname_query=Team.query.with_entities(Team.name).filter(Team.id==var).all()
teamname.append(teamname_query)
teamname=[lis[0] for lis in teamname]
@@ -1968,18 +1968,18 @@ def get_teams_stats(
.filter(TaskHistory.action_text.in_(actions))
.filter(TaskHistory.user_id==user_list[j])
.filter(TaskHistory.action_date>=start_date)
- .filter(TaskHistory.action_date<=end_date)
+ .filter(TaskHistory.action_date<=end_date)
.subquery()
.alias("filtered_actions")
)
-
+
user_tasks = (
db.session.query(filtered_actions)
- .filter(filtered_actions.c.user_id == user_list[j])
+ .filter(filtered_actions.c.user_id == user_list[j])
.subquery()
.alias("user_tasks")
)
-
+
user_stats = (
db.session.query(
actions_table.c.action_text, func.count(user_tasks.c.action_text)
@@ -1988,12 +1988,12 @@ def get_teams_stats(
user_tasks, actions_table.c.action_text == user_tasks.c.action_text
)
.group_by(actions_table.c.action_text)
-
+
)
-
+
res = user_stats.all()
- results = {key: value for key, value in res}
-
+ results = {key: value for key, value in res}
+
query = (
TaskHistory.query.with_entities(
func.date_trunc("minute", TaskHistory.action_date).label("trn"),
@@ -2009,9 +2009,9 @@ def get_teams_stats(
total_validation_time = db.session.query(
func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
).scalar()
-
-
+
+
if total_validation_time:
time_spent_validating = total_validation_time.total_seconds()
avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
@@ -2023,7 +2023,7 @@ def get_teams_stats(
cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
)
)
-
+
.filter(
or_(
TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
@@ -2032,10 +2032,10 @@ def get_teams_stats(
)
.filter(TaskHistory.user_id == user_list[j])
.filter(TaskHistory.action_date>=start_date)
- .filter(TaskHistory.action_date<=end_date)
-
+ .filter(TaskHistory.action_date<=end_date)
+
.scalar()
-
+
)
if total_mapping_time:
time_spent_mapping = total_mapping_time.total_seconds()
@@ -2045,19 +2045,19 @@ def get_teams_stats(
team_list.append({"team_id":t_id,
"team_name":teamname,
"user_id":user_list[j],
- "user_name":username[0],
- "tasks_mapped":(results["MAPPED"]),
+ "user_name":username[0],
+ "tasks_mapped":(results["MAPPED"]),
"tasks_validated":(results["VALIDATED"]),
"total_time_spent":total_time_spent,
- "time_spent_mapping":time_spent_mapping,
+ "time_spent_mapping":time_spent_mapping,
"average_time_spent_mapping":avg_time_spent_mapping,
- "time_spent_validating":time_spent_validating,
+ "time_spent_validating":time_spent_validating,
"average_time_spent_validating":avg_time_spent_validating})
break
-
-
+
+
elif(not (start_date and end_date) and not team_id):
-
+
for j in range(len(user_list)):
username_query=User.query.with_entities(User.username).filter(User.id==user_list[j])
username=[lis[0] for lis in username_query]
@@ -2065,12 +2065,12 @@ def get_teams_stats(
for i in range(len(user_list)):
team_query = TeamMembers.query.with_entities(TeamMembers.team_id).filter(TeamMembers.user_id==user_list[j]).group_by(TeamMembers.team_id).all()
t_id = [lis[0] for lis in team_query]
-
+
teamname=[]
- for var in t_id:
+ for var in t_id:
teamname_query=Team.query.with_entities(Team.name).filter(Team.id==var).all()
teamname.append(teamname_query)
-
+
teamname=[lis[0] for lis in teamname]
teamname=[lis[0] for lis in teamname]
@@ -2081,7 +2081,7 @@ def get_teams_stats(
time_spent_validating = 0
total_mapping_time = 0
total_validation_time = 0
-
+
filtered_actions = (
TaskHistory.query.with_entities(
TaskHistory.user_id,
@@ -2094,14 +2094,14 @@ def get_teams_stats(
.subquery()
.alias("filtered_actions")
)
-
+
user_tasks = (
db.session.query(filtered_actions)
- .filter(filtered_actions.c.user_id == user_list[j])
+ .filter(filtered_actions.c.user_id == user_list[j])
.subquery()
.alias("user_tasks")
)
-
+
user_stats = (
db.session.query(
actions_table.c.action_text, func.count(user_tasks.c.action_text)
@@ -2110,9 +2110,9 @@ def get_teams_stats(
user_tasks, actions_table.c.action_text == user_tasks.c.action_text
)
.group_by(actions_table.c.action_text)
-
+
)
-
+
res = user_stats.all()
results = {key: value for key, value in res}
@@ -2127,17 +2127,17 @@ def get_teams_stats(
.group_by("trn")
.subquery()
)
-
+
total_validation_time = db.session.query(
func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
).scalar()
-
-
+
+
if total_validation_time:
time_spent_validating = total_validation_time.total_seconds()
avg_time_spent_validating += (time_spent_validating/results["VALIDATED"]) if int(results["VALIDATED"]) != 0 else 0
- total_time_spent += time_spent_validating
+ total_time_spent += time_spent_validating
total_mapping_time = (
db.session.query(
@@ -2145,7 +2145,7 @@ def get_teams_stats(
cast(func.to_timestamp(TaskHistory.action_text, "HH24:MI:SS"), Time)
)
)
-
+
.filter(
or_(
TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
@@ -2160,24 +2160,24 @@ def get_teams_stats(
time_spent_mapping = total_mapping_time.total_seconds()
avg_time_spent_mapping += (time_spent_mapping/results["MAPPED"]) if int(results["MAPPED"]) != 0 else 0
total_time_spent += time_spent_mapping
-
+
team_list.append({"team_id":t_id,
- "team_name":teamname,
+ "team_name":teamname,
"user_id":user_list[j],
- "user_name":username[0],
- "tasks_mapped":(results["MAPPED"]),
+ "user_name":username[0],
+ "tasks_mapped":(results["MAPPED"]),
"tasks_validated":(results["VALIDATED"]),
"total_time_spent":total_time_spent,
- "time_spent_mapping":time_spent_mapping,
+ "time_spent_mapping":time_spent_mapping,
"average_time_spent_mapping":avg_time_spent_mapping,
- "time_spent_validating":time_spent_validating,
+ "time_spent_validating":time_spent_validating,
"average_time_spent_validating":avg_time_spent_validating})
break
-
+
teams_dto.team = team_list
return teams_dto
-
+
@staticmethod
def get_user_specific_task(
username: str,
@@ -2188,15 +2188,15 @@ def get_user_specific_task(
user = UserService.get_user_by_username(username)
task_dto = UserSpecificDTO()
- task_list=[]
+ stats_by_task=[]
- actions = [
+ action_status_list = [
TaskStatus.VALIDATED.name,
TaskStatus.MAPPED.name,
TaskStatus.INVALIDATED.name,
TaskStatus.BADIMAGERY.name
- ]
- action_list=[
+ ]
+ lock_status_list=[
TaskStatus.LOCKED_FOR_MAPPING.name,
TaskStatus.LOCKED_FOR_VALIDATION.name,
]
@@ -2218,50 +2218,50 @@ def get_user_specific_task(
for i in range(len(taskid_list)):
review_query=Task.query.with_entities(Task.validated_by).filter(Task.project_id==pro_list[j]).filter(Task.id==taskid_list[i]).all()
review_list=[lis[0] for lis in review_query]
-
+
date_query=(TaskHistory.query.with_entities(TaskHistory.action_date).filter(TaskHistory.project_id==pro_list[j])
.filter(TaskHistory.task_id==taskid_list[i])
.filter(TaskHistory.user_id==user.id)
- .filter(TaskHistory.action_text.in_(actions))
+ .filter(TaskHistory.action_text.in_(action_status_list))
).all()
date_list=[lis[0] for lis in date_query]
-
+
time_spent_mapping=0
time_spent_validating=0
total_time_spent=0
base_query=(TaskHistory.query.with_entities(
TaskHistory.task_id,
- TaskHistory.project_id,
+ TaskHistory.project_id,
TaskHistory.action_text,
)
.filter(TaskHistory.project_id==pro_list[j])
.filter(TaskHistory.task_id==taskid_list[i])
.filter(TaskHistory.user_id==user.id)
- .filter(TaskHistory.action_text.in_(actions))
+ .filter(TaskHistory.action_text.in_(action_status_list))
)
if task_status:
- if task_status.upper() in actions:
+ if task_status.upper() in action_status_list:
base_query = base_query.filter(TaskHistory.action_text == TaskStatus[task_status.upper()].name)
if (start_date and end_date):
base_query = base_query.filter(TaskHistory.action_date >= start_date).filter(TaskHistory.action_date <= end_date)
- elif task_status.upper() in action_list:
+ elif task_status.upper() in lock_status_list:
date_query=(TaskHistory.query.with_entities(TaskHistory.action_date).filter(TaskHistory.project_id==pro_list[j])
.filter(TaskHistory.task_id==taskid_list[i])
.filter(TaskHistory.user_id==user.id)
- .filter(TaskHistory.action.in_(action_list))
+ .filter(TaskHistory.action.in_(lock_status_list))
).all()
date_list=[lis[0] for lis in date_query]
base_query=(TaskHistory.query.with_entities(
TaskHistory.task_id,
- TaskHistory.project_id,
+ TaskHistory.project_id,
TaskHistory.action,
)
.filter(TaskHistory.project_id==pro_list[j])
.filter(TaskHistory.task_id==taskid_list[i])
.filter(TaskHistory.user_id==user.id)
- .filter(TaskHistory.action.in_(action_list))
+ .filter(TaskHistory.action.in_(lock_status_list))
)
base_query=base_query.filter(TaskHistory.action==TaskStatus[task_status.upper()].name)
if (start_date and end_date):
@@ -2270,7 +2270,7 @@ def get_user_specific_task(
base_query = base_query.filter(TaskHistory.action_date >= start_date).filter(TaskHistory.action_date <= end_date)
base_query=base_query.all()
-
+
query = (
TaskHistory.query.with_entities(
func.date_trunc("minute", TaskHistory.action_date).label("trn"),
@@ -2287,11 +2287,11 @@ def get_user_specific_task(
total_validation_time = db.session.query(
func.sum(cast(func.to_timestamp(query.c.tm, "HH24:MI:SS"), Time))
).scalar()
-
+
if total_validation_time:
time_spent_validating = total_validation_time.total_seconds()
total_time_spent += time_spent_validating
-
+
total_mapping_time = (
db.session.query(
func.sum(
@@ -2314,18 +2314,18 @@ def get_user_specific_task(
total_time_spent += time_spent_mapping
task_status_list=[lis[2] for lis in base_query]
-
+
if len(base_query):
- task_list.append({"user_name":username,
- "project_id":pro_list[j],
- "tasks_id":taskid_list[i],
+ stats_by_task.append({"user_name":username,
+ "project_id":pro_list[j],
+ "tasks_id":taskid_list[i],
"task_status":task_status_list[0],
- "action_date":str(date_list[0]),
+ "action_date":str(date_list[0]),
"total_time_spent":total_time_spent,
- "time_spent_mapping":time_spent_mapping,
+ "time_spent_mapping":time_spent_mapping,
"time_spent_validating":time_spent_validating,
- "reviewer":review_list[0]})
-
- task_dto.tasks = task_list
+ "reviewer":review_list[0]})
+
+ task_dto.tasks = stats_by_task
- return task_dto
\ No newline at end of file
+ return task_dto
diff --git a/frontend/src/components/teamsAndOrgs/teams.js b/frontend/src/components/teamsAndOrgs/teams.js
index 2da4b8e4c..2ca20e4e8 100644
--- a/frontend/src/components/teamsAndOrgs/teams.js
+++ b/frontend/src/components/teamsAndOrgs/teams.js
@@ -384,8 +384,6 @@ export function TeamsBoxList({ teams }: Object) {
);
}
export function TeamsStats() {
- // const mappingTeams = teams.filter((team) => team.role === 'MAPPER');
- // const validationTeams = teams.filter((team) => team.role === 'VALIDATOR');
const token = useSelector((state) => state.auth.get('token'));
const userDetails = useSelector((state) => state.auth.get('userDetails'));
const userName = userDetails.username;