# generated by datamodel-codegen:
#   filename:  release-schema.json
#   timestamp: 2023-12-14T08:36:01+00:00

from __future__ import annotations

from datetime import datetime
from enum import Enum
from typing import Any, Dict, List, Optional, Set, Union

from pydantic import AnyUrl, BaseModel, Field, constr


class TagEnum(Enum):
    planning = "planning"
    planningUpdate = "planningUpdate"
    tender = "tender"
    tenderAmendment = "tenderAmendment"
    tenderUpdate = "tenderUpdate"
    tenderCancellation = "tenderCancellation"
    award = "award"
    awardUpdate = "awardUpdate"
    awardCancellation = "awardCancellation"
    contract = "contract"
    contractUpdate = "contractUpdate"
    contractAmendment = "contractAmendment"
    implementation = "implementation"
    implementationUpdate = "implementationUpdate"
    contractTermination = "contractTermination"
    compiled = "compiled"


class InitiationType(Enum):
    tender = "tender"


class Status(Enum):
    planning = "planning"
    planned = "planned"
    active = "active"
    cancelled = "cancelled"
    unsuccessful = "unsuccessful"
    complete = "complete"
    withdrawn = "withdrawn"
    NoneType_None = None


class ProcurementMethod(Enum):
    open = "open"
    selective = "selective"
    limited = "limited"
    direct = "direct"
    NoneType_None = None


class MainProcurementCategory(Enum):
    goods = "goods"
    works = "works"
    services = "services"
    NoneType_None = None


class AwardStatus(Enum):
    pending = "pending"
    active = "active"
    cancelled = "cancelled"
    unsuccessful = "unsuccessful"
    NoneType_None = None


class ContractStatus(Enum):
    pending = "pending"
    active = "active"
    cancelled = "cancelled"
    terminated = "terminated"
    NoneType_None = None


class MilestoneStatus(Enum):
    scheduled = "scheduled"
    met = "met"
    notMet = "notMet"
    partiallyMet = "partiallyMet"
    NoneType_None = None


class Document(BaseModel):
    id: Union[constr(min_length=1), int] = Field(
        ...,
        description="A local, unique identifier for this document. This field is used to keep track of multiple revisions of a document through the compilation from release to record mechanism.",
        title="ID",
    )
    documentType: Optional[str] = Field(
        None,
        description="A classification of the document described, using the open [documentType](https://standard.open-contracting.org/1.1/en/schema/codelists/#document-type) codelist.",
        title="Document type",
    )
    title: Optional[str] = Field(None, description="The document title.", title="Title")
    description: Optional[str] = Field(
        None,
        description="A short description of the document. Descriptions are recommended to not exceed 250 words. In the event the document is not accessible online, the description field can be used to describe arrangements for obtaining a copy of the document.",
        title="Description",
    )
    url: Optional[AnyUrl] = Field(
        None,
        description="A direct link to the document or attachment. The server providing access to this document ought to be configured to correctly report the document mime type.",
        title="URL",
    )
    datePublished: Optional[datetime] = Field(
        None,
        description="The date on which the document was first published. This is particularly important for legally important documents such as notices of a tender.",
        title="Date published",
    )
    dateModified: Optional[datetime] = Field(
        None,
        description="Date that the document was last modified",
        title="Date modified",
    )
    format: Optional[str] = Field(
        None,
        description="The format of the document, using the open [IANA Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml) codelist (see the values in the 'Template' column), or using the 'offline/print' code if the described document is published offline. For example, web pages have a format of 'text/html'.",
        title="Format",
    )
    language: Optional[str] = Field(
        None,
        description="The language of the linked document using either two-letter [ISO639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), or extended [BCP47 language tags](https://www.w3.org/International/articles/language-tags/). The use of lowercase two-letter codes from [ISO639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) is recommended unless there is a clear user need for distinguishing the language subtype.",
        title="Language",
    )


class Change(BaseModel):
    property: Optional[str] = Field(
        None,
        description="The property name that has been changed relative to the place the amendment is. For example if the contract value has changed, then the property under changes within the contract.amendment would be value.amount. (Deprecated in 1.1)",
        title="Property",
    )
    former_value: Optional[Union[str, float, int, List[Any], Dict[str, Any]]] = Field(
        None,
        description="The previous value of the changed property, in whatever type the property is. (Deprecated in 1.1)",
        title="Former Value",
    )


class Amendment(BaseModel):
    date: Optional[datetime] = Field(
        None, description="The date of this amendment.", title="Amendment date"
    )
    rationale: Optional[str] = Field(
        None, description="An explanation for the amendment.", title="Rationale"
    )
    id: Optional[str] = Field(
        None,
        description="An identifier for this amendment: often the amendment number",
        title="ID",
    )
    description: Optional[str] = Field(
        None,
        description="A free text, or semi-structured, description of the changes made in this amendment.",
        title="Description",
    )
    amendsReleaseID: Optional[str] = Field(
        None,
        description="Provide the identifier (release.id) of the OCDS release (from this contracting process) that provides the values for this contracting process **before** the amendment was made.",
        title="Amended release (identifier)",
    )
    releaseID: Optional[str] = Field(
        None,
        description="Provide the identifier (release.id) of the OCDS release (from this contracting process) that provides the values for this contracting process **after** the amendment was made.",
        title="Amending release (identifier)",
    )
    changes: Optional[List[Change]] = Field(
        None,
        description="An array of change objects describing the fields changed, and their former values. (Deprecated in 1.1)",
        title="Amended fields",
    )


class Classification(BaseModel):
    scheme: Optional[str] = Field(
        None,
        description="The scheme or codelist from which the classification code is taken. For line item classifications, this uses the open [itemClassificationScheme](https://standard.open-contracting.org/1.1/en/schema/codelists/#item-classification-scheme) codelist.",
        title="Scheme",
    )
    id: Optional[Union[str, int]] = Field(
        None, description="The classification code taken from the scheme.", title="ID"
    )
    # TODO This needs to implemented. It's currently not used to simplify the schema for KuzuDB.
    # description: Optional[str] = Field(
    #     None,
    #     description="A textual description or title for the classification code.",
    #     title="Description",
    # )
    # uri: Optional[AnyUrl] = Field(
    #     None,
    #     description="A URI to uniquely identify the classification code.",
    #     title="URI",
    # )

    def __hash__(self) -> int:
        return super().__hash__()


class Identifier(BaseModel):
    scheme: Optional[str] = Field(
        None,
        description="Organization identifiers should be taken from an existing organization identifier list. The scheme field is used to indicate the list or register from which the identifier is taken. This value should be taken from the [Organization Identifier Scheme](https://standard.open-contracting.org/1.1/en/schema/codelists/#organization-identifier-scheme) codelist.",
        title="Scheme",
    )
    id: Optional[Union[str, int]] = Field(
        None,
        description="The identifier of the organization in the selected scheme.",
        title="ID",
    )
    legalName: Optional[str] = Field(
        None,
        description="The legally registered name of the organization.",
        title="Legal Name",
    )
    # TODO This needs to implemented; maybe GLEIF can be used?
    # uri: Optional[AnyUrl] = Field(
    #     None,
    #     description="A URI to identify the organization, such as those provided by [Open Corporates](https://opencorporates.com) or some other relevant URI provider. This is not for listing the website of the organization: that can be done through the URL field of the Organization contact point.",
    #     title="URI",
    # )

    def __hash__(self) -> int:
        return super().__hash__()


class Address(BaseModel):
    streetAddress: Optional[str] = Field(
        None,
        description="The street address. For example, 1600 Amphitheatre Pkwy.",
        title="Street address",
    )
    locality: Optional[str] = Field(
        None, description="The locality. For example, Mountain View.", title="Locality"
    )
    region: Optional[str] = Field(
        None, description="The region. For example, CA.", title="Region"
    )
    postalCode: Optional[str] = Field(
        None, description="The postal code. For example, 94043.", title="Postal code"
    )
    countryName: Optional[str] = Field(
        None,
        description="The country name. For example, United States.",
        title="Country name",
    )

    def __hash__(self) -> int:
        return super().__hash__()


class ContactPoint(BaseModel):
    name: Optional[str] = Field(
        None,
        description="The name of the contact person, department, or contact point, for correspondence relating to this contracting process.",
        title="Name",
    )
    email: Optional[str] = Field(
        None,
        description="The e-mail address of the contact point/person.",
        title="Email",
    )
    telephone: Optional[str] = Field(
        None,
        description="The telephone number of the contact point/person. This should include the international dialing code.",
        title="Telephone",
    )
    faxNumber: Optional[str] = Field(
        None,
        description="The fax number of the contact point/person. This should include the international dialing code.",
        title="Fax number",
    )
    # TODO Properly validate URL using AnyUrl
    url: Optional[str] = Field(
        None, description="A web address for the contact point/person.", title="URL"
    )

    def __hash__(self) -> int:
        return super().__hash__()


class Currency(Enum):
    ADP = "ADP"
    AED = "AED"
    AFA = "AFA"
    AFN = "AFN"
    ALK = "ALK"
    ALL = "ALL"
    AMD = "AMD"
    ANG = "ANG"
    AOA = "AOA"
    AOK = "AOK"
    AON = "AON"
    AOR = "AOR"
    ARA = "ARA"
    ARP = "ARP"
    ARS = "ARS"
    ARY = "ARY"
    ATS = "ATS"
    AUD = "AUD"
    AWG = "AWG"
    AYM = "AYM"
    AZM = "AZM"
    AZN = "AZN"
    BAD = "BAD"
    BAM = "BAM"
    BBD = "BBD"
    BDT = "BDT"
    BEC = "BEC"
    BEF = "BEF"
    BEL = "BEL"
    BGJ = "BGJ"
    BGK = "BGK"
    BGL = "BGL"
    BGN = "BGN"
    BHD = "BHD"
    BIF = "BIF"
    BMD = "BMD"
    BND = "BND"
    BOB = "BOB"
    BOP = "BOP"
    BOV = "BOV"
    BRB = "BRB"
    BRC = "BRC"
    BRE = "BRE"
    BRL = "BRL"
    BRN = "BRN"
    BRR = "BRR"
    BSD = "BSD"
    BTN = "BTN"
    BUK = "BUK"
    BWP = "BWP"
    BYB = "BYB"
    BYN = "BYN"
    BYR = "BYR"
    BZD = "BZD"
    CAD = "CAD"
    CDF = "CDF"
    CHC = "CHC"
    CHE = "CHE"
    CHF = "CHF"
    CHW = "CHW"
    CLF = "CLF"
    CLP = "CLP"
    CNY = "CNY"
    COP = "COP"
    COU = "COU"
    CRC = "CRC"
    CSD = "CSD"
    CSJ = "CSJ"
    CSK = "CSK"
    CUC = "CUC"
    CUP = "CUP"
    CVE = "CVE"
    CYP = "CYP"
    CZK = "CZK"
    DDM = "DDM"
    DEM = "DEM"
    DJF = "DJF"
    DKK = "DKK"
    DOP = "DOP"
    DZD = "DZD"
    ECS = "ECS"
    ECV = "ECV"
    EEK = "EEK"
    EGP = "EGP"
    ERN = "ERN"
    ESA = "ESA"
    ESB = "ESB"
    ESP = "ESP"
    ETB = "ETB"
    EUR = "EUR"
    FIM = "FIM"
    FJD = "FJD"
    FKP = "FKP"
    FRF = "FRF"
    GBP = "GBP"
    GEK = "GEK"
    GEL = "GEL"
    GHC = "GHC"
    GHP = "GHP"
    GHS = "GHS"
    GIP = "GIP"
    GMD = "GMD"
    GNE = "GNE"
    GNF = "GNF"
    GNS = "GNS"
    GQE = "GQE"
    GRD = "GRD"
    GTQ = "GTQ"
    GWE = "GWE"
    GWP = "GWP"
    GYD = "GYD"
    HKD = "HKD"
    HNL = "HNL"
    HRD = "HRD"
    HRK = "HRK"
    HTG = "HTG"
    HUF = "HUF"
    IDR = "IDR"
    IEP = "IEP"
    ILP = "ILP"
    ILR = "ILR"
    ILS = "ILS"
    INR = "INR"
    IQD = "IQD"
    IRR = "IRR"
    ISJ = "ISJ"
    ISK = "ISK"
    ITL = "ITL"
    JMD = "JMD"
    JOD = "JOD"
    JPY = "JPY"
    KES = "KES"
    KGS = "KGS"
    KHR = "KHR"
    KMF = "KMF"
    KPW = "KPW"
    KRW = "KRW"
    KWD = "KWD"
    KYD = "KYD"
    KZT = "KZT"
    LAJ = "LAJ"
    LAK = "LAK"
    LBP = "LBP"
    LKR = "LKR"
    LRD = "LRD"
    LSL = "LSL"
    LSM = "LSM"
    LTL = "LTL"
    LTT = "LTT"
    LUC = "LUC"
    LUF = "LUF"
    LUL = "LUL"
    LVL = "LVL"
    LVR = "LVR"
    LYD = "LYD"
    MAD = "MAD"
    MDL = "MDL"
    MGA = "MGA"
    MGF = "MGF"
    MKD = "MKD"
    MLF = "MLF"
    MMK = "MMK"
    MNT = "MNT"
    MOP = "MOP"
    MRO = "MRO"
    MRU = "MRU"
    MTL = "MTL"
    MTP = "MTP"
    MUR = "MUR"
    MVQ = "MVQ"
    MVR = "MVR"
    MWK = "MWK"
    MXN = "MXN"
    MXP = "MXP"
    MXV = "MXV"
    MYR = "MYR"
    MZE = "MZE"
    MZM = "MZM"
    MZN = "MZN"
    NAD = "NAD"
    NGN = "NGN"
    NIC = "NIC"
    NIO = "NIO"
    NLG = "NLG"
    NOK = "NOK"
    NPR = "NPR"
    NZD = "NZD"
    OMR = "OMR"
    PAB = "PAB"
    PEH = "PEH"
    PEI = "PEI"
    PEN = "PEN"
    PES = "PES"
    PGK = "PGK"
    PHP = "PHP"
    PKR = "PKR"
    PLN = "PLN"
    PLZ = "PLZ"
    PTE = "PTE"
    PYG = "PYG"
    QAR = "QAR"
    RHD = "RHD"
    ROK = "ROK"
    ROL = "ROL"
    RON = "RON"
    RSD = "RSD"
    RUB = "RUB"
    RUR = "RUR"
    RWF = "RWF"
    SAR = "SAR"
    SBD = "SBD"
    SCR = "SCR"
    SDD = "SDD"
    SDG = "SDG"
    SDP = "SDP"
    SEK = "SEK"
    SGD = "SGD"
    SHP = "SHP"
    SIT = "SIT"
    SKK = "SKK"
    SLL = "SLL"
    SOS = "SOS"
    SRD = "SRD"
    SRG = "SRG"
    SSP = "SSP"
    STD = "STD"
    STN = "STN"
    SUR = "SUR"
    SVC = "SVC"
    SYP = "SYP"
    SZL = "SZL"
    THB = "THB"
    TJR = "TJR"
    TJS = "TJS"
    TMM = "TMM"
    TMT = "TMT"
    TND = "TND"
    TOP = "TOP"
    TPE = "TPE"
    TRL = "TRL"
    TRY = "TRY"
    TTD = "TTD"
    TWD = "TWD"
    TZS = "TZS"
    UAH = "UAH"
    UAK = "UAK"
    UGS = "UGS"
    UGW = "UGW"
    UGX = "UGX"
    USD = "USD"
    USN = "USN"
    USS = "USS"
    UYI = "UYI"
    UYN = "UYN"
    UYP = "UYP"
    UYU = "UYU"
    UYW = "UYW"
    UZS = "UZS"
    VEB = "VEB"
    VEF = "VEF"
    VES = "VES"
    VNC = "VNC"
    VND = "VND"
    VUV = "VUV"
    WST = "WST"
    XAF = "XAF"
    XAG = "XAG"
    XAU = "XAU"
    XBA = "XBA"
    XBB = "XBB"
    XBC = "XBC"
    XBD = "XBD"
    XCD = "XCD"
    XDR = "XDR"
    XEU = "XEU"
    XFO = "XFO"
    XFU = "XFU"
    XOF = "XOF"
    XPD = "XPD"
    XPF = "XPF"
    XPT = "XPT"
    XRE = "XRE"
    XSU = "XSU"
    XTS = "XTS"
    XUA = "XUA"
    XXX = "XXX"
    YDD = "YDD"
    YER = "YER"
    YUD = "YUD"
    YUM = "YUM"
    YUN = "YUN"
    ZAL = "ZAL"
    ZAR = "ZAR"
    ZMK = "ZMK"
    ZMW = "ZMW"
    ZRN = "ZRN"
    ZRZ = "ZRZ"
    ZWC = "ZWC"
    ZWD = "ZWD"
    ZWL = "ZWL"
    ZWN = "ZWN"
    ZWR = "ZWR"
    NoneType_None = None


class Value(BaseModel):
    amount: Optional[float] = Field(
        None, description="Amount as a number.", title="Amount"
    )
    amountEur: Optional[float] = Field(
        None, description="Amount in Euro if the default amount is in different currency", title="Amount in euro"
    )
    currency: Optional[Currency] = Field(
        None,
        description="The currency of the amount, from the closed [currency](https://standard.open-contracting.org/1.1/en/schema/codelists/#currency) codelist.",
        title="Currency",
    )


class Period(BaseModel):
    startDate: Optional[datetime] = Field(
        None,
        description="The start date for the period. When known, a precise start date must be provided.",
        title="Start date",
    )
    endDate: Optional[datetime] = Field(
        None,
        description="The end date for the period. When known, a precise end date must be provided.",
        title="End date",
    )
    maxExtentDate: Optional[datetime] = Field(
        None,
        description="The period cannot be extended beyond this date. This field can be used to express the maximum available date for extension or renewal of this period.",
        title="Maximum extent",
    )
    durationInDays: Optional[int] = Field(
        None,
        description="The maximum duration of this period in days. A user interface can collect or display this data in months or years as appropriate, and then convert it into days when storing this field. This field can be used when exact dates are not known. If a startDate and endDate are set, this field, if used, should be equal to the difference between startDate and endDate. Otherwise, if a startDate and maxExtentDate are set, this field, if used, should be equal to the difference between startDate and maxExtentDate.",
        title="Duration (days)",
    )


class RelatedProcess(BaseModel):
    id: Optional[str] = Field(
        None,
        description="A local identifier for this relationship, unique within this array.",
        title="Relationship ID",
    )
    relationship: Optional[List[str]] = Field(
        None,
        description="The type of relationship, using the open [relatedProcess](https://standard.open-contracting.org/1.1/en/schema/codelists/#related-process) codelist.",
        title="Relationship",
    )
    title: Optional[str] = Field(
        None,
        description="The title of the related process, where referencing an open contracting process, this field should match the tender/title field in the related process.",
        title="Related process title",
    )
    scheme: Optional[str] = Field(
        None,
        description="The identification scheme used by this cross-reference, using the open [relatedProcessScheme](https://standard.open-contracting.org/1.1/en/schema/codelists/#related-process-scheme) codelist.",
        title="Scheme",
    )
    identifier: Optional[str] = Field(
        None,
        description="The identifier of the related process. If the scheme is 'ocid', this must be an Open Contracting ID (ocid).",
        title="Identifier",
    )
    uri: Optional[AnyUrl] = Field(
        None,
        description="A URI pointing to a machine-readable document, release or record package containing the identified related process.",
        title="Related process URI",
    )

    def __hash__(self):
        return hash(self.id)


class Milestone(BaseModel):
    id: Union[constr(min_length=1), int] = Field(
        ...,
        description="A local identifier for this milestone, unique within this block. This field is used to keep track of multiple revisions of a milestone through the compilation from release to record mechanism.",
        title="ID",
    )
    title: Optional[str] = Field(None, description="Milestone title", title="Title")
    type: Optional[str] = Field(
        None,
        description="The nature of the milestone, using the open [milestoneType](https://standard.open-contracting.org/1.1/en/schema/codelists/#milestone-type) codelist.",
        title="Milestone type",
    )
    description: Optional[str] = Field(
        None, description="A description of the milestone.", title="Description"
    )
    code: Optional[str] = Field(
        None,
        description="Milestone codes can be used to track specific events that take place for a particular kind of contracting process. For example, a code of 'approvalLetter' can be used to allow applications to understand this milestone represents the date an approvalLetter is due or signed.",
        title="Milestone code",
    )
    dueDate: Optional[datetime] = Field(
        None, description="The date the milestone is due.", title="Due date"
    )
    dateMet: Optional[datetime] = Field(
        None, description="The date on which the milestone was met.", title="Date met"
    )
    dateModified: Optional[datetime] = Field(
        None,
        description="The date the milestone was last reviewed or modified and the status was altered or confirmed to still be correct.",
        title="Date modified",
    )
    status: Optional[MilestoneStatus] = Field(
        None,
        description="The status that was realized on the date provided in `dateModified`, from the closed [milestoneStatus](https://standard.open-contracting.org/1.1/en/schema/codelists/#milestone-status) codelist.",
        title="Status",
    )
    documents: Optional[Set[Document]] = Field(
        None,
        description="List of documents associated with this milestone (Deprecated in 1.1).",
        title="Documents",
    )


class Budget(BaseModel):
    id: Optional[Union[str, int]] = Field(
        None,
        description="An identifier for the budget line item which provides funds for this contracting process. This identifier should be possible to cross-reference against the provided data source.",
        title="ID",
    )
    description: Optional[str] = Field(
        None,
        description="A short free text description of the budget source. May be used to provide the title of the budget line, or the programme used to fund this project.",
        title="Budget Source",
    )
    amount: Optional[Value] = Field(
        None,
        description="The value reserved in the budget for this contracting process. A negative value indicates anticipated income to the budget as a result of this contracting process, rather than expenditure. Where the budget is drawn from multiple sources, the budget breakdown extension can be used.",
        title="Amount",
    )
    project: Optional[str] = Field(
        None,
        description="The name of the project through which this contracting process is funded (if applicable). Some organizations maintain a registry of projects, and the data should use the name by which the project is known in that registry. No translation option is offered for this string, as translated values can be provided in third-party data, linked from the data source above.",
        title="Project title",
    )
    projectID: Optional[Union[str, int]] = Field(
        None,
        description="An external identifier for the project that this contracting process forms part of, or is funded via (if applicable). Some organizations maintain a registry of projects, and the data should use the identifier from the relevant registry of projects.",
        title="Project identifier",
    )
    uri: Optional[AnyUrl] = Field(
        None,
        description="A URI pointing directly to a machine-readable record about the budget line-item or line-items that fund this contracting process. Information can be provided in a range of formats, including using IATI, the Open Fiscal Data Standard or any other standard which provides structured data on budget sources. Human readable documents can be included using the planning.documents block.",
        title="Linked budget information",
    )
    source: Optional[AnyUrl] = Field(
        None,
        description="(Deprecated in 1.1) Used to point either to a corresponding Budget Data Package, or to a machine or human-readable source where users can find further information on the budget line item identifiers, or project identifiers, provided here.",
        title="Data Source",
    )


class Organization(BaseModel):
    name: Optional[str] = Field(
        None,
        description="A common name for this organization or other participant in the contracting process. The identifier object provides a space for the formal legal name, and so this may either repeat that value, or may provide the common name by which this organization or entity is known. This field may also include details of the department or sub-unit involved in this contracting process.",
        title="Common name",
    )
    id: Optional[str] = Field(
        None,
        description="The ID used for cross-referencing to this party from other sections of the release. This field may be built with the following structure {identifier.scheme}-{identifier.id}(-{department-identifier}).",
        title="Entity ID",
    )
    identifier: Optional[Identifier] = Field(
        None,
        description="The primary identifier for this organization or participant. Identifiers that uniquely pick out a legal entity should be preferred. Consult the [organization identifier guidance](https://standard.open-contracting.org/1.1/en/schema/identifiers/) for the preferred scheme and identifier to use.",
        title="Primary identifier",
    )
    additionalIdentifiers: Optional[Set[Identifier]] = Field(
        None,
        description="A list of additional / supplemental identifiers for the organization or participant, using the [organization identifier guidance](https://standard.open-contracting.org/1.1/en/schema/identifiers/). This can be used to provide an internally used identifier for this organization in addition to the primary legal entity identifier.",
        title="Additional identifiers",
    )
    address: Optional[Address] = Field(
        None,
        description="An address. This may be the legally registered address of the organization, or may be a correspondence address for this particular contracting process.",
        title="Address",
    )
    contactPoint: Optional[ContactPoint] = Field(
        None,
        description="Contact details that can be used for this party.",
        title="Contact point",
    )
    roles: Optional[List[str]] = Field(
        None,
        description="The party's role(s) in the contracting process, using the open [partyRole](https://standard.open-contracting.org/1.1/en/schema/codelists/#party-role) codelist.",
        title="Party roles",
    )
    details: Optional[Dict[str, Any]] = Field(
        None,
        description="Additional classification information about parties can be provided using partyDetail extensions that define particular fields and classification schemes.",
        title="Details",
    )

    def __hash__(self):
        return hash(self.id)


class Unit(BaseModel):
    scheme: Optional[str] = Field(
        None,
        description="The list from which identifiers for units of measure are taken, using the open [unitClassificationScheme](https://standard.open-contracting.org/1.1/en/schema/codelists/#unit-classification-scheme) codelist. 'UNCEFACT' is recommended.",
        title="Scheme",
    )
    id: Optional[str] = Field(
        None,
        description="The identifier from the codelist referenced in the `scheme` field. Check the [unitClassificationScheme](https://standard.open-contracting.org/1.1/en/schema/codelists/#unit-classification-scheme) codelist for details of how to find and use identifiers from the scheme in use.",
        title="ID",
    )
    name: Optional[str] = Field(None, description="Name of the unit.", title="Name")
    value: Optional[Value] = Field(
        None, description="The monetary value of a single unit.", title="Value"
    )
    uri: Optional[AnyUrl] = Field(
        None,
        description="The machine-readable URI for the unit of measure, provided by the scheme.",
        title="URI",
    )


class Item(BaseModel):
    id: Union[constr(min_length=1), int] = Field(
        ...,
        description="A local identifier to reference and merge the items by. Must be unique within a given array of items.",
        title="ID",
    )
    description: Optional[str] = Field(
        None,
        description="A description of the goods, services to be provided.",
        title="Description",
    )
    classification: Optional[Classification] = Field(
        None,
        description="The primary classification for the item.",
        title="Classification",
    )
    additionalClassifications: Optional[Set[Classification]] = Field(
        None,
        description="An array of additional classifications for the item.",
        title="Additional classifications",
    )
    quantity: Optional[float] = Field(
        None, description="The number of units to be provided.", title="Quantity"
    )
    unit: Optional[Unit] = Field(
        None,
        description="A description of the unit in which the supplies, services or works are provided (e.g. hours, kilograms) and the unit-price.",
        title="Unit",
    )


class Planning(BaseModel):
    rationale: Optional[str] = Field(
        None,
        description="The rationale for the procurement provided in free text. More detail can be provided in an attached document.",
        title="Rationale",
    )
    budget: Optional[Budget] = Field(
        None,
        description="Details of the budget that funds this contracting process.",
        title="Budget",
    )
    documents: Optional[List[Document]] = Field(
        None,
        description="A list of documents related to the planning process.",
        title="Documents",
    )
    milestones: Optional[List[Milestone]] = Field(
        None,
        description="A list of milestones associated with the planning stage.",
        title="Planning milestones",
    )


class Tender(BaseModel):
    id: Union[constr(min_length=1), int] = Field(
        ...,
        description="An identifier for this tender process. This may be the same as the ocid, or may be an internal identifier for this tender.",
        title="Tender ID",
    )
    title: Optional[str] = Field(
        None,
        description="A title for this tender. This will often be used by applications as a headline to attract interest, and to help analysts understand the nature of this procurement.",
        title="Tender title",
    )
    description: Optional[str] = Field(
        None,
        description="A summary description of the tender. This complements any structured information provided using the items array. Descriptions should be short and easy to read. Avoid using ALL CAPS.",
        title="Tender description",
    )
    status: Optional[Status] = Field(
        None,
        description="The current status of the tender, from the closed [tenderStatus](https://standard.open-contracting.org/1.1/en/schema/codelists/#tender-status) codelist.",
        title="Tender status",
    )
    procuringEntity: Optional[Organization] = Field(
        None,
        description="The entity managing the procurement. This may be different from the buyer who pays for, or uses, the items being procured.",
        title="Procuring entity",
    )
    items: Optional[Set[Item]] = Field(
        None,
        description="The goods and services to be purchased, broken into line items wherever possible. Items should not be duplicated, but the quantity specified instead.",
        title="Items to be procured",
    )
    value: Optional[Value] = Field(
        None,
        description="The total upper estimated value of the procurement. A negative value indicates that the contracting process may involve payments from the supplier to the buyer (commonly used in concession contracts).",
        title="Value",
    )
    minValue: Optional[Value] = Field(
        None,
        description="The minimum estimated value of the procurement.  A negative value indicates that the contracting process may involve payments from the supplier to the buyer (commonly used in concession contracts).",
        title="Minimum value",
    )
    procurementMethod: Optional[ProcurementMethod] = Field(
        None,
        description="The procurement method, from the closed [method](https://standard.open-contracting.org/1.1/en/schema/codelists/#method) codelist.",
        title="Procurement method",
    )
    procurementMethodDetails: Optional[str] = Field(
        None,
        description="Additional detail on the procurement method used. This field can be used to provide the local name of the particular procurement method used.",
        title="Procurement method details",
    )
    procurementMethodRationale: Optional[str] = Field(
        None,
        description="Rationale for the chosen procurement method. This is especially important to provide a justification in the case of limited tenders or direct awards.",
        title="Procurement method rationale",
    )
    mainProcurementCategory: Optional[MainProcurementCategory] = Field(
        None,
        description="The primary category describing the main object of this contracting process, from the closed [procurementCategory](https://standard.open-contracting.org/1.1/en/schema/codelists/#procurement-category) codelist.",
        title="Main procurement category",
    )
    additionalProcurementCategories: Optional[List[str]] = Field(
        None,
        description="Any additional categories describing the objects of this contracting process, using the open [extendedProcurementCategory](https://standard.open-contracting.org/1.1/en/schema/codelists/#extended-procurement-category) codelist.",
        title="Additional procurement categories",
    )
    awardCriteria: Optional[str] = Field(
        None,
        description="The award criteria for the procurement, using the open [awardCriteria](https://standard.open-contracting.org/1.1/en/schema/codelists/#award-criteria) codelist.",
        title="Award criteria",
    )
    awardCriteriaDetails: Optional[str] = Field(
        None,
        description="Any detailed or further information on the award or selection criteria.",
        title="Award criteria details",
    )
    submissionMethod: Optional[List[str]] = Field(
        None,
        description="The methods by which bids are submitted, using the open [submissionMethod](https://standard.open-contracting.org/1.1/en/schema/codelists/#submission-method) codelist.",
        title="Submission method",
    )
    submissionMethodDetails: Optional[str] = Field(
        None,
        description="Any detailed or further information on the submission method. This can include the address, e-mail address or online service to which bids are submitted, and any special requirements to be followed for submissions.",
        title="Submission method details",
    )
    tenderPeriod: Optional[Period] = Field(
        None,
        description="The period when the tender is open for submissions. The end date is the closing date for tender submissions.",
        title="Tender period",
    )
    enquiryPeriod: Optional[Period] = Field(
        None,
        description="The period during which potential bidders may submit questions and requests for clarification to the entity managing procurement. Details of how to submit enquiries should be provided in attached notices, or in submissionMethodDetails. Structured dates for when responses to questions will be made can be provided using tender milestones.",
        title="Enquiry period",
    )
    hasEnquiries: Optional[bool] = Field(
        None,
        description="A true/false field to indicate whether any enquiries were received during the tender process. Structured information on enquiries that were received, and responses to them, can be provided using the enquiries extension.",
        title="Has enquiries?",
    )
    eligibilityCriteria: Optional[str] = Field(
        None,
        description="A description of any eligibility criteria for potential suppliers.",
        title="Eligibility criteria",
    )
    awardPeriod: Optional[Period] = Field(
        None,
        description="The period for decision making regarding the contract award. The end date should be the date on which an award decision is due to be finalized. The start date may be used to indicate the start of an evaluation period.",
        title="Evaluation and award period",
    )
    contractPeriod: Optional[Period] = Field(
        None,
        description="The period over which the contract is estimated or required to be active. If the tender does not specify explicit dates, the duration field may be used.",
        title="Contract period",
    )
    numberOfTenderers: Optional[int] = Field(
        None,
        description="The number of parties who submit a bid.",
        title="Number of tenderers",
    )
    tenderers: Optional[Set[Organization]] = Field(
        None,
        description="All parties who submit a bid on a tender. More detailed information on bids and the bidding organization can be provided using the bid extension.",
        title="Tenderers",
    )
    documents: Optional[List[Document]] = Field(
        None,
        description="All documents and attachments related to the tender, including any notices. See the [documentType](https://standard.open-contracting.org/1.1/en/schema/codelists/#document-type) codelist for details of potential documents to include. Common documents include official legal notices of tender, technical specifications, evaluation criteria, and, as a tender process progresses, clarifications and replies to queries.",
        title="Documents",
    )
    milestones: Optional[List[Milestone]] = Field(
        None,
        description="A list of milestones associated with the tender.",
        title="Milestones",
    )
    amendments: Optional[List[Amendment]] = Field(
        None,
        description="A tender amendment is a formal change to the tender, and generally involves the publication of a new tender notice/release. The rationale and a description of the changes made can be provided here.",
        title="Amendments",
    )
    amendment: Optional[Amendment] = Field(
        None,
        description="The use of individual amendment objects has been deprecated. From OCDS 1.1 information should be provided in the amendments array.",
        title="Amendment",
    )
    # Extensions
    crossBorderLaw: Optional[str] = Field(
        None, description="Cross border law", title="Cross border law"
    )
    classification: Optional[Classification] = Field(
        None, description="Tender classification", title="Classification"
    )

    def __hash__(self):
        return hash(self.id)


class Award(BaseModel):
    id: Union[constr(min_length=1), int] = Field(
        ...,
        description="The identifier for this award. It must be unique and must not change within the Open Contracting Process it is part of (defined by a single ocid). See the [identifier guidance](https://standard.open-contracting.org/1.1/en/schema/identifiers/) for further details.",
        title="Award ID",
    )
    title: Optional[str] = Field(None, description="Award title", title="Title")
    description: Optional[str] = Field(
        None, description="Award description", title="Description"
    )
    status: Optional[AwardStatus] = Field(
        None,
        description="The current status of the award, from the closed [awardStatus](https://standard.open-contracting.org/1.1/en/schema/codelists/#award-status) codelist.",
        title="Award status",
    )
    date: Optional[datetime] = Field(
        None,
        description="The date of the contract award. This is usually the date on which a decision to award was made.",
        title="Award date",
    )
    value: Optional[Value] = Field(
        None,
        description="The total value of this award. In the case of a framework contract this may be the total estimated lifetime value, or maximum value, of the agreement. There may be more than one award per procurement. A negative value indicates that the award may involve payments from the supplier to the buyer (commonly used in concession contracts).",
        title="Value",
    )
    suppliers: Optional[Set[Organization]] = Field(
        None,
        description="The suppliers awarded this award. If different suppliers have been awarded different items or values, these should be split into separate award blocks.",
        title="Suppliers",
    )
    items: Optional[Set[Item]] = Field(
        None,
        description="The goods and services awarded in this award, broken into line items wherever possible. Items should not be duplicated, but the quantity specified instead.",
        min_items=1,
        title="Items awarded",
    )
    contractPeriod: Optional[Period] = Field(
        None,
        description="The period for which the contract has been awarded.",
        title="Contract period",
    )
    documents: Optional[Set[Document]] = Field(
        None,
        description="All documents and attachments related to the award, including any notices.",
        title="Documents",
    )
    amendments: Optional[List[Amendment]] = Field(
        None,
        description="An award amendment is a formal change to the details of the award, and generally involves the publication of a new award notice/release. The rationale and a description of the changes made can be provided here.",
        title="Amendments",
    )
    amendment: Optional[Amendment] = Field(
        None,
        description="The use of individual amendment objects has been deprecated. From OCDS 1.1 information should be provided in the amendments array.",
        title="Amendment",
    )

    def __hash__(self):
        return hash(self.id)


class Transaction(BaseModel):
    id: Union[constr(min_length=1), int] = Field(
        ...,
        description="A unique identifier for this transaction. This identifier should be possible to cross-reference against the provided data source. For IATI this is the transaction reference.",
        title="ID",
    )
    source: Optional[AnyUrl] = Field(
        None,
        description="Used to point either to a corresponding Fiscal Data Package, IATI file, or machine or human-readable source where users can find further information on the budget line item identifiers, or project identifiers, provided here.",
        title="Data source",
    )
    date: Optional[datetime] = Field(
        None, description="The date of the transaction", title="Date"
    )
    value: Optional[Value] = Field(
        None, description="The value of the transaction.", title="Value"
    )
    payer: Optional[Organization] = Field(
        None,
        description="An organization reference for the organization from which the funds in this transaction originate.",
        title="Payer",
    )
    payee: Optional[Organization] = Field(
        None,
        description="An organization reference for the organization which receives the funds in this transaction.",
        title="Payee",
    )
    uri: Optional[AnyUrl] = Field(
        None,
        description="A URI pointing directly to a machine-readable record about this spending transaction.",
        title="Linked spending information",
    )
    amount: Optional[Value] = Field(
        None,
        description="(Deprecated in 1.1. Use transaction.value instead) The value of the transaction. A negative value indicates a refund or correction.",
        title="Amount",
    )
    providerOrganization: Optional[Identifier] = Field(
        None,
        description="(Deprecated in 1.1. Use transaction.payer instead.) The Organization Identifier for the organization from which the funds in this transaction originate. Expressed following the Organizational Identifier standard - consult the documentation and the codelist.",
        title="Provider organization",
    )
    receiverOrganization: Optional[Identifier] = Field(
        None,
        description="(Deprecated in 1.1. Use transaction.payee instead). The Organization Identifier for the organization which receives the funds in this transaction. Expressed following the Organizational Identifier standard - consult the documentation and the codelist.",
        title="Receiver organization",
    )


class Implementation(BaseModel):
    transactions: Optional[Set[Transaction]] = Field(
        None,
        description="A list of the spending transactions made against this contract",
        title="Transactions",
    )
    milestones: Optional[Set[Milestone]] = Field(
        None,
        description="As milestones are completed, the milestone's status and dates should be updated.",
        title="Milestones",
    )
    documents: Optional[Set[Document]] = Field(
        None,
        description="Documents and reports that are part of the implementation phase e.g. audit and evaluation reports.",
        title="Documents",
    )


class Contract(BaseModel):
    id: Union[constr(min_length=1), int] = Field(
        ...,
        description="The identifier for this contract. It must be unique and must not change within the Open Contracting Process it is part of (defined by a single ocid). See the [identifier guidance](https://standard.open-contracting.org/1.1/en/schema/identifiers/) for further details.",
        title="Contract ID",
    )
    awardID: Union[constr(min_length=1), int] = Field(
        ...,
        description="The award.id against which this contract is being issued.",
        title="Award ID",
    )
    title: Optional[str] = Field(
        None, description="Contract title", title="Contract title"
    )
    description: Optional[str] = Field(
        None, description="Contract description", title="Contract description"
    )
    status: Optional[ContractStatus] = Field(
        None,
        description="The current status of the contract, from the closed [contractStatus](https://standard.open-contracting.org/1.1/en/schema/codelists/#contract-status) codelist.",
        title="Contract status",
    )
    period: Optional[Period] = Field(
        None, description="The start and end date for the contract.", title="Period"
    )
    value: Optional[Value] = Field(
        None,
        description="The total value of this contract. A negative value indicates that the contract will involve payments from the supplier to the buyer (commonly used in concession contracts).",
        title="Value",
    )
    items: Optional[Set[Item]] = Field(
        None,
        description="The goods, services, and any intangible outcomes in this contract. Note: If the items are the same as the award do not repeat.",
        min_items=1,
        title="Items contracted",
    )
    dateSigned: Optional[datetime] = Field(
        None,
        description="The date the contract was signed. In the case of multiple signatures, the date of the last signature.",
        title="Date signed",
    )
    documents: Optional[Set[Document]] = Field(
        None,
        description="All documents and attachments related to the contract, including any notices.",
        title="Documents",
    )
    implementation: Optional[Implementation] = Field(
        None,
        description="Information related to the implementation of the contract in accordance with the obligations laid out therein.",
        title="Implementation",
    )
    relatedProcesses: Optional[Set[RelatedProcess]] = Field(
        None,
        description="The details of related processes: for example, if this process is followed by one or more contracting processes, represented under a separate open contracting identifier (ocid). This is commonly used to refer to subcontracts and to renewal or replacement processes for this contract.",
        title="Related processes",
    )
    milestones: Optional[List[Milestone]] = Field(
        None,
        description="A list of milestones associated with the finalization of this contract.",
        title="Contract milestones",
    )
    amendments: Optional[List[Amendment]] = Field(
        None,
        description="A contract amendment is a formal change to, or extension of, a contract, and generally involves the publication of a new contract notice/release, or some other documents detailing the change. The rationale and a description of the changes made can be provided here.",
        title="Amendments",
    )
    amendment: Optional[Amendment] = Field(
        None,
        description="The use of individual amendment objects has been deprecated. From OCDS 1.1 information should be provided in the amendments array.",
        title="Amendment",
    )

    def __hash__(self):
        return hash(self.id)


class Release(BaseModel):
    ocid: constr(min_length=1) = Field(
        None,
        description="A globally unique identifier for this Open Contracting Process. Composed of an ocid prefix and an identifier for the contracting process. For more information see the [Open Contracting Identifier guidance](https://standard.open-contracting.org/1.1/en/schema/identifiers/)",
        title="Open Contracting ID",
    )
    id: constr(min_length=1) = Field(
        None,
        description="An identifier for this particular release of information. A release identifier must be unique within the scope of its related contracting process (defined by a common ocid). A release identifier must not contain the # character.",
        title="Release ID",
    )
    date: datetime = Field(
        None,
        description="The date on which the information contained in the release was first recorded in, or published by, any system.",
        title="Release Date",
    )
    tag: List[TagEnum] = Field(
        None,
        description="One or more values from the closed [releaseTag](https://standard.open-contracting.org/1.1/en/schema/codelists/#release-tag) codelist. Tags can be used to filter releases and to understand the kind of information that releases might contain.",
        min_items=1,
        title="Release Tag",
    )
    initiationType: InitiationType = Field(
        None,
        description="The type of initiation process used for this contract, from the closed [initiationType](https://standard.open-contracting.org/1.1/en/schema/codelists/#initiation-type) codelist.",
        title="Initiation type",
    )
    parties: Optional[Set[Organization]] = Field(
        None,
        description="Information on the parties (organizations, economic operators and other participants) who are involved in the contracting process and their roles, e.g. buyer, procuring entity, supplier etc. Organization references elsewhere in the schema are used to refer back to this entries in this list.",
        title="Parties",
    )
    buyer: Optional[Organization] = Field(
        None,
        description="A buyer is an entity whose budget will be used to pay for goods, works or services related to a contract. This may be different from the procuring entity who may be specified in the tender data.",
        title="Buyer",
    )
    planning: Optional[Planning] = Field(
        None,
        description="Information from the planning phase of the contracting process. This includes information related to the process of deciding what to contract, when and how.",
        title="Planning",
    )
    tender: Optional[Tender] = Field(
        None,
        description="The activities undertaken in order to enter into a contract.",
        title="Tender",
    )
    awards: Optional[Set[Award]] = Field(
        None,
        description="Information from the award phase of the contracting process. There can be more than one award per contracting process e.g. because the contract is split among different providers, or because it is a standing offer.",
        title="Awards",
    )
    contracts: Optional[Set[Contract]] = Field(
        None,
        description="Information from the contract creation phase of the procurement process.",
        title="Contracts",
    )
    language: Optional[str] = Field(
        "en",
        description="The default language of the data using either two-letter [ISO639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), or extended [BCP47 language tags](https://www.w3.org/International/articles/language-tags/). The use of lowercase two-letter codes from [ISO639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) is recommended.",
        title="Release language",
    )
    relatedProcesses: Optional[Set[RelatedProcess]] = Field(
        None,
        description="The details of related processes: for example, if this process follows on from one or more other processes, represented under a separate open contracting identifier (ocid). This is commonly used to relate mini-competitions to their parent frameworks or individual tenders to a broader planning process.",
        title="Related processes",
    )
    # Link to TED
    tedURL: Optional[str]

    def __hash__(self):
        return hash(self.id)
