def handle_edit(self): policy = ICheckinCheckoutPolicy(self.context) obj = policy.getWorkingCopy() #baseline = policy.getBaseline() if obj is None: obj = self.context state = get_state(obj) if state in ['private', 'sent']: url = '{0}/edit'.format(obj.absolute_url()) return self.request.response.redirect(url) elif state == 'published': # create copy, go to it wc = self._checkout() url = '{0}/edit'.format(wc.absolute_url()) return self.request.response.redirect(url) elif state == 'pending': # retract object, go to it transition(obj, to_state='sent') url = '{0}/edit'.format(obj.absolute_url()) return self.request.response.redirect(url) raise ValueError ('unknown state')
def handle_edit(self): obj = get_working_copy(self.context) # TODO: use the stagingbehavior API to get the best object, in all cases print "WC: ", obj print "Baseline: ", get_baseline(self.context) if obj is None: obj = self.context state = get_state(obj) if state == 'private': url = '{0}/edit'.format(obj.absolute_url()) return self.request.response.redirect(url) elif state == 'published': # create copy, go to it wc = self._checkout() url = '{0}/edit'.format(wc.absolute_url()) return self.request.response.redirect(url) elif state == 'pending': # create copy, go to it transition(obj, to_state='private') url = '{0}/edit'.format(obj.absolute_url()) return self.request.response.redirect(url) raise ValueError('unknown state')
def publishReport(self, justDoIt=False, duplicate=False): """ """ request = self.REQUEST alsoProvides(request, IDisableCSRFProtection) new_version = self if duplicate: new_version = content.copy(source=self, id=self.getId(), safe_id=True) # copy modules into the report? # We would lose all the reference information, which is important for the situation overview #mods = self.myModules() #for mod in mods: # content.copy(source=mod, target=new_version, safe_id=True) # create PDF, upload it data = self.restrictedTraverse("@@pdfprint")._generatePDF(raw=True) nice_filename = 'report_%s_%s.pdf' % (self.getId(), datetime.now().strftime('%Y%m%d')) nice_filename = safe_unicode(nice_filename) field = NamedBlobFile(data=data, filename=nice_filename) fid = new_version.invokeFactory(id=nice_filename, type_name="File", title=self.Title(), description="") f = new_version._getOb(fid) f.file = field f.reindexObject() content.transition(new_version, transition="publish") if not justDoIt: portalMessage(self, _("The report has been published."), "info") return self.restrictedTraverse("@@view")()
def handle_edit(self): obj = get_working_copy(self.context) # TODO: use the stagingbehavior API to get the best object, in all cases print "WC: ", obj print "Baseline: ", get_baseline(self.context) if obj is None: obj = self.context state = get_state(obj) if state == "private": url = "{0}/edit".format(obj.absolute_url()) return self.request.response.redirect(url) elif state == "published": # create copy, go to it wc = self._checkout() url = "{0}/edit".format(wc.absolute_url()) return self.request.response.redirect(url) elif state == "pending": # create copy, go to it transition(obj, to_state="private") url = "{0}/edit".format(obj.absolute_url()) return self.request.response.redirect(url) raise ValueError("unknown state")
def _checkout(self): # NOTE: this code is copied from plone.app.iterate.browser.checkout context = aq_inner(self.context) # containers = list(self._containers()) location = self.context.aq_parent #containers[0]['name'] # We want to redirect to a specific template, else we might # end up downloading a file control = getMultiAdapter((context, self.request), name=u"iterate_control") if not control.checkout_allowed(): raise CheckoutException(u"Not allowed") policy = ICheckinCheckoutPolicy(context) wc = policy.checkout(location) transition(wc, to_state='sent') # we do this for metadata update side affects which will update lock info context.reindexObject('review_state') IStatusMessage(self.request).addStatusMessage(_("Check-out created"), type='info') #view_url = wc.restrictedTraverse("@@plone_context_state").view_url() return wc
def __call__(self): changed = 0 not_changed = 0 logger.info("Changing workflow states to not_started...") for nda in self.ndas: state = get_wf_state_id(nda) if hasattr(nda, 'saved_assessment_data'): data = nda.saved_assessment_data.last() if data: not_changed += 1 continue if state == 'in_work': changed += 1 logger.info("State changing for {}".format(nda.__repr__())) transition(obj=nda, to_state='not_started') logger.info("States changed: {}, Not changed: {}".format( changed, not_changed)) return "Done"
def create_comments_folder(self, content): for id, title, trans in [ (u'tl', 'Discussion track with Topic Leads', 'open_for_tl'), (u'ec', 'Discussion track with EC', 'open_for_ec'), ]: if id not in content.contentIds(): dt = create(content, 'wise.msfd.commentsfolder', id=id, title=title) transition(obj=dt, transition=trans)
def publishModule(self, justDoIt=False): """ """ request = self.REQUEST alsoProvides(request, IDisableCSRFProtection) new_version = content.copy(source=self, id=self.getId(), safe_id=True) content.transition(new_version, transition="publish") if not justDoIt: portalMessage(self, _("The module has been published."), "info") return self.restrictedTraverse("@@view")()
def process_results(self, path): self.path = path self.run = self.get_run(path) if not self.run: return # import results and files from path log = self.process_results_xlsx(path) log += self.process_out_figures(path) log += self.process_raw_flipped(path) # transition run to 'resulted' self.run.import_log = log transition(self.run, 'result') # send result report self.create_pdf_files()
def handleApply(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return action = data['workflow_action'] msg = data['message'].strip() IAnnotations(self.request)[ANNOT_KEY] = msg notify(WorkflowMessageEvent(self.context)) transition(obj=self.context, transition=action, comment=msg) self.status = msg = u"Message will be further processed." show_message(message=msg, request=self.request, type='info') return self.request.response.redirect(self.context.absolute_url())
def setUp(self): """Custom shared utility setup for tests.""" self.portal = self.layer['portal'] self.workflow = api.portal.get_tool('portal_workflow') # in tests we have to manually map content types to workflows self.workflow.setChainForPortalTypes(['News Item'], 'simple_publication_workflow') # add test item content.create(type='News Item', title='Tést item', container=self.portal) self.newsitem = self.portal['test-item'] # publish the item content.transition(obj=self.newsitem, transition='publish')
def _attempt_invalid_transition( self, obj=None, transition=None, end_state=None, ): self.assertIsNotNone(obj) self.assertIn(transition, TRANSITIONS) self.assertIn(end_state, STATES.keys()) error_str = '' try: content.transition(obj=obj, transition=transition) except InvalidParameterError as e: error_str = e.message found_expected_error = 'Invalid transition' in error_str self.assertTrue(found_expected_error) self.assertEqual(content.get_state(obj=obj), end_state)
def after_queue(instance): """ """ assayrequests, clinicalaliquots, ichips, qcaliquots = run_objects(instance) for obj in set(qcaliquots): transition(obj, "queue") for obj in set(clinicalaliquots): transition(obj, "queue") for obj in set(ichips): transition(obj, "queue") for obj in set(assayrequests): transition(obj, "queue")
def send_to_tl(self): regions = self.get_regions() for region in regions: descriptors = self.get_descriptors(region) for desc in descriptors: assessments = self.get_articles(desc) for assessment in assessments: state_id = self.get_wf_state_id(assessment) if state_id == 'approved': transition(obj=assessment, to_state='in_work') IStatusMessage(self.request).add(u'Sent to TL', type='info') url = self.context.absolute_url() return self.request.response.redirect(url)
def setUp(self): """Custom shared utility setup for tests.""" self.portal = self.layer['portal'] self.workflow = api.portal.get_tool('portal_workflow') # in tests we have to manually map content types to workflows self.workflow.setChainForPortalTypes( ['News Item'], 'simple_publication_workflow' ) # add test item content.create( type='News Item', title='Tést item', container=self.portal ) self.newsitem = self.portal['test-item'] # publish the item content.transition(obj=self.newsitem, transition='publish')
def _verify_allowed_transition_by_role( self, obj=None, initial_state=None, role=None, transition=None, destination_state=None, end_state=None, ): self.assertIsNotNone(obj) self.assertIn(initial_state, STATES.keys()) self.assertIn(role, ROLES) self.assertIn(transition, TRANSITIONS) self.assertIn(destination_state, STATES.keys()) self.assertIn(end_state, STATES.keys()) self.assertEqual(content.get_state(obj=obj), initial_state) self._switch_role(obj, role) content.transition(obj=obj, transition=transition) self.assertEqual(content.get_state(obj=obj), destination_state) # send it back to the end state self._transition_to_state(obj, destination_state=end_state)
def add_comment(self): form = self.request.form question_id = form.get('q').lower() thread_id = form.get('thread_id') transition_id = 'open_for_{}'.format(thread_id) text = form.get('text') folder = self.context if question_id in folder.contentIds(): q_folder = folder[question_id] # Due to a bug, For 'EC' the wrong state was given (opened_for_tl) # transition to the correct state if necessary current_state = get_state(q_folder) correct_state = 'opened_for_{}'.format(thread_id) if current_state != 'closed' and current_state != correct_state: transition(obj=q_folder, transition='close') transition(obj=q_folder, transition=transition_id) else: # initially create the question folder for comments q_folder = create(folder, 'wise.msfd.commentsfolder', id=question_id, title='Comments for question ' + question_id) transition(obj=q_folder, transition=transition_id) comment = create(q_folder, 'wise.msfd.comment', text=text) logger.info('Added comment %r in %r:, %r', q_folder, comment, text) return self.template()
def _transition_and_or_roles_test( self, fast, initial_state, transition, end_state, authorized_roles, ): if fast: self.assertEqual(content.get_state(obj=self.test_obj), initial_state) content.transition(obj=self.test_obj, transition=transition) self.assertEqual(content.get_state(obj=self.test_obj), end_state) else: self._verify_transition_by_all_roles( obj=self.test_obj, initial_state=initial_state, authorized_roles=authorized_roles, transition=transition, destination_state=end_state, end_state=initial_state, )
def after_cancel_run(instance): """When cancelling a test run, objects that were linked here must be freed for use in a future test run, or cancelled. - cancels iChip and Aliquot objects - make_available on AssayRequest objects. """ assayrequests, clinicalaliquots, ichips, qcaliquots = run_objects(instance) for obj in set(qcaliquots): transition(obj, "make_available") for obj in set(clinicalaliquots): transition(obj, "make_available") for obj in set(ichips): transition(obj, "make_available") for obj in set(assayrequests): transition(obj, "make_available")
def store_aliquot(self, uid, usn, aliquot_type, target_box_type): # get active box from workflow state, if one doesn't exist make it, # check for aliquot space in box, if none make a new box aliquot_type = aliquot_type # Bulk or Working target_box_type = target_box_type # CommercialBox, RandDBox, QCBox # find the active box of the type we need, brains = find(portal_type=target_box_type, review_state='active') if brains is not None: for brain in brains: cb = brain.getObject() if cb.box_type == aliquot_type: if cb.remaining_volume > 0: box_to_use = cb.UID entry_key = str(len(cb.aliquot.keys()) + 1) entry_value = [usn, uid] # Aliquot ID, UID # thing to add it to cb.aliquot_dic else: # change box workflow to full try: transition(cb, "filled") except: msg = "Could not transition %s, action='filled'" % \ cb.Title raise ObjectInInvalidState(msg) # see if rack has empty space, if not bail, and # alert user make a new aliquot_type, and return # this UID rack = cb.aq_parent new_box = api.content.create( container=rack, type=target_box_type, title="", box_type=aliquot_type, max_samples=81, remaining_volume=80, aliquot_dic={u'1', [usn, uid]}) else: print "No Active Box for Parameters sent"
def after_begin_process(instance): """ """ assayrequests, clinicalaliquots, ichips, qcaliquots = run_objects(instance) for obj in set(qcaliquots): transition(obj, "begin_process") for obj in set(clinicalaliquots): transition(obj, "begin_process") for obj in set(assayrequests): transition(obj, "begin_process")
def transition_plate_contents(self, ichips, aliquots, action_id): """Chips, aliquots, and assay requests move together through identical states during the test run. """ transitioned = [] try: for ichip in ichips: if ichip not in transitioned: transition(ichip, action_id) transitioned.append(ichip) except InvalidParameterError: # noinspection PyUnboundLocalVariable msg = "Can't invoke '%s' transition on %s" % (action_id, ichip) raise ObjectInInvalidState(msg) try: for aliquot in aliquots: if aliquot not in transitioned: transition(aliquot, action_id) transitioned.append(aliquot) except InvalidParameterError: # noinspection PyUnboundLocalVariable msg = "Can't invoke '%s' transition on %s" % (action_id, aliquot) raise ObjectInInvalidState(msg) # get AssayRequests associated with all aliquots, and queue them. for aliquot in aliquots: sample = self.get_parent_sample_from_aliquot(aliquot) if IClinicalSample.providedBy(sample): assayrequest = self.get_assay_request_from_sample(sample) wf = get_tool('portal_workflow') t_ids = [t['id'] for t in wf.getTransitionsFor(assayrequest)] if action_id in t_ids \ and assayrequest not in transitioned: transition(assayrequest, action_id) transitioned.append(assayrequest)
def tweaks(context): """ Additional soer content tweaks """ catalog = getToolByName(context, 'portal_catalog') soer_2010 = context.restrictedTraverse("/www/SITE/soer/2010") soer_page_2010 = context.restrictedTraverse("/www/SITE/soer/2010/2010") page_keys = soer_page_2010.Schema().keys() folder_keys = soer_2010.Schema().keys() for key in page_keys: field = soer_page_2010.getField(key) if not field: continue value = field.getAccessor(soer_page_2010)() # Fix some metadata if key in folder_keys: setattr(soer_2010, key, value) soer_2010.setTitle(soer_page_2010.Title()) soer_2010.setDescription(soer_page_2010.Description()) soer_2010.setEffectiveDate(soer_page_2010.getEffectiveDate()) soer_2010.setCreationDate(soer_page_2010.creation_date) soer_2010.setSubject(soer_page_2010.Subject()) soer_2010.setCreators(soer_page_2010.Creators()) soer_2010.changeOwnership(soer_page_2010.getOwner()) soer_2010.temporalCoverage = soer_page_2010.temporalCoverage # Map relatedItems forwards = soer_page_2010.getRelatedItems() backs = soer_page_2010.getBackReferences() if forwards: soer_2010.setRelatedItems(forwards) for ob in backs: related = ob.getRelatedItems() related.append(soer_2010) ob.setRelatedItems(related) # set geotags geo_page_2010 = getAdapter(soer_page_2010, IGeoTags) geo_2010 = getAdapter(soer_2010, IGeoTags) geo_2010._set_tags(geo_page_2010.tags) soer_2010._p_changed = True soer_2010.reindexObject() catalog.reindexObject(soer_2010, update_metadata=True) transaction.commit() soer = context.restrictedTraverse("/www/SITE/soer") content.transition(obj=soer, transition='publish') soer_2020 = context.restrictedTraverse("/www/SITE/soer/2020") soer_2020.setExpirationDate(None) soer_2020._p_changed = True soer_2020.reindexObject() catalog.reindexObject(soer_2020, update_metadata=True) logger.info('Finished tweaking moved soer content ... DONE') return 'Done moving'
def handleApply(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return utils._send_emails = False try: en_folder = self.context.restrictedTraverse('en') if 'organisations' in en_folder: org_folder = en_folder.restrictedTraverse('organisations') else: org_folder = content.create( en_folder, type='osha.hwccontent.organisationfolder', title='Organisations') if 'focalpoints' in en_folder: fop_folder = en_folder.restrictedTraverse('focalpoints') else: fop_folder = content.create( en_folder, type='osha.hwccontent.organisationfolder', title='Focalpoints') type_mapping = { u'Organisation': { 'type': 'osha.hwccontent.organisation', 'schema': dict(getFieldsInOrder(IOrganisation)), 'folder': org_folder, 'wf_actions': ('approve_phase_1', ), }, u'Focalpoint': { 'type': 'osha.hwccontent.focalpoint', 'schema': dict(getFieldsInOrder(IFocalPoint)), 'folder': fop_folder, 'wf_actions': ('publish', ), } } count = 0 for data in json.loads(data['json']): # Only keep the data that's in the main schema: type_info = type_mapping[data['_type']] schema = type_info['schema'] fields = {} if data['title'].startswith('MC-'): continue for name, field in schema.items(): if name in data: value = data[name] if value and INamedImageField.providedBy(field): content_type = data.get('_%s_content_type' % name, '') filename = data.get('_%s_filename' % name, None) value = NamedBlobImage(base64.b64decode(value), str(content_type), filename) elif value and IRichText.providedBy(field): content_type = data.get('_%s_content_type', None) value = RichTextValue(value, mimeType=content_type) elif name.find("email") >= 0: value = value.strip() fields[name] = value new_obj = content.create(container=type_info['folder'], type=type_info['type'], id=data['id'], **fields) for transition in type_info['wf_actions']: try: content.transition(new_obj, transition) except Exception: logger.exception( 'Could not execute %s transition for %s' % (transition, '/'.join(new_obj.getPhysicalPath()))) logger.info('Imported %s' % new_obj.getId()) count += 1 # Set status on this form page self.status = "%s partners imported" % count except Exception: # Enable emails again: utils._send_emails = True raise
def handle_submit(self): transition(self.context, to_state='pending') url = '{0}/'.format(self.context.absolute_url()) return self.request.response.redirect(url)
def make_clinical_sample( self, usn_from_form, consent_acquired, ana_testing, clin_rash, clin_seiz_psych, clin_mouth_sores, clin_hair_loss, clin_joint_pain, clin_inflam, clin_other, clin_other_specify, diag_D89_89, diag_M32_10, diag_D89_9, diag_M35_9, diag_L93_2, diag_other, diag_other_specify, provider_nip_clean, provider_signed, draw_location, draw_tel, phlebotomist_name, draw_signed, collection_date, shipment_date, test_other_specify, clinical_impression, ordering_provider_name, site_id, assay_selection, other_clinical_symptoms, other_inflam, other_joint_pain): """Make a clinical sample via api, set serial number Need to add option for assay choice at a later date """ # logical test order passed via end user # assign serial number for sample sn = api.content.find(context=api.portal.get(), portal_type='ClinicalSample') all_sn = [] # list of all serial numbers sn_uid = [s.UID for s in sn] for i in sn_uid: value = api.content.get(UID=i) all_sn.append(value.sample_serial_number) if len(all_sn) == 0: serial_number = 10000 else: serial_number = max(all_sn) + 1 symptoms_choice = [] if clin_rash is not None: symptoms_choice.append(unicode(clin_rash, "utf-8")) if clin_seiz_psych is not None: symptoms_choice.append(unicode(clin_seiz_psych, "utf-8")) if clin_mouth_sores is not None: symptoms_choice.append(unicode(clin_mouth_sores, "utf-8")) if clin_hair_loss is not None: symptoms_choice.append(unicode(clin_hair_loss, "utf-8")) if clin_joint_pain is not None: symptoms_choice.append(unicode(clin_joint_pain, "utf-8")) if clin_inflam is not None: symptoms_choice.append(unicode(clin_inflam, "utf-8")) if clin_other is not None: symptoms_choice.append(unicode(clin_other, "utf-8")) # datetime.datetime.strptime diagnosis_code = [] if diag_D89_89 is not None: diagnosis_code.append(unicode(diag_D89_89, "utf-8")) if diag_M32_10 is not None: diagnosis_code.append(unicode(diag_M32_10, "utf-8")) if diag_D89_9 is not None: diagnosis_code.append(unicode(diag_D89_9, "utf-8")) if diag_M35_9 is not None: diagnosis_code.append(unicode(diag_M35_9, "utf-8")) if diag_L93_2 is not None: diagnosis_code.append(unicode(diag_L93_2, "utf-8")) if diag_other is not None: diagnosis_code.append(unicode(diag_other, "utf-8")) try: py_collection_date = \ datetime.datetime.strptime(collection_date, "%Y-%m-%d").date() except: py_collection_date = None try: py_shipment_date = \ datetime.datetime.strptime(shipment_date, "%Y-%m-%d").date() except: py_shipment_date = None # need to split clin_other_specify on ', ' # if clin_other_specify != "": # Get primary health care provider from site! site_objects = api.content.find(context=api.portal.get(), portal_type='Site') site_uids = [i.UID for i in site_objects] primary_provider = "null" for j in site_uids: site = api.content.get(UID=j) if site_id == str(site.title): primary_provider = site.primary_provider # set permission for clinical sample cs = api.portal.get() sample = cs['lims']['samples'] disallow_default_contenttypes(sample) clinical_sample = api.content.create( container=sample, type='ClinicalSample', id=usn_from_form, usn=usn_from_form, safe_id=True, sample_serial_number=serial_number, research_consent=consent_acquired, sample_ordering_healthcare_provider=ordering_provider_name, sample_ordering_healthcare_provider_signature=provider_signed, primary_healthcare_provider=primary_provider, ana_testing=ana_testing, clinical_impression=clinical_impression, other_test_ordered=test_other_specify, symptoms_choice=symptoms_choice, symptoms_text=clin_other_specify, phlebotomist_name=phlebotomist_name, phlebotomist_signature_provided=draw_signed, collection_date=py_collection_date, received_date=py_shipment_date, joint_pain_text=other_joint_pain, inflammation_text=other_inflam, other_symptoms_text=other_clinical_symptoms, ) clinical_sample_uid = clinical_sample.UID() # Creates Assay Request Object on Sample Creation, on for each assay # selected! for a in assay_selection: assay_request = api.content.create(container=clinical_sample, type='AssayRequest', title=a, assay_name=a) transition(assay_request, to_state='to_be_tested') # add billing program from rec to object billing_request = api.content.create( container=assay_request, type='AssayBillingRequest', title=usn_from_form, safe_id=True, assay_name=a, sample_id=usn_from_form, diagnosis_code=diagnosis_code, diagnosis_code_other=diag_other_specify) return clinical_sample_uid
def handleApply(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return utils._send_emails = False try: en_folder = self.context.restrictedTraverse('en') if 'organisations' in en_folder: org_folder = en_folder.restrictedTraverse('organisations') else: org_folder = content.create(en_folder, type='osha.hwccontent.organisationfolder', title='Organisations') if 'focalpoints' in en_folder: fop_folder = en_folder.restrictedTraverse('focalpoints') else: fop_folder = content.create(en_folder, type='osha.hwccontent.organisationfolder', title='Focalpoints') type_mapping = { u'Organisation': { 'type': 'osha.hwccontent.organisation', 'schema': dict(getFieldsInOrder(IOrganisation)), 'folder': org_folder, 'wf_actions': ('approve_phase_1',), }, u'Focalpoint': { 'type': 'osha.hwccontent.focalpoint', 'schema': dict(getFieldsInOrder(IFocalPoint)), 'folder': fop_folder, 'wf_actions': ('publish',), } } count = 0 for data in json.loads(data['json']): # Only keep the data that's in the main schema: type_info = type_mapping[data['_type']] schema = type_info['schema'] fields = {} if data['title'].startswith('MC-'): continue for name, field in schema.items(): if name in data: value = data[name] if value and INamedImageField.providedBy(field): content_type = data.get('_%s_content_type' % name, '') filename = data.get('_%s_filename' % name , None) value = NamedBlobImage(base64.b64decode(value), str(content_type), filename) elif value and IRichText.providedBy(field): content_type = data.get('_%s_content_type', None) value = RichTextValue(value, mimeType=content_type) elif name.find("email") >= 0: value = value.strip() fields[name] = value new_obj = content.create(container=type_info['folder'], type= type_info['type'], id=data['id'], **fields) for transition in type_info['wf_actions']: try: content.transition(new_obj, transition) except Exception: logger.exception('Could not execute %s transition for %s' % (transition, '/'.join(new_obj.getPhysicalPath()))) logger.info('Imported %s' % new_obj.getId()) count += 1 # Set status on this form page self.status = "%s partners imported" % count except Exception: # Enable emails again: utils._send_emails = True raise
def handle_submit(self): transition(self.context, to_state="pending") url = "{0}/".format(self.context.absolute_url()) return self.request.response.redirect(url)
def process_results_xlsx(self, path): """Take values from path/Out/Results/SLEkey_Results.xlsx, and write them to the database """ run = self.get_run(path) # Get the first sheet filename = join(path, 'Out', 'Results', 'SLEkey_Results.xlsx') wb = openpyxl.load_workbook(filename) ws = wb.get_sheet_by_name('Sheet1') # header rows for blocks containg QC and Clinical aliquot/sample info qc_head_row = self.findnextSerial_Numberrow(ws, 1) clin_head_row = self.findnextSerial_Numberrow(ws, qc_head_row + 1) # get column letters of all qc headers that start with "ichip*" qc_ichip_cols = [] passfail_col = None for col in all_cols: coord = "%s%s" % (col, qc_head_row) val = "%s" % ws[coord].value if val: if val.lower().startswith("fina"): passfail_col = coord if val.lower().startswith("ichip"): qc_ichip_cols.append(col) ichip_passfail_combos = [] if passfail_col: for row in range(qc_head_row + 1, clin_head_row): passfail = "%s" % ws["%s%s" % (passfail_col, row)].value ichip_titles = [] for col in qc_ichip_cols: ichip_titles.append(ws["%s%s" % (col, row)].value) ichip_passfail_combos.append([ichip_titles, passfail]) # for each plate for plate in run.plates: plate_ichips = [] plate_ichiplot_titles = [] # get all unique ichip lot numbers in a list for key, uid in plate.items(): if key.startswith('ichip-id'): ichip = find(UID=uid)[0].getObject() plate_ichips.append(ichip) ichiplot_title = ichip.title.upper().split('-')[0] if ichiplot_title not in plate_ichiplot_titles: plate_ichiplot_titles.append(ichiplot_title) for combo in ichip_passfail_combos: if sorted(plate_ichiplot_titles) == sorted(combo[0]): for ichip in plate_ichips: transition(ichip, 'qc_' + combo[1].lower()) # 'consume' qc aliquots. for uid in plate.values(): brains = find(object_provides=IQCAliquot.__identifier__, UID=uid, review_state='in_process') if brains: transition(brains[0].getObject(), 'done') # find the column at which the following headers are located: cols = {'Sample_ID': '', 'SLE_key_Score': '', 'SLE_key_Classification': '', 'Assay_QC_Status': ''} if not all(cols): msg = "One of the column headers can't be located:" % pformat(cols) raise SpreadsheetParseError(msg) for col in all_cols: coord = "%s%s" % (col, clin_head_row) value = ws[coord].value if value in cols: cols[value] = col # get values from each row and colum into aliquot_results. results is: # {sample_id: [SLE_key_Score, # SLE_key_Classification, # Assay_QC_Status],} aliquot_results = {} first_empty = self.get_first_empty_row(ws, clin_head_row) for row in range(clin_head_row + 1, first_empty): sample_id = ws["%s%s" % (cols['Sample_ID'], row)].value score = ws["%s%s" % (cols['SLE_key_Score'], row)].value classif = ws["%s%s" % (cols['SLE_key_Classification'], row)].value status = ws["%s%s" % (cols['Assay_QC_Status'], row)].value aliquot_results[sample_id] = { 'SLE_key_Score': score, 'SLE_key_Classification': "%s" % classif, 'Assay_QC_Status': "%s" % status } log = [] _used_uids = [] for plate in run.plates: for uid in plate.values(): if uid in _used_uids: continue _used_uids.append(uid) brains = find(UID=uid) if not brains: continue aliquot = brains[0].getObject() if not IAliquot.providedBy(aliquot): continue sample = self.get_sample_from_aliquot(aliquot) if IClinicalSample.providedBy(sample): if sample.title not in aliquot_results: msg = "Sample '%s' not in spreadsheet results: %s" % \ (sample.title, pformat(aliquot_results)) raise RuntimeError(msg) result = aliquot_results[sample.title] ar = self.get_ar_from_sample(sample, run.assay_name) state = result['Assay_QC_Status'].lower() ar.aliquot_evaluated = aliquot.title ar.date_resulted = self.get_date(ws) # assayrequest is associated with multiple aliquots, # so we only transition if the AR's state is expected. if get_state(ar) == 'in_process': transition(ar, 'qc_' + state) aliquot.numeric_result = result['SLE_key_Score'] aliquot.text_result = result['SLE_key_Classification'] ts = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M") log.append("%s: Sample: %s, Aliquot: %s, Results: %s, %s" % ( ts, sample.title, aliquot.title, result['SLE_key_Score'], result['SLE_key_Classification'], )) return log
def after_release(instance): """ """ for ichip in instance.objectValues(): if get_state(ichip) == "quarantined": transition(ichip, "release")
def make_clinical_sample( self, usn_from_form, consent_acquired, ana_testing, clin_rash, clin_seiz_psych, clin_mouth_sores, clin_hair_loss, clin_joint_pain, clin_inflam, clin_other, clin_other_specify, diag_D89_89, diag_M32_10, diag_D89_9, diag_M35_9, diag_L93_2, diag_other, diag_other_specify, provider_nip_clean, provider_signed, draw_location, draw_tel, phlebotomist_name, draw_signed, collection_date, shipment_date, test_other_specify, clinical_impression, ordering_provider_name, site_id, assay_selection, other_clinical_symptoms, other_inflam, other_joint_pain): """Make a clinical sample via api, set serial number Need to add option for assay choice at a later date """ # logical test order passed via end user # assign serial number for sample sn = api.content.find(context=api.portal.get(), portal_type='ClinicalSample') all_sn = [] # list of all serial numbers sn_uid = [s.UID for s in sn] for i in sn_uid: value = api.content.get(UID=i) all_sn.append(value.sample_serial_number) if len(all_sn) == 0: serial_number = 10000 else: serial_number = max(all_sn) + 1 symptoms_choice = [] if clin_rash is not None: symptoms_choice.append(unicode(clin_rash, "utf-8")) if clin_seiz_psych is not None: symptoms_choice.append(unicode(clin_seiz_psych, "utf-8")) if clin_mouth_sores is not None: symptoms_choice.append(unicode(clin_mouth_sores, "utf-8")) if clin_hair_loss is not None: symptoms_choice.append(unicode(clin_hair_loss, "utf-8")) if clin_joint_pain is not None: symptoms_choice.append(unicode(clin_joint_pain, "utf-8")) if clin_inflam is not None: symptoms_choice.append(unicode(clin_inflam, "utf-8")) if clin_other is not None: symptoms_choice.append(unicode(clin_other, "utf-8")) # datetime.datetime.strptime diagnosis_code = [] if diag_D89_89 is not None: diagnosis_code.append(unicode(diag_D89_89, "utf-8")) if diag_M32_10 is not None: diagnosis_code.append(unicode(diag_M32_10, "utf-8")) if diag_D89_9 is not None: diagnosis_code.append(unicode(diag_D89_9, "utf-8")) if diag_M35_9 is not None: diagnosis_code.append(unicode(diag_M35_9, "utf-8")) if diag_L93_2 is not None: diagnosis_code.append(unicode(diag_L93_2, "utf-8")) if diag_other is not None: diagnosis_code.append(unicode(diag_other, "utf-8")) try: py_collection_date = \ datetime.datetime.strptime(collection_date, "%Y-%m-%d").date() except: py_collection_date = None try: py_shipment_date = \ datetime.datetime.strptime(shipment_date, "%Y-%m-%d").date() except: py_shipment_date = None # need to split clin_other_specify on ', ' # if clin_other_specify != "": # Get primary health care provider from site! site_objects = api.content.find(context=api.portal.get(), portal_type='Site') site_uids = [i.UID for i in site_objects] primary_provider = "null" for j in site_uids: site = api.content.get(UID=j) if site_id == str(site.title): primary_provider = site.primary_provider # set permission for clinical sample cs = api.portal.get() sample = cs['lims']['samples'] disallow_default_contenttypes(sample) clinical_sample = api.content.create( container=sample, type='ClinicalSample', id=usn_from_form, usn=usn_from_form, safe_id=True, sample_serial_number=serial_number, research_consent=consent_acquired, sample_ordering_healthcare_provider=ordering_provider_name, sample_ordering_healthcare_provider_signature=provider_signed, primary_healthcare_provider=primary_provider, ana_testing=ana_testing, clinical_impression=clinical_impression, other_test_ordered=test_other_specify, symptoms_choice=symptoms_choice, symptoms_text=clin_other_specify, phlebotomist_name=phlebotomist_name, phlebotomist_signature_provided=draw_signed, collection_date=py_collection_date, received_date=py_shipment_date, joint_pain_text=other_joint_pain, inflammation_text=other_inflam, other_symptoms_text=other_clinical_symptoms, ) clinical_sample_uid = clinical_sample.UID() # Creates Assay Request Object on Sample Creation, on for each assay # selected! for a in assay_selection: assay_request = api.content.create( container=clinical_sample, type='AssayRequest', title=a, assay_name=a) transition(assay_request, to_state='to_be_tested') # add billing program from rec to object billing_request = api.content.create( container=assay_request, type='AssayBillingRequest', title=usn_from_form, safe_id=True, assay_name=a, sample_id=usn_from_form, diagnosis_code=diagnosis_code, diagnosis_code_other=diag_other_specify) return clinical_sample_uid
def _recursive_transition_to_state(self, obj, transition_steps): for transition in transition_steps: content.transition(obj=obj, transition=transition)
def _publish(obj): """Publish the object if it hasn't been published.""" if content.get_state(obj=obj) != 'published': content.transition(obj=obj, transition='publish') return True return False
def votable_update(votable_object, event): votable = IVoting(votable_object) if get_state(votable_object) == 'pending': if votable.average_vote() > 0.5: transition(votable_object, transition='publish')
def create_demo_content(context): """ Initializes demo profile with demo content :param context: """ portal = api.portal.get() current_dir = os.path.abspath(os.path.dirname(__file__)) json_path = os.path.join(current_dir, "profiles/demo/data/data.json") with open(json_path) as json_str: data = json.load(json_str) api.portal.set_registry_record( "plonemeeting.portal.core.global_categories", data["categories"]) normalizer = getUtility(IIDNormalizer) for institution in data["institutions"]: institution_id = normalizer.normalize(institution["title"]) institution_obj = content.create( container=portal, type="Institution", id=institution_id, title=institution["title"], representatives_mappings=institution[ "representatives_mappings"], plonemeeting_url=institution["plonemeeting_url"], username=institution["username"], password=institution["password"], meeting_config_id=institution["meeting_config_id"], additional_meeting_query_string_for_list=institution[ "additional_meeting_query_string_for_list"], additional_published_items_query_string=institution[ "additional_published_items_query_string"], item_decision_formatting_tal=institution[ "item_decision_formatting_tal"], info_annex_formatting_tal=institution[ "info_annex_formatting_tal"], ) content.transition(obj=institution_obj, transition="publish") user = api.user.create( username="******".format(institution_obj.id), email="*****@*****.**", password="******", ) group = api.group.get( format_institution_managers_group_id(institution_obj)) group.addMember(user.id) for meeting in institution["meetings"]: date_time = dateutil.parser.parse(meeting["datetime"]) meeting_obj = content.create( container=institution_obj, type="Meeting", title=meeting["title"], date_time=date_time, plonemeeting_last_modified=dateutil.parser.parse( meeting["plonemeeting_last_modified"]), ) content.transition(obj=meeting_obj, transition="send_to_project") content.transition(obj=meeting_obj, transition="publish") for item in meeting["items"]: decision = RichTextValue(item["decision"], "text/html", "text/html") item_obj = content.create( container=meeting_obj, type="Item", title=item["title"], sortable_number=item["sortable_number"], number=item["number"], representatives_in_charge=item[ "representatives_in_charge"], decision=decision, category=item["category"], plonemeeting_last_modified=dateutil.parser.parse( meeting["plonemeeting_last_modified"]), ) if "files" in item: for file in item["files"]: create_file(item_obj, file)