Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
63822bc
Database model changes & migrations while preparing for member registry
tuomas2 May 24, 2017
6122d03
Merge branch 'master' into member_registry
tuomas2 May 24, 2017
77aa293
Merge branch 'master' into member_registry
tuomas2 May 24, 2017
56e1511
Move Participation from models.people to models.participation
tuomas2 May 25, 2017
fdd5176
Remove ContactDetailsMixin classes
tuomas2 May 25, 2017
4cef5bb
Fix imports
tuomas2 May 25, 2017
2508978
Fix imports and others
tuomas2 May 25, 2017
1e10299
Copy PasswordMixin content to Member
tuomas2 May 25, 2017
70d214a
Migrate auth keys
tuomas2 May 25, 2017
0a9b04e
Remove PasswordMixin from Participation
tuomas2 May 25, 2017
9c98b5e
Code fixes to Member vs Participation changes
tuomas2 May 25, 2017
8e86ea8
Code fixes to Member vs Participation changes
tuomas2 May 25, 2017
73f789f
Allow emails booleanfields in Member
tuomas2 May 25, 2017
03afaf4
Remove PasswordMixing etc.
tuomas2 May 25, 2017
ab28015
Add Members to Organization in admin
tuomas2 May 25, 2017
af8f545
Rename member related fields
tuomas2 May 25, 2017
392cfc3
Some refactoring
tuomas2 May 25, 2017
cbfda2b
Some work on participation login but I'll leave it alone now for a wh…
tuomas2 May 25, 2017
4b1d969
Fix admin
tuomas2 May 25, 2017
c6b5b61
Fix reports / all responsibles view. Cache responsibles.
tuomas2 May 26, 2017
aa3597c
Fix reports / all participations view
tuomas2 May 26, 2017
08c3616
Set up DEBUG logging to templates
tuomas2 May 26, 2017
2436972
Fix all questions view
tuomas2 May 26, 2017
84e3663
Question.id_display
tuomas2 May 26, 2017
64dcd93
Move stuff from SubitemMixin to AbstractServiceFormItem
tuomas2 May 26, 2017
3c494b7
Generalize responsibles between Serviceform items + Serviceform
tuomas2 May 26, 2017
cdd6acc
Generalize skip_numbering also to be common to all Serviceform items
tuomas2 May 26, 2017
61b918d
Fix reports / view responsible
tuomas2 May 26, 2017
9743cec
Merge branch 'master' into member_registry
tuomas2 May 26, 2017
96d8adb
Merge branch 'master' into member_registry
tuomas2 May 26, 2017
f6c78a3
Helper properties for responsibles in subitems
tuomas2 May 28, 2017
9a77bf3
Start working with participation views
tuomas2 May 29, 2017
5cf5109
Merge branch 'master' into member_registry
tuomas2 May 30, 2017
7807c3f
Merge branch 'master' into member_registry
tuomas2 May 30, 2017
cd9242c
Merge branch 'master' into member_registry
tuomas2 May 31, 2017
fad6b05
Fix django debug toolbar
tuomas2 May 31, 2017
e091748
Fix django debug toolbar
tuomas2 May 31, 2017
28e44a6
Add wiki to .gitignore
tuomas2 Jun 1, 2017
6aea537
Fix reports
tuomas2 Jun 1, 2017
e4792ef
Update test data
tuomas2 Jun 1, 2017
c650ba4
Disable participation tests
tuomas2 Jun 1, 2017
6066238
Fix Serviceform.create_initial_data
tuomas2 Jun 1, 2017
d6ba6a4
Fix test runner settings (template loading)
tuomas2 Jun 1, 2017
c84e6a8
Test fixes
tuomas2 Jun 1, 2017
1baafaf
Merge branch 'master' into member_registry
tuomas2 Jun 1, 2017
77ace0d
Empty commit [skip ci]
tuomas2 Jun 1, 2017
864bf33
Contact detail page
tuomas2 Jun 2, 2017
a0cf05b
Merge branch 'master' into member_registry
tuomas2 Jun 2, 2017
0adf7e6
Contact details page + email verification
tuomas2 Jun 2, 2017
d1f0309
Authentication/email verification re-organizing
tuomas2 Jun 2, 2017
9730940
Authentication stuff etc.
tuomas2 Jun 9, 2017
22cc82d
Rename serviceform decorator to require_serviceform
tuomas2 Jun 9, 2017
f9d6f1e
Participation flow now works again
tuomas2 Jun 9, 2017
f3a260f
Updating participation now works as well.
tuomas2 Jun 9, 2017
6519e3e
Contact view now works ok (creation / updating)
tuomas2 Jun 9, 2017
ccc4b45
Move migrations temporarily to migrations_
tuomas2 Jun 9, 2017
14cb68b
Create fresh migration file for serviceform, for tests.
tuomas2 Jun 9, 2017
aaafc03
Fixes to tests
tuomas2 Jun 9, 2017
b28e019
Fixes to tests
tuomas2 Jun 9, 2017
538e906
Test fixing continues
tuomas2 Jun 11, 2017
2e68466
Make EmailTemplates per-organization rather than per-form
tuomas2 Jun 11, 2017
ded5546
Add member auth link email to Organization
tuomas2 Jun 11, 2017
dcb4487
Merge branch 'master' into feature/member_registry
tuomas2 Jun 16, 2017
5460eff
Add version information to serviceform package
tuomas2 Jun 16, 2017
085d60c
Update test data
tuomas2 Jun 16, 2017
ab0bee9
Continue fixing tests
tuomas2 Jun 16, 2017
0891236
Fix authenticate_member_mock
tuomas2 Jun 16, 2017
906cf91
Create stub for member_main page
tuomas2 Jun 16, 2017
a7337c9
Fix more tests
tuomas2 Jun 16, 2017
65c0af4
Fix more tests
tuomas2 Jun 16, 2017
be32afb
More test fixing.
tuomas2 Jun 16, 2017
88aa18c
Pass serviceform explicitly to _get_ident (do not rely on request.ser…
tuomas2 Jun 20, 2017
8899344
Fix client fixtures (make them distinct from each other)
tuomas2 Jun 20, 2017
a2b03ff
Re-enable emailing time tests
tuomas2 Jun 20, 2017
f4ea4f7
Fix auth email sending from login page
tuomas2 Jun 20, 2017
f609e0c
Fix invite
tuomas2 Jun 20, 2017
d6e50fe
Fixed the rest of broken tests
tuomas2 Jun 20, 2017
7f8b377
Fix version complaint
tuomas2 Jun 20, 2017
50ba05e
Fix docker building
tuomas2 Jun 20, 2017
6b8b5ad
Try to fix travis test building
tuomas2 Jun 20, 2017
7e03457
Upgrade requirements
tuomas2 Jun 30, 2017
2369617
Try to fix travis building
tuomas2 Jun 30, 2017
fa4417a
Fix EmailTemplate visibility in OrganizationAdmin. Also fix Organizat…
tuomas2 Jun 30, 2017
69df8f1
Remove NameDescriptionMixin
tuomas2 Jun 30, 2017
74ca30e
Improve OrganizationAdmin
tuomas2 Jun 30, 2017
00aa4fd
Remove some TODOs
tuomas2 Jun 30, 2017
1d1d5ae
Merge branch 'master' into feature/member_registry
tuomas2 Jul 2, 2017
edafe9d
Merge branch 'master' into feature/member_registry
tuomas2 Jul 2, 2017
aa84322
Merge branch 'master' into feature/member_registry
tuomas2 Jul 7, 2017
f9ce2d3
Bulk rename participant -> participation
tuomas2 Jul 7, 2017
cc475ac
Filename renames: participant->participation
tuomas2 Jul 7, 2017
3ada87a
Replace Participant->Participation
tuomas2 Jul 7, 2017
e4e7be0
Update migrations related to participant->participation renames
tuomas2 Jul 7, 2017
134339f
Update test data
tuomas2 Jul 7, 2017
3efb8ee
Fix broken test
tuomas2 Jul 7, 2017
6406264
Run create_default_email_templates and recreate testdata
tuomas2 Jul 7, 2017
f1dd300
Fix crash
tuomas2 Jul 7, 2017
216be6b
Small TODO fixes
tuomas2 Jul 7, 2017
3faf3e3
Small TODO fixes
tuomas2 Jul 7, 2017
9960287
Remove unsubscribe_participation and use only unsubscribe_member
tuomas2 Jul 7, 2017
f2997dd
Merge branch 'master' into feature/member_registry
tuomas2 Aug 1, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ case "$1" in
pip install -r requirements-tests.txt
wait_redis
cd $2
export TESTS_RUNNING=1
./manage.py collectstatic --noinput
./manage.py compress
./manage.py compilemessages
export TESTS_RUNNING=1
py.test -v --cov serviceform/ --cov tasks/ tests/
;;
'bash')
Expand Down
6 changes: 6 additions & 0 deletions serviceform/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import pkg_resources

try:
__version__ = pkg_resources.get_distribution("serviceform").version
except pkg_resources.DistributionNotFound:
__version__ = 'not installed'
108 changes: 71 additions & 37 deletions serviceform/serviceform/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,38 +177,22 @@ class QuestionInline(ResponsibleMixin, GrappelliSortableHiddenMixin, NestedTabul
fields = ('question', 'responsibles', 'answer_type', 'required', 'order')


class EmailTemplateInline(NestedStackedInline):
fields = ('name', 'subject', 'content')
model = models.EmailTemplate
extra = 0


class RevisionInline(NestedStackedInline):
fields = ('name', ('valid_from', 'valid_to'), 'send_emails_after',
'send_bulk_email_to_participants')
'send_bulk_email_to_participations')
model = models.FormRevision
extra = 0


class ResponsibilityPersonInline(NestedStackedInline):
model = models.ResponsibilityPerson
extra = 0
fields = (('forenames', 'surname'), ('email', 'phone_number'), 'street_address',
('postal_code', 'city'), 'send_email_notifications', 'hide_contact_details',
'show_full_report', 'personal_link')
readonly_fields = ('personal_link',)


@admin.register(models.ServiceForm)
class ServiceFormAdmin(OwnerSaveMixin, ExtendedLogMixin, NestedModelAdminMixin,
GuardedModelAdminMixin, admin.ModelAdmin):
class Media:
css = {'all': ('serviceform/serviceform_admin.css',)}

inlines = [RevisionInline, EmailTemplateInline, ResponsibilityPersonInline,
Level1CategoryInline, QuestionInline]
inlines = [RevisionInline, Level1CategoryInline, QuestionInline]

superuser_actions = ['bulk_email_former_participants', 'bulk_email_responsibles']
superuser_actions = ['bulk_email_former_participations', 'bulk_email_responsibles']
if settings.DEBUG:
superuser_actions.append('shuffle_data')

Expand All @@ -227,15 +211,15 @@ class Media:

email_settings = (
'require_email_verification',
'verification_email_to_participant',
'verification_email_to_participation',
'email_to_responsibles',
'email_to_invited_users',

'email_to_participant',
'resend_email_to_participant',
'email_to_participation',
'resend_email_to_participation',

'email_to_participant_on_update',
'email_to_former_participants',
'email_to_participation_on_update',
'email_to_former_participations',

'bulk_email_to_responsibles',
'email_to_responsible_auth_link',
Expand All @@ -262,8 +246,8 @@ class Media:
(_('Ownership'), {'fields': ownership}),
(_('Email settings'), {'fields': email_settings}),
(_('Customization'), {'fields': customization}),
(_('Ask details from participants'), {'fields': visible_contact_details}),
(_('Require details from participants'), {'fields': required_contact_details}),
(_('Ask details from participations'), {'fields': visible_contact_details}),
(_('Require details from participations'), {'fields': required_contact_details}),
)

new_fieldsets = ((_('Basic information'), {'fields': basic}),)
Expand All @@ -282,12 +266,12 @@ def get_actions(self, request: HttpRequest):
actions.pop(a, None)
return actions

def bulk_email_former_participants(self, request: HttpRequest,
def bulk_email_former_participations(self, request: HttpRequest,
queryset: Iterable[models.ServiceForm]) -> None:
for serviceform in queryset:
serviceform.bulk_email_former_participants()
serviceform.bulk_email_former_participations()

bulk_email_former_participants.short_description = _('Bulk email former participants now!')
bulk_email_former_participations.short_description = _('Bulk email former participations now!')

def bulk_email_responsibles(self, request: HttpRequest,
queryset: Iterable[models.ServiceForm]) -> None:
Expand All @@ -301,7 +285,7 @@ def shuffle_data(self, request: HttpRequest,
for serviceform in queryset:
utils.shuffle_person_data(serviceform)

shuffle_data.short_description = _('Shuffle participant data')
shuffle_data.short_description = _('Shuffle participation data')

def get_queryset(self, request: HttpRequest):
qs = super().get_queryset(request)
Expand All @@ -311,13 +295,13 @@ def get_queryset(self, request: HttpRequest):
def get_form(self, request: HttpRequest, obj: models.ServiceForm=None, **kwargs):
form = super().get_form(request, obj, **kwargs)
if obj:
request._responsibles = responsibles = models.ResponsibilityPerson.objects.filter(
form=obj)
request._responsibles = responsibles = models.Member.objects.filter(
organization_id=obj.organization_id)
form.base_fields['responsible'].queryset = responsibles
form.base_fields['current_revision'].queryset = models.FormRevision.objects.filter(
form=obj)

emailtemplates = models.EmailTemplate.objects.filter(form=obj)
emailtemplates = models.EmailTemplate.objects.filter(organization=obj.organization)

for name, field in form.base_fields.items():
if 'email_to' in name:
Expand Down Expand Up @@ -353,12 +337,62 @@ class EmailMessageAdmin(ExtendedLogMixin, admin.ModelAdmin):
'content_display',)


@admin.register(models.Participant)
class ParticipantAdmin(ExtendedLogMixin, admin.ModelAdmin):
class MemberInline(NestedStackedInline):
model = models.Member
extra = 0
fields = (('forenames', 'surname'), ('email', 'phone_number'), 'street_address',
('postal_code', 'city'), 'allow_responsible_email',
'allow_participation_email', 'hide_contact_details',
'show_full_report', 'personal_link')
readonly_fields = ('personal_link',)


class EmailTemplateInline(NestedStackedInline):
fields = ('name', 'subject', 'content')
model = models.EmailTemplate
extra = 0


@admin.register(models.Organization)
class OrganizationAdmin(ExtendedLogMixin, NestedModelAdminMixin, GuardedModelAdminMixin,
admin.ModelAdmin):
list_display = ('name',)
inlines = [MemberInline, EmailTemplateInline]
basic = ('name', )
new_fieldsets = ((_('Basic information'), {'fields': basic}),)

def get_form(self, request: HttpRequest, obj: models.Organization=None, **kwargs):
form = super().get_form(request, obj, **kwargs)
if obj:
emailtemplates = models.EmailTemplate.objects.filter(organization=obj)

for name, field in form.base_fields.items():
if 'email_to' in name:
field.queryset = emailtemplates
if obj and field.queryset:
field.required = True

return form

def save_model(self, request: HttpRequest, obj: models.Organization, form, change: bool):
rv = super().save_model(request, obj, form, change)
if not change:
obj.create_initial_data()
return rv

def get_fieldsets(self, request: HttpRequest, obj: models.Organization=None):
return self.new_fieldsets if obj is None else super().get_fieldsets(request, obj)

def get_inline_instances(self, request: HttpRequest, obj: models.Organization=None):
return super().get_inline_instances(request, obj) if obj else []


@admin.register(models.Participation)
class ParticipationAdmin(ExtendedLogMixin, admin.ModelAdmin):
list_display = (
'id', '__str__', 'form_display', 'form_revision', 'status', 'activities_display',
'created_at', 'last_modified', 'personal_link')
fields = ('forenames', 'surname')
'created_at', 'last_modified',)
fields = ('member',)

def get_queryset(self, request):
qs = super().get_queryset(request).select_related('form_revision__form')
Expand Down
33 changes: 23 additions & 10 deletions serviceform/serviceform/emails.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
bulk_email_to_responsibles = _("""Dear {{responsible}},

Participation results for {{form}} are now available for you to view.
You can see all participants for the activities you are responsible of in the following URL:
You can see all participations for the activities you are responsible of in the following URL:
{{url}}
From now on, you will also receive a notification message, if a new participation submitted to
the areas you are responsible of.You can also adjust your contact details and email notification
Expand All @@ -34,7 +34,7 @@
{{contact}}""")


invite = _("""Dear {{participant}},
invite = _("""Dear {{participation}},

You are invited to participate in "{{ form }}".
You can fill in your participation details at {{ url }}.
Expand All @@ -47,8 +47,8 @@

message_to_responsibles = _("""Dear {{responsible}},

New participation from {{participant}} has just been submitted to {{form}}.
You can see all participants for the activities you are responsible of in the following URL:
New participation from {{participation}} has just been submitted to {{form}}.
You can see all participations for the activities you are responsible of in the following URL:
{{url}}
You can also adjust your contact details and email notification preferences from that URL.

Expand All @@ -58,7 +58,7 @@
Contact person:
{{contact}}""")

participant_new_form_revision = _("""Dear {{participant}},
participation_new_form_revision = _("""Dear {{participation}},

New form revision to "{{ form }}" has been published.
Please update your participation information at {{ url }}.
Expand All @@ -69,7 +69,7 @@
Contact person:
{{contact}}""")

participant_on_finish = _("""Dear {{participant}},
participation_on_finish = _("""Dear {{participation}},

You submitted form "{{ form }}" on {{ last_modified }}.
If you wish to change any of the details you gave, you can go to {{ url }}.
Expand All @@ -80,7 +80,7 @@
Contact person:
{{contact}}""")

resend_email_to_participants = _("""Dear {{participant}},
resend_email_to_participations = _("""Dear {{participation}},

You submitted form "{{ form }}" on {{ last_modified }}.
If you wish to change any of the details you gave, you can go to {{ url }}.
Expand All @@ -91,7 +91,7 @@
Contact person:
{{contact}}""")

participant_on_update = _("""Dear {{participant}},
participation_on_update = _("""Dear {{participation}},

You submitted update to your data on form "{{ form }}" on {{ last_modified }}.
If you wish to change any of the details you gave, you can go to {{ url }}.
Expand All @@ -105,7 +105,7 @@

request_responsible_auth_link = _("""Dear {{responsible}},

You can see all participants for the activities you are responsible of in the following URL:
You can see all participations for the activities you are responsible of in the following URL:
{{url}}

Best regards,
Expand All @@ -115,7 +115,7 @@
{{contact}}""")


verification_email_to_participant = _("""Dear {{participant}},
verification_email_to_participation = _("""Dear {{participation}},

Your email address needs to be verified. Please do so by clicking link below. Then you can
continue filling the form.
Expand All @@ -127,3 +127,16 @@

Contact person:
{{contact}}""")


# TODO: check this email content
email_to_member_auth_link = _("""Dear {{member}},

Here is your link to access your data in {{organization}}:
{{url}}

Best regards,
Service form system administrators

Contact person:
{{contact}}""")
14 changes: 14 additions & 0 deletions serviceform/serviceform/fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from colorful.fields import RGBColorField


class ColorField(RGBColorField):
def get_prep_value(self, value: 'ColorStr') -> 'Optional[ColorStr]':
rv = super().get_prep_value(value)
if rv == '#000000':
rv = None
return rv

def from_db_value(self, value: 'Optional[ColorStr]', *args):
if value is None:
return '#000000'
return value
Loading