Commit cffa623877cdc6db005c531108e33b585a63e890

Authored by Alexis Koralewski
1 parent 67a50452
Exists in dev

fixing who can submit proposal, Add user invitation when editing an SP_Period, r…

…emoved SPForm modification when editing SP_Period
src/core/pyros_django/misc/templates/base.html
@@ -588,7 +588,7 @@ footer{ @@ -588,7 +588,7 @@ footer{
588 <footer class="sticky-footer"> 588 <footer class="sticky-footer">
589 <div> 589 <div>
590 <div class="text-right my-auto"> 590 <div class="text-right my-auto">
591 - <span>VERSION 0.2.4.0_2.0_3.6_2021-10-07</span> 591 + <span>VERSION 0.2.5.0_2.0_3.6_2021-10-08</span>
592 </div> 592 </div>
593 </div> 593 </div>
594 </footer> 594 </footer>
src/core/pyros_django/scientific_program/templates/scientific_program/scientific_program_detail_edit.html
@@ -3,20 +3,18 @@ @@ -3,20 +3,18 @@
3 {% block content %} 3 {% block content %}
4 <form id="editSPForm" action="" method="post"> 4 <form id="editSPForm" action="" method="post">
5 {% csrf_token %} 5 {% csrf_token %}
6 - {% if sp_period.status == "Draft" %}  
7 - {{ SPForm.as_p }}  
8 - {% else %} 6 +
9 {% for field in SPForm %} 7 {% for field in SPForm %}
10 <div class="fieldWrapper"> 8 <div class="fieldWrapper">
11 {{ field.label_tag }} {{ field.value }} 9 {{ field.label_tag }} {{ field.value }}
  10 + {{ field.as_hidden }}
12 </div> 11 </div>
13 {% endfor %} 12 {% endfor %}
14 - {% endif %}  
15 {% if sp_period.status == "Draft" %} 13 {% if sp_period.status == "Draft" %}
16 <p style="color:red;"><strong>This proposal will be automatically submitted for evaluation on {{ sp_period.period.submission_end_date }}</strong> </p> 14 <p style="color:red;"><strong>This proposal will be automatically submitted for evaluation on {{ sp_period.period.submission_end_date }}</strong> </p>
17 {% endif %} 15 {% endif %}
18 - {% if USER_LEVEL|ifinlist:"Unit-PI,Admin,TAC"%}  
19 - {% if sp_period.referee1 != None %} 16 + {% if USER_LEVEL|ifinlist:"Unit-PI,Admin,Unit-board"%}
  17 + {% if sp_period.referee1 != None and sp_period.referee1 == request.user %}
20 <p><strong>vote referee 1: </strong>{{ sp_period.vote_referee1 }} {{ sp_period.reason_referee1 }} by {{ sp_period.referee1.first_name }} {{ sp_period.referee1.last_name}} </p> 18 <p><strong>vote referee 1: </strong>{{ sp_period.vote_referee1 }} {{ sp_period.reason_referee1 }} by {{ sp_period.referee1.first_name }} {{ sp_period.referee1.last_name}} </p>
21 {% endif %} 19 {% endif %}
22 {% if sp_period.referee2 != None %} 20 {% if sp_period.referee2 != None %}
src/core/pyros_django/scientific_program/templates/scientific_program/scientific_program_period_detail.html
@@ -56,7 +56,7 @@ @@ -56,7 +56,7 @@
56 {% if CAN_OBSERVER_EDIT or CAN_TAC_EVALUATE or CAN_UNIT_PI_VALIDATE %} 56 {% if CAN_OBSERVER_EDIT or CAN_TAC_EVALUATE or CAN_UNIT_PI_VALIDATE %}
57 <a href="{% url "edit_scientific_program_period" id_sp=scientific_program.id id_period=sp_period.period.pk %}" class="btn btn-info" role="button">Edit</a> 57 <a href="{% url "edit_scientific_program_period" id_sp=scientific_program.id id_period=sp_period.period.pk %}" class="btn btn-info" role="button">Edit</a>
58 {% endif %} 58 {% endif %}
59 - {% if sp_period.status == "Draft" %} 59 + {% if CAN_SUBMIT_PROPOSAL %}
60 <a href="{% url "submit_proposal" sp_period.id %}" class="btn btn-info" role="button">Submit proposal</a> 60 <a href="{% url "submit_proposal" sp_period.id %}" class="btn btn-info" role="button">Submit proposal</a>
61 {% endif %} 61 {% endif %}
62 {% if CAN_OBSERVER_DELETE %} 62 {% if CAN_OBSERVER_DELETE %}
src/core/pyros_django/scientific_program/views.py
@@ -338,6 +338,10 @@ def list_evaluated_scientific_program(request): @@ -338,6 +338,10 @@ def list_evaluated_scientific_program(request):
338 338
339 @login_required 339 @login_required
340 def accept_sp_invitation(request, id_SP, id_period): 340 def accept_sp_invitation(request, id_SP, id_period):
  341 + """
  342 + An invitation to join an SP is valid until the end of Exploitation period
  343 +
  344 + """
341 sp_period = SP_Period.objects.get(scientific_program=id_SP, period=id_period) 345 sp_period = SP_Period.objects.get(scientific_program=id_SP, period=id_period)
342 current_user = PyrosUser.objects.get(username=request.user) 346 current_user = PyrosUser.objects.get(username=request.user)
343 is_user_guest_of_sp = SP_Period_Guest.objects.filter( 347 is_user_guest_of_sp = SP_Period_Guest.objects.filter(
@@ -365,6 +369,7 @@ def edit_scientific_program_period(request, id_sp, id_period): @@ -365,6 +369,7 @@ def edit_scientific_program_period(request, id_sp, id_period):
365 today = timezone.now().date() 369 today = timezone.now().date()
366 sp_period = SP_Period.objects.get( 370 sp_period = SP_Period.objects.get(
367 scientific_program=scientific_program, period=Period.objects.get(id=id_period)) 371 scientific_program=scientific_program, period=Period.objects.get(id=id_period))
  372 + period=Period.objects.get(id=id_period)
368 SP_Period_form = SP_PeriodForm(request.POST or None, instance=sp_period) 373 SP_Period_form = SP_PeriodForm(request.POST or None, instance=sp_period)
369 sp_pi = scientific_program.sp_pi 374 sp_pi = scientific_program.sp_pi
370 if request.session.get("role") == "Observer" and request.user.id != sp_pi.id: 375 if request.session.get("role") == "Observer" and request.user.id != sp_pi.id:
@@ -376,25 +381,78 @@ def edit_scientific_program_period(request, id_sp, id_period): @@ -376,25 +381,78 @@ def edit_scientific_program_period(request, id_sp, id_period):
376 users_informations = PyrosUser.objects.filter( 381 users_informations = PyrosUser.objects.filter(
377 id__in=user_of_sp.values_list("user", flat=True)) 382 id__in=user_of_sp.values_list("user", flat=True))
378 guests = ",".join(guests) 383 guests = ",".join(guests)
  384 + error = False
  385 + error_message = ""
  386 + list_of_emails = None
  387 + recipient_list = []
379 if request.POST: 388 if request.POST:
380 -  
381 - if SPForm.is_valid() and SP_Period_form.is_valid() and sp_period.status == SP_Period.STATUSES_DRAFT:  
382 - SP = SPForm.save()  
383 - SP_period = SP_Period_form.save()  
384 - if request.POST.getlist("user"):  
385 - for sp_period_user in users_informations:  
386 - if sp_period_user.id not in map(int, request.POST.getlist("user")):  
387 - sp_period_user.delete()  
388 -  
389 - for user in request.POST.getlist("user"):  
390 - user_instance = PyrosUser.objects.get(id=int(user))  
391 - if user_instance not in users_informations:  
392 - SP_Period_User.objects.create(  
393 - SP_Period=sp_period, user=user_instance)  
394 - else:  
395 - SP_Period_User.objects.filter(  
396 - SP_Period=sp_period).delete()  
397 - return redirect('detail_scientific_program_period', id_sp=scientific_program.id, id_period=id_period) 389 + if SP_Period_form.is_valid():
  390 + # can send invitation until the end of exploitation
  391 + if request.POST.get("users") and today < period.end_date:
  392 + # Invite user to join the SP
  393 + regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
  394 + list_of_emails = request.POST.get("users").strip()
  395 +
  396 + for email in list_of_emails.split(","):
  397 + if re.fullmatch(regex, email):
  398 + recipient_list.append(email)
  399 + else:
  400 + error = True
  401 + error_message = f"Invalid mail for {email}"
  402 + if not error:
  403 + domain = settings.DEFAULT_DOMAIN
  404 + url = f"{domain}{reverse('sp_register',args=(scientific_program.pk,sp_period.period.pk))}"
  405 + mail_subject = '[PyROS CC] New registration to an observing proposal'
  406 + mail_message = (f"Hi,\n\nYou were invited to join an observing proposal that as been submitted using PyROS.\n"
  407 + f"The name of the proposal is {scientific_program.name} and his PI is {sp_pi.first_name} {sp_pi.last_name}.\n"
  408 + f"To accept this invitation, click on the following link : {url}\n"
  409 + "You might be asked to login first and will be redirected to the proposal page.\n"
  410 + "If the redirection doesn't work, click again on the link after you've logged in.\n"
  411 + "If you don't own an PyROS account, go on the website in order to create an account with the same mail adress that you are using to read this mail."
  412 + "\n\nCordially,\n\nPyROS Control Center")
  413 + if len(recipient_list) > 0:
  414 + try:
  415 + # Delete previous guests (resetting list of guests)
  416 + SP_Period_Guest.objects.filter(SP_Period=sp_period).delete()
  417 + finally:
  418 + for recipient in recipient_list:
  419 + guest = SP_Period_Guest.objects.create(
  420 + SP_Period=sp_period, email=recipient)
  421 + send_mail(
  422 + mail_subject,
  423 + mail_message,
  424 + from_email=None,
  425 + recipient_list=[recipient],
  426 + fail_silently=False,
  427 + )
  428 + else:
  429 + return render(request, 'scientific_program/scientific_program_detail_edit.html', {
  430 + 'id_sp': id_sp,
  431 + "id_period": id_period,
  432 + "SPForm": SPForm,
  433 + "period": sp_period.period,
  434 + "guests": guests,
  435 + "users_of_sp_period": users_informations,
  436 + "SP_PeriodForm": SP_Period_form,
  437 + "sp_period": sp_period,
  438 + "error_message":error_message
  439 + })
  440 + SP_period = SP_Period_form.save()
  441 + # save changes on user list
  442 + if request.POST.getlist("user"):
  443 + for sp_period_user in users_informations:
  444 + if sp_period_user.id not in map(int, request.POST.getlist("user")):
  445 + sp_period_user.delete()
  446 +
  447 + for user in request.POST.getlist("user"):
  448 + user_instance = PyrosUser.objects.get(id=int(user))
  449 + if user_instance not in users_informations:
  450 + SP_Period_User.objects.create(
  451 + SP_Period=sp_period, user=user_instance)
  452 + else:
  453 + SP_Period_User.objects.filter(
  454 + SP_Period=sp_period).delete()
  455 + return redirect('detail_scientific_program_period', id_sp=scientific_program.id, id_period=id_period)
398 if SP_Period_form.is_valid() and request.session.get("role") == "TAC" and sp_period.status != SP_Period.STATUSES_DRAFT: 456 if SP_Period_form.is_valid() and request.session.get("role") == "TAC" and sp_period.status != SP_Period.STATUSES_DRAFT:
399 # vote TAC 457 # vote TAC
400 if sp_period.referee1 == None or sp_period.referee1 == request.user and request.POST.get("vote_referee1") and request.POST.get("reason_referee1"): 458 if sp_period.referee1 == None or sp_period.referee1 == request.user and request.POST.get("vote_referee1") and request.POST.get("reason_referee1"):
@@ -438,7 +496,8 @@ def edit_scientific_program_period(request, id_sp, id_period): @@ -438,7 +496,8 @@ def edit_scientific_program_period(request, id_sp, id_period):
438 "guests": guests, 496 "guests": guests,
439 "users_of_sp_period": users_informations, 497 "users_of_sp_period": users_informations,
440 "SP_PeriodForm": SP_Period_form, 498 "SP_PeriodForm": SP_Period_form,
441 - "sp_period": sp_period 499 + "sp_period": sp_period,
  500 + "error_message":error_message
442 }) 501 })
443 502
444 503
@@ -493,6 +552,7 @@ def detail_scientific_program_period(request, id_sp, id_period): @@ -493,6 +552,7 @@ def detail_scientific_program_period(request, id_sp, id_period):
493 CAN_UNIT_PI_VALIDATE = request.session.get("role") in ("Unit-PI","Unit-board") and sp_period.status == SP_Period.STATUSES_EVALUATED 552 CAN_UNIT_PI_VALIDATE = request.session.get("role") in ("Unit-PI","Unit-board") and sp_period.status == SP_Period.STATUSES_EVALUATED
494 CAN_OBSERVER_DELETE = request.session.get("role") in ("Admin","Observer") and sp_period.status == SP_Period.STATUSES_DRAFT 553 CAN_OBSERVER_DELETE = request.session.get("role") in ("Admin","Observer") and sp_period.status == SP_Period.STATUSES_DRAFT
495 CAN_VIEW_TAC_VOTES = request.session.get("role") in ("Admin","Unit-PI","Unit-board") 554 CAN_VIEW_TAC_VOTES = request.session.get("role") in ("Admin","Unit-PI","Unit-board")
  555 + CAN_SUBMIT_PROPOSAL = request.user == sp_pi and request.session.get("role") == "Observer" and sp_period.status == SP_Period.STATUSES_DRAFT
496 return render(request, 'scientific_program/scientific_program_period_detail.html', { 556 return render(request, 'scientific_program/scientific_program_period_detail.html', {
497 'scientific_program': scientific_program, 557 'scientific_program': scientific_program,
498 "users": users_informations, 558 "users": users_informations,
@@ -505,7 +565,8 @@ def detail_scientific_program_period(request, id_sp, id_period): @@ -505,7 +565,8 @@ def detail_scientific_program_period(request, id_sp, id_period):
505 "CAN_UNIT_PI_VALIDATE": CAN_UNIT_PI_VALIDATE, 565 "CAN_UNIT_PI_VALIDATE": CAN_UNIT_PI_VALIDATE,
506 "CAN_OBSERVER_DELETE": CAN_OBSERVER_DELETE, 566 "CAN_OBSERVER_DELETE": CAN_OBSERVER_DELETE,
507 "is_proposal": True, 567 "is_proposal": True,
508 - "CAN_VIEW_TAC_VOTES": CAN_VIEW_TAC_VOTES 568 + "CAN_VIEW_TAC_VOTES": CAN_VIEW_TAC_VOTES,
  569 + "CAN_SUBMIT_PROPOSAL": CAN_SUBMIT_PROPOSAL
509 }) 570 })
510 571
511 572