forked from github/wulkanowy-mirror
Refactor attendance module (#161)
This commit is contained in:
parent
a1f64baca4
commit
357b2350cb
@ -68,12 +68,13 @@ play {
|
||||
uploadImages = true
|
||||
}
|
||||
|
||||
ext.supportVersion = "28.0.0-rc02"
|
||||
ext.supportVersion = "28.0.0"
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
implementation 'com.github.wulkanowy:api:ad57669'
|
||||
|
||||
implementation('com.github.wulkanowy:api:07201a4') {
|
||||
exclude module: "threetenbp"
|
||||
}
|
||||
implementation "com.android.support:support-v4:$supportVersion"
|
||||
implementation "com.android.support:design:$supportVersion"
|
||||
implementation "com.android.support:cardview-v7:$supportVersion"
|
||||
@ -116,6 +117,7 @@ dependencies {
|
||||
debugImplementation "com.amitshekhar.android:debug-db:1.0.4"
|
||||
|
||||
testImplementation "junit:junit:4.12"
|
||||
testImplementation "io.mockk:mockk:1.8.8"
|
||||
testImplementation "org.mockito:mockito-inline:2.21.0"
|
||||
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
|
@ -0,0 +1,52 @@
|
||||
package io.github.wulkanowy.data.repositories.local
|
||||
|
||||
import android.arch.persistence.room.Room
|
||||
import android.support.test.InstrumentationRegistry
|
||||
import android.support.test.runner.AndroidJUnit4
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.entities.Attendance
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.threeten.bp.LocalDate
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class AttendanceLocalTest {
|
||||
|
||||
private lateinit var attendanceLocal: AttendanceLocal
|
||||
|
||||
private lateinit var testDb: AppDatabase
|
||||
|
||||
@Before
|
||||
fun createDb() {
|
||||
testDb = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getContext(), AppDatabase::class.java).build()
|
||||
attendanceLocal = AttendanceLocal(testDb.attendanceDao())
|
||||
}
|
||||
|
||||
@After
|
||||
fun closeDb() {
|
||||
testDb.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndReadTest() {
|
||||
attendanceLocal.saveAttendance(listOf(
|
||||
Attendance(studentId = "1", diaryId = "2", date = LocalDate.of(2018, 9, 10)),
|
||||
Attendance(studentId = "1", diaryId = "2", date = LocalDate.of(2018, 9, 14)),
|
||||
Attendance(studentId = "1", diaryId = "2", date = LocalDate.of(2018, 9, 17)) // in next week
|
||||
))
|
||||
|
||||
val attendance = attendanceLocal
|
||||
.getAttendance(Semester(studentId = "1", diaryId = "2", semesterId = "3"),
|
||||
LocalDate.of(2018, 9, 10),
|
||||
LocalDate.of(2018, 9, 14)
|
||||
)
|
||||
.blockingGet()
|
||||
assertEquals(2, attendance.size)
|
||||
assertEquals(attendance[0].date, LocalDate.of(2018, 9, 10))
|
||||
assertEquals(attendance[1].date, LocalDate.of(2018, 9, 14))
|
||||
}
|
||||
}
|
@ -11,7 +11,6 @@ import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.threeten.bp.LocalDate
|
||||
import java.sql.Date
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@ -35,16 +34,19 @@ class ExamLocalTest {
|
||||
@Test
|
||||
fun saveAndReadTest() {
|
||||
examLocal.saveExams(listOf(
|
||||
Exam(studentId = "1", diaryId = "2", date = Date.valueOf("2018-09-10")),
|
||||
Exam(studentId = "1", diaryId = "2", date = Date.valueOf("2018-09-14")),
|
||||
Exam(studentId = "1", diaryId = "2", date = Date.valueOf("2018-09-17")) // in next week
|
||||
Exam(studentId = "1", diaryId = "2", date = LocalDate.of(2018, 9, 10)),
|
||||
Exam(studentId = "1", diaryId = "2", date = LocalDate.of(2018, 9, 14)),
|
||||
Exam(studentId = "1", diaryId = "2", date = LocalDate.of(2018, 9, 17)) // in next week
|
||||
))
|
||||
|
||||
val exams = examLocal
|
||||
.getExams(Semester(studentId = "1", diaryId = "2", semesterId = "3"), LocalDate.of(2018, 9, 10))
|
||||
.getExams(Semester(studentId = "1", diaryId = "2", semesterId = "3"),
|
||||
LocalDate.of(2018, 9, 10),
|
||||
LocalDate.of(2018, 9, 14)
|
||||
)
|
||||
.blockingGet()
|
||||
assertEquals(2, exams.size)
|
||||
assertEquals(exams[0].date, Date.valueOf("2018-09-10"))
|
||||
assertEquals(exams[1].date, Date.valueOf("2018-09-14"))
|
||||
assertEquals(exams[0].date, LocalDate.of(2018, 9, 10))
|
||||
assertEquals(exams[1].date, LocalDate.of(2018, 9, 14))
|
||||
}
|
||||
}
|
||||
|
@ -52,4 +52,8 @@ internal class RepositoryModule {
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideExamDao(database: AppDatabase) = database.examsDao()
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideAttendanceDao(database: AppDatabase) = database.attendanceDao()
|
||||
}
|
||||
|
@ -3,9 +3,11 @@ package io.github.wulkanowy.data.db
|
||||
import android.arch.persistence.room.Database
|
||||
import android.arch.persistence.room.RoomDatabase
|
||||
import android.arch.persistence.room.TypeConverters
|
||||
import io.github.wulkanowy.data.db.dao.AttendanceDao
|
||||
import io.github.wulkanowy.data.db.dao.ExamDao
|
||||
import io.github.wulkanowy.data.db.dao.SemesterDao
|
||||
import io.github.wulkanowy.data.db.dao.StudentDao
|
||||
import io.github.wulkanowy.data.db.entities.Attendance
|
||||
import io.github.wulkanowy.data.db.entities.Exam
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
@ -16,7 +18,8 @@ import javax.inject.Singleton
|
||||
entities = [
|
||||
Student::class,
|
||||
Semester::class,
|
||||
Exam::class
|
||||
Exam::class,
|
||||
Attendance::class
|
||||
],
|
||||
version = 1,
|
||||
exportSchema = false
|
||||
@ -29,4 +32,6 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun semesterDao(): SemesterDao
|
||||
|
||||
abstract fun examsDao(): ExamDao
|
||||
|
||||
abstract fun attendanceDao(): AttendanceDao
|
||||
}
|
||||
|
@ -1,14 +1,18 @@
|
||||
package io.github.wulkanowy.data.db
|
||||
|
||||
import android.arch.persistence.room.TypeConverter
|
||||
import org.threeten.bp.*
|
||||
import java.util.*
|
||||
|
||||
class Converters {
|
||||
|
||||
@TypeConverter
|
||||
fun fromTimestamp(value: Long?): Date? = value?.run { Date(value) }
|
||||
|
||||
fun fromTimestamp(value: Long?): LocalDate? = value?.run {
|
||||
DateTimeUtils.toInstant(Date(value)).atZone(ZoneOffset.UTC).toLocalDate()
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun dateToTimestamp(date: Date?): Long? = date?.time
|
||||
fun dateToTimestamp(date: LocalDate?): Long? {
|
||||
return date?.atStartOfDay()?.toInstant(ZoneOffset.UTC)?.toEpochMilli()
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
package io.github.wulkanowy.data.db.dao
|
||||
|
||||
import android.arch.persistence.room.Dao
|
||||
import android.arch.persistence.room.Delete
|
||||
import android.arch.persistence.room.Insert
|
||||
import android.arch.persistence.room.Query
|
||||
import io.github.wulkanowy.data.db.entities.Attendance
|
||||
import io.reactivex.Maybe
|
||||
import org.threeten.bp.LocalDate
|
||||
|
||||
@Dao
|
||||
interface AttendanceDao {
|
||||
|
||||
@Insert
|
||||
fun insertAll(exams: List<Attendance>): List<Long>
|
||||
|
||||
@Delete
|
||||
fun deleteAll(exams: List<Attendance>)
|
||||
|
||||
@Query("SELECT * FROM Attendance WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
|
||||
fun getExams(diaryId: String, studentId: String, from: LocalDate, end: LocalDate): Maybe<List<Attendance>>
|
||||
}
|
@ -6,7 +6,7 @@ import android.arch.persistence.room.Insert
|
||||
import android.arch.persistence.room.Query
|
||||
import io.github.wulkanowy.data.db.entities.Exam
|
||||
import io.reactivex.Maybe
|
||||
import java.util.*
|
||||
import org.threeten.bp.LocalDate
|
||||
|
||||
@Dao
|
||||
interface ExamDao {
|
||||
@ -18,5 +18,5 @@ interface ExamDao {
|
||||
fun deleteAll(exams: List<Exam>)
|
||||
|
||||
@Query("SELECT * FROM Exams WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
|
||||
fun getExams(diaryId: String, studentId: String, from: Date, end: Date): Maybe<List<Exam>>
|
||||
fun getExams(diaryId: String, studentId: String, from: LocalDate, end: LocalDate): Maybe<List<Exam>>
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
package io.github.wulkanowy.data.db.entities
|
||||
|
||||
import android.arch.persistence.room.ColumnInfo
|
||||
import android.arch.persistence.room.Entity
|
||||
import android.arch.persistence.room.PrimaryKey
|
||||
import org.threeten.bp.LocalDate
|
||||
import java.io.Serializable
|
||||
|
||||
@Entity(tableName = "Attendance")
|
||||
data class Attendance(
|
||||
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long = 0,
|
||||
|
||||
@ColumnInfo(name = "student_id")
|
||||
var studentId: String = "",
|
||||
|
||||
@ColumnInfo(name = "diary_id")
|
||||
var diaryId: String = "",
|
||||
|
||||
var date: LocalDate,
|
||||
|
||||
var number: Int = 0,
|
||||
|
||||
var subject: String = "",
|
||||
|
||||
var name: String = "",
|
||||
|
||||
var presence: Boolean = false,
|
||||
|
||||
var absence: Boolean = false,
|
||||
|
||||
var exemption: Boolean = false,
|
||||
|
||||
var lateness: Boolean = false,
|
||||
|
||||
var excused: Boolean = false,
|
||||
|
||||
var deleted: Boolean = false
|
||||
) : Serializable
|
@ -3,8 +3,8 @@ package io.github.wulkanowy.data.db.entities
|
||||
import android.arch.persistence.room.ColumnInfo
|
||||
import android.arch.persistence.room.Entity
|
||||
import android.arch.persistence.room.PrimaryKey
|
||||
import org.threeten.bp.LocalDate
|
||||
import java.io.Serializable
|
||||
import java.util.*
|
||||
|
||||
@Entity(tableName = "Exams")
|
||||
data class Exam(
|
||||
@ -18,10 +18,10 @@ data class Exam(
|
||||
@ColumnInfo(name = "diary_id")
|
||||
var diaryId: String = "",
|
||||
|
||||
var date: Date,
|
||||
var date: LocalDate,
|
||||
|
||||
@ColumnInfo(name = "entry_date")
|
||||
var entryDate: Date = Date(),
|
||||
var entryDate: LocalDate = LocalDate.now(),
|
||||
|
||||
var subject: String = "",
|
||||
|
||||
|
@ -0,0 +1,43 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||
import io.github.wulkanowy.data.db.entities.Attendance
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.repositories.local.AttendanceLocal
|
||||
import io.github.wulkanowy.data.repositories.remote.AttendanceRemote
|
||||
import io.github.wulkanowy.utils.extension.getWeekFirstDayAlwaysCurrent
|
||||
import io.reactivex.Single
|
||||
import org.threeten.bp.DayOfWeek
|
||||
import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.temporal.TemporalAdjusters
|
||||
import java.net.UnknownHostException
|
||||
import javax.inject.Inject
|
||||
|
||||
class AttendanceRepository @Inject constructor(
|
||||
private val settings: InternetObservingSettings,
|
||||
private val local: AttendanceLocal,
|
||||
private val remote: AttendanceRemote
|
||||
) {
|
||||
|
||||
fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate, forceRefresh: Boolean = false): Single<List<Attendance>> {
|
||||
val start = startDate.getWeekFirstDayAlwaysCurrent()
|
||||
val end = endDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY))
|
||||
|
||||
return local.getAttendance(semester, start, end).filter { !forceRefresh }
|
||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
|
||||
if (it) remote.getAttendance(semester, start, end)
|
||||
else Single.error(UnknownHostException())
|
||||
}.flatMap { newLessons ->
|
||||
local.getAttendance(semester, start, end).toSingle(emptyList()).map { grades ->
|
||||
local.deleteAttendance(grades - newLessons)
|
||||
local.saveAttendance(newLessons - grades)
|
||||
newLessons
|
||||
}
|
||||
}).map { list ->
|
||||
list.asSequence().filter {
|
||||
it.date in startDate..endDate
|
||||
}.toList()
|
||||
}
|
||||
}
|
||||
}
|
@ -6,8 +6,12 @@ import io.github.wulkanowy.data.db.entities.Exam
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.repositories.local.ExamLocal
|
||||
import io.github.wulkanowy.data.repositories.remote.ExamRemote
|
||||
import io.github.wulkanowy.utils.extension.getWeekFirstDayAlwaysCurrent
|
||||
import io.github.wulkanowy.utils.extension.toDate
|
||||
import io.reactivex.Single
|
||||
import org.threeten.bp.DayOfWeek
|
||||
import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.temporal.TemporalAdjusters
|
||||
import java.net.UnknownHostException
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@ -19,21 +23,24 @@ class ExamRepository @Inject constructor(
|
||||
private val remote: ExamRemote
|
||||
) {
|
||||
|
||||
fun getExams(semester: Semester, date: LocalDate, forceRefresh: Boolean = false): Single<List<Exam>> {
|
||||
return local.getExams(semester, date).filter { !forceRefresh }
|
||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||
.flatMap {
|
||||
if (it) remote.getExams(semester, date)
|
||||
else Single.error(UnknownHostException())
|
||||
}.flatMap { newExams ->
|
||||
local.getExams(semester, date).toSingle(emptyList())
|
||||
.map {
|
||||
local.deleteExams(it - newExams)
|
||||
local.saveExams(newExams - it)
|
||||
fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate, forceRefresh: Boolean = false): Single<List<Exam>> {
|
||||
val start = startDate.getWeekFirstDayAlwaysCurrent()
|
||||
val end = endDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY))
|
||||
|
||||
newExams
|
||||
}
|
||||
}
|
||||
)
|
||||
return local.getExams(semester, start, end).filter { !forceRefresh }
|
||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
|
||||
if (it) remote.getExams(semester, start, end)
|
||||
else Single.error(UnknownHostException())
|
||||
}.flatMap { newExams ->
|
||||
local.getExams(semester, start, end).toSingle(emptyList()).map { grades ->
|
||||
local.deleteExams(grades - newExams)
|
||||
local.saveExams(newExams - grades)
|
||||
newExams
|
||||
}
|
||||
}).map { list ->
|
||||
list.asSequence().filter {
|
||||
it.date in startDate..endDate
|
||||
}.toList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package io.github.wulkanowy.data.repositories.local
|
||||
|
||||
import io.github.wulkanowy.data.db.dao.AttendanceDao
|
||||
import io.github.wulkanowy.data.db.entities.Attendance
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.reactivex.Maybe
|
||||
import org.threeten.bp.LocalDate
|
||||
import javax.inject.Inject
|
||||
|
||||
class AttendanceLocal @Inject constructor(private val attendanceDb: AttendanceDao) {
|
||||
|
||||
fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe<List<Attendance>> {
|
||||
return attendanceDb.getExams(semester.diaryId, semester.studentId, startDate, endDate)
|
||||
.filter { !it.isEmpty() }
|
||||
}
|
||||
|
||||
fun saveAttendance(attendance: List<Attendance>) {
|
||||
attendanceDb.insertAll(attendance)
|
||||
}
|
||||
|
||||
fun deleteAttendance(attendance: List<Attendance>) {
|
||||
attendanceDb.deleteAll(attendance)
|
||||
}
|
||||
}
|
@ -12,10 +12,9 @@ import javax.inject.Inject
|
||||
|
||||
class ExamLocal @Inject constructor(private val examDb: ExamDao) {
|
||||
|
||||
fun getExams(semester: Semester, startDate: LocalDate): Maybe<List<Exam>> {
|
||||
return examDb.getExams(semester.diaryId, semester.studentId, startDate.toDate(),
|
||||
startDate.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)).toDate()
|
||||
).filter { !it.isEmpty() }
|
||||
fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe<List<Exam>> {
|
||||
return examDb.getExams(semester.diaryId, semester.studentId, startDate, endDate)
|
||||
.filter { !it.isEmpty() }
|
||||
}
|
||||
|
||||
fun saveExams(exams: List<Exam>) {
|
||||
|
@ -0,0 +1,38 @@
|
||||
package io.github.wulkanowy.data.repositories.remote
|
||||
|
||||
import io.github.wulkanowy.api.Api
|
||||
import io.github.wulkanowy.data.db.entities.Attendance
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.utils.extension.toLocalDate
|
||||
import io.reactivex.Single
|
||||
import org.threeten.bp.LocalDate
|
||||
import javax.inject.Inject
|
||||
|
||||
class AttendanceRemote @Inject constructor(private val api: Api) {
|
||||
|
||||
fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Attendance>> {
|
||||
return Single.just(api.run {
|
||||
if (diaryId != semester.diaryId) {
|
||||
diaryId = semester.diaryId
|
||||
notifyDataChanged()
|
||||
}
|
||||
}).flatMap { api.getAttendance(startDate, endDate) }.map { attendance ->
|
||||
attendance.map {
|
||||
Attendance(
|
||||
studentId = semester.studentId,
|
||||
diaryId = semester.diaryId,
|
||||
date = it.date.toLocalDate(),
|
||||
number = it.number,
|
||||
subject = it.subject,
|
||||
name = it.name,
|
||||
presence = it.presence,
|
||||
absence = it.absence,
|
||||
exemption = it.exemption,
|
||||
lateness = it.lateness,
|
||||
excused = it.excused,
|
||||
deleted = it.deleted
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -3,35 +3,34 @@ package io.github.wulkanowy.data.repositories.remote
|
||||
import io.github.wulkanowy.api.Api
|
||||
import io.github.wulkanowy.data.db.entities.Exam
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.utils.extension.toDate
|
||||
import io.github.wulkanowy.utils.extension.toLocalDate
|
||||
import io.reactivex.Single
|
||||
import org.threeten.bp.LocalDate
|
||||
import javax.inject.Inject
|
||||
|
||||
class ExamRemote @Inject constructor(private val api: Api) {
|
||||
|
||||
fun getExams(semester: Semester, startDate: LocalDate): Single<List<Exam>> {
|
||||
fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Exam>> {
|
||||
return Single.just(api.run {
|
||||
if (diaryId != semester.diaryId) {
|
||||
diaryId = semester.diaryId
|
||||
notifyDataChanged()
|
||||
}
|
||||
}).flatMap { api.getExams(startDate.toDate()) }
|
||||
.map { exams ->
|
||||
exams.map {
|
||||
Exam(
|
||||
studentId = semester.studentId,
|
||||
diaryId = semester.diaryId,
|
||||
date = it.date,
|
||||
entryDate = it.entryDate,
|
||||
subject = it.subject,
|
||||
group = it.group,
|
||||
type = it.type,
|
||||
description = it.description,
|
||||
teacher = it.teacher,
|
||||
teacherSymbol = it.teacherSymbol
|
||||
)
|
||||
}
|
||||
}
|
||||
}).flatMap { api.getExams(startDate, endDate) }.map { exams ->
|
||||
exams.map {
|
||||
Exam(
|
||||
studentId = semester.studentId,
|
||||
diaryId = semester.diaryId,
|
||||
date = it.date.toLocalDate(),
|
||||
entryDate = it.entryDate.toLocalDate(),
|
||||
subject = it.subject,
|
||||
group = it.group,
|
||||
type = it.type,
|
||||
description = it.description,
|
||||
teacher = it.teacher,
|
||||
teacherSymbol = it.teacherSymbol
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,49 @@
|
||||
package io.github.wulkanowy.ui.main.attendance
|
||||
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.DialogFragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Attendance
|
||||
import io.github.wulkanowy.utils.extension.toFormat
|
||||
import kotlinx.android.synthetic.main.dialog_attendance.*
|
||||
|
||||
class AttendanceDialog : DialogFragment() {
|
||||
|
||||
private lateinit var attendance: Attendance
|
||||
|
||||
companion object {
|
||||
private const val ARGUMENT_KEY = "Item"
|
||||
|
||||
fun newInstance(exam: Attendance): AttendanceDialog {
|
||||
return AttendanceDialog().apply {
|
||||
arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setStyle(DialogFragment.STYLE_NORMAL, R.style.DialogFragmentTheme)
|
||||
arguments?.run {
|
||||
attendance = getSerializable(ARGUMENT_KEY) as Attendance
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
dialog.setTitle(getString(R.string.all_details))
|
||||
return inflater.inflate(R.layout.dialog_attendance, container, false)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
attendanceDialogSubject.text = attendance.subject
|
||||
attendanceDialogDescription.text = attendance.name
|
||||
attendanceDialogDate.text = attendance.date.toFormat()
|
||||
attendanceDialogNumber.text = attendance.number.toString()
|
||||
attendanceDialogClose.setOnClickListener { dismiss() }
|
||||
}
|
||||
}
|
@ -4,17 +4,111 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Attendance
|
||||
import io.github.wulkanowy.ui.base.BaseFragment
|
||||
import io.github.wulkanowy.utils.extension.setOnItemClickListener
|
||||
import kotlinx.android.synthetic.main.fragment_attendance.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class AttendanceFragment : BaseFragment() {
|
||||
class AttendanceFragment : BaseFragment(), AttendanceView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: AttendancePresenter
|
||||
|
||||
@Inject
|
||||
lateinit var attendanceAdapter: FlexibleAdapter<AbstractFlexibleItem<*>>
|
||||
|
||||
companion object {
|
||||
private const val SAVED_DATE_KEY = "CURRENT_DATE"
|
||||
fun newInstance() = AttendanceFragment()
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_attendance, container, false)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
presenter.run {
|
||||
attachView(this@AttendanceFragment)
|
||||
loadData(date = savedInstanceState?.getLong(SAVED_DATE_KEY))
|
||||
}
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
attendanceAdapter.run {
|
||||
isAutoCollapseOnExpand = true
|
||||
isAutoScrollOnExpand = true
|
||||
setOnItemClickListener { presenter.onAttendanceItemSelected(getItem(it))}
|
||||
}
|
||||
attendanceRecycler.run {
|
||||
layoutManager = SmoothScrollLinearLayoutManager(context)
|
||||
adapter = attendanceAdapter
|
||||
}
|
||||
attendanceSwipe.setOnRefreshListener { presenter.loadData(date = null, forceRefresh = true) }
|
||||
attendancePreviousButton.setOnClickListener { presenter.loadAttendanceForPreviousDay() }
|
||||
attendanceNextButton.setOnClickListener { presenter.loadAttendanceForNextDay() }
|
||||
}
|
||||
|
||||
override fun updateData(data: List<AttendanceItem>) {
|
||||
attendanceAdapter.updateDataSet(data, true)
|
||||
}
|
||||
|
||||
override fun clearData() {
|
||||
attendanceAdapter.clear()
|
||||
}
|
||||
|
||||
override fun updateNavigationDay(date: String) {
|
||||
attendanceNavDate.text = date
|
||||
}
|
||||
|
||||
override fun isViewEmpty() = attendanceAdapter.isEmpty
|
||||
|
||||
override fun showEmpty(show: Boolean) {
|
||||
attendanceEmpty.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
override fun showProgress(show: Boolean) {
|
||||
attendanceProgress.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
override fun showContent(show: Boolean) {
|
||||
attendanceRecycler.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
override fun showRefresh(show: Boolean) {
|
||||
attendanceSwipe.isRefreshing = show
|
||||
}
|
||||
|
||||
override fun showPreButton(show: Boolean) {
|
||||
attendancePreviousButton.visibility = if (show) View.VISIBLE else View.INVISIBLE
|
||||
}
|
||||
|
||||
override fun showNextButton(show: Boolean) {
|
||||
attendanceNextButton.visibility = if (show) View.VISIBLE else View.INVISIBLE
|
||||
}
|
||||
|
||||
override fun showAttendanceDialog(lesson: Attendance) {
|
||||
AttendanceDialog.newInstance(lesson).show(fragmentManager, lesson.toString())
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay())
|
||||
}
|
||||
|
||||
override fun onViewStateRestored(savedInstanceState: Bundle?) {
|
||||
super.onViewStateRestored(savedInstanceState)
|
||||
presenter.loadData(date = savedInstanceState?.getLong(SAVED_DATE_KEY))
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
presenter.detachView()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,55 @@
|
||||
package io.github.wulkanowy.ui.main.attendance
|
||||
|
||||
import android.view.View
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Attendance
|
||||
import kotlinx.android.extensions.LayoutContainer
|
||||
import kotlinx.android.synthetic.main.item_attendance.*
|
||||
|
||||
class AttendanceItem : AbstractFlexibleItem<AttendanceItem.ViewHolder>() {
|
||||
|
||||
lateinit var attendance: Attendance
|
||||
|
||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>): ViewHolder {
|
||||
return ViewHolder(view, adapter)
|
||||
}
|
||||
|
||||
override fun getLayoutRes(): Int = R.layout.item_attendance
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as AttendanceItem
|
||||
|
||||
if (attendance != other.attendance) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return attendance.hashCode()
|
||||
}
|
||||
|
||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, holder: ViewHolder,
|
||||
position: Int, payloads: MutableList<Any>?) {
|
||||
holder.bind(attendance)
|
||||
}
|
||||
|
||||
class ViewHolder(val view: View, adapter: FlexibleAdapter<*>) : FlexibleViewHolder(view, adapter),
|
||||
LayoutContainer {
|
||||
|
||||
override val containerView: View
|
||||
get() = contentView
|
||||
|
||||
fun bind(lesson: Attendance) {
|
||||
attendanceItemNumber.text = lesson.number.toString()
|
||||
attendanceItemSubject.text = lesson.subject
|
||||
attendanceItemDescription.text = lesson.name
|
||||
attendanceItemAlert.visibility = if (lesson.absence && !lesson.excused) View.VISIBLE else View.INVISIBLE
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
package io.github.wulkanowy.ui.main.attendance
|
||||
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import io.github.wulkanowy.data.ErrorHandler
|
||||
import io.github.wulkanowy.data.db.entities.Attendance
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.repositories.AttendanceRepository
|
||||
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.utils.extension.*
|
||||
import io.github.wulkanowy.utils.schedulers.SchedulersManager
|
||||
import org.threeten.bp.LocalDate
|
||||
import javax.inject.Inject
|
||||
|
||||
class AttendancePresenter @Inject constructor(
|
||||
private val errorHandler: ErrorHandler,
|
||||
private val schedulers: SchedulersManager,
|
||||
private val attendanceRepository: AttendanceRepository,
|
||||
private val sessionRepository: SessionRepository
|
||||
) : BasePresenter<AttendanceView>(errorHandler) {
|
||||
|
||||
var currentDate: LocalDate = LocalDate.now().getNearSchoolDayPrevOnWeekEnd()
|
||||
private set
|
||||
|
||||
override fun attachView(view: AttendanceView) {
|
||||
super.attachView(view)
|
||||
view.initView()
|
||||
}
|
||||
|
||||
fun loadAttendanceForPreviousDay() = loadData(currentDate.getPreviousWorkDay().toEpochDay())
|
||||
|
||||
fun loadAttendanceForNextDay() = loadData(currentDate.getNextWorkDay().toEpochDay())
|
||||
|
||||
fun loadData(date: Long?, forceRefresh: Boolean = false) {
|
||||
this.currentDate = LocalDate.ofEpochDay(date ?: currentDate.getNearSchoolDayPrevOnWeekEnd().toEpochDay())
|
||||
if (currentDate.isHolidays()) return
|
||||
|
||||
disposable.clear()
|
||||
disposable.add(sessionRepository.getSemesters()
|
||||
.map { selectSemester(it, -1) }
|
||||
.flatMap { attendanceRepository.getAttendance(it, currentDate, currentDate, forceRefresh) }
|
||||
.map { createTimetableItems(it) }
|
||||
.subscribeOn(schedulers.backgroundThread())
|
||||
.observeOn(schedulers.mainThread())
|
||||
.doOnSubscribe {
|
||||
view?.run {
|
||||
showRefresh(forceRefresh)
|
||||
showProgress(!forceRefresh)
|
||||
if (!forceRefresh) {
|
||||
showEmpty(false)
|
||||
clearData()
|
||||
}
|
||||
showPreButton(!currentDate.minusDays(1).isHolidays())
|
||||
showNextButton(!currentDate.plusDays(1).isHolidays())
|
||||
updateNavigationDay(currentDate.toFormat("EEEE \n dd.MM.YYYY").capitalize())
|
||||
}
|
||||
}
|
||||
.doFinally {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
}
|
||||
}
|
||||
.subscribe({
|
||||
view?.run {
|
||||
showEmpty(it.isEmpty())
|
||||
showContent(it.isNotEmpty())
|
||||
updateData(it)
|
||||
}
|
||||
}) {
|
||||
view?.run { showEmpty(isViewEmpty()) }
|
||||
errorHandler.proceed(it)
|
||||
})
|
||||
}
|
||||
|
||||
private fun createTimetableItems(items: List<Attendance>): List<AttendanceItem> {
|
||||
return items.map {
|
||||
AttendanceItem().apply { attendance = it }
|
||||
}
|
||||
}
|
||||
|
||||
fun onAttendanceItemSelected(item: AbstractFlexibleItem<*>?) {
|
||||
if (item is AttendanceItem) view?.showAttendanceDialog(item.attendance)
|
||||
}
|
||||
|
||||
private fun selectSemester(semesters: List<Semester>, index: Int): Semester {
|
||||
return semesters.single { it.current }.let { currentSemester ->
|
||||
if (index == -1) currentSemester
|
||||
else semesters.single { semester ->
|
||||
semester.run {
|
||||
semesterName - 1 == index && diaryId == currentSemester.diaryId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package io.github.wulkanowy.ui.main.attendance
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Attendance
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface AttendanceView : BaseView {
|
||||
|
||||
fun initView()
|
||||
|
||||
fun updateData(data: List<AttendanceItem>)
|
||||
|
||||
fun clearData()
|
||||
|
||||
fun updateNavigationDay(date: String)
|
||||
|
||||
fun isViewEmpty(): Boolean
|
||||
|
||||
fun showEmpty(show: Boolean)
|
||||
|
||||
fun showProgress(show: Boolean)
|
||||
|
||||
fun showContent(show: Boolean)
|
||||
|
||||
fun showRefresh(show: Boolean)
|
||||
|
||||
fun showPreButton(show: Boolean)
|
||||
|
||||
fun showNextButton(show: Boolean)
|
||||
|
||||
fun showAttendanceDialog(lesson: Attendance)
|
||||
}
|
@ -10,12 +10,11 @@ import io.github.wulkanowy.utils.extension.getWeekDayName
|
||||
import io.github.wulkanowy.utils.extension.toFormat
|
||||
import kotlinx.android.extensions.LayoutContainer
|
||||
import kotlinx.android.synthetic.main.header_exam.*
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
import java.util.*
|
||||
import org.threeten.bp.LocalDate
|
||||
|
||||
class ExamHeader : AbstractHeaderItem<ExamHeader.ViewHolder>() {
|
||||
|
||||
lateinit var date: Date
|
||||
lateinit var date: LocalDate
|
||||
|
||||
override fun createViewHolder(view: View?, adapter: FlexibleAdapter<IFlexible<*>>?): ViewHolder {
|
||||
return ViewHolder(view, adapter)
|
||||
@ -41,7 +40,7 @@ class ExamHeader : AbstractHeaderItem<ExamHeader.ViewHolder>() {
|
||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>?, holder: ViewHolder,
|
||||
position: Int, payloads: MutableList<Any>?) {
|
||||
holder.run {
|
||||
examHeaderDay.text = StringUtils.capitalize(date.getWeekDayName())
|
||||
examHeaderDay.text = date.getWeekDayName().capitalize()
|
||||
examHeaderDate.text = date.toFormat()
|
||||
}
|
||||
}
|
||||
|
@ -7,12 +7,11 @@ import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.repositories.ExamRepository
|
||||
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.utils.extension.getWeekFirstDayNextOnWeekEnd
|
||||
import io.github.wulkanowy.utils.extension.isHolidays
|
||||
import io.github.wulkanowy.utils.extension.toFormat
|
||||
import io.github.wulkanowy.utils.getNearMonday
|
||||
import io.github.wulkanowy.utils.schedulers.SchedulersManager
|
||||
import org.threeten.bp.LocalDate
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class ExamPresenter @Inject constructor(
|
||||
@ -22,7 +21,7 @@ class ExamPresenter @Inject constructor(
|
||||
private val sessionRepository: SessionRepository
|
||||
) : BasePresenter<ExamView>(errorHandler) {
|
||||
|
||||
var currentDate: LocalDate = getNearMonday(LocalDate.now())
|
||||
var currentDate: LocalDate = LocalDate.now().getWeekFirstDayNextOnWeekEnd()
|
||||
private set
|
||||
|
||||
override fun attachView(view: ExamView) {
|
||||
@ -35,13 +34,13 @@ class ExamPresenter @Inject constructor(
|
||||
fun loadExamsForNextWeek() = loadData(currentDate.plusDays(7).toEpochDay())
|
||||
|
||||
fun loadData(date: Long?, forceRefresh: Boolean = false) {
|
||||
this.currentDate = LocalDate.ofEpochDay(date ?: getNearMonday(currentDate).toEpochDay())
|
||||
this.currentDate = LocalDate.ofEpochDay(date ?: currentDate.getWeekFirstDayNextOnWeekEnd().toEpochDay())
|
||||
if (currentDate.isHolidays()) return
|
||||
|
||||
disposable.clear()
|
||||
disposable.add(sessionRepository.getSemesters()
|
||||
.map { selectSemester(it, -1) }
|
||||
.flatMap { examRepository.getExams(it, currentDate, forceRefresh) }
|
||||
.flatMap { examRepository.getExams(it, currentDate, currentDate.plusDays(4), forceRefresh) }
|
||||
.map { it.groupBy { exam -> exam.date }.toSortedMap() }
|
||||
.map { createExamItems(it) }
|
||||
.subscribeOn(schedulers.backgroundThread())
|
||||
@ -72,7 +71,7 @@ class ExamPresenter @Inject constructor(
|
||||
.subscribe({ view?.updateData(it) }) { errorHandler.proceed(it) })
|
||||
}
|
||||
|
||||
private fun createExamItems(items: Map<Date, List<Exam>>): List<ExamItem> {
|
||||
private fun createExamItems(items: Map<LocalDate, List<Exam>>): List<ExamItem> {
|
||||
return items.flatMap {
|
||||
val header = ExamHeader().apply { date = it.key }
|
||||
it.value.reversed().map { item ->
|
||||
|
@ -1,104 +0,0 @@
|
||||
package io.github.wulkanowy.utils
|
||||
|
||||
import org.threeten.bp.DayOfWeek.*
|
||||
import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.Year
|
||||
import org.threeten.bp.format.DateTimeFormatter
|
||||
import org.threeten.bp.temporal.TemporalAdjuster
|
||||
import org.threeten.bp.temporal.TemporalAdjusters
|
||||
import java.util.*
|
||||
|
||||
private val formatter = DateTimeFormatter.ofPattern(DATE_PATTERN)
|
||||
|
||||
fun getParsedDate(dateString: String, dateFormat: String): LocalDate {
|
||||
return LocalDate.parse(dateString, DateTimeFormatter.ofPattern(dateFormat))
|
||||
}
|
||||
|
||||
fun getMondaysFromCurrentSchoolYear() = getMondaysFromCurrentSchoolYear(LocalDate.now())
|
||||
|
||||
fun getMondaysFromCurrentSchoolYear(date: LocalDate): List<String> {
|
||||
val startDate = getFirstSchoolDay(getSchoolYearForDate(date))
|
||||
?.with(TemporalAdjusters.previousOrSame(MONDAY))
|
||||
val endDate = getFirstSchoolDay(getSchoolYearForDate(date) + 1)
|
||||
?.with(TemporalAdjusters.previousOrSame(MONDAY))
|
||||
|
||||
val dateList = ArrayList<String>()
|
||||
var monday = startDate as LocalDate
|
||||
while (monday.isBefore(endDate)) {
|
||||
dateList.add(monday.format(formatter))
|
||||
monday = monday.plusWeeks(1)
|
||||
}
|
||||
|
||||
return dateList
|
||||
}
|
||||
|
||||
fun getSchoolYearForDate(date: LocalDate): Int {
|
||||
return if (date.monthValue <= 8) date.year - 1 else date.year
|
||||
}
|
||||
|
||||
fun getFirstDayOfCurrentWeek(): String = getFirstDayOfCurrentWeek(LocalDate.now())
|
||||
|
||||
fun getFirstDayOfCurrentWeek(date: LocalDate): String {
|
||||
return when (date.dayOfWeek) {
|
||||
SATURDAY -> date.plusDays(2)
|
||||
SUNDAY -> date.plusDays(1)
|
||||
else -> date.with(MONDAY)
|
||||
}.format(formatter)
|
||||
}
|
||||
|
||||
fun getTodayOrNextDayOrder(next: Boolean): Int = getTodayOrNextDayOrder(next, LocalDate.now())
|
||||
|
||||
fun getTodayOrNextDayOrder(next: Boolean, date: LocalDate): Int {
|
||||
val day = date.dayOfWeek
|
||||
return if (next) {
|
||||
if (day == SUNDAY) {
|
||||
0
|
||||
} else day.value
|
||||
} else day.value - 1
|
||||
}
|
||||
|
||||
fun getTodayOrNextDay(next: Boolean): String? = getTodayOrNextDay(next, LocalDate.now())
|
||||
|
||||
fun getTodayOrNextDay(next: Boolean, date: LocalDate): String? {
|
||||
return (if (next) {
|
||||
date.plusDays(1)
|
||||
} else date).format(formatter)
|
||||
}
|
||||
|
||||
fun isDateInWeek(firstWeekDay: LocalDate, date: LocalDate): Boolean {
|
||||
return date.isAfter(firstWeekDay.minusDays(1)) && date.isBefore(firstWeekDay.plusDays(5))
|
||||
}
|
||||
|
||||
fun getNearMonday(date: LocalDate): LocalDate {
|
||||
return when(date.dayOfWeek) {
|
||||
MONDAY -> date
|
||||
SATURDAY, SUNDAY -> date.with(TemporalAdjusters.next(MONDAY))
|
||||
else -> date.with(TemporalAdjusters.previous(MONDAY))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Dz.U. 2016 poz. 1335](http://prawo.sejm.gov.pl/isap.nsf/DocDetails.xsp?id=WDU20160001335)
|
||||
*/
|
||||
fun isHolidays(): Boolean = isHolidays(LocalDate.now())
|
||||
|
||||
fun isHolidays(day: LocalDate): Boolean {
|
||||
return day.isAfter(getLastSchoolDay(day.year)) && day.isBefore(getFirstSchoolDay(day.year))
|
||||
}
|
||||
|
||||
fun getFirstSchoolDay(year: Int): LocalDate {
|
||||
val firstSeptember = LocalDate.of(year, 9, 1)
|
||||
|
||||
return when (firstSeptember.dayOfWeek) {
|
||||
FRIDAY,
|
||||
SATURDAY,
|
||||
SUNDAY -> firstSeptember.with(TemporalAdjusters.firstInMonth(MONDAY))
|
||||
else -> firstSeptember
|
||||
}
|
||||
}
|
||||
|
||||
fun getLastSchoolDay(year: Int): LocalDate {
|
||||
return LocalDate
|
||||
.of(year, 6, 20)
|
||||
.with(TemporalAdjusters.next(FRIDAY))
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package io.github.wulkanowy.utils.extension
|
||||
|
||||
import io.github.wulkanowy.utils.DATE_PATTERN
|
||||
import io.github.wulkanowy.utils.isHolidays
|
||||
import org.threeten.bp.Instant
|
||||
import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.ZoneId
|
||||
import org.threeten.bp.format.DateTimeFormatter
|
||||
import java.util.*
|
||||
|
||||
private val formatter = DateTimeFormatter.ofPattern(DATE_PATTERN)
|
||||
|
||||
fun LocalDate.toDate(): Date = java.sql.Date.valueOf(this.format(formatter))
|
||||
|
||||
fun LocalDate.toFormat(format: String): String = this.format(DateTimeFormatter.ofPattern(format))
|
||||
|
||||
fun LocalDate.toFormat(): String = this.toFormat(DATE_PATTERN)
|
||||
|
||||
fun LocalDate.isHolidays(): Boolean = isHolidays(this)
|
||||
|
||||
fun Date.toLocalDate(): LocalDate = Instant.ofEpochMilli(this.time).atZone(ZoneId.systemDefault()).toLocalDate()
|
||||
|
||||
fun Date.getWeekDayName(): String = this.toLocalDate().format(DateTimeFormatter.ofPattern("EEEE", Locale.getDefault()))
|
||||
|
||||
fun Date.toFormat(): String = this.toLocalDate().toFormat()
|
@ -0,0 +1,79 @@
|
||||
package io.github.wulkanowy.utils.extension
|
||||
|
||||
import io.github.wulkanowy.utils.DATE_PATTERN
|
||||
import org.threeten.bp.*
|
||||
import org.threeten.bp.format.DateTimeFormatter
|
||||
import org.threeten.bp.temporal.TemporalAdjusters
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
fun Date.toLocalDate(): LocalDate = LocalDate.parse(SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(this))
|
||||
|
||||
fun String.toDate(format: String = "yyyy-MM-dd"): LocalDate = LocalDate.parse(this, DateTimeFormatter.ofPattern(format))
|
||||
|
||||
fun LocalDate.toFormat(format: String): String = this.format(DateTimeFormatter.ofPattern(format))
|
||||
|
||||
fun LocalDate.toFormat(): String = this.toFormat(DATE_PATTERN)
|
||||
|
||||
fun LocalDate.getNextWorkDay(): LocalDate {
|
||||
return when(this.dayOfWeek) {
|
||||
DayOfWeek.FRIDAY, DayOfWeek.SATURDAY, DayOfWeek.SUNDAY -> this.with(TemporalAdjusters.next(DayOfWeek.MONDAY))
|
||||
else -> this.plusDays(1)
|
||||
}
|
||||
}
|
||||
|
||||
fun LocalDate.getPreviousWorkDay(): LocalDate {
|
||||
return when(this.dayOfWeek) {
|
||||
DayOfWeek.SATURDAY, DayOfWeek.SUNDAY, DayOfWeek.MONDAY -> this.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY))
|
||||
else -> this.minusDays(1)
|
||||
}
|
||||
}
|
||||
|
||||
fun LocalDate.getNearSchoolDayPrevOnWeekEnd(): LocalDate {
|
||||
return when(this.dayOfWeek) {
|
||||
DayOfWeek.SATURDAY, DayOfWeek.SUNDAY -> this.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY))
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
||||
fun LocalDate.getNearSchoolDayNextOnWeekEnd(): LocalDate {
|
||||
return when(this.dayOfWeek) {
|
||||
DayOfWeek.SATURDAY, DayOfWeek.SUNDAY -> this.with(TemporalAdjusters.next(DayOfWeek.MONDAY))
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
||||
fun LocalDate.getWeekDayName(): String = this.format(DateTimeFormatter.ofPattern("EEEE", Locale.getDefault()))
|
||||
|
||||
fun LocalDate.getWeekFirstDayAlwaysCurrent(): LocalDate {
|
||||
return this.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY))
|
||||
}
|
||||
|
||||
fun LocalDate.getWeekFirstDayNextOnWeekEnd(): LocalDate {
|
||||
return when(this.dayOfWeek) {
|
||||
DayOfWeek.SATURDAY, DayOfWeek.SUNDAY -> this.with(TemporalAdjusters.next(DayOfWeek.MONDAY))
|
||||
else -> this.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Dz.U. 2016 poz. 1335](http://prawo.sejm.gov.pl/isap.nsf/DocDetails.xsp?id=WDU20160001335)
|
||||
*/
|
||||
fun LocalDate.isHolidays(): Boolean = this.isAfter(this.getLastSchoolDay()) && this.isBefore(this.getFirstSchoolDay())
|
||||
|
||||
fun LocalDate.getSchoolYear(): Int = if (this.monthValue <= 8) this.year - 1 else this.year
|
||||
|
||||
fun LocalDate.getFirstSchoolDay(): LocalDate {
|
||||
return LocalDate.of(this.year, 9, 1).run {
|
||||
when (dayOfWeek) {
|
||||
DayOfWeek.FRIDAY, DayOfWeek.SATURDAY, DayOfWeek.SUNDAY -> with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY))
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun LocalDate.getLastSchoolDay(): LocalDate {
|
||||
return LocalDate
|
||||
.of(this.year, 6, 20)
|
||||
.with(TemporalAdjusters.next(DayOfWeek.FRIDAY))
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
@ -8,146 +7,84 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="300dp"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/attendance_dialog_relative_layout"
|
||||
android:layout_width="match_parent"
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingRight="20dp"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingTop="10dp"
|
||||
tools:ignore="UselessParent">
|
||||
android:text="@string/all_subject"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="17sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendance_dialog_details"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_gravity="start"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="5"
|
||||
android:minHeight="60dp"
|
||||
android:minLines="2"
|
||||
android:paddingTop="10dp"
|
||||
android:text="@string/all_details"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="20sp" />
|
||||
<TextView
|
||||
android:id="@+id/attendanceDialogSubject"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:text="@string/all_no_data"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendance_dialog_subject"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@+id/attendance_dialog_details"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/all_subject"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="17sp" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/all_description"
|
||||
android:textSize="17sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendance_dialog_subject_value"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@+id/attendance_dialog_subject"
|
||||
android:layout_marginTop="3dp"
|
||||
android:text="@string/all_no_data"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="12sp" />
|
||||
<TextView
|
||||
android:id="@+id/attendanceDialogDescription"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:text="@string/all_no_data"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendance_dialog_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@+id/attendance_dialog_subject_value"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/all_description"
|
||||
android:textSize="17sp" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/all_date"
|
||||
android:textSize="17sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendance_dialog_description_value"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@+id/attendance_dialog_description"
|
||||
android:layout_marginTop="3dp"
|
||||
android:text="@string/all_no_data"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="12sp" />
|
||||
<TextView
|
||||
android:id="@+id/attendanceDialogDate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:text="@string/all_no_data"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendance_dialog_date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@+id/attendance_dialog_description_value"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/all_date"
|
||||
android:textSize="17sp" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/attendance_number"
|
||||
android:textSize="17sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendance_dialog_date_value"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@+id/attendance_dialog_date"
|
||||
android:layout_marginTop="3dp"
|
||||
android:text="@string/all_no_data"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="12sp" />
|
||||
<TextView
|
||||
android:id="@+id/attendanceDialogNumber"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:text="@string/all_no_data"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendance_dialog_number"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@+id/attendance_dialog_date_value"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/attendance_number"
|
||||
android:textSize="17sp" />
|
||||
<Button
|
||||
android:id="@+id/attendanceDialogClose"
|
||||
style="@style/Widget.AppCompat.Button.Borderless"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginTop="15dp"
|
||||
android:padding="0dp"
|
||||
android:text="@string/all_close"
|
||||
android:textAllCaps="true"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendance_dialog_number_value"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@+id/attendance_dialog_number"
|
||||
android:layout_marginTop="3dp"
|
||||
android:text="@string/all_no_data"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/attendance_dialog_close"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@+id/attendance_dialog_number_value"
|
||||
android:layout_marginTop="25dp"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:focusable="true"
|
||||
android:text="@string/all_close"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="?android:attr/android:textColorSecondary"
|
||||
android:textSize="15sp" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
@ -1,30 +1,99 @@
|
||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/attendanceContainer"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentBottom="true">
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="Attendance" />
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!--<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.design.widget.TabLayout
|
||||
android:id="@+id/attendance_fragment_tab_layout"
|
||||
android:layout_width="match_parent"
|
||||
<ProgressBar
|
||||
android:id="@+id/attendanceProgress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:tabMinWidth="125dp"
|
||||
app:tabMode="scrollable"/>
|
||||
android:layout_gravity="center"
|
||||
android:indeterminate="true" />
|
||||
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/attendance_fragment_viewpager"
|
||||
<android.support.v4.widget.SwipeRefreshLayout
|
||||
android:id="@+id/attendanceSwipe"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/attendanceRecycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</android.support.v4.widget.SwipeRefreshLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/attendanceEmpty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/attendance_fragment_tab_layout" />
|
||||
</RelativeLayout>-->
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="10dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="100dp"
|
||||
android:minWidth="100dp"
|
||||
app:srcCompat="@drawable/ic_menu_main_attendance_24dp"
|
||||
app:tint="?android:attr/textColorPrimary"
|
||||
tools:ignore="contentDescription" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/attendance_no_items"
|
||||
android:textSize="20sp" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/attendancePreviousButton"
|
||||
style="@style/Widget.AppCompat.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawablePadding="4dp"
|
||||
android:gravity="start|center"
|
||||
android:text="@string/prev"
|
||||
android:textAlignment="gravity" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendanceNavDate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/app_name" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/attendanceNextButton"
|
||||
style="@style/Widget.AppCompat.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:layout_weight="1"
|
||||
android:drawablePadding="4dp"
|
||||
android:gravity="end|center"
|
||||
android:text="@string/next"
|
||||
android:textAlignment="gravity" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -1,77 +1,65 @@
|
||||
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tool="http://schemas.android.com/tools"
|
||||
android:id="@+id/attendance_subItem_cardView"
|
||||
android:id="@+id/attendanceItemContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="7dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:foreground="?attr/selectableItemBackgroundBorderless"
|
||||
card_view:cardElevation="0dp">
|
||||
android:paddingStart="12dp"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingTop="7dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingRight="12dp"
|
||||
android:paddingBottom="7dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
<TextView
|
||||
android:id="@+id/attendanceItemNumber"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="center"
|
||||
android:maxLength="2"
|
||||
android:text="0"
|
||||
android:textSize="32sp"
|
||||
tool:ignore="all" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendanceItemSubject"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="7dp"
|
||||
android:layout_marginEnd="7dp"
|
||||
android:layout_marginLeft="7dp"
|
||||
android:layout_marginRight="7dp"
|
||||
android:layout_marginStart="7dp"
|
||||
android:layout_marginTop="7dp">
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginEnd="40dp"
|
||||
android:layout_marginRight="40dp"
|
||||
android:layout_toEndOf="@+id/attendanceItemNumber"
|
||||
android:layout_toRightOf="@+id/attendanceItemNumber"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/app_name"
|
||||
android:textSize="17sp"
|
||||
tool:ignore="all" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendance_subItem_number"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="center"
|
||||
android:maxLength="2"
|
||||
android:text="0"
|
||||
android:textSize="32sp"
|
||||
tool:ignore="all" />
|
||||
<TextView
|
||||
android:id="@+id/attendanceItemDescription"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignStart="@id/attendanceItemSubject"
|
||||
android:layout_alignLeft="@id/attendanceItemSubject"
|
||||
android:layout_alignBottom="@+id/attendanceItemNumber"
|
||||
android:maxLines="1"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="?android:attr/android:textColorSecondary"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendance_subItem_lesson"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginEnd="40dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="40dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_toEndOf="@+id/attendance_subItem_number"
|
||||
android:layout_toRightOf="@+id/attendance_subItem_number"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/app_name"
|
||||
android:textSize="17sp"
|
||||
tool:ignore="all" />
|
||||
<ImageView
|
||||
android:id="@+id/attendanceItemAlert"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginTop="10dp"
|
||||
app:srcCompat="@drawable/ic_all_note_24dp"
|
||||
tool:ignore="contentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendance_subItem_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/attendance_subItem_number"
|
||||
android:layout_alignLeft="@id/attendance_subItem_lesson"
|
||||
android:layout_alignStart="@id/attendance_subItem_lesson"
|
||||
android:maxLines="1"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="?android:attr/android:textColorSecondary"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/attendance_subItem_alert_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginTop="10dp"
|
||||
app:srcCompat="@drawable/ic_all_note_24dp"
|
||||
tool:ignore="contentDescription" />
|
||||
|
||||
</RelativeLayout>
|
||||
</android.support.v7.widget.CardView>
|
||||
</RelativeLayout>
|
||||
|
@ -0,0 +1,56 @@
|
||||
package io.github.wulkanowy.data.repositories.remote
|
||||
|
||||
import io.github.wulkanowy.api.Api
|
||||
import io.github.wulkanowy.api.attendance.Attendance
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.reactivex.Single
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.threeten.bp.LocalDate
|
||||
import java.sql.Date
|
||||
|
||||
class AttendanceRemoteTest {
|
||||
|
||||
@MockK
|
||||
private lateinit var mockApi: Api
|
||||
|
||||
@MockK
|
||||
private lateinit var semesterMock: Semester
|
||||
|
||||
@Before
|
||||
fun initApi() {
|
||||
MockKAnnotations.init(this)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getExamsTest() {
|
||||
every { mockApi.getAttendance(
|
||||
LocalDate.of(2018, 9, 10),
|
||||
LocalDate.of(2018, 9, 15)
|
||||
) } returns Single.just(listOf(
|
||||
getAttendance("2018-09-10"),
|
||||
getAttendance("2018-09-17")
|
||||
))
|
||||
|
||||
every { mockApi.diaryId } returns "1"
|
||||
every { semesterMock.studentId } returns "1"
|
||||
every { semesterMock.diaryId } returns "1"
|
||||
|
||||
val attendance = AttendanceRemote(mockApi).getAttendance(semesterMock,
|
||||
LocalDate.of(2018, 9, 10),
|
||||
LocalDate.of(2018, 9, 15)).blockingGet()
|
||||
assertEquals(2, attendance.size)
|
||||
}
|
||||
|
||||
private fun getAttendance(dateString: String): Attendance {
|
||||
return Attendance().apply {
|
||||
subject = "Fizyka"
|
||||
name = "Obecność"
|
||||
date = Date.valueOf(dateString)
|
||||
}
|
||||
}
|
||||
}
|
@ -3,41 +3,47 @@ package io.github.wulkanowy.data.repositories.remote
|
||||
import io.github.wulkanowy.api.Api
|
||||
import io.github.wulkanowy.api.exams.Exam
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.reactivex.Single
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.ArgumentMatchers.any
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.doReturn
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.threeten.bp.LocalDate
|
||||
import java.sql.Date
|
||||
|
||||
class ExamRemoteTest {
|
||||
|
||||
@Mock
|
||||
@MockK
|
||||
private lateinit var mockApi: Api
|
||||
|
||||
@Mock
|
||||
@MockK
|
||||
private lateinit var semesterMock: Semester
|
||||
|
||||
@Before
|
||||
fun initApi() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
MockKAnnotations.init(this)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getExamsTest() {
|
||||
doReturn(Single.just(listOf(
|
||||
every { mockApi.getExams(
|
||||
LocalDate.of(2018, 9, 10),
|
||||
LocalDate.of(2018, 9, 15)
|
||||
) } returns Single.just(listOf(
|
||||
getExam("2018-09-10"),
|
||||
getExam("2018-09-17")
|
||||
))).`when`(mockApi).getExams(any())
|
||||
))
|
||||
|
||||
doReturn("1").`when`(semesterMock).studentId
|
||||
doReturn("1").`when`(semesterMock).diaryId
|
||||
every { mockApi.diaryId } returns "1"
|
||||
every { semesterMock.studentId } returns "1"
|
||||
every { semesterMock.diaryId } returns "1"
|
||||
|
||||
val exams = ExamRemote(mockApi).getExams(semesterMock, LocalDate.of(2018, 9, 10)).blockingGet()
|
||||
val exams = ExamRemote(mockApi).getExams(semesterMock,
|
||||
LocalDate.of(2018, 9, 10),
|
||||
LocalDate.of(2018, 9, 15)
|
||||
).blockingGet()
|
||||
assertEquals(2, exams.size)
|
||||
}
|
||||
|
||||
|
@ -1,140 +0,0 @@
|
||||
package io.github.wulkanowy.utils
|
||||
|
||||
import org.junit.Test
|
||||
import org.threeten.bp.LocalDate
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
|
||||
class TimeUtilsTest {
|
||||
|
||||
@Test fun getParsedDateTest() {
|
||||
assertEquals(LocalDate.of(1970, 1, 1),
|
||||
getParsedDate("1970-01-01", "yyyy-MM-dd"))
|
||||
}
|
||||
|
||||
@Test fun getMondaysFromCurrentSchoolYearTest() {
|
||||
val y201718 = getMondaysFromCurrentSchoolYear(LocalDate.of(2018, 1, 1))
|
||||
assertEquals("2017-09-04", y201718.first())
|
||||
assertEquals("2018-08-27", y201718.last())
|
||||
|
||||
val y202122 = getMondaysFromCurrentSchoolYear(LocalDate.of(2022, 1, 1))
|
||||
assertEquals("2021-08-30", y202122.first())
|
||||
assertEquals("2022-08-22", y202122.last())
|
||||
|
||||
val y202223 = getMondaysFromCurrentSchoolYear(LocalDate.of(2023, 1, 1))
|
||||
assertEquals("2022-08-29", y202223.first())
|
||||
assertEquals("2023-08-28", y202223.last())
|
||||
}
|
||||
|
||||
@Test fun getCurrentSchoolYearTest() {
|
||||
assertEquals(2017, getSchoolYearForDate(LocalDate.of(2018, 8, 31)))
|
||||
assertEquals(2018, getSchoolYearForDate(LocalDate.of(2018, 9, 1)))
|
||||
}
|
||||
|
||||
@Test fun getFirstWeekDayTest() {
|
||||
assertEquals("2018-06-18", getFirstDayOfCurrentWeek(LocalDate.of(2018, 6, 21)))
|
||||
assertEquals("2018-06-18", getFirstDayOfCurrentWeek(LocalDate.of(2018, 6, 22)))
|
||||
assertEquals("2018-06-25", getFirstDayOfCurrentWeek(LocalDate.of(2018, 6, 23)))
|
||||
assertEquals("2018-06-25", getFirstDayOfCurrentWeek(LocalDate.of(2018, 6, 24)))
|
||||
assertEquals("2018-06-25", getFirstDayOfCurrentWeek(LocalDate.of(2018, 6, 25)))
|
||||
assertEquals("2018-06-25", getFirstDayOfCurrentWeek(LocalDate.of(2018, 6, 26)))
|
||||
}
|
||||
|
||||
@Test fun getTodayOrNextDayOrderTest() {
|
||||
assertEquals(0, getTodayOrNextDayOrder(true, LocalDate.of(2018, 6, 24))) // sunday
|
||||
assertEquals(6, getTodayOrNextDayOrder(false, LocalDate.of(2018, 6, 24)))
|
||||
assertEquals(1, getTodayOrNextDayOrder(true, LocalDate.of(2018, 6, 25)))
|
||||
assertEquals(0, getTodayOrNextDayOrder(false, LocalDate.of(2018, 6, 25)))
|
||||
}
|
||||
|
||||
@Test fun getTodayOrNextDayTest() {
|
||||
assertEquals("2018-06-26", getTodayOrNextDay(false, LocalDate.of(2018, 6, 26)))
|
||||
assertEquals("2018-06-27", getTodayOrNextDay(true, LocalDate.of(2018, 6, 26)))
|
||||
}
|
||||
|
||||
@Test fun isDateInWeekInsideTest() {
|
||||
assertTrue(isDateInWeek(
|
||||
LocalDate.of(2018, 5, 28),
|
||||
LocalDate.of(2018, 5, 31)
|
||||
))
|
||||
}
|
||||
|
||||
@Test fun isDateInWeekExtremesTest() {
|
||||
assertTrue(isDateInWeek(
|
||||
LocalDate.of(2018, 5, 28),
|
||||
LocalDate.of(2018, 5, 28)
|
||||
))
|
||||
|
||||
assertTrue(isDateInWeek(
|
||||
LocalDate.of(2018, 5, 28),
|
||||
LocalDate.of(2018, 6, 1)
|
||||
))
|
||||
}
|
||||
|
||||
@Test fun isDateInWeekOutOfTest() {
|
||||
assertFalse(isDateInWeek(
|
||||
LocalDate.of(2018, 5, 28),
|
||||
LocalDate.of(2018, 6, 2)
|
||||
))
|
||||
|
||||
assertFalse(isDateInWeek(
|
||||
LocalDate.of(2018, 5, 28),
|
||||
LocalDate.of(2018, 5, 27)
|
||||
))
|
||||
}
|
||||
|
||||
@Test fun isHolidaysInSchoolEndTest() {
|
||||
assertFalse(isHolidays(LocalDate.of(2017, 6, 23)))
|
||||
assertFalse(isHolidays(LocalDate.of(2018, 6, 22)))
|
||||
assertFalse(isHolidays(LocalDate.of(2019, 6, 21)))
|
||||
assertFalse(isHolidays(LocalDate.of(2020, 6, 26)))
|
||||
assertFalse(isHolidays(LocalDate.of(2021, 6, 25)))
|
||||
assertFalse(isHolidays(LocalDate.of(2022, 6, 24)))
|
||||
assertFalse(isHolidays(LocalDate.of(2023, 6, 23)))
|
||||
assertFalse(isHolidays(LocalDate.of(2024, 6, 21)))
|
||||
assertFalse(isHolidays(LocalDate.of(2025, 6, 27)))
|
||||
}
|
||||
|
||||
@Test fun isHolidaysInHolidaysStartTest() {
|
||||
assertTrue(isHolidays(LocalDate.of(2017, 6, 24)))
|
||||
assertTrue(isHolidays(LocalDate.of(2018, 6, 23)))
|
||||
assertTrue(isHolidays(LocalDate.of(2019, 6, 22)))
|
||||
assertTrue(isHolidays(LocalDate.of(2020, 6, 27)))
|
||||
assertTrue(isHolidays(LocalDate.of(2021, 6, 26)))
|
||||
assertTrue(isHolidays(LocalDate.of(2022, 6, 25)))
|
||||
assertTrue(isHolidays(LocalDate.of(2023, 6, 24)))
|
||||
assertTrue(isHolidays(LocalDate.of(2024, 6, 22)))
|
||||
assertTrue(isHolidays(LocalDate.of(2025, 6, 28)))
|
||||
}
|
||||
|
||||
@Test fun isHolidaysInHolidaysEndTest() {
|
||||
assertTrue(isHolidays(LocalDate.of(2017, 9, 1))) // friday
|
||||
assertTrue(isHolidays(LocalDate.of(2017, 9, 2))) // saturday
|
||||
assertTrue(isHolidays(LocalDate.of(2017, 9, 3))) // sunday
|
||||
assertTrue(isHolidays(LocalDate.of(2018, 9, 1))) // saturday
|
||||
assertTrue(isHolidays(LocalDate.of(2018, 9, 2))) // sunday
|
||||
assertTrue(isHolidays(LocalDate.of(2019, 9, 1))) // sunday
|
||||
assertTrue(isHolidays(LocalDate.of(2020, 8, 31))) // monday
|
||||
assertTrue(isHolidays(LocalDate.of(2021, 8, 31))) // tuesday
|
||||
assertTrue(isHolidays(LocalDate.of(2022, 8, 31))) // wednesday
|
||||
assertTrue(isHolidays(LocalDate.of(2023, 9, 1))) // friday
|
||||
assertTrue(isHolidays(LocalDate.of(2023, 9, 2))) // saturday
|
||||
assertTrue(isHolidays(LocalDate.of(2023, 9, 3))) // sunday
|
||||
assertTrue(isHolidays(LocalDate.of(2024, 9, 1))) // sunday
|
||||
assertTrue(isHolidays(LocalDate.of(2025, 8, 31))) // sunday
|
||||
}
|
||||
|
||||
@Test fun isHolidaysInSchoolStartTest() {
|
||||
assertFalse(isHolidays(LocalDate.of(2017, 9, 4))) // monday
|
||||
assertFalse(isHolidays(LocalDate.of(2018, 9, 3))) // monday
|
||||
assertFalse(isHolidays(LocalDate.of(2019, 9, 2))) // monday
|
||||
assertFalse(isHolidays(LocalDate.of(2020, 9, 1))) // tuesday
|
||||
assertFalse(isHolidays(LocalDate.of(2021, 9, 1))) // wednesday
|
||||
assertFalse(isHolidays(LocalDate.of(2022, 9, 1))) // thursday
|
||||
assertFalse(isHolidays(LocalDate.of(2023, 9, 4))) // monday
|
||||
assertFalse(isHolidays(LocalDate.of(2024, 9, 2))) // monday
|
||||
assertFalse(isHolidays(LocalDate.of(2025, 9, 1))) // monday
|
||||
}
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
package io.github.wulkanowy.utils.extension
|
||||
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Test
|
||||
import org.threeten.bp.LocalDate
|
||||
import java.util.*
|
||||
|
||||
class TimeExtensionTest {
|
||||
|
||||
@Test
|
||||
fun toDate() {
|
||||
assertEquals(LocalDate.of(1970, 1, 1), "1970-01-01".toDate("yyyy-MM-dd"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toFormat() {
|
||||
assertEquals("2018-10-01", LocalDate.of(2018, 10, 1).toFormat())
|
||||
assertEquals("2018-10.01", LocalDate.of(2018, 10, 1).toFormat("yyyy-MM.dd"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getWeekFirstDayAlwaysCurrent() {
|
||||
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 2).getWeekFirstDayAlwaysCurrent())
|
||||
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 5).getWeekFirstDayAlwaysCurrent())
|
||||
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 6).getWeekFirstDayAlwaysCurrent())
|
||||
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 7).getWeekFirstDayAlwaysCurrent())
|
||||
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 8).getWeekFirstDayAlwaysCurrent())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getWeekFirstDayNextOnWeekEnd() {
|
||||
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 2).getWeekFirstDayNextOnWeekEnd())
|
||||
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 5).getWeekFirstDayNextOnWeekEnd())
|
||||
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 6).getWeekFirstDayNextOnWeekEnd())
|
||||
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 7).getWeekFirstDayNextOnWeekEnd())
|
||||
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 8).getWeekFirstDayNextOnWeekEnd())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getWeekDayName() {
|
||||
Locale.setDefault(Locale.forLanguageTag("PL"))
|
||||
assertEquals("poniedziałek", LocalDate.of(2018, 10, 1).getWeekDayName())
|
||||
Locale.setDefault(Locale.forLanguageTag("US"))
|
||||
assertEquals("Monday", LocalDate.of(2018, 10, 1).getWeekDayName())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getSchoolYear() {
|
||||
assertEquals(2017, LocalDate.of(2018, 8, 31).getSchoolYear())
|
||||
assertEquals(2018, LocalDate.of(2018, 9, 1).getSchoolYear())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNextSchoolDay() {
|
||||
assertEquals(LocalDate.of(2018, 10, 2), LocalDate.of(2018, 10, 1).getNextWorkDay())
|
||||
assertEquals(LocalDate.of(2018, 10, 3), LocalDate.of(2018, 10, 2).getNextWorkDay())
|
||||
assertEquals(LocalDate.of(2018, 10, 4), LocalDate.of(2018, 10, 3).getNextWorkDay())
|
||||
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 4).getNextWorkDay())
|
||||
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 5).getNextWorkDay())
|
||||
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 6).getNextWorkDay())
|
||||
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 7).getNextWorkDay())
|
||||
assertEquals(LocalDate.of(2018, 10, 9), LocalDate.of(2018, 10, 8).getNextWorkDay())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getPreviousSchoolDay() {
|
||||
assertEquals(LocalDate.of(2018, 10, 9), LocalDate.of(2018, 10, 10).getPreviousWorkDay())
|
||||
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 9).getPreviousWorkDay())
|
||||
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 8).getPreviousWorkDay())
|
||||
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 7).getPreviousWorkDay())
|
||||
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 6).getPreviousWorkDay())
|
||||
assertEquals(LocalDate.of(2018, 10, 4), LocalDate.of(2018, 10, 5).getPreviousWorkDay())
|
||||
assertEquals(LocalDate.of(2018, 10, 3), LocalDate.of(2018, 10, 4).getPreviousWorkDay())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNearSchoolDayPrevOnWeekEnd() {
|
||||
assertEquals(LocalDate.of(2018, 9, 28), LocalDate.of(2018, 9, 28).getNearSchoolDayPrevOnWeekEnd())
|
||||
assertEquals(LocalDate.of(2018, 9, 28), LocalDate.of(2018, 9, 29).getNearSchoolDayPrevOnWeekEnd())
|
||||
assertEquals(LocalDate.of(2018, 9, 28), LocalDate.of(2018, 9, 30).getNearSchoolDayPrevOnWeekEnd())
|
||||
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 1).getNearSchoolDayPrevOnWeekEnd())
|
||||
assertEquals(LocalDate.of(2018, 10, 2), LocalDate.of(2018, 10, 2).getNearSchoolDayPrevOnWeekEnd())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNearSchoolDayNextOnWeekEnd() {
|
||||
assertEquals(LocalDate.of(2018, 9, 28), LocalDate.of(2018, 9, 28).getNearSchoolDayNextOnWeekEnd())
|
||||
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 9, 29).getNearSchoolDayNextOnWeekEnd())
|
||||
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 9, 30).getNearSchoolDayNextOnWeekEnd())
|
||||
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 1).getNearSchoolDayNextOnWeekEnd())
|
||||
assertEquals(LocalDate.of(2018, 10, 2), LocalDate.of(2018, 10, 2).getNearSchoolDayNextOnWeekEnd())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isHolidays_schoolEnd() {
|
||||
assertFalse(LocalDate.of(2017, 6, 23).isHolidays())
|
||||
assertFalse(LocalDate.of(2018, 6, 22).isHolidays())
|
||||
assertFalse(LocalDate.of(2019, 6, 21).isHolidays())
|
||||
assertFalse(LocalDate.of(2020, 6, 26).isHolidays())
|
||||
assertFalse(LocalDate.of(2021, 6, 25).isHolidays())
|
||||
assertFalse(LocalDate.of(2022, 6, 24).isHolidays())
|
||||
assertFalse(LocalDate.of(2023, 6, 23).isHolidays())
|
||||
assertFalse(LocalDate.of(2024, 6, 21).isHolidays())
|
||||
assertFalse(LocalDate.of(2025, 6, 27).isHolidays())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isHolidays_holidaysStart() {
|
||||
assertTrue(LocalDate.of(2017, 6, 24).isHolidays())
|
||||
assertTrue(LocalDate.of(2018, 6, 23).isHolidays())
|
||||
assertTrue(LocalDate.of(2019, 6, 22).isHolidays())
|
||||
assertTrue(LocalDate.of(2020, 6, 27).isHolidays())
|
||||
assertTrue(LocalDate.of(2021, 6, 26).isHolidays())
|
||||
assertTrue(LocalDate.of(2022, 6, 25).isHolidays())
|
||||
assertTrue(LocalDate.of(2023, 6, 24).isHolidays())
|
||||
assertTrue(LocalDate.of(2024, 6, 22).isHolidays())
|
||||
assertTrue(LocalDate.of(2025, 6, 28).isHolidays())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isHolidays_holidaysEnd() {
|
||||
assertTrue(LocalDate.of(2017, 9, 1).isHolidays()) // friday
|
||||
assertTrue(LocalDate.of(2017, 9, 2).isHolidays()) // saturday
|
||||
assertTrue(LocalDate.of(2017, 9, 3).isHolidays()) // sunday
|
||||
assertTrue(LocalDate.of(2018, 9, 1).isHolidays()) // saturday
|
||||
assertTrue(LocalDate.of(2018, 9, 2).isHolidays()) // sunday
|
||||
assertTrue(LocalDate.of(2019, 9, 1).isHolidays()) // sunday
|
||||
assertTrue(LocalDate.of(2020, 8, 31).isHolidays()) // monday
|
||||
assertTrue(LocalDate.of(2021, 8, 31).isHolidays()) // tuesday
|
||||
assertTrue(LocalDate.of(2022, 8, 31).isHolidays()) // wednesday
|
||||
assertTrue(LocalDate.of(2023, 9, 1).isHolidays()) // friday
|
||||
assertTrue(LocalDate.of(2023, 9, 2).isHolidays()) // saturday
|
||||
assertTrue(LocalDate.of(2023, 9, 3).isHolidays()) // sunday
|
||||
assertTrue(LocalDate.of(2024, 9, 1).isHolidays()) // sunday
|
||||
assertTrue(LocalDate.of(2025, 8, 31).isHolidays()) // sunday
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isHolidays_schoolStart() {
|
||||
assertFalse(LocalDate.of(2017, 9, 4).isHolidays()) // monday
|
||||
assertFalse(LocalDate.of(2018, 9, 3).isHolidays()) // monday
|
||||
assertFalse(LocalDate.of(2019, 9, 2).isHolidays()) // monday
|
||||
assertFalse(LocalDate.of(2020, 9, 1).isHolidays()) // tuesday
|
||||
assertFalse(LocalDate.of(2021, 9, 1).isHolidays()) // wednesday
|
||||
assertFalse(LocalDate.of(2022, 9, 1).isHolidays()) // thursday
|
||||
assertFalse(LocalDate.of(2023, 9, 4).isHolidays()) // monday
|
||||
assertFalse(LocalDate.of(2024, 9, 2).isHolidays()) // monday
|
||||
assertFalse(LocalDate.of(2025, 9, 1).isHolidays()) // monday
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ buildscript {
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'com.android.tools.build:gradle:3.1.4'
|
||||
classpath 'com.android.tools.build:gradle:3.2.0'
|
||||
classpath "io.fabric.tools:gradle:1.25.4"
|
||||
classpath "com.google.gms:oss-licenses:0.9.2"
|
||||
classpath "com.github.triplet.gradle:play-publisher:1.2.2"
|
||||
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
||||
#Tue Mar 27 02:10:44 CEST 2018
|
||||
#Sat Sep 29 23:00:14 CEST 2018
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||
|
Loading…
x
Reference in New Issue
Block a user