def publishFromHTML(self, aruid, results_html): # The AR can be published only and only if allowed uc = getToolByName(self.context, 'uid_catalog') ars = uc(UID=aruid) if not ars or len(ars) != 1: return [] ar = ars[0].getObject() wf = getToolByName(ar, 'portal_workflow') allowed_states = ['verified', 'published'] # Publish/Republish allowed? if wf.getInfoFor(ar, 'review_state') not in allowed_states: # Pre-publish allowed? if not ar.getAnalyses(review_state=allowed_states): return [] # HTML written to debug file # debug_mode = App.config.getConfiguration().debug_mode "Commented by Yasir" debug_mode = True #" Added by Yasir" if debug_mode: tmp_fn = tempfile.mktemp(suffix=".html") logger.debug("Writing HTML for %s to %s" % (ar.Title(), tmp_fn)) open(tmp_fn, "wb").write(results_html) # Create the pdf report (will always be attached to the AR) # we must supply the file ourself so that createPdf leaves it alone. # This version replaces 'attachment' links; probably not required, # so it's repeated below, without these localise_images. # cleanup, results_html_for_pdf = self.localise_images(results_html) # pdf_fn = tempfile.mktemp(suffix=".pdf") # pdf_report = createPdf(htmlreport=results_html_for_pdf, outfile=pdf_fn) # for fn in cleanup: # os.remove(fn) # Create the pdf report (will always be attached to the AR) # we must supply the file ourself so that createPdf leaves it alone. pdf_fn = tempfile.mktemp(suffix=".pdf") pdf_report = createPdf(htmlreport=results_html, outfile=pdf_fn) # PDF written to debug file if debug_mode: logger.debug("Writing PDF for %s to %s" % (ar.Title(), pdf_fn)) else: os.remove(pdf_fn) recipients = [] contact = ar.getContact() lab = ar.bika_setup.laboratory if pdf_report: if contact: recipients = [{ 'UID': contact.UID(), 'Username': to_utf8(contact.getUsername()), 'Fullname': to_utf8(contact.getFullname()), 'EmailAddress': to_utf8(contact.getEmailAddress()), 'PublicationModes': contact.getPublicationPreference() }] reportid = ar.generateUniqueId('ARReport') report = _createObjectByType("ARReport", ar, reportid) report.edit(AnalysisRequest=ar.UID(), Pdf=pdf_report, Html=results_html, Recipients=recipients) report.unmarkCreationFlag() renameAfterCreation(report) # Set status to prepublished/published/republished status = wf.getInfoFor(ar, 'review_state') transitions = {'verified': 'publish', 'published': 'republish'} transition = transitions.get(status, 'prepublish') try: wf.doActionFor(ar, transition) except WorkflowException: pass # compose and send email. # The managers of the departments for which the current AR has # at least one AS must receive always the pdf report by email. # https://github.com/bikalabs/Bika-LIMS/issues/1028 mime_msg = MIMEMultipart('related') mime_msg['Subject'] = self.get_mail_subject(ar)[0] mime_msg['From'] = formataddr( (encode_header(lab.getName()), lab.getEmailAddress())) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(results_html, _subtype='html') mime_msg.attach(msg_txt) to = [] mngrs = ar.getResponsible() for mngrid in mngrs['ids']: name = mngrs['dict'][mngrid].get('name', '') email = mngrs['dict'][mngrid].get('email', '') if (email != ''): to.append(formataddr((encode_header(name), email))) if len(to) > 0: # Send the email to the managers mime_msg['To'] = ','.join(to) attachPdf(mime_msg, pdf_report, pdf_fn) try: host = getToolByName(ar, 'MailHost') host.send(mime_msg.as_string(), immediate=True) except SMTPServerDisconnected as msg: logger.warn("SMTPServerDisconnected: %s." % msg) except SMTPRecipientsRefused as msg: raise WorkflowException(str(msg)) # Send report to recipients recips = self.get_recipients(ar) for recip in recips: if 'email' not in recip.get('pubpref', []) \ or not recip.get('email', ''): continue title = encode_header(recip.get('title', '')) email = recip.get('email') formatted = formataddr((title, email)) # Create the new mime_msg object, cause the previous one # has the pdf already attached mime_msg = MIMEMultipart('related') mime_msg['Subject'] = self.get_mail_subject(ar)[0] mime_msg['From'] = formataddr( (encode_header(lab.getName()), lab.getEmailAddress())) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(results_html, _subtype='html') mime_msg.attach(msg_txt) mime_msg['To'] = formatted # Attach the pdf to the email if requested if pdf_report and 'pdf' in recip.get('pubpref'): attachPdf(mime_msg, pdf_report, pdf_fn) # For now, I will simply ignore mail send under test. if hasattr(self.portal, 'robotframework'): continue msg_string = mime_msg.as_string() # content of outgoing email written to debug file if debug_mode: tmp_fn = tempfile.mktemp(suffix=".email") logger.debug("Writing MIME message for %s to %s" % (ar.Title(), tmp_fn)) open(tmp_fn, "wb").write(msg_string) try: host = getToolByName(ar, 'MailHost') host.send(msg_string, immediate=True) except SMTPServerDisconnected as msg: logger.warn("SMTPServerDisconnected: %s." % msg) except SMTPRecipientsRefused as msg: raise WorkflowException(str(msg)) ar.setDatePublished(DateTime()) return [ar]
def __call__(self): """Create and render selected report """ # if there's an error, we return productivity.pt which requires these. self.selection_macros = SelectionMacrosView(self.context, self.request) self.additional_reports = [] adapters = getAdapters((self.context, ), IProductivityReport) for name, adapter in adapters: report_dict = adapter(self.context, self.request) report_dict['id'] = name self.additional_reports.append(report_dict) report_id = self.request.get('report_id', '') if not report_id: message = _("No report specified in request") self.logger.error(message) self.context.plone_utils.addPortalMessage(message, 'error') return self.template() self.date = DateTime() username = self.context.portal_membership.getAuthenticatedMember().getUserName() self.reporter = self.user_fullname(username) self.reporter_email = self.user_email(username) # signature image self.reporter_signature = "" c = [x for x in self.bika_setup_catalog(portal_type='LabContact') if x.getObject().getUsername() == username] if c: sf = c[0].getObject().getSignature() if sf: self.reporter_signature = sf.absolute_url() + "/Signature" lab = self.context.bika_setup.laboratory self.laboratory = lab self.lab_title = lab.getName() self.lab_address = lab.getPrintAddress() self.lab_email = lab.getEmailAddress() self.lab_url = lab.getLabURL() client = logged_in_client(self.context) if client: clientuid = client.UID() self.client_title = client.Title() self.client_address = client.getPrintAddress() else: clientuid = None self.client_title = None self.client_address = None # Render form output # the report can add file names to this list; they will be deleted # once the PDF has been generated. temporary plot image files, etc. self.request['to_remove'] = [] if "report_module" in self.request: module = self.request["report_module"] else: module = "bika.lims.browser.reports.%s" % report_id try: exec ("from %s import Report" % module) # required during error redirect: the report must have a copy of # additional_reports, because it is used as a surrogate view. Report.additional_reports = self.additional_reports except ImportError: message = "Report %s.Report not found (shouldn't happen)" % module self.logger.error(message) self.context.plone_utils.addPortalMessage(message, 'error') return self.template() # Report must return dict with: # - report_title - title string for pdf/history listing # - report_data - rendered report output = Report(self.context, self.request)() # if CSV output is chosen, report returns None if not output: return if type(output) in (str, unicode, bytes): # remove temporary files for f in self.request['to_remove']: os.remove(f) return output # The report output gets pulled through report_frame.pt self.reportout = output['report_data'] framed_output = self.frame_template() # this is the good part result = createPdf(framed_output) # remove temporary files for f in self.request['to_remove']: os.remove(f) if result: # Create new report object reportid = self.aq_parent.generateUniqueId('Report') report = _createObjectByType("Report", self.aq_parent, reportid) report.edit(Client=clientuid) report.processForm() # write pdf to report object report.edit(title=output['report_title'], ReportFile=result) report.reindexObject() fn = "%s - %s" % (self.date.strftime(self.date_format_short), _u(output['report_title'])) setheader = self.request.RESPONSE.setHeader setheader('Content-Type', 'application/pdf') setheader("Content-Disposition", "attachment;filename=\"%s\"" % _c(fn)) self.request.RESPONSE.write(result) return
def publishFromHTML(self, aruid, results_html): # The AR can be published only and only if allowed uc = getToolByName(self.context, 'uid_catalog') ars = uc(UID=aruid) if not ars or len(ars) != 1: return [] ar = ars[0].getObject(); wf = getToolByName(ar, 'portal_workflow') allowed_states = ['verified', 'published'] # Publish/Republish allowed? if wf.getInfoFor(ar, 'review_state') not in allowed_states: # Pre-publish allowed? if not ar.getAnalyses(review_state=allowed_states): return [] # HTML written to debug file # debug_mode = App.config.getConfiguration().debug_mode "Commented by Yasir" debug_mode = True #" Added by Yasir" if debug_mode: tmp_fn = tempfile.mktemp(suffix=".html") logger.debug("Writing HTML for %s to %s" % (ar.Title(), tmp_fn)) open(tmp_fn, "wb").write(results_html) # Create the pdf report (will always be attached to the AR) # we must supply the file ourself so that createPdf leaves it alone. # This version replaces 'attachment' links; probably not required, # so it's repeated below, without these localise_images. # cleanup, results_html_for_pdf = self.localise_images(results_html) # pdf_fn = tempfile.mktemp(suffix=".pdf") # pdf_report = createPdf(htmlreport=results_html_for_pdf, outfile=pdf_fn) # for fn in cleanup: # os.remove(fn) # Create the pdf report (will always be attached to the AR) # we must supply the file ourself so that createPdf leaves it alone. pdf_fn = tempfile.mktemp(suffix=".pdf") pdf_report = createPdf(htmlreport=results_html, outfile=pdf_fn) # PDF written to debug file if debug_mode: logger.debug("Writing PDF for %s to %s" % (ar.Title(), pdf_fn)) else: os.remove(pdf_fn) recipients = [] contact = ar.getContact() lab = ar.bika_setup.laboratory if pdf_report: if contact: recipients = [{ 'UID': contact.UID(), 'Username': to_utf8(contact.getUsername()), 'Fullname': to_utf8(contact.getFullname()), 'EmailAddress': to_utf8(contact.getEmailAddress()), 'PublicationModes': contact.getPublicationPreference() }] reportid = ar.generateUniqueId('ARReport') report = _createObjectByType("ARReport", ar, reportid) report.edit( AnalysisRequest=ar.UID(), Pdf=pdf_report, Html=results_html, Recipients=recipients ) report.unmarkCreationFlag() renameAfterCreation(report) # Set status to prepublished/published/republished status = wf.getInfoFor(ar, 'review_state') transitions = {'verified': 'publish', 'published' : 'republish'} transition = transitions.get(status, 'prepublish') try: wf.doActionFor(ar, transition) except WorkflowException: pass # compose and send email. # The managers of the departments for which the current AR has # at least one AS must receive always the pdf report by email. # https://github.com/bikalabs/Bika-LIMS/issues/1028 mime_msg = MIMEMultipart('related') mime_msg['Subject'] = self.get_mail_subject(ar)[0] mime_msg['From'] = formataddr( (encode_header(lab.getName()), lab.getEmailAddress())) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(results_html, _subtype='html') mime_msg.attach(msg_txt) to = [] mngrs = ar.getResponsible() for mngrid in mngrs['ids']: name = mngrs['dict'][mngrid].get('name', '') email = mngrs['dict'][mngrid].get('email', '') if (email != ''): to.append(formataddr((encode_header(name), email))) if len(to) > 0: # Send the email to the managers mime_msg['To'] = ','.join(to) attachPdf(mime_msg, pdf_report, pdf_fn) try: host = getToolByName(ar, 'MailHost') host.send(mime_msg.as_string(), immediate=True) except SMTPServerDisconnected as msg: logger.warn("SMTPServerDisconnected: %s." % msg) except SMTPRecipientsRefused as msg: raise WorkflowException(str(msg)) # Send report to recipients recips = self.get_recipients(ar) for recip in recips: if 'email' not in recip.get('pubpref', []) \ or not recip.get('email', ''): continue title = encode_header(recip.get('title', '')) email = recip.get('email') formatted = formataddr((title, email)) # Create the new mime_msg object, cause the previous one # has the pdf already attached mime_msg = MIMEMultipart('related') mime_msg['Subject'] = self.get_mail_subject(ar)[0] mime_msg['From'] = formataddr( (encode_header(lab.getName()), lab.getEmailAddress())) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(results_html, _subtype='html') mime_msg.attach(msg_txt) mime_msg['To'] = formatted # Attach the pdf to the email if requested if pdf_report and 'pdf' in recip.get('pubpref'): attachPdf(mime_msg, pdf_report, pdf_fn) # For now, I will simply ignore mail send under test. if hasattr(self.portal, 'robotframework'): continue msg_string = mime_msg.as_string() # content of outgoing email written to debug file if debug_mode: tmp_fn = tempfile.mktemp(suffix=".email") logger.debug("Writing MIME message for %s to %s" % (ar.Title(), tmp_fn)) open(tmp_fn, "wb").write(msg_string) try: host = getToolByName(ar, 'MailHost') host.send(msg_string, immediate=True) except SMTPServerDisconnected as msg: logger.warn("SMTPServerDisconnected: %s." % msg) except SMTPRecipientsRefused as msg: raise WorkflowException(str(msg)) ar.setDatePublished(DateTime()) return [ar]
def toPdf(self): html = safe_unicode(self.template()).encode('utf-8') pdf_data = createPdf(html) return pdf_data
def __call__(self): pc = self.portal_catalog self.checkPermission = self.context.portal_membership.checkPermission self.now = DateTime() self.SamplingWorkflowEnabled = self.context.bika_setup.getSamplingWorkflowEnabled() # Client details (if client is associated) self.client = None client_uid = hasattr(self.context, 'getClientUID') and self.context.getClientUID() if client_uid: proxies = pc(portal_type='Client', UID=client_uid) if proxies: self.client = proxies[0].getObject() client_address = self.client.getPostalAddress() if self.contact and not client_address: client_address = self.contact.getBillingAddress() if not client_address: client_address = self.contact.getPhysicalAddress() if client_address: _keys = ['address', 'city', 'state', 'zip', 'country'] _list = [client_address.get(v) for v in _keys if client_address.get(v)] self.client_address = "<br/>".join(_list).replace("\n", "<br/>") if self.client_address.endswith("<br/>"): self.client_address = self.client_address[:-5] else: self.client_address = None # Reporter self.member = self.context.portal_membership.getAuthenticatedMember() self.username = self.member.getUserName() self.reporter = self.user_fullname(self.username) self.reporter_email = self.user_email(self.username) self.reporter_signature = "" c = [x for x in self.bika_setup_catalog(portal_type='LabContact') if x.getObject().getUsername() == self.username] if c: sf = c[0].getObject().getSignature() if sf: self.reporter_signature = sf.absolute_url() + "/Signature" # laboratory self.laboratory = self.context.bika_setup.laboratory self.accredited = self.laboratory.getLaboratoryAccredited() lab_address = self.laboratory.getPrintAddress() if lab_address: _keys = ['address', 'city', 'state', 'zip', 'country'] _list = [lab_address.get(v) for v in _keys if lab_address.get(v)] self.lab_address = "<br/>".join(_list).replace("\n", "<br/>") if self.lab_address.endswith("<br/>"): self.lab_address = self.lab_address[:-5] else: self.lab_address = None # Analysis Request results self.ars = [] self.ar_headers = [_("Request ID"), _("Date Requested"), _("Sample Type"), _("Sample Point")] self.analysis_headers = [_("Analysis Service"), _("Method"), _("Result"), _("Analyst")] for ar in self.context.getAnalysisRequests(): datecreated = ar.created() # datereceived = ar.getDateReceived() # datepublished = ar.getDatePublished() datalines = [] for analysis in ar.getAnalyses(full_objects=True): service = analysis.getService() method = service.getMethod() sample = ar.getSample() result = analysis.getResult() formatted_result = format_numeric_result(analysis, result) datalines.append({_("Analysis Service"): analysis.getService().Title(), _("Method"): method and method.Title() or "", _("Result"): formatted_result, _("Analyst"): self.user_fullname(analysis.getAnalyst()), _("Remarks"): analysis.getRemarks()}) self.ars.append({ _("Request ID"): ar.getRequestID(), _("Date Requested"): self.ulocalized_time(datecreated), # requested->created _("Sample Type"): sample.getSampleType() and sample.getSampleType().Title() or '', _("Sample Point"): sample.getSamplePoint() and sample.getSamplePoint().Title() or '', _("datalines"): datalines, }) # Create Report fn = self.context.Title() + " " + self.ulocalized_time(self.now) report_html = self.template() # debug_mode = App.config.getConfiguration().debug_mode "Commented by Yasir" debug_mode = True #"Added by Yasir" if debug_mode: tmp_fd, tmp_fn = tempfile.mkstemp(suffix=".html") logger.debug("Writing HTML for %s to %s" % (self.context, tmp_fn)) tmp_fd.write(report_html) tmp_fd.close() pdf_fd, pdf_fn = tempfile.mkstemp(suffix="pdf") pdf_fd.close() pdf = createPdf(report_html, outfile=pdf_fn) if debug_mode: logger.debug("Wrote PDF for %s to %s" % (self.context, pdf_fn)) else: os.remove(pdf_fn) # XXX Email published batches to who? # Send PDF to browser if not pdf.err: setheader = self.request.RESPONSE.setHeader setheader('Content-Type', 'application/pdf') setheader("Content-Disposition", "attachment;filename=\"%s\"" % fn) self.request.RESPONSE.write(pdf)
def __call__(self): pc = self.portal_catalog self.checkPermission = self.context.portal_membership.checkPermission self.now = DateTime() self.SamplingWorkflowEnabled = self.context.bika_setup.getSamplingWorkflowEnabled( ) # Client details (if client is associated) self.client = None client_uid = hasattr(self.context, 'getClientUID') and self.context.getClientUID() if client_uid: proxies = pc(portal_type='Client', UID=client_uid) if proxies: self.client = proxies[0].getObject() client_address = self.client.getPostalAddress() if self.contact and not client_address: client_address = self.contact.getBillingAddress() if not client_address: client_address = self.contact.getPhysicalAddress() if client_address: _keys = ['address', 'city', 'state', 'zip', 'country'] _list = [ client_address.get(v) for v in _keys if client_address.get(v) ] self.client_address = "<br/>".join(_list).replace( "\n", "<br/>") if self.client_address.endswith("<br/>"): self.client_address = self.client_address[:-5] else: self.client_address = None # Reporter self.member = self.context.portal_membership.getAuthenticatedMember() self.username = self.member.getUserName() self.reporter = self.user_fullname(self.username) self.reporter_email = self.user_email(self.username) self.reporter_signature = "" c = [ x for x in self.bika_setup_catalog(portal_type='LabContact') if x.getObject().getUsername() == self.username ] if c: sf = c[0].getObject().getSignature() if sf: self.reporter_signature = sf.absolute_url() + "/Signature" # laboratory self.laboratory = self.context.bika_setup.laboratory self.accredited = self.laboratory.getLaboratoryAccredited() lab_address = self.laboratory.getPrintAddress() if lab_address: _keys = ['address', 'city', 'state', 'zip', 'country'] _list = [lab_address.get(v) for v in _keys if lab_address.get(v)] self.lab_address = "<br/>".join(_list).replace("\n", "<br/>") if self.lab_address.endswith("<br/>"): self.lab_address = self.lab_address[:-5] else: self.lab_address = None # Analysis Request results self.ars = [] self.ar_headers = [ _("Request ID"), _("Date Requested"), _("Sample Type"), _("Sample Point") ] self.analysis_headers = [ _("Analysis Service"), _("Method"), _("Result"), _("Analyst") ] for ar in self.context.getAnalysisRequests(): datecreated = ar.created() # datereceived = ar.getDateReceived() # datepublished = ar.getDatePublished() datalines = [] for analysis in ar.getAnalyses(full_objects=True): service = analysis.getService() method = service.getMethod() sample = ar.getSample() result = analysis.getResult() formatted_result = format_numeric_result(analysis, result) datalines.append({ _("Analysis Service"): analysis.getService().Title(), _("Method"): method and method.Title() or "", _("Result"): formatted_result, _("Analyst"): self.user_fullname(analysis.getAnalyst()), _("Remarks"): analysis.getRemarks() }) self.ars.append({ _("Request ID"): ar.getRequestID(), _("Date Requested"): self.ulocalized_time(datecreated), # requested->created _("Sample Type"): sample.getSampleType() and sample.getSampleType().Title() or '', _("Sample Point"): sample.getSamplePoint() and sample.getSamplePoint().Title() or '', _("datalines"): datalines, }) # Create Report fn = self.context.Title() + " " + self.ulocalized_time(self.now) report_html = self.template() # debug_mode = App.config.getConfiguration().debug_mode "Commented by Yasir" debug_mode = True #"Added by Yasir" if debug_mode: tmp_fd, tmp_fn = tempfile.mkstemp(suffix=".html") logger.debug("Writing HTML for %s to %s" % (self.context, tmp_fn)) tmp_fd.write(report_html) tmp_fd.close() pdf_fd, pdf_fn = tempfile.mkstemp(suffix="pdf") pdf_fd.close() pdf = createPdf(report_html, outfile=pdf_fn) if debug_mode: logger.debug("Wrote PDF for %s to %s" % (self.context, pdf_fn)) else: os.remove(pdf_fn) # XXX Email published batches to who? # Send PDF to browser if not pdf.err: setheader = self.request.RESPONSE.setHeader setheader('Content-Type', 'application/pdf') setheader("Content-Disposition", "attachment;filename=\"%s\"" % fn) self.request.RESPONSE.write(pdf)