Skip to content

Commit

Permalink
feat: added ability to handle course errors
Browse files Browse the repository at this point in the history
  • Loading branch information
dixidroid committed Jul 15, 2024
1 parent d845e5e commit 76e138f
Show file tree
Hide file tree
Showing 23 changed files with 886 additions and 112 deletions.
6 changes: 6 additions & 0 deletions core/src/main/java/org/openedx/core/data/api/CourseApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.openedx.core.data.model.BlocksCompletionBody
import org.openedx.core.data.model.CourseComponentStatus
import org.openedx.core.data.model.CourseDates
import org.openedx.core.data.model.CourseDatesBannerInfo
import org.openedx.core.data.model.CourseEnrollmentDetails
import org.openedx.core.data.model.CourseEnrollments
import org.openedx.core.data.model.CourseStructureModel
import org.openedx.core.data.model.HandoutsModel
Expand Down Expand Up @@ -76,4 +77,9 @@ interface CourseApi {
@Query("status") status: String? = null,
@Query("requested_fields") fields: List<String> = emptyList()
): CourseEnrollments

@GET("/api/mobile/v1/course_info/{course_id}/enrollment_details")
suspend fun getEnrollmentDetails(
@Path("course_id") courseId: String,
): CourseEnrollmentDetails
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.openedx.core.data.model

import com.google.gson.annotations.SerializedName
import org.openedx.core.domain.model.CourseAccessDetails
import org.openedx.core.utils.TimeUtils

data class CourseAccessDetails(
@SerializedName("has_unmet_prerequisites")
val hasUnmetPrerequisites: Boolean,
@SerializedName("is_too_early")
val isTooEarly: Boolean,
@SerializedName("is_staff")
val isStaff: Boolean,
@SerializedName("audit_access_expires")
val auditAccessExpires: String?,
@SerializedName("courseware_access")
val coursewareAccess: CoursewareAccess?,
) {
fun mapToDomain() = CourseAccessDetails(
hasUnmetPrerequisites = hasUnmetPrerequisites,
isTooEarly = isTooEarly,
isStaff = isStaff,
auditAccessExpires = TimeUtils.iso8601ToDate(auditAccessExpires ?: ""),
coursewareAccess = coursewareAccess?.mapToDomain(),
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.openedx.core.data.model

import com.google.gson.annotations.SerializedName
import org.openedx.core.domain.model.CourseEnrollmentDetails

data class CourseEnrollmentDetails(
@SerializedName("id")
val id: String,
@SerializedName("course_updates")
val courseUpdates: String,
@SerializedName("course_handouts")
val courseHandouts: String,
@SerializedName("discussion_url")
val discussionUrl: String,
@SerializedName("course_access_details")
val courseAccessDetails: CourseAccessDetails,
@SerializedName("certificate")
val certificate: Certificate?,
@SerializedName("enrollment_details")
val enrollmentDetails: EnrollmentDetails,
@SerializedName("course_info_overview")
val courseInfoOverview: CourseInfoOverview,
) {
fun mapToDomain(): CourseEnrollmentDetails {
return CourseEnrollmentDetails(
id = id,
courseUpdates = courseUpdates,
courseHandouts = courseHandouts,
discussionUrl = discussionUrl,
courseAccessDetails = courseAccessDetails.mapToDomain(),
certificate = certificate?.mapToDomain(),
enrollmentDetails = enrollmentDetails.mapToDomain(),
courseInfoOverview = courseInfoOverview.mapToDomain(),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.openedx.core.data.model

import com.google.gson.annotations.SerializedName
import org.openedx.core.domain.model.CourseInfoOverview
import org.openedx.core.utils.TimeUtils

data class CourseInfoOverview(
@SerializedName("name")
val name: String,
@SerializedName("number")
val number: String,
@SerializedName("org")
val org: String,
@SerializedName("start")
val start: String?,
@SerializedName("start_display")
val startDisplay: String,
@SerializedName("start_type")
val startType: String,
@SerializedName("end")
val end: String?,
@SerializedName("is_self_paced")
val isSelfPaced: Boolean,
@SerializedName("media")
var media: Media?,
@SerializedName("course_sharing_utm_parameters")
val courseSharingUtmParameters: CourseSharingUtmParameters,
@SerializedName("course_about")
val courseAbout: String,
@SerializedName("course_modes")
val courseModes: List<CourseMode>,
) {
fun mapToDomain() = CourseInfoOverview(
name = name,
number = number,
org = org,
start = TimeUtils.iso8601ToDate(start ?: ""),
startDisplay = startDisplay,
startType = startType,
end = TimeUtils.iso8601ToDate(end ?: ""),
isSelfPaced = isSelfPaced,
media = media?.mapToDomain(),
courseSharingUtmParameters = courseSharingUtmParameters.mapToDomain(),
courseAbout = courseAbout,
courseModes = courseModes.map { it.mapToDomain() },
)
}
25 changes: 25 additions & 0 deletions core/src/main/java/org/openedx/core/data/model/CourseMode.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.openedx.core.data.model

import com.google.gson.annotations.SerializedName
import org.openedx.core.domain.model.CourseMode as CourseMode

data class CourseMode(
@SerializedName("slug")
val slug: String,
@SerializedName("sku")
val sku: String?,
@SerializedName("android_sku")
val androidSku: String?,
@SerializedName("ios_sku")
val iosSku: String?,
@SerializedName("min_price")
val minPrice: Int,
) {
fun mapToDomain() = CourseMode(
slug = slug,
sku = sku,
androidSku = androidSku,
iosSku = iosSku,
minPrice = minPrice,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.openedx.core.data.model

import com.google.gson.annotations.SerializedName
import org.openedx.core.domain.model.EnrollmentDetails
import org.openedx.core.utils.TimeUtils

data class EnrollmentDetails(
@SerializedName("date")
val date: String?,
@SerializedName("mode")
val mode: String,
@SerializedName("is_active")
val isActive: Boolean,
@SerializedName("upgrade_deadline")
val upgradeDeadline: String?,
) {
fun mapToDomain() = EnrollmentDetails(
created = TimeUtils.iso8601ToDate(date ?: ""),
mode = mode,
isActive = isActive,
upgradeDeadline = TimeUtils.iso8601ToDate(upgradeDeadline ?: ""),
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.openedx.core.domain.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import java.util.Date

@Parcelize
data class CourseAccessDetails(
val hasUnmetPrerequisites: Boolean,
val isTooEarly: Boolean,
val isStaff: Boolean,
val auditAccessExpires: Date?,
val coursewareAccess: CoursewareAccess?
) : Parcelable
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.openedx.core.domain.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import java.util.Date

@Parcelize
data class CourseEnrollmentDetails(
val id: String,
val courseUpdates: String,
val courseHandouts: String,
val discussionUrl: String,
val courseAccessDetails: CourseAccessDetails,
val certificate: Certificate?,
val enrollmentDetails: EnrollmentDetails,
val courseInfoOverview: CourseInfoOverview,
) : Parcelable {
fun isUpgradable(): Boolean {
val start = courseInfoOverview.start ?: return false
val upgradeDeadline = enrollmentDetails.upgradeDeadline ?: return false
if (enrollmentDetails.mode != "audit") return false

return start < Date() && getCourseMode() != null && upgradeDeadline > Date()
}

fun getCourseMode(): CourseMode? {
return courseInfoOverview.courseModes
.firstOrNull { it.slug == "verified" && !it.androidSku.isNullOrEmpty() }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.openedx.core.domain.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import java.util.Date

@Parcelize
data class CourseInfoOverview(
val name: String,
val number: String,
val org: String,
val start: Date?,
val startDisplay: String,
val startType: String,
val end: Date?,
val isSelfPaced: Boolean,
var media: Media?,
val courseSharingUtmParameters: CourseSharingUtmParameters,
val courseAbout: String,
val courseModes: List<CourseMode>,
) : Parcelable
13 changes: 13 additions & 0 deletions core/src/main/java/org/openedx/core/domain/model/CourseMode.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.openedx.core.domain.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
data class CourseMode(
val slug: String?,
val sku: String?,
val androidSku: String?,
val iosSku: String?,
val minPrice: Int,
) : Parcelable
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.openedx.core.domain.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import java.util.Date

@Parcelize
data class EnrollmentDetails(
val created: Date?,
val mode: String,
val isActive: Boolean,
val upgradeDeadline: Date?
) : Parcelable
5 changes: 5 additions & 0 deletions core/src/main/java/org/openedx/core/utils/TimeUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,11 @@ object TimeUtils {
}
}

fun getCourseAccessFormattedDate(context: Context, date: Date): String {
val resourceManager = ResourceManager(context)
return dateToCourseDate(resourceManager, date)
}

/**
* Returns the number of days difference between the given date and the current date.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.openedx.core.data.api.CourseApi
import org.openedx.core.data.model.BlocksCompletionBody
import org.openedx.core.data.storage.CorePreferences
import org.openedx.core.domain.model.CourseComponentStatus
import org.openedx.core.domain.model.CourseEnrollmentDetails
import org.openedx.core.domain.model.CourseStructure
import org.openedx.core.exception.NoCachedDataException
import org.openedx.core.module.db.DownloadDao
Expand Down Expand Up @@ -58,6 +59,10 @@ class CourseRepository(
return courseStructure[courseId]!!
}

suspend fun getEnrollmentDetails(courseId: String): CourseEnrollmentDetails {
return api.getEnrollmentDetails(courseId = courseId).mapToDomain()
}

suspend fun getCourseStatus(courseId: String): CourseComponentStatus {
val username = preferencesManager.user?.username ?: ""
return api.getCourseStatus(username, courseId).mapToDomain()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.openedx.course.domain.interactor

import org.openedx.core.BlockType
import org.openedx.core.domain.model.Block
import org.openedx.core.domain.model.CourseEnrollmentDetails
import org.openedx.core.domain.model.CourseStructure
import org.openedx.course.data.repository.CourseRepository

Expand All @@ -16,6 +17,10 @@ class CourseInteractor(
return repository.getCourseStructure(courseId, isNeedRefresh)
}

suspend fun getEnrollmentDetails(courseId: String): CourseEnrollmentDetails {
return repository.getEnrollmentDetails(courseId = courseId)
}

suspend fun getCourseStructureForVideos(
courseId: String,
isNeedRefresh: Boolean = false
Expand Down Expand Up @@ -71,5 +76,4 @@ class CourseInteractor(
suspend fun removeDownloadModel(id: String) = repository.removeDownloadModel(id)

fun getDownloadModels() = repository.getDownloadModels()

}
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,6 @@ interface CourseRouter {
fun navigateToDownloadQueue(fm: FragmentManager, descendants: List<String> = arrayListOf())

fun navigateToVideoQuality(fm: FragmentManager, videoQualityType: VideoQualityType)

fun navigateToMain(fm: FragmentManager, courseId: String?, infoType: String?, openTab: String)
}
Loading

0 comments on commit 76e138f

Please sign in to comment.