File size: 5,354 Bytes
70cbb67
03c5ce9
d4a81ac
1b36ca3
d4a81ac
 
 
 
03c5ce9
 
 
8a15af8
d4a81ac
03c5ce9
 
3a4c52b
 
 
 
179904f
d4a81ac
3a4c52b
 
 
 
 
 
 
d4a81ac
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8a15af8
03c5ce9
 
 
 
 
d4a81ac
03c5ce9
 
 
 
 
d4a81ac
03c5ce9
8a15af8
f43a395
24a5104
8abafca
24a5104
8a15af8
24a5104
8a15af8
24a5104
8a15af8
 
 
24a5104
8a15af8
 
 
03c5ce9
 
 
 
 
 
d4a81ac
03c5ce9
 
 
 
 
 
d4a81ac
 
 
03c5ce9
 
d4a81ac
 
 
 
 
 
 
 
 
 
 
 
03c5ce9
1be54f0
03c5ce9
1be54f0
 
 
 
d4a81ac
1be54f0
03c5ce9
d4a81ac
03c5ce9
d4a81ac
 
 
 
 
 
 
 
8d9e16c
d4a81ac
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
from ..tool_utils import *


class EditOrCreateRecordAttributeSchema(CommonAttributeFields):
    related_template_system_name: Optional[str] = Field(
        default=None,
        description="System name of the template to link with the attribute. For edit operations, leave empty to preserve current link."
        "RU: Связанный шаблон",
    )
    related_attribute_system_name: Optional[str] = Field(
        default=None,
        description="System name of a record attribute in the related template to back-link with the current attribute. "
        "RU: Взаимная связь с атрибутом",
    )

    @field_validator("related_template_system_name", mode="before")
    def non_empty_str(cls, v: Any) -> Any:
        """
        Validate that string fields are not empty.

        This field validator is automatically applied to the name, system_name,
        application_system_name, and template_system_name fields in all schemas
        that inherit from CommonAttributeFields, ensuring consistent validation.
        """
        if isinstance(v, str) and v.strip() == "":
            raise ValueError("must be a non-empty string")
        return v

    @model_validator(mode="after")
    def _validate_create_required_fields(self) -> "EditOrCreateRecordAttributeSchema":
        """
        Validate that required fields are provided for create operations.

        When operation is 'create', the following fields are REQUIRED:
            - related_template_system_name: The template to link with the attribute

        When operation is 'edit', all fields are OPTIONAL - the tool will
        fetch current values from the API for any missing fields.
        """
        if self.operation == "create":
            if self.related_template_system_name is None:
                raise ValueError(
                    "related_template_system_name is REQUIRED when operation='create'. "
                    "Specify the template system name to link (e.g., 'Tasks', 'Clients'). "
                    "For edit operations, this field is optional."
                )
        return self


@tool(
    "edit_or_create_record_attribute",
    return_direct=False,
    args_schema=EditOrCreateRecordAttributeSchema,
)
def edit_or_create_record_attribute(
    operation: str,
    name: str,
    system_name: str,
    application_system_name: str,
    template_system_name: str,
    related_template_system_name: Optional[str] = None,
    description: Optional[str] = None,
    write_changes_to_the_log: Optional[bool] = False,
    calculate_value: Optional[bool] = False,
    expression_for_calculation: Optional[str] = None,
    store_multiple_values: Optional[bool] = False,
    related_attribute_system_name: Optional[str] = None,
) -> Dict[str, Any]:
    """
    Edit or Create a record attribute (Запись, коллекция).

    Record attribute is is linked to records in a related template.

    Record attribute stores one or several IDs of the lined records in the related template.

    Record attribute can be mutually linked with the attribute in the related template. Mutually linked attributes are automatically cross-linked whenever the values of one of the attributes change.

    Returns:
        dict: {
            "success": bool - True if the attribute was created or edited successfully
            "status_code": int - HTTP response status code
            "raw_response": dict|str|None - Raw response for auditing or payload body (sanitized)
            "error": str|None - Error message if operation failed
        }
    """

    request_body: Dict[str, Any] = {
        "globalAlias": {
            "owner": template_system_name,
            "type": "Undefined",
            "alias": system_name,
        },
        "type": "Instance",
        "name": name,
        "description": description,
        "isTracked": write_changes_to_the_log,
        "isMultiValue": store_multiple_values,
        "isCalculated": calculate_value
        if expression_for_calculation != None
        else False,
        "expression": expression_for_calculation,
    }
    if related_template_system_name is not None:
        request_body["instanceGlobalAlias"] = {
            "type": "Attribute"
            if related_attribute_system_name != None
            else "RecordTemplate",
            "owner": related_template_system_name
            if related_attribute_system_name != None
            else None,
            "alias": related_attribute_system_name
            if related_attribute_system_name != None
            else related_template_system_name,
        }

    endpoint = f"{ATTRIBUTE_ENDPOINT}/{application_system_name}"

    return execute_edit_or_create_operation(
        request_body=request_body,
        operation=operation,
        endpoint=endpoint,
        result_model=AttributeResult,
    )


if __name__ == "__main__":
    results = edit_or_create_record_attribute.invoke(
        {
            "operation": "create",
            "name": "Related Task",
            "system_name": "RelatedTask",
            "application_system_name": "AItestAndApi",
            "template_system_name": "Test",
            "related_template_system_name": "Task",
            "description": "Related task record",
            "store_multiple_values": False,
        }
    )
    print(results)