diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 749b7ce624bd3685ead0ea8c099a1986c807e786..badcd890cb8b664dac2c3edd8ba117ca644b62f2 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -62,6 +62,8 @@ dependencies {
     kapt("androidx.room:room-compiler:2.5.0")
     androidTestImplementation ("androidx.room:room-testing:2.5.0")
     implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
+    implementation ("org.apache.poi:poi:5.2.4")
+    implementation ("org.apache.poi:poi-ooxml:5.2.4")
     implementation("com.github.PhilJay:MPAndroidChart:v3.1.0")
-
+    implementation ("com.squareup.okhttp3:okhttp:4.9.1")
 }
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7d66e5469809975b468b20212dd0665b0b181801..e9c84d7765dd6ba21990362be955cabb8dcc23b2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -9,9 +9,14 @@
     <uses-permission android:name="android.permission.CAMERA"/>
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
         android:maxSdkVersion="32" />
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+
 
 
-    <uses-permission android:name="android.permission.INTERNET"/>
     <application
         android:allowBackup="true"
         android:dataExtractionRules="@xml/data_extraction_rules"
@@ -31,6 +36,7 @@
         <activity
             android:name=".MainActivity"
             android:exported="false" />
+
         <activity
             android:name=".BondoManSplashScreen"
             android:exported="true"
@@ -42,6 +48,17 @@
             </intent-filter>
         </activity>
         <service android:name=".CheckJWTBackground"/>
+        <provider
+            android:name="androidx.core.content.FileProvider"
+            android:authorities="com.example.android_hit.fileprovider"
+            android:exported="false"
+            android:grantUriPermissions="true">
+            <meta-data
+                android:name="android.support.FILE_PROVIDER_PATHS"
+                android:resource="@xml/file_paths" />
+        </provider>
+
     </application>
 
+
 </manifest>
\ No newline at end of file
diff --git a/app/src/main/java/com/example/android_hit/CheckJWTBackground.kt b/app/src/main/java/com/example/android_hit/CheckJWTBackground.kt
index 47c2e036fc77e8d97973153ce58b50a16815dd6c..5cb54e18dcd497b92718812c51c0823c26650fc7 100644
--- a/app/src/main/java/com/example/android_hit/CheckJWTBackground.kt
+++ b/app/src/main/java/com/example/android_hit/CheckJWTBackground.kt
@@ -6,7 +6,6 @@ import android.os.Handler
 import android.os.IBinder
 import android.util.Log
 import com.example.android_hit.utils.TokenManager
-import retrofit2.Response
 import kotlin.concurrent.thread
 
 class CheckJWTBackground:Service() {
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 72f6558798dd2fa67947372784586a632ed06b9c..faf07d21a074c8514cebfb40c0e31c00a21ed00b 100644
--- a/app/src/main/java/com/example/android_hit/DetailTransaction.kt
+++ b/app/src/main/java/com/example/android_hit/DetailTransaction.kt
@@ -1,13 +1,18 @@
 package com.example.android_hit
 
 import android.app.Activity
+import android.content.BroadcastReceiver
+import android.content.Context
 import android.content.Intent
+import android.content.IntentFilter
 import android.os.Bundle
+import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.Toast
 import androidx.fragment.app.Fragment
+import androidx.localbroadcastmanager.content.LocalBroadcastManager
 import com.example.android_hit.databinding.FragmentDetailTransactionBinding
 import com.example.android_hit.room.TransactionDB
 import com.example.android_hit.room.TransactionEntity
@@ -21,19 +26,45 @@ class DetailTransaction : Fragment() {
 
     private lateinit var database: TransactionDB
     private var category: String = ""
+    private lateinit var transactionReceiver: TransactionReceiver
+    private val RANDOMIZE_ACTION = "com.example.android_hit.RANDOMIZE_ACTION"
+    companion object {
+        var fragmentCounter = 0
+        var amountInput = ""
+    }
+
+    inner class TransactionReceiver : BroadcastReceiver() {
+        override fun onReceive(context: Context?, intent: Intent?) {
+            if (intent?.action == RANDOMIZE_ACTION) {
+                // Handle the broadcast message here
+                val data = intent.getStringExtra("hargaRandom")
+                Log.e("BROD", "Received randomize broadcast message $data")
+                if (data != null) {
+                    amountInput = data
+                }
+            }
+        }
+    }
 
     override fun onCreateView(
         inflater: LayoutInflater, container: ViewGroup?,
         savedInstanceState: Bundle?
     ): View? {
+        fragmentCounter++
         _binding = FragmentDetailTransactionBinding.inflate(inflater, container, false)
         return binding.root
     }
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
+
         database = TransactionDB.getInstance(requireContext())
 
+        transactionReceiver = TransactionReceiver()
+        val filter = IntentFilter(RANDOMIZE_ACTION)
+        LocalBroadcastManager.getInstance(requireContext()).registerReceiver(transactionReceiver, filter)
+
+
         binding.radioExpense.setOnCheckedChangeListener { _, isChecked ->
             if (isChecked) {
                 category = "Expense"
@@ -46,6 +77,9 @@ class DetailTransaction : Fragment() {
             }
         }
 
+        if(amountInput!=""){
+            binding.inputAmount.setText(amountInput)
+        }
         val intent = requireActivity().intent.extras
         if (intent != null) {
             val id = intent.getInt("id", 0)
@@ -144,8 +178,15 @@ class DetailTransaction : Fragment() {
         }
     }
 
+
+
     override fun onDestroyView() {
         super.onDestroyView()
         _binding = null
+        amountInput=""
+        if(fragmentCounter>1){
+            LocalBroadcastManager.getInstance(requireContext()).unregisterReceiver(transactionReceiver)
+        }
+
     }
 }
diff --git a/app/src/main/java/com/example/android_hit/HeaderNetwork.kt b/app/src/main/java/com/example/android_hit/HeaderNetwork.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c5409f42afb2c1351f5f6160fe54b9049c590df8
--- /dev/null
+++ b/app/src/main/java/com/example/android_hit/HeaderNetwork.kt
@@ -0,0 +1,59 @@
+package com.example.android_hit
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+// TODO: Rename parameter arguments, choose names that match
+// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
+private const val ARG_PARAM1 = "param1"
+private const val ARG_PARAM2 = "param2"
+
+/**
+ * A simple [Fragment] subclass.
+ * Use the [HeaderNetwork.newInstance] factory method to
+ * create an instance of this fragment.
+ */
+class HeaderNetwork : Fragment() {
+    // TODO: Rename and change types of parameters
+    private var param1: String? = null
+    private var param2: String? = null
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        arguments?.let {
+            param1 = it.getString(ARG_PARAM1)
+            param2 = it.getString(ARG_PARAM2)
+        }
+    }
+
+    override fun onCreateView(
+        inflater: LayoutInflater, container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View? {
+        // Inflate the layout for this fragment
+        return inflater.inflate(R.layout.fragment_header_network, container, false)
+    }
+
+    companion object {
+        /**
+         * Use this factory method to create a new instance of
+         * this fragment using the provided parameters.
+         *
+         * @param param1 Parameter 1.
+         * @param param2 Parameter 2.
+         * @return A new instance of fragment HeaderNetwork.
+         */
+        // TODO: Rename and change types and number of parameters
+        @JvmStatic
+        fun newInstance(param1: String, param2: String) =
+            HeaderNetwork().apply {
+                arguments = Bundle().apply {
+                    putString(ARG_PARAM1, param1)
+                    putString(ARG_PARAM2, param2)
+                }
+            }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/android_hit/MainActivity.kt b/app/src/main/java/com/example/android_hit/MainActivity.kt
index d21ebcf5843889cf2319a10c7483e0639f1fd10b..80a96b5e03481e2115d43e0924555b2e0838f4be 100644
--- a/app/src/main/java/com/example/android_hit/MainActivity.kt
+++ b/app/src/main/java/com/example/android_hit/MainActivity.kt
@@ -1,7 +1,6 @@
 package com.example.android_hit
 
 import android.app.AlertDialog
-import android.content.DialogInterface
 import android.content.Intent
 import android.content.res.Configuration
 import androidx.appcompat.app.AppCompatActivity
@@ -27,12 +26,27 @@ class MainActivity : AppCompatActivity() {
     private lateinit var userPref : UserManager
     private lateinit var sharedPref : TokenManager
     private lateinit var cryptoManager: CryptoManager
+
+    private lateinit var dialog : AlertDialog
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         binding = ActivityMainBinding.inflate(layoutInflater)
         userPref = UserManager(this)
         sharedPref = TokenManager(this)
         cryptoManager = CryptoManager()
+
+        val networkManager = NetworkManager(this)
+        var networkDialog: AlertDialog? = null
+
+        networkManager.observe(this) { isConnected ->
+            if (!isConnected) {
+                networkDialog = showNetworkDialog()
+            } else {
+                networkDialog?.dismiss()
+                networkDialog = null
+            }
+        }
         setContentView(binding.root)
 
         setCurrentFragment(Transaction(), HeaderTransaction())
@@ -41,14 +55,22 @@ class MainActivity : AppCompatActivity() {
             binding.bottomNavigation?.setOnItemSelectedListener {
                 when (it.itemId) {
                     R.id.nav_transaction -> {
+                        //                    if(!networkManager.value!!){
+                        //                        setCurrentFragment(NetworkError(), HeaderNetwork())
+                        //                    }else{
+                        //                        setCurrentFragment(Transaction(), HeaderTransaction())
+                        //                    }
                         setCurrentFragment(Transaction(), HeaderTransaction())
                     }
+
                     R.id.nav_scan -> {
-                        setCurrentFragment(Scan(),  HeaderScan())
+                        setCurrentFragment(Scan(), HeaderScan())
                     }
+
                     R.id.nav_graphs -> {
                         setCurrentFragment(Graphs(), HeaderGraphs())
                     }
+
                     R.id.nav_settings -> {
                         setCurrentFragment(Settings(), HeaderSettings())
                     }
@@ -75,6 +97,20 @@ class MainActivity : AppCompatActivity() {
         }
 
     }
+    private fun showNetworkDialog(): AlertDialog {
+        val alertDialogBuilder: AlertDialog.Builder = AlertDialog.Builder(this)
+        alertDialogBuilder.setTitle("No Internet Connection")
+        alertDialogBuilder.setMessage("Please check your internet connection")
+        alertDialogBuilder.setCancelable(false)
+
+        alertDialogBuilder.setPositiveButton("OK") { dialog, _ ->
+            dialog.dismiss()
+        }
+
+        val alertDialog: AlertDialog = alertDialogBuilder.create()
+        alertDialog.show()
+        return alertDialog
+    }
 
     private fun setCurrentFragment(fragment: Fragment, header: Fragment) =
         supportFragmentManager.beginTransaction().apply {
diff --git a/app/src/main/java/com/example/android_hit/NetworkError.kt b/app/src/main/java/com/example/android_hit/NetworkError.kt
new file mode 100644
index 0000000000000000000000000000000000000000..faeceb8f15ff12b5053691bdf56386fb81e54473
--- /dev/null
+++ b/app/src/main/java/com/example/android_hit/NetworkError.kt
@@ -0,0 +1,59 @@
+package com.example.android_hit
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+// TODO: Rename parameter arguments, choose names that match
+// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
+private const val ARG_PARAM1 = "param1"
+private const val ARG_PARAM2 = "param2"
+
+/**
+ * A simple [Fragment] subclass.
+ * Use the [NetworkError.newInstance] factory method to
+ * create an instance of this fragment.
+ */
+class NetworkError : Fragment() {
+    // TODO: Rename and change types of parameters
+    private var param1: String? = null
+    private var param2: String? = null
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        arguments?.let {
+            param1 = it.getString(ARG_PARAM1)
+            param2 = it.getString(ARG_PARAM2)
+        }
+    }
+
+    override fun onCreateView(
+        inflater: LayoutInflater, container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View? {
+        // Inflate the layout for this fragment
+        return inflater.inflate(R.layout.fragment_network_error, container, false)
+    }
+
+    companion object {
+        /**
+         * Use this factory method to create a new instance of
+         * this fragment using the provided parameters.
+         *
+         * @param param1 Parameter 1.
+         * @param param2 Parameter 2.
+         * @return A new instance of fragment NetworkError.
+         */
+        // TODO: Rename and change types and number of parameters
+        @JvmStatic
+        fun newInstance(param1: String, param2: String) =
+            NetworkError().apply {
+                arguments = Bundle().apply {
+                    putString(ARG_PARAM1, param1)
+                    putString(ARG_PARAM2, param2)
+                }
+            }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/android_hit/NetworkManager.kt b/app/src/main/java/com/example/android_hit/NetworkManager.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1d474c623dd9902b7dcfa222aa7aba404c714239
--- /dev/null
+++ b/app/src/main/java/com/example/android_hit/NetworkManager.kt
@@ -0,0 +1,71 @@
+package com.example.android_hit
+
+import android.content.Context
+import android.net.ConnectivityManager
+import android.net.Network
+import android.net.NetworkCapabilities
+import android.net.NetworkRequest
+import androidx.lifecycle.LiveData
+
+class NetworkManager(context: Context) : LiveData<Boolean>() {
+//    private val _isNetworkAvailable = MutableLiveData<Boolean>()
+//    val isNetworkAvailable: LiveData<Boolean> get() = _isNetworkAvailable
+
+
+
+    private var connectivityManager =
+        context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+
+    private val networkCallback = object : ConnectivityManager.NetworkCallback() {
+        // network is available for use
+        override fun onAvailable(network: Network) {
+            super.onAvailable(network)
+            postValue(true)
+        }
+
+        override fun onUnavailable() {
+            super.onUnavailable()
+            postValue(false)
+        }
+
+        // Network capabilities have changed for the network
+//        override fun onCapabilitiesChanged(
+//            network: Network,
+//            networkCapabilities: NetworkCapabilities
+//        ) {
+//            super.onCapabilitiesChanged(network, networkCapabilities)
+//            val unmetered =
+//                networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
+//        }
+
+        // lost network connection
+        override fun onLost(network: Network) {
+            super.onLost(network)
+            postValue(false)
+        }
+    }
+    private fun checkNetworkConnectivity() {
+        val network = connectivityManager.activeNetwork
+        if(network == null){
+           postValue(false)
+        }
+        val requestBuilder = NetworkRequest.Builder().apply {
+            addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+            addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+            addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
+            addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+            addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
+        }.build()
+        connectivityManager.registerNetworkCallback(requestBuilder, networkCallback)
+    }
+
+    override fun onActive() {
+        super.onActive()
+        checkNetworkConnectivity()
+    }
+
+    override fun onInactive() {
+        super.onInactive()
+        connectivityManager.unregisterNetworkCallback(networkCallback)
+    }
+}
\ No newline at end of file
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 faa0d42b9d84f915ce8f866c5d6005eabfd7977f..addd17e967a5fadd8743102c2312c5ab64aa5356 100644
--- a/app/src/main/java/com/example/android_hit/Scan.kt
+++ b/app/src/main/java/com/example/android_hit/Scan.kt
@@ -2,6 +2,8 @@ package com.example.android_hit
 
 import android.Manifest
 import android.app.Activity
+import android.app.AlertDialog
+import android.content.DialogInterface
 import android.content.Intent
 import android.content.pm.PackageManager
 import android.graphics.Bitmap
@@ -9,34 +11,43 @@ import android.graphics.ImageDecoder
 import android.net.Uri
 import android.os.Build
 import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
 import android.provider.MediaStore
+import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.Button
 import android.widget.ImageView
+import android.widget.Toast
 import androidx.core.app.ActivityCompat
 import androidx.core.content.ContextCompat
 import androidx.fragment.app.Fragment
+import com.example.android_hit.api.RetrofitClient
+import com.example.android_hit.data.ScanResponse
+import com.example.android_hit.room.TransactionDB
+import com.example.android_hit.room.TransactionEntity
+import com.example.android_hit.utils.TokenManager
+import okhttp3.MediaType.Companion.toMediaTypeOrNull
+import okhttp3.MultipartBody
+import okhttp3.RequestBody.Companion.toRequestBody
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+import java.io.ByteArrayOutputStream
+import java.io.File
+import java.io.FileOutputStream
 
-// TODO: Rename parameter arguments, choose names that match
-// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
-private const val ARG_PARAM1 = "param1"
-private const val ARG_PARAM2 = "param2"
-
-/**
- * A simple [Fragment] subclass.
- * Use the [Scan.newInstance] factory method to
- * create an instance of this fragment.
- */
 class Scan : Fragment() {
-    // TODO: Rename and change types of parameters
     var pickedPhoto : Uri? = null
     var pickedBitMap : Bitmap? = null
     private val CAMERA_REQUEST_CODE = 1
     private lateinit var btnCapture : Button
     private lateinit var btnPick : Button
     private lateinit var ivPicture : ImageView
+    private lateinit var sharedPref : TokenManager
+
 
 
 
@@ -52,8 +63,6 @@ class Scan : Fragment() {
         inflater: LayoutInflater, container: ViewGroup?,
         savedInstanceState: Bundle?
     ): View? {
-        // Inflate the layout for this fragment
-
         return inflater.inflate(R.layout.fragment_scan, container, false)
     }
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -62,7 +71,7 @@ class Scan : Fragment() {
         ivPicture = view.findViewById(R.id.captureImageView)
         btnPick = view.findViewById(R.id.pickImgBtn)
         btnCapture.isEnabled = true
-
+        sharedPref = TokenManager(requireContext())
         if(ActivityCompat.checkSelfPermission(requireContext(), android.Manifest.permission.CAMERA)
             != PackageManager.PERMISSION_GRANTED){
             ActivityCompat.requestPermissions(requireActivity(), arrayOf(Manifest.permission.CAMERA),
@@ -86,6 +95,13 @@ class Scan : Fragment() {
         if(requestCode == 101){
             var pic : Bitmap? = data?.getParcelableExtra<Bitmap>("data")
             ivPicture.setImageBitmap(pic)
+            pickedBitMap = pic
+            val savedImageUri = saveImageToInternalStorage(pickedBitMap!!)
+            pickedPhoto = savedImageUri
+            Handler(Looper.getMainLooper()).postDelayed({
+                showConfirmationDialog()
+            }, 700)
+
         }
         if(requestCode == 2 && resultCode == Activity.RESULT_OK && data != null){
             pickedPhoto = data.data
@@ -93,14 +109,39 @@ class Scan : Fragment() {
                 val source = ImageDecoder.createSource(requireContext().contentResolver, pickedPhoto!!)
                 pickedBitMap = ImageDecoder.decodeBitmap(source)
                 ivPicture.setImageBitmap(pickedBitMap)
+                Handler(Looper.getMainLooper()).postDelayed({
+                    showConfirmationDialog()
+                }, 700)
             }else{
                 pickedBitMap = MediaStore.Images.Media.getBitmap(requireContext().contentResolver, pickedPhoto)
                 ivPicture.setImageBitmap(pickedBitMap)
+                Handler(Looper.getMainLooper()).postDelayed({
+                    showConfirmationDialog()
+                }, 700)
+
             }
         }
 
     }
 
+
+    private fun saveImageToInternalStorage(bitmap: Bitmap?): Uri? {
+        // Check for null
+        if (bitmap == null) {
+            return null
+        }
+
+        // Save the bitmap to a file
+        val filename = "${System.currentTimeMillis()}.jpg"
+        val file = File(requireContext().externalCacheDir, filename)
+        val fileOutputStream = FileOutputStream(file)
+        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream)
+        fileOutputStream.close()
+
+        // Get the Uri of the file
+        return Uri.fromFile(file)
+    }
+
     override fun onRequestPermissionsResult(
         requestCode: Int,
         permissions: Array<out String>,
@@ -127,24 +168,79 @@ class Scan : Fragment() {
             startActivityForResult(galleryIntext, 2)
         }
     }
-    companion object {
-        /**
-         * Use this factory method to create a new instance of
-         * this fragment using the provided parameters.
-         *
-         * @param param1 Parameter 1.
-         * @param param2 Parameter 2.
-         * @return A new instance of fragment Scan.
-         */
-
-        // TODO: Rename and change types and number of parameters
-        @JvmStatic
-        fun newInstance(param1: String, param2: String) =
-            Scan().apply {
-                arguments = Bundle().apply {
-                    putString(ARG_PARAM1, param1)
-                    putString(ARG_PARAM2, param2)
-                }
+    private fun showConfirmationDialog() {
+        val alertDialogBuilder = AlertDialog.Builder(this.context)
+        alertDialogBuilder.apply {
+            setTitle("Confirmation")
+            setMessage("Are you sure to use this image?")
+            setPositiveButton("Yes") { dialogInterface: DialogInterface, _: Int ->
+
+
+                dialogInterface.dismiss()
+
+
+                // Ubah Bitmap menjadi ByteArrayOutputStream
+                val byteArrayOutputStream = ByteArrayOutputStream()
+                pickedBitMap?.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream)
+                // Ubah ByteArrayOutputStream menjadi byte array
+                val byteArray = byteArrayOutputStream.toByteArray()
+
+                // Ubah byte array menjadi RequestBody
+                val requestBody = byteArray.toRequestBody("image/jpg".toMediaTypeOrNull())
+
+                // Gunakan requestBody ini untuk mengirim gambar melalui Retrofit
+                val token = sharedPref.getToken()
+                val file = File(pickedPhoto?.path)
+                val filePart = MultipartBody.Part.createFormData("file", file.name, requestBody)
+                val call = RetrofitClient.apiService.uploadNota("Bearer $token", filePart)
+                call.enqueue(object : Callback<ScanResponse> {
+                    override fun onResponse(call: Call<ScanResponse>, response: Response<ScanResponse>) {
+                        if (response.isSuccessful) {
+                            val responseBody = response.body()
+                            Log.e("POST Success", "Response: ${responseBody.toString()}")
+                            Toast.makeText(requireContext(), "Upload Success", Toast.LENGTH_SHORT).show()
+
+                            // Get the items from the response
+                            val items = responseBody?.items?.items
+
+                            // Get a reference to the database
+                            val db = TransactionDB.getInstance(requireContext())
+                            val transactionDao = db.transactionDao
+
+                            // Loop through the items and convert them to transactions
+                            items?.forEach { item ->
+                                val amount = item.qty * item.price
+                                val transaction = TransactionEntity(
+                                    title = item.name,
+                                    amount = amount.toInt(),
+                                    category = "Expense",
+                                    location = "Location", // Replace with actual location
+                                    timestamp = System.currentTimeMillis().toString() // Replace with actual timestamp
+                                )
+
+                                // Insert the transaction into the database
+                                transactionDao.addTransaction(transaction)
+                            }
+
+                        } else {
+                            Log.e("POST Error", "Failed to make POST request: ${response.message()}")
+                            Toast.makeText(requireContext(), "Upload Failed: ${response.message()}", Toast.LENGTH_SHORT).show()
+                        }
+                    }
+                    override fun onFailure(call: Call<ScanResponse>, t: Throwable) {
+                        Log.e("POST Error", "Failed to make POST request: ${t.message}")
+                    }
+                })
             }
+            setNegativeButton("No") { dialogInterface: DialogInterface, _: Int ->
+                dialogInterface.dismiss()
+                ivPicture.setImageBitmap(null)
+            }
+            setCancelable(false)
+        }
+
+        val alertDialog = alertDialogBuilder.create()
+        alertDialog.show()
     }
+
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/example/android_hit/Settings.kt b/app/src/main/java/com/example/android_hit/Settings.kt
index 338766e7e1f66812a27244f75255f6db96bd8f27..cd1fb776c1030aef912f2ee20f5e5b43431e081c 100644
--- a/app/src/main/java/com/example/android_hit/Settings.kt
+++ b/app/src/main/java/com/example/android_hit/Settings.kt
@@ -1,46 +1,45 @@
 package com.example.android_hit
 
+import android.Manifest
 import android.annotation.SuppressLint
 import android.app.AlertDialog
 import android.content.DialogInterface
 import android.content.Intent
+import android.content.pm.PackageManager
 import android.os.Bundle
+import android.os.Environment
 import android.util.Log
-import androidx.fragment.app.Fragment
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.Button
 import android.widget.TextView
+import android.widget.Toast
+import androidx.core.app.ActivityCompat
+import androidx.core.content.ContextCompat
+import androidx.core.content.FileProvider
+import androidx.fragment.app.Fragment
+import androidx.localbroadcastmanager.content.LocalBroadcastManager
+import com.example.android_hit.room.TransactionDB
+import com.example.android_hit.room.TransactionEntity
 import com.example.android_hit.utils.TokenManager
 import com.example.android_hit.utils.UserManager
+import org.apache.poi.hssf.usermodel.HSSFWorkbook
+import org.apache.poi.xssf.usermodel.XSSFWorkbook
+import java.io.File
+import java.io.FileOutputStream
+import kotlin.random.Random
 
-// TODO: Rename parameter arguments, choose names that match
-// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
-private const val ARG_PARAM1 = "param1"
-private const val ARG_PARAM2 = "param2"
-
-/**
- * A simple [Fragment] subclass.
- * Use the [Settings.newInstance] factory method to
- * create an instance of this fragment.
- */
 class Settings : Fragment() {
-    // TODO: Rename and change types of parameters
-    private var param1: String? = null
-    private var param2: String? = null
+
     private lateinit var sharedPref : TokenManager
     private lateinit var logoutButton : Button
+    private lateinit var randomize : Button
     private lateinit var emailTextView : TextView
     private lateinit var user: UserManager
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-        arguments?.let {
-            param1 = it.getString(ARG_PARAM1)
-            param2 = it.getString(ARG_PARAM2)
-        }
-    }
+    private val RANDOMIZE_ACTION = "com.example.android_hit.RANDOMIZE_ACTION"
+    private lateinit var saveButton: Button
+    private lateinit var sendButton: Button
 
     @SuppressLint("UseRequireInsteadOfGet", "MissingInflatedId")
     override fun onCreateView(
@@ -53,14 +52,98 @@ class Settings : Fragment() {
         user = this.context?.let { UserManager(it) }!!
         logoutButton = view.findViewById(R.id.logoutButton)
         emailTextView = view.findViewById(R.id.emailTextView)
-
+        randomize = view.findViewById(R.id.randomizeTransactionButton)
+        saveButton = view.findViewById(R.id.saveTransactionButton)
+        sendButton = view.findViewById(R.id.sendTransactionButton)
         emailTextView.text = user.getEmail("EMAIL")
-        Log.e("SET","masuk sini")
-
+        val database = TransactionDB.getInstance(requireContext())
+        val transactionDao = database.transactionDao
+        val transactions = transactionDao.getAllTransaction()
         logoutButton.setOnClickListener {
             showConfirmationDialog()
+        }
+
+        randomize.setOnClickListener {
+            goToTransaction()
+            Log.e("BROD","clicked randomize")
+            val randomIntInRange = Random.nextInt(1000, 100000)
+            val intent = Intent(RANDOMIZE_ACTION)
+            intent.putExtra("hargaRandom",randomIntInRange.toString())
+            LocalBroadcastManager.getInstance(requireContext()).sendBroadcast(intent)
+
+        }
+        saveButton.setOnClickListener {
+            if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
+                ActivityCompat.requestPermissions(requireActivity(), arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 0)
+            }
+            val fileFormats = arrayOf("xls", "xlsx")
+
+            AlertDialog.Builder(requireContext()).apply {
+                setTitle("Choose file format")
+                setItems(fileFormats) { dialog, which ->
+                    val fileFormat = fileFormats[which]
+                    val documentsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
+                    val documentsFolder = File(documentsDir, "Bondoman-Transaction")
+                    if (!documentsFolder.exists()) {
+                        documentsFolder.mkdirs()
+                    }
+                    val title = "transactions.$fileFormat"
+                    val file = File(documentsFolder, title)
+                    val fileOutputStream = FileOutputStream(file)
+                    saveTransactionsToExcel(transactions, fileFormat, fileOutputStream)
+                    fileOutputStream.close()
+                    Toast.makeText(requireContext(), "Transaksi berhasil disimpan", Toast.LENGTH_SHORT).show()
+                }
+                setNegativeButton("Cancel") { dialog, _ ->
+                    dialog.dismiss()
+                }
+            }.create().show()
+        }
+        sendButton.setOnClickListener {
+            val fileFormats = arrayOf("xls", "xlsx")
+
+            AlertDialog.Builder(requireContext()).apply {
+                setTitle("Choose file format")
+                setItems(fileFormats) { dialog, which ->
+                    val fileFormat = fileFormats[which]
+                    val documentsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
+                    val documentsFolder = File(documentsDir, "Bondoman-Transaction")
+                    if (!documentsFolder.exists()) {
+                        documentsFolder.mkdirs()
+                    }
+                    val title = "transactions.$fileFormat"
+                    val file = File(documentsFolder, title)
+                    val fileOutputStream = FileOutputStream(file)
+                    Log.e("SET","fileFormat $fileFormat")
+                    saveTransactionsToExcel(transactions, fileFormat, fileOutputStream)
+                    fileOutputStream.close()
+
+
+                    val uri = FileProvider.getUriForFile(requireContext(), "com.example.android_hit.fileprovider", file)
+                    val emailIntent = Intent(Intent.ACTION_SEND).apply {
+                        type = "*/*"
+                        putExtra(Intent.EXTRA_EMAIL, arrayOf(user.getEmail("EMAIL")))
+                        putExtra(Intent.EXTRA_SUBJECT, "Daftar Transaksi")
+                        putExtra(Intent.EXTRA_TEXT, "Berikut adalah daftar transaksi Anda.")
+                        putExtra(Intent.EXTRA_STREAM, uri)
+                        addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+                    }
 
+                    Log.e("email","${user.getEmail("EMAIL")}")
+
+                    if (emailIntent.resolveActivity(requireContext().packageManager) != null) {
+                        startActivity(emailIntent)
+
+                    } else {
+                        Toast.makeText(requireContext(), "Tidak ada aplikasi email yang dapat menangani permintaan ini.", Toast.LENGTH_SHORT).show()
+                    }
+                }
+                setNegativeButton("Cancel") { dialog, _ ->
+                    dialog.dismiss()
+                }
+            }.create().show()
         }
+
         return view
     }
     private fun showConfirmationDialog() {
@@ -91,4 +174,47 @@ class Settings : Fragment() {
         startActivity(intent)
     }
 
+    private fun goToTransaction(){
+        val intent = Intent(activity, DetailTransactionActivity::class.java)
+        startActivity(intent)
+    }
+
+
+
+    private fun saveTransactionsToExcel(transactions: List<TransactionEntity>, fileFormat:String, outputStream: FileOutputStream) {
+        Log.e("SET","fileFormat $fileFormat")
+
+        val workbook = if (fileFormat == "xls") {
+            HSSFWorkbook()
+        } else {
+            XSSFWorkbook()
+        }
+
+        val sheet = workbook.createSheet("Transactions")
+
+
+        val headerRow = sheet.createRow(0)
+        headerRow.createCell(0).setCellValue("ID")
+        headerRow.createCell(1).setCellValue("Title")
+        headerRow.createCell(2).setCellValue("Amount")
+        headerRow.createCell(3).setCellValue("Category")
+        headerRow.createCell(4).setCellValue("Location")
+        headerRow.createCell(5).setCellValue("Timestamp")
+
+        transactions.forEachIndexed { index, transaction ->
+            val row = sheet.createRow(index + 1)
+            row.createCell(0).setCellValue(transaction.id?.toDouble() ?: 0.0)
+            row.createCell(1).setCellValue(transaction.title)
+            row.createCell(2).setCellValue(transaction.amount.toDouble())
+            row.createCell(3).setCellValue(transaction.category)
+            row.createCell(4).setCellValue(transaction.location)
+            row.createCell(5).setCellValue(transaction.timestamp)
+        }
+        // Menyimpan workbook ke file
+        workbook.write(outputStream)
+        workbook.close()
+
+
+    }
+
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/example/android_hit/api/ApiService.kt b/app/src/main/java/com/example/android_hit/api/ApiService.kt
index b5a69afdc173f3c83f0166289b1b6d307341cee3..8933b30ee2d9c8dfef7df28ca119b1e88fe8643d 100644
--- a/app/src/main/java/com/example/android_hit/api/ApiService.kt
+++ b/app/src/main/java/com/example/android_hit/api/ApiService.kt
@@ -2,12 +2,15 @@ package com.example.android_hit.api
 
 import com.example.android_hit.data.LoginPayload
 import com.example.android_hit.data.LoginResponse
+import com.example.android_hit.data.ScanResponse
 import com.example.android_hit.data.TokenResponse
+import okhttp3.MultipartBody
 import retrofit2.Call
 import retrofit2.http.Body
 import retrofit2.http.Header
-import retrofit2.http.Headers
+import retrofit2.http.Multipart
 import retrofit2.http.POST
+import retrofit2.http.Part
 
 interface ApiService {
 
@@ -18,4 +21,9 @@ interface ApiService {
 
     @POST("/api/auth/token")
     fun cekToken(@Header("Authorization") token: String): Call<TokenResponse>
+    @Multipart
+    @POST("/api/bill/upload")
+    fun uploadNota(@Header("Authorization") token: String,
+                   @Part file: MultipartBody.Part): Call<ScanResponse>
+
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/example/android_hit/data/ScanResponse.kt b/app/src/main/java/com/example/android_hit/data/ScanResponse.kt
new file mode 100644
index 0000000000000000000000000000000000000000..94b1062b4e4aeb855cddc8100cfa7fcf395b5f89
--- /dev/null
+++ b/app/src/main/java/com/example/android_hit/data/ScanResponse.kt
@@ -0,0 +1,13 @@
+package com.example.android_hit.data
+
+data class ScanResponse(
+    val items : Items
+)
+data class Items(
+    val items : List<Item>
+)
+data class Item(
+    val name : String,
+    val qty : Int,
+    val price : Double
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/example/android_hit/utils/TokenManager.kt b/app/src/main/java/com/example/android_hit/utils/TokenManager.kt
index 7eb358d9745d69d296cb8fe60be588e80ffb52bd..461be58aa598d625c4f4d334d0f11ba89955a851 100644
--- a/app/src/main/java/com/example/android_hit/utils/TokenManager.kt
+++ b/app/src/main/java/com/example/android_hit/utils/TokenManager.kt
@@ -56,4 +56,9 @@ class TokenManager( context: Context) {
     fun deleteToken(){
         editor.clear().apply()
     }
+
+    fun getToken(): String? {
+
+        return sharedPref.getString("TOKEN", null)
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/res/drawable/iv_network_check.xml b/app/src/main/res/drawable/iv_network_check.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dab031b17951ddffb35e3f5d8d90bb9e2b81dcde
--- /dev/null
+++ b/app/src/main/res/drawable/iv_network_check.xml
@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#322F50"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M15.9,5c-0.17,0 -0.32,0.09 -0.41,0.23l-0.07,0.15 -5.18,11.65c-0.16,0.29 -0.26,0.61 -0.26,0.96 0,1.11 0.9,2.01 2.01,2.01 0.96,0 1.77,-0.68 1.96,-1.59l0.01,-0.03L16.4,5.5c0,-0.28 -0.22,-0.5 -0.5,-0.5zM1,9l2,2c2.88,-2.88 6.79,-4.08 10.53,-3.62l1.19,-2.68C9.89,3.84 4.74,5.27 1,9zM21,11l2,-2c-1.64,-1.64 -3.55,-2.82 -5.59,-3.57l-0.53,2.82c1.5,0.62 2.9,1.53 4.12,2.75zM17,15l2,-2c-0.8,-0.8 -1.7,-1.42 -2.66,-1.89l-0.55,2.92c0.42,0.27 0.83,0.59 1.21,0.97zM5,13l2,2c1.13,-1.13 2.56,-1.79 4.03,-2l1.28,-2.88c-2.63,-0.08 -5.3,0.87 -7.31,2.88z"/>
+</vector>
diff --git a/app/src/main/res/layout/fragment_graphs.xml b/app/src/main/res/layout/fragment_graphs.xml
index c4a97b48b38fa2f5c75b09d4446e5adf8e2387aa..e2436c8874fdd9a59b1f61a8824f17294c2305dd 100644
--- a/app/src/main/res/layout/fragment_graphs.xml
+++ b/app/src/main/res/layout/fragment_graphs.xml
@@ -11,11 +11,11 @@
         android:layout_height="match_parent">
 
 
-
         <androidx.constraintlayout.widget.ConstraintLayout
             android:id="@+id/constraintLayout"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:layout_marginTop="8dp"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent">
@@ -114,7 +114,9 @@
 
             <androidx.constraintlayout.widget.ConstraintLayout
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"/>
+                android:layout_height="match_parent">
+
+            </androidx.constraintlayout.widget.ConstraintLayout>
         </androidx.constraintlayout.widget.ConstraintLayout>
 
         <androidx.constraintlayout.widget.ConstraintLayout
diff --git a/app/src/main/res/layout/fragment_header_network.xml b/app/src/main/res/layout/fragment_header_network.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8658c4eb6453f58e35e187e953ff3448e42e4dcf
--- /dev/null
+++ b/app/src/main/res/layout/fragment_header_network.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@color/primary_color_4"
+    >
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/fragment_network_error.xml b/app/src/main/res/layout/fragment_network_error.xml
new file mode 100644
index 0000000000000000000000000000000000000000..130fe170d4cca4a32cc04993696af16542824426
--- /dev/null
+++ b/app/src/main/res/layout/fragment_network_error.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout 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"
+    tools:context=".NetworkError">
+
+    <!-- TODO: Update blank fragment layout -->
+    <ImageView
+        android:id="@+id/iv_network"
+        android:layout_width="91dp"
+        android:layout_height="129dp"
+        android:layout_centerInParent="true"
+        android:src="@drawable/iv_network_check" />
+
+    <TextView
+        android:id="@+id/text_network_check"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/iv_network"
+        android:layout_alignParentEnd="true"
+        android:layout_marginTop="13dp"
+        android:layout_marginEnd="164dp"
+        android:layout_marginBottom="451dp"
+        android:text="@string/network_check" />
+
+    <TextView
+        android:id="@+id/text_network_check_desc"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/iv_network"
+        android:layout_alignParentEnd="true"
+        android:layout_alignParentBottom="true"
+        android:layout_marginTop="47dp"
+        android:layout_marginEnd="82dp"
+        android:layout_marginBottom="235dp"
+        android:text="@string/network_check_desc" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml
index f734c21dae73c35315e00db5756cee63f760e3a4..637c6d10d816c815effe64b0f4b0af83cd7ce384 100644
--- a/app/src/main/res/layout/fragment_settings.xml
+++ b/app/src/main/res/layout/fragment_settings.xml
@@ -50,6 +50,15 @@
             android:text="Send Transaction List"
             android:layout_marginVertical="10dp"
             android:textColor="@color/primary1" />
+        <Button
+            android:id="@+id/randomizeTransactionButton"
+            android:layout_marginHorizontal="16dp"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="@drawable/rounded_background_transparent"
+            android:text="Randomize"
+            android:layout_marginVertical="10dp"
+            android:textColor="@color/primary1" />
 
         <Button
             android:id="@+id/logoutButton"
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e42b46d21fe46ae7e868af63732409e79893de44..16a6ea38e2a78a35ce190a4ab139c30c29cf2d01 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,4 +1,4 @@
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools">
     <string name="app_name">Android-HIT</string>
     <string name="tagline_awal">One Touch Solution for Your Budgeting</string>
     <string name="desc_tagline_awal">Overbudget? Don’t worry! With us, managing your income and expanses is only one touch away</string>
@@ -7,7 +7,6 @@
     <string name="greet">Hi!</string>
     <string name="password">Password </string>
     <string name="email">Email</string>
-    <!-- TODO: Remove or change this placeholder text -->
     <string name="hello_blank_fragment">Hello blank fragment</string>
     <!-- Strings related to login -->
     <string name="prompt_email">Email</string>
@@ -18,10 +17,14 @@
     <string name="invalid_username">Not a valid username</string>
     <string name="invalid_password">Password must be >5 characters</string>
     <string name="login_failed">"Login failed"</string>
-    <!-- TODO: Remove or change this placeholder text -->
+
     <string name="fragment_transaction">Transaction</string>
     <string name="fragment_settings">Settings</string>
     <string name="fragment_graphs">Graphs</string>
     <string name="fragment_scan">Scan</string>
 
+    <string name="network_check">Network Error</string>
+    <string name="network_check_desc">Please check your network connection</string>
+
+
 </resources>
\ No newline at end of file