fix: Resolve build and runtime errors

This commit is contained in:
2025-10-02 10:34:00 +03:00
parent 5eb23eed5b
commit 8816377361
38 changed files with 707 additions and 703 deletions

View File

@@ -0,0 +1,63 @@
// [PACKAGE] com.homebox.lens.ui.mapper
// [FILE] ItemMapper.kt
// [SEMANTICS] ui, mapper, item
package com.homebox.lens.ui.mapper
import com.homebox.lens.domain.model.Item
import com.homebox.lens.domain.model.ItemOut
import com.homebox.lens.domain.model.Label
import com.homebox.lens.domain.model.Location
import javax.inject.Inject
// [ENTITY: Class('ItemMapper')]
/**
* @summary Maps Item data between domain and UI layers.
* @invariant This class is stateless and its methods are pure functions.
*/
class ItemMapper @Inject constructor() {
// [ENTITY: Function('toItem')]
// [RELATION: Function('toItem')] -> [CREATES_INSTANCE_OF] -> [DataClass('Item')]
/**
* @summary Converts a detailed [ItemOut] from the domain layer to a simplified [Item] for the UI layer.
* @param itemOut The [ItemOut] object to convert.
* @return The resulting [Item] object.
* @precondition itemOut MUST NOT be null.
* @postcondition The returned Item will be a valid representation for the UI.
*/
fun toItem(itemOut: ItemOut): Item {
return Item(
id = itemOut.id,
name = itemOut.name,
description = itemOut.description,
quantity = itemOut.quantity,
image = itemOut.images.firstOrNull { it.isPrimary }?.path,
location = itemOut.location?.let { Location(it.id, it.name) },
labels = itemOut.labels.map { Label(it.id, it.name) },
purchasePrice = itemOut.purchasePrice,
createdAt = itemOut.createdAt,
archived = itemOut.isArchived,
assetId = itemOut.assetId,
fields = itemOut.fields.map { com.homebox.lens.domain.model.CustomField(it.name, it.value, it.type) },
insured = itemOut.insured ?: false,
lifetimeWarranty = itemOut.lifetimeWarranty ?: false,
manufacturer = itemOut.manufacturer,
modelNumber = itemOut.modelNumber,
notes = itemOut.notes,
parentId = itemOut.parent?.id,
purchaseFrom = itemOut.purchaseFrom,
purchaseTime = itemOut.purchaseTime,
serialNumber = itemOut.serialNumber,
soldNotes = itemOut.soldNotes,
soldPrice = itemOut.soldPrice,
soldTime = itemOut.soldTime,
soldTo = itemOut.soldTo,
syncChildItemsLocations = itemOut.syncChildItemsLocations ?: false,
warrantyDetails = itemOut.warrantyDetails,
warrantyExpires = itemOut.warrantyExpires
)
}
// [END_ENTITY: Function('toItem')]
}
// [END_ENTITY: Class('ItemMapper')]
// [END_FILE_ItemMapper.kt]

View File

@@ -139,7 +139,7 @@ fun ItemEditScreen(
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = stringResource(R.string.item_general_information),
text = stringResource(R.string.item_edit_general_information),
style = MaterialTheme.typography.headlineSmall
)
Spacer(modifier = Modifier.height(16.dp))
@@ -169,11 +169,11 @@ fun ItemEditScreen(
OutlinedTextField(
value = item.location?.name ?: "",
onValueChange = { /* TODO: Implement location selection */ },
label = { Text(stringResource(R.string.item_location)) },
label = { Text(stringResource(R.string.item_edit_location)) },
readOnly = true,
trailingIcon = {
IconButton(onClick = { /* TODO: Implement location selection */ }) {
Icon(Icons.Filled.ArrowDropDown, contentDescription = stringResource(R.string.select_location))
Icon(Icons.Filled.ArrowDropDown, contentDescription = stringResource(R.string.item_edit_select_location))
}
},
modifier = Modifier.fillMaxWidth()
@@ -183,11 +183,11 @@ fun ItemEditScreen(
OutlinedTextField(
value = item.labels.joinToString { it.name },
onValueChange = { /* TODO: Implement label selection */ },
label = { Text(stringResource(R.string.item_labels)) },
label = { Text(stringResource(R.string.item_edit_labels)) },
readOnly = true,
trailingIcon = {
IconButton(onClick = { /* TODO: Implement label selection */ }) {
Icon(Icons.Filled.ArrowDropDown, contentDescription = stringResource(R.string.select_labels))
Icon(Icons.Filled.ArrowDropDown, contentDescription = stringResource(R.string.item_edit_select_labels))
}
},
modifier = Modifier.fillMaxWidth()
@@ -204,14 +204,14 @@ fun ItemEditScreen(
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = stringResource(R.string.item_purchase_information),
text = stringResource(R.string.item_edit_purchase_information),
style = MaterialTheme.typography.headlineSmall
)
Spacer(modifier = Modifier.height(16.dp))
OutlinedTextField(
value = item.purchasePrice?.toString() ?: "",
onValueChange = { viewModel.updatePurchasePrice(it.toBigDecimalOrNull()) },
label = { Text(stringResource(R.string.item_purchase_price)) },
onValueChange = { viewModel.updatePurchasePrice(it.toDoubleOrNull()) },
label = { Text(stringResource(R.string.item_edit_purchase_price)) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
modifier = Modifier.fillMaxWidth()
)
@@ -219,7 +219,7 @@ fun ItemEditScreen(
OutlinedTextField(
value = item.purchaseFrom ?: "",
onValueChange = { viewModel.updatePurchaseFrom(it) },
label = { Text(stringResource(R.string.item_purchase_from)) },
label = { Text(stringResource(R.string.item_edit_purchase_from)) },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
@@ -229,11 +229,11 @@ fun ItemEditScreen(
OutlinedTextField(
value = item.purchaseTime ?: "",
onValueChange = { }, // Read-only, handled by date picker
label = { Text(stringResource(R.string.item_purchase_time)) },
label = { Text(stringResource(R.string.item_edit_purchase_time)) },
readOnly = true,
trailingIcon = {
IconButton(onClick = { showPurchaseDatePicker = true }) {
Icon(Icons.Filled.DateRange, contentDescription = stringResource(R.string.select_date))
Icon(Icons.Filled.DateRange, contentDescription = stringResource(R.string.item_edit_select_date))
}
},
modifier = Modifier
@@ -244,7 +244,7 @@ fun ItemEditScreen(
DatePickerDialog(
onDismissRequest = { showPurchaseDatePicker = false },
confirmButton = {
Text(stringResource(R.string.ok), modifier = Modifier.clickable {
Text(stringResource(R.string.dialog_ok), modifier = Modifier.clickable {
val selectedDate = purchaseDateState.selectedDateMillis?.let {
SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date(it))
}
@@ -255,7 +255,7 @@ fun ItemEditScreen(
})
},
dismissButton = {
Text(stringResource(R.string.cancel), modifier = Modifier.clickable { showPurchaseDatePicker = false })
Text(stringResource(R.string.dialog_cancel), modifier = Modifier.clickable { showPurchaseDatePicker = false })
}
) {
DatePicker(state = purchaseDateState)
@@ -273,7 +273,7 @@ fun ItemEditScreen(
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = stringResource(R.string.item_warranty_information),
text = stringResource(R.string.item_edit_warranty_information),
style = MaterialTheme.typography.headlineSmall
)
Spacer(modifier = Modifier.height(16.dp))
@@ -282,7 +282,7 @@ fun ItemEditScreen(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(stringResource(R.string.item_lifetime_warranty))
Text(stringResource(R.string.item_edit_lifetime_warranty))
Switch(
checked = item.lifetimeWarranty,
onCheckedChange = { viewModel.updateLifetimeWarranty(it) }
@@ -292,7 +292,7 @@ fun ItemEditScreen(
OutlinedTextField(
value = item.warrantyDetails ?: "",
onValueChange = { viewModel.updateWarrantyDetails(it) },
label = { Text(stringResource(R.string.item_warranty_details)) },
label = { Text(stringResource(R.string.item_edit_warranty_details)) },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
@@ -302,11 +302,11 @@ fun ItemEditScreen(
OutlinedTextField(
value = item.warrantyExpires ?: "",
onValueChange = { }, // Read-only, handled by date picker
label = { Text(stringResource(R.string.item_warranty_expires)) },
label = { Text(stringResource(R.string.item_edit_warranty_expires)) },
readOnly = true,
trailingIcon = {
IconButton(onClick = { showWarrantyDatePicker = true }) {
Icon(Icons.Filled.DateRange, contentDescription = stringResource(R.string.select_date))
Icon(Icons.Filled.DateRange, contentDescription = stringResource(R.string.item_edit_select_date))
}
},
modifier = Modifier
@@ -317,7 +317,7 @@ fun ItemEditScreen(
DatePickerDialog(
onDismissRequest = { showWarrantyDatePicker = false },
confirmButton = {
Text(stringResource(R.string.ok), modifier = Modifier.clickable {
Text(stringResource(R.string.dialog_ok), modifier = Modifier.clickable {
val selectedDate = warrantyDateState.selectedDateMillis?.let {
SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date(it))
}
@@ -328,7 +328,7 @@ fun ItemEditScreen(
})
},
dismissButton = {
Text(stringResource(R.string.cancel), modifier = Modifier.clickable { showWarrantyDatePicker = false })
Text(stringResource(R.string.dialog_cancel), modifier = Modifier.clickable { showWarrantyDatePicker = false })
}
) {
DatePicker(state = warrantyDateState)
@@ -346,35 +346,35 @@ fun ItemEditScreen(
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = stringResource(R.string.item_identification),
text = stringResource(R.string.item_edit_identification),
style = MaterialTheme.typography.headlineSmall
)
Spacer(modifier = Modifier.height(16.dp))
OutlinedTextField(
value = item.assetId ?: "",
onValueChange = { viewModel.updateAssetId(it) },
label = { Text(stringResource(R.string.item_asset_id)) },
label = { Text(stringResource(R.string.item_edit_asset_id)) },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
OutlinedTextField(
value = item.serialNumber ?: "",
onValueChange = { viewModel.updateSerialNumber(it) },
label = { Text(stringResource(R.string.item_serial_number)) },
label = { Text(stringResource(R.string.item_edit_serial_number)) },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
OutlinedTextField(
value = item.manufacturer ?: "",
onValueChange = { viewModel.updateManufacturer(it) },
label = { Text(stringResource(R.string.item_manufacturer)) },
label = { Text(stringResource(R.string.item_edit_manufacturer)) },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
OutlinedTextField(
value = item.modelNumber ?: "",
onValueChange = { viewModel.updateModelNumber(it) },
label = { Text(stringResource(R.string.item_model_number)) },
label = { Text(stringResource(R.string.item_edit_model_number)) },
modifier = Modifier.fillMaxWidth()
)
}
@@ -389,7 +389,7 @@ fun ItemEditScreen(
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = stringResource(R.string.item_status_notes),
text = stringResource(R.string.item_edit_status_notes),
style = MaterialTheme.typography.headlineSmall
)
Spacer(modifier = Modifier.height(16.dp))
@@ -398,7 +398,7 @@ fun ItemEditScreen(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(stringResource(R.string.item_archived))
Text(stringResource(R.string.item_edit_archived))
Switch(
checked = item.archived,
onCheckedChange = { viewModel.updateArchived(it) }
@@ -410,7 +410,7 @@ fun ItemEditScreen(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(stringResource(R.string.item_insured))
Text(stringResource(R.string.item_edit_insured))
Switch(
checked = item.insured,
onCheckedChange = { viewModel.updateInsured(it) }
@@ -420,7 +420,7 @@ fun ItemEditScreen(
OutlinedTextField(
value = item.notes ?: "",
onValueChange = { viewModel.updateNotes(it) },
label = { Text(stringResource(R.string.item_notes)) },
label = { Text(stringResource(R.string.item_edit_notes)) },
modifier = Modifier.fillMaxWidth()
)
}
@@ -436,14 +436,14 @@ fun ItemEditScreen(
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = stringResource(R.string.item_sold_information),
text = stringResource(R.string.item_edit_sold_information),
style = MaterialTheme.typography.headlineSmall
)
Spacer(modifier = Modifier.height(16.dp))
OutlinedTextField(
value = item.soldPrice?.toString() ?: "",
onValueChange = { viewModel.updateSoldPrice(it.toBigDecimalOrNull()) },
label = { Text(stringResource(R.string.item_sold_price)) },
onValueChange = { viewModel.updateSoldPrice(it.toDoubleOrNull()) },
label = { Text(stringResource(R.string.item_edit_sold_price)) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
modifier = Modifier.fillMaxWidth()
)
@@ -451,14 +451,14 @@ fun ItemEditScreen(
OutlinedTextField(
value = item.soldTo ?: "",
onValueChange = { viewModel.updateSoldTo(it) },
label = { Text(stringResource(R.string.item_sold_to)) },
label = { Text(stringResource(R.string.item_edit_sold_to)) },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
OutlinedTextField(
value = item.soldNotes ?: "",
onValueChange = { viewModel.updateSoldNotes(it) },
label = { Text(stringResource(R.string.item_sold_notes)) },
label = { Text(stringResource(R.string.item_edit_sold_notes)) },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
@@ -468,11 +468,11 @@ fun ItemEditScreen(
OutlinedTextField(
value = item.soldTime ?: "",
onValueChange = { }, // Read-only, handled by date picker
label = { Text(stringResource(R.string.item_sold_time)) },
label = { Text(stringResource(R.string.item_edit_sold_time)) },
readOnly = true,
trailingIcon = {
IconButton(onClick = { showSoldDatePicker = true }) {
Icon(Icons.Filled.DateRange, contentDescription = stringResource(R.string.select_date))
Icon(Icons.Filled.DateRange, contentDescription = stringResource(R.string.item_edit_select_date))
}
},
modifier = Modifier
@@ -483,7 +483,7 @@ fun ItemEditScreen(
DatePickerDialog(
onDismissRequest = { showSoldDatePicker = false },
confirmButton = {
Text(stringResource(R.string.ok), modifier = Modifier.clickable {
Text(stringResource(R.string.dialog_ok), modifier = Modifier.clickable {
val selectedDate = soldDateState.selectedDateMillis?.let {
SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date(it))
}
@@ -494,7 +494,7 @@ fun ItemEditScreen(
})
},
dismissButton = {
Text(stringResource(R.string.cancel), modifier = Modifier.clickable { showSoldDatePicker = false })
Text(stringResource(R.string.dialog_cancel), modifier = Modifier.clickable { showSoldDatePicker = false })
}
) {
DatePicker(state = soldDateState)
@@ -504,7 +504,7 @@ fun ItemEditScreen(
}
}
}
}
}}
}
}
}

View File

@@ -7,15 +7,11 @@ package com.homebox.lens.ui.screen.itemedit
// [IMPORTS]
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.homebox.lens.data.db.entity.toDomainItem
import com.homebox.lens.domain.model.Item
import com.homebox.lens.domain.model.ItemCreate
import com.homebox.lens.domain.model.ItemUpdate
import com.homebox.lens.domain.model.Label
import com.homebox.lens.domain.model.Location
import com.homebox.lens.domain.model.*
import com.homebox.lens.domain.usecase.CreateItemUseCase
import com.homebox.lens.domain.usecase.GetItemDetailsUseCase
import com.homebox.lens.domain.usecase.UpdateItemUseCase
import com.homebox.lens.ui.mapper.ItemMapper
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -25,7 +21,6 @@ import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import timber.log.Timber
import java.math.BigDecimal
import javax.inject.Inject
// [END_IMPORTS]
@@ -47,15 +42,21 @@ data class ItemEditUiState(
// [RELATION: ViewModel('ItemEditViewModel')] -> [DEPENDS_ON] -> [UseCase('CreateItemUseCase')]
// [RELATION: ViewModel('ItemEditViewModel')] -> [DEPENDS_ON] -> [UseCase('UpdateItemUseCase')]
// [RELATION: ViewModel('ItemEditViewModel')] -> [DEPENDS_ON] -> [UseCase('GetItemDetailsUseCase')]
// [RELATION: ViewModel('ItemEditViewModel')] -> [DEPENDS_ON] -> [Class('ItemMapper')]
// [RELATION: ViewModel('ItemEditViewModel')] -> [EMITS_STATE] -> [DataClass('ItemEditUiState')]
/**
* @summary ViewModel for the item edit screen.
* @param createItemUseCase Use case for creating a new item.
* @param updateItemUseCase Use case for updating an existing item.
* @param getItemDetailsUseCase Use case for fetching item details.
* @param itemMapper Mapper for converting between domain and UI item models.
*/
@HiltViewModel
class ItemEditViewModel @Inject constructor(
private val createItemUseCase: CreateItemUseCase,
private val updateItemUseCase: UpdateItemUseCase,
private val getItemDetailsUseCase: GetItemDetailsUseCase
private val getItemDetailsUseCase: GetItemDetailsUseCase,
private val itemMapper: ItemMapper
) : ViewModel() {
private val _uiState = MutableStateFlow(ItemEditUiState())
@@ -114,8 +115,9 @@ class ItemEditViewModel @Inject constructor(
Timber.i("[INFO][ACTION][fetching_item_details] Fetching details for item ID: %s", itemId)
val itemOut = getItemDetailsUseCase(itemId)
Timber.d("[DEBUG][ACTION][mapping_item_out_to_item] Mapping ItemOut to Item for UI state.")
_uiState.value = _uiState.value.copy(isLoading = false, item = itemOut.toDomainItem())
Timber.i("[INFO][ACTION][item_details_fetched] Successfully fetched item details for ID: %s", itemId)
val item = itemMapper.toItem(itemOut)
_uiState.value = _uiState.value.copy(isLoading = false, item = item)
Timber.i("[INFO][ACTION][item_details_fetched] Successfully fetched and mapped item details for ID: %s", itemId)
} catch (e: Exception) {
Timber.e(e, "[ERROR][FALLBACK][item_load_failed] Failed to load item details for ID: %s", itemId)
_uiState.value = _uiState.value.copy(isLoading = false, error = e.localizedMessage)
@@ -141,7 +143,7 @@ class ItemEditViewModel @Inject constructor(
try {
if (currentItem.id.isBlank()) {
Timber.i("[INFO][ACTION][creating_new_item] Creating new item: %s", currentItem.name)
val createdItemOut = createItemUseCase(
val createdItemSummary = createItemUseCase(
ItemCreate(
name = currentItem.name,
description = currentItem.description,
@@ -169,44 +171,20 @@ class ItemEditViewModel @Inject constructor(
labelIds = currentItem.labels.map { it.id }
)
)
Timber.d("[DEBUG][ACTION][mapping_item_out_to_item] Mapping ItemOut to Item for UI state.")
_uiState.value = _uiState.value.copy(isLoading = false, item = createdItemOut.toDomainItem())
Timber.i("[INFO][ACTION][new_item_created] Successfully created new item with ID: %s", createdItemOut.id)
Timber.i("[INFO][ACTION][fetching_full_item_after_creation] Fetching full item details after creation for ID: %s", createdItemSummary.id)
val createdItemOut = getItemDetailsUseCase(createdItemSummary.id)
Timber.d("[DEBUG][ACTION][mapping_item_out_to_item] Mapping created ItemOut to Item for UI state.")
val item = itemMapper.toItem(createdItemOut)
_uiState.value = _uiState.value.copy(isLoading = false, item = item)
Timber.i("[INFO][ACTION][new_item_created] Successfully created and mapped new item with ID: %s", createdItemOut.id)
_saveCompleted.emit(Unit)
} else {
Timber.i("[INFO][ACTION][updating_existing_item] Updating existing item with ID: %s", currentItem.id)
val updatedItemOut = updateItemUseCase(
ItemUpdate(
id = currentItem.id,
name = currentItem.name,
description = currentItem.description,
quantity = currentItem.quantity,
archived = currentItem.archived,
assetId = currentItem.assetId,
insured = currentItem.insured,
lifetimeWarranty = currentItem.lifetimeWarranty,
manufacturer = currentItem.manufacturer,
modelNumber = currentItem.modelNumber,
notes = currentItem.notes,
parentId = currentItem.parentId,
purchaseFrom = currentItem.purchaseFrom,
purchasePrice = currentItem.purchasePrice,
purchaseTime = currentItem.purchaseTime,
serialNumber = currentItem.serialNumber,
soldNotes = currentItem.soldNotes,
soldPrice = currentItem.soldPrice,
soldTime = currentItem.soldTime,
soldTo = currentItem.soldTo,
syncChildItemsLocations = currentItem.syncChildItemsLocations,
warrantyDetails = currentItem.warrantyDetails,
warrantyExpires = currentItem.warrantyExpires,
locationId = currentItem.location?.id,
labelIds = currentItem.labels.map { it.id }
)
)
Timber.d("[DEBUG][ACTION][mapping_item_out_to_item] Mapping ItemOut to Item for UI state.")
_uiState.value = _uiState.value.copy(isLoading = false, item = updatedItemOut.toDomainItem())
Timber.i("[INFO][ACTION][item_updated] Successfully updated item with ID: %s", updatedItemOut.id)
val updatedItemOut = updateItemUseCase(currentItem)
Timber.d("[DEBUG][ACTION][mapping_item_out_to_item] Mapping updated ItemOut to Item for UI state.")
val item = itemMapper.toItem(updatedItemOut)
_uiState.value = _uiState.value.copy(isLoading = false, item = item)
Timber.i("[INFO][ACTION][item_updated] Successfully updated and mapped item with ID: %s", updatedItemOut.id)
_saveCompleted.emit(Unit)
}
} catch (e: Exception) {
@@ -367,7 +345,7 @@ class ItemEditViewModel @Inject constructor(
* @param newPurchasePrice The new purchase price for the item.
* @sideeffect Updates the `item` in `_uiState`.
*/
fun updatePurchasePrice(newPurchasePrice: BigDecimal?) {
fun updatePurchasePrice(newPurchasePrice: Double?) {
Timber.d("[DEBUG][ACTION][updating_item_purchase_price] Updating item purchase price to: %s", newPurchasePrice)
_uiState.value = _uiState.value.copy(item = _uiState.value.item?.copy(purchasePrice = newPurchasePrice))
}
@@ -415,7 +393,7 @@ class ItemEditViewModel @Inject constructor(
* @param newSoldPrice The new sold price for the item.
* @sideeffect Updates the `item` in `_uiState`.
*/
fun updateSoldPrice(newSoldPrice: BigDecimal?) {
fun updateSoldPrice(newSoldPrice: Double?) {
Timber.d("[DEBUG][ACTION][updating_item_sold_price] Updating item sold price to: %s", newSoldPrice)
_uiState.value = _uiState.value.copy(item = _uiState.value.item?.copy(soldPrice = newSoldPrice))
}
@@ -482,4 +460,4 @@ class ItemEditViewModel @Inject constructor(
// [END_ENTITY: Function('updateWarrantyExpires')]
}
// [END_ENTITY: ViewModel('ItemEditViewModel')]
// [END_FILE_ItemEditViewModel.kt]
// [END_FILE_ItemEditViewModel.kt]

View File

@@ -65,11 +65,11 @@ class LabelEditViewModel @Inject constructor(
try {
if (labelId == null) {
// Create new label
val newLabel = LabelCreate(name = uiState.name, color = uiState.color)
val newLabel = LabelCreate(name = uiState.name, color = uiState.color, description = null)
createLabelUseCase(newLabel)
} else {
// Update existing label
val updatedLabel = LabelUpdate(name = uiState.name, color = uiState.color)
val updatedLabel = LabelUpdate(name = uiState.name, color = uiState.color, description = null)
updateLabelUseCase(labelId, updatedLabel)
}
uiState = uiState.copy(isSaved = true)

View File

@@ -70,6 +70,36 @@
<string name="item_name">Название</string>
<string name="item_description">Описание</string>
<string name="item_quantity">Количество</string>
<string name="item_edit_general_information">General Information</string>
<string name="item_edit_location">Location</string>
<string name="item_edit_select_location">Select Location</string>
<string name="item_edit_labels">Labels</string>
<string name="item_edit_select_labels">Select Labels</string>
<string name="item_edit_purchase_information">Purchase Information</string>
<string name="item_edit_purchase_price">Purchase Price</string>
<string name="item_edit_purchase_from">Purchase From</string>
<string name="item_edit_purchase_time">Purchase Date</string>
<string name="item_edit_select_date">Select Date</string>
<string name="dialog_ok">OK</string>
<string name="dialog_cancel">Cancel</string>
<string name="item_edit_warranty_information">Warranty Information</string>
<string name="item_edit_lifetime_warranty">Lifetime Warranty</string>
<string name="item_edit_warranty_details">Warranty Details</string>
<string name="item_edit_warranty_expires">Warranty Expires</string>
<string name="item_edit_identification">Identification</string>
<string name="item_edit_asset_id">Asset ID</string>
<string name="item_edit_serial_number">Serial Number</string>
<string name="item_edit_manufacturer">Manufacturer</string>
<string name="item_edit_model_number">Model Number</string>
<string name="item_edit_status_notes">Status &amp; Notes</string>
<string name="item_edit_archived">Archived</string>
<string name="item_edit_insured">Insured</string>
<string name="item_edit_notes">Notes</string>
<string name="item_edit_sold_information">Sold Information</string>
<string name="item_edit_sold_price">Sold Price</string>
<string name="item_edit_sold_to">Sold To</string>
<string name="item_edit_sold_notes">Sold Notes</string>
<string name="item_edit_sold_time">Sold Date</string>
<!-- Location Edit Screen -->
<string name="location_edit_title_create">Создать локацию</string>