1
- #coding: utf-8
1
+ # coding: utf-8
2
2
import caching .base
3
3
import datetime
4
4
import logging
9
9
from django .utils .translation import ugettext_lazy as _
10
10
from django .contrib .auth .models import User
11
11
from django .core .exceptions import SuspiciousOperation , ValidationError
12
+ from django .conf import settings
12
13
13
14
from articletrack import modelmanagers
14
15
from journalmanager .models import Journal
20
21
MSG_WORKFLOW_REVIEWED = 'Checkin Reviewed'
21
22
MSG_WORKFLOW_SENT_TO_PENDING = 'Checkin Sent to Pending'
22
23
MSG_WORKFLOW_SENT_TO_REVIEW = 'Checkin Sent to Review'
24
+ MSG_WORKFLOW_EXPIRED = 'Checkin Expired'
23
25
24
26
25
27
class Notice (caching .base .CachingMixin , models .Model ):
@@ -45,6 +47,7 @@ def __unicode__(self):
45
47
('review' , _ ('Review' )),
46
48
('accepted' , _ ('Accepted' )),
47
49
('rejected' , _ ('Rejected' )),
50
+ ('expired' , _ ('Expired' )),
48
51
)
49
52
50
53
@@ -57,7 +60,7 @@ def decorated(*args, **kwargs):
57
60
log .checkin = args [0 ]
58
61
log .status = args [0 ].status
59
62
log .created_at = datetime .datetime .now ()
60
- log .user = args [1 ]
63
+ log .user = args [1 ] if len ( args ) >= 2 else None
61
64
log .description = message + (" - Reason: %s" % args [0 ].rejected_cause if getattr (args [0 ], 'rejected_cause' ) else '' )
62
65
log .save ()
63
66
@@ -91,6 +94,8 @@ class Checkin(caching.base.CachingMixin, models.Model):
91
94
92
95
submitted_by = models .ForeignKey (User , related_name = 'checkins_submitted_by' , null = True , blank = True )
93
96
97
+ expiration_at = models .DateTimeField (_ (u'Expiration Date' ), null = True , blank = True )
98
+
94
99
class Meta :
95
100
ordering = ['-created_at' ]
96
101
permissions = (("list_checkin" , "Can list Checkin" ),)
@@ -118,6 +123,14 @@ def is_newest_checkin(self):
118
123
"""
119
124
return self .pk == self .get_newest_checkin .pk
120
125
126
+ @property
127
+ def is_expirable (self ):
128
+ """
129
+ Return True if the expiration_at's date is equal to datetime.date.today()
130
+ Compared with <= to catch possibly unprocessed checkins
131
+ """
132
+ return self .status == 'pending' and self .expiration_at .date () <= datetime .date .today ()
133
+
121
134
def is_accepted (self ):
122
135
"""
123
136
Checks if this checkin has been accepted
@@ -270,7 +283,6 @@ def do_review(self, responsible):
270
283
else :
271
284
raise ValueError ('This checkin does not comply with the conditions to be reviewed' )
272
285
273
-
274
286
@log_workflow_status (MSG_WORKFLOW_REJECTED )
275
287
def do_reject (self , responsible , reason ):
276
288
"""
@@ -295,6 +307,18 @@ def do_reject(self, responsible, reason):
295
307
else :
296
308
raise ValueError ('This checkin does not comply with the conditions to change status to "rejected"' )
297
309
310
+ @log_workflow_status (MSG_WORKFLOW_EXPIRED )
311
+ def do_expires (self , responsible = None ):
312
+ """
313
+ Change self.status to 'expired'.
314
+ Change self.expiration_at to now()
315
+ This action generates a ``CheckinWorkflowLog`` entry.
316
+ """
317
+ if self .status != 'expired' :
318
+ self .status = 'expired'
319
+ self .expiration_at = datetime .datetime .now ()
320
+ self .save ()
321
+
298
322
def clean (self ):
299
323
# validation for status "accepted"
300
324
if self .status == 'accepted' and not bool (self .accepted_by and self .accepted_at and self .reviewed_by and self .reviewed_at ):
@@ -307,6 +331,12 @@ def clean(self):
307
331
308
332
def save (self , * args , ** kwargs ):
309
333
if self .status == 'pending' :
334
+ if self .expiration_at is None :
335
+ # update expiration info
336
+ now = datetime .datetime .now ()
337
+ time_span = settings .CHECKIN_EXPIRATION_TIME_SPAN
338
+ delta_next = datetime .timedelta (days = time_span )
339
+ self .expiration_at = now + delta_next
310
340
# clear 'review' fields
311
341
self .reviewed_by = None
312
342
self .reviewed_at = None
@@ -318,6 +348,8 @@ def save(self, *args, **kwargs):
318
348
self .rejected_at = None
319
349
self .rejected_cause = None
320
350
elif self .status == 'review' :
351
+ # update expiration info
352
+ self .expiration_at = None
321
353
# clear 'accepted' fields
322
354
self .accepted_by = None
323
355
self .accepted_at = None
@@ -326,12 +358,17 @@ def save(self, *args, **kwargs):
326
358
self .rejected_at = None
327
359
self .rejected_cause = None
328
360
elif self .status == 'rejected' :
361
+ # update expiration info
362
+ self .expiration_at = None
329
363
# clear 'review' fields
330
364
self .reviewed_by = None
331
365
self .reviewed_at = None
332
366
# clear 'accepted' fields
333
367
self .accepted_by = None
334
368
self .accepted_at = None
369
+ else :
370
+ # update expiration info
371
+ self .expiration_at = None
335
372
super (Checkin , self ).save (* args , ** kwargs )
336
373
337
374
def __unicode__ (self ):
0 commit comments