Commit 1e152bf2b70a24f0c925dc52f66230e897c72ed5

Authored by Zambom
1 parent e6de6131

Adding goals history report

amadeus/static/js/goals_reports.js
@@ -46,6 +46,9 @@ function getAnswered() { @@ -46,6 +46,9 @@ function getAnswered() {
46 container.find('.unanswered_link').removeClass('active'); 46 container.find('.unanswered_link').removeClass('active');
47 container.find('.unanswered').hide(); 47 container.find('.unanswered').hide();
48 48
  49 + container.find('.history_link').removeClass('active');
  50 + container.find('.history').hide();
  51 +
49 setBreadcrumb(answeredBread); 52 setBreadcrumb(answeredBread);
50 } 53 }
51 54
@@ -106,9 +109,62 @@ function getUnanswered() { @@ -106,9 +109,62 @@ function getUnanswered() {
106 container.find('.unanswered_link').addClass('active'); 109 container.find('.unanswered_link').addClass('active');
107 container.find('.unanswered').show(); 110 container.find('.unanswered').show();
108 111
  112 + container.find('.history_link').removeClass('active');
  113 + container.find('.history').hide();
  114 +
109 setBreadcrumb(unansweredBread); 115 setBreadcrumb(unansweredBread);
110 } 116 }
111 117
  118 +function getHistory() {
  119 + var container = $("#reports"),
  120 + list = container.find('.history_data');
  121 +
  122 + if (list.children().length == 0) {
  123 + var url = list.parent().data('url');
  124 +
  125 + $.ajax({
  126 + url: url,
  127 + success: function (data) {
  128 + list.html(data);
  129 +
  130 + $('#history_table').DataTable({
  131 + "dom": "Bfrtip",
  132 + "language": dataTablei18n,
  133 + buttons: {
  134 + dom: {
  135 + container: {
  136 + className: 'col-md-3'
  137 + },
  138 + buttonContainer: {
  139 + tag: 'h4',
  140 + className: 'history-header'
  141 + },
  142 + },
  143 + buttons: [
  144 + {
  145 + extend: 'csv',
  146 + text: csvBtnLabeli18n,
  147 + filename: 'report-history'
  148 + }
  149 + ],
  150 + },
  151 + });
  152 + }
  153 + });
  154 + }
  155 +
  156 + container.find('.answered_link').removeClass('active');
  157 + container.find('.answered').hide();
  158 +
  159 + container.find('.unanswered_link').removeClass('active');
  160 + container.find('.unanswered').hide();
  161 +
  162 + container.find('.history_link').addClass('active');
  163 + container.find('.history').show();
  164 +
  165 + setBreadcrumb(historyBread);
  166 +}
  167 +
112 function setBreadcrumb(text) { 168 function setBreadcrumb(text) {
113 var breadcrumb = $(".breadcrumb")[0], 169 var breadcrumb = $(".breadcrumb")[0],
114 li = $(breadcrumb).find('li:last-child'); 170 li = $(breadcrumb).find('li:last-child');
goals/templates/goals/_history.html 0 → 100644
@@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
  1 +{% load i18n goals_filters %}
  2 +
  3 +<div class="row">
  4 + <div class="col-md-12">
  5 + <table id="history_table" class="table table-striped table-bordered">
  6 + <thead>
  7 + <th>
  8 + {% trans 'Date/Hour' %}
  9 + </th>
  10 + <th>
  11 + {% trans 'Student' %}
  12 + </th>
  13 + <th>
  14 + {% trans 'Group' %}
  15 + </th>
  16 + <th>
  17 + {% trans 'Action' %}
  18 + </th>
  19 + <th>
  20 + {% trans 'Object' %}
  21 + </th>
  22 + <th>
  23 + {% trans 'Resource' %}
  24 + </th>
  25 + </thead>
  26 + <tbody>
  27 + {% for row in records %}
  28 + <tr>
  29 + <td>{{ row.datetime }}</td>
  30 + <td>{{ row.user }}</td>
  31 + <td>{{ row.user_id|log_groups }}</td>
  32 + <td>{{ row.action|log_action }}</td>
  33 + <td>{{ row|log_object }}</td>
  34 + <td>{{ row.context.goals_name }}</td>
  35 + </tr>
  36 + {% endfor %}
  37 + </tbody>
  38 + </table>
  39 + </div>
  40 +</div>
0 \ No newline at end of file 41 \ No newline at end of file
goals/templates/goals/reports.html
@@ -56,22 +56,20 @@ @@ -56,22 +56,20 @@
56 <ul class="core-subjects-options"> 56 <ul class="core-subjects-options">
57 <a href="javascript:getAnswered()"><li class="answered_link active">{% trans "Answered" %} ({{ totals.answered }})</li></a> 57 <a href="javascript:getAnswered()"><li class="answered_link active">{% trans "Answered" %} ({{ totals.answered }})</li></a>
58 <a href="javascript:getUnanswered()"><li class="unanswered_link">{% trans "Unanswered" %} ({{ totals.unanswered }})</li></a> 58 <a href="javascript:getUnanswered()"><li class="unanswered_link">{% trans "Unanswered" %} ({{ totals.unanswered }})</li></a>
59 - <a href=""><li class="">{% trans "Resource History" %}</li></a> 59 + <a href="javascript:getHistory()"><li class="history_link">{% trans "Resource History" %}</li></a>
60 </ul> 60 </ul>
61 </div> 61 </div>
62 62
63 <div class="answered" data-url="{% url 'goals:answered_report' goal.slug %}"> 63 <div class="answered" data-url="{% url 'goals:answered_report' goal.slug %}">
64 <div class="answered_data"></div> 64 <div class="answered_data"></div>
65 - <div class="text-center">  
66 - <div class="holder"></div>  
67 - </div>  
68 </div> 65 </div>
69 66
70 <div class="unanswered" data-url="{% url 'goals:unanswered_report' goal.slug %}"> 67 <div class="unanswered" data-url="{% url 'goals:unanswered_report' goal.slug %}">
71 <div class="unanswered_data"></div> 68 <div class="unanswered_data"></div>
72 - <div class="text-center">  
73 - <div class="holder"></div>  
74 - </div> 69 + </div>
  70 +
  71 + <div class="history" data-url="{% url 'goals:history_report' goal.slug %}">
  72 + <div class="history_data"></div>
75 </div> 73 </div>
76 </div> 74 </div>
77 </div> 75 </div>
@@ -104,7 +102,8 @@ @@ -104,7 +102,8 @@
104 102
105 var csvBtnLabeli18n = "<i class='fa fa-download'></i> {% trans 'Download .csv file' %}", 103 var csvBtnLabeli18n = "<i class='fa fa-download'></i> {% trans 'Download .csv file' %}",
106 answeredBread = "{% trans 'Reports: Answered' %}", 104 answeredBread = "{% trans 'Reports: Answered' %}",
107 - unansweredBread = "{% trans 'Reports: Unanswered' %}"; 105 + unansweredBread = "{% trans 'Reports: Unanswered' %}",
  106 + historyBread = "{% trans 'Reports: History' %}";
108 </script> 107 </script>
109 <script type="text/javascript" src="{% static 'js/goals_reports.js' %}"></script> 108 <script type="text/javascript" src="{% static 'js/goals_reports.js' %}"></script>
110 {% endblock %} 109 {% endblock %}
111 \ No newline at end of file 110 \ No newline at end of file
goals/templatetags/goals_filters.py
@@ -3,6 +3,7 @@ from django.utils.translation import ugettext_lazy as _ @@ -3,6 +3,7 @@ from django.utils.translation import ugettext_lazy as _
3 3
4 from goals.models import MyGoals 4 from goals.models import MyGoals
5 from log.models import Log 5 from log.models import Log
  6 +from students_group.models import StudentsGroup
6 7
7 register = template.Library() 8 register = template.Library()
8 9
@@ -17,6 +18,17 @@ def groups(user): @@ -17,6 +18,17 @@ def groups(user):
17 else: 18 else:
18 return "---" 19 return "---"
19 20
  21 +@register.filter(name = 'log_groups')
  22 +def log_groups(user_id):
  23 + groups = StudentsGroup.objects.filter(participants__id = user_id).values_list('name', flat = True)
  24 +
  25 + if groups.count() > 0:
  26 + groups = list(groups)
  27 +
  28 + return ", ".join(groups)
  29 + else:
  30 + return "---"
  31 +
20 @register.filter(name = 'creation_date') 32 @register.filter(name = 'creation_date')
21 def creation_date(user, goal): 33 def creation_date(user, goal):
22 log = Log.objects.filter(user_id = user.id, action = 'submit', resource = 'goals', context__contains = {"goals_id": goal.id}) 34 log = Log.objects.filter(user_id = user.id, action = 'submit', resource = 'goals', context__contains = {"goals_id": goal.id})
@@ -39,4 +51,26 @@ def update_date(user, goal): @@ -39,4 +51,26 @@ def update_date(user, goal):
39 def my_goals(user, goal): 51 def my_goals(user, goal):
40 mine = list(MyGoals.objects.filter(user = user, item__goal = goal).values_list('value', flat = True)) 52 mine = list(MyGoals.objects.filter(user = user, item__goal = goal).values_list('value', flat = True))
41 53
42 - return ', '.join(str(x) for x in mine)  
43 \ No newline at end of file 54 \ No newline at end of file
  55 + return ', '.join(str(x) for x in mine)
  56 +
  57 +@register.filter(name = 'log_action')
  58 +def log_action(action):
  59 + if action == 'view':
  60 + return _('Visualized')
  61 + elif action == 'create':
  62 + return _('Added')
  63 + elif action == 'update':
  64 + return _('Updated')
  65 + elif action == 'submit':
  66 + return _('Submitted')
  67 +
  68 + return '---'
  69 +
  70 +@register.filter(name = 'log_object')
  71 +def log_object(log):
  72 + if log.resource == 'my_goals':
  73 + return _('My Goals')
  74 +
  75 + name = log.context['goals_name']
  76 +
  77 + return _("%s Instance")%(name)
44 \ No newline at end of file 78 \ No newline at end of file
@@ -14,4 +14,5 @@ urlpatterns = [ @@ -14,4 +14,5 @@ urlpatterns = [
14 url(r'^reports/(?P<slug>[\w_-]+)/$', views.Reports.as_view(), name = 'reports'), 14 url(r'^reports/(?P<slug>[\w_-]+)/$', views.Reports.as_view(), name = 'reports'),
15 url(r'^answered_report/(?P<slug>[\w_-]+)/$', views.AnsweredReport.as_view(), name = 'answered_report'), 15 url(r'^answered_report/(?P<slug>[\w_-]+)/$', views.AnsweredReport.as_view(), name = 'answered_report'),
16 url(r'^unanswered_report/(?P<slug>[\w_-]+)/$', views.UnansweredReport.as_view(), name = 'unanswered_report'), 16 url(r'^unanswered_report/(?P<slug>[\w_-]+)/$', views.UnansweredReport.as_view(), name = 'unanswered_report'),
  17 + url(r'^history_report/(?P<slug>[\w_-]+)/$', views.HistoryReport.as_view(), name = 'history_report'),
17 ] 18 ]
goals/views.py
@@ -71,7 +71,6 @@ class AnsweredReport(LoginRequiredMixin, generic.ListView): @@ -71,7 +71,6 @@ class AnsweredReport(LoginRequiredMixin, generic.ListView):
71 redirect_field_name = 'next' 71 redirect_field_name = 'next'
72 72
73 template_name = 'goals/_answered.html' 73 template_name = 'goals/_answered.html'
74 - model = MyGoals  
75 context_object_name = 'students' 74 context_object_name = 'students'
76 75
77 def get_queryset(self): 76 def get_queryset(self):
@@ -110,7 +109,6 @@ class UnansweredReport(LoginRequiredMixin, generic.ListView): @@ -110,7 +109,6 @@ class UnansweredReport(LoginRequiredMixin, generic.ListView):
110 redirect_field_name = 'next' 109 redirect_field_name = 'next'
111 110
112 template_name = 'goals/_unanswered.html' 111 template_name = 'goals/_unanswered.html'
113 - model = MyGoals  
114 context_object_name = 'students' 112 context_object_name = 'students'
115 113
116 def get_queryset(self): 114 def get_queryset(self):
@@ -146,6 +144,40 @@ class UnansweredReport(LoginRequiredMixin, generic.ListView): @@ -146,6 +144,40 @@ class UnansweredReport(LoginRequiredMixin, generic.ListView):
146 144
147 return context 145 return context
148 146
  147 +class HistoryReport(LoginRequiredMixin, generic.ListView):
  148 + login_url = reverse_lazy("users:login")
  149 + redirect_field_name = 'next'
  150 +
  151 + template_name = 'goals/_history.html'
  152 + context_object_name = 'records'
  153 +
  154 + def get_queryset(self):
  155 + slug = self.kwargs.get('slug', '')
  156 + goal = get_object_or_404(Goals, slug = slug)
  157 +
  158 + rows = Log.objects.filter(context__contains = {"goals_id": goal.id})
  159 +
  160 + return rows
  161 +
  162 + def dispatch(self, request, *args, **kwargs):
  163 + slug = self.kwargs.get('slug', '')
  164 + goals = get_object_or_404(Goals, slug = slug)
  165 +
  166 + if not has_resource_permissions(request.user, goals):
  167 + return redirect(reverse_lazy('subjects:home'))
  168 +
  169 + return super(HistoryReport, self).dispatch(request, *args, **kwargs)
  170 +
  171 + def get_context_data(self, **kwargs):
  172 + context = super(HistoryReport, self).get_context_data(**kwargs)
  173 +
  174 + slug = self.kwargs.get('slug', '')
  175 + goals = get_object_or_404(Goals, slug = slug)
  176 +
  177 + context['goal'] = goals
  178 +
  179 + return context
  180 +
149 class InsideView(LoginRequiredMixin, LogMixin, generic.ListView): 181 class InsideView(LoginRequiredMixin, LogMixin, generic.ListView):
150 log_component = "resources" 182 log_component = "resources"
151 log_action = "view" 183 log_action = "view"