|
1
|
|
|
# -*- coding: utf-8 -*- |
|
2
|
|
|
# |
|
3
|
|
|
# This file is part of SENAITE.CORE |
|
4
|
|
|
# |
|
5
|
|
|
# Copyright 2018 by it's authors. |
|
6
|
|
|
# Some rights reserved. See LICENSE.rst, CONTRIBUTORS.rst. |
|
7
|
|
|
|
|
8
|
|
|
import transaction |
|
9
|
|
|
from Products.CMFPlone.utils import _createObjectByType |
|
10
|
|
|
from bika.lims import logger |
|
11
|
|
|
from bika.lims.utils import tmpID |
|
12
|
|
|
from bika.lims.utils.analysis import copy_analysis_field_values |
|
13
|
|
|
from bika.lims.workflow import doActionFor |
|
14
|
|
|
from bika.lims.workflow.analysis import events as analysis_events |
|
15
|
|
|
|
|
16
|
|
|
|
|
17
|
|
|
def after_submit(duplicate_analysis): |
|
18
|
|
|
"""Method triggered after a 'submit' transition for the duplicate analysis |
|
19
|
|
|
passed in is performed. |
|
20
|
|
|
Delegates to bika.lims.workflow.analysis.events.after_submit |
|
21
|
|
|
""" |
|
22
|
|
|
analysis_events.after_submit(duplicate_analysis) |
|
23
|
|
|
|
|
24
|
|
|
|
|
25
|
|
|
def after_verify(duplicate_analysis): |
|
26
|
|
|
"""Function called after a 'verify' transition for the duplicate analysis |
|
27
|
|
|
passed in is performed |
|
28
|
|
|
Delegates to bika.lims.workflow.analysis.events.after_verify |
|
29
|
|
|
""" |
|
30
|
|
|
analysis_events.after_verify(duplicate_analysis) |
|
31
|
|
|
|
|
32
|
|
|
|
|
33
|
|
|
def after_unassign(duplicate_analysis): |
|
34
|
|
|
"""Removes the duplicate from the system |
|
35
|
|
|
""" |
|
36
|
|
|
analysis_events.after_unassign(duplicate_analysis) |
|
37
|
|
|
parent = duplicate_analysis.aq_parent |
|
38
|
|
|
logger.info("Removing duplicate '{}' from '{}'" |
|
39
|
|
|
.format(duplicate_analysis.getId(), parent.getId())) |
|
40
|
|
|
parent.manage_delObjects([duplicate_analysis.getId()]) |
|
41
|
|
|
|
|
42
|
|
|
|
|
43
|
|
|
def after_retract(duplicate_analysis): |
|
44
|
|
|
"""Function triggered after a 'retract' transition for the duplicate passed |
|
45
|
|
|
in is performed. The duplicate transitions to "retracted" state and a new |
|
46
|
|
|
copy of the duplicate is created. |
|
47
|
|
|
""" |
|
48
|
|
|
# Rename the analysis to make way for it's successor. |
|
49
|
|
|
# Support multiple retractions by renaming to *-0, *-1, etc |
|
50
|
|
|
parent = duplicate_analysis.aq_parent |
|
51
|
|
|
keyword = duplicate_analysis.getKeyword() |
|
52
|
|
|
analyses = filter(lambda an: an.getKeyword() == keyword, |
|
53
|
|
|
parent.objectValues("DuplicateAnalysis")) |
|
54
|
|
|
|
|
55
|
|
|
# Rename the retracted duplicate |
|
56
|
|
|
# https://docs.plone.org/develop/plone/content/rename.html |
|
57
|
|
|
# _verifyObjectPaste permission check must be cancelled |
|
58
|
|
|
parent._verifyObjectPaste = str |
|
59
|
|
|
retracted_id = '{}-{}'.format(keyword, len(analyses)) |
|
60
|
|
|
# Make sure all persistent objects have _p_jar attribute |
|
61
|
|
|
transaction.savepoint(optimistic=True) |
|
62
|
|
|
parent.manage_renameObject(duplicate_analysis.getId(), retracted_id) |
|
63
|
|
|
delattr(parent, '_verifyObjectPaste') |
|
64
|
|
|
|
|
65
|
|
|
# Find out the slot position of the duplicate in the worksheet |
|
66
|
|
|
worksheet = duplicate_analysis.getWorksheet() |
|
67
|
|
|
if not worksheet: |
|
68
|
|
|
logger.warn("Duplicate {} has been retracted, but without worksheet" |
|
69
|
|
|
.format(duplicate_analysis.getId())) |
|
70
|
|
|
return |
|
71
|
|
|
|
|
72
|
|
|
dest_slot = worksheet.get_slot_position_for(duplicate_analysis) |
|
73
|
|
|
if not dest_slot: |
|
74
|
|
|
logger.warn("Duplicate {} has been retracted, but not found in any" |
|
75
|
|
|
"slot of worksheet {}" |
|
76
|
|
|
.format(duplicate_analysis.getId(), worksheet.getId())) |
|
77
|
|
|
return |
|
78
|
|
|
|
|
79
|
|
|
# Create a copy (retest) of the duplicate and assign to worksheet |
|
80
|
|
|
ref_gid = duplicate_analysis.getReferenceAnalysesGroupID() |
|
81
|
|
|
retest = _createObjectByType("DuplicateAnalysis", worksheet, tmpID()) |
|
82
|
|
|
copy_analysis_field_values(duplicate_analysis, retest) |
|
83
|
|
|
retest.setAnalysis(duplicate_analysis.getAnalysis()) |
|
84
|
|
|
retest.setRetestOf(duplicate_analysis) |
|
85
|
|
|
retest.setReferenceAnalysesGroupID(ref_gid) |
|
86
|
|
|
retest.setResult(duplicate_analysis.getResult()) |
|
87
|
|
|
worksheet.addToLayout(retest, dest_slot) |
|
88
|
|
|
worksheet.setAnalyses(worksheet.getAnalyses() + [retest, ]) |
|
89
|
|
|
|
|
90
|
|
|
# Reindex |
|
91
|
|
|
retest.reindexObject(idxs=["getAnalyst", "getWorksheetUID", "isRetest", |
|
92
|
|
|
"getReferenceAnalysesGroupID"]) |
|
93
|
|
|
worksheet.reindexObject(idxs=["getAnalysesUIDs"]) |
|
94
|
|
|
|
|
95
|
|
|
# Try to rollback the worksheet to prevent inconsistencies |
|
96
|
|
|
doActionFor(worksheet, "rollback_to_open") |
|
97
|
|
|
|