root/trunk/opentrials/repository/views.py @ 1068

Revision 1068, 53.3 kB (checked in by antonio.alves, 23 months ago)

changing mysql specifications

Line 
1# coding: utf-8
2
3try:
4    set
5except:
6    from sets import Set as set
7
8from django.core import serializers
9from django.core.exceptions import ObjectDoesNotExist
10from django.http import HttpResponseRedirect, HttpResponse, Http404
11from django.shortcuts import render_to_response, get_object_or_404
12from django.utils.translation import ugettext_lazy as _
13from django.forms.models import inlineformset_factory
14from django.core.urlresolvers import reverse
15from django.contrib.auth.decorators import login_required
16from django.template import loader
17from django.db.models import Q
18from django.views.generic.list_detail import object_list
19from django.conf import settings
20from django.template.defaultfilters import slugify
21from django.template.context import RequestContext
22from django.contrib.sites.models import Site
23from django.core.paginator import Paginator, InvalidPage, EmptyPage
24from django.contrib import messages
25from django.utils.translation import get_language
26
27from reviewapp.models import Attachment, Submission, Remark
28from reviewapp.models import STATUS_PENDING, STATUS_RESUBMIT, STATUS_DRAFT, STATUS_APPROVED
29from reviewapp.forms import ExistingAttachmentForm,NewAttachmentForm
30from reviewapp.consts import STEP_STATES, REMARK, MISSING, PARTIAL, COMPLETE
31from reviewapp.views import submission_edit_published, send_opentrials_email
32
33from repository.trial_validation import trial_validator
34from repository.models import ClinicalTrial, Descriptor, TrialNumber
35from repository.models import TrialSecondarySponsor, TrialSupportSource, Outcome
36from repository.models import PublicContact, ScientificContact, SiteContact, Contact, Institution
37from repository.models import ClinicalTrialTranslation
38from repository.trds_forms import MultilingualBaseFormSet
39from repository.trds_forms import GeneralHealthDescriptorForm, PrimarySponsorForm
40from repository.trds_forms import SecondaryIdForm, make_secondary_sponsor_form
41from repository.trds_forms import make_support_source_form, TrialIdentificationForm
42from repository.trds_forms import SpecificHealthDescriptorForm, HealthConditionsForm
43from repository.trds_forms import InterventionDescriptorForm, InterventionForm
44from repository.trds_forms import RecruitmentForm, StudyTypeForm, PrimaryOutcomesForm
45from repository.trds_forms import SecondaryOutcomesForm, make_public_contact_form
46from repository.trds_forms import make_scientifc_contact_form, make_contact_form, NewInstitution
47from repository.trds_forms import make_site_contact_form, TRIAL_FORMS
48from vocabulary.models import RecruitmentStatus, VocabularyTranslation, CountryCode, InterventionCode
49from vocabulary.models import StudyPurpose, InterventionAssigment, StudyMasking, StudyAllocation
50from vocabulary.models import MailMessage
51
52from polyglot.multilingual_forms import modelformset_factory
53
54from fossil.fields import DictKeyAttribute
55from fossil.models import Fossil
56
57from utilities import user_in_group
58import datetime
59
60import choices
61import settings
62
63EXTRA_FORMS = 1
64
65MENU_SHORT_TITLE = [_('Trial Identif.'),
66                    _('Spons.'),
67                    _('Health Cond.'),
68                    _('Interv.'),
69                    _('Recruit.'),
70                    _('Study Type'),
71                    _('Outcomes'),
72                    _('Contacts'),
73                    _('Attachs')]
74
75def is_outdate(ct):
76
77    now = datetime.date.today()
78
79    start_planned = ct.enrollment_start_planned
80    end_planned = ct.enrollment_end_planned
81    start_actual = ct.enrollment_start_actual
82    end_actual = ct.enrollment_end_planned
83
84    if start_planned is not None:
85        start_planned = start_planned
86        if start_planned < now and start_actual is None:
87            return True
88               
89    if end_planned is not None:
90        end_planned = end_planned
91        if end_planned < now and end_actual is None:
92            return True
93
94    return False
95
96def check_user_can_edit_trial(func):
97    """
98    Decorator to check if current user has permission to edit a given clinical trial
99    """
100    def _inner(request, trial_pk, *args, **kwargs):
101        request.ct = get_object_or_404(ClinicalTrial, id=int(trial_pk))
102        request.can_change_trial = True
103
104        if request.ct.submission.status == STATUS_APPROVED:
105            request.can_change_trial = False
106            parsed_link = reverse(submission_edit_published, args=[trial_pk])
107            edit_trial_button_string = '<form action="%s"><input type="submit" value="%s"/> </form>' % (parsed_link,unicode(_('Edit Trial')))
108            messages.warning(request, _('This trial cannot be modified because it has already been approved.%s') % edit_trial_button_string)
109
110        # Creator can edit in statuses draft and resubmited but can view on other statuses
111        elif request.user == request.ct.submission.creator:
112            if request.ct.submission.status not in (STATUS_DRAFT, STATUS_RESUBMIT):
113                request.can_change_trial = False
114                messages.warning(request, _('You cannot modify this trial because it is being revised.'))
115
116        elif not request.user.is_staff: # If this is a staff member...
117            request.can_change_trial = False
118            messages.warning(request, _('Only the creator can modify a trial.'))
119
120            # A reviewer in status pending
121            if not( request.ct.submission.status == STATUS_PENDING and
122                    user_in_group(request.user, 'reviewers') ):
123
124                resp = render_to_response(
125                        '403.html',
126                        {'site': Site.objects.get_current()},
127                        context_instance=RequestContext(request),
128                        )
129                resp.status_code = 403
130
131                return resp
132
133        return func(request, trial_pk, *args, **kwargs)
134
135    return _inner
136
137@login_required
138@check_user_can_edit_trial
139def edit_trial_index(request, trial_pk):
140    ct = request.ct
141
142    status = ct.submission.get_status()
143
144    if status in [REMARK, MISSING]:
145        submit = False
146    else:
147        submit = request.can_change_trial
148
149    if request.method == 'POST' and submit:
150        sub = ct.submission
151        sub.status = STATUS_PENDING
152       
153        recepient = ct.submission.creator.email
154        subject = _('Trial Submitted')
155        message =  MailMessage.objects.get(label='submitted').description       
156        if '%s' in message:
157            message = message % ct.public_title
158        send_opentrials_email(subject, message, recepient)
159
160        sub.save()
161        return HttpResponseRedirect(reverse('reviewapp.dashboard'))
162    else:
163        ''' start view '''
164
165        # Changes status from "resubmit" to "draft" if user is the creator
166        sub = ct.submission
167        if sub.status == STATUS_RESUBMIT and request.user == sub.creator:
168            sub.status = STATUS_DRAFT
169            sub.save()
170
171        fields_status = ct.submission.get_fields_status()
172
173        links = []
174        for i, name in enumerate(TRIAL_FORMS):
175            data = dict(label=_(name))
176            data['url'] = reverse('step_' + str(i + 1), args=[trial_pk])
177
178            trans_list = []
179            for lang in ct.submission.get_mandatory_languages():
180                trans = {}
181                lang = lang.lower()
182                step_status = fields_status.get(lang, {}).get(name, None)
183                if step_status == MISSING:
184                    trans['icon'] = settings.MEDIA_URL + 'images/form-status-missing.png'
185                    trans['msg'] = STEP_STATES[MISSING-1][1].title()
186                    trans['leg'] = _("There are required fields missing.")
187                elif step_status == PARTIAL:
188                    trans['icon'] = settings.MEDIA_URL + 'images/form-status-partial.png'
189                    trans['msg'] = STEP_STATES[PARTIAL-1][1].title()
190                    trans['leg'] = _("All required fields were filled.")
191                elif step_status == COMPLETE:
192                    trans['icon'] = settings.MEDIA_URL + 'images/form-status-complete.png'
193                    trans['msg'] = STEP_STATES[COMPLETE-1][1].title()
194                    trans['leg'] = _("All fields were filled.")
195                elif step_status == REMARK:
196                    trans['icon'] = settings.MEDIA_URL + 'images/form-status-remark.png'
197                    trans['msg'] = STEP_STATES[REMARK-1][1].title()
198                    trans['leg'] = _("There are fields with remarks.")
199                else:
200                    trans['icon'] = settings.MEDIA_URL + 'media/img/admin/icon_error.gif'
201                    trans['msg'] = _('Error')
202                    trans['leg'] = _('Error')
203
204                trans_list.append(trans)
205            data['trans'] = trans_list
206            links.append(data)
207
208        status_message = {}
209        if status == REMARK:
210            status_message['icon'] = settings.MEDIA_URL + 'images/form-status-remark.png'
211            status_message['msg'] = _("There are fields with remarks.")
212        elif status == MISSING:
213            status_message['icon'] = settings.MEDIA_URL + 'images/form-status-missing.png'
214            status_message['msg'] = _("There are required fields missing.")
215        elif status == PARTIAL:
216            status_message['icon'] = settings.MEDIA_URL + 'images/form-status-partial.png'
217            status_message['msg'] = _("All required fields were filled.")
218        elif status == COMPLETE:
219            status_message['icon'] = settings.MEDIA_URL + 'images/form-status-complete.png'
220            status_message['msg'] = _("All fields were filled.")
221        else:
222            status_message['icon'] = settings.MEDIA_URL + 'media/img/admin/icon_error.gif'
223            status_message['msg'] = _("Error")
224
225        return render_to_response('repository/trial_index.html',
226                                  {'trial_pk':trial_pk,
227                                   'submission':ct.submission,
228                                   'links':links,
229                                   'status': status,
230                                   'submit': submit,
231                                   'status_message': status_message,},
232                                   context_instance=RequestContext(request))
233
234def full_view(request, trial_pk):
235    ''' full view '''
236    ct = get_object_or_404(ClinicalTrial, id=int(trial_pk))
237    return render_to_response('repository/trds.html',
238                              {'fieldtable':ct.html_dump()},
239                               context_instance=RequestContext(request))
240
241
242def recruiting(request):
243    ''' List all registered trials with recruitment_status = recruiting
244    '''
245    object_list = ClinicalTrial.fossils.recruiting()
246    object_list = object_list.proxies(language=request.LANGUAGE_CODE)
247
248    """
249    recruitments = RecruitmentStatus.objects.filter(label__exact='recruiting')
250    if len(recruitments) > 0:
251        object_list = ClinicalTrial.published.filter(recruitment_status=recruitments[0])
252    else:
253        object_list = None
254
255    for obj in object_list:
256        try:
257            trans = obj.translations.get(language__iexact=request.LANGUAGE_CODE)
258        except ClinicalTrialTranslation.DoesNotExist:
259            trans = None
260
261        if trans:
262            if trans.public_title:
263                obj.public_title = trans.public_title
264            if trans.public_title:
265                obj.scientific_title = trans.scientific_title
266
267        if obj.recruitment_status:
268            try:
269                rec_status_trans = obj.recruitment_status.translations.get(language__iexact=request.LANGUAGE_CODE)
270            except VocabularyTranslation.DoesNotExist:
271                rec_status_trans = obj.recruitment_status
272            obj.rec_status = rec_status_trans.label
273    """
274
275    # pagination
276    paginator = Paginator(object_list, getattr(settings, 'PAGINATOR_CT_PER_PAGE', 10))
277
278    try:
279        page = int(request.GET.get('page', '1'))
280    except ValueError:
281        page = 1
282
283    try:
284        objects = paginator.page(page)
285    except (EmptyPage, InvalidPage):
286        objects = paginator.page(paginator.num_pages)
287
288
289    return render_to_response('repository/clinicaltrial_recruiting.html',
290                              {'objects': objects,
291                               'page': page,
292                               'paginator': paginator},
293                               context_instance=RequestContext(request))
294
295
296def index(request):
297    ''' List all registered trials
298        If you use a search term, the result is filtered
299    '''
300    q = request.GET.get('q', '').strip()
301
302    object_list = ClinicalTrial.fossils.published(q=q)
303    unsubmiteds = Submission.objects.filter(title__icontains=q).filter(Q(status='draft') | Q(status='resubmit')).order_by('-updated')
304   
305    object_list = object_list.proxies(language=request.LANGUAGE_CODE)
306
307    # pagination
308    paginator = Paginator(object_list, getattr(settings, 'PAGINATOR_CT_PER_PAGE', 10))
309
310    try:
311        page = int(request.GET.get('page', '1'))
312    except ValueError:
313        page = 1
314
315    try:
316        objects = paginator.page(page)
317    except (EmptyPage, InvalidPage):
318        objects = paginator.page(paginator.num_pages)
319
320    return render_to_response('repository/clinicaltrial_list.html',
321                              {'objects': objects,
322                               'page': page,
323                               'paginator': paginator,
324                               'q': q,
325                               'unsubmiteds':unsubmiteds,
326                               'outdated_flag':settings.MEDIA_URL + 'media/img/admin/icon_error.gif',
327                               },
328                               context_instance=RequestContext(request))
329
330@login_required
331def trial_view(request, trial_pk):
332    ''' show details of a trial of a user logged '''
333    ct = get_object_or_404(ClinicalTrial, id=int(trial_pk))
334    review_mode = True
335    if not request.user.is_staff and not user_in_group(request.user, 'reviewers'):
336        review_mode = False
337        if request.user != ct.submission.creator:
338            return render_to_response('403.html', {'site': Site.objects.get_current(),},
339                            context_instance=RequestContext(request))
340
341    if review_mode:
342        can_approve = ct.submission.status == STATUS_PENDING and ct.submission.remark_set.exclude(status='closed').count() == 0
343        can_resubmit = ct.submission.status == STATUS_PENDING
344    else:
345        can_approve = False
346        can_resubmit = False
347
348    translations = [t for t in ct.translations.all()]
349    remark_list = []
350    for tf in TRIAL_FORMS:
351         remarks = ct.submission.remark_set.filter(context=slugify(tf))
352         if remarks:
353            remark_list.append(remarks)
354
355    # get translation for recruitment status
356    recruitment_status = ct.recruitment_status
357    if recruitment_status:
358        recruitment_label = recruitment_status.label
359        try:
360            t = VocabularyTranslation.objects.get_translation_for_object(
361                                request.LANGUAGE_CODE.lower(), model=RecruitmentStatus,
362                                object_id=recruitment_status.id)
363            if t.label:
364                recruitment_label = t.label
365        except ObjectDoesNotExist:
366            pass
367    else:
368        recruitment_label = ""
369
370    # get translations for recruitment country
371    recruitment_country = ct.recruitment_country.all()
372    recruitment_country_list = recruitment_country.values('pk', 'description')
373    for obj in recruitment_country_list:
374        try:
375            t = VocabularyTranslation.objects.get_translation_for_object(
376                                request.LANGUAGE_CODE.lower(), model=CountryCode,
377                                object_id=obj['pk'])
378            if t.description:
379                obj['description'] = t.description
380        except ObjectDoesNotExist:
381            pass
382
383    # get translations for scientific contacts country
384    scientific_contacts = ct.scientific_contacts()
385    scientific_contacts_list = scientific_contacts.values('pk', 'firstname', 'middlename',
386                            'lastname', 'address', 'city', 'zip', 'country_id', 'telephone',
387                            'email', 'affiliation__name')
388
389    for obj in scientific_contacts_list:
390        try:
391            country = CountryCode.objects.get(pk=obj['country_id'])
392            obj['country_description'] = country.description
393        except CountryCode.DoesNotExist:
394            obj['country_description'] = ""
395
396        try:
397            t = VocabularyTranslation.objects.get_translation_for_object(
398                                request.LANGUAGE_CODE.lower(), model=CountryCode,
399                                object_id=obj['country_id'])
400            if t.description:
401                obj['country_description'] = t.description
402        except ObjectDoesNotExist:
403            pass
404
405    # get translations for public contacts country
406    public_contacts = ct.public_contacts()
407    public_contacts_list = public_contacts.values('pk', 'firstname', 'middlename',
408                            'lastname', 'address', 'city', 'zip', 'country_id', 'telephone',
409                            'email', 'affiliation__name')
410
411    for obj in public_contacts_list:
412        try:
413            country = CountryCode.objects.get(pk=obj['country_id'])
414            obj['country_description'] = country.description
415        except CountryCode.DoesNotExist:
416            obj['country_description'] = ""
417
418        try:
419            t = VocabularyTranslation.objects.get_translation_for_object(
420                                request.LANGUAGE_CODE.lower(), model=CountryCode,
421                                object_id=obj['country_id'])
422            if t.description:
423                obj['country_description'] = t.description
424        except ObjectDoesNotExist:
425            pass
426
427    # get translations for site contacts country
428    site_contacts = ct.site_contact.all().select_related()
429    site_contacts_list = site_contacts.values('pk', 'firstname', 'middlename',
430                            'lastname', 'address', 'city', 'zip', 'country_id', 'telephone',
431                            'email', 'affiliation__name')
432
433    for obj in site_contacts_list:
434        try:
435            country = CountryCode.objects.get(pk=obj['country_id'])
436            obj['country_description'] = country.description
437        except CountryCode.DoesNotExist:
438            obj['country_description'] = ""
439
440        try:
441            t = VocabularyTranslation.objects.get_translation_for_object(
442                                request.LANGUAGE_CODE.lower(), model=CountryCode,
443                                object_id=obj['country_id'])
444            if t.description:
445                obj['country_description'] = t.description
446        except ObjectDoesNotExist:
447            pass
448
449    enrollment_start_date = ct.enrollment_start_actual if \
450        ct.enrollment_start_actual is not None else ct.enrollment_start_planned
451    enrollment_end_date = ct.enrollment_end_actual if \
452        ct.enrollment_end_actual is not None else ct.enrollment_end_planned
453
454    return render_to_response('repository/clinicaltrial_detail_user.html',
455                                {'object': ct,
456                                'translations': translations,
457                                'host': request.get_host(),
458                                'remark_list': remark_list,
459                                'review_mode': review_mode,
460                                'can_approve': can_approve,
461                                'can_resubmit': can_resubmit,
462                                'languages': get_sorted_languages(request),
463                                'recruitment_label': recruitment_label,
464                                'recruitment_country': recruitment_country_list,
465                                'scientific_contacts': scientific_contacts_list,
466                                'public_contacts': public_contacts_list,
467                                'site_contacts': site_contacts_list,
468                                'enrollment_start_date': enrollment_start_date,
469                                'enrollment_end_date': enrollment_end_date,
470                                },
471                                context_instance=RequestContext(request))
472
473def get_sorted_languages(request):
474    # This just copy managed languages to sorte with main language first
475    languages = [lang.lower() for lang in settings.MANAGED_LANGUAGES]
476    languages.sort(lambda a,b: -1 if a == request.trials_language else cmp(a,b))
477    return languages
478
479def trial_registered(request, trial_fossil_id, trial_version=None):
480    ''' show details of a trial registered '''
481    try:
482        fossil = Fossil.objects.get(pk=trial_fossil_id)
483    except Fossil.DoesNotExist:
484        try:
485            qs = Fossil.objects.indexed(trial_id=trial_fossil_id)
486            if trial_version:
487                fossil = qs.get(revision_sequential=trial_version)
488            else:
489                fossil = qs.get(is_most_recent=True)
490        except Fossil.DoesNotExist:
491            raise Http404
492
493    ct = fossil.get_object_fossil()
494    ct.fossil['language'] = ct.fossil.get('language', settings.DEFAULT_SUBMISSION_LANGUAGE)
495    ct._language = ct.language
496    ct.hash_code = fossil.pk
497    ct.previous_revision = fossil.previous_revision
498    ct.version = fossil.revision_sequential
499
500    translations = [ct.fossil] # the Fossil dictionary must be one of the translations
501    translations.extend(ct.translations)
502    try:
503        scientific_title = [t['scientific_title'] for t in translations
504                if t['language'] == get_language() and t['scientific_title'].strip()][0]
505    except IndexError:
506        scientific_title = ct.scientific_title
507
508    created = datetime.datetime.strptime(ct.fossil['created'], "%Y-%m-%d %H:%M:%S")
509
510    trial = get_object_or_404(ClinicalTrial, trial_id=trial_fossil_id)
511    attachs = [attach for attach in trial.trial_attach() if attach.public]
512   
513    try:
514        time_perspective = trial.time_perspective
515    except ObjectDoesNotExist: 
516        time_perspective = None
517    observational_study_design = trial.observational_study_design
518
519    return render_to_response('repository/clinicaltrial_detail_published.html',
520                                {'object': ct,
521                                'attachs': attachs,
522                                'translations': translations,
523                                'time_perspective':time_perspective,
524                                'observational_study_design':observational_study_design,
525                                'host': request.get_host(),
526                                'fossil_created': created,
527                                'register_number': trial_fossil_id,
528                                'scientific_title': scientific_title,
529                                'languages': get_sorted_languages(request),
530                                'outdated_flag':settings.MEDIA_URL + 'media/img/admin/icon_error.gif',
531                                },
532                                context_instance=RequestContext(request))
533
534@login_required
535def new_institution(request):
536
537    if request.method == 'POST':
538        new_institution = NewInstitution(request.POST)
539        if new_institution.is_valid():
540            institution = new_institution.save(commit=False)
541            institution.creator = request.user
542            institution.save()
543            json = serializers.serialize('json',[institution])
544            return HttpResponse(json, mimetype='application/json')
545        else:
546            return HttpResponse(new_institution.as_table(), mimetype='text/html')
547
548    else:
549        new_institution = NewInstitution()
550
551    return render_to_response('repository/new_institution.html',
552                             {'form':new_institution},
553                               context_instance=RequestContext(request))
554
555@login_required
556def contacts(request):
557    from django import forms
558
559    if request.method == 'POST':
560        if request.POST.get('contact') != '-':
561            contact = Contact.objects.get(pk=request.POST.get('contact'))
562            contact.delete()
563            contact.save()
564   
565    choices = [('-','-----------')] + [(c.pk, c.name()) for c in Contact.objects.filter(creator=request.user)]
566    class ContactsForm(forms.Form):
567        contact = forms.ChoiceField(label=_('Contact'),                                 
568                                  choices=choices,
569                                  )
570   
571    form = ContactsForm()
572
573    return render_to_response('repository/delete_contact.html',
574                             { 'form':form,
575                               'form_title':_('Delete Contact'),
576                               'title':_('Delete Contact'),},
577                               context_instance=RequestContext(request))
578
579
580def step_list(trial_pk):
581    import sys
582    current_step = int( sys._getframe(1).f_code.co_name.replace('step_','') )
583    steps = []
584    for i in range(1,10):
585        steps.append({'link': reverse('step_%d'%i,args=[trial_pk]),
586                      'is_current': (i == current_step),
587                      'name': MENU_SHORT_TITLE[i-1]})
588    return steps
589
590@login_required
591@check_user_can_edit_trial
592def step_1(request, trial_pk):
593    ct = request.ct
594
595    if not request.user.is_staff and not user_in_group(request.user, 'reviewers'):
596        if request.user != ct.submission.creator:
597            return render_to_response('403.html', {'site': Site.objects.get_current(),},
598                            context_instance=RequestContext(request))
599
600    if request.method == 'POST' and request.can_change_trial:
601        form = TrialIdentificationForm(request.POST, instance=ct,
602                                       display_language=request.user.get_profile().preferred_language)
603        SecondaryIdSet = inlineformset_factory(ClinicalTrial, TrialNumber,
604                                               form=SecondaryIdForm,
605                                               extra=EXTRA_FORMS)
606        secondary_forms = SecondaryIdSet(request.POST, instance=ct)
607
608        if form.is_valid() and secondary_forms.is_valid():
609            secondary_forms.save()
610            form.save()
611            return HttpResponseRedirect(reverse('step_1',args=[trial_pk]))
612    else:
613        form = TrialIdentificationForm(instance=ct,
614                                       default_second_language=ct.submission.get_secondary_language(),
615                                       display_language=request.user.get_profile().preferred_language,
616                                       )
617        SecondaryIdSet = inlineformset_factory(ClinicalTrial, TrialNumber,
618                                               form=SecondaryIdForm,
619                                               extra=EXTRA_FORMS, can_delete=True)
620        secondary_forms = SecondaryIdSet(instance=ct)
621
622    forms = [form]
623    formsets = [secondary_forms]
624    return render_to_response('repository/trial_form.html',
625                              {'forms':forms,'formsets':formsets,
626                               'trial_pk':trial_pk,
627                               'title':TRIAL_FORMS[0],
628                               'steps': step_list(trial_pk),
629                               'remarks':Remark.status_open.filter(submission=ct.submission,context=slugify(TRIAL_FORMS[0])),
630                               'default_second_language': ct.submission.get_secondary_language(),
631                               'available_languages': [lang.lower() for lang in ct.submission.get_mandatory_languages()],
632                               },
633                               context_instance=RequestContext(request))
634
635
636@login_required
637@check_user_can_edit_trial
638def step_2(request, trial_pk):
639    ct = request.ct
640
641    if not request.user.is_staff and not user_in_group(request.user, 'reviewers'):
642        if request.user != ct.submission.creator:
643            return render_to_response('403.html', {'site': Site.objects.get_current(),},
644                            context_instance=RequestContext(request))
645
646    qs_primary_sponsor = Institution.objects.filter(creator=request.user).order_by('name')
647
648    if request.method == 'POST' and request.can_change_trial:
649        form = PrimarySponsorForm(request.POST, instance=ct, queryset=qs_primary_sponsor,
650                                  display_language=request.user.get_profile().preferred_language)
651        SecondarySponsorSet = inlineformset_factory(ClinicalTrial, TrialSecondarySponsor,
652                           form=make_secondary_sponsor_form(request.user),extra=EXTRA_FORMS)
653        SupportSourceSet = inlineformset_factory(ClinicalTrial, TrialSupportSource,
654                           form=make_support_source_form(request.user),extra=EXTRA_FORMS)
655
656        secondary_forms = SecondarySponsorSet(request.POST, instance=ct)
657        sources_form = SupportSourceSet(request.POST, instance=ct)
658
659        if form.is_valid() and secondary_forms.is_valid() and sources_form.is_valid():
660            secondary_forms.save()
661            sources_form.save()
662            form.save()
663        return HttpResponseRedirect(reverse('step_2',args=[trial_pk]))
664    else:
665        form = PrimarySponsorForm(instance=ct, queryset=qs_primary_sponsor,
666                                  default_second_language=ct.submission.get_secondary_language(),
667                                  display_language=request.user.get_profile().preferred_language)
668        SecondarySponsorSet = inlineformset_factory(ClinicalTrial, TrialSecondarySponsor,
669            form=make_secondary_sponsor_form(request.user),extra=EXTRA_FORMS, can_delete=True)
670        SupportSourceSet = inlineformset_factory(ClinicalTrial, TrialSupportSource,
671               form=make_support_source_form(request.user),extra=EXTRA_FORMS,can_delete=True)
672
673        secondary_forms = SecondarySponsorSet(instance=ct)
674        sources_form = SupportSourceSet(instance=ct)
675
676    forms = [form]
677    formsets = [secondary_forms,sources_form]
678    return render_to_response('repository/step_2.html',
679                              {'forms':forms,'formsets':formsets,
680                               'trial_pk':trial_pk,
681                               'title':TRIAL_FORMS[1],
682                               'steps': step_list(trial_pk),
683                               'remarks':Remark.status_open.filter(submission=ct.submission,context=slugify(TRIAL_FORMS[1])),
684                               'default_second_language': ct.submission.get_secondary_language(),
685                               'available_languages': [lang.lower() for lang in ct.submission.get_mandatory_languages()],},
686                               context_instance=RequestContext(request))
687
688
689@login_required
690@check_user_can_edit_trial
691def step_3(request, trial_pk):
692    ct = request.ct
693
694    if not request.user.is_staff and not user_in_group(request.user, 'reviewers'):
695        if request.user != ct.submission.creator:
696            return render_to_response('403.html', {'site': Site.objects.get_current(),},
697                            context_instance=RequestContext(request))
698
699    GeneralDescriptorSet = modelformset_factory(Descriptor,
700                                                formset=MultilingualBaseFormSet,
701                                                form=GeneralHealthDescriptorForm,
702                                                can_delete=True,
703                                                extra=EXTRA_FORMS,
704                                                extra_formset_attrs={
705                                                    'default_second_language':ct.submission.get_secondary_language(),
706                                                    'available_languages':[lang.lower() for lang in ct.submission.get_mandatory_languages()],
707                                                    'display_language':request.user.get_profile().preferred_language,
708                                                    },
709                                                )
710
711    SpecificDescriptorSet = modelformset_factory(Descriptor,
712                                                formset=MultilingualBaseFormSet,
713                                                form=SpecificHealthDescriptorForm,
714                                                can_delete=True,
715                                                extra=EXTRA_FORMS,
716                                                extra_formset_attrs={
717                                                    'default_second_language':ct.submission.get_secondary_language(),
718                                                    'available_languages':[lang.lower() for lang in ct.submission.get_mandatory_languages()],
719                                                    'display_language':request.user.get_profile().preferred_language,
720                                                    },
721                                                )
722
723    general_qs = Descriptor.objects.filter(trial=trial_pk,
724                                           aspect=choices.TRIAL_ASPECT[0][0],
725                                           level=choices.DESCRIPTOR_LEVEL[0][0])
726
727    specific_qs = Descriptor.objects.filter(trial=trial_pk,
728                                           aspect=choices.TRIAL_ASPECT[0][0],
729                                           level=choices.DESCRIPTOR_LEVEL[1][0])
730
731    if request.method == 'POST' and request.can_change_trial:
732        form = HealthConditionsForm(request.POST, instance=ct,
733                                    display_language=request.user.get_profile().preferred_language)
734        general_desc_formset = GeneralDescriptorSet(request.POST,queryset=general_qs,prefix='g')
735        specific_desc_formset = SpecificDescriptorSet(request.POST,queryset=specific_qs,prefix='s')
736
737        if form.is_valid() and general_desc_formset.is_valid() and specific_desc_formset.is_valid():
738            descriptors = general_desc_formset.save(commit=False)
739            descriptors += specific_desc_formset.save(commit=False)
740
741
742            for descriptor in descriptors:
743                descriptor.trial = ct
744
745            general_desc_formset.save()
746            specific_desc_formset.save()
747            form.save()
748
749            return HttpResponseRedirect(reverse('step_3',args=[trial_pk]))
750    else:
751        form = HealthConditionsForm(instance=ct,
752                                    default_second_language=ct.submission.get_secondary_language(),
753                                    display_language=request.user.get_profile().preferred_language)
754        general_desc_formset = GeneralDescriptorSet(queryset=general_qs,prefix='g')
755        specific_desc_formset = SpecificDescriptorSet(queryset=specific_qs,prefix='s')
756
757
758    forms = [form]
759    formsets = [general_desc_formset, specific_desc_formset]
760    return render_to_response('repository/step_3.html',
761                              {'forms':forms,'formsets':formsets,
762                               'trial_pk':trial_pk,
763                               'title':TRIAL_FORMS[2],
764                               'steps': step_list(trial_pk),
765                               'remarks':Remark.status_open.filter(submission=ct.submission,context=slugify(TRIAL_FORMS[2])),
766                               'default_second_language': ct.submission.get_secondary_language(),
767                               'available_languages': [lang.lower() for lang in ct.submission.get_mandatory_languages()],},
768                               context_instance=RequestContext(request))
769
770
771@login_required
772@check_user_can_edit_trial
773def step_4(request, trial_pk):
774    ct = request.ct
775
776    if not request.user.is_staff and not user_in_group(request.user, 'reviewers'):
777        if request.user != ct.submission.creator:
778            return render_to_response('403.html', {'site': Site.objects.get_current(),},
779                            context_instance=RequestContext(request))
780
781    DescriptorFormSet = modelformset_factory(Descriptor,
782                                          formset=MultilingualBaseFormSet,
783                                          form=InterventionDescriptorForm,
784                                          can_delete=True,
785                                          extra=EXTRA_FORMS,
786                                          extra_formset_attrs={
787                                            'default_second_language':ct.submission.get_secondary_language(),
788                                            'available_languages':[lang.lower() for lang in ct.submission.get_mandatory_languages()],
789                                            'display_language':request.user.get_profile().preferred_language,
790                                            },
791                                          )
792
793    queryset = Descriptor.objects.filter(trial=trial_pk,
794                                           aspect=choices.TRIAL_ASPECT[1][0],
795                                           level=choices.DESCRIPTOR_LEVEL[0][0])
796    if request.method == 'POST' and request.can_change_trial:
797        form = InterventionForm(request.POST, instance=ct,
798                                display_language=request.user.get_profile().preferred_language)
799        specific_desc_formset = DescriptorFormSet(request.POST, queryset=queryset)
800
801        if form.is_valid() and specific_desc_formset.is_valid():
802            descriptors = specific_desc_formset.save(commit=False)
803
804
805            for descriptor in descriptors:
806                descriptor.trial = ct
807
808            specific_desc_formset.save()
809            form.save()
810            return HttpResponseRedirect(reverse('step_4',args=[trial_pk]))
811    else:
812        form = InterventionForm(instance=ct,
813                                default_second_language=ct.submission.get_secondary_language(),
814                                display_language=request.trials_language)
815        specific_desc_formset = DescriptorFormSet(queryset=queryset)
816
817    forms = [form]
818    formsets = [specific_desc_formset]
819    return render_to_response('repository/step_4.html',
820                              {'forms':forms,'formsets':formsets,
821                               'trial_pk':trial_pk,
822                               'title':TRIAL_FORMS[3],
823                               'steps': step_list(trial_pk),
824                               'remarks':Remark.status_open.filter(submission=ct.submission,context=slugify(TRIAL_FORMS[3])),
825                               'default_second_language': ct.submission.get_secondary_language(),
826                               'available_languages': [lang.lower() for lang in ct.submission.get_mandatory_languages()],},
827                               context_instance=RequestContext(request))
828
829
830@login_required
831@check_user_can_edit_trial
832def step_5(request, trial_pk):
833    ct = request.ct
834
835    if not request.user.is_staff and not user_in_group(request.user, 'reviewers'):
836        if request.user != ct.submission.creator:
837            return render_to_response('403.html', {'site': Site.objects.get_current(),},
838                            context_instance=RequestContext(request))
839
840    if request.method == 'POST' and request.can_change_trial:
841        form = RecruitmentForm(request.POST, instance=ct,
842                               display_language=request.user.get_profile().preferred_language)
843
844        if form.is_valid():
845            form.save()
846
847            ct.outdated = is_outdate(ct)
848            ct.save()
849            return HttpResponseRedirect(reverse('step_5',args=[trial_pk]))
850    else:
851        form = RecruitmentForm(instance=ct,
852                               default_second_language=ct.submission.get_secondary_language(),
853                               display_language=request.trials_language)
854
855    forms = [form]
856
857    return render_to_response('repository/trial_form.html',
858                              {'forms':forms,
859                               'trial_pk':trial_pk,
860                               'title':TRIAL_FORMS[4],
861                               'steps': step_list(trial_pk),
862                               'remarks':Remark.status_open.filter(submission=ct.submission,context=slugify(TRIAL_FORMS[4])),
863                               'default_second_language': ct.submission.get_secondary_language(),
864                               'available_languages': [lang.lower() for lang in ct.submission.get_mandatory_languages()],
865                               },
866                               context_instance=RequestContext(request))
867
868
869@login_required
870@check_user_can_edit_trial
871def step_6(request, trial_pk):
872    ct = request.ct
873
874    if not request.user.is_staff and not user_in_group(request.user, 'reviewers'):
875        if request.user != ct.submission.creator:
876            return render_to_response('403.html', {'site': Site.objects.get_current(),},
877                            context_instance=RequestContext(request))
878
879    if request.method == 'POST' and request.can_change_trial:
880        form = StudyTypeForm(request.POST, instance=ct,
881                             display_language=request.user.get_profile().preferred_language)
882
883        if form.is_valid():
884            form.save()
885            return HttpResponseRedirect(reverse('step_6',args=[trial_pk]))
886    else:
887        form = StudyTypeForm(instance=ct,
888                             default_second_language=ct.submission.get_secondary_language(),
889                             display_language=request.trials_language)
890
891    forms = [form]
892    return render_to_response('repository/trial_form.html',
893                              {'forms':forms,
894                               'trial_pk':trial_pk,
895                               'title':TRIAL_FORMS[5],
896                               'steps': step_list(trial_pk),
897                               'remarks':Remark.status_open.filter(submission=ct.submission,context=slugify(TRIAL_FORMS[5])),
898                               'default_second_language': ct.submission.get_secondary_language(),
899                               'available_languages': [lang.lower() for lang in ct.submission.get_mandatory_languages()],},
900                               context_instance=RequestContext(request))
901
902
903@login_required
904@check_user_can_edit_trial
905def step_7(request, trial_pk):
906    ct = request.ct
907
908    if not request.user.is_staff and not user_in_group(request.user, 'reviewers'):
909        if request.user != ct.submission.creator:
910            return render_to_response('403.html', {'site': Site.objects.get_current(),},
911                            context_instance=RequestContext(request))
912
913    PrimaryOutcomesSet = modelformset_factory( Outcome,
914                                formset=MultilingualBaseFormSet,
915                                form=PrimaryOutcomesForm,extra=EXTRA_FORMS,
916                                can_delete=True,
917                                extra_formset_attrs={
918                                    'default_second_language':ct.submission.get_secondary_language(),
919                                    'available_languages':[lang.lower() for lang in ct.submission.get_mandatory_languages()],
920                                    'display_language':request.user.get_profile().preferred_language,
921                                    },
922                                )
923    SecondaryOutcomesSet = modelformset_factory(Outcome,
924                                formset=MultilingualBaseFormSet,
925                                form=SecondaryOutcomesForm,extra=EXTRA_FORMS,
926                                can_delete=True,
927                                extra_formset_attrs={
928                                    'default_second_language':ct.submission.get_secondary_language(),
929                                    'available_languages':[lang.lower() for lang in ct.submission.get_mandatory_languages()],
930                                    'display_language':request.user.get_profile().preferred_language,
931                                    },
932                                )
933
934    primary_qs = Outcome.objects.filter(trial=ct, interest=choices.OUTCOME_INTEREST[0][0])
935    secondary_qs = Outcome.objects.filter(trial=ct, interest=choices.OUTCOME_INTEREST[1][0])
936
937    if request.method == 'POST' and request.can_change_trial:
938        primary_outcomes_formset = PrimaryOutcomesSet(request.POST, queryset=primary_qs, prefix='primary')
939        secondary_outcomes_formset = SecondaryOutcomesSet(request.POST, queryset=secondary_qs, prefix='secondary')
940
941        if primary_outcomes_formset.is_valid() and secondary_outcomes_formset.is_valid():
942            outcomes = primary_outcomes_formset.save(commit=False)
943            outcomes += secondary_outcomes_formset.save(commit=False)
944
945            for outcome in outcomes:
946                outcome.trial = ct
947
948            primary_outcomes_formset.save()
949            secondary_outcomes_formset.save()
950
951            # Executes validation of current trial submission (for mandatory fields)
952            trial_validator.validate(ct)
953
954            return HttpResponseRedirect(reverse('step_7',args=[trial_pk]))
955    else:
956        primary_outcomes_formset = PrimaryOutcomesSet(queryset=primary_qs, prefix='primary')
957        secondary_outcomes_formset = SecondaryOutcomesSet(queryset=secondary_qs, prefix='secondary')
958
959    formsets = [primary_outcomes_formset,secondary_outcomes_formset]
960    return render_to_response('repository/trial_form.html',
961                              {'formsets':formsets,
962                               'trial_pk':trial_pk,
963                               'title':TRIAL_FORMS[6],
964                               'steps': step_list(trial_pk),
965                               'remarks':Remark.status_open.filter(submission=ct.submission,context=slugify(TRIAL_FORMS[6])),
966                               'default_second_language': ct.submission.get_secondary_language(),
967                               'available_languages': [lang.lower() for lang in ct.submission.get_mandatory_languages()],},
968                               context_instance=RequestContext(request))
969
970
971@login_required
972@check_user_can_edit_trial
973def step_8(request, trial_pk):
974    ct = request.ct
975
976    if not request.user.is_staff and not user_in_group(request.user, 'reviewers'):
977        if request.user != ct.submission.creator:
978            return render_to_response('403.html', {'site': Site.objects.get_current(),},
979                            context_instance=RequestContext(request))
980
981    contact_type = {
982        'PublicContact': (PublicContact,make_public_contact_form(request.user)),
983        'ScientificContact': (ScientificContact,make_scientifc_contact_form(request.user)),
984        'SiteContact': (SiteContact,make_site_contact_form(request.user))
985    }
986
987    InlineFormSetClasses = []
988    for model,form in contact_type.values():
989        InlineFormSetClasses.append(
990            inlineformset_factory(ClinicalTrial,model,form=form,can_delete=True,extra=EXTRA_FORMS)
991        )
992
993    ContactFormSet = modelformset_factory(Contact,
994                                          form=make_contact_form(request.user,formset_prefix='new_contact'),
995                                          extra=1)
996
997    contact_qs = Contact.objects.none()
998
999    if request.method == 'POST' and request.can_change_trial:
1000        inlineformsets = [fs(request.POST,instance=ct) for fs in InlineFormSetClasses]
1001        new_contact_formset = ContactFormSet(request.POST,queryset=contact_qs,prefix='new_contact')
1002
1003        if not False in [fs.is_valid() for fs in inlineformsets] \
1004                and new_contact_formset.is_valid():
1005
1006            for contactform in new_contact_formset.forms:
1007                if contactform.cleaned_data:
1008                    Relation = contact_type[contactform.cleaned_data.pop('relation')][0]
1009                    new_contact = contactform.save(commit=False)
1010                    new_contact.creator = request.user
1011                    new_contact.save()
1012                    Relation.objects.create(trial=ct,contact=new_contact)
1013
1014            for fs in inlineformsets:
1015                fs.save()
1016
1017            # Executes validation of current trial submission (for mandatory fields)
1018            trial_validator.validate(ct)
1019
1020            return HttpResponseRedirect(reverse('step_8',args=[trial_pk]))
1021    else:
1022        inlineformsets = [fs(instance=ct) for fs in InlineFormSetClasses]
1023        new_contact_formset = ContactFormSet(queryset=contact_qs,prefix='new_contact')
1024
1025    formsets = inlineformsets + [new_contact_formset]
1026    return render_to_response('repository/step_8.html',
1027                              {'formsets':formsets,
1028                               'trial_pk':trial_pk,
1029                               'title':TRIAL_FORMS[7],
1030                               'steps': step_list(trial_pk),
1031                               'remarks':Remark.status_open.filter(submission=ct.submission,context=slugify(TRIAL_FORMS[7])),
1032                               'default_second_language': ct.submission.get_secondary_language(),
1033                               'available_languages': [lang.lower() for lang in ct.submission.get_mandatory_languages()],},
1034                               context_instance=RequestContext(request))
1035
1036@login_required
1037@check_user_can_edit_trial
1038def step_9(request, trial_pk):
1039    # TODO: this function should be on another place
1040    ct = request.ct
1041
1042    if not request.user.is_staff and not user_in_group(request.user, 'reviewers'):
1043        if request.user != ct.submission.creator:
1044            return render_to_response('403.html', {'site': Site.objects.get_current(),},
1045                            context_instance=RequestContext(request))
1046
1047    su = Submission.objects.get(trial=ct)
1048
1049    NewAttachmentFormSet = modelformset_factory(Attachment,
1050                                             extra=1,
1051                                             can_delete=False,
1052                                             form=NewAttachmentForm)
1053
1054    existing_attachments = Attachment.objects.filter(submission=su)
1055   
1056    if request.method == 'POST' and request.can_change_trial:
1057
1058        if 'remove' in request.POST:
1059            attach = Attachment.objects.get(id=request.POST.get('remove'))
1060            attach.delete()
1061
1062            return HttpResponseRedirect(reverse('step_9',args=[trial_pk]))
1063
1064        else:
1065
1066            new_attachment_formset = NewAttachmentFormSet(request.POST,
1067                                                          request.FILES,
1068                                                          prefix='new')
1069
1070            if new_attachment_formset.is_valid():
1071                new_attachments = new_attachment_formset.save(commit=False)
1072
1073                for attachment in new_attachments:
1074                    attachment.submission = su
1075
1076                new_attachment_formset.save()
1077                return HttpResponseRedirect(reverse('step_9',args=[trial_pk]))
1078
1079    else:
1080        new_attachment_formset = NewAttachmentFormSet(queryset=Attachment.objects.none(),
1081                                                      prefix='new')
1082
1083    formsets = [new_attachment_formset]
1084
1085    return render_to_response('repository/attachments.html',
1086                              {'formsets':formsets,
1087                               'existing_attachments':existing_attachments,
1088                               'trial_pk':trial_pk,
1089                               'title':TRIAL_FORMS[8],
1090                               'host': request.get_host(),
1091                               'steps': step_list(trial_pk),
1092                               'remarks':Remark.status_open.filter(submission=ct.submission,context=slugify(TRIAL_FORMS[8])),
1093                               'default_second_language': ct.submission.get_secondary_language(),
1094                               'available_languages': [lang.lower() for lang in ct.submission.get_mandatory_languages()],},
1095                               context_instance=RequestContext(request))
1096
1097from repository.xml.generate import xml_ictrp, xml_opentrials
1098
1099def trial_ictrp(request, trial_fossil_id, trial_version=None):
1100    """
1101    Returns a XML content structured on ICTRP standard, you can find more details
1102    about it on:
1103
1104    - http://reddes.bvsalud.org/projects/clinical-trials/wiki/RegistrationDataModel
1105    - http://reddes.bvsalud.org/projects/clinical-trials/attachment/wiki/RegistrationDataModel/who_ictrp_dtd.txt
1106    - http://reddes.bvsalud.org/projects/clinical-trials/attachment/wiki/RegistrationDataModel/ICTRP%20Data%20format%201.1%20.doc
1107    - http://reddes.bvsalud.org/projects/clinical-trials/attachment/wiki/RegistrationDataModel/xmlsample.xml
1108    - http://reddes.bvsalud.org/projects/clinical-trials/attachment/wiki/RegistrationDataModel/ICTRPTrials.xml
1109    """
1110
1111    try:
1112        fossil = Fossil.objects.get(pk=trial_fossil_id)
1113    except Fossil.DoesNotExist:
1114        try:
1115            qs = Fossil.objects.indexed(trial_id=trial_fossil_id)
1116            if trial_version:
1117                fossil = qs.get(revision_sequential=trial_version)
1118            else:
1119                fossil = qs.get(is_most_recent=True)
1120        except Fossil.DoesNotExist:
1121            raise Http404
1122
1123    ct = fossil.get_object_fossil()
1124    xml = xml_ictrp([fossil])
1125
1126    resp = HttpResponse(xml,
1127            mimetype = 'text/xml'
1128            )
1129
1130    resp['Content-Disposition'] = 'attachment; filename=%s-ictrp.xml' % ct.trial_id
1131
1132    return resp
1133
1134def all_trials_ictrp(request):
1135
1136    trials = ClinicalTrial.fossils.published()
1137    xml = xml_ictrp(trials)
1138
1139    resp = HttpResponse(xml,
1140            mimetype = 'text/xml'
1141            )
1142
1143    resp['Content-Disposition'] = 'attachment; filename=%s-ictrp.xml' % settings.TRIAL_ID_PREFIX
1144
1145    return resp
1146
1147
1148def trial_otxml(request, trial_fossil_id, trial_version=None):
1149    """
1150    Returns a XML content structured on OpenTrials standard, you can find more details
1151    about it on:
1152
1153    - ToDo
1154    """
1155   
1156    try:
1157        fossil = Fossil.objects.get(pk=trial_fossil_id)
1158    except Fossil.DoesNotExist:
1159        try:
1160            qs = Fossil.objects.indexed(trial_id=trial_fossil_id)
1161            if trial_version:
1162                fossil = qs.get(revision_sequential=trial_version)
1163            else:
1164                fossil = qs.get(is_most_recent=True)
1165        except Fossil.DoesNotExist:
1166            raise Http404
1167
1168    ct = fossil.get_object_fossil()
1169    ct.hash_code = fossil.pk
1170    ct.previous_revision = fossil.previous_revision
1171    ct.version = fossil.revision_sequential
1172    ct.status = fossil.indexers.key('status', fail_silent=True).value
1173
1174    persons = set(ct.scientific_contact + ct.public_contact + ct.site_contact)
1175
1176    xml = xml_opentrials(ct, persons)
1177
1178    resp = HttpResponse(xml,
1179            mimetype = 'text/xml'
1180            )
1181
1182    resp['Content-Disposition'] = 'attachment; filename=%s-ot.xml' % ct.trial_id
1183
1184    return resp
Note: See TracBrowser for help on using the browser.