Commit 753af621682a731955e3c03a5a08203ef6a0bc44

Authored by filipecmedeiros
2 parents e277621c ee5a5f23

Merge branch 'dev' of https://github.com/amadeusproject/amadeuslms into dev

courses/models.py
@@ -65,9 +65,11 @@ class Course(models.Model): @@ -65,9 +65,11 @@ class Course(models.Model):
65 65
66 def show_subscribe(self): 66 def show_subscribe(self):
67 today = datetime.date.today() 67 today = datetime.date.today()
68 -  
69 return today >= self.init_register_date and today <= self.end_register_date 68 return today >= self.init_register_date and today <= self.end_register_date
70 69
  70 + def duration(self):
  71 + return self.end_date - self.init_date
  72 +
71 class Subject(models.Model): 73 class Subject(models.Model):
72 74
73 name = models.CharField(_('Name'), max_length = 100) 75 name = models.CharField(_('Name'), max_length = 100)
courses/static/js/course.js
1 /* 1 /*
2 * 2 *
  3 +* Function to get a cookie stored on browser
  4 +*
  5 +*/
  6 +function getCookie(name) {
  7 + var cookieValue = null;
  8 + if (document.cookie && document.cookie !== '') {
  9 + var cookies = document.cookie.split(';');
  10 + for (var i = 0; i < cookies.length; i++) {
  11 + var cookie = jQuery.trim(cookies[i]);
  12 + // Does this cookie string begin with the name we want?
  13 + if (cookie.substring(0, name.length + 1) === (name + '=')) {
  14 + cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
  15 + break;
  16 + }
  17 + }
  18 + }
  19 + return cookieValue;
  20 +}
  21 +/*
  22 +*
3 * Function to subscribe (works for courses and subjects) 23 * Function to subscribe (works for courses and subjects)
4 * 24 *
5 */ 25 */
@@ -19,4 +39,42 @@ function subscribe(elem, url, id, confirm_message) { @@ -19,4 +39,42 @@ function subscribe(elem, url, id, confirm_message) {
19 } 39 }
20 }); 40 });
21 }); 41 });
  42 +}
  43 +
  44 +/*
  45 +*
  46 +* Function to delete a course
  47 +*
  48 +*/
  49 +function delete_course(url, course, message, return_url) {
  50 + alertify.confirm(message, function(){
  51 + var csrftoken = getCookie('csrftoken');
  52 +
  53 + $.ajax({
  54 + method: 'post',
  55 + beforeSend: function (request) {
  56 + request.setRequestHeader('X-CSRFToken', csrftoken);
  57 + },
  58 + url: url,
  59 + success: function(data) {
  60 + alertify.alert('Remove Course', 'Course removed successfully!', function(){
  61 + window.location.href = return_url;
  62 + });
  63 + }
  64 + });
  65 + });
  66 +}
  67 +/*
  68 +*
  69 +* Function to load create course's form
  70 +*
  71 +*/
  72 +function replicate_course(url, course) {
  73 + $.ajax({
  74 + url: url,
  75 + data: {'form': course},
  76 + success: function(data) {
  77 + $(".course_replicate_form").html(data);
  78 + }
  79 + });
22 } 80 }
23 \ No newline at end of file 81 \ No newline at end of file
courses/templates/category/index.html
@@ -80,11 +80,9 @@ @@ -80,11 +80,9 @@
80 <td>{{ category }}</td> 80 <td>{{ category }}</td>
81 <td>{{ category.slug }}</td> 81 <td>{{ category.slug }}</td>
82 <td class="text-center"> 82 <td class="text-center">
83 - <a href="{% url 'course:view_cat' category.slug %}" class="btn btn-info btn-sm"><span class="glyphicon glyphicon-eye-open"></span></a>  
84 - <a href="{% url 'course:update_cat' category.slug %}" class="btn btn-primary btn-sm"><span class="glyphicon glyphicon-edit"></span></a>  
85 - <a href="javascript:modal.get('{% url 'course:delete_cat' category.slug %}','#category','#modal_category');" class="btn btn-danger btn-sm"><span class="glyphicon glyphicon-trash"></span></a>  
86 -  
87 - </td> 83 + <a href="{% url 'course:update_cat' category.slug %}" class="btn btn-primary btn-sm"><span class="glyphicon glyphicon-edit"></span></a>
  84 + <a href="javascript:modal.get('{% url 'course:delete_cat' category.slug %}','#category','#modal_category');" class="btn btn-danger btn-sm"><span class="glyphicon glyphicon-trash"></span></a>
  85 + </td>
88 </tr> 86 </tr>
89 {% endfor %} 87 {% endfor %}
90 {% else %} 88 {% else %}
courses/templates/category/view.html
@@ -1,69 +0,0 @@ @@ -1,69 +0,0 @@
1 -{% extends 'base.html' %}  
2 -  
3 -{% load static i18n permission_tags %}  
4 -{% load widget_tweaks %}  
5 -{% load static i18n %}  
6 -  
7 -  
8 -{% block breadcrumbs %}  
9 - <ol class="breadcrumb">  
10 - <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>  
11 - <li class="active">{{ category }}</li>  
12 - </ol>  
13 -{% endblock %}  
14 -  
15 -{% block sidebar %}  
16 - <div class="panel panel-primary navigation">  
17 - <div class="panel-heading">  
18 - <h5>{% trans 'Menu' %}</h5>  
19 - </div>  
20 - <div class="panel-body">  
21 - <ul class="nav nav-pills nav-stacked">  
22 - <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li>  
23 - <li><a href="{% url 'course:manage' %}">{% trans 'My Courses' %}</a></li>  
24 - </ul>  
25 - </div>  
26 - </div>  
27 - {% if user|has_role:'professor' or user|has_role:'system_admin' %}  
28 -  
29 - <div class="panel panel-primary navigation">  
30 - <div class="panel-heading">  
31 - <h3 class="panel-title">Actions</h3>  
32 - </div>  
33 - <div class="panel-body">  
34 - <ul class="nav nav-pills nav-stacked">  
35 - <li><a href="javascript:void(0)">Replicate Course</a></li>  
36 - <li><a href="{% url 'course:create' %}">Create Course</a></li>  
37 - <li><a href="{% url 'course:create_cat' %}">Create Category</a></li>  
38 - </ul>  
39 - </div>  
40 - </div>  
41 -  
42 - <div class="panel panel-primary navigation">  
43 - <div class="panel-heading">  
44 - <h3 class="panel-title">Category</h3>  
45 - </div>  
46 - <div class="panel-body">  
47 - <ul class="nav nav-pills nav-stacked">  
48 - <li><a href="{% url 'course:create_cat' %}">Create Category</a></li>  
49 - <li><a href="{% url 'course:manage_cat' %}">List Category</a></li>  
50 - <li><a href="{% url 'course:delete_cat' category.slug %}">Remove Category</a></li>  
51 - <li><a href="{% url 'course:update_cat' category.slug %}">Update Category</a></li>  
52 - </ul>  
53 - </div>  
54 - </div>  
55 - {% endif %}  
56 -{% endblock %}  
57 -  
58 -{% block content %}  
59 - <div class="card card-content">  
60 - <div class="card-body">  
61 - <div class="row">  
62 - <div class="col-sm-12">  
63 - <p><b>{% trans 'Name:' %} </b> {{ category }}</p>  
64 - <p><b>{% trans 'Slug:' %} </b> {{ category.slug }}</p>  
65 - </div>  
66 - </div>  
67 - </div>  
68 - </div>  
69 -{% endblock %}  
courses/templates/course/course_card.html
1 {% load static i18n permission_tags %} 1 {% load static i18n permission_tags %}
2 {% load django_bootstrap_breadcrumbs %} 2 {% load django_bootstrap_breadcrumbs %}
3 3
4 -<div class="panel-group ui-accordion ui-widget ui-helper-reset ui-sortable" id="accordion" role="tablist" aria-multiselectable="false">  
5 - <div class="group">  
6 - <div class="panel panel-info">  
7 - <div class="panel-heading" role="tab">  
8 - <div class="row">  
9 - <div class="col-xs-9 col-md-10 titleTopic">  
10 - <a role="button" data-toggle="collapse" data-parent="#accordion" href=".collapseOne" aria-expanded="false" aria-controls="collapseOne" class="collapsed">  
11 - <h4 style="color:white">{{course.name}}</h4>  
12 - </a>  
13 - </div>  
14 - {% if user|has_role:'professor' or user|has_role:'system_admin' %}  
15 - <div class="col-xs-4 col-md-2" id="divMoreActions">  
16 - <div class="btn-group">  
17 - <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">  
18 - <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>  
19 - </button>  
20 - <ul class="dropdown-menu" aria-labelledby="moreActions">  
21 - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal4"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>&nbsp; Replicate</a></li>  
22 - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#removeCourse"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp; Remove</a></li>  
23 - </ul>  
24 - </div>  
25 - </div>  
26 - {% endif %}  
27 - </div>  
28 - </div>  
29 - <div class="panel-collapse collapseOne collapse in" role="tabpanel" aria-labelledby="headingOne" aria-expanded="true" aria-hidden="false" tabindex="0">  
30 - <div class="panel-body">  
31 - <p><b>Course Name: </b>{{course.name}}</p>  
32 - <p><b>Coordinator: </b>{{course.professors.all.0}}</p>  
33 - <p>  
34 - <b>Description:</b>  
35 - <i>  
36 - {{course.description}}  
37 - </i>  
38 - </p>  
39 - <a href="{% url 'course:view' course.slug %}" class="btn btn-raised btn-default center-block">{% trans 'View Course' %}<div class="ripple-container"></div></a>  
40 - </div>  
41 - </div>  
42 - </div>  
43 - </div>  
44 - </div>  
45 \ No newline at end of file 4 \ No newline at end of file
  5 +<div class="panel-group ui-accordion ui-widget ui-helper-reset ui-sortable" id="accordion-{{course.slug}}" role="tablist" aria-multiselectable="false">
  6 + <div class="group">
  7 + <div class="panel panel-info">
  8 + <div class="panel-heading" role="tab">
  9 + <div class="row">
  10 + <div class="col-xs-9 col-md-10 titleTopic">
  11 + <a role="button" data-toggle="collapse" data-parent="#accordion-{{course.slug}}" href=".collapseOne-{{course.slug}}" aria-expanded="false" aria-controls="collapseOne-{{course.slug}}" class="collapsed">
  12 + <h4 style="color:white">{{course.name}}</h4>
  13 + </a>
  14 + </div>
  15 + {% if user|has_role:'professor' or user|has_role:'system_admin' %}
  16 + <div class="col-xs-4 col-md-2" id="divMoreActions">
  17 + <div class="btn-group">
  18 + <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  19 + <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>
  20 + </button>
  21 + <ul class="dropdown-menu" aria-labelledby="moreActions">
  22 + <li><a href="{% url 'course:replicate_course' course.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>{% trans 'Replicate' %}</a></li>
  23 + <li><a href="javascript:delete_course('{% url 'course:delete' course.slug %}', '{{ course.slug }}', '{% trans "Are you sure you want to delete this course?" %}', '{% url 'course:manage' %}')"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>{% trans 'Remove' %}</a></li>
  24 + </ul>
  25 + </div>
  26 + </div>
  27 + {% endif %}
  28 + </div>
  29 + </div>
  30 + <div class="panel-collapse collapseOne-{{course.slug}} collapse in" role="tabpanel" aria-labelledby="headingOne" aria-expanded="true" aria-hidden="false" tabindex="0">
  31 + <div class="panel-body">
  32 + <p><b>Course Name: </b>{{course.name}}</p>
  33 + <p><b>Coordinator: </b>{{course.professors.all.0}}</p>
  34 + <p>
  35 + <b>Description:</b>
  36 + <i>
  37 + {{course.content}}
  38 + </i>
  39 + </p>
  40 + <a href="{% url 'course:view' course.slug %}" class="btn btn-raised btn-default center-block">{% trans 'View Course' %}<div class="ripple-container"></div></a>
  41 + </div>
  42 + </div>
  43 + </div>
  44 + </div>
  45 +</div>
  46 +
  47 +<div class="modal fade" id="replicateCourse" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  48 + <div class="modal-dialog" role="document">
  49 + <div class="modal-content">
  50 + <div class="modal-header">
  51 + <h4 class="modal-title" id="myModalLabel">{% trans 'Repicate Course' %}</h4>
  52 + </div>
  53 + <div class="modal-body">
  54 + <section>
  55 + <div class="course_replicate_form"></div>
  56 + </section>
  57 + </div>
  58 + <div class="modal-footer">
  59 + <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans 'Close' %}</button>
  60 + <button type="button" onclick="$('#course_replicate').submit();" class="btn btn-primary btn-raised">{% trans 'Create' %}</button>
  61 + </div>
  62 + </div>
  63 + </div>
  64 +</div>
46 \ No newline at end of file 65 \ No newline at end of file
courses/templates/course/index.html
@@ -41,6 +41,21 @@ @@ -41,6 +41,21 @@
41 </ul> 41 </ul>
42 </div> 42 </div>
43 </div> 43 </div>
  44 +
  45 + {% if user|has_role:'professor' or user|has_role:'system_admin' %}
  46 +
  47 + <div class="panel panel-primary navigation">
  48 + <div class="panel-heading">
  49 + <h3 class="panel-title">Category</h3>
  50 + </div>
  51 + <div class="panel-body">
  52 + <ul class="nav nav-pills nav-stacked">
  53 + <li><a href="{% url 'course:create_cat' %}">Create Category</a></li>
  54 + <li><a href="{% url 'course:manage_cat' %}">List Category</a></li>
  55 + </ul>
  56 + </div>
  57 + </div>
  58 + {% endif %}
44 {% endblock %} 59 {% endblock %}
45 60
46 {% block content %} 61 {% block content %}
@@ -81,74 +96,13 @@ @@ -81,74 +96,13 @@
81 {% for course in courses_category %} 96 {% for course in courses_category %}
82 {% if course.category.name == request.GET.category %} 97 {% if course.category.name == request.GET.category %}
83 <!-- Put your content here! --> 98 <!-- Put your content here! -->
84 - <div class="panel-group ui-accordion ui-widget ui-helper-reset ui-sortable" id="accordion" role="tablist" aria-multiselectable="false">  
85 - <div class="group">  
86 - <div class="panel panel-info">  
87 - <div class="panel-heading" role="tab">  
88 - <div class="row">  
89 - <div class="col-xs-9 col-md-9 titleTopic">  
90 - <a role="button" data-toggle="collapse" data-parent="#accordion" href=".collapseOne" aria-expanded="false" aria-controls="collapseOne" class="collapsed">  
91 - <h4 style="color:white">{{course.name}}</h4>  
92 - </a>  
93 - </div>  
94 - {% if user|has_role:'professor' or user|has_role:'system_admin' %}  
95 - <div class="col-xs-4 col-md-3" id="divMoreActions">  
96 - <div class="btn-group">  
97 - <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">  
98 - <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>  
99 - </button>  
100 - <ul class="dropdown-menu" aria-labelledby="moreActions">  
101 - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal4"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>&nbsp; Replicate</a></li>  
102 - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#removeCourse"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp; Remove</a></li>  
103 - </ul>  
104 - </div>  
105 - </div>  
106 - {% endif %}  
107 - </div>  
108 - </div>  
109 - <div class="panel-collapse collapseOne collapse in" role="tabpanel" aria-labelledby="headingOne" aria-expanded="true" aria-hidden="false" tabindex="0">  
110 - <div class="panel-body">  
111 - <p><b>Course Name: </b>{{course.name}}</p>  
112 - <p><b>Duration (in semesters): </b>09</p>  
113 - <p><b>Coordinator: </b>{{course.professors}}</p>  
114 - <p>  
115 - <b>Description:</b>  
116 - <i>  
117 - {{course.description}}  
118 - </i>  
119 - </p>  
120 - <a href="{% url 'course:view' course.slug %}" class="btn btn-raised btn-default center-block">{% trans 'View Course' %}<div class="ripple-container"></div></a>  
121 - </div>  
122 - </div>  
123 - </div>  
124 - </div>  
125 - </div> 99 + {% include "course/course_card.html" %}
126 {% endif %} 100 {% endif %}
127 {% endfor %} 101 {% endfor %}
128 {% endif %} 102 {% endif %}
129 {% else %} 103 {% else %}
130 {% trans 'No courses found' %} 104 {% trans 'No courses found' %}
131 {% endif %} 105 {% endif %}
132 - <div class="group">  
133 - <div class="modal" id="removeCourse">  
134 - <div class="modal-dialog">  
135 - <div class="modal-content">  
136 - <div class="modal-header">  
137 - <button type="button" class="close" data-dismiss="modal" aria-hidden="true">X</button>  
138 - <h4 class="modal-title"></h4>  
139 - </div>  
140 - <div class="modal-body">  
141 - <p>Delete your course?</p>  
142 - </div>  
143 - <div class="modal-footer">  
144 -  
145 - <a href="http://127.0.0.1:8080/html/screens/users/profile_user.html" target="_self"><button type="button" class="btn btn-primary">Confirm</button></a>  
146 -  
147 - </div>  
148 - </div>  
149 - </div>  
150 - </div>  
151 - </div>  
152 </div> 106 </div>
153 <div class="col-md-12"> 107 <div class="col-md-12">
154 <nav aria-label="Page navigation"> 108 <nav aria-label="Page navigation">
@@ -171,4 +125,6 @@ @@ -171,4 +125,6 @@
171 </ul> 125 </ul>
172 </nav> 126 </nav>
173 </div> 127 </div>
  128 +
  129 + <script type="text/javascript" src="{% static 'js/course.js' %}"></script>
174 {% endblock %} 130 {% endblock %}
courses/templates/course/replicate.html 0 → 100644
@@ -0,0 +1,135 @@ @@ -0,0 +1,135 @@
  1 +{% extends 'course/view.html' %}
  2 +
  3 +{% load static i18n %}
  4 +{% load widget_tweaks %}
  5 +
  6 +{% block breadcrumbs %}
  7 + <ol class="breadcrumb">
  8 + <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>
  9 + <li class="active">{% trans 'Replicate Course' %}</li>
  10 + </ol>
  11 +{% endblock %}
  12 +
  13 +{% block content %}
  14 +<div class="card card-content">
  15 + <div class="card-body">
  16 + <form method="post" action="" enctype="multipart/form-data">{% csrf_token %}
  17 + <div class="form-group is-fileinput">
  18 + <label for="id_name">Name</label>
  19 +
  20 +
  21 + <input class="form-control" id="id_name" maxlength="100" name="name" type="text" required="" value="{{course.name}}">
  22 +
  23 + <span class="help-block">Course name</span>
  24 +
  25 + </div>
  26 +
  27 + <div class="form-group is-fileinput">
  28 + <label for="id_objectivies">Objectives</label>
  29 +
  30 + <textarea class="form-control" cols="80" id="id_objectivies" name="objectivies" rows="5">{{course.objectivies}}</textarea>
  31 +
  32 + <span class="help-block">Course objective</span>
  33 +
  34 + </div>
  35 +
  36 + <div class="form-group is-fileinput">
  37 + <label for="id_content">Content</label>
  38 +
  39 +
  40 + <textarea class="form-control" cols="80" id="id_content" name="content" rows="5">{{course.content}}</textarea>
  41 +
  42 + <span class="help-block">Course modules</span>
  43 +
  44 + </div>
  45 +
  46 + <div class="form-group is-fileinput">
  47 + <label for="id_max_students">Number of studets maximum</label>
  48 +
  49 +
  50 + <input class="form-control" id="id_max_students" min="0" name="max_students" type="number" value="{{course.max_students}}">
  51 +
  52 + <span class="help-block">Max number of students that a class can have</span>
  53 +
  54 + </div>
  55 +
  56 + <div class="form-group is-fileinput">
  57 + <label for="id_init_register_date">Course registration start date</label>
  58 +
  59 +
  60 + <input type="date" class="form-control" name="init_register_date" value="None" min="2016-10-24">
  61 +
  62 + <span class="help-block">Date that starts the registration period of the course (dd/mm/yyyy)</span>
  63 +
  64 + </div>
  65 +
  66 + <div class="form-group is-fileinput">
  67 + <label for="id_end_register_date">Course registration end date</label>
  68 +
  69 +
  70 + <input type="date" class="form-control" name="end_register_date" value="None" min="2016-10-24">
  71 +
  72 + <span class="help-block">Date that ends the registration period of the course (dd/mm/yyyy)</span>
  73 +
  74 + </div>
  75 +
  76 + <div class="form-group is-fileinput">
  77 + <label for="id_init_date">Course start date</label>
  78 +
  79 +
  80 + <input type="date" class="form-control" name="init_date" value="None" min="2016-10-24">
  81 +
  82 + <span class="help-block">Date that the course starts (dd/mm/yyyy)</span>
  83 +
  84 + </div>
  85 +
  86 + <div class="form-group is-fileinput">
  87 + <label for="id_end_date">Course end date</label>
  88 +
  89 +
  90 + <input type="date" class="form-control" name="end_date" value="None" min="2016-10-24">
  91 +
  92 + <span class="help-block">Date that the course ends (dd/mm/yyyy)</span>
  93 +
  94 + </div>
  95 +
  96 + <div class="form-group is-fileinput">
  97 + <label for="id_image">Imagem</label>
  98 +
  99 +
  100 + <input class="form-control" id="id_image" name="image" type="file">
  101 + <div class="input-group">
  102 + <input type="text" readonly="" class="form-control" placeholder="Choose your photo...">
  103 + <span class="input-group-btn input-group-sm">
  104 + <button type="button" class="btn btn-fab btn-fab-mini">
  105 + <i class="material-icons">attach_file</i>
  106 + </button>
  107 + </span>
  108 + </div>
  109 +
  110 + <span class="help-block">Representative image of the course</span>
  111 +
  112 + </div>
  113 +
  114 + <div class="form-group is-fileinput">
  115 + <label for="id_category">CourseCategory</label>
  116 +
  117 +
  118 + <select class="form-control" id="id_category" name="category" required="">
  119 + {% for category in categorys_courses %}
  120 + <option value="{{category.id}}">{{category}}</option>
  121 + {% endfor %}
  122 + </select>
  123 +
  124 + <span class="help-block">CourseCategory which the course belongs</span>
  125 +
  126 + </div>
  127 +
  128 + <div class="row text-center">
  129 + <input type="submit" value="Create" class="btn btn-primary">
  130 + </div>
  131 + </form>
  132 + </div>
  133 +</div>
  134 +</br>
  135 +{% endblock %}
0 \ No newline at end of file 136 \ No newline at end of file
courses/templates/course/view.html
@@ -49,7 +49,6 @@ @@ -49,7 +49,6 @@
49 </div> 49 </div>
50 </div> 50 </div>
51 {% endif %} 51 {% endif %}
52 -  
53 {% endblock %} 52 {% endblock %}
54 53
55 {% block content %} 54 {% block content %}
courses/urls.py
@@ -4,6 +4,7 @@ from . import views @@ -4,6 +4,7 @@ from . import views
4 urlpatterns = [ 4 urlpatterns = [
5 url(r'^$', views.IndexView.as_view(), name='manage'), 5 url(r'^$', views.IndexView.as_view(), name='manage'),
6 url(r'^create/$', views.CreateCourseView.as_view(), name='create'), 6 url(r'^create/$', views.CreateCourseView.as_view(), name='create'),
  7 + url(r'^replicate_course/(?P<slug>[\w_-]+)/$', views.ReplicateCourseView.as_view(), name='replicate_course'),
7 url(r'^edit/(?P<slug>[\w_-]+)/$', views.UpdateCourseView.as_view(), name='update'), 8 url(r'^edit/(?P<slug>[\w_-]+)/$', views.UpdateCourseView.as_view(), name='update'),
8 url(r'^(?P<slug>[\w_-]+)/$', views.CourseView.as_view(), name='view'), 9 url(r'^(?P<slug>[\w_-]+)/$', views.CourseView.as_view(), name='view'),
9 url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteCourseView.as_view(), name='delete'), 10 url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteCourseView.as_view(), name='delete'),
@@ -12,7 +13,6 @@ urlpatterns = [ @@ -12,7 +13,6 @@ urlpatterns = [
12 url(r'^categories/view/$', views.IndexCatView.as_view(), name='manage_cat'), 13 url(r'^categories/view/$', views.IndexCatView.as_view(), name='manage_cat'),
13 url(r'^categories/create/$', views.CreateCatView.as_view(), name="create_cat"), 14 url(r'^categories/create/$', views.CreateCatView.as_view(), name="create_cat"),
14 url(r'^categories/edit/(?P<slug>[\w_-]+)/$', views.UpdateCatView.as_view(), name='update_cat'), 15 url(r'^categories/edit/(?P<slug>[\w_-]+)/$', views.UpdateCatView.as_view(), name='update_cat'),
15 - url(r'^categories/(?P<slug>[\w_-]+)/$', views.ViewCat.as_view(), name='view_cat'),  
16 url(r'^categories/delete/(?P<slug>[\w_-]+)/$', views.DeleteCatView.as_view(), name='delete_cat'), 16 url(r'^categories/delete/(?P<slug>[\w_-]+)/$', views.DeleteCatView.as_view(), name='delete_cat'),
17 url(r'^subjects/(?P<slug>[\w_-]+)/$', views.SubjectsView.as_view(), name='view_subject'), 17 url(r'^subjects/(?P<slug>[\w_-]+)/$', views.SubjectsView.as_view(), name='view_subject'),
18 url(r'^subjects/create/(?P<slug>[\w_-]+)/$', views.CreateSubjectView.as_view(), name='create_subject'), 18 url(r'^subjects/create/(?P<slug>[\w_-]+)/$', views.CreateSubjectView.as_view(), name='create_subject'),
courses/views.py
@@ -36,9 +36,12 @@ class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView): @@ -36,9 +36,12 @@ class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView):
36 context = super(IndexView, self).get_context_data(**kwargs) 36 context = super(IndexView, self).get_context_data(**kwargs)
37 list_courses = None 37 list_courses = None
38 categorys_courses = None 38 categorys_courses = None
39 - if has_role(self.request.user,'professor') or has_role(self.request.user,'system_admin'): 39 + if has_role(self.request.user,'professor'):
40 list_courses = Course.objects.filter(Q(professors = True)|Q(professors__name = self.request.user.name)).order_by('name') 40 list_courses = Course.objects.filter(Q(professors = True)|Q(professors__name = self.request.user.name)).order_by('name')
41 categorys_courses = CourseCategory.objects.filter(course_category__professors__name = self.request.user.name).distinct() 41 categorys_courses = CourseCategory.objects.filter(course_category__professors__name = self.request.user.name).distinct()
  42 + elif has_role(self.request.user,'system_admin'):
  43 + list_courses = queryset.order_by('name')
  44 + categorys_courses = CourseCategory.objects.all()
42 else: 45 else:
43 list_courses = Course.objects.filter(Q(students = True)|Q(students__name = self.request.user.name)).order_by('name') 46 list_courses = Course.objects.filter(Q(students = True)|Q(students__name = self.request.user.name)).order_by('name')
44 categorys_courses = CourseCategory.objects.filter(course_category__students__name = self.request.user.name).distinct() 47 categorys_courses = CourseCategory.objects.filter(course_category__students__name = self.request.user.name).distinct()
@@ -102,6 +105,38 @@ class CreateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,gener @@ -102,6 +105,38 @@ class CreateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,gener
102 context['now'] = date.today() 105 context['now'] = date.today()
103 return context 106 return context
104 107
  108 +class ReplicateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edit.CreateView):
  109 +
  110 + allowed_roles = ['professor', 'system_admin']
  111 + login_url = reverse_lazy("core:home")
  112 + redirect_field_name = 'next'
  113 + template_name = 'course/replicate.html'
  114 + form_class = CourseForm
  115 + success_url = reverse_lazy('course:manage')
  116 +
  117 + def form_valid(self, form):
  118 + self.object = form.save()
  119 + self.object.professors.add(self.request.user)
  120 + return super(ReplicateCourseView, self).form_valid(form)
  121 +
  122 + def get_context_data(self, **kwargs):
  123 + context = super(ReplicateCourseView, self).get_context_data(**kwargs)
  124 + course = get_object_or_404(Course, slug = self.kwargs.get('slug'))
  125 + if has_role(self.request.user,'system_admin'):
  126 + courses = Course.objects.all()
  127 + elif has_role(self.request.user,'professor'):
  128 + courses = self.request.user.courses.all()
  129 + categorys_courses = CourseCategory.objects.all()
  130 + context['courses'] = courses
  131 + context['course'] = course
  132 + context['categorys_courses'] = categorys_courses
  133 + context['title'] = _("Replicate Course")
  134 + context['now'] = date.today()
  135 + return context
  136 +
  137 + def get_success_url(self):
  138 + return reverse_lazy('course:view', kwargs={'slug' : self.object.slug})
  139 +
105 class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): 140 class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
106 141
107 allowed_roles = ['professor', 'system_admin'] 142 allowed_roles = ['professor', 'system_admin']
@@ -133,8 +168,6 @@ class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): @@ -133,8 +168,6 @@ class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
133 def get_success_url(self): 168 def get_success_url(self):
134 return reverse_lazy('course:view', kwargs={'slug' : self.object.slug}) 169 return reverse_lazy('course:view', kwargs={'slug' : self.object.slug})
135 170
136 -  
137 -  
138 class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): 171 class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView):
139 172
140 allowed_roles = ['professor', 'system_admin'] 173 allowed_roles = ['professor', 'system_admin']
@@ -297,13 +330,6 @@ class UpdateCatView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): @@ -297,13 +330,6 @@ class UpdateCatView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
297 messages.success(self.request, _('Category updated successfully!')) 330 messages.success(self.request, _('Category updated successfully!'))
298 return reverse_lazy('course:update_cat', kwargs={'slug' : self.object.slug}) 331 return reverse_lazy('course:update_cat', kwargs={'slug' : self.object.slug})
299 332
300 -class ViewCat(LoginRequiredMixin, generic.DetailView):  
301 - login_url = reverse_lazy("core:home")  
302 - redirect_field_name = 'next'  
303 - model = CourseCategory  
304 - template_name = 'category/view.html'  
305 - context_object_name = 'category'  
306 -  
307 class DeleteCatView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): 333 class DeleteCatView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView):
308 334
309 allowed_roles = ['professor', 'system_admin'] 335 allowed_roles = ['professor', 'system_admin']