-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlogic.py
More file actions
191 lines (155 loc) · 5.97 KB
/
logic.py
File metadata and controls
191 lines (155 loc) · 5.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
from django.utils import timezone
from core.models import AccountRole
from utils import notify_helpers, render_template, setting_handler
from plugins.vae_workflow import models
def _get_setting(name, journal):
return setting_handler.get_setting(
'plugin:vae_workflow',
name,
journal,
).processed_value
def _journal_editors(journal):
return AccountRole.objects.filter(
journal=journal,
role__slug='editor',
).select_related('user').values_list('user', flat=True)
def _send_email(request, setting_name, to, claim):
template = _get_setting(setting_name, request.journal)
context = {'claim': claim}
body = render_template.get_message_content(
request,
context,
template,
template_is_setting=True,
)
log_dict = {
'level': 'Info',
'action_text': 'VAE Workflow: {}'.format(setting_name),
'types': 'VAE Workflow',
'actor': request.user,
'target': claim.article,
}
notify_helpers.send_email_with_body_from_user(
request=request,
subject='[{}] VAE Claim — {}'.format(request.journal.code, claim.article.title),
to=to,
body=body,
log_dict=log_dict,
)
def notify_claim(request, claim):
"""Email journal editors when a VAE claims an article."""
from core.models import Account
editors = Account.objects.filter(
accountrole__journal=request.journal,
accountrole__role__slug='editor',
)
for editor in editors:
_send_email(request, 'vae_claim_notification', editor.email, claim)
def notify_withdrawn(request, claim):
"""Email journal editors when a VAE withdraws their claim."""
from core.models import Account
editors = Account.objects.filter(
accountrole__journal=request.journal,
accountrole__role__slug='editor',
)
for editor in editors:
_send_email(request, 'vae_withdrawn_notification', editor.email, claim)
def notify_confirmed(request, claim):
"""Email the VAE when their claim is confirmed."""
_send_email(request, 'vae_confirmed_notification', claim.claimed_by.email, claim)
def notify_rejected(request, claim):
"""Email the VAE when their claim is rejected."""
_send_email(request, 'vae_rejected_notification', claim.claimed_by.email, claim)
def allow_multiple_claims(journal):
return setting_handler.get_setting(
'plugin:vae_workflow',
'allow_multiple_claims',
journal,
).processed_value
def user_is_in_pool(user, journal):
return models.VAEPoolMember.objects.filter(
journal=journal,
account=user,
).exists()
def get_active_claim(article):
"""Return the confirmed or most recent pending claim for an article."""
confirmed = article.vae_claims.filter(status='confirmed').first()
if confirmed:
return confirmed
return article.vae_claims.filter(status='pending').order_by('-date_claimed').first()
def article_is_claimable(article, user, journal):
"""
Returns True if the user can claim the article.
Rules:
- User must be in the VAE pool.
- User must not already have a pending/confirmed claim on this article.
- If allow_multiple_claims is False, no other pending claim may exist.
"""
if not user_is_in_pool(user, journal):
return False
if article.vae_claims.filter(claimed_by=user, status__in=('pending', 'confirmed')).exists():
return False
if not allow_multiple_claims(journal):
if article.vae_claims.filter(status__in=('pending', 'confirmed')).exists():
return False
return True
def rescind_confirmed_claim(claim, rescinded_by):
"""
Withdraw a confirmed claim and remove the VAE's editor assignment.
Used both when a VAE rescinds their own claim and when an editor removes one.
"""
from review.models import EditorAssignment
claim.resolve('withdrawn', rescinded_by)
EditorAssignment.objects.filter(
article=claim.article,
editor=claim.claimed_by,
).delete()
def confirm_claim(claim, confirmed_by):
"""
Confirm a claim: reject all other pending claims for the same article,
assign the VAE as section editor, and return the claim.
"""
from review.models import EditorAssignment
article = claim.article
# Reject all other pending claims
now = timezone.now()
for other in article.vae_claims.filter(status='pending').exclude(pk=claim.pk):
other.status = 'rejected'
other.date_resolved = now
other.resolved_by = confirmed_by
other.save()
# Confirm this claim
claim.resolve('confirmed', confirmed_by)
# Assign the VAE as section editor
EditorAssignment.objects.get_or_create(
article=article,
editor=claim.claimed_by,
defaults={'editor_type': 'section-editor'},
)
return claim
def notify_vaes_pool(request, article):
"""Email all VAEs in the pool that a new article is available for claiming."""
pool = models.VAEPoolMember.objects.filter(journal=request.journal).select_related('account')
template = _get_setting('vae_new_article_notification', request.journal)
log_dict = {
'level': 'Info',
'action_text': 'VAE Workflow: new article notification sent',
'types': 'VAE Workflow',
'actor': request.user,
'target': article,
}
for member in pool:
context = {'article': article, 'recipient': member.account}
body = render_template.get_message_content(
request, context, template, template_is_setting=True,
)
notify_helpers.send_email_with_body_from_user(
request=request,
subject='[{}] New preprint available — {}'.format(request.journal.code, article.title),
to=member.account.email,
body=body,
log_dict=log_dict,
)
def confirmed_claim(article):
"""Return the confirmed claim for an article, if one exists."""
return article.vae_claims.filter(status='confirmed').first()