Repository: dlubal-software/RFEM_Python_Client (language: python)

Issue:
BUG: SteelMemberLocalSectionReduction 
Getting error in branch : heet-memberLocalSectionReduction

after importing and calling SteelMemberLocalSectionReduction in example(Demo2), It raises WebFault: b"Server raised fault: 'Enumeration item '' not found.'"


Discussion / hints:

Fix patch:
diff --git a/Examples/Cantilever/demo2.py b/Examples/Cantilever/demo2.py
new file mode 100644
index 00000000..fd32173b
--- /dev/null
+++ b/Examples/Cantilever/demo2.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import os
+import sys
+baseName = os.path.basename(__file__)
+dirName = os.path.dirname(__file__)
+print('basename:    ', baseName)
+print('dirname:     ', dirName)
+sys.path.append(dirName + r'/../..')
+
+from RFEM.enums import *
+from RFEM.initModel import Model, Calculate_all
+from RFEM.BasicObjects.material import Material
+from RFEM.BasicObjects.section import Section
+from RFEM.BasicObjects.node import Node
+from RFEM.BasicObjects.member import Member
+from RFEM.TypesForNodes.nodalSupport import NodalSupport
+from RFEM.LoadCasesAndCombinations.staticAnalysisSettings import StaticAnalysisSettings
+from RFEM.LoadCasesAndCombinations.loadCase import LoadCase
+from RFEM.Loads.nodalLoad import NodalLoad
+from RFEM.Calculate.meshSettings import GetModelInfo
+from RFEM.TypesForSteelDesign.SteelMemberLocalSectionReduction import SteelMemberLocalSectionReduction
+from RFEM.enums import SteelMemberLocalSectionReductionType,MemberTransverseStiffenerPosition
+
+if __name__ == '__main__':
+
+    Model(True, "Demo1") # crete new model called Demo1
+    Model.clientModel.service.begin_modification()
+
+    Material(1, 'S235')
+
+    Section(1, 'IPE 200')
+
+    Node(1, 0.0, 0.0, 0.0)
+    Node(2, 6, 0.0, 0.0)
+
+    Member(1, 1, 2, 0.0, 1, 1)
+
+    SteelMemberLocalSectionReduction()
+
+    Model.clientModel.service.finish_modification()
diff --git a/RFEM/TypesForSteelDesign/SteelMemberLocalSectionReduction.py b/RFEM/TypesForSteelDesign/SteelMemberLocalSectionReduction.py
new file mode 100644
index 00000000..b296e46e
--- /dev/null
+++ b/RFEM/TypesForSteelDesign/SteelMemberLocalSectionReduction.py
@@ -0,0 +1,100 @@
+#SteelMemberLocalSectionReduction
+
+from RFEM.initModel import Model, clearAtributes, ConvertToDlString
+from RFEM.enums import SteelMemberLocalSectionReductionType, MultipleOffsetDefinitionType, FastenerDefinitionType
+
+class SteelMemberLocalSectionReduction():
+
+    def __init__(self,
+                 no: int = 1,
+                 members: str = '1',
+                 member_sets: str = '',
+                 components: list = [
+                    [SteelMemberLocalSectionReductionType.REDUCTION_COMPONENT_TYPE_DESIGN_PARAMETERS, 1.0, False,\
+                     FastenerDefinitionType.DEFINITION_TYPE_ABSOLUTE, 0.5, 2,\
+                     MultipleOffsetDefinitionType.OFFSET_DEFINITION_TYPE_ABSOLUTE, 1.0]
+                                    ],
+                 user_defined_name: str = '',
+                 comment: str = '',
+                 params: dict = None,
+                 model = Model):
+        """
+        Args:
+            no (int): Member Local Section Reduction Tag
+            members (str): Assigned Members
+            member_sets (str): Assigned Member Sets
+            components (list of lists): Components Table Definition
+                components[i][0] (enum): Steel Member Local Section Reduction Type Enumeration
+                components[i][1] (float): Position Value
+                components[i][2] (bool): Enable/Disable Multiple Option
+                components[i][3] (enum): Fastener Definition Type Enumeration
+                for components[i][3] == FastenerDefinitionType.DEFINITION_TYPE_ABSOLUTE
+                    components[i][4] (float): Reduction Area
+                for components[i][3] == FastenerDefinitionType.DEFINITION_TYPE_RELATIVE
+                    components[i][4] (float): Reduction Area Factor (value must be between 0.0 and 1.0)
+                if components[i][2] == True
+                    components[i][5] (int): Multiple Number
+                    components[i][6] (enum): Multiple Offset Definition Type Enumeration
+                    for MultipleOffsetDefinitionType.OFFSET_DEFINITION_TYPE_ABSOLUTE
+                        components[i][7] (float): Multiple Offset Value
+                    for MultipleOffsetDefinitionType.OFFSET_DEFINITION_TYPE_RELATIVE
+                        components[i][7] (float): Multiple Offset Value (value must be between 0.0 and 1.0)
+            user_defined_name (str): User Defined  Member Local Section Reduction Name
+            comment (str): Comments
+            params (dict): Any WS Parameter relevant to the object and its value in form of a dictionary
+            model (RFEM Class, optional): Model to be edited
+        """
+
+        # Client Model | Types For Steel Member Local Section Reduction
+        clientObject = model.clientModel.factory.create('ns0:steel_member_local_section_reduction')
+
+        # Clears object atributes | Sets all atributes to None
+        clearAtributes(clientObject)
+
+        #Local Section Reduction No.
+        clientObject.no = no
+
+        #Local Section Reduction Assigned Members
+        clientObject.members = ConvertToDlString(members)
+
+        #Local Section Reduction Assigned Member Sets
+        clientObject.member_sets = ConvertToDlString(member_sets)
+
+        #Local Section Reduction User defined Name
+        if user_defined_name:
+            clientObject.user_defined_name_enabled = True
+            clientObject.name = user_defined_name
+
+        #Local Section Reduction Components
+        clientObject.components = model.clientModel.factory.create('ns0:array_of_steel_member_local_section_reduction_components')
+
+        for i,j in enumerate(components):
+            smlsr = model.clientModel.factory.create('ns0:steel_member_local_section_reduction_components_row')
+            smlsr.no = i+1
+            smlsr.row.reduction_type = components[i][0].name
+            smlsr.row.position = components[i][1]
+            smlsr.row.multiple = components[i][2]
+            smlsr.row.fastener_definition_type = components[i][3].name
+            if smlsr.row.fastener_definition_type == "DEFINITION_TYPE_ABSOLUTE":
+                smlsr.row.reduction_area = components[i][4]
+            elif smlsr.row.fastener_definition_type == "DEFINITION_TYPE_RELATIVE":
+                smlsr.row.reduction_area_factor = components[i][4]
+            if smlsr.row.multiple:
+                smlsr.row.multiple_number = components[i][5]
+                smlsr.row.multiple_offset_definition_type = components[i][6].name
+                smlsr.row.multiple_offset = components[i][7]
+            else:
+                smlsr.row.multiple_offset_definition_type = None # important
+
+            clientObject.components.steel_member_local_section_reduction_components.append(smlsr)
+
+        # Comment
+        clientObject.comment = comment
+
+        # Adding optional parameters via dictionary
+        if params:
+            for key in params:
+                clientObject[key] = params[key]
+
+        #Add Steel Member Local Section Reduction to Client Model
+        model.clientModel.service.set_steel_member_local_section_reduction(clientObject)
diff --git a/RFEM/enums.py b/RFEM/enums.py
index 7d9b4753..62eab71d 100644
--- a/RFEM/enums.py
+++ b/RFEM/enums.py
@@ -2105,3 +2105,21 @@ class OpeningLoadDirection(Enum):
     Opening Load Direction Type
     '''
     LOAD_DIRECTION_GLOBAL_X_OR_USER_DEFINED_U_PROJECTED, LOAD_DIRECTION_GLOBAL_X_OR_USER_DEFINED_U_TRUE, LOAD_DIRECTION_GLOBAL_Y_OR_USER_DEFINED_V_PROJECTED, LOAD_DIRECTION_GLOBAL_Y_OR_USER_DEFINED_V_TRUE, LOAD_DIRECTION_GLOBAL_Z_OR_USER_DEFINED_W_PROJECTED, LOAD_DIRECTION_GLOBAL_Z_OR_USER_DEFINED_W_TRUE, LOAD_DIRECTION_LOCAL_Z = range(7)
+
+class SteelMemberLocalSectionReductionType(Enum):
+    '''
+    Steel Member Local Section Reduction Type
+    '''
+    REDUCTION_COMPONENT_TYPE_DESIGN_PARAMETERS = range(1)
+
+class FastenerDefinitionType(Enum):
+    '''
+    Steel Member Local Section Reduction Fastener Definition Type
+    '''
+    DEFINITION_TYPE_ABSOLUTE,DEFINITION_TYPE_RELATIVE = range(2)
+
+class MultipleOffsetDefinitionType(Enum):
+    '''
+    Steel Member Local Section Reduction Multiple Offset Definition Type
+    '''
+    OFFSET_DEFINITION_TYPE_ABSOLUTE,OFFSET_DEFINITION_TYPE_RELATIVE = range(2)


Test patch:
diff --git a/UnitTests/test_SteelMemberLocalSectionReduction.py b/UnitTests/test_SteelMemberLocalSectionReduction.py
new file mode 100644
index 00000000..497ff654
--- /dev/null
+++ b/UnitTests/test_SteelMemberLocalSectionReduction.py
@@ -0,0 +1,72 @@
+import os
+import sys
+PROJECT_ROOT = os.path.abspath(os.path.join(
+    os.path.dirname(__file__),
+    os.pardir)
+)
+sys.path.append(PROJECT_ROOT)
+
+from RFEM.enums import SteelMemberLocalSectionReductionType, FastenerDefinitionType, MultipleOffsetDefinitionType
+from RFEM.initModel import Model, CheckIfMethodOrTypeExists
+from RFEM.TypesForSteelDesign.SteelMemberLocalSectionReduction import SteelMemberLocalSectionReduction
+from RFEM.initModel import AddOn, SetAddonStatus
+import pytest
+
+
+if Model.clientModel is None:
+    Model()
+
+
+@pytest.mark.skipif(CheckIfMethodOrTypeExists(Model.clientModel, 'set_model_settings_and_options', True), reason="set_model_settings_and_options not in RFEM GM yet")
+
+def test_SteelMemberLocalSectionReduction():
+
+    Model.clientModel.service.begin_modification()
+
+    SetAddonStatus(Model.clientModel, AddOn.steel_design_active, True)
+
+    SteelMemberLocalSectionReduction(1, "", "",
+        [
+            [SteelMemberLocalSectionReductionType.REDUCTION_COMPONENT_TYPE_DESIGN_PARAMETERS, 1, False, FastenerDefinitionType.DEFINITION_TYPE_ABSOLUTE, 0.2, 0, MultipleOffsetDefinitionType.OFFSET_DEFINITION_TYPE_ABSOLUTE, 0.0]
+        ],
+        "")
+
+    SteelMemberLocalSectionReduction(2, "", "",
+        [
+            [SteelMemberLocalSectionReductionType.REDUCTION_COMPONENT_TYPE_DESIGN_PARAMETERS, 1.2, True, FastenerDefinitionType.DEFINITION_TYPE_ABSOLUTE, 0.1, 2, MultipleOffsetDefinitionType.OFFSET_DEFINITION_TYPE_ABSOLUTE, 2],
+            [SteelMemberLocalSectionReductionType.REDUCTION_COMPONENT_TYPE_DESIGN_PARAMETERS, 2.0, True, FastenerDefinitionType.DEFINITION_TYPE_RELATIVE, 0.20, 3, MultipleOffsetDefinitionType.OFFSET_DEFINITION_TYPE_RELATIVE, 0.1]
+        ],
+        "")
+
+    SteelMemberLocalSectionReduction(3, "", "",
+        [
+            [SteelMemberLocalSectionReductionType.REDUCTION_COMPONENT_TYPE_DESIGN_PARAMETERS, 1.5, False, FastenerDefinitionType.DEFINITION_TYPE_RELATIVE, 0.15, 0, MultipleOffsetDefinitionType.OFFSET_DEFINITION_TYPE_ABSOLUTE, 0.0],
+            [SteelMemberLocalSectionReductionType.REDUCTION_COMPONENT_TYPE_DESIGN_PARAMETERS, 1.8, True, FastenerDefinitionType.DEFINITION_TYPE_RELATIVE, 0.25, 4, MultipleOffsetDefinitionType.OFFSET_DEFINITION_TYPE_ABSOLUTE, 0.3]
+        ], ""
+        )
+
+    smlr_1 = Model.clientModel.service.get_steel_member_local_section_reduction(1)
+    assert smlr_1.components[0][0].row['position'] == 1
+    assert smlr_1.components[0][0].row['multiple'] == False
+    assert smlr_1.components[0][0].row['fastener_definition_type'] == 'DEFINITION_TYPE_ABSOLUTE'
+    assert smlr_1.components[0][0].row['reduction_area'] == 0.2
+
+    smlr_2 = Model.clientModel.service.get_steel_member_local_section_reduction(2)
+    assert smlr_2.components[0][0].row['position'] == 1.2
+    assert smlr_2.components[0][0].row['multiple'] == True
+    assert smlr_2.components[0][1].row['fastener_definition_type'] == 'DEFINITION_TYPE_RELATIVE'
+    assert smlr_2.components[0][1].row['reduction_area_factor'] == 0.20
+    assert smlr_2.components[0][0].row['multiple_offset'] == 2
+
+    smlr_3 = Model.clientModel.service.get_steel_member_local_section_reduction(3)
+    assert smlr_3.components[0][1].row['position'] == 1.8
+    assert smlr_3.components[0][0].row['multiple'] == False
+    assert smlr_3.components[0][1].row['multiple'] == True
+    assert smlr_3.components[0][1].row['multiple_offset_definition_type'] == 'OFFSET_DEFINITION_TYPE_ABSOLUTE'
+    assert smlr_3.components[0][1].row['multiple_offset'] == 0.3
+
+    # assert smlr_1.components[][].row[''] ==
+    # assert Model.clientModel is not None, "WARNING: clientModel is not initialized"
+
+    Model.clientModel.service.finish_modification()
+