Commit 2eb82fb9 by Jason Bau

Merge branch 'dcadams/cme_registration' into edx-west/rc-20130912

Conflicts:
	common/djangoapps/student/views.py
	lms/envs/common.py
parents 4b38505e 0eef7a90
......@@ -150,3 +150,6 @@ MITX_FEATURES['ENABLE_SERVICE_STATUS'] = True
# This is to disable a test under the common directory that will not pass when run under CMS
MITX_FEATURES['DISABLE_PASSWORD_RESET_EMAIL_TEST'] = True
# This is to disable tests CME Registration tests, under common, that will not pass when run under CMS
MITX_FEATURES['DISABLE_CME_REGISTRATION_TESTS'] = True
# -*- coding: utf-8 -*-
import 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 'CmeUserProfile'
db.create_table('cme_registration', (
('userprofile_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['student.UserProfile'], unique=True, primary_key=True)),
('profession', self.gf('django.db.models.fields.CharField')(max_length=30, null=True, blank=True)),
('professional_designation', self.gf('django.db.models.fields.CharField')(max_length=3, null=True, blank=True)),
('license_number', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)),
('organization', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)),
('stanford_affiliated', self.gf('django.db.models.fields.BooleanField')(default=False)),
('how_stanford_affiliated', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)),
('patient_population', self.gf('django.db.models.fields.CharField')(max_length=25, null=True, blank=True)),
('specialty', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)),
('sub_specialty', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)),
('address_1', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
('address_2', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
('city', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
('state_province', self.gf('django.db.models.fields.CharField')(max_length=50, null=True, blank=True)),
('postal_code', self.gf('django.db.models.fields.CharField')(max_length=20, null=True, blank=True)),
('country', self.gf('django.db.models.fields.CharField')(max_length=50, null=True, blank=True)),
('phone_number', self.gf('django.db.models.fields.CharField')(max_length=30, null=True, blank=True)),
('extension', self.gf('django.db.models.fields.CharField')(max_length=10, null=True, blank=True)),
('fax', self.gf('django.db.models.fields.CharField')(max_length=30, null=True, blank=True)),
('hear_about_us', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)),
('mailing_list', self.gf('django.db.models.fields.BooleanField')(default=False)),
))
db.send_create_signal('cme_registration', ['CmeUserProfile'])
def backwards(self, orm):
# Deleting model 'CmeUserProfile'
db.delete_table('cme_registration')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'cme_registration.cmeuserprofile': {
'Meta': {'object_name': 'CmeUserProfile', 'db_table': "'cme_registration'", '_ormbases': ['student.UserProfile']},
'address_1': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'address_2': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'city': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'country': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
'extension': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
'fax': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
'hear_about_us': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'how_stanford_affiliated': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'license_number': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'mailing_list': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'organization': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'patient_population': ('django.db.models.fields.CharField', [], {'max_length': '25', 'null': 'True', 'blank': 'True'}),
'phone_number': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}),
'profession': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
'professional_designation': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True', 'blank': 'True'}),
'specialty': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'stanford_affiliated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'state_province': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
'sub_specialty': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'userprofile_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['student.UserProfile']", 'unique': 'True', 'primary_key': 'True'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'student.userprofile': {
'Meta': {'object_name': 'UserProfile', 'db_table': "'auth_userprofile'"},
'allow_certificate': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'courseware': ('django.db.models.fields.CharField', [], {'default': "'course.xml'", 'max_length': '255', 'blank': 'True'}),
'gender': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '6', 'null': 'True', 'blank': 'True'}),
'goals': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'level_of_education': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '6', 'null': 'True', 'blank': 'True'}),
'location': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'mailing_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'meta': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"}),
'year_of_birth': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'})
}
}
complete_apps = ['cme_registration']
\ No newline at end of file
"""
Models for CME Registration
"""
from django.db import models
from student.models import UserProfile
# Create your models here.
#Fields for CME specific registration page
class CmeUserProfile(UserProfile):
"""
Object for storing CME Registration information
Uses multi-table inheritance of UserProfile
"""
class Meta:
db_table = "cme_registration"
PROFESSION_CHOICES = (('Allied Health Professional', 'Allied Health Professional'),
('Fellow', 'Fellow'),
('Nurse', 'Nurse'),
('Nurse Practioner', 'Nurse Practioner'),
('Physician', 'Physician'),
('Physician Assistant', 'Physician Assistant'),
('Resident', 'Resident'),
('Student', 'Student'))
profession = models.CharField(blank=True, null=True, max_length=30, choices=PROFESSION_CHOICES)
PROFESSIONAL_DESIGNATION_CHOICES = (('MD', 'MD'),
('DO', 'DO'),
('PA', 'PA'),
('NP', 'NP'),
('RN', 'RN'))
professional_designation = models.CharField(blank=True, null=True, max_length=3, choices=PROFESSIONAL_DESIGNATION_CHOICES)
license_number = models.CharField(blank=True, null=True, max_length=255)
organization = models.CharField(blank=True, null=True, max_length=255)
stanford_affiliated = models.BooleanField(default=0)
HOW_STANFORD_AFFILIATED_CHOICES = (('Lucile Packard Children\'s Hospital at Stanford', 'Lucile Packard Children\'s Hospital at Stanford'),
('Packard Children\'s Health Alliance (PCHA)', 'Packard Children\'s Health Alliance (PCHA)'),
('Stanford Hospital & Clinics', 'Stanford Hospital & Clinics'),
('Stanford University', 'Stanford University'),
('University Healthcare Alliance (UHA)', 'University Healthcare Alliance (UHA)'),
('Other', 'Other, please enter:'))
how_stanford_affiliated = models.CharField(blank=True, null=True, max_length=255, choices=HOW_STANFORD_AFFILIATED_CHOICES)
PATIENT_POPULATION_CHOICES = (('Adult', 'Adult'),
('Pediatric', 'Pediatric'),
('Both (Adult/Pediatric)', 'Both (Adult/Pediatric)'))
patient_population = models.CharField(blank=True, null=True, max_length=25, choices=PATIENT_POPULATION_CHOICES)
specialty = models.CharField(blank=True, null=True, max_length=255)
sub_specialty = models.CharField(blank=True, null=True, max_length=255)
address_1 = models.TextField(blank=True, null=True)
address_2 = models.TextField(blank=True, null=True)
city = models.TextField(blank=True, null=True)
STATE_CHOICES = (('Alabama', 'Alabama'),
('Alaska', 'Alaska'),
('Arizona', 'Arizona'),
('Arkansas', 'Arkansas'),
('California', 'California'),
('Colorado', 'Colorado'),
('Connecticut', 'Connecticut'),
('Delaware', 'Deleware'),
('District of Columbia', 'District of Columbia'),
('Florida', 'Florida'),
('Georgia', 'Georgia'),
('Hawaii', 'Hawaii'),
('Idaho', 'Idaho'),
('Illinois', 'Indiana'),
('Iowa', 'Iowa'),
('Kansas', 'Kansas'),
('Kentucky', 'Kentucky'),
('Louisiana', 'Louisiana'),
('Maine', 'Maine'),
('Maryland', 'Maryland'),
('Massachusetts', 'Massachusetts'),
('Michigan', 'Michigan'),
('Minnesota', 'Minnesota'),
('Mississippi', 'Mississippi'),
('Missouri', 'Missouri'),
('Montana', 'Montana'),
('Nebraska', 'Nebraska'),
('Nevada', 'Nevada'),
('Vermont', 'Vermont'),
('Virginia', 'Virginia'),
('Washington', 'Washington'),
('West Virginia', 'West Virginia'),
('Wisconsin', 'Wisconsin'),
('Wyoming', 'Wyoming'),
('American Samoa', 'American Samoa'),
('Armed Forces America', 'Armed Forces America'),
('Armed Forces Europe', 'Armed Forces Europe'),
('Armed Forces Pacific', 'Armed Forces Pacific'),
('Guam', 'Guam'),
('Northern Mariana Islands', 'Northern, Mariana Islands'),
('Palau', 'Palau'),
('Puerto Rico', 'Puerto Rico'),
('Utah', 'Utah'),
('Virgin Island', 'Virgin Island'),
('Alberta', 'Alberta'),
('British Columbia', 'British Columbia'),
('Manitoba', 'Manitoba'),
('Nanavut', 'Nanavut'),
('New Brunswick', 'New Brunswick'),
('Newfoundland and Labrador', 'Newfoundland and Labrador'),
('Northwest Territories', 'Northwest Territories'),
('Nova Scotia', 'Nova Scotia'),
('Ontario', 'Ontario'),
('Prince Edward Island', 'Prince Edward Island'),
('Quebec', 'Quebec'),
('Saskatchewan', 'Saskatchewan'),
('Yukon Territory', 'Yukon Territory'),
('Other', 'Other'))
state_province = models.CharField(blank=True, null=True, max_length=50, choices=STATE_CHOICES)
postal_code = models.CharField(blank=True, null=True, max_length=20)
COUNTRY_CHOICES = (('United States', 'United States'),
('Afghanistan', 'Afghanistan'),
('Aland Islands', 'Aland Islands'),
('Albania', 'Albania'),
('Algeria', 'Algeria'),
('American Samoa', 'American Samoa'),
('Andorra', 'Andorra'),
('Angola', 'Angola'),
('Anguilla', 'Anguilla'),
('Antarctica', 'Antarctica'),
('Antigua And Barbuda', 'Antigua And Barbuda'),
('Argentina', 'Argentina'),
('Armenia', 'Armenia'),
('Aruba', 'Aruba'),
('Australia', 'Australia'),
('Austria', 'Austria'),
('Azerbaijan', 'Azerbaijan'),
('Bahamas', 'Bahamas'),
('Bahrain', 'Bahrain'),
('Bangladesh', 'Bangladesh'),
('Barbados', 'Barbados'),
('Belarus', 'Belarus'),
('Belgium', 'Belgium'),
('Belize', 'Belize'),
('Benin', 'Benin'),
('Bermuda', 'Bermuda'),
('Bhutan', 'Bhutan'),
('Bolivia', 'Bolivia'),
('Bosnia And Herzegovina', 'Bosnia And Herzegovina'),
('Botswana', 'Botswana'),
('Bouvet Island', 'Bouvet Island'),
('Brazil', 'Brazil'),
('British Indian Ocean Territory', 'British Indian Ocean Territory'),
('Brunei Darussalam', 'Brunei Darussalam'),
('Bulgaria', 'Bulgaria'),
('Burkina Faso', 'Burkina Faso'),
('Burundi', 'Burundi'),
('Cambodia', 'Cambodia'),
('Cameroon', 'Cameroon'),
('Canada', 'Canada'),
('Cape Verde', 'Cape Verde'),
('Cayman Islands', 'Cayman Islands'),
('Central African Republic', 'Central African Republic'),
('Chad', 'Chad'),
('Chile', 'Chile'),
('China', 'China'),
('Christmas Island', 'Christmas Island'),
('Cocos (Keeling) Islands', 'Cocos (Keeling) Islands'),
('Colombia', 'Colombia'),
('Comoros', 'Comoros'),
('Congo', 'Congo'),
('Congo, The Democratic Republic OfThe', 'Congo, The Democratic Republic OfThe'),
('Cook Islands', 'Cook Islands'),
('Costa Rica', 'Costa Rica'),
('Cote D\'lvoire', 'Cote D\'lvoire'),
('Croatia', 'Croatia'),
('Cuba', 'Cuba'),
('Cyprus', 'Cyprus'),
('Czech Republic', 'Czech Republic'),
('Denmark', 'Denmark'),
('Djibouti', 'Djibouti'),
('Dominica', 'Dominica'),
('Dominican Republic', 'Dominican Republic'),
('Ecuador', 'Ecuador'),
('Egypt', 'Egypt'),
('El Salvador', 'El Salvador'),
('Equatorial Guinea', 'Equatorial Guinea'),
('Eritrea', 'Eritrea'),
('Estonia', 'Estonia'),
('Ethiopia', 'Ethiopia'),
('Falkland Islands (Malvinas)', 'Falkland Islands (Malvinas)'),
('Faroe Islands', 'Faroe Islands'),
('Fiji', 'Fiji'),
('Finland', 'Finland'),
('France', 'France'),
('French Guiana', 'French Guiana'),
('French Polynesia', 'French Polynesia'),
('French Southern Territories', 'French Southern Territories'),
('Gabon', 'Gabon'),
('Gambia', 'Gambia'),
('Georgia', 'Georgia'),
('Germany', 'Germany'),
('Ghana', 'Ghana'),
('Gibraltar', 'Gibraltar'),
('Greece', 'Greece'),
('Greenland', 'Greenland'),
('Grenada', 'Grenada'),
('Guadeloupe', 'Guadeloupe'),
('Guam', 'Guam'),
('Guatemala', 'Guatemala'),
('Guernsey', 'Guernsey'),
('Guinea', 'Guinea'),
('Guinea-Bissau', 'Guinea-Bissau'),
('Guyana', 'Guyana'),
('Haiti', 'Haiti'),
('Heard Island And McDonald Is lands', 'Heard Island And McDonald Is lands'),
('Holy See (V.atican City State)', 'Holy See (V.atican City State)'),
('Honduras', 'Honduras'),
('Hong Kong', 'Hong Kong'),
('Hungary', 'Hungary'),
('Iceland', 'Iceland'),
('India', 'India'),
('Indonesia', 'Indonesia'),
('Iran, Islamic Republic Of', 'Iran, Islamic Republic Of'),
('Iraq', 'Iraq'),
('Ireland', 'Ireland'),
('Isle Of Man', 'Isle Of Man'),
('Israel', 'Israel'),
('Italy', 'Italy'),
('Jamaica', 'Jamaica'),
('Japan', 'Japan'),
('Jersey', 'Jersey'),
('Jordan', 'Jordan'),
('Kazakhstan', 'Kazakhstan'),
('Kenya', 'Kenya'),
('Kiribati', 'Kiribati'),
('Korea, Democratic People\'s Republic Of', 'Korea, Democratic People\'s Republic Of'),
('Korea, Republic Of', 'Korea, Republic Of'),
('Kuwait', 'Kuwait'),
('Kyrgyzstan', 'Kyrgyzstan'),
('Lao People\'s Democratic Republic', 'Lao People\'s Democratic Republic'),
('Latvia', 'Latvia'),
('Lebanon', 'Lebanon'),
('Lesotho', 'Lesotho'),
('Liberia', 'Liberia'),
('Libyan Arab Jamahiriya', 'Libyan Arab Jamahiriya'),
('Liechtenstein', 'Liechtenstein'),
('Lithuania', 'Lithuania'),
('Luxembourg', 'Luxembourg'),
('MacAo', 'MacAo'),
('MacEdonia, The Former Yugoslav Republic Of', 'MacEdonia, The Former Yugoslav Republic Of'),
('Madagascar', 'Madagascar'),
('Malawi', 'Malawi'),
('Malaysia', 'Malaysia'),
('Maldives', 'Maldives'),
('Mali', 'Mali'),
('Malta', 'Malta'),
('Marshall Islands', 'Marshall Islands'),
('Martinique', 'Martinique'),
('Mauritan ia', 'Mauritan ia'),
('Mauritius', 'Mauritius'),
('Mayotte', 'Mayotte'),
('Mexico', 'Mexico'),
('Micronesia, Federated States Of', 'Micronesia, Federated States Of'),
('Moldova, Republic Of', 'Moldova, Republic Of'),
('Monaco', 'Monaco'),
('Mongolia', 'Mongolia'),
('Montenegro', 'Montenegro'),
('Montserrat', 'Montserrat'),
('Morocco', 'Morocco'),
('Mozambique', 'Mozambique'),
('Myanmar', 'Myanmar'),
('Namibia', 'Namibia'),
('Nauru', 'Nauru'),
('Nepal', 'Nepal'),
('Netherlands', 'Netherlands'),
('Netherlands Antilles', 'Netherlands Antilles'),
('New Caledonia', 'New Caledonia'),
('New Zealand', 'New Zealand'),
('Nicaragua', 'Nicaragua'),
('Niger', 'Niger'),
('Nigeria', 'Nigeria'),
('Niue', 'Niue'),
('Norfolk Island', 'Norfolk Island'),
('Northern Mariana Islands', 'Northern Mariana Islands'),
('Norway', 'Norway'),
('Not Specified', 'Not Specified'),
('Oman', 'Oman'),
('Pakistan', 'Pakistan'),
('Palau', 'Palau'),
('Palestinian Territory, Occupied', 'Palestinian Territory, Occupied'),
('Panama', 'Panama'),
('Papua New Guinea', 'Papua New Guinea'),
('Paraguay', 'Paraguay'),
('Peru', 'Peru'),
('Philippines', 'Philippines'),
('Pitc.airn', 'Pitc.airn'),
('Poland', 'Poland'),
('Portugal', 'Portugal'),
('Puerto Rico', 'Puerto Rico'),
('Qatar', 'Qatar'),
('Reunion', 'Reunion'),
('Romania', 'Romania'),
('Russia', 'Russia'),
('Rwanda', 'Rwanda'),
('Saint Helena', 'Saint Helena'),
('Saint Kitts And Nevis', 'Saint Kitts And Nevis'),
('Saint Lucia', 'Saint Lucia'),
('Saint Pierre And Miquelon', 'Saint Pierre And Miquelon'),
('Saint Vincent And The Grenadines', 'Saint Vincent And The Grenadines'),
('Samoa', 'Samoa'),
('San Marino', 'San Marino'),
('Sao Tome And Principe', 'Sao Tome And Principe'),
('Saudi Arabia', 'Saudi Arabia'),
('Senegal', 'Senegal'),
('Serbia', 'Serbia'),
('Seychelles', 'Seychelles'),
('Sierra Leone', 'Sierra Leone'),
('Singapore', 'Singapore'),
('Slovakia', 'Slovakia'),
('Slovenia', 'Slovenia'),
('Solomon Islands', 'Solomon Islands'),
('Somalia', 'Somalia'),
('South Africa', 'South Africa'),
('South Georgia And The South Sandwich Islands', 'South Georgia And The South Sandwich Islands'),
('Spain', 'Spain'),
('Sri Lanka', 'Sri Lanka'),
('Sudan', 'Sudan'),
('Suriname', 'Suriname'),
('Svalbard And Jan Mayen', 'Svalbard And Jan Mayen'),
('Swaziland', 'Swaziland'),
('Sweden', 'Sweden'),
('Switzerland', 'Switzerland'),
('Syrian Alab Republic', 'Syrian Alab Republic'),
('Taiwan', 'Taiwan'),
('Tajikistan', 'Tajikistan'),
('Tanzania, United Republic Of', 'Tanzania, United Republic Of'),
('Thailand', 'Thailand'),
('Timor-Leste', 'Timor-Leste'),
('Togo', 'Togo'),
('Tokelau', 'Tokelau'),
('Tonga', 'Tonga'),
('Trinidad And Tobago', 'Trinidad And Tobago'),
('Tunisia', 'Tunisia'),
('Turkey', 'Turkey'),
('Turkmenistan', 'Turkmenistan'),
('Turks And Caicos Islands', 'Turks And Caicos Islands'),
('Tuvalu', 'Tuvalu'),
('U.S. Minor Outlying Islands', 'U.S. Minor Outlying Islands'),
('Uganda', 'Uganda'),
('Ukraine', 'Ukraine'),
('United Alab Emirates', 'United Alab Emirates'),
('United Kingdom', 'United Kingdom'),
('Uruguay', 'Uruguay'),
('Uzbekistan', 'Uzbekistan'),
('Vanuatu', 'Vanuatu'),
('Venezuela', 'Venezuela'),
('Viet Nam', 'Viet Nam'),
('Virgin Islands, British', 'Virgin Islands, British'),
('Virgin Islands, U.S.', 'Virgin Islands, U.S.'),
('Wallis And Futuna', 'Wallis And Futuna'),
('Western Sahara', 'Western Sahara'),
('Yemen', 'Yemen'),
('Zambia', 'Zambia'),
('Zimbabwe', 'Zimbabwe'),
('Other', 'Other'))
country = models.CharField(blank=True, null=True, max_length=50, choices=COUNTRY_CHOICES)
phone_number = models.CharField(blank=True, null=True, max_length=30)
extension = models.CharField(blank=True, null=True, max_length=10)
fax = models.CharField(blank=True, null=True, max_length=30)
HEAR_ABOUT_US_CHOICES = (('Direct Mail Brochure', 'Direct Mail Brochure'),
('Email Announcement', 'Email Announcement'),
('SCCME Web site', 'SCCME Web site'),
('Friend/Colleague', 'Friend/Colleague'),
('Other', 'Other, please enter:'))
hear_about_us = models.CharField(blank=True, null=True, max_length=255)
mailing_list = models.BooleanField(default=0)
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
import unittest
from textwrap import dedent
from mock import Mock, patch
from django.conf import settings
from django.test import TestCase
from django.test.utils import override_settings
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from student.models import Registration, UserProfile
from cme_registration.models import CmeUserProfile
from student.tests.factories import UserFactory
TEST_MITX_FEATURES = settings.MITX_FEATURES.copy()
TEST_MITX_FEATURES['USE_CME_REGISTRATION'] = True
@override_settings(MITX_FEATURES=TEST_MITX_FEATURES)
class TestCmeRegistration(TestCase):
"""
Check registration using CME registration functionality
"""
def setUp(self):
self.post_vars = {'username': 'testuser',
'email': 'test@email.com',
'password': '1234',
'name': 'Chester Tester',
'stanford_affiliated': '1',
'how_stanford_affiliated': 'j\'st affiliat\'d',
'honor_code': 'true',
'terms_of_service': 'true',
'profession': 'profession',
'professional_designation': 'professional_designation',
'license_number': 'license_number',
'organization': 'organization',
'patient_population': 'patient_population',
'specialty': 'specialty',
'sub_specialty': 'sub_specialty',
'address_1': 'address_1',
'address_2': 'address_2',
'city': 'city',
'state_province': 'state_province',
'postal_code': 'postal_code',
'country': 'country',
'phone_number': 'phone_number',
'extension': 'extension',
'fax': 'fax',
'hear_about_us': 'hear_about_us',
'mailing_list': 'false'}
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_badly_formed_message(self):
"""
Post itself is badly formed
"""
url = reverse('create_account')
response = self.client.post(url, {})
self.assertContains(response, '{"field": "username", "value": "Error (401 username). E-mail us.", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_profession_required(self):
"""
Profession required field
"""
self.post_vars['profession'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "profession", "value": "Choose your profession.", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_license_number_required(self):
"""
License number required field
"""
self.post_vars['license_number'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "license_number", "value": "Enter your license number.", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_patient_population_required(self):
"""
Patient population required field
"""
self.post_vars['patient_population'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "patient_population", "value": "Choose your patient population", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_specialty_required(self):
"""
Specialty required field
"""
self.post_vars['specialty'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "specialty", "value": "Choose your specialty", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_sub_specialty_not_required(self):
"""
Sub specialty not required
"""
self.post_vars['sub_specialty'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"success": true}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_address_1_required(self):
"""
Address 1 required field
"""
self.post_vars['address_1'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "address_1", "value": "Enter your Address 01", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_city_required(self):
"""
City required field
"""
self.post_vars['city'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "city", "value": "Enter your city", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_state_province_required(self):
"""
State Province required field
"""
self.post_vars['state_province'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "state_province", "value": "Choose your state/Province", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_postal_code_required(self):
"""
Postal Code required field
"""
self.post_vars['postal_code'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "postal_code", "value": "Enter your postal code", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_country_required(self):
"""
Country required field
"""
self.post_vars['country'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "country", "value": "Choose your country", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_phone_number_required(self):
"""
Phone number required field
"""
self.post_vars['phone_number'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "phone_number", "value": "Enter your phone number", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_hear_about_us_required(self):
"""
Hear about us required field
"""
self.post_vars['hear_about_us'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "hear_about_us", "value": "Choose how you heard about us", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_specialty_other(self):
"""
Specialty "other" required field
"""
self.post_vars['specialty'] = 'Other'
self.post_vars['specialty_free'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "specialty", "value": "Enter your specialty.", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_sub_specialty_other(self):
"""
Sub specialty "other" required field
"""
self.post_vars['sub_specialty'] = 'Other'
self.post_vars['sub_specialty_free'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "sub_specialty", "value": "Enter your sub-specialty.", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_hear_about_us_other(self):
"""
Hear about us "other" required field
"""
self.post_vars['hear_about_us'] = 'Other'
self.post_vars['hear_about_us_free'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "hear_about_us", "value": "Enter how you heard about us.", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_stanford_affiliated_required(self):
"""
Stanford affiliated required field
"""
del self.post_vars['stanford_affiliated']
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "stanford_affiliated", "value": "Select whether, or not, you are affiliated with Stanford.", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_honor_code_required(self):
"""
Honor code required field
"""
del self.post_vars['honor_code']
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "honor_code", "value": "To enroll, you must follow the honor code.", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_tos_required(self):
"""
TOS required field
"""
del self.post_vars['terms_of_service']
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "terms_of_service", "value": "You must accept the terms of service.", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_stanford_affiliated_choose(self):
"""
How Stanford affiliated required if stanford affiliated
"""
self.post_vars['how_stanford_affiliated'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "stanford_affiliated", "value": "Choose how you are affiliated with Stanford.", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_stanford_affiliated_other(self):
"""
Stanford affiliated "other" required field
"""
self.post_vars['how_stanford_affiliated'] = 'Other'
self.post_vars['how_stanford_affiliated_free'] = ''
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "how_stanford_affiliated", "value": "Enter how you are affiliated with Stanford.", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_db_records_created(self):
"""
Everything gets created correctly when all input data good
"""
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
#Check page displays success
self.assertContains(response, '{"success": true}')
#Check user was created
user = User.objects.filter(email='test@email.com')
self.assertEqual(1, len(user))
#Check registration was created
registration = Registration.objects.filter(user=user[0])
self.assertEqual(1, len(registration))
#Check cme_user_profile was created
cme_user_profile = CmeUserProfile.objects.filter(user=user[0],
name='Chester Tester',
stanford_affiliated=True,
how_stanford_affiliated='j\'st affiliat\'d',
profession='profession',
professional_designation='professional_designation',
license_number='license_number',
organization='organization',
patient_population='patient_population',
specialty='specialty',
sub_specialty='sub_specialty',
address_1='address_1',
address_2='address_2',
city='city',
state_province='state_province',
postal_code='postal_code',
country='country',
phone_number='phone_number',
extension='extension',
fax='fax',
hear_about_us='hear_about_us',
mailing_list=False)
self.assertEqual(1, len(cme_user_profile))
#Check user_profile was created
user_profile = UserProfile.objects.filter(user=user[0])
self.assertEqual(1, len(user_profile))
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_db_records_with_others_created(self):
"""
Everything gets created correctly when all input data good with "others"
"""
self.post_vars['how_stanford_affiliated'] = 'Other'
self.post_vars['how_stanford_affiliated_free'] = 'Wife of the provost'
self.post_vars['specialty'] = 'Other'
self.post_vars['specialty_free'] = 'Patient care'
self.post_vars['sub_specialty'] = 'Other'
self.post_vars['sub_specialty_free'] = 'Legs and feet'
self.post_vars['hear_about_us'] = 'Other'
self.post_vars['hear_about_us_free'] = 'Through the grapevine'
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
#Check page displays success
self.assertContains(response, '{"success": true}')
#Check user was created
user = User.objects.filter(email='test@email.com')
self.assertEqual(1, len(user))
#Check registration was created
registration = Registration.objects.filter(user=user[0])
self.assertEqual(1, len(registration))
#Check cme_user_profile was created
cme_user_profile = CmeUserProfile.objects.filter(user=user[0],
name='Chester Tester',
stanford_affiliated=True,
how_stanford_affiliated='Wife of the provost',
profession='profession',
license_number='license_number',
patient_population='patient_population',
specialty='Patient care',
sub_specialty='Legs and feet',
address_1='address_1',
city='city',
state_province='state_province',
postal_code='postal_code',
country='country',
phone_number='phone_number',
hear_about_us='Through the grapevine')
self.assertEqual(1, len(cme_user_profile))
#Check user_profile was created
user_profile = UserProfile.objects.filter(user=user[0])
self.assertEqual(1, len(user_profile))
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_valid_email(self):
"""
Email address conforms
"""
self.post_vars['email'] = 'garbage_email_string'
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "email", "value": "Valid e-mail is required.", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_valid_username(self):
"""
Username conforms
"""
self.post_vars['username'] = ' $%$%$# '
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "username", "value": "Username should only consist of A-Z and 0-9, with no spaces.", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_dupe_username(self):
"""
Username not already existing
"""
UserFactory.create(username="student001", email="student001@test.com")
self.post_vars['username'] = 'student001'
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertContains(response, '{"field": "username", "value": "An account with the Public Username \'student001\' already exists.", "success": false}')
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_register_when_logged_in(self):
"""
Must be logged out to register
"""
user = UserFactory.create(username="student002", email="student002@test.com")
self.client.login(username=user.username, password='test')
url = reverse('register_user')
response = self.client.post(url, {})
self.assertRedirects(response, reverse('dashboard'), status_code=302)
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_register_page_loads(self):
"""
CME Register page itself renders
"""
url = reverse('register_user')
response = self.client.post(url, {})
self.assertEqual(response.status_code, 200)
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_reroute_activation_email(self):
"""
Registration successful with reroute activation email true
"""
settings.MITX_FEATURES['REROUTE_ACTIVATION_EMAIL'] = 'a@b.edu'
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
#Check page displays success
self.assertContains(response, '{"success": true}')
@patch('cme_registration.models.CmeUserProfile.save', Mock(side_effect=Exception()))
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_save_profile_exception(self):
"""
Profile doesn't get created on exception
"""
url = reverse('create_account')
self.client.post(url, self.post_vars)
cme_user_profile = CmeUserProfile.objects.filter(name='Chester Tester')
self.assertEqual(0, len(cme_user_profile))
@patch('django.contrib.auth.models.User.email_user', Mock(side_effect=Exception()))
@unittest.skipIf(settings.MITX_FEATURES.get('DISABLE_CME_REGISTRATION_TESTS', False),
dedent("""Skipping Test because the url is not in CMS"""))
def test_activation_email_exception(self):
"""
Exception if activation email not sent
"""
url = reverse('create_account')
response = self.client.post(url, self.post_vars)
self.assertRaises(Exception)
self.assertContains(response, 'Could not send activation e-mail.')
"""
CME Registration methods
"""
import json
import logging
from statsd import statsd
from django_future.csrf import ensure_csrf_cookie
from django.conf import settings
from django.core.validators import validate_email, validate_slug, ValidationError
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.contrib.auth import authenticate, login
from django.shortcuts import redirect
from django.core.urlresolvers import reverse
from django.db import IntegrityError
from django.core.mail import send_mail
from student.models import Registration
from cme_registration.models import CmeUserProfile
from mitxmako.shortcuts import render_to_response, render_to_string
log = logging.getLogger("mitx.student")
@ensure_csrf_cookie
def cme_register_user(request, extra_context=None):
"""
This view will display the non-modal registration form which has been customised
from the standard registration form for CME.
"""
if request.user.is_authenticated():
return redirect(reverse('dashboard'))
context = {
'course_id': request.GET.get('course_id'),
'enrollment_action': request.GET.get('enrollment_action'),
'patient_population_choices': PATIENT_POPULATION_CHOICES,
'specialty_choices': SPECIALTY_CHOICES,
'sub_specialty_choices': SUB_SPECIALTY_CHOICES
}
if extra_context is not None:
context.update(extra_context)
return render_to_response('cme_register.html', context)
@ensure_csrf_cookie
def cme_create_account(request, post_override=None):
'''
JSON call to create new edX account; modified for the CME registration form.
Used by form in signup_modal.html, which is included into navigation.html
'''
json_string = {'success': False}
post_vars = post_override if post_override else request.POST
# Confirm we have a properly formed request
for var in ['username', 'email', 'password', 'name']:
if var not in post_vars:
json_string['value'] = "Error (401 {field}). E-mail us.".format(field=var)
json_string['field'] = var
return HttpResponse(json.dumps(json_string))
#Validate required felds
error = validate_required_fields(post_vars)
if error is not None:
return HttpResponse(json.dumps(error))
#Validate required check boxes
error = validate_required_boxes(post_vars)
if error is not None:
return HttpResponse(json.dumps(error))
#Validate required radio buttons
error = validate_required_radios(post_vars)
if error is not None:
return HttpResponse(json.dumps(error))
#Validate required secondary fields
error = validate_required_secondaries(post_vars)
if error is not None:
return HttpResponse(json.dumps(error))
#Validate email address
try:
validate_email(post_vars['email'])
except ValidationError:
json_string['value'] = "Valid e-mail is required."
json_string['field'] = 'email'
return HttpResponse(json.dumps(json_string))
#Validate username conforms
try:
validate_slug(post_vars['username'])
except ValidationError:
json_string['value'] = "Username should only consist of A-Z and 0-9, with no spaces."
json_string['field'] = 'username'
return HttpResponse(json.dumps(json_string))
# Ok, looks like everything is legit. Create the account.
ret = _do_cme_create_account(post_vars)
if isinstance(ret, HttpResponse): # if there was an error then return that
return ret
(user, cme_user_profile, registration) = ret
email_dict = {
'name': post_vars['name'],
'key': registration.activation_key,
}
# composes activation email
subject = render_to_string('emails/activation_email_subject.txt', email_dict)
# Email subject *must not* contain newlines
subject = ''.join(subject.splitlines())
message = render_to_string('emails/activation_email.txt', email_dict)
try:
if settings.MITX_FEATURES.get('REROUTE_ACTIVATION_EMAIL'):
dest_addr = settings.MITX_FEATURES['REROUTE_ACTIVATION_EMAIL']
message = ("Activation for %s (%s): %s\n" % (user, user.email, cme_user_profile.name) +
'-' * 80 + '\n\n' + message)
send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [dest_addr], fail_silently=False)
else:
user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
except:
log.warning('Unable to send activation email to user', exc_info=True)
json_string['value'] = 'Could not send activation e-mail.'
return HttpResponse(json.dumps(json_string))
# Immediately after a user creates an account, we log them in. They are only
# logged in until they close the browser. They can't log in again until they click
# the activation link from the email.
login_user = authenticate(username=post_vars['username'], password=post_vars['password'])
login(request, login_user)
request.session.set_expiry(0)
statsd.increment("common.student.account_created")
json_string = {'success': True}
HttpResponse(json.dumps(json_string), mimetype="application/json")
response = HttpResponse(json.dumps({'success': True}))
return response
def _do_cme_create_account(post_vars):
"""
Given cleaned post variables, create the User, UserProfile and CmeUserProfile objects, as well as the
registration for this user.
Returns a tuple (User, CmeUserProfile, Registration).
Since CmeUserProfile is implemented using multi-table inheritence of UserProfile, the CmeUserProfile object
will also contain all the UserProfile fields.
"""
user = User(username=post_vars['username'],
email=post_vars['email'],
is_active=False)
user.set_password(post_vars['password'])
registration = Registration()
# @todo: Rearrange so that if part of the process fails, the whole process fails.
# Right now, we can have e.g. no registration e-mail sent out and a zombie account
try:
user.save()
except IntegrityError:
json_string = {'success': False}
# Figure out the cause of the integrity error
if len(User.objects.filter(username=post_vars['username'])) > 0:
json_string['value'] = "An account with the Public Username '" + post_vars['username'] + "' already exists."
json_string['field'] = 'username'
return HttpResponse(json.dumps(json_string))
if len(User.objects.filter(email=post_vars['email'])) > 0:
json_string['value'] = "An account with the Email '" + post_vars['email'] + "' already exists."
json_string['field'] = 'email'
return HttpResponse(json.dumps(json_string))
registration.register(user)
cme_user_profile = CmeUserProfile(user=user)
#UserProfile fields
cme_user_profile.name = post_vars['name']
#CmeUserProfile fields
cme_user_profile.profession = post_vars.get('profession')
cme_user_profile.professional_designation = post_vars.get('professional_designation')
cme_user_profile.license_number = post_vars.get('license_number')
cme_user_profile.organization = post_vars.get('organization')
cme_user_profile.stanford_affiliated = True if post_vars.get('stanford_affiliated') == '1' else False
if post_vars.get('how_stanford_affiliated') == 'Other':
cme_user_profile.how_stanford_affiliated = post_vars.get('how_stanford_affiliated_free')
else:
cme_user_profile.how_stanford_affiliated = post_vars.get('how_stanford_affiliated')
cme_user_profile.patient_population = post_vars.get('patient_population')
if post_vars.get('specialty') == 'Other':
cme_user_profile.specialty = post_vars.get('specialty_free')
else:
cme_user_profile.specialty = post_vars.get('specialty')
if post_vars.get('sub_specialty') == 'Other':
cme_user_profile.sub_specialty = post_vars.get('sub_specialty_free')
else:
cme_user_profile.sub_specialty = post_vars.get('sub_specialty')
cme_user_profile.address_1 = post_vars.get('address_1')
cme_user_profile.address_2 = post_vars.get('address_2')
cme_user_profile.city = post_vars.get('city')
cme_user_profile.state_province = post_vars.get('state_province')
cme_user_profile.postal_code = post_vars.get('postal_code')
cme_user_profile.country = post_vars.get('country')
cme_user_profile.phone_number = post_vars.get('phone_number')
cme_user_profile.extension = post_vars.get('extension')
cme_user_profile.fax = post_vars.get('fax')
if post_vars.get('hear_about_us') == 'Other':
cme_user_profile.hear_about_us = post_vars.get('hear_about_us_free')
else:
cme_user_profile.hear_about_us = post_vars.get('hear_about_us')
cme_user_profile.mailing_list = 1 if post_vars.get('mailing_list') == 'true' else 0
try:
cme_user_profile.save()
except Exception:
log.exception("UserProfile creation failed for user {0}.".format(user.email))
return (user, cme_user_profile, registration)
def validate_required_fields(post_vars):
"""
Checks that required free text fields contain at least 2 chars
`post_vars` is dict of post parameters (a `dict`)
Returns a dict indicating failure, field and message on empty field else None
"""
#Add additional required fields here
required_fields_dict = {'username': 'Username must be minimum of two characters long.',
'email': 'A properly formatted e-mail is required.',
'name': 'Your legal name must be a minimum of two characters long.',
'password': 'A valid password is required.',
'profession': 'Choose your profession.',
'license_number': 'Enter your license number.',
'patient_population': 'Choose your patient population',
'specialty': 'Choose your specialty',
'address_1': 'Enter your Address 01',
'city': 'Enter your city',
'state_province': 'Choose your state/Province',
'postal_code': 'Enter your postal code',
'country': 'Choose your country',
'phone_number': 'Enter your phone number',
'hear_about_us': 'Choose how you heard about us'
}
error = {}
for k, val in required_fields_dict.items():
if len(post_vars.get(k)) < 2:
error['success'] = False
error['value'] = val
error['field'] = k
return error
def validate_required_boxes(post_vars):
"""
Checks that required check boxes are checked
`post_vars is dict of post parameters (a `dict)
Returns a dict indicating failure, field and message on empty field else None
"""
#Add additional required boxes here
required_boxes_dict = {'terms_of_service': 'You must accept the terms of service.',
'honor_code': 'To enroll, you must follow the honor code.',
}
error = {}
for k, val in required_boxes_dict.items():
if post_vars.get(k, 'false') != u'true':
error['success'] = False
error['value'] = val
error['field'] = k
return error
def validate_required_secondaries(post_vars):
"""
Checks that required "secondary" text fields contain at least 2 chars. A secondary field is one that appears on the form if
the user chooses a particular value in the corresponding primary. E.g. if "Other" chosen in sub_specialty then the
sub_specialty_free secondary field pops up on the registration form.
`post_vars is dict of post parameters (a `dict)
Returns a dict indicating failure, field and message on empty field else None
"""
#Add additional required secondaries here
required_secondaries_dict = {'stanford_affiliated': ('1', 'how_stanford_affiliated', 'Choose how you are affiliated with Stanford.'),
'how_stanford_affiliated': ('Other', 'how_stanford_affiliated_free', 'Enter how you are affiliated with Stanford.'),
'specialty': ('Other', 'specialty_free', 'Enter your specialty.'),
'sub_specialty': ('Other', 'sub_specialty_free', 'Enter your sub-specialty.'),
'hear_about_us': ('Other', 'hear_about_us_free', 'Enter how you heard about us.')
}
error = {}
for k, val in required_secondaries_dict.items():
if post_vars.get(k) == val[0] and len(post_vars.get(val[1])) < 2:
error['success'] = False
error['value'] = val[2]
error['field'] = k
return error
def validate_required_radios(post_vars):
"""
Checks that required radio buttons have been checked
`post_vars is dict of post parameters (a `dict)
Returns a dict indicating failure, field and message on empty field else None
"""
#Add additional required radios here
required_radios_dict = {'stanford_affiliated': 'Select whether, or not, you are affiliated with Stanford.'
}
error = {}
for k, val in required_radios_dict.items():
if k not in post_vars:
error['success'] = False
error['value'] = val
error['field'] = k
return error
#Construct dicts for specialty and sub-specialty dropdowns
SPECIALTY_CHOICES = {}
SUB_SPECIALTY_CHOICES = {}
PATIENT_POPULATION_CHOICES = (('Adult', 'Adult'),
('Pediatric', 'Pediatric'),
('Both', 'Both (Adult/Pediatric)'))
SPECIALTY_CHOICES['Adult'] = (('Addiction_Medicine', 'Addiction Medicine'),
('Allergy', 'Allergy'),
('Anesthesiology', 'Anesthesiology'),
('Cardiology', 'Cardiology'),
('Complimentary_Medicine', 'Complimentary Medicine'),
('Critical_Care_Medicine_&_ICU', 'Critical Care Medicine & ICU'),
('Dentistry', 'Dentistry'),
('Dermatology', 'Dermatology'),
('Emergency_Medicine', 'Emergency Medicine'),
('Endocrinology', 'Endocrinology'),
('Family_Practice', 'Family Practice'),
('Gastroenterology_&_Hepatology', 'Gastroenterology & Hepatology'),
('General_Practice', 'General Practice'),
('Gerontology', 'Gerontology'),
('Head_&_Neck_Surgery', 'Head & Neck Surgery'),
('Health_Education', 'Health Education'),
('Hematology', 'Hematology'),
('Immunology_&_Rheumatology', 'Immunology & Rheumatology'),
('Infectious_Disease', 'Infectious Disease'),
('Internal_Medicine', 'Internal Medicine'),
('Nephrology', 'Nephrology'),
('Neurology', 'Neurology'),
('Neurosurgery', 'Neurosurgery'),
('Nutrition', 'Nutrition'),
('Obstetrics & Gynecology', 'Obstetrics & Gynecology'),
('Oncology', 'Oncology'),
('Ophthalmology', 'Ophthalmology'),
('Orthopaedic_Surgery', 'Orthopaedic Surgery'),
('Palliative_Care', 'Palliative Care'),
('Pathology', 'Pathology'),
('Pharmacology', 'Pharmacology'),
('Physical_Medicine_&_Rehabilitation', 'Physical Medicine & Rehabilitation'),
('Psychiatry', 'Psychiatry'),
('Psychology', 'Psychology'),
('Public_Health', 'Public Health'),
('Pulmonology', 'Pulmonology'),
('Radiology', 'Radiology'),
('Radiation_Oncology', 'Radiation Oncology'),
('Surgery', 'Surgery'),
('Transplant', 'Transplant'),
('Urology', 'Urology'))
SPECIALTY_CHOICES['Pediatric'] = (('Addiction_Medicine', 'Addiction Medicine'),
('Adolescent_Medicine', 'Adolescent Medicine'),
('Allergy', 'Allergy'),
('Anesthesiology', 'Anesthesiology'),
('Cardiology', 'Cardiology'),
('Complimentary_Medicine', 'Complimentary Medicine'),
('Critical_Care_Medicine_&_ICU', 'Critical Care Medicine & ICU'),
('Dentistry', 'Dentistry'),
('Dermatology', 'Dermatology'),
('Emergency_Medicine', 'Emergency Medicine'),
('Endocrinology', 'Endocrinology'),
('Family_Practice', 'Family Practice'),
('Gastroenterology_&_Hepatology', 'Gastroenterology & Hepatology'),
('General_Practice', 'General Practice'),
('Head_&_Neck_Surgery', 'Head & Neck Surgery'),
('Health_Education', 'Health Education'),
('Hematology', 'Hematology'),
('Immunology_&_Rheumatology', 'Immunology & Rheumatology'),
('Infectious_Disease', 'Infectious Disease'),
('Internal_Medicine', 'Internal Medicine'),
('Neonatology', 'Neonatology'),
('Nephrology', 'Nephrology'),
('Neurology', 'Neurology'),
('Neurosurgery', 'Neurosurgery'),
('Nutrition', 'Nutrition'),
('Obstetrics_&_Gynecology', 'Obstetrics & Gynecology'),
('Oncology', 'Oncology'),
('Ophthalmology', 'Ophthalmology'),
('Orthopaedic_Surgery', 'Orthopaedic Surgery'),
('Pathology', 'Pathology'),
('Pediatrics', 'Pediatrics'),
('Pharmacology', 'Pharmacology'),
('Physical_Medicine_&_Rehabilitation', 'Physical Medicine & Rehabilitation'),
('Psychiatry', 'Psychiatry'),
('Psychology', 'Psychology'),
('Public_Health', 'Public Health'),
('Pulmonology', 'Pulmonology'),
('Radiology', 'Radiology'),
('Radiation_Oncology', 'Radiation Oncology'),
('Surgery', 'Surgery'),
('Transplant', 'Transplant'),
('Urology', 'Urology'),
('Other', 'Other, please enter:'))
SPECIALTY_CHOICES['Both'] = (('Addiction_Medicine', 'Addiction Medicine'),
('Adolescent_Medicine', 'Adolescent Medicine'),
('Allergy', 'Allergy'),
('Anesthesiology', 'Anesthesiology'),
('Cardiology', 'Cardiology'),
('Complimentary_Medicine', 'Complimentary Medicine'),
('Critical_Care_Medicine_&_ICU', 'Critical Care Medicine & ICU'),
('Dentistry', 'Dentistry'),
('Dermatology', 'Dermatology'),
('Emergency_Medicine', 'Emergency Medicine'),
('Endocrinology', 'Endocrinology'),
('Family_Practice', 'Family Practice'),
('Gastroenterology_&_Hepatology', 'Gastroenterology & Hepatology'),
('General_Practice', 'General Practice'),
('Gerontology', 'Gerontology'),
('Head_&_Neck_Surgery', 'Head & Neck Surgery'),
('Health_Education', 'Health Education'),
('Hematology', 'Hematology'),
('Immunology_&_Rheumatology', 'Immunology & Rheumatology'),
('Infectious_Disease', 'Infectious Disease'),
('Internal_Medicine', 'Internal Medicine'),
('Neonatology', 'Neonatology'),
('Nephrology', 'Nephrology'),
('Neurology', 'Neurology'),
('Neurosurgery', 'Neurosurgery'),
('Nutrition', 'Nutrition'),
('Obstetrics_&_Gynecology', 'Obstetrics & Gynecology'),
('Oncology', 'Oncology'),
('Ophthalmology', 'Ophthalmology'),
('Orthopaedic_Surgery', 'Orthopaedic Surgery'),
('Palliative_Care', 'Palliative Care'),
('Pathology', 'Pathology'),
('Pediatrics', 'Pediatrics'),
('Pharmacology', 'Pharmacology'),
('Physical_Medicine_&_Rehabilitation', 'Physical Medicine & Rehabilitation'),
('Psychiatry', 'Psychiatry'),
('Psychology', 'Psychology'),
('Public_Health', 'Public Health'),
('Pulmonology', 'Pulmonology'),
('Radiology', 'Radiology'),
('Radiation_Oncology', 'Radiation Oncology'),
('Surgery', 'Surgery'),
('Transplant', 'Transplant'),
('Urology', 'Urology'),
('Other', 'Other, please enter:'))
SUB_SPECIALTY_CHOICES['Cardiology'] = (('Cardiopulmonary', 'Cardiopulmonary'),
('Cardiothoracic', 'Cardiothoracic'),
('Cardiovascular_Disease', 'Cardiovascular Disease'),
('Cath_Angio_Lab', 'Cath Angio/Lab'),
('Electrophysiology', 'Electrophysiology'),
('Interventional_Cardiology', 'Interventional Cardiology'),
('Surgery', 'Surgery'),
('Vascular', 'Vascular'),
('Other', 'Other, please enter:'))
SUB_SPECIALTY_CHOICES['Internal_Medicine'] = (('Cardiology', 'Cardiology'),
('Dermatology', 'Dermatology'),
('Endocrinology_Gerontology_&_Metabolism', 'Endocrinology, Gerontology & Metabolism'),
('Gastroenterology_&_Hepatology', 'Gastroenterology & Hepatology'),
('Hematology', 'Hematology'),
('Immunology_&_Rheumatology', 'Immunology & Rheumatology'),
('Infectious_Disease', 'Infectious Disease'),
('Nephrology', 'Nephrology'),
('Preventative_Medicine', 'Preventative Medicine'),
('Pulmonary', 'Pulmonary'),
('Other', 'Other, please enter:'))
SUB_SPECIALTY_CHOICES['Obstetrics_Gynecology'] = (('Gynecology', 'Gynecology'),
('Obstetrics', 'Obstetrics'),
('Maternal_&_Fetal_Medicine', 'Maternal & Fetal Medicine'),
('Women_Health', 'Women\'s Health'),
('Other', 'Other, please enter:'))
SUB_SPECIALTY_CHOICES['Oncology'] = (('Breast', 'Breast'),
('Gastroenterology', 'Gastroenterology'),
('Gynecology', 'Gynecology'),
('Hematology', 'Hematology'),
('Medical', 'Medical'),
('Radiation', 'Radiation'),
('Surgical', 'Surgical'),
('Urology', 'Urology'),
('Other', 'Other, please enter:'))
SUB_SPECIALTY_CHOICES['Palliative_Care'] = (('Hospice', 'Hospice'),
('Other', 'Other, please enter:'))
SUB_SPECIALTY_CHOICES['Pediatrics'] = (('Adolescent_Medicine', 'Adolescent Medicine'),
('Allergy', 'Allergy'),
('Anesthesiology', 'Anesthesiology'),
('Cardiac_Surgery', 'Cardiac Surgery'),
('Cardiology', 'Cardiology'),
('Critical_Care', 'Critical Care'),
('Dermatology', 'Dermatology'),
('Emergency', 'Emergency'),
('Endocrinology', 'Endocrinology'),
('Family Practice', 'Family Practice'),
('Gastroenterology', 'Gastroenterology'),
('Hematology_&_Oncology', 'Hematology & Oncology'),
('Immunology_&_Rheumatology', 'Immunology & Rheumatology'),
('Internal_Medicine', 'Internal Medicine'),
('Infectious_Disease', 'Infectious Disease'),
('Neonatology', 'Neonatology'),
('Nephrology', 'Nephrology'),
('Neurology', 'Neurology'),
('Obstetrics_&_Gynecology', 'Obstetrics & Gynecology'),
('Otolaryngology_Head_&_Neck', 'Otolaryngology/ Head & Neck'),
('Oncology', 'Oncology'),
('Ophthalmology', 'Ophthalmology'),
('Orthopaedic_Surgery', 'Orthopaedic Surgery'),
('Osteopathy', 'Osteopathy'),
('Pathology', 'Pathology'),
('Pediatric_Intensive_Care', 'Pediatric Intensive Care'),
('Psychiatry', 'Psychiatry'),
('Psychology', 'Psychology'),
('Pulmonary', 'Pulmonary'),
('Radiology', 'Radiology'),
('Surgery', 'Surgery'),
('Urology', 'Urology'),
('Other', 'Other, please enter:'))
SUB_SPECIALTY_CHOICES['Pulmonology'] = (('Critical_Care', 'Critical Care'),
('Respiratory', 'Respiratory'),
('Other', 'Other, please enter:'))
SUB_SPECIALTY_CHOICES['Surgery'] = (('Bariatric_Surgery', 'Bariatric Surgery'),
('Cardiac_Surgery', 'Cardiac Surgery'),
('Cardiothoracic_Surgery', 'Cardiothoracic Surgery'),
('Colon_&_Rectal_Surgery', 'Colon & Rectal Surgery'),
('Emergency_Medicine', 'Emergency Medicine'),
('Gastrointestinal_Surgery', 'Gastrointestinal Surgery'),
('Neurosurgery', 'Neurosurgery'),
('Oral_&_Maxillofacial_Surgery', 'Oral & Maxillofacial Surgery'),
('Orthopaedic_Surgery', 'Orthopaedic Surgery'),
('Plastic_&_Reconstructive_Surgery', 'Plastic & Reconstructive Surgery'),
('Surgical_Critical_Care', 'Surgical Critical Care'),
('Surgical_Oncology', 'Surgical Oncology'),
('Thoracic_Surgery', 'Thoracic Surgery'),
('Trauma_Surgery', 'Trauma Surgery'),
('Upper_Extremity_Hand_Surgery', 'Upper Extremity/ Hand Surgery'),
('Vascular_Surgery', 'Vascular Surgery'),
('Other', 'Other, please enter:'))
SUB_SPECIALTY_CHOICES['Transplant'] = (('Solid_Organ', 'Solid Organ'),
('Blood_and_Bone_Marrow', 'Blood and Bone Marrow'),
('Other', 'Other, please enter:'))
......@@ -56,7 +56,7 @@ from courseware.access import has_access
from external_auth.models import ExternalAuthMap
from bulk_email.models import Optout
from cme_registration.views import cme_register_user, cme_create_account
import track.views
from statsd import statsd
......@@ -242,6 +242,9 @@ def register_user(request, extra_context=None):
"""
This view will display the non-modal registration form
"""
if settings.MITX_FEATURES.get('USE_CME_REGISTRATION'):
return cme_register_user(request, extra_context=extra_context)
if request.user.is_authenticated():
return redirect(reverse('dashboard'))
......@@ -599,6 +602,9 @@ def create_account(request, post_override=None):
JSON call to create new edX account.
Used by form in signup_modal.html, which is included into navigation.html
"""
if settings.MITX_FEATURES.get('USE_CME_REGISTRATION'):
return cme_create_account(request, post_override=post_override)
js = {'success': False}
post_vars = post_override if post_override else request.POST
......
......@@ -48,6 +48,9 @@ class LoginEnrollmentTestCase(TestCase):
Provides support for user creation,
activation, login, and course enrollment.
"""
def setUp(self):
from django.conf import settings
def setup_user(self):
"""
Create a user account, activate, and log in.
......
......@@ -172,6 +172,9 @@ MITX_FEATURES = {
# Toggle storing detailed billing information
'STORE_BILLING_INFO': False,
#Toggle using CME registration instead of normal
'USE_CME_REGISTRATION': False
}
# Used for A/B testing
......@@ -836,6 +839,10 @@ INSTALLED_APPS = (
# Student Identity Verification
'verify_student',
# CME Registration
'cme_registration',
)
######################### MARKETING SITE ###############################
......
......@@ -211,11 +211,11 @@
fieldset {
margin: 0;
padding-top: 0;
padding-bottom: $baseline;
padding-bottom: $baseline*2;
}
.list-input {
margin: 0;
margin: 0 0 0 25px;
padding: 0;
list-style: none;
}
......@@ -305,9 +305,9 @@
}
// types - checkboxes/radio buttons
&.checkbox {
&.checkbox, .radio {
input[type="checkbox"] {
input[type="checkbox"], input[type="radio"] {
display: inline-block;
width: auto;
margin-right: ($baseline/4);
......
<%inherit file="main.html" />
<%namespace name='static' file='static_content.html'/>
<%namespace file='main.html' import="login_query"/>
<%! from django.core.urlresolvers import reverse %>
<%! from django.utils import html %>
<%! from django_countries.countries import COUNTRIES %>
<%! from django.utils.translation import ugettext as _ %>
<%! from student.models import UserProfile %>
<%! from cme_registration.models import CmeUserProfile %>
<%! from datetime import date %>
<%! import calendar %>
<%block name="title"><title>Register for ${settings.PLATFORM_NAME}</title></%block>
<%block name="js_extra">
<script type="text/javascript">
$(function() {
var view_name = 'view-register';
// adding js class for styling with accessibility in mind
$('body').addClass('js').addClass(view_name);
// new window/tab opening
$('a[rel="external"], a[class="new-vp"]')
.click( function() {
window.open( $(this).attr('href') );
return false;
});
// form field label styling on focus
$("form :input").focus(function() {
$("label[for='" + this.id + "']").parent().addClass("is-focused");
}).blur(function() {
$("label").parent().removeClass("is-focused");
});
// display dependent form sections
$('input.controller-show').click(function() {
$(this).parent().siblings('.controlled').slideDown('fast');
});
$('input.controller-hide').click(function() {
$(this).parent().siblings('.controlled').slideUp('fast');
});
$('select.controller').change(function() {
if ($(this).children("option:selected").val() === 'Other') {
$(this).siblings('.controlled').slideDown('fast');
} else {
$(this).siblings('.controlled').slideUp('fast');
}
});
$('select.select-controller').change(function() {
var controllerClasses = $(this).children("option:selected").attr('class');
var controllerClass = controllerClasses.split(' ')[0];
var controlledFieldContents = '#' + controllerClass;
var controlledField = '#' + controllerClass.split('-')[0];
$(controlledField).html('<option value="">--</option>').siblings('.controlled').hide().children('input').val('');
$(controlledField).parent().hide();
var controllerClass2 = '#' + controllerClasses.split(' ')[1];
$(controllerClass2).html('<option value="">--</option>').siblings('.controlled').hide().children('input').val('');
$(controllerClass2).parent().hide();
if ($(controlledFieldContents).html() != null) {
$(controlledField).html($(controlledFieldContents).html()).parent().show();
}
});
});
(function() {
toggleSubmitButton(true);
$('#register-form').on('submit', function() {
toggleSubmitButton(false);
});
$('#register-form').on('ajax:complete', function() {
toggleSubmitButton(true);
});
$('#register-form').on('ajax:success', function(event, json, xhr) {
if(json.success) {
$('.message.submission-error').removeClass('is-shown');
location.href="${reverse('dashboard')}";
} else {
$('.status.message.submission-error').addClass('is-shown').focus();
$('.status.message.submission-error .message-copy').html(json.value).stop().css("display", "block");
$(".field-error").removeClass('field-error');
$("[data-field='"+json.field+"']").addClass('field-error')
}
});
})(this);
function toggleSubmitButton(enable) {
var $submitButton = $('form .form-actions #submit');
if(enable) {
$submitButton.
removeClass('is-disabled').
removeProp('disabled').
html('Create my ${settings.PLATFORM_NAME} Account');
}
else {
$submitButton.
addClass('is-disabled').
prop('disabled', true).
html('Processing your account information &hellip;');
}
}
</script>
</%block>
<section class="introduction">
<header>
<h1 class="sr">${_("Welcome! Register below to create your %(platform_name)s account") % {'platform_name': settings.PLATFORM_NAME}}</h1>
</header>
</section>
<section class="register container">
<section role="main" class="content">
<form role="form" id="register-form" method="post" data-remote="true" action="${reverse('create_account')}" novalidate>
<!-- status messages -->
<div role="alert" class="status message">
<h3 class="message-title">We're sorry, ${settings.PLATFORM_NAME} enrollment is not available in your region</h3>
<p class="message-copy">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
</div>
<div role="alert" class="status message submission-error" tabindex="-1">
<h3 class="message-title">The following errors occured while processing your registration: </h3>
<ul class="message-copy"> </ul>
</div>
<p class="instructions">
Please complete the following fields to register for an account. <br />
Required fields are noted by <strong class="indicator">bold text and an asterisk (*)</strong>.
</p>
<fieldset class="group group-form group-form-requiredinformation">
<hr />
<h3><strong>Required Information</strong></h3>
% if has_extauth_info is UNDEFINED:
<ol class="list-input">
<li class="field required text" id="field-email">
<label for="email">E-mail</label>
<input class="" id="email" type="email" name="email" value="" placeholder="example: username@domain.com" required aria-required="true" />
</li>
<li class="field required password" id="field-password">
<label for="password">Password</label>
<input id="password" type="password" name="password" value="" required aria-required="true" />
</li>
<li class="field required text" id="field-username">
<label for="username">Public Username</label>
<input id="username" type="text" name="username" value="" placeholder="example: JaneDoe" required aria-required="true" />
<span class="tip tip-input">Will be shown in any discussions or forums you participate in</span>
</li>
<li class="field required text" id="field-name">
<label for="name">Full Name</label>
<input id="name" type="text" name="name" value="" placeholder="example: Jane C Doe" required aria-required="true" />
<span class="tip tip-input">Needed for any certificates you may earn <strong>(cannot be changed later)</strong></span>
</li>
</ol>
% else:
<div class="message">
<h3 class="message-title">Welcome ${extauth_id}</h3>
<p class="message-copy">Enter a public username:</p>
</div>
<ol class="list-input">
% if ask_for_email:
<li class="field required text" id="field-email">
<label for="email">E-mail</label>
<input class="" id="email" type="email" name="email" value="" placeholder="example: username@domain.com" />
</li>
% endif
<li class="field required text" id="field-username">
<label for="username">Public Username</label>
<input id="username" type="text" name="username" value="${extauth_username}" placeholder="example: JaneDoe" required aria-required="true" />
<span class="tip tip-input">Will be shown in any discussions or forums you participate in</span>
</li>
% if ask_for_fullname:
<li class="field required text" id="field-name">
<label for="name">Full Name</label>
<input id="name" type="text" name="name" value="" placeholder="example: Jane Doe" />
<span class="tip tip-input">Needed for any certificates you may earn <strong>(cannot be changed later)</strong></span>
</li>
% endif
</ol>
% endif
</fieldset>
<fieldset class="group group-form group-form-secondary group-form-personalinformation">
<hr />
<h3><strong>Professional Information</strong></h3>
<ol class="list-input">
<li class="field required text" id="field-profession">
<label for="profession">Profession</label>
<select id="profession" name="profession">
<option value="">--</option>
%for code, profession in CmeUserProfile.PROFESSION_CHOICES:
<option value="${code}">${profession}</option>
%endfor
</select>
</li>
<li class="field select" id="field-professional-designation">
<label for="professional_designation">Professional Designation</label>
<select id="professional_designation" name="professional_designation">
<option value="">--</option>
%for code, professional_designation in CmeUserProfile.PROFESSIONAL_DESIGNATION_CHOICES:
<option value="${code}">${professional_designation}</option>
%endfor
</select>
</li>
<li class="field required text" id="license-number">
<label for="license_number">License Number</label>
<input id="license_number" type="text" name="license_number" />
</li>
</ol>
</fieldset>
<fieldset class="group group-form group-form-secondary group-form-organizationinformation">
<hr />
<h3><strong>Organization Information</strong></h3>
<ol class="list-input">
<li class="field select" id="organization">
<label for="organization">Organization</label>
<input id="organization" type="text" name="organization" />
</li>
<li class="field required" id="stanford_affiliated">
<label for="stanford_affiliated">Are you affiliated with Stanford?</label>
<div class="field select radio " id="is_stanford_affiliated">
<span><input id="stanford_affiliated_yes" class="controller-show" type="radio" value="1" name="stanford_affiliated" aria-label="Yes" /> Yes</span>
<span><input id="stanford_affiliated_no" class="controller-hide" type="radio" value="0" name="stanford_affiliated" aria-label="No" style="margin-left: 50px;" /> No</span>
<div class="field select controlled" id="how_stanford_affiliated" style="display: none;">
<br />
<label for="how_stanford_affiliated">How are you affiliated with Stanford?</label>
<select class="controller" id="how_stanford_affiliated" name="how_stanford_affiliated">
<option value="">--</option>
% for code, how_stanford_affiliated in CmeUserProfile.HOW_STANFORD_AFFILIATED_CHOICES:
% if code == "Other, please enter:":
<option value="${code}" class="controller-show">${how_stanford_affiliated}</option>
% else:
<option value="${code}" class="controller-hide">${how_stanford_affiliated}</option>
% endif
% endfor
</select>
<div class="field controlled" id="how_stanford_affililiated_free_container" style="display: none;">
<br />
<input id="how_stanford_affililiated_free" type="text" name="how_stanford_affiliated_free" title="Please enter how you are affiliated with Stanford here." />
</div>
</div>
</div>
</li>
</ol>
</fieldset>
<fieldset class="group group-form group-form-secondary group-form-patientinformation">
<hr />
<h3><strong>Your Patient Information</strong></h3>
<ol class="list-input">
<li class="field required" id="patient_population">
<label for="patient_population">Patient population</label>
<select id="patient_population" name="patient_population" class="select-controller">
<option value="">--</option>
%for code, patient_population in patient_population_choices:
<option value="${code}" class="specialty-${code} sub_specialty">${patient_population}</option>
%endfor
</select>
</li>
#####################################################
## Specialty Select Field
#####################################################
<li class="field required" style="display: none;">
<label for="specialty">Specialty</label>
<select id="specialty" name="specialty" class="controller select-controller">
<option value="">--</option>
</select>
<div class="field controlled" id="specialty_free_container" style="display: none;">
<br />
<input id="specialty_free" type="text" name="specialty_free" title="Please enter your Specialty here." />
</div>
</li>
<div id="specialty-Adult" class="specialty-container" style="display: none;">
<option value="">--</option>
%for code, specialty in specialty_choices['Adult']:
<option value="${code}" class="sub_specialty-${code}">${specialty}</option>
%endfor
</div>
<div id="specialty-Pediatric" class="specialty-container" style="display: none;">
<option value="">--</option>
%for code, specialty in specialty_choices['Pediatric']:
<option value="${code}" class="sub_specialty-${code}">${specialty}</option>
%endfor
</div>
<div id="specialty-Both" class="specialty-container" style="display: none;">
<option value="">--</option>
%for code, specialty in specialty_choices['Both']:
<option value="${code}" class="sub_specialty-${code}">${specialty}</option>
%endfor
</div>
#####################################################
## Sub Specialty Select Field
#####################################################
<li class="field" style="display: none;">
<label for="sub_specialty">Sub-Specialty</label>
<select id="sub_specialty" name="sub_specialty" class="controller">
<option value="">--</option>
</select>
<div class="field controlled" id="sub_specialty_free_container" style="display: none;">
<br />
<input id="sub_specialty_free" type="text" name="sub_specialty_free" title="Please enter your Sub-Specialty here." />
</div>
</li>
<div id="sub_specialty-Cardiology" class="sub_specialty-container" style="display: none;">
<option value="">--</option>
%for code, sub_specialty in sub_specialty_choices['Cardiology']:
<option value="${code}">${sub_specialty}</option>
%endfor
</div>
<div id="sub_specialty-Internal_Medicine" class="sub_specialty-container" style="display: none;">
<option value="">--</option>
%for code, sub_specialty in sub_specialty_choices['Internal_Medicine']:
<option value="${code}">${sub_specialty}</option>
%endfor
</div>
<div id="sub_specialty-Obstetrics_Gynecology" class="sub_specialty-container" style="display: none;">
<option value="">--</option>
%for code, sub_specialty in sub_specialty_choices['Obstetrics_Gynecology']:
<option value="${code}">${sub_specialty}</option>
%endfor
</div>
<div id="sub_specialty-Oncology" class="sub_specialty-container" style="display: none;">
<option value="">--</option>
%for code, sub_specialty in sub_specialty_choices['Oncology']:
<option value="${code}">${sub_specialty}</option>
%endfor
</div>
<div id="sub_specialty-Palliative_Care" class="sub_specialty-container" style="display: none;">
<option value="">--</option>
%for code, sub_specialty in sub_specialty_choices['Palliative_Care']:
<option value="${code}">${sub_specialty}</option>
%endfor
</div>
<div id="sub_specialty-Pediatrics" class="sub_specialty-container" style="display: none;">
<option value="">--</option>
%for code, sub_specialty in sub_specialty_choices['Pediatrics']:
<option value="${code}">${sub_specialty}</option>
%endfor
</div>
<div id="sub_specialty-Pulmonology" class="sub_specialty-container" style="display: none;">
<option value="">--</option>
%for code, sub_specialty in sub_specialty_choices['Pulmonology']:
<option value="${code}">${sub_specialty}</option>
%endfor
</div>
<div id="sub_specialty-Surgery" class="sub_specialty-container" style="display: none;">
<option value="">--</option>
%for code, sub_specialty in sub_specialty_choices['Surgery']:
<option value="${code}">${sub_specialty}</option>
%endfor
</div>
<div id="sub_specialty-Transplant" class="sub_specialty-container" style="display: none;">
<option value="">--</option>
%for code, sub_specialty in sub_specialty_choices['Transplant']:
<option value="${code}">${sub_specialty}</option>
%endfor
</div>
</ol>
</fieldset>
<fieldset class="group group-form group-form-secondary group-form-personalinformation">
<hr />
<h3><strong>Professional Contact Information</strong></h3>
<ol class="list-input">
<li class="field required" id="address_1">
<label for="address_1">Address 1</label>
<input id="address_1" type="text" name="address_1" />
</li>
<li class="field select" id="address_2">
<label for="address_2">Address 2</label>
<input id="address_2" type="text" name="address_2" />
</li>
<li class="field required" id="city">
<label for="city">City</label>
<input id="city" type="text" name="city" />
</li>
<li class="field required" id="state_province">
<label for="state_province">State/Province</label>
<select id="state_province" name="state_province">
<option value="">--</option>
%for code, state in CmeUserProfile.STATE_CHOICES:
<option value="${code}">${state}</option>
%endfor
</select>
</li>
<li class="field required" id="postal_code">
<label for="postal_code">Postal Code</label>
<input id="postal_code" type="text" name="postal_code" />
</li>
<li class="field required" id="country">
<label for="country">Country</label>
<select id="country" name="country">
<option value="">--</option>
%for code, country in CmeUserProfile.COUNTRY_CHOICES:
<option value="${code}">${country}</option>
%endfor
</select>
</li>
<li class="field required" id="phone_number">
<label for="phone_number">Phone Number</label>
<input id="phone_number" type="text" name="phone_number" />
</li>
<li class="field select" id="extension">
<label for="extension">Extension</label>
<input id="extension" type="text" name="extension" />
</li>
<li class="field select" id="fax">
<label for="fax">Fax</label>
<input id="fax" type="text" name="fax" />
</li>
<li class="field required" id="hear_about_us">
<label for="hear_about_us">How did you hear about us?</label>
<select class="controller" id="hear_about_us" name="hear_about_us">
<option value="">--</option>
%for code, about_us in CmeUserProfile.HEAR_ABOUT_US_CHOICES:
% if code == "Other, please enter:":
<option value="${code}" class="controller-show">${about_us}</option>
% else:
<option value="${code}" class="controller-hide">${about_us}</option>
% endif
%endfor
</select>
<div class="field controlled" id="hear_about_us_free" style="display: none;">
<br />
<input id="hear_about_us_free" type="text" name="hear_about_us_free" title="Please enter how you heard about us here." />
</div>
</li>
<div class="field select checkbox" id="mailing_list">
<input id="mailing_list" type="checkbox" name="mailing_list" value="true" checked />
<label for="mailing_list">Yes, include me on the mailing list for future educational activities</label>
</div>
</ol>
</fieldset>
<fieldset class="group group-form group-form-accountacknowledgements">
<hr />
<legend class="sr">Account Acknowledgements</legend>
<ol class="list-input">
<li class="field-group">
% if has_extauth_info is UNDEFINED or ask_for_tos :
<div class="field required checkbox" id="field-tos">
<input id="tos-yes" type="checkbox" name="terms_of_service" value="true" required aria-required="true" />
<label for="tos-yes">I agree to the <a href="${marketing_link('TOS')}" class="new-vp">Terms of Service</a></label>
</div>
% endif
<div class="field required checkbox" id="field-honorcode">
<input id="honorcode-yes" type="checkbox" name="honor_code" value="true" />
<%
## TODO: provide a better way to override these links
if self.stanford_theme_enabled():
honor_code_path = marketing_link('TOS') + "#honor"
else:
honor_code_path = marketing_link('HONOR')
%>
<label for="honorcode-yes">I agree to the <a href="${honor_code_path}" class="new-vp">Honor Code</a></label>
</div>
</li>
</ol>
</fieldset>
% if course_id and enrollment_action:
<input type="hidden" name="enrollment_action" value="${enrollment_action | h}" />
<input type="hidden" name="course_id" value="${course_id | h}" />
% endif
<div class="form-actions">
<button name="submit" type="submit" id="submit" class="action action-primary action-update">Register <span class="orn-plus">+</span> Create My Account</button>
</div>
</form>
</section>
<aside role="complementary">
<header>
<h3 class="sr">Registration Help</h3>
</header>
% if has_extauth_info is UNDEFINED:
<div class="cta">
<h3>Already registered?</h3>
<p class="instructions">
<a href="${reverse('signin_user')}${login_query()}">
Click here to log in.
</a>
</p>
</div>
% endif
## TODO: Use a %block tag or something to allow themes to
## override in a more generalizable fashion.
% if not self.stanford_theme_enabled():
<div class="cta cta-welcome">
<h3>Welcome to ${settings.PLATFORM_NAME}</h3>
<p>Registering with ${settings.PLATFORM_NAME} gives you access to all of our current and future free courses. Not ready to take a course just yet? Registering puts you on our mailing list – we will update you as courses are added.</p>
</div>
% endif
<div class="cta cta-nextsteps">
<h3>Next Steps</h3>
% if self.stanford_theme_enabled():
<p>You will receive an activation email. You must click on the activation link to complete the process. Don’t see the email? Check your spam folder and mark emails from class.stanford.edu as ‘not spam’, since you'll want to be able to receive email from your courses.</p>
% else:
<p>As part of joining ${settings.PLATFORM_NAME}, you will receive an activation email. You must click on the activation link to complete the process. Don’t see the email? Check your spam folder and mark ${settings.PLATFORM_NAME} emails as ‘not spam’. At ${settings.PLATFORM_NAME}, we communicate mostly through email.</p>
% endif
</div>
% if settings.MKTG_URL_LINK_MAP.get('FAQ'):
<div class="cta cta-help">
<h3>Need Help?</h3>
<p>Need help in registering with ${settings.PLATFORM_NAME}?
<a href="${marketing_link('FAQ')}">
View our FAQs for answers to commonly asked questions.
</a>
Once registered, most questions can be answered in the course specific discussion forums or through the FAQs.</p>
</div>
% endif
</aside>
</section>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment