def sendAlertEmail(self): # Send an alert email laboratory = self.context.bika_setup.laboratory subject = self.request.get('subject') to = self.request.get('to') body = self.request.get('body') body = "<br/>".join(body.split("\r\n")) mime_msg = MIMEMultipart('related') mime_msg['Subject'] = subject mime_msg['From'] = formataddr((encode_header(laboratory.getName()), laboratory.getEmailAddress())) mime_msg['To'] = to msg_txt = MIMEText(safe_unicode(body).encode('utf-8'), _subtype='html') mime_msg.preamble = 'This is a multi-part MIME message.' mime_msg.attach(msg_txt) succeed = False try: host = getToolByName(self.context, 'MailHost') host.send(mime_msg.as_string(), immediate=True) except Exception, msg: ar = self.context.id logger.error("Panic level email %s: %s" % (ar, str(msg))) message = _('Unable to send an email to alert client ' 'that some results exceeded the panic levels') \ + (": %s" % str(msg)) self.addMessage(message, 'warning')
def resolve_client_for_doctor(doctor): # If the doctor has a client assigned already, return it directly. We # consider that a patient with a client assigned this way has been processed # already or does not require any further checks client = doctor.getClient() if client: return client # Try to infer the client from Samples or Batches batches = doctor.getBatches(full_objects=True) client_uids = map(lambda b: b.getClientUID(), batches) client_uids.extend(map(lambda s: s.getClientUID, doctor.getSamples())) client_uids = filter(None, list(set(client_uids))) if not client_uids: # This Doctor has no batch/sample assigned return None clients = map(api.get_object_by_uid, client_uids) internals = map(is_internal_client, clients) if all(internals): # All clients are internal, return the first one return clients[0] else: # OOps, we have a problem here. This Doctor is assigned to samples and # batches that belong to different types of client! logger.error( "Doctor {} is assigned to clients from different types".format( api.get_id(doctor), repr(clients))) return None
def install_senaite_panic(portal): """Install the senaite.panic addon """ qi = api.get_tool("portal_quickinstaller") profile = "senaite.panic" if profile not in qi.listInstallableProfiles(): logger.error( "Profile '{}' not found. Forgot to run buildout?".format(profile)) return if qi.isProductInstalled(profile): logger.info("'{}' is installed".format(profile)) return qi.installProduct(profile)
def Import(self): folder = self.context.patients rows = self.get_rows(3) for row in rows: if not row['Firstname'] or not row['PrimaryReferrer']: continue pc = getToolByName(self.context, 'portal_catalog') client = pc(portal_type='Client', Title=row['PrimaryReferrer']) if len(client) == 0: error = "Primary referrer invalid: '%s'. Patient '%s %s' will not be uploaded" logger.error(error, row['PrimaryReferrer'], row['Firstname'], row.get('Surname', '')) continue client = client[0].getObject() # Getting an existing ethnicity bsc = getToolByName(self.context, 'bika_setup_catalog') ethnicity = bsc(portal_type='Ethnicity', Title=row.get('Ethnicity', '')) if len(ethnicity) == 0: raise IndexError("Invalid ethnicity: '%s'" % row['Ethnicity']) ethnicity = ethnicity[0].getObject() _id = folder.invokeFactory('Patient', id=tmpID()) obj = folder[_id] obj.unmarkCreationFlag() renameAfterCreation(obj) Fullname = (row['Firstname'] + " " + row.get('Surname', '')).strip() obj.edit(PatientID=row.get('PatientID'), title=Fullname, ClientPatientID = row.get('ClientPatientID', ''), Salutation = row.get('Salutation', ''), Firstname = row.get('Firstname', ''), Surname = row.get('Surname', ''), PrimaryReferrer = client.UID(), Gender = row.get('Gender', 'dk'), Age = row.get('Age', ''), BirthDate = row.get('BirthDate', ''), BirthDateEstimated =self.to_bool(row.get('BirthDateEstimated','False')), BirthPlace = row.get('BirthPlace', ''), # TODO Ethnicity_Obj -> Ethnicity on health v319 Ethnicity_Obj=ethnicity.UID(), Citizenship =row.get('Citizenship', ''), MothersName = row.get('MothersName', ''), CivilStatus =row.get('CivilStatus', ''), Anonymous = self.to_bool(row.get('Anonymous','False')) ) self.fill_contactfields(row, obj) self.fill_addressfields(row, obj) if 'Photo' in row and row['Photo']: try: path = resource_filename(self.dataset_project, "setupdata/%s/%s" \ % (self.dataset_name, row['Photo'])) file_data = open(path, "rb").read() if os.path.isfile(path) \ else open(path+'.jpg', "rb").read() obj.setPhoto(file_data) except: logger.error("Unable to load Photo %s"%row['Photo']) if 'Feature' in row and row['Feature']: try: path = resource_filename(self.dataset_project, "setupdata/%s/%s" \ % (self.dataset_name, row['Feature'])) file_data = open(path, "rb").read() if os.path.isfile(path) \ else open(path+'.pdf', "rb").read() obj.setFeature(file_data) except: logger.error("Unable to load Feature %s"%row['Feature']) obj.unmarkCreationFlag() transaction.savepoint(optimistic=True) if row.get('PatientID'): # To maintain the patient spreadsheet's IDs, we cannot do a 'renameaftercreation()' if obj.getPatientID() != row.get('PatientID'): transaction.savepoint(optimistic=True) obj.aq_inner.aq_parent.manage_renameObject(obj.id, row.get('PatientID')) else: renameAfterCreation(obj)
def __call__(self): # Do generic bika.lims stuff _AnalysisRequestWorkflowAction.__call__(self) # Do bika-health specific actions when submit action = _AnalysisRequestWorkflowAction._get_form_workflow_action(self) addPortalMessage = self.context.plone_utils.addPortalMessage if action[0] == 'submit' and isActive(self.context): inpanicanalyses = [] workflow = getToolByName(self.context, 'portal_workflow') translate = self.context.translate rc = getToolByName(self.context, REFERENCE_CATALOG) uc = getToolByName(self.context, 'uid_catalog') # retrieve the results from database and check if # the values are exceeding panic levels alerts = {} for uid in self.request.form.get('Result', [{}])[0].keys(): analysis = rc.lookupObject(uid) analysis = analysis.getObject() if hasattr(analysis, 'getObject') else analysis if not analysis: continue astate = workflow.getInfoFor(analysis, 'review_state') if astate == 'retracted': continue alerts.update(ResultOutOfRange(analysis)()) if alerts: message = translate(_('Some results exceeded the ' 'panic levels that may ' 'indicate an imminent ' 'life-threatening condition' )) addPortalMessage(message, 'warning') self.request.response.redirect(self.context.absolute_url()) # If panic levels alert email enabled, send an email to # labmanagers bs = self.context.bika_setup if hasattr(bs, 'getEnablePanicAlert') \ and bs.getEnablePanicAlert(): laboratory = self.context.bika_setup.laboratory lab_address = "<br/>".join(laboratory.getPrintAddress()) managers = self.context.portal_groups.getGroupMembers('LabManagers') mime_msg = MIMEMultipart('related') mime_msg['Subject'] = _("Panic alert") mime_msg['From'] = formataddr( (encode_header(laboratory.getName()), laboratory.getEmailAddress())) to = [] for manager in managers: user = self.portal.acl_users.getUser(manager) uemail = user.getProperty('email') ufull = user.getProperty('fullname') to.append(formataddr((encode_header(ufull), uemail))) mime_msg['To'] = ','.join(to) strans = [] ars = {} for analysis_uid, alertlist in alerts: analysis = uc(analysis_uid).getObject() for alert in alertlist: ars[analysis.aq_parent.Title()] = 1 strans.append("- {0}, {1}: {2}".format( analysis.Title(), translate(_("Result")), analysis.getResult())) ars = ", ".join(ars.keys()) stran = "<br/>".join(strans) text = translate(_( "Some results from ${items} exceeded the panic levels " "that may indicate an imminent life-threatening " "condition: <br/><br/>{analysisresults}<br/><br/>" "<b>Please, check the Analysis Request if you " "want to re-test the analysis or immediately " "alert the client.</b><br/><br/>{lab_address}", mapping={'items': ars, 'analysisresults': stran, 'lab_address': lab_address})) msg_txt = MIMEText(safe_unicode(text).encode('utf-8'), _subtype='html') mime_msg.preamble = 'This is a multi-part MIME message.' mime_msg.attach(msg_txt) try: host = getToolByName(self.context, 'MailHost') host.send(mime_msg.as_string(), immediate=True) except Exception as msg: ar = inpanicanalyses[0].getRequestID() logger.error("Panic level email %s: %s" % (ar, str(msg))) message = translate( _('Unable to send an email to alert lab ' 'managers that some analyses exceeded the ' 'panic levels') + (": %s" % str(msg))) addPortalMessage(message, 'warning')