def folderitems(self, **kwargs):
        items = super(SampleImportsView, self).folderitems()
        for x in range(len(items)):
            if 'obj' not in items[x]:
                continue
            obj = items[x]['obj']
            # NOTE: Some about obj that returns the brains and not the object
            # it could be that folderitems has been changange on the listing
            # this is a hack for to make it work
            if api.is_brain(obj):
                obj = obj.getObject()
            # End of NOTE

            items[x]['Title'] = obj.title_or_id()
            if items[x]['review_state'] == 'invalid':
                items[x]['replace']['Title'] = "<a href='%s/edit'>%s</a>" % (
                    obj.absolute_url(), items[x]['Title'])
            else:
                items[x]['replace']['Title'] = "<a href='%s/view'>%s</a>" % (
                    obj.absolute_url(), items[x]['Title'])
            items[x]['Creator'] = obj.Creator()
            items[x]['Filename'] = obj.getFilename()
            parent = obj.aq_parent
            items[x]['Client'] = parent if IClient.providedBy(parent) else ''
            items[x]['replace']['Client'] = "<a href='%s'>%s</a>" % (
                parent.absolute_url(), parent.Title())
            items[x]['DateCreated'] = ulocalized_time(
                obj.created(), long_format=True, time_only=False, context=obj)
            date = getTransitionDate(obj, 'validate')
            items[x]['DateValidated'] = date if date else ''
            date = getTransitionDate(obj, 'import')
            items[x]['DateImported'] = date if date else ''

        return items
Esempio n. 2
0
    def folderitems(self, **kwargs):
        items = super(ARImportsView, self).folderitems()
        for x in range(len(items)):
            if 'obj' not in items[x]:
                continue
            obj = items[x]['obj']
            items[x]['Title'] = obj.title_or_id()
            if items[x]['review_state'] == 'invalid':
                items[x]['replace']['Title'] = "<a href='%s/edit'>%s</a>" % (
                    obj.absolute_url(), items[x]['Title'])
            else:
                items[x]['replace']['Title'] = "<a href='%s/view'>%s</a>" % (
                    obj.absolute_url(), items[x]['Title'])
            items[x]['Creator'] = obj.Creator()
            items[x]['Filename'] = obj.getFilename()
            parent = obj.aq_parent
            items[x]['Client'] = parent if IClient.providedBy(parent) else ''
            items[x]['replace']['Client'] = "<a href='%s'>%s</a>" % (
                parent.absolute_url(), parent.Title())
            items[x]['DateCreated'] = ulocalized_time(
                obj.created(), long_format=True, time_only=False, context=obj)
            date = getTransitionDate(obj, 'validate')
            items[x]['DateValidated'] = date if date else ''
            date = getTransitionDate(obj, 'import')
            items[x]['DateImported'] = date if date else ''

        return items
Esempio n. 3
0
    def folderitems(self, **kwargs):
        items = super(ARImportsView, self).folderitems()
        for x in range(len(items)):
            if 'obj' not in items[x]:
                continue
            obj = items[x]['obj']
            items[x]['Title'] = obj.title_or_id()
            if items[x]['review_state'] == 'invalid':
                items[x]['replace']['Title'] = "<a href='%s/edit'>%s</a>" % (
                    obj.absolute_url(), items[x]['Title'])
            else:
                items[x]['replace']['Title'] = "<a href='%s/view'>%s</a>" % (
                    obj.absolute_url(), items[x]['Title'])
            items[x]['Creator'] = obj.Creator()
            items[x]['Filename'] = obj.getFilename()
            parent = obj.aq_parent
            items[x]['Client'] = parent if IClient.providedBy(parent) else ''
            items[x]['replace']['Client'] = "<a href='%s'>%s</a>" % (
                parent.absolute_url(), parent.Title())
            items[x]['DateCreated'] = ulocalized_time(obj.created(),
                                                      long_format=True,
                                                      time_only=False,
                                                      context=obj)
            date = getTransitionDate(obj, 'validate')
            items[x]['DateValidated'] = date if date else ''
            date = getTransitionDate(obj, 'import')
            items[x]['DateImported'] = date if date else ''

        return items
    def get_sample_container_info(self):
        """Returns the storage container this Sample is stored in
        """
        # Search the container the sample is stored in
        query = {
            "portal_type": "StorageSamplesContainer",
            "get_samples_uids": api.get_uid(self.context)
        }
        brains = api.search(query, SENAITE_STORAGE_CATALOG)
        if not brains:
            return None

        # Get the data info from the container
        container = api.get_object(brains[0])
        position = container.get_object_position(self.context)
        position = container.position_to_alpha(position[0], position[1])
        return {
            "uid": api.get_uid(container),
            "id": api.get_id(container),
            "title": api.get_title(container),
            "url": api.get_url(container),
            "position": position,
            "full_title": container.get_full_title(),
            "when": wf.getTransitionDate(self.context, "store"),
        }
Esempio n. 5
0
 def getDateVerified(self):
     """Returns the time the analysis was verified. If the analysis hasn't
     been yet verified, returns None
     :return: the time the analysis was verified or None
     :rtype: DateTime
     """
     return getTransitionDate(self, 'verify', return_as_datetime=True)
Esempio n. 6
0
 def getDateVerified(self):
     """Returns the time the analysis was verified. If the analysis hasn't
     been yet verified, returns None
     :return: the time the analysis was verified or None
     :rtype: DateTime
     """
     return getTransitionDate(self, 'verify', return_as_datetime=True)
Esempio n. 7
0
 def get_transition_date(self, obj, transition=None):
     """Returns the date of the given Transition
     """
     if self.is_model(obj):
         obj = obj.instance
     if transition is None:
         return None
     return getTransitionDate(obj, transition, return_as_datetime=True)
Esempio n. 8
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 = BikaListingView.folderitem(self, obj, item, index)
        if not item:
            return None

        member = self.mtool.getAuthenticatedMember()
        roles = member.getRoles()
        hideclientlink = 'RegulatoryInspector' in roles \
            and 'Manager' not in roles \
            and 'LabManager' not in roles \
            and 'LabClerk' not in roles

        sample = obj.getSample()
        url = obj.absolute_url()
        if getSecurityManager().checkPermission(EditResults, obj):
            url += "/manage_results"

        item['Client'] = obj.aq_parent.Title()
        if (hideclientlink == False):
            item['replace']['Client'] = "<a href='%s'>%s</a>" % \
                (obj.aq_parent.absolute_url(), obj.aq_parent.Title())
        item['Creator'] = self.user_fullname(obj.Creator())
        item['getRequestID'] = obj.getRequestID()
        item['replace']['getRequestID'] = "<a href='%s'>%s</a>" % \
             (url, item['getRequestID'])
        item['getSample'] = sample
        item['replace']['getSample'] = \
            "<a href='%s'>%s</a>" % (sample.absolute_url(), sample.Title())

        item['replace']['getProfilesTitle'] = ", ".join(
            [p.Title() for p in obj.getProfiles()])

        analysesnum = obj.getAnalysesNum()
        if analysesnum:
            item['getAnalysesNum'] = str(analysesnum[0]) + '/' + str(analysesnum[1])
        else:
            item['getAnalysesNum'] = ''

        batch = obj.getBatch()
        if batch:
            item['BatchID'] = batch.getBatchID()
            item['replace']['BatchID'] = "<a href='%s'>%s</a>" % \
                 (batch.absolute_url(), item['BatchID'])
        else:
            item['BatchID'] = ''

        val = obj.Schema().getField('SubGroup').get(obj)
        item['SubGroup'] = val.Title() if val else ''

        samplingdate = obj.getSample().getSamplingDate()
        item['SamplingDate'] = self.ulocalized_time(samplingdate, long_format=1)
        item['getDateReceived'] = self.ulocalized_time(obj.getDateReceived())
        item['getDatePublished'] = self.ulocalized_time(obj.getDatePublished())
            items[x]['getDateVerified'] = getTransitionDate(obj, 'verify')
Esempio n. 9
0
def after_receive(analysis_request):
    """Method triggered after "receive" transition for the Analysis Request
    passed in is performed
    """
    events.after_receive(analysis_request)

    # Set the date the Sample was received at the lab, not at point of testing
    # https://github.com/bhp-lims/bhp.lims/issues/233
    date_received = wf.getTransitionDate(analysis_request, "deliver", True)
    if date_received:
        analysis_request.setDateReceived(date_received)

    events.do_action_to_ancestors(analysis_request, "receive")
    events.do_action_to_descendants(analysis_request, "receive")
Esempio n. 10
0
def fix_i233(portal):
    """Set the date the Sample was received at the lab, not at point of testing
    https://github.com/bhp-lims/bhp.lims/issues/233
    """
    logger.info("Reseting Date Received (#233) ...")
    brains = api.search({}, CATALOG_ANALYSIS_REQUEST_LISTING)
    total = len(brains)
    for num, brain in enumerate(brains):
        if num % 100 == 0:
            logger.info("Reseting Date Received: {}/{}".format(num, total))
        if num % TRANSACTION_THERESHOLD == 0:
            commit_transaction(portal)

        sample = api.get_object(brain)
        date_received = getTransitionDate(sample, "deliver", True)
        if date_received and date_received != sample.getDateReceived():
            sample.setDateReceived(date_received)
            sample.reindexObject(idxs=["getDateReceived", "is_received"])

    logger.info("Reseting Date Received (#233) [DONE]")
Esempio n. 11
0
    def createInvoice(self, client_title, items):
        """ Creates and invoice for a client and a set of items
        """
        plone_view = self.restrictedTraverse('@@plone')
        invoice_id = self.generateUniqueId('Invoice')
        invoice = _createObjectByType("Invoice", self, invoice_id)
        pc = getToolByName(self, "portal_catalog")
        client = pc(portal_type="Client", getName=client_title)[0].getObject()
        invoice.edit(
            Client=client,
            InvoiceDate=DateTime(),
        )

        invoice.processForm()
        invoice.invoice_lineitems = []
        for item in items:
            lineitem = InvoiceLineItem()
            if item.portal_type == 'AnalysisRequest':
                lineitem['ItemDate'] = plone_view.toLocalizedTime(
                    getTransitionDate(item, 'publish'), long_format=1)
                lineitem['OrderNumber'] = item.getRequestID()
                lineitem['AnalysisRequest'] = item
                lineitem['SupplyOrder'] = ''
                description = get_invoice_item_description(item)
                lineitem['ItemDescription'] = description
            elif item.portal_type == 'SupplyOrder':
                lineitem['ItemDate'] = item.getDateDispatched()
                lineitem['OrderNumber'] = item.getOrderNumber()
                lineitem['AnalysisRequest'] = ''
                lineitem['SupplyOrder'] = item
                description = get_invoice_item_description(item)
                lineitem['ItemDescription'] = description
            lineitem['Subtotal'] = item.getSubtotal()
            lineitem['VATAmount'] = item.getVATAmount()
            lineitem['Total'] = item.getTotal()
            invoice.invoice_lineitems.append(lineitem)
        invoice.reindexObject()
        return invoice
Esempio n. 12
0
    def createInvoice(self, client_title, items):
        """ Creates and invoice for a client and a set of items
        """
        plone_view = self.restrictedTraverse('@@plone')
        invoice_id = self.generateUniqueId('Invoice')
        invoice = _createObjectByType("Invoice", self, invoice_id)
        pc = getToolByName(self, "portal_catalog")
        client = pc(portal_type="Client", getName=client_title)[0].getObject()
        invoice.edit(
            Client=client,
            InvoiceDate=DateTime(),
        )

        invoice.processForm()
        invoice.invoice_lineitems = []
        for item in items:
            lineitem = InvoiceLineItem()
            if item.portal_type == 'AnalysisRequest':
                lineitem['ItemDate'] = plone_view.toLocalizedTime(
                    getTransitionDate(item, 'publish'), long_format=1)
                lineitem['OrderNumber'] = item.getRequestID()
                lineitem['AnalysisRequest'] = item
                lineitem['SupplyOrder'] = ''
                description = get_invoice_item_description(item)
                lineitem['ItemDescription'] = description
            elif item.portal_type == 'SupplyOrder':
                lineitem['ItemDate'] = item.getDateDispatched()
                lineitem['OrderNumber'] = item.getOrderNumber()
                lineitem['AnalysisRequest'] = ''
                lineitem['SupplyOrder'] = item
                description = get_invoice_item_description(item)
                lineitem['ItemDescription'] = description
            lineitem['Subtotal'] = item.getSubtotal()
            lineitem['VATAmount'] = item.getVATAmount()
            lineitem['Total'] = item.getTotal()
            invoice.invoice_lineitems.append(lineitem)
        invoice.reindexObject()
        return invoice
Esempio n. 13
0
    def __call__(self):
        bc = getToolByName(self.context, 'bika_catalog')
        self.report_content = {}
        parm_lines = {}
        parms = []
        headings = {}
        headings['header'] = _("Samples not invoiced")
        headings['subheader'] = _(
            "Published Samples which have not been invoiced")

        count_all = 0

        query = {'portal_type': 'AnalysisRequest',
                 'getInvoiced': False,
                 'review_state': 'published',
                 'sort_order': 'reverse'}

        date_query = formatDateQuery(self.context, 'c_DatePublished')
        if date_query:
            query['getDatePublished'] = date_query
            pubished = formatDateParms(self.context, 'c_DatePublished')
        else:
            pubished = 'Undefined'
        parms.append(
            {'title': _('Published'),
             'value': pubished,
             'type': 'text'})

        parms.append(
            {'title': _('Active'),
             'value': 'Undefined',
             'type': 'text'})



        # and now lets do the actual report lines
        formats = {'columns': 6,
                   'col_heads': [_('Client'), \
                                 _('Request'), \
                                 _('Sample type'), \
                                 _('Sample point'), \
                                 _('Published'), \
                                 _('Amount'), \
                       ],
                   'class': '',
        }

        datalines = []
        clients = {}
        sampletypes = {}
        samplepoints = {}
        categories = {}
        services = {}

        for ar_proxy in bc(query):
            ar = ar_proxy.getObject()

            dataline = []

            dataitem = {'value': ar.aq_parent.Title()}
            dataline.append(dataitem)

            dataitem = {'value': ar.getId()}
            dataline.append(dataitem)

            dataitem = {'value': ar.getSampleTypeTitle()}
            dataline.append(dataitem)

            dataitem = {'value': ar.getSamplePointTitle()}
            dataline.append(dataitem)

            dataitem = {'value':
                        self.ulocalized_time(getTransitionDate(ar, 'publish'),
                                             long_format=True)}
            dataline.append(dataitem)

            dataitem = {'value': ar.getTotalPrice()}
            dataline.append(dataitem)

            datalines.append(dataline)

            count_all += 1

        # table footer data
        footlines = []
        footline = []
        footitem = {'value': _('Number of analyses retested for period'),
                    'colspan': 5,
                    'class': 'total_label'}
        footline.append(footitem)
        footitem = {'value': count_all}
        footline.append(footitem)
        footlines.append(footline)

        self.report_content = {
            'headings': headings,
            'parms': parms,
            'formats': formats,
            'datalines': datalines,
            'footings': footlines}

        return {'report_title': t(headings['header']),
                'report_data': self.template()}
Esempio n. 14
0
 def getDateSampled(self):
     """Used to populate catalog values.
     Only has value when sampling_workflow is active.
     """
     return getTransitionDate(self, 'sample', return_as_datetime=True)
Esempio n. 15
0
 def getDateReceived(self):
     """Used to populate catalog values.
     Returns the date on which the "receive" transition was invoked on this
     analysis' Sample.
     """
     return getTransitionDate(self, 'receive', return_as_datetime=True)
    def __call__(self):
        bc = getToolByName(self.context, 'bika_catalog')
        self.report_content = {}
        parm_lines = {}
        parms = []
        headings = {}
        headings['header'] = _("Analysis requests not invoiced")
        headings['subheader'] = _(
            "Published Analysis Requests which have not been invoiced")

        count_all = 0

        query = {'portal_type': 'AnalysisRequest',
                 'getInvoiced': False,
                 'review_state': 'published',
                 'sort_order': 'reverse'}

        date_query = formatDateQuery(self.context, 'c_DatePublished')
        if date_query:
            query['getDatePublished'] = date_query
            pubished = formatDateParms(self.context, 'c_DatePublished')
        else:
            pubished = 'Undefined'
        parms.append(
            {'title': _('Published'),
             'value': pubished,
             'type': 'text'})

        if self.request.form.has_key('cancellation_state'):
            query['cancellation_state'] = self.request.form['cancellation_state']
            cancellation_state = wf_tool.getTitleForStateOnType(
                self.request.form['cancellation_state'], 'AnalysisRequest')
        else:
            cancellation_state = 'Undefined'
        parms.append(
            {'title': _('Active'),
             'value': cancellation_state,
             'type': 'text'})



        # and now lets do the actual report lines
        formats = {'columns': 6,
                   'col_heads': [_('Client'), \
                                 _('Request'), \
                                 _('Sample type'), \
                                 _('Sample point'), \
                                 _('Published'), \
                                 _('Amount'), \
                       ],
                   'class': '',
        }

        datalines = []
        clients = {}
        sampletypes = {}
        samplepoints = {}
        categories = {}
        services = {}

        for ar_proxy in bc(query):
            ar = ar_proxy.getObject()

            dataline = []

            dataitem = {'value': ar.aq_parent.Title()}
            dataline.append(dataitem)

            dataitem = {'value': ar.getRequestID()}
            dataline.append(dataitem)

            dataitem = {'value': ar.getSampleTypeTitle()}
            dataline.append(dataitem)

            dataitem = {'value': ar.getSamplePointTitle()}
            dataline.append(dataitem)

            dataitem = {'value':
                        self.ulocalized_time(getTransitionDate(ar, 'publish'),
                                             long_format=True)}
            dataline.append(dataitem)

            dataitem = {'value': ar.getTotalPrice()}
            dataline.append(dataitem)

            datalines.append(dataline)

            count_all += 1

        # table footer data
        footlines = []
        footline = []
        footitem = {'value': _('Number of analyses retested for period'),
                    'colspan': 5,
                    'class': 'total_label'}
        footline.append(footitem)
        footitem = {'value': count_all}
        footline.append(footitem)
        footlines.append(footline)

        self.report_content = {
            'headings': headings,
            'parms': parms,
            'formats': formats,
            'datalines': datalines,
            'footings': footlines}

        return {'report_title': t(headings['header']),
                'report_data': self.template()}
Esempio n. 17
0
 def getDateSubmitted(self):
     """Returns the time the result was submitted.
     :return: a DateTime object.
     :rtype: DateTime
     """
     return getTransitionDate(self, 'submit', return_as_datetime=True)
    def __call__(self):
        bc = getToolByName(self.context, "bika_catalog")
        self.report_content = {}
        parm_lines = {}
        parms = []
        headings = {}
        headings["header"] = _("Analysis requests not invoiced")
        headings["subheader"] = _("Published Analysis Requests which have not been invoiced")

        count_all = 0

        query = {
            "portal_type": "AnalysisRequest",
            "getInvoiced": False,
            "review_state": "published",
            "sort_order": "reverse",
        }

        date_query = formatDateQuery(self.context, "c_DatePublished")
        if date_query:
            query["getDatePublished"] = date_query
            pubished = formatDateParms(self.context, "c_DatePublished")
        else:
            pubished = "Undefined"
        parms.append({"title": _("Published"), "value": pubished, "type": "text"})

        if self.request.form.has_key("cancellation_state"):
            query["cancellation_state"] = self.request.form["cancellation_state"]
            cancellation_state = wf_tool.getTitleForStateOnType(
                self.request.form["cancellation_state"], "AnalysisRequest"
            )
        else:
            cancellation_state = "Undefined"
        parms.append({"title": _("Active"), "value": cancellation_state, "type": "text"})

        # and now lets do the actual report lines
        formats = {
            "columns": 6,
            "col_heads": [_("Client"), _("Request"), _("Sample type"), _("Sample point"), _("Published"), _("Amount")],
            "class": "",
        }

        datalines = []
        clients = {}
        sampletypes = {}
        samplepoints = {}
        categories = {}
        services = {}

        for ar_proxy in bc(query):
            ar = ar_proxy.getObject()

            dataline = []

            dataitem = {"value": ar.aq_parent.Title()}
            dataline.append(dataitem)

            dataitem = {"value": ar.getRequestID()}
            dataline.append(dataitem)

            dataitem = {"value": ar.getSampleTypeTitle()}
            dataline.append(dataitem)

            dataitem = {"value": ar.getSamplePointTitle()}
            dataline.append(dataitem)

            dataitem = {"value": self.ulocalized_time(getTransitionDate(ar, "publish"), long_format=True)}
            dataline.append(dataitem)

            dataitem = {"value": ar.getTotalPrice()}
            dataline.append(dataitem)

            datalines.append(dataline)

            count_all += 1

        # table footer data
        footlines = []
        footline = []
        footitem = {"value": _("Number of analyses retested for period"), "colspan": 5, "class": "total_label"}
        footline.append(footitem)
        footitem = {"value": count_all}
        footline.append(footitem)
        footlines.append(footline)

        self.report_content = {
            "headings": headings,
            "parms": parms,
            "formats": formats,
            "datalines": datalines,
            "footings": footlines,
        }

        return {"report_title": t(headings["header"]), "report_data": self.template()}
Esempio n. 19
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 = BikaListingView.folderitem(self, obj, item, index)
        if not item:
            return None

        member = self.mtool.getAuthenticatedMember()
        roles = member.getRoles()
        hideclientlink = 'RegulatoryInspector' in roles \
            and 'Manager' not in roles \
            and 'LabManager' not in roles \
            and 'LabClerk' not in roles

        sample = obj.getSample()
        url = obj.absolute_url()
        if getSecurityManager().checkPermission(EditResults, obj):
            url += "/manage_results"

        item['Client'] = obj.aq_parent.Title()
        if (hideclientlink == False):
            item['replace']['Client'] = "<a href='%s'>%s</a>" % \
                (obj.aq_parent.absolute_url(), obj.aq_parent.Title())
        item['Creator'] = self.user_fullname(obj.Creator())
        item['getRequestID'] = obj.getRequestID()
        item['replace']['getRequestID'] = "<a href='%s'>%s</a>" % \
             (url, item['getRequestID'])
        item['getSample'] = sample
        item['replace']['getSample'] = \
            "<a href='%s'>%s</a>" % (sample.absolute_url(), sample.Title())

        item['replace']['getProfilesTitle'] = ", ".join(
            [p.Title() for p in obj.getProfiles()])

        analysesnum = obj.getAnalysesNum()
        if analysesnum:
            item['getAnalysesNum'] = str(analysesnum[0]) + '/' + str(
                analysesnum[1])
        else:
            item['getAnalysesNum'] = ''

        batch = obj.getBatch()
        if batch:
            item['BatchID'] = batch.getBatchID()
            item['replace']['BatchID'] = "<a href='%s'>%s</a>" % \
                 (batch.absolute_url(), item['BatchID'])
        else:
            item['BatchID'] = ''

        val = obj.Schema().getField('SubGroup').get(obj)
        item['SubGroup'] = val.Title() if val else ''

        sd = obj.getSample().getSamplingDate()
        item['SamplingDate'] = \
            self.ulocalized_time(sd, long_format=1) if sd else ''
        item['getDateReceived'] = \
            self.ulocalized_time(obj.getDateReceived())
        item['getDatePublished'] = \
            self.ulocalized_time(getTransitionDate(obj, 'publish'))
        item['getDateVerified'] = \
            self.ulocalized_time(getTransitionDate(obj, 'verify'))

        deviation = sample.getSamplingDeviation()
        item['SamplingDeviation'] = deviation and deviation.Title() or ''
        priority = obj.getPriority()
        item['Priority'] = ''  # priority.Title()

        item['getStorageLocation'] = sample.getStorageLocation(
        ) and sample.getStorageLocation().Title() or ''
        item['AdHoc'] = sample.getAdHoc() and True or ''

        after_icons = ""
        state = self.workflow.getInfoFor(obj, 'worksheetanalysis_review_state')
        if state == 'assigned':
            after_icons += "<img src='%s/++resource++bika.lims.images/worksheet.png' title='%s'/>" % \
                (self.portal_url, t(_("All analyses assigned")))
        if self.workflow.getInfoFor(obj, 'review_state') == 'invalid':
            after_icons += "<img src='%s/++resource++bika.lims.images/delete.png' title='%s'/>" % \
                (self.portal_url, t(_("Results have been withdrawn")))
        if obj.getLate():
            after_icons += "<img src='%s/++resource++bika.lims.images/late.png' title='%s'>" % \
                (self.portal_url, t(_("Late Analyses")))
        if sd and sd > DateTime():
            after_icons += "<img src='%s/++resource++bika.lims.images/calendar.png' title='%s'>" % \
                (self.portal_url, t(_("Future dated sample")))
        if obj.getInvoiceExclude():
            after_icons += "<img src='%s/++resource++bika.lims.images/invoice_exclude.png' title='%s'>" % \
                (self.portal_url, t(_("Exclude from invoice")))
        if sample.getSampleType().getHazardous():
            after_icons += "<img src='%s/++resource++bika.lims.images/hazardous.png' title='%s'>" % \
                (self.portal_url, t(_("Hazardous")))
        if after_icons:
            item['after']['getRequestID'] = after_icons

        item['Created'] = self.ulocalized_time(obj.created())

        contact = obj.getContact()
        if contact:
            item['ClientContact'] = contact.Title()
            item['replace']['ClientContact'] = "<a href='%s'>%s</a>" % \
                (contact.absolute_url(), contact.Title())
        else:
            item['ClientContact'] = ""

        SamplingWorkflowEnabled = sample.getSamplingWorkflowEnabled()
        if SamplingWorkflowEnabled and (not sd or not sd > DateTime()):
            datesampled = self.ulocalized_time(sample.getDateSampled(),
                                               long_format=True)
            if not datesampled:
                datesampled = self.ulocalized_time(DateTime(),
                                                   long_format=True)
                item['class']['getDateSampled'] = 'provisional'
            sampler = sample.getSampler().strip()
            if sampler:
                item['replace']['getSampler'] = self.user_fullname(sampler)
            if 'Sampler' in member.getRoles() and not sampler:
                sampler = member.id
                item['class']['getSampler'] = 'provisional'
        else:
            datesampled = ''
            sampler = ''
        item['getDateSampled'] = datesampled
        item['getSampler'] = sampler

        # sampling workflow - inline edits for Sampler and Date Sampled
        checkPermission = self.context.portal_membership.checkPermission
        state = self.workflow.getInfoFor(obj, 'review_state')
        if state == 'to_be_sampled' \
                and checkPermission(SampleSample, obj) \
                and (not sd or not sd > DateTime()):
            item['required'] = ['getSampler', 'getDateSampled']
            item['allow_edit'] = ['getSampler', 'getDateSampled']
            samplers = getUsers(sample, ['Sampler', 'LabManager', 'Manager'])
            username = 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 ''
            item['getSampler'] = Sampler

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

        # inline edits for Preserver and Date Preserved
        checkPermission = self.context.portal_membership.checkPermission
        if checkPermission(PreserveSample, obj):
            item['required'] = ['getPreserver', 'getDatePreserved']
            item['allow_edit'] = ['getPreserver', 'getDatePreserved']
            preservers = getUsers(obj, ['Preserver', 'LabManager', 'Manager'])
            username = member.getUserName()
            users = [({
                'ResultValue': u,
                'ResultText': preservers.getValue(u)
            }) for u in preservers]
            item['choices'] = {'getPreserver': users}
            preserver = username in preservers.keys() and username or ''
            item['getPreserver'] = preserver
            item['getDatePreserved'] = self.ulocalized_time(DateTime(),
                                                            long_format=1)
            item['class']['getPreserver'] = 'provisional'
            item['class']['getDatePreserved'] = 'provisional'

        # Submitting user may not verify results
        if item['review_state'] == 'to_be_verified':
            username = member.getUserName()
            allowed = api.user.has_permission(VerifyPermission,
                                              username=username)
            if allowed and not obj.isUserAllowedToVerify(member):
                item['after']['state_title'] = \
                     "<img src='++resource++bika.lims.images/submitted-by-current-user.png' title='%s'/>" % \
                     t(_("Cannot verify: Submitted by current user"))

        return item
Esempio n. 20
0
 def getDateReceived(self):
     """Used to populate catalog values.
     Returns the date on which the "receive" transition was invoked on this
     analysis' Sample.
     """
     return getTransitionDate(self, 'receive', return_as_datetime=True)
Esempio n. 21
0
def getDateImported(instance):
    return getTransitionDate(instance, 'import')
Esempio n. 22
0
def getDateValidated(instance):
    return getTransitionDate(instance, 'validate')
    def __call__(self):

        parms = []
        titles = []

        # Apply filters
        self.contentFilter = {'portal_type': 'AnalysisRequest'}
        val = self.selection_macros.parse_daterange(self.request,
                                                    'created',
                                                    _('Date Created'))
        if val:
            self.contentFilter[val['contentFilter'][0]] = val['contentFilter'][1]
            parms.append(val['parms'])
            titles.append(val['titles'])

        # Query the catalog and store results in a dictionary
        catalog = getToolByName(self.context, CATALOG_ANALYSIS_REQUEST_LISTING)
        ars = catalog(self.contentFilter)
        if not ars:
            message = _("No Analysis Requests matched your query")
            self.context.plone_utils.addPortalMessage(message, "error")
            return self.default_template()

        datalines = {}
        footlines = {}
        totalcreatedcount = len(ars)
        totalreceivedcount = 0
        totalpublishedcount = 0
        totalanlcount = 0
        totalreceptionlag = 0
        totalpublicationlag = 0

        for ar in ars:
            ar = ar.getObject()
            datecreated = ar.created()
            datereceived = ar.getDateReceived()
            datepublished = getTransitionDate(ar, 'publish')
            receptionlag = 0
            publicationlag = 0
            anlcount = len(ar.getAnalyses())

            dataline = {
                "AnalysisRequestID": ar.getId(),
                "DateCreated": self.ulocalized_time(datecreated),
                "DateReceived": self.ulocalized_time(datereceived),
                "DatePublished": self.ulocalized_time(datepublished),
                "ReceptionLag": receptionlag,
                "PublicationLag": publicationlag,
                "TotalLag": receptionlag + publicationlag,
                "BatchID": ar.getBatch().getId() if ar.getBatch() else '',
                "SampleID": ar.getSample().Title(),
                "SampleType": ar.getSampleTypeTitle(),
                "NumAnalyses": anlcount,
                "ClientID": ar.aq_parent.id,
                "Creator": ar.Creator(),
                "Remarks": ar.getRemarks()
            }

            datalines[ar.getId()] = dataline

            totalreceivedcount += ar.getDateReceived() and 1 or 0
            totalpublishedcount += 1 if datepublished else 0
            totalanlcount += anlcount
            totalreceptionlag += receptionlag
            totalpublicationlag += publicationlag

        # Footer total data
        totalreceivedcreated_ratio = float(totalreceivedcount) / float(
            totalcreatedcount)
        totalpublishedcreated_ratio = float(totalpublishedcount) / float(
            totalcreatedcount)
        totalpublishedreceived_ratio = totalreceivedcount and float(
            totalpublishedcount) / float(totalreceivedcount) or 0

        footline = {'Created': totalcreatedcount,
                    'Received': totalreceivedcount,
                    'Published': totalpublishedcount,
                    'ReceivedCreatedRatio': totalreceivedcreated_ratio,
                    'ReceivedCreatedRatioPercentage': ('{0:.0f}'.format(
                        totalreceivedcreated_ratio * 100)) + "%",
                    'PublishedCreatedRatio': totalpublishedcreated_ratio,
                    'PublishedCreatedRatioPercentage': ('{0:.0f}'.format(
                        totalpublishedcreated_ratio * 100)) + "%",
                    'PublishedReceivedRatio': totalpublishedreceived_ratio,
                    'PublishedReceivedRatioPercentage': ('{0:.0f}'.format(
                        totalpublishedreceived_ratio * 100)) + "%",
                    'AvgReceptionLag': (
                    '{0:.1f}'.format(totalreceptionlag / totalcreatedcount)),
                    'AvgPublicationLag': (
                    '{0:.1f}'.format(totalpublicationlag / totalcreatedcount)),
                    'AvgTotalLag': ('{0:.1f}'.format((
                                                     totalreceptionlag + totalpublicationlag) / totalcreatedcount)),
                    'NumAnalyses': totalanlcount
        }

        footlines['Total'] = footline

        self.report_data = {'parameters': parms,
                            'datalines': datalines,
                            'footlines': footlines}

        if self.request.get('output_format', '') == 'CSV':
            import csv
            import StringIO
            import datetime

            fieldnames = [
                "AnalysisRequestID",
                "DateCreated",
                "DateReceived",
                "DatePublished",
                "ReceptionLag",
                "PublicationLag",
                "TotalLag",
                "BatchID",
                "SampleID",
                "SampleType",
                "NumAnalyses",
                "ClientID",
                "Creator",
                "Remarks",
            ]
            output = StringIO.StringIO()
            dw = csv.DictWriter(output, extrasaction='ignore',
                                fieldnames=fieldnames)
            dw.writerow(dict((fn, fn) for fn in fieldnames))
            for ar_id, row in datalines.items():
                dw.writerow({
                    "AnalysisRequestID": row["AnalysisRequestID"],
                    "DateCreated": row["DateCreated"],
                    "DateReceived": row["DateReceived"],
                    "DatePublished": row["DatePublished"],
                    "ReceptionLag": row["ReceptionLag"],
                    "PublicationLag": row["PublicationLag"],
                    "TotalLag": row["TotalLag"],
                    "BatchID": row["BatchID"],
                    "SampleID": row["SampleID"],
                    "SampleType": row["SampleType"],
                    "NumAnalyses": row["NumAnalyses"],
                    "ClientID": row["ClientID"],
                    "Creator": row["Creator"],
                    "Remarks": row["Remarks"],
                })
            report_data = output.getvalue()
            output.close()
            date = datetime.datetime.now().strftime("%Y%m%d%H%M")
            setheader = self.request.RESPONSE.setHeader
            setheader('Content-Type', 'text/csv')
            setheader("Content-Disposition",
                      "attachment;filename=\"dataentrydaybook_%s.csv\"" % date)
            self.request.RESPONSE.write(report_data)
        else:
            return {'report_title': _('Data entry day book'),
                    'report_data': self.template()}
Esempio n. 24
0
 def getDateSubmitted(self):
     """Returns the time the result was submitted.
     :return: a DateTime object.
     :rtype: DateTime
     """
     return getTransitionDate(self, 'submit', return_as_datetime=True)
Esempio n. 25
0
    def __call__(self):
        context = self.context
        workflow = getToolByName(context, 'portal_workflow')
        # Collect related data and objects
        invoice = context.getInvoice()
        sample = context.getSample()
        samplePoint = sample.getSamplePoint()
        reviewState = workflow.getInfoFor(context, 'review_state')
        # Collection invoice information
        if invoice:
            self.invoiceId = invoice.getId()
        else:
            self.invoiceId = _('Proforma (Not yet invoiced)')
        # Collect verified invoice information
        verified = reviewState in VERIFIED_STATES
        if verified:
            self.verifiedBy = context.getVerifier()
        self.verified = verified
        self.request['verified'] = verified
        # Collect published date
        self.datePublished = \
            self.ulocalized_time(getTransitionDate(context, 'publish'),
                                 long_format=1)
        # Collect received date
        dateReceived = context.getDateReceived()
        if dateReceived is not None:
            dateReceived = self.ulocalized_time(dateReceived, long_format=1)
        self.dateReceived = dateReceived
        # Collect general information
        self.reviewState = reviewState
        contact = context.getContact()
        self.contact = contact.Title() if contact else ""
        self.clientOrderNumber = context.getClientOrderNumber()
        self.clientReference = context.getClientReference()
        self.clientSampleId = sample.getClientSampleID()
        self.sampleType = sample.getSampleType().Title()
        self.samplePoint = samplePoint and samplePoint.Title()
        self.requestId = context.getId()
        self.headers = [
            {
                'title': 'Invoice ID',
                'value': self.invoiceId
            },
            {
                'title': 'Client Reference',
                'value': self.clientReference
            },
            {
                'title': 'Sample Type',
                'value': self.sampleType
            },
            {
                'title': 'Request ID',
                'value': self.requestId
            },
            {
                'title': 'Date Received',
                'value': self.dateReceived
            },
        ]
        if not isAttributeHidden('AnalysisRequest', 'ClientOrderNumber'):
            self.headers.append({
                'title': 'Client Sample Id',
                'value': self.clientOrderNumber
            })
        if not isAttributeHidden('AnalysisRequest', 'SamplePoint'):
            self.headers.append({
                'title': 'Sample Point',
                'value': self.samplePoint
            })
        if self.verified:
            self.headers.append({
                'title': 'Verified By',
                'value': self.verifiedBy
            })
            if self.datePublished:
                self.headers.append({
                    'title': 'datePublished',
                    'value': self.datePublished
                })

        analyses = []
        profiles = []
        # Retrieve required data from analyses collection
        all_analyses, all_profiles, analyses_from_profiles = context.getServicesAndProfiles(
        )
        # Relating category with solo analysis
        for analysis in all_analyses:
            categoryName = analysis.getCategoryTitle()
            # Find the category
            try:
                category = (o for o in analyses
                            if o['name'] == categoryName).next()
            except:
                category = {'name': categoryName, 'analyses': []}
                analyses.append(category)
            # Append the analysis to the category
            category['analyses'].append({
                'title':
                analysis.Title(),
                'price':
                analysis.getPrice(),
                'priceVat':
                "%.2f" % analysis.getVATAmount(),
                'priceTotal':
                "%.2f" % analysis.getTotalPrice(),
            })
        # Relating analysis services with their profiles
        # We'll take the analysis contained on each profile
        for profile in all_profiles:
            # If profile's checkbox "Use Analysis Profile Price" is enabled, only the profile price will be displayed.
            # Otherwise each analysis will display its own price.
            pservices = []
            if profile.getUseAnalysisProfilePrice():
                # We have to use the profiles price only
                for pservice in profile.getService():
                    pservices.append({
                        'title': pservice.Title(),
                        'price': None,
                        'priceVat': None,
                        'priceTotal': None,
                    })
                profiles.append({
                    'name': profile.title,
                    'price': profile.getAnalysisProfilePrice(),
                    'priceVat': profile.getVATAmount(),
                    'priceTotal': profile.getTotalPrice(),
                    'analyses': pservices
                })
            else:
                # We need the analyses prices instead of profile price
                for pservice in profile.getService():
                    # We want the analysis instead of the service, because we want the price for the client
                    # (for instance the bulk price)
                    panalysis = self._getAnalysisForProfileService(
                        pservice.getKeyword(), analyses_from_profiles)
                    pservices.append({
                        'title':
                        pservice.Title(),
                        'price':
                        panalysis.getPrice()
                        if panalysis else pservice.getPrice(),
                        'priceVat':
                        "%.2f" % panalysis.getVATAmount()
                        if panalysis else pservice.getVATAmount(),
                        'priceTotal':
                        "%.2f" % panalysis.getTotalPrice()
                        if panalysis else pservice.getTotalPrice(),
                    })
                profiles.append({
                    'name': profile.title,
                    'price': None,
                    'priceVat': None,
                    'priceTotal': None,
                    'analyses': pservices
                })
        self.analyses = analyses
        self.profiles = profiles
        # Get subtotals
        self.subtotal = context.getSubtotal()
        self.subtotalVATAmount = "%.2f" % context.getSubtotalVATAmount()
        self.subtotalTotalPrice = "%.2f" % context.getSubtotalTotalPrice()
        # Get totals
        self.memberDiscount = Decimal(context.getDefaultMemberDiscount())
        self.discountAmount = context.getDiscountAmount()
        self.VATAmount = "%.2f" % context.getVATAmount()
        self.totalPrice = "%.2f" % context.getTotalPrice()
        # Render the template
        return self.template()
Esempio n. 26
0
 def getDatePublished(self):
     """Used to populate catalog values.
     Returns the date on which the "publish" transition was invoked on this
     analysis.
     """
     return getTransitionDate(self, 'publish', return_as_datetime=True)
Esempio n. 27
0
 def getDateSampled(self):
     """Used to populate catalog values.
     Only has value when sampling_workflow is active.
     """
     return getTransitionDate(self, 'sample', return_as_datetime=True)
Esempio n. 28
0
 def getDatePublished(self):
     """Used to populate catalog values.
     Returns the date on which the "publish" transition was invoked on this
     analysis.
     """
     return getTransitionDate(self, 'publish', return_as_datetime=True)
Esempio n. 29
0
    def __call__(self):
        context = self.context
        workflow = getToolByName(context, 'portal_workflow')
        # Collect related data and objects
        invoice = context.getInvoice()
        sample = context.getSample()
        samplePoint = sample.getSamplePoint()
        reviewState = workflow.getInfoFor(context, 'review_state')
        # Collection invoice information
        if invoice:
            self.invoiceId = invoice.getId()
        else:
            self.invoiceId = _('Proforma (Not yet invoiced)')
        # Collect verified invoice information
        verified = reviewState in VERIFIED_STATES
        if verified:
            self.verifiedBy = context.getVerifier()
        self.verified = verified
        self.request['verified'] = verified
        # Collect published date
        self.datePublished = \
            self.ulocalized_time(getTransitionDate(context, 'publish'),
                                 long_format=1)
        # Collect received date
        dateReceived = context.getDateReceived()
        if dateReceived is not None:
            dateReceived = self.ulocalized_time(dateReceived, long_format=1)
        self.dateReceived = dateReceived
        # Collect general information
        self.reviewState = reviewState
        contact = context.getContact()
        self.contact = contact.Title() if contact else ""
        self.clientOrderNumber = context.getClientOrderNumber()
        self.clientReference = context.getClientReference()
        self.clientSampleId = sample.getClientSampleID()
        self.sampleType = sample.getSampleType().Title()
        self.samplePoint = samplePoint and samplePoint.Title()
        self.requestId = context.getRequestID()
        self.headers = [
            {'title': 'Invoice ID', 'value': self.invoiceId},
            {'title': 'Client Reference',
                'value': self.clientReference },
            {'title': 'Sample Type', 'value': self.sampleType},
            {'title': 'Request ID', 'value': self.requestId},
            {'title': 'Date Received', 'value': self.dateReceived},
        ]
        if not isAttributeHidden('AnalysisRequest', 'ClientOrderNumber'):
            self.headers.append({'title': 'Client Sample Id',
                                 'value': self.clientOrderNumber})
        if not isAttributeHidden('AnalysisRequest', 'SamplePoint'):
            self.headers.append(
                {'title': 'Sample Point', 'value': self.samplePoint})
        if self.verified:
            self.headers.append(
                {'title': 'Verified By', 'value': self.verifiedBy})
            if self.datePublished:
                self.headers.append(
                    {'title': 'datePublished', 'value': self.datePublished})

        analyses = []
        profiles = []
        # Retrieve required data from analyses collection
        all_analyses, all_profiles, analyses_from_profiles = context.getServicesAndProfiles()
        # Relating category with solo analysis
        for analysis in all_analyses:
            service = analysis.getService()
            categoryName = service.getCategory().Title()
            # Find the category
            try:
                category = (
                    o for o in analyses if o['name'] == categoryName
                ).next()
            except:
                category = {'name': categoryName, 'analyses': []}
                analyses.append(category)
            # Append the analysis to the category
            category['analyses'].append({
                'title': analysis.Title(),
                'price': analysis.getPrice(),
                'priceVat': "%.2f" % analysis.getVATAmount(),
                'priceTotal': "%.2f" % analysis.getTotalPrice(),
            })
        # Relating analysis services with their profiles
        # We'll take the analysis contained on each profile
        for profile in all_profiles:
            # If profile's checkbox "Use Analysis Profile Price" is enabled, only the profile price will be displayed.
            # Otherwise each analysis will display its own price.
            pservices = []
            if profile.getUseAnalysisProfilePrice():
                # We have to use the profiles price only
                for pservice in profile.getService():
                    pservices.append({
                               'title': pservice.Title(),
                               'price': None,
                               'priceVat': None,
                               'priceTotal': None,
                               })
                profiles.append({'name': profile.title,
                                 'price': profile.getAnalysisProfilePrice(),
                                 'priceVat': profile.getVATAmount(),
                                 'priceTotal': profile.getTotalPrice(),
                                 'analyses': pservices})
            else:
                # We need the analyses prices instead of profile price
                for pservice in profile.getService():
                    # We want the analysis instead of the service, because we want the price for the client
                    # (for instance the bulk price)
                    panalysis = self._getAnalysisForProfileService(pservice.getKeyword(), analyses_from_profiles)
                    pservices.append({
                                     'title': pservice.Title(),
                                     'price': panalysis.getPrice() if panalysis else pservice.getPrice(),
                                     'priceVat': "%.2f" % panalysis.getVATAmount() if panalysis
                                                                                   else pservice.getVATAmount(),
                                     'priceTotal': "%.2f" % panalysis.getTotalPrice() if panalysis
                                                                                   else pservice.getTotalPrice(),
                                     })
                profiles.append({'name': profile.title,
                                 'price': None,
                                 'priceVat': None,
                                 'priceTotal': None,
                                 'analyses': pservices})
        self.analyses = analyses
        self.profiles = profiles
        # Get subtotals
        self.subtotal = context.getSubtotal()
        self.subtotalVATAmount = "%.2f" % context.getSubtotalVATAmount()
        self.subtotalTotalPrice = "%.2f" % context.getSubtotalTotalPrice()
        # Get totals
        self.memberDiscount = Decimal(context.getDefaultMemberDiscount())
        self.discountAmount = context.getDiscountAmount()
        self.VATAmount = "%.2f" % context.getVATAmount()
        self.totalPrice = "%.2f" % context.getTotalPrice()
        # Render the template
        return self.template()
Esempio n. 30
0
 def get_transition_date(self, obj, transition=None):
     """Returns the date of the given Transition
     """
     if transition is None:
         return None
     return getTransitionDate(obj, transition, return_as_datetime=True)
Esempio n. 31
0
def getDateValidated(instance):
    return getTransitionDate(instance, 'validate')
Esempio n. 32
0
def getDateStored(self):
    """Returns the date the sample was stored
    """
    return wf.getTransitionDate(self, "store") or None
Esempio n. 33
0
def getDateImported(instance):
    return getTransitionDate(instance, 'import')
    def __call__(self):

        parms = []
        titles = []

        # Apply filters
        self.contentFilter = {'portal_type': 'AnalysisRequest'}
        val = self.selection_macros.parse_daterange(self.request,
                                                    'getDateCreated',
                                                    _('Date Created'))
        if val:
            self.contentFilter["created"] = val['contentFilter'][1]
            parms.append(val['parms'])
            titles.append(val['titles'])

        # Query the catalog and store results in a dictionary
        catalog = getToolByName(self.context, CATALOG_ANALYSIS_REQUEST_LISTING)
        ars = catalog(self.contentFilter)

        logger.info("Catalog Query '{}' returned {} results".format(
            self.contentFilter, len(ars)))

        if not ars:
            message = _("No Samples matched your query")
            self.context.plone_utils.addPortalMessage(message, "error")
            return self.default_template()

        datalines = {}
        footlines = {}
        totalcreatedcount = len(ars)
        totalreceivedcount = 0
        totalpublishedcount = 0
        totalanlcount = 0
        totalreceptionlag = 0
        totalpublicationlag = 0

        for ar in ars:
            ar = ar.getObject()
            datecreated = ar.created()
            datereceived = ar.getDateReceived()
            datepublished = getTransitionDate(ar, 'publish')
            receptionlag = 0
            publicationlag = 0
            anlcount = len(ar.getAnalyses())

            dataline = {
                "AnalysisRequestID": ar.getId(),
                "DateCreated": self.ulocalized_time(datecreated),
                "DateReceived": self.ulocalized_time(datereceived),
                "DatePublished": self.ulocalized_time(datepublished),
                "ReceptionLag": receptionlag,
                "PublicationLag": publicationlag,
                "TotalLag": receptionlag + publicationlag,
                "BatchID": ar.getBatch().getId() if ar.getBatch() else '',
                "SampleID": ar.getId(),
                "SampleType": ar.getSampleTypeTitle(),
                "NumAnalyses": anlcount,
                "ClientID": ar.aq_parent.id,
                "Creator": ar.Creator(),
                "Remarks": ar.getRemarks()
            }

            datalines[ar.getId()] = dataline

            totalreceivedcount += ar.getDateReceived() and 1 or 0
            totalpublishedcount += 1 if datepublished else 0
            totalanlcount += anlcount
            totalreceptionlag += receptionlag
            totalpublicationlag += publicationlag

        # Footer total data
        totalreceivedcreated_ratio = float(totalreceivedcount) / float(
            totalcreatedcount)
        totalpublishedcreated_ratio = float(totalpublishedcount) / float(
            totalcreatedcount)
        totalpublishedreceived_ratio = totalreceivedcount and float(
            totalpublishedcount) / float(totalreceivedcount) or 0

        footline = {
            'Created':
            totalcreatedcount,
            'Received':
            totalreceivedcount,
            'Published':
            totalpublishedcount,
            'ReceivedCreatedRatio':
            totalreceivedcreated_ratio,
            'ReceivedCreatedRatioPercentage':
            ('{0:.0f}'.format(totalreceivedcreated_ratio * 100)) + "%",
            'PublishedCreatedRatio':
            totalpublishedcreated_ratio,
            'PublishedCreatedRatioPercentage':
            ('{0:.0f}'.format(totalpublishedcreated_ratio * 100)) + "%",
            'PublishedReceivedRatio':
            totalpublishedreceived_ratio,
            'PublishedReceivedRatioPercentage':
            ('{0:.0f}'.format(totalpublishedreceived_ratio * 100)) + "%",
            'AvgReceptionLag':
            ('{0:.1f}'.format(totalreceptionlag / totalcreatedcount)),
            'AvgPublicationLag':
            ('{0:.1f}'.format(totalpublicationlag / totalcreatedcount)),
            'AvgTotalLag': ('{0:.1f}'.format(
                (totalreceptionlag + totalpublicationlag) /
                totalcreatedcount)),
            'NumAnalyses':
            totalanlcount
        }

        footlines['Total'] = footline

        self.report_data = {
            'parameters': parms,
            'datalines': datalines,
            'footlines': footlines
        }

        if self.request.get('output_format', '') == 'CSV':
            import csv
            import StringIO
            import datetime

            fieldnames = [
                "AnalysisRequestID",
                "DateCreated",
                "DateReceived",
                "DatePublished",
                "ReceptionLag",
                "PublicationLag",
                "TotalLag",
                "BatchID",
                "SampleID",
                "SampleType",
                "NumAnalyses",
                "ClientID",
                "Creator",
                "Remarks",
            ]
            output = StringIO.StringIO()
            dw = csv.DictWriter(output,
                                extrasaction='ignore',
                                fieldnames=fieldnames)
            dw.writerow(dict((fn, fn) for fn in fieldnames))
            for ar_id, row in datalines.items():
                dw.writerow({
                    "AnalysisRequestID": row["AnalysisRequestID"],
                    "DateCreated": row["DateCreated"],
                    "DateReceived": row["DateReceived"],
                    "DatePublished": row["DatePublished"],
                    "ReceptionLag": row["ReceptionLag"],
                    "PublicationLag": row["PublicationLag"],
                    "TotalLag": row["TotalLag"],
                    "BatchID": row["BatchID"],
                    "SampleID": row["SampleID"],
                    "SampleType": row["SampleType"],
                    "NumAnalyses": row["NumAnalyses"],
                    "ClientID": row["ClientID"],
                    "Creator": row["Creator"],
                    "Remarks": row["Remarks"],
                })
            report_data = output.getvalue()
            output.close()
            date = datetime.datetime.now().strftime("%Y%m%d%H%M")
            setheader = self.request.RESPONSE.setHeader
            setheader('Content-Type', 'text/csv')
            setheader("Content-Disposition",
                      "attachment;filename=\"dataentrydaybook_%s.csv\"" % date)
            self.request.RESPONSE.write(report_data)
        else:
            return {
                'report_title': _('Data entry day book'),
                'report_data': self.template()
            }
Esempio n. 35
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 = BikaListingView.folderitem(self, obj, item, index)
        if not item:
            return None

        member = self.mtool.getAuthenticatedMember()
        roles = member.getRoles()
        hideclientlink = 'RegulatoryInspector' in roles \
            and 'Manager' not in roles \
            and 'LabManager' not in roles \
            and 'LabClerk' not in roles

        sample = obj.getSample()
        url = obj.absolute_url()
        if getSecurityManager().checkPermission(EditResults, obj):
            url += "/manage_results"

        item['Client'] = obj.aq_parent.Title()
        if (hideclientlink == False):
            item['replace']['Client'] = "<a href='%s'>%s</a>" % \
                (obj.aq_parent.absolute_url(), obj.aq_parent.Title())
        item['Creator'] = self.user_fullname(obj.Creator())
        item['getRequestID'] = obj.getRequestID()
        item['replace']['getRequestID'] = "<a href='%s'>%s</a>" % \
             (url, item['getRequestID'])
        item['getSample'] = sample
        item['replace']['getSample'] = \
            "<a href='%s'>%s</a>" % (sample.absolute_url(), sample.Title())

        item['replace']['getProfilesTitle'] = ", ".join(
            [p.Title() for p in obj.getProfiles()])

        analysesnum = obj.getAnalysesNum()
        if analysesnum:
            item['getAnalysesNum'] = str(analysesnum[0]) + '/' + str(analysesnum[1])
        else:
            item['getAnalysesNum'] = ''

        batch = obj.getBatch()
        if batch:
            item['BatchID'] = batch.getBatchID()
            item['replace']['BatchID'] = "<a href='%s'>%s</a>" % \
                 (batch.absolute_url(), item['BatchID'])
        else:
            item['BatchID'] = ''

        val = obj.Schema().getField('SubGroup').get(obj)
        item['SubGroup'] = val.Title() if val else ''

        samplingdate = obj.getSample().getSamplingDate()
        item['SamplingDate'] = self.ulocalized_time(samplingdate, long_format=1)
        item['getDateReceived'] = self.ulocalized_time(obj.getDateReceived())
        item['getDatePublished'] = self.ulocalized_time(obj.getDatePublished())
        item['getDateVerified'] = getTransitionDate(obj, 'verify')

        deviation = sample.getSamplingDeviation()
        item['SamplingDeviation'] = deviation and deviation.Title() or ''
        priority = obj.getPriority()
        item['Priority'] = '' # priority.Title()

        item['getStorageLocation'] = sample.getStorageLocation() and sample.getStorageLocation().Title() or ''
        item['AdHoc'] = sample.getAdHoc() and True or ''

        after_icons = ""
        state = self.workflow.getInfoFor(obj, 'worksheetanalysis_review_state')
        if state == 'assigned':
            after_icons += "<img src='%s/++resource++bika.lims.images/worksheet.png' title='%s'/>" % \
                (self.portal_url, t(_("All analyses assigned")))
        if self.workflow.getInfoFor(obj, 'review_state') == 'invalid':
            after_icons += "<img src='%s/++resource++bika.lims.images/delete.png' title='%s'/>" % \
                (self.portal_url, t(_("Results have been withdrawn")))
        if obj.getLate():
            after_icons += "<img src='%s/++resource++bika.lims.images/late.png' title='%s'>" % \
                (self.portal_url, t(_("Late Analyses")))
        if samplingdate > DateTime():
            after_icons += "<img src='%s/++resource++bika.lims.images/calendar.png' title='%s'>" % \
                (self.portal_url, t(_("Future dated sample")))
        if obj.getInvoiceExclude():
            after_icons += "<img src='%s/++resource++bika.lims.images/invoice_exclude.png' title='%s'>" % \
                (self.portal_url, t(_("Exclude from invoice")))
        if sample.getSampleType().getHazardous():
            after_icons += "<img src='%s/++resource++bika.lims.images/hazardous.png' title='%s'>" % \
                (self.portal_url, t(_("Hazardous")))
        if after_icons:
            item['after']['getRequestID'] = after_icons

        item['Created'] = self.ulocalized_time(obj.created())

        contact = obj.getContact()
        if contact:
            item['ClientContact'] = contact.Title()
            item['replace']['ClientContact'] = "<a href='%s'>%s</a>" % \
                (contact.absolute_url(), contact.Title())
        else:
            item['ClientContact'] = ""

        SamplingWorkflowEnabled = sample.getSamplingWorkflowEnabled()
        if SamplingWorkflowEnabled and not samplingdate > DateTime():
            datesampled = self.ulocalized_time(sample.getDateSampled())
            if not datesampled:
                datesampled = self.ulocalized_time(
                    DateTime(),
                    long_format=1)
                item['class']['getDateSampled'] = 'provisional'
            sampler = sample.getSampler().strip()
            if sampler:
                item['replace']['getSampler'] = self.user_fullname(sampler)
            if 'Sampler' in member.getRoles() and not sampler:
                sampler = member.id
                item['class']['getSampler'] = 'provisional'
        else:
            datesampled = ''
            sampler = ''
        item['getDateSampled'] = datesampled
        item['getSampler'] = sampler

        # sampling workflow - inline edits for Sampler and Date Sampled
        checkPermission = self.context.portal_membership.checkPermission
        state = self.workflow.getInfoFor(obj, 'review_state')
        if state == 'to_be_sampled' \
                and checkPermission(SampleSample, obj) \
                and not samplingdate > DateTime():
            item['required'] = ['getSampler', 'getDateSampled']
            item['allow_edit'] = ['getSampler', 'getDateSampled']
            samplers = getUsers(sample, ['Sampler', 'LabManager', 'Manager'])
            username = 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 ''
            item['getSampler'] = Sampler

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

        # inline edits for Preserver and Date Preserved
        checkPermission = self.context.portal_membership.checkPermission
        if checkPermission(PreserveSample, obj):
            item['required'] = ['getPreserver', 'getDatePreserved']
            item['allow_edit'] = ['getPreserver', 'getDatePreserved']
            preservers = getUsers(obj, ['Preserver', 'LabManager', 'Manager'])
            username = member.getUserName()
            users = [({'ResultValue': u, 'ResultText': preservers.getValue(u)})
                     for u in preservers]
            item['choices'] = {'getPreserver': users}
            preserver = username in preservers.keys() and username or ''
            item['getPreserver'] = preserver
            item['getDatePreserved'] = self.ulocalized_time(
                DateTime(),
                long_format=1)
            item['class']['getPreserver'] = 'provisional'
            item['class']['getDatePreserved'] = 'provisional'

        # Submitting user may not verify results
        if item['review_state'] == 'to_be_verified' and \
           not checkPermission(VerifyOwnResults, obj):
            self_submitted = False
            try:
                review_history = list(self.workflow.getInfoFor(obj, 'review_history'))
                review_history.reverse()
                for event in review_history:
                    if event.get('action') == 'submit':
                        if event.get('actor') == member.getId():
                            self_submitted = True
                        break
                if self_submitted:
                    item['after']['state_title'] = \
                         "<img src='++resource++bika.lims.images/submitted-by-current-user.png' title='%s'/>" % \
                         t(_("Cannot verify: Submitted by current user"))
            except Exception:
                pass

        return item