diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e59bf23..d07ff18 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,6 +1,7 @@ plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.compose) + id("com.google.gms.google-services") } android { @@ -46,6 +47,15 @@ dependencies { implementation(libs.androidx.compose.ui.graphics) implementation(libs.androidx.compose.ui.tooling.preview) implementation(libs.androidx.compose.material3) + implementation(libs.retrofit) + implementation(libs.retrofit.converter.gson) + implementation(libs.okhttp) + implementation(libs.okhttp.logging) + implementation(platform(libs.firebase.bom)) + implementation(libs.firebase.auth.ktx) + implementation(libs.kotlinx.coroutines.play.services) + implementation(platform("com.google.firebase:firebase-bom:34.8.0")) + implementation(libs.google.firebase.auth.ktx) testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) @@ -53,4 +63,4 @@ dependencies { androidTestImplementation(libs.androidx.compose.ui.test.junit4) debugImplementation(libs.androidx.compose.ui.tooling) debugImplementation(libs.androidx.compose.ui.test.manifest) -} \ No newline at end of file +} diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..13855f9 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,39 @@ +{ + "project_info": { + "project_number": "193837005934", + "project_id": "hoteltrisolaris-b1c34", + "storage_bucket": "hoteltrisolaris-b1c34.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:193837005934:android:4eae5c8b77ff988228ba7f", + "android_client_info": { + "package_name": "com.android.trisolarispms" + } + }, + "oauth_client": [ + { + "client_id": "193837005934-vbjdpp55t9s2r8c0l62kt16sic4ipaon.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyC1f0SmJDHk_V9X1SNn_jlXpMc7wjuLfsY" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "193837005934-vbjdpp55t9s2r8c0l62kt16sic4ipaon.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f609afd..941efb4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ + + - \ No newline at end of file + diff --git a/app/src/main/java/com/android/trisolarispms/data/api/ApiClient.kt b/app/src/main/java/com/android/trisolarispms/data/api/ApiClient.kt new file mode 100644 index 0000000..4dc0978 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/ApiClient.kt @@ -0,0 +1,54 @@ +package com.android.trisolarispms.data.api + +import com.google.firebase.auth.FirebaseAuth +import okhttp3.Interceptor +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import java.util.concurrent.TimeUnit + +object ApiClient { + fun create( + auth: FirebaseAuth = FirebaseAuth.getInstance(), + baseUrl: String = ApiConstants.BASE_URL, + enableLogging: Boolean = true + ): ApiService { + val tokenProvider = FirebaseAuthTokenProvider(auth) + val authInterceptor = Interceptor { chain -> + val original = chain.request() + val token = try { + kotlinx.coroutines.runBlocking { tokenProvider.token() } + } catch (e: Exception) { + null + } + val request = if (token.isNullOrBlank()) { + original + } else { + original.newBuilder() + .addHeader("Authorization", "Bearer $token") + .build() + } + chain.proceed(request) + } + + val logging = HttpLoggingInterceptor().apply { + level = if (enableLogging) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE + } + + val client = OkHttpClient.Builder() + .addInterceptor(authInterceptor) + .addInterceptor(logging) + .connectTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS) + .build() + + return Retrofit.Builder() + .baseUrl(baseUrl) + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + .create(ApiService::class.java) + } +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/ApiConstants.kt b/app/src/main/java/com/android/trisolarispms/data/api/ApiConstants.kt new file mode 100644 index 0000000..a60b3ce --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/ApiConstants.kt @@ -0,0 +1,5 @@ +package com.android.trisolarispms.data.api + +object ApiConstants { + const val BASE_URL = "https://api.hoteltrisolaris.in/" +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/ApiService.kt b/app/src/main/java/com/android/trisolarispms/data/api/ApiService.kt new file mode 100644 index 0000000..39a0277 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/ApiService.kt @@ -0,0 +1,16 @@ +package com.android.trisolarispms.data.api + +interface ApiService : + AuthApi, + OrgApi, + PropertyApi, + RoomTypeApi, + RoomApi, + RoomImageApi, + BookingApi, + RoomStayApi, + CardApi, + GuestApi, + GuestDocumentApi, + TransportApi, + InboundEmailApi diff --git a/app/src/main/java/com/android/trisolarispms/data/api/AuthApi.kt b/app/src/main/java/com/android/trisolarispms/data/api/AuthApi.kt new file mode 100644 index 0000000..0ecaf28 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/AuthApi.kt @@ -0,0 +1,15 @@ +package com.android.trisolarispms.data.api + +import com.android.trisolarispms.data.api.model.AuthVerifyResponse +import com.android.trisolarispms.data.api.model.UserDto +import retrofit2.Response +import retrofit2.http.GET +import retrofit2.http.POST + +interface AuthApi { + @POST("auth/verify") + suspend fun verifyAuth(): Response + + @GET("auth/me") + suspend fun me(): Response +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/AuthTokenProvider.kt b/app/src/main/java/com/android/trisolarispms/data/api/AuthTokenProvider.kt new file mode 100644 index 0000000..cc311f8 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/AuthTokenProvider.kt @@ -0,0 +1,5 @@ +package com.android.trisolarispms.data.api + +interface AuthTokenProvider { + suspend fun token(): String? +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/BookingApi.kt b/app/src/main/java/com/android/trisolarispms/data/api/BookingApi.kt new file mode 100644 index 0000000..5725762 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/BookingApi.kt @@ -0,0 +1,50 @@ +package com.android.trisolarispms.data.api + +import com.android.trisolarispms.data.api.model.ActionResponse +import com.android.trisolarispms.data.api.model.BookingCancelRequest +import com.android.trisolarispms.data.api.model.BookingCheckInRequest +import com.android.trisolarispms.data.api.model.BookingCheckOutRequest +import com.android.trisolarispms.data.api.model.BookingNoShowRequest +import com.android.trisolarispms.data.api.model.BookingRoomStayCreateRequest +import com.android.trisolarispms.data.api.model.RoomStayDto +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.POST +import retrofit2.http.Path + +interface BookingApi { + @POST("properties/{propertyId}/bookings/{bookingId}/check-in") + suspend fun checkIn( + @Path("propertyId") propertyId: String, + @Path("bookingId") bookingId: String, + @Body body: BookingCheckInRequest + ): Response + + @POST("properties/{propertyId}/bookings/{bookingId}/check-out") + suspend fun checkOut( + @Path("propertyId") propertyId: String, + @Path("bookingId") bookingId: String, + @Body body: BookingCheckOutRequest + ): Response + + @POST("properties/{propertyId}/bookings/{bookingId}/cancel") + suspend fun cancelBooking( + @Path("propertyId") propertyId: String, + @Path("bookingId") bookingId: String, + @Body body: BookingCancelRequest + ): Response + + @POST("properties/{propertyId}/bookings/{bookingId}/no-show") + suspend fun noShow( + @Path("propertyId") propertyId: String, + @Path("bookingId") bookingId: String, + @Body body: BookingNoShowRequest + ): Response + + @POST("properties/{propertyId}/bookings/{bookingId}/room-stays") + suspend fun preAssignRoomStay( + @Path("propertyId") propertyId: String, + @Path("bookingId") bookingId: String, + @Body body: BookingRoomStayCreateRequest + ): Response +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/CardApi.kt b/app/src/main/java/com/android/trisolarispms/data/api/CardApi.kt new file mode 100644 index 0000000..18a1f57 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/CardApi.kt @@ -0,0 +1,39 @@ +package com.android.trisolarispms.data.api + +import com.android.trisolarispms.data.api.model.ActionResponse +import com.android.trisolarispms.data.api.model.CardDto +import com.android.trisolarispms.data.api.model.CardIssueRequest +import com.android.trisolarispms.data.api.model.CardPrepareRequest +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.GET +import retrofit2.http.POST +import retrofit2.http.Path + +interface CardApi { + @POST("properties/{propertyId}/room-stays/{roomStayId}/cards/prepare") + suspend fun prepareCard( + @Path("propertyId") propertyId: String, + @Path("roomStayId") roomStayId: String, + @Body body: CardPrepareRequest + ): Response + + @POST("properties/{propertyId}/room-stays/{roomStayId}/cards") + suspend fun issueCard( + @Path("propertyId") propertyId: String, + @Path("roomStayId") roomStayId: String, + @Body body: CardIssueRequest + ): Response + + @GET("properties/{propertyId}/room-stays/{roomStayId}/cards") + suspend fun listCards( + @Path("propertyId") propertyId: String, + @Path("roomStayId") roomStayId: String + ): Response> + + @POST("properties/{propertyId}/room-stays/cards/{cardId}/revoke") + suspend fun revokeCard( + @Path("propertyId") propertyId: String, + @Path("cardId") cardId: String + ): Response +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/FirebaseAuthTokenProvider.kt b/app/src/main/java/com/android/trisolarispms/data/api/FirebaseAuthTokenProvider.kt new file mode 100644 index 0000000..2664895 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/FirebaseAuthTokenProvider.kt @@ -0,0 +1,13 @@ +package com.android.trisolarispms.data.api + +import com.google.firebase.auth.FirebaseAuth +import kotlinx.coroutines.tasks.await + +class FirebaseAuthTokenProvider( + private val auth: FirebaseAuth +) : AuthTokenProvider { + override suspend fun token(): String? { + val user = auth.currentUser ?: return null + return user.getIdToken(false).await().token + } +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/GuestApi.kt b/app/src/main/java/com/android/trisolarispms/data/api/GuestApi.kt new file mode 100644 index 0000000..6eb55d4 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/GuestApi.kt @@ -0,0 +1,42 @@ +package com.android.trisolarispms.data.api + +import com.android.trisolarispms.data.api.model.GuestDto +import com.android.trisolarispms.data.api.model.GuestRatingDto +import com.android.trisolarispms.data.api.model.GuestRatingRequest +import com.android.trisolarispms.data.api.model.GuestVehicleDto +import com.android.trisolarispms.data.api.model.GuestVehicleRequest +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.GET +import retrofit2.http.POST +import retrofit2.http.Path +import retrofit2.http.Query + +interface GuestApi { + @GET("properties/{propertyId}/guests/search") + suspend fun searchGuests( + @Path("propertyId") propertyId: String, + @Query("phone") phone: String? = null, + @Query("vehicleNumber") vehicleNumber: String? = null + ): Response> + + @POST("properties/{propertyId}/guests/{guestId}/vehicles") + suspend fun addGuestVehicle( + @Path("propertyId") propertyId: String, + @Path("guestId") guestId: String, + @Body body: GuestVehicleRequest + ): Response + + @POST("properties/{propertyId}/guests/{guestId}/ratings") + suspend fun addGuestRating( + @Path("propertyId") propertyId: String, + @Path("guestId") guestId: String, + @Body body: GuestRatingRequest + ): Response + + @GET("properties/{propertyId}/guests/{guestId}/ratings") + suspend fun listGuestRatings( + @Path("propertyId") propertyId: String, + @Path("guestId") guestId: String + ): Response> +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/GuestDocumentApi.kt b/app/src/main/java/com/android/trisolarispms/data/api/GuestDocumentApi.kt new file mode 100644 index 0000000..dc57034 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/GuestDocumentApi.kt @@ -0,0 +1,39 @@ +package com.android.trisolarispms.data.api + +import com.android.trisolarispms.data.api.model.GuestDocumentDto +import okhttp3.MultipartBody +import okhttp3.RequestBody +import okhttp3.ResponseBody +import retrofit2.Response +import retrofit2.http.GET +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Path +import retrofit2.http.Streaming + +interface GuestDocumentApi { + @Multipart + @POST("properties/{propertyId}/guests/{guestId}/documents") + suspend fun uploadGuestDocument( + @Path("propertyId") propertyId: String, + @Path("guestId") guestId: String, + @Part file: MultipartBody.Part, + @Part("docType") docType: RequestBody, + @Part("bookingId") bookingId: RequestBody + ): Response + + @GET("properties/{propertyId}/guests/{guestId}/documents") + suspend fun listGuestDocuments( + @Path("propertyId") propertyId: String, + @Path("guestId") guestId: String + ): Response> + + @Streaming + @GET("properties/{propertyId}/guests/{guestId}/documents/{documentId}/file") + suspend fun getGuestDocumentFile( + @Path("propertyId") propertyId: String, + @Path("guestId") guestId: String, + @Path("documentId") documentId: String + ): Response +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/InboundEmailApi.kt b/app/src/main/java/com/android/trisolarispms/data/api/InboundEmailApi.kt new file mode 100644 index 0000000..bb08af3 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/InboundEmailApi.kt @@ -0,0 +1,30 @@ +package com.android.trisolarispms.data.api + +import com.android.trisolarispms.data.api.model.ActionResponse +import okhttp3.MultipartBody +import okhttp3.RequestBody +import okhttp3.ResponseBody +import retrofit2.Response +import retrofit2.http.GET +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Path +import retrofit2.http.Streaming + +interface InboundEmailApi { + @Streaming + @GET("properties/{propertyId}/inbound-emails/{emailId}/file") + suspend fun getInboundEmailFile( + @Path("propertyId") propertyId: String, + @Path("emailId") emailId: String + ): Response + + @Multipart + @POST("properties/{propertyId}/inbound-emails/manual") + suspend fun uploadInboundEmail( + @Path("propertyId") propertyId: String, + @Part file: MultipartBody.Part, + @Part("sourceBookingId") sourceBookingId: RequestBody? + ): Response +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/OrgApi.kt b/app/src/main/java/com/android/trisolarispms/data/api/OrgApi.kt new file mode 100644 index 0000000..ddcc903 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/OrgApi.kt @@ -0,0 +1,17 @@ +package com.android.trisolarispms.data.api + +import com.android.trisolarispms.data.api.model.OrgCreateRequest +import com.android.trisolarispms.data.api.model.OrgDto +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.GET +import retrofit2.http.POST +import retrofit2.http.Path + +interface OrgApi { + @POST("orgs") + suspend fun createOrg(@Body body: OrgCreateRequest): Response + + @GET("orgs/{orgId}") + suspend fun getOrg(@Path("orgId") orgId: String): Response +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/PropertyApi.kt b/app/src/main/java/com/android/trisolarispms/data/api/PropertyApi.kt new file mode 100644 index 0000000..bb212be --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/PropertyApi.kt @@ -0,0 +1,51 @@ +package com.android.trisolarispms.data.api + +import com.android.trisolarispms.data.api.model.PropertyCreateRequest +import com.android.trisolarispms.data.api.model.PropertyDto +import com.android.trisolarispms.data.api.model.PropertyUpdateRequest +import com.android.trisolarispms.data.api.model.UserDto +import com.android.trisolarispms.data.api.model.UserRolesUpdateRequest +import com.android.trisolarispms.data.api.model.ActionResponse +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.DELETE +import retrofit2.http.GET +import retrofit2.http.POST +import retrofit2.http.PUT +import retrofit2.http.Path + +interface PropertyApi { + @POST("orgs/{orgId}/properties") + suspend fun createProperty( + @Path("orgId") orgId: String, + @Body body: PropertyCreateRequest + ): Response + + @GET("orgs/{orgId}/properties") + suspend fun listProperties(@Path("orgId") orgId: String): Response> + + @PUT("properties/{propertyId}") + suspend fun updateProperty( + @Path("propertyId") propertyId: String, + @Body body: PropertyUpdateRequest + ): Response + + @GET("orgs/{orgId}/users") + suspend fun listOrgUsers(@Path("orgId") orgId: String): Response> + + @GET("properties/{propertyId}/users") + suspend fun listPropertyUsers(@Path("propertyId") propertyId: String): Response> + + @PUT("properties/{propertyId}/users/{userId}/roles") + suspend fun updateUserRoles( + @Path("propertyId") propertyId: String, + @Path("userId") userId: String, + @Body body: UserRolesUpdateRequest + ): Response + + @DELETE("properties/{propertyId}/users/{userId}") + suspend fun deletePropertyUser( + @Path("propertyId") propertyId: String, + @Path("userId") userId: String + ): Response +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/RoomApi.kt b/app/src/main/java/com/android/trisolarispms/data/api/RoomApi.kt new file mode 100644 index 0000000..b21fcde --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/RoomApi.kt @@ -0,0 +1,51 @@ +package com.android.trisolarispms.data.api + +import com.android.trisolarispms.data.api.model.AvailabilityResponse +import com.android.trisolarispms.data.api.model.RoomBoardDto +import com.android.trisolarispms.data.api.model.RoomCreateRequest +import com.android.trisolarispms.data.api.model.RoomDto +import com.android.trisolarispms.data.api.model.RoomUpdateRequest +import okhttp3.ResponseBody +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.GET +import retrofit2.http.POST +import retrofit2.http.PUT +import retrofit2.http.Path +import retrofit2.http.Query +import retrofit2.http.Streaming + +interface RoomApi { + @GET("properties/{propertyId}/rooms") + suspend fun listRooms(@Path("propertyId") propertyId: String): Response> + + @POST("properties/{propertyId}/rooms") + suspend fun createRoom( + @Path("propertyId") propertyId: String, + @Body body: RoomCreateRequest + ): Response + + @PUT("properties/{propertyId}/rooms/{roomId}") + suspend fun updateRoom( + @Path("propertyId") propertyId: String, + @Path("roomId") roomId: String, + @Body body: RoomUpdateRequest + ): Response + + @GET("properties/{propertyId}/rooms/board") + suspend fun getRoomBoard(@Path("propertyId") propertyId: String): Response + + @Streaming + @GET("properties/{propertyId}/rooms/board/stream") + suspend fun streamRoomBoard(@Path("propertyId") propertyId: String): Response + + @GET("properties/{propertyId}/rooms/availability") + suspend fun getRoomAvailability(@Path("propertyId") propertyId: String): Response + + @GET("properties/{propertyId}/rooms/availability-range") + suspend fun getRoomAvailabilityRange( + @Path("propertyId") propertyId: String, + @Query("from") from: String, + @Query("to") to: String + ): Response +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/RoomImageApi.kt b/app/src/main/java/com/android/trisolarispms/data/api/RoomImageApi.kt new file mode 100644 index 0000000..3361f7f --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/RoomImageApi.kt @@ -0,0 +1,38 @@ +package com.android.trisolarispms.data.api + +import com.android.trisolarispms.data.api.model.ImageDto +import okhttp3.MultipartBody +import okhttp3.ResponseBody +import retrofit2.Response +import retrofit2.http.GET +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Path +import retrofit2.http.Query +import retrofit2.http.Streaming + +interface RoomImageApi { + @GET("properties/{propertyId}/rooms/{roomId}/images") + suspend fun listRoomImages( + @Path("propertyId") propertyId: String, + @Path("roomId") roomId: String + ): Response> + + @Multipart + @POST("properties/{propertyId}/rooms/{roomId}/images") + suspend fun uploadRoomImage( + @Path("propertyId") propertyId: String, + @Path("roomId") roomId: String, + @Part file: MultipartBody.Part + ): Response + + @Streaming + @GET("properties/{propertyId}/rooms/{roomId}/images/{imageId}/file") + suspend fun getRoomImageFile( + @Path("propertyId") propertyId: String, + @Path("roomId") roomId: String, + @Path("imageId") imageId: String, + @Query("size") size: String? = null + ): Response +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/RoomStayApi.kt b/app/src/main/java/com/android/trisolarispms/data/api/RoomStayApi.kt new file mode 100644 index 0000000..4bcd651 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/RoomStayApi.kt @@ -0,0 +1,17 @@ +package com.android.trisolarispms.data.api + +import com.android.trisolarispms.data.api.model.RoomChangeRequest +import com.android.trisolarispms.data.api.model.RoomStayDto +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.POST +import retrofit2.http.Path + +interface RoomStayApi { + @POST("properties/{propertyId}/room-stays/{roomStayId}/change-room") + suspend fun changeRoom( + @Path("propertyId") propertyId: String, + @Path("roomStayId") roomStayId: String, + @Body body: RoomChangeRequest + ): Response +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/RoomTypeApi.kt b/app/src/main/java/com/android/trisolarispms/data/api/RoomTypeApi.kt new file mode 100644 index 0000000..09c93bb --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/RoomTypeApi.kt @@ -0,0 +1,37 @@ +package com.android.trisolarispms.data.api + +import com.android.trisolarispms.data.api.model.ActionResponse +import com.android.trisolarispms.data.api.model.RoomTypeCreateRequest +import com.android.trisolarispms.data.api.model.RoomTypeDto +import com.android.trisolarispms.data.api.model.RoomTypeUpdateRequest +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.DELETE +import retrofit2.http.GET +import retrofit2.http.POST +import retrofit2.http.PUT +import retrofit2.http.Path + +interface RoomTypeApi { + @POST("properties/{propertyId}/room-types") + suspend fun createRoomType( + @Path("propertyId") propertyId: String, + @Body body: RoomTypeCreateRequest + ): Response + + @GET("properties/{propertyId}/room-types") + suspend fun listRoomTypes(@Path("propertyId") propertyId: String): Response> + + @PUT("properties/{propertyId}/room-types/{roomTypeId}") + suspend fun updateRoomType( + @Path("propertyId") propertyId: String, + @Path("roomTypeId") roomTypeId: String, + @Body body: RoomTypeUpdateRequest + ): Response + + @DELETE("properties/{propertyId}/room-types/{roomTypeId}") + suspend fun deleteRoomType( + @Path("propertyId") propertyId: String, + @Path("roomTypeId") roomTypeId: String + ): Response +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/TransportApi.kt b/app/src/main/java/com/android/trisolarispms/data/api/TransportApi.kt new file mode 100644 index 0000000..efa0e93 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/TransportApi.kt @@ -0,0 +1,11 @@ +package com.android.trisolarispms.data.api + +import com.android.trisolarispms.data.api.model.TransportModeDto +import retrofit2.Response +import retrofit2.http.GET +import retrofit2.http.Path + +interface TransportApi { + @GET("properties/{propertyId}/transport-modes") + suspend fun listTransportModes(@Path("propertyId") propertyId: String): Response> +} diff --git a/app/src/main/java/com/android/trisolarispms/data/api/model/AuthModels.kt b/app/src/main/java/com/android/trisolarispms/data/api/model/AuthModels.kt new file mode 100644 index 0000000..53ee367 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/model/AuthModels.kt @@ -0,0 +1,7 @@ +package com.android.trisolarispms.data.api.model + +data class AuthVerifyResponse( + val user: UserDto? = null, + val orgId: String? = null, + val propertyId: String? = null +) diff --git a/app/src/main/java/com/android/trisolarispms/data/api/model/BookingModels.kt b/app/src/main/java/com/android/trisolarispms/data/api/model/BookingModels.kt new file mode 100644 index 0000000..5a245d9 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/model/BookingModels.kt @@ -0,0 +1,58 @@ +package com.android.trisolarispms.data.api.model + +data class BookingCheckInRequest( + val roomIds: List, + val checkInAt: String? = null, + val transportMode: String? = null, + val transportVehicleNumber: String? = null, + val notes: String? = null, + val adultCount: Int? = null, + val childCount: Int? = null, + val maleCount: Int? = null, + val femaleCount: Int? = null, + val totalGuestCount: Int? = null +) + +data class BookingCheckOutRequest( + val checkOutAt: String? = null, + val notes: String? = null +) + +data class BookingCancelRequest( + val cancelledAt: String? = null, + val reason: String? = null +) + +data class BookingNoShowRequest( + val noShowAt: String? = null, + val reason: String? = null +) + +data class BookingRoomStayCreateRequest( + val roomId: String, + val fromAt: String, + val toAt: String, + val notes: String? = null +) + +// Room Stays + +data class RoomStayCreateRequest( + val roomId: String, + val guestId: String? = null, + val checkIn: String? = null, + val checkOut: String? = null +) + +data class RoomStayDto( + val id: String? = null, + val bookingId: String? = null, + val roomId: String? = null, + val status: String? = null +) + +data class RoomChangeRequest( + val newRoomId: String, + val movedAt: String? = null, + val idempotencyKey: String +) diff --git a/app/src/main/java/com/android/trisolarispms/data/api/model/CardModels.kt b/app/src/main/java/com/android/trisolarispms/data/api/model/CardModels.kt new file mode 100644 index 0000000..fe49eb4 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/model/CardModels.kt @@ -0,0 +1,18 @@ +package com.android.trisolarispms.data.api.model + +data class CardPrepareRequest( + val expiresAt: String? = null +) + +data class CardIssueRequest( + val cardId: String, + val cardIndex: Int, + val issuedAt: String? = null, + val expiresAt: String +) + +data class CardDto( + val id: String? = null, + val cardNumber: String? = null, + val status: String? = null +) diff --git a/app/src/main/java/com/android/trisolarispms/data/api/model/CommonModels.kt b/app/src/main/java/com/android/trisolarispms/data/api/model/CommonModels.kt new file mode 100644 index 0000000..0edff31 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/model/CommonModels.kt @@ -0,0 +1,6 @@ +package com.android.trisolarispms.data.api.model + +data class ActionResponse( + val success: Boolean? = null, + val message: String? = null +) diff --git a/app/src/main/java/com/android/trisolarispms/data/api/model/GuestModels.kt b/app/src/main/java/com/android/trisolarispms/data/api/model/GuestModels.kt new file mode 100644 index 0000000..e4bf097 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/model/GuestModels.kt @@ -0,0 +1,37 @@ +package com.android.trisolarispms.data.api.model + +data class GuestDto( + val id: String? = null, + val name: String? = null, + val phone: String? = null, + val email: String? = null +) + +data class GuestVehicleRequest( + val vehicleNumber: String +) + +data class GuestVehicleDto( + val id: String? = null, + val vehicleNumber: String? = null +) + +data class GuestRatingRequest( + val bookingId: String, + val score: String, + val notes: String? = null +) + +data class GuestRatingDto( + val id: String? = null, + val score: String? = null, + val notes: String? = null, + val createdAt: String? = null +) + +data class GuestDocumentDto( + val id: String? = null, + val type: String? = null, + val fileName: String? = null, + val createdAt: String? = null +) diff --git a/app/src/main/java/com/android/trisolarispms/data/api/model/OrgModels.kt b/app/src/main/java/com/android/trisolarispms/data/api/model/OrgModels.kt new file mode 100644 index 0000000..9571826 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/model/OrgModels.kt @@ -0,0 +1,14 @@ +package com.android.trisolarispms.data.api.model + +data class OrgCreateRequest( + val name: String, + val emailAliases: List? = null, + val allowedTransportModes: List? = null +) + +data class OrgDto( + val id: String? = null, + val name: String? = null, + val emailAliases: List? = null, + val allowedTransportModes: List? = null +) diff --git a/app/src/main/java/com/android/trisolarispms/data/api/model/PropertyModels.kt b/app/src/main/java/com/android/trisolarispms/data/api/model/PropertyModels.kt new file mode 100644 index 0000000..7f6b5a0 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/model/PropertyModels.kt @@ -0,0 +1,38 @@ +package com.android.trisolarispms.data.api.model + +data class PropertyCreateRequest( + val code: String, + val name: String, + val addressText: String? = null, + val timezone: String? = null, + val currency: String? = null, + val emailAddresses: List? = null, + val otaAliases: List? = null, + val allowedTransportModes: List? = null +) + +data class PropertyUpdateRequest( + val code: String? = null, + val name: String? = null, + val addressText: String? = null, + val timezone: String? = null, + val currency: String? = null, + val active: Boolean? = null, + val emailAddresses: List? = null, + val otaAliases: List? = null, + val allowedTransportModes: List? = null +) + +data class PropertyDto( + val id: String? = null, + val orgId: String? = null, + val code: String? = null, + val name: String? = null, + val addressText: String? = null, + val timezone: String? = null, + val currency: String? = null, + val active: Boolean? = null, + val emailAddresses: List? = null, + val otaAliases: List? = null, + val allowedTransportModes: List? = null +) diff --git a/app/src/main/java/com/android/trisolarispms/data/api/model/RoomModels.kt b/app/src/main/java/com/android/trisolarispms/data/api/model/RoomModels.kt new file mode 100644 index 0000000..6b64ecf --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/model/RoomModels.kt @@ -0,0 +1,62 @@ +package com.android.trisolarispms.data.api.model + +data class RoomCreateRequest( + val roomNumber: String, + val floor: String? = null, + val roomTypeId: String, + val hasNfc: Boolean? = null, + val active: Boolean? = null, + val maintenance: Boolean? = null, + val notes: String? = null +) + +data class RoomUpdateRequest( + val roomNumber: String, + val floor: String? = null, + val roomTypeId: String, + val hasNfc: Boolean? = null, + val active: Boolean? = null, + val maintenance: Boolean? = null, + val notes: String? = null +) + +data class RoomDto( + val id: String? = null, + val roomNumber: String? = null, + val roomTypeId: String? = null, + val floor: String? = null, + val hasNfc: Boolean? = null, + val active: Boolean? = null, + val maintenance: Boolean? = null, + val notes: String? = null +) + +data class RoomBoardDto( + val items: List = emptyList() +) + +data class RoomBoardItemDto( + val roomId: String? = null, + val status: String? = null, + val roomStayId: String? = null, + val guestName: String? = null +) + +data class AvailabilityResponse( + val rooms: List = emptyList() +) + +data class RoomAvailabilityDto( + val roomId: String? = null, + val date: String? = null, + val available: Boolean? = null, + val rate: Double? = null +) + +// Images + +data class ImageDto( + val id: String? = null, + val url: String? = null, + val fileName: String? = null +) diff --git a/app/src/main/java/com/android/trisolarispms/data/api/model/RoomTypeModels.kt b/app/src/main/java/com/android/trisolarispms/data/api/model/RoomTypeModels.kt new file mode 100644 index 0000000..222ed42 --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/model/RoomTypeModels.kt @@ -0,0 +1,26 @@ +package com.android.trisolarispms.data.api.model + +data class RoomTypeCreateRequest( + val code: String, + val name: String, + val maxAdults: Int? = null, + val maxChildren: Int? = null, + val otaAliases: List? = null +) + +data class RoomTypeUpdateRequest( + val code: String? = null, + val name: String? = null, + val maxAdults: Int? = null, + val maxChildren: Int? = null, + val otaAliases: List? = null +) + +data class RoomTypeDto( + val id: String? = null, + val code: String? = null, + val name: String? = null, + val maxAdults: Int? = null, + val maxChildren: Int? = null, + val otaAliases: List? = null +) diff --git a/app/src/main/java/com/android/trisolarispms/data/api/model/TransportModels.kt b/app/src/main/java/com/android/trisolarispms/data/api/model/TransportModels.kt new file mode 100644 index 0000000..81fc4ea --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/model/TransportModels.kt @@ -0,0 +1,6 @@ +package com.android.trisolarispms.data.api.model + +data class TransportModeDto( + val id: String? = null, + val name: String? = null +) diff --git a/app/src/main/java/com/android/trisolarispms/data/api/model/UserModels.kt b/app/src/main/java/com/android/trisolarispms/data/api/model/UserModels.kt new file mode 100644 index 0000000..3dead1c --- /dev/null +++ b/app/src/main/java/com/android/trisolarispms/data/api/model/UserModels.kt @@ -0,0 +1,13 @@ +package com.android.trisolarispms.data.api.model + +data class UserDto( + val id: String? = null, + val name: String? = null, + val email: String? = null, + val phone: String? = null, + val roles: List? = null +) + +data class UserRolesUpdateRequest( + val roles: List +) diff --git a/build.gradle.kts b/build.gradle.kts index 18318be..1263c00 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,4 +2,5 @@ plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.kotlin.compose) apply false + id("com.google.gms.google-services") version "4.4.4" apply false } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8ddeeac..9a00e43 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,6 +8,11 @@ lifecycleRuntimeKtx = "2.6.1" activityCompose = "1.8.0" kotlin = "2.0.21" composeBom = "2024.09.00" +retrofit = "2.11.0" +okhttp = "4.12.0" +firebaseBom = "33.5.1" +coroutinesPlayServices = "1.7.3" +firebaseAuthKtx = "24.0.1" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -24,8 +29,15 @@ androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "u androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } +retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" } +retrofit-converter-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" } +okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" } +okhttp-logging = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" } +firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebaseBom" } +firebase-auth-ktx = { group = "com.google.firebase", name = "firebase-auth-ktx" } +kotlinx-coroutines-play-services = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-play-services", version.ref = "coroutinesPlayServices" } +google-firebase-auth-ktx = { group = "com.google.firebase", name = "firebase-auth-ktx", version.ref = "firebaseAuthKtx" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } -