diff --git a/cdisc_rules_engine/dataset_builders/define_variables_with_library_metadata.py b/cdisc_rules_engine/dataset_builders/define_variables_with_library_metadata.py index 45f5c8cb0..9e9e80a84 100644 --- a/cdisc_rules_engine/dataset_builders/define_variables_with_library_metadata.py +++ b/cdisc_rules_engine/dataset_builders/define_variables_with_library_metadata.py @@ -24,6 +24,7 @@ def build(self): "define_variable_codelist_coded_codes", "define_variable_mandatory", "define_variable_has_comment", + "define_variable_has_method", "library_variable_name", "library_variable_label", "library_variable_data_type", diff --git a/cdisc_rules_engine/dataset_builders/variables_metadata_with_define_dataset_builder.py b/cdisc_rules_engine/dataset_builders/variables_metadata_with_define_dataset_builder.py index 2a62e0575..25237c09f 100644 --- a/cdisc_rules_engine/dataset_builders/variables_metadata_with_define_dataset_builder.py +++ b/cdisc_rules_engine/dataset_builders/variables_metadata_with_define_dataset_builder.py @@ -28,8 +28,9 @@ def build(self): define_variable_has_codelist, define_variable_codelist_coded_values, define_variable_codelist_coded_codes, - define_variable_mandatory - define_variable_has_comment + define_variable_mandatory, + define_variable_has_comment, + define_variable_has_method """ # get Define XML metadata for domain and use it as a rule comparator variable_metadata: List[dict] = self.get_define_xml_variables_metadata() diff --git a/cdisc_rules_engine/services/define_xml/base_define_xml_reader.py b/cdisc_rules_engine/services/define_xml/base_define_xml_reader.py index 5d08f235c..7a3c9afe1 100644 --- a/cdisc_rules_engine/services/define_xml/base_define_xml_reader.py +++ b/cdisc_rules_engine/services/define_xml/base_define_xml_reader.py @@ -382,6 +382,7 @@ def _get_item_def_representation(self, itemdef, itemref, codelists, index) -> di "define_variable_codelist_coded_codes": [], "define_variable_mandatory": None, "define_variable_has_comment": False, + "define_variable_has_method": False, } if itemdef: data["define_variable_mandatory"] = itemref.Mandatory @@ -418,6 +419,7 @@ def _get_item_def_representation(self, itemdef, itemref, codelists, index) -> di itemref, index ) data["define_variable_has_comment"] = itemdef.CommentOID is not None + data["define_variable_has_method"] = itemref.MethodOID is not None return data def _get_codelist_ccode(self, codelist): diff --git a/resources/schema/rule-merged/MetaVariables.json b/resources/schema/rule-merged/MetaVariables.json index 5af22ca7f..b3cab88dc 100644 --- a/resources/schema/rule-merged/MetaVariables.json +++ b/resources/schema/rule-merged/MetaVariables.json @@ -82,6 +82,10 @@ "const": "define_variable_has_comment", "markdownDescription": "\nItemGroupDef.ItemDef.CommentOID exists\n" }, + { + "const": "define_variable_has_method", + "markdownDescription": "\nItemGroupDef.ItemRef.MethodOID exists\n" + }, { "const": "define_variable_has_no_data", "markdownDescription": "\nItemGroupDef.ItemRef.HasNoData\n" @@ -198,6 +202,14 @@ "const": "library_variable_core", "markdownDescription": "\ncore attribute of a variable from the CDISC Library\n" }, + { + "const": "library_variable_has_codelist", + "markdownDescription": "\nIndicates whether a variable has an associated codelist in the CDISC Library\n" + }, + { + "const": "library_variable_ccode", + "markdownDescription": "\nccode attribute of a variable from the CDISC Library\n" + }, { "const": "library_variable_data_type", "markdownDescription": "\nsimpleDatatype attribute of a variable from the CDISC Library\n" diff --git a/resources/schema/rule-merged/Rule_Type.json b/resources/schema/rule-merged/Rule_Type.json index ee910a5cb..8dfb5afd5 100644 --- a/resources/schema/rule-merged/Rule_Type.json +++ b/resources/schema/rule-merged/Rule_Type.json @@ -20,7 +20,7 @@ { "const": "Define Item Metadata Check against Library Metadata", "title": "Define xml metadata at variable level and corresponding library variable metadata", - "markdownDescription": "\n#### Columns\n\n- `define_variable_name`\n- `define_variable_label`\n- `define_variable_data_type`\n- `define_variable_role`\n- `define_variable_size`\n- `define_variable_ccode`\n- `define_variable_format`\n- `define_variable_allowed_terms`\n- `define_variable_origin_type`\n- `define_variable_is_collected`\n- `define_variable_has_no_data`\n- `define_variable_order_number`\n- `define_variable_has_codelist`\n- `define_variable_codelist_coded_values`\n- `define_variable_codelist_coded_codes`\n- `define_variable_mandatory`\n- `define_variable_has_comment`\n- `library_variable_name`\n- `library_variable_order_number`\n- `library_variable_label`\n- `library_variable_data_type`\n- `library_variable_role`\n- `library_variable_core`\n- `library_variable_ccode`\n\n#### Rule Macro\n\nChecks variable-level metadata, codelists, and codelist terms from Define-XML against the corresponding standard variable definitions from the CDISC Library.\n" + "markdownDescription": "\n#### Columns\n\n- `define_variable_name`\n- `define_variable_label`\n- `define_variable_data_type`\n- `define_variable_role`\n- `define_variable_size`\n- `define_variable_ccode`\n- `define_variable_format`\n- `define_variable_allowed_terms`\n- `define_variable_origin_type`\n- `define_variable_is_collected`\n- `define_variable_has_no_data`\n- `define_variable_order_number`\n- `define_variable_has_codelist`\n- `define_variable_codelist_coded_values`\n- `define_variable_codelist_coded_codes`\n- `define_variable_mandatory`\n- `define_variable_has_comment`\n- `define_variable_has_method`\n- `library_variable_name`\n- `library_variable_order_number`\n- `library_variable_label`\n- `library_variable_data_type`\n- `library_variable_role`\n- `library_variable_core`\n- `library_variable_has_codelist`\n- `library_variable_ccode`\n\n#### Rule Macro\n\nChecks variable-level metadata, codelists, and codelist terms from Define-XML against the corresponding standard variable definitions from the CDISC Library.\n" }, { "const": "Domain Presence Check", @@ -65,7 +65,7 @@ { "const": "Variable Metadata Check against Define XML", "title": "Content metadata at variable level and define xml metadata at variable level", - "markdownDescription": "\n#### Columns\n\n- `variable_name`\n- `variable_order_number`\n- `variable_label`\n- `variable_size`\n- `variable_data_type`\n- `define_variable_name`\n- `define_variable_label`\n- `define_variable_data_type`\n- `define_variable_is_collected`\n- `define_variable_role`\n- `define_variable_size`\n- `define_variable_ccode`\n- `define_variable_format`\n- `define_variable_allowed_terms`\n- `define_variable_origin_type`\n- `define_variable_has_no_data`\n- `define_variable_order_number`\n- `define_variable_length`\n- `define_variable_has_codelist`\n- `define_variable_codelist_coded_values`\n- `define_variable_codelist_coded_codes`\n- `define_variable_mandatory`\n- `define_variable_has_comment`\n\n#### Rule Macro\n\nCombines variable-level metadata from submission dataset contents against the matching variable definitions in Define-XML.\n\n#### Example\n\n```yaml\n- name: variable_name\n operator: not_equal_to\n value: define_variable_name\n```\n" + "markdownDescription": "\n#### Columns\n\n- `variable_name`\n- `variable_order_number`\n- `variable_label`\n- `variable_size`\n- `variable_data_type`\n- `define_variable_name`\n- `define_variable_label`\n- `define_variable_data_type`\n- `define_variable_is_collected`\n- `define_variable_role`\n- `define_variable_size`\n- `define_variable_ccode`\n- `define_variable_format`\n- `define_variable_allowed_terms`\n- `define_variable_origin_type`\n- `define_variable_has_no_data`\n- `define_variable_order_number`\n- `define_variable_length`\n- `define_variable_has_codelist`\n- `define_variable_codelist_coded_values`\n- `define_variable_codelist_coded_codes`\n- `define_variable_mandatory`\n- `define_variable_has_comment`\n- `define_variable_has_method`\n\n#### Rule Macro\n\nCombines variable-level metadata from submission dataset contents against the matching variable definitions in Define-XML.\n\n#### Example\n\n```yaml\n- name: variable_name\n operator: not_equal_to\n value: define_variable_name\n```\n" }, { "const": "Variable Metadata Check against Library Metadata", diff --git a/resources/schema/rule/MetaVariables.json b/resources/schema/rule/MetaVariables.json index 85c873e3a..cc28cfca3 100644 --- a/resources/schema/rule/MetaVariables.json +++ b/resources/schema/rule/MetaVariables.json @@ -56,6 +56,9 @@ { "const": "define_variable_has_comment" }, + { + "const": "define_variable_has_method" + }, { "const": "define_variable_has_no_data" }, diff --git a/resources/schema/rule/MetaVariables.md b/resources/schema/rule/MetaVariables.md index d25e53de0..928ba3d32 100644 --- a/resources/schema/rule/MetaVariables.md +++ b/resources/schema/rule/MetaVariables.md @@ -86,6 +86,10 @@ ItemGroupDef.ItemDef.CodeListRef exists ItemGroupDef.ItemDef.CommentOID exists +## define_variable_has_method + +ItemGroupDef.ItemRef.MethodOID exists + ## define_variable_has_no_data ItemGroupDef.ItemRef.HasNoData diff --git a/resources/schema/rule/Rule_Type.md b/resources/schema/rule/Rule_Type.md index fa8e46eda..d9b838dd7 100644 --- a/resources/schema/rule/Rule_Type.md +++ b/resources/schema/rule/Rule_Type.md @@ -191,6 +191,7 @@ Columns are the columns within the original dataset along with the following col - `define_variable_codelist_coded_values` - `define_variable_codelist_coded_values` - `define_variable_has_comment` +- `define_variable_has_method` #### Rule Macro @@ -309,6 +310,7 @@ all: - `define_variable_codelist_coded_codes` - `define_variable_mandatory` - `define_variable_has_comment` +- `define_variable_has_method` - `library_variable_name` - `library_variable_order_number` - `library_variable_label` @@ -498,6 +500,7 @@ all: - `define_variable_codelist_coded_codes` - `define_variable_mandatory` - `define_variable_has_comment` +- `define_variable_has_method` #### Rule Macro @@ -561,6 +564,7 @@ Combines variable-level metadata from submission dataset contents against the co - `define_variable_codelist_coded_codes` - `define_variable_mandatory` - `define_variable_has_comment` +- `define_variable_has_method` - `library_variable_name` - `library_variable_role` - `library_variable_label` diff --git a/tests/unit/test_dataset_builders/test_define_variables_with_library_metadata.py b/tests/unit/test_dataset_builders/test_define_variables_with_library_metadata.py index 3c36c1478..1f477027a 100644 --- a/tests/unit/test_dataset_builders/test_define_variables_with_library_metadata.py +++ b/tests/unit/test_dataset_builders/test_define_variables_with_library_metadata.py @@ -227,6 +227,7 @@ def test_define_variables_metadata_with_library_metadata_dataset_builder( "define_variable_codelist_coded_codes", "define_variable_mandatory", "define_variable_has_comment", + "define_variable_has_method", "library_variable_name", "library_variable_role", "library_variable_label", diff --git a/tests/unit/test_dataset_builders/test_variables_metadata_with_define_and_library_dataset_builder.py b/tests/unit/test_dataset_builders/test_variables_metadata_with_define_and_library_dataset_builder.py index 430ad609e..674e01176 100644 --- a/tests/unit/test_dataset_builders/test_variables_metadata_with_define_and_library_dataset_builder.py +++ b/tests/unit/test_dataset_builders/test_variables_metadata_with_define_and_library_dataset_builder.py @@ -176,6 +176,7 @@ def test_build_combined_metadata( "define_variable_codelist_coded_codes", "define_variable_mandatory", "define_variable_has_comment", + "define_variable_has_method", "library_variable_name", "library_variable_label", "library_variable_data_type", diff --git a/tests/unit/test_define_xml_reader.py b/tests/unit/test_define_xml_reader.py index b31c52a87..57b00f6fd 100644 --- a/tests/unit/test_define_xml_reader.py +++ b/tests/unit/test_define_xml_reader.py @@ -223,6 +223,15 @@ def test_extract_variable_metadata(filename): "define_variable_is_collected": False, "define_variable_order_number": 11, "define_variable_has_comment": True, + "define_variable_has_method": False, + } + expected_exdose_metadata = { + "define_variable_name": "EXDOSE", + "define_variable_data_type": "integer", + "define_variable_origin_type": "Derived", + "define_variable_is_collected": False, + "define_variable_has_comment": False, + "define_variable_has_method": True, } for index, variable in enumerate(variable_metadata): assert variable["define_variable_name"] in expected_variables @@ -232,6 +241,12 @@ def test_extract_variable_metadata(filename): ): for key in expected_exroute_metadata.keys(): assert variable[key] == expected_exroute_metadata[key] + if ( + variable["define_variable_name"] + == expected_exdose_metadata["define_variable_name"] + ): + for key in expected_exdose_metadata.keys(): + assert variable[key] == expected_exdose_metadata[key] assert variable["define_variable_order_number"] == index + 1