diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index bba3e321a3861f73ac47f7d6bd7001208eb8b38e..2272f789944aba680437d791883e802dea47c956 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,6 +3,9 @@
 
     <uses-feature android:name="android.hardware.camera.any" />
 
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission
         android:name="android.permission.WRITE_EXTERNAL_STORAGE"
diff --git a/app/src/main/java/com/example/bondoman/MainApplication.kt b/app/src/main/java/com/example/bondoman/MainApplication.kt
index ba1311aaa4be2bafbfe761de781e88089cf347bf..5e736d3d5485ad046251c06d10b40ccdcdfd3af1 100644
--- a/app/src/main/java/com/example/bondoman/MainApplication.kt
+++ b/app/src/main/java/com/example/bondoman/MainApplication.kt
@@ -7,6 +7,7 @@ import com.example.bondoman.data.databases.TransactionDatabase
 
 class MainApplication : Application() {
 	lateinit var container: AppContainer
+
 	override fun onCreate() {
 		super.onCreate()
 		val database = TransactionDatabase.getInstance(applicationContext)
diff --git a/app/src/main/java/com/example/bondoman/data/dataaccess/TransactionDao.kt b/app/src/main/java/com/example/bondoman/data/dataaccess/TransactionDao.kt
index ff77ff3708c8122ef514ed250ea866cc08a17cbb..f795d8a85fba16282f9074831a4de965d97f9a6f 100644
--- a/app/src/main/java/com/example/bondoman/data/dataaccess/TransactionDao.kt
+++ b/app/src/main/java/com/example/bondoman/data/dataaccess/TransactionDao.kt
@@ -24,7 +24,7 @@ interface TransactionDao {
 		id: Long,
 		owner: String,
 		title: String,
-		amount: Double,
+		amount: Long,
 		location: String?,
 	)
 
diff --git a/app/src/main/java/com/example/bondoman/data/models/Transaction.kt b/app/src/main/java/com/example/bondoman/data/models/Transaction.kt
index 543459384f541c8502fdc69d77608da180590e90..9c47fd4c1e56abcc8e104783b2efdb9d983dddae 100644
--- a/app/src/main/java/com/example/bondoman/data/models/Transaction.kt
+++ b/app/src/main/java/com/example/bondoman/data/models/Transaction.kt
@@ -23,17 +23,17 @@ data class Transaction(
 	val title: String,
 	val owner: String,
 	val category: TransactionCategory,
-	val amount: Double,
+	val amount: Long,
 	val date: Date = Date(),
 	val location: String? = null,
 ) : Serializable {
 	init {
 		require(title.isNotEmpty()) { "Transaction " }
-		require(amount in -MAX_AMOUNT..MAX_AMOUNT) { "Amount cannot exceed $MAX_AMOUNT" }
+		require(amount in 0..MAX_AMOUNT) { "Amount cannot exceed $MAX_AMOUNT" }
 		require(location == null || location.isNotEmpty()) { "Location cannot be blank" }
 	}
 
 	companion object {
-		const val MAX_AMOUNT = Double.MAX_VALUE
+		const val MAX_AMOUNT = Long.MAX_VALUE
 	}
 }
diff --git a/app/src/main/java/com/example/bondoman/data/repositories/TransactionRepository.kt b/app/src/main/java/com/example/bondoman/data/repositories/TransactionRepository.kt
index 8e7b496876682b7addfc62a3cc9d258889c87925..a840fb70da0d869a3debe4257418c4b849e3b691 100644
--- a/app/src/main/java/com/example/bondoman/data/repositories/TransactionRepository.kt
+++ b/app/src/main/java/com/example/bondoman/data/repositories/TransactionRepository.kt
@@ -17,7 +17,7 @@ class TransactionRepository(private val transactionDao: TransactionDao) {
 		id: Long,
 		owner: String,
 		title: String,
-		amount: Double,
+		amount: Long,
 		location: String?,
 	) = transactionDao.update(id, owner, title, amount, location)
 
diff --git a/app/src/main/java/com/example/bondoman/data/utils/TransactionParser.kt b/app/src/main/java/com/example/bondoman/data/utils/TransactionParser.kt
index 363a75908eb2c3b815f1e1d500d9b05e8f2e6894..ba2c947167eb83ce7855b1d7c6df540b2495f2f1 100644
--- a/app/src/main/java/com/example/bondoman/data/utils/TransactionParser.kt
+++ b/app/src/main/java/com/example/bondoman/data/utils/TransactionParser.kt
@@ -1,9 +1,9 @@
 package com.example.bondoman.data.utils
 
+import com.example.bondoman.data.models.TransactionCategory
 import java.text.SimpleDateFormat
 import java.util.Date
 import java.util.Locale
-import kotlin.math.abs
 
 class TransactionParser {
 	companion object {
@@ -14,7 +14,7 @@ class TransactionParser {
 
 	private val dateFormat = SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH)
 
-	private fun formatIntegerString(integerString: String): String {
+	private fun formatAmountString(integerString: String): String {
 		val reversedString = integerString.reversed()
 		val formattedBuilder = StringBuilder()
 
@@ -32,13 +32,12 @@ class TransactionParser {
 		return dateFormat.format(date)
 	}
 
-	fun getAmountString(amount: Double): String {
-		val formattedAmount = String.format("%.2f", abs(amount))
-		val sign = if (amount < 0) "-" else ""
-		val parts = formattedAmount.split(".")
-		val integerPart = parts[0]
-		val decimalPart = parts.getOrElse(1) { "00" }
-		val integerFormatted = formatIntegerString(integerPart)
-		return "$sign Rp$integerFormatted,$decimalPart"
+	fun getAmountString(
+		amount: Long,
+		category: TransactionCategory,
+	): String {
+		val sign = if (category == TransactionCategory.EXPENSE) "-" else ""
+		val amountFormatted = formatAmountString(amount.toString())
+		return "$sign Rp$amountFormatted"
 	}
 }
diff --git a/app/src/main/java/com/example/bondoman/data/viewmodels/transaction/TransactionViewModel.kt b/app/src/main/java/com/example/bondoman/data/viewmodels/transaction/TransactionViewModel.kt
index 87c6b0c94d7ea89028c125f7da7cf6cf8c2f8f4f..64a4441a0c3ded721ccf2b2145c737c00a85dee8 100644
--- a/app/src/main/java/com/example/bondoman/data/viewmodels/transaction/TransactionViewModel.kt
+++ b/app/src/main/java/com/example/bondoman/data/viewmodels/transaction/TransactionViewModel.kt
@@ -42,7 +42,7 @@ class TransactionViewModel(
 	fun insertTransaction(
 		title: String,
 		category: TransactionCategory,
-		amount: Double,
+		amount: Long,
 		location: String?,
 	) {
 		try {
@@ -69,7 +69,7 @@ class TransactionViewModel(
 
 	fun updateCurrentTransaction(
 		title: String,
-		amount: Double,
+		amount: Long,
 		location: String,
 	) {
 	}
diff --git a/app/src/main/java/com/example/bondoman/views/adapters/TransactionListAdapter.kt b/app/src/main/java/com/example/bondoman/views/adapters/TransactionListAdapter.kt
index 0d8b7e2ecc881bb6eb4f40bddc6cb48e01731639..8446a9b14fc236707e54fad670cb1af74b0f16f0 100644
--- a/app/src/main/java/com/example/bondoman/views/adapters/TransactionListAdapter.kt
+++ b/app/src/main/java/com/example/bondoman/views/adapters/TransactionListAdapter.kt
@@ -72,7 +72,7 @@ class TransactionListAdapter(
 		)
 
 		holder.dateTextView.text = transactionParser.getDateString(item.date)
-		holder.amountTextView.text = transactionParser.getAmountString(item.amount)
+		holder.amountTextView.text = transactionParser.getAmountString(item.amount, item.category)
 		holder.titleTextView.text = item.title
 		holder.locationTextView.text = item.location ?: "Unknown"
 
diff --git a/app/src/main/java/com/example/bondoman/views/components/TextInputComponent.kt b/app/src/main/java/com/example/bondoman/views/components/TextInputComponent.kt
index 2f8e48db3a101ad8b038f7526c2aa0d39385e2fd..f5262780de4b67a9d56c36aa23101b145c255cc9 100644
--- a/app/src/main/java/com/example/bondoman/views/components/TextInputComponent.kt
+++ b/app/src/main/java/com/example/bondoman/views/components/TextInputComponent.kt
@@ -2,7 +2,9 @@ package com.example.bondoman.views.components
 
 import android.content.Context
 import android.text.Editable
+import android.text.InputType
 import android.text.TextWatcher
+import android.text.method.DigitsKeyListener
 import android.util.AttributeSet
 import android.view.LayoutInflater
 import android.widget.LinearLayout
@@ -35,11 +37,28 @@ class TextInputComponent
 			val attributes = context.obtainStyledAttributes(attrs, R.styleable.TextInputComponent)
 			val labelText = attributes.getString(R.styleable.TextInputComponent_textInputLabel) ?: ""
 			val hint = attributes.getString(R.styleable.TextInputComponent_textInputHint) ?: ""
+			val inputType =
+				attrs?.getAttributeIntValue(
+					"http://schemas.android.com/apk/res/android",
+					"inputType",
+					InputType.TYPE_CLASS_TEXT,
+				) ?: InputType.TYPE_CLASS_TEXT
+
+			val digits =
+				attrs?.getAttributeValue(
+					"http://schemas.android.com/apk/res/android",
+					"digits",
+				)
 			attributes.recycle()
 
-			// Set label text and hint
+			// Set attributes
 			labelTextView.text = labelText
 			inputEditText.hint = hint
+			inputEditText.inputType = inputType
+
+			if (digits != null) {
+				inputEditText.keyListener = DigitsKeyListener.getInstance(digits)
+			}
 
 			// Set up text watcher
 			inputEditText.addTextChangedListener(
diff --git a/app/src/main/java/com/example/bondoman/views/components/TransactionDetailComponent.kt b/app/src/main/java/com/example/bondoman/views/components/TransactionDetailComponent.kt
index 309b18d37feec2ea3c11a0a1bbe56b63619d342e..71e0ee550e62bf2adb96c86e4c42960606714964 100644
--- a/app/src/main/java/com/example/bondoman/views/components/TransactionDetailComponent.kt
+++ b/app/src/main/java/com/example/bondoman/views/components/TransactionDetailComponent.kt
@@ -117,7 +117,7 @@ class TransactionDetailComponent
 		fun setTransaction(transaction: Transaction) {
 			viewBinding.transactionDetailDate.text = transactionParser.getDateString(transaction.date)
 			viewBinding.transactionDetailAmount.text =
-				transactionParser.getAmountString(transaction.amount)
+				transactionParser.getAmountString(transaction.amount, transaction.category)
 			viewBinding.transactionDetailTitle.text = transaction.title
 			viewBinding.transactionDetailLocationText.text = transaction.location ?: "Unknown"
 
diff --git a/app/src/main/java/com/example/bondoman/views/fragments/TransactionAddFragment.kt b/app/src/main/java/com/example/bondoman/views/fragments/TransactionAddFragment.kt
index 31c4efb6a2cabe36c0f296a8798c3e154ddd649a..d3fd8be1f5ca1c6252a427d03014a335a4f316f0 100644
--- a/app/src/main/java/com/example/bondoman/views/fragments/TransactionAddFragment.kt
+++ b/app/src/main/java/com/example/bondoman/views/fragments/TransactionAddFragment.kt
@@ -4,9 +4,7 @@ import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
-import com.example.bondoman.R
 import com.example.bondoman.data.models.TransactionCategory
-import com.example.bondoman.views.components.TextInputComponent
 import java.util.Date
 
 class TransactionAddFragment : TransactionFormFragment() {
@@ -27,7 +25,7 @@ class TransactionAddFragment : TransactionFormFragment() {
 		category: TransactionCategory?,
 		date: Date?,
 		title: String,
-		amount: Double?,
+		amount: Long?,
 		location: String?,
 	) {
 		TODO("Not yet implemented")
@@ -41,7 +39,7 @@ class TransactionAddFragment : TransactionFormFragment() {
 		// Inflate the layout for this fragment
 		val view = super.onCreateView(inflater, container, savedInstanceState)!!
 
-		view.findViewById<TextInputComponent>(R.id.transaction_form_date).visibility = View.GONE
+		getBinding().transactionFormDate.visibility = View.GONE
 
 		return view
 	}
diff --git a/app/src/main/java/com/example/bondoman/views/fragments/TransactionFormFragment.kt b/app/src/main/java/com/example/bondoman/views/fragments/TransactionFormFragment.kt
index 6055d428e689e11d570527168209b487b0c34d0b..441612e4f911608abc503509da0dc1980f7c1694 100644
--- a/app/src/main/java/com/example/bondoman/views/fragments/TransactionFormFragment.kt
+++ b/app/src/main/java/com/example/bondoman/views/fragments/TransactionFormFragment.kt
@@ -1,11 +1,21 @@
 package com.example.bondoman.views.fragments
 
+import android.content.Context
+import android.content.pm.PackageManager
+import android.location.Location
+import android.location.LocationListener
+import android.location.LocationManager
+import android.os.Build
 import android.os.Bundle
+import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.AdapterView
 import android.widget.ArrayAdapter
+import android.widget.Toast
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.core.content.ContextCompat
 import androidx.fragment.app.Fragment
 import com.example.bondoman.R
 import com.example.bondoman.data.models.TransactionCategory
@@ -15,24 +25,95 @@ import com.example.bondoman.databinding.FragmentTransactionFormBinding
 import com.example.bondoman.views.utils.interfaces.ParentActivityService
 import com.example.bondoman.views.utils.interfaces.SecondaryFragment
 import java.util.Date
+import java.util.function.Consumer
 
 abstract class TransactionFormFragment : Fragment(), SecondaryFragment {
+	companion object {
+		private val REQUIRED_PERMISSIONS =
+			mutableListOf(
+				android.Manifest.permission.ACCESS_FINE_LOCATION,
+				android.Manifest.permission.ACCESS_COARSE_LOCATION,
+			).toTypedArray()
+	}
+
 	private lateinit var parentActivityService: ParentActivityService
 	private lateinit var binding: FragmentTransactionFormBinding
+	lateinit var locationManager: LocationManager
 
 	private var category: TransactionCategory? = null
-	private var date: Date? = null
 	private var title: String = ""
-	private var amount: Double? = null
+	private var date: Date? = null
+	private var amount: Long? = null
 	private var location: String? = null
+	private var currentGpsLocation: Location? = null
+	private var currentNetworkLocation: Location? = null
 
 	private val transactionParser = TransactionParser()
 
+	private val activityResultLauncher =
+		registerForActivityResult(
+			ActivityResultContracts.RequestMultiplePermissions(),
+		) { permissions ->
+			when {
+				permissions.getOrDefault(android.Manifest.permission.ACCESS_FINE_LOCATION, false) -> {
+					// Precise location access granted.
+					requestLocation()
+				}
+
+				permissions.getOrDefault(android.Manifest.permission.ACCESS_COARSE_LOCATION, false) -> {
+					// Only approximate location access granted.
+					requestLocation()
+				}
+
+				else -> {
+					Toast.makeText(
+						requireActivity().baseContext,
+						"Permission request denied",
+						Toast.LENGTH_SHORT,
+					).show()
+				}
+			}
+		}
+
+	private val gpsLocationListener: LocationListener =
+		object : LocationListener {
+			override fun onLocationChanged(location: Location) {
+				currentGpsLocation = location
+			}
+
+			override fun onStatusChanged(
+				provider: String,
+				status: Int,
+				extras: Bundle,
+			) {}
+
+			override fun onProviderEnabled(provider: String) {}
+
+			override fun onProviderDisabled(provider: String) {}
+		}
+
+	private val networkLocationListener: LocationListener =
+		object : LocationListener {
+			override fun onLocationChanged(location: Location) {
+				currentNetworkLocation = location
+			}
+
+			override fun onStatusChanged(
+				provider: String,
+				status: Int,
+				extras: Bundle,
+			) {}
+
+			override fun onProviderEnabled(provider: String) {}
+
+			override fun onProviderDisabled(provider: String) {}
+		}
+
 	protected abstract fun onTransactionSave(
 		category: TransactionCategory?,
 		date: Date?,
 		title: String,
-		amount: Double?,
+		amount: Long?,
 		location: String?,
 	)
 
@@ -55,9 +136,9 @@ abstract class TransactionFormFragment : Fragment(), SecondaryFragment {
 		binding.transactionFormDate.setText(transactionParser.getDateString(date))
 	}
 
-	protected fun setAmount(amount: Double) {
+	protected fun setAmount(amount: Long) {
 		this.amount = amount
-		binding.transactionFormAmount.setText(transactionParser.getAmountString(amount))
+		binding.transactionFormAmount.setText(amount.toString().split(".").first())
 	}
 
 	protected fun setLocation(location: String?) {
@@ -69,6 +150,8 @@ abstract class TransactionFormFragment : Fragment(), SecondaryFragment {
 		super.onCreate(savedInstanceState)
 
 		parentActivityService = requireActivity() as ParentActivityService
+		locationManager =
+			requireActivity().getSystemService(Context.LOCATION_SERVICE) as LocationManager
 	}
 
 	private fun configureDropdown() {
@@ -92,26 +175,151 @@ abstract class TransactionFormFragment : Fragment(), SecondaryFragment {
 			}
 	}
 
+	private val gpsLocationCallback =
+		Consumer<Location> { location ->
+			if (location != null) {
+				currentGpsLocation = location
+				changeLocationData()
+
+				Log.d("gps LOCAAAAA", currentGpsLocation.toString())
+			}
+		}
+
+	private val networkLocationCallback =
+		Consumer<Location> { location ->
+			if (location != null) {
+				currentNetworkLocation = location
+				changeLocationData()
+
+				Log.d("network LOCAAAAA", currentNetworkLocation.toString())
+			}
+		}
+
+	private fun changeLocationData() {
+		assert(currentGpsLocation != null || currentNetworkLocation != null)
+
+		var currentLocation: Location? = null
+
+		if (currentGpsLocation != null && currentNetworkLocation != null) {
+			currentLocation =
+				if (currentGpsLocation!!.accuracy >= currentNetworkLocation!!.accuracy) {
+					currentGpsLocation
+				} else {
+					currentNetworkLocation
+				}
+		} else if (currentGpsLocation != null) {
+			currentLocation = currentGpsLocation
+		} else if (currentNetworkLocation != null) {
+			currentLocation = currentNetworkLocation
+		}
+
+		location = currentLocation.toString()
+		binding.transactionFormLocationField.setText(currentLocation.toString())
+	}
+
+	private fun requestLocation() {
+		assert(
+			ContextCompat.checkSelfPermission(
+				requireContext(),
+				android.Manifest.permission.ACCESS_FINE_LOCATION,
+			) == PackageManager.PERMISSION_GRANTED ||
+				ContextCompat.checkSelfPermission(
+					requireContext(),
+					android.Manifest.permission.ACCESS_COARSE_LOCATION,
+				) == PackageManager.PERMISSION_GRANTED,
+		)
+
+		currentGpsLocation = null
+		currentNetworkLocation = null
+
+		val hasGps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
+		val hasNetwork = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
+
+		val currentApiVersion = Build.VERSION.SDK_INT
+
+		Log.d("HAS GPS", hasGps.toString())
+		Log.d("HAS NETWORK", hasNetwork.toString())
+
+		if (hasGps) {
+			if (currentApiVersion >= Build.VERSION_CODES.R) {
+				locationManager.getCurrentLocation(
+					LocationManager.GPS_PROVIDER,
+					null,
+					requireActivity().mainExecutor,
+					gpsLocationCallback,
+				)
+			} else {
+				locationManager.requestSingleUpdate(
+					LocationManager.GPS_PROVIDER,
+					gpsLocationListener,
+					null,
+				)
+			}
+		}
+
+		if (hasNetwork) {
+			if (currentApiVersion >= Build.VERSION_CODES.R) {
+				locationManager.getCurrentLocation(
+					LocationManager.NETWORK_PROVIDER,
+					null,
+					requireActivity().mainExecutor,
+					networkLocationCallback,
+				)
+			} else {
+				locationManager.requestSingleUpdate(
+					LocationManager.NETWORK_PROVIDER,
+					networkLocationListener,
+					null,
+				)
+			}
+		}
+
+		if (!hasGps and !hasNetwork) {
+			Toast.makeText(
+				requireActivity().baseContext,
+				"No provider to get location. Enable GPS",
+				Toast.LENGTH_SHORT,
+			).show()
+		}
+	}
+
 	private fun changeLocation() {
-		val currentLocation = "new"
-		location = currentLocation
-		binding.transactionFormLocationField.setText(currentLocation)
+		if (
+			ContextCompat.checkSelfPermission(
+				requireContext(),
+				android.Manifest.permission.ACCESS_FINE_LOCATION,
+			) != PackageManager.PERMISSION_GRANTED
+		) {
+			activityResultLauncher.launch(REQUIRED_PERMISSIONS)
+		} else {
+			requestLocation()
+		}
 	}
 
 	private fun configureInputFields() {
 		configureDropdown()
 
 		binding.transactionFormAutoComplete.onItemClickListener =
-			AdapterView.OnItemClickListener { parent, view, position, id ->
+			AdapterView.OnItemClickListener { parent, _, position, _ ->
 				val selectedItem = parent.getItemAtPosition(position).toString()
 				category = transactionCategoryMap[selectedItem]
 			}
 
-		binding.transactionFormTitle.setBeforeTextChangedListener { text, _, _, _ ->
+		binding.transactionFormTitle.setOnTextChangedListener { text, _, _, _ ->
 			title = text.toString()
 		}
 
 		// TODO: set text watcher for amount field
+		binding.transactionFormAmount.setOnTextChangedListener { text, _, _, _ ->
+			val textString = text.toString()
+
+			amount =
+				if (textString.isNotEmpty()) {
+					textString.toLong()
+				} else {
+					null
+				}
+		}
 
 		binding.transactionFormChangeLocationText.setOnClickListener {
 			changeLocation()
diff --git a/app/src/main/java/com/example/bondoman/views/fragments/TransactionListFragment.kt b/app/src/main/java/com/example/bondoman/views/fragments/TransactionListFragment.kt
index d5c7fb02694106bf9b679675e132a712efbde1c4..773ed23df5b5c296b15ceccab1580a37c6399ddc 100644
--- a/app/src/main/java/com/example/bondoman/views/fragments/TransactionListFragment.kt
+++ b/app/src/main/java/com/example/bondoman/views/fragments/TransactionListFragment.kt
@@ -41,7 +41,7 @@ class TransactionListFragment : Fragment(), TransactionClickListener {
 					title = "Transaction 2",
 					owner = "13521148",
 					category = TransactionCategory.EXPENSE,
-					amount = -20000.05,
+					amount = 200000000000000L,
 				),
 			)
 
diff --git a/app/src/main/java/com/example/bondoman/views/fragments/TransactionUpdateFragment.kt b/app/src/main/java/com/example/bondoman/views/fragments/TransactionUpdateFragment.kt
index 2b1eab038ced644b8c91030962486c2b08f49a70..0a4136bda88f2f85e39b408ab1a8bba4c965eed2 100644
--- a/app/src/main/java/com/example/bondoman/views/fragments/TransactionUpdateFragment.kt
+++ b/app/src/main/java/com/example/bondoman/views/fragments/TransactionUpdateFragment.kt
@@ -4,13 +4,10 @@ import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
-import android.widget.AutoCompleteTextView
 import androidx.navigation.fragment.navArgs
 import com.example.bondoman.R
 import com.example.bondoman.data.models.TransactionCategory
-import com.example.bondoman.views.components.TextInputComponent
 import com.example.bondoman.views.utils.interfaces.ParentActivityService
-import com.google.android.material.textfield.TextInputLayout
 import java.util.Date
 
 class TransactionUpdateFragment : TransactionFormFragment() {
@@ -35,7 +32,7 @@ class TransactionUpdateFragment : TransactionFormFragment() {
 		category: TransactionCategory?,
 		date: Date?,
 		title: String,
-		amount: Double?,
+		amount: Long?,
 		location: String?,
 	) {
 		TODO("Not yet implemented")
@@ -56,13 +53,11 @@ class TransactionUpdateFragment : TransactionFormFragment() {
 		val view = super.onCreateView(inflater, container, savedInstanceState)!!
 
 		// configure category dropdown
-		val textInputLayout =
-			view.findViewById<TextInputLayout>(R.id.transaction_form_category_dropdown)
+		val textInputLayout = getBinding().transactionFormCategoryDropdown
 		textInputLayout.hint = getString(R.string.hint_category)
 		textInputLayout.endIconDrawable = null
 
-		val autoCompleteTextView =
-			textInputLayout.findViewById<AutoCompleteTextView>(R.id.transaction_form_auto_complete)
+		val autoCompleteTextView = getBinding().transactionFormAutoComplete
 		autoCompleteTextView.dropDownHeight = 0
 
 		// fill input fields
@@ -74,7 +69,7 @@ class TransactionUpdateFragment : TransactionFormFragment() {
 		setLocation(currentTransaction.location)
 
 		// configure date input
-		val dateFieldComponent = view.findViewById<TextInputComponent>(R.id.transaction_form_date)
+		val dateFieldComponent = getBinding().transactionFormDate
 		dateFieldComponent.disable()
 		return view
 	}
diff --git a/app/src/main/res/layout/component_transaction_card.xml b/app/src/main/res/layout/component_transaction_card.xml
index f9771df49bf63771dd879eae19472ab33389ae0b..f63bf37d0dd9bc610793aadabd810d7e7d97f529 100644
--- a/app/src/main/res/layout/component_transaction_card.xml
+++ b/app/src/main/res/layout/component_transaction_card.xml
@@ -1,108 +1,117 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:background="@color/bg_main"
     android:layout_width="match_parent"
     android:layout_height="120dp"
-    android:padding="20dp"
-    android:layout_marginBottom="1dp">
+    android:layout_marginBottom="1dp"
+    android:background="@color/bg_main"
+    android:padding="20dp">
+
     <androidx.cardview.widget.CardView
         android:id="@+id/transaction_icon_card"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         app:cardCornerRadius="10dp"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
+        app:cardElevation="0dp"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:cardElevation="0dp">
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
         <ImageView
             android:id="@+id/transaction_icon_image"
             android:layout_width="40dp"
             android:layout_height="40dp"
             android:background="@color/rose_200"
             android:contentDescription="@string/desc_transaction_icon"
-            android:src="@drawable/ic_shopping_bag_minus"
-            android:scaleType="fitCenter"
             android:padding="5dp"
-            app:tint="@color/zinc_700"/>
+            android:scaleType="fitCenter"
+            android:src="@drawable/ic_shopping_bag_minus"
+            app:tint="@color/zinc_700" />
     </androidx.cardview.widget.CardView>
+
     <TextView
         android:id="@+id/date_text"
-        android:theme="@style/TextAppearance.Transaction.Date"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="@string/dummy_transaction_date"
+        android:theme="@style/TextAppearance.Transaction.Date"
+        app:layout_constraintBottom_toTopOf="@id/transaction_card_guideline2"
         app:layout_constraintLeft_toRightOf="@id/transaction_card_guideline1"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toTopOf="@id/transaction_card_guideline2"/>
+        app:layout_constraintTop_toTopOf="parent" />
+
     <TextView
         android:id="@+id/amount_text"
-        android:theme="@style/TextAppearance.Transaction.Amount"
-        android:maxWidth="200dp"
-        android:layout_width="wrap_content"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:text="@string/dummy_transaction_amount"
+        android:layout_marginLeft="20dp"
         android:ellipsize="end"
         android:maxLines="1"
+        android:text="@string/dummy_transaction_amount"
+        android:theme="@style/TextAppearance.Transaction.Amount"
+        app:layout_constraintBottom_toTopOf="@id/transaction_card_guideline2"
+        app:layout_constraintHorizontal_bias="1"
         app:layout_constraintLeft_toRightOf="@id/date_text"
         app:layout_constraintRight_toRightOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toTopOf="@id/transaction_card_guideline2"
-        app:layout_constraintHorizontal_bias="1"/>
+        app:layout_constraintTop_toTopOf="parent" />
+
     <TextView
         android:id="@+id/title_text"
-        android:theme="@style/TextAppearance.Transaction.Title"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:text="@string/dummy_transaction_title"
         android:ellipsize="end"
         android:maxLines="1"
-        app:layout_constraintStart_toEndOf="@id/transaction_card_guideline1"
-        app:layout_constraintTop_toBottomOf="@id/transaction_card_guideline2"
+        android:text="@string/dummy_transaction_title"
+        android:theme="@style/TextAppearance.Transaction.Title"
         app:layout_constraintBottom_toTopOf="@id/transaction_card_guideline3"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintHorizontal_bias="0"/>
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintStart_toEndOf="@id/transaction_card_guideline1"
+        app:layout_constraintTop_toBottomOf="@id/transaction_card_guideline2" />
+
     <ImageView
         android:id="@+id/transaction_location_icon_image"
         android:layout_width="18dp"
         android:layout_height="18dp"
         android:contentDescription="@string/desc_location_icon"
-        android:src="@drawable/ic_map_pin"
         android:scaleType="fitCenter"
+        android:src="@drawable/ic_map_pin"
+        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toEndOf="@id/transaction_card_guideline1"
         app:layout_constraintTop_toBottomOf="@id/transaction_card_guideline3"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:tint="@color/zinc_400"/>
+        app:tint="@color/zinc_400" />
+
     <TextView
         android:id="@+id/transaction_location_text"
-        android:theme="@style/TextAppearance.Transaction.Location"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_marginStart="5dp"
-        android:text="@string/dummy_transaction_location"
         android:ellipsize="end"
         android:maxLines="1"
-        app:layout_constraintStart_toEndOf="@id/transaction_location_icon_image"
-        app:layout_constraintTop_toBottomOf="@id/transaction_card_guideline3"
+        android:text="@string/dummy_transaction_location"
+        android:theme="@style/TextAppearance.Transaction.Location"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"/>
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@id/transaction_location_icon_image"
+        app:layout_constraintTop_toBottomOf="@id/transaction_card_guideline3" />
+
     <androidx.constraintlayout.widget.Guideline
         android:id="@+id/transaction_card_guideline1"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:orientation="vertical"
-        app:layout_constraintGuide_begin="60dp"/>
+        app:layout_constraintGuide_begin="60dp" />
+
     <androidx.constraintlayout.widget.Guideline
         android:id="@+id/transaction_card_guideline2"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
-        app:layout_constraintGuide_percent="0.33"/>
+        app:layout_constraintGuide_percent="0.33" />
+
     <androidx.constraintlayout.widget.Guideline
         android:id="@+id/transaction_card_guideline3"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
-        app:layout_constraintGuide_percent="0.66"/>
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
+        app:layout_constraintGuide_percent="0.66" />
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/fragment_transaction_form.xml b/app/src/main/res/layout/fragment_transaction_form.xml
index 2b2fd0bafd294e2fd8de585513df0bc00e7008d3..b640e3a9b85e7cbfb2efa4ce5de92ea66c1f44b3 100644
--- a/app/src/main/res/layout/fragment_transaction_form.xml
+++ b/app/src/main/res/layout/fragment_transaction_form.xml
@@ -49,6 +49,7 @@
         android:id="@+id/transaction_form_amount"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:inputType="number"
         app:textInputHint="@string/hint_transaction_form_amount"
         app:textInputLabel="Amount (Rp)" />
 
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index 74ce450a8e8c2a616d3a89b06cd56ed19b59b68a..9c80c19ece14f94b444c75aafd43de53074acd6b 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -15,30 +15,33 @@
         <attr name="borderBottomRightRadius" format="dimension" />
     </declare-styleable>
     <declare-styleable name="TextInputComponent">
-        <attr name="textInputLabel" format="string"/>
-        <attr name="textInputHint" format="string"/>
+        <attr name="textInputLabel" format="string" />
+        <attr name="textInputHint" format="string" />
+        <attr name="textInputType" format="string" />
+        <attr name="android:inputType" />
+        <attr name="android:digits" />
     </declare-styleable>
     <declare-styleable name="DateInputComponent">
-        <attr name="dateInputLabel" format="string"/>
+        <attr name="dateInputLabel" format="string" />
     </declare-styleable>
     <declare-styleable name="DialogComponent">
-        <attr name="dialogText" format="string"/>
-        <attr name="firstButtonText" format="string"/>
-        <attr name="secondButtonText" format="string"/>
+        <attr name="dialogText" format="string" />
+        <attr name="firstButtonText" format="string" />
+        <attr name="secondButtonText" format="string" />
         <attr name="dialogFirstButtonType" format="enum">
-            <enum name="positive" value="1"/>
-            <enum name="neutral" value="0"/>
-            <enum name="negative" value="-1"/>
+            <enum name="positive" value="1" />
+            <enum name="neutral" value="0" />
+            <enum name="negative" value="-1" />
         </attr>
         <attr name="dialogSecondButtonType" format="enum">
-            <enum name="positive" value="1"/>
-            <enum name="neutral" value="0"/>
-            <enum name="negative" value="-1"/>
+            <enum name="positive" value="1" />
+            <enum name="neutral" value="0" />
+            <enum name="negative" value="-1" />
         </attr>
     </declare-styleable>
     <declare-styleable name="SettingButtonComponent">
-        <attr name="settingButtonIcon" format="reference"/>
-        <attr name="settingButtonTitle" format="string"/>
-        <attr name="settingButtonSubtitle" format="string"/>
+        <attr name="settingButtonIcon" format="reference" />
+        <attr name="settingButtonTitle" format="string" />
+        <attr name="settingButtonSubtitle" format="string" />
     </declare-styleable>
 </resources>