Skip to content

Instantly share code, notes, and snippets.

@Aldikitta
Last active July 29, 2023 14:34
Show Gist options
  • Save Aldikitta/b86cc0079b2a985e4ff92475df10e00a to your computer and use it in GitHub Desktop.
Save Aldikitta/b86cc0079b2a985e4ff92475df10e00a to your computer and use it in GitHub Desktop.
// Dto Class
sealed interface MockDraftDetailResponseDto {
data class MockDraftDetail(
@SerializedName("code")
val code: Int,
@SerializedName("data")
val data: Data,
@SerializedName("errors")
val errors: Errors? = null,
@SerializedName("message")
val message: String,
@SerializedName("request_id")
val requestId: String,
@SerializedName("timestamp")
val timestamp: String
)
data class Data(
@SerializedName("assets")
val assets: List<Asset>,
@SerializedName("branch_id")
val branchId: String,
@SerializedName("created_at")
val createdAt: String,
@SerializedName("cro_id")
val croId: String,
@SerializedName("cro_name")
val croName: String,
@SerializedName("customer_id")
val customerId: String,
@SerializedName("customer_limit_category")
val customerLimitCategory: String,
@SerializedName("customer_mobile_phone")
val customerMobilePhone: String,
@SerializedName("customer_name")
val customerName: String,
@SerializedName("group_category_code")
val groupCategoryCode: String,
@SerializedName("group_category_id")
val groupCategoryId: Int,
@SerializedName("group_category_name")
val groupCategoryName: String,
@SerializedName("is_editable")
val isEditable: Boolean,
@SerializedName("is_near_customer")
val isNearCustomer: Boolean,
@SerializedName("is_new_wg")
val isNewWg: Boolean,
@SerializedName("latitude")
val latitude: String,
@SerializedName("longitude")
val longitude: String,
@SerializedName("prospect_id")
val prospectId: String,
@SerializedName("source_application")
val sourceApplication: String,
@SerializedName("supplier_address")
val supplierAddress: String,
@SerializedName("supplier_id")
val supplierId: String,
@SerializedName("supplier_key")
val supplierKey: String,
@SerializedName("supplier_name")
val supplierName: String,
@SerializedName("total_otr")
val totalOtr: Int,
@SerializedName("updated_at")
val updatedAt: String,
@SerializedName("user_id")
val userId: String
)
class Errors
data class Asset(
@SerializedName("category_id")
val categoryId: String,
@SerializedName("category_name")
val categoryName: String,
@SerializedName("code")
val code: String,
@SerializedName("description")
val description: String,
@SerializedName("otr")
val otr: Int,
@SerializedName("qty")
val qty: Int
)
}
// Model Class
sealed interface MockDraftDetailResponse {
data class MockDraftDetail(
val code: Int,
val data: Data,
val errors: Errors? = null,
val message: String,
val requestId: String,
val timestamp: String
)
data class Data(
val assets: List<Asset>,
val branchId: String,
val createdAt: String,
val croId: String,
val croName: String,
val customerId: String,
val customerLimitCategory: String,
val customerMobilePhone: String,
val customerName: String,
val groupCategoryCode: String,
val groupCategoryId: Int,
val groupCategoryName: String,
val isEditable: Boolean,
val isNearCustomer: Boolean,
val isNewWg: Boolean,
val latitude: String,
val longitude: String,
val prospectId: String,
val sourceApplication: String,
val supplierAddress: String,
val supplierId: String,
val supplierKey: String,
val supplierName: String,
val totalOtr: Int,
val updatedAt: String,
val userId: String
)
class Errors
data class Asset(
val categoryId: String,
val categoryName: String,
val code: String,
val description: String,
val otr: Int,
val qty: Int
)
}
// Model Mapper
fun MockDraftDetailResponseDto.MockDraftDetail.toMockDraftDetailResponseModel(): MockDraftDetailResponse.MockDraftDetail {
return MockDraftDetailResponse.MockDraftDetail(
code = this.code,
data = this.data.toMockDraftDetailDataModel(),
message = this.message,
requestId = this.requestId,
timestamp = this.timestamp,
)
}
fun MockDraftDetailResponseDto.Data.toMockDraftDetailDataModel(): MockDraftDetailResponse.Data {
return MockDraftDetailResponse.Data(
assets = this.assets.map {
it.toMockDraftDetailAssetModel()
},
branchId = this.branchId,
createdAt = this.createdAt,
croId = this.croId,
croName = this.croName,
customerId = this.customerId,
customerLimitCategory = this.customerLimitCategory,
customerMobilePhone = this.customerMobilePhone,
customerName = this.customerName,
groupCategoryCode = this.groupCategoryCode,
groupCategoryId = this.groupCategoryId,
groupCategoryName = this.groupCategoryName,
isEditable = this.isEditable,
isNearCustomer = this.isNearCustomer,
isNewWg = this.isNewWg,
latitude = this.latitude,
longitude = this.longitude,
prospectId = this.prospectId,
sourceApplication = this.sourceApplication,
supplierAddress = this.supplierAddress,
supplierId = this.supplierId,
supplierKey = this.supplierKey,
supplierName = this.supplierName,
totalOtr = this.totalOtr,
updatedAt = this.updatedAt,
userId = this.userId
)
}
fun MockDraftDetailResponseDto.Asset.toMockDraftDetailAssetModel(): MockDraftDetailResponse.Asset {
return MockDraftDetailResponse.Asset(
categoryId = this.categoryId,
categoryName = this.categoryName,
code = this.code,
description = this.description,
otr = this.otr,
qty = this.qty
)
}
// API Service
@GET("submissions/wg/draft-orders/NWG-1")
suspend fun getDraftDetailMock(): MockDraftDetailResponseDto.MockDraftDetail
// Data Source
fun getDetailDraftMock(): Flow<MockDraftDetailResponseDto.MockDraftDetail> = flow {
delay(5_000)
while (true) {
val draftDetail = mockServices.getDraftDetailMock()
emit(draftDetail)
delay(5 * 60 * 1000)
}
}
// Rpository
override fun getDetailDraftMock(): Flow<SallyResponseResource<MockDraftDetailResponse.MockDraftDetail>> {
return remoteDataSource.getDetailDraftMock().map {
it.toMockDraftDetailResponseModel()
}.asSallyResponseResourceFlow()
}
// Usecase
override fun getDraftDetailMock(): Flow<SallyResponseResource<MockDraftDetailResponse.MockDraftDetail>> {
return iWGRepository.getDetailDraftMock()
}
// PAGING
// api service
@GET("submissions/wg/draft-orders")
suspend fun getDraftListMock(
@QueryMap body: MutableMap<String, Any>,
): MockDraftListResponseDto.MockDraftList
// data source
suspend fun getListDraftMock(body: MockDraftListRequestDto.MockDraftList): MockDraftListResponseDto.MockDraftList {
return mockServices.getDraftListMock(body = convertDataClassToMap(body))
}
// Paging source
class DraftListPagingSource(
private val wgRemoteDataSource: WGRemoteDataSource,
private val mockDraftListRequestDto: MockDraftListRequestDto.MockDraftList
) : PagingSource<Int, MockDraftListResponseDto.Data>() {
override val keyReuseSupported: Boolean = true
override fun getRefreshKey(state: PagingState<Int, MockDraftListResponseDto.Data>): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
}
}
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MockDraftListResponseDto.Data> {
return try {
val nextPage = params.key ?: 1
val bodyWithPage = mockDraftListRequestDto.copy(page = nextPage, pageSize = 20)
val getListResponse = wgRemoteDataSource.getListDraftMock(
body = bodyWithPage
)
val currentPage = getListResponse.paginator.currentPage
val totalPages = getListResponse.paginator.totalPages
val prevKey = getListResponse.paginator.backPage
val nextKey = getListResponse.paginator.nextPage
LoadResult.Page(
data = getListResponse.data,
prevKey = prevKey,
nextKey = nextKey
// prevKey = if (nextPage == 1) null else nextPage - 1,
// nextKey = if (currentPage + 1 > totalPages) null else currentPage + 1
)
// ALTERNATIVE 1
val nextPage = params.key ?: 1
val bodyWithPage = draftListRequestRequestDto.copy(page = nextPage, pageSize = 20)
val getListResponse = wgRemoteDataSource.getListDraft(
token = token,
body = bodyWithPage
)
LoadResult.Page(
data = getListResponse.data,
prevKey = if (nextPage == 1) null else nextPage - 1,
nextKey = if (getListResponse.data.isEmpty()) null else nextPage + 1
)
// ALTERNATIVE 2
val nextPage = params.key ?: 1
val bodyWithPage = pengajuanListRequestDto.copy(page = nextPage, limit = 20)
val getListResponse = wgRemoteDataSource.getListPengajuan(
token = token,
body = bodyWithPage
)
LoadResult.Page(
data = getListResponse.data,
prevKey = if (nextPage == 1) null else nextPage - 1,
nextKey = if (getListResponse.data.isEmpty()) null else nextPage + 1
)
} catch (e: IOException) {
LoadResult.Error(e)
} catch (e: Exception) {
LoadResult.Error(e)
} catch (e: HttpException) {
LoadResult.Error(e)
}
}
}
// repository
override fun getListDaftMock(body: MockDraftListRequest.MockDraftList): Flow<PagingData<MockDraftListResponse.Data>> {
val requestModel = body.toMockDraftListRequestDtoModel()
return Pager(
config = PagingConfig(
pageSize = 20,
prefetchDistance = 10
),
pagingSourceFactory = {
DraftListPagingSource(
wgRemoteDataSource = remoteDataSource,
mockDraftListRequestDto = requestModel
)
}
).flow.map { pagingData ->
pagingData.map { data ->
data.toMockDraftListResponseDataModel()
}
}
}
// use case
override fun getListDaftMock(body: MockDraftListRequest.MockDraftList): Flow<PagingData<MockDraftListResponse.Data>> {
return iWGRepository.getListDaftMock(body = body)
}
// viewmodel
sealed interface DraftListUiEvent {
data class DateFilterOnClick(val startDate: String, val endDate: String) : DraftListUiEvent
data class CategoryLimitOnClick(val category: String) : DraftListUiEvent
data class SearchOnClick(val search: String) : DraftListUiEvent
data class StatusOnChange(val status: String) : DraftListUiEvent
}
data class DraftListUiState(
val draftList: Flow<PagingData<MockDraftListResponse.Data>>,
) {
companion object {
val default: DraftListUiState = DraftListUiState(
draftList = emptyFlow(),
)
}
}
data class FilterDraftListUiState(
val search: String,
val startDate: String,
val endDate: String,
val customerLimitCategory: String,
val status: String
) {
companion object {
val default: FilterDraftListUiState = FilterDraftListUiState(
search = "",
startDate = "",
endDate = "",
customerLimitCategory = "",
status = ""
)
}
}
@OptIn(ExperimentalCoroutinesApi::class)
val getDraftList: StateFlow<DraftListUiState> =
filterDraftListState.flatMapLatest { filterDraftListState ->
flow {
val draftList = useCase.getListDaftMock(
body = MockDraftListRequest.MockDraftList(
search = filterDraftListState.search,
startDate = filterDraftListState.startDate,
endDate = filterDraftListState.endDate,
customerLimitCategory = filterDraftListState.customerLimitCategory
)
).cachedIn(viewModelScope)
emit(DraftListUiState(draftList = draftList))
}
}.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5_000),
DraftListUiState.default
)
fun setFilterDraftListState(
search: String? = null,
startDate: String? = null,
endDate: String? = null,
customerLimitCategory: String? = null
) {
val currentFilter = filterDraftListState.value
val updatedFilter = currentFilter.copy(
search = search ?: currentFilter.search,
startDate = startDate ?: currentFilter.startDate,
endDate = endDate ?: currentFilter.endDate,
customerLimitCategory = customerLimitCategory ?: currentFilter.customerLimitCategory
)
filterDraftListState.value = updatedFilter
}
fun onEvent(draftListUiEvent: DraftListUiEvent) {
when (draftListUiEvent) {
is DraftListUiEvent.DateFilterOnClick -> {
setFilterDraftListState(
startDate = draftListUiEvent.startDate,
endDate = draftListUiEvent.endDate
)
}
is DraftListUiEvent.CategoryLimitOnClick -> {
setFilterDraftListState(
customerLimitCategory = draftListUiEvent.category
)
}
is DraftListUiEvent.SearchOnClick -> {
setFilterDraftListState(
search = draftListUiEvent.search
)
}
is DraftListUiEvent.StatusOnChange -> {
setFilterDraftListState(
status = draftListUiEvent.status
)
}
}
}
fun resetFilterDraftListState() {
filterDraftListState.value = FilterDraftListUiState.default
}
// SUSPEND FUNCTION
// MAPPER CLASS
// REQUEST
fun CreateProspectAgentRequestModel.CreateProspectAgentRequest.toCreateProspectAgentRequestDto(): CreateProspectAgentRequestDto.CreateProspectAgentRequest {
return CreateProspectAgentRequestDto.CreateProspectAgentRequest(
agentName = this.agentName,
agentProfession = this.agentProfession,
agentProfessionCode = this.agentProfessionCode,
branchCode = this.branchCode,
fotoAgentUrl = this.fotoAgentUrl,
latitude = this.latitude,
longitude = this.longitude,
moId = this.moId,
moName = this.moName,
mobilePhone = this.mobilePhone,
)
}
// RESPONSE
fun CreateProspectAgentResponseDto.CreateProspectAgentResponse.toCreateProspectAgentResponseModel(): CreateProspectAgentResponseModel.CreateProspectAgentResponse {
return CreateProspectAgentResponseModel.CreateProspectAgentResponse(
status = this.status,
message = this.message,
validation = this.validation
)
}
// API SERVICE
@POST("agent-prospect")
suspend fun createAgentProspect(
@Header("Authorization") token: String,
@Body body: CreateProspectAgentRequestDto.CreateProspectAgentRequest,
): CreateProspectAgentResponseDto.CreateProspectAgentResponse
// DATA SOURCE
suspend fun createAgentProspect(
token: String,
body: CreateProspectAgentRequestDto.CreateProspectAgentRequest
): CreateProspectAgentResponseDto.CreateProspectAgentResponse {
return agentActivityService.createAgentProspect(
token = token,
body = body
)
}
// REPOSITORY
override suspend fun createAgentProspect(body: CreateProspectAgentRequestModel.CreateProspectAgentRequest): KreditPlusResponse<CreateProspectAgentResponseModel.CreateProspectAgentResponse> {
return asSuspendKreditPlusResponse {
val requestDto = body.toCreateProspectAgentRequestDto()
val responseDto = agentVisitDataSource.createAgentProspect(
token = "Bearer ${getAccountInfo().token}",
body = requestDto
)
responseDto.toCreateProspectAgentResponseModel()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment