Пример #1
0
    def folderitem(self, obj, item, index):
        """Applies new properties to the item (Client) that is currently being
        rendered as a row in the list

        :param obj: client to be rendered as a row in the list
        :param item: dict representation of the client, suitable for the list
        :param index: current position of the item within the list
        :type obj: ATContentType/DexterityContentType
        :type item: dict
        :type index: int
        :return: the dict representation of the item
        :rtype: dict
        """

        url = obj.absolute_url()
        title = obj.Title()

        item['Description'] = obj.Description()
        item["replace"]["Title"] = get_link(url, value=title)

        # Icons
        after_icons = ""
        if obj.getBlank():
            after_icons += get_image("blank.png", title=t(_("Blank")))
        if obj.getHazardous():
            after_icons += get_image("hazardous.png", title=t(_("Hazardous")))
        if after_icons:
            item["after"]["Title"] = after_icons

        return item
Пример #2
0
def _folder_item_specifications(self, analysis_brain, item):
    """Set the results range to the item passed in"""
    # Everyone can see valid-ranges
    item['Specification'] = ''
    analysis = api.get_object(analysis_brain)
    results_range = analysis.getResultsRange()
    if not results_range:
        return

    # Display the specification interval
    item["Specification"] = get_formatted_interval(results_range, "")

    # Show an icon if out of range
    out_range, out_shoulders = is_out_of_range(analysis_brain)
    if not out_range:
        return
    # At least is out of range
    img = get_image("exclamation.png", title=_("Result out of range"))
    if not out_shoulders:
        img = get_image("warning.png", title=_("Result in shoulder range"))
    self._append_html_element(item, "Result", img)

    # Grades
    grade = api.get_grade_number(analysis_brain)
    if grade:
        span = "&nbsp;<span class='small grade_{}'>G{}</span>".format(
            grade, grade)
        self._append_html_element(item, "Result", span)
Пример #3
0
    def _folder_item_specifications(self, analysis_brain, item):
        """Set the results range to the item passed in"""
        # Everyone can see valid-ranges
        item['Specification'] = ''
        results_range = analysis_brain.getResultsRange
        if not results_range:
            return
        min_str = results_range.get('min', '')
        max_str = results_range.get('max', '')
        min_str = api.is_floatable(min_str) and "{0}".format(min_str) or ""
        max_str = api.is_floatable(max_str) and "{0}".format(max_str) or ""
        specs = ", ".join([val for val in [min_str, max_str] if val])
        if not specs:
            return
        item["Specification"] = "[{}]".format(specs)

        # Show an icon if out of range
        out_range, out_shoulders = is_out_of_range(analysis_brain)
        if not out_range:
            return
        # At least is out of range
        img = get_image("exclamation.png", title=_("Result out of range"))
        if not out_shoulders:
            img = get_image("warning.png", title=_("Result in shoulder range"))
        self._append_html_element(item, "Result", img)
Пример #4
0
    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
        """
        # ensure we have an object and not a brain
        obj = api.get_object(obj)
        uid = api.get_uid(obj)
        url = api.get_url(obj)
        title = api.get_title(obj)

        # get the category
        if self.show_categories_enabled():
            category = obj.getCategoryTitle()
            if category not in self.categories:
                self.categories.append(category)
            item["category"] = category

        config = self.configuration.get(uid, {})
        hidden = config.get("hidden", False)

        item["replace"]["Title"] = get_link(url, value=title)
        item["Price"] = self.format_price(obj.Price)
        item["allow_edit"] = self.get_editable_columns()
        item["selected"] = False
        item["Hidden"] = hidden
        item["selected"] = uid in self.configuration

        # Add methods
        methods = obj.getMethods()
        if methods:
            links = map(
                lambda m: get_link(
                    m.absolute_url(), value=m.Title(), css_class="link"),
                methods)
            item["replace"]["Methods"] = ", ".join(links)
        else:
            item["methods"] = ""

        # Icons
        after_icons = ""
        if obj.getAccredited():
            after_icons += get_image(
                "accredited.png", title=_("Accredited"))
        if obj.getAttachmentOption() == "r":
            after_icons += get_image(
                "attach_reqd.png", title=_("Attachment required"))
        if obj.getAttachmentOption() == "n":
            after_icons += get_image(
                "attach_no.png", title=_("Attachment not permitted"))
        if after_icons:
            item["after"]["Title"] = after_icons

        return item
Пример #5
0
    def folderitem(self, obj, item, index):
        """Applies new properties to the item (Client) that is currently being
        rendered as a row in the list

        :param obj: client to be rendered as a row in the list
        :param item: dict representation of the client, suitable for the list
        :param index: current position of the item within the list
        :type obj: ATContentType/DexterityContentType
        :type item: dict
        :type index: int
        :return: the dict representation of the item
        :rtype: dict
        """

        obj = api.get_object(obj)

        # XXX Refactor expiration to a proper place
        # ---------------------------- 8< -------------------------------------
        if item.get("review_state", "current") == "current":
            # Check expiry date
            exdate = obj.getExpiryDate()
            if exdate:
                expirydate = DT2dt(exdate).replace(tzinfo=None)
                if (datetime.today() > expirydate):
                    # Trigger expiration
                    self.workflow.doActionFor(obj, "expire")
                    item["review_state"] = "expired"
                    item["obj"] = obj

        if self.contentFilter.get('review_state', '') \
           and item.get('review_state', '') == 'expired':
            # This item must be omitted from the list
            return None
        # ---------------------------- >8 -------------------------------------

        url = api.get_url(obj)
        id = api.get_id(obj)

        item["ID"] = id
        item["replace"]["ID"] = get_link(url, value=id)
        item["DateSampled"] = self.ulocalized_time(
            obj.getDateSampled(), long_format=True)
        item["DateReceived"] = self.ulocalized_time(obj.getDateReceived())
        item["DateOpened"] = self.ulocalized_time(obj.getDateOpened())
        item["ExpiryDate"] = self.ulocalized_time(obj.getExpiryDate())

        # Icons
        after_icons = ''
        if obj.getBlank():
            after_icons += get_image(
                "blank.png", title=t(_("Blank")))
        if obj.getHazardous():
            after_icons += get_image(
                "hazardous.png", title=t(_("Hazardous")))
        if after_icons:
            item["after"]["ID"] = after_icons

        return item
    def folderitem(self, obj, item, index):
        """Processed once per analysis
        """
        cat = obj.getCategoryTitle()
        # Category (upper C) is for display column value
        item["Category"] = cat
        if self.do_cats:
            # category is for bika_listing to groups entries
            item["category"] = cat
            if cat not in self.categories:
                self.categories.append(cat)

        analyses = [a.UID() for a in self.fieldvalue]

        item["selected"] = item["uid"] in analyses
        item["class"]["Title"] = "service_title"

        # Price
        item["Price"] = self.format_price(obj.Price)
        item["class"]["Price"] = "nowrap"

        # Icons
        after_icons = ""
        if obj.getAccredited():
            after_icons += get_image("accredited.png", title=_("Accredited"))
        if obj.getAttachmentOption() == "r":
            after_icons += get_image("attach_reqd.png",
                                     title=_("Attachment required"))
        if obj.getAttachmentOption() == "n":
            after_icons += get_image("attach_no.png",
                                     title=_("Attachment not permitted"))
        if after_icons:
            item["after"]["Title"] = after_icons

        if self.profile:
            # Display analyses for this Analysis Service in results?
            ser = self.profile.getAnalysisServiceSettings(obj.UID())
            item["allow_edit"] = [
                "Hidden",
            ]
            item["Hidden"] = ser.get("hidden", obj.getHidden())

        # Add methods
        methods = obj.getMethods()
        if methods:
            links = map(
                lambda m: get_link(
                    m.absolute_url(), value=m.Title(), css_class="link"),
                methods)
            item["replace"]["Methods"] = ", ".join(links)
        else:
            item["methods"] = ""

        return item
Пример #7
0
    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
        """
        # ensure we have an object and not a brain
        obj = api.get_object(obj)
        uid = api.get_uid(obj)
        url = api.get_url(obj)
        title = api.get_title(obj)

        # get the category
        if self.show_categories_enabled():
            category = obj.getCategoryTitle()
            if category not in self.categories:
                self.categories.append(category)
            item["category"] = category

        rr = self.referenceresults.get(uid, {})
        item["Title"] = title
        item["replace"]["Title"] = get_link(url, value=title)
        item["allow_edit"] = self.get_editable_columns()
        item["required"] = self.get_required_columns()
        item["selected"] = rr and True or False
        item["result"] = rr.get("result", "")
        item["min"] = rr.get("min", "")
        item["max"] = rr.get("max", "")
        item["error"] = rr.get("error", "")

        # Icons
        after_icons = ""
        if obj.getAccredited():
            after_icons += get_image(
                "accredited.png", title=_("Accredited"))
        if obj.getAttachmentOption() == "r":
            after_icons += get_image(
                "attach_reqd.png", title=_("Attachment required"))
        if obj.getAttachmentOption() == "n":
            after_icons += get_image(
                "attach_no.png", title=_("Attachment not permitted"))
        if after_icons:
            item["after"]["Title"] = after_icons

        return item
Пример #8
0
    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
        """
        DueDate = obj.getDueDate

        item["getDateReceived"] = self.ulocalized_time(obj.getDateReceived)
        item["getDueDate"] = self.ulocalized_time(DueDate)

        if DueDate and DueDate < DateTime():
            item["after"]["DueDate"] = get_image("late.png",
                                                 title=t(_("Late Analysis")))

        # Add Priority column
        priority_sort_key = obj.getPrioritySortkey
        if not priority_sort_key:
            # Default priority is Medium = 3.
            # The format of PrioritySortKey is <priority>.<created>
            priority_sort_key = "3.%s" % obj.created.ISO8601()

        priority = priority_sort_key.split(".")[0]
        priority_text = t(PRIORITIES.getValue(priority))
        html = "<div title='{}' class='priority-ico priority-{}'><div>"
        item["replace"]["Priority"] = html.format(priority_text, priority)

        return item
Пример #9
0
    def _folder_item_assigned_worksheet(self, analysis_brain, item):
        """Adds an icon to the item dict if the analysis is assigned to a
        worksheet and if the icon is suitable for the current context

        :param analysis_brain: Brain that represents an analysis
        :param item: analysis' dictionary counterpart that represents a row
        """
        if not IAnalysisRequest.providedBy(self.context):
            # We want this icon to only appear if the context is an AR
            return

        if analysis_brain.worksheetanalysis_review_state != 'assigned':
            # No need to go further. This analysis is not assigned to any WS
            return

        analysis_obj = self.get_object(analysis_brain)
        worksheet = analysis_obj.getBackReferences('WorksheetAnalysis')
        if not worksheet:
            # No worksheet assigned. Do nothing
            return

        worksheet = worksheet[0]
        title = t(
            _("Assigned to: ${worksheet_id}",
              mapping={'worksheet_id': safe_unicode(worksheet.id)}))
        img = get_image('worksheet.png', title=title)
        anchor = get_link(worksheet.absolute_url(), img)
        self._append_html_element(item, 'state_title', anchor)
Пример #10
0
    def _folder_item_duedate(self, analysis_brain, item):
        """Set the analysis' due date to the item passed in.

        :param analysis_brain: Brain that represents an analysis
        :param item: analysis' dictionary counterpart that represents a row
        """

        # Note that if the analysis is a Reference Analysis, `getDueDate`
        # returns the date when the ReferenceSample expires. If the analysis is
        # a duplicate, `getDueDate` returns the due date of the source analysis
        due_date = analysis_brain.getDueDate
        if not due_date:
            return None
        due_date_str = self.ulocalized_time(due_date, long_format=0)
        item['DueDate'] = due_date_str

        # If the Analysis is late/overdue, display an icon
        capture_date = analysis_brain.getResultCaptureDate
        capture_date = capture_date or DateTime()
        if capture_date > due_date:
            # The analysis is late or overdue
            img = get_image('late.png',
                            title=t(_("Late Analysis")),
                            width='16px',
                            height='16px')
            item['replace']['DueDate'] = '{} {}'.format(due_date_str, img)
Пример #11
0
 def get_icon_for(self, typename):
     """Returns the big image icon by its (type-)name
     """
     image = "{}_big.png".format(typename)
     return get_image(image,
                      width="20px",
                      style="vertical-align: baseline;")
Пример #12
0
    def folderitem(self, obj, item, index):
        # Date of Birth
        dob = obj.getBirthDate
        item['getBirthDate'] = dob and self.ulocalized_time(dob) or ""
        try:
            item["age"] = dob and get_age_ymd(dob) or ""
        except:
            # Wrong date??
            msg = _("Date of Birth might be wrong")
            img = get_image("exclamation.png", title=msg)
            item["replace"]["age"] = img

        # make the columns patient title, patient ID and client patient ID
        # redirect to the Analysis Requests of the patient
        ars_url = "{}/{}".format(api.get_url(obj), "analysisrequests")
        for column in ['Title', 'getPatientID', 'getClientPatientID']:
            value = getattr(obj, column, None)
            if value:
                item["replace"][column] = get_link(ars_url, value)

        # Display the internal/external icons, but only if the logged-in user
        # does not belong to an external client
        if not self.is_external_user():
            # Renders an icon (shared/private/warn) next to the title of the
            # item based on the client
            item["before"]["Title"] = get_client_aware_html_image(obj)

        return item
Пример #13
0
    def folderitem(self, obj, item, index):
        item = super(QCAnalysesView, self).folderitem(obj, item, index)

        obj = self.get_object(obj)

        # Fill Worksheet cell
        worksheet = obj.getWorksheet()
        if not worksheet:
            return item

        # Fill the Worksheet cell
        ws_id = api.get_id(worksheet)
        ws_url = api.get_url(worksheet)
        item["replace"]["Worksheet"] = get_link(ws_url, value=ws_id)

        if IDuplicateAnalysis.providedBy(obj):
            an_type = "d"
            img_name = "duplicate.png"
            parent = obj.getRequest()
        else:
            an_type = obj.getReferenceType()
            img_name = an_type == "c" and "control.png" or "blank.png"
            parent = obj.aq_parent

        # Render the image
        an_type = QCANALYSIS_TYPES.getValue(an_type)
        item['before']['Service'] = get_image(img_name, title=an_type)

        # Fill the Parent cell
        parent_url = api.get_url(parent)
        parent_id = api.get_id(parent)
        item["replace"]["Parent"] = get_link(parent_url, value=parent_id)

        return item
Пример #14
0
    def folderitem(self, obj, item, index):
        """Augment folder listing item
        """
        url = item.get("url")
        title = item.get("Title")

        item["replace"]["Title"] = get_link(url, value=title)
        item["getType"] = _(obj.getType()[0])
        item["getDownFrom"] = self.localize_date(obj.getDownFrom())
        item["getDownTo"] = self.localize_date(obj.getDownTo())
        item["getMaintainer"] = obj.getMaintainer()

        status = obj.getCurrentState()
        statustext = obj.getCurrentStateI18n()
        statusimg = ""

        if status == mstatus.CLOSED:
            statusimg = "instrumentmaintenance_closed.png"
            item["state_class"] = "state-inactive"
        elif status == mstatus.CANCELLED:
            statusimg = "instrumentmaintenance_cancelled.png"
            item["state_class"] = "state-cancelled"
        elif status == mstatus.INQUEUE:
            statusimg = "instrumentmaintenance_inqueue.png"
            item["state_class"] = "state-open"
        elif status == mstatus.OVERDUE:
            statusimg = "instrumentmaintenance_overdue.png"
            item["state_class"] = "state-open"
        elif status == mstatus.PENDING:
            statusimg = "instrumentmaintenance_pending.png"
            item["state_class"] = "state-pending"

        item["replace"]["getCurrentState"] = get_image(statusimg,
                                                       title=statustext)
        return item
Пример #15
0
    def _folder_item_specifications(self, analysis_brain, item):
        """Set the results range to the item passed in"""
        # Everyone can see valid-ranges
        item['Specification'] = ''
        results_range = analysis_brain.getResultsRange
        if not results_range:
            return

        # Display the specification interval
        item["Specification"] = get_formatted_interval(results_range, "")

        # Show an icon if out of range
        out_range, out_shoulders = is_out_of_range(analysis_brain)
        if not out_range:
            return
        # At least is out of range
        img = get_image("exclamation.png", title=_("Result out of range"))
        if not out_shoulders:
            img = get_image("warning.png", title=_("Result in shoulder range"))
        self._append_html_element(item, "Result", img)
Пример #16
0
    def _folder_item_result(self, analysis_brain, item):
        """Set the analysis' result to the item passed in.

        :param analysis_brain: Brain that represents an analysis
        :param item: analysis' dictionary counterpart that represents a row
        """

        item["Result"] = ""

        if not self.has_permission(ViewResults, analysis_brain):
            # If user has no permissions, don"t display the result but an icon
            img = get_image("to_follow.png", width="16px", height="16px")
            item["before"]["Result"] = img
            return

        result = analysis_brain.getResult
        capture_date = analysis_brain.getResultCaptureDate
        capture_date_str = self.ulocalized_time(capture_date, long_format=0)

        item["Result"] = result
        item["CaptureDate"] = capture_date_str
        item["result_captured"] = capture_date_str
        item["string_result"] = False

        # Edit mode enabled of this Analysis
        if self.is_analysis_edition_allowed(analysis_brain):
            # Allow to set Remarks
            item["allow_edit"].append("Remarks")

            # Set the results field editable
            if self.is_result_edition_allowed(analysis_brain):
                item["allow_edit"].append("Result")

            # Prepare result options
            choices = analysis_brain.getResultOptions
            if choices:
                # N.B.we copy here the list to avoid persistent changes
                choices = copy(choices)
                # By default set empty as the default selected choice
                choices.insert(0, dict(ResultValue="", ResultText=""))
                item["choices"]["Result"] = choices
            else:
                # If not choices, set whether the result must be floatable
                obj = self.get_object(analysis_brain)
                item["string_result"] = obj.getStringResult()

        if not result:
            return

        obj = self.get_object(analysis_brain)
        formatted_result = obj.getFormattedResult(sciformat=int(self.scinot),
                                                  decimalmark=self.dmk)
        item["formatted_result"] = formatted_result
Пример #17
0
    def _folder_item_reflex_icons(self, analysis_brain, item):
        """Adds an icon to the item dictionary if the analysis has been
        automatically generated due to a reflex rule

        :param analysis_brain: Brain that represents an analysis
        :param item: analysis' dictionary counterpart that represents a row
        """
        if not analysis_brain.getIsReflexAnalysis:
            # Do nothing
            return
        img = get_image('reflexrule.png',
                        title=t(_('It comes form a reflex rule')))
        self._append_html_element(item, 'Service', img)
Пример #18
0
    def _folder_item_result(self, analysis_brain, item):
        """Set the analysis' result to the item passed in.

        :param analysis_brain: Brain that represents an analysis
        :param item: analysis' dictionary counterpart that represents a row
        """

        item['Result'] = ''
        if not self.has_permission(ViewResults, analysis_brain):
            # If user has no permissions, don't display the result but an icon
            img = get_image('to_follow.png', width='16px', height='16px')
            item['before']['Result'] = img
            return

        result = analysis_brain.getResult
        capture_date = analysis_brain.getResultCaptureDate
        capture_date_str = self.ulocalized_time(capture_date, long_format=0)
        item['Result'] = result
        item['CaptureDate'] = capture_date_str
        item['result_captured'] = capture_date_str

        if self.is_analysis_edition_allowed(analysis_brain):
            item['allow_edit'].extend(['Remarks'])
            item['allow_edit'].extend(['Result'])

            # If this analysis has a predefined set of options as result,
            # tell the template that selection list (choices) must be
            # rendered instead of an input field for the introduction of
            # result.
            choices = analysis_brain.getResultOptions
            if choices:
                # N.B.we copy here the list to avoid persistent changes
                choices = copy(choices)
                # By default set empty as the default selected choice
                choices.insert(0, dict(ResultValue="", ResultText=""))
                item['choices']['Result'] = choices

        # Wake up the object only if necessary. If there is no result set, then
        # there is no need to go further with formatted result
        if not result:
            return

        # TODO: Performance, we wake-up the full object here
        full_obj = self.get_object(analysis_brain)
        formatted_result = full_obj.getFormattedResult(sciformat=int(
            self.scinot),
                                                       decimalmark=self.dmk)
        item['formatted_result'] = formatted_result
Пример #19
0
    def folder_item(self, obj, item, index):
        batch = api.get_object(obj)
        # Doctor
        doctor = get_field_value(batch, "Doctor", None)
        item["Doctor"] = doctor and doctor.Title() or ""
        item["replace"]["Doctor"] = doctor and get_link(
            api.get_url(doctor), doctor.Title())
        # Onset Date
        onset = get_field_value(batch, "OnsetDate", None)
        item["OnsetDate"] = onset and self.listing.ulocalized_time(onset) or ""

        # Patient
        item["Patient"] = ""
        item["getPatientID"] = ""
        item["getClientPatientID"] = ""
        item["PatientAgeOnsetDate"] = ""
        patient = get_field_value(batch, "Patient", None)
        if patient:
            url = api.get_url(patient)
            item["Patient"] = patient.Title()
            item["replace"]["Patient"] = get_link(url, patient.Title())

            item["getPatientID"] = patient.id
            item["replace"]["getPatientID"] = get_link(url, patient.id)

            pid = patient.getClientPatientID()
            pid_link = pid and get_link(url, pid) or ""
            item["getClientPatientID"] = pid or ""
            item["replace"]["getClientPatientID"] = pid_link

            dob = patient.getBirthDate()
            if onset and dob:
                try:
                    age_ymd = get_age_ymd(patient.getBirthDate(), onset)
                    item["replace"]["PatientAgeOnsetDate"] = age_ymd
                except:
                    # Wrong date??
                    msg = _("Date of Birth or Case Onset Date are wrong")
                    img = get_image("exclamation.png", title=msg)
                    item["replace"]["PatientAgeOnsetDate"] = img

        # Display the internal/external icons, but only if the logged-in user
        # does not belong to an external client
        if not self.is_external_user:
            item["before"]["BatchID"] = get_client_aware_html_image(obj)

        return item
Пример #20
0
    def render_remarks_tag(self, ar):
        """Renders a remarks image icon
        """
        uid = api.get_uid(ar)
        url = ar.absolute_url()
        title = ar.Title()
        tooltip = _("Remarks of {}").format(title)

        # Note: The 'href' is picked up by the overlay handler, see
        #       bika.lims.worksheet.coffee
        attrs = {
            "css_class": "slot-remarks",
            "title": tooltip,
            "uid": uid,
            "href": "{}/base_view".format(url),
        }

        return get_image("remarks_ico.png", **attrs)
Пример #21
0
    def folderitem(self, obj, item, index):
        """Applies new properties to the item (Client) that is currently being
        rendered as a row in the list

        :param obj: client to be rendered as a row in the list
        :param item: dict representation of the client, suitable for the list
        :param index: current position of the item within the list
        :type obj: ATContentType/DexterityContentType
        :type item: dict
        :type index: int
        :return: the dict representation of the item
        :rtype: dict
        """

        obj = api.get_object(obj)
        url = obj.absolute_url()
        title = obj.Title()

        item["replace"]["Title"] = get_link(url, value=title)

        instruments = obj.getInstruments()
        if instruments:
            links = map(
                lambda i: get_link(i.absolute_url(), i.Title()), instruments)
            item["replace"]["Instrument"] = ", ".join(links)
        else:
            item["Instrument"] = ""

        calculation = obj.getCalculation()
        if calculation:
            title = calculation.Title()
            url = calculation.absolute_url()
            item["Calculation"] = title
            item["replace"]["Calculation"] = get_link(url, value=title)
        else:
            item["Calculation"] = ""

        manual_entry_of_results_allowed = obj.isManualEntryOfResults()
        item["ManualEntry"] = manual_entry_of_results_allowed
        item["replace"]["ManualEntry"] = " "
        if manual_entry_of_results_allowed:
            item["replace"]["ManualEntry"] = get_image("ok.png")

        return item
Пример #22
0
    def folderitem(self, obj, item, index):
        """Augment folder listing item with additional data
        """
        obj = api.get_object(obj)
        url = item.get("url")
        title = item.get("Title")

        item["replace"]["Title"] = get_link(url, value=title)
        item["getDate"] = self.localize_date(obj.getDate())
        item["getValidFrom"] = self.localize_date(obj.getValidFrom())
        item["getValidTo"] = self.localize_date(obj.getValidTo())

        if obj.getInternal() is True:
            item["replace"]["getAgency"] = ""
            item["state_class"] = "%s %s" % \
                (item["state_class"], "internalcertificate")

        item["getDocument"] = ""
        item["replace"]["getDocument"] = ""
        doc = self.get_document(obj)
        if doc and doc.get_size() > 0:
            filename = doc.filename
            download_url = "{}/at_download/Document".format(url)
            anchor = get_link(download_url, filename)
            item["getDocument"] = filename
            item["replace"]["getDocument"] = anchor

        # Latest valid certificate
        if obj == self.latest_certificate:
            item["state_class"] = "state-published"
        # Valid certificate
        elif obj in self.valid_certificates:
            item["state_class"] = "state-valid state-published"
        # Invalid certificates
        else:
            img = get_image("exclamation.png", title=t(_("Out of date")))
            item["replace"]["getValidTo"] = "%s %s" % (item["getValidTo"], img)
            item["state_class"] = "state-invalid"

        return item
Пример #23
0
    def _folder_item_remarks(self, analysis_brain, item):
        """Renders the Remarks field for the passed in analysis and if the
        edition of the analysis is permitted, adds a button to toggle the
        visibility of remarks field

        :param analysis_brain: Brain that represents an analysis
        :param item: analysis' dictionary counterpart that represents a row"""
        item['Remarks'] = analysis_brain.getRemarks

        if not self.is_analysis_edition_allowed(analysis_brain):
            # Edition not allowed, do not add the remarks toggle button, the
            # remarks field will be displayed without the option to hide it
            return

        if not self.context.bika_setup.getEnableAnalysisRemarks():
            # Remarks not enabled in Setup, so don't display the balloon button
            return

        # Analysis can be edited. Add the remarks toggle button
        title = t(_("Add Remark"))
        img = get_image('comment_ico.png', title=title)
        kwargs = {'class': "add-remark"}
        anchor = get_link('#', img, **kwargs)
        self._append_html_element(item, 'Service', anchor, after=False)
Пример #24
0
    def get_slot_header_data(self, obj):
        """Prepare the data for the slot header template
        """

        item_obj = None
        item_title = ""
        item_url = ""
        item_img = ""
        item_img_url = ""
        item_img_text = ""
        additional_item_icons = []

        parent_obj = None
        parent_title = ""
        parent_url = ""
        parent_img = ""
        parent_img_text = ""
        additional_parent_icons = []

        sample_type_obj = None
        sample_type_title = ""
        sample_type_url = ""
        sample_type_img = ""
        sample_type_img_text = ""

        if IDuplicateAnalysis.providedBy(obj):
            # item
            request = obj.getRequest()
            item_obj = request
            item_title = api.get_id(request)
            item_url = api.get_url(request)
            item_img = "duplicate.png"
            item_img_url = api.get_url(request)
            item_img_text = t(_("Duplicate"))
            # additional item icons
            additional_item_icons.append(self.render_remarks_tag(request))
            # parent
            client = request.getClient()
            parent_obj = client
            parent_title = api.get_title(client)
            parent_url = api.get_url(client)
            parent_img = "client.png"
            parent_img_text = t(_("Client"))
            # sample type
            sample_type = request.getSampleType()
            sample_type_title = request.getSampleTypeTitle()
            sample_type_url = api.get_url(sample_type)
            sample_type_img = "sampletype.png"
            sample_type_img_text = t(_("Sample Type"))

        elif IReferenceAnalysis.providedBy(obj):
            # item
            sample = obj.getSample()
            item_obj = sample
            item_title = api.get_id(sample)
            item_url = api.get_url(sample)
            item_img_url = api.get_url(sample)
            item_img = "control.png"
            item_img_text = t(_("Control"))
            if obj.getReferenceType() == "b":
                item_img = "blank.png"
                item_img_text = t(_("Blank"))
            # parent
            supplier = obj.getSupplier()
            parent_obj = supplier
            parent_title = api.get_title(supplier)
            parent_url = api.get_url(supplier)
            parent_img = "supplier.png"
            parent_img_text = t(_("Supplier"))
        elif IRoutineAnalysis.providedBy(obj):
            # item
            request = obj.getRequest()
            item_obj = request
            item_title = api.get_id(request)
            item_url = api.get_url(request)
            item_img = "sample.png"
            item_img_url = api.get_url(request)
            item_img_text = t(_("Sample"))
            # additional item icons
            additional_item_icons.append(self.render_remarks_tag(request))

            # parent
            client = obj.getClient()
            parent_obj = client
            parent_title = api.get_title(client)
            parent_url = api.get_url(client)
            parent_img = "client.png"
            parent_img_text = t(_("Client"))
            # sample type
            client_ref = request.getClientReference()
            client_sid = request.getClientSampleID()
            tokens = filter(None, [client_ref, client_sid])
            sample_type_title = ' / '.join(tokens)
            sample_type = obj.getSampleType()
            sample_type_img = "sampletype.png"
            sample_type_img_text = t(_("Tank / Blend ID"))

        return {
            # item
            "item_obj":
            item_obj,
            "item_title":
            item_title,
            "item_url":
            item_url,
            "item_img":
            get_image(item_img, title=item_img_text),
            "item_img_url":
            item_img_url,
            "additional_item_icons":
            additional_item_icons,
            # parent
            "parent_obj":
            parent_obj,
            "parent_title":
            parent_title,
            "parent_url":
            parent_url,
            "parent_img":
            get_image(parent_img, title=parent_img_text),
            "additional_parent_icons":
            additional_parent_icons,
            # sample type
            "sample_type_obj":
            sample_type_obj,
            "sample_type_title":
            sample_type_title,
            "sample_type_url":
            sample_type_url,
            "sample_type_img":
            get_image(sample_type_img, title=sample_type_img_text),
        }
Пример #25
0
    def __init__(self, context, request):
        super(AnalysesView, self).__init__(context, request)

        self.context = context
        self.request = request

        self.analyst = None
        self.instrument = None

        self.contentFilter = {
            "getWorksheetUID": api.get_uid(context),
            "sort_on": "sortable_title",
        }

        self.icon = "{}/{}".format(
            self.portal_url, "++resource++bika.lims.images/worksheet_big.png")

        self.allow_edit = True
        self.show_categories = False
        self.expand_all_categories = False
        self.show_search = False

        self.bika_setup = api.get_bika_setup()
        self.uids_strpositions = self.get_uids_strpositions()
        self.items_rowspans = dict()

        self.columns = collections.OrderedDict((
            ("Pos", {
                "sortable": False,
                "title": _("Position")
            }),
            ("Service", {
                "sortable": False,
                "title": _("Analysis")
            }),
            ("Method", {
                "sortable": False,
                "ajax": True,
                "title": _("Method")
            }),
            ("Instrument", {
                "sortable": False,
                "ajax": True,
                "title": _("Instrument")
            }),
            ("DetectionLimitOperand", {
                "title": _("DL"),
                "sortable": False,
                "ajax": True,
                "autosave": True,
                "toggle": False
            }),
            ("Result", {
                "title": _("Result"),
                "ajax": True,
                "sortable": False
            }),
            ("retested", {
                "title": get_image("retested.png", title=t(_("Retested"))),
                "toggle": False,
                "type": "boolean"
            }),
            ("Specification", {
                "title": _("Specification"),
                "sortable": False
            }),
            ("Uncertainty", {
                "sortable": False,
                "title": _("+-")
            }),
            ("DueDate", {
                "sortable": False,
                "title": _("Due Date")
            }),
            ("state_title", {
                "sortable": False,
                "title": _("State")
            }),
            ("Attachments", {
                "sortable": False,
                "title": _("Attachments")
            }),
        ))

        # Inject Remarks column for listing
        if self.is_analysis_remarks_enabled():
            self.columns["Remarks"] = {
                "title": "Remarks",
                "ajax": True,
                "toggle": False,
                "sortable": False,
                "type": "remarks"
            }

        self.review_states = [
            {
                "id": "default",
                "title": _("All"),
                "contentFilter": {},
                "columns": self.columns.keys(),
            },
        ]
Пример #26
0
    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
        """
        # ensure we have an object and not a brain
        obj = api.get_object(obj)
        uid = api.get_uid(obj)

        # settings for this analysis
        service_settings = self.context.getAnalysisServiceSettings(uid)
        hidden = service_settings.get("hidden", obj.getHidden())

        # get the category
        category = obj.getCategoryTitle()
        item["category"] = category
        if category not in self.categories:
            self.categories.append(category)

        price = obj.getPrice()
        keyword = obj.getKeyword()

        if uid in self.analyses:
            analysis = self.analyses[uid]
            # Might differ from the service keyword
            keyword = analysis.getKeyword()
            # Mark the row as disabled if the analysis has been submitted
            item["disabled"] = ISubmitted.providedBy(analysis)
            # get the hidden status of the analysis
            hidden = analysis.getHidden()
            # get the price of the analysis
            price = analysis.getPrice()

        # get the specification of this object
        rr = self.get_results_range()
        spec = rr.get(keyword, ResultsRangeDict())

        item["Title"] = obj.Title()
        item["Unit"] = obj.getUnit()
        item["Price"] = price
        item["before"]["Price"] = self.get_currency_symbol()
        item["allow_edit"] = self.get_editable_columns(obj)
        item["selected"] = uid in self.selected
        item["min"] = str(spec.get("min", ""))
        item["max"] = str(spec.get("max", ""))
        item["warn_min"] = str(spec.get("warn_min", ""))
        item["warn_max"] = str(spec.get("warn_max", ""))
        item["Hidden"] = hidden

        # Append info link before the service
        # see: bika.lims.site.coffee for the attached event handler
        item["before"]["Title"] = get_link(
            "analysisservice_info?service_uid={}".format(uid),
            value="<span class='glyphicon glyphicon-info-sign'></span>",
            css_class="service_info")

        # Icons
        after_icons = ""
        if obj.getAccredited():
            after_icons += get_image("accredited.png",
                                     title=t(_("Accredited")))
        if obj.getAttachmentOption() == "r":
            after_icons += get_image("attach_reqd.png",
                                     title=t(_("Attachment required")))
        if obj.getAttachmentOption() == "n":
            after_icons += get_image("attach_no.png",
                                     title=t(_('Attachment not permitted')))
        if after_icons:
            item["after"]["Title"] = after_icons

        return item
Пример #27
0
    def folderitem(self, obj, item, index):
        # Additional info from AnalysisRequest to be added in the item
        # generated by default by bikalisting.
        # Call the folderitem method from the base class
        item = super(SamplesView, self).folderitem(obj, item, index)
        if not item:
            return None

        item["Creator"] = self.user_fullname(obj.Creator)
        # If we redirect from the folderitems view we should check if the
        # user has permissions to medify the element or not.
        priority_sort_key = obj.getPrioritySortkey
        if not priority_sort_key:
            # Default priority is Medium = 3.
            # The format of PrioritySortKey is <priority>.<created>
            priority_sort_key = "3.%s" % obj.created.ISO8601()
        priority = priority_sort_key.split(".")[0]
        priority_text = PRIORITIES.getValue(priority)
        priority_div = """<div class="priority-ico priority-%s">
                          <span class="notext">%s</span><div>
                       """
        item["replace"]["Priority"] = priority_div % (priority, priority_text)
        item["replace"]["getProfilesTitle"] = obj.getProfilesTitleStr

        analysesnum = obj.getAnalysesNum
        if analysesnum:
            num_verified = str(analysesnum[0])
            num_total = str(analysesnum[1])
            item["getAnalysesNum"] = "{0}/{1}".format(num_verified, num_total)
        else:
            item["getAnalysesNum"] = ""

        # Progress
        progress_perc = obj.getProgress
        item["Progress"] = progress_perc
        item["replace"]["Progress"] = get_progress_bar_html(progress_perc)

        item["BatchID"] = obj.getBatchID
        if obj.getBatchID:
            item['replace']['BatchID'] = "<a href='%s'>%s</a>" % \
                                         (obj.getBatchURL, obj.getBatchID)
        # TODO: SubGroup ???
        # val = obj.Schema().getField('SubGroup').get(obj)
        # item['SubGroup'] = val.Title() if val else ''

        item["SamplingDate"] = self.str_date(obj.getSamplingDate)
        item["getDateReceived"] = self.str_date(obj.getDateReceived)
        item["getDueDate"] = self.str_date(obj.getDueDate)
        item["getDatePublished"] = self.str_date(obj.getDatePublished)
        item["getDateVerified"] = self.str_date(obj.getDateVerified)

        if self.is_printing_workflow_enabled:
            item["Printed"] = ""
            printed = obj.getPrinted if hasattr(obj, "getPrinted") else "0"
            print_icon = ""
            if printed == "0":
                print_icon = get_image("delete.png",
                                       title=t(_("Not printed yet")))
            elif printed == "1":
                print_icon = get_image("ok.png",
                                       title=t(_("Printed")))
            elif printed == "2":
                print_icon = get_image(
                    "exclamation.png",
                    title=t(_("Republished after last print")))
            item["after"]["Printed"] = print_icon
        item["SamplingDeviation"] = obj.getSamplingDeviationTitle

        item["getStorageLocation"] = obj.getStorageLocationTitle

        after_icons = ""
        if obj.assigned_state == 'assigned':
            after_icons += get_image("worksheet.png",
                                     title=t(_("All analyses assigned")))
        if item["review_state"] == 'invalid':
            after_icons += get_image("delete.png",
                                     title=t(_("Results have been withdrawn")))

        due_date = obj.getDueDate
        if due_date and due_date < (obj.getDatePublished or DateTime()):
            due_date_str = self.ulocalized_time(due_date)
            img_title = "{}: {}".format(t(_("Late Analyses")), due_date_str)
            after_icons += get_image("late.png", title=img_title)

        if obj.getSamplingDate and obj.getSamplingDate > DateTime():
            after_icons += get_image("calendar.png",
                                     title=t(_("Future dated sample")))
        if obj.getInvoiceExclude:
            after_icons += get_image("invoice_exclude.png",
                                     title=t(_("Exclude from invoice")))
        if obj.getHazardous:
            after_icons += get_image("hazardous.png",
                                     title=t(_("Hazardous")))

        if obj.getInternalUse:
            after_icons += get_image("locked.png", title=t(_("Internal use")))

        if after_icons:
            item['after']['getId'] = after_icons

        item['Created'] = self.ulocalized_time(obj.created, long_format=1)
        if obj.getContactUID:
            item['ClientContact'] = obj.getContactFullName
            item['replace']['ClientContact'] = "<a href='%s'>%s</a>" % \
                                               (obj.getContactURL, obj.getContactFullName)
        else:
            item["ClientContact"] = ""
        # TODO-performance: If SamplingWorkflowEnabled, we have to get the
        # full object to check the user permissions, so far this is
        # a performance hit.
        if obj.getSamplingWorkflowEnabled:
            # We don't do anything with Sampling Date.
            # User can modify Sampling date
            # inside AR view. In this listing view,
            # we only let the user to edit Date Sampled
            # and Sampler if he wants to make 'sample' transaction.
            if not obj.getDateSampled:
                datesampled = self.ulocalized_time(
                    DateTime(), long_format=True)
                item["class"]["getDateSampled"] = "provisional"
            else:
                datesampled = self.ulocalized_time(obj.getDateSampled,
                                                   long_format=True)

            sampler = obj.getSampler
            if sampler:
                item["replace"]["getSampler"] = obj.getSamplerFullName
            if "Sampler" in self.roles and not sampler:
                sampler = self.member.id
                item["class"]["getSampler"] = "provisional"
            # sampling workflow - inline edits for Sampler and Date Sampled
            if item["review_state"] == 'to_be_sampled':
                # We need to get the full object in order to check
                # the permissions
                full_object = obj.getObject()
                checkPermission = \
                    self.context.portal_membership.checkPermission

                # TODO Do we really need this check?
                if checkPermission(TransitionSampleSample, full_object):
                    item["required"] = ["getSampler", "getDateSampled"]
                    item["allow_edit"] = ["getSampler", "getDateSampled"]
                    # TODO-performance: hit performance while getting the
                    # sample object...
                    # TODO Can LabManagers be a Sampler?!
                    samplers = getUsers(full_object, ["Sampler", ])
                    username = self.member.getUserName()
                    users = [({
                        "ResultValue": u,
                        "ResultText": samplers.getValue(u)}) for u in samplers]
                    item['choices'] = {'getSampler': users}
                    Sampler = sampler and sampler or \
                              (username in samplers.keys() and username) or ''
                    sampler = Sampler
                else:
                    datesampled = self.ulocalized_time(obj.getDateSampled,
                                                       long_format=True)
                    sampler = obj.getSamplerFullName if obj.getSampler else ''
        else:
            datesampled = self.ulocalized_time(obj.getDateSampled,
                                               long_format=True)
            sampler = ""
        item["getDateSampled"] = datesampled
        item["getSampler"] = sampler

        # These don't exist on ARs
        # XXX This should be a list of preservers...
        item["getPreserver"] = ""
        item["getDatePreserved"] = ""

        # Assign parent and children partitions of this sample
        if self.show_partitions:
            item["parent"] = obj.getRawParentAnalysisRequest
            item["children"] = obj.getDescendantsUIDs or []

        return item
Пример #28
0
    def __init__(self, context, request):
        super(SamplesView, self).__init__(context, request)

        self.catalog = CATALOG_ANALYSIS_REQUEST_LISTING
        self.contentFilter = {
            "sort_on": "created",
            "sort_order": "descending",
            "isRootAncestor": True,  # only root ancestors
        }

        self.title = self.context.translate(_("Samples"))
        self.description = ""

        self.show_select_column = True
        self.form_id = "samples"
        self.context_actions = {}
        self.icon = "{}{}".format(
            self.portal_url, "/senaite_theme/icon/sample")

        self.url = api.get_url(self.context)

        # Toggle some columns if the sampling workflow is enabled
        sampling_enabled = api.get_setup().getSamplingWorkflowEnabled()

        self.columns = collections.OrderedDict((
            ("Priority", {
                "title": "",
                "index": "getPrioritySortkey",
                "sortable": True, }),
            ("Progress", {
                "title": "Progress",
                "index": "getProgress",
                "sortable": True,
                "toggle": True}),
            ("getId", {
                "title": _("Sample ID"),
                "attr": "getId",
                "replace_url": "getURL",
                "index": "getId"}),
            ("getClientOrderNumber", {
                "title": _("Client Order"),
                "sortable": True,
                "toggle": False}),
            ("Creator", {
                "title": _("Creator"),
                "index": "getCreatorFullName",
                "sortable": True,
                "toggle": True}),
            ("Created", {
                "title": _("Date Registered"),
                "index": "created",
                "toggle": False}),
            ("SamplingDate", {
                "title": _("Expected Sampling Date"),
                "index": "getSamplingDate",
                "toggle": sampling_enabled}),
            ("getDateSampled", {
                "title": _("Date Sampled"),
                "toggle": True,
                "input_class": "datetimepicker_nofuture",
                "input_width": "10"}),
            ("getDatePreserved", {
                "title": _("Date Preserved"),
                "toggle": False,
                "input_class": "datetimepicker_nofuture",
                "input_width": "10",
                "sortable": False}),  # no datesort without index
            ("getDateReceived", {
                "title": _("Date Received"),
                "toggle": False}),
            ("getDueDate", {
                "title": _("Due Date"),
                "toggle": False}),
            ("getDateVerified", {
                "title": _("Date Verified"),
                "input_width": "10",
                "toggle": False}),
            ("getDatePublished", {
                "title": _("Date Published"),
                "toggle": False}),
            ("BatchID", {
                "title": _("SDG ID"),
                "index": "getBatchID",
                "sortable": True,
                "toggle": False}),
            ("Client", {
                "title": _("Client"),
                "index": "getClientTitle",
                "attr": "getClientTitle",
                "replace_url": "getClientURL",
                "toggle": True}),
            ("ClientID", {
                "title": _("Client ID"),
                "index": "getClientID",
                "attr": "getClientID",
                "replace_url": "getClientURL",
                "toggle": True}),
            ("Province", {
                "title": _("Province"),
                "sortable": True,
                "index": "getProvince",
                "attr": "getProvince",
                "toggle": False}),
            ("District", {
                "title": _("District"),
                "sortable": True,
                "index": "getDistrict",
                "attr": "getDistrict",
                "toggle": False}),
            ("getClientReference", {
                "title": _("Client Ref"),
                "sortable": True,
                "index": "getClientReference",
                "toggle": False}),
            ("getClientSampleID", {
                "title": _("Client SID"),
                "toggle": False}),
            ("ClientContact", {
                "title": _("Contact"),
                "sortable": True,
                "index": "getContactFullName",
                "toggle": False}),
            ("getSampleTypeTitle", {
                "title": _("Sample Type"),
                "sortable": True,
                "toggle": True}),
            ("getSamplePointTitle", {
                "title": _("Sample Point"),
                "sortable": True,
                "index": "getSamplePointTitle",
                "toggle": False}),
            ("getStorageLocation", {
                "title": _("Storage Location"),
                "sortable": True,
                "index": "getStorageLocationTitle",
                "toggle": False}),
            ("SamplingDeviation", {
                "title": _("Sampling Deviation"),
                "sortable": True,
                "index": "getSamplingDeviationTitle",
                "toggle": False}),
            ("getSampler", {
                "title": _("Sampler"),
                "toggle": sampling_enabled}),
            ("getPreserver", {
                "title": _("Preserver"),
                "sortable": False,
                "toggle": False}),
            ("getProfilesTitle", {
                "title": _("Profile"),
                "sortable": True,
                "index": "getProfilesTitle",
                "toggle": False}),
            ("getAnalysesNum", {
                "title": _("Number of Analyses"),
                "sortable": True,
                "index": "getAnalysesNum",
                "toggle": False}),
            ("getTemplateTitle", {
                "title": _("Template"),
                "sortable": True,
                "index": "getTemplateTitle",
                "toggle": False}),
            ("Printed", {
                "title": _("Printed"),
                "sortable": False,
                "index": "getPrinted",
                "toggle": False}),
            ("state_title", {
                "title": _("State"),
                "sortable": True,
                "index": "review_state"}),
        ))

        # custom print transition
        print_stickers = {
            "id": "print_stickers",
            "title": _("Print stickers"),
            "url": "{}/workflow_action?action=print_stickers".format(self.url)
        }

        self.review_states = [
            {
                "id": "default",
                "title": _("Active"),
                "contentFilter": {
                    "review_state": (
                        "sample_registered",
                        "scheduled_sampling",
                        "to_be_sampled",
                        "sample_due",
                        "sample_received",
                        "to_be_preserved",
                        "to_be_verified",
                        "verified",
                    ),
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            }, {
                "id": "to_be_sampled",
                "title": _("To Be Sampled"),
                "contentFilter": {
                    "review_state": ("to_be_sampled",),
                    "sort_on": "created",
                    "sort_order": "descending"},
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys()
            }, {
                "id": "to_be_preserved",
                "title": _("To Be Preserved"),
                "contentFilter": {
                    "review_state": ("to_be_preserved",),
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            }, {
                "id": "scheduled_sampling",
                "title": _("Scheduled sampling"),
                "contentFilter": {
                    "review_state": ("scheduled_sampling",),
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            }, {
                "id": "sample_due",
                "title": _("Due"),
                "contentFilter": {
                    "review_state": (
                        "to_be_sampled",
                        "to_be_preserved",
                        "sample_due"),
                    "sort_on": "created",
                    "sort_order": "descending"},
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            }, {
                "id": "sample_received",
                "title": _("Received"),
                "contentFilter": {
                    "review_state": "sample_received",
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            }, {
                "id": "to_be_verified",
                "title": _("To be verified"),
                "contentFilter": {
                    "review_state": "to_be_verified",
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            }, {
                "id": "verified",
                "title": _("Verified"),
                "contentFilter": {
                    "review_state": "verified",
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            }, {
                "id": "published",
                "title": _("Published"),
                "contentFilter": {
                    "review_state": ("published"),
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [],
                "columns": self.columns.keys(),
            }, {
                "id": "dispatched",
                "title": _("Dispatched"),
                "flat_listing": True,
                "confirm_transitions": ["restore"],
                "contentFilter": {
                    "review_state": ("dispatched"),
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [],
                "columns": self.columns.keys(),
            }, {
                "id": "cancelled",
                "title": _("Cancelled"),
                "contentFilter": {
                    "review_state": "cancelled",
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [],
                "columns": self.columns.keys(),
            }, {
                "id": "invalid",
                "title": _("Invalid"),
                "contentFilter": {
                    "review_state": "invalid",
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            }, {
                "id": "all",
                "title": _("All"),
                "contentFilter": {
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            }, {
                "id": "rejected",
                "title": _("Rejected"),
                "contentFilter": {
                    "review_state": "rejected",
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            }, {
                "id": "assigned",
                "title": get_image("assigned.png",
                                   title=t(_("Assigned"))),
                "contentFilter": {
                    "assigned_state": "assigned",
                    "review_state": ("sample_received",),
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            }, {
                "id": "unassigned",
                "title": get_image("unassigned.png",
                                   title=t(_("Unsassigned"))),
                "contentFilter": {
                    "assigned_state": "unassigned",
                    "review_state": (
                        "sample_received",
                    ),
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            }, {
                "id": "late",
                "title": get_image("late.png",
                                   title=t(_("Late"))),
                "contentFilter": {
                    # Query only for unpublished ARs that are late
                    "review_state": (
                        "sample_received",
                        "to_be_verified",
                        "verified",
                    ),
                    "getDueDate": {
                        "query": DateTime(),
                        "range": "max",
                    },
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            }
        ]
Пример #29
0
    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
        """
        # ensure we have an object and not a brain
        obj = api.get_object(obj)
        url = api.get_url(obj)
        title = api.get_title(obj)
        keyword = obj.getKeyword()

        # dynamic analysisspecs
        dspecs = self.get_dynamic_analysisspecs()
        dspec = dspecs.get(keyword)
        # show the dynamic specification icon next to the Keyword
        if dspec:
            item["before"]["Keyword"] = get_image(
                "dynamic_analysisspec.png",
                title=_(
                    "Found Dynamic Analysis Specification for '{}' in '{}'".
                    format(keyword, self.dynamic_spec.Title())))

        # get the category
        if self.show_categories_enabled():
            category = obj.getCategoryTitle()
            if category not in self.categories:
                self.categories.append(category)
            item["category"] = category

        item["Title"] = title
        item["replace"]["Title"] = get_link(url, value=title)
        item["choices"]["min_operator"] = self.min_operator_choices
        item["choices"]["max_operator"] = self.max_operator_choices
        item["allow_edit"] = self.get_editable_columns()
        item["required"] = self.get_required_columns()

        spec = self.specification.get(keyword, {})

        item["selected"] = spec and True or False
        item["min_operator"] = spec.get("min_operator", "geq")
        item["min"] = spec.get("min", "")
        item["max_operator"] = spec.get("max_operator", "leq")
        item["max"] = spec.get("max", "")
        item["warn_min"] = spec.get("warn_min", "")
        item["warn_max"] = spec.get("warn_max", "")
        item["hidemin"] = spec.get("hidemin", "")
        item["hidemax"] = spec.get("hidemax", "")
        item["rangecomment"] = spec.get("rangecomment", "")

        # Add methods
        methods = obj.getMethods()
        if methods:
            links = map(
                lambda m: get_link(
                    m.absolute_url(), value=m.Title(), css_class="link"),
                methods)
            item["replace"]["Methods"] = ", ".join(links)
        else:
            item["methods"] = ""

        # Icons
        after_icons = ""
        if obj.getAccredited():
            after_icons += get_image("accredited.png", title=_("Accredited"))
        if obj.getAttachmentOption() == "r":
            after_icons += get_image("attach_reqd.png",
                                     title=_("Attachment required"))
        if obj.getAttachmentOption() == "n":
            after_icons += get_image("attach_no.png",
                                     title=_("Attachment not permitted"))
        if after_icons:
            item["after"]["Title"] = after_icons

        return item
Пример #30
0
    def __init__(self, context, request):
        super(AnalysisRequestsView, self).__init__(context, request)

        # hide the right column
        request.set("disable_plone.rightcolumn", 1)

        # hide the editable border
        if self.context.portal_type == "AnalysisRequestsFolder":
            self.request.set("disable_border", 1)

        # catalog used for the query
        self.catalog = CATALOG_ANALYSIS_REQUEST_LISTING

        self.contentFilter = {
            "sort_on": "created",
            "sort_order": "descending",
            "isRootAncestor": True,  # only root ancestors
        }

        self.context_actions = {}

        self.allow_edit = True

        self.show_select_row = False
        self.show_select_column = True
        self.form_id = "analysisrequests"

        ar_image_path = "/++resource++bika.lims.images/sample_big.png"
        self.icon = "{}{}".format(self.portal_url, ar_image_path)
        self.title = self.context.translate(_("Samples"))
        self.description = ""

        SamplingWorkflowEnabled = \
            self.context.bika_setup.getSamplingWorkflowEnabled()

        self.columns = collections.OrderedDict((
            ("Priority", {
                "title": "",
                "index": "getPrioritySortkey",
                "sortable": True,
            }),
            ("Progress", {
                "title": "Progress",
                "sortable": False,
                "toggle": True
            }),
            ("getId", {
                "title": _("Sample ID"),
                "attr": "getId",
                "replace_url": "getURL",
                "index": "getId"
            }),
            ("getClientOrderNumber", {
                "title": _("Client Order"),
                "sortable": True,
                "toggle": False
            }),
            ("Creator", {
                "title": _("Creator"),
                "index": "getCreatorFullName",
                "sortable": True,
                "toggle": True
            }),
            ("Created", {
                "title": _("Date Registered"),
                "index": "created",
                "toggle": False
            }),
            ("SamplingDate", {
                "title": _("Expected Sampling Date"),
                "index": "getSamplingDate",
                "toggle": SamplingWorkflowEnabled
            }),
            ("getDateSampled", {
                "title": _("Date Sampled"),
                "toggle": True,
                "input_class": "datetimepicker_nofuture",
                "input_width": "10"
            }),
            ("getDatePreserved", {
                "title": _("Date Preserved"),
                "toggle": False,
                "input_class": "datetimepicker_nofuture",
                "input_width": "10",
                "sortable": False
            }),  # no datesort without index
            ("getDateReceived", {
                "title": _("Date Received"),
                "toggle": False
            }),
            ("getDueDate", {
                "title": _("Due Date"),
                "toggle": False
            }),
            ("getDateVerified", {
                "title": _("Date Verified"),
                "input_width": "10",
                "toggle": False
            }),
            ("getDatePublished", {
                "title": _("Date Published"),
                "toggle": False
            }),
            ("BatchID", {
                "title": _("Batch ID"),
                "index": "getBatchID",
                "sortable": True,
                "toggle": False
            }),
            ("Client", {
                "title": _("Client"),
                "index": "getClientTitle",
                "attr": "getClientTitle",
                "replace_url": "getClientURL",
                "toggle": True
            }),
            ("ClientID", {
                "title": _("Plant ID"),
                "index": "getClientID",
                "attr": "getClientID",
                "replace_url": "getClientURL",
                "toggle": True
            }),
            ("Province", {
                "title": _("Province"),
                "sortable": True,
                "index": "getProvince",
                "attr": "getProvince",
                "toggle": False
            }),
            ("District", {
                "title": _("District"),
                "sortable": True,
                "index": "getDistrict",
                "attr": "getDistrict",
                "toggle": False
            }),
            ("getClientReference", {
                "title": _("VesselTank"),
                "sortable": True,
                "index": "getClientReference",
                "toggle": False
            }),
            ("getClientSampleID", {
                "title": _("Blend Code"),
                "toggle": False
            }),
            ("ClientContact", {
                "title": _("Contact"),
                "sortable": True,
                "index": "getContactFullName",
                "toggle": False
            }),
            ("getSampleTypeTitle", {
                "title": _("Sample Type"),
                "sortable": True,
                "toggle": True
            }),
            ("getSamplePointTitle", {
                "title": _("Sample Point"),
                "sortable": True,
                "index": "getSamplePointTitle",
                "toggle": False
            }),
            ("getStorageLocation", {
                "title": _("Storage Location"),
                "sortable": True,
                "index": "getStorageLocationTitle",
                "toggle": False
            }),
            ("SamplingDeviation", {
                "title": _("Sampling Deviation"),
                "sortable": True,
                "index": "getSamplingDeviationTitle",
                "toggle": False
            }),
            ("getSampler", {
                "title": _("Sampler"),
                "toggle": SamplingWorkflowEnabled
            }),
            ("getPreserver", {
                "title": _("Preserver"),
                "sortable": False,
                "toggle": False
            }),
            ("getProfilesTitle", {
                "title": _("Profile"),
                "sortable": True,
                "index": "getProfilesTitle",
                "toggle": False
            }),
            ("getAnalysesNum", {
                "title": _("Number of Analyses"),
                "sortable": True,
                "index": "getAnalysesNum",
                "toggle": False
            }),
            ("getTemplateTitle", {
                "title": _("Template"),
                "sortable": True,
                "index": "getTemplateTitle",
                "toggle": False
            }),
            ("Printed", {
                "title": _("Printed"),
                "sortable": False,
                "index": "getPrinted",
                "toggle": False
            }),
            ("state_title", {
                "title": _("State"),
                "sortable": True,
                "index": "review_state"
            }),
        ))

        # custom print transition
        print_stickers = {
            "id": "print_stickers",
            "title": _("Print stickers"),
            "url": "workflow_action?action=print_stickers"
        }

        self.review_states = [
            {
                "id": "default",
                "title": _("Active"),
                "contentFilter": {
                    "review_state": (
                        "sample_registered",
                        "scheduled_sampling",
                        "to_be_sampled",
                        "sample_due",
                        "sample_received",
                        "attachment_due",
                        "to_be_preserved",
                        "to_be_verified",
                        "verified",
                    ),
                    "sort_on":
                    "created",
                    "sort_order":
                    "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            },
            {
                "id": "to_be_sampled",
                "title": _("To Be Sampled"),
                "contentFilter": {
                    "review_state": ("to_be_sampled", ),
                    "sort_on": "created",
                    "sort_order": "descending"
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys()
            },
            {
                "id": "to_be_preserved",
                "title": _("To Be Preserved"),
                "contentFilter": {
                    "review_state": ("to_be_preserved", ),
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            },
            {
                "id": "scheduled_sampling",
                "title": _("Scheduled sampling"),
                "contentFilter": {
                    "review_state": ("scheduled_sampling", ),
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            },
            {
                "id": "sample_due",
                "title": _("Due"),
                "contentFilter": {
                    "review_state":
                    ("to_be_sampled", "to_be_preserved", "sample_due"),
                    "sort_on":
                    "created",
                    "sort_order":
                    "descending"
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            },
            {
                "id": "sample_received",
                "title": _("Received"),
                "contentFilter": {
                    "review_state": "sample_received",
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            },
            {
                "id": "to_be_verified",
                "title": _("To be verified"),
                "contentFilter": {
                    "review_state": "to_be_verified",
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            },
            {
                "id": "verified",
                "title": _("Verified"),
                "contentFilter": {
                    "review_state": "verified",
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            },
            {
                "id": "published",
                "title": _("Published"),
                "contentFilter": {
                    "review_state": ("published"),
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [],
                "columns": self.columns.keys(),
            },
            {
                "id": "cancelled",
                "title": _("Cancelled"),
                "contentFilter": {
                    "review_state": "cancelled",
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [],
                "columns": self.columns.keys(),
            },
            {
                "id": "invalid",
                "title": _("Invalid"),
                "contentFilter": {
                    "review_state": "invalid",
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            },
            {
                "id": "all",
                "title": _("All"),
                "contentFilter": {
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            },
            {
                "id":
                "rejected",
                "title":
                _("Rejected"),
                "contentFilter": {
                    "review_state": "rejected",
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [
                    {
                        "id": "print_stickers",
                        "title": _("Print stickers"),
                        "url": "workflow_action?action=print_stickers"
                    },
                ],
                "columns":
                self.columns.keys(),
            },
            {
                "id": "assigned",
                "title": get_image("assigned.png", title=t(_("Assigned"))),
                "contentFilter": {
                    "assigned_state": "assigned",
                    "review_state": (
                        "sample_received",
                        "attachment_due",
                    ),
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            },
            {
                "id": "unassigned",
                "title": get_image("unassigned.png",
                                   title=t(_("Unsassigned"))),
                "contentFilter": {
                    "assigned_state": "unassigned",
                    "review_state": (
                        "sample_received",
                        "attachment_due",
                    ),
                    "sort_on": "created",
                    "sort_order": "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            },
            {
                "id": "late",
                "title": get_image("late.png", title=t(_("Late"))),
                "contentFilter": {
                    # Query only for unpublished ARs that are late
                    "review_state": (
                        "sample_received",
                        "attachment_due",
                        "to_be_verified",
                        "verified",
                    ),
                    "getDueDate": {
                        "query": DateTime(),
                        "range": "max",
                    },
                    "sort_on":
                    "created",
                    "sort_order":
                    "descending",
                },
                "custom_transitions": [print_stickers],
                "columns": self.columns.keys(),
            }
        ]