Uprość obsługę urlopów w aplikacji kierowcy
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
.gradle/
|
.gradle/
|
||||||
|
.kotlin/
|
||||||
build/
|
build/
|
||||||
local.properties
|
local.properties
|
||||||
app/google-services.json
|
app/google-services.json
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package pl.firmatpp.kierowca.data
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.provider.OpenableColumns
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -20,8 +21,12 @@ import pl.firmatpp.kierowca.data.model.DispatchSheetUploadResponse
|
|||||||
import pl.firmatpp.kierowca.data.model.CreateLeaveRequestBody
|
import pl.firmatpp.kierowca.data.model.CreateLeaveRequestBody
|
||||||
import pl.firmatpp.kierowca.data.model.DriverDto
|
import pl.firmatpp.kierowca.data.model.DriverDto
|
||||||
import pl.firmatpp.kierowca.data.model.DriverLeaveCalendarEntryDto
|
import pl.firmatpp.kierowca.data.model.DriverLeaveCalendarEntryDto
|
||||||
|
import pl.firmatpp.kierowca.data.model.DriverLeaveDocumentDto
|
||||||
|
import pl.firmatpp.kierowca.data.model.DriverLeaveForecastDto
|
||||||
import pl.firmatpp.kierowca.data.model.DriverLeaveRequestDto
|
import pl.firmatpp.kierowca.data.model.DriverLeaveRequestDto
|
||||||
|
import pl.firmatpp.kierowca.data.model.DriverLeaveSummaryDto
|
||||||
import pl.firmatpp.kierowca.data.model.FinishRouteBody
|
import pl.firmatpp.kierowca.data.model.FinishRouteBody
|
||||||
|
import pl.firmatpp.kierowca.data.model.LeaveForecastBody
|
||||||
import pl.firmatpp.kierowca.data.model.NotificationPreferencesBody
|
import pl.firmatpp.kierowca.data.model.NotificationPreferencesBody
|
||||||
import pl.firmatpp.kierowca.data.model.NotificationPreferencesDto
|
import pl.firmatpp.kierowca.data.model.NotificationPreferencesDto
|
||||||
import pl.firmatpp.kierowca.data.model.OtpResponse
|
import pl.firmatpp.kierowca.data.model.OtpResponse
|
||||||
@@ -70,18 +75,92 @@ class DriverRepository(
|
|||||||
suspend fun leaveRequests(): List<DriverLeaveRequestDto> =
|
suspend fun leaveRequests(): List<DriverLeaveRequestDto> =
|
||||||
api.leaveRequests(authHeader(requireToken())).data
|
api.leaveRequests(authHeader(requireToken())).data
|
||||||
|
|
||||||
|
suspend fun leaveSummary(): DriverLeaveSummaryDto =
|
||||||
|
api.leaveSummary(authHeader(requireToken())).data
|
||||||
|
|
||||||
|
suspend fun leaveForecast(
|
||||||
|
dateFrom: String,
|
||||||
|
dateTo: String,
|
||||||
|
type: String,
|
||||||
|
requestMode: String,
|
||||||
|
requestedQuantity: Int?,
|
||||||
|
): DriverLeaveForecastDto =
|
||||||
|
api.leaveForecast(
|
||||||
|
authHeader(requireToken()),
|
||||||
|
LeaveForecastBody(type, dateFrom, dateTo, requestMode, requestedQuantity),
|
||||||
|
).data
|
||||||
|
|
||||||
suspend fun leaveCalendar(from: String, to: String): List<DriverLeaveCalendarEntryDto> =
|
suspend fun leaveCalendar(from: String, to: String): List<DriverLeaveCalendarEntryDto> =
|
||||||
api.leaveCalendar(authHeader(requireToken()), from, to).data
|
api.leaveCalendar(authHeader(requireToken()), from, to).data
|
||||||
|
|
||||||
suspend fun leaveRequest(id: String): DriverLeaveRequestDto =
|
suspend fun leaveRequest(id: String): DriverLeaveRequestDto =
|
||||||
api.leaveRequest(authHeader(requireToken()), id).data
|
api.leaveRequest(authHeader(requireToken()), id).data
|
||||||
|
|
||||||
suspend fun createLeaveRequest(dateFrom: String, dateTo: String, type: String, note: String?): DriverLeaveRequestDto =
|
suspend fun createLeaveRequest(
|
||||||
api.createLeaveRequest(authHeader(requireToken()), CreateLeaveRequestBody(dateFrom, dateTo, type, note)).data
|
dateFrom: String,
|
||||||
|
dateTo: String,
|
||||||
|
type: String,
|
||||||
|
requestMode: String,
|
||||||
|
requestedQuantity: Int?,
|
||||||
|
details: Map<String, String>,
|
||||||
|
idempotencyKey: String,
|
||||||
|
note: String?,
|
||||||
|
): DriverLeaveRequestDto =
|
||||||
|
api.createLeaveRequest(
|
||||||
|
authHeader(requireToken()),
|
||||||
|
CreateLeaveRequestBody(
|
||||||
|
dateFrom = dateFrom,
|
||||||
|
dateTo = dateTo,
|
||||||
|
type = type,
|
||||||
|
requestMode = requestMode,
|
||||||
|
requestedQuantity = requestedQuantity,
|
||||||
|
details = details,
|
||||||
|
idempotencyKey = idempotencyKey,
|
||||||
|
note = note,
|
||||||
|
),
|
||||||
|
).data
|
||||||
|
|
||||||
suspend fun cancelLeaveRequest(id: String, expectedVersion: Long, comment: String? = null): DriverLeaveRequestDto =
|
suspend fun cancelLeaveRequest(id: String, expectedVersion: Long, comment: String? = null): DriverLeaveRequestDto =
|
||||||
api.cancelLeaveRequest(authHeader(requireToken()), id, CancelLeaveRequestBody(comment, expectedVersion)).data
|
api.cancelLeaveRequest(authHeader(requireToken()), id, CancelLeaveRequestBody(comment, expectedVersion)).data
|
||||||
|
|
||||||
|
suspend fun leaveDocuments(id: String): List<DriverLeaveDocumentDto> =
|
||||||
|
api.leaveDocuments(authHeader(requireToken()), id).data
|
||||||
|
|
||||||
|
suspend fun uploadLeaveDocument(id: String, documentType: String, uri: Uri): DriverLeaveDocumentDto {
|
||||||
|
val resolver = context.contentResolver
|
||||||
|
val mimeType = resolver.getType(uri) ?: "application/octet-stream"
|
||||||
|
val fileMetadata = resolver.query(
|
||||||
|
uri,
|
||||||
|
arrayOf(OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
)?.use { cursor ->
|
||||||
|
if (!cursor.moveToFirst()) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
cursor.getString(0) to cursor.getLong(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((fileMetadata?.second ?: 0L) > 20L * 1024L * 1024L) {
|
||||||
|
error("Dokument jest za duży. Maksymalny rozmiar pliku to 20 MB.")
|
||||||
|
}
|
||||||
|
val bytes = resolver.openInputStream(uri)?.use { it.readBytes() }
|
||||||
|
?: error("Nie można odczytać wybranego dokumentu.")
|
||||||
|
val originalName = fileMetadata?.first
|
||||||
|
?.takeIf { it.isNotBlank() }
|
||||||
|
?: "dokument"
|
||||||
|
val body = bytes.toRequestBody(mimeType.toMediaTypeOrNull())
|
||||||
|
val file = MultipartBody.Part.createFormData("file", originalName, body)
|
||||||
|
|
||||||
|
return api.uploadLeaveDocument(
|
||||||
|
authHeader(requireToken()),
|
||||||
|
id,
|
||||||
|
file,
|
||||||
|
documentType.toPlainTextBody(),
|
||||||
|
).data
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun completeRoute(routeId: String) =
|
suspend fun completeRoute(routeId: String) =
|
||||||
api.completeRoute(authHeader(requireToken()), routeId)
|
api.completeRoute(authHeader(requireToken()), routeId)
|
||||||
|
|
||||||
|
|||||||
@@ -13,9 +13,14 @@ import pl.firmatpp.kierowca.data.model.CreateLeaveRequestBody
|
|||||||
import pl.firmatpp.kierowca.data.model.DispatchSheetUploadResponse
|
import pl.firmatpp.kierowca.data.model.DispatchSheetUploadResponse
|
||||||
import pl.firmatpp.kierowca.data.model.FinishRouteBody
|
import pl.firmatpp.kierowca.data.model.FinishRouteBody
|
||||||
import pl.firmatpp.kierowca.data.model.LeaveCalendarResponse
|
import pl.firmatpp.kierowca.data.model.LeaveCalendarResponse
|
||||||
|
import pl.firmatpp.kierowca.data.model.LeaveDocumentListResponse
|
||||||
|
import pl.firmatpp.kierowca.data.model.LeaveDocumentResponse
|
||||||
|
import pl.firmatpp.kierowca.data.model.LeaveForecastBody
|
||||||
|
import pl.firmatpp.kierowca.data.model.LeaveForecastResponse
|
||||||
import pl.firmatpp.kierowca.data.model.LeaveRequestListResponse
|
import pl.firmatpp.kierowca.data.model.LeaveRequestListResponse
|
||||||
import pl.firmatpp.kierowca.data.model.LeaveRequestResponse
|
import pl.firmatpp.kierowca.data.model.LeaveRequestResponse
|
||||||
import pl.firmatpp.kierowca.data.model.LeaveRequestTypesResponse
|
import pl.firmatpp.kierowca.data.model.LeaveRequestTypesResponse
|
||||||
|
import pl.firmatpp.kierowca.data.model.LeaveSummaryResponse
|
||||||
import pl.firmatpp.kierowca.data.model.OtpResponse
|
import pl.firmatpp.kierowca.data.model.OtpResponse
|
||||||
import pl.firmatpp.kierowca.data.model.NotificationPreferencesBody
|
import pl.firmatpp.kierowca.data.model.NotificationPreferencesBody
|
||||||
import pl.firmatpp.kierowca.data.model.NotificationPreferencesDto
|
import pl.firmatpp.kierowca.data.model.NotificationPreferencesDto
|
||||||
@@ -80,6 +85,17 @@ interface MobileDriverApi {
|
|||||||
@Header("Authorization") authorization: String,
|
@Header("Authorization") authorization: String,
|
||||||
): LeaveRequestTypesResponse
|
): LeaveRequestTypesResponse
|
||||||
|
|
||||||
|
@GET("mobile/driver/leave-summary")
|
||||||
|
suspend fun leaveSummary(
|
||||||
|
@Header("Authorization") authorization: String,
|
||||||
|
): LeaveSummaryResponse
|
||||||
|
|
||||||
|
@POST("mobile/driver/leave-forecast")
|
||||||
|
suspend fun leaveForecast(
|
||||||
|
@Header("Authorization") authorization: String,
|
||||||
|
@Body body: LeaveForecastBody,
|
||||||
|
): LeaveForecastResponse
|
||||||
|
|
||||||
@GET("mobile/driver/leave-requests")
|
@GET("mobile/driver/leave-requests")
|
||||||
suspend fun leaveRequests(
|
suspend fun leaveRequests(
|
||||||
@Header("Authorization") authorization: String,
|
@Header("Authorization") authorization: String,
|
||||||
@@ -104,6 +120,21 @@ interface MobileDriverApi {
|
|||||||
@Path("id") id: String,
|
@Path("id") id: String,
|
||||||
): LeaveRequestResponse
|
): LeaveRequestResponse
|
||||||
|
|
||||||
|
@GET("mobile/driver/leave-requests/{id}/documents")
|
||||||
|
suspend fun leaveDocuments(
|
||||||
|
@Header("Authorization") authorization: String,
|
||||||
|
@Path("id") id: String,
|
||||||
|
): LeaveDocumentListResponse
|
||||||
|
|
||||||
|
@Multipart
|
||||||
|
@POST("mobile/driver/leave-requests/{id}/documents")
|
||||||
|
suspend fun uploadLeaveDocument(
|
||||||
|
@Header("Authorization") authorization: String,
|
||||||
|
@Path("id") id: String,
|
||||||
|
@Part file: MultipartBody.Part,
|
||||||
|
@Part("documentType") documentType: RequestBody,
|
||||||
|
): LeaveDocumentResponse
|
||||||
|
|
||||||
@POST("mobile/driver/leave-requests/{id}/cancel")
|
@POST("mobile/driver/leave-requests/{id}/cancel")
|
||||||
suspend fun cancelLeaveRequest(
|
suspend fun cancelLeaveRequest(
|
||||||
@Header("Authorization") authorization: String,
|
@Header("Authorization") authorization: String,
|
||||||
|
|||||||
@@ -223,13 +223,94 @@ data class LeaveRequestTypesResponse(
|
|||||||
|
|
||||||
data class LeaveRequestTypeDto(
|
data class LeaveRequestTypeDto(
|
||||||
val value: String,
|
val value: String,
|
||||||
|
val code: String? = null,
|
||||||
|
val ruleCode: String? = null,
|
||||||
val label: String,
|
val label: String,
|
||||||
|
val category: String? = null,
|
||||||
|
val unit: String? = null,
|
||||||
|
val poolCode: String? = null,
|
||||||
|
val requestModes: List<String> = listOf("days"),
|
||||||
|
val requiredFields: List<String> = emptyList(),
|
||||||
|
val requiredDocuments: List<String> = emptyList(),
|
||||||
|
val fieldOptions: Map<String, Map<String, String>> = emptyMap(),
|
||||||
|
val description: String? = null,
|
||||||
|
val decisionMode: String? = null,
|
||||||
|
val payrollMode: String? = null,
|
||||||
|
val legalBasis: String? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class LeaveSummaryResponse(
|
||||||
|
val data: DriverLeaveSummaryDto,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class DriverLeaveSummaryDto(
|
||||||
|
val pools: List<DriverLeavePoolDto> = emptyList(),
|
||||||
|
val dailyNormMinutes: Int = 480,
|
||||||
|
val balanceConfigured: Boolean = false,
|
||||||
|
val overdueQuantity: Int = 0,
|
||||||
|
val availableTypes: List<LeaveRequestTypeDto> = emptyList(),
|
||||||
|
val reminders: List<DriverLeaveReminderDto> = emptyList(),
|
||||||
|
)
|
||||||
|
|
||||||
|
data class DriverLeavePoolDto(
|
||||||
|
val id: Int,
|
||||||
|
val poolCode: String,
|
||||||
|
val year: Int,
|
||||||
|
val unit: String,
|
||||||
|
val calculatedQuantity: Int = 0,
|
||||||
|
val confirmedQuantity: Int? = null,
|
||||||
|
val availableQuantity: Int = 0,
|
||||||
|
val reservedQuantity: Int = 0,
|
||||||
|
val usedQuantity: Int = 0,
|
||||||
|
val grantedQuantity: Int = 0,
|
||||||
|
val overdue: Boolean = false,
|
||||||
|
val status: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class DriverLeaveReminderDto(
|
||||||
|
val code: String,
|
||||||
|
val message: String,
|
||||||
|
val poolId: Int? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class LeaveForecastBody(
|
||||||
|
val type: String,
|
||||||
|
val dateFrom: String,
|
||||||
|
val dateTo: String,
|
||||||
|
val requestMode: String,
|
||||||
|
val requestedQuantity: Int? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class LeaveForecastResponse(
|
||||||
|
val data: DriverLeaveForecastDto,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class DriverLeaveForecastDto(
|
||||||
|
val ruleCode: String,
|
||||||
|
val quantityUnit: String,
|
||||||
|
val days: List<DriverLeaveForecastDayDto> = emptyList(),
|
||||||
|
val workingDaysCount: Int = 0,
|
||||||
|
val requestedQuantity: Int = 0,
|
||||||
|
val availableQuantity: Int = 0,
|
||||||
|
val balanceConfigured: Boolean = false,
|
||||||
|
val sufficientBalance: Boolean = true,
|
||||||
|
val pools: List<DriverLeavePoolDto> = emptyList(),
|
||||||
|
)
|
||||||
|
|
||||||
|
data class DriverLeaveForecastDayDto(
|
||||||
|
val date: String,
|
||||||
|
val quantity: Int,
|
||||||
|
val source: String? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class CreateLeaveRequestBody(
|
data class CreateLeaveRequestBody(
|
||||||
val dateFrom: String,
|
val dateFrom: String,
|
||||||
val dateTo: String,
|
val dateTo: String,
|
||||||
val type: String,
|
val type: String,
|
||||||
|
val requestMode: String = "days",
|
||||||
|
val requestedQuantity: Int? = null,
|
||||||
|
val details: Map<String, String> = emptyMap(),
|
||||||
|
val idempotencyKey: String? = null,
|
||||||
val note: String?,
|
val note: String?,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -244,7 +325,12 @@ data class DriverLeaveRequestDto(
|
|||||||
val dateFrom: String?,
|
val dateFrom: String?,
|
||||||
val dateTo: String?,
|
val dateTo: String?,
|
||||||
val type: String,
|
val type: String,
|
||||||
|
val ruleCode: String? = null,
|
||||||
val typeLabel: String? = null,
|
val typeLabel: String? = null,
|
||||||
|
val requestMode: String = "days",
|
||||||
|
val requestedQuantity: Int? = null,
|
||||||
|
val rule: DriverLeaveRuleSnapshotDto? = null,
|
||||||
|
val details: Map<String, String> = emptyMap(),
|
||||||
val note: String? = null,
|
val note: String? = null,
|
||||||
val status: String,
|
val status: String,
|
||||||
val version: Long = 1,
|
val version: Long = 1,
|
||||||
@@ -255,6 +341,54 @@ data class DriverLeaveRequestDto(
|
|||||||
val decidedAt: String? = null,
|
val decidedAt: String? = null,
|
||||||
val decisionComment: String? = null,
|
val decisionComment: String? = null,
|
||||||
val events: List<DriverLeaveRequestEventDto> = emptyList(),
|
val events: List<DriverLeaveRequestEventDto> = emptyList(),
|
||||||
|
| ||||||