Skip to content

Commit

Permalink
Merge pull request #69 from MuindiStephen/68-respective-gaps
Browse files Browse the repository at this point in the history
68 respective gaps
  • Loading branch information
MuindiStephen authored Jul 21, 2024
2 parents b7f45ec + 7e3ca32 commit 9a316b0
Show file tree
Hide file tree
Showing 36 changed files with 1,216 additions and 90 deletions.
10 changes: 5 additions & 5 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,19 @@ dependencies {

// Testing
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'

// Navigation Components
implementation("androidx.navigation:navigation-fragment-ktx:2.7.7")
implementation("androidx.navigation:navigation-ui-ktx:2.7.7")


// Alternatively - just LiveData
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.2")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.3")

// Alternatively - just ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.2")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.3")

// Dagger - Hilt
implementation 'com.google.dagger:hilt-android:2.50'
Expand Down Expand Up @@ -123,7 +123,7 @@ dependencies {


// Maps - Dependency
implementation 'com.google.android.gms:play-services-maps:18.2.0'
implementation 'com.google.android.gms:play-services-maps:19.0.0'
implementation 'com.google.android.gms:play-services-location:21.3.0'

// Lottie Animation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import com.bumptech.glide.Glide
import com.steve_md.smartmkulima.databinding.HomeGapRowBinding
import com.steve_md.smartmkulima.model.GAP

/**
* - Bind fetched GAPS to the Ui (Recycler View)
* - In order to display a list of available GAPs to the RecyclerView Ui
*/
class GapAdapter(private val onClickListener: OnClickListener) :
ListAdapter<GAP, GapAdapter.MyViewHolder>(TaskDiffUtil) {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.steve_md.smartmkulima.adapter.others

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.steve_md.smartmkulima.databinding.CropCycleTaskRowBinding
import com.steve_md.smartmkulima.model.LocalFarmCycle

/**
* Attach data to locally created Farm cycles to Room DB
*/
class LocalFarmCycleAdapter(private val onClickListener: OnClickListener) :
ListAdapter<LocalFarmCycle, LocalFarmCycleAdapter.MyViewHolder>(TaskDiffUtil) {

object TaskDiffUtil : DiffUtil.ItemCallback<LocalFarmCycle>() {
override fun areItemsTheSame(oldItem: LocalFarmCycle, newItem: LocalFarmCycle): Boolean {
return oldItem == newItem
}

override fun areContentsTheSame(oldItem: LocalFarmCycle, newItem: LocalFarmCycle): Boolean {
return oldItem.cropName == newItem.cropName
}
}

inner class MyViewHolder(private var binding: CropCycleTaskRowBinding) :
RecyclerView.ViewHolder(binding.root) {

@SuppressLint("SetTextI18n")
fun bind(cycle: LocalFarmCycle?) {
binding.farmID.text = cycle?.farmName
binding.cycleData.text = cycle?.cropName
binding.dateForCycle.text = cycle?.startDate
binding.textView85.text = "Crop cycle"
}
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(
CropCycleTaskRowBinding.inflate(LayoutInflater.from(parent.context), parent, false)
)
}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val cycle = getItem(position)
holder.bind(cycle)

holder.itemView.setOnClickListener {
onClickListener.onClick(cycle = cycle)
}
}

class OnClickListener(val clickListener: (cycle: LocalFarmCycle) -> Unit) {
fun onClick(cycle: LocalFarmCycle) = clickListener(cycle)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.steve_md.smartmkulima.adapter.others

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.steve_md.smartmkulima.databinding.DetailCycleRowBinding
import com.steve_md.smartmkulima.model.LocalTasks

/**
* Able to view actual tasks for cycle - respective tasks
*/
class LocalFarmCycleTasksAdapter : RecyclerView.Adapter<LocalFarmCycleTasksAdapter.TaskViewHolder>() {

private var tasks: List<LocalTasks> = ArrayList()

inner class TaskViewHolder(private val binding: DetailCycleRowBinding) :
RecyclerView.ViewHolder(binding.root) {

fun bind(task: LocalTasks) {
binding.textView75.text = task.taskName
binding.textView76.text = task.startDate
binding.textView77.text = task.endDate
}
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskViewHolder {
val binding =
DetailCycleRowBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return TaskViewHolder(binding)
}

override fun onBindViewHolder(holder: TaskViewHolder, position: Int) {
val task = tasks[position]
holder.bind(task)
}

override fun getItemCount(): Int {
return tasks.size
}

@SuppressLint("NotifyDataSetChanged")
fun submitList(taskList: List<LocalTasks>) {
tasks = taskList
notifyDataSetChanged()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import com.steve_md.smartmkulima.model.GAP
import retrofit2.Call
import retrofit2.http.GET

/**
* Fetch a list of
* Good Agricultural Practices from the API
*/
interface GAPsAPiService {

@GET("goodagriculturalpractices")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.steve_md.smartmkulima.data.repositories

import androidx.lifecycle.LiveData
import com.steve_md.smartmkulima.data.room.AppDatabase
import com.steve_md.smartmkulima.data.room.GAPDao
import com.steve_md.smartmkulima.data.room.LocalFarmCycleDao
import com.steve_md.smartmkulima.model.Cycle
import com.steve_md.smartmkulima.model.GAP
import com.steve_md.smartmkulima.model.LocalFarmCycle
import com.steve_md.smartmkulima.utils.apiRequestByResource
import com.steve_md.smartmkulima.utils.safeCall
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import javax.inject.Inject

/**
* Farm cycles repository
* Manual creating of repositories
*/
class FarmCycleRepository @Inject constructor(
database: AppDatabase
) {
private val gapDao: GAPDao = database.gapDao()

private val localCycleDao: LocalFarmCycleDao = database.localFarmCycleDao()

suspend fun insertCycle(cycle: LocalFarmCycle) = apiRequestByResource {
localCycleDao.insertLocalFarmCycle(cycle)
}

val allCycles : Flow<List<Cycle>> = gapDao.getAllCycle()




fun getAllCycles(): LiveData<List<LocalFarmCycle>> {
return localCycleDao.getAllFarmCycle()
}

suspend fun updateTaskStatus(status: String) {
localCycleDao.updateTaskStatus(status)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,28 @@ package com.steve_md.smartmkulima.data.room

import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import com.steve_md.smartmkulima.data.room.converters.Converters
import com.steve_md.smartmkulima.data.room.converters.LocalFarmCycleConverter
import com.steve_md.smartmkulima.model.Cycle
import com.steve_md.smartmkulima.model.FarmProduce
import com.steve_md.smartmkulima.model.LocalFarmCycle
import com.steve_md.smartmkulima.model.Tasks
import com.steve_md.smartmkulima.model.Transaction


@Database(entities = [Transaction::class,FarmProduce::class], version = 3, exportSchema = false)
@TypeConverters(Converters::class,LocalFarmCycleConverter::class)
@Database(entities = [Transaction::class, FarmProduce::class, Cycle::class,
Tasks::class, LocalFarmCycle::class], version = 5, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {

abstract fun transactionDao(): TransactionDao
abstract fun farmProduceDao() : FarmProduceDao

abstract fun gapDao(): GAPDao

abstract fun localFarmCycleDao(): LocalFarmCycleDao

/**
* Implement singleton pattern in room to prevent
* multiple instances of room database opening at the sametime
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/java/com/steve_md/smartmkulima/data/room/GAPDao.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.steve_md.smartmkulima.data.room

import androidx.room.*
import com.steve_md.smartmkulima.model.Cycle
import com.steve_md.smartmkulima.model.GAP
import kotlinx.coroutines.flow.Flow

@Dao
interface GAPDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertGAP(cycle: Cycle)

@Query("SELECT * FROM cycle")
fun getAllCycle(): Flow<List<Cycle>>

@Delete
suspend fun deleteGAP(cycle: Cycle)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.steve_md.smartmkulima.data.room

import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.steve_md.smartmkulima.model.LocalFarmCycle
import kotlinx.coroutines.flow.Flow


@Dao
interface LocalFarmCycleDao {

@Insert
suspend fun insertLocalFarmCycle(localFarmCycle: LocalFarmCycle)

@Update
suspend fun updateLocalFarmCycle(localFarmCycle: LocalFarmCycle)

@Query("SELECT * FROM localcycle WHERE cropName = :cropName")
suspend fun getFarmCycleBYName(cropName: String): LocalFarmCycle?

@Query("SELECT * FROM localcycle")
fun getAllFarmCycle(): LiveData<List<LocalFarmCycle>>

@Query("UPDATE localcycle SET status = :status")
suspend fun updateTaskStatus(status: String)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.steve_md.smartmkulima.data.room.converters

import androidx.room.TypeConverter
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.steve_md.smartmkulima.model.Cycle
import com.steve_md.smartmkulima.model.GAPtask
import com.steve_md.smartmkulima.model.Tasks

class Converters {
@TypeConverter
fun fromTasksList(tasks: List<Tasks>?): String? {
return Gson().toJson(tasks)
}

@TypeConverter
fun toTasksList(tasksString: String?): List<Tasks>? {
val listType = object : TypeToken<List<Tasks>>() {}.type
return Gson().fromJson(tasksString, listType)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.steve_md.smartmkulima.data.room.converters

import androidx.room.TypeConverter
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.steve_md.smartmkulima.model.LocalTasks

class LocalFarmCycleConverter {
@TypeConverter
fun fromLocalTasksList(value: List<LocalTasks>?): String {
val gson = Gson()
val type = object : TypeToken<List<LocalTasks>>() {}.type
return gson.toJson(value, type)
}

@TypeConverter
fun toLocalTasksList(value: String): List<LocalTasks>? {
val gson = Gson()
val type = object : TypeToken<List<LocalTasks>>() {}.type
return gson.fromJson(value, type)
}
}
15 changes: 15 additions & 0 deletions app/src/main/java/com/steve_md/smartmkulima/di/DatabaseModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package com.steve_md.smartmkulima.di

import android.app.Application
import androidx.room.Room
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.steve_md.smartmkulima.data.room.AppDatabase
import com.steve_md.smartmkulima.data.room.FarmProduceDao
import com.steve_md.smartmkulima.data.room.GAPDao
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand All @@ -25,9 +28,21 @@ object DatabaseModule {
.build()
}


private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE localcycle ADD COLUMN status TEXT NOT NULL DEFAULT 'Upcoming'")
}
}
@Provides
@Singleton
fun providesFarmProduceDao(appDatabase: AppDatabase): FarmProduceDao {
return appDatabase.farmProduceDao()
}

@Provides
@Singleton
fun providesCycleDao(appDatabase: AppDatabase): GAPDao {
return appDatabase.gapDao()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.steve_md.smartmkulima.di

import com.steve_md.smartmkulima.data.remote.FarmProduceApiService
import com.steve_md.smartmkulima.data.repositories.AuthRepository
import com.steve_md.smartmkulima.data.repositories.FarmCycleRepository
import com.steve_md.smartmkulima.data.repositories.FarmProduceRepository
import com.steve_md.smartmkulima.data.repositories.impl.AuthRepositoryImpl
import com.steve_md.smartmkulima.data.room.AppDatabase
Expand All @@ -27,6 +28,14 @@ object RepositoryModule {
return FarmProduceRepository(farmProduceApiService, appDatabase)
}

@Singleton
@Provides
fun providesFarmCycleRepo(
database: AppDatabase
): FarmCycleRepository {
return FarmCycleRepository(database)
}

@Singleton
@Provides
fun providesDispatcher() = Dispatchers.Main as CoroutineDispatcher
Expand Down
Loading

0 comments on commit 9a316b0

Please sign in to comment.