Skip to content

Commit 4a6e062

Browse files
authored
Merge pull request #326 from ansforge/feat/rc-ri-conversion
feat(converter): conversion RC-RI/RS-RI
2 parents c6f39ec + 811c7f7 commit 4a6e062

27 files changed

+372
-75
lines changed

converter/converter/cisu/base_cisu_converter.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
class BaseCISUConverter:
1+
from converter.conversion_mixin import ConversionMixin
2+
from typing import Any, Dict
3+
4+
5+
class BaseCISUConverter(ConversionMixin):
26
def __init__(self):
37
raise ValueError(
48
"BaseMessageConverter is an abstract class and cannot be instantiated directly. Use a subclass instead."
@@ -27,3 +31,47 @@ def from_cisu_to_rs(cls, edxl_json):
2731
raise ValueError(
2832
f"Traduction from '{cls.get_cisu_message_type()}' to '{cls.get_rs_message_type()}' is not supported."
2933
)
34+
35+
@classmethod
36+
def copy_cisu_input_content(cls, edxl_json: Dict[str, Any]) -> Dict[str, Any]:
37+
return cls._copy_input_content(edxl_json, cls.get_cisu_message_type())
38+
39+
@classmethod
40+
def copy_cisu_input_use_case_content(
41+
cls, edxl_json: Dict[str, Any]
42+
) -> Dict[str, Any]:
43+
return cls._copy_input_use_case_content(edxl_json, cls.get_cisu_message_type())
44+
45+
@classmethod
46+
def format_cisu_output_json(
47+
cls,
48+
output_json: Dict[str, Any],
49+
output_use_case_json: Dict[str, Any],
50+
) -> Dict[str, Any]:
51+
return cls._format_output_json(
52+
output_json,
53+
output_use_case_json,
54+
cls.get_cisu_message_type(),
55+
)
56+
57+
@classmethod
58+
def copy_rs_input_content(cls, edxl_json: Dict[str, Any]) -> Dict[str, Any]:
59+
return cls._copy_input_content(edxl_json, cls.get_rs_message_type())
60+
61+
@classmethod
62+
def copy_rs_input_use_case_content(
63+
cls, edxl_json: Dict[str, Any]
64+
) -> Dict[str, Any]:
65+
return cls._copy_input_use_case_content(edxl_json, cls.get_rs_message_type())
66+
67+
@classmethod
68+
def format_rs_output_json(
69+
cls,
70+
output_json: Dict[str, Any],
71+
output_use_case_json: Dict[str, Any],
72+
) -> Dict[str, Any]:
73+
return cls._format_output_json(
74+
output_json,
75+
output_use_case_json,
76+
cls.get_rs_message_type(),
77+
)

converter/converter/cisu/create_case/create_case_cisu_converter.py

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -170,21 +170,11 @@ def add_object_to_medical_notes(
170170
json_data["medicalNote"].append(new_note)
171171

172172
# Create independent envelope copy without usecase for output
173-
output_json = copy.deepcopy(input_json)
174-
if "createCase" not in input_json.get("content", [{}])[0].get(
175-
"jsonContent", {}
176-
).get("embeddedJsonContent", {}).get("message", {}):
177-
raise ValueError("Input JSON must contain 'createCase' key")
178-
del output_json["content"][0]["jsonContent"]["embeddedJsonContent"]["message"][
179-
"createCase"
180-
]
173+
output_json = cls.copy_cisu_input_content(input_json)
181174

182175
# Create independent use case copy for output
183-
input_use_case_json = input_json["content"][0]["jsonContent"][
184-
"embeddedJsonContent"
185-
]["message"]["createCase"]
186176
sender_id = get_sender(input_json)
187-
output_use_case_json = copy.deepcopy(input_use_case_json)
177+
output_use_case_json = cls.copy_cisu_input_use_case_content(input_json)
188178

189179
# - Updates
190180
output_use_case_json["owner"] = get_recipient(input_json)
@@ -204,10 +194,7 @@ def add_object_to_medical_notes(
204194
# - Delete paths - /!\ It must be the last step
205195
delete_paths(output_use_case_json, cls.CISU_PATHS_TO_DELETE)
206196

207-
output_json["content"][0]["jsonContent"]["embeddedJsonContent"]["message"][
208-
"createCaseHealth"
209-
] = output_use_case_json
210-
return output_json
197+
return cls.format_rs_output_json(output_json, output_use_case_json)
211198

212199
@staticmethod
213200
def count_victims(json_data: Dict[str, Any]) -> int:
@@ -264,19 +251,10 @@ def add_default_external_info_type(json_data: Dict[str, Any]):
264251
info["type"] = "AUTRE"
265252

266253
# Create independent envelope copy without usecase for output
267-
output_json = copy.deepcopy(input_json)
268-
if "createCaseHealth" not in input_json.get("content", [{}])[0].get(
269-
"jsonContent", {}
270-
).get("embeddedJsonContent", {}).get("message", {}):
271-
raise ValueError("Input JSON must contain 'createCaseHealth' key")
272-
del output_json["content"][0]["jsonContent"]["embeddedJsonContent"]["message"][
273-
"createCaseHealth"
274-
]
254+
output_json = cls.copy_rs_input_content(input_json)
275255

276256
# Create independent usecase copy for output
277-
input_usecase_json = input_json["content"][0]["jsonContent"][
278-
"embeddedJsonContent"
279-
]["message"]["createCaseHealth"]
257+
input_usecase_json = cls.copy_rs_input_use_case_content(input_json)
280258
output_usecase_json = copy.deepcopy(input_usecase_json)
281259

282260
# Generate unique IDs
@@ -330,7 +308,4 @@ def add_default_external_info_type(json_data: Dict[str, Any]):
330308
get_field_value(output_usecase_json, "$.location")
331309
)
332310

333-
output_json["content"][0]["jsonContent"]["embeddedJsonContent"]["message"][
334-
"createCase"
335-
] = output_usecase_json
336-
return output_json
311+
return cls.format_cisu_output_json(output_json, output_usecase_json)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class ResourcesInfoCISUConstants:
2+
RESOURCE_PATH = "$.resource"
3+
STATE_PATH = "$.state"
4+
VEHICLE_TYPE_PATH = "$.vehicleType"
5+
6+
PATIENT_ID_KEY = "patientId"
7+
8+
VEHICLE_TYPE_SIS = "SIS"
9+
DEFAULT_CISU_STATE_VEHICLE_TYPE = "SMUR"
10+
11+
DEFAULT_CISU_STATE_STATUS = "DECISION"

converter/converter/cisu/resources_info/resources_info_cisu_converter.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1+
import datetime
2+
13
from converter.cisu.base_cisu_converter import BaseCISUConverter
4+
from typing import Any, Dict
5+
6+
from converter.cisu.resources_info.resources_info_cisu_constants import (
7+
ResourcesInfoCISUConstants,
8+
)
9+
from converter.utils import get_field_value, set_value, delete_paths
210

311

412
class ResourcesInfoCISUConverter(BaseCISUConverter):
@@ -9,3 +17,63 @@ def get_rs_message_type(cls) -> str:
917
@classmethod
1018
def get_cisu_message_type(cls) -> str:
1119
return "resourcesInfoCisu"
20+
21+
@classmethod
22+
def from_cisu_to_rs(cls, edxl_json: Dict[str, Any]) -> Dict[str, Any]:
23+
output_json = cls.copy_cisu_input_content(edxl_json)
24+
output_use_case_json = cls.copy_cisu_input_use_case_content(edxl_json)
25+
resources = get_field_value(
26+
output_use_case_json, ResourcesInfoCISUConstants.RESOURCE_PATH
27+
)
28+
29+
for resource in resources:
30+
state = get_field_value(resource, ResourcesInfoCISUConstants.STATE_PATH)
31+
set_value(resource, ResourcesInfoCISUConstants.STATE_PATH, [state])
32+
33+
return cls.format_rs_output_json(output_json, output_use_case_json)
34+
35+
@classmethod
36+
def from_rs_to_cisu(cls, edxl_json: Dict[str, Any]) -> Dict[str, Any]:
37+
output_json = cls.copy_rs_input_content(edxl_json)
38+
output_use_case_json = cls.copy_rs_input_use_case_content(edxl_json)
39+
40+
resources = get_field_value(
41+
output_use_case_json, ResourcesInfoCISUConstants.RESOURCE_PATH
42+
)
43+
for resource in resources:
44+
rs_vehicle_type = get_field_value(
45+
resource, ResourcesInfoCISUConstants.VEHICLE_TYPE_PATH
46+
)
47+
cisu_vehicle_type = cls.translate_to_cisu_vehicle_type(rs_vehicle_type)
48+
set_value(
49+
resource,
50+
ResourcesInfoCISUConstants.VEHICLE_TYPE_PATH,
51+
cisu_vehicle_type,
52+
)
53+
54+
cls.keep_last_state(resource)
55+
56+
delete_paths(resource, [ResourcesInfoCISUConstants.PATIENT_ID_KEY])
57+
58+
return cls.format_cisu_output_json(output_json, output_use_case_json)
59+
60+
@classmethod
61+
def translate_to_cisu_vehicle_type(cls, rs_vehicle_type: str) -> str:
62+
if rs_vehicle_type.startswith(ResourcesInfoCISUConstants.VEHICLE_TYPE_SIS):
63+
return ResourcesInfoCISUConstants.VEHICLE_TYPE_SIS
64+
return ResourcesInfoCISUConstants.DEFAULT_CISU_STATE_VEHICLE_TYPE
65+
66+
@classmethod
67+
def keep_last_state(cls, resource: Dict[str, Any]) -> None:
68+
states = get_field_value(resource, ResourcesInfoCISUConstants.STATE_PATH)
69+
if states and len(states) > 0:
70+
latest_state = sorted(states, key=lambda x: x.get("datetime", ""))[-1]
71+
else:
72+
latest_state = {
73+
"datetime": datetime.datetime.now(datetime.timezone.utc).isoformat(
74+
timespec="seconds"
75+
),
76+
"status": ResourcesInfoCISUConstants.DEFAULT_CISU_STATE_STATUS,
77+
}
78+
79+
set_value(resource, ResourcesInfoCISUConstants.STATE_PATH, latest_state)

converter/converter/versions/conversion_mixin.py renamed to converter/converter/conversion_mixin.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
import copy
22
from typing import Dict, Any
33

4-
from converter.versions.base_message_converter import BaseMessageConverter
54

6-
7-
class ConversionMixin(BaseMessageConverter):
5+
class ConversionMixin:
86
CONTENT_KEY = "content"
97
JSON_CONTENT_KEY = "jsonContent"
108
EMBEDDED_JSON_CONTENT_KEY = "embeddedJsonContent"
119
MESSAGE_KEY = "message"
1210

1311
@classmethod
14-
def copy_input_content(cls, input_json: Dict[str, Any]) -> Dict[str, Any]:
12+
def _copy_input_content(
13+
cls, input_json: Dict[str, Any], message_type: str
14+
) -> Dict[str, Any]:
1515
output_json = copy.deepcopy(input_json)
16-
message_type = cls.get_message_type()
1716

1817
message_content = (
1918
input_json.get(cls.CONTENT_KEY, [{}])[0]
@@ -30,18 +29,21 @@ def copy_input_content(cls, input_json: Dict[str, Any]) -> Dict[str, Any]:
3029
return output_json
3130

3231
@classmethod
33-
def copy_input_use_case_content(cls, input_json: Dict[str, Any]) -> Dict[str, Any]:
34-
message_type = cls.get_message_type()
32+
def _copy_input_use_case_content(
33+
cls, input_json: Dict[str, Any], message_type: str
34+
) -> Dict[str, Any]:
3535
input_use_case_json = input_json[cls.CONTENT_KEY][0][cls.JSON_CONTENT_KEY][
3636
cls.EMBEDDED_JSON_CONTENT_KEY
3737
][cls.MESSAGE_KEY][message_type]
3838
return copy.deepcopy(input_use_case_json)
3939

4040
@classmethod
41-
def format_output_json(
42-
cls, output_json: Dict[str, Any], output_use_case_json: Dict[str, Any]
41+
def _format_output_json(
42+
cls,
43+
output_json: Dict[str, Any],
44+
output_use_case_json: Dict[str, Any],
45+
message_type: str,
4346
) -> Dict[str, Any]:
44-
message_type = cls.get_message_type()
4547
output_json[cls.CONTENT_KEY][0][cls.JSON_CONTENT_KEY][
4648
cls.EMBEDDED_JSON_CONTENT_KEY
4749
][cls.MESSAGE_KEY][message_type] = output_use_case_json

converter/converter/versions/base_message_converter.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
from converter.conversion_mixin import ConversionMixin
2+
from typing import Dict, Any
3+
14
version_order_list = ["v1", "v2", "v3"]
25

36

4-
class BaseMessageConverter:
7+
class BaseMessageConverter(ConversionMixin):
58
def __init__(self):
69
raise ValueError(
710
"BaseMessageConverter is an abstract class and cannot be instantiated directly. Use a subclass instead."
@@ -112,3 +115,21 @@ def raise_conversion_impossible_error(cls, source_version, target_version):
112115
raise ValueError(
113116
f"Version conversion from {source_version} to {target_version} is not possible."
114117
)
118+
119+
@classmethod
120+
def copy_input_content(cls, input_json: Dict[str, Any]) -> Dict[str, Any]:
121+
return cls._copy_input_content(input_json, cls.get_message_type())
122+
123+
@classmethod
124+
def copy_input_use_case_content(cls, input_json: Dict[str, Any]) -> Dict[str, Any]:
125+
return cls._copy_input_use_case_content(input_json, cls.get_message_type())
126+
127+
@classmethod
128+
def format_output_json(
129+
cls,
130+
output_json: Dict[str, Any],
131+
output_use_case_json: Dict[str, Any],
132+
) -> Dict[str, Any]:
133+
return cls._format_output_json(
134+
output_json, output_use_case_json, cls.get_message_type()
135+
)

converter/converter/versions/create_case_health/create_case_health_converter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
is_field_completed,
88
map_to_new_value,
99
)
10-
from converter.versions.conversion_mixin import ConversionMixin
10+
from converter.versions.base_message_converter import BaseMessageConverter
1111
from converter.versions.create_case_health.v1_v2.constants import V1V2Constants
1212
from converter.versions.create_case_health.v2_v3.constants import V2V3Constants
1313
from converter.versions.utils import (
@@ -17,7 +17,7 @@
1717
)
1818

1919

20-
class CreateHealthCaseConverter(ConversionMixin):
20+
class CreateHealthCaseConverter(BaseMessageConverter):
2121
@staticmethod
2222
def get_message_type() -> str:
2323
return "createCaseHealth"

converter/converter/versions/document_link/document_link_converter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from typing import Dict, Any
22

33
from converter.utils import delete_paths
4-
from converter.versions.conversion_mixin import ConversionMixin
4+
from converter.versions.base_message_converter import BaseMessageConverter
55
from converter.versions.document_link.document_link_constants import (
66
DocumentLinkConstants,
77
)
88

99

10-
class DocumentLinkConverter(ConversionMixin):
10+
class DocumentLinkConverter(BaseMessageConverter):
1111
@staticmethod
1212
def get_message_type():
1313
return "documentLink"

converter/converter/versions/geo_positions_update/geo_positions_update_converter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
from typing import Dict, Any
22

33
from converter.utils import get_field_value, update_json_value, delete_paths
4-
from converter.versions.conversion_mixin import ConversionMixin
4+
from converter.versions.base_message_converter import BaseMessageConverter
55
from converter.versions.geo_positions_update.geo_positions_update_constants import (
66
GeoPositionsUpdateConstants,
77
)
88
from converter.versions.utils import convert_to_float, convert_to_str
99

1010

11-
class GeoPositionsUpdateConverter(ConversionMixin):
11+
class GeoPositionsUpdateConverter(BaseMessageConverter):
1212
@staticmethod
1313
def get_message_type():
1414
return "geoPositionsUpdate"

converter/converter/versions/geo_resources_details/geo_resources_details_converter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
from typing import Dict, Any
22

33
from converter.utils import get_field_value, map_to_new_value, update_json_value
4-
from converter.versions.conversion_mixin import ConversionMixin
4+
from converter.versions.base_message_converter import BaseMessageConverter
55
from converter.versions.geo_resources_details.geo_resources_details_constants import (
66
GeoResourcesDetailsConstants,
77
)
88
from converter.versions.utils import reverse_map_to_new_value
99

1010

11-
class GeoResourcesDetailsConverter(ConversionMixin):
11+
class GeoResourcesDetailsConverter(BaseMessageConverter):
1212
@staticmethod
1313
def get_message_type():
1414
return "geoResourcesDetails"

0 commit comments

Comments
 (0)