diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiService.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiService.kt index 34e4a86..c889c3c 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiService.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiService.kt @@ -274,10 +274,13 @@ interface ApiService { @Part halal: MultipartBody.Part? ): Response - @PUT("store/editproduct/{id}") + @Multipart + @PUT("store/editproduct") suspend fun updateProduct( - @Path("id") productId: Int?, - @Body updatedProduct: Map + @PartMap data: Map, + @Part productImage: MultipartBody.Part?, + @Part halal: MultipartBody.Part?, + @Part sppirt: MultipartBody.Part? ): Response @DELETE("store/deleteproduct/{id}") diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/repository/ProductRepository.kt b/app/src/main/java/com/alya/ecommerce_serang/data/repository/ProductRepository.kt index 7022d8b..a3a1358 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/repository/ProductRepository.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/repository/ProductRepository.kt @@ -12,10 +12,8 @@ import com.alya.ecommerce_serang.data.api.response.customer.cart.AddCartResponse import com.alya.ecommerce_serang.data.api.response.customer.product.ProductResponse import com.alya.ecommerce_serang.data.api.response.customer.product.ReviewsItem import com.alya.ecommerce_serang.data.api.response.customer.product.StoreProduct -import com.alya.ecommerce_serang.data.api.response.store.product.UpdateProductResponse import com.alya.ecommerce_serang.data.api.response.product.Search import com.alya.ecommerce_serang.data.api.retrofit.ApiService -import com.alya.ecommerce_serang.utils.SessionManager import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaTypeOrNull @@ -267,16 +265,13 @@ class ProductRepository(private val apiService: ApiService) { } } - suspend fun updateProduct(productId: Int?, updatedProduct: Map) : UpdateProductResponse { - // Build the request with the updated fields - val response = apiService.updateProduct(productId, updatedProduct) - if (response.isSuccessful) { - return response.body()!! - } else { - throw Exception("Gagal memperbarui produk: ${response.code()}") - } - } - + suspend fun updateProduct( + productId: Int?, + data: Map, + image: MultipartBody.Part?, + halal: MultipartBody.Part?, + sppirt: MultipartBody.Part? + ) = apiService.updateProduct(data, image, halal, sppirt) suspend fun deleteProduct(productId: Int): Result { return withContext(Dispatchers.IO) { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/product/DetailStoreProductActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/product/DetailStoreProductActivity.kt index 66ef9e7..cb7385d 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/product/DetailStoreProductActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/product/DetailStoreProductActivity.kt @@ -110,17 +110,6 @@ class DetailStoreProductActivity : AppCompatActivity() { adapterCondition.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) binding.spinnerKondisiProduk.adapter = adapterCondition - // Setup Pre-Order visibility - binding.switchIsPreOrder.setOnCheckedChangeListener { _, isChecked -> - togglePreOrderVisibility(isChecked) - validateForm() - } - - binding.switchIsWholesale.setOnCheckedChangeListener { _, isChecked -> - toggleWholesaleVisibility(isChecked) - validateForm() - } - with(binding) { edtNamaProduk.doAfterTextChanged { validateForm() } edtDeskripsiProduk.doAfterTextChanged { validateForm() } @@ -131,8 +120,14 @@ class DetailStoreProductActivity : AppCompatActivity() { edtDurasi.doAfterTextChanged { validateForm() } edtMinPesanGrosir.doAfterTextChanged { validateForm() } edtHargaGrosir.doAfterTextChanged { validateForm() } - switchIsPreOrder.setOnCheckedChangeListener { _, _ -> validateForm() } - switchIsWholesale.setOnCheckedChangeListener { _, _ -> validateForm() } + switchIsPreOrder.setOnCheckedChangeListener { _, isChecked -> + togglePreOrderVisibility(isChecked) + validateForm() + } + switchIsWholesale.setOnCheckedChangeListener { _, isChecked -> + toggleWholesaleVisibility(isChecked) + validateForm() + } } validateForm() @@ -424,27 +419,61 @@ class DetailStoreProductActivity : AppCompatActivity() { } private fun updateProduct(productId: Int?) { - val updatedProduct = mapOf( - "name" to binding.edtNamaProduk.text.toString(), - "description" to binding.edtDeskripsiProduk.text.toString(), - "price" to binding.edtHargaProduk.text.toString(), - "stock" to binding.edtStokProduk.text.toString().toInt(), - "min_order" to binding.edtMinOrder.text.toString().toInt(), - "weight" to binding.edtBeratProduk.text.toString().toInt(), - "is_pre_order" to binding.switchIsPreOrder.isChecked, - "duration" to (binding.edtDurasi.text.toString().toIntOrNull() ?: 0), - "is_wholesale" to binding.switchIsWholesale.isChecked, - "wholesale_min_item" to (binding.edtMinPesanGrosir.text.toString().toIntOrNull() ?: 0), - "wholesale_price" to (binding.edtHargaGrosir.text.toString().toIntOrNull() ?: 0), - "category_id" to categoryList[binding.spinnerKategoriProduk.selectedItemPosition].id, - "status" to if (binding.switchIsActive.isChecked) "active" else "inactive", - "condition" to binding.spinnerKondisiProduk.selectedItem.toString(), - "productimg" to imageUri?.path, - "sppirt" to sppirtUri?.path, - "halal" to halalUri?.path + if (productId == null) return + + val imageFile = imageUri?.let { uriToNamedFile(it, this, "productimg") } + val sppirtFile = sppirtUri?.let { uriToNamedFile(it, this, "sppirt") } + val halalFile = halalUri?.let { uriToNamedFile(it, this, "halal") } + + val imagePart = createPartFromFile("productimg", imageFile) + val sppirtPart = createPartFromFile("sppirt", sppirtFile) + val halalPart = createPartFromFile("halal", halalFile) + + val data = mutableMapOf( + "product_id" to toRequestBody(productId.toString()), + "name" to toRequestBody(binding.edtNamaProduk.text.toString()), + "description" to toRequestBody(binding.edtDeskripsiProduk.text.toString()), + "price" to toRequestBody(binding.edtHargaProduk.text.toString()), + "stock" to toRequestBody(binding.edtStokProduk.text.toString()), + "min_order" to toRequestBody(binding.edtMinOrder.text.toString()), + "weight" to toRequestBody(binding.edtBeratProduk.text.toString()), + "is_pre_order" to toRequestBody(binding.switchIsPreOrder.isChecked.toString()), + "preorder_duration" to toRequestBody( + if (binding.switchIsPreOrder.isChecked) + binding.edtDurasi.text.toString() + else + "0" + ), + "is_wholesale" to toRequestBody(binding.switchIsWholesale.isChecked.toString()), + "wholesale_min_item" to toRequestBody( + if (binding.switchIsWholesale.isChecked) + binding.edtMinPesanGrosir.text.toString() + else + "0" + ), + "wholesale_price" to toRequestBody( + if (binding.switchIsWholesale.isChecked) + binding.edtHargaGrosir.text.toString() + else + "0" + ), + "category_id" to toRequestBody( + categoryList[binding.spinnerKategoriProduk.selectedItemPosition].id.toString() + ), + "status" to toRequestBody( + if (binding.switchIsActive.isChecked) "active" else "inactive" + ), + "condition" to toRequestBody(binding.spinnerKondisiProduk.selectedItem.toString()) + ) + + viewModel.updateProduct( + productId, + data, + imagePart, + halalPart, + sppirtPart ) - viewModel.updateProduct(productId, updatedProduct) viewModel.productUpdateResult.observe(this) { result -> when (result) { is Result.Loading -> binding.btnSaveProduct.isEnabled = false @@ -461,4 +490,7 @@ class DetailStoreProductActivity : AppCompatActivity() { } } } + + private fun toRequestBody(value: String): RequestBody = + RequestBody.create("text/plain".toMediaTypeOrNull(), value) } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/ProductViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/ProductViewModel.kt index 3f80593..e2d5611 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/ProductViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/ProductViewModel.kt @@ -17,6 +17,7 @@ import com.alya.ecommerce_serang.data.repository.ProductRepository import com.alya.ecommerce_serang.data.repository.Result import kotlinx.coroutines.launch import okhttp3.MultipartBody +import okhttp3.RequestBody class ProductViewModel(private val repository: ProductRepository) : ViewModel() { @@ -107,14 +108,20 @@ class ProductViewModel(private val repository: ProductRepository) : ViewModel() } } - fun updateProduct(productId: Int?, updatedProduct: Map) { - _productUpdateResult.value = Result.Loading + fun updateProduct( + productId: Int?, + data: Map, + image: MultipartBody.Part?, + halal: MultipartBody.Part?, + sppirt: MultipartBody.Part? + ) { viewModelScope.launch { + _productUpdateResult.postValue(Result.Loading) try { - val response = repository.updateProduct(productId, updatedProduct) - _productUpdateResult.value = Result.Success(response) + val response = repository.updateProduct(productId, data, image, halal, sppirt) + _productUpdateResult.postValue(Result.Success(response.body()!!)) } catch (e: Exception) { - _productUpdateResult.value = Result.Error(e) + _productUpdateResult.postValue(Result.Error(e)) } } }