Skip to content

Commit

Permalink
Merge pull request #86 from MuindiStephen/dev/buyer
Browse files Browse the repository at this point in the history
Dev/buyer
  • Loading branch information
MuindiStephen authored Oct 14, 2024
2 parents 5894a37 + 106914a commit 6b42ab6
Show file tree
Hide file tree
Showing 31 changed files with 797 additions and 174 deletions.
2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -185,5 +185,12 @@ dependencies {
// Daraja
implementation 'com.androidstudy.daraja:daraja:2.0.2'

// In App Updates
implementation("com.google.android.play:app-update-ktx:2.1.0")

// Google Firebase Analytics
implementation(platform("com.google.firebase:firebase-bom:33.4.0"))
implementation("com.google.firebase:firebase-analytics")


}
Binary file added app/release/app-release.aab
Binary file not shown.
11 changes: 11 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-feature
android:name="android.hardware.telephony"
android:required="false" />



<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Expand All @@ -11,6 +17,7 @@
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />


<application
Expand Down Expand Up @@ -58,6 +65,10 @@
android:name="android.app.lib_name"
android:value="" />
</activity>

<service
android:name="com.steve_md.smartmkulima.utils.OverlayService"
/>
</application>

</manifest>
61 changes: 56 additions & 5 deletions app/src/main/java/com/steve_md/smartmkulima/ShambaApp.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package com.steve_md.smartmkulima

import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.SharedPreferences
import android.os.Build
import android.os.Bundle
import android.os.StrictMode
import androidx.appcompat.app.AppCompatDelegate
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.database.FirebaseDatabase
import com.steve_md.smartmkulima.utils.SnackbarHelper
import dagger.hilt.android.HiltAndroidApp
import timber.log.Timber
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors


/**
Expand All @@ -19,16 +20,55 @@ import timber.log.Timber
*/
@HiltAndroidApp
class ShambaApp : Application() {

private lateinit var firebaseAnalytics: FirebaseAnalytics
override fun onCreate() {
super.onCreate()
timber()
setNetworkSecurity()
// setNetworkSecurity()
FirebaseDatabase.getInstance().setPersistenceEnabled(true)
val sharedPreferences: SharedPreferences =
getSharedPreferences("ui_mode", Context.MODE_PRIVATE)
val itemUIMode: Boolean = sharedPreferences.getBoolean("ISCHECKED", false)
Timber.d("UI Theme: $itemUIMode")
uiMode(itemUIMode)

initializeSDKS()
}

private fun initializeSDKS() {
val executorService: ExecutorService = Executors.newFixedThreadPool(2)
executorService.execute {
initializeAnalyticsSDKS(context = this.applicationContext)
}

executorService.execute {
initializeCrashReportingSDKS()
}
}

private fun initializeCrashReportingSDKS() {

}

private fun initializeAnalyticsSDKS(context: Context) {
// Initialize Firebase Analytics
firebaseAnalytics = FirebaseAnalytics.getInstance(context)

// Example of logging an event after initialization
val bundle = Bundle().apply {
putString(FirebaseAnalytics.Param.METHOD, "app_start")
}

/*
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT) {
param(FirebaseAnalytics.Param.ITEM_ID, bundle);
param(FirebaseAnalytics.Param.ITEM_NAME, name);
param(FirebaseAnalytics.Param.CONTENT_TYPE, "image");
}
*/

firebaseAnalytics.logEvent(FirebaseAnalytics.Event.APP_OPEN, bundle)
}


Expand All @@ -44,9 +84,20 @@ class ShambaApp : Application() {
}
}

/**
* StrictMode is a developer tool which detects things you might be doing
* by accident and brings them to your attention so you can fix them
*
*/
private fun setNetworkSecurity() {
val builder = StrictMode.VmPolicy.Builder()
StrictMode.setVmPolicy(builder.build())
StrictMode.setVmPolicy(builder
.detectAll()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.penaltyDeath()
.build())
}

private fun timber() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.steve_md.smartmkulima.databinding.ProductsRowBinding
import com.steve_md.smartmkulima.model.AgroDealer
import com.steve_md.smartmkulima.model.FarmProduce


class FarmProduceAdapter : ListAdapter<FarmProduce, FarmProduceAdapter.MyViewHolder>(MyDiffUtil) {
class FarmProduceAdapter(
private val onClickListener: OnClickListener
) : ListAdapter<FarmProduce, FarmProduceAdapter.MyViewHolder>(MyDiffUtil) {
object MyDiffUtil : DiffUtil.ItemCallback<FarmProduce>() {
override fun areItemsTheSame(oldItem: FarmProduce, newItem: FarmProduce): Boolean {
return oldItem == newItem
Expand Down Expand Up @@ -47,5 +50,13 @@ class FarmProduceAdapter : ListAdapter<FarmProduce, FarmProduceAdapter.MyViewHol
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val product = getItem(position)
holder.bind(product)

holder.itemView.setOnClickListener {
onClickListener.onClick(farmProduce = product)
}
}

class OnClickListener(val clickListener: (farmProduce: FarmProduce) -> Unit) {
fun onClick(farmProduce: FarmProduce) = clickListener(farmProduce)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -141,23 +141,34 @@ class FarmCycleRepository @Inject constructor(
}

suspend fun fieldAgentAddANewAgroDealer(fieldAgentAddAgroDealerData: FieldAgentAddAgroDealerData) = apiRequestByResource {

// Inserting AgroDealer Into db
fieldAgentAddAgrodealerDao.fieldAgentAddANewAgrodealer(fieldAgentAddAgroDealerData)
}

fun getAllFieldAgentAddedAgroDealers(): LiveData<List<FieldAgentAddAgroDealerData>> {
return fieldAgentAddAgrodealerDao.getAllFieldAgentAddedAgrodealers()
}
// Update field agent points
val agentPoints = fieldAgentEarningsDao.getPointsByAgentId(fieldAgentAddAgroDealerData.agentId)
if (agentPoints != null) {
agentPoints.points += 10
agentPoints.earnings += 200.0
fieldAgentEarningsDao.saveOrUpdatePoints(agentPoints)
} else {
// First time this agent registers/ adds a new farmer
val newAgentPoints = FieldAgentEarnings(
fieldAgentID = fieldAgentAddAgroDealerData.agentId,
points = 10,
earnings = 200.0
)

// Field agent earnings METHODS
suspend fun saveEarnings(fieldAgentEarnings: FieldAgentEarnings) = apiRequestByResource {
fieldAgentEarningsDao.saveFieldAgentEarnings(fieldAgentEarnings)
fieldAgentEarningsDao.saveOrUpdatePoints(newAgentPoints)
}
}

suspend fun updateFieldAgentEarnings(newPoints: Int, earnings: Double) {
fieldAgentEarningsDao.updateFieldAgentEarnings(newPoints, earnings)

suspend fun getAgentPoints(agentId: String): FieldAgentEarnings? {
return fieldAgentEarningsDao.getPointsByAgentId(agentId)
}

fun getAllFieldAgentEarnings(): LiveData<FieldAgentEarnings> {
return fieldAgentEarningsDao.fetchAllFieldAgentEarnings()
fun getAllFieldAgentAddedAgroDealers(): LiveData<List<FieldAgentAddAgroDealerData>> {
return fieldAgentAddAgrodealerDao.getAllFieldAgentAddedAgrodealers()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import com.steve_md.smartmkulima.model.responses.fieldagent.Data
OrderCheckoutByFarmer::class,
FieldAgentAddAgroDealerData::class,
Data::class, FieldAgentEarnings::class, com.steve_md.smartmkulima.model.responses.buyer.Data::class],
version = 12,exportSchema = false)
version = 13,exportSchema = false)
abstract class AppDatabase : RoomDatabase() {

abstract fun transactionDao(): TransactionDao
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,16 @@ import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.steve_md.smartmkulima.model.OrderCheckoutByFarmer
import com.steve_md.smartmkulima.model.fieldagentmodels.FieldAgentEarnings


@Dao
interface FieldAgentEarningsDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun saveFieldAgentEarnings(fieldAgentEarnings: FieldAgentEarnings)
suspend fun saveOrUpdatePoints(fieldAgentEarnings: FieldAgentEarnings)

@Query("UPDATE field_agents_earnings SET points =:newPoints, earnings = :newEarnings")
suspend fun updateFieldAgentEarnings(newPoints: Int, newEarnings: Double)

@Query("SELECT * FROM field_agents_earnings")
fun fetchAllFieldAgentEarnings(): LiveData<FieldAgentEarnings>
@Query("SELECT * FROM field_agents_earnings WHERE fieldAgentID = :agentId LIMIT 1")
suspend fun getPointsByAgentId(agentId: String): FieldAgentEarnings? // Only expecting a single result.
// save loads of data and improve query performance.
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ data class FieldAgentAddAgroDealerData(
val email: String,
val phone: String,
val location: String,
val physicalLocationAddress: String
val physicalLocationAddress: String,
val agentId: String, // field agent who registered this farmer
val offers: String // offer categories ie. select where applicable
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey


/**
* A model data class to track the field agent's points
* for registering / adding new farmers.
*/
@Entity(tableName = "field_agents_earnings")
data class FieldAgentEarnings(
@PrimaryKey(autoGenerate = true)
val id: Long = 0,
val points: Int = 0,
val earnings: Double = 0.0
val fieldAgentID: String,
var points: Int = 0,
var earnings: Double = 0.0
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,24 @@ import android.os.Bundle
import android.view.View
import android.view.Window
import android.view.WindowManager
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.setupWithNavController
import com.google.android.play.core.appupdate.AppUpdateManager
import com.google.android.play.core.appupdate.AppUpdateManagerFactory
import com.google.android.play.core.appupdate.AppUpdateOptions
import com.google.android.play.core.install.model.AppUpdateType
import com.google.android.play.core.install.model.UpdateAvailability
import com.steve_md.smartmkulima.R
import com.steve_md.smartmkulima.databinding.ActivityMainBinding
import com.steve_md.smartmkulima.utils.SnackbarHelper
import dagger.hilt.android.AndroidEntryPoint
import timber.log.Timber

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
Expand All @@ -32,13 +39,16 @@ class MainActivity : AppCompatActivity() {

private var screenCaptureCallback: ScreenCaptureCallback? = null

private val appUpdateManager: AppUpdateManager by lazy { AppUpdateManagerFactory.create(this) }

@RequiresApi(Build.VERSION_CODES.TIRAMISU)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

checkUpdate()

supportActionBar?.hide()

Expand Down Expand Up @@ -73,9 +83,34 @@ class MainActivity : AppCompatActivity() {
}
}

private val updateLauncher = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) {
if (it?.data == null) return@registerForActivityResult
if (it.resultCode == UPDATE_REQUEST_CODE) {
Timber.d("Download Started")
if (it.resultCode != Activity.RESULT_OK) {
Timber.d("Download Failed")
}
}
}

/**
* we are getting the info if the update is available or not
*/
private fun checkUpdate() {
val appUpdateInfoTask = appUpdateManager.appUpdateInfo
appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
appUpdateManager.startUpdateFlowForResult( // to start the app update process.
appUpdateInfo,
updateLauncher,
AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build())
}
}
}


companion object {
const val UPDATE_REQUEST_CODE = 1
}
}


Expand Down
Loading

0 comments on commit 6b42ab6

Please sign in to comment.