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
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 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"), }
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)
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)
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')
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")
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]")
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
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()}
def getDateSampled(self): """Used to populate catalog values. Only has value when sampling_workflow is active. """ return getTransitionDate(self, 'sample', return_as_datetime=True)
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()}
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()}
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
def getDateImported(instance): return getTransitionDate(instance, 'import')
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()}
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()
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)
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()
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)
def getDateStored(self): """Returns the date the sample was stored """ return wf.getTransitionDate(self, "store") or None
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() }
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