From 8394bc31db673a4e43913b2dd5df3a736feb9e51 Mon Sep 17 00:00:00 2001
From: Stanislav Pankevich <s.pankevich@gmail.com>
Date: Fri, 29 Dec 2023 13:34:00 +0100
Subject: [PATCH] export/html: requirement_form_object: simplify MID field
 factory method

---
 .../form_objects/requirement_form_object.py   | 50 +++++++++++--------
 strictdoc/server/routers/main_router.py       |  8 +++
 2 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/strictdoc/export/html/form_objects/requirement_form_object.py b/strictdoc/export/html/form_objects/requirement_form_object.py
index 66171ee32..b6e908a76 100644
--- a/strictdoc/export/html/form_objects/requirement_form_object.py
+++ b/strictdoc/export/html/form_objects/requirement_form_object.py
@@ -88,7 +88,7 @@ def create_from_grammar_field(
         multiline: bool,
         value_unescaped: str,
         value_escaped: str,
-    ):
+    ) -> "RequirementFormField":
         assert isinstance(value_unescaped, str), (
             grammar_field,
             multiline,
@@ -116,7 +116,7 @@ def create_existing_from_grammar_field(
         grammar_field: GrammarElementField,
         multiline: bool,
         requirement_field: RequirementField,
-    ):
+    ) -> "RequirementFormField":
         if grammar_field.gef_type == RequirementFieldType.STRING:
             field_value = (
                 requirement_field.field_value_multiline
@@ -136,6 +136,16 @@ def create_existing_from_grammar_field(
             )
         raise NotImplementedError(grammar_field)
 
+    @staticmethod
+    def create_mid_field(mid: MID) -> "RequirementFormField":
+        return RequirementFormField(
+            field_mid=MID.create().get_string_value(),
+            field_name="MID",
+            field_type=RequirementFormFieldType.SINGLELINE,
+            field_unescaped_value=mid.get_string_value(),
+            field_escaped_value=html.escape(mid.get_string_value()),
+        )
+
 
 @auto_described
 class RequirementReferenceFormField:
@@ -176,6 +186,7 @@ class RequirementFormObject(ErrorObject):
     def __init__(
         self,
         *,
+        is_new: bool,
         requirement_mid: Optional[str],
         document_mid: str,
         mid_field: Optional[RequirementFormField],
@@ -187,6 +198,7 @@ def __init__(
         relation_types: List[str],
     ):
         super().__init__()
+        self.is_new: bool = is_new
         self.requirement_mid: Optional[str] = requirement_mid
         self.document_mid: str = document_mid
         self.mid_field: Optional[RequirementFormField] = mid_field
@@ -204,6 +216,7 @@ def __init__(
     @staticmethod
     def create_from_request(
         *,
+        is_new: bool,
         requirement_mid: str,
         request_form_data: FormData,
         document: Document,
@@ -275,12 +288,10 @@ def create_from_request(
                 sanitized_field_value: str = sanitize_html_form_field(
                     requirement_field_value, multiline=False
                 )
-                mid_field = RequirementFormField(
-                    field_mid=MID.create().get_string_value(),
-                    field_name="MID",
-                    field_type=RequirementFormFieldType.SINGLELINE,
-                    field_unescaped_value=sanitized_field_value,
-                    field_escaped_value=html.escape(sanitized_field_value),
+                mid_field: RequirementFormField = (
+                    RequirementFormField.create_mid_field(
+                        MID(sanitized_field_value)
+                    )
                 )
 
                 # This is where the original requirement MID auto-generated
@@ -320,6 +331,7 @@ def create_from_request(
                 form_fields.append(form_field)
 
         form_object = RequirementFormObject(
+            is_new=is_new,
             requirement_mid=requirement_mid,
             document_mid=document.reserved_mid.get_string_value(),
             mid_field=mid_field,
@@ -344,12 +356,8 @@ def create_new(
 
         mid_field: Optional[RequirementFormField] = None
         if document.config.enable_mid:
-            mid_field = RequirementFormField(
-                field_mid=MID.create().get_string_value(),
-                field_name="MID",
-                field_type=RequirementFormFieldType.SINGLELINE,
-                field_unescaped_value=new_requirement_mid.get_string_value(),
-                field_escaped_value=new_requirement_mid.get_string_value(),
+            mid_field: RequirementFormField = (
+                RequirementFormField.create_mid_field(new_requirement_mid)
             )
         form_fields: List[RequirementFormField] = []
 
@@ -375,6 +383,7 @@ def create_new(
                 form_field.field_escaped_value = next_uid
 
         return RequirementFormObject(
+            is_new=True,
             requirement_mid=new_requirement_mid.get_string_value(),
             document_mid=document.reserved_mid.get_string_value(),
             mid_field=mid_field,
@@ -398,12 +407,8 @@ def create_from_requirement(
 
         mid_field: Optional[RequirementFormField] = None
         if document.config.enable_mid:
-            mid_field = RequirementFormField(
-                field_mid=MID.create().get_string_value(),
-                field_name="MID",
-                field_type=RequirementFormFieldType.SINGLELINE,
-                field_unescaped_value=requirement.reserved_mid.get_string_value(),
-                field_escaped_value=requirement.reserved_mid.get_string_value(),
+            mid_field: RequirementFormField = (
+                RequirementFormField.create_mid_field(requirement.reserved_mid)
             )
 
         grammar_element_relations = element.get_relation_types()
@@ -481,6 +486,7 @@ def create_from_requirement(
                         )
                         form_refs_fields.append(form_ref_field)
         return RequirementFormObject(
+            is_new=False,
             requirement_mid=requirement.reserved_mid.get_string_value(),
             document_mid=document.reserved_mid.get_string_value(),
             mid_field=mid_field,
@@ -595,7 +601,7 @@ def validate(
         assert isinstance(traceability_index, TraceabilityIndex)
         assert isinstance(context_document, Document)
 
-        if self.mid_field is not None:
+        if self.is_new and self.mid_field is not None:
             existing_node_with_this_mid = (
                 traceability_index.get_node_by_mid_weak(
                     MID(self.mid_field.field_unescaped_value)
@@ -607,7 +613,7 @@ def validate(
                     (
                         f"A node with this MID already exists, "
                         "please select another MID: "
-                        f"{self.mid_field.field_unescaped_value}.",
+                        f"{self.mid_field.field_unescaped_value}."
                     ),
                 )
 
diff --git a/strictdoc/server/routers/main_router.py b/strictdoc/server/routers/main_router.py
index 3d37d105a..0a9ac3324 100644
--- a/strictdoc/server/routers/main_router.py
+++ b/strictdoc/server/routers/main_router.py
@@ -811,6 +811,7 @@ async def create_requirement(request: Request):
             MID(document_mid)
         )
         form_object = RequirementFormObject.create_from_request(
+            is_new=True,
             requirement_mid=requirement_mid,
             request_form_data=request_form_data,
             document=document,
@@ -1062,6 +1063,7 @@ async def document__update_requirement(request: Request):
 
         form_object: RequirementFormObject = (
             RequirementFormObject.create_from_request(
+                is_new=False,
                 requirement_mid=requirement_mid,
                 request_form_data=request_form_data,
                 document=document,
@@ -1741,9 +1743,12 @@ def document__add_comment(requirement_mid: str, document_mid: str):
             "add_requirement_comment/"
             "stream_add_requirement_comment.jinja.html"
         )
+        # The data of the form object is ignored. What matters is the comment
+        # form data.
         output = template.render(
             requirement_mid=requirement_mid,
             form_object=RequirementFormObject(
+                is_new=False,
                 requirement_mid=requirement_mid,
                 document_mid=document.reserved_mid.get_string_value(),
                 mid_field=None,
@@ -1786,9 +1791,12 @@ def document__add_relation(requirement_mid: str, document_mid: str):
             "add_requirement_relation/"
             "stream_add_requirement_relation.jinja.html"
         )
+        # The data of the form object is ignored. What matters is the relation
+        # form data.
         output = template.render(
             requirement_mid=requirement_mid,
             form_object=RequirementFormObject(
+                is_new=False,
                 requirement_mid=requirement_mid,
                 document_mid=document_mid,
                 mid_field=None,