Completed
Push — master ( 04980f...90016b )
by Vijay
01:16
created

Workshop

Size/Duplication

Total Lines 177
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 177

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __str__() 0 2 1
A get_presenter_list() 0 2 2
B assign_me() 0 44 4
A get_tweet() 0 13 2
A is_organiser() 0 2 1
A is_presenter() 0 2 1
A set_status() 0 13 3
A manage_action() 0 18 2
A toggle_active() 0 13 1
1
from django.contrib.auth.models import User
2
from django.contrib.sites.models import Site
3
from django.core.validators import MaxValueValidator
4
from django.core.urlresolvers import reverse_lazy
5
from django.db import models
6
from django.template import loader
7
8
from wye.base.constants import (
9
    FeedbackType,
10
    WorkshopAction,
11
    WorkshopLevel,
12
    WorkshopStatus,
13
)
14
from wye.base.emailer_html import send_email_to_list
15
from wye.base.models import TimeAuditModel
16
from wye.organisations.models import Organisation
17
# from wye.profiles.models import Profile
18
from wye.regions.models import Location
19
20
from .decorators import validate_action_param, validate_assignme_action
21
22
23
class WorkshopSections(TimeAuditModel):
24
    '''
25
    python2, Python3, Django, Flask, Gaming
26
    '''
27
    name = models.CharField(max_length=300, unique=True)
28
29
    class Meta:
30
        db_table = 'workshop_section'
31
32
    def __str__(self):
33
        return '{}'.format(self.name)
34
35
36
class Workshop(TimeAuditModel):
37
    no_of_participants = models.PositiveIntegerField(
38
        validators=[MaxValueValidator(1000)])
39
    expected_date = models.DateField()
40
    description = models.TextField()
41
    requester = models.ForeignKey(
42
        Organisation, related_name='workshop_requester')
43
    presenter = models.ManyToManyField(User, related_name='workshop_presenter')
44
    location = models.ForeignKey(Location, related_name='workshop_location')
45
    workshop_level = models.PositiveSmallIntegerField(
46
        choices=WorkshopLevel.CHOICES, verbose_name="Workshop Level")
47
    workshop_section = models.ForeignKey(WorkshopSections)
48
    is_active = models.BooleanField(default=True)
49
    status = models.PositiveSmallIntegerField(
50
        choices=WorkshopStatus.CHOICES, verbose_name="Current Status",
51
        default=WorkshopStatus.REQUESTED)
52
53
    class Meta:
54
        db_table = 'workshops'
55
56
    def __str__(self):
57
        return '{}-{}'.format(self.requester, self.workshop_section)
58
59
    # def save(self, force_insert=False, force_update=False, using=None):
60
    #     """
61
    #     send mail to region interested member whenever new workshop
62
    #     is requested in respective region, therefore overriding
63
    #     pre save method so mails are only send when new object
64
    #     is created.
65
    #     :param force_insert: bool force_insert
66
    #     :param force_update: bool force_insert
67
    #     :param using: using
68
    #     :return: instance
69
    #     """
70
    #     if not self.id:
71
    #         domain = Site.objects.get_current().domain
72
    #         context = {
73
    #             'workshop': self,
74
    #             'date': self.expected_date,
75
    #             'workshop_url': domain + '/workshop/{}/'.format(self.id)
76
    #         }
77
    #         # get region_interested_member email ids to notify them
78
    #         region_interested_member = Profile.objects.filter(
79
    #             interested_locations=self.requester.location,
80
    #             usertype__slug='tutor'
81
    #         ).values_list('user__email', flat=True)
82
83
    #         subject = '[PythonExpress] Workshop request status.'
84
    #         email_body = loader.get_template(
85
    #             'email_messages/workshop/create_workshop/message.html').render(context)
86
    #         text_body = loader.get_template(
87
    #             'email_messages/workshop/create_workshop/message.txt').render(context)
88
    #         send_email_to_list(
89
    #             subject,
90
    #             body=email_body,
91
    #             users_list=region_interested_member,
92
    #             text_body=text_body)
93
94
    #     super(Workshop, self).save(force_insert, force_update, using)
95
96
97
    def is_presenter(self, user):
98
        return self.presenter.filter(pk=user.pk).exists()
99
100
    def is_organiser(self, user):
101
        return self.requester.user.filter(pk=user.pk).exists()
102
103
    def manage_action(self, user, **kwargs):
104
        actions = {
105
            'accept': ("opt-in", self.assign_me),
106
            'reject': ("opt-out", self.assign_me),
107
            'decline': (WorkshopStatus.DECLINED, self.set_status),
108
            'publish': (WorkshopStatus.REQUESTED, self.set_status),
109
            'hold': (WorkshopStatus.HOLD, self.set_status),
110
            'assign': ""
111
        }
112
        if kwargs.get('action') not in actions:
113
            return {
114
                'status': False,
115
                'msg': 'Action not allowed'
116
            }
117
118
        action, func = actions.get(kwargs.get('action'))
119
        kwargs["action"] = action
120
        return func(user, **kwargs)
121
122
    def set_status(self, user, **kwargs):
123
        self.status = kwargs.get('action')
124
        presenter_list = self.presenter.all()
125
        for u in presenter_list:
126
            self.presenter.remove(u)
127
        if kwargs.get('action') == WorkshopStatus.DECLINED:
128
            self.is_active = False
129
        else:
130
            self.is_active = True
131
        self.save()
132
        return {
133
            'status': True,
134
            'msg': 'Workshop successfully updated.'}
135
136
    @validate_action_param(WorkshopAction.ACTIVE)
137
    def toggle_active(self, user, **kwargs):
138
        """
139
        Helper method to toggle is_active for the model.
140
        """
141
142
        action_map = {'active': True, 'deactive': False}
143
        action = kwargs.get('action')
144
        self.is_active = action_map.get(action)
145
        self.save()
146
        return {
147
            'status': True,
148
            'msg': 'Workshop successfully updated.'}
149
150
    # @validate_action_param(WorkshopAction.ASSIGNME)
151
    @validate_assignme_action
152
    def assign_me(self, user, **kwargs):
153
        """
154
        Method to assign workshop by presenter self.
155
        """
156
157
        action_map = {
158
            'opt-in': self.presenter.add,
159
            'opt-out': self.presenter.remove
160
        }
161
        message_map = {
162
            'opt-in': 'Assigned successfully.',
163
            'opt-out': 'Unassigned successfully.'
164
        }
165
        assigned = {
166
            'opt-in': True,
167
            'opt-out': False
168
        }
169
        action = kwargs.get('action')
170
        if assigned[action] and self.presenter.filter(pk=user.pk).exists():
171
            # This save has been added as fail safe
172
            # once the logic is consolidated may be
173
            # it can be removed
174
            self.status = WorkshopStatus.ACCEPTED
175
            self.save()
176
            return {
177
                'status': False,
178
                'msg': 'Workshop has already been assigned.'
179
            }
180
181
        func = action_map.get(action)
182
        func(user)
183
184
        if self.presenter.count() > 0:
185
            self.status = WorkshopStatus.ACCEPTED
186
        else:
187
            self.status = WorkshopStatus.REQUESTED
188
        self.save()
189
190
        return {
191
            'status': True,
192
            'assigned': assigned[action],
193
            'msg': message_map[action],
194
            'notify': True
195
        }
196
197
    def get_presenter_list(self):
198
        return [user.get_full_name() for user in self.presenter.all()]
199
200
    def get_tweet(self, context):
201
        workshop = self
202
        date = workshop.expected_date
203
        topic = workshop.workshop_section
204
        organization = workshop.requester
205
        workshop_url = context.get('workshop_url', None)
206
        message = "{} workshop at {} on {} confirmed! Details at {}".format(
207
            topic, organization, date, workshop_url)
208
        if len(message) >= 140:
209
            message = "{} workshop on {} confirmed! Details at {}".format(
210
                topic, date, workshop_url)
211
212
        return message
213
214
215
class WorkshopRatingValues(TimeAuditModel):
216
    '''
217
    Requesting Rating values -2, -1, 0 , 1, 2
218
    '''
219
220
    name = models.CharField(max_length=300)
221
222
    class Meta:
223
        db_table = 'workshop_vote_value'
224
225
    def __str__(self):
226
        return '{}'.format(self.name)
227
228
    @classmethod
229
    def get_questions(cls):
230
        return cls.objects.values('name', 'pk')
231
232
233
class WorkshopFeedBack(TimeAuditModel):
234
    '''
235
    Requesting for Feedback from requester and Presenter
236
    '''
237
238
    workshop = models.ForeignKey(Workshop)
239
    comment = models.TextField()
240
    feedback_type = models.PositiveSmallIntegerField(
241
        choices=FeedbackType.CHOICES, verbose_name="User_type")
242
243
    class Meta:
244
        db_table = 'workshop_feedback'
245
246
    def __str__(self):
247
        return '{}'.format(self.workshop)
248
249
    @classmethod
250
    def save_feedback(cls, user, workshop_id, **kwargs):
251
        workshop = Workshop.objects.get(pk=workshop_id)
252
        presenter = workshop.is_presenter(user)
253
        organiser = workshop.is_organiser(user)
254
        comment = kwargs.get('comment', '')
255
        del kwargs['comment']
256
257
        if presenter:
258
            feedback_type = FeedbackType.PRESENTER
259
        elif organiser:
260
            feedback_type = FeedbackType.ORGANISATION
261
262
        workshop_feedback = cls.objects.create(
263
            workshop=workshop,
264
            comment=comment,
265
            feedback_type=feedback_type
266
        )
267
        WorkshopVoting.save_rating(workshop_feedback, **kwargs)
268
269
270
class WorkshopVoting(TimeAuditModel):
271
    workshop_feedback = models.ForeignKey(
272
        WorkshopFeedBack, related_name='workshop_feedback')
273
    workshop_rating = models.ForeignKey(
274
        WorkshopRatingValues, related_name='workshop_rating')
275
    rating = models.IntegerField()
276
277
    class Meta:
278
        db_table = 'workshop_votes'
279
280
    def __str__(self):
281
        return '{}-{}-{}'.format(self.workshop_feedback,
282
                                 self.workshop_rating,
283
                                 self.rating)
284
285
    @classmethod
286
    def save_rating(cls, workshop_feedback, **kwargs):
287
        object_list = [
288
            cls(workshop_feedback=workshop_feedback,
289
                workshop_rating_id=int(k), rating=v)
290
            for k, v in kwargs.items()
291
        ]
292
293
        cls.objects.bulk_create(object_list)
294