Commit 1026c9775abfd07f389334b0011ac6422b9d8f5a

Authored by Jailson Dias
1 parent ac55c658

Criando os telatórios de arquivo pdf

pdf_file/locale/pt_BR/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid "" @@ -8,7 +8,7 @@ msgid ""
8 msgstr "" 8 msgstr ""
9 "Project-Id-Version: PACKAGE VERSION\n" 9 "Project-Id-Version: PACKAGE VERSION\n"
10 "Report-Msgid-Bugs-To: \n" 10 "Report-Msgid-Bugs-To: \n"
11 -"POT-Creation-Date: 2017-04-15 00:12-0300\n" 11 +"POT-Creation-Date: 2017-04-28 20:39-0300\n"
12 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" 13 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14 "Language-Team: LANGUAGE <LL@li.org>\n" 14 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,100 +18,139 @@ msgstr &quot;&quot; @@ -18,100 +18,139 @@ msgstr &quot;&quot;
18 "Content-Transfer-Encoding: 8bit\n" 18 "Content-Transfer-Encoding: 8bit\n"
19 "Plural-Forms: nplurals=2; plural=(n > 1);\n" 19 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
20 20
21 -#: pdf_file/forms.py:25 21 +#: forms.py:25
22 msgid "Tags" 22 msgid "Tags"
23 -msgstr "" 23 +msgstr "Tags"
24 24
25 -#: pdf_file/forms.py:30 25 +#: forms.py:30
26 msgid "File name" 26 msgid "File name"
27 msgstr "Nome do arquivo" 27 msgstr "Nome do arquivo"
28 28
29 -#: pdf_file/forms.py:51 29 +#: forms.py:51
30 msgid "This subject already has a pdf file with this name" 30 msgid "This subject already has a pdf file with this name"
31 msgstr "Este assunto já possui um arquivo PDF com este nome" 31 msgstr "Este assunto já possui um arquivo PDF com este nome"
32 32
33 -#: pdf_file/forms.py:63 33 +#: forms.py:63
34 msgid "The file is too large. It should have less than 10MB." 34 msgid "The file is too large. It should have less than 10MB."
35 msgstr "O arquivo é muito grande. Deve ser menor do que 10MB" 35 msgstr "O arquivo é muito grande. Deve ser menor do que 10MB"
36 36
37 -#: pdf_file/forms.py:68 37 +#: forms.py:68
38 msgid "This field is required." 38 msgid "This field is required."
39 -msgstr "" 39 +msgstr "Este campo é requerido."
40 40
41 -#: pdf_file/models.py:16 41 +#: models.py:16
42 msgid "File not supported, use PDF format instead." 42 msgid "File not supported, use PDF format instead."
43 msgstr "Este formato não é suportado, use PDF." 43 msgstr "Este formato não é suportado, use PDF."
44 44
45 -#: pdf_file/models.py:19 45 +#: models.py:19
46 msgid "File" 46 msgid "File"
47 -msgstr "" 47 +msgstr "Arquivo"
48 48
49 -#: pdf_file/models.py:42 49 +#: models.py:42
50 msgid "Are you sure you want delete the PDF File" 50 msgid "Are you sure you want delete the PDF File"
51 msgstr "Tem certeza que deseja deletar este arquivo PDF?" 51 msgstr "Tem certeza que deseja deletar este arquivo PDF?"
52 52
53 -#: pdf_file/templates/pdf_file/_form.html:32 53 +#: templates/pdf_file/_form.html:32
54 msgid "Choose your file..." 54 msgid "Choose your file..."
55 msgstr "" 55 msgstr ""
56 56
57 -#: pdf_file/templates/pdf_file/_form.html:46 57 +#: templates/pdf_file/_form.html:46
58 msgid "Click or drop the file here" 58 msgid "Click or drop the file here"
59 msgstr "Clique ou arraste o arquivo aqui." 59 msgstr "Clique ou arraste o arquivo aqui."
60 60
61 -#: pdf_file/templates/pdf_file/_form.html:48 61 +#: templates/pdf_file/_form.html:48
62 msgid "The file could not exceed 10MB." 62 msgid "The file could not exceed 10MB."
63 msgstr "O arquivo não pode exceder 10MB." 63 msgstr "O arquivo não pode exceder 10MB."
64 64
65 -#: pdf_file/templates/pdf_file/_form.html:68 65 +#: templates/pdf_file/_form.html:68
66 msgid "Common resources settings" 66 msgid "Common resources settings"
67 -msgstr "" 67 +msgstr "Configurações comuns à todos os recursos"
68 68
69 -#: pdf_file/templates/pdf_file/_form.html:119 69 +#: templates/pdf_file/_form.html:119
70 msgid "Pendencies Notifications" 70 msgid "Pendencies Notifications"
71 -msgstr "" 71 +msgstr "Notificações pendentes"
72 72
73 -#: pdf_file/templates/pdf_file/_form.html:135 73 +#: templates/pdf_file/_form.html:135
74 msgid "Action not performed by the user" 74 msgid "Action not performed by the user"
75 -msgstr "" 75 +msgstr "Ação não permitida pelo usuário"
76 76
77 -#: pdf_file/templates/pdf_file/_form.html:161 77 +#: templates/pdf_file/_form.html:161
78 msgid "Wished period" 78 msgid "Wished period"
79 msgstr "" 79 msgstr ""
80 80
81 -#: pdf_file/templates/pdf_file/_form.html:257 81 +#: templates/pdf_file/_form.html:257
82 msgid "Attribute students to file link" 82 msgid "Attribute students to file link"
83 msgstr "" 83 msgstr ""
84 84
85 -#: pdf_file/templates/pdf_file/_form.html:277 85 +#: templates/pdf_file/_form.html:277
86 msgid "Attribute groups to file link" 86 msgid "Attribute groups to file link"
87 msgstr "" 87 msgstr ""
88 88
89 -#: pdf_file/templates/pdf_file/_form.html:346 89 +#: templates/pdf_file/_form.html:346
90 msgid "Save" 90 msgid "Save"
91 -msgstr "" 91 +msgstr "Salvar"
92 92
93 -#: pdf_file/templates/pdf_file/create.html:20 93 +#: templates/pdf_file/create.html:20
94 msgid "Create PDF file" 94 msgid "Create PDF file"
95 msgstr "Criar arquivo PDF" 95 msgstr "Criar arquivo PDF"
96 96
97 -#: pdf_file/templates/pdf_file/update.html:20 97 +#: templates/pdf_file/relatorios.html:16 templates/pdf_file/relatorios.html:30
  98 +#: templates/pdf_file/relatorios.html:37
  99 +msgid "User"
  100 +msgstr "Usuário"
  101 +
  102 +#: templates/pdf_file/relatorios.html:16 templates/pdf_file/relatorios.html:30
  103 +#: templates/pdf_file/relatorios.html:37
  104 +msgid "Group"
  105 +msgstr "Grupo"
  106 +
  107 +#: templates/pdf_file/relatorios.html:16 templates/pdf_file/relatorios.html:30
  108 +msgid "Action"
  109 +msgstr "Ação"
  110 +
  111 +#: templates/pdf_file/relatorios.html:16 templates/pdf_file/relatorios.html:30
  112 +msgid "Date of Action"
  113 +msgstr "Data da ação"
  114 +
  115 +#: templates/pdf_file/relatorios.html:135
  116 +#: templates/pdf_file/relatorios.html:155
  117 +msgid "Reports"
  118 +msgstr "Relatórios"
  119 +
  120 +#: templates/pdf_file/relatorios.html:162
  121 +msgid "Report of the resource "
  122 +msgstr "Relatórios do recurso "
  123 +
  124 +#: templates/pdf_file/relatorios.html:165
  125 +msgid "Select the period: "
  126 +msgstr "Selecione o período: "
  127 +
  128 +#: templates/pdf_file/relatorios.html:178
  129 +msgid "Search"
  130 +msgstr "Pesquisar"
  131 +
  132 +#: templates/pdf_file/relatorios.html:200
  133 +msgid "Filter: "
  134 +msgstr "Filtro: "
  135 +
  136 +#: templates/pdf_file/update.html:20
98 msgid "Edit: " 137 msgid "Edit: "
99 msgstr "Editar: " 138 msgstr "Editar: "
100 139
101 -#: pdf_file/templates/pdf_file/view.html:52 140 +#: templates/pdf_file/view.html:52
102 msgid "PDF could not be displayed" 141 msgid "PDF could not be displayed"
103 msgstr "PDF não pode ser mostrado" 142 msgstr "PDF não pode ser mostrado"
104 143
105 -#: pdf_file/views.py:110 pdf_file/views.py:123 pdf_file/views.py:234  
106 -#: pdf_file/views.py:236 pdf_file/views.py:252 pdf_file/views.py:254 144 +#: views.py:112 views.py:125 views.py:236 views.py:238 views.py:254
  145 +#: views.py:256
107 msgid "Visualize" 146 msgid "Visualize"
108 -msgstr "" 147 +msgstr "Visualizar"
109 148
110 -#: pdf_file/views.py:183 149 +#: views.py:185
111 msgid "Create PDF File" 150 msgid "Create PDF File"
112 msgstr "Criar o arquivo PDF" 151 msgstr "Criar o arquivo PDF"
113 152
114 -#: pdf_file/views.py:194 153 +#: views.py:196
115 #, python-format 154 #, python-format
116 msgid "" 155 msgid ""
117 "The PDF File \"%s\" was added to the Topic \"%s\" of the virtual environment " 156 "The PDF File \"%s\" was added to the Topic \"%s\" of the virtual environment "
@@ -120,18 +159,50 @@ msgstr &quot;&quot; @@ -120,18 +159,50 @@ msgstr &quot;&quot;
120 "O arquivo PDF \"%s\" foi adicionado ao topico \"%s\" do ambiente virtual " 159 "O arquivo PDF \"%s\" foi adicionado ao topico \"%s\" do ambiente virtual "
121 "\"%s\" com sucesso!" 160 "\"%s\" com sucesso!"
122 161
123 -#: pdf_file/views.py:298 162 +#: views.py:300
124 msgid "Update PDF File" 163 msgid "Update PDF File"
125 msgstr "Atualize arquivo PDF" 164 msgstr "Atualize arquivo PDF"
126 165
127 -#: pdf_file/views.py:309 166 +#: views.py:311
128 #, python-format 167 #, python-format
129 msgid "The PDF File \"%s\" was updated successfully!" 168 msgid "The PDF File \"%s\" was updated successfully!"
130 msgstr "O arquivo PDF \"%s\" foi atualizado com sucesso!" 169 msgstr "O arquivo PDF \"%s\" foi atualizado com sucesso!"
131 170
132 -#: pdf_file/views.py:336 171 +#: views.py:338
133 #, python-format 172 #, python-format
134 msgid "" 173 msgid ""
135 "The PDF File \"%s\" was removed successfully from virtual environment \"%s\"!" 174 "The PDF File \"%s\" was removed successfully from virtual environment \"%s\"!"
136 msgstr "" 175 msgstr ""
137 "O arquivo PDF \"%s\" foi removido com sucesso do ambiente virtual \"%s\" " 176 "O arquivo PDF \"%s\" foi removido com sucesso do ambiente virtual \"%s\" "
  177 +
  178 +#: views.py:396
  179 +msgid "PDF File Reports"
  180 +msgstr "Relatórios do arquivo de PDF"
  181 +
  182 +#: views.py:414
  183 +msgid "Users who viewed"
  184 +msgstr "Usuário que visualizaram"
  185 +
  186 +#: views.py:414
  187 +msgid "Users who did not viewed"
  188 +msgstr "Usuários que não visualizaram"
  189 +
  190 +#: views.py:414
  191 +msgid "Historic"
  192 +msgstr "Histórico"
  193 +
  194 +#: views.py:446
  195 +msgid "PDF File"
  196 +msgstr "Criar o arquivo PDF"
  197 +
  198 +#: views.py:447
  199 +msgid "View"
  200 +msgstr "Visualizar"
  201 +
  202 +#: views.py:451
  203 +msgid "Students viewing the PDF File"
  204 +msgstr "Estudantes que visualizaram o arquivo PDF"
  205 +
  206 +#: views.py:452
  207 +msgid "Quantity"
  208 +msgstr "Quantidade"
pdf_file/templates/pdf_file/relatorios.html 0 → 100644
@@ -0,0 +1,357 @@ @@ -0,0 +1,357 @@
  1 +{% extends "pdf_file/view.html" %}
  2 +
  3 +{% load static i18n pagination permissions_tags subject_counter %}
  4 +{% load django_bootstrap_breadcrumbs %}
  5 +
  6 +{% block javascript%}
  7 + {{ block.super }}
  8 + <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  9 + <script type="text/javascript">
  10 +
  11 + var array_history = [];
  12 + {%for data_json in json_history.data%}
  13 + array_history.push(["{{data_json.0}}","{{data_json.1}}","{{data_json.2}}",{% if data_json.3 is not None %}new Date('{{data_json.3.isoformat}}'){% else%}null{% endif %}]);
  14 + {% endfor%}
  15 + var json_history = {"data":array_history};
  16 + var column_history = [{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":'{% trans "Action" %}'},{"date":'{% trans "Date of Action" %}'}];
  17 +
  18 + var search = [];
  19 + for (var i in json_history["data"]){
  20 + search.push([json_history["data"][i][0],json_history["data"][i][1],
  21 + json_history["data"][i][2],json_history["data"][i][3]]);
  22 + }
  23 +
  24 +
  25 + var array_did = [];
  26 + {%for data_json in json_did.data%}
  27 + array_did.push(["{{data_json.0}}","{{data_json.1}}","{{data_json.2}}",{% if data_json.3 is not None %}new Date('{{data_json.3.isoformat}}'){% else%}null{% endif %}]);
  28 + {% endfor%}
  29 + var json_did = {"data":array_did};
  30 + var column_did = [{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":'{% trans "Action" %}'},{"date":'{% trans "Date of Action" %}'}];
  31 +
  32 + var array_n_did = [];
  33 + {%for data_json in json_n_did.data%}
  34 + array_n_did.push(["{{data_json.0}}","{{data_json.1}}"]);
  35 + {% endfor%}
  36 + var json_n_did = {"data":array_n_did};
  37 + var column_n_did = [{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'}];
  38 + </script>
  39 +
  40 +
  41 + <script type="text/javascript">
  42 + google.charts.load('current', {'packages':['corechart',"table"]});
  43 + google.charts.setOnLoadCallback(drawChart);
  44 + google.charts.setOnLoadCallback(drawTable);
  45 +
  46 + function drawChart() {
  47 + var data = google.visualization.arrayToDataTable({{db_data|safe}});
  48 + var options = {
  49 + title: '{{title_chart}}',
  50 + // legend: {position: 'right', maxLines: 1},
  51 + bar: { groupWidth: '30%' },
  52 + chartArea:{width:"50%"},
  53 + titlePosition: 'out',
  54 + vAxis: {
  55 + title: '{{title_vAxis}}',
  56 + ticks: [0, .20, .40, .60, .80, 1],
  57 + viewWindow: {
  58 + min: 0,
  59 + max: 1
  60 + }
  61 + },
  62 + isStacked: "percent",
  63 + };
  64 +
  65 + function selectHandler() {
  66 + var selectedItem = chart.getSelection()[0];
  67 + if (selectedItem) {
  68 + var col = data.getColumnLabel(selectedItem.column);
  69 + var element = '<li id="link-history">\
  70 + <a id="call-history" href="javascript:void(0);" onclick="return backhistory();"> <i class="fa fa-arrow-left ta-fw"> </i> {{history_table}}</a>\
  71 + </li>';
  72 + if (col == "{{n_did_table}}" && text("#title-table") != "{{n_did_table}}"){
  73 + if (length("#link-history") <= 0){
  74 + add(element,"#view-table",true);
  75 + }
  76 + altertitle("{{n_did_table}}");
  77 + search = [];
  78 + for (var i in json_n_did["data"]){
  79 + search.push([json_n_did["data"][i][0],json_n_did["data"][i][1]]);
  80 + }
  81 + drawTable(column_n_did,pagination(json_n_did["data"],1),false);
  82 + putpagination(json_n_did["data"]);
  83 +
  84 + } else if (col == "{{did_table}}" && text("#title-table") != "{{did_table}}"){
  85 + if (length("#link-history") <= 0){
  86 + add(element,"#view-table",true);
  87 + }
  88 + altertitle("{{did_table}}");
  89 + search = [];
  90 + for (var i in json_did["data"]){
  91 + search.push([json_did["data"][i][0],json_did["data"][i][1],
  92 + json_did["data"][i][2],json_did["data"][i][3]]);
  93 + }
  94 + drawTable(column_did,pagination(json_did["data"],1),true,3);
  95 + putpagination(json_did["data"]);
  96 + }
  97 + }
  98 + chart.setSelection([])
  99 + }
  100 +
  101 + var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
  102 + google.visualization.events.addListener(chart, 'select', selectHandler);
  103 + chart.draw(data, options);
  104 +
  105 + }
  106 + function drawTable(columns = column_history,rows = pagination(json_history["data"],1),isdate = true,columndate = 3) {
  107 + var data_table = new google.visualization.DataTable();
  108 + for (var i in columns){
  109 + for (var item in columns[i]){
  110 + data_table.addColumn(item,columns[i][item]);
  111 + }
  112 + }
  113 +
  114 + data_table.addRows(rows);
  115 + var formate_date = new google.visualization.DateFormat({pattern: 'dd/MM/yyyy HH:mm'});
  116 + if (isdate) formate_date.format(data_table, columndate);
  117 +
  118 + // var methods = [];
  119 + // for (var m in data_table) {
  120 + // if (typeof data_table[m] == "function") {
  121 + // methods.push(m);
  122 + // }
  123 + // }
  124 + // console.log(methods.join(","));
  125 +
  126 + var table = new google.visualization.Table(document.getElementById('table_div'));
  127 +
  128 + table.draw(data_table, {showRowNumber: true, width: '100%', height: '100%'});
  129 + }
  130 + </script>
  131 +{% endblock%}
  132 +
  133 +{% block breadcrumbs %}
  134 + {{ block.super }}
  135 + {% trans 'Reports' as bread %}
  136 + {% breadcrumb bread pdf_file%}
  137 +{% endblock %}
  138 +
  139 +{% block content %}
  140 + {% if messages %}
  141 + {% for message in messages %}
  142 + <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">
  143 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  144 + <span aria-hidden="true">&times;</span>
  145 + </button>
  146 + <p>{{ message }}</p>
  147 + </div>
  148 + {% endfor %}
  149 + {% endif %}
  150 + <div class="panel panel-info topic-panel">
  151 + <div class="panel-heading">
  152 + <div class="row">
  153 + <div class="col-md-12 category-header">
  154 + <h4 class="panel-title" style="margin-top: 10px; margin-bottom: 8px">
  155 + <span>{{pdf_file}} / {% trans "Reports" %}</span>
  156 + </h4>
  157 + </div>
  158 + </div>
  159 + </div>
  160 + <div class="row">
  161 + <div class="col-md-12 text-center">
  162 + <h4 style="margin-top: 15px; margin-bottom: 10px" ><strong>{% trans "Report of the resource " %}{{pdf_file}}</strong></h4>
  163 + </div>
  164 + <div class="col-md-2 text-right">
  165 + <h4>{% trans "Select the period: " %}</h4>
  166 + </div>
  167 + <div class="col-md-8">
  168 + <div id="general-parameters-div">
  169 + <form id="period-form" action="" method="get">
  170 + <div class="general-parameters-field">
  171 + <input class="form-control datetime-picker" name="init_date" type="text" required="" value="{% if LANGUAGE_CODE == 'pt-br' %}{{init_date|date:'d/m/Y H:i'}} {% else %} {{init_date|date:'m/d/Y H:i P'}} {% endif %}">
  172 + </div>
  173 +
  174 + <div class="general-parameters-field">
  175 + {# <label class="form-field-report"> {% trans "Final Date" %} </label> #}
  176 + <input id="inputdate" class="form-control datetime-picker" name="end_date" type="text" required="" value="{% if LANGUAGE_CODE == 'pt-br' %}{{end_date|date:'d/m/Y H:i'}} {% else %} {{end_date|date:'m/d/Y H:i P'}} {% endif %}">
  177 + </div>
  178 + <input type="submit" value="{% trans 'Search' %}" style="margin-left: 15px;" class="btn btn-success btn-raised">
  179 + </form>
  180 + </div>
  181 + </div>
  182 + </div>
  183 + <div class="row">
  184 + <div class="col-md-10 col-md-offset-1">
  185 + <div id="chart_div" style="height: 500px; margin-top: -50px;"></div>
  186 + </div>
  187 + </div>
  188 +
  189 + <div class="row">
  190 + <div class="col-md-10 col-md-offset-1">
  191 + <div class="text-center">
  192 + <ul class="list-inline nav-justified">
  193 + <li>
  194 + <ul id="view-table" class="list-inline text-right">
  195 + <li><h3 id="title-table">{{history_table}}</h3></li>
  196 + </ul>
  197 + </li>
  198 + <li>
  199 + <ul class="list-inline text-right">
  200 + <li><p>{% trans "Filter: " %}</p></li>
  201 + <li><input id="search-input" class="form-control" type="text" name="search" value=""></li>
  202 + </ul>
  203 + </li>
  204 + </ul>
  205 + </div>
  206 +
  207 + <div id="table_div"></div>
  208 + <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12 text-center">
  209 + <ul class="pagination">
  210 +
  211 + </ul>
  212 + </div>
  213 + </div>
  214 + </div>
  215 + <div class="row">
  216 + <br><br>
  217 + </div>
  218 + </div>
  219 +
  220 + <script type="text/javascript">
  221 + function putpagination(data = json_history["data"]){
  222 + var len = Math.ceil(data.length / 20);
  223 + $(".pagination").empty();
  224 + $(".pagination").append('<li class="disabled"><span>«</span></li>');
  225 + $(".pagination").append('<li id="1" class="active">\
  226 + <a href="javascript:void(0);" onclick="return clickPagination(1);">1</a>\
  227 + </li>');
  228 + for (var i = 2; i <= len;i++){
  229 + $(".pagination").append('<li id="' + i + '">\
  230 + <a href="javascript:void(0);" onclick="return clickPagination(' + i +');">' + i + '</a>\
  231 + </li>');
  232 + }
  233 + if (len > 1) $(".pagination").append('<li><a href="javascript:void(0);" onclick="return clickPagination(2);"><span>»</span></a></li>');
  234 + else $(".pagination").append('<li class="disabled"><span>»</span></li>');
  235 + };
  236 + putpagination();
  237 +
  238 + $('#period-form').submit(function(event) {
  239 + $('<input />').attr('type', 'hidden')
  240 + .attr('name', "language")
  241 + .attr('value', '{{ LANGUAGE_CODE }}')
  242 + .appendTo('#period-form');
  243 + });
  244 + function altertitle(value) {
  245 + $("#title-table").text(value);
  246 + }
  247 + function add(element,local, first = false){
  248 + if (first) $(local).prepend(element);
  249 + else $(local).append(element);
  250 + }
  251 + function text(element){
  252 + return $(element).text();
  253 + }
  254 + function length(element) {
  255 + return $(element).length;
  256 + }
  257 + function backhistory(){
  258 + drawTable(column_history,json_history["data"],true,3);
  259 + $("#title-table").text("{{history_table}}");
  260 + $("#link-history").remove();
  261 + search = [];
  262 + for (var i in json_history["data"]){
  263 + search.push([json_history["data"][i][0],json_history["data"][i][1],
  264 + json_history["data"][i][2],json_history["data"][i][3]]);
  265 + }
  266 + putpagination(json_history["data"]);
  267 + }
  268 + // $("#search-input").on("keyup",function(){
  269 + // console.log($("#search-input").val());
  270 + // });
  271 + $("#search-input").on("keyup",function(){
  272 + search = [];
  273 + var text = $("#search-input").val();
  274 + var data = [];
  275 + if ($("#title-table").text() == "{{n_did_table}}"){
  276 + data = $.map(json_n_did["data"], function (obj) {
  277 + return $.extend(true, {}, obj);
  278 + });
  279 + } else if ($("#title-table").text() == "{{did_table}}") {
  280 + data = $.map(json_did["data"], function (obj) {
  281 + return $.extend(true, {}, obj);
  282 + });
  283 + } else {
  284 + data = $.map(json_history["data"], function (obj) {
  285 + return $.extend(true, {}, obj);
  286 + });
  287 + }
  288 + if ($("#title-table").text() != "{{n_did_table}}"){
  289 + for (var i in data){
  290 + data[i][3] = moment(data[i][3]).format("DD/MM/YYYY HH:mm");
  291 + }
  292 + }
  293 + if ($("#title-table").text() != "{{n_did_table}}"){
  294 + for (var i in data){
  295 + if (data[i][0].toLowerCase().includes(text.toLowerCase())
  296 + || data[i][1].toLowerCase().includes(text.toLowerCase())
  297 + || data[i][2].toLowerCase().includes(text.toLowerCase())
  298 + || data[i][3].toLowerCase().includes(text.toLowerCase())){
  299 + if ($("#title-table").text() == "{{did_table}}"){
  300 + search.push(json_did["data"][i]);
  301 + } else {
  302 + search.push(json_history["data"][i]);
  303 + }
  304 + }
  305 + }
  306 + }
  307 + else {
  308 + for (var i in data){
  309 + if (data[i][0].toLowerCase().includes(text.toLowerCase())
  310 + || data[i][1].toLowerCase().includes(text.toLowerCase())){
  311 + search.push(json_n_did["data"][i]);
  312 + }
  313 + }
  314 + }
  315 + // console.log(search,"busca");
  316 + if (($("#title-table").text() == "{{did_table}}")){
  317 + drawTable(column_did,pagination(search,1),true,3);
  318 + } else if (($("#title-table").text() == "{{n_did_table}}")){
  319 + drawTable(column_n_did,pagination(search,1),false);
  320 + } else {
  321 + drawTable(column_history,pagination(search,1),true,3);
  322 + }
  323 + putpagination(search);
  324 + });
  325 +
  326 + function pagination(data,pag){
  327 + var len = data.length;
  328 + var first = (pag * 20 - 20 < len) ? pag * 20 - 20:len;
  329 + var end = (pag * 20 < len) ? pag * 20:len;
  330 + var search = data.slice(first,end);
  331 + return search;
  332 + // $(".pagination > .disabled").css("color","red");
  333 + }
  334 + function clickPagination(pag){
  335 + $(".pagination > li").last().remove();
  336 + $(".pagination > li").first().remove();
  337 +
  338 + // console.log(search,"texto");
  339 + if (($("#title-table").text() == "{{did_table}}")){
  340 + drawTable(column_did,pagination(search,pag),true,3);
  341 + } else if (($("#title-table").text() == "{{n_did_table}}")){
  342 + drawTable(column_n_did,pagination(search,pag),false);
  343 + } else {
  344 + drawTable(column_history,pagination(search,pag),true,3);
  345 + }
  346 +
  347 + if (pag < Math.ceil(search.length / 20))
  348 + $(".pagination").append('<li><a href="javascript:void(0);" onclick="return clickPagination(' + (pag + 1) + ');"><span>»</span></a></li>');
  349 + else $(".pagination").append('<li class="disabled"><span>»</span></li>');
  350 + if (pag > 1)
  351 + $(".pagination").prepend('<li><a href="javascript:void(0);" onclick="return clickPagination(' + (pag - 1) + ');"><span>«</span></a></li>');
  352 + else $(".pagination").prepend('<li class="disabled"><span>«</span></li>');
  353 + $(".active").removeClass("active");
  354 + $("#" + pag).addClass("active");
  355 + }
  356 + </script>
  357 +{% endblock %}
pdf_file/templates/pdf_file/view.html
@@ -18,8 +18,8 @@ @@ -18,8 +18,8 @@
18 {% breadcrumb subject.category 'subjects:cat_view' subject.category.slug %} 18 {% breadcrumb subject.category 'subjects:cat_view' subject.category.slug %}
19 {% breadcrumb subject 'subjects:view' subject.slug %} 19 {% breadcrumb subject 'subjects:view' subject.slug %}
20 {% breadcrumb pdf_file.topic 'subjects:topic_view' subject.slug pdf_file.topic.slug %} 20 {% breadcrumb pdf_file.topic 'subjects:topic_view' subject.slug pdf_file.topic.slug %}
21 - {% breadcrumb pdf_file 'pdf_file:view' pdf_file.slug %}  
22 - 21 + {% breadcrumb pdf_file 'pdf_files:view' pdf_file.slug %}
  22 +
23 {% endblock %} 23 {% endblock %}
24 24
25 25
@@ -52,6 +52,6 @@ @@ -52,6 +52,6 @@
52 <p>{% trans "PDF could not be displayed" %}</p> 52 <p>{% trans "PDF could not be displayed" %}</p>
53 </object> 53 </object>
54 54
55 -  
56 -  
57 -{% endblock content %}  
58 \ No newline at end of file 55 \ No newline at end of file
  56 +
  57 +
  58 +{% endblock content %}
pdf_file/urls.py
@@ -8,5 +8,5 @@ urlpatterns = [ @@ -8,5 +8,5 @@ urlpatterns = [
8 url(r'^update/(?P<topic_slug>[\w_-]+)/(?P<slug>[\w_-]+)/$', views.UpdateView.as_view(), name = 'update'), 8 url(r'^update/(?P<topic_slug>[\w_-]+)/(?P<slug>[\w_-]+)/$', views.UpdateView.as_view(), name = 'update'),
9 url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteView.as_view(), name = 'delete'), 9 url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteView.as_view(), name = 'delete'),
10 url(r'^view/(?P<slug>[\w_-]+)/$', views.ViewPDFFile.as_view(), name = 'view'), 10 url(r'^view/(?P<slug>[\w_-]+)/$', views.ViewPDFFile.as_view(), name = 'view'),
11 -  
12 -]  
13 \ No newline at end of file 11 \ No newline at end of file
  12 + url(r'^chart/(?P<slug>[\w_-]+)/$', views.StatisticsView.as_view(), name = 'get_chart'),
  13 +]
pdf_file/views.py
@@ -10,6 +10,8 @@ from django.contrib import messages @@ -10,6 +10,8 @@ from django.contrib import messages
10 from amadeus.permissions import has_subject_permissions, has_resource_permissions 10 from amadeus.permissions import has_subject_permissions, has_resource_permissions
11 from .forms import PDFFileForm 11 from .forms import PDFFileForm
12 from os import path 12 from os import path
  13 +import datetime
  14 +from log.models import Log
13 from django.http import HttpResponse, Http404 15 from django.http import HttpResponse, Http404
14 16
15 from log.mixins import LogMixin 17 from log.mixins import LogMixin
@@ -100,7 +102,7 @@ class PDFFileCreateView(LoginRequiredMixin, LogMixin , generic.CreateView): @@ -100,7 +102,7 @@ class PDFFileCreateView(LoginRequiredMixin, LogMixin , generic.CreateView):
100 102
101 def get(self, request, *args, **kwargs): 103 def get(self, request, *args, **kwargs):
102 self.object = None 104 self.object = None
103 - 105 +
104 form_class = self.get_form_class() 106 form_class = self.get_form_class()
105 form = self.get_form(form_class) 107 form = self.get_form(form_class)
106 108
@@ -113,7 +115,7 @@ class PDFFileCreateView(LoginRequiredMixin, LogMixin , generic.CreateView): @@ -113,7 +115,7 @@ class PDFFileCreateView(LoginRequiredMixin, LogMixin , generic.CreateView):
113 115
114 def post(self, request, *args, **kwargs): 116 def post(self, request, *args, **kwargs):
115 self.object = None 117 self.object = None
116 - 118 +
117 form_class = self.get_form_class() 119 form_class = self.get_form_class()
118 form = self.get_form(form_class) 120 form = self.get_form(form_class)
119 121
@@ -121,7 +123,7 @@ class PDFFileCreateView(LoginRequiredMixin, LogMixin , generic.CreateView): @@ -121,7 +123,7 @@ class PDFFileCreateView(LoginRequiredMixin, LogMixin , generic.CreateView):
121 topic = get_object_or_404(Topic, slug = slug) 123 topic = get_object_or_404(Topic, slug = slug)
122 124
123 pendencies_form = PendenciesForm(self.request.POST, initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]}) 125 pendencies_form = PendenciesForm(self.request.POST, initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
124 - 126 +
125 if (form.is_valid() and pendencies_form.is_valid()): 127 if (form.is_valid() and pendencies_form.is_valid()):
126 return self.form_valid(form, pendencies_form) 128 return self.form_valid(form, pendencies_form)
127 else: 129 else:
@@ -134,7 +136,7 @@ class PDFFileCreateView(LoginRequiredMixin, LogMixin , generic.CreateView): @@ -134,7 +136,7 @@ class PDFFileCreateView(LoginRequiredMixin, LogMixin , generic.CreateView):
134 136
135 topic = get_object_or_404(Topic, slug = slug) 137 topic = get_object_or_404(Topic, slug = slug)
136 initial['subject'] = topic.subject 138 initial['subject'] = topic.subject
137 - 139 +
138 return initial 140 return initial
139 141
140 def form_invalid(self, form, pendencies_form): 142 def form_invalid(self, form, pendencies_form):
@@ -156,10 +158,10 @@ class PDFFileCreateView(LoginRequiredMixin, LogMixin , generic.CreateView): @@ -156,10 +158,10 @@ class PDFFileCreateView(LoginRequiredMixin, LogMixin , generic.CreateView):
156 158
157 pend_form = pendencies_form.save(commit = False) 159 pend_form = pendencies_form.save(commit = False)
158 pend_form.resource = self.object 160 pend_form.resource = self.object
159 - 161 +
160 if not pend_form.action == "": 162 if not pend_form.action == "":
161 - pend_form.save()  
162 - 163 + pend_form.save()
  164 +
163 self.log_context['category_id'] = self.object.topic.subject.category.id 165 self.log_context['category_id'] = self.object.topic.subject.category.id
164 self.log_context['category_name'] = self.object.topic.subject.category.name 166 self.log_context['category_name'] = self.object.topic.subject.category.name
165 self.log_context['category_slug'] = self.object.topic.subject.category.slug 167 self.log_context['category_slug'] = self.object.topic.subject.category.slug
@@ -221,7 +223,7 @@ class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView): @@ -221,7 +223,7 @@ class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView):
221 223
222 def get(self, request, *args, **kwargs): 224 def get(self, request, *args, **kwargs):
223 self.object = self.get_object() 225 self.object = self.get_object()
224 - 226 +
225 form_class = self.get_form_class() 227 form_class = self.get_form_class()
226 form = self.get_form(form_class) 228 form = self.get_form(form_class)
227 229
@@ -239,7 +241,7 @@ class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView): @@ -239,7 +241,7 @@ class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView):
239 241
240 def post(self, request, *args, **kwargs): 242 def post(self, request, *args, **kwargs):
241 self.object = self.get_object() 243 self.object = self.get_object()
242 - 244 +
243 form_class = self.get_form_class() 245 form_class = self.get_form_class()
244 form = self.get_form(form_class) 246 form = self.get_form(form_class)
245 247
@@ -252,12 +254,12 @@ class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView): @@ -252,12 +254,12 @@ class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView):
252 pendencies_form = PendenciesForm(self.request.POST, instance = pend_form[0], initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]}) 254 pendencies_form = PendenciesForm(self.request.POST, instance = pend_form[0], initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
253 else: 255 else:
254 pendencies_form = PendenciesForm(self.request.POST, initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]}) 256 pendencies_form = PendenciesForm(self.request.POST, initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
255 - 257 +
256 if (form.is_valid() and pendencies_form.is_valid()): 258 if (form.is_valid() and pendencies_form.is_valid()):
257 return self.form_valid(form, pendencies_form) 259 return self.form_valid(form, pendencies_form)
258 else: 260 else:
259 return self.form_invalid(form, pendencies_form) 261 return self.form_invalid(form, pendencies_form)
260 - 262 +
261 def form_invalid(self, form, pendencies_form): 263 def form_invalid(self, form, pendencies_form):
262 return self.render_to_response(self.get_context_data(form = form, pendencies_form = pendencies_form)) 264 return self.render_to_response(self.get_context_data(form = form, pendencies_form = pendencies_form))
263 265
@@ -266,7 +268,7 @@ class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView): @@ -266,7 +268,7 @@ class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView):
266 268
267 if not self.object.topic.visible and not self.object.topic.repository: 269 if not self.object.topic.visible and not self.object.topic.repository:
268 self.object.visible = False 270 self.object.visible = False
269 - 271 +
270 self.object.save() 272 self.object.save()
271 273
272 pend_form = pendencies_form.save(commit = False) 274 pend_form = pendencies_form.save(commit = False)
@@ -274,7 +276,7 @@ class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView): @@ -274,7 +276,7 @@ class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView):
274 276
275 if not pend_form.action == "": 277 if not pend_form.action == "":
276 pend_form.save() 278 pend_form.save()
277 - 279 +
278 self.log_context['category_id'] = self.object.topic.subject.category.id 280 self.log_context['category_id'] = self.object.topic.subject.category.id
279 self.log_context['category_name'] = self.object.topic.subject.category.name 281 self.log_context['category_name'] = self.object.topic.subject.category.name
280 self.log_context['category_slug'] = self.object.topic.subject.category.slug 282 self.log_context['category_slug'] = self.object.topic.subject.category.slug
@@ -352,5 +354,104 @@ class DeleteView(LoginRequiredMixin, LogMixin, generic.DeleteView): @@ -352,5 +354,104 @@ class DeleteView(LoginRequiredMixin, LogMixin, generic.DeleteView):
352 354
353 return reverse_lazy('subjects:view', kwargs = {'slug': self.object.topic.subject.slug}) 355 return reverse_lazy('subjects:view', kwargs = {'slug': self.object.topic.subject.slug})
354 356
  357 +class StatisticsView(LoginRequiredMixin, LogMixin, generic.DetailView):
  358 + log_component = 'resources'
  359 + log_action = 'view_statistics'
  360 + log_resource = 'pdf_file'
  361 + log_context = {}
  362 +
  363 + login_url = reverse_lazy("users:login")
  364 + redirect_field_name = 'next'
  365 + model = PDFFile
  366 + template_name = 'pdf_file/relatorios.html'
  367 +
  368 + def dispatch(self, request, *args, **kwargs):
  369 + slug = self.kwargs.get('slug', '')
  370 + pdf_file = get_object_or_404(PDFFile, slug = slug)
355 371
  372 + if not has_subject_permissions(request.user, pdf_file.topic.subject):
  373 + return redirect(reverse_lazy('subjects:home'))
356 374
  375 + return super(StatisticsView, self).dispatch(request, *args, **kwargs)
  376 +
  377 + def get_context_data(self, **kwargs):
  378 + context = super(StatisticsView, self).get_context_data(**kwargs)
  379 +
  380 + self.log_context['category_id'] = self.object.topic.subject.category.id
  381 + self.log_context['category_name'] = self.object.topic.subject.category.name
  382 + self.log_context['category_slug'] = self.object.topic.subject.category.slug
  383 + self.log_context['subject_id'] = self.object.topic.subject.id
  384 + self.log_context['subject_name'] = self.object.topic.subject.name
  385 + self.log_context['subject_slug'] = self.object.topic.subject.slug
  386 + self.log_context['topic_id'] = self.object.topic.id
  387 + self.log_context['topic_name'] = self.object.topic.name
  388 + self.log_context['topic_slug'] = self.object.topic.slug
  389 + self.log_context['pdffile_id'] = self.object.id
  390 + self.log_context['pdffile_name'] = self.object.name
  391 + self.log_context['pdffile_slug'] = self.object.slug
  392 +
  393 + super(StatisticsView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  394 +
  395 +
  396 + context['title'] = _('PDF File Reports')
  397 +
  398 + slug = self.kwargs.get('slug')
  399 + pdf_file = get_object_or_404(PDFFile, slug = slug)
  400 + context['pdf_file'] = pdf_file
  401 + date_format = "%d/%m/%Y %H:%M" if self.request.GET.get('language','') == 'pt-br' else "%m/%d/%Y %I:%M %p"
  402 + if self.request.GET.get('language','') == "":
  403 + start_date = datetime.datetime.now() - datetime.timedelta(30)
  404 + end_date = datetime.datetime.now()
  405 + else :
  406 + start_date = datetime.datetime.strptime(self.request.GET.get('init_date',''),date_format)
  407 + end_date = datetime.datetime.strptime(self.request.GET.get('end_date',''),date_format)
  408 + # print (start_date," depois")
  409 + context["init_date"] = start_date
  410 + context["end_date"] = end_date
  411 + alunos = pdf_file.students.all()
  412 +
  413 + vis_ou = Log.objects.filter(context__contains={'pdffile_id':pdf_file.id},resource="pdffile",action="view",user_email__in=(aluno.email for aluno in alunos), datetime__range=(start_date,end_date + datetime.timedelta(minutes = 1)))
  414 + did,n_did,history = str(_("Users who viewed")),str(_("Users who did not viewed")),str(_("Historic"))
  415 + re = []
  416 + data_did, data_n_did,data_history = [],[],[]
  417 + json_did, json_n_did, json_history = {},{},{}
  418 +
  419 + from django.db.models import Count, Max
  420 + views_user = vis_ou.values("user_email").annotate(views=Count("user_email"))
  421 + date_last = vis_ou.values("user_email").annotate(last=Max("datetime"))
  422 +
  423 + for i in range(0,len(views_user)):
  424 + data_did.append([str(alunos.get(email=views_user[i].get("user_email"))),
  425 + ", ".join([str(x) for x in pdf_file.topic.subject.group_subject.filter(participants__email=views_user[i].get("user_email"))]),
  426 + views_user[i].get("views"),date_last.get(user_email=views_user[i].get("user_email")).get("last")])
  427 + json_did["data"] = data_did
  428 +
  429 +
  430 + for log_al in vis_ou.order_by("datetime"):
  431 + data_history.append([str(alunos.get(email=log_al.user_email)),
  432 + ", ".join([str(x) for x in pdf_file.topic.subject.group_subject.filter(participants__email=log_al.user_email)]),
  433 + log_al.action,log_al.datetime])
  434 + json_history["data"] = data_history
  435 +
  436 + not_view = alunos.exclude(email__in=[log.user_email for log in vis_ou.distinct("user_email")])
  437 + for alun in not_view:
  438 + data_n_did.append([str(alun),", ".join([str(x) for x in pdf_file.topic.subject.group_subject.filter(participants__email=alun.email)])])
  439 + json_n_did["data"] = data_n_did
  440 +
  441 +
  442 + context["json_did"] = json_did
  443 + context["json_n_did"] = json_n_did
  444 + context["json_history"] = json_history
  445 + c_visualizou = vis_ou.distinct("user_email").count()
  446 + re.append([str(_('PDF File')),did,n_did])
  447 + re.append([str(_('View')),c_visualizou, alunos.count() - c_visualizou])
  448 + context['topic'] = pdf_file.topic
  449 + context['subject'] = pdf_file.topic.subject
  450 + context['db_data'] = re
  451 + context['title_chart'] = _('Students viewing the PDF File')
  452 + context['title_vAxis'] = _('Quantity')
  453 +
  454 + context["n_did_table"] = n_did
  455 + context["did_table"] = did
  456 + context["history_table"] = history
  457 + return context
topics/templates/resources/list.html
@@ -33,6 +33,9 @@ @@ -33,6 +33,9 @@
33 {% if resource|class_name == 'webpage' %} 33 {% if resource|class_name == 'webpage' %}
34 <li><a href="{% url 'webpages:get_chart' resource.slug %}" class="edit"><i class="fa fa-line-chart fa-fw" aria-hidden="true"></i>{% trans 'Reports' %}</a></li> 34 <li><a href="{% url 'webpages:get_chart' resource.slug %}" class="edit"><i class="fa fa-line-chart fa-fw" aria-hidden="true"></i>{% trans 'Reports' %}</a></li>
35 {% endif %} 35 {% endif %}
  36 + {% if resource|class_name == 'pdffile' %}
  37 + <li><a href="{% url 'pdf_files:get_chart' resource.slug %}" class="edit"><i class="fa fa-line-chart fa-fw" aria-hidden="true"></i>{% trans 'Reports' %}</a></li>
  38 + {% endif %}
36 {% if resource|class_name == 'goals' %} 39 {% if resource|class_name == 'goals' %}
37 <li><a href="{% url 'goals:reports' resource.slug %}" class="edit"><i class="fa fa-file-pdf-o fa-fw" aria-hidden="true"></i>{% trans 'Reports' %}</a></li> 40 <li><a href="{% url 'goals:reports' resource.slug %}" class="edit"><i class="fa fa-file-pdf-o fa-fw" aria-hidden="true"></i>{% trans 'Reports' %}</a></li>
38 {% endif %} 41 {% endif %}