generate pdf code added n
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
package `in`.sminnovations.smiadmin.data
|
||||
|
||||
object Constant {
|
||||
const val COMPANY_NAME = "ShanMukha Innovations"
|
||||
const val STORAGE_PERMISSION_CODE = 101
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package `in`.sminnovations.smiadmin.ui
|
||||
|
||||
import android.app.DatePickerDialog
|
||||
import android.app.Dialog
|
||||
import android.content.res.Resources
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import `in`.sminnovations.smiadmin.R
|
||||
import java.util.Calendar
|
||||
|
||||
class MonthYearPickerDialog : DialogFragment() {
|
||||
private var onDateSelected: ((Int, Int) -> Unit)? = null
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val calendar = Calendar.getInstance()
|
||||
val year = calendar.get(Calendar.YEAR)
|
||||
val month = calendar.get(Calendar.MONTH)
|
||||
|
||||
val dialog = DatePickerDialog(
|
||||
requireContext(),
|
||||
R.style.DialogTheme,
|
||||
{ _, selectedYear, selectedMonth, _ ->
|
||||
onDateSelected?.invoke(selectedYear, selectedMonth + 1)
|
||||
},
|
||||
year,
|
||||
month,
|
||||
1
|
||||
)
|
||||
|
||||
// Hide the day picker as we only need month and year
|
||||
val datePicker = dialog.datePicker
|
||||
datePicker.findViewById<View>(Resources.getSystem().getIdentifier("day", "id", "android"))?.visibility = View.GONE
|
||||
|
||||
return dialog
|
||||
}
|
||||
|
||||
fun setOnDateSelectedListener(listener: (Int, Int) -> Unit) {
|
||||
onDateSelected = listener
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package `in`.sminnovations.smiadmin.ui.attendance
|
||||
package `in`.sminnovations.smiadmin.ui.adapter
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
@@ -1,4 +1,4 @@
|
||||
package `in`.sminnovations.smiadmin
|
||||
package `in`.sminnovations.smiadmin.ui.adapter
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
@@ -6,6 +6,7 @@ import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.switchmaterial.SwitchMaterial
|
||||
import `in`.sminnovations.smiadmin.R
|
||||
import `in`.sminnovations.smiadmin.data.Employee
|
||||
|
||||
class EmployeeListAdapter(
|
||||
@@ -1,4 +1,4 @@
|
||||
package `in`.sminnovations.smiadmin.ui.attendance
|
||||
package `in`.sminnovations.smiadmin.ui.adapter
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
@@ -8,9 +8,9 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import `in`.sminnovations.smiadmin.R
|
||||
import `in`.sminnovations.smiadmin.data.Employee
|
||||
|
||||
class EmployeeListAdapter(
|
||||
class EmployeeStatusListAdapter(
|
||||
private val onEmployeeClick: (Employee) -> Unit
|
||||
) : RecyclerView.Adapter<EmployeeListAdapter.ViewHolder>() {
|
||||
) : RecyclerView.Adapter<EmployeeStatusListAdapter.ViewHolder>() {
|
||||
|
||||
private val employees = mutableListOf<Employee>()
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
package `in`.sminnovations.smiadmin.ui
|
||||
package `in`.sminnovations.smiadmin.ui.fragments
|
||||
|
||||
import android.Manifest
|
||||
import android.app.ProgressDialog
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.ContentUris
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.provider.MediaStore
|
||||
import android.provider.Settings
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
@@ -18,23 +15,16 @@ import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.cardview.widget.CardView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.google.firebase.Firebase
|
||||
import com.google.firebase.firestore.firestore
|
||||
import `in`.sminnovations.smiadmin.data.Constant.STORAGE_PERMISSION_CODE
|
||||
import `in`.sminnovations.smiadmin.R
|
||||
import `in`.sminnovations.smiadmin.data.Employee
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import `in`.sminnovations.smiadmin.ui.utils.ExportTask
|
||||
import `in`.sminnovations.smiadmin.ui.utils.MonthYearPickerDialog
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.tasks.await
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class HomeFragment : Fragment() {
|
||||
private lateinit var exportTask: ExportTask
|
||||
private val STORAGE_PERMISSION_CODE = 101
|
||||
private var currentExcelTask: Job? = null
|
||||
|
||||
override fun onCreateView(
|
||||
@@ -84,39 +74,6 @@ class HomeFragment : Fragment() {
|
||||
}
|
||||
exportTask.exportAttendance(year, month)
|
||||
progressDialog.dismiss()
|
||||
|
||||
// currentExcelTask = lifecycleScope.launch {
|
||||
// try {
|
||||
// // First get all employees
|
||||
// val employeesSnapshot = withContext(Dispatchers.IO) {
|
||||
// db.collection("employees").get().await()
|
||||
// }
|
||||
//
|
||||
// val employees = employeesSnapshot.documents.map { doc ->
|
||||
// Employee(
|
||||
// Id = doc.getString("Id") ?: "Unknown",
|
||||
// Name = doc.getString("Name") ?: "Unknown"
|
||||
// )
|
||||
// }.sortedBy { it.Name }
|
||||
//
|
||||
// // Generate CSV file
|
||||
// val pdfGenerator = PDFGenerator(requireContext(), "ShanMukha Innovations")
|
||||
// val pdfFile = pdfGenerator.generateAttendanceReport(employees, year, month)
|
||||
//
|
||||
// progressDialog.dismiss()
|
||||
//
|
||||
// // Show success message with file location
|
||||
// Toast.makeText(
|
||||
// context,
|
||||
// "Report saved in Downloads folder: ${pdfFile.name}",
|
||||
// Toast.LENGTH_LONG
|
||||
// ).show()
|
||||
//
|
||||
// } catch (e: Exception) {
|
||||
// progressDialog.dismiss()
|
||||
// Toast.makeText(context, "Error: ${e.message}", Toast.LENGTH_LONG).show()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private fun checkStoragePermission(): Boolean {
|
||||
@@ -1,4 +1,4 @@
|
||||
package `in`.sminnovations.smiadmin.ui
|
||||
package `in`.sminnovations.smiadmin.ui.fragments
|
||||
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
@@ -1,4 +1,4 @@
|
||||
package `in`.sminnovations.smiadmin.ui.attendance
|
||||
package `in`.sminnovations.smiadmin.ui.fragments.attendance
|
||||
|
||||
import android.R
|
||||
import android.os.Bundle
|
||||
@@ -12,6 +12,7 @@ import androidx.fragment.app.Fragment
|
||||
import com.google.firebase.firestore.FirebaseFirestore
|
||||
import `in`.sminnovations.smiadmin.data.AttendanceData
|
||||
import `in`.sminnovations.smiadmin.databinding.FragmentAttendanceDetailBinding
|
||||
import `in`.sminnovations.smiadmin.ui.adapter.AttendanceAdapter
|
||||
import java.util.Calendar
|
||||
|
||||
class AttendanceDetailFragment : Fragment() {
|
||||
@@ -1,4 +1,4 @@
|
||||
package `in`.sminnovations.smiadmin.ui.attendance
|
||||
package `in`.sminnovations.smiadmin.ui.fragments.attendance
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
@@ -11,12 +11,13 @@ import com.google.firebase.firestore.FirebaseFirestore
|
||||
import `in`.sminnovations.smiadmin.R
|
||||
import `in`.sminnovations.smiadmin.data.Employee
|
||||
import `in`.sminnovations.smiadmin.databinding.FragmentEmployeeAttendanceListBinding
|
||||
import `in`.sminnovations.smiadmin.ui.adapter.EmployeeStatusListAdapter
|
||||
|
||||
class EmployeeAttendanceListFragment : Fragment() {
|
||||
private var _binding: FragmentEmployeeAttendanceListBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private lateinit var adapter: EmployeeListAdapter
|
||||
private lateinit var adapter: EmployeeStatusListAdapter
|
||||
private val db = FirebaseFirestore.getInstance()
|
||||
|
||||
override fun onCreateView(
|
||||
@@ -36,7 +37,7 @@ class EmployeeAttendanceListFragment : Fragment() {
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
adapter = EmployeeListAdapter { employee ->
|
||||
adapter = EmployeeStatusListAdapter { employee ->
|
||||
val bundle = Bundle().apply {
|
||||
putString("employeeId", employee.Id)
|
||||
putString("employeeName", employee.Name)
|
||||
@@ -1,4 +1,4 @@
|
||||
package `in`.sminnovations.smiadmin.ui
|
||||
package `in`.sminnovations.smiadmin.ui.fragments.attendance
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
@@ -7,7 +7,7 @@ import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.firebase.firestore.FirebaseFirestore
|
||||
import `in`.sminnovations.smiadmin.EmployeeListAdapter
|
||||
import `in`.sminnovations.smiadmin.ui.adapter.EmployeeListAdapter
|
||||
import `in`.sminnovations.smiadmin.data.Employee
|
||||
import `in`.sminnovations.smiadmin.databinding.FragmentEmployeeListBinding
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package `in`.sminnovations.smiadmin.ui
|
||||
package `in`.sminnovations.smiadmin.ui.utils
|
||||
|
||||
import android.app.ProgressDialog
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.gms.common.internal.Constants
|
||||
import com.google.firebase.Firebase
|
||||
import com.google.firebase.firestore.firestore
|
||||
import `in`.sminnovations.smiadmin.data.Constant
|
||||
import `in`.sminnovations.smiadmin.data.Employee
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
@@ -15,7 +15,6 @@ import kotlinx.coroutines.tasks.await
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class ExportTask(private val fragment: Fragment) {
|
||||
private val companyName = "ShanMukha Innovations"
|
||||
private val db = Firebase.firestore
|
||||
private var currentExcelTask: Job? = null
|
||||
|
||||
@@ -49,7 +48,7 @@ class ExportTask(private val fragment: Fragment) {
|
||||
|
||||
// Switch to IO dispatcher for file operations
|
||||
withContext(Dispatchers.IO) {
|
||||
val pdfGenerator = PDFGenerator(fragment.requireContext(), companyName)
|
||||
val pdfGenerator = PDFGenerator(fragment.requireContext(), Constant.COMPANY_NAME)
|
||||
pdfGenerator.generateAttendanceReport(employees, year, month)
|
||||
}.also { pdfFile ->
|
||||
// Switch back to Main dispatcher for UI updates
|
||||
@@ -0,0 +1,57 @@
|
||||
package `in`.sminnovations.smiadmin.ui.utils
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.app.DatePickerDialog
|
||||
import android.app.Dialog
|
||||
import android.content.res.Resources
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.NumberPicker
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import `in`.sminnovations.smiadmin.R
|
||||
import java.util.Calendar
|
||||
|
||||
class MonthYearPickerDialog : DialogFragment() {
|
||||
private var onDateSelected: ((Int, Int) -> Unit)? = null
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
// Inflate the custom layout
|
||||
val view = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_month_year_picker, null)
|
||||
|
||||
// Initialize NumberPickers for Month and Year
|
||||
val monthPicker = view.findViewById<NumberPicker>(R.id.month_picker)
|
||||
val yearPicker = view.findViewById<NumberPicker>(R.id.year_picker)
|
||||
|
||||
// Set up the Month Picker
|
||||
monthPicker.minValue = 1
|
||||
monthPicker.maxValue = 12
|
||||
monthPicker.displayedValues = arrayOf(
|
||||
"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"
|
||||
)
|
||||
|
||||
// Set up the Year Picker
|
||||
val currentYear = Calendar.getInstance().get(Calendar.YEAR)
|
||||
yearPicker.minValue = currentYear - 100 // 100 years in the past
|
||||
yearPicker.maxValue = currentYear + 100 // 100 years in the future
|
||||
yearPicker.value = currentYear
|
||||
|
||||
// Build the Dialog
|
||||
val dialog = AlertDialog.Builder(requireContext())
|
||||
.setView(view)
|
||||
.setPositiveButton("OK") { _, _ ->
|
||||
val selectedMonth = monthPicker.value
|
||||
val selectedYear = yearPicker.value
|
||||
onDateSelected?.invoke(selectedYear, selectedMonth)
|
||||
}
|
||||
.setNegativeButton("Cancel", null)
|
||||
.create()
|
||||
|
||||
return dialog
|
||||
}
|
||||
|
||||
fun setOnDateSelectedListener(listener: (Int, Int) -> Unit) {
|
||||
onDateSelected = listener
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package `in`.sminnovations.smiadmin.ui
|
||||
package `in`.sminnovations.smiadmin.ui.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.pdf.PdfDocument
|
||||
21
app/src/main/res/layout/dialog_month_year_picker.xml
Normal file
21
app/src/main/res/layout/dialog_month_year_picker.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<!-- Month Picker -->
|
||||
<NumberPicker
|
||||
android:id="@+id/month_picker"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<!-- Year Picker -->
|
||||
<NumberPicker
|
||||
android:id="@+id/year_picker"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<fragment
|
||||
android:id="@+id/navigation_home"
|
||||
android:name="in.sminnovations.smiadmin.ui.HomeFragment"
|
||||
android:name="in.sminnovations.smiadmin.ui.fragments.HomeFragment"
|
||||
android:label="Home">
|
||||
<action
|
||||
android:id="@+id/action_home_to_employee_list"
|
||||
@@ -18,17 +18,17 @@
|
||||
|
||||
<fragment
|
||||
android:id="@+id/navigation_settings"
|
||||
android:name="in.sminnovations.smiadmin.ui.SettingsFragment"
|
||||
android:name="in.sminnovations.smiadmin.ui.fragments.SettingsFragment"
|
||||
android:label="Settings" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/navigation_employee_list"
|
||||
android:name="in.sminnovations.smiadmin.ui.EmployeeListFragment"
|
||||
android:name="in.sminnovations.smiadmin.ui.fragments.attendance.EmployeeListFragment"
|
||||
android:label="Employee List" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/navigation_employee_attendance_list"
|
||||
android:name="in.sminnovations.smiadmin.ui.attendance.EmployeeAttendanceListFragment"
|
||||
android:name="in.sminnovations.smiadmin.ui.fragments.attendance.EmployeeAttendanceListFragment"
|
||||
android:label="Employee List">
|
||||
<action
|
||||
android:id="@+id/action_employee_list_to_attendance_detail"
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
<fragment
|
||||
android:id="@+id/navigation_attendance_detail"
|
||||
android:name="in.sminnovations.smiadmin.ui.attendance.AttendanceDetailFragment"
|
||||
android:name="in.sminnovations.smiadmin.ui.fragments.attendance.AttendanceDetailFragment"
|
||||
android:label="Attendance Detail">
|
||||
<argument
|
||||
android:name="employeeId"
|
||||
|
||||
Reference in New Issue
Block a user