diff --git a/.idea/misc.xml b/.idea/misc.xml
index 0ad17cbd33a2f389d524bc4bfef9c52e1f7ab490..f1044879e31aa73a3e757a2f81a68e7c26bd222a 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="ExternalStorageConfigurationManager" enabled="true" />
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/build/classes" />
   </component>
   <component name="ProjectType">
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index a20d57ed3c0bc8cac41cee5a5d5ce1c215bc4a8d..e40a96212e0ca27ed185ec5e1d5de957ca615d08 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -64,6 +64,8 @@ dependencies {
 
     //QR COde
     implementation ("com.github.yuriy-budiyev:code-scanner:2.3.0")
+    implementation ("com.journeyapps:zxing-android-embedded:4.2.0")
+    implementation ("com.google.zxing:core:3.4.1") // note
 
     // Graph
     implementation("com.github.PhilJay:MPAndroidChart:v3.1.0")
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 1332daba8108a151989a0ad68341ece09f1de182..d5df3c05c5c719ea7e646e892b520d138135fd98 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,15 +7,14 @@
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
-    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
-        android:maxSdkVersion="32" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
-        android:maxSdkVersion="32" />
     <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
     <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
     <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
 
     <uses-permission android:name="android.permission.CAMERA"/>
+    <uses-sdk tools:overrideLibrary="com.google.zxing.client.android" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
     <uses-feature
         android:name="android.hardware.camera"
@@ -25,6 +24,7 @@
     <application
         android:name=".BondowowoApp"
         android:allowBackup="true"
+        android:requestLegacyExternalStorage="true"
         android:dataExtractionRules="@xml/data_extraction_rules"
         android:fullBackupContent="@xml/backup_rules"
         android:icon="@mipmap/ic_launcher"
@@ -50,6 +50,10 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <activity
+            android:name="com.journeyapps.barcodescanner.CaptureActivity"
+            android:screenOrientation="fullSensor"
+            tools:replace="screenOrientation" />
         <activity android:name=".ui.settings.ExportToFileActivity" />
         <activity android:name=".ui.settings.SendEmailActivity" />
 
diff --git a/app/src/main/java/com/atm/bondowowo/ui/scan/ScanFragment.kt b/app/src/main/java/com/atm/bondowowo/ui/scan/ScanFragment.kt
index 13d2dbb861c9d51b5a496376f8c0f56cb6277be3..ce83385dda48152622b0ff4d94614de1d10680f6 100644
--- a/app/src/main/java/com/atm/bondowowo/ui/scan/ScanFragment.kt
+++ b/app/src/main/java/com/atm/bondowowo/ui/scan/ScanFragment.kt
@@ -1,12 +1,23 @@
 package com.atm.bondowowo.ui.scan
 
 import android.Manifest
+import android.app.Activity
+import android.app.AlertDialog
+import android.content.Intent
 import android.content.pm.PackageManager
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.net.Uri
 import android.os.Bundle
+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.TextView
 import android.widget.Toast
+import androidx.activity.result.contract.ActivityResultContracts
 import androidx.core.app.ActivityCompat
 import androidx.core.content.ContextCompat
 import androidx.fragment.app.Fragment
@@ -14,8 +25,25 @@ import com.atm.bondowowo.R
 import com.budiyev.android.codescanner.CodeScanner
 import com.budiyev.android.codescanner.CodeScannerView
 import com.budiyev.android.codescanner.DecodeCallback
+import com.google.zxing.BinaryBitmap
+import com.google.zxing.ChecksumException
+import com.google.zxing.FormatException
+import com.google.zxing.LuminanceSource
+import com.google.zxing.MultiFormatReader
+import com.google.zxing.NotFoundException
+import com.google.zxing.RGBLuminanceSource
+import com.google.zxing.Reader
+import com.google.zxing.common.HybridBinarizer
+import java.io.BufferedInputStream
+import java.io.File
+import java.io.FileInputStream
+import java.io.InputStream
 
 class ScanFragment : Fragment() {
+    private lateinit var tvResult: TextView
+    private var WRITE_EXTERNAL_STORAGE_PERMISSION_CODE: Int = 1
+    private var READ_EXTERNAL_STORAGE_PERMISSION_CODE: Int = 2
+
     private val CAMERA_PERMISSION_REQUEST_CODE = 100
     private lateinit var codeScanner: CodeScanner
 
@@ -26,6 +54,12 @@ class ScanFragment : Fragment() {
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
         val scannerView = view.findViewById<CodeScannerView>(R.id.scanner)
+        tvResult = view.findViewById(R.id.tv_result) //
+
+        val btnUpload = view.findViewById<Button>(R.id.btn_upload)
+        btnUpload.setOnClickListener {
+            openGallery()
+        }
 
         // Check camera permission
         if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
@@ -33,13 +67,71 @@ class ScanFragment : Fragment() {
         } else {
             initializeCodeScanner(scannerView)
         }
+
+        // for file
+        if (ContextCompat.checkSelfPermission(requireContext(),Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
+            ActivityCompat.requestPermissions(
+                requireActivity(),
+                arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
+                WRITE_EXTERNAL_STORAGE_PERMISSION_CODE
+            )
+        } else if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
+            ActivityCompat.requestPermissions(
+                requireActivity(),
+                arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
+                READ_EXTERNAL_STORAGE_PERMISSION_CODE
+            )
+        }
+    }
+
+    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+        if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
+            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+                val scannerView = requireView().findViewById<CodeScannerView>(R.id.scanner)
+                initializeCodeScanner(scannerView)
+            } else {
+                Toast.makeText(requireContext(), "Camera permission denied", Toast.LENGTH_SHORT).show()
+            }
+        } else if (requestCode == WRITE_EXTERNAL_STORAGE_PERMISSION_CODE) {
+            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_DENIED) {
+                Toast.makeText(
+                    requireContext(),
+                    "Anda perlu memberikan semua izin untuk menggunakan aplikasi ini.",
+                    Toast.LENGTH_SHORT
+                ).show()
+                requireActivity().finish()
+            }
+        } else if (requestCode == READ_EXTERNAL_STORAGE_PERMISSION_CODE) {
+            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_DENIED) {
+                Toast.makeText(
+                    requireContext(),
+                    "Anda perlu memberikan semua izin untuk menggunakan aplikasi ini.",
+                    Toast.LENGTH_SHORT
+                ).show()
+                requireActivity().finish()
+            }
+        }
     }
 
     private fun initializeCodeScanner(scannerView: CodeScannerView) {
         codeScanner = CodeScanner(requireActivity(), scannerView)
+        codeScanner.startPreview()
+
         codeScanner.decodeCallback = DecodeCallback {
             requireActivity().runOnUiThread {
+                val contents =  it.text
+                tvResult.text = contents
                 Toast.makeText(requireContext(), "Scanned: ${it.text}", Toast.LENGTH_LONG).show()
+
+                val scanOptions = arrayOf<String>("Ya", "Tidak")
+                AlertDialog.Builder(requireContext())
+                    .setTitle("Scan Berhasil!\nApakah ingin mengulagi proses Scan?")
+                    .setItems(scanOptions) {_, which -> when (which) {
+                        0 -> codeScanner.startPreview()
+                        1 -> setToTransaction()
+                    } }
+                    .create().show()
             }
         }
         scannerView.setOnClickListener {
@@ -47,15 +139,85 @@ class ScanFragment : Fragment() {
         }
     }
 
-    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
-        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
-        if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
-            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
-                val scannerView = requireView().findViewById<CodeScannerView>(R.id.scanner)
-                initializeCodeScanner(scannerView)
+    private fun setToTransaction() {
+        Log.d("TODO", "next to transaction")
+        TODO("Not yet implemented")
+    }
+
+    private fun openGallery() {
+        Log.d("ScanFragment", "Fungsi openGallery() dipanggil")
+        val galleryIntent =
+            Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
+        resultLauncherGallery.launch(galleryIntent)
+    }
+
+    private val resultLauncherGallery =
+        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
+            if (result.resultCode == Activity.RESULT_OK) {
+                val data: Intent? = result.data
+
+                val imageUri = data!!.data!!
+                val imagePath = convertMediaUriToPath(imageUri)
+                Log.d("ScanFragment", "Berhasil convertMediaUriToPath")
+                val imgFile = File(imagePath)
+                scanImageQRCode(imgFile)
+                Log.d("ScanFragment", "Berhasil scanImageQRCode")
             } else {
-                Toast.makeText(requireContext(), "Camera permission denied", Toast.LENGTH_SHORT).show()
+                Toast.makeText(requireContext(), "Result Not Found", Toast.LENGTH_LONG).show()
             }
         }
+
+    private fun convertMediaUriToPath(uri: Uri): String {
+        val proj = arrayOf(MediaStore.Images.Media.DATA)
+        val cursor = requireActivity().contentResolver.query(uri, proj, null, null, null)
+        val columnIndex = cursor!!.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
+        cursor.moveToFirst()
+        val path = cursor.getString(columnIndex)
+        cursor.close()
+        return path
+    }
+
+    private fun scanImageQRCode(file: File) {
+        val inputStream: InputStream = BufferedInputStream(FileInputStream(file))
+        val bitmap = BitmapFactory.decodeStream(inputStream)
+        val decoded = scanQRImage(bitmap)
+        Log.i("QrTest", "Decoded string=$decoded")
+    }
+
+    private fun scanQRImage(bMap: Bitmap): String? {
+        var contents: String? = null
+        val intArray = IntArray(bMap.width * bMap.height)
+        //copy pixel data from the Bitmap into the 'intArray' array
+        bMap.getPixels(intArray, 0, bMap.width, 0, 0, bMap.width, bMap.height)
+        val source: LuminanceSource = RGBLuminanceSource(bMap.width, bMap.height, intArray)
+        val bitmap = BinaryBitmap(HybridBinarizer(source))
+        val reader: Reader = MultiFormatReader()
+        try {
+            val result: com.google.zxing.Result = reader.decode(bitmap)
+            Log.d("scanQRImage", "berhasil yang bagian Result")
+            contents = result.text
+            // TODO MASUKIN BE DISINI
+
+            tvResult.text = contents
+
+            val scanOptions = arrayOf<String>("Ya", "Tidak")
+            AlertDialog.Builder(requireContext())
+                .setTitle("Scan Berhasil!\nApakah ingin mengulagi proses Scan?")
+                .setItems(scanOptions) {_, which -> when (which) {
+                    0 -> codeScanner.startPreview()
+                    1 -> setToTransaction()
+                } }
+                .create().show()
+
+        } catch (e: Exception) {
+            Log.e("QrTest", "Error decoding qr code", e)
+            Toast.makeText(
+                requireContext(),
+                "Error decoding QR Code, Mohon pilih gambar QR Code yang benar!",
+                Toast.LENGTH_SHORT
+            ).show()
+        }
+        return contents
     }
+
 }
diff --git a/app/src/main/res/layout/fragment_scan.xml b/app/src/main/res/layout/fragment_scan.xml
index 36b25531628c364f13e92516cd573573bdeaba13..b55566c2f84d7bbc7d926f81ab12fc799c37e21b 100644
--- a/app/src/main/res/layout/fragment_scan.xml
+++ b/app/src/main/res/layout/fragment_scan.xml
@@ -40,12 +40,23 @@
             android:layout_height="600dp"
             app:autoFocusButtonVisible="true"/>
 
+        <Button
+            android:id="@+id/btn_upload"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_marginTop="5dp"
+
+            android:text="Upload File"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent" />
+
         <TextView
-            android:id="@+id/tv_output"
+            android:id="@+id/tv_result"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginTop="20dp"
-            android:text="The result is here"
+            android:layout_marginTop="1dp"
+            android:text="..."
             android:textAlignment="center"
             android:textSize="20sp"
             android:textColor="#A92B"/>
diff --git a/build.gradle.kts b/build.gradle.kts
index 3893b8309e82cda878bd47d6c643304e6c98b23d..83773511e0af7d549b6f7d6225b49850fc1fca51 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -3,4 +3,12 @@ plugins {
     id("com.android.application") version "8.2.1" apply false
     id("org.jetbrains.kotlin.android") version "1.9.22" apply false
 
-}
\ No newline at end of file
+}
+
+// QR
+//allprojects {
+//    repositories {
+//        google()
+//        mavenCentral()
+//    }
+//}
\ No newline at end of file