def __call__(self): # TODO: Refactor this function call showRejectionMessage(self.context) # Save the results layout rlayout = self.request.get("resultslayout", "") if rlayout and rlayout in WORKSHEET_LAYOUT_OPTIONS.keys() \ and rlayout != self.context.getResultsLayout(): self.context.setResultsLayout(rlayout) message = _("Changes saved.") self.context.plone_utils.addPortalMessage(message, "info") # Classic/Transposed View Switch if self.context.getResultsLayout() == "1": view = "analyses_classic_view" self.Analyses = api.get_view( view, context=self.context, request=self.request) else: view = "analyses_transposed_view" self.Analyses = api.get_view( view, context=self.context, request=self.request) self.analystname = self.context.getAnalystName() self.instrumenttitle = self.get_instrument_title() # Check if the instruments used are valid self.checkInstrumentsValidity() return self.template()
def get_attachments_view(self): # refactored functionality into this separate Browser view, to be able # to have a form submit target. attachments_view = api.get_view("attachments_view", context=self.context, request=self.request) return attachments_view
def get_attachments(self): """Returns a list of attachments from the AR base view """ context = self.context request = self.request view = api.get_view("base_view", context=context, request=request) return view.getAttachments()
def __call__(self, context): portal_state = api.get_view("plone_portal_state") content_types = portal_state.friendly_types() # filter out non supported types content_types = filter(lambda pt: pt not in NON_SUPPORTED_TYPES, content_types) items = [SimpleTerm(item, item, item) for item in content_types] return SimpleVocabulary(items)
def analysis_log_view(self): """Get the log view of the requested analysis """ analysis = self.get_analysis() if analysis is None: return None view = api.get_view("log", context=analysis, request=self.request) view.update() view.before_render() return view
def analysis_log_view(self): """Get the log view of the requested analysis """ service = self.get_analysis_or_service() if not self.can_view_logs_of(service): return None view = api.get_view("auditlog", context=service, request=self.request) view.update() view.before_render() return view
def ReferenceResults(self, field, allow_edit=False): """Render Reference Results Table """ instance = getattr(self, "instance", field.aq_parent) table = api.get_view("table_reference_results", context=instance, request=self.REQUEST) # Call listing hooks table.update() table.before_render() return table.ajax_contents_table()
def AnalysisSpecificationResults(self, field, allow_edit=False): """Render Analyses Specifications Table """ instance = getattr(self, "instance", field.aq_parent) table = api.get_view("table_analysis_specifications", context=instance, request=self.REQUEST) # Call listing hooks table.update() table.before_render() return table.ajax_contents_table()
def Services(self, field, show_select_column=True): """Render Analyses Services Listing Table """ instance = getattr(self, "instance", field.aq_parent) table = api.get_view("table_analyses_services", context=instance, request=self.REQUEST) # Call listing hooks table.update() table.before_render() return table.ajax_contents_table()
def render_analyses_table(self, table="lab"): """Render Analyses Table """ if table not in ["lab", "field", "qc"]: raise KeyError("Table '{}' does not exist".format(table)) view_name = "table_{}_analyses".format(table) view = api.get_view( view_name, context=self.context, request=self.request) # Call listing hooks view.update() view.before_render() return view.ajax_contents_table()
def __call__(self): filename = "invoice.pdf" pdf = self.context.getInvoicePDF() if pdf: data = pdf.data else: ar = self.context.getAnalysisRequest() so = self.context.getSupplyOrder() context = ar or so view = api.get_view("invoice_create", context=context) data = view.create_pdf() self.context.setInvoicePDF(data) return self.download(data, filename)
def available(self): """Control availability of the viewlet """ context_state = api.get_view("plone_context_state") url = context_state.current_page_url() portal_url = api.get_url(api.get_portal()) # render on the portal root if url.endswith(portal_url): return True # render on the front-page if url.endswith("/front-page"): return True # render for manage_results if url.endswith("/manage_results"): return True return False
def get_analyses_table_view(self): view_name = "table_referenceanalyses" view = api.get_view( view_name, context=self.context, request=self.request) # Call listing hooks view.update() view.before_render() # TODO Refactor QC Charts as React Components # The current QC Chart is rendered by looking at the value from a # hidden input with id "graphdata", that is rendered below the contents # listing (see referenceanalyses.pt). # The value is a json, is built by folderitem function and is returned # by self.chart.get_json(). This function is called directly by the # template on render, but the template itself does not directly render # the contents listing, but is done asyncronously. # Hence the function at this point returns an empty dictionary because # folderitems hasn't been called yet. As a result, the chart appears # empty. Here, we force folderitems function to be called in order to # ensure the graphdata is filled before the template is rendered. view.get_folderitems() return view
def action_add_to_ws(self): """Form action to add a new attachment in a worksheet """ ws = self.context form = self.request.form attachment_file = form.get('AttachmentFile_file', None) analysis_uid = self.request.get('analysis_uid', None) service_uid = self.request.get('Service', None) AttachmentType = form.get('AttachmentType', '') AttachmentKeys = form.get('AttachmentKeys', '') ReportOption = form.get('ReportOption', 'i') # nothing to do if the attachment file is missing if attachment_file is None: logger.warn( "AttachmentView.action_add_attachment: Attachment file is missing" ) return if analysis_uid: rc = api.get_tool("reference_catalog") analysis = rc.lookupObject(analysis_uid) # create attachment attachment = self.create_attachment(ws, attachment_file, AttachmentType=AttachmentType, AttachmentKeys=AttachmentKeys, ReportOption=ReportOption) others = analysis.getAttachment() attachments = [] for other in others: attachments.append(other.UID()) attachments.append(attachment.UID()) analysis.setAttachment(attachments) # The metadata for getAttachmentUIDs need to get updated, # otherwise the attachments are not displayed # https://github.com/senaite/bika.lims/issues/521 analysis.reindexObject() if service_uid: workflow = api.get_tool('portal_workflow') # XXX: refactor out dependency to this view. view = api.get_view("manage_results", context=self.context, request=self.request) analyses = self.context.getAnalyses() allowed_states = ["assigned", "unassigned", "to_be_verified"] for analysis in analyses: if analysis.portal_type not in ('Analysis', 'DuplicateAnalysis'): continue if not analysis.getServiceUID() == service_uid: continue review_state = workflow.getInfoFor(analysis, 'review_state', '') if review_state not in allowed_states: continue # create attachment attachment = self.create_attachment( ws, attachment_file, AttachmentType=AttachmentType, AttachmentKeys=AttachmentKeys, ReportOption=ReportOption) others = analysis.getAttachment() attachments = [] for other in others: attachments.append(other.UID()) attachments.append(attachment.UID()) analysis.setAttachment(attachments) # The metadata for getAttachmentUIDs need to get updated, # otherwise the attachments are not displayed # https://github.com/senaite/bika.lims/issues/521 analysis.reindexObject() if self.request['HTTP_REFERER'].endswith('manage_results'): self.request.response.redirect('{}/manage_results'.format( self.context.absolute_url())) else: self.request.response.redirect(self.context.absolute_url())
def folderitem(self, obj, item, index): """Service triggered each time an item is iterated in folderitems. The use of this service prevents the extra-loops in child objects. :obj: the instance of the class to be foldered :item: dict containing the properties of the object to be used by the template :index: current index of the item """ obj = api.get_object(obj) # We are using the existing logic from the auditview logview = api.get_view("auditlog", context=obj, request=self.request) # get the last snapshot snapshot = get_last_snapshot(obj) # get the metadata of the last snapshot metadata = get_snapshot_metadata(snapshot) title = obj.Title() url = obj.absolute_url() auditlog_url = "{}/@@auditlog".format(url) # Title item["title"] = title # Link the title to the auditlog of the object item["replace"]["title"] = get_link(auditlog_url, value=title) # Version version = get_snapshot_version(obj, snapshot) item["version"] = version # Modification Date m_date = metadata.get("modified") item["modified"] = logview.to_localized_time(m_date) # Actor actor = metadata.get("actor") item["actor"] = actor # Fullname properties = api.get_user_properties(actor) item["fullname"] = properties.get("fullname", actor) # Roles roles = metadata.get("roles", []) item["roles"] = ", ".join(roles) # Remote Address remote_address = metadata.get("remote_address") item["remote_address"] = remote_address # Action action = metadata.get("action") item["action"] = logview.translate_state(action) # Review State review_state = metadata.get("review_state") item["review_state"] = logview.translate_state(review_state) # get the previous snapshot prev_snapshot = get_snapshot_by_version(obj, version - 1) if prev_snapshot: prev_metadata = get_snapshot_metadata(prev_snapshot) prev_review_state = prev_metadata.get("review_state") if prev_review_state != review_state: item["replace"]["review_state"] = "{} → {}".format( logview.translate_state(prev_review_state), logview.translate_state(review_state)) # Rendered Diff diff = compare_snapshots(snapshot, prev_snapshot) item["diff"] = logview.render_diff(diff) return item