Skip to main content

Overview

The GreenhousesRepository provides CRUD operations for managing greenhouses within a tenant. Greenhouses can have locations, area measurements, timezones, and active status. All methods are suspend functions that return Result<T> for consistent error handling.

Methods

getGreenhousesByTenantId()

Fetches all greenhouses for a specific tenant.
suspend fun getGreenhousesByTenantId(tenantId: Long): Result<List<Greenhouse>>
Parameters
tenantId
Long
required
The tenant ID to filter greenhouses by
Returns
Result<List<Greenhouse>>
Result
Result containing a list of Greenhouse objects or an error

createGreenhouse()

Creates a new greenhouse for a tenant.
suspend fun createGreenhouse(
    tenantId: Long,
    name: String,
    location: Location? = null,
    areaM2: Double? = null,
    timezone: String? = "Europe/Madrid",
    isActive: Boolean = true
): Result<Greenhouse>
Parameters
tenantId
Long
required
The tenant ID the greenhouse belongs to
name
String
required
The greenhouse name
location
Location
default:"null"
Optional geographic location of the greenhouse
areaM2
Double
default:"null"
Optional area in square meters
timezone
String
default:"Europe/Madrid"
Optional timezone (defaults to Europe/Madrid)
isActive
Boolean
default:"true"
Whether the greenhouse is active
Returns
Result<Greenhouse>
Result
Result containing the created Greenhouse object or an error

updateGreenhouse()

Updates an existing greenhouse. All update fields are optional for partial updates.
suspend fun updateGreenhouse(
    tenantId: Long,
    greenhouseId: Long,
    name: String? = null,
    location: Location? = null,
    areaM2: Double? = null,
    timezone: String? = null,
    isActive: Boolean? = null
): Result<Greenhouse>
Parameters
tenantId
Long
required
The tenant ID the greenhouse belongs to
greenhouseId
Long
required
The greenhouse ID to update
name
String
default:"null"
New name (optional)
location
Location
default:"null"
New location (optional)
areaM2
Double
default:"null"
New area (optional)
timezone
String
default:"null"
New timezone (optional)
isActive
Boolean
default:"null"
New active status (optional)
Returns
Result<Greenhouse>
Result
Result containing the updated Greenhouse object or an error

deleteGreenhouse()

Deletes a greenhouse by ID.
suspend fun deleteGreenhouse(tenantId: Long, greenhouseId: Long): Result<Unit>
Parameters
tenantId
Long
required
The tenant ID the greenhouse belongs to
greenhouseId
Long
required
The greenhouse ID to delete
Returns
Result<Unit>
Result
Result indicating success or error

Usage Example

class GreenhousesViewModel(
    private val greenhousesRepository: GreenhousesRepository
) : ViewModel() {
    
    private val _greenhouses = MutableStateFlow<List<Greenhouse>>(emptyList())
    val greenhouses: StateFlow<List<Greenhouse>> = _greenhouses.asStateFlow()
    
    private val _error = MutableStateFlow<String?>(null)
    val error: StateFlow<String?> = _error.asStateFlow()
    
    fun loadGreenhouses(tenantId: Long) {
        viewModelScope.launch {
            greenhousesRepository.getGreenhousesByTenantId(tenantId)
                .onSuccess { _greenhouses.value = it }
                .onFailure { _error.value = it.message }
        }
    }
    
    fun createGreenhouse(
        tenantId: Long,
        name: String,
        location: Location?,
        areaM2: Double?
    ) {
        viewModelScope.launch {
            greenhousesRepository.createGreenhouse(
                tenantId = tenantId,
                name = name,
                location = location,
                areaM2 = areaM2,
                timezone = "Europe/Madrid",
                isActive = true
            )
                .onSuccess { loadGreenhouses(tenantId) }
                .onFailure { _error.value = it.message }
        }
    }
    
    fun updateGreenhouse(
        tenantId: Long,
        greenhouseId: Long,
        name: String? = null,
        isActive: Boolean? = null
    ) {
        viewModelScope.launch {
            greenhousesRepository.updateGreenhouse(
                tenantId = tenantId,
                greenhouseId = greenhouseId,
                name = name,
                isActive = isActive
            )
                .onSuccess { loadGreenhouses(tenantId) }
                .onFailure { _error.value = it.message }
        }
    }
}

Dependency Injection

Inject the repository using Koin in your Composables:
import org.koin.compose.viewmodel.koinViewModel

@Composable
fun GreenhousesScreen(tenantId: Long) {
    val viewModel: GreenhousesViewModel = koinViewModel()
    val greenhouses by viewModel.greenhouses.collectAsState()
    
    LaunchedEffect(tenantId) {
        viewModel.loadGreenhouses(tenantId)
    }
    
    // UI implementation
}

Build docs developers (and LLMs) love