def update_schedule_case_properties(): """ Iterate through all pact patient cases in the domain and set schedule case properties if necessary. """ case_ids = get_case_ids_in_domain('pact', 'cc_path_client') # this is intentionally not user iter_docs since pact cases are *huge* and we want to use # get_lite and only load one at a time. for case_id in case_ids: case = PactPatientCase.get_lite(case_id) set_schedule_case_properties(case)
def post(self, *args, **kwargs): from pact.models import PactPatientCase, CDotWeeklySchedule pdoc = PactPatientCase.get(self.request.GET['case_id']) resp = HttpResponse() if self.method == "rm_schedule": if self.request.POST.has_key('rm_schedule'): #hacky remove schedule method pdoc.rm_last_schedule() pdoc.save() resp.status_code = 204 return resp elif self.method == "schedule": form = ScheduleForm(data=self.request.POST) if form.is_valid(): sched = CDotWeeklySchedule() for day in DAYS_OF_WEEK: if form.cleaned_data[day] != 'None': setattr(sched, day, form.cleaned_data[day]) if form.cleaned_data['active_date'] == None: sched.started = datetime.utcnow() else: sched.started = datetime.combine(form.cleaned_data['active_date'], time.min) sched.comment = form.cleaned_data['comment'] sched.created_by = self.request.user.username sched.deprecated = False pdoc.set_schedule(sched) pdoc.save() set_schedule_case_properties(pdoc) resp.status_code = 204 return resp else: resp.write(str(form.errors)) resp.status_code = 406 return resp elif self.method == 'providers': try: submitted_provider_ids = json.loads(self.request.POST['selected_providers']) case_provider_ids = list(pdoc.get_provider_ids()) if submitted_provider_ids != case_provider_ids: try: #len difference submitted_len = len(submitted_provider_ids) case_len = len(case_provider_ids) if submitted_len < case_len: for x in range(case_len-submitted_len): submitted_provider_ids.append('') pdoc.update_providers(self.request.couch_user, submitted_provider_ids) resp.write("success") resp.status_code=204 except Exception, ex: resp.write("Error submitting: %s" % ex) resp.status_code=500 else: resp.write("") resp.status_code=304
def get(self, *args, **kwargs): from pact.models import PactPatientCase if self.request.GET.get('case_id', None) is None: raise Http404 case = PactPatientCase.get(self.request.GET['case_id']) if self.method is None: return HttpResponse("API Method unknown: no method", status=400) elif self.method == "schedule": scheds = case.get_schedules(raw_json=True) if scheds is None: scheds = [] payload = json.dumps(scheds) response = HttpResponse(payload, content_type="application/json") return response elif self.method == 'providers': providers = get_all_providers() providers = sorted( providers, key=lambda x: x.fields_without_attributes['last_name']) providers_by_id = dict((x.fields_without_attributes['id'], x.fields_without_attributes) for x in providers) case_providers = [ providers_by_id.get(x, None) for x in case.get_provider_ids() ] facilities = set() for prov in providers: facility = prov.fields_without_attributes['facility_name'] if facility is None: facility = 'N/A' facilities.add(facility) ret = { 'facilities': ['All Facilities'] + sorted(list(facilities)), "providers": [x.fields_without_attributes for x in providers], "case_providers": case_providers, } resp = HttpResponse(json.dumps(ret), content_type='application/json') return resp else: return HttpResponse("API Method unknown", status=400)
def _doTestNoPillbox(self, bundle): submit_xform(self.submit_url, self.domain.name, bundle['xml']) submitted = XFormInstance.get(bundle['xform_id']) self.assertTrue(hasattr(submitted, PACT_DOTS_DATA_PROPERTY)) observations = query_observations(CASE_ID, bundle['start_date'], bundle['end_date']) observed_dates = set() #assume to be five - 3,2 same as the regimen count, we are refilling empties self.assertEqual( 5, len(observations), msg="Observations do not match regimen count: %d != %d" % (5, len(observations))) art_nonart = set() for obs in observations: observed_dates.add(obs.observed_date) self.assertEquals( obs.day_note, "No check, from form" ) #magic string from the view to indicate a generated DOT observation from form data. art_nonart.add(obs.is_art) self.assertEquals(obs.doc_id, bundle['xform_id']) art = filter(lambda x: x.is_art, observations) self.assertEquals(2, len(art)) art_answered = filter(lambda x: x.adherence != "unchecked", art) self.assertEquals(1, len(art_answered)) nonart = filter(lambda x: not x.is_art, observations) self.assertEquals(3, len(nonart)) nonart_answered = filter(lambda x: x.adherence != "unchecked", nonart) self.assertEquals(1, len(nonart_answered)) #this only does SINGLE observations for art and non art self.assertEquals(len(observed_dates), 1) self.assertEquals(len(art_nonart), 2) # inspect the regenerated submission and ensure the built xml block is correctly filled. case_json = get_dots_case_json(PactPatientCase.get(CASE_ID), anchor_date=bundle['anchor_date']) enddate = bundle['anchor_date'] # anchor date of this submission #encounter_date = datetime.strptime(submitted.form['encounter_date'], '%Y-%m-%d') encounter_date = submitted.form['encounter_date'] for day_delta in range(DOT_DAYS_INTERVAL): obs_date = enddate - timedelta(days=day_delta) ret_index = DOT_DAYS_INTERVAL - day_delta - 1 day_arr = case_json['days'][ret_index] nonart_day_data = day_arr[0] art_day_data = day_arr[1] self.assertEquals(len(nonart_day_data), 3) self.assertEquals(len(art_day_data), 2)
def testExtendingPatientSchedule(self): test_patient = PactPatientCase() test_patient.computed_ = {} # hand make it test_patient.computed_[WEEKLY_SCHEDULE_KEY] = WEEKLY_SCHEDULE_EXAMPLES # verify that tail is <date> - null api_schedules = test_patient.get_schedules(raw_json=True) self.assertIsNone(api_schedules[-1]['ended']) self.assertEquals(api_schedules[-1]['started'], '2011-02-25T14:05:32Z') self.assertEquals(len(api_schedules), len(WEEKLY_SCHEDULE_EXAMPLES)) # add a new schedule, verify tail is <date>-present, and [-2] is <datex> - <datey> test_patient.set_schedule(CDotWeeklySchedule.wrap(NEW_SCHEDULE)) updated_schedules = test_patient.get_schedules(raw_json=True) self.assertIsNone(updated_schedules[-1]['ended']) self.assertEquals(len(updated_schedules), len(WEEKLY_SCHEDULE_EXAMPLES)+1) self.assertEquals(updated_schedules[-1]['started'][0:10], datetime.utcnow().isoformat()[0:10]) self.assertIsNotNone(updated_schedules[-2]['ended']) self.assertLess(updated_schedules[-2]['ended'], datetime.utcnow().isoformat()) # remove tail test_patient.save() loaded_patient = PactPatientCase.get(test_patient.get_id) loaded_patient.rm_last_schedule() removed_schedules = loaded_patient.get_schedules(raw_json=True) self.assertEquals(len(removed_schedules), len(WEEKLY_SCHEDULE_EXAMPLES)) self.assertIsNone(removed_schedules[-1]['ended']) self.assertEquals(removed_schedules[-1]['started'], '2011-02-25T14:05:32Z')
def testCreatePatientSchedule(self): """ Single schedule create/remove """ test_patient = PactPatientCase() test_patient.computed_ = {} test_patient.set_schedule(CDotWeeklySchedule.wrap(NEW_SCHEDULE)) schedules = test_patient.get_schedules() self.assertEqual(len(schedules), 1) self.assertIsNone(schedules[0].ended) self.assertEquals(schedules[0].started.isoformat()[0:10], datetime.utcnow().isoformat()[0:10]) self.assertTrue(schedules[0].is_current) test_patient.rm_last_schedule() updated_schedules = test_patient.get_schedules() self.assertEqual(len(updated_schedules), 0)
def recalculate_dots_data(case_id, cc_user, sync_token=None): """ Recalculate the dots data and resubmit calling the pact api for dot recompute """ from pact.models import PactPatientCase from pact.api import recompute_dots_casedata if DOT_RECOMPUTE: try: casedoc = PactPatientCase.get(case_id) recompute_dots_casedata(casedoc, cc_user, sync_token=sync_token) except Exception, ex: tb = traceback.format_exc() notify_exception(None, message="PACT error recomputing DOTS case block: %s\n%s" % (ex, tb))
def tabular_data(self, mode, case_id, start_date, end_date): #, limit=50, skip=0): try: case_doc = PactPatientCase.get(case_id) except ResourceNotFound: case_doc = None if case_doc is not None: # patient is selected startkey = [ case_id, 'anchor_date', start_date.year, start_date.month, start_date.day ] endkey = [ case_id, 'anchor_date', end_date.year, end_date.month, end_date.day ] elif case_doc is None: # patient is not selected, do all patients startkey = [start_date.year, start_date.month, start_date.day] endkey = [end_date.year, end_date.month, end_date.day] skip = 0 view_results = CObservation.view( 'pact/dots_observations', startkey=startkey, endkey=endkey, limit=COUCH_CHUNK_LIMIT, skip=skip, classes={ None: CObservation }, ).all() while len(view_results) > 0: if skip > COUCH_MAX_LIMIT: logging.error( "Pact DOT admin query: Too much data returned for query %s-%s" % (startkey, endkey)) break for v in view_results: yield v skip += COUCH_CHUNK_LIMIT view_results = CObservation.view( 'pact/dots_observations', startkey=startkey, endkey=endkey, limit=COUCH_CHUNK_LIMIT, skip=skip, classes={ None: CObservation }, ).all()
def testForA_B(self): self.testFormA() self.testFormB(verify=False) updated_case = PactPatientCase.get(CASE_ID) case_dots = updated_case.dots days = json.loads(case_dots)['days'] nonart = [["full", "pillbox", "", 0], ["empty", "pillbox", "", 3]] art = [["full", "self", "", 0], ["empty", "pillbox", "", 3]] examine_day = days[-2] self._verify_dot_cells(nonart, art, examine_day)
def report_context(self): ret = {} if 'dot_patient' not in self.request.GET or self.request.GET.get( 'dot_patient') == "": self.report_template_path = "pact/dots/dots_report_nopatient.html" return ret submit_id = self.request.GET.get('submit_id', None) ret['dot_case_id'] = self.request.GET['dot_patient'] casedoc = PactPatientCase.get(ret['dot_case_id']) ret['patient_case'] = casedoc start_date_str = self.request.GET.get( 'startdate', json_format_date(datetime.utcnow() - timedelta(days=7))) end_date_str = self.request.GET.get( 'enddate', json_format_date(datetime.utcnow())) start_date = datetime.combine(iso_string_to_date(start_date_str), time()) end_date = datetime.combine(iso_string_to_date(end_date_str), time()) ret['startdate'] = start_date_str ret['enddate'] = end_date_str dcal = DOTCalendarReporter(casedoc, start_date=start_date, end_date=end_date, submit_id=submit_id) ret['dot_calendar'] = dcal unique_visits = dcal.unique_xforms() xform_es = ReportXFormES(PACT_DOMAIN) q = xform_es.base_query(size=len(unique_visits)) lvisits = list(unique_visits) if len(lvisits) > 0: q['filter']['and'].append({"ids": {"values": lvisits}}) #todo double check pactid/caseid matches q['sort'] = {'received_on': 'desc'} res = xform_es.run_query(q) #ugh, not storing all form data by default - need to get? ret['sorted_visits'] = [ DOTSubmission.wrap(x['_source']) for x in [ x for x in res['hits']['hits'] if x['_source']['xmlns'] == XMLNS_DOTS_FORM ] ] return ret
def get(self, *args, **kwargs): from pact.models import PactPatientCase if self.request.GET.get('case_id', None) is None: raise Http404 case = PactPatientCase.get(self.request.GET['case_id']) if self.method is None: return HttpResponse("API Method unknown: no method", status=400) elif self.method == "schedule": scheds = case.get_schedules(raw_json=True) if scheds is None: scheds = [] payload = simplejson.dumps(scheds) response = HttpResponse(payload, content_type="application/json") return response elif self.method == 'providers': provider_type = FixtureDataType.by_domain_tag(PACT_DOMAIN, PACT_PROVIDER_FIXTURE_TAG).first() fixture_type = provider_type._id providers = get_all_providers() #providers = sorted(providers, key=lambda x: (x.fields['facility_name'], x.fields['last_name'])) providers = sorted(providers, key=lambda x: x.fields['last_name']) providers_by_id = dict((x.fields['id'], x.fields) for x in providers) case_providers = [providers_by_id.get(x, None) for x in case.get_provider_ids()] facilities = set() for prov in providers: facility = prov.fields['facility_name'] if facility is None: facility = 'N/A' facilities.add(facility) ret = {'facilities': ['All Facilities'] + sorted(list(facilities)), "providers": [x['fields'] for x in providers], "case_providers": case_providers, } resp = HttpResponse(simplejson.dumps(ret), content_type='application/json') return resp else: return HttpResponse("API Method unknown", status=400)
def _doTestNoPillbox(self, bundle): submit_xform(self.submit_url, self.domain.name, bundle['xml']) submitted = XFormInstance.get(bundle['xform_id']) self.assertTrue(hasattr(submitted, PACT_DOTS_DATA_PROPERTY)) observations = query_observations(CASE_ID, bundle['start_date'], bundle['end_date']) observed_dates = set() #assume to be five - 3,2 same as the regimen count, we are refilling empties self.assertEqual(5, len(observations), msg="Observations do not match regimen count: %d != %d" % ( 5, len(observations))) art_nonart = set() for obs in observations: observed_dates.add(obs.observed_date) self.assertEquals(obs.day_note, "No check, from form") #magic string from the view to indicate a generated DOT observation from form data. art_nonart.add(obs.is_art) self.assertEquals(obs.doc_id, bundle['xform_id']) art = filter(lambda x: x.is_art, observations) self.assertEquals(2, len(art)) art_answered = filter(lambda x: x.adherence != "unchecked", art) self.assertEquals(1, len(art_answered)) nonart = filter(lambda x: not x.is_art, observations) self.assertEquals(3, len(nonart)) nonart_answered = filter(lambda x: x.adherence != "unchecked", nonart) self.assertEquals(1, len(nonart_answered)) #this only does SINGLE observations for art and non art self.assertEquals(len(observed_dates), 1) self.assertEquals(len(art_nonart), 2) # inspect the regenerated submission and ensure the built xml block is correctly filled. case_json = get_dots_case_json(PactPatientCase.get(CASE_ID), anchor_date=bundle['anchor_date']) enddate = bundle['anchor_date'] # anchor date of this submission #encounter_date = datetime.strptime(submitted.form['encounter_date'], '%Y-%m-%d') encounter_date = submitted.form['encounter_date'] for day_delta in range(DOT_DAYS_INTERVAL): obs_date = enddate - timedelta(days=day_delta) ret_index = DOT_DAYS_INTERVAL - day_delta -1 day_arr = case_json['days'][ret_index] nonart_day_data = day_arr[0] art_day_data = day_arr[1] self.assertEquals(len(nonart_day_data), 3) self.assertEquals(len(art_day_data), 2)
def testDOTFormatConversion(self): """ When a DOT submission comes in, it gets sliced into the CObservations and put into the DOTDay format. On resubmit/recompute, it's transmitted back into the packed json format and sent back to the phone and resubmitted with new data. This test confirms that the conversion process works. """ self.testSignal() submitted = XFormInstance.get(PILLBOX_ID) orig_data = getattr(submitted, PACT_DOTS_DATA_PROPERTY)['dots'] orig_anchor = orig_data['anchor'] del orig_data['anchor'] # can't reproduce gmt offset observations = query_observations(CASE_ID, START_DATE, END_DATE) #hack, bootstrap the labels manually nonart_idx = [0, 2, 3] art_idx = [0, 1] casedoc = PactPatientCase.get(CASE_ID) casedoc.nonartregimen = 3 casedoc.dot_n_one = 0 casedoc.dot_n_two = 2 casedoc.dot_n_three = 3 casedoc.dot_n_four = None casedoc.artregimen = 2 casedoc.dot_a_one = 0 casedoc.dot_a_two = 1 casedoc.dot_a_three = '' casedoc.dot_a_four = None computed_json = simplejson.loads( simplejson.dumps( get_dots_case_json(casedoc, anchor_date=ANCHOR_DATE))) computed_anchor = computed_json['anchor'] del computed_json['anchor'] for k in orig_data.keys(): if k != 'days': self.assertEquals(orig_data[k], computed_json[k]) self.assertEquals(simplejson.dumps(orig_data), simplejson.dumps(computed_json))
def _submitAndVerifyBundle(self, bundle, verify=True): start_nums = len(self.case.xform_ids) submit_xform(self.submit_url, self.domain.name, bundle['xml']) time.sleep(1) submitted = XFormInstance.get(bundle['xform_id']) self.assertTrue(hasattr(submitted, PACT_DOTS_DATA_PROPERTY)) submitted_dots = getattr(submitted, PACT_DOTS_DATA_PROPERTY) updated_case = PactPatientCase.get(CASE_ID) case_dots = get_dots_case_json(updated_case) days = case_dots['days'] if verify: nonart_submissions = bundle['nonart'] art_submissions = bundle['art'] examine_day = days[bundle['check_idx']] self._verify_dot_cells(nonart_submissions, art_submissions, examine_day)
def testDOTFormatConversion(self): """ When a DOT submission comes in, it gets sliced into the CObservations and put into the DOTDay format. On resubmit/recompute, it's transmitted back into the packed json format and sent back to the phone and resubmitted with new data. This test confirms that the conversion process works. """ self.testSignal() submitted = XFormInstance.get(PILLBOX_ID) orig_data = getattr(submitted, PACT_DOTS_DATA_PROPERTY)['dots'] orig_anchor = orig_data['anchor'] del orig_data['anchor'] # can't reproduce gmt offset observations = query_observations(CASE_ID, START_DATE, END_DATE) #hack, bootstrap the labels manually nonart_idx = [0, 2, 3] art_idx = [0, 1] casedoc = PactPatientCase.get(CASE_ID) casedoc.nonartregimen = 3 casedoc.dot_n_one = 0 casedoc.dot_n_two = 2 casedoc.dot_n_three = 3 casedoc.dot_n_four = None casedoc.artregimen = 2 casedoc.dot_a_one = 0 casedoc.dot_a_two = 1 casedoc.dot_a_three = '' casedoc.dot_a_four = None computed_json = simplejson.loads( simplejson.dumps(get_dots_case_json(casedoc, anchor_date=ANCHOR_DATE))) computed_anchor = computed_json['anchor'] del computed_json['anchor'] for k in orig_data.keys(): if k != 'days': self.assertEquals(orig_data[k], computed_json[k]) self.assertEquals(simplejson.dumps(orig_data), simplejson.dumps(computed_json))
def report_context(self): ret = {} if not self.request.GET.has_key('dot_patient') or self.request.GET.get('dot_patient') == "": self.report_template_path = "pact/dots/dots_report_nopatient.html" return ret submit_id = self.request.GET.get('submit_id', None) ret['dot_case_id'] = self.request.GET['dot_patient'] casedoc = PactPatientCase.get(ret['dot_case_id']) ret['patient_case'] = casedoc start_date_str = self.request.GET.get('startdate', (datetime.utcnow() - timedelta(days=7)).strftime( '%Y-%m-%d')) end_date_str = self.request.GET.get('enddate', datetime.utcnow().strftime("%Y-%m-%d")) start_date = datetime.strptime(start_date_str, "%Y-%m-%d") end_date = datetime.strptime(end_date_str, "%Y-%m-%d") ret['startdate'] = start_date_str ret['enddate'] = end_date_str dcal = DOTCalendarReporter(casedoc, start_date=start_date, end_date=end_date, submit_id=submit_id) ret['dot_calendar'] = dcal unique_visits = dcal.unique_xforms() xform_es = ReportXFormES(PACT_DOMAIN) q = xform_es.base_query(size=len(unique_visits)) lvisits = list(unique_visits) if len(lvisits) > 0: q['filter']['and'].append({"ids": {"values": lvisits}}) #todo double check pactid/caseid matches q['sort'] = {'received_on': 'desc'} res = xform_es.run_query(q) #ugh, not storing all form data by default - need to get? ret['sorted_visits'] = [DOTSubmission.wrap(x['_source']) for x in filter(lambda x: x['_source']['xmlns'] == XMLNS_DOTS_FORM, res['hits']['hits'])] return ret
def tabular_data(self, mode, case_id, start_date, end_date):#, limit=50, skip=0): try: case_doc = PactPatientCase.get(case_id) except ResourceNotFound: case_doc = None if case_doc is not None: #patient is selected startkey = [case_id, 'anchor_date', start_date.year, start_date.month, start_date.day] endkey = [case_id, 'anchor_date', end_date.year, end_date.month, end_date.day] elif case_doc is None: #patient is not selected, do all patients startkey = [start_date.year, start_date.month, start_date.day] endkey = [end_date.year, end_date.month, end_date.day] skip = 0 view_results = CObservation.view( 'pact/dots_observations', startkey=startkey, endkey=endkey, limit=COUCH_CHUNK_LIMIT, skip=skip, classes={None: CObservation}, ).all() while len(view_results) > 0: if skip > COUCH_MAX_LIMIT: logging.error("Pact DOT admin query: Too much data returned for query %s-%s" % (startkey, endkey)) break for v in view_results: yield v skip += COUCH_CHUNK_LIMIT view_results = CObservation.view( 'pact/dots_observations', startkey=startkey, endkey=endkey, limit=COUCH_CHUNK_LIMIT, skip=skip, classes={None: CObservation}, ).all()
def get(self, *args, **kwargs): from pact.models import PactPatientCase if self.request.GET.get("case_id", None) is None: raise Http404 case = PactPatientCase.get(self.request.GET["case_id"]) if self.method is None: return HttpResponse("API Method unknown: no method", status=400) elif self.method == "schedule": scheds = case.get_schedules(raw_json=True) if scheds is None: scheds = [] payload = simplejson.dumps(scheds) response = HttpResponse(payload, content_type="application/json") return response elif self.method == "providers": providers = get_all_providers() providers = sorted(providers, key=lambda x: x.fields_without_attributes["last_name"]) providers_by_id = dict((x.fields_without_attributes["id"], x.fields_without_attributes) for x in providers) case_providers = [providers_by_id.get(x, None) for x in case.get_provider_ids()] facilities = set() for prov in providers: facility = prov.fields_without_attributes["facility_name"] if facility is None: facility = "N/A" facilities.add(facility) ret = { "facilities": ["All Facilities"] + sorted(list(facilities)), "providers": [x.fields_without_attributes for x in providers], "case_providers": case_providers, } resp = HttpResponse(simplejson.dumps(ret), content_type="application/json") return resp else: return HttpResponse("API Method unknown", status=400)
def testExtendingPatientSchedule(self): def fmt_datetime(dt): """Hacky timezone somewhat aware way to get date outputs right""" return utc.localize(dt).strftime("%Y-%m-%dT%H:%M:%SZ") #return dt.strftime("%Y-%m-%dT%H:%M:%SZ") test_patient = PactPatientCase() test_patient.computed_ = {} #hand make it #test_patient.computed_[WEEKLY_SCHEDULE_KEY] = [CDotWeeklySchedule.wrap(x) for x in WEEKLY_SCHEDULE_EXAMPLES] test_patient.computed_[WEEKLY_SCHEDULE_KEY] = WEEKLY_SCHEDULE_EXAMPLES #verify that tail is <date> - null api_schedules = test_patient.get_schedules(raw_json=True) self.assertIsNone(api_schedules[-1]['ended']) self.assertEquals(api_schedules[-1]['started'], '2011-02-25T14:05:32Z') self.assertEquals(len(api_schedules), len(WEEKLY_SCHEDULE_EXAMPLES)) #add a new schedule, verify tail is <date>-present, and [-2] is <datex> - <datey> test_patient.set_schedule(CDotWeeklySchedule.wrap(NEW_SCHEDULE)) updated_schedules = test_patient.get_schedules(raw_json=True) self.assertIsNone(updated_schedules[-1]['ended']) self.assertEquals(len(updated_schedules), len(WEEKLY_SCHEDULE_EXAMPLES)+1) #pdb.set_trace() self.assertEquals(updated_schedules[-1]['started'][0:10], datetime.utcnow().isoformat()[0:10]) self.assertIsNotNone(updated_schedules[-2]['ended']) print updated_schedules[-2]['ended'] print datetime.utcnow().isoformat() self.assertLess(updated_schedules[-2]['ended'], datetime.utcnow().isoformat()) ### remove tail test_patient.save() loaded_patient = PactPatientCase.get(test_patient.get_id) loaded_patient.rm_last_schedule() removed_schedules = loaded_patient.get_schedules(raw_json=True) self.assertEquals(len(removed_schedules), len(WEEKLY_SCHEDULE_EXAMPLES)) self.assertIsNone(removed_schedules[-1]['ended']) self.assertEquals(removed_schedules[-1]['started'], '2011-02-25T14:05:32Z')
def get_case(self): if self.request.GET.get('patient_id', None) is None: return None return PactPatientCase.get(self.request.GET['patient_id'])
def get_case(self): if self.patient_id is None: return None return PactPatientCase.get(self.patient_id)