Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jul 19 sprint #32

Open
wants to merge 45 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
f306afd
Upgrade to Python3 Django 2.x
davidmiller Jul 8, 2019
ab3cfdf
Update to add new delcaration format"
davidmiller Jul 8, 2019
1e4581f
Split declaration history and archived declarations
davidmiller Jul 8, 2019
472b21d
Update homepage text
davidmiller Jul 8, 2019
b38bef2
Change employment details and rewrite declaration form
davidmiller Jul 9, 2019
df60fa2
Tell us if something is wrong
davidmiller Jul 9, 2019
9858a2d
Adjust header in doctor list
davidmiller Jul 9, 2019
3158fed
I don't believe claiming that a domain name owns copyright of somethi…
davidmiller Jul 9, 2019
d6a4d21
Add declaration search
davidmiller Jul 9, 2019
9f260ea
Adds django reversion to the requirments.txt
fredkingham Jul 9, 2019
6989879
upgrade unicode strings
fredkingham Jul 9, 2019
8719fea
Merge pull request #33 from openhealthcare/minor-fixes
davidmiller Jul 9, 2019
30c7a8f
The search link should point to the declaration
fredkingham Jul 9, 2019
d1295ae
Removes the band requirement in the form
fredkingham Jul 9, 2019
2620f16
smaller bands look better (IMO)
fredkingham Jul 9, 2019
5af434c
Merge pull request #36 from openhealthcare/remove-form-band-validation
davidmiller Jul 9, 2019
6cc2220
Merge pull request #37 from openhealthcare/shrink-the-band-fields
davidmiller Jul 9, 2019
486d9af
Merge pull request #35 from openhealthcare/search-link-fix
davidmiller Jul 9, 2019
069452f
only save work details when the field is populated
fredkingham Jul 9, 2019
8232e5c
We have a div tag in the wrong place so when we loop over the pages r…
fredkingham Jul 9, 2019
43bf3af
Merge pull request #42 from openhealthcare/multiple-declarations-rend…
davidmiller Jul 9, 2019
8e51331
Merge pull request #40 from openhealthcare/only-save-work-details-whe…
davidmiller Jul 9, 2019
5fb8a22
ordering by multiple related fields results in multiple rows https://…
fredkingham Jul 9, 2019
c76e291
Declar is not how you spell Declare, fixes a typo in a view name
fredkingham Jul 10, 2019
84e1ed3
Merge pull request #43 from openhealthcare/order-doctors-by-name
davidmiller Jul 10, 2019
cd3e527
set up white noise for static assets when we deploy
fredkingham Jul 10, 2019
f7de2a9
Merge pull request #44 from openhealthcare/deployment-settings
davidmiller Jul 10, 2019
65509cf
bumps the settings to use the suggested SEND_GRID format, adds detail…
fredkingham Jul 10, 2019
bf55823
typo bug, send_mail is a module with a method called send_mail
fredkingham Jul 10, 2019
86bb667
use python 3.7
fredkingham Jul 10, 2019
5ca1f1f
display work positions better, otherwise None is displayed a lot
fredkingham Jul 10, 2019
837b250
Merge pull request #45 from openhealthcare/models-send-mail-typo-bug
davidmiller Jul 10, 2019
2fe99c2
Merge pull request #47 from openhealthcare/display-work-positions
davidmiller Jul 10, 2019
f7ce520
restore us back to using the non api key method for send grid in sett…
fredkingham Jul 10, 2019
cbcca5a
Merge pull request #46 from openhealthcare/production-settings
davidmiller Jul 10, 2019
695e197
OHC aren't really the point, don't mention us on the home page
davidmiller Jul 10, 2019
eb8bfb0
use the default domain but allow it to be overridden by a conf variable
fredkingham Jul 10, 2019
7d45574
fixes the name of the gmc field in the form
fredkingham Jul 10, 2019
8a64488
Rolls back the form change and changes the settings to point to openh…
fredkingham Jul 10, 2019
7d153eb
Make sure validation for when enters an email with an incorrect suffi…
fredkingham Jul 10, 2019
b371c87
Shorten bio for [email protected]
davidmiller Jul 15, 2019
1613785
Reverse date create order for archived declarations
davidmiller Jul 15, 2019
55b2122
update the copy for the front page
fredkingham Aug 21, 2019
3b0f929
Merge branch 'jul-19-sprint' of https://github.com/openhealthcare/who…
fredkingham Aug 21, 2019
1a79f48
reband and repoint the user to sunshineuk.org
fredkingham Nov 11, 2019
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
4 changes: 2 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
### This is the Website at WhoPaysThisDoctor.org
### This is the Website at Sunshineuk.org

You would probably prefer to be looking at www.whoPaysThisDoctor.org
You would probably prefer to be looking at www.sunshineuk.org

### Contributing

Expand Down
1 change: 0 additions & 1 deletion doctors/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
from doctors import views
15 changes: 12 additions & 3 deletions doctors/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Admin config for Doctors app.
"""
from django.contrib import admin
import reversion
from reversion.admin import VersionAdmin

from doctors import models

Expand All @@ -18,10 +18,13 @@ class FeeBenefitInline(admin.StackedInline):
class GrantBenefitInline(admin.StackedInline):
model = models.GrantBenefit

class DoctorAdmin(reversion.VersionAdmin):
class WorkDetailsInline(admin.StackedInline):
model = models.WorkDetails

class DoctorAdmin(VersionAdmin):
pass

class DeclarationAdmin(reversion.VersionAdmin):
class DeclarationAdmin(VersionAdmin):
inlines = (PharmaBenefitInline, OtherMedicalBenefitInline,
FeeBenefitInline, GrantBenefitInline)
list_display = ['doctor', 'dt_created']
Expand All @@ -32,6 +35,12 @@ class DeclarationLinkAdmin(admin.ModelAdmin):
search_fields = ['email']
list_display = ['email', 'expires', 'key']


class DetailedDeclarationAdmin(VersionAdmin):
inlines = (WorkDetailsInline,)
search_fields = ['doctor__name']

admin.site.register(models.DetailedDeclaration, DetailedDeclarationAdmin)
admin.site.register(models.Doctor, DoctorAdmin)
admin.site.register(models.Declaration, DeclarationAdmin)
admin.site.register(models.DeclarationLink, DeclarationLinkAdmin)
5 changes: 5 additions & 0 deletions doctors/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class DoctorsConfig(AppConfig):
name = 'doctors'
53 changes: 46 additions & 7 deletions doctors/forms.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
"""
Forms for Who Pays This Doctor
Forms for Sunshine UK
"""
import datetime

from django import forms
from django.conf import settings
from django.forms import widgets
from django.forms.models import ModelForm
from django.forms.models import ModelForm, inlineformset_factory

from doctors.models import DeclarationLink, Doctor
from doctors.models import DeclarationLink, Doctor, DetailedDeclaration, WorkDetails

class NHSEmailField(forms.EmailField):
def validate(self, value):
Expand Down Expand Up @@ -53,11 +53,50 @@ class ReEstablishIdentityForm(DeclarationIdentityForm):
email = NHSEmailField()
gmc = forms.CharField(widget=widgets.HiddenInput())


def clean(self):
super(ReEstablishIdentityForm, self).clean()
email = self.cleaned_data.get("email")

email, gmc = self.cleaned_data['email'], self.cleaned_data['gmc']
doctor = Doctor.objects.get(gmc_number=gmc)
if doctor.email != email:
raise forms.ValidationError('A different email address was used to submit declarations for that doctor in the past')
if email:
gmc = self.cleaned_data['gmc']
doctor = Doctor.objects.get(gmc_number=gmc)
if doctor.email != email:
raise forms.ValidationError('A different email address was used to submit declarations for that doctor in the past')
return self.cleaned_data


class DetailedDeclarationForm(ModelForm):
for_year = forms.ChoiceField(label="Declaration period")

def __init__(self, *a, **k):
super().__init__(*a, **k)
year_choices = [
(str(i), str(i)) for i in
range(2010, datetime.date.today().year+1)
]
year_choices.reverse()
self.fields['for_year'].choices = year_choices

class Meta:
model = DetailedDeclaration
exclude = ['dt_created']


class WorkDetailsForm(ModelForm):
class Meta:
model = WorkDetails
exclude = ['dt_created']

def is_populated(self):
fields = ["category", "institution", "job_title"]
return any(self.cleaned_data.get(i) for i in fields)


DeclarationIdentityFormSet = inlineformset_factory(
Doctor, DetailedDeclaration, form=DetailedDeclarationForm, extra=1
)

WorkDetailsFormSet = inlineformset_factory(
DetailedDeclaration, WorkDetails, form=WorkDetailsForm, extra=1
)
265 changes: 110 additions & 155 deletions doctors/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,155 +1,110 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

def forwards(self, orm):
# Adding model 'Doctor'
db.create_table(u'doctors_doctor', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=200)),
('gmc_number', self.gf('django.db.models.fields.CharField')(unique=True, max_length=100)),
('job_title', self.gf('django.db.models.fields.CharField')(max_length=200)),
('primary_employer', self.gf('django.db.models.fields.CharField')(max_length=200)),
('employment_address', self.gf('django.db.models.fields.TextField')()),
))
db.send_create_signal(u'doctors', ['Doctor'])

# Adding model 'Declaration'
db.create_table(u'doctors_declaration', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('doctor', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['doctors.Doctor'])),
('interests', self.gf('django.db.models.fields.BooleanField')(default=True)),
('past_declarations', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
('other_declarations', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
('date_created', self.gf('django.db.models.fields.DateField')(default=datetime.datetime(2014, 1, 3, 0, 0))),
))
db.send_create_signal(u'doctors', ['Declaration'])

# Adding model 'PharmaBenefit'
db.create_table(u'doctors_pharmabenefit', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('doctor', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['doctors.Doctor'])),
('declaration', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['doctors.Declaration'], null=True, blank=True)),
('company', self.gf('django.db.models.fields.CharField')(max_length=200)),
('reason', self.gf('django.db.models.fields.CharField')(max_length=200)),
('amount', self.gf('django.db.models.fields.FloatField')()),
))
db.send_create_signal(u'doctors', ['PharmaBenefit'])

# Adding model 'OtherMedicalBenefit'
db.create_table(u'doctors_othermedicalbenefit', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('doctor', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['doctors.Doctor'])),
('declaration', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['doctors.Declaration'], null=True, blank=True)),
('company', self.gf('django.db.models.fields.CharField')(max_length=200)),
('reason', self.gf('django.db.models.fields.CharField')(max_length=200)),
('amount', self.gf('django.db.models.fields.FloatField')()),
))
db.send_create_signal(u'doctors', ['OtherMedicalBenefit'])

# Adding model 'FeeBenefit'
db.create_table(u'doctors_feebenefit', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('doctor', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['doctors.Doctor'])),
('declaration', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['doctors.Declaration'], null=True, blank=True)),
('company', self.gf('django.db.models.fields.CharField')(max_length=200)),
('reason', self.gf('django.db.models.fields.CharField')(max_length=200)),
('amount', self.gf('django.db.models.fields.FloatField')()),
))
db.send_create_signal(u'doctors', ['FeeBenefit'])

# Adding model 'GrantBenefit'
db.create_table(u'doctors_grantbenefit', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('doctor', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['doctors.Doctor'])),
('declaration', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['doctors.Declaration'], null=True, blank=True)),
('company', self.gf('django.db.models.fields.CharField')(max_length=200)),
('reason', self.gf('django.db.models.fields.CharField')(max_length=200)),
('amount', self.gf('django.db.models.fields.FloatField')()),
))
db.send_create_signal(u'doctors', ['GrantBenefit'])


def backwards(self, orm):
# Deleting model 'Doctor'
db.delete_table(u'doctors_doctor')

# Deleting model 'Declaration'
db.delete_table(u'doctors_declaration')

# Deleting model 'PharmaBenefit'
db.delete_table(u'doctors_pharmabenefit')

# Deleting model 'OtherMedicalBenefit'
db.delete_table(u'doctors_othermedicalbenefit')

# Deleting model 'FeeBenefit'
db.delete_table(u'doctors_feebenefit')

# Deleting model 'GrantBenefit'
db.delete_table(u'doctors_grantbenefit')


models = {
u'doctors.declaration': {
'Meta': {'object_name': 'Declaration'},
'date_created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2014, 1, 3, 0, 0)'}),
'doctor': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doctors.Doctor']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'interests': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'other_declarations': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'past_declarations': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
},
u'doctors.doctor': {
'Meta': {'object_name': 'Doctor'},
'employment_address': ('django.db.models.fields.TextField', [], {}),
'gmc_number': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'job_title': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'primary_employer': ('django.db.models.fields.CharField', [], {'max_length': '200'})
},
u'doctors.feebenefit': {
'Meta': {'object_name': 'FeeBenefit'},
'amount': ('django.db.models.fields.FloatField', [], {}),
'company': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'declaration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doctors.Declaration']", 'null': 'True', 'blank': 'True'}),
'doctor': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doctors.Doctor']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'reason': ('django.db.models.fields.CharField', [], {'max_length': '200'})
},
u'doctors.grantbenefit': {
'Meta': {'object_name': 'GrantBenefit'},
'amount': ('django.db.models.fields.FloatField', [], {}),
'company': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'declaration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doctors.Declaration']", 'null': 'True', 'blank': 'True'}),
'doctor': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doctors.Doctor']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'reason': ('django.db.models.fields.CharField', [], {'max_length': '200'})
},
u'doctors.othermedicalbenefit': {
'Meta': {'object_name': 'OtherMedicalBenefit'},
'amount': ('django.db.models.fields.FloatField', [], {}),
'company': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'declaration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doctors.Declaration']", 'null': 'True', 'blank': 'True'}),
'doctor': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doctors.Doctor']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'reason': ('django.db.models.fields.CharField', [], {'max_length': '200'})
},
u'doctors.pharmabenefit': {
'Meta': {'object_name': 'PharmaBenefit'},
'amount': ('django.db.models.fields.FloatField', [], {}),
'company': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'declaration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doctors.Declaration']", 'null': 'True', 'blank': 'True'}),
'doctor': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doctors.Doctor']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'reason': ('django.db.models.fields.CharField', [], {'max_length': '200'})
}
}

complete_apps = ['doctors']
# Generated by Django 2.2.3 on 2019-07-08 11:18

import datetime
from django.db import migrations, models
import django.db.models.deletion
import doctors.models


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='Declaration',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('interests', models.BooleanField(default=False)),
('past_declarations', models.TextField(blank=True, null=True)),
('other_declarations', models.TextField(blank=True, null=True)),
('date_created', models.DateField(default=datetime.date.today)),
('dt_created', models.DateTimeField(default=datetime.datetime.now)),
],
),
migrations.CreateModel(
name='DeclarationLink',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('email', models.EmailField(max_length=254, unique=True)),
('expires', models.DateTimeField(default=doctors.models.in_two_weeks)),
('key', models.CharField(default=doctors.models.random_token, max_length=64, unique=True)),
],
),
migrations.CreateModel(
name='Doctor',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200)),
('gmc_number', models.CharField(max_length=100, unique=True)),
('job_title', models.CharField(max_length=200)),
('primary_employer', models.CharField(max_length=200)),
('employment_address', models.TextField()),
('email', models.EmailField(blank=True, max_length=254, null=True)),
],
),
migrations.CreateModel(
name='PharmaBenefit',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('company', models.CharField(max_length=200)),
('reason', models.CharField(max_length=200)),
('band', models.IntegerField(choices=[(1, 'under £100'), (5, '£5000 - £10000'), (6, '£10000 - £50 000'), (7, '£50000- £100000'), (8, '£100000+')])),
('declaration', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='doctors.Declaration')),
('doctor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doctors.Doctor')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='OtherMedicalBenefit',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('company', models.CharField(max_length=200)),
('reason', models.CharField(max_length=200)),
('band', models.IntegerField(choices=[(1, 'under £100'), (5, '£5000 - £10000'), (6, '£10000 - £50 000'), (7, '£50000- £100000'), (8, '£100000+')])),
('declaration', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='doctors.Declaration')),
('doctor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doctors.Doctor')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='GrantBenefit',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('company', models.CharField(max_length=200)),
('reason', models.CharField(max_length=200)),
('band', models.IntegerField(choices=[(1, 'under £100'), (5, '£5000 - £10000'), (6, '£10000 - £50 000'), (7, '£50000- £100000'), (8, '£100000+')])),
('declaration', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='doctors.Declaration')),
('doctor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doctors.Doctor')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='FeeBenefit',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('company', models.CharField(max_length=200)),
('reason', models.CharField(max_length=200)),
('band', models.IntegerField(choices=[(1, 'under £100'), (5, '£5000 - £10000'), (6, '£10000 - £50 000'), (7, '£50000- £100000'), (8, '£100000+')])),
('declaration', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='doctors.Declaration')),
('doctor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doctors.Doctor')),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='declaration',
name='doctor',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doctors.Doctor'),
),
]
Loading