Skip to content

Commit

Permalink
Finish 3.1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
rockfruit committed Jul 14, 2014
2 parents 1d0d4ae + 32e93d9 commit 6d84d92
Show file tree
Hide file tree
Showing 148 changed files with 53,625 additions and 501,064 deletions.
28 changes: 28 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
3.1.2 (2014-07-15)
------------------

LIMS-1292: UI fix Retracted ARs workfow: Warning msg on "full" retract.
LIMS.1287: UI fix Report parameter formatting
LIMS-1230: UI fix Livesearch's box
LIMS-1257: UI fix Long titles in Analysis Profiles, Sample Points, etc.
LIMS-1214: UI fix More columns
LIMS-1199: UI fix Worksheet listing: better columns
LIMS-1303: jsi18n strings must be added to bika-manual.pot. i18ndude cannot find.
LIMS-1310: Filter SamplePoints by client in AR Template Edit View
LIMS-1256: Client objects included in AR-Add filters for Sample Point etc.
LIMS-1290: Allows Analyst to retract analyses, without giving extra permissions.
LIMS-1218: Slightly nicer monkey patch for translating content object ID's and titles.
LIMS-1070: Accreditation text can be customised in bika_setup
LIMS-1245: off-by-one in part indicators in ar_add
LIMS-1240: Hide "copy to new" from Analyst users

LIMS-1059: Added worksheet rejection workflow
RejectAnalysis (Analysis subclass (has IAnalysis!)) workflow transition.
Does not retract individual Analysis objects - instead, forces their state
back to "Received", and assigns them onto newly created WS.
Sets attributes on src and dst worksheets:
WS instance rejected worksheet attribute: .replaced_by = UID
WS instance replacement worksheet attribute: .replaces_rejected_worksheet:UID

Fixed some i18n and encoding snags, and updated translations.

3.1.1 (2014-06-29)
------------------

Expand Down
1 change: 1 addition & 0 deletions bika/lims/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def initialize(context):
from content.referencedefinition import ReferenceDefinition
from content.referencesample import ReferenceSample
from content.referencesamplesfolder import ReferenceSamplesFolder
from content.rejectanalysis import RejectAnalysis
from content.report import Report
from content.reportfolder import ReportFolder
from content.sample import Sample
Expand Down
4 changes: 2 additions & 2 deletions bika/lims/browser/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from Products.CMFPlone.i18nl10n import ulocalized_time
from Products.Five.browser import BrowserView
from bika.lims import logger
from zope.i18n import translate
from zope.cachedescriptors.property import Lazy as lazy_property
from zope.i18n import translate

class BrowserView(BrowserView):

Expand Down Expand Up @@ -99,7 +99,7 @@ def python_date_format(self, long_format=None, time_only=False):
if time_only:
msgid = 'time_format'
# get the formatstring
formatstring = translate(msgid, 'bika', {}, self.request)
formatstring = translate(msgid, domain='bika', mapping={}, context=self.request)
if formatstring is None or formatstring.startswith('date_') or formatstring.startswith('time_'):
self.logger.error("bika/%s/%s could not be translated" %
(self.request.get('LANGUAGE'), msgid))
Expand Down
51 changes: 29 additions & 22 deletions bika/lims/browser/accreditation.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
# encoding=utf-8

from Products.CMFPlone.utils import safe_unicode
from bika.lims.controlpanel.bika_analysisservices import AnalysisServicesView
from bika.lims import bikaMessageFactory as _
from bika.lims.utils import t
from bika.lims.utils import to_utf8 as _c, to_utf8
from plone.app.content.browser.interfaces import IFolderContentsView
from zope.interface import implements


class AccreditationView(AnalysisServicesView):
"""
>>> portal = layer['portal']
>>> portal_url = portal.absolute_url()
>>> from plone.app.testing import SITE_OWNER_NAME
>>> from plone.app.testing import SITE_OWNER_PASSWORD
>>> browser = layer['getBrowser'](portal)
>>> browser.open(portal_url+"/accreditation")
>>> 'SAI is the' in browser.contents
True
"""
implements(IFolderContentsView)

def __init__(self, context, request):
Expand All @@ -21,31 +35,24 @@ def __init__(self, context, request):

lab = context.bika_setup.laboratory
accredited = lab.getLaboratoryAccredited()
self.mapping = {'accredited': accredited,
'labname': lab.getName(),
'labcountry': lab.getPhysicalAddress().get('country', ''),
'confidence': lab.getConfidence(),
'abbr': lab.getAccreditationBody(),
'body': lab.getAccreditationBodyLong(),
'url': lab.getAccreditationBodyURL(),
'accr': lab.getAccreditation(),
'ref': lab.getAccreditationReference()
self.mapping = {'lab_is_accredited': accredited,
'lab_name': safe_unicode(lab.getName()),
'lab_country': safe_unicode(lab.getPhysicalAddress().get('country', '')),
'confidence': safe_unicode(lab.getConfidence()),
'accreditation_body_abbr': safe_unicode(lab.getAccreditationBody()),
'accreditation_body_name': safe_unicode(lab.getAccreditationBodyURL()),
'accreditation_standard': safe_unicode(lab.getAccreditation()),
'accreditation_reference': safe_unicode(lab.getAccreditationReference())
}
if accredited:
msg = t(_(
"${labname} has been accredited as ${accr} " + \
"conformant by ${abbr}, (${body}). ${abbr} is " + \
"recognised by government as a national " + \
"accreditation body in ${labcountry}. ",
mapping=self.mapping
self.description = t(_(safe_unicode(lab.getAccreditationPageHeader()),
mapping=self.mapping
))
else:
msg = t(_("The lab is not accredited, or accreditation has not "
"been configured. "))
self.description = msg
msg = _("All Accredited analysis services are listed here.")
self.description = "%s<p><br/>%s</p>" % (self.description,
_c(context.translate(_(msg))))
self.description = t(_("The lab is not accredited, or accreditation has "
"not been configured. "))
msg = t(_("All Accredited analysis services are listed here."))
self.description = "%s<p><br/>%s</p>" % (self.description, msg)

self.show_select_column = False
request.set('disable_border', 1)
Expand Down
2 changes: 2 additions & 0 deletions bika/lims/browser/analyses.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ def folderitems(self):
elif self.context.portal_type == "Worksheet":
if obj.portal_type == "DuplicateAnalysis":
sample = obj.getAnalysis().getSample()
elif obj.portal_type == "RejectAnalysis":
sample = obj.getAnalysis().getSample()
else:
sample = obj.aq_parent.getSample()
st_uid = sample.getSampleType().UID()
Expand Down
40 changes: 10 additions & 30 deletions bika/lims/browser/analysisrequest/analysisrequests.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,7 @@ def __init__(self, context, request):
{'id': 'republish'},
{'id': 'cancel'},
{'id': 'reinstate'}],
'custom_actions': [{'id': 'copy_to_new',
'title': _('Copy to new'),
'url': 'workflow_action?action=copy_to_new'}, ],
'custom_actions': [],
'columns': ['getRequestID',
'getSample',
'BatchID',
Expand Down Expand Up @@ -183,9 +181,7 @@ def __init__(self, context, request):
{'id': 'receive'},
{'id': 'cancel'},
{'id': 'reinstate'}],
'custom_actions': [{'id': 'copy_to_new',
'title': _('Copy to new'),
'url': 'workflow_action?action=copy_to_new'}, ],
'custom_actions': [],
'columns': ['getRequestID',
'getSample',
'BatchID',
Expand Down Expand Up @@ -218,9 +214,7 @@ def __init__(self, context, request):
'transitions': [{'id': 'prepublish'},
{'id': 'cancel'},
{'id': 'reinstate'}],
'custom_actions': [{'id': 'copy_to_new',
'title': _('Copy to new'),
'url': 'workflow_action?action=copy_to_new'}, ],
'custom_actions': [],
'columns': ['getRequestID',
'getSample',
'BatchID',
Expand Down Expand Up @@ -255,9 +249,7 @@ def __init__(self, context, request):
{'id': 'prepublish'},
{'id': 'cancel'},
{'id': 'reinstate'}],
'custom_actions': [{'id': 'copy_to_new',
'title': _('Copy to new'),
'url': 'workflow_action?action=copy_to_new'}, ],
'custom_actions': [],
'columns': ['getRequestID',
'getSample',
'BatchID',
Expand Down Expand Up @@ -288,9 +280,7 @@ def __init__(self, context, request):
'sort_on': 'created',
'sort_order': 'reverse'},
'transitions': [{'id': 'publish'}],
'custom_actions': [{'id': 'copy_to_new',
'title': _('Copy to new'),
'url': 'workflow_action?action=copy_to_new'}, ],
'custom_actions': [],
'columns': ['getRequestID',
'getSample',
'BatchID',
Expand Down Expand Up @@ -321,9 +311,7 @@ def __init__(self, context, request):
'sort_on': 'created',
'sort_order': 'reverse'},
'transitions': [{'id': 'republish'}],
'custom_actions': [{'id': 'copy_to_new',
'title': _('Copy to new'),
'url': 'workflow_action?action=copy_to_new'}, ],
'custom_actions': [],
'columns': ['getRequestID',
'getSample',
'BatchID',
Expand Down Expand Up @@ -359,9 +347,7 @@ def __init__(self, context, request):
'sort_on': 'created',
'sort_order': 'reverse'},
'transitions': [{'id': 'reinstate'}],
'custom_actions': [{'id': 'copy_to_new',
'title': _('Copy to new'),
'url': 'workflow_action?action=copy_to_new'}, ],
'custom_actions': [],
'columns': ['getRequestID',
'getSample',
'BatchID',
Expand Down Expand Up @@ -394,9 +380,7 @@ def __init__(self, context, request):
'sort_on': 'created',
'sort_order': 'reverse'},
'transitions': [],
'custom_actions': [{'id': 'copy_to_new',
'title': _('Copy to new'),
'url': 'workflow_action?action=copy_to_new'}, ],
'custom_actions': [],
'columns':['getRequestID',
'getSample',
'BatchID',
Expand Down Expand Up @@ -439,9 +423,7 @@ def __init__(self, context, request):
{'id': 'republish'},
{'id': 'cancel'},
{'id': 'reinstate'}],
'custom_actions': [{'id': 'copy_to_new',
'title': _('Copy to new'),
'url': 'workflow_action?action=copy_to_new'}, ],
'custom_actions': [],
'columns': ['getRequestID',
'getSample',
'BatchID',
Expand Down Expand Up @@ -485,9 +467,7 @@ def __init__(self, context, request):
{'id': 'republish'},
{'id': 'cancel'},
{'id': 'reinstate'}],
'custom_actions': [{'id': 'copy_to_new',
'title': _('Copy to new'),
'url': 'workflow_action?action=copy_to_new'}, ],
'custom_actions': [],
'columns': ['getRequestID',
'getSample',
'BatchID',
Expand Down
14 changes: 14 additions & 0 deletions bika/lims/browser/analysisrequest/manage_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@ def __call__(self):
t.show_select_column = True
poc_value = POINTS_OF_CAPTURE.getValue(poc)
self.tables[poc_value] = t.contents_table()
# If a general retracted is done, rise a waring
if workflow.getInfoFor(ar, 'review_state') == 'sample_received':
allstatus = list()
for analysis in ar.getAnalyses():
status = workflow.getInfoFor(analysis.getObject(), 'review_state')
if status not in ['retracted','to_be_verified','verified']:
allstatus = []
break
else:
allstatus.append(status)
if len(allstatus) > 0:
message = "General Retract Done"
self.context.plone_utils.addPortalMessage(message, 'warning')

self.checkInstrumentsValidity()
return self.template()

Expand Down
2 changes: 1 addition & 1 deletion bika/lims/browser/analysisrequest/published_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def __call__(self):
and ar.getChildAnalysisRequest() or None
childid = childar and childar.getRequestID() or None
message = _('This Analysis Request has been withdrawn and is '
'shown for trace-ability purposes only. Retest:'
'shown for trace-ability purposes only. Retest: '
'${retest_child_id}.',
mapping={'retest_child_id': safe_unicode(childid) or ''})
self.context.plone_utils.addPortalMessage(
Expand Down
12 changes: 6 additions & 6 deletions bika/lims/browser/analysisrequest/results_not_requested.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@ def __call__(self):
and ar.getChildAnalysisRequest() or None
childid = childar and childar.getRequestID() or None
message = _('This Analysis Request has been withdrawn and is shown '
'for trace-ability purposes only. Retest: %s.') \
% (childid or '')
'for trace-ability purposes only. Retest: ${retest_child_id}.',
mapping={"retest_child_id":childid if childid else ''})
self.context.plone_utils.addPortalMessage(message, 'warning')

# If is an AR automatically generated due to a Retraction, show it's
# parent AR information
if hasattr(ar, 'getParentAnalysisRequest') \
and ar.getParentAnalysisRequest():
par = ar.getParentAnalysisRequest()
message = _('This Analysis Request has been '
'generated automatically due to '
'the retraction of the Analysis '
'Request %s.') % par.getRequestID()
message = _(
'This Analysis Request has been generated automatically due to '
'the retraction of the Analysis Request ${retracted_request_id}.',
mapping={"retracted_request_id": par.getRequestID()})
self.context.plone_utils.addPortalMessage(message, 'info')

can_do = getSecurityManager().checkPermission(ResultsNotRequested, ar)
Expand Down
15 changes: 9 additions & 6 deletions bika/lims/browser/analysisrequest/templates/ar_add.pt
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,13 @@
<input type="hidden" name="came_from" tal:attributes="value view/came_from" />

<span id="bika_setup" style="display:none;"
tal:define="bs python: context.bika_setup;"
tal:attributes="EnableARSpecs python: 'true' if bs.getEnableARSpecs() else '';
bika_analysisspecs_uid python: bs.bika_analysisspecs.UID();">
tal:define="bika_setup python: context.bika_setup;"
tal:attributes="EnableARSpecs python: 'true' if bika_setup.getEnableARSpecs() else '';
bika_samplepoints_uid python: bika_setup.bika_samplepoints.UID();
bika_artemplates_uid python: bika_setup.bika_artemplates.UID();
bika_analysisprofiles_uid python: bika_setup.bika_analysisspecs.UID();
bika_analysisspecs_uid python: bika_setup.bika_analysisspecs.UID();
bika_analysisspecs_path python:'/'.join(bika_setup.bika_analysisspecs.getPhysicalPath())">
</span>

<!-- member discount percentage if applicable -->
Expand All @@ -77,13 +81,12 @@
tal:attributes="
poc python: dms.getPointOfCapture();
cat python: dms.getCategoryUID();
value python: dms.UID();"/>
value python: dms.UID()"/>
</tal:i>

<input type="hidden"
id="PhysicalPath"
tal:attributes="here python:'/'.join(context.getPhysicalPath()[:-3]);
lab_specs python:'/'.join(context.bika_setup.bika_analysisspecs.getPhysicalPath())"/>
tal:attributes="here python:'/'.join(context.getPhysicalPath()[:-3])"/>

<table summary="Add analysis requests"
class="listing analysisrequest add nosort"
Expand Down
13 changes: 13 additions & 0 deletions bika/lims/browser/analysisrequest/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,19 @@ def __call__(self):
{'id': 'retract'},
{'id': 'verify'}]
self.qctable = qcview.contents_table()
# If a general retracted is done, rise a waring
if workflow.getInfoFor(ar, 'review_state') == 'sample_received':
allstatus = list()
for analysis in ar.getAnalyses():
status = workflow.getInfoFor(analysis.getObject(), 'review_state')
if status not in ['retracted','to_be_verified','verified']:
allstatus = []
break
else:
allstatus.append(status)
if len(allstatus) > 0:
self.addMessage("General Retract Done", 'warning')

# If is a retracted AR, show the link to child AR and show a warn msg
if workflow.getInfoFor(ar, 'review_state') == 'invalid':
childar = hasattr(ar, 'getChildAnalysisRequest') \
Expand Down
15 changes: 9 additions & 6 deletions bika/lims/browser/analysisrequest/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,8 @@ def workflow_action_retract_ar(self):
laboratory = self.context.bika_setup.laboratory
lab_address = "<br/>".join(laboratory.getPrintAddress())
mime_msg = MIMEMultipart('related')
mime_msg['Subject'] = _("Erroneus result publication from %s") % \
ar.getRequestID()
mime_msg['Subject'] = t(_("Erroneus result publication from ${request_id}",
mapping={"request_id": ar.getRequestID()}))
mime_msg['From'] = formataddr(
(encode_header(laboratory.getName()),
laboratory.getEmailAddress()))
Expand Down Expand Up @@ -452,12 +452,15 @@ def workflow_action_retract_ar(self):
or ''

body = _("Some errors have been detected in the results report "
"published from the Analysis Request %s. The Analysis "
"Request %s has been created automatically and the "
"published from the Analysis Request ${request_link}. The Analysis "
"Request ${new_request_link} has been created automatically and the "
"previous has been invalidated.<br/>The possible mistake "
"has been picked up and is under investigation.<br/><br/>"
"%s%s"
) % (aranchor, naranchor, addremarks, lab_address)
"${remarks}${lab_address}",
mapping={"request_link":aranchor,
"new_request_link":naranchor,
"remarks": addremarks,
"lab_address": lab_address})
msg_txt = MIMEText(safe_unicode(body).encode('utf-8'),
_subtype='html')
mime_msg.preamble = 'This is a multi-part MIME message.'
Expand Down
Loading

0 comments on commit 6d84d92

Please sign in to comment.