Skip to main content
Client models represent tenants in the greenhouse management system. Each client can have multiple greenhouses, users, and associated resources.

Client

Main data class representing a client/tenant in the system. Matches the TenantResponse structure from the API.
@Serializable
data class Client(
    val id: Long,
    val code: String,
    val name: String,
    val email: String,
    val phone: String = "",
    val province: String = "",
    val country: String = "",
    val location: Location? = null,
    val isActive: Boolean? = true,
    val status: ClientStatus = ClientStatus.ACTIVE
)

Fields

id
Long
required
Unique identifier for the client
code
String
required
Unique code assigned to the client
name
String
required
Client’s display name
email
String
required
Client’s contact email address
phone
String
default:"\"\""
Client’s phone number
province
String
default:"\"\""
Province where the client is located
country
String
default:"\"\""
Country where the client is located
location
Location
default:"null"
Geographic coordinates of the client’s location
isActive
Boolean
default:"true"
Whether the client account is active
status
ClientStatus
default:"ClientStatus.ACTIVE"
Current status of the client account

Computed Properties

The Client class provides computed properties for display purposes:
initials
String
Returns the first letter of each word in the client’s name (up to 2 letters) in uppercase.
val initials: String
    get() = name.split(" ")
        .take(2)
        .mapNotNull { it.firstOrNull()?.uppercaseChar() }
        .joinToString("")
Example: “Acme Corporation” → “AC”
fullLocation
String
Returns a formatted location string combining province and country, or ”-” if both are blank.
val fullLocation: String
    get() = buildString {
        if (province.isNotBlank()) append(province)
        if (province.isNotBlank() && country.isNotBlank()) append(", ")
        if (country.isNotBlank()) append(country)
    }.ifBlank { "-" }
Example: “Almería, España”

Location

Represents geographic coordinates. Matches the JSONB location field in the database.
@Serializable
data class Location(
    val lat: Double? = null,
    val lon: Double? = null
)

Fields

lat
Double
default:"null"
Latitude coordinate
lon
Double
default:"null"
Longitude coordinate

Computed Properties

isValid
Boolean
Returns true if both latitude and longitude are set.
val isValid: Boolean
    get() = lat != null && lon != null
displayString
String
Returns a formatted string of coordinates or empty string if not valid.
val displayString: String
    get() = if (isValid) "$lat, $lon" else ""
Example: “36.8381, -2.4597”

ClientStatus

Enum representing the status of a client account.
@Serializable
enum class ClientStatus {
    ACTIVE,
    PENDING,
    INACTIVE
}

Values

  • ACTIVE: Client account is active and operational
  • PENDING: Client account is pending activation or approval
  • INACTIVE: Client account is inactive or disabled

Extension Functions

toIsActive
() -> Boolean?
Converts ClientStatus to nullable Boolean for API compatibility.
fun ClientStatus.toIsActive(): Boolean? = when (this) {
    ClientStatus.ACTIVE -> true
    ClientStatus.INACTIVE -> false
    ClientStatus.PENDING -> null
}
Maps: ACTIVEtrue, INACTIVEfalse, PENDINGnull
toApiStatus
() -> String
Converts ClientStatus to API status string (Spanish).
fun ClientStatus.toApiStatus(): String = when (this) {
    ClientStatus.ACTIVE -> "Activo"
    ClientStatus.INACTIVE -> "Inactivo"
    ClientStatus.PENDING -> "Pendiente"
}

ClientStatusFilter

Enum for filtering clients by status.
enum class ClientStatusFilter {
    ALL,
    ACTIVE,
    PENDING,
    INACTIVE
}

Values

  • ALL: Show all clients regardless of status
  • ACTIVE: Show only active clients
  • PENDING: Show only pending clients
  • INACTIVE: Show only inactive clients

Methods

matches
(ClientStatus) -> Boolean
Determines if a given ClientStatus matches this filter.
fun matches(status: ClientStatus): Boolean = when (this) {
    ALL -> true
    ACTIVE -> status == ClientStatus.ACTIVE
    PENDING -> status == ClientStatus.PENDING
    INACTIVE -> status == ClientStatus.INACTIVE
}

PaginationInfo

Data class for managing pagination state in client lists.
data class PaginationInfo(
    val currentPage: Int = 0,
    val pageSize: Int = 10,
    val totalItems: Int = 0
)

Fields

currentPage
Int
default:"0"
Current page number (zero-indexed)
pageSize
Int
default:"10"
Number of items per page
totalItems
Int
default:"0"
Total number of items across all pages

Computed Properties

totalPages
Int
Total number of pages based on items and page size.
val totalPages: Int
    get() = if (totalItems == 0) 0 else (totalItems + pageSize - 1) / pageSize
startIndex
Int
Starting index for the current page.
val startIndex: Int
    get() = currentPage * pageSize
endIndex
Int
Ending index for the current page (inclusive).
val endIndex: Int
    get() = minOf(startIndex + pageSize, totalItems)
hasNextPage
Boolean
Whether there is a next page available.
val hasNextPage: Boolean
    get() = currentPage < totalPages - 1
hasPreviousPage
Boolean
Whether there is a previous page available.
val hasPreviousPage: Boolean
    get() = currentPage > 0
displayRange
String
Human-readable range display (e.g., “1-10” or “11-20”).
val displayRange: String
    get() = if (totalItems == 0) "0-0" else "${startIndex + 1}-$endIndex"

API DTOs

TenantResponse

Response DTO from the API representing a tenant. Maps to Client domain model.
@Serializable
data class TenantResponse(
    val id: Long,
    val code: String,
    val name: String,
    val email: String,
    val phone: String? = null,
    val province: String? = null,
    val country: String? = null,
    val location: Location? = null,
    val isActive: Boolean? = true,
    val status: String = "Activo"
)
toClient
() -> Client
Converts TenantResponse to Client domain model.
fun TenantResponse.toClient(): Client = Client(
    id = id,
    code = code,
    name = name,
    email = email,
    phone = phone ?: "",
    province = province ?: "",
    country = country ?: "",
    location = location,
    isActive = isActive,
    status = when (status) {
        "Activo" -> ClientStatus.ACTIVE
        "Inactivo" -> ClientStatus.INACTIVE
        "Pendiente" -> ClientStatus.PENDING
        else -> ClientStatus.ACTIVE
    }
)

CreateTenantRequest

Request DTO for creating a new tenant.
@Serializable
data class CreateTenantRequest(
    val name: String,
    val email: String,
    val phone: String? = null,
    val province: String? = null,
    val country: String? = "España",
    val location: Location? = null,
    val status: String? = "Activo"
)

UpdateTenantRequest

Request DTO for updating an existing tenant. All fields are optional for partial updates.
@Serializable
data class UpdateTenantRequest(
    val name: String? = null,
    val email: String? = null,
    val phone: String? = null,
    val province: String? = null,
    val country: String? = null,
    val location: Location? = null,
    val status: String? = null
)

Usage Examples

Creating a Client

val client = Client(
    id = 1L,
    code = "CLT001",
    name = "Acme Corporation",
    email = "[email protected]",
    phone = "+34 950 123 456",
    province = "Almería",
    country = "España",
    location = Location(lat = 36.8381, lon = -2.4597),
    isActive = true,
    status = ClientStatus.ACTIVE
)

println(client.initials) // "AC"
println(client.fullLocation) // "Almería, España"

Filtering Clients

val filter = ClientStatusFilter.ACTIVE
val clients = listOf(client1, client2, client3)
val activeClients = clients.filter { filter.matches(it.status) }

Pagination

val pagination = PaginationInfo(
    currentPage = 0,
    pageSize = 10,
    totalItems = 45
)

println(pagination.displayRange) // "1-10"
println(pagination.totalPages) // 5
println(pagination.hasNextPage) // true

Converting API Response

val response: TenantResponse = apiClient.getTenant(1L)
val client: Client = response.toClient()

val createRequest: CreateTenantRequest = client.toCreateRequest()
val updateRequest: UpdateTenantRequest = client.toUpdateRequest()

Build docs developers (and LLMs) love