diff --git a/.idea/misc.xml b/.idea/misc.xml index f3514419..e41c484c 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -10,7 +10,7 @@ diff --git a/app/build.gradle b/app/build.gradle index 4f769f82..73e2905b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -162,6 +162,10 @@ dependencies { implementation files('libs/A26Library-debug.aar') // vpos + implementation files('libs/dpuareu.jar') + + + // Sweet Alert Dialog implementation 'cn.pedant.sweetalert:library:1.3' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index abd6568d..80991916 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -28,6 +28,10 @@ + + diff --git a/app/src/main/java/com/steve_md/smartmkulima/adapter/AgroDealersAdapter.kt b/app/src/main/java/com/steve_md/smartmkulima/adapter/AgroDealersAdapter.kt new file mode 100644 index 00000000..9868273a --- /dev/null +++ b/app/src/main/java/com/steve_md/smartmkulima/adapter/AgroDealersAdapter.kt @@ -0,0 +1,63 @@ +package com.steve_md.smartmkulima.adapter + +import android.location.Location +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.google.android.gms.maps.model.LatLng +import com.steve_md.smartmkulima.R +import com.steve_md.smartmkulima.model.AgroDealer + +class AgrodealerAdapter( + private val agrodealers: List, + private val userLocation: LatLng, + private val onClickListener: OnClickListener +) : RecyclerView.Adapter() { + + class AgrodealerViewHolder(view: View) : RecyclerView.ViewHolder(view) { + val nameTextView: TextView = view.findViewById(R.id.agrodealer_name) + val contactTextView: TextView = view.findViewById(R.id.textViewPhone) + val tvEmail: TextView = view.findViewById(R.id.textViewEmail) + val distanceTextView : TextView = view.findViewById(R.id.tvLocation) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AgrodealerViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.item_agrodealer, parent, false) + return AgrodealerViewHolder(view) + } + + override fun onBindViewHolder(holder: AgrodealerViewHolder, position: Int) { + val agrodealer = agrodealers[position] + holder.nameTextView.text = agrodealer.name + holder.contactTextView.text = agrodealer.phone + holder.tvEmail.text = agrodealer.email + + // Calculate the distance between the user's location and the agrodealer + val agrovetLatLng = LatLng(agrodealer.latitude, agrodealer.longitude) + val distance = calculateDistance(userLocation, agrovetLatLng) + holder.distanceTextView.text = String.format("%.2f km away", distance / 1000) + + holder.itemView.setOnClickListener { + onClickListener.onClick(agrodealer = agrodealer) + } + } + + override fun getItemCount(): Int = agrodealers.size + + private fun calculateDistance(startLatLng: LatLng, endLatLng: LatLng): Float { + val results = FloatArray(1) + Location.distanceBetween( + startLatLng.latitude, startLatLng.longitude, + endLatLng.latitude, endLatLng.longitude, + results + ) + return results[0] + } + + class OnClickListener(val clickListener: (agrodealer: AgroDealer) -> Unit) { + fun onClick(agrodealer: AgroDealer) = clickListener(agrodealer) + } +} diff --git a/app/src/main/java/com/steve_md/smartmkulima/model/AgriTechCompany.kt b/app/src/main/java/com/steve_md/smartmkulima/model/AgriTechCompany.kt deleted file mode 100644 index c9a000be..00000000 --- a/app/src/main/java/com/steve_md/smartmkulima/model/AgriTechCompany.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.steve_md.smartmkulima.model - -/** @Class - * Populate all available AgriTech Companies - */ -data class AgriTechCompany( - val name:String, - val latitude:Double, - val longitude:Double -) diff --git a/app/src/main/java/com/steve_md/smartmkulima/model/AgroDealerData.kt b/app/src/main/java/com/steve_md/smartmkulima/model/AgroDealerData.kt new file mode 100644 index 00000000..844a055e --- /dev/null +++ b/app/src/main/java/com/steve_md/smartmkulima/model/AgroDealerData.kt @@ -0,0 +1,28 @@ +package com.steve_md.smartmkulima.model + +import android.os.Parcelable +import com.google.android.gms.maps.model.LatLng +import kotlinx.parcelize.Parcelize + +/** + * A data class to represent agro-dealer data / supplier data + */ +data class AgroDealerData( + val name:String, + val latitude:Double, + val longitude:Double +) + + +@Parcelize +data class AgroDealer( + val name: String, + val phone: String, + val email: String, + val latitude: Double, + val longitude:Double, + val servicesOffered: String, + val categories: String, + val leasingOptionsAvailable: String, + val leasingDetails: String +) : Parcelable diff --git a/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/HireFarmEquipmentsFragment.kt b/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/HireFarmEquipmentsFragment.kt index 79dbb3d0..de9032cf 100644 --- a/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/HireFarmEquipmentsFragment.kt +++ b/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/HireFarmEquipmentsFragment.kt @@ -41,11 +41,13 @@ class HireFarmEquipmentsFragment : Fragment() { (activity as AppCompatActivity).supportActionBar?.hide() - farmEquipmentsRecylerView = view.findViewById(R.id.farmEquipmentsRecyclerView) setUpBinding() + /** + * Passing @param FarmEquipment as an argument + */ farmEquipmentsAdapter = FarmEquipmentAdapter(FarmEquipmentAdapter.OnClickListener { farmEquipment -> Timber.i("Farm Equipments: ${farmEquipment.name}") diff --git a/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/LocateAgriTechCompaniesFragment.kt b/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/LocateAgriTechCompaniesFragment.kt index 76e00a12..084d5c61 100644 --- a/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/LocateAgriTechCompaniesFragment.kt +++ b/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/LocateAgriTechCompaniesFragment.kt @@ -1,15 +1,22 @@ package com.steve_md.smartmkulima.ui.fragments.main +import android.Manifest.permission.ACCESS_COARSE_LOCATION import android.Manifest.permission.ACCESS_FINE_LOCATION import android.content.pm.PackageManager +import android.location.Location import android.os.Bundle -import android.printservice.PrintService import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.LinearLayout import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.fragment.app.Fragment +import androidx.navigation.fragment.findNavController +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.google.android.gms.location.FusedLocationProviderClient +import com.google.android.gms.location.LocationServices import com.google.android.gms.maps.CameraUpdateFactory import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.MapView @@ -18,23 +25,34 @@ import com.google.android.gms.maps.model.BitmapDescriptorFactory import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.MarkerOptions import com.steve_md.smartmkulima.R -import com.steve_md.smartmkulima.model.AgriTechCompany +import com.steve_md.smartmkulima.adapter.AgrodealerAdapter +import com.steve_md.smartmkulima.model.AgroDealer import dagger.hilt.android.AndroidEntryPoint -import com.nexgo.oaf.apiv3.device.printer.Printer - +import timber.log.Timber /** - * Display near Agrovet companies via a Map + * AGRO-DEALERS_LOCATION_FRAGMENT + * + * Display near Agro-Dealers companies :) + * + * AgroDealers Location + * - AgroDealer's name, Contact details, Location (0.95 km away), + * - Farm inputs, Leasing options, Services offering + * + * - Filter Agro-Dealers with proximity to the user's location */ @AndroidEntryPoint class LocateAgriTechCompaniesFragment : Fragment() , OnMapReadyCallback { private lateinit var mapView: MapView private lateinit var googleMap: GoogleMap + private lateinit var fusedLocationClient: FusedLocationProviderClient + companion object { private const val LOCATION_PERMISSION_REQUEST_CODE = 1 + private const val SEARCH_RADIUS_METERS = 50000 // 50 km radius } override fun onCreateView( @@ -51,77 +69,145 @@ class LocateAgriTechCompaniesFragment : Fragment() , OnMapReadyCallback { // Initialize the MapView mapView = rootView.findViewById(R.id.mapView) mapView.onCreate(savedInstanceState) + + // Trigger map ready to be used, from the callback (OnMapReadyCallback) mapView.getMapAsync(this) (activity as AppCompatActivity).supportActionBar?.hide() + + fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireActivity()) + return rootView } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + setUpBinding() } + private fun setUpBinding() { + view?.findViewById(R.id.topbar_linear_layout)?.setOnClickListener { + // findNavController().popBackStack(R.id.newFarmingTechnologyFragment, true) + findNavController().navigateUp() + } - override fun onResume() { - super.onResume() - mapView.onResume() - } + // Inflate Data To Recycler View + val recyclerView = view?.findViewById(R.id.agrodealersListRecView) + recyclerView!!.layoutManager = LinearLayoutManager(requireContext()) - override fun onPause() { - super.onPause() - mapView.onPause() - } + if (ActivityCompat.checkSelfPermission( + requireContext(), + ACCESS_FINE_LOCATION + ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( + requireContext(), + ACCESS_COARSE_LOCATION + ) != PackageManager.PERMISSION_GRANTED + ) { + requestLocationPermission() + return + } + fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? -> + location?.let { + val userLatLng = LatLng(it.latitude, it.longitude) + val filteredAgrodealers = getAgroDealersData().filter { agrovet -> + + val agroDealerLatLng = LatLng(agrovet.latitude,agrovet.longitude) + calculateDistance(userLatLng, agroDealerLatLng) <= SEARCH_RADIUS_METERS + } + + recyclerView.adapter = AgrodealerAdapter( + filteredAgrodealers, + userLatLng, + AgrodealerAdapter.OnClickListener { agrodealer -> + Timber.i("Agrodealer: ${agrodealer.name}") + + val directions = LocateAgriTechCompaniesFragmentDirections.actionLocateAgriTechCompaniesFragmentToViewAgroDealerInDetailFragment( + agrodealer + ) + + findNavController().navigate(directions) + + }) + } + } - override fun onStop() { - super.onStop() - mapView.onStop() - } - override fun onDestroyView() { - super.onDestroyView() - requireActivity().isDestroyed - } - override fun onDestroy() { - super.onDestroy() - mapView.onDestroy() - } - override fun onLowMemory() { - super.onLowMemory() - mapView.onLowMemory() } + override fun onMapReady(map: GoogleMap) { googleMap = map + /** + * If permissions have been already granted + */ if (ActivityCompat.checkSelfPermission( requireContext(), ACCESS_FINE_LOCATION ) == PackageManager.PERMISSION_GRANTED ) { googleMap.isMyLocationEnabled = true + getMyCurrentLocation() } else { - // Request location permission + // Otherwise, Request location permission by prompting the user returning to the app requestLocationPermission() } + } - // Add sample Agrovet Markers - val agrovets = getAgrovetsData() - for (agrovet in agrovets) { - val location = LatLng(agrovet.latitude, agrovet.longitude) - googleMap.addMarker(MarkerOptions() - .position(location) - .title(agrovet.name)) - ?.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)) + private fun getMyCurrentLocation() { + if (ActivityCompat.checkSelfPermission( + requireContext(), + ACCESS_FINE_LOCATION + ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( + requireContext(), + ACCESS_COARSE_LOCATION + ) != PackageManager.PERMISSION_GRANTED + ) { + promptUserForLocationPermissions() + return } + fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? -> + location?.let { + val userLatLng = LatLng(it.latitude, it.longitude) + val agrodealers = getAgroDealersData().filter { agrovet -> + val agrovetLatLng = LatLng(agrovet.latitude, agrovet.longitude) + calculateDistance(userLatLng, agrovetLatLng) <= SEARCH_RADIUS_METERS + } + + // Add filtered Agro-Dealers Markers to the map + for (agrodealer in agrodealers) { + val location = LatLng(agrodealer.latitude, agrodealer.longitude) + googleMap.addMarker( + MarkerOptions() + .position(location) + .title(agrodealer.name) + )?.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)) + } - if (agrovets.isNotEmpty()) { - val firstLocation = LatLng(agrovets[0].latitude, agrovets[0].longitude) - googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(firstLocation, 18f)) - googleMap.animateCamera(CameraUpdateFactory.zoomIn()) - googleMap.animateCamera(CameraUpdateFactory.zoomTo(13f), 2000, null) + if (agrodealers.isNotEmpty()) { + googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(userLatLng, 13f)) + } + } } } + + // Nearby within 50 kilometres + private fun calculateDistance(startLatLng: LatLng, endLatLng: LatLng): Float { + val results = FloatArray(1) + Location.distanceBetween( + startLatLng.latitude, startLatLng.longitude, + endLatLng.latitude, endLatLng.longitude, + results + ) + return results[0] + } + + + /** + * Prompt the user to enter permissions In case permissions aren't granted / == null + */ private fun requestLocationPermission() { ActivityCompat.requestPermissions( requireActivity(), @@ -130,14 +216,129 @@ class LocateAgriTechCompaniesFragment : Fragment() , OnMapReadyCallback { ) } - // Just Dummy Data to Display Available AgriTech Companies - private fun getAgrovetsData(): List { + // Gathered & Collected Agro-Dealers data to display Available AgroDealers + // filter agrodealers based on proximity to the user's exact location and nearby agrodealers + private fun getAgroDealersData(): List { return listOf( - AgriTechCompany("SIKATA AGRITECH FARMERS CHOICE", 0.5929, 34.5429839), - AgriTechCompany("ROSE AGRITECH COMPANY", 0.5960, 34.543333), - AgriTechCompany("JOSEMO AGRITECH & DISTRIBUTORS BUNGOMA", 0.565110, 34.5431684), - AgriTechCompany("OMUSALE AGRITECH & AGROVET", 0.565095, 34.5431600), - AgriTechCompany("MULTIDUSH AGRITECH & AGROVET SUPPLIES", 0.565100, 34.545406) + + // Near Bung-oma Town + AgroDealer("SIKATA AGRITECH FARMERS CHOICE","254712907551", "sikataagrifarm@gmail.com",0.5929, 34.5429839,"Fertilizer","Agricultural","true","6 months duration, monthly payment terms"), + AgroDealer("ROSE AGRITECH COMPANY", "0740408989" ,"roseag@gmail.com",0.5960, 34.543333,"Fertilizer","Agricultural","true","1 year duration, monthly payment terms"), + AgroDealer("JOSEMO AGRITECH & DISTRIBUTORS BUNGOMA", "0791347689","josemoagrodealers@yahoo.com",0.565110, 34.5431684,"Fertilizer","Agricultural","true","3 months duration, weekly payment terms"), + AgroDealer("OMUSALE AGRITECH & AGROVET","0747909084","info@omusale.com", 0.565095, 34.5431600,"Fertilizer","Agricultural","true","1 months duration, weekly payment terms"), + AgroDealer("MULTIDUSH AGRITECH & AGROVET SUPPLIES", "","info@multidushagritechsupplies.co.ke", 0.565100, 34.545406,"Fertilizer","Agricultural","true","2 months duration, monthly payment terms"), + + // Near Nairobi + AgroDealer("Farmers Solution Agrovet","254700932932", "farmerssolutionagrovet@gmail.com",-1.2860464,36.8026465,"Agrochemicals","Agricultural inputs","false","Leasing is not available"), + AgroDealer("Mifugo Agrovet centre","254701898905", "info@mifugoagrovetcentre.co.ke",-1.286548536,36.8067588,"Fertilizers, farm machinery","Agricultural","true","6 months duration, monthly payment terms"), + + + // Near Kiambu + + // Near Makueni + + // Near Kijabe + + // Near Soko Mjinga + + // Near Murang'a + + // Near Nyandarua + + // Near Uthiru + + // Near Thika + + // Near Kitui + + // Near Machakos + + // Near Naivasha + + // Near Nakuru + + // Near Eldoret + + // Near Mombasa + + // Near Bomet + ) + } + + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + + if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) { + if (grantResults.isNotEmpty() && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) { + + // Enable the location + if (ActivityCompat.checkSelfPermission( + requireContext(), + ACCESS_FINE_LOCATION + ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( + requireContext(), + ACCESS_COARSE_LOCATION + ) != PackageManager.PERMISSION_GRANTED + ) { + promptUserForLocationPermissions() + return + } + googleMap.isMyLocationEnabled = true + } + } else { + getMyCurrentLocation() + } + } + + private fun promptUserForLocationPermissions() { + ActivityCompat.requestPermissions( + requireActivity(), + arrayOf(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION), + LOCATION_PERMISSION_REQUEST_CODE ) } + + + override fun onResume() { + super.onResume() + mapView.onResume() + } + + override fun onPause() { + super.onPause() + mapView.onPause() + } + + override fun onStop() { + super.onStop() + mapView.onStop() + } + override fun onDestroyView() { + super.onDestroyView() + requireActivity().isDestroyed + + googleMap.clear() + + mapView.onDestroy() + + googleMap.setOnMapClickListener(null) + googleMap.setOnMarkerClickListener(null) + } + override fun onDestroy() { + super.onDestroy() + mapView.onDestroy() + googleMap.clear() + googleMap.setOnMarkerClickListener(null) + googleMap.setOnMapClickListener(null) + } + + override fun onLowMemory() { + super.onLowMemory() + mapView.onLowMemory() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/MonitorFarmConditionFragment.kt b/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/MonitorFarmConditionFragment.kt index 2d08d974..208bd169 100644 --- a/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/MonitorFarmConditionFragment.kt +++ b/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/MonitorFarmConditionFragment.kt @@ -7,9 +7,11 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView +import android.widget.ProgressBar import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat +import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController import com.google.android.gms.maps.CameraUpdateFactory @@ -22,6 +24,7 @@ import com.google.android.gms.maps.model.MarkerOptions import com.steve_md.smartmkulima.R import com.steve_md.smartmkulima.model.FarmConditions import com.steve_md.smartmkulima.ui.fragments.others.LocationProvider +import com.steve_md.smartmkulima.utils.displaySnackBar import dagger.hilt.android.AndroidEntryPoint import timber.log.Timber @@ -59,11 +62,19 @@ class MonitorFarmConditionFragment : Fragment(),OnMapReadyCallback { // Request user's location locationProvider.getLastKnownLocation { location -> + + val loading = view.findViewById(R.id.progressBar8) + loading.isVisible = true + if (location != null) { + loading.isVisible = false monitorFarmConditions(location.latitude, location.longitude) + displaySnackBar("Location Update successful.") } else { // Handle case when location is null + loading.isVisible = false Timber.e("An error occurred") + displaySnackBar("Could not update your location") } } } diff --git a/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/SuccessfulPaymentFragment.kt b/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/SuccessfulPaymentFragment.kt index 6fe89b30..28516e35 100644 --- a/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/SuccessfulPaymentFragment.kt +++ b/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/SuccessfulPaymentFragment.kt @@ -1,5 +1,6 @@ package com.steve_md.smartmkulima.ui.fragments.main +import android.content.Intent import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -10,7 +11,14 @@ import androidx.navigation.fragment.findNavController import com.airbnb.lottie.LottieDrawable import com.steve_md.smartmkulima.R import com.steve_md.smartmkulima.databinding.FragmentSuccessfulPaymentBinding +import com.steve_md.smartmkulima.utils.services.Config +import com.steve_md.smartmkulima.utils.services.NumberUtil +import com.steve_md.smartmkulima.utils.services.PrintServiceActivity import dagger.hilt.android.AndroidEntryPoint +import org.json.JSONException +import org.json.JSONObject + +var map: HashMap = HashMap() @AndroidEntryPoint @@ -45,5 +53,55 @@ class SuccessfulPaymentFragment : Fragment() { binding.buttonGoHome.setOnClickListener { findNavController().navigate(R.id.action_successfulPaymentFragment_to_applyInsuranceFragment) } + binding.buttonPrintReceipt.setOnClickListener { + map["reference"] = "txnReference" + map["qr_auth_code"] = "qr_auth_code" + + // Create an empty JSONObject if you don't have any data to pass + val jsonObject = JSONObject() + + PrintServiceActivity.startPrinting(context, map, getDepositReceiptText(jsonObject)) + startActivity(Intent(requireContext(), PrintServiceActivity::class.java)) + requireActivity().finish() + } + + } + + + @Throws(JSONException::class) + private fun getDepositReceiptText(jsonObject: JSONObject): Array { + val wasTxnSuccessful = jsonObject.optBoolean("wasTxnSuccessful", false) + return if (wasTxnSuccessful) { + + val totalAmount = + (jsonObject.getString("amount").replace(",", "") + .toDouble() + jsonObject.getString("charge").replace(",", "") + .toDouble() + jsonObject.getString("tax").replace(",", "") + .toDouble()).toString() + arrayOf( + PrintServiceActivity.centeredText(jsonObject.getString("txnType"), 48), + PrintServiceActivity.centeredText(jsonObject.getString("txnResultMessage"), 44), + PrintServiceActivity.SEPARATOR_LINE, + ("Txn Amount: " + Config.CURRENCY_CODE).toString() + " " + NumberUtil.formatNumber( + jsonObject.getString("amount") + ), + ("Txn Fee: " + Config.CURRENCY_CODE).toString() + " " + NumberUtil.formatNumber( + jsonObject.getString("charge") + ), + ("Excise Duty: " + Config.CURRENCY_CODE).toString() + " " + NumberUtil.formatNumber( + jsonObject.getString("tax") + ), + ("Total Amount: " + Config.CURRENCY_CODE).toString() + " " + NumberUtil.formatNumber( + totalAmount + ), + PrintServiceActivity.SEPARATOR_LINE, + "\n", + "Account No.: " + jsonObject.getString("accountNo"), + "Account Name: " + jsonObject.getString("customerName"), + "Narration: " + jsonObject.getString("narration") + ) + } else { + arrayOf() + } } } \ No newline at end of file diff --git a/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/ViewAgroDealerInDetailFragment.kt b/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/ViewAgroDealerInDetailFragment.kt new file mode 100644 index 00000000..2bf5c5b6 --- /dev/null +++ b/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/main/ViewAgroDealerInDetailFragment.kt @@ -0,0 +1,42 @@ +package com.steve_md.smartmkulima.ui.fragments.main + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity +import androidx.navigation.fragment.navArgs +import com.steve_md.smartmkulima.R +import com.steve_md.smartmkulima.databinding.FragmentViewAgroDealerInDetailBinding + +/** + * Viewing Agro-Dealer in Detail + */ +class ViewAgroDealerInDetailFragment : Fragment() { + + private lateinit var binding: FragmentViewAgroDealerInDetailBinding + private val args: ViewAgroDealerInDetailFragmentArgs by navArgs() + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentViewAgroDealerInDetailBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + (activity as AppCompatActivity).supportActionBar?.hide() + + val agrodealer = args.agrodealer + + binding.apply { + textViewAgroDealerNameDetail.text = agrodealer.name + textViewAgroDealerServices.text = agrodealer.servicesOffered + textViewAgroDealerCategories.text = agrodealer.categories + textViewIfLeasingOptionOfferred.text = agrodealer.leasingOptionsAvailable + textViewLeasingDetails.text = agrodealer.leasingDetails + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/others/LocationProvider.kt b/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/others/LocationProvider.kt index 2a204162..728acfdd 100644 --- a/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/others/LocationProvider.kt +++ b/app/src/main/java/com/steve_md/smartmkulima/ui/fragments/others/LocationProvider.kt @@ -1,12 +1,14 @@ package com.steve_md.smartmkulima.ui.fragments.others import android.Manifest +import android.app.Activity import android.content.Context import android.content.pm.PackageManager import android.location.Location import androidx.core.app.ActivityCompat import com.google.android.gms.location.FusedLocationProviderClient import com.google.android.gms.location.LocationServices +import com.steve_md.smartmkulima.ui.fragments.main.LocateAgriTechCompaniesFragment /** @@ -28,11 +30,24 @@ class LocationProvider(private val context:Context) { Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) { + // promptUserRequestingPermissions() return } - fusedLocationClient.lastLocation - .addOnSuccessListener { location: Location? -> - callback(location) - } + + fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? -> + callback(location) + } + } + + companion object { + private const val LOCATION_REQUEST_CODE = 1 + } + + private fun promptUserRequestingPermissions() { + ActivityCompat.requestPermissions( + Activity().parent, + arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), + LOCATION_REQUEST_CODE + ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/steve_md/smartmkulima/utils/ExtensionFunctions.kt b/app/src/main/java/com/steve_md/smartmkulima/utils/ExtensionFunctions.kt index 4dab3684..a83a21b2 100644 --- a/app/src/main/java/com/steve_md/smartmkulima/utils/ExtensionFunctions.kt +++ b/app/src/main/java/com/steve_md/smartmkulima/utils/ExtensionFunctions.kt @@ -29,6 +29,10 @@ fun Fragment.toast(text:String) { ).show() } +fun Activity.showToast(text: String) { + Toast.makeText(this, text, Toast.LENGTH_SHORT).show() +} + fun Fragment.hideKeyboard(): Boolean { return (context?.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager) diff --git a/app/src/main/java/com/steve_md/smartmkulima/utils/services/AppConstants.java b/app/src/main/java/com/steve_md/smartmkulima/utils/services/AppConstants.java new file mode 100644 index 00000000..edf657ec --- /dev/null +++ b/app/src/main/java/com/steve_md/smartmkulima/utils/services/AppConstants.java @@ -0,0 +1,81 @@ +package com.steve_md.smartmkulima.utils.services; + +public final class AppConstants { + + private String enabledServices; + public Boolean isSharedAgency = false; + private String enabledMenus; + + private String mKey; + private String sKey; + + public String getBankCaption() { + return bankCaption; + } + + public void setBankCaption(String bankCaption) { + this.bankCaption = bankCaption; + } + + private String bankCaption; + + // private static UserProfile INSTANCE = new UserProfile(); + private static volatile AppConstants INSTANCE; + + // For Singleton instantiation + private static final Object LOCK = new Object(); + + + /** + * Gets instance. + * + * @return the instance + */ + public static AppConstants getInstance() { + if (INSTANCE == null) { + synchronized (LOCK) { + if (INSTANCE == null) { + INSTANCE = new AppConstants(); + } + } + } + return INSTANCE; + } + + public String getEnabledServices() { + return enabledServices; + } + + public void setEnabledServices(String enabledServices) { + this.enabledServices = enabledServices; + } + + public String getEnabledMenus() { + return enabledMenus; + } + + public void setEnabledMenus(String enabledMenus) { + this.enabledMenus = enabledMenus; + } + + + public String getmKey() { + return mKey; + } + + public void setmKey(String mKey) { + this.mKey = mKey; + } + + public String getsKey() { + return sKey; + } + + public void setsKey(String sKey) { + this.sKey = sKey; + } + + + +} + diff --git a/app/src/main/java/com/steve_md/smartmkulima/utils/services/Config.java b/app/src/main/java/com/steve_md/smartmkulima/utils/services/Config.java new file mode 100644 index 00000000..539580fb --- /dev/null +++ b/app/src/main/java/com/steve_md/smartmkulima/utils/services/Config.java @@ -0,0 +1,607 @@ +package com.steve_md.smartmkulima.utils.services; + +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.preference.PreferenceManager; + +import org.json.JSONArray; + +import java.util.ArrayList; +import java.util.List; + +public class Config { + /** + * The constant MSKEY. + */ + public static String MSKEY = null; + /** + * The constant PINKEY. + */ + public static String PINKEY = null; + /** + * The constant DEBUG_MODE. + */ + public static boolean DEBUG_MODE = false; // true = test, false = live + /** + * The constant APP_VERSION_HASHSUM. + */ + public static final String APP_VERSION_HASHSUM = "0123456789"; // same for similar app version + + + /** + * The constant isTempAdminAuth. + */ + public static boolean isTempAdminAuth = false; // let user see settings page + + /** + * The constant CASH_PAYMENT. + */ + public static final String QR_CODE = "qr_code"; + + /** + * The constant CASH_PAYMENT. + */ + public static final String CASH_PAYMENT = "CASH"; + /** + * The constant CARD_PAYMENT. + */ + public static final String CARD_PAYMENT = "CARD"; + /** + * The constant DIRECT_SCHOOL_FEES. + */ + public static final String DIRECT_SCHOOL_FEES = "DIRECT"; + /** + * The constant REPRINT_RECEIPT_REQUEST. + */ + public static final String REPRINT_RECEIPT_REQUEST = "REPRINT_RECEIPT"; + /** + * The constant INDIRECT_SCHOOL_FEES. + */ + public static final String INDIRECT_SCHOOL_FEES = "INDIRECT"; + /** + * The constant PAYMENT_METHOD. + */ + public static String PAYMENT_METHOD = null; + /** + * The constant SCHOOL_FEES_TYPE. + */ + public static String SCHOOL_FEES_TYPE = null; + /** + * The constant AGENT_NAME. + */ + public static String AGENT_NAME = null; + + public static String OPERATOR_ID=null; + /** + * The constant TERMINAL_NO. + */ + public static String TERMINAL_NO = null; + /** + * The constant banks. + */ + public static List banks = new ArrayList<>(); + /** + * The constant bankDetailName. + */ + public static List bankDetailName = new ArrayList<>(); + + /** + * The constant PERMISSIONS_CAMERA. + */ + public static final int PERMISSIONS_CAMERA = 54; + /** + * The constant PERMISSIONS_PHOTO_GALLERY. + */ + public static final int PERMISSIONS_PHOTO_GALLERY = 69; + + /** + * The constant SAO_ACCOUNTS. + */ + public static final String SAO_ACCOUNTS = "soaAccounts"; + /** + * The constant BRANCHES_LOOK_UP. + */ + public static final String BRANCHES_LOOK_UP = "lookUpBranches"; + /** + * The constant SCHOOLS_LOOK_UP. + */ + public static final String SCHOOLS_LOOK_UP = "lookUpSchools"; + + /** + * The constant PHOTO_GALLERY_REQUEST. + */ + public static final int PHOTO_GALLERY_REQUEST = 10; + /** + * The constant CAMERA_REQUEST. + */ + public static final int CAMERA_REQUEST = 20; + /** + * The constant AGENT_BANK. + */ + public static String AGENT_BANK; + /** + * The constant AGENT_BANK_STREET. + */ + public static String AGENT_BANK_STREET; + /** + * The constant LATEST_APK_VERSION. + */ + public static String LATEST_APK_VERSION = "v1.0.0"; + /** + * The constant AUTH_TYPE. + */ + public static String AUTH_TYPE; + /** + * The constant AGENT_FINGERPRINT. + */ + public static String AGENT_FINGERPRINT; + + public static String POS_OPERATOR_NAME; + + /** + * The constant CURRENCY_CODE. + */ + public static final String CURRENCY_CODE = "KES"; + + /** + * Gets all banks. + * + * @return the all banks + */ + public static List getAllBanks() { + // return banks; + return bankDetailName; + } + + /** + * The constant TITLE_EXTRA. + */ + public static final String TITLE_EXTRA = "com.eclectics.dss.agencybanking.title_extra"; + /** + * The constant SELECTED_MENU_EXTRA. + */ + public static final String SELECTED_MENU_EXTRA = "com.eclectics.dss.agencybanking.menu_extra"; + /** + * The constant REGISTRATION_TYPE_EXTRA. + */ + public static final String REGISTRATION_TYPE_EXTRA = "com.eclectics.dss.agencybanking.registration_type_extra"; + /** + * The constant PAN_EXTRA. + */ + public static final String PAN_EXTRA = "com.eclectics.dss.agencybanking.pan"; + /** + * The constant TRACK2_EXTRA. + */ +//public static final String ACCOUNT_NAME_EXTRA ="com.eclectics.dss.agencybanking.accountName"; + public static final String TRACK2_EXTRA = "com.eclectics.dss.agencybanking.track2Data"; + /** + * The constant TOPUP_CARD. + */ + public static final String TOPUP_CARD = "com.eclectics.dss.agencybanking.topup_card"; + /** + * The constant BILL_CARD. + */ + public static final String BILL_CARD = "com.eclectics.dss.agencybanking.bill_card"; + + + /** + * The type Request. + */ + public static class REQUEST { + /** + * The constant FAO. + */ + public static final String FAO = ""; + /** + * The constant ACTIVATION. + */ + public static final String ACTIVATION = ""; + /** + * The constant CASH_DEPOSIT. + */ + public static final String CASH_DEPOSIT = "CDP"; + /** + * The constant CASH_WITHDRAWAL. + */ + public static final String CASH_WITHDRAWAL = "CWD"; + /** + * The constant CASH_WITHDRAWAL_BIOMETRIC. + */ + public static final String CASH_WITHDRAWAL_BIOMETRIC = "CWD_BIOMETRIC"; + /** + * The constant CARDLESS_FULFILLMENT. + */ + public static final String CARDLESS_FULFILLMENT = "CLF"; + /** + * The constant CARDLESS_FULFILLMENT_DEPOSIT. + */ + public static final String CARDLESS_FULFILLMENT_DEPOSIT = "CLFD"; + /** + * The constant AIRTIME_TOPUP_CASH. + */ + public static final String AIRTIME_TOPUP_CASH = "TPCS"; + /** + * The constant AIRTIME_TOPUP_CARD. + */ + public static final String AIRTIME_TOPUP_CARD = "TPCR"; + /** + * The constant BILL_PAYMENT_CASH. + */ + public static final String BILL_PAYMENT_CASH = "BPCS"; + /** + * The constant BILL_PAYMENT_CARD. + */ + public static final String BILL_PAYMENT_CARD = "BPCR"; + /** + * The constant COLLECTIONS_CASH. + */ + public static final String COLLECTIONS_CASH = "COCS"; + /** + * The constant COLLECTIONS_CARD. + */ + public static final String COLLECTIONS_CARD = "COCR"; + /** + * The constant BALANCE_INQUIRY. + */ + public static final String BALANCE_INQUIRY = "BI"; + /** + * The constant MINISTATEMENT. + */ + public static final String MINISTATEMENT = "MINI"; + /** + * The constant AGENT_FLOAT_TRANSFER. + */ + public static final String AGENT_FLOAT_TRANSFER = "FLOAT_PURCHASE"; + /** + * The constant SUMMARY_REPORTS. + */ + public static final String SUMMARY_REPORTS = ""; + /** + * The constant AGENT_FLOAT_REQUEST. + */ + public static final String AGENT_FLOAT_REQUEST = "FLOAT_REQUEST"; + + + public static final String FUNDS_TRANSFER= "FT"; + + + /** + * The constant FEES_PAYMENT. + */ + public static final String FEES_PAYMENT_CARD= "FEES_PAYMENT_CARD"; + } + + /** + * The constant JWT_TOKEN. + */ + public static String JWT_TOKEN = ""; + /** + * The constant TRANSACTION_TYPE. + */ + public static String TRANSACTION_TYPE = "transactionType"; + /** + * The constant AGENT_ID. + */ + public static String AGENT_ID = ""; + /** + * The constant AGENT_CODE. + */ + public static String AGENT_CODE = ""; + /** + * The constant bankDetails. + */ + public static JSONArray bankDetails = null; + /** + * The constant PASSWORD. + */ + public static String PASSWORD = ""; + /** + * The constant billAccount. + */ + public static String billAccount = ""; + /** + * The constant billPan. + */ + public static String billPan = ""; + /** + * The constant billRegion. + */ + public static String billRegion = ""; + /** + * The constant billPhone. + */ + public static String billPhone = ""; + /** + * The constant billNarration. + */ + public static String billNarration = ""; + /** + * The constant billCustMobile. + */ + public static String billCustMobile = ""; + /** + * The constant billAmt. + */ + public static String billAmt = ""; + /** + * The constant tpPhone. + */ + public static String tpPhone = ""; + /** + * The constant tpAmt. + */ + public static String tpAmt = ""; + /** + * The constant tpcarrierName. + */ + public static String tpcarrierName = ""; + /** + * The constant billTrack2Data. + */ + public static String billTrack2Data = ""; + /** + * The constant bankCode. + */ + public static String bankCode = ""; + /** + * The constant cwdAmount. + */ + public static String cwdAmount = ""; + /** + * The constant ftAmount. + */ + public static String ftAmount = ""; + /** + * The constant cfAmount. + */ + public static String cfAmount = ""; + /** + * The constant cfphone. + */ + public static String cfphone = ""; + /** + * The constant cfpin. + */ + public static String cfpin = ""; + /** + * The constant ftAccountTo. + */ + public static String ftAccountTo = ""; + /** + * The constant encryptedPinBlock. + */ + public static String encryptedPinBlock = ""; + /** + * The constant encryptedTrack2data. + */ + public static String encryptedTrack2data = ""; + /** + * The constant currentKSN. + */ + public static String currentKSN = ""; + /** + * The constant FIRST_NAME_EXTRA. + */ + public static final String FIRST_NAME_EXTRA = "com.eclectics.dss.agencybanking.first_name"; + /** + * The constant LAST_NAME_EXTRA. + */ + public static final String LAST_NAME_EXTRA = "com.eclectics.dss.agencybanking.last_name"; + /** + * The constant MIDDLE_NAME_EXTRA. + */ + public static final String MIDDLE_NAME_EXTRA = "com.eclectics.dss.agencybanking.middle_name"; + /** + * The constant BANK_SORT_CODE_EXTRA. + */ + public static final String BANK_SORT_CODE_EXTRA = "com.eclectics.dss.agencybanking.bank_sort_code"; + /** + * The constant ACCOUNT_NO_EXTRA. + */ + public static final String ACCOUNT_NO_EXTRA = "com.eclectics.dss.agencybanking.account_no"; + /** + * The constant ACCOUNT_NAME_EXTRA. + */ + public static final String ACCOUNT_NAME_EXTRA = "com.eclectics.dss.agencybanking.account_name"; + /** + * The constant NARRATION_EXTRA. + */ + public static final String NARRATION_EXTRA = "com.eclectics.dss.agencybanking.narration"; + /** + * The constant TXN_REF_EXTRA. + */ + public static final String TXN_REF_EXTRA = "com.eclectics.dss.agencybanking.trans_ref"; + /** + * The constant MESSAGE_EXTRA. + */ + public static final String MESSAGE_EXTRA = "com.eclectics.dss.agencybanking.message"; + /** + * The constant AMOUNT_EXTRA. + */ + public static final String AMOUNT_EXTRA = "com.eclectics.dss.agencybanking.amount"; + /** + * The constant FTCHARGE_EXTRA. + */ + public static final String FTCHARGE_EXTRA = "com.eclectics.dss.agencybanking.ftcharge"; + /** + * The constant FTTAX_EXTRA. + */ + public static final String FTTAX_EXTRA = "com.eclectics.dss.agencybanking.fttax"; + + /** + * The constant BALANCE_ENQUIRIES. + */ + public static final int BALANCE_ENQUIRIES = 2; + /** + * The constant CASH_DEPOSIT. + */ + public static final int CASH_DEPOSIT = 3; + /** + * The constant CASH_WITHDRAWAL. + */ + public static final int CASH_WITHDRAWAL = 4; + /** + * The constant BILL_PAYMENT. + */ + public static final int BILL_PAYMENT = 5; + /** + * The constant COLLECTIONS. + */ + public static final int COLLECTIONS = 1; + /** + * The constant AIRTIME_TOPUP. + */ + public static final int CARD_TOPUP = 6; + /** + * The constant REPORTS. + */ + public static final int REPORTS = 7; + /** + * The constant PIN_CHANGE. + */ + public static final int PIN_CHANGE = 8; + /** + * The constant LEAD_GENERATION. + */ + public static final int LEAD_GENERATION = 17; + /** + * The constant MINISTATEMENT. + */ + public static final int MINISTATEMENT = 9; + /** + * The constant FUNDS_TRANSFER. + */ + public static final int FUNDS_TRANSFER = 10; + /** + * The constant CARDLESS_FULFILLMENT. + */ + public static final int NATCASH = 11; + /** + * The constant FAO. + */ + public static final int SAO = 12; + /** + * The constant ACCOUNT_ACTIVATION. + */ + public static final int ACCOUNT_ACTIVATION = 13; + /** + * The constant AGENTFLOAT. + */ + public static final int AGENTFLOAT = 14; + /** + * The constant REPRINT_RECEIPT. + */ + public static final int REPRINT_RECEIPT = 15; + /** + * The constant CARDLESS_FULFILLMENT_DEPOSIT. + */ + public static final int CARDLESS_FULFILLMENT_DEPOSIT = 16; + + + /** + * The constant FEES_PAYMENT. + */ + public static final int FEES_PAYMENT= 21; + + /** + * The constant LATEST_APK_URL. + */ + public static String LATEST_APK_URL = ""; + + + public static String getBaseUrl() { + return BASE_URL; + } + +// public static void setBaseUrl(String baseUrl) { +// BASE_URL = formatURL(baseUrl); +// } + + /** + * The constant BASE_URL. + */ + + public static String BASE_URL; + + /** + * The constant RETROFIT_MEDIA_TYPE. + */ + public static String RETROFIT_MEDIA_TYPE = "application/json; charset=utf-8"; + + public static Bitmap SignatureBitmap; + /** + * The constant OK. + */ + public static final int OK = 1; + /** + * The constant FAIL. + */ + public static final int FAIL = 0; + /** + * The constant UNAUTHORIZED. + */ + public static final int UNAUTHORIZED = 404; + + + + + /** + * Get absolute url. + * + * @param relativeUrl the relative url + * @return absolute url + */ + public static String RELATIVEURL = ""; + + /** + * Gets absolute url. + * + * @param relativeUrl the relative url + * @return the absolute url + */ + public static String getRelativeUrl(String relativeUrl) { + RELATIVEURL = relativeUrl; + return relativeUrl; + } + + + /** + * Clear login. + * + * @param context the context + */ + public static void clearLogin(Context context) { + Config.AGENT_ID = null; + Config.AGENT_CODE = null; + Config.AGENT_NAME = null; + Config.TERMINAL_NO = null; + Config.bankDetails = null; + Config.JWT_TOKEN = null; + Config.bankDetails = null; + Config.bankDetailName = new ArrayList<>(); + Config.MSKEY = null; + Config.PINKEY = null; + + // remove keys from shared preferences + SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit(); + editor.remove("sMasterKey"); + editor.remove("sPinKey"); + editor.commit(); + + // Intent intent = new Intent(context, SignInActivity.class); + // intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + // context.startActivity(intent); + // UserIdleTimer.getInstance(context).cancel(); + } + +// private static String formatURL(String rawURL) { +// String yek; +// byte[] data = NumberUtil.decodeData(rawURL); +// yek = new String(data, StandardCharsets.UTF_8); +// return yek; +// } + +} + diff --git a/app/src/main/java/com/steve_md/smartmkulima/utils/services/DataUtil.java b/app/src/main/java/com/steve_md/smartmkulima/utils/services/DataUtil.java new file mode 100644 index 00000000..b7fec0ac --- /dev/null +++ b/app/src/main/java/com/steve_md/smartmkulima/utils/services/DataUtil.java @@ -0,0 +1,162 @@ +package com.steve_md.smartmkulima.utils.services; + +import android.graphics.Bitmap; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +public class DataUtil { + + private static String fingerprintDeviceName = ""; + public static byte[] inputStream2byte(InputStream inputStream) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = inputStream.read(buff, 0, 100)) > 0) { + byteArrayOutputStream.write(buff, 0, rc); + } + return byteArrayOutputStream.toByteArray(); + } + + /** RGB图片转YUV420数据 + * 宽、高不能为奇数 + * @param pixels 图片像素集合 + * @param width 宽 + * @param height 高 + * @return */ + public static byte[] rgb2YCbCr420(int[] pixels, int width, int height) { + int len = width * height; + //yuv格式数组大小,y亮度占len长度,u,v各占len/4长度。 + byte[] yuv = new byte[len * 3 / 2]; + int y, u, v; + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + //屏蔽ARGB的透明度值 + int rgb = pixels[i * width + j] & 0x00FFFFFF; + //像素的颜色顺序为bgr,移位运算。 + int r = rgb & 0xFF; + int g = (rgb >> 8) & 0xFF; + int b = (rgb >> 16) & 0xFF; + //套用公式 + y = ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16; + u = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128; + v = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128; + //调整 + y = y < 16 ? 16 : (y > 255 ? 255 : y); + u = u < 0 ? 0 : (u > 255 ? 255 : u); + v = v < 0 ? 0 : (v > 255 ? 255 : v); + //赋值 + yuv[i * width + j] = (byte) y; + yuv[len + (i >> 1) * width + (j & ~1) + 0] = (byte) u; + yuv[len + +(i >> 1) * width + (j & ~1) + 1] = (byte) v; + } + } + return yuv; + } + + /* + * 获取位图的YUV数据 + */ + public static byte[] getYUVByBitmap(Bitmap bitmap) { + if (bitmap == null) { + return null; + } + int width = bitmap.getWidth(); + int height = bitmap.getHeight(); + + int size = width * height; + + int pixels[] = new int[size]; + bitmap.getPixels(pixels, 0, width, 0, 0, width, height); + + // byte[] data = convertColorToByte(pixels); + byte[] data = rgb2YCbCr420(pixels, width, height); + + return data; + } + + public String getFingerprintDeviceName() { + return fingerprintDeviceName; + } + + public static void setFingerprintDeviceName(String mFingerprintDeviceName) { + fingerprintDeviceName = mFingerprintDeviceName; + } +} + +///** +// * author:huangmin +// * time:3/17/21 +// * describe: +// */ +//public class DataUtil { +// public static byte[] inputStream2byte(InputStream inputStream) throws IOException { +// ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); +// byte[] buff = new byte[100]; +// int rc = 0; +// while ((rc = inputStream.read(buff, 0, 100)) > 0) { +// byteArrayOutputStream.write(buff, 0, rc); +// } +// return byteArrayOutputStream.toByteArray(); +// } +// +// /** RGB图片转YUV420数据 +// * 宽、高不能为奇数 +// * @param pixels 图片像素集合 +// * @param width 宽 +// * @param height 高 +// * @return */ +// public static byte[] rgb2YCbCr420(int[] pixels, int width, int height) { +// int len = width * height; +// //yuv格式数组大小,y亮度占len长度,u,v各占len/4长度。 +// byte[] yuv = new byte[len * 3 / 2]; +// int y, u, v; +// for (int i = 0; i < height; i++) { +// for (int j = 0; j < width; j++) { +// //屏蔽ARGB的透明度值 +// int rgb = pixels[i * width + j] & 0x00FFFFFF; +// //像素的颜色顺序为bgr,移位运算。 +// int r = rgb & 0xFF; +// int g = (rgb >> 8) & 0xFF; +// int b = (rgb >> 16) & 0xFF; +// //套用公式 +// y = ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16; +// u = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128; +// v = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128; +// //调整 +// y = y < 16 ? 16 : (y > 255 ? 255 : y); +// u = u < 0 ? 0 : (u > 255 ? 255 : u); +// v = v < 0 ? 0 : (v > 255 ? 255 : v); +// //赋值 +// yuv[i * width + j] = (byte) y; +// yuv[len + (i >> 1) * width + (j & ~1) + 0] = (byte) u; +// yuv[len + +(i >> 1) * width + (j & ~1) + 1] = (byte) v; +// } +// } +// return yuv; +// } +// +// /* +// * 获取位图的YUV数据 +// */ +// public static byte[] getYUVByBitmap(Bitmap bitmap) { +// if (bitmap == null) { +// return null; +// } +// int width = bitmap.getWidth(); +// int height = bitmap.getHeight(); +// +// int size = width * height; +// +// int pixels[] = new int[size]; +// bitmap.getPixels(pixels, 0, width, 0, 0, width, height); +// +// // byte[] data = convertColorToByte(pixels); +// byte[] data = rgb2YCbCr420(pixels, width, height); +// +// return data; +// } +// +//} + diff --git a/app/src/main/java/com/steve_md/smartmkulima/utils/services/NumberUtil.java b/app/src/main/java/com/steve_md/smartmkulima/utils/services/NumberUtil.java new file mode 100644 index 00000000..8f69cbca --- /dev/null +++ b/app/src/main/java/com/steve_md/smartmkulima/utils/services/NumberUtil.java @@ -0,0 +1,103 @@ +package com.steve_md.smartmkulima.utils.services; + +import android.text.TextUtils; +import android.util.Base64; + +import java.text.DecimalFormat; + +public class NumberUtil { + + /** + * Round off to 2dp + * and add comma separator. + * + * @param wholeNumber the whole number + * @return string string + */ + public static String formatNumber(String wholeNumber) { + + Double number = Double.parseDouble(wholeNumber); + + //NumberFormat.getInstance().format(myNumber); + + DecimalFormat formatter = new DecimalFormat("#,##0.00"); + //NumberFormat formatter =NumberFormat.getInstance(); + final String formattedNumber = formatter.format(number);//add commas + + return formattedNumber; + } + + /** + * This method takes an account number and obscures the number leaving only + * four trailing/last digits + * + * @param accountNo an account number that needs to be obscured so as to be displayed safely + * @return the accountNo padded with *'s to reveal only the last four digits + */ + public static final String displayAccountNumber(String accountNo) { + return displayAccountNumber(accountNo, 4); + } + + /** + * This method takes an account number and obscures the number leaving only + * a few trailing/last digits + * + * @param accountNo an account number that needs to be obscured so as to be displayed safely + * @param revealedChars specifies how many trailing digits of the account number to reveal + * @return the accountNo padded with *'s to reveal only the last four digits + */ + public static final String displayAccountNumber(String accountNo, int revealedChars) { + if (TextUtils.isEmpty(accountNo)) { + return ""; + } else if (accountNo.length() <= revealedChars) { + return accountNo; + } + String leadingChars = TextUtils.substring(accountNo, 0, + accountNo.length() - revealedChars); + String replacementChars = ""; + int len = leadingChars.length(); + for (int i = 0; i < len; i++) { + replacementChars += "*"; + } + accountNo = accountNo.replace(leadingChars, replacementChars); + return accountNo; + } + + + /** + * Mobile number string. + * + * @param mobileNumber the mobile number + * @return the string + */ + public static String mobileNumber(String mobileNumber) { + + if (mobileNumber.startsWith("0")) { + return mobileNumber.substring(1, mobileNumber.length()).replaceAll("\\W", ""); + + } + + return mobileNumber; + } + + /** + * Hex string to byte array byte [ ]. + * + * @param s the s + * @return the byte [ ] + */ + public static byte[] hexStringToByteArray(String s) { + int len = s.length(); + byte[] data = new byte[len / 2]; + for (int i = 0; i < len; i += 2) { + data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + + Character.digit(s.charAt(i + 1), 16)); + } + return data; + } + + public static byte[] decodeData(String data) { + return Base64.decode(data, Base64.DEFAULT); + } +} + diff --git a/app/src/main/java/com/steve_md/smartmkulima/utils/services/PrintServiceActivity.java b/app/src/main/java/com/steve_md/smartmkulima/utils/services/PrintServiceActivity.java index de7b526b..ecd5f427 100644 --- a/app/src/main/java/com/steve_md/smartmkulima/utils/services/PrintServiceActivity.java +++ b/app/src/main/java/com/steve_md/smartmkulima/utils/services/PrintServiceActivity.java @@ -1,28 +1,64 @@ package com.steve_md.smartmkulima.utils.services; +import static com.steve_md.smartmkulima.utils.ExtensionFunctionsKt.showToast; + +import android.annotation.SuppressLint; import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Handler; +import android.os.Message; +import android.os.RemoteException; +import android.preference.PreferenceManager; +import android.text.TextUtils; +import android.util.Base64; import android.util.Log; +import android.view.View; +import android.view.WindowManager; +import android.widget.ImageView; import android.widget.TextView; +import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.appcompat.widget.ViewUtils; import com.google.android.material.button.MaterialButton; +import com.google.android.material.snackbar.Snackbar; +import com.google.gson.Gson; +import com.nexgo.oaf.apiv3.APIProxy; import com.nexgo.oaf.apiv3.DeviceEngine; import com.nexgo.oaf.apiv3.SdkResult; +import com.nexgo.oaf.apiv3.device.printer.AlignEnum; +import com.nexgo.oaf.apiv3.device.printer.GrayLevelEnum; import com.nexgo.oaf.apiv3.device.printer.OnPrintListener; import com.nexgo.oaf.apiv3.device.printer.Printer; +import com.pos.sdk.DeviceManager; +import com.pos.sdk.DevicesFactory; +import com.pos.sdk.callback.ResultCallback; import com.pos.sdk.printer.PrinterDevice; +import com.pos.sdk.printer.PrinterState; +import com.pos.sdk.printer.param.PrintItemAlign; +import com.pos.sdk.printer.param.QrPrintItemParam; +import com.steve_md.smartmkulima.R; import com.steve_md.smartmkulima.model.DeviceType; +import com.steve_md.smartmkulima.utils.ExtensionFunctionsKt; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; import java.util.HashMap; +import dagger.hilt.android.AndroidEntryPoint; import vpos.apipackage.PosApiHelper; +import vpos.apipackage.Print; + +@AndroidEntryPoint public class PrintServiceActivity extends AppCompatActivity implements OnPrintListener { private BroadcastReceiver receiver; @@ -31,6 +67,28 @@ public class PrintServiceActivity extends AppCompatActivity implements OnPrintLi private int BatteryV; + /** + * The constant Customer + */ + public static final String CUSTOMER = "CUSTOMER"; + /** + * + * + */ + + /** + * The constant AGENT. + */ + public static final String AGENT = "AGENT"; + /** + * The constant BOTH. + */ + public static final String BOTH = "BOTH"; + /** + * The constant NONE. + */ + public static final String NONE = "NONE"; + /** * The Preferences. @@ -118,20 +176,872 @@ public class PrintServiceActivity extends AppCompatActivity implements OnPrintLi private Printer printer; private PrinterDevice k9printer; + private String TAG = "PrintServiceActivity"; + public static String HIRE_FARM_EQUIPMENT = "HIRE FARM EQUIPMENT"; + public static String PURCHASE_FARM_INPUTS = "PURCHASE FARM INPUTS"; + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_print_service); + Toolbar toolbar = (Toolbar) findViewById(R.id.dashboard_toolbar); + toolbar.setTitle("Print Preview"); + setSupportActionBar(toolbar); + toolbar.setNavigationIcon(R.drawable.ic_arrow_back); + toolbar.setNavigationOnClickListener(v -> finish()); + printButton = findViewById(R.id.print); + if (this.getIntent().hasExtra("params")) + paramsMap = (HashMap) this.getIntent().getExtras().getSerializable("params"); + else { + paramsMap = new HashMap<>(); + paramsMap.put("requestTime", "2024-08-12"); + paramsMap.put("reference", "5256565456545"); + } + + loadImage(); + + PrintServiceActivityTV = findViewById(R.id.print_preview_tv); + + if (this.getIntent().hasExtra("params")) { + printText = this.getIntent().getExtras().getStringArray("printText"); + receiptTitle = printText[1].replace("CENTRE:", ""); + } else { + printText = new String[]{}; + //View parentLayout = findViewById(androidx.appcompat.R.id.content); +// Snackbar.make(parentLayout, "Nothing to Print!", Snackbar.LENGTH_SHORT) +// .show(); + + } + + printText = preparePrintText(printText); + printButton.setOnClickListener(view -> onButtonPushed()); + + if (this.getIntent().hasExtra("params")) { + finishActivityOnPrint = this.getIntent().getExtras().getBoolean("finishActivityOnPrint"); + } else { + finishActivityOnPrint = true; + } + + //Initialize the SDK components + try { + Log.e(TAG, "device: " + PosApiHelper.getInstance()); + deviceEngine = APIProxy.getDeviceEngine(this); + printer = deviceEngine.getPrinter(); + deviceType = DeviceType.N5; + } catch (Throwable e) { + + } + + + try { + posApiHelper = PosApiHelper.getInstance(); + deviceType = DeviceType.CS10; + } catch (Throwable e) { + + } + + try { + DevicesFactory.create(this, new ResultCallback() { + @Override + public void onFinish(DeviceManager deviceManager) { + Log.d(TAG, "onFinish: "); + k9printer = deviceManager.getPrintDevice(); + deviceType = DeviceType.CTA_K; + resume(); + } + + @Override + public void onError(int i, String s) { + Log.d(TAG, "onError: " + i + "," + s); + resume(); + } + }); + } catch (Exception exception) { + resume(); + } + } + private void resume() { + init_Gray(); + try { + if (deviceType == DeviceType.CS10) { + posApiHelper.PrintInit(); + posApiHelper.PrintCtnStart(); + }else if (deviceType == DeviceType.CTA_K){ + + } else if(deviceType == DeviceType.N5){ + printer.initPrinter(); + + int initResult = printer.getStatus(); + switch (initResult) { + case SdkResult.Success: + Log.d(TAG, "Printer init success"); + break; + case SdkResult.Printer_PaperLack: + Log.w(TAG, "Printer is out of paper"); + Toast.makeText(this, "Out of Paper!", Toast.LENGTH_LONG).show(); + break; + default: + Log.w(TAG, "Printer Init Misc Error: " + initResult); + break; + } + } + } catch (Exception ex) { + handlePrintingException(ex); + Log.e(TAG, "Exception Response :- " + ex.getMessage()); + } + } + + + private void onButtonPushed() { + + disablePrintButton(); + new Thread() { + @Override + public void run() { + try { + if (deviceType == DeviceType.CS10) { + int ret = posApiHelper.PrintCheckStatus(); + Log.e(TAG, "PrintCheckStatus :- " + ret); + posApiHelper.PrintInit(); + posApiHelper.PrintCtnStart(); + Print.Lib_PrnSetAlign(0); + printCS10(paramsMap, printText); + } else if (deviceType == DeviceType.N5){ + print(paramsMap, printText); + }else if(deviceType == DeviceType.CTA_K){ + printK9(); + } + } catch (Exception ex) { + handlePrintingException(ex); + Log.e(TAG, "Exception Response :- " + ex.getMessage()); + } finally { + if (deviceType == DeviceType.CS10) { + posApiHelper.PrintClose(); + } + } + } + }.start(); + + + } + + + private void printK9() { + try { + addTestData(); + Bundle bundle = new Bundle(); + //you can also set grayscale here + //bundle.putInt(PrinterParamTag.TAG_PRINT_GRAY, 0x18); + PrinterState printerState = k9printer.printSync(bundle); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void addTestData() { + long begin = System.currentTimeMillis(); + SlipModelUtils slip = new SlipModelUtils(); + try { + k9printer.addTextPrintItem(slip.addTextOnePrint("\n\n", false, -1, PrintItemAlign.CENTER)); + k9printer.addBitmapPrintItem(slip.addBitmapAsset(this, "kcb_logo.bmp")); + k9printer.addTextPrintItem(slip.addTextOnePrint("\n\n", false, -1, PrintItemAlign.CENTER)); + k9printer.addTextPrintItem(slip.addTextOnePrint("CASH DEPOSIT SUCCESSFUL", false, 32, PrintItemAlign.LEFT)); + addLineHa(slip); + k9printer.addTextPrintItem(slip.addTextOnePrint("AGENT COPY", false, -1, PrintItemAlign.LEFT)); + k9printer.addTextPrintItem(slip.addTextOnePrint("Pata Kila Kitu stall", false, -1, PrintItemAlign.LEFT)); + k9printer.addTextPrintItem(slip.addTextOnePrint("AGENT ID : 103000", false, -1, PrintItemAlign.LEFT)); + k9printer.addTextPrintItem(slip.addTextOnePrint("Awesome Jim Enterprises", false, -1, PrintItemAlign.LEFT)); + k9printer.addTextPrintItem(slip.addTextOnePrint("DATE TIME TERMINAL ID", false, -1, PrintItemAlign.LEFT)); + k9printer.addTextPrintItem(slip.addTextOnePrint("2022-05-09 20:32:30 100000 78", false, -1, PrintItemAlign.LEFT)); + k9printer.addTextPrintItem(slip.addTextOnePrint("TRANS REF: 0509115937219", false, -1, PrintItemAlign.LEFT)); + addLineHa(slip); + k9printer.addTextPrintItem(slip.addTextOnePrint("CASH DEPOSIT", false, -1, PrintItemAlign.CENTER)); + k9printer.addTextPrintItem(slip.addTextOnePrint("CASH DEPOSIT SUCCESSFUL", false, -1, PrintItemAlign.CENTER)); + addLineHa(slip); + k9printer.addMultipleTextPrintItem(slip.addLeftAndRightItem("Txn Amount:", "KES 2,000", null)); + k9printer.addMultipleTextPrintItem(slip.addLeftAndRightItem("Txn Fee", "KES 0.00", null)); + k9printer.addMultipleTextPrintItem(slip.addLeftAndRightItem("Excise Duty", "KES 0.00", null)); + k9printer.addMultipleTextPrintItem(slip.addLeftAndRightItem("Total Amount:", "KES 2,000", null)); + addLineHa(slip); + k9printer.addMultipleTextPrintItem(slip.addLeftAndRightItem("Account No: ", "KES 2,000", null)); + k9printer.addMultipleTextPrintItem(slip.addLeftAndRightItem("Total Amount:", "KES 2,000", null)); + k9printer.addMultipleTextPrintItem(slip.addLeftAndRightItem("Total Amount:", "KES 2,000", null)); + k9printer.addMultipleTextPrintItem(slip.addLeftAndRightItem("Account No:", "********367", null)); + k9printer.addMultipleTextPrintItem(slip.addLeftAndRightItem("Account Name:", "Awesome Jim", -1, 32, new float[]{1, 3})); + k9printer.addMultipleTextPrintItem(slip.addLeftAndRightItem("Narration:", "Custom to NCBA", null)); + addLineHa(slip); + k9printer.addMultipleTextPrintItem(slip.addLeftAndRightItem("Served by:", "James Maina Mbugua", null)); + k9printer.addMultipleTextPrintItem(slip.addLeftAndRightItem("Powered by:", "Eclectics International", -1, 32, new float[]{1, 1})); + k9printer.addTextPrintItem(slip.addTextOnePrint("\n", false, -1, PrintItemAlign.CENTER)); + + QrPrintItemParam qrPrintItemParam = new QrPrintItemParam(); + qrPrintItemParam.setQRCode("dkodkod"); + qrPrintItemParam.setQrWidth(250); + qrPrintItemParam.setItemAlign(PrintItemAlign.CENTER); + k9printer.addQrPrintItemParam(qrPrintItemParam); + k9printer.addTextPrintItem(slip.addTextOnePrint("\n", false, -1, PrintItemAlign.CENTER)); + + k9printer.addTextPrintItem(slip.addTextOnePrint("I ACKNOWLEDGE SATISFACTORY RECEIPT OF RELATIVE GOODS/SERVICES", false, 16, PrintItemAlign.CENTER)); + k9printer.addTextPrintItem(slip.addTextOnePrint("\n\n", false, -1, PrintItemAlign.CENTER)); + enablePrintButton(); + long end = System.currentTimeMillis(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void addLineHa(SlipModelUtils slip) throws RemoteException { + k9printer.addTextPrintItem(slip.addTextOnePrint("--------------------------------------", true, -1, PrintItemAlign.CENTER)); + } + + /** + * Send msg. + * + * @param strInfo the str info + */ + public void SendMsg(String strInfo) { + Message msg = new Message(); + Bundle b = new Bundle(); + b.putString("MSG", strInfo); + msg.setData(b); + handler.sendMessage(msg); + } + + private void handlePrintingException(Exception ex) { + ex.printStackTrace(); + // runOnUiThread( ()-> showToast(PrintServiceActivity.this,"Exception thrown: ")); + } + + + private String formatPreviewLine(String line) { + + String separatorLine = SEPARATOR_LINE + SEPARATOR_LINE + SEPARATOR_LINE + SEPARATOR_LINE; + + if (line.startsWith(CENTER_PREFIX)) { + return centerText(line.substring(CENTER_PREFIX.length()), 36); + } else if (SEPARATOR_LINE.equals(line)) { + return separatorLine.substring(0, 50); + } + return line; + } + + private String formatPreviewText(String[] header, String[] printText, String[] footer) { + String previewText = "\n"; + for (String line : header) { + previewText += formatPreviewLine(line) + "\n"; + } + for (String line : printText) { + previewText += formatPreviewLine(line) + "\n"; + } + for (String line : footer) { + previewText += formatPreviewLine(line) + "\n"; + } + return previewText; + } + + private String[] preparePrintText(String[] printText) { + + return printText; + } + + + + private void print(final HashMap paramsMap, final String[] printText) { + disablePrintButton(); + final String copies; + if (paramsMap.containsKey("receiptCopies")) { + copies = paramsMap.get("receiptCopies"); + } else { + copies = "BOTH"; + } + InputStream imageStream = this.getResources().openRawResource(R.raw.payment_option); + Bitmap bmp1 = BitmapFactory.decodeStream(imageStream); + //Bitmap bmp1 = BitmapFactory.decodeResource(getApplication().getResources(), R.drawable.abc3); + boolean mNeedsCuttingPause = false; + + if (TextUtils.equals(copies, AGENT) || + TextUtils.equals(copies, BOTH)) { + mNeedsCuttingPause = true; +// Print.Lib_PrnSetAlign(1); +// posApiHelper.PrintSetAlign(0); +// int ret = posApiHelper.PrintBmp(bmp1); + Log.e("PrintBmp", "Lib_PrnStart fail, ret = " + ret); + Log.e("PrintBmp height", "Lib_PrnStart fail, ret = " + bitmap.getHeight()); + Log.e("PrintBmp width", "Lib_PrnStart fail, ret = " + bitmap.getWidth()); + sendData(getHeader(paramsMap, "AGENT COPY"), false, AlignEnum.LEFT); // print header text + //Print.Lib_PrnSetAlign(0); +// posApiHelper.PrintSetAlign(0); + sendData(preparePrintText(printText), false, AlignEnum.LEFT); // print receipt text + //Print.Lib_PrnSetAlign(0); + sendData(getFooter(paramsMap), false, AlignEnum.LEFT); // print footer text + if (getIntent().hasExtra("hasSignatureBitmap") && getIntent().getBooleanExtra("hasSignatureBitmap", false)) { + // printImage(Config.SignatureBitmap); // print Signature image +// int ret2 = posApiHelper.PrintBmp(Config.SignatureBitmap); +// Log.e("PrintBmp", "Lib_PrnStart fail, ret = " + ret2); +// Log.e("PrintBmp height", "Lib_PrnStart fail, ret = " + Config.SignatureBitmap.getHeight()); +// Log.e("PrintBmp width", "Lib_PrnStart fail, ret = " + Config.SignatureBitmap.getWidth()); + printer.appendImage(Config.SignatureBitmap, AlignEnum.CENTER); + Config.SignatureBitmap = null; + } + if (paramsMap.containsKey("qr_auth_code")) { +// posApiHelper.PrintSetAlign(1); + printer.appendImage(QRBitmap, AlignEnum.CENTER); +// posApiHelper.PrintBmp(QRBitmap); // print QR image +// posApiHelper.PrintStr("\n\n\n"); + printer.appendPrnStr("\n\n\n", 20, AlignEnum.CENTER, false); +// posApiHelper.PrintSetAlign(0); +// posApiHelper.PrintStr( AppConstants.getInstance().getBankCaption()); + printer.appendPrnStr(AppConstants.getInstance().getBankCaption(), 24, AlignEnum.CENTER, false); + printer.appendPrnStr("\n\n\n", 20, AlignEnum.CENTER, false); +// posApiHelper.PrintStr("\n\n\n"); + } + printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); + printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); +// posApiHelper.PrintStr(" \n"); +// posApiHelper.PrintStr(" \n"); +// posApiHelper.PrintStart(); + printer.startPrint(true, this); + } + + if (TextUtils.equals(copies, CUSTOMER) || // if BI/MI, print customer copy only + TextUtils.equals(copies, BOTH)) { // print customer copy + if (mNeedsCuttingPause) { + this.paramsMap.put("receiptCopies", CUSTOMER); // makes sure only customer copy is printed by clicking button + enablePrintButton(); + return; + } + disablePrintButton(); + +// Print.Lib_PrnSetAlign(1); + +// posApiHelper.PrintSetAlign(0); + //printImage(bitmap);// print image image +// posApiHelper.PrintBmp(bmp1); + printer.appendImage(bmp1, AlignEnum.CENTER); + // Print.Lib_PrnSetAlign(0); +// posApiHelper.PrintSetAlign(0); + sendData(getHeader(paramsMap, "CUSTOMER COPY"), false, AlignEnum.LEFT); + //Print.Lib_PrnSetAlign(0); + sendData(preparePrintText(printText), false, AlignEnum.LEFT); + if (paramsMap.containsKey("qr_auth_code")) { + sendData(getFooter(paramsMap), false, AlignEnum.LEFT); +// posApiHelper.PrintSetAlign(1); +// posApiHelper.PrintBmp(QRBitmap); + printer.appendImage(QRBitmap, AlignEnum.CENTER); + printer.appendPrnStr("\n\n\n", 20, AlignEnum.CENTER, false); +// posApiHelper.PrintStr("\n\n\n"); +// posApiHelper.PrintSetAlign(0); + printer.appendPrnStr(AppConstants.getInstance().getBankCaption(), 20, AlignEnum.CENTER, false); + printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); + printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); + printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); +// posApiHelper.PrintStr( AppConstants.getInstance().getBankCaption()); +// posApiHelper.PrintStr(" \n"); +// posApiHelper.PrintStr(" \n"); +// posApiHelper.PrintStr(" \n"); + } else { + sendData(getFooter(paramsMap), true, AlignEnum.LEFT); +// posApiHelper.PrintStr("\n\n\n"); + printer.appendPrnStr("\n\n\n", 20, AlignEnum.CENTER, false); +// posApiHelper.PrintStr( AppConstants.getInstance().getBankCaption()); +// posApiHelper.PrintStr(" \n"); +// posApiHelper.PrintStr(" \n"); +// posApiHelper.PrintStr(" \n"); + printer.appendPrnStr(AppConstants.getInstance().getBankCaption(), 24, AlignEnum.CENTER, false); + printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); + printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); + printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); + + } +// posApiHelper.PrintStart(); + printer.startPrint(true, this); + } + finishedPrinting(true); + } + + private void loadImage() { + InputStream imageStream = this.getResources().openRawResource(R.raw.money_mart_print); + ImageView logoPrintServiceActivityIV = (ImageView) findViewById(R.id.logoPrintServiceActivityImageView); + bitmap = BitmapFactory.decodeStream(imageStream); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.PNG, 1, baos); //bm is the bitmap object + byteArrayImage = baos.toByteArray(); + logoPrintServiceActivityIV.setImageBitmap(bitmap); + encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT); + + if (paramsMap.containsKey("qr_auth_code")) { + QRBitmap = getQRBitmap(paramsMap.get("qr_auth_code")); + ((ImageView) findViewById(R.id.qrPrintServiceActivityImageView)).setImageBitmap(QRBitmap); + // logoPrintServiceActivityIV.setImageBitmap(bitmap); + + } + } + + /** + * Disable print button. + */ + public void disablePrintButton() { + runOnUiThread(() -> { + printButton.setEnabled(false); + printButton.setBackgroundColor(getResources().getColor(R.color.bg_gray)); + }); + } + + /** + * Enable print button. + */ + public void enablePrintButton() { + runOnUiThread(() -> { + printButton.setEnabled(true); + printButton.setBackgroundColor(getResources().getColor(R.color.main)); + }); + } + + public static String centeredText(String text, int val) { + return centeredText(text); + } + public static String centeredText(String text) { + return CENTER_PREFIX + text; + } + + public static String centerText(String text, int paperSize) { + if (TextUtils.isEmpty(text)) { + return ""; + } + int textLength = text.length(); + + if (textLength > paperSize) { + String compactText = text.substring(0, paperSize); + int lastSpaceIndex = compactText.lastIndexOf(" "); + if (lastSpaceIndex <= 0) { + return compactText + "\n" + + centerText(text.substring(paperSize, textLength), paperSize); + } else { + return centerText(compactText.substring(0, lastSpaceIndex), paperSize) + "\n" + + centerText(text.substring(lastSpaceIndex + 1, textLength), paperSize); + } + } else if (textLength == paperSize) { + return text; + } else { + int whiteSpaceLength = paperSize - textLength; + int padding = whiteSpaceLength / 2; + for (int i = 0; i < padding; i++) { + text = " " + text; + } + return text; + } + } + + + private String[] getFooter(HashMap paramsMap) { + return new String[]{ + SEPARATOR_LINE, + "Served by: " + Config.POS_OPERATOR_NAME,//+ "\n", + "Powered by: " + "Eclectics International",//+ "\n", + SEPARATOR_LINE, + "\n", + "\n" + }; + } + + + private String[] getHeader(HashMap paramsMap, String copyOwner) { + /*if (paramsMap.get("txnResultMessage") != null) { + + header = new String[]{ + "***** " + paramsMap.get("txnResultMessage") + " *****", + SEPARATOR_LINE, + copyOwner, + *//* "\n",*//* + Config.AGENT_BANK_STREET, + *//* "\n",*//* + "AGENT ID: " + Config.AGENT_CODE, + Config.AGENT_NAME, + *//* "\n",*//* + "DATE TIME TERMINAL ID", + paramsMap.get("requestTime") + " " + Config.TERMINAL_NO,//+ "\n", + *//* "\n",*//* + "TRANS REF: " + paramsMap.get("reference"), + SEPARATOR_LINE + }; + + } else if(paramsMap.get("txnResultMessage") != null) { + header = new String[]{ + "***** " + paramsMap.get("txnResultMessage") + " *****", + SEPARATOR_LINE, + copyOwner, + *//* "\n",*//* + Config.AGENT_BANK_STREET, + *//* "\n",*//* + "AGENT ID: " + Config.AGENT_CODE, + Config.AGENT_NAME, + *//* "\n",*//* + "DATE TIME TERMINAL ID", + paramsMap.get("requestTime") + " " + Config.TERMINAL_NO,//+ "\n", + *//* "\n",*//* + "TRANS REF: " + paramsMap.get("reference"), + SEPARATOR_LINE + }; + } + else */ + Log.d("taggerd",receiptTitle); + + return new String[]{ + "** " + receiptTitle + " **", + SEPARATOR_LINE, + copyOwner , + /* "\n",*/ + Config.AGENT_BANK_STREET, + /* "\n",*/ + "AGENT ID: " + Config.AGENT_CODE, + Config.AGENT_NAME, + /* "\n",*/ + "DATE TIME TERMINAL ID", + paramsMap.get("requestTime") + " " + Config.TERMINAL_NO,//+ "\n", + /* "\n",*/ + "TRANS REF: " + paramsMap.get("reference"), + SEPARATOR_LINE + }; + + } + + public static void startPrinting(Context context, HashMap map, String[] printText, boolean shouldArchive) { + if (shouldArchive) { + archiveReceiptData(context, map, printText); + } +// Intent intent = new Intent(context, SignatureCapture.class); +// intent.putExtra("finishActivityOnPrint", true); +// intent.putExtra("printText", printText); +// intent.putExtra("params", map); +// context.startActivity(intent); + + //this.finish(); + + /* Intent intent = new Intent(context, PrintServiceActivity.class); + intent.putExtra("finishActivityOnPrint", true); + intent.putExtra("printText", printText); + intent.putExtra("params", map); + context.startActivity(intent);*/ + } - private String TAG = "PrintServiceActivity"; - public static String HIRE_FARM_EQUIPMENT = "HIRE FARM EQUIPMENT"; - public static String PURCHASE_FARM_INPUTS = "PURCHASE FARM INPUTS"; @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + public void onBackPressed() { + super.onBackPressed(); + // showToast(PrintServiceActivity.this, "Print receipt to go back"); + } + + + private Bitmap getQRBitmap(String qrUrl) { + Bitmap qrBtMap = QRUtil.generateQR(qrUrl); + return qrBtMap; + } + + private void printImage(Bitmap btMap) { + posApiHelper.PrintBmp(btMap); + } + + private void setValue(int val) { + sp = getSharedPreferences("Gray", MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putInt("value", val); + editor.commit(); + } + + private int getValue() { + sp = getSharedPreferences("Gray", MODE_PRIVATE); + int value = sp.getInt("value", 3); + return value; + } + + private void init_Gray() { + if (deviceType == DeviceType.CS10) { + int flag = getValue(); + posApiHelper.PrintSetGray(flag); + } else if (deviceType == DeviceType.N5 ){ + printer.setGray(GrayLevelEnum.LEVEL_0); + } + + } + + @Override + protected void onResume() { + disableFunctionLaunch(true); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); +// printButton.callOnClick(); + receiptTitle = printText[1].replace("CENTRE:",""); + + String previewText = formatPreviewText(getHeader(paramsMap, "AGENT COPY"), printText, getFooter(paramsMap)); + PrintServiceActivityTV.setText(previewText); + super.onResume(); + filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); + receiver = new BatteryReceiver(); + registerReceiver(receiver, filter); + } + + @Override + protected void onPause() { + disableFunctionLaunch(false); + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + disablePrintButton(); + if (isFinishing()) { + } + super.onPause(); + // QuitHandler(); + unregisterReceiver(receiver); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + +// stopService(mPrintServiceIntent); +// unbindService(serviceConnection); + } + + public static void startPrinting(Context context, HashMap map, String[] printText) { + startPrinting(context, map, printText, true); + } + + + private static void archiveReceiptData(Context context, HashMap map, String[] printText) { + // these fields should not be saved + map.remove("cardSecurityInfo"); + map.remove("cardPinBlock"); + map.remove("cardPAN"); + map.remove("cardField60"); + map.remove("cardTrack2Data"); + map.remove("cardICCData"); + map.remove("cardTrack1Data"); + map.remove("cardExpiryDate"); + map.remove("cardPANSequence"); + map.remove("jwtToken"); + map.remove("charges"); + map.remove("cashPin"); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor editor = prefs.edit(); + + Gson gson = new Gson(); + String params = gson.toJson(map); + String text = gson.toJson(printText); + + // move second receipt to index of third receipt + if (prefs.getString("params_1", null) != null) { + editor.putString("params_2", prefs.getString("params_1", null)); + editor.putString("text_2", prefs.getString("text_1", null)); + } + + // move first receipt to index of second receipt + if (prefs.getString("params_0", null) != null) { + editor.putString("params_1", prefs.getString("params_0", null)); + editor.putString("text_1", prefs.getString("text_0", null)); + } + + // save new receipt with index of first receipt i.e. 0 + editor.putString("params_0", params); + editor.putString("text_0", text); + + editor.apply(); + } + + + + private void finishedPrinting(boolean closeConnection) { + if (closeConnection) { + if (finishActivityOnPrint) { + handler.postDelayed(() -> finish(), 1000); + } + } + } + + + + void sendData(String[] printText, boolean closeConnection, AlignEnum alignEnum) { + try { + for (String line : printText) { + if (line.startsWith(CENTER_PREFIX)) { +// posApiHelper.PrintSetAlign(0); + line = line.substring(CENTER_PREFIX.length()); + } + printer.appendPrnStr(line, 24, alignEnum, false); +// posApiHelper.PrintStr(line); + // posApiHelper.PrintCtnStart(); + } + finishedPrinting(closeConnection); + } catch (NullPointerException e) { + Log.e(TAG, "Exception Response :- " + e.getMessage()); + } catch (Exception e) { + Log.e(TAG, "Exception Response :- " + e.getMessage()); + } + } + + + + + + + /** + * The type Battery receiver. + */ + public class BatteryReceiver extends BroadcastReceiver { + public void onReceive(Context context, Intent intent) { + voltage_level = intent.getExtras().getInt("level"); + Log.e("wbw", "current = " + voltage_level); + BatteryV = intent.getIntExtra("voltage", 0); + Log.e("wbw", "BatteryV = " + BatteryV); + Log.e("wbw", "V = " + BatteryV * 2 / 100); + // m_voltage = (int) (65+19*voltage_level/100); //放大十倍 + // Log.e("wbw","m_voltage = " + m_voltage ); + } + } + + // disable the power key when the device is boot from alarm but not ipo boot + private static final String DISABLE_FUNCTION_LAUNCH_ACTION = "android.intent.action.DISABLE_FUNCTION_LAUNCH"; + + private void disableFunctionLaunch(boolean state) { + Intent disablePowerKeyIntent = new Intent(DISABLE_FUNCTION_LAUNCH_ACTION); + if (state) { + disablePowerKeyIntent.putExtra("state", true); + } else { + disablePowerKeyIntent.putExtra("state", false); + } + sendBroadcast(disablePowerKeyIntent); + } + + private void printCS10(final HashMap paramsMap, final String[] printText) { + disablePrintButton(); + final String copies; + if (paramsMap.containsKey("receiptCopies")) { + copies = paramsMap.get("receiptCopies"); + } else { + copies = "BOTH"; + } + InputStream imageStream = this.getResources().openRawResource(R.raw.payment_option); + Bitmap bmp1 = BitmapFactory.decodeStream(imageStream); + //Bitmap bmp1 = BitmapFactory.decodeResource(getApplication().getResources(), R.drawable.abc3); + boolean mNeedsCuttingPause = false; + + if (TextUtils.equals(copies, AGENT) || + TextUtils.equals(copies, BOTH)) { + mNeedsCuttingPause = true; + Print.Lib_PrnSetAlign(1); + posApiHelper.PrintSetAlign(0); + int ret = posApiHelper.PrintBmp(bmp1); + sendCS10Data(getHeader(paramsMap, "AGENT COPY"), false); // print header text + Print.Lib_PrnSetAlign(0); + posApiHelper.PrintSetAlign(0); + sendCS10Data(preparePrintText(printText), false); // print receipt text + Print.Lib_PrnSetAlign(0); + sendCS10Data(getFooter(paramsMap), false); // print footer text + if (getIntent().hasExtra("hasSignatureBitmap") && getIntent().getBooleanExtra("hasSignatureBitmap", false)) { + printImage(Config.SignatureBitmap); // print Signature image +// int ret2 = posApiHelper.PrintBmp(Config.SignatureBitmap); +// Log.e("PrintBmp", "Lib_PrnStart fail, ret = " + ret2); +// Log.e("PrintBmp height", "Lib_PrnStart fail, ret = " + Config.SignatureBitmap.getHeight()); +// Log.e("PrintBmp width", "Lib_PrnStart fail, ret = " + Config.SignatureBitmap.getWidth()); + Config.SignatureBitmap = null; + } + if (paramsMap.containsKey("qr_auth_code")) { + posApiHelper.PrintSetAlign(1); +// printer.appendImage(QRBitmap, AlignEnum.CENTER); + posApiHelper.PrintBmp(QRBitmap); // print QR image + posApiHelper.PrintStr("\n\n\n"); +// printer.appendPrnStr("\n\n\n", 20, AlignEnum.CENTER, false); + posApiHelper.PrintSetAlign(0); + posApiHelper.PrintStr(AppConstants.getInstance().getBankCaption()); +// printer.appendPrnStr(AppConstants.getInstance().getBankCaption(), 24, AlignEnum.CENTER, false); +// printer.appendPrnStr("\n\n\n", 20, AlignEnum.CENTER, false); + posApiHelper.PrintStr("\n\n\n"); + } +// printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); +// printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); + posApiHelper.PrintStr(" \n"); + posApiHelper.PrintStr(" \n"); + posApiHelper.PrintStart(); +// printer.startPrint(true, this); + } + + if (TextUtils.equals(copies, CUSTOMER) || // if BI/MI, print customer copy only + TextUtils.equals(copies, BOTH)) { // print customer copy + if (mNeedsCuttingPause) { + this.paramsMap.put("receiptCopies", CUSTOMER); // makes sure only customer copy is printed by clicking button + enablePrintButton(); + return; + } + disablePrintButton(); + +// Print.Lib_PrnSetAlign(1); + + posApiHelper.PrintSetAlign(0); + //printImage(bitmap);// print image image + posApiHelper.PrintBmp(bmp1); +// printer.appendImage(bmp1, AlignEnum.CENTER); + Print.Lib_PrnSetAlign(0); + posApiHelper.PrintSetAlign(0); + sendCS10Data(getHeader(paramsMap, "CUSTOMER COPY"), false); + Print.Lib_PrnSetAlign(0); + sendCS10Data(preparePrintText(printText), false); + if (paramsMap.containsKey("qr_auth_code")) { + sendCS10Data(getFooter(paramsMap), false); + posApiHelper.PrintSetAlign(1); + posApiHelper.PrintBmp(QRBitmap); +// printer.appendImage(QRBitmap, AlignEnum.CENTER); +// printer.appendPrnStr("\n\n\n", 20, AlignEnum.CENTER, false); + posApiHelper.PrintStr("\n\n\n"); + posApiHelper.PrintSetAlign(0); +// printer.appendPrnStr(AppConstants.getInstance().getBankCaption(), 20, AlignEnum.CENTER, false); +// printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); +// printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); +// printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); + posApiHelper.PrintStr(AppConstants.getInstance().getBankCaption()); + posApiHelper.PrintStr(" \n"); + posApiHelper.PrintStr(" \n"); + posApiHelper.PrintStr(" \n"); + } else { + sendCS10Data(getFooter(paramsMap), true); + posApiHelper.PrintStr("\n\n\n"); +// printer.appendPrnStr("\n\n\n", 20, AlignEnum.CENTER, false); + posApiHelper.PrintStr(AppConstants.getInstance().getBankCaption()); + posApiHelper.PrintStr(" \n"); + posApiHelper.PrintStr(" \n"); + posApiHelper.PrintStr(" \n"); +// printer.appendPrnStr(AppConstants.getInstance().getBankCaption(), 24, AlignEnum.CENTER, false); +// printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); +// printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); +// printer.appendPrnStr(" \n", 20, AlignEnum.CENTER, false); + + } + posApiHelper.PrintStart(); +// printer.startPrint(true, this); + } + finishedPrinting(true); + } + + + + + void sendCS10Data(String[] printText, boolean closeConnection) { + try { + for (String line : printText) { + if (line.startsWith(CENTER_PREFIX)) { + posApiHelper.PrintSetAlign(0); + line = line.substring(CENTER_PREFIX.length()); + } + posApiHelper.PrintStr(line); + posApiHelper.PrintCtnStart(); + } + finishedPrinting(closeConnection); + } catch (NullPointerException e) { + Log.e(TAG, "Exception Response :- " + e.getMessage()); + } catch (Exception e) { + Log.e(TAG, "Exception Response :- " + e.getMessage()); + } } diff --git a/app/src/main/java/com/steve_md/smartmkulima/utils/services/QRUtil.java b/app/src/main/java/com/steve_md/smartmkulima/utils/services/QRUtil.java new file mode 100644 index 00000000..abc032f0 --- /dev/null +++ b/app/src/main/java/com/steve_md/smartmkulima/utils/services/QRUtil.java @@ -0,0 +1,37 @@ +package com.steve_md.smartmkulima.utils.services; + +import android.graphics.Bitmap; +import android.graphics.Color; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; + +public class QRUtil { + + /** + * Generate qr bitmap. + * + * @param content the content + * @return the bitmap + */ + public static Bitmap generateQR(String content) { + QRCodeWriter writer = new QRCodeWriter(); + try { + BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, 300, 300); + int width = bitMatrix.getWidth(); + int height = bitMatrix.getHeight(); + Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bmp.setPixel(x, y, bitMatrix.get(x, y) ? Color.BLACK : Color.WHITE); + } + } + return bmp; + } catch (WriterException e) { + //Trace(); + } + return null; + } +} diff --git a/app/src/main/java/com/steve_md/smartmkulima/utils/services/SlipModelUtils.java b/app/src/main/java/com/steve_md/smartmkulima/utils/services/SlipModelUtils.java new file mode 100644 index 00000000..d59be482 --- /dev/null +++ b/app/src/main/java/com/steve_md/smartmkulima/utils/services/SlipModelUtils.java @@ -0,0 +1,107 @@ +package com.steve_md.smartmkulima.utils.services; + +import android.content.Context; +import android.graphics.Bitmap; + +import com.pos.sdk.printer.param.BitmapPrintItemParam; +import com.pos.sdk.printer.param.MultipleTextPrintItemParam; +import com.pos.sdk.printer.param.PrintItemAlign; +import com.pos.sdk.printer.param.TextPrintItemParam; + +import java.io.ByteArrayOutputStream; + +public class SlipModelUtils { + private static final String TAG = "SlipModelUtils"; + private final static String FONT_PATH = "mnt/sdcard/addTestData.ttf"; + private final static String LETTER_FONT_PATH = "mnt/sdcard/NanumGothicCoding.ttf"; + + public MultipleTextPrintItemParam createMultipleTextPrintItemParam(float[] scales, TextPrintItemParam[] list) { + MultipleTextPrintItemParam param = new MultipleTextPrintItemParam(scales, list); + return param; + } + + public MultipleTextPrintItemParam addLeftAndRightItem(String left, String right, float[] scales) { + return addLeftAndRightItem(left, right, -1, -1, scales); + } + + + public MultipleTextPrintItemParam addCenterAndRightItem(String center, String right) { + float[] scales = new float[]{2, 1}; + TextPrintItemParam leftItem = addTextOnePrint(center, false, -1, PrintItemAlign.RIGHT); + TextPrintItemParam rightItem = addTextOnePrint(right, false, -1, PrintItemAlign.RIGHT); + TextPrintItemParam[] list = new TextPrintItemParam[]{leftItem, rightItem}; + return createMultipleTextPrintItemParam(scales, list); + } + + + public TextPrintItemParam addTextOnePrint(String content, boolean isBold, int textSize, PrintItemAlign align) { + TextPrintItemParam param = new TextPrintItemParam(); +// param.setTypefacePath("mnt/sdcard/Caveat.ttf"); + param.setContent(content); + if (textSize > 0) { + param.setTextSize(textSize); + } else { + param.setTextSize(16); + param.setScaleHeight(1.6f); + param.setScaleWidth(1.2f); + } + param.setItemAlign(align); + param.setBold(isBold); + return param; + } + + public MultipleTextPrintItemParam addFourItem(String first, String second, String third, String fourth, float[] scales) { + if (scales == null) { + scales = new float[]{1, 3.5f, 1, 1.5f}; + } + TextPrintItemParam firstItem = addTextOnePrint(first, false, -1, PrintItemAlign.LEFT); + TextPrintItemParam secondItem = addTextOnePrint(second, false, -1, PrintItemAlign.CENTER); + TextPrintItemParam thirdItem = addTextOnePrint(third, false, -1, PrintItemAlign.CENTER); + TextPrintItemParam fourthItem = addTextOnePrint(fourth, false, -1, PrintItemAlign.RIGHT); + TextPrintItemParam[] list = new TextPrintItemParam[]{firstItem, secondItem, thirdItem, fourthItem}; + return new MultipleTextPrintItemParam(scales, list); + } + + + public BitmapPrintItemParam addBitmapAsset(Context context, String nameInAssets) { + BitmapPrintItemParam printItemParam = new BitmapPrintItemParam(); + try { + printItemParam.setBitmap(DataUtil.inputStream2byte(context.getAssets().open("image/" + nameInAssets))); + printItemParam.setHeight(100); + printItemParam.setWidth(300); + printItemParam.setItemAlign(PrintItemAlign.CENTER); + } catch (Exception e) { + e.printStackTrace(); + } + return printItemParam; + } + + public BitmapPrintItemParam addBitmapItem(Context context, Bitmap bitmap) { + BitmapPrintItemParam printItemParam = new BitmapPrintItemParam(); + try { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); + byte[] byteArray = stream.toByteArray(); + printItemParam.setBitmap(byteArray); + printItemParam.setHeight(100); + printItemParam.setWidth(300); + printItemParam.setItemAlign(PrintItemAlign.CENTER); + bitmap.recycle(); + } catch (Exception e) { + e.printStackTrace(); + } + return printItemParam; + } + + public MultipleTextPrintItemParam addLeftAndRightItem(String left, String right, int leftSize, int rightSize, float[] scales) { + if (scales == null) { + scales = new float[]{1, 1}; + } + TextPrintItemParam leftItem = addTextOnePrint(left, false, leftSize, PrintItemAlign.LEFT); + TextPrintItemParam rightItem = addTextOnePrint(right, false, rightSize, PrintItemAlign.RIGHT); +// rightItem.setLetterAndNumberTypefacePath("mnt/sdcard/msyhc.ttf"); + TextPrintItemParam[] list = new TextPrintItemParam[]{leftItem, rightItem}; + return createMultipleTextPrintItemParam(scales, list); + } + +} diff --git a/app/src/main/java/com/steve_md/smartmkulima/utils/services/SpinnerItem.java b/app/src/main/java/com/steve_md/smartmkulima/utils/services/SpinnerItem.java new file mode 100644 index 00000000..872d6ef8 --- /dev/null +++ b/app/src/main/java/com/steve_md/smartmkulima/utils/services/SpinnerItem.java @@ -0,0 +1,90 @@ +package com.steve_md.smartmkulima.utils.services; + +public class SpinnerItem { + private String id; + private String title; + private int image; + + /** + * Instantiates a new Spinner item. + * + * @param id the id + * @param title the title + * @param image the image + */ + public SpinnerItem(String id, String title, int image) { + this.id = id; + this.title = title; + this.image = image; + } + + /** + * Instantiates a new Spinner item. + * + * @param title the title + * @param image the image + */ + public SpinnerItem(String title, int image) { + this.title = title; + this.image = image; + + } + + /** + * Gets id. + * + * @return the id + */ + public String getId() { + return id; + } + + /** + * Sets id. + * + * @param id the id + */ + public void setId(String id) { + this.id = id; + } + + /** + * Gets title. + * + * @return the title + */ + public String getTitle() { + return title; + } + + /** + * Sets title. + * + * @param title the title + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * Gets image. + * + * @return the image + */ + public int getImage() { + return image; + } + + /** + * Sets image. + * + * @param image the image + */ + public void setImage(int image) { + this.image = image; + } + + +} + + diff --git a/app/src/main/res/drawable/ic_call_24.xml b/app/src/main/res/drawable/ic_call_24.xml new file mode 100644 index 00000000..0375be22 --- /dev/null +++ b/app/src/main/res/drawable/ic_call_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_email_24.xml b/app/src/main/res/drawable/ic_email_24.xml new file mode 100644 index 00000000..71e1bf58 --- /dev/null +++ b/app/src/main/res/drawable/ic_email_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_location_on_.xml b/app/src/main/res/drawable/ic_location_on_.xml new file mode 100644 index 00000000..9d2b92fc --- /dev/null +++ b/app/src/main/res/drawable/ic_location_on_.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/layout/activity_print_service.xml b/app/src/main/res/layout/activity_print_service.xml index 172b6e5e..e8cbf759 100644 --- a/app/src/main/res/layout/activity_print_service.xml +++ b/app/src/main/res/layout/activity_print_service.xml @@ -8,7 +8,7 @@ + app:layout_constraintTop_toBottomOf="@id/dashboard_toolbar"> + + + + + + + + + + + - \ No newline at end of file + app:layout_constraintTop_toBottomOf="@+id/tVFindAgroDealersNearYou" + tools:listitem="@layout/item_agrodealer" /> + + + diff --git a/app/src/main/res/layout/fragment_monitor_farm_condition.xml b/app/src/main/res/layout/fragment_monitor_farm_condition.xml index 71593bbb..1c532b5a 100644 --- a/app/src/main/res/layout/fragment_monitor_farm_condition.xml +++ b/app/src/main/res/layout/fragment_monitor_farm_condition.xml @@ -13,9 +13,9 @@ android:id="@+id/cardView15" android:layout_width="match_parent" android:layout_height="200dp" - android:layout_marginStart="32dp" + android:layout_marginStart="16dp" android:layout_marginTop="80dp" - android:layout_marginEnd="32dp" + android:layout_marginEnd="16dp" app:cardCornerRadius="20dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" @@ -43,7 +43,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/montserrat_medium" - android:text="23.00" + android:text="0.00" android:textSize="22sp" app:layout_constraintBottom_toBottomOf="@+id/textView57" app:layout_constraintStart_toEndOf="@+id/textView57" @@ -67,7 +67,7 @@ android:layout_height="wrap_content" android:layout_marginStart="4dp" android:fontFamily="@font/montserrat_medium" - android:text="25.00" + android:text="0.00" android:textSize="22sp" app:layout_constraintBottom_toBottomOf="@+id/textView59" app:layout_constraintStart_toEndOf="@+id/textView59" @@ -89,7 +89,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/montserrat_medium" - android:text="21.00" + android:text="0.00" android:textSize="22sp" app:layout_constraintBottom_toBottomOf="@+id/textView61" app:layout_constraintStart_toEndOf="@+id/textView61" @@ -107,6 +107,19 @@ app:layout_constraintHorizontal_bias="0.113" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + + @@ -133,7 +146,7 @@ android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginStart="32dp" - android:fontFamily="@font/montserrat_medium" + android:fontFamily="@font/montserrat_semibold" android:textColor="@color/white" android:textSize="18sp" android:text="Monitor Your Farm" /> @@ -141,13 +154,14 @@ + app:layout_constraintVertical_bias="0.15"/> + +