diff --git a/app/src/main/java/com/example/android_hit/DetailTransaction.kt b/app/src/main/java/com/example/android_hit/DetailTransaction.kt index d279d5ad4aa6e4b580e7e85a40e3ce4998eeb171..4293baa13cbf06fa73f4e5f9aa97e8c5151057a7 100644 --- a/app/src/main/java/com/example/android_hit/DetailTransaction.kt +++ b/app/src/main/java/com/example/android_hit/DetailTransaction.kt @@ -2,7 +2,6 @@ package com.example.android_hit import android.Manifest import android.app.Activity -import android.app.AlertDialog import android.content.BroadcastReceiver import android.content.Context import android.content.Intent @@ -19,7 +18,6 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.EditText import android.widget.Toast import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat @@ -34,7 +32,6 @@ import com.google.android.gms.location.FusedLocationProviderClient import com.google.android.gms.location.LocationServices import com.google.android.gms.location.LocationSettingsRequest import com.google.android.gms.location.LocationSettingsStatusCodes -import com.google.android.material.textfield.TextInputLayout import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -44,9 +41,10 @@ class DetailTransaction : Fragment(), LocationListener { private val binding get() = _binding!! private lateinit var database: TransactionDB private var category: String = "" + private var coordinate: String = "-6.927314530264154, 107.77007155415649" + private var location: String = "" private lateinit var transactionReceiver: TransactionReceiver private val RANDOMIZE_ACTION = "com.example.android_hit.RANDOMIZE_ACTION" - private val LOCATION_PERMISSION_REQUEST_CODE = 1001 // Request code for location permission private lateinit var locationManager: LocationManager private lateinit var locationRequest: LocationRequest private lateinit var fusedLocationProviderClient: FusedLocationProviderClient @@ -90,10 +88,9 @@ class DetailTransaction : Fragment(), LocationListener { LocalBroadcastManager.getInstance(requireContext()).registerReceiver(transactionReceiver, filter) locationManager = requireContext().getSystemService(Context.LOCATION_SERVICE) as LocationManager - fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(requireContext()) - binding.inputLocation.setOnClickListener { + Log.d("Location", "Input location clicked") checkLocationPermission() } @@ -150,7 +147,9 @@ class DetailTransaction : Fragment(), LocationListener { binding.buttonSave.setOnClickListener { val title = binding.inputTitle.text.toString() val amount = binding.inputAmount.text.toString() - val location = binding.inputLocation.text.toString() + location = binding.inputLocation.text.toString() + Log.d("koordinat", "Coordinate: $coordinate") + Log.d("lokasi", "Location: $location") if (title.isNotEmpty() && amount.isNotEmpty() && location.isNotEmpty() && (binding.radioExpense.isChecked || binding.radioIncome.isChecked)) { try { @@ -161,9 +160,7 @@ class DetailTransaction : Fragment(), LocationListener { val transaction = database.transactionDao.getId(id) timestamp = transaction.timestamp - } - if (intent != null) { database.transactionDao.updateTransaction( TransactionEntity( intent.getInt("id", 0), @@ -171,6 +168,7 @@ class DetailTransaction : Fragment(), LocationListener { amount.toInt(), category, location, + coordinate, timestamp.toString() ) ) @@ -189,6 +187,7 @@ class DetailTransaction : Fragment(), LocationListener { amountValue, category, location, + coordinate, currentDateAndTime ) ) @@ -233,36 +232,18 @@ class DetailTransaction : Fragment(), LocationListener { Manifest.permission.ACCESS_FINE_LOCATION ) == PackageManager.PERMISSION_GRANTED ) { + Log.d("Location", "Permission granted") checkGPS() } else { - ActivityCompat.requestPermissions(requireActivity(), arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 100) + Log.d("Location", "Requesting location permission") + ActivityCompat.requestPermissions( + requireActivity(), + arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), + 44 + ) } } - private fun requestManualLocation() { - // Show dialog or dialogSheet to input manual address - // Example: - val input = EditText(requireContext()) - AlertDialog.Builder(requireContext()) - .setTitle("Manual Address Input") - .setMessage("Enter address manually:") - .setView(input) - .setPositiveButton("OK") { dialog, _ -> - val manualAddress = input.text.toString() - if (manualAddress.isNotBlank()) { - // Use manual address in transaction - binding.inputLocation.setText(manualAddress) - } else { - Toast.makeText(requireContext(), "Please enter a valid address", Toast.LENGTH_SHORT).show() - } - dialog.dismiss() - } - .setNegativeButton("Cancel") { dialog, _ -> - dialog.dismiss() - } - .show() - } - private fun getUserLocation() { if (ActivityCompat.checkSelfPermission( @@ -280,7 +261,6 @@ class DetailTransaction : Fragment(), LocationListener { // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. - requestManualLocation() return } fusedLocationProviderClient.lastLocation.addOnSuccessListener { task -> @@ -290,13 +270,15 @@ class DetailTransaction : Fragment(), LocationListener { if (location != null) { try { val geocoder = Geocoder(requireContext(), Locale.getDefault()) - val address = geocoder.getFromLocation(location.latitude, location.longitude, 1) - val address_line = address?.get(0)?.getAddressLine(0) + coordinate = "${location.latitude},${location.longitude}" binding.inputLocation.setText(address_line) + Log.d("Location", "Address: $address_line") + Log.d("Location", "Coordinate: $coordinate") + } catch (e: Exception) { e.printStackTrace() diff --git a/app/src/main/java/com/example/android_hit/Scan.kt b/app/src/main/java/com/example/android_hit/Scan.kt index addd17e967a5fadd8743102c2312c5ab64aa5356..e7d9bf304f975064da5dc47bff5fd093bfca4d07 100644 --- a/app/src/main/java/com/example/android_hit/Scan.kt +++ b/app/src/main/java/com/example/android_hit/Scan.kt @@ -215,6 +215,7 @@ class Scan : Fragment() { amount = amount.toInt(), category = "Expense", location = "Location", // Replace with actual location + coordinate = "0,0", // Replace with actual coordinate timestamp = System.currentTimeMillis().toString() // Replace with actual timestamp ) diff --git a/app/src/main/java/com/example/android_hit/Transaction.kt b/app/src/main/java/com/example/android_hit/Transaction.kt index ee32b6d9397ed1c1096cd8a2c9997f2fd7fca007..e1482e6e05720e0e06ce1f6071836d3fb9bf2d76 100644 --- a/app/src/main/java/com/example/android_hit/Transaction.kt +++ b/app/src/main/java/com/example/android_hit/Transaction.kt @@ -52,11 +52,14 @@ class Transaction : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) recyclerView = binding.rvTransaction + fab = binding.fabAdd + recyclerView.layoutManager = LinearLayoutManager(requireContext()) recyclerView.addItemDecoration( DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL) ) + adapter = TransactionAdapter(list) recyclerView.adapter = adapter fab.setOnClickListener { @@ -68,15 +71,13 @@ class Transaction : Fragment() { deleteTransaction(position) } }) + database = TransactionDB.getInstance(requireContext()) getData() - val totalExpenseAmount = database.transactionDao.getTotalExpense() - binding.amountExpense.text = totalExpenseAmount.toString() } private fun deleteTransaction(position: Int) { val deletedItem = list[position] - // Kurangi total expense amount jika transaksi yang dihapus memiliki kategori expense if (deletedItem.category == "Expense") { val expenseAmount = deletedItem.amount val currentTotalExpense = database.transactionDao.getTotalExpense() @@ -88,21 +89,25 @@ class Transaction : Fragment() { val newTotalIncome = currentTotalIncome - incomeAmount binding.amountIncome.text = newTotalIncome.toString() } - // Hapus transaksi dari database dan daftar transaksi database.transactionDao.deleteTransaction(deletedItem) list.removeAt(position) adapter.notifyItemRemoved(position) + getIncomeExpense() + } + + private fun getIncomeExpense() { + val currencyFormat = NumberFormat.getCurrencyInstance(Locale("id", "ID")) + val totalExpenseAmount = database.transactionDao.getTotalExpense() + val totalIncomeAmount = database.transactionDao.getTotalIncome() + binding.amountExpense.text = currencyFormat.format(totalExpenseAmount) + binding.amountIncome.text = currencyFormat.format(totalIncomeAmount) } private fun getData() { list.clear() list.addAll(database.transactionDao.getAllTransaction()) adapter.notifyDataSetChanged() - val totalExpenseAmount = database.transactionDao.getTotalExpense() - val currencyFormat = NumberFormat.getCurrencyInstance(Locale("id", "ID")) - binding.amountExpense.text = currencyFormat.format(totalExpenseAmount) - val totalIncomeAmount = database.transactionDao.getTotalIncome() - binding.amountIncome.text = currencyFormat.format(totalIncomeAmount) + getIncomeExpense() } override fun onResume() { diff --git a/app/src/main/java/com/example/android_hit/adapter/TransactionAdapter.kt b/app/src/main/java/com/example/android_hit/adapter/TransactionAdapter.kt index e6bb02d00c71d2a87fac4fbdf408c4eb3a66349f..66cc0a7b3a1b05d05de2bb795610a713445cb6a3 100644 --- a/app/src/main/java/com/example/android_hit/adapter/TransactionAdapter.kt +++ b/app/src/main/java/com/example/android_hit/adapter/TransactionAdapter.kt @@ -1,14 +1,20 @@ package com.example.android_hit.adapter import android.content.Intent +import android.location.Geocoder import android.net.Uri +import android.util.Log import android.view.LayoutInflater import android.view.ViewGroup +import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat.startActivity import androidx.recyclerview.widget.RecyclerView import com.example.android_hit.DetailTransactionActivity +import com.example.android_hit.R import com.example.android_hit.databinding.RowTransactionBinding import com.example.android_hit.room.TransactionEntity +import java.text.NumberFormat +import java.util.Locale class TransactionAdapter(private val list: MutableList<TransactionEntity>) : RecyclerView.Adapter<TransactionAdapter.TransactionViewHolder>() { @@ -16,11 +22,18 @@ class TransactionAdapter(private val list: MutableList<TransactionEntity>) : Rec fun bind(transaction: TransactionEntity) { binding.apply { title.text = transaction.title - amount.text = transaction.amount.toString() + val currencyFormat = NumberFormat.getCurrencyInstance(Locale("id", "ID")) + amount.text = currencyFormat.format(transaction.amount) category.text = transaction.category location.text = transaction.location date.text = transaction.timestamp + if (transaction.category == "Expense") { + category.setTextColor(ContextCompat.getColor(itemView.context, R.color.secondary4)) + } else { + category.setTextColor(ContextCompat.getColor(itemView.context, R.color.secondary5)) + } + deleteButton.setOnClickListener { val position = adapterPosition onDeleteClickListener?.onDeleteClick(position) @@ -33,10 +46,18 @@ class TransactionAdapter(private val list: MutableList<TransactionEntity>) : Rec } location.setOnClickListener { - val locationUri = "geo:0,0?q=${transaction.location}" - val mapIntent = Intent(Intent.ACTION_VIEW, Uri.parse(locationUri)) - mapIntent.setPackage("com.google.android.apps.maps") - startActivity(binding.root.context, mapIntent, null) + Log.d("Masuk klik Location", transaction.location) + if (transaction.coordinate != "-6.927314530264154, 107.77007155415649") { + val locationUri = "geo:0,0?q=${transaction.location}" + val mapIntent = Intent(Intent.ACTION_VIEW, Uri.parse(locationUri)) + mapIntent.setPackage("com.google.android.apps.maps") + startActivity(binding.root.context, mapIntent, null) + } else { + val locationUri = "geo:0,0?q=${transaction.coordinate}" + val mapIntent = Intent(Intent.ACTION_VIEW, Uri.parse(locationUri)) + mapIntent.setPackage("com.google.android.apps.maps") + startActivity(binding.root.context, mapIntent, null) + } } } } diff --git a/app/src/main/java/com/example/android_hit/room/TransactionDB.kt b/app/src/main/java/com/example/android_hit/room/TransactionDB.kt index a7e316cb86bf70b7608f53c85a8268c49d82adbe..172598b297ef53f3a8a3111265ccb9490b2abc52 100644 --- a/app/src/main/java/com/example/android_hit/room/TransactionDB.kt +++ b/app/src/main/java/com/example/android_hit/room/TransactionDB.kt @@ -7,7 +7,7 @@ import androidx.room.RoomDatabase @Database( entities = [TransactionEntity::class], - version = 5, + version = 6, exportSchema = false ) abstract class TransactionDB : RoomDatabase() { diff --git a/app/src/main/java/com/example/android_hit/room/TransactionEntity.kt b/app/src/main/java/com/example/android_hit/room/TransactionEntity.kt index 4fb6391189fb4799ecb1bcb0af7b032d900649b8..7ece1a50b79e2d6230856e000cdd28deb8cfd39b 100644 --- a/app/src/main/java/com/example/android_hit/room/TransactionEntity.kt +++ b/app/src/main/java/com/example/android_hit/room/TransactionEntity.kt @@ -11,5 +11,6 @@ class TransactionEntity ( @ColumnInfo(name = "amount") val amount : Int, @ColumnInfo(name = "category") val category : String, @ColumnInfo(name = "location") val location : String, + @ColumnInfo(name = "coordinate") val coordinate: String, @ColumnInfo(name = "timestamp") val timestamp: String ) \ No newline at end of file diff --git a/app/src/main/res/layout-land/fragment_detail_transaction.xml b/app/src/main/res/layout-land/fragment_detail_transaction.xml index 429f1adc556073db835e06ba712cec7206a94112..9bed128a3bcfbbe8e9452dbc3a2730297114f2de 100644 --- a/app/src/main/res/layout-land/fragment_detail_transaction.xml +++ b/app/src/main/res/layout-land/fragment_detail_transaction.xml @@ -81,7 +81,8 @@ android:layout_height="wrap_content" android:layout_marginRight="24dp" android:text="Income" - android:textSize="24sp" /> + android:textSize="24sp" + android:textColor="@color/primary_color_1"/> <RadioButton android:id="@+id/radioExpense" @@ -89,7 +90,8 @@ android:layout_height="wrap_content" android:layout_marginLeft="24dp" android:text="Expense" - android:textSize="24sp" /> + android:textSize="24sp" + android:textColor="@color/primary_color_1"/> </RadioGroup> <TextView diff --git a/app/src/main/res/layout/fragment_detail_transaction.xml b/app/src/main/res/layout/fragment_detail_transaction.xml index 348b0f88eed34695cad30ff900794141e339d0a0..617269914565b8649c9ccf8f94730c254d2e4f7c 100644 --- a/app/src/main/res/layout/fragment_detail_transaction.xml +++ b/app/src/main/res/layout/fragment_detail_transaction.xml @@ -53,7 +53,8 @@ android:layout_height="wrap_content" android:inputType="textPersonName" android:padding="8dp" - android:textSize="36sp" /> + android:textSize="36sp" + android:gravity="end"/> </com.google.android.material.textfield.TextInputLayout> <TextView @@ -77,7 +78,7 @@ android:layout_height="wrap_content" android:layout_marginRight="24dp" android:text="Income" - android:textSize="24sp" /> + android:textSize="24sp"/> <RadioButton android:id="@+id/radioExpense" @@ -85,7 +86,7 @@ android:layout_height="wrap_content" android:layout_marginLeft="24dp" android:text="Expense" - android:textSize="24sp" /> + android:textSize="24sp"/> </RadioGroup> <TextView diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index fd194862f96cc5afabca08f3b27f813053db3a6f..ec35c5ced0b731b0b4bc9a239f3bf3bb7d930ff5 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -15,4 +15,5 @@ <color name="secondary2">#47455B</color> <color name="secondary3">#095BFA</color> <color name="secondary4">#D65C5C</color> + <color name="secondary5">#2DA039</color> </resources> \ No newline at end of file