Add excuse function to "not excusable" account
MODIFY
app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceAdapter.kt
app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceAdapter.kt
@@ -10,6 +10,7 @@ import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.enums.SentExcuseStatus
import io.github.wulkanowy.databinding.ItemAttendanceBinding
import io.github.wulkanowy.utils.description
+import io.github.wulkanowy.utils.isExcusableOrNotExcused
import javax.inject.Inject
class AttendanceAdapter @Inject constructor() :
@@ -56,7 +57,7 @@ class AttendanceAdapter @Inject constructor() :
attendanceItemExcuseInfo.visibility = View.VISIBLE
}
else -> {
- if (item.excusable && excuseActionMode) {
+ if (item.isExcusableOrNotExcused && excuseActionMode) {
attendanceItemNumber.visibility = View.GONE
attendanceItemExcuseCheckbox.visibility = View.VISIBLE
} else {

MODIFY
app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt
app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt
@@ -24,6 +24,7 @@ import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
+import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.SchoolDaysValidator
import io.github.wulkanowy.utils.dpToPx
@@ -120,7 +121,9 @@ class AttendanceFragment : BaseFragment<FragmentAttendanceBinding>(R.layout.frag
attendanceSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
attendanceSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary))
attendanceSwipe.setProgressBackgroundColorSchemeColor(
- requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh)
+ requireContext().getThemeAttrColor(
+ R.attr.colorSwipeRefresh
+ )
)
attendanceErrorRetry.setOnClickListener { presenter.onRetry() }
attendanceErrorDetails.setOnClickListener { presenter.onDetailsClick() }
@@ -253,8 +256,13 @@ class AttendanceFragment : BaseFragment<FragmentAttendanceBinding>(R.layout.frag
.setNegativeButton(android.R.string.cancel) { _, _ -> }
.create()
.apply {
- setButton(BUTTON_POSITIVE, getString(R.string.attendance_excuse_dialog_submit)) { _, _ ->
- presenter.onExcuseDialogSubmit(dialogBinding.excuseReason.text?.toString().orEmpty())
+ setButton(
+ BUTTON_POSITIVE,
+ getString(R.string.attendance_excuse_dialog_submit)
+ ) { _, _ ->
+ presenter.onExcuseDialogSubmit(
+ dialogBinding.excuseReason.text?.toString().orEmpty()
+ )
}
}.show()
}
@@ -267,6 +275,17 @@ class AttendanceFragment : BaseFragment<FragmentAttendanceBinding>(R.layout.frag
actionMode = (activity as MainActivity?)?.startSupportActionMode(actionModeCallback)
}
+ override fun startSendMessageIntent(date: LocalDate, numbers: String, reason: String) {
+ val reasonFullText = getString(
+ R.string.attendance_excuse_formula,
+ date,
+ numbers,
+ if (reason.isNotBlank()) " ${getString(R.string.attendance_excuse_reason)} " else "",
+ reason.ifBlank { "" }
+ )
+ startActivity(SendMessageActivity.getStartIntent(requireContext(), reasonFullText))
+ }
+
override fun showExcuseCheckboxes(show: Boolean) {
attendanceAdapter.apply {
excuseActionMode = show

MODIFY
app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt
app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt
@@ -15,6 +15,7 @@ import io.github.wulkanowy.utils.capitalise
import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.flowWithResourceIn
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
+import io.github.wulkanowy.utils.isExcusableOrNotExcused
import io.github.wulkanowy.utils.isHolidays
import io.github.wulkanowy.utils.nextSchoolDay
import io.github.wulkanowy.utils.previousOrSameSchoolDay
@@ -47,6 +48,8 @@ class AttendancePresenter @Inject constructor(
private val attendanceToExcuseList = mutableListOf<Attendance>()
+ private var isVulcanExcusedFunctionEnabled = false
+
fun onAttachView(view: AttendanceView, date: Long?) {
super.onAttachView(view)
view.initView()
@@ -148,7 +151,21 @@ class AttendancePresenter @Inject constructor(
fun onExcuseDialogSubmit(reason: String) {
view?.finishActionMode()
- excuseAbsence(if (reason != "") reason else null, attendanceToExcuseList.toList())
+
+ if (isVulcanExcusedFunctionEnabled) {
+ excuseAbsence(
+ reason = reason.takeIf { it.isNotBlank() },
+ toExcuseList = attendanceToExcuseList.toList()
+ )
+ } else {
+ val attendanceToExcuseNumbers = attendanceToExcuseList.map { it.number }
+
+ view?.startSendMessageIntent(
+ date = attendanceToExcuseList[0].date,
+ numbers = attendanceToExcuseNumbers.joinToString(", "),
+ reason = reason
+ )
+ }
}
fun onPrepareActionMode(): Boolean {
@@ -188,8 +205,12 @@ class AttendancePresenter @Inject constructor(
private fun loadData(forceRefresh: Boolean = false) {
Timber.i("Loading attendance data started")
+ var isParent = false
+
flowWithResourceIn {
val student = studentRepository.getCurrentStudent()
+ isParent = student.isParent
+
val semester = semesterRepository.getCurrentSemester(student)
attendanceRepository.getAttendance(
student,
@@ -227,12 +248,17 @@ class AttendancePresenter @Inject constructor(
it.data?.filter { item -> !item.presence }.orEmpty()
}
+ isVulcanExcusedFunctionEnabled =
+ filteredAttendance.any { item -> item.excusable }
+
view?.apply {
updateData(filteredAttendance.sortedBy { item -> item.number })
showEmpty(filteredAttendance.isEmpty())
showErrorView(false)
showContent(filteredAttendance.isNotEmpty())
- showExcuseButton(filteredAttendance.any { item -> item.excusable })
+ showExcuseButton(filteredAttendance.any { item ->
+ (!isParent && isVulcanExcusedFunctionEnabled) || (isParent && item.isExcusableOrNotExcused)
+ })
}
analytics.logEvent(
"load_data",

MODIFY
app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceView.kt
app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceView.kt
@@ -54,6 +54,8 @@ interface AttendanceView : BaseView {
fun openSummaryView()
+ fun startSendMessageIntent(date: LocalDate, numbers: String, reason: String)
+
fun startActionMode()
fun showExcuseCheckboxes(show: Boolean)

MODIFY
app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt
app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt
@@ -35,6 +35,8 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter, ActivitySendMessa
companion object {
private const val EXTRA_MESSAGE = "EXTRA_MESSAGE"
+ private const val EXTRA_REASON = "EXTRA_REASON"
+
private const val EXTRA_REPLY = "EXTRA_REPLY"
fun getStartIntent(context: Context) = Intent(context, SendMessageActivity::class.java)
@@ -44,6 +46,11 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter, ActivitySendMessa
.putExtra(EXTRA_MESSAGE, message)
.putExtra(EXTRA_REPLY, reply)
}
+
+ fun getStartIntent(context: Context, reason: String): Intent {
+ return getStartIntent(context)
+ .putExtra(EXTRA_REASON, reason)
+ }
}
override val isDropdownListVisible: Boolean
@@ -79,6 +86,7 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter, ActivitySendMessa
presenter.onAttachView(
view = this,
+ reason = intent.getSerializableExtra(EXTRA_REASON) as? String,
message = intent.getSerializableExtra(EXTRA_MESSAGE) as? Message,
reply = intent.getSerializableExtra(EXTRA_REPLY) as? Boolean
)

MODIFY
app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt
app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt
@@ -40,7 +40,7 @@ class SendMessagePresenter @Inject constructor(
private val messageUpdateChannel = Channel<Unit>()
- fun onAttachView(view: SendMessageView, message: Message?, reply: Boolean?) {
+ fun onAttachView(view: SendMessageView, reason: String?, message: Message?, reply: Boolean?) {
super.onAttachView(view)
view.initView()
initializeSubjectStream()
@@ -50,6 +50,10 @@ class SendMessagePresenter @Inject constructor(
if (messageRepository.draftMessage != null && reply == null) {
view.showMessageBackupDialog()
}
+ reason?.let {
+ setSubject("Usprawiedliwenie")
+ setContent(it)
+ }
message?.let {
setSubject(when (reply) {
true -> "RE: "

MODIFY
app/src/main/java/io/github/wulkanowy/utils/AttendanceExtension.kt
app/src/main/java/io/github/wulkanowy/utils/AttendanceExtension.kt
@@ -16,6 +16,9 @@ private inline val AttendanceSummary.allPresences: Double
private inline val AttendanceSummary.allAbsences: Double
get() = absence.toDouble() + absenceExcused
+inline val Attendance.isExcusableOrNotExcused: Boolean
+ get() = excusable || ((absence || lateness) && !excused)
+
fun AttendanceSummary.calculatePercentage() = calculatePercentage(allPresences, allAbsences)
fun List<AttendanceSummary>.calculatePercentage(): Double {

Add excuse function to "not excusable" account (#1429)