Skip to content

Commit f025993

Browse files
author
Martin Qvist
committed
Bug fixes, changes based on feedback from RjS. Abandon, recharter and initial charter views. Forward snapshots for abandoned efforts.
- Legacy-Id: 3421
1 parent ebafa58 commit f025993

16 files changed

Lines changed: 191 additions & 316 deletions

ietf/idrfc/views_edit.py

Lines changed: 13 additions & 223 deletions
Original file line numberDiff line numberDiff line change
@@ -154,75 +154,6 @@ def change_stateREDESIGN(request, name):
154154
def dehtmlify_textarea_text(s):
155155
return s.replace("<br>", "\n").replace("<b>", "").replace("</b>", "").replace(" ", " ")
156156

157-
class EditInfoForm(forms.Form):
158-
intended_status = forms.ModelChoiceField(IDIntendedStatus.objects.all(), empty_label=None, required=True)
159-
status_date = forms.DateField(required=False, help_text="Format is YYYY-MM-DD")
160-
area_acronym = forms.ModelChoiceField(Area.active_areas(), required=True, empty_label='None Selected')
161-
via_rfc_editor = forms.BooleanField(required=False, label="Via IRTF or RFC Editor")
162-
job_owner = forms.ModelChoiceField(IESGLogin.objects.filter(user_level__in=(IESGLogin.AD_LEVEL, IESGLogin.INACTIVE_AD_LEVEL)).order_by('user_level', 'last_name'), label="Responsible AD", empty_label=None, required=True)
163-
create_in_state = forms.ModelChoiceField(IDState.objects.filter(document_state_id__in=(IDState.PUBLICATION_REQUESTED, IDState.AD_WATCHING)), empty_label=None, required=True)
164-
state_change_notice_to = forms.CharField(max_length=255, label="Notice emails", help_text="Separate email addresses with commas", required=False)
165-
note = forms.CharField(widget=forms.Textarea, label="IESG note", required=False)
166-
telechat_date = forms.TypedChoiceField(coerce=lambda x: datetime.datetime.strptime(x, '%Y-%m-%d').date(), empty_value=None, required=False)
167-
returning_item = forms.BooleanField(required=False)
168-
169-
def __init__(self, *args, **kwargs):
170-
old_ads = kwargs.pop('old_ads')
171-
172-
super(self.__class__, self).__init__(*args, **kwargs)
173-
174-
job_owners = IESGLogin.objects.in_bulk([t[0] for t in self.fields['job_owner'].choices])
175-
choices = [("","None Selected"), ]
176-
if old_ads:
177-
# separate active ADs from inactive
178-
separated = False
179-
for t in self.fields['job_owner'].choices:
180-
if job_owners[t[0]].user_level != IESGLogin.AD_LEVEL and not separated:
181-
choices.append(("", "----------------"))
182-
separated = True
183-
choices.append(t)
184-
self.fields['job_owner'].choices = choices
185-
else:
186-
# remove old ones
187-
for t in self.fields['job_owner'].choices:
188-
if job_owners[t[0]].user_level==IESGLogin.AD_LEVEL:
189-
choices.append(t)
190-
self.fields['job_owner'].choices = choices
191-
192-
# telechat choices
193-
dates = TelechatDates.objects.all()[0].dates()
194-
init = kwargs['initial']['telechat_date']
195-
if init and init not in dates:
196-
dates.insert(0, init)
197-
198-
choices = [("", "(not on agenda)")]
199-
for d in dates:
200-
choices.append((d, d.strftime("%Y-%m-%d")))
201-
202-
self.fields['telechat_date'].choices = choices
203-
204-
# if kwargs['initial']['area_acronym'] == Acronym.INDIVIDUAL_SUBMITTER:
205-
# # default to "gen"
206-
# kwargs['initial']['area_acronym'] = 1008
207-
208-
# returning item is rendered non-standard
209-
self.standard_fields = [x for x in self.visible_fields() if x.name not in ('returning_item',)]
210-
211-
def clean_status_date(self):
212-
d = self.cleaned_data['status_date']
213-
if d:
214-
if d < date.today():
215-
raise forms.ValidationError("Date must not be in the past.")
216-
if d >= date.today() + timedelta(days=365 * 2):
217-
raise forms.ValidationError("Date must be within two years.")
218-
219-
return d
220-
221-
def clean_note(self):
222-
# note is stored munged in the database
223-
return self.cleaned_data['note'].replace('\n', '<br>').replace('\r', '').replace(' ', '&nbsp; ')
224-
225-
226157
def get_initial_state_change_notice(doc):
227158
# set change state notice to something sensible
228159
receivers = []
@@ -245,167 +176,25 @@ def get_initial_state_change_notice(doc):
245176
def get_new_ballot_id():
246177
return IDInternal.objects.aggregate(Max('ballot'))['ballot__max'] + 1
247178

248-
@group_required('Area_Director','Secretariat')
249-
def edit_info(request, name):
250-
"""Edit various Internet Draft attributes, notifying parties as
251-
necessary and logging changes as document comments."""
252-
doc = get_object_or_404(InternetDraft, filename=name)
253-
if doc.status.status == "Expired":
254-
raise Http404()
255-
256-
login = IESGLogin.objects.get(login_name=request.user.username)
257-
258-
new_document = False
259-
if not doc.idinternal:
260-
new_document = True
261-
doc.idinternal = IDInternal(draft=doc,
262-
rfc_flag=type(doc) == Rfc,
263-
cur_state_id=IDState.PUBLICATION_REQUESTED,
264-
prev_state_id=IDState.PUBLICATION_REQUESTED,
265-
state_change_notice_to=get_initial_state_change_notice(doc),
266-
primary_flag=1,
267-
area_acronym_id=Acronym.INDIVIDUAL_SUBMITTER,
268-
# would be better to use NULL to
269-
# signify an empty ballot
270-
ballot_id=get_new_ballot_id(),
271-
via_rfc_editor = False,
272-
)
273-
274-
if doc.idinternal.agenda:
275-
initial_telechat_date = doc.idinternal.telechat_date
276-
else:
277-
initial_telechat_date = None
278-
279-
if request.method == 'POST':
280-
form = EditInfoForm(request.POST,
281-
old_ads=False,
282-
initial=dict(telechat_date=initial_telechat_date,
283-
area_acronym=doc.idinternal.area_acronym_id))
284-
if form.is_valid():
285-
changes = []
286-
r = form.cleaned_data
287-
entry = "%s has been changed to <b>%s</b> from <b>%s</b>"
288-
if new_document:
289-
doc.idinternal.cur_state_id=r['create_in_state'].document_state_id
290-
doc.idinternal.prev_state_id=r['create_in_state'].document_state_id
291-
# Django barfs in the diff below because these fields
292-
# can't be NULL
293-
doc.idinternal.job_owner = r['job_owner']
294-
if 'area_acronym' in r:
295-
doc.idinternal.area_acronym = r['area_acronym']
296-
297-
replaces = doc.replaces_set.all()
298-
if replaces and replaces[0].idinternal:
299-
c = "Earlier history may be found in the Comment Log for <a href=\"%s\">%s</a>" % (replaces[0], replaces[0].idinternal.get_absolute_url())
300-
add_document_comment(request, doc, c)
301-
302-
orig_job_owner = doc.idinternal.job_owner
303-
304-
# update the attributes, keeping track of what we're doing
305-
306-
# coalesce some of the changes into one comment, mail them below
307-
def diff(obj, attr, name):
308-
v = getattr(obj, attr)
309-
if r[attr] != v:
310-
changes.append(entry % (name, r[attr], v))
311-
setattr(obj, attr, r[attr])
312-
313-
diff(doc, 'intended_status', "Intended Status")
314-
diff(doc.idinternal, 'status_date', "Status date")
315-
if 'area_acronym' in r and r['area_acronym']:
316-
diff(doc.idinternal, 'area_acronym', 'Area acronym')
317-
diff(doc.idinternal, 'job_owner', 'Responsible AD')
318-
diff(doc.idinternal, 'state_change_notice_to', "State Change Notice email list")
319-
320-
if changes and not new_document:
321-
add_document_comment(request, doc, "<br>".join(changes))
322-
323-
# handle note (for some reason the old Perl code didn't
324-
# include that in the changes)
325-
if r['note'] != doc.idinternal.note:
326-
if not r['note']:
327-
if doc.idinternal.note:
328-
add_document_comment(request, doc, "Note field has been cleared")
329-
else:
330-
if doc.idinternal.note:
331-
add_document_comment(request, doc, "[Note]: changed to '%s'" % r['note'])
332-
else:
333-
add_document_comment(request, doc, "[Note]: '%s' added" % r['note'])
334-
335-
doc.idinternal.note = r['note']
336-
337-
update_telechat(request, doc.idinternal,
338-
r['telechat_date'], r['returning_item'])
339-
340-
if in_group(request.user, 'Secretariat'):
341-
doc.idinternal.via_rfc_editor = bool(r['via_rfc_editor'])
342-
343-
doc.idinternal.email_display = str(doc.idinternal.job_owner)
344-
doc.idinternal.token_name = str(doc.idinternal.job_owner)
345-
doc.idinternal.token_email = doc.idinternal.job_owner.person.email()[1]
346-
doc.idinternal.mark_by = login
347-
doc.idinternal.event_date = date.today()
348-
349-
if changes and not new_document:
350-
email_owner(request, doc, orig_job_owner, login, "\n".join(changes))
351-
if new_document:
352-
add_document_comment(request, doc, "Draft added in state %s" % doc.idinternal.cur_state.state)
353-
354-
doc.idinternal.save()
355-
doc.save()
356-
return HttpResponseRedirect(doc.idinternal.get_absolute_url())
357-
else:
358-
init = dict(intended_status=doc.intended_status_id,
359-
status_date=doc.idinternal.status_date,
360-
area_acronym=doc.idinternal.area_acronym_id,
361-
job_owner=doc.idinternal.job_owner_id,
362-
state_change_notice_to=doc.idinternal.state_change_notice_to,
363-
note=dehtmlify_textarea_text(doc.idinternal.note),
364-
telechat_date=initial_telechat_date,
365-
returning_item=doc.idinternal.returning_item,
366-
)
367-
368-
form = EditInfoForm(old_ads=False, initial=init)
369-
370-
if not in_group(request.user, 'Secretariat'):
371-
form.standard_fields = [x for x in form.standard_fields if x.name != "via_rfc_editor"]
372-
373-
374-
return render_to_response('idrfc/edit_info.html',
375-
dict(doc=doc,
376-
form=form,
377-
user=request.user,
378-
login=login),
379-
context_instance=RequestContext(request))
380-
381179
class EditInfoFormREDESIGN(forms.Form):
382180
intended_std_level = forms.ModelChoiceField(IntendedStdLevelName.objects.all(), empty_label=None, required=True)
383181
status_date = forms.DateField(required=False, help_text="Format is YYYY-MM-DD")
384182
via_rfc_editor = forms.BooleanField(required=False, label="Via IRTF or RFC Editor")
385-
ad = forms.ModelChoiceField(Person.objects.filter(email__role__name__in=("ad", "ex-ad")).order_by('email__role__name', 'name'), label="Responsible AD", empty_label=None, required=True)
183+
ad = forms.ModelChoiceField(Person.objects.filter(email__role__name="ad", email__role__group__state="active").order_by('name'), label="Responsible AD", empty_label=None, required=True)
386184
create_in_state = forms.ModelChoiceField(IesgDocStateName.objects.filter(slug__in=("pub-req", "watching")), empty_label=None, required=True)
387185
notify = forms.CharField(max_length=255, label="Notice emails", help_text="Separate email addresses with commas", required=False)
388186
note = forms.CharField(widget=forms.Textarea, label="IESG note", required=False)
389187
telechat_date = forms.TypedChoiceField(coerce=lambda x: datetime.datetime.strptime(x, '%Y-%m-%d').date(), empty_value=None, required=False)
390188
returning_item = forms.BooleanField(required=False)
391189

392190
def __init__(self, *args, **kwargs):
393-
old_ads = kwargs.pop('old_ads')
394-
395191
super(self.__class__, self).__init__(*args, **kwargs)
396192

397-
# fix up ad field
193+
# if previous AD is now ex-AD, append that person to the list
194+
ad_pk = self.initial.get('ad')
398195
choices = self.fields['ad'].choices
399-
ex_ads = dict((e.pk, e) for e in Person.objects.filter(email__role__name="ex-ad").distinct())
400-
if old_ads:
401-
# separate active ADs from inactive
402-
for i, t in enumerate(choices):
403-
if t[0] in ex_ads:
404-
choices.insert(i, ("", "----------------"))
405-
break
406-
else:
407-
# remove old ones
408-
self.fields['ad'].choices = [t for t in choices if t[0] not in ex_ads]
196+
if ad_pk and ad_pk not in [pk for pk, name in choices]:
197+
self.fields['ad'].choices = list(choices) + [("", "-------"), (ad_pk, Person.objects.get(pk=ad_pk).name)]
409198

410199
# telechat choices
411200
dates = TelechatDates.objects.all()[0].dates()
@@ -473,8 +262,8 @@ def edit_infoREDESIGN(request, name):
473262

474263
if request.method == 'POST':
475264
form = EditInfoForm(request.POST,
476-
old_ads=False,
477-
initial=dict(telechat_date=initial_telechat_date))
265+
initial=dict(ad=doc.ad_id,
266+
telechat_date=initial_telechat_date))
478267
if form.is_valid():
479268
save_document_in_history(doc)
480269

@@ -539,6 +328,7 @@ def diff(attr, name):
539328

540329
for c in changes:
541330
e = DocEvent(doc=doc, by=login)
331+
e.desc = c
542332
e.type = "changed_document"
543333
e.save()
544334

@@ -550,8 +340,8 @@ def diff(attr, name):
550340
if r["status_date"] != status_date:
551341
e = StatusDateDocEvent(doc=doc, by=login)
552342
e.type ="changed_status_date"
553-
d = desc("Status date", r["status_date"], status_date)
554-
changes.append(d)
343+
e.desc = desc("Status date", r["status_date"], status_date)
344+
changes.append(e.desc)
555345
e.date = r["status_date"]
556346
e.save()
557347

@@ -572,16 +362,16 @@ def diff(attr, name):
572362
else:
573363
e = doc.latest_event(StatusDateDocEvent)
574364
status = e.date if e else None
575-
init = dict(intended_std_level=doc.intended_std_level,
365+
init = dict(intended_std_level=doc.intended_std_level_id,
576366
status_date=status,
577-
ad=doc.ad,
367+
ad=doc.ad_id,
578368
notify=doc.notify,
579369
note=dehtmlify_textarea_text(doc.note),
580370
telechat_date=initial_telechat_date,
581371
returning_item=initial_returning_item,
582372
)
583373

584-
form = EditInfoForm(old_ads=False, initial=init)
374+
form = EditInfoForm(initial=init)
585375

586376
if not has_role(request.user, 'Secretariat'):
587377
# filter out Via RFC Editor

ietf/templates/wgrecord/change_state.html

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
{% extends "base.html" %}
22

3-
{% block title %}Change state of WG {{ wg.acronym }}{% endblock %}
3+
{% block title %}
4+
{% ifequal option "initcharter" %}
5+
Initiate chartering of WG {{ wg.acronym }}
6+
{% else %}
7+
{% ifequal option "recharter" %}
8+
Recharter WG {{ wg.acronym }}
9+
{% else %}
10+
{% ifequal option "abandon" %}
11+
Abandon effort on WG {{ wg.acronym }}
12+
{% else %}
13+
Change state of WG {{ wg.acronym }}
14+
{% endifequal %}
15+
{% endifequal %}
16+
{% endifequal %}
17+
{% endblock %}
418

519
{% block morecss %}
620
form.change-state select {
@@ -19,22 +33,49 @@
1933
{% endblock %}
2034

2135
{% block content %}
22-
<h1>Change state of {{ wg.acronym }}</h1>
36+
<h1>{% ifequal option "initcharter" %}
37+
Initiate chartering of WG {{ wg.acronym }}
38+
{% else %}
39+
{% ifequal option "recharter" %}
40+
Recharter WG {{ wg.acronym }}
41+
{% else %}
42+
{% ifequal option "abandon" %}
43+
Abandon effort on WG {{ wg.acronym }}
44+
{% else %}
45+
Change state of WG {{ wg.acronym }}
46+
{% endifequal %}
47+
{% endifequal %}
48+
{% endifequal %}
49+
</h1>
2350

24-
<p class="helptext">For help on the states, see the <a href="{% url help_charter_states %}">state table</a>.</p>
51+
{% ifnotequal option "initcharter" %}{% ifnotequal option "recharter" %}{% ifnotequal option "abandon" %}<p class="helptext">For help on the states, see the <a href="{% url help_charter_states %}">state table</a>.</p>{% endifnotequal %}{% endifnotequal %}{% endifnotequal %}
2552

2653
<form class="change-state" action="" method="post">
2754
<table>
2855
{% for field in form.visible_fields %}
2956
<tr>
30-
<th>{{ field.label_tag }}:</th>
31-
<td>{{ field }}
57+
{% ifequal field.name "initial_time" %}
58+
{% ifequal option "recharter" %}
59+
<th>{{ field.label_tag }}:</th>
60+
<td>{{ field }}
61+
{% if field.help_text %}<div class="help">{{ field.help_text }}</div>{% endif %}
62+
{% else %}
63+
{% ifequal option "initcharter" %}
64+
<th>{{ field.label_tag }}:</th>
65+
<td>{{ field }}
66+
{% if field.help_text %}<div class="help">{{ field.help_text }}</div>{% endif %}
67+
{% endifequal %}
68+
{% endifequal %}
69+
{% else %}
70+
<th>{{ field.label_tag }}:</th>
71+
<td>{{ field }}
72+
{% if field.help_text %}<div class="help">{{ field.help_text }}</div>{% endif %}
73+
{% endifequal %}
3274
{% ifequal field.name "charter_state" %}
3375
{% ifequal field.errors "warning" %}
34-
<ul><li>The initial review time hasn't elapsed. Proceed anyway? <label><input type="checkbox" name="confirm_state" /></label></li></ul>
76+
<ul><li>The initial review time hasn't elapsed. Select this checkbox to proceed anyway: <label><input type="checkbox" name="confirm_state" /></label></li></ul>
3577
{% endifequal %}
3678
{% endifequal %}
37-
{% if field.help_text %}<div class="help">{{ field.help_text }}</div>{% endif %}
3879
{% ifnotequal field.name "charter_state" %}
3980
{{ field.errors }}
4081
{% endifnotequal %}
@@ -43,8 +84,12 @@ <h1>Change state of {{ wg.acronym }}</h1>
4384
{% endfor %}
4485
<tr>
4586
<td colspan="2" class="actions">
87+
{% if option %}
88+
<input type="submit" value="Submit"/>
89+
{% else %}
4690
<a href="{% url wg_view_record name=wg.acronym %}">Back</a>
4791
<input type="submit" value="Save"/>
92+
{% endif %}
4893
</td>
4994
</tr>
5095
</table>

0 commit comments

Comments
 (0)