# coding: utf-8

"""
    Identity Security Cloud Beta API

    Use these APIs to interact with the Identity Security Cloud platform to achieve repeatable, automated processes with greater scalability. These APIs are in beta and are subject to change. We encourage you to join the SailPoint Developer Community forum at https://developer.sailpoint.com/discuss to connect with other developers using our APIs.

    The version of the OpenAPI document: 3.1.0-beta
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json
import warnings

from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional
from sailpoint.beta.models.approval_comment import ApprovalComment
from sailpoint.beta.models.approval_description import ApprovalDescription
from sailpoint.beta.models.approval_identity import ApprovalIdentity
from sailpoint.beta.models.approval_name import ApprovalName
from sailpoint.beta.models.approval_reference import ApprovalReference
from typing import Optional, Set
from typing_extensions import Self

class Approval(BaseModel):
    """
    Approval Object
    """ # noqa: E501
    approval_id: Optional[StrictStr] = Field(default=None, description="The Approval ID", alias="approvalId")
    approvers: Optional[List[ApprovalIdentity]] = Field(default=None, description="Object representation of an approver of an approval")
    created_date: Optional[StrictStr] = Field(default=None, description="Date the approval was created", alias="createdDate")
    type: Optional[StrictStr] = Field(default=None, description="Type of approval")
    name: Optional[List[ApprovalName]] = Field(default=None, description="The name of the approval for a given locale")
    batch_request: Optional[Dict[str, Any]] = Field(default=None, description="The name of the approval for a given locale", alias="batchRequest")
    description: Optional[List[ApprovalDescription]] = Field(default=None, description="The description of the approval for a given locale")
    priority: Optional[StrictStr] = Field(default=None, description="The priority of the approval")
    requester: Optional[Dict[str, Any]] = Field(default=None, description="Object representation of the requester of the approval")
    comments: Optional[List[ApprovalComment]] = Field(default=None, description="Object representation of a comment on the approval")
    approved_by: Optional[List[ApprovalIdentity]] = Field(default=None, description="Array of approvers who have approved the approval", alias="approvedBy")
    rejected_by: Optional[List[ApprovalIdentity]] = Field(default=None, description="Array of approvers who have rejected the approval", alias="rejectedBy")
    completed_date: Optional[StrictStr] = Field(default=None, description="Date the approval was completed", alias="completedDate")
    approval_criteria: Optional[StrictStr] = Field(default=None, description="Criteria that needs to be met for an approval to be marked as approved", alias="approvalCriteria")
    status: Optional[StrictStr] = Field(default=None, description="The current status of the approval")
    additional_attributes: Optional[StrictStr] = Field(default=None, description="Json string representing additional attributes known about the object to be approved.", alias="additionalAttributes")
    reference_data: Optional[List[ApprovalReference]] = Field(default=None, description="Reference data related to the approval", alias="referenceData")
    __properties: ClassVar[List[str]] = ["approvalId", "approvers", "createdDate", "type", "name", "batchRequest", "description", "priority", "requester", "comments", "approvedBy", "rejectedBy", "completedDate", "approvalCriteria", "status", "additionalAttributes", "referenceData"]

    @field_validator('priority')
    def priority_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['HIGH', 'MEDIUM', 'LOW']):
            warnings.warn(f"must be one of enum values ('HIGH', 'MEDIUM', 'LOW') unknown value: {value}")
        return value

    @field_validator('approval_criteria')
    def approval_criteria_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['SINGLE', 'DOUBLE', 'TRIPLE', 'QUARTER', 'HALF', 'ALL']):
            warnings.warn(f"must be one of enum values ('SINGLE', 'DOUBLE', 'TRIPLE', 'QUARTER', 'HALF', 'ALL') unknown value: {value}")
        return value

    @field_validator('status')
    def status_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['PENDING', 'APPROVED', 'REJECTED']):
            warnings.warn(f"must be one of enum values ('PENDING', 'APPROVED', 'REJECTED') unknown value: {value}")
        return value

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of Approval from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of each item in approvers (list)
        _items = []
        if self.approvers:
            for _item_approvers in self.approvers:
                if _item_approvers:
                    _items.append(_item_approvers.to_dict())
            _dict['approvers'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in name (list)
        _items = []
        if self.name:
            for _item_name in self.name:
                if _item_name:
                    _items.append(_item_name.to_dict())
            _dict['name'] = _items
        # override the default output from pydantic by calling `to_dict()` of batch_request
        if self.batch_request:
            _dict['batchRequest'] = self.batch_request.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in description (list)
        _items = []
        if self.description:
            for _item_description in self.description:
                if _item_description:
                    _items.append(_item_description.to_dict())
            _dict['description'] = _items
        # override the default output from pydantic by calling `to_dict()` of requester
        if self.requester:
            _dict['requester'] = self.requester.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in comments (list)
        _items = []
        if self.comments:
            for _item_comments in self.comments:
                if _item_comments:
                    _items.append(_item_comments.to_dict())
            _dict['comments'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in approved_by (list)
        _items = []
        if self.approved_by:
            for _item_approved_by in self.approved_by:
                if _item_approved_by:
                    _items.append(_item_approved_by.to_dict())
            _dict['approvedBy'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in rejected_by (list)
        _items = []
        if self.rejected_by:
            for _item_rejected_by in self.rejected_by:
                if _item_rejected_by:
                    _items.append(_item_rejected_by.to_dict())
            _dict['rejectedBy'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in reference_data (list)
        _items = []
        if self.reference_data:
            for _item_reference_data in self.reference_data:
                if _item_reference_data:
                    _items.append(_item_reference_data.to_dict())
            _dict['referenceData'] = _items
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of Approval from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "approvalId": obj.get("approvalId"),
            "approvers": [ApprovalIdentity.from_dict(_item) for _item in obj["approvers"]] if obj.get("approvers") is not None else None,
            "createdDate": obj.get("createdDate"),
            "type": obj.get("type"),
            "name": [ApprovalName.from_dict(_item) for _item in obj["name"]] if obj.get("name") is not None else None,
            "batchRequest": ApprovalBatch.from_dict(obj["batchRequest"]) if obj.get("batchRequest") is not None else None,
            "description": [ApprovalDescription.from_dict(_item) for _item in obj["description"]] if obj.get("description") is not None else None,
            "priority": obj.get("priority"),
            "requester": ApprovalIdentity.from_dict(obj["requester"]) if obj.get("requester") is not None else None,
            "comments": [ApprovalComment.from_dict(_item) for _item in obj["comments"]] if obj.get("comments") is not None else None,
            "approvedBy": [ApprovalIdentity.from_dict(_item) for _item in obj["approvedBy"]] if obj.get("approvedBy") is not None else None,
            "rejectedBy": [ApprovalIdentity.from_dict(_item) for _item in obj["rejectedBy"]] if obj.get("rejectedBy") is not None else None,
            "completedDate": obj.get("completedDate"),
            "approvalCriteria": obj.get("approvalCriteria"),
            "status": obj.get("status"),
            "additionalAttributes": obj.get("additionalAttributes"),
            "referenceData": [ApprovalReference.from_dict(_item) for _item in obj["referenceData"]] if obj.get("referenceData") is not None else None
        })
        return _obj


