From 18f03eb5c63760692ca72b9a7d9d8abed5e31b6b Mon Sep 17 00:00:00 2001 From: sks444 <krishnasingh.ss30@gmail.com> Date: Mon, 20 Jul 2020 16:25:51 +0530 Subject: [PATCH] Implement score field without text box block --- hypha/apply/review/blocks.py | 36 +++++++++++++++++++ hypha/apply/review/forms.py | 9 +++++ .../0023_add_score_without_text_block.py | 26 ++++++++++++++ hypha/apply/review/models.py | 5 +++ hypha/apply/review/options.py | 12 +++++++ 5 files changed, 88 insertions(+) create mode 100644 hypha/apply/review/migrations/0023_add_score_without_text_block.py diff --git a/hypha/apply/review/blocks.py b/hypha/apply/review/blocks.py index 35a4cb38e..8598e5d61 100644 --- a/hypha/apply/review/blocks.py +++ b/hypha/apply/review/blocks.py @@ -12,6 +12,7 @@ from hypha.apply.review.options import ( RATE_CHOICE_NA, RATE_CHOICES_DICT, RECOMMENDATION_CHOICES, + SCORE_CHOICES, VISIBILILTY_HELP_TEXT, VISIBILITY, ) @@ -53,6 +54,40 @@ class ScoreFieldBlock(OptionalFormFieldBlock): return super().render(value, context) +class ScoreFieldWithoutTextBlock(OptionalFormFieldBlock): + """ + There are two ways score could be accepted on reviews. + + One is to use ScoreFieldBlock, where you need to put text answer along with + giving score on the review. + + Second is to use this block to just select a reasonable score with adding + any text as answer. + + This block uses SCORE_CHOICES instead of RATE_CHOICES, only difference is to + have empty string('') in place of NA for text value `n/a - choose not to answer` + as it helps to render this value as default to the forms and also when this field is + required it automatically handles validation on empty string. + """ + name = 'score without text' + field_class = forms.ChoiceField + + class Meta: + icon = 'order' + + def get_field_kwargs(self, struct_value): + kwargs = super().get_field_kwargs(struct_value) + kwargs['choices'] = SCORE_CHOICES + return kwargs + + def render(self, value, context=None): + data = int(context['data']) + choices = dict(SCORE_CHOICES) + context['data'] = choices[data] + + return super().render(value, context) + + class ReviewMustIncludeFieldBlock(MustIncludeFieldBlock): pass @@ -117,6 +152,7 @@ class ReviewCustomFormFieldsBlock(CustomFormFieldsBlock): text = TextFieldBlock(group=_('Fields')) text_markup = RichTextBlock(group=_('Fields'), label=_('Paragraph')) score = ScoreFieldBlock(group=_('Fields')) + score_without_text = ScoreFieldWithoutTextBlock(group=_('Fields')) checkbox = CheckboxFieldBlock(group=_('Fields')) dropdown = DropdownFieldBlock(group=_('Fields')) diff --git a/hypha/apply/review/forms.py b/hypha/apply/review/forms.py index 76b636818..cf9641f0e 100644 --- a/hypha/apply/review/forms.py +++ b/hypha/apply/review/forms.py @@ -89,6 +89,15 @@ class ReviewModelForm(StreamBaseForm, forms.ModelForm, metaclass=MixedMetaClass) score = 0 scores.append(score) + # Check if there are score_fields_without_text and also + # append scores from them. + for field in self.instance.score_fields_without_text: + score = int(data.get(field.id)) + # Include '' answers as 0. + if score == '': + score = 0 + scores.append(score) + try: return sum(scores) / len(scores) except ZeroDivisionError: diff --git a/hypha/apply/review/migrations/0023_add_score_without_text_block.py b/hypha/apply/review/migrations/0023_add_score_without_text_block.py new file mode 100644 index 000000000..d6dccfb47 --- /dev/null +++ b/hypha/apply/review/migrations/0023_add_score_without_text_block.py @@ -0,0 +1,26 @@ +# Generated by Django 2.2.13 on 2020-07-20 10:55 + +from django.db import migrations +import wagtail.core.blocks +import wagtail.core.blocks.static_block +import wagtail.core.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('review', '0022_add_word_limit_to_text_blocks'), + ] + + operations = [ + migrations.AlterField( + model_name='review', + name='form_fields', + field=wagtail.core.fields.StreamField([('rich_text', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.core.blocks.TextBlock(label='Default value', required=False)), ('word_limit', wagtail.core.blocks.IntegerBlock(default=1000, label='Word limit'))], group='Fields')), ('markdown_text', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.core.blocks.TextBlock(label='Default value', required=False)), ('word_limit', wagtail.core.blocks.IntegerBlock(default=1000, label='Word limit'))], group='Fields')), ('char', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False)), ('format', wagtail.core.blocks.ChoiceBlock(choices=[('email', 'Email'), ('url', 'URL')], label='Format', required=False)), ('default_value', wagtail.core.blocks.CharBlock(label='Default value', required=False))], group='Fields')), ('text', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.core.blocks.TextBlock(label='Default value', required=False)), ('word_limit', wagtail.core.blocks.IntegerBlock(default=1000, label='Word limit'))], group='Fields')), ('text_markup', wagtail.core.blocks.RichTextBlock(group='Fields', label='Paragraph')), ('score', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False))], group='Fields')), ('score_without_text', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False))], group='Fields')), ('checkbox', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.core.blocks.BooleanBlock(required=False))], group='Fields')), ('dropdown', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False)), ('choices', wagtail.core.blocks.ListBlock(wagtail.core.blocks.CharBlock(label='Choice')))], group='Fields')), ('recommendation', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('info', wagtail.core.blocks.static_block.StaticBlock())], group=' Required')), ('comments', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('info', wagtail.core.blocks.static_block.StaticBlock())], group=' Required')), ('visibility', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('info', wagtail.core.blocks.static_block.StaticBlock())], group=' Required'))]), + ), + migrations.AlterField( + model_name='reviewform', + name='form_fields', + field=wagtail.core.fields.StreamField([('rich_text', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.core.blocks.TextBlock(label='Default value', required=False)), ('word_limit', wagtail.core.blocks.IntegerBlock(default=1000, label='Word limit'))], group='Fields')), ('markdown_text', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.core.blocks.TextBlock(label='Default value', required=False)), ('word_limit', wagtail.core.blocks.IntegerBlock(default=1000, label='Word limit'))], group='Fields')), ('char', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False)), ('format', wagtail.core.blocks.ChoiceBlock(choices=[('email', 'Email'), ('url', 'URL')], label='Format', required=False)), ('default_value', wagtail.core.blocks.CharBlock(label='Default value', required=False))], group='Fields')), ('text', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.core.blocks.TextBlock(label='Default value', required=False)), ('word_limit', wagtail.core.blocks.IntegerBlock(default=1000, label='Word limit'))], group='Fields')), ('text_markup', wagtail.core.blocks.RichTextBlock(group='Fields', label='Paragraph')), ('score', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False))], group='Fields')), ('score_without_text', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False))], group='Fields')), ('checkbox', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.core.blocks.BooleanBlock(required=False))], group='Fields')), ('dropdown', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.core.blocks.BooleanBlock(label='Required', required=False)), ('choices', wagtail.core.blocks.ListBlock(wagtail.core.blocks.CharBlock(label='Choice')))], group='Fields')), ('recommendation', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('info', wagtail.core.blocks.static_block.StaticBlock())], group=' Required')), ('comments', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('info', wagtail.core.blocks.static_block.StaticBlock())], group=' Required')), ('visibility', wagtail.core.blocks.StructBlock([('field_label', wagtail.core.blocks.CharBlock(label='Label')), ('help_text', wagtail.core.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.core.blocks.URLBlock(label='Help link', required=False)), ('info', wagtail.core.blocks.static_block.StaticBlock())], group=' Required'))]), + ), + ] diff --git a/hypha/apply/review/models.py b/hypha/apply/review/models.py index de821de34..528db5b54 100644 --- a/hypha/apply/review/models.py +++ b/hypha/apply/review/models.py @@ -20,6 +20,7 @@ from .blocks import ( RecommendationCommentsBlock, ReviewCustomFormFieldsBlock, ScoreFieldBlock, + ScoreFieldWithoutTextBlock, VisibilityBlock, ) from .options import ( @@ -46,6 +47,10 @@ class ReviewFormFieldsMixin(models.Model): def score_fields(self): return self._get_field_type(ScoreFieldBlock, many=True) + @property + def score_fields_without_text(self): + return self._get_field_type(ScoreFieldWithoutTextBlock, many=True) + @property def recommendation_field(self): return self._get_field_type(RecommendationBlock) diff --git a/hypha/apply/review/options.py b/hypha/apply/review/options.py index 3bcdde018..7bb125260 100644 --- a/hypha/apply/review/options.py +++ b/hypha/apply/review/options.py @@ -9,6 +9,18 @@ RATE_CHOICES = ( (5, '5. Excellent'), (NA, 'n/a - choose not to answer'), ) + +SCORE_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'), + ('', 'n/a - choose not to answer'), +) + + RATE_CHOICES_DICT = dict(RATE_CHOICES) RATE_CHOICE_NA = RATE_CHOICES_DICT[NA] -- GitLab