/* Options:
Date: 2025-04-13 14:37:08
SwiftVersion: 5.0
Version: 8.23
Tip: To override a DTO option, remove "//" prefix before updating
BaseUrl: https://testapi.bokamera.se

//BaseClass: 
//AddModelExtensions: True
//AddServiceStackTypes: True
IncludeTypes: CreateCustomer.*
//ExcludeTypes: 
//ExcludeGenericBaseTypes: False
//AddResponseStatus: False
//AddImplicitVersion: 
//AddDescriptionAsComments: True
//InitializeCollections: True
//TreatTypesAsStrings: 
//DefaultImports: Foundation,ServiceStack
*/

import Foundation
import ServiceStack

// @Route("/customers", "POST")
// @ApiResponse(Description="Returned if there is a validation error on the input parameters", StatusCode=400)
// @ApiResponse(Description="Returned if the current user is not allowed to perform the action", StatusCode=401)
// @ValidateRequest(Validator="IsAuthenticated")
public class CreateCustomer : IReturn, Codable
{
    public typealias Return = UpdateCustomerResponse

    /**
    * Enter the company and id for the customer, if blank company id and you are an admin, your company id will be used.
    */
    // @ApiMember(Description="Enter the company and id for the customer, if blank company id and you are an admin, your company id will be used.", ParameterType="query")
    public var companyId:String?

    // @ApiMember(IsRequired=true)
    public var firstname:String

    // @ApiMember(IsRequired=true)
    public var lastname:String

    // @ApiMember(IsRequired=true)
    public var phone:String

    // @ApiMember()
    public var email:String

    /**
    * If Custom Fields are added to the customer, here you will send the id and the value for each custom field to be updated
    */
    // @ApiMember(Description="If Custom Fields are added to the customer, here you will send the id and the value for each custom field to be updated")
    public var customFields:[AddCustomField] = []

    /**
    * List of Access Keys
    */
    // @ApiMember(Description="List of Access Keys")
    public var accessKeys:[AddUserAccessKey] = []

    /**
    * Customer invoice adress
    */
    // @ApiMember(Description="Customer invoice adress")
    public var invoiceAddress:InvoiceAddress

    required public init(){}
}

public class UpdateCustomerResponse : CustomerQueryResponse
{
    public var facebookUserName:String
    public var userId:String?
    public var companyId:String?
    public var createdDate:Date?
    public var deletedAccessKeys:[UserAccessKeys] = []
    public var createdOrUpdatedAccessKeys:[UserAccessKeys] = []

    required public init(){ super.init() }

    private enum CodingKeys : String, CodingKey {
        case facebookUserName
        case userId
        case companyId
        case createdDate
        case deletedAccessKeys
        case createdOrUpdatedAccessKeys
    }

    required public init(from decoder: Decoder) throws {
        try super.init(from: decoder)
        let container = try decoder.container(keyedBy: CodingKeys.self)
        facebookUserName = try container.decodeIfPresent(String.self, forKey: .facebookUserName)
        userId = try container.decodeIfPresent(String.self, forKey: .userId)
        companyId = try container.decodeIfPresent(String.self, forKey: .companyId)
        createdDate = try container.decodeIfPresent(Date.self, forKey: .createdDate)
        deletedAccessKeys = try container.decodeIfPresent([UserAccessKeys].self, forKey: .deletedAccessKeys) ?? []
        createdOrUpdatedAccessKeys = try container.decodeIfPresent([UserAccessKeys].self, forKey: .createdOrUpdatedAccessKeys) ?? []
    }

    public override func encode(to encoder: Encoder) throws {
        try super.encode(to: encoder)
        var container = encoder.container(keyedBy: CodingKeys.self)
        if facebookUserName != nil { try container.encode(facebookUserName, forKey: .facebookUserName) }
        if userId != nil { try container.encode(userId, forKey: .userId) }
        if companyId != nil { try container.encode(companyId, forKey: .companyId) }
        if createdDate != nil { try container.encode(createdDate, forKey: .createdDate) }
        if deletedAccessKeys.count > 0 { try container.encode(deletedAccessKeys, forKey: .deletedAccessKeys) }
        if createdOrUpdatedAccessKeys.count > 0 { try container.encode(createdOrUpdatedAccessKeys, forKey: .createdOrUpdatedAccessKeys) }
    }
}

public class AddCustomField : Codable
{
    public var id:Int
    public var value:String

    required public init(){}
}

public class AddUserAccessKey : Codable
{
    public var id:String?
    public var companyId:String?
    public var accessKeyTypeId:Int
    public var value:String
    public var customerId:String?
    public var Description:String

    required public init(){}
}

public class InvoiceAddress : Codable
{
    public var corporateIdentityNumber:String
    public var invoiceAddress1:String
    public var invoiceAddress2:String
    public var invoiceCity:String
    public var invoicePostalCode:String
    public var invoiceCountryCode:String

    required public init(){}
}

public class UserAccessKeys : BaseModel
{
    // @Required()
    public var companyId:String?

    // @Required()
    public var accessKeyTypeId:Int?

    // @Required()
    public var value:String?

    // @Required()
    public var customerId:String?

    public var Description:String
    // @Required()
    public var id:String?

    required public init(){ super.init() }

    private enum CodingKeys : String, CodingKey {
        case companyId
        case accessKeyTypeId
        case value
        case customerId
        case Description
        case id
    }

    required public init(from decoder: Decoder) throws {
        try super.init(from: decoder)
        let container = try decoder.container(keyedBy: CodingKeys.self)
        companyId = try container.decodeIfPresent(String.self, forKey: .companyId)
        accessKeyTypeId = try container.decodeIfPresent(Int.self, forKey: .accessKeyTypeId)
        value = try container.decodeIfPresent(String.self, forKey: .value)
        customerId = try container.decodeIfPresent(String.self, forKey: .customerId)
        Description = try container.decodeIfPresent(String.self, forKey: .Description)
        id = try container.decodeIfPresent(String.self, forKey: .id)
    }

    public override func encode(to encoder: Encoder) throws {
        try super.encode(to: encoder)
        var container = encoder.container(keyedBy: CodingKeys.self)
        if companyId != nil { try container.encode(companyId, forKey: .companyId) }
        if accessKeyTypeId != nil { try container.encode(accessKeyTypeId, forKey: .accessKeyTypeId) }
        if value != nil { try container.encode(value, forKey: .value) }
        if customerId != nil { try container.encode(customerId, forKey: .customerId) }
        if Description != nil { try container.encode(Description, forKey: .Description) }
        if id != nil { try container.encode(id, forKey: .id) }
    }
}

public class BaseModel : Codable
{
    required public init(){}
}

public class CustomerQueryResponse : Codable
{
    public var id:String
    public var firstname:String
    public var lastname:String
    public var email:String
    public var phone:String
    public var imageUrl:String
    public var customFields:[CustomFieldConfigData] = []
    public var customFieldValues:[CustomFieldDataResponse] = []
    public var comments:[CustomerCommentsResponse] = []
    public var accessKeys:[UserAccessKeys] = []
    public var updated:Date
    public var created:Date
    //responseStatus:Object ignored. Type could not be extended in Swift
    public var subscribedToNewsletter:Bool
    public var invoiceAddress:InvoiceAddress

    required public init(){}
}