Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance. Analysis structure and relationship with Analysis Service refactored #95

Closed
wants to merge 40 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
92cd627
Create BaseAnalysis class as base for Analyis and AnalysisService
rockfruit May 3, 2017
8141eec
Add UIDReferenceField
rockfruit May 5, 2017
c029dbb
Finalize the BaseAnalysis/Analysis/Service schemas
rockfruit May 10, 2017
a3c5d7d
Add migration v3_2_0_1705
rockfruit May 7, 2017
30a1239
Refactor all code references to reflect BaseAnalysis changes
rockfruit May 10, 2017
40d0156
BaseAnalysis -> AbstractBaseAnalysis
rockfruit May 12, 2017
27fd304
Migration handles duplicate analyses and references
rockfruit May 12, 2017
4b7afcb
fixing bugs
rockfruit May 16, 2017
eb45f9b
Fix get_allowed_instruments vocabulary
rockfruit May 16, 2017
95eadd2
Replace AnalysisSamplePartition backreference with an index
rockfruit May 16, 2017
a55328a
Merge branch 'wip' into HistoryAwareReferenceField
rockfruit May 16, 2017
e1105e4
Update Analysis Method and Instrument accessors, vocabularies and cat…
rockfruit May 17, 2017
0a4de6a
Cleanup the hierarchy of Abstract analysis classes
rockfruit May 17, 2017
58307ef
More refactoring of marker interfaces (IAnalysis, IRoutineAnalysis)
rockfruit May 18, 2017
5c01a0b
AbstractAnalysis.getAnalysisService and getServiceUID work as expected
rockfruit May 18, 2017
9de0aa7
Remove pdbs
rockfruit May 18, 2017
177a9c5
Convert getDueDate from a schema field to an accessor
rockfruit May 18, 2017
6a08b18
Remove getReviewState method from attachments.
rockfruit May 18, 2017
29f327f
Merge branch 'wip' into HistoryAwareReferenceField
rockfruit May 19, 2017
824e5c4
migration sets analysis.AnalysisService not analysis.ServiceUID.
rockfruit May 19, 2017
a410c43
Ensure REFERENCE_CATALOG is updated after migration
rockfruit May 19, 2017
73c0670
NMRL-303: HistoryAwareReferenceField wide removal
rockfruit May 19, 2017
c9b2099
NMRL-303: HistoryAwareReferenceField wide removal
rockfruit May 19, 2017
c891ca6
Small tweaks for Instrument/Method
xispa May 19, 2017
ea88823
Removal of methods related with verification from ReferenceAnalysis
xispa May 19, 2017
7ed5d42
Removal of getWorksheetUID from ReferenceAnalysis
xispa May 19, 2017
4471b13
Removal of Uncertainty-related methods from ReferenceAnalysis
xispa May 19, 2017
397f20a
Replace self.aq_parent by getRequest
xispa May 19, 2017
1be4839
use uid_catalog for resolving ReferenceSampleUID (not reference_catalog)
rockfruit May 19, 2017
87b381f
clean up order of AnalysisService schema
rockfruit May 19, 2017
ec0af16
Fix broken call to getAnalysisRequestsBrains(kwargs): use (**kwargs)
rockfruit May 19, 2017
732f89f
Add NMRL-303 comment to migration
rockfruit May 19, 2017
017904c
Rebuild reference_catalog after 1705 migration
rockfruit May 19, 2017
6b50b59
ReferenceAnalysis cleanup
xispa May 19, 2017
9e709d1
Remove whitelines
xispa May 19, 2017
d2d4afc
Same UpgradeUtils instance must be referenced everywhere in UpgradeStep
xispa May 23, 2017
6d6e6d3
Remove ARPriority objects and references completely.
rockfruit May 23, 2017
48beced
Revert lowercasing of CHANGELOG
xispa May 23, 2017
7dadbd8
Merge branch 'wip' into HistoryAwareReferenceField
rockfruit May 23, 2017
4a80ec4
Merge remote-tracking branch 'rockfruit/HistoryAwareReferenceField' i…
rockfruit May 23, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Convert getDueDate from a schema field to an accessor
rockfruit committed May 18, 2017

Verified

This commit was signed with the committer’s verified signature.
wallyqs Waldemar Quevedo
commit 177a9c53472da462707d2c2b1e83e7a2d8b70eb9
1 change: 0 additions & 1 deletion bika/lims/browser/analysisrequest/workflow.py
Original file line number Diff line number Diff line change
@@ -181,7 +181,6 @@ def workflow_action_save_analyses_button(self):
ar.REQUEST['workflow_skiplist'].remove("retract all analyses")
ar_state = workflow.getInfoFor(ar, 'review_state')
# Then we need to forward new analyses state
analysis.updateDueDate()
changeWorkflowState(analysis, 'bika_analysis_workflow', ar_state)

message = PMF("Changes saved.")
25 changes: 11 additions & 14 deletions bika/lims/content/abstractanalysis.py
Original file line number Diff line number Diff line change
@@ -24,8 +24,7 @@
from bika.lims.content.abstractbaseanalysis import AbstractBaseAnalysis
from bika.lims.content.abstractbaseanalysis import schema
from bika.lims.content.reflexrule import doReflexRuleAction
from bika.lims.interfaces import IAnalysis, ISamplePrepWorkflow, \
IDuplicateAnalysis
from bika.lims.interfaces import ISamplePrepWorkflow, IDuplicateAnalysis
from bika.lims.permissions import *
from bika.lims.permissions import Verify as VerifyPermission
from bika.lims.utils import changeWorkflowState, formatDecimalMark
@@ -103,16 +102,6 @@
'DetectionLimitOperand'
)

# DueDate is calculated by adding the MaxTimeAllowed to the date that the
# Analysis' sample was received. It's used to create alerts when analyses
# are "late", and also to populate catalog values.
DueDate = DateTimeField(
'DueDate',
widget=DateTimeWidget(
label=_("Due Date")
)
)

# This is used to calculate turnaround time reports.
# The value is set when the Analysis is published.
Duration = IntegerField(
@@ -161,7 +150,6 @@
Calculation,
DateAnalysisPublished,
DetectionLimitOperand,
DueDate,
Duration,
Earliness,
# NumberOfRequiredVerifications overrides AbstractBaseClass
@@ -193,6 +181,7 @@ def getServiceUID(self):
service = self.getAnalysisService()
if service:
return service.UID()
logger.error("Cannot get ServiceUID for %s"%self)

@security.public
def getNumberOfVerifications(self):
@@ -1163,6 +1152,15 @@ def getDateSubmitted(self):
except WorkflowException:
return ''

@security.public
def getDueDate(self):
"""Used to populate getDueDate index and metadata.
This very simply returns the expiry date of the parent reference sample.
"""
ref_sample = self.aq_parent
expiry_date = ref_sample.getExpiryDate()
return expiry_date

@security.public
def getParentUID(self):
"""This method is used to populate catalog values
@@ -1351,7 +1349,6 @@ def workflow_script_receive(self):
state = workflow.getInfoFor(self, 'cancellation_state', 'active')
if state == "cancelled":
return False
self.updateDueDate()
self.reindexObject()

@security.public
111 changes: 15 additions & 96 deletions bika/lims/content/abstractroutineanalysis.py
Original file line number Diff line number Diff line change
@@ -8,105 +8,19 @@
from AccessControl import ClassSecurityInfo

from Products.Archetypes.Field import BooleanField, FixedPointField, \
IntegerField, StringField, TextField
StringField
from Products.Archetypes.Schema import Schema
from bika.lims import bikaMessageFactory as _
from bika.lims.browser.fields import DateTimeField, UIDReferenceField
from bika.lims.browser.widgets import DateTimeWidget, DecimalWidget, \
IntegerWidget
from bika.lims import bikaMessageFactory as _, logger
from bika.lims.browser.fields import UIDReferenceField
from bika.lims.browser.widgets import DecimalWidget
from bika.lims.content.abstractanalysis import AbstractAnalysis
from bika.lims.content.abstractanalysis import schema
from bika.lims.interfaces import IAnalysis, ISamplePrepWorkflow, \
IRoutineAnalysis
from bika.lims.interfaces import IAnalysis, IRoutineAnalysis, \
ISamplePrepWorkflow
from bika.lims.workflow import getTransitionDate
from plone.api.portal import get_tool
from zope.interface import implements

# Attachments which are added manually in the UI, or automatically when
# results are imported from a file supplied by an instrument.
Attachment = UIDReferenceField(
'Attachment',
multiValued=1,
allowed_types=('Attachment',)
)

# The final result of the analysis is stored here. The field contains a
# String value, but the result itself is required to be numeric. If
# a non-numeric result is needed, ResultOptions can be used.
Result = StringField(
'Result'
)

# When the result is changed, this value is updated to the current time.
# Only the most recent result capture date is recorded here and used to
# populate catalog values, however the workflow review_history can be
# used to get all dates of result capture
ResultCaptureDate = DateTimeField(
'ResultCaptureDate'
)

# If ReportDryMatter is True in the AnalysisService, the adjusted result
# is stored here.
ResultDM = StringField(
'ResultDM'
)

# If the analysis has previously been retracted, this flag is set True
# to indicate that this is a re-test.
Retested = BooleanField(
'Retested',
default=False
)

# When the AR is published, the date of publication is recorded here.
# It's used to populate catalog values.
DateAnalysisPublished = DateTimeField(
'DateAnalysisPublished',
widget=DateTimeWidget(
label=_("Date Published")
)
)

# DueDate is calculated by adding the MaxTimeAllowed to the date that the
# Analysis' sample was received. It's used to create alerts when analyses
# are "late", and also to populate catalog values.
DueDate = DateTimeField(
'DueDate',
widget=DateTimeWidget(
label=_("Due Date")
)
)

# This is used to calculate turnaround time reports.
# The value is set when the Analysis is published.
Duration = IntegerField(
'Duration',
widget=IntegerWidget(
label=_("Duration")
)
)

# This is used to calculate turnaround time reports.
# The value is set when the Analysis is published.
Earliness = IntegerField(
'Earliness',
widget=IntegerWidget(
label=_("Earliness")
)
)

# The ID of the logged in user who submitted the result for
# this Analysis.
Analyst = StringField(
'Analyst'
)

# Remarks entered in the manage_results screen are stored here. This
# is also used for remarks generated by results import, or other automated
# processes
Remarks = TextField(
'Remarks'
)

# The physical sample partition linked to the Analysis.
SamplePartition = UIDReferenceField(
'SamplePartition',
@@ -285,10 +199,15 @@ def getSamplePartitionID(self):
return ''

@security.public
def updateDueDate(self):
def getDueDate(self):
"""Used to populate getDueDate index and metadata.
This calculates the difference between the time that the sample
partition associated with this analysis was recieved, and the
maximum turnaround time.
"""
maxtime = self.getMaxTimeAllowed()
if not maxtime:
maxtime = {'days': 0, 'hours': 0, 'minutes': 0}
maxtime = get_tool('bika_setup').getDefaultTurnaroundTime()
max_days = float(maxtime.get('days', 0)) + (
(float(maxtime.get('hours', 0)) * 3600 +
float(maxtime.get('minutes', 0)) * 60)
@@ -298,7 +217,7 @@ def updateDueDate(self):
if part:
starttime = part.getDateReceived()
duetime = starttime + max_days if starttime else ''
self.setDueDate(duetime)
return duetime

@security.public
def getAnalysisRequestTitle(self):
19 changes: 16 additions & 3 deletions bika/lims/content/bikasetup.py
Original file line number Diff line number Diff line change
@@ -513,9 +513,22 @@ class PrefixesField(RecordsField):
widget=DurationWidget(
label=_("Default sample retention period"),
description=_(
"The number of days before a sample expires and cannot be analysed "
"any more. This setting can be overwritten per individual sample type "
"in the sample types setup"),
"The number of days before a sample expires and cannot be "
"analysed any more. This setting can be overwritten per "
"individual sample type in the sample types setup"),
)
),
DurationField(
'DefaultTurnaroundTime',
schemata="Analyses",
required=1,
default={"days": 5, "hours": 0, "minutes": 0},
widget=DurationWidget(
label=_("Default turnaround time for analyses."),
description=_(
"This is the default maximum time allowed for performing "
"analyses. It is only used for analyses where the analysis "
"service does not specify a turnaround time."),
)
),
StringField(
1 change: 0 additions & 1 deletion bika/lims/exportimport/setupdata/__init__.py
Original file line number Diff line number Diff line change
@@ -2174,7 +2174,6 @@ def load_analyses(self, sample):
ReportDryMatter=self.to_bool(row['ReportDryMatter']),
)

obj.updateDueDate()
part = sample.objectValues()[0].UID()
obj.setSamplePartition(part)
analyses = ar.objectValues('Analyses')
2 changes: 0 additions & 2 deletions bika/lims/subscribers/analysis.py
Original file line number Diff line number Diff line change
@@ -48,8 +48,6 @@ def ObjectInitializedEventHandler(instance, event):
wf_tool.doActionFor(ar, 'unassign')
skip(ar, 'unassign', unskip=True)

instance.updateDueDate()

return

def ObjectRemovedEventHandler(instance, event):