diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index a79da3eada321358d21e6086d5fda1c08f7b88e0..ae2f3131c513f71950115534b8b2d369d43f2e28 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -17,6 +17,10 @@ android {
         versionName = "1.0"
 
         testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+
+        ksp {
+            arg("room.schemaLocation", "$projectDir/schemas")
+        }
     }
 
     buildTypes {
@@ -69,4 +73,7 @@ dependencies {
 
     implementation("androidx.camera:camera-view:${camerax_version}")
     implementation("androidx.camera:camera-extensions:${camerax_version}")
+
+    implementation("com.google.android.gms:play-services-maps:18.1.0")
+    implementation("com.google.android.libraries.places:places:2.5.0")
 }
\ No newline at end of file
diff --git a/app/schemas/com.example.bondoman.database.AppDatabase/1.json b/app/schemas/com.example.bondoman.database.AppDatabase/1.json
new file mode 100644
index 0000000000000000000000000000000000000000..5ec7dc09e5ff35c6e165e1d9a692a38914d5560c
--- /dev/null
+++ b/app/schemas/com.example.bondoman.database.AppDatabase/1.json
@@ -0,0 +1,64 @@
+{
+  "formatVersion": 1,
+  "database": {
+    "version": 1,
+    "identityHash": "fadf0257d3b7363213c2692248f23c6b",
+    "entities": [
+      {
+        "tableName": "transactions",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `category` TEXT NOT NULL, `amount` INTEGER NOT NULL, `location` TEXT NOT NULL, `timestamp` TEXT NOT NULL)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "id",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "title",
+            "columnName": "title",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "category",
+            "columnName": "category",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "amount",
+            "columnName": "amount",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "location",
+            "columnName": "location",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "timestamp",
+            "columnName": "timestamp",
+            "affinity": "TEXT",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "columnNames": [
+            "id"
+          ],
+          "autoGenerate": true
+        },
+        "indices": [],
+        "foreignKeys": []
+      }
+    ],
+    "views": [],
+    "setupQueries": [
+      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'fadf0257d3b7363213c2692248f23c6b')"
+    ]
+  }
+}
\ No newline at end of file
diff --git a/app/schemas/com.example.bondoman.database.AppDatabase/2.json b/app/schemas/com.example.bondoman.database.AppDatabase/2.json
new file mode 100644
index 0000000000000000000000000000000000000000..5e43c0ff99e2065d03b933de057ee7e137c98cd6
--- /dev/null
+++ b/app/schemas/com.example.bondoman.database.AppDatabase/2.json
@@ -0,0 +1,70 @@
+{
+  "formatVersion": 1,
+  "database": {
+    "version": 2,
+    "identityHash": "0c38aca315bc7b70ca59650db5dda354",
+    "entities": [
+      {
+        "tableName": "transactions",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `category` TEXT NOT NULL, `amount` INTEGER NOT NULL, `latitude` REAL, `longitude` REAL, `timestamp` TEXT NOT NULL)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "id",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "title",
+            "columnName": "title",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "category",
+            "columnName": "category",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "amount",
+            "columnName": "amount",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "latitude",
+            "columnName": "latitude",
+            "affinity": "REAL",
+            "notNull": false
+          },
+          {
+            "fieldPath": "longitude",
+            "columnName": "longitude",
+            "affinity": "REAL",
+            "notNull": false
+          },
+          {
+            "fieldPath": "timestamp",
+            "columnName": "timestamp",
+            "affinity": "TEXT",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "columnNames": [
+            "id"
+          ],
+          "autoGenerate": true
+        },
+        "indices": [],
+        "foreignKeys": []
+      }
+    ],
+    "views": [],
+    "setupQueries": [
+      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '0c38aca315bc7b70ca59650db5dda354')"
+    ]
+  }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e849b22f2e7d0bda3833c6832feec52961bb57df..0a842620b0d1eb4d5e5e51fdcbb05d8ed2da7063 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -8,6 +8,8 @@
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
 
     <application
         android:name=".BondomanApp"
@@ -32,7 +34,7 @@
         <activity android:name=".ui.login.LoginActivity"/>
         <activity android:name=".ui.transaction.TransactionActivity"/>
 
-        <provider
+    <provider
             android:name="androidx.core.content.FileProvider"
             android:authorities="${applicationId}.provider"
             android:exported="false"
diff --git a/app/src/main/java/com/example/bondoman/BondomanApp.kt b/app/src/main/java/com/example/bondoman/BondomanApp.kt
index e8231b8f7e97e31027b557ce5064a0b4eefc7ecb..e95390f5cddf71c499b69340d1d97aee4bfa45df 100644
--- a/app/src/main/java/com/example/bondoman/BondomanApp.kt
+++ b/app/src/main/java/com/example/bondoman/BondomanApp.kt
@@ -2,6 +2,7 @@ package com.example.bondoman
 
 import android.app.Application
 import android.content.IntentFilter
+import android.os.Build
 import com.example.bondoman.database.AppDatabase
 import com.example.bondoman.ui.transaction.RandomBroadcastReceiver
 
@@ -13,7 +14,12 @@ class BondomanApp : Application() {
         AppDatabase.getInstance(this)
 
         val filter = IntentFilter(ACTION_RANDOM_TRANSACTION)
-        registerReceiver(randomReceiver, filter)
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+            registerReceiver(randomReceiver, filter, RECEIVER_EXPORTED)
+        } else {
+            registerReceiver(randomReceiver, filter)
+        }
     }
 
     // Global statics should be here
diff --git a/app/src/main/java/com/example/bondoman/database/AppDatabase.kt b/app/src/main/java/com/example/bondoman/database/AppDatabase.kt
index 0a8c58151c5d3c03c6e3d682df7e09d8320aa660..e1cf59f81ff0aee436645e7e5f411aa6f50e7fe6 100644
--- a/app/src/main/java/com/example/bondoman/database/AppDatabase.kt
+++ b/app/src/main/java/com/example/bondoman/database/AppDatabase.kt
@@ -1,16 +1,34 @@
 package com.example.bondoman.database
 
 import android.content.Context
+import androidx.room.AutoMigration
 import androidx.room.Database
+import androidx.room.DeleteColumn
 import androidx.room.Room
 import androidx.room.RoomDatabase
+import androidx.room.migration.AutoMigrationSpec
 import com.example.bondoman.database.dao.TransactionDao
 import com.example.bondoman.database.entity.TransactionEntity
 
-@Database(entities = [TransactionEntity::class], version = 1, exportSchema = false)
+@Database(
+    entities = [TransactionEntity::class],
+    version = 2,
+    exportSchema = true,
+    autoMigrations = [
+        AutoMigration (
+            from = 1,
+            to = 2,
+            spec = AppDatabase.MyAutoMigration::class
+        )
+    ]
+)
 abstract class AppDatabase : RoomDatabase() {
     abstract val transactionDao: TransactionDao
 
+    // Migration
+    @DeleteColumn(tableName = "transactions", columnName = "location")
+    class MyAutoMigration : AutoMigrationSpec
+
     // Static Instance
     companion object {
         @Volatile
diff --git a/app/src/main/java/com/example/bondoman/database/entity/TransactionEntity.kt b/app/src/main/java/com/example/bondoman/database/entity/TransactionEntity.kt
index e21f2dae908b0d72aaa162fb57a3865921e2ba5c..51a1b629aefce5df552d81af4b9675f72209cc37 100644
--- a/app/src/main/java/com/example/bondoman/database/entity/TransactionEntity.kt
+++ b/app/src/main/java/com/example/bondoman/database/entity/TransactionEntity.kt
@@ -1,5 +1,6 @@
 package com.example.bondoman.database.entity
 
+import androidx.annotation.Nullable
 import androidx.room.ColumnInfo
 import androidx.room.Entity
 import androidx.room.PrimaryKey
@@ -18,8 +19,13 @@ data class TransactionEntity (
     @ColumnInfo(name = "amount")
     var amount: Int,
 
-    @ColumnInfo(name = "location")
-    var location: String,
+    @ColumnInfo(name = "latitude")
+    @Nullable
+    val latitude: Double?,
+
+    @ColumnInfo(name = "longitude")
+    @Nullable
+    val longitude: Double?,
 
     @ColumnInfo(name = "timestamp")
     val timestamp: String,
diff --git a/app/src/main/java/com/example/bondoman/database/repository/TransactionRepository.kt b/app/src/main/java/com/example/bondoman/database/repository/TransactionRepository.kt
index b7339e16287f8ba68fc06f45316ad4343aacc933..e86553243eee8ed104049e1d19ae4a574d46920f 100644
--- a/app/src/main/java/com/example/bondoman/database/repository/TransactionRepository.kt
+++ b/app/src/main/java/com/example/bondoman/database/repository/TransactionRepository.kt
@@ -61,7 +61,9 @@ class TransactionRepository(private val transactionDao: TransactionDao) {
                         // TODO: Category
                         category = "scanned", amount = item.qty * item.price.toInt(),
                         // TODO: Location
-                        location = "lokasi", timestamp = SimpleDateFormat(
+                        latitude = null,
+                        longitude = null,
+                        timestamp = SimpleDateFormat(
                             "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
                         ).format(
                             Date()
diff --git a/app/src/main/java/com/example/bondoman/types/util/ExcelUtil.kt b/app/src/main/java/com/example/bondoman/types/util/ExcelUtil.kt
index ef89d93c1e157f2805e72381cd765b159531d954..4ffaa6770661c4abf231c15991d4c51f84055479 100644
--- a/app/src/main/java/com/example/bondoman/types/util/ExcelUtil.kt
+++ b/app/src/main/java/com/example/bondoman/types/util/ExcelUtil.kt
@@ -46,7 +46,8 @@ class ExcelUtil(val context: Context) {
             context.getString(R.string.transaction_label_title),
             context.getString(R.string.transaction_label_category),
             context.getString(R.string.transaction_label_amount),
-            context.getString(R.string.transaction_label_location),
+            context.getString(R.string.latitude),
+            context.getString(R.string.longitude),
             context.getString(R.string.transaction_label_timestamp)
         )
 
@@ -84,10 +85,14 @@ class ExcelUtil(val context: Context) {
             cell.cellStyle = cellStyle
 
             cell = row.createCell(4)
-            cell.setCellValue(transaction.location)
+            transaction.latitude?.let { cell.setCellValue(it) }
             cell.cellStyle = cellStyle
 
             cell = row.createCell(5)
+            transaction.longitude?.let { cell.setCellValue(it) }
+            cell.cellStyle = cellStyle
+
+            cell = row.createCell(6)
             cell.setCellValue(transaction.timestamp)
             cell.cellStyle = cellStyle
         }
diff --git a/app/src/main/java/com/example/bondoman/ui/hub/settings/SettingsFragment.kt b/app/src/main/java/com/example/bondoman/ui/hub/settings/SettingsFragment.kt
index 058bbb542c755e0c1aa1e9fcb47b77e3dd19b178..66ec5ff90de0b2e0634421cdad1854f48c2f56e5 100644
--- a/app/src/main/java/com/example/bondoman/ui/hub/settings/SettingsFragment.kt
+++ b/app/src/main/java/com/example/bondoman/ui/hub/settings/SettingsFragment.kt
@@ -127,7 +127,7 @@ class SettingsFragment : Fragment(), ExcelDialogFragment.ExcelDialogListener {
                 emailIntent.type = "text/plain"
                 emailIntent.putExtra(Intent.EXTRA_EMAIL, emailRecipient)
                 emailIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.email_subject))
-                emailIntent.putExtra(Intent.EXTRA_TEXT, getString(R.string.email_text) + SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date()))
+                emailIntent.putExtra(Intent.EXTRA_TEXT, "${getString(R.string.email_text)} ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date())}")
                 emailIntent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(requireContext(), requireContext().packageName + ".provider", file))
                 emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
 
diff --git a/app/src/main/java/com/example/bondoman/ui/hub/stats/StatsFragment.kt b/app/src/main/java/com/example/bondoman/ui/hub/stats/StatsFragment.kt
index 966d3dc3b60e85dd190405b58664c704d06d83d3..20c8d9ecaecfd02efe4ee8fccbeb6aef4c5468f4 100644
--- a/app/src/main/java/com/example/bondoman/ui/hub/stats/StatsFragment.kt
+++ b/app/src/main/java/com/example/bondoman/ui/hub/stats/StatsFragment.kt
@@ -55,25 +55,32 @@ class StatsFragment : Fragment() {
     }
 
     private fun setupChart() {
-        binding.pieChart.setUsePercentValues(true)
-        binding.pieChart.description.isEnabled = false
-        binding.pieChart.setExtraOffsets(5f, 3f, 5f, 3f)
-        binding.pieChart.dragDecelerationFrictionCoef = 0.95f
-
-        binding.pieChart.isDrawHoleEnabled = true
-        binding.pieChart.setHoleColor(ContextCompat.getColor(requireActivity(), R.color.white))
-        binding.pieChart.holeRadius = 50f
-        binding.pieChart.setDrawCenterText(true)
-
-        binding.pieChart.rotationAngle = 0f
-        binding.pieChart.isRotationEnabled = true
-        binding.pieChart.isHighlightPerTapEnabled = true
-        binding.pieChart.animateY(1400, Easing.EaseInOutQuad)
-
-        binding.pieChart.legend.isEnabled = true
-        binding.pieChart.legend.horizontalAlignment = Legend.LegendHorizontalAlignment.CENTER
-        binding.pieChart.setEntryLabelColor(ContextCompat.getColor(requireActivity(), R.color.white))
-        binding.pieChart.setEntryLabelTextSize(12f)
+        binding.pieChart.apply {
+            setUsePercentValues(true)
+            description.isEnabled = false
+            setExtraOffsets(5f, 3f, 5f, 3f)
+            dragDecelerationFrictionCoef = 0.95f
+
+            isDrawHoleEnabled = true
+            setHoleColor(ContextCompat.getColor(requireActivity(), R.color.white))
+            holeRadius = 50f
+            setDrawCenterText(true)
+
+            rotationAngle = 0f
+            isRotationEnabled = true
+            isHighlightPerTapEnabled = true
+            animateY(1400, Easing.EaseInOutQuad)
+
+            legend.isEnabled = true
+            legend.horizontalAlignment = Legend.LegendHorizontalAlignment.CENTER
+            setEntryLabelColor(
+                ContextCompat.getColor(
+                    requireActivity(),
+                    R.color.white
+                )
+            )
+            setEntryLabelTextSize(12f)
+        }
     }
 
     private fun observeChart(tsList: List<TransactionEntity>) {
diff --git a/app/src/main/java/com/example/bondoman/ui/hub/transaction/TransactionAdapter.kt b/app/src/main/java/com/example/bondoman/ui/hub/transaction/TransactionAdapter.kt
index 3512b5429264953e9cf056488e3d76391a0a0bc8..e9dc39a0aa9056d117ee5b79a9fa6b98c86b2869 100644
--- a/app/src/main/java/com/example/bondoman/ui/hub/transaction/TransactionAdapter.kt
+++ b/app/src/main/java/com/example/bondoman/ui/hub/transaction/TransactionAdapter.kt
@@ -4,6 +4,7 @@ import android.content.Context
 import android.content.Intent
 import android.net.Uri
 import android.view.LayoutInflater
+import android.view.View
 import android.view.ViewGroup
 import androidx.fragment.app.DialogFragment
 import androidx.fragment.app.FragmentManager
@@ -45,16 +46,29 @@ class TransactionAdapter(
             tvAmount.text = amount
 
             // TODO: Reverse Geocoding
-            tvLocation.text = tsList[position].location
+            var locStr = context.getString(R.string.no_location_data)
+            if (tsList[position].latitude != null && tsList[position].longitude != null) {
+                locStr = "(${tsList[position].latitude}, ${tsList[position].longitude})"
+
+                btnLocation.visibility = View.VISIBLE
+                tvLocation.visibility = View.VISIBLE
+                locationIcon.visibility = View.VISIBLE
+            } else {
+                btnLocation.visibility = View.GONE
+                tvLocation.visibility = View.GONE
+                locationIcon.visibility = View.GONE
+            }
 
             btnLocation.setOnClickListener {
-                // TODO: location
-                val gmapsIntentUri = Uri.parse("geo:46.414382,10.013988")
+                val gmapsIntentUri = Uri.parse("geo:${tsList[position].latitude}, ${tsList[position].longitude}")
                 val mapIntent = Intent(Intent.ACTION_VIEW, gmapsIntentUri)
                 mapIntent.setPackage("com.google.android.apps.maps")
                 context.startActivity(mapIntent)
             }
 
+            tvLocation.text = locStr
+
+
             btnEdit.setOnClickListener {
                 val intent = Intent(context, TransactionActivity::class.java)
                 intent.putExtra(TransactionActivity.KEY_ACTION, TransactionActivity.ACTION_EDIT)
@@ -64,7 +78,7 @@ class TransactionAdapter(
                 intent.putExtra(TransactionActivity.KEY_TITLE, tsList[position].title)
                 intent.putExtra(TransactionActivity.KEY_AMOUNT, tsList[position].amount)
                 intent.putExtra(TransactionActivity.KEY_CATEGORY, context.resources.getStringArray(R.array.category_choices).indexOf(tsList[position].category))
-                intent.putExtra(TransactionActivity.KEY_LOCATION, tsList[position].location)
+                intent.putExtra(TransactionActivity.KEY_LOCATION, locStr)
                 intent.putExtra(TransactionActivity.KEY_TIMESTAMP, tsList[position].timestamp)
 
                 context.startActivity(intent)
diff --git a/app/src/main/java/com/example/bondoman/ui/transaction/TransactionActivity.kt b/app/src/main/java/com/example/bondoman/ui/transaction/TransactionActivity.kt
index 4d0029ef2cc597299266642286dccd45d09f76bd..fca3c0cd34040546af05042a60f6a4333221da85 100644
--- a/app/src/main/java/com/example/bondoman/ui/transaction/TransactionActivity.kt
+++ b/app/src/main/java/com/example/bondoman/ui/transaction/TransactionActivity.kt
@@ -1,10 +1,14 @@
 package com.example.bondoman.ui.transaction
 
+import android.Manifest
+import android.content.pm.PackageManager
+import android.location.Location
 import android.os.Bundle
 import android.view.View
 import android.widget.TextView
 import android.widget.Toast
 import androidx.appcompat.app.AppCompatActivity
+import androidx.core.app.ActivityCompat
 import androidx.core.content.ContextCompat
 import androidx.lifecycle.ViewModelProvider
 import com.example.bondoman.R
@@ -12,8 +16,12 @@ import com.example.bondoman.database.AppDatabase
 import com.example.bondoman.database.entity.TransactionEntity
 import com.example.bondoman.database.repository.TransactionRepository
 import com.example.bondoman.databinding.ActivityTransactionBinding
+import com.example.bondoman.viewmodel.transaction.LocationViewModel
+import com.example.bondoman.viewmodel.transaction.LocationViewModelFactory
 import com.example.bondoman.viewmodel.transaction.TransactionViewModel
 import com.example.bondoman.viewmodel.transaction.TransactionViewModelFactory
+import com.google.android.gms.location.FusedLocationProviderClient
+import com.google.android.gms.location.LocationServices
 import java.text.SimpleDateFormat
 import java.util.Date
 import java.util.Locale
@@ -23,6 +31,11 @@ class TransactionActivity : AppCompatActivity() {
     private lateinit var transactionViewModel: TransactionViewModel
     private var actionCode: Int = 0
     private var transactionId: Int = 0
+    
+    private lateinit var fusedLocationClient: FusedLocationProviderClient
+    private lateinit var locationViewModel: LocationViewModel
+    private var savedLat: Double? = null
+    private var savedLng: Double? = null
 
     override fun onCreate(savedInstanceState: Bundle?){
         super.onCreate(savedInstanceState)
@@ -36,9 +49,32 @@ class TransactionActivity : AppCompatActivity() {
         val transactionModelFactory = TransactionViewModelFactory(transactionRepo)
         transactionViewModel = ViewModelProvider(this, transactionModelFactory)[TransactionViewModel::class.java]
 
+        // Location VM
+        val locationModelFactory = LocationViewModelFactory()
+        locationViewModel = ViewModelProvider(this, locationModelFactory)[LocationViewModel::class.java]
+        locationViewModel.location.observe(this) {
+            observeLocation(it)
+        }
+
         // Initialize header
         binding.header.navTitle.text = getString(R.string.hub_nav_transaction)
         val backButton = binding.header.navBackButton
+        backButton.setOnClickListener(::onBackClick)
+
+        // Initialize category dropdown
+        val spinner = binding.categoryInput
+        spinner.setSelection(0, true);
+        (spinner.selectedView as TextView).setTextColor(ContextCompat.getColor(this, R.color.black))
+
+        // Locate button
+        val locateButton = binding.btnLocate
+        locateButton.setOnClickListener(::onLocateClick)
+
+        // Delete button
+        val deleteButton = binding.btnDelete
+        deleteButton.setOnClickListener(::onDeleteClick)
+
+        // Initialize category dropdown
         val submitButton = binding.submitButton
         backButton.setOnClickListener(::onBackClick)
         submitButton.setOnClickListener(::onSubmitClick)
@@ -47,12 +83,12 @@ class TransactionActivity : AppCompatActivity() {
         val titleInitial = intent.getStringExtra(KEY_TITLE)
         val amountInitial = intent.getIntExtra(KEY_AMOUNT, 0)
         val categoryInitial = intent.getIntExtra(KEY_CATEGORY, 0)
-        val locationInitial = intent.getStringExtra(KEY_LOCATION)
+        var locationInitial = intent.getStringExtra(KEY_LOCATION)
 
         binding.titleInput.setText(titleInitial)
         binding.amountInput.setText(amountInitial.toString())
         binding.categoryInput.setSelection(categoryInitial, true)
-        binding.locationInput.setText(locationInitial)
+        binding.locationText.text = locationInitial
 
         // Initialize category dropdown color
         (binding.categoryInput.selectedView as TextView).setTextColor(ContextCompat.getColor(this, R.color.black))
@@ -61,6 +97,63 @@ class TransactionActivity : AppCompatActivity() {
         transactionId = intent.getIntExtra(KEY_TRANSACTION_ID, 0)
 
         if(actionCode == ACTION_EDIT) binding.categoryInput.isEnabled = false
+
+        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
+    }
+
+    private fun onDeleteClick(view: View) {
+        locationViewModel.setLoc(null, null)
+    }
+
+    private fun onLocateClick(view: View) {
+        getLastLocation()
+    }
+
+    private fun getLastLocation() {
+        if (ActivityCompat.checkSelfPermission(
+                this,
+                Manifest.permission.ACCESS_FINE_LOCATION
+            ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
+                this,
+                Manifest.permission.ACCESS_COARSE_LOCATION
+            ) != PackageManager.PERMISSION_GRANTED
+        ) {
+            ActivityCompat.requestPermissions(this,
+                arrayOf(
+                    Manifest.permission.ACCESS_FINE_LOCATION,
+                    Manifest.permission.ACCESS_COARSE_LOCATION
+                ),
+                1
+            )
+
+            if (ActivityCompat.checkSelfPermission(
+                    this,
+                    Manifest.permission.ACCESS_FINE_LOCATION
+                ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
+                    this,
+                    Manifest.permission.ACCESS_COARSE_LOCATION
+                ) != PackageManager.PERMISSION_GRANTED) {
+
+                return
+            }
+        }
+
+        fusedLocationClient.lastLocation
+            .addOnSuccessListener { location: Location? ->
+                locationViewModel.setLoc(location?.latitude, location?.longitude)
+            }
+    }
+
+    private fun observeLocation(loc: Pair<Double?, Double?>) {
+        val (lat, lng) = loc
+        savedLat = lat
+        savedLng = lng
+
+        if (lat != null && lng != null) {
+            binding.locationText.text = loc.toString()
+        } else {
+            binding.locationText.text = getString(R.string.no_location_data)
+        }
     }
 
     // Header back button
@@ -72,8 +165,6 @@ class TransactionActivity : AppCompatActivity() {
         val title = binding.titleInput.text.toString()
         val category = binding.categoryInput.selectedItem.toString()
         val amount = binding.amountInput.text.toString()
-        // TODO: Location
-        val location = binding.locationInput.text.toString()
 
         if (title.isEmpty()){
             Toast.makeText(this, getString(R.string.transaction_add_toast_error_title), Toast.LENGTH_SHORT).show()
@@ -83,29 +174,31 @@ class TransactionActivity : AppCompatActivity() {
         }
         else{
             when (actionCode){
-                ACTION_ADD ->{
+                ACTION_ADD -> {
                         transactionViewModel.insert(
                             TransactionEntity(
                                 id = 0,
                                 title = title,
                                 category = category,
                                 amount = amount.toInt(),
-                                location = location,
-                                timestamp = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date())
+                                timestamp = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date()),
+                                latitude = savedLat,
+                                longitude = savedLng
                             )
                         )
                         Toast.makeText(this, getString(R.string.transaction_add_toast_success), Toast.LENGTH_SHORT).show()
                     }
 
-                ACTION_EDIT ->{
+                ACTION_EDIT -> {
                     transactionViewModel.update(
                         TransactionEntity(
                             id = intent.getIntExtra(KEY_TRANSACTION_ID, 0),
                             title = title,
                             category = category,
                             amount = amount.toInt(),
-                            location = location,
-                            timestamp = intent.getStringExtra(KEY_TIMESTAMP)!!
+                            timestamp = intent.getStringExtra(KEY_TIMESTAMP)!!,
+                            latitude = savedLat,
+                            longitude = savedLng
                         )
                     )
                     Toast.makeText(this, getString(R.string.transaction_edit_toast_success), Toast.LENGTH_SHORT).show()
diff --git a/app/src/main/java/com/example/bondoman/viewmodel/placeholder.txt b/app/src/main/java/com/example/bondoman/viewmodel/placeholder.txt
deleted file mode 100644
index a46b82772895c1e2841c51607ae16729c37b6715..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/example/bondoman/viewmodel/placeholder.txt
+++ /dev/null
@@ -1 +0,0 @@
-biar ngeliat folderingnya enak
\ No newline at end of file
diff --git a/app/src/main/java/com/example/bondoman/viewmodel/transaction/LocationViewModel.kt b/app/src/main/java/com/example/bondoman/viewmodel/transaction/LocationViewModel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ead57e98ac159e1cca433741be9bc9ad9bece02f
--- /dev/null
+++ b/app/src/main/java/com/example/bondoman/viewmodel/transaction/LocationViewModel.kt
@@ -0,0 +1,16 @@
+package com.example.bondoman.viewmodel.transaction
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+
+class LocationViewModel : ViewModel() {
+    private val _location = MutableLiveData<Pair<Double?, Double?>>(Pair(null, null))
+
+    val location: LiveData<Pair<Double?, Double?>>
+        get() = _location
+
+    fun setLoc(lat: Double?, lng: Double?) {
+        _location.value = Pair(lat, lng)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/bondoman/viewmodel/transaction/LocationViewModelFactory.kt b/app/src/main/java/com/example/bondoman/viewmodel/transaction/LocationViewModelFactory.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4a0c72dd990621f3165f44795163d41828facedc
--- /dev/null
+++ b/app/src/main/java/com/example/bondoman/viewmodel/transaction/LocationViewModelFactory.kt
@@ -0,0 +1,10 @@
+package com.example.bondoman.viewmodel.transaction
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+
+class LocationViewModelFactory() : ViewModelProvider.Factory {
+    override fun <T : ViewModel> create(modelClass: Class<T>): T {
+        return LocationViewModel() as T
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_trash.xml b/app/src/main/res/drawable/ic_trash.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bffadc8b7e21756dbc2b7bc22db70553eb0c50b1
--- /dev/null
+++ b/app/src/main/res/drawable/ic_trash.xml
@@ -0,0 +1,13 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="800dp"
+    android:height="800dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:pathData="M4,6H20M16,6L15.729,5.188C15.467,4.401 15.336,4.008 15.093,3.717C14.878,3.46 14.602,3.261 14.29,3.139C13.938,3 13.523,3 12.694,3H11.306C10.477,3 10.062,3 9.71,3.139C9.398,3.261 9.122,3.46 8.907,3.717C8.664,4.008 8.533,4.401 8.271,5.188L8,6M18,6V16.2C18,17.88 18,18.72 17.673,19.362C17.385,19.927 16.927,20.385 16.362,20.673C15.72,21 14.88,21 13.2,21H10.8C9.12,21 8.28,21 7.638,20.673C7.074,20.385 6.615,19.927 6.327,19.362C6,18.72 6,17.88 6,16.2V6M14,10V17M10,10V17"
+      android:strokeLineJoin="round"
+      android:strokeWidth="2"
+      android:fillColor="#00000000"
+      android:strokeColor="#000000"
+      android:strokeLineCap="round"/>
+</vector>
diff --git a/app/src/main/res/layout/activity_transaction.xml b/app/src/main/res/layout/activity_transaction.xml
index 3cdd6fc9976c6065ddb20e6171e61284eed02059..1b4bd41dde7dd5e7801f81578bdf16d4d053d0c6 100644
--- a/app/src/main/res/layout/activity_transaction.xml
+++ b/app/src/main/res/layout/activity_transaction.xml
@@ -2,6 +2,7 @@
 <androidx.constraintlayout.widget.ConstraintLayout
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
@@ -18,10 +19,10 @@
 
         <LinearLayout
             android:id="@+id/login_cluster"
-            android:layout_marginTop="20dp"
-            android:layout_marginHorizontal="30dp"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:layout_marginHorizontal="30dp"
+            android:layout_marginTop="20dp"
             android:orientation="vertical">
 
             <TextView
@@ -33,14 +34,14 @@
                 android:textSize="10pt" />
 
             <EditText
-                android:paddingHorizontal="10sp"
                 android:id="@+id/title_input"
                 android:layout_width="match_parent"
                 android:layout_height="16pt"
                 android:background="@color/gray"
                 android:ems="10"
                 android:inputType="text"
-                android:textColor="@color/black"/>
+                android:paddingHorizontal="10sp"
+                android:textColor="@color/black" />
 
             <TextView
                 android:id="@+id/amount_label"
@@ -52,19 +53,20 @@
                 android:textSize="10pt" />
 
             <EditText
-                android:paddingHorizontal="10sp"
                 android:id="@+id/amount_input"
                 android:layout_width="match_parent"
                 android:layout_height="16pt"
                 android:background="@color/gray"
                 android:ems="10"
                 android:inputType="numberDecimal"
-                android:textColor="@color/black"/>
+                android:paddingHorizontal="10sp"
+                android:textColor="@color/black" />
 
             <TextView
                 android:id="@+id/category_label"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:layout_marginTop="5pt"
                 android:text="@string/transaction_label_category"
                 android:textColor="?android:textColorPrimary"
                 android:textSize="10pt" />
@@ -74,7 +76,7 @@
                 android:layout_width="match_parent"
                 android:layout_height="16pt"
                 android:background="@color/gray"
-                android:entries="@array/category_choices"/>
+                android:entries="@array/category_choices" />
 
             <TextView
                 android:id="@+id/location_label"
@@ -85,15 +87,55 @@
                 android:textColor="?android:textColorPrimary"
                 android:textSize="10pt" />
 
-            <EditText
-                android:paddingHorizontal="10sp"
-                android:id="@+id/location_input"
+            <androidx.constraintlayout.widget.ConstraintLayout
                 android:layout_width="match_parent"
-                android:layout_height="16pt"
-                android:background="@color/gray"
-                android:ems="10"
-                android:inputType="text"
-                android:textColor="@color/black"/>
+                android:layout_height="wrap_content">
+                <TextView
+                    android:id="@+id/location_text"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_marginEnd="8dp"
+                    android:paddingHorizontal="0dp"
+                    android:text="@string/no_location_data"
+                    android:textColor="@color/black"
+                    app:layout_constraintBottom_toBottomOf="parent"
+                    app:layout_constraintEnd_toStartOf="@+id/btnLocate"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toTopOf="parent" />
+
+                <ImageButton
+                    android:id="@+id/btnLocate"
+                    android:layout_width="48dp"
+                    android:layout_height="40dp"
+                    android:adjustViewBounds="true"
+                    android:backgroundTint="@color/purple_500"
+                    android:contentDescription="@string/get_latest_location"
+                    android:paddingHorizontal="5dp"
+                    android:paddingVertical="10dp"
+                    android:scaleType="centerInside"
+                    app:layout_constraintBottom_toBottomOf="@+id/location_text"
+                    app:layout_constraintEnd_toStartOf="@+id/btnDelete"
+                    app:layout_constraintTop_toTopOf="@+id/location_text"
+                    app:srcCompat="@drawable/ic_hub_location"
+                    app:tint="@color/white" />
+
+                <ImageButton
+                    android:id="@+id/btnDelete"
+                    android:layout_width="48dp"
+                    android:layout_height="40dp"
+                    android:adjustViewBounds="true"
+                    android:backgroundTint="@color/red"
+                    android:contentDescription="@string/delete_location"
+                    android:paddingHorizontal="5dp"
+                    android:paddingVertical="10dp"
+                    android:scaleType="centerInside"
+                    app:layout_constraintBottom_toBottomOf="@+id/btnLocate"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintTop_toTopOf="@+id/btnLocate"
+                    app:srcCompat="@drawable/ic_trash"
+                    app:tint="@color/white" />
+
+            </androidx.constraintlayout.widget.ConstraintLayout>
 
             <Button
                 android:id="@+id/submit_button"
diff --git a/app/src/main/res/layout/item_transaction.xml b/app/src/main/res/layout/item_transaction.xml
index 8dd0443b684ba7f0a717cf57337aac2dd57a6e86..095653939d97577d5e7cacdd76a0ee6cca8e93d2 100644
--- a/app/src/main/res/layout/item_transaction.xml
+++ b/app/src/main/res/layout/item_transaction.xml
@@ -13,13 +13,11 @@
         android:id="@+id/divider1"
         android:layout_width="match_parent"
         android:layout_height="1dp"
-        android:layout_marginTop="20dp"
+        android:layout_marginTop="16dp"
         android:background="@color/gray"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/btnLocation"
-        tools:layout_editor_absoluteX="20dp" />
+        app:layout_constraintStart_toStartOf="parent" />
 
     <TextView
         android:id="@+id/tvDate"
@@ -62,29 +60,31 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="Edit"
-        app:layout_constraintBottom_toBottomOf="@+id/btnLocation"
+        app:layout_constraintBottom_toBottomOf="@+id/btnDelete"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="@+id/btnLocation" />
+        app:layout_constraintTop_toTopOf="@+id/btnDelete" />
 
     <Button
         android:id="@+id/btnLocation"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginTop="16dp"
         android:layout_marginEnd="10dp"
         android:text="View Location"
+        app:layout_constraintBottom_toBottomOf="@+id/btnDelete"
         app:layout_constraintEnd_toStartOf="@+id/btnEdit"
-        app:layout_constraintTop_toBottomOf="@+id/tvAmount" />
+        app:layout_constraintTop_toTopOf="@+id/btnDelete" />
 
     <Button
         android:id="@+id/btnDelete"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:text="Delete"
+        android:layout_marginTop="16dp"
+        android:layout_marginBottom="16dp"
         android:backgroundTint="@color/red"
-        app:layout_constraintBottom_toBottomOf="@+id/btnLocation"
+        android:text="Delete"
+        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="@+id/btnLocation" />
+        app:layout_constraintTop_toBottomOf="@+id/tvAmount" />
 
     <ImageView
         android:id="@+id/locationIcon"
@@ -113,9 +113,9 @@
         android:id="@+id/tvLocation"
         android:layout_width="60dp"
         android:layout_height="wrap_content"
-        android:text="TextView"
         android:ellipsize="end"
         android:maxLines="1"
+        android:text="TextView"
         app:layout_constraintBottom_toBottomOf="@+id/locationIcon"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintTop_toTopOf="@+id/locationIcon" />
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2352c58d7b48af769db20cd4a5cb62a285835f23..36dd85dddb31c2d6f34e41db634996aa5c11279a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -35,7 +35,7 @@
 
     <string name="email_subject">Bondoman: Transaction Data</string>
     <string name="email_text">Attached are transaction
-        data from Bondoman, data is recorded at </string>
+        data from Bondoman, data is recorded at</string>
     <string name="email_toast_success">Sending file...</string>
     <string name="email_toast_fail">Failed to send file</string>
 
@@ -65,4 +65,13 @@
         <item>Income</item>
         <item>Expenses</item>
     </string-array>
+
+    <string name="start_capture">Start Capture</string>
+    <string name="stop_capture">Stop Capture</string>
+
+    <string name="longitude">Longitude</string>
+    <string name="latitude">Latitude</string>
+    <string name="get_latest_location">Get latest location</string>
+    <string name="delete_location">Delete location</string>
+    <string name="no_location_data">No location data</string>
 </resources>