diff --git a/opentech/apply/review/forms.py b/opentech/apply/review/forms.py new file mode 100644 index 0000000000000000000000000000000000000000..ef1b48cf6c22ff78a7c930f4371f26e90569bd34 --- /dev/null +++ b/opentech/apply/review/forms.py @@ -0,0 +1,114 @@ +import json + +from django import forms + +from .models import Review, RECOMMENDATION_CHOICES + + +RATE_CHOICES = ( + (0, '0. Need more info'), + (1, '1. Poor'), + (2, '2. Not so good'), + (3, '3. Is o.k.'), + (4, '4. Good'), + (5, '5. Excellent'), + (99, 'n/a - choose not to answer'), +) + + +class BaseReviewForm(forms.ModelForm): + class Meta: + model = Review + fields: list = [] + + def __init__(self, *args, **kwargs): + self.request = kwargs.pop('request') + self.submission = kwargs.pop('submission') + super().__init__(*args, **kwargs) + + def save(self, *args, **kwargs): + self.instance.submission = self.submission + self.instance.author = self.request.user + self.instance.review = json.dumps(self.cleaned_data) + super().save(*args, **kwargs) + + +class ConceptReviewForm(BaseReviewForm): + recommendation = forms.ChoiceField( + choices=RECOMMENDATION_CHOICES, + label='Overall recommendation', + help_text='Do you recommend requesting a proposal based on this concept note?' + ) + recommendation_comments = forms.CharField( + widget=forms.Textarea(attrs={'rows': 5}), + label='Recommendation comments' + ) + principles = forms.CharField( + widget=forms.Textarea(attrs={'rows': 5}), + label='Goals and principles', + help_text='Does the project contribute and/or have relevance to OTF goals and principles? ' + 'Are the goals and objectives of the project clear? Is it a technology research, development, or deployment project? ' + 'Can project’s effort be explained to external audiences and non-technical people? What problem are they ' + 'trying to solve and is the solution strategical or tactical? Is the project strategically or tactically ' + 'important to OTF’s goals, principles and rationale and other OTF efforts? Is it clear how? What tools, ' + 'if any, currently exist to solve this problem? How is this project different? Does the effort have any ' + 'overlap with existing OTF and/or USG supported projects? Is the overlap complementary or duplicative? ' + 'If complementary, can it be explained clearly? I.e. geographic focus, technology, organization profile, etc. ' + 'What are the liabilities and risks of taking on this project? I.e. political personalities, ' + 'financial concerns, technical controversial, etc. Is the organization or its members known within any relevant ' + 'communities? If yes, what is their reputation and why? What is the entity’s motivation and principles? ' + 'What are the entity member(s) motivations and principles? Where is the organization physically and legally ' + 'based? If the organization is distributed, where is the main point of contact? Does the organization have any ' + 'conflicts of interest with RFA, OTF, the Advisory Council, or other RFA-OTF projects? Is the project team ' + 'an organization, community or an individual?' + ) + + principles_rate = forms.ChoiceField( + choices=RATE_CHOICES, + label='Rate goals and principles' + ) + + technical = forms.CharField( + widget=forms.Textarea(attrs={'rows': 5}), + label='Technical merit', + help_text='Does the project clearly articulate the technical problem, solution, and approach? ' + 'Is the problem clearly justifiable? Does the project clearly articulate the technological objectives? ' + 'Is it an open or closed development project? I.e. Open source like Android or open source like Firefox OS ' + 'or closed like iOS. Does a similar technical solution already exist? If so, what are the differentiating ' + 'factors? Is the effort to sustain an existing technical approach? If so, are these considered successful? ' + 'Is the effort a new technical approach or improvement to an existing solution? If so, how? Is the effort ' + 'a completely new technical approach fostering new solutions in the field? Does the project’s technical ' + 'approach solve the problem? What are the limitations of the project’s technical approach and solution? ' + 'What are the unintended or illicit uses and consequences of this technology? Has the project identified ' + 'and/or developed any safeguards for these consequences?' + ) + technical_rate = forms.ChoiceField( + choices=RATE_CHOICES, + label='Rate technical merit' + ) + + sustainable = forms.CharField( + widget=forms.Textarea(attrs={'rows': 5}), + label='Reasonable and realistic', + help_text='Is the requested amount reasonable, realistic, and justified? Does the project provide a detailed ' + 'and realistic description of effort and schedule? I.e. is the project capable of creating a work plan ' + 'including objectives, activities, and deliverable(s)?' + ) + sustainable_rate = forms.ChoiceField( + choices=RATE_CHOICES, + label='Rate reasonable and realisti' + ) + + comments = forms.CharField( + widget=forms.Textarea(attrs={'rows': 5}), + label='General comments' + ) + + request_questions = forms.CharField( + widget=forms.Textarea(attrs={'rows': 5}), + label='Request specific questions' + ) + + +class ProposalReviewForm(BaseReviewForm): + pass diff --git a/opentech/apply/review/urls.py b/opentech/apply/review/urls.py index 8fa9e91eb5e47c886dc6e7fbb14974439c2a28ec..d9a6f631060c47c75e0650977f4309edd9f3c300 100644 --- a/opentech/apply/review/urls.py +++ b/opentech/apply/review/urls.py @@ -1,10 +1,10 @@ from django.urls import path -from .views import CreateReviewView +from .views import ReviewCreateView app_name = 'reviews' urlpatterns = [ - path('', CreateReviewView.as_view(), name='create'), + path('', ReviewCreateView.as_view(), name='create'), ] diff --git a/opentech/apply/review/views.py b/opentech/apply/review/views.py index fe72183b9754cfbf6cf5b25f0101c9f69d1cd114..6469587b7d9f492c44aee0a74a5e50f0549c0e73 100644 --- a/opentech/apply/review/views.py +++ b/opentech/apply/review/views.py @@ -1,17 +1,29 @@ from django.shortcuts import get_object_or_404 from django.views.generic import CreateView +from django.urls import reverse from opentech.apply.funds.models import ApplicationSubmission +from .forms import ConceptReviewForm from .models import Review -class CreateReviewView(CreateView): +class ReviewCreateView(CreateView): model = Review - fields = ['review'] + form_class = ConceptReviewForm def get_context_data(self, **kwargs): submission = get_object_or_404(ApplicationSubmission, id=self.kwargs['submission_pk']) + return super().get_context_data( submission=submission, **kwargs, ) + + def get_form_kwargs(self): + kwargs = super().get_form_kwargs() + kwargs['request'] = self.request + kwargs['submission'] = get_object_or_404(ApplicationSubmission, id=self.kwargs['submission_pk']) + return kwargs + + def get_success_url(self): + return reverse('apply:submission', args=(self.kwargs['submission_pk'],))