Passed
Push — master ( 314925...bb82db )
by Pau
04:03
created

AddSampleBatchInfo.get_object_info()   A

Complexity

Conditions 3

Size

Total Lines 36
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 25
dl 0
loc 36
rs 9.28
c 0
b 0
f 0
cc 3
nop 1
1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of SENAITE.HEALTH.
4
#
5
# SENAITE.HEALTH is free software: you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by the Free
7
# Software Foundation, version 2.
8
#
9
# This program is distributed in the hope that it will be useful, but WITHOUT
10
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12
# details.
13
#
14
# You should have received a copy of the GNU General Public License along with
15
# this program; if not, write to the Free Software Foundation, Inc., 51
16
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
#
18
# Copyright 2018-2019 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
from zope.component import adapts
22
23
from bika.health.interfaces import IDoctor
24
from bika.health.interfaces import IPatient
25
from bika.lims import api
26
from bika.lims.adapters.addsample import AddSampleObjectInfoAdapter
27
from bika.lims.interfaces import IAddSampleFieldsFlush
28
from bika.lims.interfaces import IBatch
29
from bika.lims.interfaces import IClient
30
from bika.lims.interfaces import IGetDefaultFieldValueARAddHook
31
32
33
class AddFormFieldDefaultValueAdapter(object):
34
    """Generic adapter for objects retrieval based on request uid and field name
35
    """
36
37
    def __init__(self, request):
38
        self.request = request
39
40
    def get_object_from_request_field(self, field_name):
41
        """Returns the object for the field_name specified in the request
42
        """
43
        uid = self.request.get(field_name)
44
        return api.get_object_by_uid(uid, default=None)
45
46
47
class ClientDefaultFieldValue(AddFormFieldDefaultValueAdapter):
48
    """Adapter that returns the default value for field Client in Sample form
49
    """
50
51
    adapts(IGetDefaultFieldValueARAddHook)
52
53
    def __call__(self, context):
54
55
        if IClient.providedBy(context):
56
            return context
57
58
        # Try to get the client from selected Batch
59
        batch = BatchDefaultFieldValue(self.request)(context)
60
        client = batch and batch.getClient() or None
61
        if client:
62
            return client
63
64
        # Try to get the client from selected Patient
65
        patient = PatientDefaultFieldValue(self.request)(context)
66
        client = patient and patient.getPrimaryReferrer() or None
67
        if client:
68
            return client
69
70
        # Try to get the client from selected Doctor
71
        doctor = DoctorDefaultFieldValue(self.request)(context)
72
        client = doctor and doctor.getPrimaryReferrer() or None
73
        if client:
74
            return client
75
76
        # Try with client object explicitly defined in request
77
        return self.get_object_from_request_field("Client")
78
79
80
class PatientDefaultFieldValue(AddFormFieldDefaultValueAdapter):
81
    """Adapter that returns the default value for field Patient in Sample form
82
    """
83
    adapts(IGetDefaultFieldValueARAddHook)
84
85
    def __call__(self, context):
86
        if IPatient.providedBy(context):
87
            return context
88
89
        # Try to get the client from selected Batch
90
        batch = BatchDefaultFieldValue(self.request)(context)
91
        patient = batch and batch.getField("Patient").get(context) or None
92
        if patient:
93
            return patient
94
95
        # Try with patient explicitly defined in request
96
        return self.get_object_from_request_field("Patient")
97
98
99
class DoctorDefaultFieldValue(AddFormFieldDefaultValueAdapter):
100
    """Adapter that returns the default value for field Doctor in Sample form
101
    """
102
    adapts(IGetDefaultFieldValueARAddHook)
103
104
    def __call__(self, context):
105
        if IDoctor.providedBy(context):
106
            return context
107
108
        # Try to get the client from selected Batch
109
        batch = BatchDefaultFieldValue(self.request)(context)
110
        doctor = batch and batch.getField("Doctor").get(context) or None
111
        if doctor:
112
            return doctor
113
114
        # Try with doctor explicitly defined in request
115
        return self.get_object_from_request_field("Doctor")
116
117
118
class BatchDefaultFieldValue(AddFormFieldDefaultValueAdapter):
119
    """Adapter that returns the default value for field Batch in Sample form
120
    """
121
    adapts(IGetDefaultFieldValueARAddHook)
122
123
    def __call__(self, context):
124
        if IBatch.providedBy(context):
125
            return context
126
127
        # Try with batch explicitly defined in request
128
        return self.get_object_from_request_field("Batch")
129
130
131
class AddSampleClientInfo(AddSampleObjectInfoAdapter):
132
    """Returns the additional filter queries to apply when the value for the
133
    Client from Sample Add form changes
134
    """
135
    def get_object_info(self):
136
        object_info = self.get_base_info()
137
        uid = api.get_uid(self.context)
138
        filter_queries = {
139
            # Allow to choose Patients from same Client only
140
            "Patient": {
141
                "getPrimaryReferrerUID": [uid, ""],
142
            },
143
            "ClientPatientID": {
144
                "getPrimaryReferrerUID": [uid, ""],
145
            }
146
        }
147
        object_info["filter_queries"] = filter_queries
148
        return object_info
149
150
151
class AddSampleBatchInfo(AddSampleObjectInfoAdapter):
152
    """Returns the info metadata representation of a Batch object used in Add
153
    Sample form
154
    """
155
    def get_object_info(self):
156
        object_info = self.get_base_info()
157
158
        # Default values for other fields when the Batch is selected
159
        doctor = self.context.getField("Doctor").get(self.context)
160
        client = self.context.getClient()
161
        field_values = {
162
            "Doctor": self.to_field_value(doctor),
163
            "Client": self.to_field_value(client),
164
        }
165
        patient = self.context.getField("Patient").get(self.context)
166
        if patient:
167
            field_values.update({
168
                "Patient": self.to_field_value(patient),
169
                "ClientPatientID": {
170
                    "uid": api.get_uid(patient),
171
                    "title": patient.getClientPatientID() or api.get_id(patient),
172
                }
173
            })
174
175
        # Allow to choose Patients from same Client only and apply
176
        # generic filters when a client is selected too
177
        filter_queries = {}
178
        if client:
179
            uid = api.get_uid(client)
180
            filter_queries = {
181
                "Patient": {
182
                    "getPrimaryReferrerUID": [uid, ""],
183
                },
184
                "ClientPatientID": {
185
                    "getPrimaryReferrerUID": [uid, ""],
186
                }
187
            }
188
        object_info["field_values"] = field_values
189
        object_info["filter_queries"] = filter_queries
190
        return object_info
191
192
    def to_field_value(self, obj):
193
        return {
194
            "uid": obj and api.get_uid(obj) or "",
195
            "title": obj and api.get_title(obj) or ""}
196
197
198
class AddSampleFieldsFlush(object):
199
    """Health-specific flush of fields for Sample Add form. When the value for
200
    Client field changes, flush the fields "Patient", "Doctor" and "Batch"
201
    """
202
    adapts(IAddSampleFieldsFlush)
203
204
    def __init__(self, context):
205
        self.context = context
206
207
    def get_flush_settings(self):
208
        flush_settings = {
209
            "Client": [
210
                "Batch",
211
                "ClientPatientID",
212
                "Doctor",
213
                "Patient",
214
            ]
215
        }
216
        return flush_settings
217