This commit is contained in:
Aryankc2 2025-04-30 10:22:07 +05:30
parent baf0c5cbca
commit f1d2895202
6 changed files with 153 additions and 151 deletions

View file

@ -1,44 +0,0 @@
package com.example.fieldagent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import com.example.fieldagent.databinding.FragmentFirstBinding
/**
* A simple [Fragment] subclass as the default destination in the navigation.
*/
class FirstFragment : Fragment() {
private var _binding: FragmentFirstBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentFirstBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.buttonFirst.setOnClickListener {
// findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View file

@ -1,59 +0,0 @@
package com.example.fieldagent
import android.os.Bundle
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import android.view.Menu
import android.view.MenuItem
import com.example.fieldagent.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
val navController = findNavController(R.id.nav_host_fragment_content_main)
appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
binding.fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null)
.setAnchorView(R.id.fab).show()
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
return when (item.itemId) {
R.id.action_settings -> true
else -> super.onOptionsItemSelected(item)
}
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment_content_main)
return navController.navigateUp(appBarConfiguration)
|| super.onSupportNavigateUp()
}
}

View file

@ -1,44 +0,0 @@
package com.example.fieldagent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import com.example.fieldagent.databinding.FragmentSecondBinding
/**
* A simple [Fragment] subclass as the second destination in the navigation.
*/
class SecondFragment : Fragment() {
private var _binding: FragmentSecondBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentSecondBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.buttonSecond.setOnClickListener {
// findNavController().navigate(R.id.action_SecondFragment_to_FirstFragment)
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View file

@ -306,8 +306,11 @@ class DamageDetailsFragment : Fragment() {
if (from=="edit")
{
val jsonArray = JSONArray(urlList)
hashMap["images"] = jsonArray.toString().toRequestBody("application/json".toMediaType())
for ((index, url) in urlList.withIndex()) {
val key = "images[$index]"
val body = url.toRequestBody("text/plain".toMediaType()) // or "application/json" if backend expects
hashMap[key] = body
}
viewModel.editDamage(damageId,hashMap,imageParts)
}else{
viewModel.addDamage(hashMap,imageParts)

View file

@ -1,10 +1,18 @@
package com.example.fieldagent.ui.damagelist
import android.content.ContentValues
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.pdf.PdfDocument
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
@ -21,7 +29,12 @@ import com.example.fieldagent.utils.showConfirmDialog
import com.example.fieldagent.utils.visible
import com.google.gson.Gson
import dagger.hilt.android.AndroidEntryPoint
import java.io.File
import java.io.FileOutputStream
import java.text.SimpleDateFormat
import java.util.Date
import java.util.HashMap
import java.util.Locale
import javax.inject.Inject
@ -172,8 +185,135 @@ class DamageListFragment : Fragment() {
findNavController().popBackStack()
}
binding.btnExportPdf.setOnClickListener {
setUpPdf()
}
}
private fun setUpPdf(){
val pdfDocument = PdfDocument()
val pageInfo = PdfDocument.PageInfo.Builder(595, 842, 1).create()
val page = pdfDocument.startPage(pageInfo)
val canvas = page.canvas
val borderPaint = Paint().apply {
color = Color.BLACK
style = Paint.Style.STROKE
strokeWidth = 1f
}
val textPaint = Paint().apply {
textSize = 12f
color = Color.BLACK
style = Paint.Style.FILL
isAntiAlias = true
}
val whiteTextPaint = Paint(textPaint).apply { color = Color.WHITE }
val fillPaint = Paint().apply {
style = Paint.Style.FILL
}
// Column layout
val colWidths = listOf(40f, 100f, 60f, 100f, 60f, 120f)
val rowHeight = 40f
val startX = 40f
var startY = 60f
val title = "Damage Report Table"
val headers = listOf("No.", "Item", "Number", "Individual Cost", "Unit", "Total Cost (Riyals)")
val rows = listOf(
listOf("1", "Chair", "4", "50", "pcs", "200"),
listOf("2", "Table", "2", "150", "pcs", "300"),
listOf("3", "مكتب", "1", "500", "قطعة", "500"),
listOf("4", "Desk", "1", "450", "pcs", "450")
)
val centerAlignedColumns = setOf(0, 2, 3, 5) // columns to center text
fun drawCellText(canvas: Canvas, text: String, x: Float, y: Float, width: Float, paint: Paint, center: Boolean) {
val drawX = if (center) {
x + (width / 2f) - (paint.measureText(text) / 2f)
} else {
x + 5f
}
canvas.drawText(text, drawX, y, paint)
}
// --- Draw title row ---
fillPaint.color = Color.parseColor("#006400") // dark green
canvas.drawRect(startX, startY, startX + colWidths.sum(), startY + rowHeight, fillPaint)
canvas.drawRect(startX, startY, startX + colWidths.sum(), startY + rowHeight, borderPaint)
val titleX = startX + (colWidths.sum() / 2f) - (whiteTextPaint.measureText(title) / 2f)
canvas.drawText(title, titleX, startY + 25f, whiteTextPaint)
startY += rowHeight
// --- Draw header row ---
fillPaint.color = Color.parseColor("#90EE90") // light green
var x = startX
for ((i, header) in headers.withIndex()) {
val width = colWidths[i]
canvas.drawRect(x, startY, x + width, startY + rowHeight, fillPaint)
canvas.drawRect(x, startY, x + width, startY + rowHeight, borderPaint)
drawCellText(canvas, header, x, startY + 25f, width, textPaint, i in centerAlignedColumns)
x += width
}
startY += rowHeight
// --- Draw data rows ---
for ((index, row) in rows.withIndex()) {
fillPaint.color = if (index % 2 == 0) Color.WHITE else Color.parseColor("#E6FFE6")
x = startX
for ((i, cell) in row.withIndex()) {
val width = colWidths[i]
canvas.drawRect(x, startY, x + width, startY + rowHeight, fillPaint)
canvas.drawRect(x, startY, x + width, startY + rowHeight, borderPaint)
drawCellText(canvas, cell, x, startY + 25f, width, textPaint, i in centerAlignedColumns)
x += width
}
startY += rowHeight
}
pdfDocument.finishPage(page)
val fileName = "damage_report_" + SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(
Date()
)
savePdfToDocuments(pdfDocument, fileName)
}
fun savePdfToDocuments( pdfDocument: PdfDocument, fileName: String) {
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "$fileName.pdf")
put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf")
put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOCUMENTS)
put(MediaStore.MediaColumns.IS_PENDING, 1)
}
val resolver = requireActivity().contentResolver
val uri = resolver.insert(MediaStore.Files.getContentUri("external"), contentValues)
uri?.let {
resolver.openOutputStream(it)?.use { outputStream ->
pdfDocument.writeTo(outputStream)
pdfDocument.close()
}
contentValues.clear()
contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0)
resolver.update(uri, contentValues, null, null)
Toast.makeText(context, "PDF saved to Documents!", Toast.LENGTH_LONG).show()
} ?: run {
Toast.makeText(context, "Failed to save PDF", Toast.LENGTH_SHORT).show()
}
}
fun clickItem(pos: Int) {
val gson = Gson()

View file

@ -158,6 +158,14 @@
<string name="save">Save</string>
<string name="profile_updated_successfully">Profile updated successfully</string>
<string name="are_you_sure_you_want_to_delete">Are you sure you want to delete?</string>
<string name="damage_report_table">Damage Report Table</string>
<string name="no.">No.</string>
<string name="item">Item</string>
<string name="number">Number</string>
<string name="unit">Unit</string>
<string name="total_cost_in_riyals">Total Cost in Riyals</string>
<string name="total_cost">Total Cost</string>
<string name="individual_cost">Individual Cost in Riyals</string>
<string-array name="availability">
@ -205,6 +213,4 @@
<item>@string/liter</item>
<item>@string/kg</item>
</string-array>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
</resources>